glMapBufferRange 持久缓冲区和交错数据
glMapBufferRange persistent buffers and interleaved data
好吧,经过更长的休息,我在这里有点茫然。 我正在尝试使用持久映射的缓冲区,拆分为 2 个缓冲区以提高性能。如果将其用作一个缓冲区,一切正常,一旦将其用作 2,它就会惨败。我不确定我错过了什么,但也许有人可以启发我。我阅读了很多教程和描述,但到目前为止,没有运气更好地理解它或找到这些问题的答案。
对于我的设置,我有以下数据:
Buffer[0] = Point.X;
Buffer[1] = Point.Y;
Buffer[2] = Point.Z;
Buffer[3] = U;
Buffer[4] = V;
Buffer[5] = Color.X;
Buffer[6] = Color.Y;
Buffer[7] = Color.Z;
Buffer[8] = Color.W;
在我的没有持久缓冲区的方法中,我这样做:
...
glBufferData(GL_ARRAY_BUFFER, sizeof(float) * TotalSize, Buffer, GL_STREAM_DRAW);
...
glVertexAttribPointer(VERTEX_COORD_ATTRIB, 3, GL_FLOAT, GL_FALSE, StrideSize, 0);
glVertexAttribPointer(TEXTURE_COORD_ATTRIB, 2, GL_FLOAT, GL_FALSE, StrideSize, (void*)VertFloatSize);
glVertexAttribPointer(COLOR_ATTRIB, 4, GL_FLOAT, GL_FALSE, StrideSize, (void*)(VertFloatSize+TexFloatSize));
...
glDrawArrays(Mode, 0, (BufferData.VertSize / FloatsPerVertex));
...
现在到持久性部分(我在这里省略了栅栏和同步内容,因为这似乎不是问题。
GLbitfield PersistentBufferFlags = GL_MAP_WRITE_BIT | GL_MAP_PERSISTENT_BIT | GL_MAP_COHERENT_BIT;
GLsizeiptr BufferSize=(2 * BUFFER_SIZE);
glBindBuffer(GL_ARRAY_BUFFER, PMB);
glBufferStorage(GL_ARRAY_BUFFER, BufferSize, 0, PersistentBufferFlags);
Buffer = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, BufferSize, PersistentBufferFlags);
现在这已经是我的第一个问题 - 这是正确的方法吗?用一个映射它并使用第一个缓冲区运行大小的偏移量继续,然后从那里继续使用第二个缓冲区的数据,或者它应该是像这样的相同存储的 2 个映射?:
glBindBuffer(GL_ARRAY_BUFFER, PMB);
glBufferStorage(GL_ARRAY_BUFFER, BufferSize, 0, PersistentBufferFlags);
Buffer[0] = (float*)glMapBufferRange(GL_ARRAY_BUFFER, 0, BUFFER_SIZE, PersistentBufferFlags)
Buffer[1] = (float*)glMapBufferRange(GL_ARRAY_BUFFER, BUFFER_SIZE, BUFFER_SIZE, PersistentBufferFlags)
我没有发现任何提示,什么是首选的,什么是对的,甚至是错的。如何正确拆分?
然后尝试画画
glDrawArrays(Mode, 0, (BufferData.VertSize / FloatsPerVertex)); //Draw "first" buffer, everything works if only this one.
...next round...
glDrawArrays(Mode, offset_of_datasize_first_buffer, (BufferData.VertSize / FloatsPerVertex)); //Second part of the buffer, fails.
这里不完全确定第二个参数,我发现它的解释令人困惑:
指定已启用数组中的起始索引。
我是否正确,这应该是第二次运行中第一个缓冲区的偏移大小?
除此之外,我使用与上面相同的设置,只是没有glBufferData。 所以无论如何,无论我使用上面的哪个版本,如果我只将其用作 1 缓冲区,它都可以工作,但如果将其用作 2,它看起来就像忽略了缓冲区第二部分的数据。 所以这是我的下一个问题 - 甚至允许使用这样的持久缓冲区吗?它是否尊重使用 glVertexAttribPointer 完成的交错设置,还是仅对顶点和仅对顶点进行简单设置?
如果您需要更多信息或不清楚,请告诉我。非常感谢。
glDrawArrays()
的第二个参数不是偏移量,而是第一个顶点的索引,就像使用带有glDrawElements()
的索引渲染一样。使用offset_in_bytes/stride_in_bytes
获取正确的值,或者实际计算具有步幅函数BUFFER_SIZE
并将该值用于glDrawArrays()
。
第二个参数几乎肯定会给你带来麻烦。offset_of_datasize_first_buffer
是索引偏移量还是字节偏移量? 试试offset_of_datasize_first_buffer / FloatsPerVertex
.
此外,还可以重新绑定属性指针,并将BUFFER_SIZE
添加到最后一个参数,以在第二个缓冲区的开头设置0
索引。
在尝试切换属性指针之前,请尝试先确保offset_of_datasize_first_buffer
是索引类型而不是字节偏移量。 那应该更快。
- C++:使用缓冲区中的数据填充结构
- 串行端口写入究竟如何从缓冲区实际写入数据?
- 如何避免将数据缓冲区的额外副本复制到字符串?
- 深度缓冲区未填充阴影贴图渲染通道中的数据
- 缓冲区填充了不同类型的数据和严格的混叠
- 增强循环缓冲区push_back在前面插入数据
- 如何用尽可能少的数据将数据缓冲区计算为零校验和值
- 使用 OpenGL 插值数据缓冲区?
- 使用 boost::p ython 将数据缓冲区放入C++中
- 将二进制数据缓冲区存储在协议缓冲区消息中
- 调用readAll()后,不再无法从QIODevices检索数据.缓冲区已冲洗
- gpsd客户端数据缓冲区
- 如何从数据缓冲区执行 x86 命令
- 在 c++ 中使用消息结构读取/填充数据缓冲区的正确方法是什么?
- C++多次使用更多数据缓冲区
- 如何从MediaCodec输出缓冲区中获取pcm数据缓冲区
- 在不违反严格混叠的情况下使用数据缓冲区
- 在C/ c++中从数据缓冲区中扫描
- opencv C++从android NV21图像数据缓冲区创建Mat对象
- 优化内存和性能的传输数据缓冲区