2011-05-23 41 views
0

我正在制作LWJGL中的2D游戏。我已经使用glBegin成功地渲染了QUADS纹理,但是转到VBOs却成了一件大事。目前,我可以使用布尔值在vbo和non-vbo之间切换,两者都使用相同的顶点和纹理坐标。 VBO实现不会在屏幕上绘制任何东西。任何人都可以将我指向正确的方向吗?在lwjgl中使用VBO进行2D渲染不会画出

这是我的初始化:

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

以上渲染功能位于我的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

完全不相关的评论:您实际上可以放弃您的默认IBO,并使用glDrawArrays,因为您的IBO不仅仅是按顺序遍历数组。 – 2011-05-23 01:49:16

+0

您是否检查过缓冲区对象是否受支持,缓冲区ID是否有有效值(!= 0)? – 2011-05-23 01:51:30

+0

感谢您的回复家伙。我所有的缓冲区都有有效的ID(精确为1,2和3)和GLContext.getCapabilities()。GL_ARB_vertex_buffer_object返回true。 – asker 2011-05-23 01:56:37

回答

0

你没有把它们传递给OpenGL的前呼吁FloatBuffers“翻转”。您需要需要在将它们传递给OpenGL之前调用FloatBuffers上的“flip()”,否则它将无法读取它们。值得注意的是,在你自己调用'flip()'后,你无法读取FloatBuffers。