#include #include #include /* Globale Variablen: - aktueller Drehwinkel für 3 Achsen - Art der Projektion: orthogonal oder perspektivisch - Aktuelle Breite und Höhe des Viewports */ float fRotAngleX = 0.0f; float fRotAngleY = 0.0f; float fRotAngleZ = 0.0f; int iOrthoProj = 0; int iWidth = 600; int iHeight = 600; /* GLUT keyboardHandler wird in main() registriert und vom glutMainLoop() aus ausgerufen, falls eine Taste gedrückt wird: - Programmende mit ESC-Taste - x,y,z zur Rotation um jeweilige Achse - p und o für perspektivische vzw. orthogonale Projektion */ void keyboardHandler( unsigned char uKey, int x, int y ) { switch ( uKey ) { case VK_ESCAPE: exit( 0 ); break; case 'x' : fRotAngleX += 1.0; break; case 'y' : fRotAngleY += 1.0; break; case 'z' : fRotAngleZ += 1.0; break; case 'o': iOrthoProj = 1; break; case 'p': iOrthoProj = 0; } glutPostRedisplay(); } /* GLUT resizeHandler wird in main() registriert und vom glutMainLoop() aus ausgerufen, falls die Größe des Fensters und damit des Viewports geändert wird */ void resizeHandler( int iW, int iH ) { iWidth = iW; iHeight = iH; glViewport( 0, 0, (GLsizei)iWidth, (GLsizei)iHeight ); } /* GLUT redrawHandler wird in main() registriert und immer dann aufgerufen, wenn die Grafik neu gezeichnet werden muss, z.B. - implizit nach einem resize - durch expliziten Aufruf von glutPostRedisplay() nach einem Tatstaturereignis */ void redrawHandler() { // Zuerst wird die gegenwärtig aktuelle Projektionsmethode // durch Modifikation der Projektionsmatrix gesetzt glMatrixMode( GL_PROJECTION ); glLoadIdentity(); if (iOrthoProj) glOrtho(-2, 2, -2, 2,-10,20); else gluPerspective(45.0, (float)iWidth/iHeight, 1.0 , 20.0); // Bildschirm und Buffer Löschen glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); // Zurück zur Modellmatrix, Identitätsmatrix laden, // verschieben des Objektes in einen sichtabren Bereich // und drehen auf die aktuelle Drehposition glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glTranslatef( 0.0f, 0.0f, -5.0f ); glRotatef( fRotAngleX, 1.0f, 0.0f, 0.0f ); glRotatef( fRotAngleY, 0.0f, 1.0f, 0.0f ); glRotatef( fRotAngleZ, 0.0f, 0.0f, 1.0f ); // Zeichnen des Würfels auf den Hintergrund-Buffer: // 2 Seitenflächen als Line Loops plus 4 einzelen // Verbindungslinien zwischen den Flächen glBegin(GL_LINE_LOOP); glColor3f(1.0f,1.0f,1.0f); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glEnd(); glBegin(GL_LINE_LOOP); glVertex3f(1.0f, -1.0f, -1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glEnd(); glBegin(GL_LINES); glVertex3f(-1.0f, -1.0f, -1.0f); glVertex3f(1.0f, -1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, -1.0f); glVertex3f(1.0f, 1.0f, -1.0f); glVertex3f(-1.0f, 1.0f, 1.0f); glVertex3f(1.0f, 1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, 1.0f); glVertex3f(1.0f, -1.0f, 1.0f); glEnd(); // Zeichen-Buffer nach vorn holen glutSwapBuffers(); } int main( int argc, char **argv ) { // Initialisierung von GLUT und Erzeugen eines Fensters glutInitDisplayMode( GLUT_RGB | GLUT_DEPTH | GLUT_DOUBLE ); glutInitWindowSize( iWidth, iHeight ); glutInit( &argc, argv ); glutCreateWindow( "Rotierender Würfel" ); // Registrierung der Handler-Funktionen (siehe oben) glutKeyboardFunc( keyboardHandler ); glutReshapeFunc( resizeHandler ); glutDisplayFunc( redrawHandler ); // Die Haupt-Schleife des Programms - ab jetzt wird // alles weitere über den Aufruf der registrierten // Handler-Funktionen gesteuert (inklusive Programm-Exit) glutMainLoop(); return 0; }