/* melite2b.c - visualizza un pianeta e una navetta in 2D * usando le primitive viste e muove pianeta e navetta con le frecce * * Autore: Andrea Fusiello, Andrea Colombari 2004 * * arrow keys - trasla la telecamera ortografica rispetto a x e y * s key - commuta tra modalita' con shading e flat * SPACE key - accellera * - key - decellera * Escape Key - esce dal programma */ #include /* includes gl.h, glu.h */ #include #include #include /* Function Prototypes */ void initgfx( void ); void keyboard( GLubyte, GLint, GLint ); void specialkeys( GLint, GLint, GLint ); void drawScene( void ); void checkError( char * ); void printHelp( char * ); /* Global Definitions */ GLsizei width, height; GLdouble tx; // x translation GLdouble ty; // y translation GLdouble ar; // aspect ratio GLdouble g_v; // current speed GLboolean flat = GL_TRUE; GLfloat PI; #define KEY_ESC 27 /* ascii value for the escape key */ #define CAM_SPEED_STEP 0.05f /* step di incremento velocita' */ #define CAM_MAX_SPEED 1.0f /* massima velocita' */ int main( int argc, char *argv[] ) { glutInit( &argc, argv ); width = glutGet( GLUT_SCREEN_WIDTH ) / 2; height = glutGet( GLUT_SCREEN_HEIGHT ) / 2; // Importante, fate una conversione esplicita in float di width e height, altrimenti farebbe una divisione tra interi. // In c: 800 / 600 con divisione intera = 1, 800.0f / 600.0f = 1.3333333 ar = (float)width/(float)height; printf("Width: %d Height: %d Aspect Ratio: %f \n", width, height, ar); glutInitWindowPosition( width / 2, height / 2 ); glutInitWindowSize( width, height ); glutInitDisplayMode( GLUT_RGBA ); glutCreateWindow( argv[0] ); initgfx(); glutKeyboardFunc( keyboard ); glutSpecialFunc( specialkeys ); glutDisplayFunc( drawScene ); printHelp( argv[0] ); glutMainLoop(); return(0); } /* ----------------------------------------------------------*/ void printHelp( char *progname ) { fprintf(stdout, "\n%s - elite in 2D with moving orthographic camera\n\n" "arrow keys - translate the orthographic camera in x and y directions\n" " key - toggle smooth/flat shading\n" "SPACE key - speed up\n" "- key - slow down\n" "Escape Key - exit the program\n\n", progname); } /* ----------------------------------------------------------*/ void initgfx( void ) { /* set clear color to black */ glClearColor( 0.0, 0.0, 0.0, 1.0 ); ty = 0; tx = 0; g_v = CAM_MAX_SPEED/2.0f; PI = acos(-1.0); } /* ----------------------------------------------------------*/ void checkError( char *label ) { GLenum error; while ( (error = glGetError()) != GL_NO_ERROR ) printf( "%s: %s\n", label, gluErrorString(error) ); } /* ----------------------------------------------------------*/ void keyboard( GLubyte key, GLint x, GLint y ) { switch (key) { case 's': /* s key */ if (flat) glShadeModel( GL_FLAT ); else glShadeModel( GL_SMOOTH ); glutPostRedisplay(); /* toggle between smooth and flat shading */ flat = !flat; break; case ' ': if (g_v+CAM_SPEED_STEP <= CAM_MAX_SPEED) g_v+=CAM_SPEED_STEP; glutPostRedisplay(); break; case '-': if (g_v > 0) g_v-=CAM_SPEED_STEP; glutPostRedisplay(); break; case KEY_ESC: /* Exit when the Escape key is pressed */ exit(0); } } /* ----------------------------------------------------------*/ void specialkeys( GLint key, GLint u, GLint v ) { switch (key) { case GLUT_KEY_UP: ty += g_v; glutPostRedisplay(); break; case GLUT_KEY_DOWN: ty -= g_v; glutPostRedisplay(); break; case GLUT_KEY_LEFT: tx -= g_v; glutPostRedisplay(); break; case GLUT_KEY_RIGHT: tx += g_v; glutPostRedisplay(); break; } } /* ----------------------------------------------------------*/ void drawScene( void ) { static GLfloat yellow[] = { 1.0f, 1.0f, 0.0f }; static GLfloat darkgreen[] = { 0.0f, 0.25f, 0.0f }; static GLfloat blue[] = { 0.0f, 0.0f, 1.0f }; static GLfloat grey[] = { 0.5f, 0.5f, 0.5f }; GLint t; /* Do all your OpenGL rendering here */ glClear( GL_COLOR_BUFFER_BIT ); /* ora andiamo a modificare lo stack in gl_projection - in questo punto dovrebbe essere cariacta la matrice identità */ glMatrixMode( GL_PROJECTION ); /* salvo contenuto dello stack di proiezione per evitare l'accumulo di trasformazioni */ glPushMatrix(); /* definisco il volume di vista in base alla traslazione effettuata */ gluOrtho2D( (4.0f * ar) + tx, (-4.0f * ar) + tx, (4.0f) + ty, (-4.0f) + ty ); // Alternativamente gluOrtho2D( (4.0f) + tx, (-4.0f) + tx, (4.0f/ar) + ty, (-4.0f/ar) + ty ); /* ora andiamo a modificare lo stack in modelview */ glMatrixMode( GL_MODELVIEW ); /* salvo il contenuto */ glPushMatrix(); /* Draw a triangle fan for the planet; make * the center yellow, and the edges darkgreen */ glBegin( GL_TRIANGLE_FAN ); glColor3fv( yellow ); glVertex2f( 0, 0 ); glColor3fv( darkgreen ); for(t=0; t<=200; t++) glVertex2f(1.5*cos(t/200.0*2*PI), 1.5*sin(t/200.0*2*PI)); glEnd(); /* Draw a triangle strip for the spaceship; * use your fantasy to give it a shape * and use two different color for shading */ glBegin( GL_TRIANGLE_FAN ); glColor3fv( blue ); glVertex2f( 2.1f, 2.0f ); glColor3fv( grey ); glVertex2f( 2.2f, 2.2f ); glVertex2f( 1.8f, 2.0f ); glVertex2f( 2.2f, 1.8f ); glVertex2f( 2.1f, 2.0f ); glEnd(); /* Ripristino il contenuto precedentemnte salvata in GL_MODELVIEW (matrice identità)*/ glPopMatrix(); glMatrixMode( GL_PROJECTION ); /* Ripristino il contenuto precedentemnte salvata in GL_PROJECTION (matrice identità)*/ glPopMatrix(); /* Alternativamente a glPush-glPop potrei usare glLoadIdentity) */ checkError( "drawScene" ); glFlush(); }