Problem with Vertex Buffer Objects

Hi all,

i’m a beginner in OpenGL and trying to understand VBOs.
The Problem is, that i can’t find the mistake in the following program. The program uses VBOs and has two variants. The first variant uses glDrawElements and the seconds glDrawArrays.
Both variants work fine on my desktop pc but on my laptop only glDrawArrays works. glDrawElements just produces rubbish.

To compile the DrawElements variant use:

g++ -Wall -o test test.cpp -lglut

To compile the DrawArrays variant use:

g++ -DUSE_DRAW_ARRAYS -Wall -o test test.cpp -lglut

The OS on both computers is Ubuntu 9.10 64Bit.
The desktop pc has a geforce 8800gts and the laptop an intel gm45 gpu.

I would like to hear if someone has any idea what could cause this problem.


#define GL_GLEXT_PROTOTYPES
#include <GL/glut.h>
#include <iostream>

using namespace std;

GLfloat position[] = { 1.0, 1.0, 1.1 };
GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 };
GLfloat red[] = { 1.0, 0.0, 0.0, 1.0 };

#define X .525731112119133606
#define Z .850650808352039932

struct Vertex
{
  GLfloat x,y,z;
};

Vertex vdata[12] = {
      {-X, 0.0, Z}, {X, 0.0, Z}, {-X, 0.0, -Z}, {X, 0.0, -Z},
      {0.0, Z, X}, {0.0, Z, -X}, {0.0, -Z, X}, {0.0, -Z, -X},
      {Z, X, 0.0}, {-Z, X, 0.0}, {Z, -X, 0.0}, {-Z, -X, 0.0}
};

GLushort indices[20][3] = {
      {0, 4, 1}, {0, 9, 4}, {9, 5, 4}, {4, 5, 8}, {4, 8, 1},
      {8, 10, 1}, {8, 3, 10}, {5, 3, 8}, {5, 2, 3}, {2, 7, 3},
      {7, 10, 3}, {7, 6, 10}, {7, 11, 6}, {11, 0, 6}, {0, 1, 6},
      {6, 1, 10}, {9, 0, 11}, {9, 11, 2}, {9, 2, 5}, {7, 2, 11}
};

GLushort vertexCount = 12;
GLushort indexCount = 60;

GLuint vbo[2];


void
initGL (void)
{
  glClearColor (0, 0, 0, 1);

  glEnable (GL_DEPTH_TEST);

  glEnable (GL_LIGHTING);
  glEnable (GL_LIGHT0);

  glLightfv (GL_LIGHT0, GL_POSITION, position);
  glLightfv (GL_LIGHT0, GL_SPECULAR, white);
  glMaterialfv (GL_FRONT, GL_AMBIENT_AND_DIFFUSE, red);

  glPolygonMode (GL_FRONT_AND_BACK, GL_FILL);
  glShadeModel (GL_SMOOTH);

  glEnableClientState (GL_VERTEX_ARRAY);
  glEnableClientState (GL_NORMAL_ARRAY);


#ifdef USE_DRAW_ARRAYS
  Vertex *vertices = new Vertex[indexCount];
  vertexCount = 0;

  for (int i = 0; i < 20; i++)
    for (int j = 0; j < 3; j++)
      vertices[vertexCount++] = vdata[indices[i][j]];

  cout << "using glDrawArrays" << endl;
#else
  Vertex *vertices = vdata;
  cout << "using glDrawElements" << endl;
#endif

  glGenBuffers (2, vbo);

  glBindBuffer (GL_ARRAY_BUFFER, vbo[0]);
  glBufferData (GL_ARRAY_BUFFER, vertexCount*sizeof(Vertex), 
                vertices, GL_STATIC_DRAW);
  glVertexPointer (3, GL_FLOAT, 0, 0);
  glNormalPointer (GL_FLOAT, 0, 0);

  glBindBuffer (GL_ELEMENT_ARRAY_BUFFER, vbo[1]);
  glBufferData (GL_ELEMENT_ARRAY_BUFFER, indexCount*sizeof(GLushort), indices, 
                GL_STATIC_DRAW);
}

void 
resize (int w, int h)
{
  glViewport (0, 0, w, h);

  glMatrixMode (GL_PROJECTION);
  glLoadIdentity ();
  gluPerspective (60.0, (GLfloat)w/(GLfloat)h, 0.1, 100.0);

  glMatrixMode (GL_MODELVIEW);
  glLoadIdentity ();
}


void
draw (void)
{
  static GLfloat angle = 0.0;

  glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

  glLoadIdentity ();

  glTranslatef (0.0, 0.0, -2.0);

  if (angle >= 360.0)
    angle -= 360.0;
  else
    angle += 0.01;

  glRotatef (angle, 1.0, 1.0, 1.0);

#ifdef USE_DRAW_ARRAYS
  glDrawArrays (GL_TRIANGLES, 0, vertexCount);
#else
  glDrawElements (GL_TRIANGLES, indexCount, GL_UNSIGNED_SHORT, 0);
#endif

  glutSwapBuffers ();
}

int
main (int argc, char **argv)
{
  glutInit (&argc, argv);
  glutInitDisplayMode (GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);

  glutInitWindowSize (682, 384);
  glutCreateWindow ("VBO Example");

  initGL ();

  glutDisplayFunc (draw);
  glutIdleFunc (draw);
  glutReshapeFunc (resize);

  glutMainLoop ();

  glDeleteBuffers (2, vbo);

  return 0;
}

Does it work if you use unsigned ints instead of shorts? Perhaps it’s an alignment issue?

  • Chris

Hi,

thanks for your suggestion. I just tested the program with integer instead of short but sadly there is no change. The funny thing is, that glDrawElements works fine with regular vertex arrays but not with VBOs.

Ahh, try a four-component vertex. I bet that’s where the alignment issue is cropping up. If you make the fourth component 1 for all your vertices, you’ll be replicating what glVertex3f does behind the scenes:

http://www.opengl.org/sdk/docs/man/xhtml/glVertex.xml

  • Chris

Ok,

i hope that i understand you correctly. These are the changes i made:



..
..
..

struct Vertex
{
  GLfloat x,y,z,w;
};

Vertex vdata[12] = {
      {-X, 0.0, Z,1}, {X, 0.0, Z,1}, {-X, 0.0, -Z,1}, {X, 0.0, -Z,1},
      {0.0, Z, X,1}, {0.0, Z, -X,1}, {0.0, -Z, X,1}, {0.0, -Z, -X,1},
      {Z, X, 0.0,1}, {-Z, X, 0.0,1}, {Z, -X, 0.0,1}, {-Z, -X, 0.0,1}
};

...
...
...

glVertexPointer (4, GL_FLOAT, 0, 0);
glNormalPointer (GL_FLOAT, sizeof(Vertex), 0);


It still doesn’t work. That’s really a strange problem. Does the program work for you in both variants?

Yes, it works fine on my desktop in both cases. Someone more savvy than myself will have to chime in.

  • Chris

Works fine here: NVidia 190.32 / GTX285

That sounds like a driver issue to me. I once had a problem using 1D textures in a Cg program years back with no success. I ended up switching to a 2D texture on some advice from my friend even though I only needed a row of data and it worked. Drivers are complex and I think Intel’s aren’t as reliable in many circumstances. If anything, you might see if you can upgrade your intel driver if it’s not up to date.

Hi again,

thank you all for your help. It’s probably really a driver issue.
Maybe i can file this to the Mesa/DRI bug list or the gpu could be broken :frowning: that wouldn’t be nice.

Ok,

it was definitly a driver issue. i just upgraded mesa3d to the latest development release (7.8) and the intel driver to version 2.10 and the problem is gone. :slight_smile:

I have a good program, called OpenGL Viewer.
It is very convenient to show all the functions is supported,the driver version and the library(opengl) of your video adapterProg called OpenGL Viewer, you can download here http://depositfiles.com/files/d9a5l2ze3 OpenGL Viewer, thanks to the creators

gridandy, do you trust a random program from depositfiles ?