Texture and color together in GLSL?

Constantin picture Constantin · Feb 15, 2011 · Viewed 16.3k times · Source

I cant figure out, how to get with OpenGL ES 2.0 similiar Results to OpenGL ES 1.1. I want to use actually a Sampler2D (to blend my texture with Alpha Channel to the Framebuffer) and also set an Color. The texture should be painted in the color - like in OpenGL ES 1.1 My FragmentShader looks like this:

varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) + colorVarying;
}

But the part "+ colorVarying" destroys my alphachannel with black (because I also add colorVarying, if the AlphaValue is 0) and makes an strange gradient effect... How is the texture & color channel combined in the fixed function pipeline? My Replacement for glColor4f is:

void gl2Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a){
    const GLfloat pointer[] = {r, g, b, a};
    glVertexAttribPointer(ATTRIB_COLOR, 2, GL_FLOAT, 0, 0, pointer);
    glEnableVertexAttribArray(ATTRIB_COLOR);
}

And I'm using glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); if this is somehow relevant...

For the color 1.0, 0.0, 1.0, 1.0 here is what I get now: Now

And I want to get:

What I want to see

Some ideas to accomplish this? Any help would be appreciated.

Answer

Pivot picture Pivot · Feb 15, 2011

To combine your vertex color with your texture the way OpenGL ES 1.1 does by default, you’ll want your fragment shader to be:

varying lowp vec4 colorVarying;
varying mediump vec2 texcoordVarying;
uniform sampler2D texture;

void main(){
    gl_FragColor = texture2D(texture, texcoordVarying) * colorVarying;
}

Note that GL_MODULATE multiplies the texture by the color, rather than adding to it.

You’re seeing a gradient in your image because passing a stride of 0 to vertex array specification functions in OpenGL ES (both 1.1 and 2.0) doesn’t result in a stride of 0—rather, OpenGL ES calculates the stride for you, assuming tightly packed elements of the format/type you specified. As a result, you’re actually reading past the end of your array into random memory. If you want the same value across all vertices, you should set the current attribute value and disable the associated array:

void gl2Color4f(GLfloat r, GLfloat g, GLfloat b, GLfloat a){
    const GLfloat pointer[] = {r, g, b, a};
    glVertexAttrib4fv(ATTRIB_COLOR, pointer);
    glDisableVertexAttribArray(ATTRIB_COLOR);
}