我正在研究LWJGL中的2D游戏。我使用glBegin成功地使用纹理渲染了QUADS,但转向VBO却是一项艰巨的任务。目前,我可以使用布尔值在vbo和非vbo渲染之间切换,两者都使用相同的顶点和纹理坐标。 VBO实现不会在屏幕上绘制任何内容。有人能指出我正确的方向吗?
这是我的初始化:
public void init() {
VBOID = VBOHandler.createVBOID();
TBOID = VBOHandler.createVBOID();
float[] vdata = {0, 0,
width, 0,
width, height,
0, height};
float[] tdata = {sx, sy,
ex, sy,
ex, ey,
sx, ey};
//Texture coordinates: (0,0)(1,0)(1,1) and (0,1)
FloatBuffer fb = BufferUtils.createFloatBuffer(8);
fb.put(vdata);
VBOHandler.bufferData(VBOID, fb);
fb = BufferUtils.createFloatBuffer(8);
fb.put(tdata);
VBOHandler.bufferData(TBOID, fb);
}
这是我的渲染代码:
private void render() {
texture.bind();
if(vbo) {
GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
VBOHandler.bindBuffer(VBOID);
GL11.glVertexPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindBuffer(TBOID);
GL11.glTexCoordPointer(2, GL11.GL_FLOAT, 0, 0);
VBOHandler.bindElementBuffer(VBOHandler.getDefaultIBOID());
// I figured why not use a standard IBO for all my sprite drawing
// The default IBO ID is initialized earlier in the program, not shown in this code
GL12.glDrawRangeElements(GL11.GL_TRIANGLE_FAN, 0, 3, 4, GL11.GL_UNSIGNED_SHORT, 0);
GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
} else {
GL11.glBegin(GL11.GL_TRIANGLE_FAN);
GL11.glTexCoord2f(sx, sy);
GL11.glVertex2f(0, 0);
GL11.glTexCoord2f(ex, sy);
GL11.glVertex2f(width,0);
GL11.glTexCoord2f(ex, ey);
GL11.glVertex2f(width, height);
GL11.glTexCoord2f(sx, ey);
GL11.glVertex2f(0, height);
GL11.glEnd();
}
}
和VBOHandler类,对于那些感兴趣的人
public class VBOHandler {
private static int IBOID;
public static void initDefaultIBO() {
IBOID = createVBOID();
short[] indexdata = {0, 1, 2, 3};
ShortBuffer shortBuffer = BufferUtils.createShortBuffer(4);
shortBuffer.put(indexdata);
VBOHandler.bufferElementData(IBOID, shortBuffer);
}
public static int getDefaultIBOID() {
return IBOID;
}
public static int createVBOID() {
if(GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
return ARBVertexBufferObject.glGenBuffersARB();
}
return 0;
}
public static void bufferData(int id, FloatBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bufferElementData(int id, ShortBuffer buffer) {
if (GLContext.getCapabilities().GL_ARB_vertex_buffer_object) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, buffer, ARBVertexBufferObject.GL_STATIC_DRAW_ARB);
}
}
public static void bindBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, id);
}
public static void bindElementBuffer(int id) {
ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ELEMENT_ARRAY_BUFFER_ARB, id);
}
}
上面的render-function位于我的Sprite类中。我的GameView每帧都调用它:
public void renderGame() {
GL11.glMatrixMode(GL11.GL_MODELVIEW);
GL11.glLoadIdentity();
sprite.render();
}
使用以下代码初始化GameView:
Display.setDisplayMode(new DisplayMode(1024, 768));
GL11.glEnable(GL11.GL_TEXTURE_2D);
GL11.glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
GL11.glEnable(GL11.GL_BLEND); // enable alpha blending
GL11.glBlendFunc(GL11.GL_SRC_ALPHA, GL11.GL_ONE_MINUS_SRC_ALPHA);
GL11.glMatrixMode(GL11.GL_PROJECTION);
GL11.glLoadIdentity();
GL11.glOrtho(x - width/2, x + width/2, y + height / 2, y - height / 2, -1, 1);
GL11.glMatrixMode(GL11.GL_MODELVIEW);
答案 0 :(得分:0)
在将FloatBuffers传递给OpenGL之前,您没有在FloatBuffers上调用'flip'。在将它们传递给OpenGL之前,你需要在FloatBuffers上调用'flip()',否则它将无法读取它们。值得注意的是,在您自己调用'flip()'之后,您无法读取FloatBuffers。