Simple working VBO in LWJGL

It’s come to this, I’ve been learning Open GL (via LWJGL) for the last few months and managed to learn enough from website and the Open GL documentation to write code using display lists, normals, colors, textures, and transparency.
However, all my attempts to learn about Buffer Objects and server side memory have been thwarted by blank black windows.

Below is some code, but first here’s some information about my current progress.
I have tried adding calls to glGetError, but did not see any errors.
I have also tried calling glGetBufferSubData on both the VBO and EBO and I printed the contents and found it to be identical to the input buffers.
Note: The code tries to render without custom shaders using calls to *Pointer (fixed pipeline or something).
I feel apprehensive about switching to shaders because I have had similar blank black windows when trying to test shaders.

Here’s the simplest version of my current efforts to create a VBO with EBO and render using *Pointer and glDrawElements:

Main


final int maxFps = 60;
final int numberVertices = 6;
final int vertexSize = 3;
final int normalSize = 3;
final int colorSize = 1;
final int paddingSize = 1;
final int interleavingElementSize = (vertexSize+normalSize+colorSize+paddingSize);

public VBODemo() {
   int[] vboEbo = initGL();
   gameLoop(vboEbo[0], vboEbo[1]);
   destroy(vboEbo);
}

Open GL initialization


/** initGL, initialize Open GL display and create vbo
 * @return two ints, the first is the vbo created and the second is the ibo created
 */
private int[] initGL() {
   try {
      Display.setDisplayMode(new DisplayMode(640, 480));
      Display.setTitle("Vertex Buffer Test");
      Display.create();
   } catch (LWJGLException e) {
      e.printStackTrace();
   }

   GL11.glMatrixMode(GL11.GL_PROJECTION);
   GL11.glLoadIdentity();
   GL11.glOrtho(-2, 2, -2, 2, 4, -4);

   GL11.glMatrixMode(GL11.GL_MODELVIEW);
   GL11.glLoadIdentity();

   // Create the data buffer with vertex, normal, and color elements interleaving
   int color = Color.GREEN.getRGB();
   ByteBuffer vertexData; // Format vertex3f(x,y,z),normal3f(x,y,z),color4b(x,y,z,0),padding4b
   vertexData = BufferUtils.createByteBuffer(interleavingElementSize * numberVertices * 4);
   // Vertices 0,1, -1,-1, 1,-1,
   vertexData.putFloat(0).putFloat(1).putFloat(-1).putFloat(0).putFloat(0).putFloat(1).putInt(color).putInt(0)
      .putFloat(-1).putFloat(-1).putFloat(-1).putFloat(0).putFloat(0).putFloat(1).putInt(color).putInt(0)
      .putFloat(1).putFloat(-1).putFloat(-1).putFloat(0).putFloat(0).putFloat(1).putInt(color).putInt(0);
   vertexData.flip();

   // Create the buffer of indices for each vertex
   ByteBuffer indexData;
   indexData = BufferUtils.createByteBuffer(numberVertices * 4);
   indexData.putInt(0).putInt(32).putInt(64);
   indexData.flip();

   // Create the buffer objects for the vertex data and the list of indices
   int buffer = createBO(vertexData, GL15.GL_ARRAY_BUFFER, GL15.GL_STATIC_DRAW);
   int element = createBO(indexData, GL15.GL_ELEMENT_ARRAY_BUFFER, GL15.GL_STATIC_DRAW);

   return new int[] {buffer, element};
}

gameLoop


private void gameLoop(int buffer, int element) {
   while(!Display.isCloseRequested()) {
      GL11.glClear(GL11.GL_COLOR_BUFFER_BIT | GL11.GL_DEPTH_BUFFER_BIT);

      renderVBO(buffer, element);

      Display.update();
      Display.sync(maxFps);
   }
}

createBO


private int createBO(ByteBuffer vertexData, int targetType, int drawType) {
   int id = GL15.glGenBuffers();
   GL15.glBindBuffer(targetType, id); // Bind the new buffer
   GL15.glBufferData(targetType, vertexData, drawType); // Upload the buffer data
   GL15.glBindBuffer(targetType, 0); // Unbind the buffer once data uploading is done
   return id;
}

renderVBO


private void renderVBO(int vbo, int ebo) {
   // Bind buffers
   GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
   GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, ebo);
   // Enable attribute types
   GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
   GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
   GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
   // Bind attribute types
   GL11.glNormalPointer(GL11.GL_FLOAT, 32, 12);
   GL11.glColorPointer(4, GL11.GL_BYTE, 32, 24);
   GL11.glVertexPointer(vertexSize, GL11.GL_FLOAT, 32, 0);
   // Draw attributes from GL_ARRAY_BUFFER using indices from GL_ELEMENT_ARRAY_BUFFER
   GL11.glDrawElements(GL11.GL_TRIANGLES, numberVertices, GL11.GL_INT, 0);
   // Disable attribute types
   GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
   GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
   GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
   // Unbind buffers
   GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
   GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
}

As I mentioned, the code currently renders a blank black window. I don’t understand most of the method calls in renderVBO() so I am thinking that there may be an error in that method.
I would love to learn how to render buffer objects correctly so that I can continue learning about Open GL! :smiley:

I have spent quite a lot of time trying to find out how to use Open GL Buffer Objects with VertexPointer(), NormalPointer(), etc. without using shaders, and I have not found a solution.
If someone with the same question comes across this in the future, all I can recommend is switch to shaders, I know it’s not fun, but hopefully these resources will help:

Good example shader source code.
http://nehe.gamedev.net/article/glsl_an_introduction/25007/

Dozens of tutorials covering modern Open GL topics
http://www.arcsynthesis.org/gltut/

If you are trying to use generic attributes in your code and custom variables in your shaders (trying to render using EnableVertexAttribArray() and VertexAttribPointer()), then these pages might be helpful.

Explanation of using BindAttribLocation() and GetAttribLocation() to work with attribute/in variables from a shader.
http://www.opengl.org/sdk/docs/tutorials/ClockworkCoders/attributes.php

More information about generic vertex attributes in shaders and in code.
http://stackoverflow.com/questions/9561348/glsl-opengl-3-x-how-to-specify-the-mapping-between-generic-vertex-attribute-indi