2

我现在正在学习 OpenGL ES,并从蓝皮书中复制和修改一些示例。该示例只是在黑色背景上绘制一个红色三角形;我做到了,它奏效了。

所以我把它改成了立方体图,效果也很好。但是,一旦我将其更改为使用 VBO 和 IBO,它就会在 glDrawElements 函数中崩溃,内存访问 violaiton 为 0x00000005。

我搜索了许多网站以找出原因,但我能够找到任何有帮助的网站。

你会发现我的代码有什么问题吗?

更改说明

  • 我用三角形代替了立方体。
  • 如果它们产生任何错误,我检查了所有 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;
}

我想知道它是否与 egl 版本有关,因为我的 eglInitialize 结果的主要和次要版本是 1.3。我不知道这些版本是什么意思;我以为我有 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 回答