Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I get Alpha blending transparency working in OpenGL ES 2.0?

I'm in the midst of porting some code from OpenGL ES 1.x to OpenGL ES 2.0, and I'm struggling to get transparency working as it did before; all my triangles are being rendered fully opaque.

My OpenGL setup has these lines:

// Draw objects back to front
glDisable(GL_DEPTH_TEST);

glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);

glDepthMask(false);

And my shaders look like this:

attribute vec4 Position;
uniform highp mat4 mat;
attribute vec4 SourceColor;
varying vec4 DestinationColor;

void main(void) {
  DestinationColor = SourceColor;
  gl_Position = Position * mat;
}

and this:

varying lowp vec4 DestinationColor;

void main(void) {
  gl_FragColor = DestinationColor;
}

What could be going wrong?

EDIT: If I set the alpha in the fragment shader manually to 0.5 in the fragment shader (or indeed in the vertex shader) as suggested by keaukraine below, then I get transparent everything. Furthermore, if I change the color values I'm passing in to OpenGL to be floats instead of unsigned bytes, then the code works correctly.

So it looks as though something is wrong with the code that was passing the color information into OpenGL, and I'd still like to know what the problem was.

My vertices were defined like this (unchanged from the OpenGL ES 1.x code):

typedef struct
{
  GLfloat x, y, z, rhw;
  GLubyte r, g, b, a;
} Vertex;

And I was using the following code to pass them into OpenGL (similar to the OpenGL ES 1.x code):

glBindBuffer(GL_ARRAY_BUFFER, glTriangleVertexBuffer);
glBufferData(GL_ARRAY_BUFFER, sizeof(Vertex) * nTriangleVertices, triangleVertices, GL_STATIC_DRAW);
glUniformMatrix4fv(matLocation, 1, GL_FALSE, m);
glVertexAttribPointer(positionSlot, 4, GL_FLOAT, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, x));
glVertexAttribPointer(colorSlot, 4, GL_UNSIGNED_BYTE, GL_FALSE, sizeof(Vertex), (void*)offsetof(Vertex, r));
glDrawArrays(GL_TRIANGLES, 0, nTriangleVertices);
glBindBuffer(GL_ARRAY_BUFFER, 0);

What is wrong with the above?

like image 759
Rich Avatar asked Jun 12 '13 17:06

Rich


2 Answers

Your Colour vertex attribute values are not being normalized. This means that the vertex shader sees values for that attribute in the range 0-255.

Change the fourth argument of glVertexAttribPointer to GL_TRUE and the values will be normalized (scaled to the range 0.0-1.0) as you originally expected.

see http://www.khronos.org/opengles/sdk/docs/man/xhtml/glVertexAttribPointer.xml

like image 67
GuyRT Avatar answered Sep 27 '22 22:09

GuyRT


I suspect the DestinationColor varying to your fragment shader always contains 0xFF for the alpha channel? If so, that is your problem. Try changing that so that the alpha actually varies.

Update: We found 2 good solutions:

  1. Use floats instead of unsigned bytes for the varyings that are supplied to the DestinationColor in the fragment shader.

  2. Or, as GuyRT pointed out, you can change the fourth argument of glVertexAttribPointer to GL_TRUE to tell OpenGL ES to normalize the values when they are converted from integers to floats.

like image 44
ClayMontgomery Avatar answered Sep 27 '22 22:09

ClayMontgomery