Hey guys,
I too am trying to get basic basic basic VBO code to work w/ LWJGL. If it's not totally obvious from my code, I'm very new to this. I was trying to do something more complex (not much), and got so desperate that I dropped down to a single quad. Nothing but my GL_CLEAR_COLOR shows up.
Oh, and I know what you might guess first, so I'll just tell you now that I'm remembering to flip my buffers :)
One more thing: I realize that almost everywhere people are using ARBblahblah.glBlahBlahARB() instead of just GLXX.glBlahBlah(). Why is that? My insistence on using GLXX may be my problem, but I'd like to understand when I have to use ARB extension classes vs. when it's ok to use the gl-built-in functions. For instance, the LWJGL tutorial for working with shaders used ARB, but I made some shaders just fine with GL20.
So here's the code. Rip me apart. Don't worry about View. That's basically just an interface. And don't worry about GraphicsTest. It's just some boilerplate to set up a Display window and a game loop.
EDIT: If it matters, I'm on a laptop with Mac OS Snow Leopard (10.6.8) and an NVIDIA GeForce GT 330M.
import static org.lwjgl.opengl.GL11.*;
import static org.lwjgl.opengl.GL15.*;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;
import org.lwjgl.BufferUtils;
import org.lwjgl.opengl.Display;
import org.lwjgl.opengl.GLContext;
import org.lwjgl.util.glu.GLU;
public class SimpleVboTest extends View {
protected int vertexBufferId;
protected int colorBufferId;
protected int indexBufferId;
@Override
public void initialize() {
if (!GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
throw new RuntimeException("OH MAH GAHD NO VBOS!!1!");
}
// Set up all of our buffers.
vertexBufferId = glGenBuffers();
// Four vertices, three floats per vertex.
FloatBuffer vertexBuffer = BufferUtils.createFloatBuffer(4 * 3);
vertexBuffer.put(new float[] {
// Front face (facing viewer), correct winding order.
0.0f, 0.0f, 0.0f,
1.0f, 0.0f, 0.0f,
1.0f, 1.0f, 0.0f,
0.0f, 1.0f, 0.0f
});
vertexBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glBufferData(GL_ARRAY_BUFFER, vertexBuffer, GL_STATIC_DRAW);
colorBufferId = glGenBuffers();
// Four vertices, four floats for RGBA for each vertex.
FloatBuffer colorBuffer = BufferUtils.createFloatBuffer(4 * 4);
colorBuffer.put(new float[] {
// Until things are figured out, everything is red.
1.0f, 0, 0, 1.0f,
1.0f, 0, 0, 1.0f,
1.0f, 0, 0, 1.0f,
1.0f, 0, 0, 1.0f
});
colorBuffer.flip();
glBindBuffer(GL_ARRAY_BUFFER, colorBufferId);
glBufferData(GL_ARRAY_BUFFER, colorBuffer, GL_STATIC_DRAW);
indexBufferId = glGenBuffers();
// Four vertices, one index per vertex.
IntBuffer indexBuffer = BufferUtils.createIntBuffer(4);
indexBuffer.put(new int[] {
0, 1, 2, 3
});
indexBuffer.flip();
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, indexBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ARRAY_BUFFER, GL_NONE);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_NONE);
// Set up the camera at (0, 0, 4) looking at the origin.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
GLU.gluPerspective(70, 1.0f * Display.getWidth() / Display.getHeight(), 0.5f, 100);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
GLU.gluLookAt(0, 0, 10, 0, 0, 0, 0, 1, 0);
}
@Override
public void draw(GameTime gameTime) {
glClearColor(0.5f, 0.5f, 1.0f, 1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnableClientState(GL_VERTEX_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, vertexBufferId);
glVertexPointer(3, GL_FLOAT, 0, 0);
glEnableClientState(GL_COLOR_ARRAY);
glBindBuffer(GL_ARRAY_BUFFER, colorBufferId);
glColorPointer(4, GL_FLOAT, 0, 0);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, indexBufferId);
glDrawElements(GL_QUADS, 12, GL_INT, 0);
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_COLOR_ARRAY);
Display.update();
}
/**
* @param args
*/
public static void main(String[] args) {
new GraphicsTest(new SimpleVboTest());
}
}
Thanks so much for your help!
DEAR PEOPLE FROM THE FUTURE UPDATE: I needed to use GL_UNSIGNED_INT instead of GL_INT in glDrawElements(). Balls.
Quote from: honktronic on November 15, 2011, 10:05:12
Oh, and I know what you might guess first, so I'll just tell you now that I'm remembering to flip my buffers :)
Actually, my first guess was that your camera is at the wrong place. ;D
Try moving the camera by changing the GLU.gluLookAt() call (probably go along the negative z-axis instead).
Another (probably less likely) possibility is that you are getting into a backface-culling problem (i.e. you are drawing the quad in such a way that OpenGL thinks it is facing away from the camera). This can be fixed by reversing the order you draw the vertexes.
Quote from: honktronic on November 15, 2011, 10:05:12
One more thing: I realize that almost everywhere people are using ARBblahblah.glBlahBlahARB() instead of just GLXX.glBlahBlah(). Why is that? My insistence on using GLXX may be my problem, but I'd like to understand when I have to use ARB extension classes vs. when it's ok to use the gl-built-in functions. For instance, the LWJGL tutorial for working with shaders used ARB, but I made some shaders just fine with GL20.
The reason for this is that when you use GL20, you are requiring that the entire OpenGL 2.0 spec has to be implemented in the drivers. When you use the ARB*.*ARB() a driver can implement the entire OpenGL 1.4 (for instance) and also put in shaders without needing the entire OpenGL 2.0 spec. This would mean you could run on some hardware that only has OpenGL 1.4 instead of 2.0.
Both your suggestions address the same issue. Moving the camera to the other side of the polygon (down the negative vs. positive z axis) would only make the polygon show up if I was looking at its back face before, and reversing the winding order would flip which face was visible. Winding order / back-face culling does not appear to be my problem, and neither of these suggestions work. Am I misunderstanding something you said?
Your explanation for GL* vs. ARB* makes perfect sense. Thanks for clarifying that for me!
Bump?
This is a total blocker. I'd be super appreciative of any help!
not sure, but I think I remember something about having to call rewind(); on your FloatBuffers.. At least that solved my problem a bunch of months back.
Quote from: bartvbl on November 19, 2011, 01:54:58something about having to call rewind(); on your FloatBuffers
Thanks for the tip, but it's still a no-go! >:(
Quote from: honktronic on November 15, 2011, 10:05:12
...
glDrawElements(GL_QUADS, 12, GL_INT, 0);
...
God dammit. Why is it never something interesting? Behold the fix:
glDrawElements(GL_QUADS, 12, GL_UNSIGNED_INT, 0);