PDA

View Full Version : inverse video for text



advorak
07-31-2015, 04:02 PM
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?

carsten neumann
07-31-2015, 05:23 PM
If I'm reading it correctly your vertex shader hard codes the z coordinate to 0.9.

advorak
07-31-2015, 06:08 PM
Of the text, That is correct. It is a fixed overlay.

carsten neumann
07-31-2015, 06:19 PM
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.

advorak
07-31-2015, 06:25 PM
vertex shader is only active in the render text module. It will not be active when I draw the quad.

GClements
08-01-2015, 01:42 AM
As you can see, the quad is well "below" where the text should be rendered.
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).

advorak
08-03-2015, 07:59 AM
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.

GClements
08-03-2015, 09:27 AM
Here is the projection and model view matrices I have defined:


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


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.

advorak
08-03-2015, 11:36 AM
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?

GClements
08-03-2015, 12:51 PM
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?
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.