我正在尝试使用 glDrawRangeElements 从 VBO 和元素缓冲区对象渲染点。
VBO 和 EBO 的实例化如下:
glGenBuffers(1, &vertex_buffer);
glGenBuffers(1, &index_buffer);
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBufferData(GL_ARRAY_BUFFER, vertex_buffer_size, NULL, GL_STREAM_DRAW);
glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 0, (char*)(NULL));
glEnableVertexAttribArray(0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, index_buffer_size, NULL, GL_STREAM_DRAW);
如您所见,它们没有任何“静态”数据。
我使用 glMapBuffer 填充缓冲区,然后使用 glDrawRangeElements 渲染它们。
问题:
具体来说,我想做的是制作一个具有连续LOD的地形。 我使用和发布的代码主要来自 Andras Balogh 的 Ranger Mk2。
我的问题是这样的:当我想要渲染三角形带时,三角形的 3 个点上似乎有一个点在不应该在的地方。 例如, 这是我在线框模式下得到的 -> /image/lCPqR.jpg
这就是我在点模式下得到的结果(注意向上延伸的列,这是放置得不好的点)-> /image/CF04p.jpg
在您要求我转到名为“使用 glDrawRangeElements() 渲染无法正常工作”的帖子之前,我想让您知道我已经去过那里。
代码:
渲染过程如下:
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
glEnableClientState(GL_VERTEX_ARRAY);
glVertexPointer(4, GL_FLOAT, 0, 0);
glEnableVertexAttribArray(0);
glDrawRangeElements(GL_TRIANGLE_STRIP, 0, va_index, ia_index, GL_UNSIGNED_INT, BUFFER_OFFSET(0));
glDisableClientState(GL_VERTEX_ARRAY);
就在我执行此操作之前(pre_render 函数):
glBindBuffer(GL_ARRAY_BUFFER, vertex_buffer);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, index_buffer);
vertex_array = (v4f*)(glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY));
index_array = (u32*)(glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY));
//[...] Populate the buffers
glUnmapBuffer(GL_ARRAY_BUFFER);
glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER);
PS:当我像这样渲染地形时:
glBegin(GL_TRIANGLE_STRIP);
printf("%u %u\n", va_index, ia_index);
for(u32 i = 0; i < va_index; ++i){
//if(i <= va_index)
glVertex4fv(&vertex_array[i].x);
}
glEnd();
奇怪的是它有效(虽然部分三角形没有渲染,但这是另一个问题)。
所以我的问题是如何使 glDrawRangeElements 正常工作?
如果您需要更多信息,请询问,我很乐意回答。
编辑:我使用 Qt Creator 作为 IDE,在 Windows 7 上使用 Mingw 4.8。我的显卡支持 Opengl 4.4(来自 Nvidia)。
最佳答案
不确定这是否会导致您的问题,但我注意到您混合了对内置顶点属性和通用顶点属性的 API 调用。
诸如glVertexAttribPointer
、glEnableVertexAttribArray
和glDisableVertexAttribArray
之类的调用用于通用顶点属性。
诸如 glVertexPointer
、glEnableClientState
和 glDisableClientState
之类的调用用于内置顶点属性。
您需要决定要使用哪种方法,然后为该方法使用一组一致的 API 调用。如果使用固定渲染管线,则需要使用内置属性。如果您使用兼容性配置文件编写自己的着色器,则可以使用其中任何一个。如果使用核心配置文件,则需要使用通用顶点属性。
此调用看起来也很可疑,因为它指定了大小 3,而代码的其余部分表明您正在使用具有 4 个坐标的位置:
glVertexAttribPointer(0,3,GL_FLOAT, GL_FALSE, 0, (char*)(NULL));
关于c++ - GL_TRIANGLE_STRIP 的 glDrawRangeElements 无法正常工作(使用 glMapBuffer),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/23184371/