0

我尝试使用顶点缓冲区对象在 OpenGL ES 2.0 中实现一些相对简单的 2D 精灵批处理。但是,我的几何图形没有正确绘制,并且我似乎无法找到的一些错误导致 Instruments 中的 GL ES 分析器报告:

绘制调用超出数组缓冲区边界

一个绘图调用访问了一个超出正在使用的数组缓冲区范围的顶点。这是一个严重的错误,可能会导致崩溃。

我已经通过一次绘制单个四边形而不是批处理来测试具有相同顶点布局的绘图,并且它按预期绘制。

// This technique doesn't necessarily result in correct layering, 
// but for this game it is unlikely that the same texture will 
// need to be drawn both in front of and behind other images.
while (!renderQueue.empty()) 
{
    vector<GLfloat> batchVertices;
    GLuint texture = renderQueue.front()->textureName;

    // find all the draw descriptors with the same texture as the first 
    // item in the vector and batch them together, back to front
    for (int i = 0; i < renderQueue.size(); i++) 
    {
        if (renderQueue[i]->textureName == texture)
        {
            for (int vertIndex = 0; vertIndex < 24; vertIndex++) 
            {
                batchVertices.push_back(renderQueue[i]->vertexData[vertIndex]);
            }

            // Remove the item as it has been added to the batch to be drawn 
            renderQueue.erase(renderQueue.begin() + i);
            i--;
        }
    }

    int elements = batchVertices.size();
    GLfloat *batchVertArray = new GLfloat[elements];
    memcpy(batchVertArray, &batchVertices[0], elements * sizeof(GLfloat));

    // Draw the batch
    bindTexture(texture);
    glBufferData(GL_ARRAY_BUFFER, elements, batchVertArray, GL_STREAM_DRAW);
    prepareToDraw();
    glDrawArrays(GL_TRIANGLES, 0, elements / BufferStride);

    delete [] batchVertArray;
}

其他可能相关的信息:renderQueue 是 DrawDescriptors 的向量。BufferStride 是 4,因为我的顶点缓冲格式是交错的 position2, texcoord2: X,Y,U,V...

谢谢你。

4

1 回答 1

4

glBufferData期望它的第二个参数是以字节为单位的数据大小。因此,将顶点数据复制到 GPU 的正确方法是:

glBufferData(GL_ARRAY_BUFFER, elements * sizeof(GLfloat), batchVertArray, GL_STREAM_DRAW);

还要确保调用时绑定了正确的顶点缓冲区glBufferData

在性能说明上,这里绝对不需要分配临时数组。直接使用向量即可:

glBufferData(GL_ARRAY_BUFFER, batchVertices.size() * sizeof(GLfloat), &batchVertices[0], GL_STREAM_DRAW);
于 2012-06-23T14:19:06.050 回答