sources:


website:
more info here


screenshot:
studies/grafik/Computergrafik-Code2/Aufgabe4/cgsphere.cpp
download file

  1 // Computergrafik I
  2 // Prof. Dr. Juergen Doellner
  3 // Sommersemester 2001
  4 //
  5 // Programmrahmen fuer Aufgabe 4
  6
  7
  8 // Stephan Brumme, 702544
  9 // last changes: May 07, 2001
 10
 11
 12 // ----------------------------------------------------------
 13 // It might be useful to use the class "Vector" presented in
 14 // the exercises
 15 // ----------------------------------------------------------
 16
 17 #include "cgsphere.h"
 18 #include <math.h>
 19
 20
 21
 22 CGSphere::CGSphere() {
 23     // adjust to fit the window
 24     m_fRadius            = 0.95;
 25     m_nTessellationLevel = 6;
 26
 27     m_bUseFlatShade      = true;
 28     m_bUseWireframe      = false;
 29     m_bUseTriangleTessellation = true;
 30 }
 31
 32 CGSphere::~CGSphere() {
 33 }
 34
 35 void CGSphere::onInit() {
 36     // Set background color.
 37     glClearColor(0.4, 0.4, 0.7, 0); // blue
 38
 39     // Set Shading
 40     if (m_bUseFlatShade)
 41        glShadeModel(GL_FLAT);
 42     else        glShadeModel(GL_SMOOTH);
 43
 44     // Enable Lighting
 45     GLfloat am[] = {0.5, 0.5, 0.5, 1.0};
 46     GLfloat df[] = {1.0, 1.0, 1.0, 1.0};
 47     GLfloat sp[] = {0.0, 0.0, 0.0, 1.0};
 48     GLfloat pos[] = {1.0, 1.0, 0.0, 1.0};
 49     glEnable(GL_LIGHTING);
 50     glLightfv(GL_LIGHT0, GL_AMBIENT, am);
 51     glLightfv(GL_LIGHT0, GL_DIFFUSE, df);
 52     glLightfv(GL_LIGHT0, GL_SPECULAR, sp);
 53     glLightfv(GL_LIGHT0, GL_POSITION, pos);
 54     glLightf(GL_LIGHT0, GL_QUADRATIC_ATTENUATION, 0.2);
 55     glEnable(GL_LIGHT0);
 56
 57     // Let OpenGL compute normals automatically
 58     glEnable(GL_NORMALIZE);
 59    
 60     glEnable(GL_DEPTH_TEST);
 61 }
 62
 63 void CGSphere::TessellateTriangle(const Vector& v1, const Vector& v2, const Vector& v3, int nLevel)
 64 {
 65     if (nLevel == 1)
 66     {
 67         // Dreieck zeichnen (eventuell als Drahtgittermodell)
 68         if (m_bUseWireframe)
 69             glBegin(GL_LINE_LOOP);
 70         else             glBegin(GL_TRIANGLES);
 71    
 72         glVertex3f(v1[0], v1[1], v1[2]);
 73         glVertex3f(v2[0], v2[1], v2[2]);
 74         glVertex3f(v3[0], v3[1], v3[2]);
 75         glEnd();
 76     }
 77     else     {
 78         // Mittelpunkte der Seiten bestimmen
 79         Vector s1((v2[0]+v3[0])/2, (v2[1]+v3[1])/2, (v2[2]+v3[2])/2);
 80         Vector s2((v1[0]+v3[0])/2, (v1[1]+v3[1])/2, (v1[2]+v3[2])/2);
 81         Vector s3((v2[0]+v1[0])/2, (v2[1]+v1[1])/2, (v2[2]+v1[2])/2);
 82
 83         // und normalisieren
 84         s1.normalize();
 85         s2.normalize();
 86         s3.normalize();
 87
 88         // weiter tessellieren
 89         TessellateTriangle(s1, s2, s3, nLevel-1);
 90         TessellateTriangle(v1, s3, s2, nLevel-1);
 91         TessellateTriangle(v2, s1, s3, nLevel-1);
 92         TessellateTriangle(v3, s1, s2, nLevel-1);
 93     }
 94 }
 95
 96 void CGSphere::onDraw() {
 97     // Clear framebuffer using background color.
 98     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
 99    
100     // Set current color for drawing.
101     glColor3f (1.0, 1.0, 1.0); // white
102
103     glPushMatrix();
104
105     // Radius anpassen (da eigentlich nur Einheitskugel berechnet)
106     glScalef (m_fRadius, m_fRadius, m_fRadius);
107
108     // urgently needed ...
109     const GLfloat fPi         = 3.1415926;
110
111     if (m_bUseTriangleTessellation)
112     {
113         // triangle tessellation
114
115         // Eckpunkte festlegen
116         const GLfloat fOffset = 1/sqrt(3);
117         Vector v[4] = { Vector( fOffset, fOffset, fOffset),
118                         Vector(-fOffset,-fOffset, fOffset),
119                         Vector(-fOffset, fOffset,-fOffset),
120                         Vector( fOffset,-fOffset,-fOffset)};
121
122         // mit den 4 Seiten des Tetraeders die Tessellation beginnen
123         TessellateTriangle(v[0], v[1], v[2], m_nTessellationLevel);
124         TessellateTriangle(v[0], v[1], v[3], m_nTessellationLevel);
125          TessellateTriangle(v[0], v[2], v[3], m_nTessellationLevel);
126         TessellateTriangle(v[1], v[2], v[3], m_nTessellationLevel);
127     }
128     else     {
129         // quad tessellation
130
131         // Winkelschrittweite
132         const GLfloat fDeltaAlpha =   fPi/m_nTessellationLevel;
133         const GLfloat fDeltaBeta  = 2*fPi/m_nTessellationLevel;
134
135         // "Breitengrade"
136         for (GLfloat fAlpha = -fPi/2; fAlpha < fPi/2; fAlpha += fDeltaAlpha)
137         {
138             // "Längengrade"
139             for (GLfloat fBeta = 0; fBeta < 2*fPi; fBeta += fDeltaBeta)
140             {
141                 // 4 Eckpunkte berechnen
142                 // Formeln in Aufgabe 3 erläutert
143                 Vector v1(cos(fAlpha)*sin(fBeta),
144                           sin(fAlpha),
145                           cos(fAlpha)*cos(fBeta))
;
146
147                 Vector v2(cos(fAlpha+fDeltaAlpha)*sin(fBeta),
148                           sin(fAlpha+fDeltaAlpha),
149                           cos(fAlpha+fDeltaAlpha)*cos(fBeta))
;
150            
151                 Vector v3(cos(fAlpha+fDeltaAlpha)*sin(fBeta+fDeltaBeta),
152                           sin(fAlpha+fDeltaAlpha),
153                           cos(fAlpha+fDeltaAlpha)*cos(fBeta+fDeltaBeta))
;
154            
155                 Vector v4(cos(fAlpha)*sin(fBeta+fDeltaBeta),
156                           sin(fAlpha),
157                           cos(fAlpha)*cos(fBeta+fDeltaBeta))
;
158
159                 // Viereck zeichnen (eventuell als Drahtgittermodell)
160                 if (m_bUseWireframe)
161                     glBegin(GL_LINE_LOOP);
162                 else                     glBegin(GL_QUADS);
163                    
164                 glVertex3f(v1[0], v1[1], v1[2]);
165                 glVertex3f(v2[0], v2[1], v2[2]);
166                 glVertex3f(v3[0], v3[1], v3[2]);
167                 glVertex3f(v4[0], v4[1], v4[2]);
168                 glEnd();
169             }
170         }
171     }
172            
173     glPopMatrix();
174
175     glFlush();
176     // Do not forget to swap front- and backbuffer!
177     swapBuffers();
178 }
179
180 void CGSphere::onKey(unsigned char key) {
181     cout << key << endl;
182     switch (key) {
183         case 'q': exit(0); break; // Quit application.
184
185             // Tessellationsgrad erhöhen
186         case '+': m_nTessellationLevel++;
187                   cout << m_nTessellationLevel << endl;
188                   break;
189
190             // Tessellationsgrad senken
191         case '-': if (m_nTessellationLevel > 1)
192                      m_nTessellationLevel--;
193                   cout << m_nTessellationLevel << endl;
194                   break;
195
196             // Rotationen rückgängig machen
197         case 'r': glLoadIdentity();
198                   break;
199
200             // Shadingmodell umschalten flat/smooth
201         case 's': m_bUseFlatShade = !m_bUseFlatShade;
202                   if (m_bUseFlatShade)
203                      glShadeModel(GL_FLAT);
204                   else                      glShadeModel(GL_SMOOTH);
205                   break;
206
207             // Tessellationsmethode umschalten Dreieck/Viereck
208         case 't': m_bUseTriangleTessellation = !m_bUseTriangleTessellation;
209                   break;
210
211             // umschalten solid/Drahtgitter
212         case 'w': m_bUseWireframe = !m_bUseWireframe;
213                   break;
214
215             // um x-Achse drehen
216         case 'x': glRotated(5, 1, 0, 0);
217                   break;
218         case 'X': glRotated(-5, 1, 0, 0);
219                   break;
220             // um y-Achse drehen
221         case 'y': glRotated(5, 0, 1, 0);
222                   break;
223         case 'Y': glRotated(-5, 0, 1, 0);
224                   break;
225             // um z-Achse drehen
226         case 'z': glRotated(5, 0, 0, 1);
227                   break;
228         case 'Z': glRotated(-5, 0, 0, 1);
229                   break;
230     }
231
232     // Neuzeichnen erzwingen
233     glutPostRedisplay();
234 }
235
236 void CGSphere::onSize(int newWidth, int newHeight) {
237     if((newWidth > 0) && (newHeight > 0)) {
238         // Adjust OpenGL-Viewport according to new window dimensions.
239         glViewport(0, 0, newWidth - 1, newHeight - 1);
240                
241         // Switch to modelview matrix stack and initialize
242         // with identity matrix.
243         glMatrixMode(GL_MODELVIEW);
244         glLoadIdentity();
245     }
246 }
247
248 // main program
249 int main(int argc, char* argv[]) {
250     // Generate an instance of the sample application.
251     CGSphere* sample = new CGSphere();
252    
253     // Starts the sample application.
254     sample->start("CGSphere, Stephan Brumme, 702544");
255     return(0);
256 }
257