OpenGL 3D + 2D [SOLVED]

Whether you're a newbie or an experienced programmer, any questions, help, or just talk of any language will be welcomed here.

Moderator: Coders of Rage

Post Reply
User avatar
superLED
Chaos Rift Junior
Chaos Rift Junior
Posts: 303
Joined: Sun Nov 21, 2010 10:56 am
Current Project: Engine
Favorite Gaming Platforms: N64
Programming Language of Choice: C++, PHP
Location: Norway

OpenGL 3D + 2D [SOLVED]

Post 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)
Last edited by superLED on Tue May 15, 2012 4:02 pm, edited 3 times in total.
XianForce
Chaos Rift Devotee
Chaos Rift Devotee
Posts: 767
Joined: Wed Oct 29, 2008 8:36 pm

Re: OpenGL 3D + 2D

Post 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.
User avatar
superLED
Chaos Rift Junior
Chaos Rift Junior
Posts: 303
Joined: Sun Nov 21, 2010 10:56 am
Current Project: Engine
Favorite Gaming Platforms: N64
Programming Language of Choice: C++, PHP
Location: Norway

Re: OpenGL 3D + 2D

Post 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.
User avatar
superLED
Chaos Rift Junior
Chaos Rift Junior
Posts: 303
Joined: Sun Nov 21, 2010 10:56 am
Current Project: Engine
Favorite Gaming Platforms: N64
Programming Language of Choice: C++, PHP
Location: Norway

Re: OpenGL 3D + 2D

Post 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.
User avatar
Ginto8
ES Beta Backer
ES Beta Backer
Posts: 1064
Joined: Tue Jan 06, 2009 4:12 pm
Programming Language of Choice: C/C++, Java

Re: OpenGL 3D + 2D [SOLVED]

Post 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.
Quit procrastinating and make something awesome.
Ducky wrote:Give a man some wood, he'll be warm for the night. Put him on fire and he'll be warm for the rest of his life.
User avatar
superLED
Chaos Rift Junior
Chaos Rift Junior
Posts: 303
Joined: Sun Nov 21, 2010 10:56 am
Current Project: Engine
Favorite Gaming Platforms: N64
Programming Language of Choice: C++, PHP
Location: Norway

Re: OpenGL 3D + 2D [SOLVED]

Post 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?
User avatar
bbguimaraes
Chaos Rift Junior
Chaos Rift Junior
Posts: 294
Joined: Wed Apr 11, 2012 4:34 pm
Programming Language of Choice: c++
Location: Brazil
Contact:

Re: OpenGL 3D + 2D [SOLVED]

Post 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();
Post Reply