Camera Problems

Started by
1 comment, last by arophous 15 years, 4 months ago
Hello, I have been frustrating myself today with trying to get the camera/keyboard movement working in my program. It basically hacked bits of some tutorials which I am testing to make sure i can do certain parts of a project before i need to start it. I have managed to get some movement in different directions but am having a problem simply spinning on the spot from the camera perspective. Anyway here is the complete code bar the headers & 3ds loader class. Once i get the camera sorted I will be keeping it for re-use in other projects.
 
#include <iostream>
#include <stdlib.h> //Needed for "exit" function
#include <windows.h>		// Header File For Windows
#include <gl\glut.h>			// Header File For The OpenGL32 Library
#include "structs.h"
#include "3dsloader.h"
#include <math.h>


using namespace std;

void handleKeypress(unsigned char key, int x, int y);
void initRendering();
void handleResize(int w, int h);
void drawScene();
void update(int value);
void load3dModel();

const float BOX_SIZE = 15.0f;
const float piover180 = 0.0174532925f;
float heading;
float _cameraAngle = 0.0f;
float _angle = 90.0f; //The rotation of the box
float xpos;
float zpos;

obj_type object;
GLfloat	yrot = 0.0f;				// Y Rotation
GLfloat walkbias = 0;
GLfloat walkbiasangle = 0;
GLfloat lookupdown = 0.0f;
GLfloat	z=0.0f;				// Depth Into The Screen
GLfloat xtrans = -xpos;
GLfloat ztrans = -zpos;
GLfloat ytrans = 0.0f;  //-walkbias-0.25f;
GLfloat sceneroty = 360.0f - yrot;

void cameraUpdate(int direction)
{
	if( direction == 1)
	{
		//look left
		sceneroty += 0.5f;
		//xpos -= 1.0f;
		//now redraw the screen, but how
		glMatrixMode(GL_PROJECTION);
	    glRotatef(sceneroty,0.0f,1.0f,0);
	    glTranslatef(xtrans, ytrans, ztrans);
		return;
	}
	if( direction == 2)
	{
		//look right
		sceneroty -= 0.5f;
		//xpos -= 1.0f;
		//now redraw the screen, but how
		glMatrixMode(GL_PROJECTION);
	    glRotatef(sceneroty,0.0f,1.0f,0);
	    glTranslatef(xtrans, ytrans, ztrans);
		return;
	}
	if( direction == 3)
	{
		//move foward
		xpos -= (float)sin(heading*piover180) * 0.05f;
		zpos -= (float)cos(heading*piover180) * 0.05f;
		if (walkbiasangle >= 359.0f)
		{
			walkbiasangle = 0.0f;
		}
		else
		{
			walkbiasangle+= 10;
		}
		walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
		return;
	}
	if( direction == 4)
	{
		xpos += (float)sin(heading*piover180) * 0.05f;
		zpos += (float)cos(heading*piover180) * 0.05f;
		if (walkbiasangle <= 1.0f)
		{
			walkbiasangle = 359.0f;
		}
		else
		{
			walkbiasangle-= 10;
		}
		walkbias = (float)sin(walkbiasangle * piover180)/20.0f;
		return;
	}
	if( direction == 5)
	{
		//look up
	}
	if( direction == 6)
	{
		//look down
	}
}

int main(int argc, char **argv){
	//Initialize GLUT
	glutInit(&argc, argv);
	glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH);
	glutInitWindowSize(800, 600); //Set the window size
	
	//Create the window
	glutCreateWindow("Basic 3ds loader - James Birchall");
	initRendering(); //Initialize rendering
	
	//Set handler functions for drawing, keypresses, and window resizes
	glutDisplayFunc(drawScene);
	glutKeyboardFunc(handleKeypress);
	glutReshapeFunc(handleResize);

	glutTimerFunc(25, update, 0); //Add a timer

	glutMainLoop(); //Start the main loop.  glutMainLoop doesn't return.
	return 0; //This line is never reached
}

//Called when a key is pressed
void handleKeypress(unsigned char key, //The key that was pressed
					int x, int y) {    //The current mouse coordinates
	switch (key) {
		case 27: //Escape key
			exit(0); //Exit the program
		case 'a': //turn left
			cameraUpdate(1);
			break;
		case 'd': //turn right - seems to be just rotating the object...
			cameraUpdate(2);
			break;
		case 'w': //move foward
			cameraUpdate(3);
			break;
		case 's': //move back
			cameraUpdate(4);
			break;
		case 'z': //lookup
			cameraUpdate(5);
			break;
		case 'x': //look down
			cameraUpdate(6);
			break;
	}
}

//Initializes 3D rendering
void initRendering() {
    glEnable(GL_DEPTH_TEST);
    glEnable(GL_LIGHTING);
    glEnable(GL_LIGHT0);
    glEnable(GL_COLOR_MATERIAL);

	Load3DS (&object,"spaceship.3ds"); //change to load multiples later on
}

//Called when the window is resized
void handleResize(int w, int h) {
	//Tell OpenGL how to convert from coordinates to pixel values
	glViewport(0, 0, w, h);
	
	glMatrixMode(GL_PROJECTION); //Switch to setting the camera perspective
	
	//Set the camera perspective
	glLoadIdentity(); //Reset the camera
	gluPerspective(45.0,                  //The camera angle
				   (double)w / (double)h, //The width-to-height ratio
				   1.0,                   //The near z clipping coordinate
				   200.0);                //The far z clipping coordinate
}

//Draws the 3D scene
void drawScene() {

	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// Clear The Screen And The Depth Buffer
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
	glTranslatef(0.0f, -7.0f, -20.0f); //where the camera is
    GLfloat ambientLight[] = {0.3f, 0.3f, 0.3f, 1.0f};
    glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambientLight);
    GLfloat lightColor[] = {0.7f, 0.7f, 0.7f, 1.0f};
    GLfloat lightPos[] = {-2 * BOX_SIZE, BOX_SIZE, 4 * BOX_SIZE, 1.0f};
    glLightfv(GL_LIGHT0, GL_DIFFUSE, lightColor);
    glLightfv(GL_LIGHT0, GL_POSITION, lightPos);
	
	//take this out and do it for projection
	//glMatrixMode(GL_PROJECTION);
	//glRotatef(lookupdown,1.0f,0.0f,0.0f);
	//glRotatef(sceneroty,0.0f,1.0f,0);
	//glTranslatef(xtrans, ytrans, ztrans);
	//include drawing here for model 3ds
	load3dModel();
	glutSwapBuffers(); //Send the 3D scene to the screen
}

void update(int value) {
    _angle += 2.0f;
    if (_angle > 360) {
        _angle -= 360;
    }
    
    glutPostRedisplay(); //Tell GLUT that the scene has changed
    
    //Tell GLUT to call update again in 25 milliseconds
    glutTimerFunc(25, update, 0);
}

void load3dModel(){
    int l_index;

	glBegin(GL_TRIANGLES); // glBegin and glEnd delimit the vertices that define a primitive (in our case triangles)
	
    for (l_index=0; l_index<object.polygons_qty; l_index++)
    {
		glColor3f(1.0f, 0.0f, 0.0f);
        //----------------- FIRST VERTEX -----------------
        // Coordinates of the first vertex
        glVertex3f( object.vertex[ object.polygon[l_index].a ].x,
                    object.vertex[ object.polygon[l_index].a ].y,
                    object.vertex[ object.polygon[l_index].a ].z); //Vertex definition

        //----------------- SECOND VERTEX -----------------
        // Coordinates of the second vertex
        glVertex3f( object.vertex[ object.polygon[l_index].b ].x,
                    object.vertex[ object.polygon[l_index].b ].y,
                    object.vertex[ object.polygon[l_index].b ].z);
        
        //----------------- THIRD VERTEX -----------------
        // Coordinates of the Third vertex
        glVertex3f( object.vertex[ object.polygon[l_index].c ].x,
                    object.vertex[ object.polygon[l_index].c ].y,
                    object.vertex[ object.polygon[l_index].c ].z);
    }
    glEnd();
    glFlush(); // This force the execution of OpenGL commands
}
Does anyone know whats going wrong? Cheers, Aro
Advertisement
1) calculate camera position based on keystates.
2) apply these calculations only in your renderer...
void RenderOpenGL(void){   glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);   glLoadIdentity();   glRotatef(rx,1.0F,0.0F,0.0F);   glRotatef(ry,0.0F,1.0F,0.0F);   glRotatef(rz,0.0F,0.0F,1.0F);   glTranslatef(-tx,-ty,-tz);   // draw objects here}
thanks Bitshift, appreciate it :)

This topic is closed to new replies.

Advertisement