[英]OpenGL render multiple objects using single VBO and updata object's matrices using another VBO
So, I need the way to render multiple objects(not instances) using one draw call. 因此,我需要一种使用一次绘制调用来呈现多个对象(而非实例)的方法。 Actually I know how to do this, just to place data into single vbo/ibo and render, using glDrawElements.
实际上,我知道如何做到这一点,只是使用glDrawElements将数据放入单个vbo / ibo中并进行渲染。
The question is: what is efficient way to update uniform data without setting it up for every single object, using glUniform...? 问题是:使用glUniform ...无需为每个对象设置统一数据即可更新统一数据的有效方法是什么?
How can I setup one buffer containing all uniform data of dozens of objects, include MVP matrices, bind it and perform render using single draw call? 如何设置一个包含数十个对象的所有统一数据,包括MVP矩阵,绑定它并使用一次draw调用执行渲染的缓冲区? I tried to use UBOs, but it's not what I need at all.
我尝试使用UBO,但这根本不是我所需要的。
For rendering instances we just place uniform data, including matrices, at another VBO and set up attribute divisor using glVertexAttribDivisor, but it only works for instances. 对于渲染实例,我们仅将统一的数据(包括矩阵)放置在另一个VBO上,并使用glVertexAttribDivisor设置属性除数,但它仅适用于实例。
Is there a way to do that I want in OpenGL? 有什么方法可以在OpenGL中进行吗? If not, what can I do to overcome overheads of setting uniform data for dozens of objects?
如果没有,我该如何克服为数十个对象设置统一数据的开销?
For example like this: 例如这样:
{
// setting up VBO
glGenBuffers(1, &vbo);
glBindBuffer(vbo);
glBufferData(..., data_size);
// setup buffer
for(int i = 0; i < objects_num; i++)
glBufferSubData(...offset, size, &(objects[i]));
// the same for IBO
.........
// when setup some buffer, that will store all uniforms, for every object
.........
glDrawElements(...);
}
Thanks in advance for helping. 在此先感谢您的帮助。
If you're ok with requiring OpenGL 4.3 or higher, I believe you can render this with a single draw call using glMultiDrawElementsIndirect()
. 如果您可以要求使用OpenGL 4.3或更高版本,我相信您可以使用
glMultiDrawElementsIndirect()
通过一次绘制调用来渲染此图像。 This allows you to essentially make multiple draw calls with a single API call. 这实际上使您可以通过单个API调用进行多个绘制调用。 Each sub-call is defined by values in a struct of the form:
每个子调用均由以下形式的结构中的值定义:
typedef struct {
GLuint count;
GLuint instanceCount;
GLuint firstIndex;
GLuint baseVertex;
GLuint baseInstance;
} DrawElementsIndirectCommand;
Since you do not want to draw multiple instances of the same vertices, you use 1 for the instanceCount
in each draw call. 由于您不想绘制相同顶点的多个实例,因此在每个绘制调用中对
instanceCount
使用1。 The key idea is that you can still use instancing by specifying a different baseInstance
value for each one. 关键思想是您仍然可以通过为每个实例指定不同的
baseInstance
值来使用实例化。 So each object will have a different gl_InstanceID
value, and you can use instanced attributes for the values (matrices, etc) that you want to vary per object. 因此,每个对象将具有不同的
gl_InstanceID
值,并且您可以将实例化属性用于要针对每个对象而变化的值(矩阵等)。
So if you currently have a rendering loop: 因此,如果您当前有一个渲染循环:
for (int k = 0; k < objectCount; ++k) {
// set uniforms for object k.
glDrawElements(GL_TRIANGLES, object[k].indexCount,
GL_UNSIGNED_INT, object[k].indexOffset * sizeof(GLuint));
}
you would instead fill an array of the struct defined above with the arguments: 您可以使用以下参数填充上面定义的结构数组:
DrawElementsIndirectCommand cmds[objectCount];
for (int k = 0; k < objectCount; ++k) {
cmds[k].count = object[k].indexCount;
cmds[k].instanceCount = 1;
cmds[k].firstIndex = object[k].indexOffset;
cmds[k].baseVertex = 0;
cmds[k].baseInstance = k;
}
// Rest of setup.
glMultiDrawElementsIndirect(GL_TRIANGLES, GL_UNSIGNED_INT, 0, objectCount, 0);
I didn't provide code for the full setup above. 我没有为上面的完整设置提供代码。 The key steps include:
关键步骤包括:
cmds
array into a buffer, and bind it as GL_DRAW_INDIRECT_BUFFER
. cmds
数组放入缓冲区中,并将其绑定为GL_DRAW_INDIRECT_BUFFER
。 glVertexAttribDivisor(1)
. glVertexAttribDivisor(1)
实例指定它们。 For this to work, the indices for all the objects will have to be in the same index buffer, and the values for each attribute will have to be in the same VBO across all objects. 为此,所有对象的索引必须位于同一索引缓冲区中,并且每个属性的值必须在所有对象之间均位于同一VBO中。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.