我想要身体健康 2023-01-22 13:23 采纳率: 100%
浏览 89
已结题

OpenGL框选动画

问题遇到的现象和发生背景

你好,我需要OpenGL实现框选的动画,就是鼠标按下移动时会跟随鼠标生成矩形,松开时矩形消失

遇到的现象和发生背景,请写出第一个错误信息

顶点应该是正确的,但窗口上没有图像

用代码块功能插入代码,请勿粘贴截图。 不用代码块回答率下降 50%
import numpy as np
from OpenGL.GL import *
from OpenGL.GLUT import *
from OpenGL.GL import shaders


class RectPainter():
    def __init__(self):
        """准备模型数据"""
        vshader_src = """
            #version 420 core
            layout (location = 0) in vec3 aPos;
            void main(){ 
                gl_Position = vec4(aPos.x, aPos.y, aPos.z, 1.0); // gl_Position是内置变量
            }
        """

        fshader_src = """
            #version 420 core
            out vec4 frag_color;
            void main(){
                frag_color = vec4(1.0f, 0.5f, 0.2f, 1.0f);// gl_FragColor是内置变量    
            } 
        """
        vshader = shaders.compileShader(vshader_src, GL_VERTEX_SHADER)
        fshader = shaders.compileShader(fshader_src, GL_FRAGMENT_SHADER)
        self.PROGRAM = shaders.compileProgram(vshader, fshader)
        self.start_x = 0
        self.start_y = 0
        self.end_x = 0
        self.end_y = 0
        self.clear_flag = False
        self.vao = glGenVertexArrays(1) 
        self.vertices_buffer = glGenBuffers(1)

    def draw(self):
        """绘制模型"""
        glClearColor(178 / 255, 195 / 255, 234 / 255, 0.5)
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)  # 清除缓冲区
        glUseProgram(self.PROGRAM)
        glBindVertexArray(self.vao)
        if self.clear_flag is True:
            self.start_x = 0
            self.start_y = 0
            self.end_x = 0
            self.end_y = 0
        # 顶点数据
        vertices = [[self.start_x, self.start_y, 0.0], [self.end_x, self.start_y, 0.0], [self.end_x, self.end_y, 0.0], [self.start_x, self.end_y, 0.0]]
        vertices = np.array(vertices, dtype=np.float32)

        glBindBuffer(GL_ARRAY_BUFFER, self.vertices_buffer)
        glBufferData(GL_ARRAY_BUFFER, vertices, GL_DYNAMIC_DRAW)  # 动态绘制
        glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, None)
        glEnableVertexAttribArray(0)
        # 绘制
        print("四点数据:", vertices)
        glDrawArrays(GL_LINE_LOOP, 0, 4)
        # 结束
        glBindVertexArray(0)
        glBindBuffer(GL_ARRAY_BUFFER, 0)
        glUseProgram(0)
        glFlush()  # 执行缓冲区指令


def mymouse(button, state, x, y):
    if button == GLUT_LEFT_BUTTON and state == GLUT_DOWN:
        painter.start_x, painter.start_y = x, y
        painter.end_x, painter.end_y = x, y
        painter.clear_flag = False
    elif button == GLUT_LEFT_BUTTON and state == GLUT_UP:
        painter.end_x, painter.end_y = x, y
        painter.clear_flag = True
        glutPostRedisplay()#update

    '''
    glutPostRedisplay()是一个OpenGL函数,用于重绘当前窗口。
    它通知OpenGL重新渲染整个窗口,以便更新视图。
    这通常用于动画等场景,在窗口大小、位置或其他视图参数发生变化时也会调用。
    '''

def mymotion(x, y):
    painter.end_x, painter.end_y = x, y
    glutPostRedisplay()#update


if __name__ == "__main__":
    glutInit()  # 1. 初始化glut库
    glutInitDisplayMode(GLUT_RGBA | GLUT_SINGLE)  # 2. 设置显示模式
    glutInitWindowSize(600, 400)  # 3. 设置窗口大小
    glutCreateWindow('OpenGL Demo')  # 2. 创建glut窗口
    painter = RectPainter()  # 3. 生成着色器程序、顶点数据集、颜色数据集
    glutDisplayFunc(painter.draw)  # 4. 绑定模型绘制函数
    glutMouseFunc(mymouse)  # 5. 绑定鼠标事件
    glutMotionFunc(mymotion)
    glutMainLoop()  # 6. 进入glut主循环


我的解答思路和尝试过的方法

定义一个类RectPainter,包含了初始化,绘图方法,重写鼠标点击,释放事件,在点击释放时记录坐标,释放时clear_flag为True,这样绘制时顶点坐标重置为0(不绘制)同时更新画面,重写鼠标移动事件,鼠标移动时记录坐标并更新画面

  • 写回答

1条回答

      报告相同问题?

      问题事件

      • 系统已结题 2月4日
      • 已采纳回答 1月27日
      • 创建了问题 1月22日

      悬赏问题

      • ¥15 ABAQUS简单的带传动系统运转不了
      • ¥15 关于git actions自动部署的问题
      • ¥25 小程序 view wx:for 循环太多时,如何在循环结束执行某个事件?
      • ¥15 曲率模态差matlab程序计算
      • ¥15 大概算是比较简单的坐标系旋转问题
      • ¥15 关于#python#的问题:安装完gym环境后
      • ¥15 关于稳像云台姿态控制中相机姿态误差表征
      • ¥15 求sm16306s驱动例程
      • ¥15 本地生活媒体平台口碑选品怎么获得权限
      • ¥15 R语言 回归树/袋装树/随机森林预测