对于带有运动部件的模型,VAO/VBO 的 OpenGL 结构?
我来自这个问题:
我使用 OpenGL 3.3 并且不会使用已弃用的功能。我使用 Assimp 导入我的搅拌机模型。但我有点困惑,我应该将它们分成多少 VAO 和 VBO。
首先问一个小问题。我使用 glDrawElements,这是否意味着我无法交错顶点属性,或者 VAO 可以使用 glVertexAttribPointer 和 glDrawElements 偏移量来确定我的顶点位置在哪里?
我想主要问题归结为我如何为具有多个移动部件和多个网格的模型构建 VAO/VBO。部分。
assimp 中的每个节点可以包含多个网格,其中每个网格都有纹理、顶点、法线、材质等。assimp 中的节点包含变换。假设我有一艘上面有炮塔的船。我希望能够旋转炮塔。这是否意味着我将使船舶节点成为一个单独的 VAO,其中每个网格包含其属性(或多个 VBO 等)。 我想我
draw(ship); //call to draw ship VAO
pushMatrix(turretMatrix) //updating uniform modelview matrix for the shader
draw(turret); //call to draw turret VAO
还没有完全理解 UBO(统一缓冲对象),但似乎我可以传递多个制服,这会帮助我在单个 VAO 中包含带有可移动部件的完整模型吗?
I came from this question:
I use OpenGL 3.3 and will not to use deprecated features. Im using Assimp to import my blender models. But im a bit confused as to how much i should split them up in terms of VAO's and VBO's.
First off a little side question. I use glDrawElements, do that mean i cannot interleave my vertex attributes or can the VAO figure out using the glVertexAttribPointer and the glDrawElements offset to see where my vertex position is?
Main question i guess, boils down to how do i structure my VAO/VBO's for a model with multiple moving parts, and multiple meshes pr. part.
Each node in assimp can contain multiple meshes where each mesh has texture, vertices, normals, material etc. The nodes in assimp contains the transformations. Say i have a ship with a cannon turret on it. I want to be able to roatate the turret. Do this mean i will make the ship node a seperate VAO with VBO's for each mesh containing its attributes(or multiple VBO's etc.).
I guess it goes like
draw(ship); //call to draw ship VAO
pushMatrix(turretMatrix) //updating uniform modelview matrix for the shader
draw(turret); //call to draw turret VAO
I don't fully understand UBO(uniform buffer objects) yet, but it seems i can pass in multiple uniforms, will that help me contain a full model with moveable parts in a single VAO?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
首先,关闭 VAO 仅“记住”最后一个顶点属性绑定(以及索引缓冲区的 VBO 绑定(GL_ELEMENT_ARRAY_BUFFER_BINDING),如果有的话)。因此它不会记住
glDrawElements()
中的偏移量,您需要稍后在使用 VAO 时调用它。它不会阻止您使用交错顶点数组。让我尝试解释一下:稍后...
所以您会看到...您可以使用单个 VAO 和一个或多个 VBO 使用
glDrawElements
绘制交错顶点数组。要回答问题的第二部分,您可以为网格的不同部分使用不同的 VAO 和 VBO(因此绘制单独的部分很容易),或者您可以将所有内容融合为一对 VAO VBO(因此您无需调用
glBind*()
经常)并使用多个glDraw*()
调用来绘制网格的各个部分(如上面的代码所示 - 想象一下第一个glDrawElements()
绘制船舶,第二个绘制炮塔,您只需在调用之间更新一些矩阵统一即可)。由于着色器可以在制服中包含多个模型视图矩阵,因此您还可以将网格 ID 编码为另一个顶点属性,并让顶点着色器根据此属性选择使用哪个矩阵来变换顶点。这个想法也可以扩展到每个单个顶点使用多个矩阵,并为每个矩阵分配一些权重。这通常在为有机对象(例如玩家角色)设置动画时使用(查找“蒙皮”)。
作为统一缓冲区对象,唯一的优点是您可以将大量数据打包到其中,并且它们可以在着色器之间轻松共享(只需将 UBO 绑定到任何能够使用它的着色器即可)。使用它们并没有真正的优势,除非您想要拥有包含 1000 个矩阵的对象。
另外,上面的源代码是我凭记忆写的。如果有一些错误/问题请告诉我...
first, off VAO only "remembers" the last vertex attribute bindings (and VBO binding for an index buffer (the
GL_ELEMENT_ARRAY_BUFFER_BINDING
), if there is one). So it does not remember offsets inglDrawElements()
, you need to call that later when using the VAO. It laso does not prevent you from using interleaved vertex arrays. Let me try to explain:Later ...
So you see ... you can draw interleaved vertex arrays using
glDrawElements
using a single VAO and one or more VBOs.To answer the second part of your question, you either can have different VAOs and VBOs for different parts of the mesh (so drawing separate parts is easy), or you can fuse all into one VAO VBO pair (so you need not call
glBind*()
often) and use multipleglDraw*()
calls to draw individual parts of the mesh (as seen in the code above - imagine the firstglDrawElements()
draws the ship and the second draws the turret, you just update some matrix uniform between the calls).Because shaders can contain multiple modelview matrices in uniforms, you can also encode mesh id as another vertex attribute, and let the vertex shader choose which matrix to use to transform the vertex, based on this attribute. This idea can also be extended to using multiple matrices per a single vertex, with some weights assigned for each matrix. This is commonly used when animating organic objects such as player character (look up "skinning").
As uniform buffer objects go, the only advantage is that you can pack a lot of data into them and that they can be easily shared between shaders (just bind the UBO to any shader that is able to use it). There is no real advantage in using them for you, except if you would be to have objects with 1OOOs of matrices.
Also, i wrote the source codes above from memory. Let me know if there are some errors / problems ...
@theswine
在 VAO 初始化期间不绑定它会导致我的程序崩溃,但是在绑定 VAO 后绑定它会导致它正确运行。您确定这没有保存在 VAO 中吗?
(顺便说一句:很抱歉提出一个旧话题,我只是认为这对其他人可能有用,这篇文章确实有用!(这提醒了我,谢谢!!))
@theswine
Not binding this during VAO initialization causes my program to crash, but binding it after binding the VAO causes it to run correctly. Are you sure this isn't saved in the VAO?
(BTW: sorry for bringing up an old topic, I just thought this could be useful to others, this post sure was! (which reminds me, thank you!!))