c++ - GL_TRIANGLE_STRIP 的 glDrawRangeElements 无法正常工作(使用 glMapBuffer)

标签 c++ opengl

我正在尝试使用 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 调用。

诸如glVertexAttribPointerglEnableVertexAttribArrayglDisableVertexAttribArray之类的调用用于通用顶点属性。

诸如 glVertexPointerglEnableClientStateglDisableClientState 之类的调用用于内置顶点属性。

您需要决定要使用哪种方法,然后为该方法使用一组一致的 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/

相关文章:

C++ - "Most important const"不适用于表达式?

c++ - 从 QT 按钮运行外部程序

c++ - glGenVertexArrays(1, &vao) 处的段错误;

opengl - 使用灯光

c++ - GLUT 程序仅适用于几帧

c++ - 将 googletest 与通过 std::cin 从用户获取输入的功能一起使用?

c++ - 如何在不格式化的情况下写入 std::ostream?

通过函数签名时 C++ 模板不编译

opengl - GL_PROJECTION矩阵或GL_MODELVIEW矩阵上的gluLookAt()最佳用法

python - 如何在 PyOpenGL 中使用 glBufferData()?