Jump to content
  • Advertisement
Sign in to follow this  
eggmatters

OpenGL Need some basic undertanding of OpenGL state mechanics

This topic is 2859 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts

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.)


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.

Share this post


Link to post
Share on other sites
Advertisement
Hi,


at a quick glance you're calling glClear twice each frame, once for the terrain and once for the text. This means that the terrain never gets drawn if you draw the text after it. It only needs to be called once each frame.

Hope that helps.

Share this post


Link to post
Share on other sites
I certainly wish it did friend but commenting out the glClear() call in the drawText() routine did not change the behavior I described. This is why I'm at such a loss with how states are handled. My assumption is: I compile a list object that draws something in the modelview. before I draw that, I gather information about that and switch to orhtographic and draw the "text" data. I then switch back and perform necessary translations on the modelview data and draw that. There must be something else I'm missing.

Share this post


Link to post
Share on other sites
Can you confirm that when you comment out glPrint the terrain is displayed with a texture?
If not it might be a good idea to comment things out in your text drawing function until the terrain is drawn with a texture so that you can narrow it down to figure out exactly what state is causing the terrain texture not to be drawn.

Share this post


Link to post
Share on other sites
Wait, sorry about that. I commented out the glClear in the terrain rendering routine as well. That helped but the quads textures are still in black. If you see any glaring missteps in my code, let me know, but I will see if I can get those textures to render.

Share this post


Link to post
Share on other sites
@stevenmarky: Apparantly, the texture is rendered, but the color I specify for the text overrides everything and also colors the quads that are textured. I tested this by changing the rgb for the text in the drawText() routine from 0 ,0,0 to 0,5,0 and saw my textures but with a massively green hue to them.
Thanks to JackTheRapper for pointing out a major crux of my issue though. If I or anybody else can figure out why the drawText() routine is coloring my landscape and not just the text, then we can close this thing, call it solved and go home. Thanks for the insight. Much appreciated!!!

Share this post


Link to post
Share on other sites
Now that I think about it, when one calls glColor3f() it is outside of any matrix is it not? I am basically stating a global color for rendering the next thing on the stack - which is my modelview - the rendered terrain. So. . . what would I need to tell openGl "hey! apply this color to the rendered font in this context!"?

Share this post


Link to post
Share on other sites
The glColor functions are independent of the matrix stack and any scope you are in, I think your solution is to set the color back to white after drawing your text.

e.g. glColor3f(1.0f, 1.0f, 1.0f);

This would work because the color of the texel being drawn is multiplied by the color of the vertex.

Share this post


Link to post
Share on other sites
Whew, that is correct. I remember reading that after I posted this response. Thanks for everybody's help and advice. I think we can mark this "Solved" (For now, I just removed the color call altogether and the text is rendered with the ground texture. Which will do for now.)

Thanks!

Share this post


Link to post
Share on other sites
Sign in to follow this  

  • Advertisement
×

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!