我有一个要使用glMultiDrawElements渲染的模型。准备数据并使用简单的矢量进行渲染可以很好地工作,但是当我使用顶点缓冲区时失败。显然我在计算缓冲区偏移时犯了某种错误。首先是工作代码:

我第一步是准备数据供以后使用(包含伪代码以使其更易于阅读):

for(each face in the model){
    const Face &f = *face;

    drawSizes.push_back(3);

    for(int i=0;i<f.numberVertices;++i){
        const Vertex &v = vertices[f.vertices[i]]]; // points to vertex array
    vertexArray.push_back(v.x);
    indexArray.push_back(vertexArray.size() - 1);
    vertexArray.push_back(v.y);
    indexArray.push_back(vertexArray.size() - 1);
    vertexArray.push_back(v.z);
    indexArray.push_back(vertexArray.size() - 1);

    normalArray.push_back(f.normalx);
    normalArray.push_back(f.normaly);
    normalArray.push_back(f.normalz);
    }
}

int counter = 0;

for(each face in the model){
    vertexIndexStart.push_back(&indexArray[counter*3]);
    offsetIndexArray.push_back(static_cast<void*>(0) + counter*3);
    counter++;
}

drawSizes is a vector<Glint>
vertexArray is a vector<GLfloat>
indexArray is a vector<GLint>
vertexIndexStart is a vector<Glvoid *>
offsetIndexArray is a vector<GLvoid *>


现在,我使用glMultiDrawElements-function通过以下方式绘制此图形:

glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glVertexPointer(3,GL_FLOAT,3*sizeof(GLfloat),&vertexArray[0]);
glNormalPointer(GL_FLOAT,0,&normalArray[0]);
glMultiDrawElements(GL_POLYGON,&drawSizes[0],GL_UNSIGNED_INT,&vertexIndexStart[0],vertexIndexStart.size());
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);


而且它会按原样绘制模型,尽管性能并不比即时模式好多少。

现在,当我尝试缓冲创建的数据并使用缓冲区渲染模型时,它显然不起作用。再次在第一步中,我对已经处理过的数据进行预处理:

glGenBuffers(2,buffers);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBufferData(GL_ARRAY_BUFFER,sizeof(vertexArray),&vertexArray[0],GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(indexArray),&indexArray[0],GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);

buffers is a GLuint[]


然后,我尝试呈现数据:

glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, buffers[0]);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glVertexPointer(3,GL_FLOAT,3*sizeof(GLfloat),0);
glMultiDrawElements(GL_POLYGON,&drawSizes[0],GL_UNSIGNED_INT,&offsetIndexArray[0],vertexIndexStart.size());
glBindBuffer(GL_ARRAY_BUFFER,0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);
glDisableClientState(GL_VERTEX_ARRAY);


导致屏幕空白。有任何想法吗?

编辑:我现在按照建议使用正确的索引,但是我仍然没有得到想要的结果。

最佳答案

这是错误的:

glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, buffers[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(vertexIndexStart),&vertexIndexStart[0],GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER,0);


元素数组缓冲区应包含索引数组,这意味着指向顶点数组的索引,而不是指向索引数组的索引。

另请注意,您的代码正在使用许多不推荐使用的GL功能(内置属性,甚至可能是固定功能管道,没有VAO的图形),并且无法在现代OpenGL的核心配置文件中使用。

谈到现代GL:在现代GL中甚至通过glMultiDrawElements支持间接的更高级别,其中glMultiDrawElemetnsIndirect的参数数组本身来自缓冲区对象。

关于c++ - glMultiDrawElements VBO,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/40342111/

10-12 05:24