无法使用VBO渲染四边形

时间:2013-12-19 22:10:11

标签: java opengl lwjgl

我正在尝试使用LWJGL中的顶点缓冲区对象渲染四边形。

[5, 5, 6]
[6, 5, 6]
[6, 6, 6]
[5, 6, 6]

有点有用:

enter image description here

但它只渲染一个三角形(立方体是使用立即模式渲染的),而且我不确定顶点或tex坐标(或完全不同的东西)是否有问题。

Block.java :( x = 5,y = 5,z = 5)

private final Texture top;

public void render() {
    top.render(x, y, z + 1, x, y + 1, z + 1, x + 1, y + 1, z + 1, x + 1, y, z + 1);
}

Texture.java:

    public final TextureResource textureResource;

    public final int width, height;

    private final int texID;
    private FloatBuffer vBuffer;
    private FloatBuffer tBuffer;

    private boolean changed = true;

    private IntBuffer ib = BufferUtils.createIntBuffer(2);
    private final int vHandle;
    private final int tHandle;

    public void render(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4) {
        updateBuffers3D(x1, y1, z1, x2, y2, z2, x3, y3, z3, x4, y4, z4);
        textureResource.render(texID, vBuffer, tBuffer, changed, vHandle, tHandle, Color.WHITE, 3);
    }

    private void updateBuffers3D(float x1, float y1, float z1, float x2, float y2, float z2, float x3, float y3, float z3, float x4, float y4, float z4) {
        FloatBuffer tempVertexBuffer = BufferUtils.createFloatBuffer(12);
        FloatBuffer tempTextureCoordsBuffer = BufferUtils.createFloatBuffer(8);

        tempVertexBuffer.clear();
        tempTextureCoordsBuffer.clear();

        System.out.println(x1 + ", " + y1 + ", " + z1 + " | " + x2 + ", " + y2 + ", " + z2 + " | " + x3 + ", " + y3 + ", " + z3 + " | " + x4 + ", " + y4 + ", " + z4);

        tempVertexBuffer.put(x1).put(y1).put(z1);
        tempVertexBuffer.put(x2).put(y2).put(z2);
        tempVertexBuffer.put(x3).put(y3).put(z3);
        tempVertexBuffer.put(x4).put(y4).put(z4);
        /*tempVertexBuffer.put(x1).put(x2).put(x3).put(x4);
        tempVertexBuffer.put(y1).put(y2).put(y3).put(y4);
        tempVertexBuffer.put(z1).put(z2).put(z3).put(z4);*/

        tempTextureCoordsBuffer.put(0).put(0);
        tempTextureCoordsBuffer.put(0).put(1);
        tempTextureCoordsBuffer.put(1).put(1);
        tempTextureCoordsBuffer.put(1).put(0);

        for (int i = 0; i < 12; i++) {
            if (vBuffer.get(i) != tempVertexBuffer.get(i)) {
                vBuffer.clear();
                tempVertexBuffer.flip();
                vBuffer.put(tempVertexBuffer);
                vBuffer.flip();
                changed = true;
                break;
            } else {
                changed = false;
            }
        }
        for (int i = 0; i < 8; i++) {
            if (tBuffer.get(i) != tempTextureCoordsBuffer.get(i) || changed) {
                tBuffer.clear();
                tempTextureCoordsBuffer.flip();
                tBuffer.put(tempTextureCoordsBuffer);
                tBuffer.flip();
                changed = true;
                break;
            } else {
                changed = false;
            }
        }
    }

TextureResource.java:

    private void use(int texID, ReadableColor color) {
        glEnable(GL_TEXTURE_2D);
        glColor4f((float) color.getRed() / 255f, (float) color.getGreen() / 255f, (float) color.getBlue() / 255f, (float) color.getAlpha() / 255f);
        glBindTexture(GL_TEXTURE_2D, texID);
        glEnable(GL_BLEND);
        glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    }

    private void endUse() {
        glDisable(GL_BLEND);
        glDisable(GL_TEXTURE_2D);
    }

    public void render(int texID, FloatBuffer vBuffer, FloatBuffer tBuffer, boolean changed, int vHandle, int tHandle, ReadableColor color, int size) {
        if (!loaded) {
            return;
        }

        use(texID, color);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, vHandle);
        if (changed) {
            glBufferDataARB(GL_ARRAY_BUFFER_ARB, vBuffer, GL_STATIC_DRAW_ARB);
        }
        glVertexPointer(size, GL_FLOAT, 8, 0L);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, tHandle);
        if (changed) {
            glBufferDataARB(GL_ARRAY_BUFFER_ARB, tBuffer, GL_STATIC_DRAW_ARB);
        }
        glTexCoordPointer(2, GL_FLOAT, 8, 0L);

        glDrawArrays(GL_QUADS, 0, 4);

        glBindBufferARB(GL_ARRAY_BUFFER_ARB, 0);

        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);

        endUse();
    }

有什么想法吗?我做错了什么?

1 个答案:

答案 0 :(得分:4)

经过仔细检查,我相信您对glVertexPointer (...)glTexCoordPointer (...)的来电中的争论很重要。它应该是 0 而不是 8 ,因为它们是两个紧密堆积的缓冲区,而不是交错顶点和纹理坐标的缓冲区。即使你使用交错缓冲区,步幅也是8 + 12 = 20

glVertexPointer(size, GL_FLOAT, 0, 0L);

[...]

glTexCoordPointer(size, GL_FLOAT, 0, 0L);

当你使用 8 的步幅时,在仅绘制第二个顶点之后会超出顶点数组。