Please help...Mouse Position in OPENGL not working!

Started by
4 comments, last by CyberNano 14 years, 5 months ago
Hello, I am relatively new to OpenGL but I write C++. So, I have been working on an application in which I just need to determine my mouse position so I can draw a line but this feat has been elusive. :( I have read Nehe Tutorials (GluUnproject - Article 13: http://nehe.gamedev.net/data/articles/article.asp?article=13) on this subject and tried to use the code but I am not getting the correct coordinates. I think my windows coordinates are correct thought but, this OpenGL is the big, big problem. I have tried other approaches and I have run out of options. I am hoping someone can try and help me. I have a 2D Plot of a graph and all I just need is for the program to tell me if I click say point (0,0) or (35, 10) in OpenGL. This is not a 3D graph. Thank you and I hope to hear from you soon.
Advertisement
Couldn't you take the raw mouse coords from your OS's window function and map them accordingly?
Thanks for your response!

Well, I could you please give me an idea of how to do this method? My OS is Windows XP if this information is relevant. If you give me an idea of how this mapping looks like, I will gladly explore it.
For windows lookup the functions

GetCursorPos(LPPOINT lpPoint)
- gets xy pixel location of mouse in window, including borders and titlebar

ScreenToClient(HWND hWnd, LPPOINT lpPoint)
- takes the xy coordinates from GetCursorPos and translates it to ignore borders and titlebar (so that 0,0 is in your usable window space)
[size=2]My Projects:
[size=2]Portfolio Map for Android - Free Visual Portfolio Tracker
[size=2]Electron Flux for Android - Free Puzzle/Logic Game
Are you using straight up OpenGL and Win32 or are you using GLUT? If the latter, I believe you can hookup a function to recieve mouse input with relative ease, but I don't have much experience with GLUT.

If the former, look into what karwosts posted. I personally have something like this in my window procedure (I've left out tracking mouse window enter and exit for simplicity):

LRESULT CWin32Window::WindowProc(UINT Msg, WPARAM wParam, LPARAM lParam){    switch (Msg)    {        // other message handling here...        // Mouse Events																(int)	X				(int)	Y		case WM_LBUTTONDOWN:							usrInput.btnMouse[MOUSE_BTN_L] = true;			if(evListener) evListener->EventHandler(pUserData, eventMouseDownL,		(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_MBUTTONDOWN:						usrInput.btnMouse[MOUSE_BTN_M] = true;			if(evListener) evListener->EventHandler(pUserData, eventMouseDownM,		(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_RBUTTONDOWN:						usrInput.btnMouse[MOUSE_BTN_R] = true;			if(evListener) evListener->EventHandler(pUserData, eventMouseDownR,		(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_LBUTTONUP:								usrInput.btnMouse[MOUSE_BTN_L] = false;			if(evListener) evListener->EventHandler(pUserData, eventMouseUpL,			(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_MBUTTONUP:						usrInput.btnMouse[MOUSE_BTN_M] = false;			if(evListener) evListener->EventHandler(pUserData, eventMouseUpM,			(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_RBUTTONUP:						usrInput.btnMouse[MOUSE_BTN_R] = false;			if(evListener) evListener->EventHandler(pUserData, eventMouseUpR,			(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);						return 0;		case WM_MOUSEMOVE:			usrInput.mouseX = (UInt32) LOWER(lParam);			usrInput.mouseY = (UInt32) UPPER(lParam);			// Offset mouse y by menu height			if(flgStatus & WIN32_FULLSCREEN && wndMenu)			{       // Gamedev source tags wouldn't allow me to put 'plus equals' (+ = without the space)				usrInput.mouseY = usrInput.mouseY + GetSystemMetrics(SM_CYMENU);				}			if(evListener) evListener->EventHandler(pUserData, eventMouseMove,		(EvParam)usrInput.mouseX, (EvParam)usrInput.mouseY);			// Track the mouse input so the mouse leave message can be recieved upon the mouse leaving the window			if(!flgMouseTracking)			{				tme.cbSize = sizeof(TRACKMOUSEEVENT);				tme.dwFlags = TME_LEAVE;				tme.hwndTrack = hWnd;				if (TrackMouseEvent(&tme))				{					flgMouseTracking = true;					// Mouse has entered window...					if(evListener) evListener->EventHandler(pUserData, eventMouseEnter,	(EvParam)wParam, (EvParam)lParam);				}				else				{					ErrLog()->Write(Event_SilentWarning, "Mouse Tracking", "Couldn't track mouse!");				}			}			return 0;		case WM_MOUSEWHEEL:						if((short)HIWORD(wParam) > 0)			{				// Up				if(evListener) evListener->EventHandler(pUserData, eventMouseWheelUp,	(EvParam)HIWORD(lParam), 0);			}			else			{				// Down				if(evListener) evListener->EventHandler(pUserData, eventMouseWheelDown, (EvParam)HIWORD(lParam), 0);			}			return 0;  


So as you can see, I'm storing the mouse status in a structure (usrInput) before sending the mouse event info to a callback function (evListener).

I'm tracking the mouse position with the WM_MOUSEMOVE message and storing it in the usrInput structure. Note the lines:

usrInput.mouseX = (UInt32) LOWER(lParam);usrInput.mouseY = (UInt32) UPPER(lParam);


The UPPER and LOWER macros decompress the mouse x and y position from the lParam arguement which are then cast to unsigned int (probs better to keep them as signed ints but to late now for me).

When the mouse up/down events are handled, the mouse x and y position (stored in the structure as explained) are sent along to my callback function that handles mouse input (and other stuff).

The following lines properly offset the y position when the app is running in fullscreen and the app is using a menu. In windowed mode, this is handled for you but in fullscreen you have to take into consideration the menu height otherwise you'll get incorrect results. If you don't have a menu then you don't have to worry about this.
if(flgStatus & WIN32_FULLSCREEN && wndMenu){   // Gamedev source tags wouldn't allow me to put 'plus equals' (+ = without the space)    usrInput.mouseY  = usrInput.mouseY + GetSystemMetrics(SM_CYMENU);	}


So, if you're rendering 2D stuff in ortho perspective then all you have to do is compare the mouse position to that of the geometry in your scene and see if there's a hit.

Hope this helps (may not be too clear, it's 3 in the morning over here heh).

edit: i did leave part of the mouse tracking code in there but you can ignore it for now. I personally use it for GUI and camera stuff where the mouse is being moved with the buttons down. This allows you to trap the mouse before it leaves so it doen't get "stuck" in a mouse down state when the mouse leaves the window.
Thank you all for responding.

I am using OpenGL and Windows XP 64-bit.

so far, I have been able to get the Windows mouse coordinates:

GLfloat winX, winY;
POINT mouse;
GetCursorPos(&mouse);
ScreenToClient((HWND)this->Handle.ToPointer(), &mouse);
winX = (float)mouse.x;
winY = (float)mouse.y;

But, please karwosts, can you just give this example of putting the above coordinates within the 0,0 point you mentioned? If I get an example of this translation, I think I will be able to adapt it to my coordinates.

Thank you.

This topic is closed to new replies.

Advertisement