Sign in to follow this  
b1gjo3

fps camera techniques

Recommended Posts

I have a great 3d solar system that i made and im wanting to be able to move around my 3d scene. I dont have any good way of doing this except changing the x,y,z pos when the user hits the arrow keys (your always looking at the same direction) it would be nice to implement a fps type of camera to where the mouse pointer is where you want to look at. this is the class im using with the call to gluLookAt, the eye i am using is global so i can modify it wherever i want in code. I can also get the x,y coords of the mouse position. I just dont know what to do with these coords.
class VirtualEye
{
public:
	float eyePos[3];
	float lookAt[3];
	float up[3];
};


any light on this subject would be very much appreciated, or some links to some good tutorials because i haven't found any. and on another matter, how come i cant rotate my whole scene when i set the matrix mode to projection. it just rotates where the eye is. here is my drawing function.
void DisplayFunc()
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

	//set projection matrix, and load identity
	//glModeIdentity(false, true);
        //gluPerspective(15.0f,(GLfloat)WIDTH/(GLfloat)HEIGHT,1.0f,500.0f);
	//glRotatef(pRot, 0, 1, 0);

	glModeIdentity(true, true);
	ThreeDSolarSystem(eye, true);
	SpaceBox(eye);
}


here is my function that draws the solar system
void DrawSun()
{
	GLUquadricObj* q = gluNewQuadric();

	glColor3f(0.98f, 0.91f, 0.17f);
	glRotatef(threeDrot[0], 0, 1, 0);
	gluSphere(q, 2.0, 50, 50);

	gluDeleteQuadric(q);
}

void DrawMercury()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.5, 0.5, 0.5);
	glRotatef(threeDrot[1], 0, 1, 0);
	glTranslatef(3.5, 0, 0);
	glRotatef(planet_spin[0], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.2, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawVenus()
{
	GLUquadricObj* q = gluNewQuadric();
	
	glPushMatrix();
	glColor3f(1, 0.5, 0);
	glRotatef(threeDrot[2], 0, 1, 0);
	glTranslatef(5.0, 0, 0);
	glRotatef(planet_spin[1], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.35, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawEarth()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.25f, 0.5f, 0.75f);
	glRotatef(threeDrot[3], 0, 1, 0);
	glTranslatef(7.0f, 0, 0);
	glRotatef(planet_spin[2], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.4, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawEarthMoon()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.25f, 0.25f, 0.25f);
	glRotatef(threeDrot[3], 0.0f, 1.0f, 0.0f);
	glTranslatef(7.0f, 0, 0);
	glRotatef(threeDrot[4], 0.2f, 1.0f, 0.0f);
	glTranslatef(1.0f, 0, 0);
	glRotatef(planet_spin[3], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[3]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.2f, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawMars()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(1.0f, 0.2f, 0.0f);
	glRotatef(threeDrot[5], 0, 1, 0);
	glTranslatef(9.0, 0, 0);
	glRotatef(planet_spin[4], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[4]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.35, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawJupiter()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(1.0f, 0.5f, 0.5f);
	glRotatef(threeDrot[6], 0, 1, 0);
	glTranslatef(11.5, 0, 0);
	glRotatef(planet_spin[5], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[5]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.75, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawSaturn()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.75f, 0.65f, 0.65f);
	glRotatef(threeDrot[7], 0, 1, 0);
	glTranslatef(16, 0, 0);
	glRotatef(planet_spin[6], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[6]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.65, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawUranus()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.15f, 0.0f, 0.85f);
	glRotatef(threeDrot[8], 0, 1, 0);
	glTranslatef(21, 0, 0);
	glRotatef(planet_spin[7], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[7]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.65, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawNeptune()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.15f, 0.0f, 1.0f);
	glRotatef(threeDrot[9], 0, 1, 0);
	glTranslatef(24, 0, 0);
	glRotatef(planet_spin[8], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[8]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.60, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawPluto()
{
	GLUquadricObj* q = gluNewQuadric();

	glPushMatrix();
	glColor3f(0.15f, 0.15f, 0.15f);
	glRotatef(threeDrot[10], 0, 1, 0);
	glTranslatef(29, 0, 0);
	glRotatef(planet_spin[9], 0, 1, 0);
	glRotatef(-90, 1, 0, 0); //turn planets right side up
		glEnable(GL_TEXTURE_2D);
		glBindTexture(GL_TEXTURE_2D, texture[9]);
		q = gluNewQuadric();
		gluQuadricTexture(q, GL_TRUE);
	gluSphere(q, 0.15, 50, 50);
	glDisable(GL_TEXTURE_2D);
	glPopMatrix();

	gluDeleteQuadric(q);
}

void DrawOrbits()
{
	glPushMatrix();
		glDisable(GL_LIGHT0);
		glDisable(GL_LIGHT1);
	DrawOrbit(3.5, 1);
	DrawOrbit(5.0, 1);
	DrawOrbit(7.0, 1);
	DrawOrbit(9.0, 1);
	DrawOrbit(11.5, 1);
	DrawOrbit(16, 1);
	DrawOrbit(21, 1);
	DrawOrbit(24, 1);
	DrawOrbit(29, 1);
	glPopMatrix();
}

void ThreeDSolarSystem(VirtualEye eye, bool orbits)
{
	GLfloat specref[] = { 1.0f, 1.0f, 1.0f, 1.0f };
	GLfloat	lightPos[] = { 0.0f, 0.0f, 0.0f, 1.0f };
	GLfloat emissionSun[] = { 0.9f, 0.9f, 0.0f, 0.0f};
	GLfloat nullv[] = { 0.0f, 0.0f, 0.0f, 1.0f};

	glEnable(GL_LIGHT0);
	gluLookAt(eye.eyePos[0], eye.eyePos[1], eye.eyePos[2], 
			eye.lookAt[0], eye.lookAt[1], eye.lookAt[2],
			eye.up[0], eye.up[1], eye.up[2]);
	glPushMatrix();

	//set sun material and draw sun
	glMaterialfv(GL_FRONT, GL_SPECULAR, specref);
	glMateriali(GL_FRONT, GL_SHININESS, 3);
	glMaterialfv(GL_FRONT, GL_EMISSION, emissionSun); //make sun glow
	glLightfv(GL_LIGHT1, GL_POSITION, lightPos); //move light 1 under sun
	DrawSun();

	//save lighting and set other planets material
	glPushAttrib(GL_LIGHTING_BIT);
	glDisable(GL_LIGHT0);
	glEnable(GL_LIGHT1); //turn on the sun
	glMaterialfv(GL_FRONT, GL_SPECULAR, nullv);
	glMaterialfv(GL_FRONT, GL_EMISSION, nullv);

	//draw rest of the planets
	DrawMercury();
	DrawVenus();
	DrawEarth();
	DrawEarthMoon();
	DrawMars();
	DrawJupiter();
	DrawSaturn();
	DrawUranus();
	DrawNeptune();
	DrawPluto();

	//do orbits or not?
	if (orbits)
	{
		DrawOrbits();
	}
}


thanks again

Share this post


Link to post
Share on other sites
this site has a good tutorial for FPS camera here

maybe a modeling style camera like 3DS MAX would be good to look around the solar system? the camera always looks at an object and holding middle mouse and moving the mouse rotates the camera, middle mouse zooms in and out? you could then set it up so you can "focus" on each planet

I don't know of any good tutorials for this system although I have implemented one for some projects so can give you some info if you need :)

hope this helps

Share this post


Link to post
Share on other sites
First thing you want to do is create a method to poll the X and Y position of the Mouse. Then every frame set the X and Y position of the mouse at the center of the screen. When you move the mouse compare the current X and Y mouse position to the previous X and Y position (the Center of the screen). From here you can change your lookAt Vector by a rotation matrix created according to the direction your mouse cursor moved. You can then change your eyePosition vector with the WASD keys using a translation matrix with your desired camera movement speed.

I hope this helps

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now

Sign in to follow this