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!