2D рендеринг с VBO в lwjgl не будет рисовать - PullRequest
0 голосов
/ 23 мая 2011

Я работаю над 2D-игрой в LWJGL. Я успешно рендерил QUADS с текстурами, используя glBegin, но переход к VBO оказался большим делом. В настоящий момент я могу переключаться между рендерингом vbo и non-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);
}
 }

Вышеприведенная функция визуализации находится в моем классе 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);

1 Ответ

0 голосов
/ 02 июля 2012

Вы не вызывали 'flip' на FloatBuffers перед передачей их в OpenGL.Вам нужно , чтобы вызвать flip () для FloatBuffers, прежде чем передать их в OpenGL, иначе он не сможет их прочитать.Стоит отметить, что вы не можете читать FloatBuffers после того, как сами вызвали flip ().

...