Created
July 6, 2012 22:18
Revisions
-
dlivingstone created this gist
Jul 6, 2012 .There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters. Learn more about bidirectional Unicode charactersOriginal file line number Diff line number Diff line change @@ -0,0 +1,196 @@ // main.cpp // A very basic OpenGL/GLUT application using the deprecated OpenGL 1.x // (c) Daniel Livingstone, 2012 // The structure of this program is typical of many simple OpenGL demonstration // programs, but is unsuitable for larger projects: The very basic structure // is useful when learning OpenGL, but very poor for building large, complex // systems such as modern games // In this 'game' the player has to move (using w,s,a,d keys) and resize (using // arrow keys) a white cursor to surround a red target as tightly as possible. // When the player succeeds, the red target will be randomly resized and positioned // Many to-do's in this project: // - Seperate update from keyboard and render functions // - - Fix keyboard to recognise multiple key presses // - Use timers to provide better control over frame-rate // - - Try GLUT timers first // - - Then frame limiter // - - Then independent physics/render loop // - Introduce game-state, with main menu and 'game' and pause screens #define FREEGLUT_STATIC #include <GL/freeglut.h> // C stdlib and C time libraries for rand and time functions #include <cstdlib> #include <ctime> // iostream for cin and cout #include <iostream> // stringstream and string #include <sstream> #include <string> float xpos = 0.0f; float ypos = 0.0f; float xsize = 0.25f; float ysize = 0.25f; float targetXPos = 0.0f; float targetYPos = 0.0f; float targetXSize = 0.0f; float targetYSize = 0.0f; int score = 0; clock_t lastTime; // clock_t is an integer type clock_t currentTime; // use this to trace time between frames void displayString(float x, float y, void* font, const char *str) { glRasterPos2f(x, y); while (*str != NULL) glutBitmapCharacter(font, *str++); } void init(void) { glClearColor(0.0, 0.0, 0.0, 0.0); // set background colour std::srand( std::time(NULL) ); targetXPos = (float)rand()/RAND_MAX - 0.75f; targetYPos = (float)rand()/RAND_MAX - 0.75f; targetXSize = 0.19f; targetYSize= 0.19f; lastTime = clock(); } void render(void) { glClear(GL_COLOR_BUFFER_BIT); // Clear all pixels // drawing code goes in here! // draw player glColor3f(1.0,1.0,1.0); glBegin(GL_POLYGON); glVertex3f (xpos, ypos, 0.0); // first corner glVertex3f (xpos+xsize, ypos, 0.0); // second corner glVertex3f (xpos+xsize, ypos+ysize, 0.0); // third corner glVertex3f (xpos, ypos+ysize, 0.0); // fourth corner glEnd(); displayString(xpos+(xsize/2.0f), ypos+ysize, GLUT_BITMAP_TIMES_ROMAN_10, "Player"); // draw target glColor3f(1.0,0.0,0.0); glBegin(GL_POLYGON); glVertex3f (targetXPos, targetYPos, 0.0); // first corner glVertex3f (targetXPos+targetXSize, targetYPos, 0.0); // second corner glVertex3f (targetXPos+targetXSize, targetYPos+targetYSize, 0.0); // third corner glVertex3f (targetXPos, targetYPos+targetYSize, 0.0); // fourth corner glEnd(); displayString(targetXPos+(targetXSize/2.0f), targetYPos+targetYSize, GLUT_BITMAP_TIMES_ROMAN_10, "Target"); if ( (targetXPos >= xpos) && (targetXPos+targetXSize <= xpos+xsize) // cursor surrounds target in x && (targetYPos >= ypos) && (targetYPos+targetYSize <= ypos+ysize) // cursor surrounds target in y && ( xsize <= targetXSize+0.1f) && ( ysize <= targetYSize+0.1f) ) // cursor only slightly larger than target { // congrats, player has scored! score += 100; std::cout << "Score: " << score << std::endl; // randomize target targetXPos = (float)rand()/RAND_MAX - 0.75f; targetYPos = (float)rand()/RAND_MAX - 0.75f; targetXSize = (float)rand()/RAND_MAX * 0.8f; targetYSize= (float)rand()/RAND_MAX * 0.8f; } // Calculate ms/frame // Some OpenGL drivers will limit the frames to 60fps (16.66 ms/frame) // If so, expect to see the time to rapidly switch between 16 and 17... glColor3f(1.0,1.0,1.0); currentTime = clock(); // On some systems, CLOCKS_PER_SECOND is 1000, which makes the arithmetic below redundant // - but this is not necessarily the case on all systems float milliSecondsPerFrame = ((currentTime - lastTime)/(float)CLOCKS_PER_SEC*1000); // Print out the score and frame time information std::stringstream strStream; strStream << "Score:" << score; strStream << " ms/frame: " << milliSecondsPerFrame; displayString(-0.9,0.9, GLUT_BITMAP_9_BY_15, strStream.str().c_str()); lastTime = clock(); glutSwapBuffers(); // Redraw (double buffered) } void keyboard(unsigned char key, int x, int y) { switch (key) { case 'w': case 'W': ypos += 0.05; break; case 's': case 'S': ypos -= 0.05; break; case 'a': case 'A': xpos -= 0.05; break; case 'd': case 'D': xpos += 0.05; break; } glutPostRedisplay(); } void specialKeys(int key, int x, int y) { switch (key) { case GLUT_KEY_UP: ysize += 0.05; break; case GLUT_KEY_DOWN: ysize -= 0.05; break; case GLUT_KEY_LEFT: xsize -= 0.05; break; case GLUT_KEY_RIGHT: xsize += 0.05; break; } glutPostRedisplay(); } int main(int argc, char **argv) { glutInit(&argc, argv); glutInitWindowPosition(100,100); glutInitWindowSize(400,400 ); glutInitDisplayMode(GLUT_DOUBLE); glutCreateWindow("Demo Project"); init(); glutDisplayFunc(render); // Register the render callack glutKeyboardFunc(keyboard); // Setup keyboard callback glutSpecialFunc(specialKeys); // Setup special keys callback glutIdleFunc(render); // Set idle callback to the render function glutMainLoop(); // loop while waiting for messages // by default, window will respond // to resize, move and close events return 0; // return 0 indicates program exited OK }