copenglvbovertex-buffer-objects

OpenGL: try to draw lines using VBO(vertex buffer object), it doesn't display


I try to switch my openGL code from using display list to using VBO. In the code, I tried to draw a green-grid floor, which is composed by green lines in parallel with x-axis and green lines in parallel with z-axis. But when the program runs, floor doesn't display. And I can't find where goes wrong.

Here is my code initialize VBO of floor:

//**********************************
//defined in head of my source code
struct BufferVBO1
{
    GLfloat x;
    GLfloat y;
    GLfloat z;
    GLfloat r;
    GLfloat g;
    GLfloat b;
};
struct IdVBO
{
    GLuint id;
    size_t bufsiz;
};
IdVBO vboGround;
//**************************************
glGenBuffers(1, &vboGround.id);
int groundSiz1 = ( (floorEdge_x_max-floorEdge_x_min)/(5*LENGTH_UNIT)+1 )*2 ;
int groundSiz2 = ( (floorEdge_z_max-floorEdge_z_min)/(5*LENGTH_UNIT)+1 )*2 ;
vboGround.bufsiz = groundSiz1+groundSiz2 ;
BufferVBO1 *groundBuf = new BufferVBO1 [vboGround.bufsiz];
for(int i=0, idx=0; idx<groundSiz1; ++i)
{
    groundBuf[idx].x = floorEdge_x_min+i*5*LENGTH_UNIT;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;

    groundBuf[idx].x = floorEdge_x_min+i*5*LENGTH_UNIT;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_max;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;
}
for(int i=0, idx=groundSiz1; idx<vboGround.bufsiz; ++i)
{
    groundBuf[idx].x = floorEdge_x_min;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min+i*5*LENGTH_UNIT;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;

    groundBuf[idx].x = floorEdge_x_max;
    groundBuf[idx].y = 0;
    groundBuf[idx].z = floorEdge_z_min+i*5*LENGTH_UNIT;
    groundBuf[idx].r = 75/255.0;
    groundBuf[idx].g = 1.0;
    groundBuf[idx].b = 63/255.0;
    ++idx;
}

glBindBuffer(GL_ARRAY_BUFFER, vboGround.id);
glBufferData(GL_ARRAY_BUFFER, sizeof(BufferVBO1)*vboGround.bufsiz, groundBuf, GL_STATIC_DRAW);
delete [] groundBuf ;
glBindBuffer(GL_ARRAY_BUFFER, 0);

Here is the code to display:

 glDisable(GL_LIGHTING);
 glBindBuffer(GL_ARRAY_BUFFER, vboGround.id);
 glEnableClientState(GL_VERTEX_ARRAY);
 glVertexPointer(3, GL_FLOAT, sizeof(BufferVBO1), (void*)0);
 glEnableClientState(GL_COLOR_ARRAY);
 glColorPointer( 3, GL_FLOAT, sizeof(BufferVBO1), (void*)(sizeof(GLfloat)*3) );
 for(int i=0; i<vboGround.bufsiz; i+=2)
    glDrawArrays(GL_LINE, i, 2);
 glDisableClientState(GL_VERTEX_ARRAY);
 glDisableClientState(GL_COLOR_ARRAY);
 glBindBuffer(GL_ARRAY_BUFFER, 0);
 glEnable(GL_LIGHTING);

I've tried to draw a simple GL_QUADS floor using VBO, and it works! But when I tried to draw green-grid floor, it doesn't display.

Tell me where is the problem.


Solution

  • The first argument to glDrawArrays() here is invalid:

    glDrawArrays(GL_LINE, i, 2);
    

    GL_LINE is not a valid primitive type. You need to use GL_LINES:

    glDrawArrays(GL_LINES, i, 2);
    

    GL_LINE may look very similar, but it's one of the possible arguments for glPolygonMode().

    You should always call glGetError() when your OpenGL call does not behave as expected. In this case, it should have returned GL_INVALID_ENUM.

    BTW, you can draw all the lines in a single glDrawArrays() call, instead of using a loop:

    glDrawArrays(GL_LINES, 0, vboGround.bufsize);