glDrawElements crash (OpenGL 3.2 / Windows 7)

后端 未结 2 666
小鲜肉
小鲜肉 2021-01-03 07:26

I\'m trying to draw a simple quad in OpenGL 3.2 however the application crashes with \"Access violation reading location 0x00000000\" when I call \"glDrawElements\".

相关标签:
2条回答
  • 2021-01-03 07:57

    You are not allocating enough space for your vertices in your call to glBufferData. You pass sizeof(TexColorVertex) which allocates space for 1 vertex. If you want to draw a quad then you need to allocate space for 4 vertices so you should change your call to glBuffer Data as follows:

    glBufferData(GL_ARRAY_BUFFER, 4*sizeof(TexColorVertex), NULL, GL_DYNAMIC_DRAW);
    

    That way when you make your subsequent calls to glBufferSubData you will not be attempting to access GPU memory that is out of range.

    0 讨论(0)
  • 2021-01-03 08:10

    While user3256930 does bring up a valid point about the allocated size of your buffer, that is actually not the cause of your crash.

    The problem is not with glBufferSubData (...), but rather with the call to glDrawElements (...). This call is attempting to dereference a NULL pointer, which is a red flag that nothing is bound to GL_ELEMENT_ARRAY_BUFFER.

    When nothing is bound to GL_ELEMENT_ARRAY_BUFFER, then the pointer you pass to glDrawElements (...) is an actual pointer to client memory rather than an offset into Buffer Object (server) memory.


    To understand why this occurs, recall what Vertex Array Objects store:

    1. Vertex Attribute State [Pointers, Enable/Disable]
    2. Element Array Buffer Binding (GL_ELEMENT_ARRAY_BUFFER)

    Now, consider the order of these two calls:

    glBindBuffer      (GL_ELEMENT_ARRAY_BUFFER, m_Elements);
    glBindVertexArray (m_Array);
    

    First you bind something to GL_ELEMENT_ARRAY_BUFFER (m_Elements) and immediately afterwards you bind a Vertex Array Object (m_Array), which replaces the element array buffer you just bound with the binding it keeps track of internally.

    You should consider either (1) using your VAO to persistently reference a single element array buffer or (2) reversing the order of these two calls.


    If your Vertex Array Object (m_Array) will always be used with the same element array buffer, then I would suggest you use the first approach. This can be implemented simply by moving the following code in your initialization:

    glGenVertexArrays (1, &m_Array);
    glBindVertexArray (m_Array);
    

    To come before:

    glGenBuffers (1, &m_Elements);
    glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, m_Elements);
    glBufferData (GL_ELEMENT_ARRAY_BUFFER, Indices.size() * sizeof(CUShort), &Indices[0], GL_STATIC_DRAW);
    

    With this approach, nothing needs to be explicitly bound to GL_ELEMENT_ARRAY_BUFFER in your drawing code.

    0 讨论(0)
提交回复
热议问题