2012-10-03 110 views
2

我現在在學習OpenGL ES,並從藍皮書中複製和修改了一些示例。 這個例子只是在黑色背景上繪製一個紅色的三角形;我做到了,它工作。opengl es gldrawelements函數導致內存訪問衝突

所以我把它改成了一個立方體繪圖,它也起作用。 但是,只要我將其更改爲使用VBO和IBO,它就會在內存訪問violaiton 0x00000005的glDrawElements函數中崩潰。

我搜索了很多網站找出原因,但我能找到任何幫助。

你會發現我的代碼有問題嗎?

漲跌備註

  • 我換成立方體三角形。
  • 我檢查了所有的gl/egl函數,如果他們產生任何錯誤,但他們沒有。

我使用的是OpenGL ES 1.3 vertsion。

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。我不知道這些版本是什麼意思;我認爲我有2.0或更高版本的opengl。

我也檢查了所有的gl/egl函數錯誤檢查,並沒有錯誤。

回答

0

相當舊的貼子,但很久以前我就解決了這個問題。
只要我改變我的Opengl ES庫文件,一切正常。

對我來說,我用glError檢查每一個glCode並且沒有發現任何東西,這是非常奇怪的。
但是一旦glDrawElement被調用,程序就會崩潰。
由於我更改了gles庫文件,問題消失了。
我想指定我移動到哪個版本,但我不記得。

希望這可以幫助別人。 :)

2

我不確定這是您唯一的問題,但您不能撥打glBindAttribLocation您目前的位置。

glBindAttribLocation只有在下次鏈接程序後纔會生效,然後再調用它。如果你在鏈接之後調用它,它什麼也不做。

要麼在綁定着色器之前綁定屬性,要麼在程序鏈接後使用glGetAttribLocation來查找屬性位置。

+0

嘿,蒂姆。感謝您的回答,我認爲這是我的程序崩潰的主要原因。 – hanstar17

+0

我沒有測試它是否停止崩潰,但我想你指出了我的代碼的主要問題。我的另一個問題是,繪圖顯示在我的Mac窗口中,但不是在我的工作場所計算機上,它解決了問題。 – hanstar17

+0

感謝您的幫助,我會盡量在家中與VBO並選擇最好的答案。非常感謝你 – hanstar17