A gluProject Problem

Started by
5 comments, last by Koshums 20 years, 6 months ago
I''m working on a shoot ''em up game where you control a tank. I would like to have the tank''s turret rotated so that it always faces in the direction of a mouse cursor. The tank is drawn from a top-down view with perspective projection, and the mouse cursor is just a textured poly rendered in ortho mode afterwards. I have it all worked out in theory: Use gluProject to get the screen coords of the center of the tank, and then calculate the necessary angle of rotation using arctan from the screen coords of the 2 objects (tank and crosshair). But when I coded it I found that it doesn''t work as I expected. (Sorry for not explaining what happens exactly. I can post more details when I get home from work) I''m not sure I fully understand what gluProject is doing (I have searched the forums but couldn''t find what I''m looking for), so here are a couple of questions that might help me if they were answered: 1) Ortho mode for the mouse cursor is set up to be the same size as the screen resolution (1024x768 in this case). So does that mean the final screen coords will be in the range (0,0) to (1024,768)? i.e. Can I just take the cursor''s coords at render time and use them in the arctan calculation, or do I have to gluProject those too? 2) Similar question for the tank - What will the range of the screen coords be after gluProject? (0,0) for the top left corner to (1024,768) in the bottom right? Thanks for any help. I can post some code/screenshots when I get home from work if that would help to explain what I''m trying to do.
Advertisement
gluProject projects a point in the scene to a screen coordinate. If you are using the Win32 API you might get confused though, since OpenGL regards the lower left corner of the screen as origo and positive y direction upward, while in Win32 origo is in the upper left corner with positive y direction down.

Also, if you are not running full screen you must make sure you get the cusor position relative to the window you draw in, not the screen. If you use Win32:
case WM_LBUTTONDOWN:{	POINTS mpos = MAKEPOINTS(lParam);	oglmposx = mpos.x;	oglmposy = yres - mpos.y;} 
Thanks for your reply. I am using directX for input and keeping track of the x,y coords in my program, so I don't think that's my problem.

This is what I'm trying to achieve (please excuse the polygon art!):



Here's my code at the moment:

	GLdouble mouseScreen[3];	GLdouble tankScreen[3];		// get mouse screen coords	glMatrixMode(GL_PROJECTION);	glPushMatrix();		glLoadIdentity();		glOrtho(0, 1024, 768, 0, 0, 1 );		GetScreenCoords(crosshair->GetX(), crosshair->GetY(), 0.0, mouseScreen[0], mouseScreen[1], mouseScreen[2]);	glPopMatrix();	glMatrixMode(GL_MODELVIEW);	// get tank screen coords	GetScreenCoords(_xPos, 0.0, _zPos, tankScreen[0], tankScreen[1], tankScreen[2]);	// calculate turret rotation angle	GLdouble dx = mouseScreen[0] - tankScreen[0];	GLdouble dy = mouseScreen[1] - tankScreen[1];	_turretRotation = RAD2DEG(atan2(-dy, dx)) - 90.0; 


and elsewhere in the code:

   int GetScreenCoords(GLdouble x, GLdouble y, GLdouble z, GLdouble &sx, GLdouble &sy, GLdouble &sz){	GLint viewport[4];	GLdouble mvmatrix[16],projmatrix[16]; 	glGetIntegerv(GL_VIEWPORT, viewport);	glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);	glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);	return gluProject(x, y, z, mvmatrix, projmatrix, viewport, &sx, &sy, &sz);} 


When I run the program, the tank's turret seems to point towards the position of the mouse cursor relative to the top-left of the screen, but only when the tank is in the top half of the screen. When it's in the bottom half, the turret faces in exactly the opposite direction.

For example, when I position the cursor in the top-middle of the screen, the turret faces directly to the right when the tank is in the top half of the screen, and to the left when it's in the bottom half.

Any ideas as to what I'm doing wrong?

[edited by - Koshums on October 8, 2003 4:23:34 PM]

[edited by - Koshums on October 8, 2003 4:25:26 PM]

[edited by - Koshums on October 8, 2003 4:28:47 PM]
The math looks ok to me. It could be the RAD2DEG maybe? (deg = 180*rad/PI).

One thing, why use gluProject on crosshair->GetX/Y() when they are already in screen coordinates?
Here''s my RAD2DEG:

#define RAD2DEG(x) ( (float)(x) * (float)(180.0f / PI) ) 


I wasn''t sure if I had to gluProject the crosshair. Exactly the same thing happens if I just use GetX/Y() straight in the trig calculation.

Any other suggestions? Is this even the right way of achieving the effect?
I did the math on paper and I also got arctan(y/x) (only you got -y but that depends on your how your coordinate system is placed)

An alternate way would be to use glPushMatrix and gluLookAt before drawing the turret and glPopMatrix after. And make it so that the camera looks at the turret, while the up direction is in the cursor direction. (still have to use gluProject though, to get the dx and dy)

[edited by - Jesper T on October 10, 2003 5:38:16 PM]
I''ve finally found the problem!

I simply forgot to push/pop the modelview matrix when drawing the crosshair. It works fine now!
Hehe, now I feel stupid

Thanks for the help Jesper, I appreciate it!

This topic is closed to new replies.

Advertisement