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.