OpenGL:顶点和颜色(RGBA)的VBO不显示

时间:2011-09-08 17:33:11

标签: java opengl colors vbo

情况:

我在OpenGL中使用顶点缓冲对象(LWJGL java binding,GL11)来渲染矩形。我可以毫无问题地渲染纹理(顶点和纹理坐标),同时为它添加颜色可以产生所需的效果(比如使它变成半透明)。 仅使用顶点和颜色使其不可见


期试验研究

  1. 禁用alpha测试和混合导致黑色矩形,这显然是没有alpha测试和混合的顶点和颜色VBO - >它被渲染。
  2. 仅禁用alpha测试会导致与之前相同的结果。
  3. 仅禁用混合也无济于事。
  4. 我在代码中找不到任何错误,也无法找到问题的根源。


    渲染时已激活状态:

    GL_TEXTURE_2D,GL_SMOOTH(阴影模型),GL_DEPTH_TEST,GL_LEQUAL(深度函数),GL_BACK(剔除脸)

    Blend Func:GL_SRC_ALPHA和GL_ONE_MINUS_SRC_ALPHA
    Alpha Func:GL_GREATER和0.1F
    投影:glOrtho(0,1,1,0,0,1000);

    所有矩形在Z轴上为-1(我在渲染GUI之前调用glTranslatef(0,0,-1)),在X轴和Y轴之间在0和1之间。另外我必须说a纹理是绑定的,但这不应该是问题。


    重要代码

    注意: Color类基本上包装了RGBA颜色,并且由我编写,因此它不是java.awt包的Color类。
    注2:我知道我的VertexBufferObject类没有使用动态绘制VBO进行优化,但我找不到时间来处理它。

    顶点缓冲区对象

    private boolean isStatic;
    private boolean hasColor;
    private boolean hasTexture;
    private boolean hasNormals;
    private int renderMode;
    private int vertices;
    private int vertexSize;
    
    private ByteBuffer buffer;
    private int vboId;
    private boolean isDirty;
    
    public VertexBufferObject (int renderMode, boolean isStatic, boolean hasColor, boolean hasTexture, boolean hasNormals, int vertices) {
        this.isStatic = isStatic;
        this.hasColor = hasColor;
        this.hasTexture = hasTexture;
        this.hasNormals = hasNormals;
        this.vertices = vertices;
        this.renderMode = renderMode;
        vertexSize = calculateVertexSize();
    }
    
    
    public void markDirty () {
        isDirty = true;
    }
    
    
    public void createBuffer () {
        buffer = BufferUtils.createByteBuffer(getVertexSize());
        markDirty();
    }
    
    public void createVBO () {
        buffer.flip();
    
        vboId = ARBVertexBufferObject.glGenBuffersARB();
    
        // Buffer into vbo
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboId);
        ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, (isStatic ? ARBVertexBufferObject.GL_STATIC_DRAW_ARB : ARBVertexBufferObject.GL_DYNAMIC_DRAW_ARB));
    
        // Unbind
        ARBVertexBufferObject.glUnmapBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB);
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
    
        if (isStatic) buffer = null;
    }
    
    
    
    public void addVertex (float x, float y, float z) {
        buffer.putFloat(x);
        buffer.putFloat(y);
        buffer.putFloat(z);
    }
    
    public void addTextureCoordinates (float u, float v) {
        buffer.putFloat(u);
        buffer.putFloat(v);
    
    }
    
    public void addColor (Color color) {
        addColor(color.getRGBAInt());
    }
    
    public void addColor (int rgba) {
        buffer.putInt(rgba);
        System.out.println(Integer.toBinaryString(rgba));
    }
    
    public void addNormal (byte x, byte y, byte z) {
        buffer.put(x);
        buffer.put(y);
        buffer.put(z);
    }
    
    
    
    public void setVertex (int index, float x, float y, float z) {
        index *= vertexSize;
        buffer.position(index);
        buffer.putFloat(x);
        buffer.putFloat(y);
        buffer.putFloat(z);
        markDirty();
    }
    
    public void setTextureCoordinates (int index, float u, float v) {
        index *= vertexSize + 12;
        buffer.position(index);
        buffer.putFloat(u);
        buffer.putFloat(v);
        markDirty();
    }
    
    public void setColor (int index, Color color) {
        setColor(index, color.getRGBAInt());
    }
    
    public void setColor (int index, int rgba) {
        index *= vertexSize + (hasTexture ? 20 : 12);
        buffer.position(index);
        buffer.putInt(rgba);
        markDirty();
    }
    
    public void setNormal (int index, byte x, byte y, byte z) {
        index *= vertexSize - 3;
        buffer.position(index);
        buffer.put(x);
        buffer.put(y);
        buffer.put(z);
        markDirty();
    }
    
    
    public void draw () {
        draw(0, vertices);
    }
    
    public void draw (int start, int vertexNumber) {
        if (vboId == 0) return;
    
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, vboId);
    
        // Update Dynamic VBO
        if (isDirty && !isStatic) {
            buffer.position(0);
            int vboType = isStatic ? ARBVertexBufferObject.GL_STATIC_DRAW_ARB : ARBVertexBufferObject.GL_DYNAMIC_DRAW_ARB;
            ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0, vboType);
            ARBVertexBufferObject.glBufferDataARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, buffer, vboType);
            isDirty = false;
        }
    
        // Stride
        int stride = 12;
        if (hasTexture) stride += 8;
        if (hasColor) stride += 4;
        if (hasNormals) stride += 3;
    
        // Apply Pointers
        GL11.glEnableClientState(GL11.GL_VERTEX_ARRAY);
        GL11.glVertexPointer(3, GL11.GL_FLOAT, stride, 0);
    
        if (hasTexture) {
            GL11.glEnableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
            GL11.glTexCoordPointer(2, GL11.GL_FLOAT, stride, 12);
        }
    
        if (hasColor) {
            GL11.glEnableClientState(GL11.GL_COLOR_ARRAY);
            GL11.glColorPointer(4, GL11.GL_UNSIGNED_BYTE, stride, hasTexture ? 20 : 12);
        }
    
        if (hasNormals) {
            GL11.glEnableClientState(GL11.GL_NORMAL_ARRAY);
            GL11.glNormalPointer(GL11.GL_BYTE, stride, stride - 3);
        }
    
        // Draw with specified render mode
        GL11.glDrawArrays(renderMode, start, vertexNumber);
    
        // Unbind VBO
        if (hasTexture) GL11.glDisableClientState(GL11.GL_TEXTURE_COORD_ARRAY);
        if (hasColor) GL11.glDisableClientState(GL11.GL_COLOR_ARRAY);
        if (hasNormals) GL11.glDisableClientState(GL11.GL_NORMAL_ARRAY);
        GL11.glDisableClientState(GL11.GL_VERTEX_ARRAY);
    
        ARBVertexBufferObject.glBindBufferARB(ARBVertexBufferObject.GL_ARRAY_BUFFER_ARB, 0);
    }
    
    
    public void destroy () {
        ARBVertexBufferObject.glDeleteBuffersARB(vboId);
    }
    
    
    private int calculateVertexSize () {
        return vertices * 12 + vertices * (hasTexture ? 8 : 0) + vertices * (hasColor ? 4 : 0) + vertices * (hasNormals ? 4 : 0);
    }
    


    ColorFrameRenderer (基本上是矩形)

    private VertexBufferObject vbo;
    private Color color;
    
    public ColorFrameRenderer(int sizeX, int sizeY, Color color) {
        super(sizeX, sizeY);
        this.color = color;
    }
    
    @Override
    public void render() {
        if (!render) return;
        vbo.draw();
    }
    
    @Override
    public void init() {
        vbo = new VertexBufferObject(GL11.GL_QUADS, false, true, false, false, 4);
    
        vbo.createBuffer();
    
        vbo.addVertex(x, y, 0);
        vbo.addColor(color);
        vbo.addVertex(x, y + sizeY, 0);
        vbo.addColor(color);
        vbo.addVertex(x + sizeX, y + sizeY, 0);
        vbo.addColor(color);
        vbo.addVertex(x + sizeX, y, 0);
        vbo.addColor(color);
    
        vbo.createVBO();
    }
    
    @Override
    public void setPosition (float x, float y, float z) {
        super.setPosition(x, y, z);
    
        if (vbo != null) {
            vbo.setVertex(0, this.x, this.y, 0);
            vbo.setVertex(1, this.x, this.y + sizeY, 0);
            vbo.setVertex(2, this.x + sizeX, this.y + sizeY, 0);
            vbo.setVertex(3, this.x + sizeX, this.y, 0);
        }
    }
    


    感谢您的帮助和建议! 请理解,由于它所属的或多或少的秘密项目,我无法提供整个代码。

1 个答案:

答案 0 :(得分:4)

  

渲染时激活状态:   GL_TEXTURE_2D

我认为那是你的问题:如果你不想纹理,请禁用GL_TEXTURE_ ....否则整个基元将从最后使用的纹理坐标中采样,可能是alpha = 0样本。