Page 1 of 1
OpenGL 3D + 2D [SOLVED]
Posted: Tue May 15, 2012 12:55 pm
by superLED
Hi there, folks!
I am currently making my first game in OpenGL (c++). I am able to make some 2D stuff and 3D stuff. But not together. I mean, having a 3D game with 2D elements glued to the screen (HUD/GUI).
Somehow, only one of them (2D or 3D) works at a given time.
I'll show you my drawing function:
Code: Select all
Window::clear();
// 3D
glPushMatrix();
glLoadIdentity();
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW);
camera.updateCamera();
for(unsigned int i = 0; i < cubes.size(); i++) {
cubes.at(i)->draw();
}
for(unsigned int i = 0; i < floor.size(); i++) {
floor.at(i)->draw();
}
player->draw();
glPopMatrix();
// 2D
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, Window::getWidth(), Window::getHeight(), 0.0f, -1.0f, 1.0f);
glDisable(GL_DEPTH_TEST);
//glMatrixMode(GL_PROJECTION); // <---- Removing this line = 3D, un-comment this line = 2D
Menu::draw();
glPopMatrix();
Window::flipScreen();
This is how I'm switching between 2D and 3D. If I'm viewing it in 3D, the 2D stuff is not to be seen. When viewing in 2D, only the 2D stuff shows, and the rest is completely black.
Do you need to see more code to be able to help me out here?
(Yeah, I guess I don't need those glPopMatrix and glPushMatrix functions, and some other stuff, but I am not really sure when to use them, as I am not that into OpenGL yet)
Re: OpenGL 3D + 2D
Posted: Tue May 15, 2012 2:19 pm
by XianForce
I'm not really experienced with OpenGL, but I did a few small things with it.
As far as I know, you'll need a separate 2D and 3D drawing function. With your 3D drawing function, just set the matrix mode to perspective and for 2D set it to projection. (Are you sure it's projection though? I thought I remember it being Ortho? It's been a while, so I'm real rusty).
Anyways, you'll probably want to also write functions that draw all of your 3D stuff first, then all of your 2d stuff on top. That way you only change the matrix mode 2x per frame, rather than going back and forth.
Re: OpenGL 3D + 2D
Posted: Tue May 15, 2012 3:24 pm
by superLED
XianForce wrote:I'm not really experienced with OpenGL, but I did a few small things with it.
As far as I know, you'll need a separate 2D and 3D drawing function. With your 3D drawing function, just set the matrix mode to perspective and for 2D set it to projection. (Are you sure it's projection though? I thought I remember it being Ortho? It's been a while, so I'm real rusty).
Anyways, you'll probably want to also write functions that draw all of your 3D stuff first, then all of your 2d stuff on top. That way you only change the matrix mode 2x per frame, rather than going back and forth.
Thanks for your response!
Yes, I am keeping 3D stuff and 2D stuff separated, so I'm switching only 2 times per frame (one for 2D, second for 3D).
I'm using glOrtho for the 2D stuff, and gluPerspective for 3D, in chase that matters.
I will check more into the projection stuff and see what I can figure out.
Re: OpenGL 3D + 2D
Posted: Tue May 15, 2012 3:40 pm
by superLED
Okay, I solved it. It was a problem with the MatrixModes. I gotta learn more in depth how these works.
This is how I draw stuff:
Code: Select all
Window::clear();
// 3D
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
gluPerspective(80, Window::getWidth()/Window::getHeight(), 1.0, 200.0);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
camera.updateCamera();
for(unsigned int i = 0; i < cubes.size(); i++) {
cubes.at(i)->draw();
}
for(unsigned int i = 0; i < floor.size(); i++) {
floor.at(i)->draw();
}
face->draw();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
// 2D
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0.0f, Window::getWidth(), Window::getHeight(), 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
Menu::draw();
glPopMatrix();
glMatrixMode(GL_PROJECTION);
glPopMatrix();
Window::flipScreen();
I cannot explain to you a person who would have the same issue, how this works. I have to study it myself to actually understand the magic behind it.
Re: OpenGL 3D + 2D [SOLVED]
Posted: Wed May 16, 2012 10:18 am
by Ginto8
It's a pretty simple process, actually; all GL matrix operations act on the currently selected matrix. In your original 3d code:
Code: Select all
glPushMatrix(); // pushes to the current matrix stack. Projection? ModelView? Who knows?
glLoadIdentity(); // loads identity, who knows which matrix it acts on?
glEnable(GL_DEPTH_TEST);
glMatrixMode(GL_MODELVIEW); // switches to ModelView, which has had nothing done to it
camera.updateCamera(); // presumably modifies the ModelView matrix
// this code might do stuff with ModelView
for(unsigned int i = 0; i < cubes.size(); i++) {
cubes.at(i)->draw();
}
for(unsigned int i = 0; i < floor.size(); i++) {
floor.at(i)->draw();
}
player->draw();
glPopMatrix(); // pop from the top of the ModelView stack (which might not have been pushed onto)
And your 2d code:
Code: Select all
glLoadIdentity(); // Might be on projection, might be on modelview
glOrtho(0.0f, Window::getWidth(), Window::getHeight(), 0.0f, -1.0f, 1.0f); // if it's on modelview, it would work weirdly
glDisable(GL_DEPTH_TEST);
//glMatrixMode(GL_PROJECTION); // <---- Removing this line = 3D, un-comment this line = 2D
Menu::draw();
glPopMatrix();
So you're just working with the wrong matrices when doing stuff.
Re: OpenGL 3D + 2D [SOLVED]
Posted: Wed May 16, 2012 10:28 am
by superLED
Oh, I think I actually understand that. Thanks for the insight.
When going into Projection, you are setting up/modifying the scene, and when going into Modelview, you are actually drawing on the screen?
Re: OpenGL 3D + 2D [SOLVED]
Posted: Wed May 16, 2012 2:03 pm
by bbguimaraes
By the way, the great OpenGL book is freely available online:
http://www.glprogramming.com/red
On Chapter 3, it explains how projection transformations work, even with code examples. But basically, what you need to know is: model/view matrix is used to setup the scene. Put your objects is place, scale them, position the "camera", etc. You may say (for now) that that's where your "rendering" is done, because it is where you specify your objects' vertices.
Projection matrix is used to setup the... projection.
Projections have two main types: orthogonal (or parallel) and perspective. Parallel projections are viewed as a kind of floor plan, where all the angles are preserved (parallel lines remain parallel). Perspective is how we see the world: with parallel lines eventually intersecting on infinity (like railroad tracks in the distance, that seem to intersect on the horizon).
I once saw a video on this forum showing the difference between them... Here it is:
Click here to see the hidden message (It might contain spoilers)
But just to finish this already long post, the order you do thigs is (almost) always like this:
Code: Select all
// Set up projection.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Either one of the lines below:
gluPerspective(/*...*/);
gluOrtho2D(/*...*/);
// Set up model/view.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Draw your scene.
glRectf(0.0f, 0.0f, 1.0f, 1.0f);
If you need a 3D view with a 2D view on top, you use this code, removing the gluOrtho2D call, and draw your 3D scene. Then use the same code again, removing the gluPerspective call, and draw your 2D scene. Just for completion:
Click here to see the hidden message (It might contain spoilers)
Code: Select all
// Set up 3D projection.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(/*...*/);
// Set up model/view.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Draw your scene.
draw3DScene();
// Set up 2D projection.
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluOrtho2D(/*...*/);
// Set up model/view.
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Draw 2D scene.
drawHUD();