Opaque shader

I’m writing a program that uses OpenGL 3.3 and I’ve been using a pretty simple fragment shader to deal with the colors. However, I’ve just noticed that, even though gl_FragColor is given an alpha value of 1.0, I can still see objects that occur behind any given object.

Should it be relevant, here’s my fragment shader code.

#version 330
precision highp float;

uniform vec3 EyeAxis = vec3(0.0,0.0,1.0);
uniform mat4 Modelview;
uniform mat4 Projection;
in vec3 ex_Color;
in vec4 ex_Normal;
out vec4 gl_FragColor;

void main(void)
{
	vec4 Normal = Projection*Modelview*ex_Normal;
	vec4 Eye = vec4(EyeAxis,1.0);
	float c = abs(dot(normalize(Eye.xyz),normalize(Normal.xyz)));
	gl_FragColor = vec4((0.2+0.8*c)*ex_Color,1.0);
}

Is there some rendering attribute I need to activate in the shader or in my code?

I’ve annexed an image to demonstrate what happens. It’s a lateral view of a surface, and that central mess is really just the surface changing direction and moving “behind itself” from this view, but the meshes from both parts (near us and behind itself) can be seen. It’s not just the meshes. If I turn them off, I can still see what seems to be some serious aliasing, with a mess of slightly-differently-coloured triangles.

Alpha means exactly and only what you make OpenGL do with it. If you have a blending mode set that doesn’t use alpha, then it doesn’t matter what the alpha is.

Ah, thanks.

Using

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

worked perfectly.

I’ve been away from my code for a few days, but just realized that this actually didn’t work. I can still see through my objects.

Something I didn’t mention before but that might somehow be relevant is that I am also using Qt. In fact, the object that is doing the OpenGL drawing is an NGLWidget, a child of QGLWidget. QGLWidget contains a QGLFormat which defines the OpenGL context being used.

Here is the relevant code snippet regarding blending and depth-testing.

void MyNGLWidget::Initialize()
{
	GenBuffers();
	GenShaders();
	glEnable(GL_BLEND);
	glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
	glEnable(GL_DEPTH_TEST);

	Initialized = true;
	updateGL();
}
void MyNGLWidget::initializeGL()
{
	glewInit();
	format().setDepth(true); //these two work on the NGLFormat context. The depth buffer is actually on by default, but I do this just to be sure.
	format().setDepthBufferSize(32);
}

The second function (initializeGL()) is the first one called, before anything is performed. The first (Initialize()) is called only after the drawing data (coordinates, color, normal, etc) is collected.

The shader code is still the same as above. However, my meshes remain transparent. Is there something fundamentally wrong in what I’m doing?

Maybe QT is overwriting your initial glBlendFunc call on every frame?

I’ve considered that (or some other such thing) and have thus also posted this question at qtcentre.org forums. Should I take that to mean that, from a purely OpenGL perspective, what I’m doing seems right?

Oh, and I also have

glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

before every draw-call.

Yes, generally what you do is correct. Though as Brink’s developers mentioned recently, it’s best to reset state to known values on every frame :slight_smile:

What do you mean? How have I altered the state in such a way that it needs to be reset?

It’s not you that changed state, but probably the Qt.