PDA

View Full Version : newbie question:



newsb
11-29-2011, 03:49 PM
Dear all

I have some code, giving a 3D world where I can move around. I then want to print some things out (like current xyz-coordinates etc), so I have a printText function:




void printText(string this_string,
GLfloat xpos, GLfloat ypos)
{
const char* charWritten = this_string.c_str();
glRasterPos2f(xpos, ypos);
int len = (int) strlen(charWritten);
for (int i = 0; i < len; i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, charWritten[i]);
}
}


I use it like this:


void RenderScene(void)
{
glClear(...)
glPushMatrix();
...
...
// should I use something like gluOrtho2D ?
glMatrixMode(GL_MODELVIEW)

// print stuff of calculations like FPS etc...
printText( someStream.str(), xcoord, ycoord); // <=== HERE I USE IT
// drawing objects...
}



My problem:

Sometimes I move / rotate the world and admitted - I don't 100% know what I'm doing, when I'm messing around with modelview and perspective matrices. The point is that sometimes my text (printed with the above function) is *ALSO* moved/rotated/translated around (but I only want the objects to be rotated/moved, not this text - I would like the text to the "static" on top of the rotated world).

So: I want instead is that the text stays where it is forever - and the world is moving in the "background"...

Example: In the upper left corner, perhaps I print the current FPS, frames per second. This FPS-text should be in the exact same position no matter how I orient/rotate the whole world...

Can you please explain, what it is that I should be careful of and what it is that could be my problem? If I have to, I'll make a compilable example, but if you can come with some qualified answers then maybe I'll understand what to do without having to create a compilable (minimal) example for you... Thank you.

aqnuep
11-29-2011, 03:58 PM
1. Select the projection matrix using glMatrixMode(GL_PROJECTION).
2. Load an dentity matrix into it with glLoadIdentity().
3. Set an orthogonal projection matrix by using either glOrtho or gluOrtho2D, whatever you prefer.
4. Select the modelview matrix using glMatrixMode(GL_MODELVIEW).
5. Load an dentity matrix into it with glLoadIdentity().
6. Place your text properly based on the orthogonal projection you've set up earlier.

Be sure to save the previous state of the matrices e.g. using the matrix stack (glPushMatrix/glPopMatrix) so that you don't mess up the rest of the rendering.

newsb
11-30-2011, 03:58 AM
Hi aqnuep - Thanks a lot for your comments/advice!

I'll try it when I get back home from work (in the evening today). Just to be sure, I increase my chance of success: This is the structure you say I should use?:



void RenderScene(void)
{
glClear(...)
glPushMatrix();
...
...
// 1. Select the projection matrix using glMatrixMode(GL_PROJECTION).

// 2. Load an identity matrix into it with glLoadIdentity().
glLoadIdentity()

// 3. Set an orthogonal projection matrix by using either glOrtho or gluOrtho2D...
// (I'll look at that at home and maybe google for code
// pieces if I get into problems...)

// 4. Select the modelview matrix using glMatrixMode(GL_MODELVIEW).
glMatrixMode(GL_MODELVIEW)
// I suppose, this is where I draw my objects??

// 5. Load an dentity matrix into it with glLoadIdentity().
glLoadIdentity()

// 6. Place text properly based on the orthogonal projection you've set up earlier.
printText( someStream.str(), xcoord, ycoord); // <=== HERE I USE IT
// I suppose by using glLoadIdentity(), just before
// printText-function call, I will see no effect of any kind
// of world rotation / gluperspective stuff - that's great!

}


I'll try to put this together tonight, if the above "recipe" is correct... I might need a bit of help, though - and will write back the status of the "project"...

newsb
11-30-2011, 04:10 PM
Ok, it was not much I got to work on. I think I succeeded, but only because I was very lucky to find some code on google:



void printText(string this_string,
GLfloat xpos, GLfloat ypos)
{
const char* charWritten = this_string.c_str();
glRasterPos2f(xpos, ypos);
int len = (int) strlen(charWritten);

glMatrixMode(GL_PROJECTION);
glPushMatrix(); // ----------------------------- PUSH PROJECTION MATRIX
glLoadIdentity(); // reset projection matrix - it is now changed...
glOrtho(0, 1, 0, 1, -1.0f, 1.0f); // and modified again

glMatrixMode(GL_MODELVIEW);

glPushMatrix(); // <--------------------------- PUSH MODELVIEW MATRIX
glLoadIdentity(); // clear modelview matrix
glPushAttrib(GL_DEPTH_TEST); // <---------------- PUSH ATTRIB (DEPTH TEST)
glDisable(GL_DEPTH_TEST); // overwrite anything (=no depth test)...
glRasterPos2f(xpos,ypos);
for (int i = 0; i < len; i++)
{
glutBitmapCharacter(GLUT_BITMAP_TIMES_ROMAN_24, charWritten[i]);
//glutBitmapCharacter(GLUT_BITMAP_9_BY_15, charWritten[i]);
}
glPopAttrib(); // <------------------- POP ATTRIB (MODELVIEW CHANGES BACK)

glMatrixMode(GL_MODELVIEW);
glPopMatrix(); // <--------------------------- POP MODELVIEW MATRIX

glMatrixMode(GL_PROJECTION);
glPopMatrix(); // <--------------------------- POP PROJECTION MATRIX
}





Question:

1) Just look at the last 4 lines - is it ok that I pop the modelview matrix before the projection matrix? Because the code I found on google popped the projection matrix first, then the modelview.

Since the projection matrix is pushed first, then the modelview, I pop the modelview first and then the projection. Am I right? I don't understand why the google-code did it the other way around... ?


2) Another really easy newbie question: Why should I print text out to the screen, as the last thing I do (*AFTER* drawing the world)? Why does it make a difference?

I think it works better to print out the text in the end, I just don't understand why...

BionicBytes
12-01-2011, 04:03 AM
1) Just look at the last 4 lines - is it ok that I pop the modelview matrix before the projection matrix? Because the code I found on google popped the projection matrix first, then the modelview.

You essentially have done the following:



glMatrixMode(GL_PROJECTION);
glPushMatrix(); // ----------------------------- PUSH PROJECTION MATRIX

glMatrixMode(GL_MODELVIEW);
glPushMatrix(); // <--------------------------- PUSH MODELVIEW MATRIX


.....

glMatrixMode(GL_MODELVIEW);
glPopMatrix(); // <--------------------------- POP MODELVIEW MATRIX

glMatrixMode(GL_PROJECTION);
glPopMatrix(); // <--------------------------- POP PROJECTION MATRIX

OpenGL maintains a matrix stack, so the order in which you push and pop is important. The Last one pushed must the the first one poped. In your case, the last one pushed was for the ModelMatrix, so the first on poped must be for the ModelMatrix.

Notice how you have left the matrixmode in GL_Projection. Personally, I never leave the matrix in that way, I'd always ensure the last selected matrixmode is GL_MODELVIEW. Why? because all your rendering code assumes that is the case. For instance, we don't issue a glTranslatef command against the projection matrix.



I don't understand why the google-code did it the other way around... ? Who knows. It might just be a mistake.



2) Another really easy newbie question: Why should I print text out to the screen, as the last thing I do (*AFTER* drawing the world)? Why does it make a difference?
Because you want to 'overlay' your GUI/HUD/Debug text over the scene - you want it to be the top-most level so it's visible and not obscured by anything else. Typically printing text or GUI elements is done by blending, and that means drawing the blend layer ontop of what has already been drawn.
Of course, you can try the otherway round. You'll soon change your mind when you can't read the text as it gets overritten by the rendered scene.

newsb
12-01-2011, 07:20 PM
BionicBytes:

Thank you very much! It all makes sense to me now! I'm very grateful! :-)