#include #include #ifdef _WIN32 #include #else #include #endif #include #ifndef M_PI // for Windows #define M_PI 3.14159265358979323846 #endif #define SGN(y) ((y < 0) ? -1 : (y > 0)) ////////////////////////////////////////////////////////////// // Fenster Initialisierung ////////////////////////////////////////////////////////////// //! Die Startposition des Fensters #define WIN_POS_X 0 #define WIN_POS_Y 0 //! Breite des Fensters #define WIN_WIDTH 1000 //! Hoehe des Fensters #define WIN_HEIGHT 1000 ////////////////////////////////////////////////////////////// // OpenGL Darstellungsmodus ////////////////////////////////////////////////////////////// //! Default OpenGL Modus: RGBA mit double Buffering und //! depth buffer (Z-Buffer) #define USED_MODUS GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE //! Single buffering mit RGBA modus und depth Buffer //#define USED_MODUS GLUT_RGBA | GLUT_DEPTH | GLUT_SINGLE //! Verwendung des Accumulator Buffers //#define USED_MODUS USED_MODUS | GLUT_ACCUM //! Verwendung des Stencil Buffers //#define USED_MODUS USED_MODUS | GLUT_STENCIL //! Verwendung des Stereo Window //#define USED_MODUS USED_MODUS | GLUT_STEREO //! Multisampling Support //#define USED_MODUS USED_MODUS | GLUT_MULTISAMPLE ///////////////////////////////////////////////////////////// // Menuelemente ///////////////////////////////////////////////////////////// #define MENU_LIGHTINGMode "Beleuchtung an / aus" #define MENU_AMBIENTLight "Ambientes Licht auswählen" #define MENU_POINTLight "Punktlichtquelle auswählen" #define MENU_SPOTLight "Spotlicht auswählen" #define MENU_DIRECTIONALLight "Direktionales Licht auswählen" #define MENU_LOCAL_VIEWER "Local Viewer an / aus" #define MENU_TWOSIDE "Twoside an / aus" #define MENU_FLAMMEN "Kerzen an / aus" #define MENU_EXIT "Exit" #define ID_MENU_LIGHTINGMode 1 #define ID_MENU_AMBIENTLight 2 #define ID_MENU_POINTLight 3 #define ID_MENU_SPOTLight 4 #define ID_MENU_DIRECTIONALLight 5 #define ID_MENU_LOCAL_VIEWER 7 #define ID_MENU_TWOSIDE 8 #define ID_MENU_FLAMMEN 9 #define ID_MENU_EXIT 6 ////////////////////////////////////////////////////////////// // Programanhaengige Konstanten und Variablen ///////////////////////////////////////////////////////////// #define PROG_NAME "Template for OpenGL" int MainWin; // Identifier vom Hauptfenster int MainMenu; // Identifier vom Hauptmenu //! Struktur fuer Bearbeitung der Mausevents struct MouseStruct { int LastState; int OldX; int OldY; int ScreenX; int ScreenY; int MoveX; int MoveY; double Radius; } globMouse; ///////////////////////////////////////////////////////////// // Funktionen und Prozeduren ///////////////////////////////////////////////////////////// void MenuFuncFile (int); void DisplayFunc (); void ReshapeFunc (int,int); void MouseFunc (int,int,int,int); void MouseMove (int,int); void KeyboardFunc (unsigned char,int,int); void SpecialFunc (int,int,int); void IdleFunc (); void DrawKoordSystem (GLfloat,GLfloat,GLfloat,GLfloat,GLfloat,GLfloat); void Initialisierung_Beleuchtung(void); void Zeichne_Szene(void); // // Resize CALLBACK Funktion - wird aufgerufen, wenn sich die // Fenstergroesse aendert // w,h: neue Breite und Hoehe des Fensters // void ReshapeFunc (int w,int h) { h = (h == 0) ? 1 : h; w = (w == 0) ? 1 : w; glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective (60, (GLfloat) w / h, 1, 100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); glViewport (0, 0, w, h); globMouse.ScreenX = w; globMouse.ScreenY = h; } // // Maus Button CALLBACK Funktion // void MouseFunc (int button,int state,int x,int y) { switch (button) { // Linke Taste case GLUT_LEFT_BUTTON: if (state == GLUT_DOWN) { globMouse.LastState = state; globMouse.OldX = x; globMouse.OldY = y; } if (state == GLUT_UP) globMouse.LastState = -1; break; // Mittlere Taste case GLUT_MIDDLE_BUTTON: break; // Rechte Taste case GLUT_RIGHT_BUTTON: break; } } // // Maus Movement CALLBACK Funktion, wenn das Mausbutton gedrueckt // wurde. Fuer reine Mausbewegung muss man GlutPassiveMotionFunc // einstellen. // void MouseMove (int x,int y) { switch (globMouse.LastState) { case GLUT_LEFT_BUTTON: globMouse.MoveX += x - globMouse.OldX; globMouse.MoveY += y - globMouse.OldY; globMouse.OldX = x; globMouse.OldY = y; glutPostRedisplay (); break; case GLUT_MIDDLE_BUTTON: break; case GLUT_RIGHT_BUTTON: break; } } // // CALLBACK Funktion fuer Idle: wird aufgerufen, wenn die CPU nichts // anderes zu tun hat: sehr oft verwendet fuer Animation // void IdleFunc () { } // // Prozedur fuer Zeichnen eines Koordinatensystemes // void DrawKoordSystem (GLfloat xmin, GLfloat xmax, GLfloat ymin, GLfloat ymax, GLfloat zmin, GLfloat zmax) { GLfloat i; GLfloat akt_color[4]; GLUquadricObj *spitze; GLint akt_mode; glPushAttrib(GL_ALL_ATTRIB_BITS); glGetFloatv(GL_CURRENT_COLOR, akt_color); glBegin(GL_LINES); glColor3f ( 1.0, 0.0, 0.0 ); glVertex3f (xmin,0,0); glVertex3f (xmax,0,0); for (i = xmin; i <= xmax; i++) { glVertex3f(i, -0.15, 0.0); glVertex3f(i, 0.15, 0.0); } glColor3f ( 0.0, 1.0, 0.0 ); glVertex3f (0,ymin,0); glVertex3f (0,ymax,0); for (i = ymin; i <= ymax; i++) { glVertex3f (-0.15, i, 0.0); glVertex3f (0.15, i, 0.0); } glColor3f ( 0.0, 0.0, 1.0 ); glVertex3f (0,0,zmin); glVertex3f (0,0,zmax); for (i = zmin; i <= zmax; i++) { glVertex3f(-0.15, 0.0, i); glVertex3f(0.15, 0.0, i); } glEnd(); // Ende Linienpaare glGetIntegerv(GL_MATRIX_MODE, &akt_mode); glMatrixMode(GL_MODELVIEW); // zuerst die X-Achse glPushMatrix(); glTranslatef(xmax, 0., 0.); glRotatef(90., 0., 1., 0.); glColor3f( 1.0, 0.0, 0.0 ); spitze = gluNewQuadric(); gluCylinder(spitze, 0.5, 0., 1., 10, 10); gluDeleteQuadric(spitze); glPopMatrix(); // dann die Y-Achse glPushMatrix(); glTranslatef(0., ymax, 0.); glRotatef(-90., 1., 0., 0.); glColor3f( 0.0, 1.0, 0.0 ); spitze = gluNewQuadric(); gluCylinder(spitze, 0.5, 0., 1., 10, 10); gluDeleteQuadric(spitze); glPopMatrix(); // zum Schluss die Z-Achse glPushMatrix(); glTranslatef(0., 0., zmax); // glRotatef(-90., 1., 0., 0.); glColor3f( 0.0, 0.0, 1.0 ); spitze = gluNewQuadric(); gluCylinder(spitze, 0.5, 0., 1., 10, 10); gluDeleteQuadric(spitze); glPopMatrix(); glMatrixMode(akt_mode); glColor4fv(akt_color); glPopAttrib(); } ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// //////////////// HIER GEHT`LOS ///////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////// // // Display CALLBACK Funktion - wird immer aufgerufen, wenn der // Inhalt des Viewport aktualisiert werden muss (z.B. nach // Aufruf der Funktion 'glutPostRedisplay ()' // void DisplayFunc () { // Buffer neu initialisieren glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glMatrixMode (GL_MODELVIEW); glLoadIdentity (); // Ansichtstransformationen double The,Phi; Phi = (double)globMouse.MoveX / (double)globMouse.ScreenX * M_PI * 2.0; The = (double)globMouse.MoveY / (double)globMouse.ScreenY * M_PI * 2.0; /* double x, y, z; x = globMouse.Radius * cos (Phi) * cos (The); y = globMouse.Radius * sin (The); z = globMouse.Radius * sin (Phi) * cos (The); gluLookAt (x,y,z, 0,0,0, 0, 1,0); */ glTranslatef(0, 0, -1 * globMouse.Radius); glRotatef(45 * Phi, 0, 1, 0); glRotatef(45 * The, 1, 0, 0); // Modellierungstransformationen und Ausgabe des Modells /////////////////////////////////////////////////////////////////////////////////////////////////// ///////// hier ansetzen /////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////// glDisable(GL_LIGHTING); DrawKoordSystem (-10, 10, -10, 13, -10, 10); // Setzen_Beleuchtung(); Zeichne_Szene(); glFlush (); // Daten an Server (fuer die Darstellung) // schicken glutSwapBuffers(); // Buffers wechseln } // // Anfang des OpenGL Programmes // int main (int argc,char **argv) { // Fensterinitialisierung glutInit (&argc,argv); glutInitWindowSize (WIN_WIDTH,WIN_HEIGHT); glutInitWindowPosition (WIN_POS_X,WIN_POS_Y); glutInitDisplayMode (USED_MODUS); MainWin = glutCreateWindow (PROG_NAME); // Initialisierung der Darstellung glClearColor (0, 0, 0, 0); glClearDepth (1.0); glEnable (GL_DEPTH_TEST); glDepthFunc (GL_LEQUAL); glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glPolygonMode (GL_FRONT_AND_BACK,GL_FILL); // Menu erzeugen MainMenu = glutCreateMenu (MenuFuncFile); glutAddMenuEntry (MENU_LIGHTINGMode, ID_MENU_LIGHTINGMode); glutAddMenuEntry (MENU_AMBIENTLight, ID_MENU_AMBIENTLight); glutAddMenuEntry (MENU_POINTLight, ID_MENU_POINTLight); glutAddMenuEntry (MENU_SPOTLight, ID_MENU_SPOTLight); glutAddMenuEntry (MENU_DIRECTIONALLight, ID_MENU_DIRECTIONALLight); glutAddMenuEntry (MENU_TWOSIDE, ID_MENU_TWOSIDE); glutAddMenuEntry (MENU_LOCAL_VIEWER, ID_MENU_LOCAL_VIEWER); glutAddMenuEntry (MENU_FLAMMEN, ID_MENU_FLAMMEN); glutAddMenuEntry (MENU_EXIT,ID_MENU_EXIT); glutAttachMenu (GLUT_RIGHT_BUTTON); // Menu ist mapped auf // rechte Maustaste // Callback funktion glutDisplayFunc (DisplayFunc); glutReshapeFunc (ReshapeFunc); glutMouseFunc (MouseFunc); glutMotionFunc (MouseMove); glutKeyboardFunc (KeyboardFunc); glutSpecialFunc (SpecialFunc); glutIdleFunc (DisplayFunc); globMouse.LastState = -1; globMouse.MoveX = 45; globMouse.MoveY = 45; globMouse.Radius = 30; Initialisierung_Beleuchtung(); glEnable(GL_NORMALIZE); // Die Hauptschleife glutMainLoop (); return 0; } /////////////////////////////////////////////////////////////////////// // // Menu CALLBACK Funktion // static enum Lichtquellen { Point, Spot, Direction, Ambient } aktives_licht = Ambient; static GLenum gl_light = GL_LIGHT0; static GLint two_side = GL_FALSE; static GLint local_viewer = GL_FALSE; static GLint flammen_an = GL_TRUE; static bool beleuchtungsmodus = true; // Beleuchtung an / aus void MenuFuncFile (int Item) { switch (Item) { case ID_MENU_EXIT: exit (0); break; case ID_MENU_LIGHTINGMode: if (beleuchtungsmodus) { printf("Beleuchtungsmodus AUS ---> FARBEN werden benutzt\n"); beleuchtungsmodus = false; } else { printf("Beleuchtungsmodus AN ---> MATERIALIEN werden benutzt\n"); beleuchtungsmodus = true; } break; case ID_MENU_AMBIENTLight: printf("Aktives Licht: Globales Ambientes Licht\n"); aktives_licht = Ambient; break; case ID_MENU_POINTLight: printf("Aktives Licht: Punktlicht\n"); aktives_licht = Point; gl_light = GL_LIGHT0; break; case ID_MENU_SPOTLight: printf("Aktives Licht: Spotlicht\n"); aktives_licht = Spot; gl_light = GL_LIGHT1; break; case ID_MENU_DIRECTIONALLight: printf("Aktives Licht: direktionales, paralleles Licht\n"); aktives_licht = Direction; gl_light = GL_LIGHT2; break; case ID_MENU_TWOSIDE: if (two_side == GL_FALSE) { printf("TWO_SIDE ist nun angeschaltet.\n"); two_side = GL_TRUE; } else { printf("TWO_SIDE ist nun ausgeschaltet.\n"); two_side = GL_FALSE; }; glLightModeli(GL_LIGHT_MODEL_TWO_SIDE, two_side); break; case ID_MENU_LOCAL_VIEWER: if (local_viewer == GL_FALSE) { printf("LOCAL_VIEWER ist nun angeschaltet.\n"); local_viewer = GL_TRUE; } else { printf("LOCAL_VIEWER ist nun ausgeschaltet.\n"); local_viewer = GL_FALSE; }; glLightModeli(GL_LIGHT_MODEL_LOCAL_VIEWER, local_viewer); break; case ID_MENU_FLAMMEN: if (flammen_an == GL_FALSE) { printf("KERZEN sind nun angeschaltet.\n"); flammen_an = GL_TRUE; } else { printf("KERZEN sind nun ausgeschaltet.\n"); flammen_an = GL_FALSE; } break; } } struct lichtparameter { bool angeschaltet; // das Licht ist an / aus GLfloat position[4]; // x, y, z, w - Koordinate (w = 1) bzw. Richtung (w = 0) GLfloat spot_direction[3]; // Hauptstrahlrichtung des Spots GLfloat spot_cutoff, spot_exponent; // Cutoff und Exponent, nur für Spots GLfloat spin_horizontal, spin_vertikal; // Drehwinkel GLfloat ambienter_anteil[4], diffuser_anteil[4], spekularer_anteil[4]; // Spezifikation } lichter[4]; void Initialisierung_Beleuchtung(void) { // Lichtquellen initialisieren // ambientes Licht, nur ambienter Lichtanteil ist relevant lichter[Ambient].angeschaltet = false; lichter[Ambient].ambienter_anteil[0] = 0.1; lichter[Ambient].ambienter_anteil[1] = 0.1; lichter[Ambient].ambienter_anteil[2] = 0.1; lichter[Ambient].ambienter_anteil[3] = 1.0; // Point lichter[Point].angeschaltet = false; lichter[Point].spin_horizontal = 0; lichter[Point].spin_vertikal = 0; lichter[Point].position[0] = 0; lichter[Point].position[1] = 0; lichter[Point].position[2] = 15; lichter[Point].position[3] = 1.0; lichter[Point].ambienter_anteil[0] = 0.2; lichter[Point].ambienter_anteil[1] = 0.2; lichter[Point].ambienter_anteil[2] = 0.2; lichter[Point].ambienter_anteil[3] = 1.0; lichter[Point].diffuser_anteil[0] = 0.9; lichter[Point].diffuser_anteil[1] = 0.9; lichter[Point].diffuser_anteil[2] = 0.9; lichter[Point].diffuser_anteil[3] = 1.0; lichter[Point].spekularer_anteil[0] = 0.9; lichter[Point].spekularer_anteil[1] = 0.9; lichter[Point].spekularer_anteil[2] = 0.9; lichter[Point].spekularer_anteil[3] = 1.0; // Spot lichter[Spot].angeschaltet = false; lichter[Spot].spin_horizontal = 0; lichter[Spot].spin_vertikal = 0; lichter[Spot].position[0] = 0; lichter[Spot].position[1] = 0; lichter[Spot].position[2] = 15; lichter[Spot].position[3] = 1.0; lichter[Spot].spot_direction[0] = 0; lichter[Spot].spot_direction[1] = 0; lichter[Spot].spot_direction[2] = -1; lichter[Spot].spot_cutoff = 20; // [0..90], 180 lichter[Spot].spot_exponent = 64; // [0..128] lichter[Spot].ambienter_anteil[0] = 0.0; lichter[Spot].ambienter_anteil[1] = 0.0; lichter[Spot].ambienter_anteil[2] = 0.0; lichter[Spot].ambienter_anteil[3] = 1.0; lichter[Spot].diffuser_anteil[0] = 0.9; lichter[Spot].diffuser_anteil[1] = 0.9; lichter[Spot].diffuser_anteil[2] = 0.9; lichter[Spot].diffuser_anteil[3] = 1.0; lichter[Spot].spekularer_anteil[0] = 0.9; lichter[Spot].spekularer_anteil[1] = 0.9; lichter[Spot].spekularer_anteil[2] = 0.9; lichter[Spot].spekularer_anteil[3] = 1.0; // Direction lichter[Direction].angeschaltet = false; lichter[Direction].spin_horizontal = 0; lichter[Direction].spin_vertikal = 0; lichter[Direction].position[0] = 0; lichter[Direction].position[1] = 0; lichter[Direction].position[2] = 15; lichter[Direction].position[3] = 0.0; lichter[Direction].ambienter_anteil[0] = 0.4; lichter[Direction].ambienter_anteil[1] = 0.4; lichter[Direction].ambienter_anteil[2] = 0.4; lichter[Direction].ambienter_anteil[3] = 1.0; lichter[Direction].diffuser_anteil[0] = 0.9; lichter[Direction].diffuser_anteil[1] = 0.9; lichter[Direction].diffuser_anteil[2] = 0.9; lichter[Direction].diffuser_anteil[3] = 1.0; lichter[Direction].spekularer_anteil[0] = 0.9; lichter[Direction].spekularer_anteil[1] = 0.9; lichter[Direction].spekularer_anteil[2] = 0.9; lichter[Direction].spekularer_anteil[3] = 1.0; }; void Setzen_Beleuchtung(void) { GLfloat ambient_aus[] = {0,0,0,1}; // Statusvariablen auswerten // Licht an / aus ? if (beleuchtungsmodus) { if (aktives_licht == Ambient) // ambientes Licht einstellen if (lichter[aktives_licht].angeschaltet) glLightModelfv(GL_LIGHT_MODEL_AMBIENT, lichter[Ambient].ambienter_anteil); else glLightModelfv(GL_LIGHT_MODEL_AMBIENT, ambient_aus); else { if (lichter[aktives_licht].angeschaltet) { // indiv. Licht ist angeschaltet glPushMatrix(); glRotatef(lichter[aktives_licht].spin_horizontal, 0, 1, 0); // Position einstellen glRotatef(lichter[aktives_licht].spin_vertikal, 1, 0, 0); glLightfv(gl_light, GL_POSITION, lichter[aktives_licht].position); // Lichtanteile einstellen glLightfv(gl_light, GL_AMBIENT, lichter[aktives_licht].ambienter_anteil); glLightfv(gl_light, GL_DIFFUSE, lichter[aktives_licht].diffuser_anteil); glLightfv(gl_light, GL_SPECULAR, lichter[aktives_licht].spekularer_anteil); if (aktives_licht == Spot) { // nur bei Spot: Richtung, Winkel und Exponent einstellen glLightfv(gl_light, GL_SPOT_DIRECTION, lichter[aktives_licht].spot_direction); glLightf(gl_light, GL_SPOT_CUTOFF, lichter[aktives_licht].spot_cutoff); glLightf(gl_light, GL_SPOT_EXPONENT, lichter[aktives_licht].spot_exponent); } glEnable(gl_light); // das Licht anschalten // Geometrie zeichnen glDisable(GL_LIGHTING); // Beleuchtung komplett abstellen : Farbmodus glColor4fv(lichter[aktives_licht].diffuser_anteil); glTranslatef(lichter[aktives_licht].position[0], lichter[aktives_licht].position[1], lichter[aktives_licht].position[2]); if (aktives_licht == Spot) glutSolidCone(0.1, 1.0, 10, 1); else if (aktives_licht == Point) glutSolidSphere(0.1, 10, 10); else { // Direction glBegin(GL_LINES); for (GLfloat i = -1 ; i <= 1; i+=0.2) for (GLfloat j = -1 ; j <= 1; j+=0.2) { glVertex3f(i,j,0); glVertex3f(i,j,1); } glEnd(); } glPopMatrix(); } else glDisable(gl_light); // das individuelle Licht abschalten }; glEnable(GL_LIGHTING); // die Beleuchtung wieder anschalten } else glDisable(GL_LIGHTING); // die Beleuchtung ausschalten : Farbmodus }; // // Tastatur CALLBACK Funktion // key: Wert der Taste die gedrueckt wurde // x,y: Position des Mauskursors auf dem Viewport // void SpecialFunc (int key,int x,int y) { switch (key) { // Cursor Links case GLUT_KEY_LEFT: lichter[aktives_licht].spin_horizontal--; break; case GLUT_KEY_RIGHT: lichter[aktives_licht].spin_horizontal++; break; case GLUT_KEY_UP: lichter[aktives_licht].spin_vertikal--; break; case GLUT_KEY_DOWN: lichter[aktives_licht].spin_vertikal++; break; case GLUT_KEY_INSERT: if (lichter[aktives_licht].angeschaltet) { lichter[aktives_licht].angeschaltet = false; switch (aktives_licht) { case Ambient : printf("globales ambientes Licht : AUS \n"); break; case Point : printf("Punktlicht : AUS\n"); break; case Spot : printf("Spot : AUS\n"); break; case Direction :printf("gerichtetes Licht : AUS\n"); break; } } else { lichter[aktives_licht].angeschaltet = true; switch (aktives_licht) { case Ambient : printf("globales ambientes Licht : AN \n"); break; case Point : printf("Punktlicht : AN\n"); break; case Spot : printf("Spot : AN\n"); break; case Direction :printf("gerichtetes Licht : AN\n"); break; }; } break; } } // // Tastatur CALLBACK Funktion // key: Wert der Taste die gedrueckt wurde // x,y: Position des Mauskursors auf dem Viewport // void KeyboardFunc (unsigned char key,int x,int y) { switch (key) { // Escape case 27: exit (0); // Initialisierung case 'i': case 'I': globMouse.MoveX = 0; globMouse.MoveY = 0; glutPostRedisplay (); break; case 'a': case 'A': globMouse.Radius++; glutPostRedisplay (); break; case 'y': case 'Y': globMouse.Radius--; glutPostRedisplay (); break; case 'C': lichter[Spot].spot_cutoff++; break; case 'c': lichter[Spot].spot_cutoff--; break; case 'E': lichter[Spot].spot_exponent++; break; case 'e': lichter[Spot].spot_exponent--; break; case 'w': glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break; case 'W': glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break; } } static void zeichne_fluegel(void) { GLUquadricObj *q; q = gluNewQuadric(); glColor3f(0.5, 0.5, 0.5); gluPartialDisk(q, 0.5, 6, 10, 10, -15, 30); gluDeleteQuadric(q); }; static void zeichne_fluegelrad(void){ GLUquadricObj *q; q = gluNewQuadric(); glColor3f(0.6, 0.6, 0.6); gluSphere(q, 0.5, 20, 20); for (int winkel = 0; winkel < 360 ; winkel += 45) { glPushMatrix(); glRotatef(winkel, 0, 0, 1); glRotatef(15, 0, 1, 0); zeichne_fluegel(); glPopMatrix(); }; gluDeleteQuadric(q); }; static void zeichne_teller(void) { GLUquadricObj *q; q = gluNewQuadric(); glColor3f(0.6, 0.4, 0.1); gluDisk(q, 0.2, 4, 30, 10); for (int i = 0; i < 360; i += 90) { glRotatef(i, 0, 0, 1); glPushMatrix(); glTranslatef(0, 2.5, 0.76); glRotatef(90, 1, 0, 0); glColor3f(0.3, 0.6, 0.8); // 2 Clip-Planes Setzen, BOOLSCHES UND der Halbräume // wird gezeichnet GLdouble plane1[4] = {0,0,1,0}; // {a,b,c,d} --> 0 = ax + by +cz +d glPushMatrix(); // ClipPlanes sind transformierbar glRotatef(45,1,0,0); glClipPlane(GL_CLIP_PLANE1, plane1); glEnable(GL_CLIP_PLANE1); glPopMatrix(); GLdouble plane2[4] = {1,0,0,0.75}; glClipPlane(GL_CLIP_PLANE2, plane2); glEnable(GL_CLIP_PLANE2); glFrontFace(GL_CW); // Teapot korrekt zeichnen, Vorderseite = aussen glutSolidTeapot(1); glFrontFace(GL_CCW); glDisable(GL_CLIP_PLANE1); glDisable(GL_CLIP_PLANE2); gluSphere(q,0.3,50,50); // eine Kugel im Inneren des Teapots, nicht geclippt glPopMatrix(); }; gluDeleteQuadric(q); }; void zeichne_drehbar(void) { GLUquadricObj *q; q = gluNewQuadric(); glColor3f(0.6, 0.6, 0.6); glPushMatrix(); glTranslatef(0, 1, 0); glRotatef(-90, 1, 0, 0); zeichne_teller(); glColor3f(0.6, 0.6, 0.4); gluCylinder(q, 0.2, 0.2, 9, 20, 20); glPopMatrix(); glPushMatrix(); glTranslatef( 0, 10, 0); glRotatef(-90, 1, 0, 0); zeichne_fluegelrad(); glPopMatrix(); gluDeleteQuadric(q); }; void zeichne_pyramiden_licht(void) { GLUquadricObj *q = gluNewQuadric(); GLfloat mat1_ambient[] = { 0.2, 0.2, 0.2, 1 }; GLfloat mat1_diffuse[] = { 0.5, 0.5, 0.1, 1 }; GLfloat mat1_specular[] = { 0.8, 0.8, 0.3, 1 }; GLfloat mat1_emission[] = { 0.8, 0.8, 0.2, 1 }; GLfloat mat1_emission_aus[] = { 0, 0, 0, 1}; GLfloat mat1_shininess = 64; glColor3f(0.7, 0.7, 0.3); glPushMatrix(); glRotatef(90, 0, 1, 0); gluCylinder(q, 0.2, 0.2, 5, 10, 10); glPopMatrix(); glPushMatrix(); glTranslatef(5, 0, 0); glRotatef(-90, 1, 0, 0); glColor3f(0.8, 0.8, 0.4); gluDisk(q, 0, 0.5, 10, 10); gluCylinder(q, 0.5, 0.75, 0.5, 10, 10); // Tülle glTranslatef(0, 0, 0.5); glColor3f(0.8, 0.8, 0.8); gluCylinder(q, 0.3, 0.3, 1, 10, 10); // Kerze glScalef(0.6, 0.6, 1.5); glTranslatef(0, 0, 1.3); glColor3f(1,1,0); //gluQuadricDrawStyle(q, GLU_LINE); if (flammen_an) { glMaterialfv(GL_FRONT_AND_BACK, GL_AMBIENT, mat1_ambient); glMaterialfv(GL_FRONT_AND_BACK, GL_DIFFUSE, mat1_diffuse); glMaterialfv(GL_FRONT_AND_BACK, GL_SPECULAR, mat1_specular); glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat1_emission); glMaterialf (GL_FRONT_AND_BACK, GL_SHININESS, mat1_shininess); } gluSphere(q, 0.6, 5, 5); // Flamme glMaterialfv(GL_FRONT_AND_BACK, GL_EMISSION, mat1_emission_aus); glPopMatrix(); gluDeleteQuadric(q); }; void zeichne_stuetzen(void) { GLUquadricObj *q = gluNewQuadric(); glColor3f(0.7, 0.7, 0.5); gluCylinder(q, 0.15, 0.1, 9, 20, 20); gluDeleteQuadric(q); }; static int winkel = 0; //////////////////////////////////////////////////////////////////////// void Zeichne_Szene(void) { GLfloat mat1_ambient[] = { 0.2, 0.2, 0.2, 1 }; GLfloat mat1_diffuse[] = { 0.5, 0.5, 0.1, 1 }; GLfloat mat1_specular[] = { 0.8, 0.8, 0.3, 1 }; GLfloat mat1_emission[] = { 0.0, 0.0, 0.0, 1 }; GLfloat mat1_shininess = 64; GLfloat mat2_ambient[] = { 0.2, 0.2, 0.2, 1 }; GLfloat mat2_diffuse[] = { 0.8, 0.1, 0.1, 1 }; GLfloat mat2_specular[] = { 1.0, 0.5, 0.5, 1 }; GLfloat mat2_emission[] = { 0.0, 0.0, 0.0, 1 }; GLfloat mat2_shininess = 128; GLfloat mat3_ambient[] = { 0.2, 0.2, 0.2, 1 }; GLfloat mat3_diffuse[] = { 0.1, 0.1, 0.7, 1 }; GLfloat mat3_specular[] = { 0.5, 0.5, 0.7, 1 }; GLfloat mat3_emission[] = { 0.0, 0.0, 0.0, 1 }; GLfloat mat3_shininess = 10; Setzen_Beleuchtung(); // Lichtquellen in den Lichtern der Pyramide setzen const GLfloat position[] = {0, 0, 0, 1}; const GLfloat ambient[] = {0.1, 0.1, 0.1, 1}; const GLfloat diffuse[] = {1, 1, 1, 1}; const GLfloat specular[] = {1, 1, 1, 1}; GLfloat feld[3][4] = { {0, 0, 0, 1}, {0.1, 0.1, 0.1, 1}, {1, 1, 1, 1} }; if (flammen_an == GL_TRUE) { for (int i = 0; i <= 5; i++) { glPushMatrix(); glRotatef(60 * i, 0,1,0); glTranslatef(5,3,0); glLightfv(GL_LIGHT3+i, GL_POSITION, position); glLightfv(GL_LIGHT3+i, GL_AMBIENT, ambient); glLightfv(GL_LIGHT3+i, GL_DIFFUSE, diffuse); glLightfv(GL_LIGHT3+i, GL_SPECULAR, specular); glLightf (GL_LIGHT3+i, GL_CONSTANT_ATTENUATION, 0.1); glLightf (GL_LIGHT3+i, GL_LINEAR_ATTENUATION, 0.3); glLightf (GL_LIGHT3+i, GL_QUADRATIC_ATTENUATION, 0.2); glColor3f(1,1,0); glutSolidSphere(0.2, 10, 10); glEnable(GL_LIGHT3 + i); glPopMatrix(); } } else { for (int i = 0; i<=5; i++) glDisable(GL_LIGHT3 +i); }; glColorMaterial(GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE); glEnable(GL_COLOR_MATERIAL); for (int i = 0; i < 360; i+= 60) { glPushMatrix(); glTranslatef(0, 0.5, 0); glRotatef(i, 0, 1, 0); zeichne_pyramiden_licht(); if (! (i % 120)) { glPushMatrix(); glRotatef(i, 0, 1, 0); glTranslatef(4.5, 0, 0.); glRotatef(90, 0, 1, 0); glRotatef(-117.5, 1, 0,0); zeichne_stuetzen(); glPopMatrix(); }; glPopMatrix(); } glPushMatrix(); glTranslatef(0, 8.5, 0); glRotatef(90, 1, 0, 0); glutSolidTorus(0.2, 0.4, 20, 20); glPopMatrix(); glPushMatrix(); winkel = winkel % 360; glRotatef(winkel--, 0, 1, 0); zeichne_drehbar(); glPopMatrix(); };