inverse video for text

I have a weird problem. I am using an alpha texture to render text in my scene.

I am trying to add inverse text to the system. Here is my vertex shader:


#version 450

layout (location = 0) out vec2 texpos;
layout (location = 1) in vec4 coord;

void main(void) {
  gl_Position = vec4(coord.xy, 0.9, 1);
  texpos = coord.zw;
}

I have modified my fragment shader to look like this:


#version 450

layout (location = 0) in vec2 texpos;
layout (location = 1) uniform sampler2D tex;
layout (location = 2) uniform vec4 color;
layout (location = 3) uniform int inverse;

void main(void) {
    if( inverse == 1 )
    {
        gl_FragColor = vec4(0, 0, 0, texture2D(tex, texpos).a);
    }
    else
    {
        gl_FragColor = vec4(1, 1, 1, texture2D(tex, texpos).a) * color;
    }
}

If I do nothing else, the text I flag as inverse is rendered as black. That’s cool.

My problem starts when I try to draw a light color quad under where the text will be rendered.
If I add the following code before the text render module is called, the text does not appear over the quad.


    if( Inverse )
    {
        width = pixel_width( a, text );
        glColor4fv( &outln_color.r );
        glBegin( GL_QUADS );
        glVertex3f( x-sx,          y-sy,        0.000 );
        glVertex3f( x+sx+width*sx, y-sy,        0.000 );
        glVertex3f( x+sx+width*sx, y+sy+a.h*sy, 0.000 );
        glVertex3f( x-sx,          y+sy+a.h*sy, 0.000 );
        glEnd();
        glColor4fv( &Current_Color.r );
        glBegin( GL_QUADS );
        glVertex3f( x,          y,        0.100 );
        glVertex3f( x+width*sx, y,        0.100 );
        glVertex3f( x+width*sx, y+a.h*sy, 0.100 );
        glVertex3f( x,          y+a.h*sy, 0.100 );
        glEnd();
    }

As you can see, the quad is well “below” where the text should be rendered. What am I doing wrong?

If I’m reading it correctly your vertex shader hard codes the z coordinate to 0.9.

Of the text, That is correct. It is a fixed overlay.

Ah, I thought that vertex shader was active when you render the quad? I guess you are saying it isn’t? Sorry, no idea then.

vertex shader is only active in the render text module. It will not be active when I draw the quad.

We can’t see any such thing, as we don’t know what the projection and model-view matrices contain. You show the quad’s Z coordinate in object space (i.e. the values passed to glVertex()) but the text’s Z coordinate in clip space (i.e. the value of gl_Position).

sorry, I haven’t changed the code for a while and forgot to include. Here is the projection and model view matrices I have defined:


                glMatrixMode(GL_PROJECTION);
                glLoadIdentity();
                glOrtho(-1., 1., -1., 1., -1., 1.);

                glMatrixMode(GL_MODELVIEW);
                glLoadIdentity();

I did this so I can easily place objects into a normalized depth field of -1.0 to 1.0.

[QUOTE=advorak;1277802]Here is the projection and model view matrices I have defined:


                glOrtho(-1., 1., -1., 1., -1., 1.);

[/QUOTE]
Did you overlook the fact that glOrtho() etc negate the Z coordinate? The above call results in a projection matrix of


  1  0  0  0 
  0  1  0  0 
  0  0 -1  0 
  0  0  0  1 

i.e. [x,y,z,w] is transformed to [x,y,-z,w].

With that matrix, your quads have clip-space Z coordinates of 0.0 and -0.1 (corresponding to depth values of 0.5 and 0.45 respectively) while your text has a clip-space Z coordinate of 0.9 (corresponding to a depth value of 0.95). If your depth function is GL_LESS or GL_LEQUAL, the quads will obscure the text.

A very dim bulb just went on in my head. I was equating model space with clip space and not applying the projection matrix correctly.

In my head, it makes sense that Z comes out of the screen. And if I want an object to be “in the back”, I give it a negative value. I should just be able to inverse the value of the vertex shader text Z position to a negative value and leave the objects in model space as they are.

Is that correct?

[QUOTE=advorak;1277823]In my head, it makes sense that Z comes out of the screen. And if I want an object to be “in the back”, I give it a negative value. I should just be able to inverse the value of the vertex shader text Z position to a negative value and leave the objects in model space as they are.

Is that correct?[/QUOTE]
Yes.

If you want to work directly in clip space with glVertex() etc, you can omit the glOrtho() call and just leave both the model-view and projection matrices as identity matrices.

Alternatively, if you want to have depth increasing as clip space Z decreases, you can use glDepthRange(1, 0). Or you can use glDepthFunc(GL_GREATER) (or GL_GEQUAL) to have objects with greater depth obscure those with lesser depth.

Conventionally, clip space and NDC have Z increasing away from the viewpoint (the initial settings are glDepthRange(0,1) and glDepthFunc(GL_LESS), meaning that fragments with greater NDC Z are obscured by fragments with lesser NDC Z), while eye space has Z increasing toward the viewpoint (glOrtho(), glFrustum(), gluOrtho2D() and gluPerspective() all create matrices which “flip” the direction of Z/W in the conversion from eye space to clip space).

But that can be changed by changing the matrices, or the depth range, or the depth-test function. Coordinates are just numbers; they “mean” whatever you choose to make them mean.