Original Post
Hi all,
I apologize in advance for the ambiguity of the question and the way I'm about to present it. I am trying to create a head's up display in a simple font displaying debugging information which will track x, z and y transformations. I can get that to work, but the scene rendering loses it's texture and is painted in the same color as the text (black). Also, the desired debugging text is not rendered.
If I comment out the scene rendering stuff, the text will render and does what it should. If I comment out the text drawing routine, the scene renders fine. I would like to do both. Not just for debugging but any game needs HUD's to display player / game status etc.
For kicks, I'm using SDL to manage my window. I have a routine which renders an landscape environment from GL_QUADS, with an applied texture, another which does translations on the MODELVIEW_MATRIX based on user input. I have a separate routine which switches to orthographic projection and prints out respective x, y, z positions plus rotation angles in the upper left hand corner of the screen. When I call the text rendering routine, I push the MODELVIEW matrix, do the orthographic rendering, and then pop it back. I've investigated this to some extent and am basing my assumptions about what should be happening based on several tutorials, namely swift and nehe. The font rendering mostly came from NeHe but I adapted it for SDL.
Here is some sample code:
routine, void setupOpengl(). This sets up the perspective, viewport and applies texture (I have lighting and fog etc. But I'm trying to reduce as much noise as possible to solve this.)
the preceding code was called from main which then calls the a buildTerrain() function which renders the terrain of quads. This is compiled as a list since it is only computed once:
Yah so my rendering and translation occurs in a routine which loops continuously (until esc key is pressed) which renders the list defined above and my text drawing routine (or at least, is supposed to.)
So the orthographic stuff to draw the text, called from above:
So, what am I missing here. It seems that I have a great lack of understanding of the state mechanics of openGL. Do I need to also preserve state for the textures matrix? (it prints my quads as black when they're drawn.) How is it that I can either get the list to compile or the drawText() routine to work but not both? What do I need to do to preserve state for each of these different routines? Is it costly? Is it an SDL issue? I have a pretty good idea that it is basically arising from mistaken assumptions I'm making about how openGL operates - how it preserves state and / or what state conditions it preserves. I need one of those "aha" moments when it will all become clear to me.
Thanks for your time with such a dysfunctional issue.
I apologize in advance for the ambiguity of the question and the way I'm about to present it. I am trying to create a head's up display in a simple font displaying debugging information which will track x, z and y transformations. I can get that to work, but the scene rendering loses it's texture and is painted in the same color as the text (black). Also, the desired debugging text is not rendered.
If I comment out the scene rendering stuff, the text will render and does what it should. If I comment out the text drawing routine, the scene renders fine. I would like to do both. Not just for debugging but any game needs HUD's to display player / game status etc.
For kicks, I'm using SDL to manage my window. I have a routine which renders an landscape environment from GL_QUADS, with an applied texture, another which does translations on the MODELVIEW_MATRIX based on user input. I have a separate routine which switches to orthographic projection and prints out respective x, y, z positions plus rotation angles in the upper left hand corner of the screen. When I call the text rendering routine, I push the MODELVIEW matrix, do the orthographic rendering, and then pop it back. I've investigated this to some extent and am basing my assumptions about what should be happening based on several tutorials, namely swift and nehe. The font rendering mostly came from NeHe but I adapted it for SDL.
Here is some sample code:
routine, void setupOpengl(). This sets up the perspective, viewport and applies texture (I have lighting and fog etc. But I'm trying to reduce as much noise as possible to solve this.)
void setupOpengl() { //sky blue color for background const float bgColor[4] = {.7, .8, 1.0, 1.0}; glClearColor(bgColor[0], bgColor[1], bgColor[2], bgColor[3]); //basic screen setup. width and height provided by #defines for the screen size sdl has rendered. glMatrixMode(GL_PROJECTION); glViewport(0, 0, width, height); glEnable(GL_DEPTH_TEST); gluPerspective(45, (float)width/height, .2, 80); //adapted from a nehe lesson for sdl. BuildFont(); glShadeModel(GL_SMOOTH); glMatrixMode(GL_MODELVIEW); //setup texture: glEnable(GL_TEXTURE_2D); myTexture = loadTexture("textures/grassb512.bmp", false);}the preceding code was called from main which then calls the a buildTerrain() function which renders the terrain of quads. This is compiled as a list since it is only computed once:
void buildTerrain(){//here I set up a 2d array of x and y coordinates containing randomly generated values which are heights. I then apply those to my GL_QUADS vertices: glNewList(1, GL_COMPILE); // Terrain rendering routine goes here glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); //This is the texture loaded from setupOpenGL. glBindTexture(GL_TEXTURE_2D, myTexture); glBegin(GL_QUADS); for(int x = 0; x<tWidth-1; x++){ for(int y = 0; y<tHeight-1; y++){ glTexCoord2f(0.0f, 0.0f); glVertex3f(x+0, terrain[x+0][y+1], y+1); glTexCoord2f(1.0f, 0.0f); glVertex3f(x+1, terrain[x+1][y+1], y+1); glTexCoord2f(1.0f, 1.0f); glVertex3f(x+1, terrain[x+1][y+0], y+0); glTexCoord2f(0.0f, 1.0f); glVertex3f(x+0, terrain[x+0][y+0], y+0); } } glEnd(); glEndList(); }Yah so my rendering and translation occurs in a routine which loops continuously (until esc key is pressed) which renders the list defined above and my text drawing routine (or at least, is supposed to.)
void mainLoop() { while(true) { //assign values based on user input: processEvents(); //values derived from event handler y_input += y_pos; x_input += x_pos; z_input += z_pos; cw_input += x_rot; ccw_input += y_rot; // Graphical commands... glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); //routine to draw above values in the upper left hand corner of the screen. drawText(); //perform our necessary translations glRotatef(cw_input, 0.0, 1.0, 0.0); glRotatef(ccw_input, 0.0, -1.0, 0.0); glTranslatef(-tWidth/2, -12, -tHeight/2); glTranslatef(x_input, y_input, z_input); glCallList(1); // <--(Render terrain from list) described above. //I am not sure at all what this does: SDL_GL_SwapBuffers(); }}So the orthographic stuff to draw the text, called from above:
void drawText() { //here we are rendering something in a different matrix: glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_PROJECTION); //this is the sticky point for me. I assume I'm pushing necessary matrix data for the ortho stuff, drawing it and reverting back to the former state (all of the stuff above, when I'm finished. glPushMatrix(); glLoadIdentity (); gluOrtho2D(0, width, 0, height); //select the 2d viewport. glScalef(1, -1, 1); //flip everthing upside down. glTranslatef(0, height, 0); //print my font in black glColor3f(0.0f,0.0f,0.0f); //glRasterPos2f(0.0, -height - 5); // prints it at the bottom. //using glRasterPos2f from Nehe tutorial glRasterPos2f(0.0, -height - (height - 15)); glPrint("x_input - %4.2f", x_input); //and so on. This is one line out of many. //the swift tutorial claims to put this line here: glMatrixMode(GL_PROJECTION); //now I want to go back to rendering all of the stuff I was doing earlier: glPopMatrix(); glMatrixMode(GL_MODELVIEW); }So, what am I missing here. It seems that I have a great lack of understanding of the state mechanics of openGL. Do I need to also preserve state for the textures matrix? (it prints my quads as black when they're drawn.) How is it that I can either get the list to compile or the drawText() routine to work but not both? What do I need to do to preserve state for each of these different routines? Is it costly? Is it an SDL issue? I have a pretty good idea that it is basically arising from mistaken assumptions I'm making about how openGL operates - how it preserves state and / or what state conditions it preserves. I need one of those "aha" moments when it will all become clear to me.
Thanks for your time with such a dysfunctional issue.