4
votes

I'm struggling a bit to apply the color for my geometry. When I specify it directly in the vertex shader ("varColor = vec4(1.0, 0.5, 0.4, 1.0);") - everything is ok. But if I use color values from the "vColor" attribue - everything gets messed up.

(Added some screenshots to show what I mean)

Can someone help me to figure out what am I doing wrong, or point me in the right direction? Thanks.

Using "varColor = vec4(1.0, 0.5, 0.4, 1.0);" Using "varColor = vec4(1.0, 0.5, 0.4, 1.0);"

Using "varColor = vColor" Using "varColor = vColor"

Vertex shader:

precision mediump float;

uniform mat4 modelViewProjectionMatrix;

attribute vec4 vPosition;
attribute vec2 vTexCoord;
attribute vec4 vColor;

varying lowp vec4 varColor;
varying mediump vec2 varTexCoord;

void main()
{
    gl_Position = modelViewProjectionMatrix * vPosition;
    varTexCoord = vTexCoord;
//  varColor    = vColor;
    varColor    = vec4(1.0, 0.5, 0.4, 1.0);
}

Fragment shader:

precision mediump float;

uniform sampler2D Texture0;

varying vec4 varColor;
varying vec2 varTexCoord;

void main() 
{
    gl_FragColor = texture2D(Texture0, varTexCoord) * varColor;
}

After shader is linked, I'm binding my attributes like this:

mMatrixMVP = glGetUniformLocation(mProgramId, "modelViewProjectionMatrix");

glBindAttribLocation(mProgramId, 0, "vPosition");
glBindAttribLocation(mProgramId, 1, "vTexCoord");
glBindAttribLocation(mProgramId, 2, "vColor");

mTexture = glGetUniformLocation(mProgramId, "Texture0");
glUniform1i(mTexture, 0);

Structure that holds my vertex information:

struct Vertex
{
   float         xyz[3];
   float         st[2];
   unsigned char color[4]; // All assigned to value of 255
};

When rendering, after vertex buffer is bound, I'm setting vertex attributes like this:

glEnableVertexAttribArray(0);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) offsetof(Vertex, xyz));

glEnableVertexAttribArray(1);
glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(Vertex), (GLvoid*) offsetof(Vertex, st));

glEnableVertexAttribArray(2);
glVertexAttribPointer(2, 4, GL_UNSIGNED_BYTE, GL_TRUE, sizeof(Vertex), (GLvoid*) offsetof(Vertex, color));

glActiveTexture(GL_TEXTURE0);
pTexture->Bind(); // Just a "glBindTexture(GL_TEXTURE_2D, mTextureId);"
glUniform1i(mpCurrentShader->GetTexture(), 0);

After this I'm binding the index buffer and calling "glDrawElements".

Then, calling glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); and disabling all attributes with "glDisableVertexAttribArray" and finally - calling glBindBuffer(GL_ARRAY_BUFFER, 0);

1
If I understand your screenshot correctly, you have problems with your texture coordinates rather than (or in addition to) vertex color. Actually using a vertex attribute in a shader will make it active, and will change the automatically assigned locations.Andon M. Coleman

1 Answers

2
votes

You need to make your glBindAttribLocation() calls before linking the shader program.

If you link a program without specifying the location of attributes with either glBindAttribLocation(), or with layout qualifiers in the shader code, the attribute locations will be assigned automatically when the shader program is linked. If you call glBindAttribLocation() after linking the program, the new locations will only take effect if you link the shader program again.