glOrtho

Started by
6 comments, last by FlorianapoliS 20 years, 1 month ago
I''m making a little 3D Pong game in OpenGL atm, and I was planning on using glOrtho to draw the paddles because I can only get the position of the mouse in pixels, so this makes it far easier to work out where to draw the paddle. I can draw the paddle closest nps, but I want to draw the paddle in the distance. I was just wondering is there anyway to translate down the Z axis then change to ortho mode, so that you can draw in the distance? Or will glOrtho only draw when there is no translations on the Z axis? Cheers. Mark
Advertisement
glOrtho() can specify a near and far clip plane, so it is possible to translate the object along the Z axis. The problem is, orthographic projection does not perform perspective projection, so a paddle at Z=0 is drawn exactly the same size and location as a paddle at Z=10000. If you want distance, perspective, etc... you''ll have to abandon orthographic projection and go with perspective projection when drawing the far paddle. It is possible, of course, to mix orthographic and perspective modes (many game switch to ortho for drawing interface graphics and displays) but it may cause a strange appearance since the far paddle will be drawn perspective correct while the near one will not. You could perform some wierd math to scale the far paddle in size and movement--but why complicate things, when that is exactly the point of doing it full 3D and perspective correct?

The fact that the mouse is in pixels (screen coords) shouldn''t be a limiting factor. You can perform a simple glUnProject()call with the winZ parameter set to the Z value of the plane upon which your near paddle moves, to reverse-project the mouse coordinates to a point in the game world on that plane corresponding to the mouse location. You would probably get better results doing something like this than trying to mix ortho and perspective modes when drawing the game world. Google for glUnProject() to learn more of how it works.

Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller
Yeah I found the gluUnProject function when I was looking for different solutions. The winZ value is in screen co-ordinates as well I gather, so do I just use gluProject to find out the z co-ordinate of the paddle then just use that value in gluUnProject from now on? Or is there an easier way?

Cheers.
Mark
Yeah, that is what I would do. winZ maps from 0.0 on the near clip plane to 1.0 on the far clip plane. If you project the location of your paddle at some point and obtain the projected Z value, this gives you the Z value of the plane on which the paddle moves. Reverse projecting the mouse coordinates with this Z value gives a location on the paddle''s movement plane.

Glad you''re getting it figured out, and best of luck.


Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller
I have it sort of working. The cloest paddle is drawn at 8.0f, and the far paddle drawn at -8.0f. Then I use gluLookAt to pull back 17.0f along the Z Axis so you can see it all.

I used this:
	glLoadIdentity();	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);	glGetIntegerv(GL_VIEWPORT, viewPort);	gluProject(0.0f, 0.0f, 8.0f, modelMatrix, projMatrix, viewPort, &Test.x, &Test.y, &Test.z); 


to find winZ for the cloest paddle, and it returned 4.5f. Which I then put it to gluUnProject like this:
gluUnProject(MousePt.x, MousePt.y, 4.5f, modelMatrix, projMatrix, viewPort, &Test.x, &Test.y, &Test.z); 


However, gluUnProject is only returning X and Y object positions between -1 and 1. So as you move the mouse the paddle moves in the same direction but far slower than the mouse, I want to try and somehow get it to stay under the mouse? Here is my drawing code:

int DrawGLScene(GLvoid)									{	Vector3Dd Test;	int viewPort[4];	double modelMatrix[16];	double projMatrix[16];			glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear Screen And Depth Buffer	glLoadIdentity();	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);	glGetIntegerv(GL_VIEWPORT, viewPort);	gluUnProject(MousePt.x, MousePt.y, 4.5f, modelMatrix, projMatrix, viewPort, &Test.x, &Test.y, &Test.z);	gluPerspective(45.0f,(GLfloat)viewPort[2]/(GLfloat)viewPort[3],0.1f,100.0f);	gluLookAt( 0, 0, 17, 0, 0, 0, 0, 1, 0 );	DrawWorld(0.0f, 0.0f, 0.0f, 6.5f, 6.5f, 16.0f); //Draw Walls	DrawBox(bPong.pos.x, bPong.pos.y, bPong.pos.z, 0.3f, 0.3f, 0.3f); //Draw Ball		DrawBox((float)Test.x, (float)-Test.y, 8.0f, 1.0f, 1.0f, 1.0f);  //Draw Paddle		Enable2D();		glRasterPos2f(50.0f, 50.0f);		glPrint("test.x = %f test.y = %f test.z = %f", Test.x, Test.y, Test.z);	glRasterPos2f(50.0f, 100.0f);	glPrint("MousePt.x = %f, MousePt.y = %f", MousePt.x, MousePt.y);		Disable2D();			return TRUE;										// Everything Went OK} 


Cheers.
Mark
quote:
glLoadIdentity();	glGetDoublev(GL_MODELVIEW_MATRIX, modelMatrix);	glGetDoublev(GL_PROJECTION_MATRIX, projMatrix);	glGetIntegerv(GL_VIEWPORT, viewPort);	gluUnProject(MousePt.x, MousePt.y, 4.5f, modelMatrix, projMatrix, viewPort, &Test.x, &Test.y, &Test.z);	gluPerspective(45.0f,(GLfloat)viewPort[2]/(GLfloat)viewPort[3],0.1f,100.0f);	gluLookAt( 0, 0, 17, 0, 0, 0, 0, 1, 0 ); 


It looks like you are calling UnProject() before you set your projection and modelview matrices. In other words, you are reverse projecting using an identity matrix, which is roughly equivalent to multiplying by 1. This isn''t what you want. You want to do your projection and reverse projection after you set your projection (glPerspective()) and viewing direction (gluLookAt()). Un-projecting merely takes the current matrix/matrices and reverses their transformations to put a point into world space. If the matrices you use are identity, you get the exact same point back (with modifications, of course, since gluUnProject() will take screen coords in pixels and convert them to device coords in the range of -1 to 1 using the viewport dimensions before applying the inverse projection/modelview transforms).

Set your projection/view with glPerspective() and gluLookAt() before you use glGetDoublev() to read the matrices and Project or UnProject any points using those matrices.

Also, typically you may want to separate your projection and modelview matrices into their associated OpenGL state. This isn''t necessary of course, but it saves having to constantly rebuild your matrix every time you change state. You will want to select the PROJECTION_MATRIX before calling glPerspective() and the MODELVIEW_MATRIX before calling gluLookAt(). This way, if the viewpoint changes you can make the changes to the MODELVIEW_MATRIX without having to call glPerspective() to set up the projection matrix again. Functions such as glPerspective() and gluLookAt() operate on the currently selected matrix, rather than guessing and trying to operate on the matrix that makes most sense. Just a suggestion, but its the reason they implemented separate projection and modelview matrices in OpenGL state in the first place. Of course, for a game where you don''t change the viewpoint at all, it''s not a big deal.

Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller
Ahhh cheers, I''m trying to teach myself so my understanding of how everything works is a little sketchy, but I''m slowly getting there. I put my gluUnProject code after all the matrix work and it works like a treat now.

Cheers.
Mark
quote:Original post by FlorianapoliS
Ahhh cheers, I''m trying to teach myself so my understanding of how everything works is a little sketchy, but I''m slowly getting there. I put my gluUnProject code after all the matrix work and it works like a treat now.

Cheers.
Mark


Hey, I understand that. Glad it''s working for you. Good luck, and have fun.

Golem
Blender--The Gimp--Python--Lua--SDL
Nethack--Crawl--ADOM--Angband--Dungeondweller

This topic is closed to new replies.

Advertisement