OpenGL - 多个glDrawArrays()调用只显示第一个的结果?

3

我正在遍历一些网格,每个网格都存储在自己的GL_ARRAY_BUFFER中,但它们共享同一个glVertexAttribPointer结构。我通过for循环遍历每个渲染/绘制过程:

if (sConfig.mRendering.isRenderTypeActive(RENDER_TYPE_SINGLE_MESH) || 
    sConfig.mRendering.isRenderTypeActive(RENDER_TYPE_TWO_MESH)) {
    const int mesh_count = sConfig.mRendering.isRenderTypeActive(RENDER_TYPE_TWO_MESH) ? 2 : 1;
    for (int i = 0; i < mesh_count; i++) {
        std::lock_guard<std::mutex> lock(mModelDataMutex[i]);
        mUniV_VertexTransform->setValue(mModelTransform[i]);
        glBindBuffer(GL_ARRAY_BUFFER, mVBOs[i]); CHECK_GL_ERR;
        glDrawArrays(GL_TRIANGLES, 0, (GLsizei)mVertexCount[i]); CHECK_GL_ERR;
    }
}

使用以下函数的几个调用来为每个VBO设置数据:

bool ::updateModelData(const RenderCloud& data, VERTEX_BUFFER_ID id /*= VBID_MESH_0*/)
{
    if (id < VBID_COUNT)
    {
        std::lock_guard<std::mutex> lock(mModelDataMutex[id]);
        // Bind Point VBO
        glBindBuffer(GL_ARRAY_BUFFER, mVBOs[id]); CHECK_GL_ERR_RET;
        // Set coordinate attribute
        glVertexAttribPointer(BTID_COORDS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)BT_COORDS_OFFSET); CHECK_GL_ERR_RET;
        glEnableVertexAttribArray(BTID_COORDS); CHECK_GL_ERR_RET;

        // Set the normals attribute
        glVertexAttribPointer(BTID_NORMALS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)(BT_NORMALS_OFFSET)); CHECK_GL_ERR_RET;
        glEnableVertexAttribArray(BTID_NORMALS); CHECK_GL_ERR_RET;

        // Set the colors attribute
        glVertexAttribPointer(BTID_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, RenderCloud::elemSize(), (GLvoid*)(BT_COLOR_OFFSET)); CHECK_GL_ERR_RET;
        glEnableVertexAttribArray(BTID_COLOR); CHECK_GL_ERR_RET;
        // Copy Data
        glBufferData(GL_ARRAY_BUFFER, data.pts.size() * data.elemSize(), data.pts.data(), GL_STATIC_DRAW); CHECK_GL_ERR_RET;
        mVertexCount[id] = data.pts.size();
        // Unbind buffer
        glBindBuffer(GL_ARRAY_BUFFER, 0); CHECK_GL_ERR_RET;
        return true;
    }
    return false;
}

我可以验证两个VBO中都有数据,但是在for循环中只有第一个VBO使用了glDrawArrays()进行渲染。

它们共享同一个几何着色器,然后被延迟渲染堆栈用于应用效果。

每个glDrawArrays()调用是否需要其自己的几何着色器,只要它们都共享相同的绘制缓冲区?


你使用的OpenGL版本是哪个(在上下文创建时)?如果你要求一个核心配置文件(对于OGL > 3.1),那么你还需要一个顶点数组对象,并在glDrawArrays调用之前绑定它。 - Ripi2
我相信我正在使用某种 OGL 4 的子版本。实际上,我似乎创建了 VAO,但从未在任何地方使用过它们。这很奇怪,因为它已经适用于单个网格很长时间了。我是否正确地假设它只是在运行时默认绑定任何 VAO(0?)? - Scott Mudge
请解决您的不确定性:OGL上下文类型和版本,VAO的使用。行为可能会因这些问题而改变。 - Ripi2
1个回答

3

这不是绑定的顶点缓冲对象定义了通用顶点属性数据数组,而是存储在默认顶点数组对象中的状态。

当您调用glVertexAttribPointer时,定义了通用顶点属性数据数组。如果此时绑定了一个数组缓冲区,则数组定义将引用该缓冲区对象。

这意味着您必须在绘制对象之前切换数组定义:

glBindBuffer(GL_ARRAY_BUFFER, mVBOs[id]);

glVertexAttribPointer(BTID_COORDS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)BT_COORDS_OFFSET);
glEnableVertexAttribArray(BTID_COORDS);

glVertexAttribPointer(BTID_NORMALS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)(BT_NORMALS_OFFSET));
glEnableVertexAttribArray(BTID_NORMALS);

glVertexAttribPointer(BTID_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, RenderCloud::elemSize(), (GLvoid*)(BT_COLOR_OFFSET));
glEnableVertexAttribArray(BTID_COLOR);

glDrawArrays(GL_TRIANGLES, 0, (GLsizei)mVertexCount[i]);
glBindBuffer(GL_ARRAY_BUFFER, 0);

但我建议使用顶点数组对象。顶点数组对象存储通用顶点数组定义的状态:

GLuint vao[VBID_COUNT];

....

glGenVertexArrays( 1, vao[i] );
glBindVertexArray( vao[i] );

glBindBuffer(GL_ARRAY_BUFFER, mVBOs[id]);

glVertexAttribPointer(BTID_COORDS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)BT_COORDS_OFFSET);
glEnableVertexAttribArray(BTID_COORDS);

glVertexAttribPointer(BTID_NORMALS, 3, GL_FLOAT, GL_FALSE, RenderCloud::elemSize(), (GLvoid*)(BT_NORMALS_OFFSET));
glEnableVertexAttribArray(BTID_NORMALS);

glVertexAttribPointer(BTID_COLOR, 4, GL_UNSIGNED_BYTE, GL_TRUE, RenderCloud::elemSize(), (GLvoid*)(BT_COLOR_OFFSET));
glEnableVertexAttribArray(BTID_COLOR);

glBufferData(GL_ARRAY_BUFFER, data.pts.size() * data.elemSize(), data.pts.data(), GL_STATIC_DRAW);
mVertexCount[id] = data.pts.size();

glBindBuffer(GL_ARRAY_BUFFER, 0);

glBindVertexArray( 0 );

glBindVertexArray( vao[i] );
glDrawArrays(GL_TRIANGLES, 0, (GLsizei)mVertexCount[i]); 
glBindVertexArray( 0 );

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接