-2

After giving up on the slow glBegin/glEnd technique, I finally decided to use VBOs. After hours and hours of frustration, I finally got it to compile. But it doesn't mean it works. The function "CreateVBO" executes without errors, but as soon as glutMainLoop() is called, the program crashes, it doesn't even call the Reshape() or Render() functions.

Here is the CreateVBO() function: (note: the "lines" variable is equal to 4 million, the whole program is just a stress-test for rendering many lines before I can do something that actually makes sense)

void CreateVBO()
{
    glGenBuffers = (PFNGLGENBUFFERSPROC)wglGetProcAddress("glGenBuffers");
    glBindBuffer=(PFNGLBINDBUFFERPROC)wglGetProcAddress("glBindBuffer");
    glBufferData=(PFNGLBUFFERDATAPROC)wglGetProcAddress("glBufferData");
    glDeleteBuffers=(PFNGLDELETEBUFFERSPROC)wglGetProcAddress("glDeleteBuffers");
    glMapBuffer=(PFNGLMAPBUFFERPROC)wglGetProcAddress("glMapBuffer");


    for(float i=0; i<lines*2; i++)
    {

        t_vertices.push_back(i/9000);
        t_vertices.push_back(5 * (((int)i%2)*2-1));
        t_vertices.push_back(20);

        vert_cols.push_back(0);
        vert_cols.push_back(255);
        vert_cols.push_back(0);


        t_indices.push_back((int)i);
    }

    glGenBuffers(1, &VertexVBOID);
    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glBufferData(GL_ARRAY_BUFFER, sizeof(float)*t_vertices.size(), &t_vertices[0], GL_STATIC_DRAW);

    glGenBuffers(1, &IndexVBOID);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glBufferData(GL_ELEMENT_ARRAY_BUFFER, sizeof(int)*t_indices.size(), NULL, GL_STATIC_DRAW);

    GLvoid * buf = glMapBuffer( GL_ARRAY_BUFFER, GL_WRITE_ONLY );

    memcpy( (void*)buf, &vert_cols[0], (size_t)(sizeof(float)*vert_cols.size()));

    glBindBuffer( GL_ARRAY_BUFFER, 0 );
}

And here's the Render() function. I don't know what may be wrong with it since the program crashes before even calling that function.

void Display()
{
    glRotatef(1, 0, 1, 0);
    glClearColor(0, 0, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);

    glBindBuffer(GL_ARRAY_BUFFER, VertexVBOID);
    glEnableClientState(GL_VERTEX_ARRAY);
    glVertexPointer(t_vertices.size(), GL_FLOAT, 0, 0);   //The starting point of the VBO, for the vertices
    glEnableClientState(GL_COLOR_ARRAY);
    glColorPointer(vert_cols.size(), GL_FLOAT, 0, 0);

    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IndexVBOID);
    glDrawElements(GL_LINES, lines, GL_UNSIGNED_INT, 0);
    glutSwapBuffers();
    //Sleep(16);
    glutPostRedisplay();
}
CrizerPL
  • 277
  • 2
  • 10

1 Answers1

1

Your code doesn't make sense.

First, you create your vertexVBOID big enough to hold your t_vertices vector, and fill it with exactly that array. Then, you map that VBO and overwrite the data in it with the data from the vert_color vector. For drawing, you specify both the vertex position and the color attribute to come from the same position in memory - so effectively using the color as position, too.

But that is not the reason of the crash. There are actually two main reasons for crashing:

  1. You create IndexVBOID big enough to hold your index array, but you never initalize that buffer with some data. You instead specify NULL as the data pointer, so the storage is created, but left uninitialized. So you end up with an undefined content in that buffer, and the GL will access arbtrary memory positions when drawing with that.

  2. Your glVertexPointer and glColorPointer calls are wrong. The first parameter, size, is not the size of an array. It is the size of a single vector, which can be 1,2,3 or 4. Your array size is probably something else, so this calls end up generating an GL_INVALID_VALUE error, and not setting the attrib pointers at all. And by default, those pointers are NULL.

So ultimately, you are asking the GL to draw from undefined array indices relative to a NULL pointer. That's very likely to crash. In general, it is just undefined behavior, and the result could be anything.

Furthermore, you also keep the VertexVBOID buffer mapped - you never unmap it. It is invalid to use a buffer as the source or destination for GL commands as long as it is mapped (unless a persistent mapping is created, which is a relatively new feature which doesn't really belong here).

derhass
  • 38,787
  • 2
  • 42
  • 61
  • Thank you very much, I didn't really know what were I writing and now I realized how dumb the code was... Apparently my code is good now, but there seems to be a 65535 vertex limit even though I'm using 32-bit integers for indexing. But huge thanks to you anyway ;) – CrizerPL Nov 25 '15 at 21:14