?
Solved

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

Posted on 2003-02-27
5
Medium Priority
?
854 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
  • 2
4 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

VIDEO: THE CONCERTO CLOUD FOR HEALTHCARE

Modern healthcare requires a modern cloud. View this brief video to understand how the Concerto Cloud for Healthcare can help your organization.

Question has a verified solution.

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

As game developers, we quickly learn that Artificial Intelligence (AI) doesn’t need to be so tough.  To reference Space Ghost: “Moltar, I have a giant brain that is able to reduce any complex machine into a simple yes or no answer. (http://www.youtu…
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…
Exchange organizations may use the Journaling Agent of the Transport Service to archive messages going through Exchange. However, if the Transport Service is integrated with some email content management application (such as an anti-spam), the admin…
The Relationships Diagram is a good way to get an overall view of what a database is keeping track of. It is also where relationships are defined. A relationship specifies how two tables connect to each other. As you build tables in Microsoft Ac…
Suggested Courses

569 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