?
Solved

Quake-Style (6DOF) Camera: Window v. Fullscreen

Posted on 2003-02-27
5
Medium Priority
?
851 Views
Last Modified: 2013-12-06
Experts,
I'm having problems implementing a Quake-style (6 degrees of freedom) camera in an OpenGL Win32 app. The camera works fine in fullscreen mode, however, in Window mode the camera behaves eradically and any movement of the mouse makes the camera tilt upward very quickly so that the camera faces almost directly overhead. This problem has stumped me for days now. Any help would be greatly appreciated.

Some code segments: (I'll provide any more if necessary.)

******************************************

static bool changeMouse = false;
...

LRESULT CALLBACK WindowProc (...) {
...
   case WM_MOUSEMOVE:
      camera->handleMouseMotion(LOWORD(lParam), HIWORD(lParam));
      if (changeMouse = !changeMouse) SetCursorPos((windowWidth)/2, (windowHeight)/2);
      return 0;
      break;
...

void Camera::HandleMouseMotion(int x, int y) {
   if (!mouseMotionEnabled) return;

   int deltaX = x - viewPortCenterX;
   int deltaY = y - viewPortCenterY;

   if (deltaX == 0 && deltaY == 0) return;

   camYaw -= ANGLE_SENSITIVITY * deltaX;
   camPitch -= ANGLE_SENSITIVITY * deltaY * (mouseIsInverted ? -1.0 : 1.0);
   clampCamera();
}

void Camera::clampCamera() {
   // Clamp the camera's pitch.
   if (camPitch > 90.0) {
      camPitch = 90.0;
   } else if(camPitch < -90.0) {
      camPitch = -90.0;
   }

   // Modulus the yaw (0.0 to 360.0, exclusive).
   while (camYaw < 0.0)    
      camYaw += 360.0;

   while (camYaw >= 360.0)
      camYaw -= 360.0;
}

void Camera::applyCamera() {
   glRotatef(-camPitch,     1.0, 0.0, 0.0 ); // apply pitch
   glRotatef(-camYaw, 0.0, 1.0, 0.0 ); // apply yaw
   glTranslatef(-camX, -camY, -camZ ); // position camera
}

void Draw (void) {
   glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
   glMatrixMode(GL_MODELVIEW);
   glLoadIdentity();
   camera->applyCamera(); // above
   renderer->drawScene(); // renders objects (works fine)
   glFlush();
}

******************************************

The only thing I can think of, is that it involves a difference in how a window handles mouse events to how a fullscreen app handles them. It's almost like (in window mode) upon first moving the mouse in any direction, the window registers the mouse as moving up and gets stuck in a loop (or something to this effect).

Like I said, this is stumping me and that's why I'm offering 50 points.

Cheers,
Simon
0
Comment
Question by:simon_mcf
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 2
5 Comments
 

Author Comment

by:simon_mcf
ID: 8038699
P.S.

void Camera::HandleMouseMotion(...)
should be
void Camera::handleMouseMotion(...)

Damn typo errors... ;)
0
 
LVL 4

Expert Comment

by:joachimc
ID: 8041077
Why not try to use direct input. That is much fast. Could be that you are loosing lot of time to other apps.
0
 

Accepted Solution

by:
simon_mcf earned 0 total points
ID: 8046768
I posted my question over @ openglforums.com and got the following responses: which are both correct.

Wichetael:
----------------

SetCursorPos works in screen coördinates not in window coördinates. Change your code to:

Code:
if (changeMouse = !changeMouse) {
  POINT cursor;
  cursor.x = windowWidth/2;
  cursor.y = windowHeight/2;
  ClientToScreen(&cursor);
  SetCursorPos(cursor.x, cursor.y);
}

Aragorn:
---------------------
I suppose the problem is that the coordinates passed to SetCursorPos are in screen coordinates while the coordinates passes with WM_MOUSEMOVE are client space which is ok if you are in fullscreen mode as screen coords == client coords there. But will cause havy confusion in windowed mode. Here is why:

Suppose the window takes the upper left corner of your screen now if you always reset the cursor to the middle of the screen it will be near the lower left corner of the client area of the window when WM_MOUSEMOVE is fired. meaning you will always turn to lower left very fast.

=========================
Shame I can't award these guys the points. ;(
- Simon
0
 

Expert Comment

by:CleanupPing
ID: 9464806
simon_mcf:
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
EXPERTS:
Post your closing recommendations!  No comment means you don't care.
0

Featured Post

Free Tool: IP Lookup

Get more info about an IP address or domain name, such as organization, abuse contacts and geolocation.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Artificial Intelligence comes in many forms, and for game developers, Path-Finding is an important ability for making an NPC (Non-Playable Character) maneuver through terrain.  A* is a particularly easy way to approach it.  I’ll start with the algor…
Recently, in one of the tech-blogs I usually read, I saw a post about the best-selling video games through history. The first place in the list is for the classic, extremely addictive Tetris. Well, a long time ago, in a galaxy far far away, I was…
Monitoring a network: how to monitor network services and why? Michael Kulchisky, MCSE, MCSA, MCP, VTSP, VSP, CCSP outlines the philosophy behind service monitoring and why a handshake validation is critical in network monitoring. Software utilized …
If you’ve ever visited a web page and noticed a cool font that you really liked the look of, but couldn’t figure out which font it was so that you could use it for your own work, then this video is for you! In this Micro Tutorial, you'll learn yo…

800 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question