如何在没有性能问题的情况下渲染大对象

时间:2018-06-02 00:00:36

标签: opengl

我有两个每帧渲染的对象,其中一个渲染速度很快,每帧都会更新,另一个渲染速度慢(使用实例渲染的大对象)。由于我不能在两个不同的线程中使用opengl,每次更新大对象时(为此,我调用glBufferData并使用新数据重置其缓冲区),程序滞后并且灯光对象停止渲染。我想一个解决方案是每帧渲染重物的部分,而不是一次渲染所有部分。但这种划分不太实际,所以有更好的方法吗?

1 个答案:

答案 0 :(得分:1)

由于您没有包含代码或描述性细节,我会尽力理解它。如果您的大型模型是静态的,并且不变,最好的办法是创建一个VBO(顶点缓冲区对象)并分配一次数据,然后使用提供的句柄进行渲染,在此处阅读更多内容; https://www.khronos.org/opengl/wiki/VBO_-_just_examples

但是,从您的大纲来看,我相信您的大型模型每帧都修改了顶点。此外,我相信你说你在每一帧使用glBufferData来更新GPU端的顶点/索引数据。

更有效的方法是改为映射索引/顶点缓冲区并仅修改需要更改的内容,而不是每帧重置数据。

<强> C ++

要执行此操作,请映射缓冲区并获取CPU端只写缓冲区;

void* result = glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY)

然后,您可以覆盖需要更改的值。执行此操作后,只需释放指针以使其更新;

glUnmapBuffer(GL_ARRAY_BUFFER);

可以将void*强制转换为顶点数据结构,然后将其修改为好像它是顶点数据数组。例如;

m_Buffer = (VertexData*)result;

此外,请注意glMapBuffer将等待GPU完成使用缓冲区。如果您不想要同步写入,请使用glMapBufferRange;

void* result = glMapBufferRange(GL_ARRAY_BUFFER, 0, getSize(), GL_MAP_WRITE_BIT | GL_MAP_UNSYNCHRONIZED_BIT | GL_MAP_INVALIDATE_RANGE_BIT)

以下是此方法的规格,说明和教程。阅读它们并充分了解正在发生的事情将是有益的。

glMapBuffer:https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBuffer.xhtml

glMapBufferRange:https://www.khronos.org/registry/OpenGL-Refpages/gl4/html/glMapBufferRange.xhtml

缓冲区映射:https://www.khronos.org/opengl/wiki/Buffer_Object#Mapping

缓冲流:https://www.khronos.org/opengl/wiki/Buffer_Object_Streaming