/* picking.c */ /* Purpose : view vectors & create normals */ #ifdef __APPLE__ #include #else #include #endif #include #include #include #define KEY_ESC 27 /* New types */ typedef struct ViewInfo ViewInfo; struct ViewInfo { GLfloat radius; GLfloat angle; GLfloat elevation; }; /* Module level variables and constants */ static const int mMaxSize = 3; static ViewInfo mViewInfo = { 1.5, /* radius */ 0.0, /* angle */ 0.0, /* elevation */ }; /* Functions */ GLvoid checkError( const char* const label ) { GLenum error; error = glGetError(); while ( GL_NO_ERROR != error ) { fprintf( stderr,"%s: %s\n", label, (char*) gluErrorString(error) ); error = glGetError(); } } void reshape( GLint width, GLint height ) { /* We still want the output to cover the whole window */ glViewport( 0, 0, width, height ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); glOrtho( -mMaxSize, mMaxSize, -mMaxSize, mMaxSize, -mMaxSize, mMaxSize ); glMatrixMode( GL_MODELVIEW ); } GLvoid keyboard( GLubyte key, GLint x, GLint y) { switch (key) { case KEY_ESC: /* exit when escape key is pressed */ exit(0); break; case 'a': case 'A': mViewInfo.elevation += 2.0; break; case 'z': case 'Z': mViewInfo.elevation -= 2.0; break; } glutPostRedisplay(); } void specialkeys( GLint key, GLint xpos, GLint ypos ) { switch( key ) { case GLUT_KEY_LEFT: /* move left */ mViewInfo.angle += 2.0; break; case GLUT_KEY_RIGHT: /* move left */ mViewInfo.angle -= 2.0; break; } glutPostRedisplay(); } /* Make a graphical representation of a vector */ void drawVec( const float vec[3] ) { glBegin( GL_LINES ); glVertex3f( 0.0, 0.0, 0.0 ); glVertex3fv( vec ); glEnd(); } /* retVec = v1 x v2 Caller is responsible for allocation retVec space. */ void crossProduct( float retVec[3], const float v1[3], const float v2[3]) { retVec[0] = v1[1]*v2[2] - v1[2]*v2[1]; retVec[1] = v1[2]*v2[0] - v1[0]*v2[2]; retVec[2] = v1[0]*v2[1] - v1[1]*v2[0]; } /* Take a c-string and display it at raster location (x,y,z) */ void displayStr(const char* const str, const GLfloat x, const GLfloat y, const GLfloat z) { /* choose what font we wish to use */ void* fontName = GLUT_BITMAP_HELVETICA_18; unsigned int index = 0; /* where do we want the text to go */ glRasterPos3f(x, y, z); /* Display the string on the screen */ while( str[index] != 0 && index < 1000 ) { if( '\t' != str[index] ) { glutBitmapCharacter( fontName, str[index] ); } else { int loop; for( loop = 0; loop < 8; ++loop ) glutBitmapCharacter( fontName, ' ' ); } ++index; } } void drawAxes( void ) { glColor3f( 0.0, 0.0, 1.0 ); glBegin( GL_LINES ); glVertex3f( 0.0, 0.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glEnd(); displayStr( "x", 1.2, 0.0, 0.0 ); displayStr( "y", 0.0, 1.2, 0.0 ); displayStr( "z", 0.0, 0.0, 1.2 ); } /* Draw a simple scene with three objects. */ void drawScene( void ) { glLoadIdentity(); /* Reset the ModelView transformation every time we draw */ /* set up viewing position */ glTranslatef( 0, 0, -mViewInfo.radius ); glRotatef( mViewInfo.elevation, 1, 0, 0 ); glRotatef( mViewInfo.angle, 0, 1, 0 ); drawAxes(); /* draw here */ { float v1[3] = { 1.0, 0.0, 1.0 }; float v2[3] = { 1.0, 1.0, 0.0 }; float normal[3]; glColor3f( 0.0, 1.0, 1.0 ); drawVec( v1 ); drawVec( v2 ); glColor3f( 1.0, 0.0, 0.0 ); crossProduct( normal, v1, v2 ); drawVec( normal ); } } GLvoid display( GLvoid ) { /* Do all your OpenGL rendering here */ glClear( GL_COLOR_BUFFER_BIT ); /* Draw some objects for picking */ drawScene(); /* Don't check errors every frame - expensive. Only do it while debugging. */ checkError( "display" ); glFlush(); } void init( void ) { glClearColor( 0.0, 0.0, 0.0, 1.0 ); glLineWidth( 3.0 ); } int main( int argc, char* argv[] ) { glutInit( &argc, argv ); glutInitDisplayMode( GLUT_RGBA ); glutCreateWindow( argv[0] ); glutDisplayFunc( display ); glutKeyboardFunc( keyboard ); glutReshapeFunc( reshape ); glutSpecialFunc( specialkeys ); init(); glutMainLoop(); return 0; }