2

私は現在 OpenGL ES を学んでおり、ブルーブックからいくつかの例をコピーして変更しています。この例は、黒い背景に赤い三角形を描いているだけです。私はそれを作りました、そしてそれはうまくいきました。

それで、それを立方体の図面に変更したところ、同様に機能しました。しかし、VBO と IBO を使用するように変更するとすぐに、メモリ アクセス違反 0x00000005 で glDrawElements 関数でクラッシュします。

原因を突き止めようと色々なサイトを検索しましたが、参考になるサイトを見つけることができました。

私のコードに問題はありますか?

変更記事

  • 立方体を三角形に置き換えました。
  • エラーが発生するかどうか、すべての gl/egl 関数をチェックしましたが、エラーは発生しませんでした。

OpenGL ES 1.3 バージョンを使用しています。

struct Vertex
{
GLfloat x;
GLfloat y;
GLfloat z;
};


void NewTriangle( Vertex*& vertices, GLuint& verticesCount, GLubyte*& indices, GLuint& indicesCount )
{
    verticesCount = 3;
    vertices = new Vertex[verticesCount];
    vertices[0] = Vertex( 0, 0 );
    vertices[1] = Vertex( -0.5, -0.5 );
    vertices[2] = Vertex( 0.5, -0.5 );
    indicesCount = 3;
    indices = new GLubyte[indicesCount];
    indices[0] = 0;
    indices[1] = 1;
    indices[2] = 2;
}

void NewVerticesAndIndices( Vertex*& vertices, GLuint& verticesCount, GLubyte*& indices, GLuint& indicesCount )
{
    NewTriangle( vertices, verticesCount, indices, indicesCount );
    //NewCube( vertices, verticesCount, indices, indicesCount );
}

void RenderCommon( Vertex*& vertices, GLuint& verticesCount, GLubyte*& indices, GLuint& indicesCount )
{
    const GLfloat color[] = { 1, 0, 0, 1 };
    glVertexAttrib4fv( 0, color );
    glEnableVertexAttribArray( 1 );
    glVertexAttribPointer( 1, 3, GL_FLOAT, GL_FALSE, 0, (const void*)vertices );

    glDrawElements( GL_TRIANGLES, indicesCount, GL_UNSIGNED_BYTE, (const void*)indices );
}

void RenderWithMemories( Vertex*& vertices, GLuint& verticesCount, GLubyte*& indices, GLuint& indicesCount )
{
    RenderCommon( vertices, verticesCount, indices, indicesCount );
}

void RenderWithVBO( const GLuint& vbo, const GLuint& ibo, Vertex*& vertices, GLuint& verticesCount, GLubyte*& indices, GLuint& indicesCount )
{
    glBindBuffer( GL_ARRAY_BUFFER, vbo );
    glBufferData( GL_ARRAY_BUFFER, verticesCount*sizeof(*vertices), (void*)vertices, GL_STATIC_DRAW );

    glBindBuffer( GL_ELEMENT_ARRAY_BUFFER, ibo );
    glBufferData( GL_ELEMENT_ARRAY_BUFFER, indicesCount*sizeof(*indices), (void*)indices, GL_STATIC_DRAW );

    GLuint vboOffset = 0;
    GLuint iboOffset = 0;
    RenderCommon( (Vertex*&)vboOffset, verticesCount, (GLubyte*&)iboOffset, indicesCount );
}

void BlueEyeApp::OnRender()
{
    glViewport( 0, 0, 640, 480 );
    glClear( GL_COLOR_BUFFER_BIT );

    glUseProgram(m_program);

    GLuint verticesCount;
    Vertex* vertices = NULL;
    GLuint indicesCount;
    GLubyte* indices = NULL;
    NewVerticesAndIndices( vertices, verticesCount, indices, indicesCount );

    //RenderWithMemories( vertices, verticesCount, indices, indicesCount ); // successfully output
    RenderWithVBO( m_vbo, m_ibo, vertices, verticesCount, indices, indicesCount ); // crashes

    eglSwapBuffers( GetDisplay(), GetSurface() );

    delete[] vertices;
    delete[] indices;
}

そして、私は初期化でこれを持っています:

bool BlueEyeApp::CreateBuffers()
{
    glGenBuffers( 1, &m_vbo );
    glGenBuffers( 1, &m_ibo );
    return true;
}

私のeglInitializeの結果のメジャー&マイナーバージョンは1.3なので、eglバージョンと関係があるのだろうか。バージョンの意味がわかりません。私はopengl es 2.0以上を持っていると思いました。

また、すべての gl/egl 関数のエラー チェックを確認しましたが、エラーはありませんでした。

4

2 に答える 2

2

これがあなただけの問題かどうかはわかりませんglBindAttribLocationが、現在いる場所に電話をかけることはできません。

glBindAttribLocation次回リンクするときにのみ有効になります。プログラムは、呼び出した後にリンクされます。リンク後に呼び出すと、何もしません。

シェーダをリンクする前にアトリビュートをバインドするかglGetAttribLocation、プログラムがリンクされた後にアトリビュートの場所を見つけるために使用します。

于 2012-10-03T16:22:21.163 に答える
0

かなり古い投稿ですが、私はずっと前にこの問題を解決しました。
Opengl ES ライブラリ ファイルを変更するとすぐに、すべてが正常に機能しました。

glError を使用してすべての glCode をチェックしたのに、何も検出されなかったのは非常に奇妙でした。
しかし、glDrawElement が呼び出されるとすぐに、プログラムがクラッシュしました。
そして、glesライブラリファイルを変更すると、問題はなくなりました。
どのバージョンに移行したかを特定したいのですが、覚えていません。

これが誰かに役立つことを願っています。:)

于 2014-06-22T05:35:06.603 に答える