用于运动部件的VAO/VBO的OpenGL结构? [英] OpenGL structure of VAO/VBO for model with moving parts?

查看:113
本文介绍了用于运动部件的VAO/VBO的OpenGL结构?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我来自这个问题:

opengl vbo建议

我使用OpenGL 3.3,并且不会使用不推荐使用的功能.我正在使用Assimp导入我的搅拌器模型.但是对于我应该按照VAO和VBO的多少来划分它们,我有些困惑.

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.

首先提出一个小问题.我使用glDrawElements,这是否意味着我无法交织我的顶点属性,或者VAO可以使用glVertexAttribPointer和glDrawElements偏移量来确定我的顶点位置在哪里?

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?

我想,主要问题归结为如何为具有多个运动部件和多个网格的模型构造VAO/VBO.部分.

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.

assimp中的每个节点可以包含多个网格,其中每个网格具有纹理,顶点,法线,材质等.assimp中的节点包含变换.说我有一艘上面有炮塔的船.我希望能够旋转炮塔.这是否意味着我将使每个包含其属性(或多个VBO等)的网格物体的VAO成为单独的VAO. 我想这就像

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

我还没有完全了解UBO(统一缓冲区对象),但是看来我可以传递多个制服,这是否可以帮助我在单个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?

推荐答案

首先,关闭VAO仅记住"最后一个顶点属性绑定(以及索引缓冲区(GL_ELEMENT_ARRAY_BUFFER_BINDING)的VBO绑定,如果有的话) .因此,它不记得glDrawElements()中的偏移量,您需要在以后使用VAO时调用它.同样,它也不会阻止您使用交错的顶点数组.让我尝试解释一下:

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 in glDrawElements(), 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:

int vbo[3];
glGenBuffers(3, vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo[0]);
glBufferData(GL_ARRAY_BUFFER, data0, size0);
glBindBuffer(GL_ARRAY_BUFFER, vbo[1]);
glBufferData(GL_ARRAY_BUFFER, data1, size1);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, data2, size2);
// create some buffers and fill them with data

int vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);
// create a VAO

{
    glBindBuffer(GL_ARRAY_BUFFER, vbo[0]); // not saved in VAO
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 3 * sizeof(float), NULL); // this is VAO saved state
    glEnableVertexAttribArray(0); // this is VAO saved state
    // sets up one vertex attrib array from vbo[0] (say positions)

    glBindBuffer(GL_ARRAY_BUFFER, vbo[1]); // not saved in VAO
    glVertexAttribPointer(1, 3, GL_FLOAT, false, 5 * sizeof(float), NULL); // this is VAO saved state
    glVertexAttribPointer(2, 2, GL_FLOAT, false, 5 * sizeof(float), (const void*)(2 * sizeof(float))); // this is VAO saved state
    glEnableVertexAttribArray(1); // this is VAO saved state
    glEnableVertexAttribArray(2); // this is VAO saved state
    // sets up two more VAAs from vbo[1] (say normals interleaved with texcoords)

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vbo[2]); // this is VAO saved state
    // uses the third buffer as the source for indices
}
// set up state that VAO "remembers"

glBindVertexArray(0); // bind different vaos, etc ...

稍后...

glBindVertexArray(vao); // bind our VAO (so we have VAAs 0, 1 and 2 as well as index buffer)
glDrawElements(GL_TRIANGLE_STRIP, 57, GL_UNSIGNED_INT, NULL);
glDrawElements(GL_TRIANGLE_STRIP, 23, GL_UNSIGNED_INT, (const void*)(57 * sizeof(unsigned int)));
// draws two parts of the mesh as triangle strips

所以您看到...您可以使用glDrawElements使用单个VAO和一个或多个VBO绘制交织的顶点阵列.

So you see ... you can draw interleaved vertex arrays using glDrawElements using a single VAO and one or more VBOs.

要回答问题的第二部分,您可以为网格的不同部分使用不同的VAO和VBO(这样就可以轻松绘制单独的部分),也可以将全部融合为一个VAO VBO对(因此您不必经常调用glBind*())并使用多个glDraw*()调用绘制网格的各个部分(如上面的代码所示-想象第一个glDrawElements()绘制飞船,第二个glDrawElements()绘制炮塔,您只需更新一些矩阵统一在通话之间).

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 multiple glDraw*() calls to draw individual parts of the mesh (as seen in the code above - imagine the first glDrawElements() draws the ship and the second draws the turret, you just update some matrix uniform between the calls).

因为着色器可以在制服中包含多个Modelview矩阵,所以您还可以将网格ID编码为另一个顶点属性,并让顶点着色器基于该属性选择用于变换顶点的矩阵.这个想法也可以扩展到每个单个顶点使用多个矩阵,并为每个矩阵分配一些权重.在为诸如角色角色之类的有机物体设置动画(查找蒙皮")时,通常使用此方法.

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").

随着统一的缓冲对象的发展,唯一的优势是您可以将大量数据打包到其中,并且可以在着色器之间轻松共享它们(只需将UBO绑定到能够使用它的任何着色器).为您使用它们并没有真正的优势,除非您要拥有的对象具有1OOOs的矩阵.

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 ...

这篇关于用于运动部件的VAO/VBO的OpenGL结构?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆