0
\$\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\$
1
\$\begingroup\$

There are a couple potential reasons why it doesn't work:

  1. you have not enabled the Vertex Attrib 3: glEnableVertexAttribArray(3).
  2. you have not told GL where to find the color attribute: glBindAttribLocation(..., 3, "i_color") before linking. You should be doing the same thing for position, as Gabriel Roy mentioned, if you didn't yet.
\$\endgroup\$
1
  • \$\begingroup\$ I enabled the vertex attrib in my init code though that wasn't posted. I will bear in mind the glBindAttribLocation tip in mind though, thank you. In the end, I had to use AttribArray(1) instead of (3) which in turn solved my problem. Thanks though \$\endgroup\$ Feb 8 '16 at 13:09
0
\$\begingroup\$

Okay, I think your problem comes from the

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

Let me explain what this function does and what are its parameters :)

The first parameter (0) specify which vertex attribute we want to allocate. This determine which determine which VAO pointer will be linked to your array. Remember that OpenGL is a state machine and that the CURRENT binded buffer is linked with your vexter pointer. If you put 0 there, you must put 0 when u create your shader program and set the

glBindAttribLocation(m_Program_Cube, 0, "vertexPosition");

See the 0 (This is the index of the vertex pointer)

Next we have the size (This is either a 1,2,3 or 4) and determine which kind of vector is going to enter your vertex shader. Pretty simple.

Next is the type of variable which will enter the buffer ... Most of the time its GL_FLOAT

Next is the normalization of the vertex, it's a pretty complicated thing and help with rotating when using geometry shader later one. Leave it at GL_False

Next is the most important part, which is the STRIDE. The STRIDE helps determine the space in (GL_Float) between each SETS of vertices. In your case you are using (7*4) I personnaly don't know where u are getting that "4" at but put

7 * sizeof(GLfloat)

This will mean that between each set of Vertex Position (The first 3 vertices making the first vec3) there will be 7 other GL_Float

Next and finally is the OFFSET which is pretty important when making a single VBO containing all the position, colors and maybe texturecoords

Another error you made there is using "3*4". I still don't know where u are getting that "4" but its alright :) I'll correct it. The OFFSET is a value that is increase to the base starting position. For example your color vector3 start at the position 3 so it should be

(GLvoid*)(0* sizeof(GLfloat))

Don't worry about the GLvoid* .. There is alot of things in OpenGL that you just simply cannot understand by yourself and you just need to accept them. This is one. Change the 0 for "3" which mean that your OFFSET will be set to 3.

Finally, you need to make sure that you are working in the same VAO. In your case you are using a single VBO (A big array) to contain every vertices for the position and colors. Later on you will learn to create multiple VBO to separate your arrays but right now keep it at one :)

But don't worry I'm sure you will learn just fine!!! :)

Ps: Don't forget to bind your attribute properly in your shader using the good location of the pointer.

This was my first time helping someone with OpenGl and I hope I did good :)

\$\endgroup\$
2
  • \$\begingroup\$ sizeof(float) == 4 on just about every platform you care to use opengl on. \$\endgroup\$ Feb 8 '16 at 11:20
  • \$\begingroup\$ Yes, 4 is the float size. Thank you for your explanations, you explained well though I do understand what the function does. I found my error, it turned out that I was binding the wrong attrib index, instead of 3 I should have used 1. I solved my problem since, but thank you. \$\endgroup\$ Feb 8 '16 at 13:06
0
\$\begingroup\$

Turns out I was using the wrong attribute index (3 instead of 1).

In enabling attrib index 1 instead of 3, and changing my

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

to

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

I was able to solve the issue.

\$\endgroup\$
1
  • \$\begingroup\$ If you don't specify the 1 yourself, you have no guarantee it is indeed 1. That's why you need to use glBindAttribLocation (to say where you want it). \$\endgroup\$
    – Bahbar
    Feb 8 '16 at 14:53

You must log in to answer this question.

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