Hello! First post, so I want to start off with a big Thank You to those who contribute to LWJGL. I'm relatively new to the library and to the new OpenGL 3+ specification, so it's possible that the problem I'm encountering is caused by incorrect usage, although I am writing my code following a number of fairly thorough examples (OpenGL SuperBible, Learning Modern 3D Graphics Programming, mostly).
In a nutshell:
The overridden "glDrawElements" method that directly takes an index buffer will produce the expected geometry, if and only if GL_ELEMENT_ARRAY_BUFFER is bound to zero. If the buffer is bound to anything else, an exception is thrown.
The "normal-syntax" glDrawElements method, on the other hand, will throw an exception if this buffer is NOT bound (that's the expected behavior right?). But, when I bind the GL_ELEMENT_ARRAY_BUFFER it still does not produce any geometry, whereas the overridden method uses the same indexes and does.
In other words, there are four cases. And since I'm not 100% what the expected behavior IS, I'm going to post all four of them for consideration

The simplified, "Overridden" DrawElements method only works when the GL_ELEMENT_ARRAY_BUFFER is UNBOUND:
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL11.glDrawElements(GL11.GL_TRIANGLES, indexData);
This case produces the expected geometry. If the GL_ELEMENT_ARRAY_BUFFER IS bound, an exception is thrown:
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
GL11.glDrawElements(GL11.GL_TRIANGLES, indexData);
OpenGLException: Cannot use Buffers when Element Array Buffer Object is enabled
Using the "normal" syntax, DrawElements throws an exception when the GL_ELEMENT_ARRAY_BUFFER is Unbound (this is expected right?):
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL11.glDrawElements(GL11.GL_TRIANGLES, indexData.limit(), GL11.GL_INT, (long)0);
OpenGLException: Cannot use offsets when Element Array Buffer Object is disabled
But even with the proper GL_ELEMENT_ARRAY_BUFFER bound, this code doesn't work:
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
GL11.glDrawElements(GL11.GL_TRIANGLES, 24, GL11.GL_INT, (long)0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
Maybe the '24' was messing things up? Nope, this change fixes nothing:
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
indexData.rewind();
GL11.glDrawElements(GL11.GL_TRIANGLES, indexData.limit(), GL11.GL_INT, (long)0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
I'll post the source code of this entire file below. If it turns out this is actually a bug and not improper usage on my part, I'll be happy to send over the rest of my source code if that will help expedite the bug reproduction.
Thanks for reading!
Bryan
/*
* To change this template, choose Tools | Templates
* and open the template in the editor.
*/
package bryan.terrain;
import bryan.util.ShaderProgram;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.opengl.GL20;
import org.lwjgl.opengl.GL30;
import org.lwjgl.util.vector.Matrix4f;
import org.lwjgl.util.vector.Vector3f;
/**
*
* @author Bryan
*/
public class Shape {
private static ShaderProgram shader;
private static int unifProjectionMatrix;
private static int unifModelViewMatrix;
static{
shader = new ShaderProgram("\\src\\bryan\\shaders\\", "screen.vert", "screen.frag");
unifProjectionMatrix = GL20.glGetUniformLocation(shader.getHandle(), "projectionMatrix");
unifModelViewMatrix = GL20.glGetUniformLocation(shader.getHandle(), "modelViewMatrix");
}
private ObjectManager objectManager;
private int vertexArrayObject;
private int vertexBufferObject;
private int indexBufferObject;
private IntBuffer indexData;
private double dtAccum;
private FloatBuffer modelViewMatrixBuffer;
private Matrix4f modelViewMatrix;
private Vector3f position;
public Shape(ObjectManager theObjectManager){
this.objectManager = theObjectManager;
initGLState();
position = new Vector3f(0,0,-10);
modelViewMatrix = new Matrix4f();
modelViewMatrixBuffer = BufferUtils.createFloatBuffer(16);
}
void Logic(double dt) {
dtAccum += dt;
}
public void Draw(double dt){
shader.Use();
generateModelViewMatrix();
GL20.glUniformMatrix4(unifModelViewMatrix, false, modelViewMatrixBuffer);
GL20.glUniformMatrix4(unifProjectionMatrix, false, objectManager.renderer.getProjectionMatrix());
GL30.glBindVertexArray(vertexArrayObject);
// Is this a bug in LWJGL? The two glDrawElement functions work differently -
// the overidden DrawElements function will ONLY work if there is no
// GL_ELEMENT_ARRAY_BUFFER bound, while the "normal-syntax" DrawElements
// function requires the element array buffer to be bound. The overidden
// function produces the expected geometry, but the "normal" one does not.
// CASE 1: Only works when GL_ELEMENT_ARRAY_BUFFER is bound to Zero.
// If the buffer is bound, an exception is thrown.
//GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
GL11.glDrawElements(GL11.GL_TRIANGLES, indexData);
// Case 2: The "normal-syntax" version doesn't work at all (though it should!),
//GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
//indexData.rewind();
//GL11.glDrawElements(GL11.GL_TRIANGLES, indexData.limit(), GL11.GL_INT, (long)0);
//GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
shader.Release();
}
private void generateModelViewMatrix() {
modelViewMatrix.setIdentity();
modelViewMatrix.translate(position);
Matrix4f.mul(modelViewMatrix, objectManager.camera.getCameraTransform(), modelViewMatrix);
modelViewMatrix.store(modelViewMatrixBuffer);
modelViewMatrixBuffer.rewind();
}
private void initGLState() {
FloatBuffer vertexData = generateVertexData();
vertexArrayObject = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vertexArrayObject);
vertexBufferObject = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vertexBufferObject);
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, vertexData, GL15.GL_STATIC_DRAW);
GL20.glEnableVertexAttribArray(0);
GL20.glVertexAttribPointer(0, 3, GL11.GL_FLOAT, false, 0, (long)0);
GL20.glEnableVertexAttribArray(1);
GL20.glVertexAttribPointer(1, 4, GL11.GL_FLOAT, false, 0, (long)(8*3*4));
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
indexData = generateIndexData();
indexBufferObject = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, indexBufferObject);
//GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, indexData, GL15.GL_STATIC_DRAW);
GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, GL11.GL_INT, GL15.GL_STATIC_DRAW);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
GL30.glBindVertexArray(0);
}
private FloatBuffer generateVertexData() {
float[] raw = new float[]{
+1.0f, +1.0f, +1.0f,
-1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, -1.0f,
+1.0f, -1.0f, -1.0f,
-1.0f, -1.0f, -1.0f,
+1.0f, +1.0f, -1.0f,
+1.0f, -1.0f, +1.0f,
-1.0f, +1.0f, +1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f,
0.0f, 1.0f, 0.0f, 1.0f,
0.0f, 0.0f, 1.0f, 1.0f,
1.0f, 0.0f, 0.0f, 1.0f,
0.5f, 0.5f, 0.0f, 1.0f
};
FloatBuffer generatedVertexData = BufferUtils.createFloatBuffer(raw.length);
generatedVertexData.put(raw);
generatedVertexData.rewind();
return generatedVertexData;
}
private IntBuffer generateIndexData(){
int[] raw = new int[]{
0, 1, 2,
1, 0, 3,
2, 3, 0,
3, 2, 1,
5, 4, 6,
4, 5, 7,
7, 6, 4,
6, 7, 5
};
IntBuffer generatedIndexData = BufferUtils.createIntBuffer(raw.length);
generatedIndexData.put(raw);
generatedIndexData.rewind();
return generatedIndexData;
}
}