Mouse coordinates to OpenGL coordinates?

Started by
13 comments, last by Explosive 20 years, 1 month ago
I have found a demo "smooth.zip" on http://www.opengl.org/resources/code/basics/more_samples/ .
It is written in c, and I was able to run it with Visual C++.
It uses the gluUnProject Feature.

Fanny
Advertisement
i am having the same type of problems, although the code on this thread has not helped. i am drawing a QUAD onto the screen using glVertex2f calls. 4 of them to make a rectangle against the screen. well i want to be able to check when the mouse pointer is over this rectangle i.e. or any portion of it.

glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
glBegin(GL_QUADS);
glColor3f(0,1.0, 1.0);
glVertex2i(0, 0);
glColor3f(0,1.0,1.0);
glVertex2i(0, -1);
glColor3f(0,0, 1);
glVertex2i(5, -1);
glColor3f(0, 0, 1);
glVertex2i(5, 0);
glEnd();

so i would like to know when the mouse pointer falls within the boundaries of this QUAD. this of course involves converting the screen coordinates to the the 2D windows coordinates?? please write if you have some insight, ive been racking my brain trying to get this to work.

heh
Back when I designing a space RTS game in 3d I ran into this problem, and solved it with peoples help.

I''ll drag out that old source in a bit but suffice it to say that this is how I remember it being done: (I might be wrong. . i''ll double check in a lil bit)

The entire scene is redrawn into another back buffer and instead of drawing a texture onto the polygon/quad, I drew a single colored polygon with the color being the index of the object.

Say we had ships 1, 2 and 3. There was a function in GL to tell you the RGB value of a pixel on that back buffer, and ship 1 was painted the value of 1,0,0.

I might not be right, I think in fact I may have used gluUnproject and I''ll dig that old CD out right now to straighten this out.
Here's the code. Apparently, I did use gluProject. Unfortunately, I have just about completely forgot how I did it. It was about 3 years go. This code works, though, as I was just testing the demo out.

void CheckClick(){    	// CHECK SELETION	double modelMatrix[16];	double projMatrix[16];	GLint viewport[4];	glLoadIdentity();	RenderCamera();	double sx1,sy1,sz1;	double sx,sy,sz;	bool renderhit = false;	//int selship;	glGetDoublev(GL_MODELVIEW_MATRIX,modelMatrix);    glGetDoublev(GL_PROJECTION_MATRIX,projMatrix);    glGetIntegerv(GL_VIEWPORT,viewport); 	// clear all selected		for (int curship = 0; curship < numships; curship++)	{		sx = craft[curship].x;		sy = craft[curship].y;		sz = craft[curship].z;        gluProject(sx,sy,sz, modelMatrix, projMatrix, viewport, &sx1, &sy1, &sz1);		sy1=(480-sy1);        		// compare sh and mouse to see if selected		if (mousex>sx1-90)		{			if(mousex<sx1+90)			{				if(mousey>sy1-90)				{					if(mousey<sy1+90)					{							for (int cship = 0; cship<numships; cship++)							{								selship[cship]=false;							}							renderhit=true;						    selship[curship]=true;							Mcamera.target=curship;														Mcamera.ctargetstep=1;																			    Mcamera.cx=(ship[Mcamera.target].x-Mcamera.x)/10;							Mcamera.cy=(ship[Mcamera.target].y-Mcamera.y)/10;							Mcamera.cz=(ship[Mcamera.target].z-Mcamera.z)/10;					        					}				}			}		}						}		if (mouseclk & MK_LBUTTON)	{	if (renderhit)		{			sprintf(str3, "x: %f y: %f ship#: %i", mousex, mousey, selship);			sprintf(str4, "ship x: %f y: %f z: %f", sx1, sy1, sz1);		}	if (!renderhit)		{			sprintf(str3, "");			sprintf(str4, "");		}	}}


Actually, after taking a second look, it looks as though the routine takes the current matrixes, uses gluProject to figure out the current 2d screen coordinate for the given 3d coordinate from the ship array. From that, it's easy enough to compare the coordinates with the mouse coordinates which should be known.

I think i might have cannibalized some code from a NEHE tutorial or something to derive the mouse screen coords.

Ok, I've also dragged out that subroutine out of my code to make sure you have everything. I'm pretty sure this is out of a NEHE tut. The WndProc routine is probably actually in your program, actually. Just add the code to store the mouse location in it.

LRESULT CALLBACK WndProc(	HWND	hWnd,			// Handle For This Window							UINT	uMsg,			// Message For This Window							WPARAM	wParam,			// Additional Message Information							LPARAM	lParam)			// Additional Message Information{	switch (uMsg)									// Check For Windows Messages	{		case WM_ACTIVATE:							// Watch For Window Activate Message		{			if (!HIWORD(wParam))					// Check Minimization State			{				active=TRUE;						// Program Is Active			}			else			{				active=FALSE;						// Program Is No Longer Active			}			return 0;								// Return To The Message Loop		}		case WM_SYSCOMMAND:							// Intercept System Commands		{			switch (wParam)							// Check System Calls			{				case SC_SCREENSAVE:					// Screensaver Trying To Start?				case SC_MONITORPOWER:				// Monitor Trying To Enter Powersave?				return 0;							// Prevent From Happening			}			break;									// Exit		}		case WM_CLOSE:								// Did We Receive A Close Message?		{			PostQuitMessage(0);						// Send A Quit Message			return 0;								// Jump Back		}		case WM_KEYDOWN:							// Is A Key Being Held Down?		{			keys[wParam] = TRUE;					// If So, Mark It As TRUE			console.keys[wParam] = TRUE;			//if (console.keys['M'])		    //		sprintf(console.c1, "key pressed");			return 0;								// Jump Back		}		//console.CheckKeys();		//sprintf(console.c1, "lkjsd lksdf lksdlkflk");		case WM_KEYUP:								// Has A Key Been Released?		{			keys[wParam] = FALSE;					// If So, Mark It As FALSE			console.keys[wParam] = FALSE;			return 0;								// Jump Back		}		case WM_SIZE:								// Resize The OpenGL Window		{			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // LoWord=Width, HiWord=Height			return 0;								// Jump Back		}   case WM_MOUSEMOVE:	   {		// GetMouseMovePoints(sizeof(zazou), zazou, 0,1,GMMP_USE_DISPLAY_POINTS);		zazou.x=LOWORD(lParam);		zazou.y=HIWORD(lParam);        		mousex=zazou.x;		mousey=zazou.y;		mx=zazou.x-340;		my=-(zazou.y)+240;	    mouseclk=wParam;		      	   }   case WM_RBUTTONDOWN:	   {	   RmouseBut=TRUE;	   }			};	// Pass All Unhandled Messages To DefWindowProc	return DefWindowProc(hWnd,uMsg,wParam,lParam);}


hope this helps, and hope it actually works and I posted it right. This code has been pulled right out of the source code for a working demo. Yeah, I know the code is messy.

[edited by - Crunchdown on March 1, 2004 11:43:08 PM]
I have an MFC demo that covers this on my site too.

Love means nothing to a tennis player

My nothing-to-write-home-about OpenGL webpage. (please pardon the popups!)

This topic is closed to new replies.

Advertisement