4
$\begingroup$

I am using a single VBO to store vertices in the follow format:

v1X, v1Y, v1Z, v1R, v1G, v1B, v2A, v2X, ...

Vertex positioning is fine, shapes show up where expected, however instead of using the colour provided, all shapes show up red.

The code given below simply draws two triangles to form one square ground shape.

Buffer data preparation method

public void prepare(float[] data) {
    glBindBuffer(GL_ARRAY_BUFFER, vboID);
    FloatBuffer dataBuffer = RenderUtils.fArrayToBuffer(data);
    if(dataLength != data.length) {
        glBufferData(GL_ARRAY_BUFFER, dataBuffer, GL_STATIC_DRAW);
        dataLength = data.length;
    } else {
        glBufferSubData(GL_ARRAY_BUFFER, 0, dataBuffer);
    }
    glVertexAttribPointer(0, 3, GL_FLOAT, false, 7*4, 0);
    glVertexAttribPointer(3, 4, GL_FLOAT, false, 7*4, 3*4);
}

Render code

floorObj.prepare(new float[]{
    -5, 0, -5,   1, 0, 0, 1,
    5, 0, -5,   0, 1, 0, 1,
    -5, 0, 5,   0, 0, 1, 1,

    5, 0, -5,   1, 0, 0, 1,
    5, 0, 5,   0, 1, 0, 1,
    -5, 0, 5,   0, 0, 1, 1,
});
glDrawArrays(GL_TRIANGLES, 0, 6);

Vertex shader

#version 330 core

in vec3 position;
in vec4 i_color;
out vec4 color;

uniform mat4 transform;

void main(){
    gl_Position = transform * vec4(position, 1);
    color = i_color;
}

Fragment shader

#version 330 core

in vec4 color;
out vec4 f_color;

void main(){
    f_color = color;
}

As previously stated, vertex positions work fine, however colour does not. Just ask if any other code would be useful to determine the problem.

Thanks, - Jasper

$\endgroup$
3
  • 1
    $\begingroup$ the first parameter of glVertexAttribPointer should be queried with glGetAttribLocation $\endgroup$ Feb 7, 2016 at 23:50
  • $\begingroup$ Perhaps you are missing enabling the attrin pointers? Take a look at glEnableVertexAttribArray(). $\endgroup$
    – BRabbit27
    Jul 5, 2016 at 5:05
  • $\begingroup$ Another thing that comes to mind is trying to set the location in the shaders. The first parameter in glVertexAttribPointer is the index of the vertex attribute. Therefore, trying something in your shader like layout(location = 0) in vec3 posición; and layout(location = 3) in vec4 i_color; might help. $\endgroup$
    – BRabbit27
    Jul 5, 2016 at 5:09

3 Answers 3

2
$\begingroup$

Your attribute locations could be wrong, because you're not querying them:

glVertexAttribPointer(0, 3, GL_FLOAT, false, 7*4, 0);
glVertexAttribPointer(3, 4, GL_FLOAT, false, 7*4, 3*4);

The first parameter should be queried using glGetAttribLocation:

glVertexAttribPointer(glGetAttribLocation( program, "position" ), 3, GL_FLOAT, false, 7*4, 0);
glVertexAttribPointer(glGetAttribLocation( program, "i_color" ), 4, GL_FLOAT, false, 7*4, 3*4);

If using more modern OpenGL, the locations can be set manually in the shader, eliminating the need for glGetAttribLocation:

layout(location=0) in vec3 position;
layout(location=3) in vec4 i_color;
$\endgroup$
0
1
$\begingroup$

While normally I'd agree with @Survival Machine's assessment, since you say that the geometry is correct, but the color is showing up as solid red, it sounds like your colors have their color channels backwards. Normally, I would expect RGBA to be correct. But if everything's red, that sounds like the alpha is where the red should be. (Your alpha is always 1, so if they're swapped, now your red is always 1.) You can test this by changing your fragment shader to try different color orderings. Just add a swizzle to the last line:

f_color = color.yzwx;

That will switch it from RGBA to ARGB. You might also try going the other way:

f_color = color.wxyz;

It could also be in ABGR format (unlikely). You'd fix that by doing:

f_color = color.wzyx;

It seems strange that any of these would happen. If that does turn out to be the issue, it would be worth investigating why it's happening.

$\endgroup$
1
$\begingroup$

This:

glVertexAttribPointer(0, 3, GL_FLOAT, false, 7*4, 0);
glVertexAttribPointer(3, 4, GL_FLOAT, false, 7*4, 3*4);

should be this:

GLint posAttrib = glGetAttribLocation(yourShader, "position");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 3, GL_FLOAT, false, sizeof(float)*7, 0);

posAttrib = glGetAttribLocation(yourShader, "i_color");
glEnableVertexAttribArray(posAttrib);
glVertexAttribPointer(posAttrib, 4, GL_FLOAT, false, sizeof(float)*7, sizeof(float)*2);

as both are byte offsets, not array indices. A GLfloat is currently defined as 32 bit = 4 Byte, but you should never hard code that.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.