0

頂点バッファオブジェクトを使用して、OpenGLES2.0で比較的単純な2Dスプライトバッチ処理を実装しようとしています。ただし、ジオメトリが正しく描画されておらず、特定できないエラーが原因で、InstrumentsのGLESアナライザーが次のように報告します。

Draw Call Exceeded Array Buffer Bounds

描画呼び出しは、使用中の配列バッファーの範囲外の頂点にアクセスしました。これは重大なエラーであり、クラッシュする可能性があります。

バッチ処理ではなく、一度に1つの四角形を描画することで、同じ頂点レイアウトで描画をテストしましたが、期待どおりに描画されます。

// 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のベクトルです。私の頂点バッファフォーマットはインターリーブされたposition2、texcoord2:X、Y、U、V ..であるため、BufferStrideは4です。

ありがとうございました。

4

1 に答える 1

4

glBufferData2番目の引数はバイト単位のデータのサイズであると想定しています。したがって、頂点データを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 に答える