Hi everyone!
My plateform (Ubuntu 14.4 LTS 64 bits) only support opengl 3.0 and GLSL 130, I can’t use pixel linked list from opengl 450.
I’m trying to find an alternative so :
Here is the technique which I use :
I clear an FBO with a clear color, at each time I draw something, I get the texture. I also use an FBO with transparent color, and I get a second texture. (for the depthbuffer)
In the first texture I save the color of each fragment and in the second texture I save the depth and the alpha of each fragment. (You’ll see why further)
The first object is drawn with the classical blending equation so :
Blending : clear color (0, 0, 0, 1)
FB color : (0, 0, 0, 1)
DB z : 0
a : 0
Current Color : (1, 0, 0, 0.5)
Current z : 0
a = 0.5
Final color = (1, 0, 0, 0.5) * 0.5 + (0, 0, 0, 1) * (1 - 0.5) = (0.5, 0, 0, 0.75)
FB color is the color written in the first texture, DB z and a are the depth and the alpha written in the second texture, Current Color and Current z and a are the color, the z and the alpha of what I’m curretly drawing.
So the equation is SRCCOLOR * SRCALPHA + DSTCOLOR * (1 - SRCALPHA)
I need to change the blending equation, if the object I draw is behind the object which is already drawn, so in this case the bleding equation is
DSTCOLOR * DSTALPHA + SRCCOLOR * (1 - DSTALPHA)
So dstalpha is the alpha of the fragment which has been drawn previously, I give the same color in the two cases so it doesn’t matter is an object is behind or before another one, in other worlds, the order in which I draw my objects doesn’t matter.
Case 1 : (The object which is drawn is behind the object to draw.)
FB color : (1, 0, 0, 0.75)
DB z : 0
DB a : 0.5
Current Color : (1, 1, 0, 0.5)
Current z : 1
a : 0.5
Final color : (1, 1, 0, 0.5) * 0.5 + (1, 0, 0, 0.75) * (1 - 0.5) = (1, 0.5, 0, 0.652)
Cas 2 : (The object which is drawn is before the object I draw.)
FB color : (1, 0, 0, 0.75)
DB z : 1
DB a : 0.5
Current Color : (1, 1, 0, 0.5)
Current z : 0
a : 0.5
Final color : (1, 1, 0, 0.5) * 0.5 + (1, 0, 0, 0.75) * (1 - 0.5) = (1,0.5, 0, 0, 625)
So I desactivated the opengl blending and I’ve written this two shader (he one to generate the first texture, and the second to generate the second and the final texture that I draw on the window)
The vertex shader is very simple and is the same for both textures.
#version 130
out mat4 projMat;
void main () {
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;
gl_TexCoord[0] = gl_TextureMatrix[0] * gl_MultiTexCoord0;
gl_FrontColor = gl_Color;
projMat = gl_ProjectionMatrix;
};
The fragment shader for the first texture is :
#version 130
uniform sampler2D depthBuffer;
uniform sampler2D texture;
uniform vec3 resolution;"
uniform float haveTexture;
in mat4 projMat;
void main () {
vec2 position = ( gl_FragCoord.xy / resolution.xy );
vec4 color = texture2D(depthBuffer, position);
vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;
float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;
vec4 colors[2];
colors[1] = vec4(z, pixel.a, z, pixel.a);
colors[0] = vec4(z, pixel.a, color.b, color.a);
bool b = (z >= color.z && pixel.a >= color.a);
gl_FragColor = colors[int(b)];
}
And the one for the second texture is :
#version 130
uniform sampler2D depthBuffer;
uniform sampler2D frameBuffer;
uniform sampler2D texture;
uniform vec3 resolution;
uniform float haveTexture;
in mat4 projMat;
void main () {
vec2 position = ( gl_FragCoord.xy / resolution.xy );
vec4 depth = texture2D(depthBuffer, position);
vec4 color = texture2D(frameBuffer, position);
vec4 pixel = (haveTexture==1) ? gl_Color * texture2D(texture, gl_TexCoord[0].xy) : gl_Color;
float z = (gl_FragCoord.w != 1.f) ? (inverse(projMat) * vec4(0, 0, 0, gl_FragCoord.w)).w : gl_FragCoord.z;
vec4 colors[2];
colors[1] = pixel * pixel.a + color * (1 - pixel.a);
colors[0] = color * depth.g + pixel * (1 - depth.g);
bool b = (z >= depth.r);
gl_FragColor = colors[int(b)];
I avoid to use an if structure for optimization purposes.
My code simply draw two rectangles (a semi-transparent red one and a semi-transparent yellow one) on the textures with the shaders.
currentStates.shader = frameBufferGenerator;
frameBuffer->draw(m_instances[i]->getVertexArray(), currentStates);
frameBuffer->display();
currentStates.shader = depthBufferGenerator;
depthBuffer->draw(m_instances[i]->getVertexArray(), currentStates);
depthBuffer->display();
But the result I get is not the result that I expected.
The alpha blending is not performed.
Here is what I have :
[ATTACH=CONFIG]934[/ATTACH]
Why the blending isn’t applied in my fragment shader ?
Thanks for help.