Qt 面向对象的OpenGL绘图

Qt 面向对象的OpenGL绘图,qt,opengl,opengl-3,particle-system,multi-agent,Qt,Opengl,Opengl 3,Particle System,Multi Agent,我尝试在OSX10.9上用Qt(v5.1.1)编写OpenGL项目,采用现代管道实现的方式。该程序应该是一个基于多智能体的系统或粒子系统。然而,我缺乏理解如何从另一门课中画出一些东西 在cinder中有一些简单的DrawThisandth()命令,您可以调用它。我读了第六版的“OpenGL超级圣经”。从本教程和几个教程中,所有示例似乎都只涵盖了对初始化OpenGL的类进行所有修改的程序 我想实例化一些在网格上移动的对象,并绘制像素来显示它们的位置。我知道我必须调用void glVertexAtt

我尝试在OSX10.9上用Qt(v5.1.1)编写OpenGL项目,采用现代管道实现的方式。该程序应该是一个基于多智能体的系统或粒子系统。然而,我缺乏理解如何从另一门课中画出一些东西

在cinder中有一些简单的DrawThisandth()命令,您可以调用它。我读了第六版的“OpenGL超级圣经”。从本教程和几个教程中,所有示例似乎都只涵盖了对初始化OpenGL的类进行所有修改的程序

我想实例化一些在网格上移动的对象,并绘制像素来显示它们的位置。我知道我必须调用
void glVertexAttrib4fv(GLuint index,const GLfloat*vi)但这还不够

  • 我是否需要调用
    GlenableVertexAttributeArray(1)
    gldrawArray(GL_点,0,3)还有什么
  • 在实例化OpenGL和bevor主循环之后,我实例化了控制粒子的类,对吗
  • 我如何管理粒子在删除他被绘制的位置时绘制他自己

本课程正是基于此。

为了完整地回答您的问题,我必须写一大堆文字,我将尽量只指出最重要的方面。我希望这将有助于你充分利用你的知识,并可能进一步阅读,使其发挥作用

所有修改都是从初始化OpenGL的类中进行的

您可以为对象封装
update(time)
draw()
方法,然后在主循环中调用这些方法

我是否需要调用
GlenableVertexAttributeArray(1)
gldrawArray(GL_点,0,3)还有什么

我将把所有粒子放在一个顶点数组中,以避免在每个粒子之后重新绑定不同的顶点数组。然后必须使用
glBindVertexArray(vaid)
gldrawArray(GL_点,0,顶点计数)代码。注意
vertexCount
,它不是浮点数(正如您的问题所暗示的),而是顶点数,在您的示例中应该是1,或者在我建议的方法中应该是粒子数(如果我正确地假设
3
代表“我的顶点的x、y和z”)

因为你只有粒子
glpaurements(…)可能已经满足您的需要

在实例化OpenGL和bevor主循环之后,我实例化了控制粒子的类,对吗

这样,您的实例化顺序可能是正确的。在您的案例中,在调用主循环之前,您肯定应该执行所有实例化

我如何管理粒子在删除他被绘制的位置时绘制他自己

如果正确理解上一个问题:只需更改缓冲区对象中的元素(
glBufferData(…);
)。由于每次循环后都会清除屏幕并交换缓冲区,这将使它们移动。只需使用
update(time)
call更新他们的位置,例如
pos=pos+dir*time
,将新位置放入缓冲区,并使用
glBufferData(…)
将该缓冲区推送到顶点数组。请记住在推送缓冲区之前绑定顶点数组


我还想指出一些其他的事情

GlenableVertexAttributeArray(1)是为了使着色器程序中的顶点属性能够将数据传递给该属性。您应该创建一个着色器程序

  id = glCreateProgram()
  // ... create and attach shaders here
  // then bind attribute locations, e.g. positionMC
  glBindAttribLocation(id, 0, "positionMC"); 
  glLinkProgram(id);
在使用
glgenvertexarray()初始化顶点数组之后应该在着色器程序中启用顶点数组所需的所有属性。在本例中,
positionMC
将位于位置0,因此您可以调用

  glUseProgram(pid);
  glBindVertexArray(vaid);
  glEnableVertexAttribArray(1);
  glVertexAttribPointer(...);
这只需执行一次,因为OpenGL存储每个特定顶点数组的状态。通过重新绑定顶点数组,可以恢复该状态

在主循环中,您现在需要做的就是调用update和draw方法,例如:

  handleInputs();
  update(deltaTime);
  glClear(...);
  draw();
  swapBuffers();

为了完整地回答你的问题,我必须写一堆文字,我将尝试只指出最重要的方面。我希望这将有助于你充分利用你的知识,并可能进一步阅读,使其发挥作用

所有修改都是从初始化OpenGL的类中进行的

您可以为对象封装
update(time)
draw()
方法,然后在主循环中调用这些方法

我是否需要调用
GlenableVertexAttributeArray(1)
gldrawArray(GL_点,0,3)还有什么

我将把所有粒子放在一个顶点数组中,以避免在每个粒子之后重新绑定不同的顶点数组。然后必须使用
glBindVertexArray(vaid)
gldrawArray(GL_点,0,顶点计数)代码。注意
vertexCount
,它不是浮点数(正如您的问题所暗示的),而是顶点数,在您的示例中应该是1,或者在我建议的方法中应该是粒子数(如果我正确地假设
3
代表“我的顶点的x、y和z”)

因为你只有粒子
glpaurements(…)可能已经满足您的需要

在实例化OpenGL和bevor主循环之后,我实例化了控制粒子的类,对吗

这样,您的实例化顺序可能是正确的。在您的案例中,在调用主循环之前,您肯定应该执行所有实例化

我如何管理粒子在删除他被绘制的位置时绘制他自己

如果正确理解上一个问题:只需更改缓冲区对象中的元素(
glBufferData(…);
)。因为你会清除屏幕