I've put together a 3rd person camera system using OpenGL and C++ from tutorials and such online, but I can't seem to figure out a specific problem. When I turn using mouse movement, my character is rotated around the camera rather than the camera around the character and the character turning on the spot. What should I do to have the character turn on the spot?
// variables ..
void checkMouse(){
if (mouseXPos > SCREEN_WIDTH/2){
// turn right
yrot += abs(mouseXPos - SCREEN_WIDTH/2) * .005;
} else if (mouseXPos < SCREEN_WIDTH/2){
// turn left
yrot -= abs(mouseXPos - SCREEN_WIDTH/2) * .005;
}
if (mouseYPos > SCREEN_HEIGHT/2){
// look up
xrot += abs(mouseYPos - SCREEN_HEIGHT/2) * .005;
} else if (mouseYPos < SCREEN_HEIGHT/2){
// look down
xrot -= abs(mouseYPos - SCREEN_HEIGHT/2) * .005;
}
}
void checkKeys(){
if(keys['t'] == true){
wireframe=!wireframe;
if(wireframe){
glPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
}
else glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
}
if (keys['w'] == true){
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos += float(sin(yrotrad)) * 10 ;
zpos -= float(cos(yrotrad)) * 10 ;
}
if (keys['s'] == true){
float xrotrad, yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xrotrad = (xrot / 180 * 3.141592654f);
xpos -= float(sin(yrotrad)) * 10;
zpos += float(cos(yrotrad)) * 10;
}
if (keys['a'] == true){
float yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xpos -= float(cos(yrotrad)) * 10;
zpos -= float(sin(yrotrad)) * 10;
}
if (keys['d'] == true){
float yrotrad;
yrotrad = (yrot / 180 * 3.141592654f);
xpos += float(cos(yrotrad)) * 10;
zpos += float(sin(yrotrad)) * 10;
}
}
void renderScene(){
// Clear framebuffer & depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Reset Modelview matrix
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// Set view position & direction
gluLookAt(0,0,5, 0,0,-1, 0,1,0);
checkKeys();
checkMouse();
// 3rd person object
// draw body
glPushMatrix();
glRotatef(xrot,1.0,0.0,0.0); // keeps object on ground level rather than always in front of camera
glTranslatef(0,-90,-400.0); // keep object 400 away from camera
glRotatef(-90,0.0,1.0,0.0);
glutSolidCube(20);
glPopMatrix();
// CAMERA
glRotatef(xrot,1.0,0.0,0.0); //rotate our camera on the x-axis (left and right)
glRotatef(yrot,0.0,1.0,0.0); //rotate our camera on the y-axis (up and down)
glTranslated(-xpos,-ypos-200,-zpos);
// rest of world
glPushMatrix();
glutSolidCube(30);
glPopMatrix();
// ..
glDisable(GL_TEXTURE_2D);
// Swap double buffer for flicker-free animation
glutSwapBuffers();
}
void updateScene(){
// Wait until at least 16ms passed since start of last frame
// Effectively caps framerate at ~60fps
while(timeGetTime()-lastTickCount<16);
lastTickCount=timeGetTime();
// Draw the next frame
glutPostRedisplay();
}
void keypress (unsigned char key, int x, int y) {
keys[key] = true;
// Test if user pressed ESCAPE (ascii 27)
// If so, exit the program
if(key==27){
exitScene();
}
}
void keypressup (unsigned char key, int x, int y) {
keys[key] = false;
wheel_turn = 0;
}
void mouseMovement(int x, int y) {
mouseXPos = x;
mouseYPos = y;
}
void mouseClick(int button, int state, int x, int y){
if (button == GLUT_LEFT_BUTTON){
if (state == GLUT_DOWN)
lButton = true;
else
lButton = false;
}
}
void setupScene(){
forwards = 0;
strafe = 0;
turn = 0;
std::cout<<"Initializing scene..."<<std::endl;
//Set up Lighting Stuff
glLightfv(GL_LIGHT0, GL_POSITION, left_light_position);
glLightfv(GL_LIGHT0, GL_AMBIENT, white_light);
glEnable(GL_LIGHTING);
glEnable(GL_LIGHT0);
glLightfv(GL_LIGHT0, GL_DIFFUSE, white_light);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
}
void exitScene(){
std::cout<<"Exiting scene..."<<std::endl;
// Close window
glutDestroyWindow(windowId);
// Free any allocated memory
// Exit program
exit(0);
}
void setViewport(int width, int height) {
// Work out window ratio, avoid divide-by-zero
if(height==0)height=1;
float ratio = float(width)/float(height);
// Reset projection matrix
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
// Fill screen with viewport
glViewport(0, 0, width, height);
// Set a 45 degree perspective
gluPerspective(45, ratio, .1, 200000);
}
int main(int argc, char *argv[]){
// Initialise OpenGL
glutInit(&argc, argv);
// Set window position, size & create window
glutInitDisplayMode(GLUT_RGBA | GLUT_DOUBLE | GLUT_DEPTH);
glutInitWindowPosition(50,50);
glutInitWindowSize(SCREEN_WIDTH,SCREEN_HEIGHT);
windowId = glutCreateWindow("3rd person cam");
// Set GLUT callback functions
glutReshapeFunc(setViewport);
glutDisplayFunc(renderScene);
glutIdleFunc(updateScene);
glutKeyboardFunc(keypress);
glutKeyboardUpFunc(keypressup);
glutPassiveMotionFunc(mouseMovement); //check for mouse movement
glutMotionFunc(mouseMovement);
glutMouseFunc(mouseClick);
// Setup OpenGL state & scene resources (models, textures etc)
setupScene();
// Show window & start update loop
glutMainLoop();
return 0;
}
You're rotating the camera around itself — it's akin to you turning your head. You want to change the camera position, revolving around your object of interest.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With