/* melite3b.c - visualizza un pianeta e una navetta in 2D * e in basso alla finestra visualizza pannello di controllo * con radar e barra della velocita': utilizzare le primitive * viste, gli stack di matrici e le trasformazioni base * * 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 #include #include /* segue inclusione di una piccola libreria con alcune definizioni di tipo e utils */ #include "eliteutils.h" #include /* includes gl.h, glu.h */ /* Function Prototypes */ void initgfx( void ); void keyboard( GLubyte, GLint, GLint ); void specialkeys( GLint, GLint, GLint ); void drawScene( void ); void checkError( char * ); void printHelp( char * ); void drawControlPanel(); /* Global Definitions */ GLsizei width, height, ctrl_panel_height; GLdouble tx; GLdouble ty; GLdouble ar; GLdouble g_v; GLboolean flat = GL_TRUE; #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' */ #define FOVx 8 /* field of fiew in0 direction */ #define FOVy (3.0f*(FOVx/4.0f)) /* field of view in y direction with 4:3 proportion */ int main( int argc, char *argv[] ) { glutInit( &argc, argv ); width = glutGet( GLUT_SCREEN_WIDTH ) / 2; height = glutGet( GLUT_SCREEN_HEIGHT ) / 2; ctrl_panel_height = 50; ar = (float)width/(float)height; glutInitWindowPosition( width / 2, height / 2 ); glutInitWindowSize( width, height+ctrl_panel_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 a control panel\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; } /* ----------------------------------------------------------*/ 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 }; /* Do all your OpenGL rendering here */ glClear( GL_COLOR_BUFFER_BIT ); /* attiva il viewport principale */ glViewport( 0, ctrl_panel_height, width, height); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho( tx-FOVx/2.0f, tx+FOVx/2.0f, ty-FOVy/2.0f, ty+FOVy/2.0f, 0.0f, 1.0f ); glMatrixMode(GL_MODELVIEW); glPushMatrix(); /* Draw a triangle fan for the planet; make * the center yellow, and the edges darkgreen */ glBegin( GL_TRIANGLE_FAN ); glColor3fv( yellow ); glVertex3f( 0, 0, 0 ); glColor3fv( darkgreen ); { GLint t; for(t=0; t<=200; t++) glVertex3f(1.5*cos(t/200.0*2*PI), 1.5*sin(t/200.0*2*PI), 0.0f); } 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 ); glVertex3f( 2.1f, 2.0f, 0.0f ); glColor3fv( grey ); glVertex3f( 2.2f, 2.2f, 0.0f ); glVertex3f( 1.8f, 2.0f, 0.0f ); glVertex3f( 2.2f, 1.8f, 0.0f ); glVertex3f( 2.1f, 2.0f, 0.0f ); glEnd(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); /* Attiva il viewport del pannello, in basso */ glViewport( 0, 0, width, ctrl_panel_height); glMatrixMode(GL_PROJECTION); glPushMatrix(); gluOrtho2D(0, (GLfloat)width/ctrl_panel_height, 0, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); drawControlPanel(); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); checkError( "drawScene" ); glFlush(); } /* ----------------------------------------------------------*/ void drawControlPanel() { /* disegna il pannello di controllo in un vieport di altezza 1 e larghezza dipendente da quella della finestra */ GLfloat v; /* velocita' tra 0 e 1; */ GLfloat xr, yr; /* coordinate radar */ /* -- barra della velocita' */ glLineWidth( 1 ); glColor3f( 0, 0, 1); glBegin( GL_LINE_LOOP ); /* quadrato */ glVertex2f(1, 0.5); glVertex2f(2, 0.5); glVertex2f(2, 0); glVertex2f(1, 0); glEnd(); v = (g_v)/(CAM_MAX_SPEED); if ( v < 0.8 ) glColor3f( 1, 1, 0); else glColor3f( 1, 0, 0); glBegin( GL_QUADS); glVertex3f(1.05, 0, 0.1); glVertex3f(1.05, 0.5, 0.1); glVertex3f(1.05+1.0*v, 0.5, 0.1); glVertex3f(1.05+1.0*v, 0, 0.1); glEnd(); /* posizioniamo la scritta */ glColor3f( 0, 0, 1); glRasterPos2f(2.1, 0.1); renderBitmapString(GLUT_BITMAP_HELVETICA_18, "SP"); /* radar */ glColor3f( 0, 0, 1 ); glLineWidth( 0.2 ); glBegin( GL_LINES ); /* cerchio */ { GLint t; for(t=0; t<200; t++) glVertex3f(0.5+0.5*cos(t/200.0*2*PI), 0.5+0.5*sin(t/200.0*2*PI),0.1); } glEnd(); /* crocetta */ glColor3f( 1, 1, 1); glLineWidth( 0.2 ); glBegin( GL_LINES); /* uso la z per disegnarla dietro */ glVertex3f(0.5, 0,-0.1); glVertex3f(0.5, 1,-0.1); glVertex3f(0, 0.5,-0.1); glVertex3f(1, 0.5,-0.1); glEnd(); /* punto rosso */ xr = tx/(3*FOVx); yr = ty/(3*FOVy); if (xr*xr+yr*yr <= 0.25) { glColor3f( 1.0f, 0.0f, 0.0f); glPointSize(4); glBegin(GL_POINTS); glVertex2f(0.5 + xr, 0.5+ yr); glEnd(); } } /* Credits: Riccardo Giannitrapani per la scrittura di bitmap in "eliteutils" Tutorial SGI (quello che c'e' sulla pagina web del lab) in generale */