Orthographic Projection: Lessons Learned

Started by
8 comments, last by mitchbb 23 years, 6 months ago
Hi all, Those of you who read my preious post yesterday on this same subject know what a predicament I was in. I just though I''d just follow up and pass on what I learned. As it turns out, I was finally able to solve my problem with superimposing 2D text and interface over a 3D scene. Although I can proudly say that I managed to solve this, the help of the veterans here, especially Davepermen and Zedzeke got me started in the right direction Fellow newbies, what I''m about to write may have some errors or misconceptions. I don''t want to lead anyone astray. I would like to try to give back to the community here at least a little of what was given me Veterans, hope you''ll correct any mistakes I''ve made here The problem boiled down to 2 things basically. 1: some confusion on my part on how class constructors initialize objects, and 2: fundamental lack of understanding concerning the various transformations and their matrix stacks. I''ll repost the faulty code from yesterday here: GLvoid CInterface::DrawInterface() { glPushMatrix(); glLoadIdentity(); glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f); PrintText(180, 20, "OpenGL Text -%7.2f", txtcnt1); glPopMatrix(); } GLvoid CInterface:rintText(GLint x, GLint y, const char *fmt, ...) { char text[256]; va_list ap; if (fmt == NULL) return; va_start(ap, fmt); vsprintf(text, fmt, ap); va_end(ap); glTranslated(x,y,0); glListBase(fontset - 32); glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } The first thing I had to do was move my CInterface::SetData() (not shown here, sorry call out of CInterface''s constructor because it wasn''t being called at all. This is the function that initializes my fontset. I''m still not sure why this had to be done, because I''ve used my constructors to initialize other objects in a similar fashion without problems. Anyway once I did that, the text appeared to the screen but instead of stationary, it was zigzagging across the bottom of the screen. Almost as if it was being drawn to a different point with each rendering pass. The problem here of course was due to my misunderstadning of the transformation matrices. Originally, I had thought I could simply call PushMatrix() and PopMatrix() and everything would be hunky dorey. Not so! Davepermen pointed out that I needed to call glMatrixMode() to switch to the projection matrix at the front and the call it again at the back to switch back to modelview matrix. This defintely got me thinking on the right track. What I didn''t realize was that each transformation has it''s own seperate matrix stack. I had naively assumed that calling PushMatrix() and PopMatrix() applied to all the transformations. Instead, I found out that you have to call successive Push and PopMatrix() for each tranformation that you are working with. So, the final, fully functioning code is like this: GLvoid CInterface:rintText(const char *fmt, ...) { char text[256]; va_list ap; if (fmt == NULL) return; va_start(ap, fmt); vsprintf(text, fmt, ap); va_end(ap); glListBase(fontset - 32); glCallLists(strlen(text), GL_UNSIGNED_BYTE, text); } GLvoid CInterface::DrawInterface() //switch to 2D for drawing, then switch back to 3D { glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glColor3f(1.0f, 1.0f, 1.0f); glRasterPos2i(20,20); PrintText("OpenGL Text"); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW); } You''ll notice that switched from glTranslated() to glRasterPos2i() That was more a matter of taste than anything I guess. Anyway, I know I''ve taken up enough message space. Hope somebody found something useful here Brad
Advertisement
Wow, was that ever a long post and a LOT OF WRONG CODE!!! Actually, there''s nothing wrong with it, I''m just joking. It''s a good explination that will hopefully help a few people out... This goes for all of you people out there... Don''t limit your post size because you think it''s too lengthy, if your information is good, people will appreciate the effort.

S.
Glad to receive your blessing Strylinys

Actually I just discovered one more line of code to get it to function 100% correctly.

glTranslatef(0.0f, 0.0f, 1.0f);

needs to be inserted just before

glColor3f(1.0f, 1.0f, 1.0f);
glRasterPos2i(20,20);
PrintText("OpenGL Text");

That way, objects that get really close to your screen won''t mysteriously pass through the print. Just thought I''d clear that up before somebody busted me
You should have kept glTranslatef(), glRasterPos() is a bad bad thing to use. You should always use glTranslatef() when you need to position things on the screen. A thing you should be doing is preserving your OpenGL states. If you have lighting enabled in your scene or some odd blending modes your text will get messed up. It''s best to get the current GL modes, set your text mode and render and then restore the GL modes. The objects passing through text seems odd, you should try drawing the text after your world and also turning off depth testing. Your constructor problem is because your object is probably being created before you have an OpenGL context, if you don''t have a context your OpenGL calls won''t work. Since your using display lists I am assuming you setup the lists in the constructor.

Nate Miller
http://nate.scuzzy.net
Thanks, Nate. I will take that advice to heart. It actually clears up a number points on overall theory that I was wondering about.
u sure this is right
glOrtho(0.0f, 640, 480, 0.0f, -1.0f, 1.0f);
it could work though im not saying it doesnt but it seems a bit cockeyed
i know, why it doesnt work with the constructor (i mailed it to you, but my mailprogram did, how its looking, problems):
its, because you use a opengl-func in your constructor (something like wglCreateBmpFromText or so.., cant remember from brain), but your object MyInterface is Global, that means, the constuctor is callt at the start of the programm (even before winmain, perhaps, but surely ..) in front of CreateGLWindow, and that means you use an openGL-func before initializeing your openGL, and that doesnt work (had the same problem, so I thought at this)

thats why you have to use SetData().. perhaps you dont create real objects, but Pointers and inizialize them after CreateGLWindow

CInterface* MyInterface
WinMain()
{
CreateGLWindow();
MyInterface=new CInterface;
while(no quit)
{
render();
}
delete MyInterface;
DestroyGLWindow();
}

..something like this

or
you dont create your values global(for example in CSzene (as pointers), that could be best(could be give some complications, I know.. but I think its bether to do so..)

we wanna play, not watch the pictures

If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

OK, I looked at the glOrtho() function again. No, I''m not sure if that''s the *correct* way to implement it, but yes it does work... at least in the case of my program. *shrugs* I just copied the parameter settings from what NeHe had used in his tut on lines, AA, AI, and Ortho.

Zedzeke, I agree it does look a little odd. (I assume we''re talking about the same thing) I thought the near and far parameters were backward but, it does appear to work fine this way. What about gluOrtho2d though? Is that a desireable alternative?

Also, Nate mentioned that I didn''t need to translate 1 unit on the z axis. Nate, is turning depth testing off and then back on again is more efficient than gltranslatef()? BTW, my text is the last thing to render and still need glTranslatef().

Davepermen,
Yep, you hit the nail on the head alright. Nate pointed that out as well. Hehe, so many details I''m overlooking You mention though at the end about having pointers to (class objects?)declared from within CScene. It makes sense and it''s actually what I''d like to do. There''s still a few rules on scope I need to get straightened out.

Thanks again ya''ll for the input
nice I have had helped you at the end..

I hope I could see the project, when its finished sometimes, mitchbb (you could see ours, too)

we wanna play, not watch the pictures

If that's not the help you're after then you're going to have to explain the problem better than what you have. - joanusdmentia

My Page davepermen.net | My Music on Bandcamp and on Soundcloud

Davepermen,
That''s an offer I can''t refuse!
Actually, my boss is wanting me to have some kind of initial prototype ready in November. I don''t know how much I''ll have done by then, but I''ll keep you posted on my progress

This topic is closed to new replies.

Advertisement