0
\$\begingroup\$

I am trying to render a colored quad with LWJGL and OpenGL.

The vertices array is specified in interleaved format and look like this:

float[] vertices = {
    -0.5,0.5, MAGENTA_FLOAT,
    -0.5,-0.5, YELLOW_FLOAT,
    0.5,-0.5, RED_FLOAT,
    0.5,0.5, WHITE_FLOAT
};

I am trying to specify the colors as single float values. For this, I am packing each color using the following method:

public static float toFloatBits (int r, int g, int b, int a) {
    int color = (a << 24) | (b << 16) | (g << 8) | r;
    float floatColor = NumberUtils.intToFloatColor(color);
    return floatColor;
}

In my shader code, the attributes declarations look like this:

in vec2 a_position;
in vec4 a_color;

I expect the graphics driver to correctly interpret the float color value into 4 color components.

Creating the VAO

This is the snippet of creating the VAO:

vao = GL30.glGenVertexArrays();
GL30.glBindVertexArray(vao);

int vbo = GL15.glGenBuffers();
GL15.glBindBuffer(GL15.GL_ARRAY_BUFFER, vbo);
FloatBuffer interleavedBuffer = BufferUtils.createFloatBuffer(vertices.length);
interleavedBuffer.put(vertices).flip();
GL15.glBufferData(GL15.GL_ARRAY_BUFFER, interleavedBuffer, GL15.GL_STATIC_DRAW);

int vertexSize = 2 * Float.BYTES + Integer.BYTES;
GL20.glVertexAttribPointer(0, 2, GL11.GL_FLOAT, false, vertexSize, 0);
GL20.glVertexAttribPointer(1, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);

GL20.glEnableVertexAttribArray(0);       
GL20.glEnableVertexAttribArray(1);

I am not getting the expected result: the colors of the rendered quad are incorrect. (getting red where it should be green, getting all black, ignoring alpha even though blending enabled, etc.)

Can someone spot an error here?

\$\endgroup\$
1
  • \$\begingroup\$ have you taken a look at glVertexAttribPointer, it would mean you can have 3 floats in the vertices array for xyz, and add extra for example for rgba. Its a much better way to do it. \$\endgroup\$
    – Pow
    Commented Mar 13 at 15:07

2 Answers 2

2
\$\begingroup\$

You don't need to pack to a float for this to work.

You specify it as a 4-component byte array in your program code, with each component (of RGBA) in the range 0 to 255. Set up your vertex attrib pointer to use size 4, type GL_UNSIGNED_BYTE and normalized GL_TRUE. Then set your shader code to read it as a vec4 and the conversion is automatic, nothing further required.

\$\endgroup\$
1
  • \$\begingroup\$ This is what I was talking about yeah \$\endgroup\$
    – Pow
    Commented Mar 14 at 10:30
0
\$\begingroup\$

Ok, found where the problem was. Change the attribute length from 1 to 4:

incorrect:

GL20.glVertexAttribPointer(1, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);

correct:

GL20.glVertexAttribPointer(4, 1, GL11.GL_UNSIGNED_BYTE, true, vertexSize, Float.BYTES * 2);
\$\endgroup\$

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .