开发者

2D rendering with VBO in lwjgl won't draw

I'm working on a 2D game in LWJGL. I have successfully rendered QUADS with textures using glBegin but moving to VBOs turned out to be a big undertaking. At the moment I can switch between the vbo and non-vbo rendering with a boolean, both using the same vertex- and texture coordinates. The VBO-implementation won't draw anything onto the screen. Can anyone point me in the right direction?

This is my initialization:

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);
}

And here is my rendering code:

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();
    }

}

And the VBOHandler class, for those interested

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, FloatBuff开发者_开发知识库er 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);
}
 }

The above render-function lies within my Sprite class. It is called by my GameView every frame as so:

public void renderGame() {
    GL11.glMatrixMode(GL11.GL_MODELVIEW);
    GL11.glLoadIdentity();
    sprite.render();
}

The GameView is initialized with the following code:

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);


You did not call 'flip' on the FloatBuffers before passing them to OpenGL. You need to call 'flip()' on FloatBuffers before you pass them to OpenGL, or it will not be able to read them. It is worth noting that you cannot read the FloatBuffers after you call 'flip()' yourself.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜