Smooth key scrolling

Published May 09, 2006
Advertisement
I fixed the key repeat issue with my engine tonight. Before, I was relying on the operating system key repeat setting to implement movement. So when the player held down the 'W' key, for example, the engine would move forward a frame, pause, and then start smooth scrolling forward.

There were two problems with this. First, the pause before scrolling kicked in was ugly. Second, the player could only hold down one key at a time. There was no way to hold down 'w' and 'a' at the same time and move diagonally. Now all that is fixed.

It works well with the collision detection and sliding planes also. Basically, I used the keypress routine here (as found on the old lighthouse3D website)


#include #include #include float angle=0.0,deltaAngle = 0.0,ratio;float x=0.0f,y=1.75f,z=5.0f;float lx=0.0f,ly=0.0f,lz=-1.0f;GLint snowman_display_list;int deltaMove = 0;void changeSize(int w, int h)	{	// Prevent a divide by zero, when window is too short	// (you cant make a window of zero width).	if(h == 0)		h = 1;	ratio = 1.0f * w / h;	// Reset the coordinate system before modifying	glMatrixMode(GL_PROJECTION);	glLoadIdentity();		// Set the viewport to be the entire window    glViewport(0, 0, w, h);	// Set the clipping volume	gluPerspective(45,ratio,1,1000);	glMatrixMode(GL_MODELVIEW);	glLoadIdentity();	gluLookAt(x, y, z, 		      x + lx,y + ly,z + lz,			  0.0f,1.0f,0.0f);	}void drawSnowMan() {	glColor3f(1.0f, 1.0f, 1.0f);// Draw Body		glTranslatef(0.0f ,0.75f, 0.0f);	glutSolidSphere(0.75f,20,20);// Draw Head	glTranslatef(0.0f, 1.0f, 0.0f);	glutSolidSphere(0.25f,20,20);// Draw Eyes	glPushMatrix();	glColor3f(0.0f,0.0f,0.0f);	glTranslatef(0.05f, 0.10f, 0.18f);	glutSolidSphere(0.05f,10,10);	glTranslatef(-0.1f, 0.0f, 0.0f);	glutSolidSphere(0.05f,10,10);	glPopMatrix();// Draw Nose	glColor3f(1.0f, 0.5f , 0.5f);	glRotatef(0.0f,1.0f, 0.0f, 0.0f);	glutSolidCone(0.08f,0.5f,10,2);}GLuint createDL() {	GLuint snowManDL;	// Create the id for the list	snowManDL = glGenLists(1);	// start list	glNewList(snowManDL,GL_COMPILE);	// call the function that contains the rendering commands		drawSnowMan();	// endList	glEndList();	return(snowManDL);}void initScene() {	glEnable(GL_DEPTH_TEST);	snowman_display_list = createDL();}void orientMe(float ang) {	lx = sin(ang);	lz = -cos(ang);	glLoadIdentity();	gluLookAt(x, y, z, 		      x + lx,y + ly,z + lz,			  0.0f,1.0f,0.0f);}void moveMeFlat(int i) {	x = x + i*(lx)*0.1;	z = z + i*(lz)*0.1;	glLoadIdentity();	gluLookAt(x, y, z, 		      x + lx,y + ly,z + lz,			  0.0f,1.0f,0.0f);}void renderScene(void) {	if (deltaMove)		moveMeFlat(deltaMove);	if (deltaAngle) {		angle += deltaAngle;		orientMe(angle);	}	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// Draw ground	glColor3f(0.9f, 0.9f, 0.9f);	glBegin(GL_QUADS);		glVertex3f(-100.0f, 0.0f, -100.0f);		glVertex3f(-100.0f, 0.0f,  100.0f);		glVertex3f( 100.0f, 0.0f,  100.0f);		glVertex3f( 100.0f, 0.0f, -100.0f);	glEnd();// Draw 36 SnowMen	for(int i = -3; i < 3; i++)		for(int j=-3; j < 3; j++) {			glPushMatrix();			glTranslatef(i*10.0,0,j * 10.0);			glCallList(snowman_display_list);;			glPopMatrix();		}	glutSwapBuffers();}void pressKey(int key, int x, int y) {	switch (key) {		case GLUT_KEY_LEFT : deltaAngle = -0.01f;break;		case GLUT_KEY_RIGHT : deltaAngle = 0.01f;break;		case GLUT_KEY_UP : deltaMove = 1;break;		case GLUT_KEY_DOWN : deltaMove = -1;break;	}}void releaseKey(int key, int x, int y) {	switch (key) {		case GLUT_KEY_LEFT : 		case GLUT_KEY_RIGHT : deltaAngle = 0.0f;break;		case GLUT_KEY_UP : 		case GLUT_KEY_DOWN : deltaMove = 0;break;	}}void processNormalKeys(unsigned char key, int x, int y) {	if (key == 27) 		exit(0);}int main(int argc, char **argv){	glutInit(&argc, argv);	glutInitDisplayMode(GLUT_DEPTH | GLUT_DOUBLE | GLUT_RGBA);	glutInitWindowPosition(100,100);	glutInitWindowSize(640,360);	glutCreateWindow("SnowMen from Lighthouse 3D");	initScene();	glutIgnoreKeyRepeat(1);	glutKeyboardFunc(processNormalKeys);	glutSpecialFunc(pressKey);	glutSpecialUpFunc(releaseKey);	glutDisplayFunc(renderScene);	glutIdleFunc(renderScene);	glutReshapeFunc(changeSize);	glutMainLoop();	return(0);}


I already have a timer built into the engine to calculate framerate. Next I will modify the code to implement framerate independence.

I also want to implement a perlin noise shader soon in Cg. I plan to use this shader for various effects throughout the levels. I recently had to give a presentation regarding GPU depth buffers, so I have Cg fresh on my mind.

Sound is also on the horizon, and this is something that I do not have much experience with at the moment. I believe I will use openAl to do this, but I really know nothing about it currently. It should be interesting learning about it.

Finally, I found a bug the other day in my code that was responsible for constructing my data structures from OBJs. It was a small little looping bug, but it caused certain faces to be added twice, while the face count was only incremented once. Since the faces that were added twice were identical, there was no noticeable difference when rendering. Unfortunately, all my rendering benchmarks are now suspect. Suspect for the better, but suspect nonetheless. I might benchmark again sometime to get more accurate results, but for the moment I would like to continue coding.
0 likes 0 comments

Comments

Nobody has left a comment. You can be the first!
You must log in to join the conversation.
Don't have a GameDev.net account? Sign up!
Profile
Author
Advertisement
Advertisement