sources:
cgapplication.cpp (4.3k)
cgapplication.h (3.2k)
cgsphere.cpp (7.8k)
cgsphere.h (870 bytes)
vector.cpp (553 bytes)
vector.h (1.9k)


binaries:
Release/CGSphere.exe (64.0k)


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