Created
July 6, 2012 22:18
-
-
Save dlivingstone/3063071 to your computer and use it in GitHub Desktop.
OpenGL demo project: A project that needs lots of fixing and restructuring
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 characters
// 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 | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment