OpenGL: VBO с вершиной и цветом (RGBA) не отображается - PullRequest
2 голосов
/ 08 сентября 2011

Ситуация:

Я использую объекты буфера вершин в OpenGL (Java-привязка LWJGL, GL11) для визуализации прямоугольников.Я могу без проблем визуализировать текстуры (вершины и координаты текстуры), добавление к ним цвета приводит к желаемому эффекту (например, делает его полупрозрачным). Только использование вершин и цвета делает его невидимым .


Исследования:

  1. Отключение альфа-теста и смешивание приводит к черномуrect, который, очевидно, является VBO вершины и цвета без альфа-тестирования и наложения -> Он отображается.
  2. Отключение только альфа-тестирования приводит к тому же результату, что и раньше.
  3. Отключение только наложения такжене помогает.

Я не могу найти ни ошибки в своем коде, ни источник проблемы.


Состояния, активированные при рендеринге:

1028 * GL_TEXTURE_2D, GL_SMOOTH (Shade Model), GL_DEPTH_TEST, GL_LEQUAL (Глубина Func), GL_BACK (Калл лица)

Смешать Func: GL_SRC_ALPHA и GL_ONE_MINUS_SRC_ALPHA
Альфа Func: GL_GREATER и0.1F
Проекция: glOrtho (0, 1, 1, 0, 0, 1000);

Все прямоугольники на оси Z в -1 (я вызывал один раз glTranslatef(0,0,-1) перед рендерингом GUI)на осях X и Y от 0 до 1.
Дополнительно I чЯ хочу сказать, что текстура связана, но это не должно быть проблемой.


Важный код

Примечание: ЦветЭтот класс в основном содержит цвет RGBA и был написан мной, поэтому это не класс Color пакета java.awt.
Примечание 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 Ответ

4 голосов
/ 08 сентября 2011

Состояния активируются при рендеринге: GL_TEXTURE_2D

Думаю, в этом ваша проблема: если вы не хотите текстурировать, отключите GL_TEXTURE_…. В противном случае весь примитив будет взят из последних использованных текстурных координат, возможно, альфа = 0.

...