I'm reasonably familar with vertex buffer objects. I've checked this over and over, rewritten it multiple times and can't find a thing wrong with it. Still, no output from glDrawElements.
package shaders0.shaders3;
import java.nio.ByteBuffer;
import java.nio.ByteOrder;
import java.nio.FloatBuffer;
import java.nio.ShortBuffer;
import org.lwjgl.LWJGLException;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.DisplayMode;
import org.lwjgl.opengl.GL11;
import org.lwjgl.opengl.GL15;
import org.lwjgl.util.glu.GLU;
public final class Main implements Runnable
{
private static final int SCREEN_WIDTH = 640;
private static final int SCREEN_HEIGHT = 480;
private final FloatBuffer vertices;
private final int vertices_name;
private int indices_name;
private ShortBuffer indices;
/**
* Abort if an OpenGL error occurred.
*/
private static void checkGL()
{
final int code = GL11.glGetError();
if (code != 0) {
final String x = GLU.gluErrorString(code);
final String message = "OpenGL error (" + code + "): " + x;
System.err.println(message);
System.exit(1);
}
}
public Main()
{
// Initialize a vertex buffer object with vertex data.
{
// Allocate buffer name.
this.vertices_name = GL15.glGenBuffers();
// Bind buffer name.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vertices_name);
// Create and upload vertex data.
final ByteBuffer vertices_bytes =
ByteBuffer.allocateDirect(3 * 3 * 4).order(ByteOrder.nativeOrder());
this.vertices = vertices_bytes.asFloatBuffer();
this.vertices.put(new float[] { 0.0f, 0.0f, 0.0f });
this.vertices.put(new float[] { 200.0f, 0.0f, 0.0f });
this.vertices.put(new float[] { 200.0f, 200.0f, 0.0f });
assert this.vertices.remaining() == 0;
assert this.vertices.order() == ByteOrder.LITTLE_ENDIAN;
GL15.glBufferData(
GL15.GL_ARRAY_BUFFER,
this.vertices,
GL15.GL_STATIC_DRAW);
// Unbind buffer name.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
Main.checkGL();
}
// Initialize an index buffer to reference the above vertices.
{
// Allocate buffer name.
this.indices_name = GL15.glGenBuffers();
// Bind buffer name.
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.indices_name);
// Allocate and upload indices.
final ByteBuffer indices_bytes =
ByteBuffer.allocateDirect(3 * 2).order(ByteOrder.nativeOrder());
this.indices = indices_bytes.asShortBuffer();
this.indices.put(new short[] { 0, 1, 2 });
assert this.indices.remaining() == 0;
assert this.indices.order() == ByteOrder.LITTLE_ENDIAN;
GL15.glBufferData(
GL15.GL_ELEMENT_ARRAY_BUFFER,
this.indices,
GL15.GL_STATIC_DRAW);
// Unbind buffer name.
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
Main.checkGL();
}
}
private static void setupCamera()
{
GL11.glViewport(0, 0, Main.SCREEN_WIDTH, Main.SCREEN_HEIGHT);
GL11.glClearColor(0.3f, 0.3f, 0.3f, 1.0f);
GL11.glClear(GL11.GL_COLOR_BUFFER_BIT);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(0, Main.SCREEN_WIDTH, 0, Main.SCREEN_HEIGHT, -1.0, 100.0);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
}
private void draw()
{
// Draw a blue triangle that should be completely overwritten
// by the triangle drawn by the VBO.
GL11.glColor3d(0.0, 0.0, 1.0);
GL11.glBegin(GL11.GL_TRIANGLES);
{
GL11.glVertex3f(0.0f, 0.0f, 0.0f);
GL11.glVertex3f(200.0f, 0.0f, 0.0f);
GL11.glVertex3f(200.0f, 200.0f, 0.0f);
}
GL11.glEnd();
// Reset colour to white.
GL11.glColor3d(1.0, 1.0, 1.0);
// Bind vertex array and index buffer.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, this.vertices_name);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, this.indices_name);
// Enable vertex array.
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
// Tell GL where vertex data can be found.
GL11.glVertexPointer(3, GL11.GL_FLOAT, 0, 0L);
// Draw triangle.
GL11.glDrawElements(GL11.GL_TRIANGLES, 3, GL11.GL_UNSIGNED_SHORT, 0L);
// Disable vertex array.
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
// Unbind buffers.
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, 0);
GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, 0);
Main.checkGL();
}
private void render()
{
Main.setupCamera();
this.draw();
}
@Override public void run()
{
while (!Display.isCloseRequested()) {
this.render();
Display.update();
Display.sync(60);
}
Display.destroy();
}
public static void main(
final String args[])
{
try {
Display.setDisplayMode(new DisplayMode(
Main.SCREEN_WIDTH,
Main.SCREEN_HEIGHT));
Display.setTitle("shaders0");
Display.create();
} catch (final LWJGLException e) {
e.printStackTrace();
System.exit(0);
}
final Main m = new Main();
m.run();
}
}