sources:
cgapplication.cpp (3.2k)
cgapplication.h (3.5k)
cgwave.cpp (8.5k)
cgwave.h (1.0k)
vector.cpp (1.4k)
vector.h (4.9k)


binaries:
Release/wave.exe (27.0k)


website:
more info here


screenshot:
studies/grafik2/Computergrafik-Code5/cgwave.cpp
download file

  1 //
  2 // Computergraphik II
  3 // Prof. Dr. Juergen Doellner
  4 // Wintersemester 2001/02
  5 //
  6 // Rahmenprogramm zu Aufgabenzettel 5
  7 //
  8
  9 #include "cgwave.h"
 10 #include "vector.h"
 11 #include <fstream.h>
 12 #include <stdlib.h>
 13
 14 #ifndef PI
 15 const double PI = 3.14159265358979323846;
 16 #endif
 17
 18 CGWave::CGWave() {
 19     run_ = false;
 20     culling_ = false;
 21     showNormals_ = false;
 22     periodAnim_ = false;
 23     lightAnim_ = false;
 24     zoom_ = 1.5;
 25     periode_=0;
 26     list_ = NULL;
 27     rot_ = 180.0;
 28    
 29     buildPatch(40);
 30 }
 31
 32 CGWave::~CGWave() {
 33 }
 34
 35 static GLfloat light_position1[] = {0.0, 1.0, 0.0, 1.0};  /* Point light location. */   
 36
 37 void CGWave::drawScene() {
 38
 39     glPushMatrix();
 40     glRotatef(60,1,0,0);
 41     glScaled(zoom_, zoom_, zoom_);
 42
 43
 44     glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
 45     drawObject();
 46     // Positionieren bzw. Animieren der Lichtquelle 1
 47      
 48
 49     // draw light source (yellow !)
 50     glPushMatrix();
 51     glDisable(GL_LIGHTING);
 52
 53     // draw vector from light source
 54     glColor4f(1, 1, 0, 0.5);
 55
 56     glBegin(GL_LINES);
 57     glVertex3f(light_position1[0], light_position1[1], light_position1[2]);
 58     glVertex3f(light_position1[0], 0, light_position1[2]);
 59     glEnd();
 60     // translate sphere that represents our light source
 61
 62     glTranslatef(light_position1[0], light_position1[1], light_position1[2]);
 63     glutSolidSphere(0.03,10,10);
 64
 65     glEnable(GL_LIGHTING);
 66     glPopMatrix();
 67
 68     glPopMatrix();
 69 }
 70
 71 Vector CGWave::WavedNormal(const Vector& v) const {
 72     // get distance, stretch wave length
 73     double distance = abs(v)*20;
 74     // add periode shift
 75     distance += periode_;
 76
 77     // normalize to [0,2*PI[
 78 // while (distance >= 2*PI)
 79 // distance -= 2*PI;
 80
 81     // normalize point vector
 82     const Vector v_norm = v.normalized();
 83
 84     const double cos_dist = cos(distance);
 85     const double nx = v_norm[0]*cos_dist;
 86     const double ny = 1; // alternative: sin(distance);
 87     const double nz = v_norm[2]*cos_dist;
 88
 89     return Vector(nx, ny, nz).normalized();
 90 }
 91
 92 void CGWave::handleVertex(const Vector& v) const {
 93     // compute normal according to wave functions
 94     glNormal3dv(WavedNormal(v).rep());
 95     // send vertex
 96     glVertex3dv(v.rep());
 97 }
 98
 99 void CGWave::drawObject() {
100     // draw geometry
101     int c=0;
102     for(int j=0; j<num_; j++) {
103         glBegin(GL_TRIANGLE_STRIP); // Performance
104         // 1)
105         handleVertex(list_[c]); c++;
106         // 2)
107         handleVertex(list_[c]); c++;
108         // 3)
109         handleVertex(list_[c]); c++;
110
111         for(int i=0; i<((num_+1)*2)-3; i++) {
112             // Rest des Strips
113             handleVertex(list_[c]); c++;
114         }
115
116         glEnd();
117     }
118
119     // show normals ?
120     if(showNormals_) {
121         glDisable(GL_LIGHTING);
122
123         // lady in red
124         glColor3f(1,0,0);
125         glBegin(GL_LINES);
126
127         c = 0;
128         // process all vertices
129         for (int i=0; i<2*num_+2; i++)
130             for (int j=0; j<num_; j++)
131             {
132                 // get vertex
133                 Vector& v = list_[c++];
134                 // beginning from surface (small offset, though) ...
135                 glVertex3d (v[0], v[1]+0.01, v[2]);
136                 // ... to the end which we get by adding (stretched) normal to v
137                 glVertex3dv((v+(0.1*WavedNormal(v))).rep());
138             }
139
140         glEnd();
141         glEnable(GL_LIGHTING);
142     }
143 }
144
145 void CGWave::buildPatch(int detail) {
146     // In Dreiecken tessellierten Fläche
147     if(list_) delete list_;
148
149     const int points = (detail)*(4+((detail-1)*2));
150     list_ = new Vector[points];
151
152     double offset = 1.0/detail;
153
154     double x;
155     double z;
156     num_ = detail;
157     int c = 0;
158     for(int j=0; j<detail; j++) { // passend zu Triangle-Strip (s.o.)
159         x = -0.5;
160         z =  0.5 - (j+1)*offset;
161         list_[c] = Vector(x,0,z); c++;
162
163         x = -0.5;
164         z =  0.5 - j*offset;
165         list_[c] = Vector(x,0,z); c++;
166
167         x = -0.5 + offset;
168         z =  0.5 - (j+1)*offset;
169         list_[c] = Vector(x,0,z); c++;
170
171         for(int i=0; i<detail; ) {
172             if( (c%2)!=0) {
173                 x = -0.5 + (i+1)*offset;
174                 z =  0.5 - (j)*offset;
175                 i++;
176             } else {
177                 x = -0.5 + (i+1)*offset;
178                 z =  0.5 - (j+1)*offset;
179             }
180             list_[c] = Vector(x,0,z); c++;
181         }
182     }
183 }
184
185 void CGWave::onInit() {
186     // OpenGL Lichtquelle 0
187     static GLfloat light_diffuse[] = {0.7, 0.8, 0.5, 1.0};
188     static GLfloat light_position[] = {0.0, 1.0, 0.0, 1.0};
189     glLightfv(GL_LIGHT0, GL_DIFFUSE, light_diffuse);
190     glLightfv(GL_LIGHT0, GL_POSITION, light_position);
191     // glEnable(GL_LIGHT0); // wenn T&L nicht unterstützt
192
193     // OpenGL Lichtquelle 1
194     static GLfloat light_diffuse1[] = {0.7, 0.8, 1.0, 1.0};   /* Diffuse light. */
195     static GLfloat light_specular1[] = {0.6, 0.8, 0.6, 1.0};  /* Positional light source */
196     glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse1);
197     glLightfv(GL_LIGHT1, GL_SPECULAR, light_specular1);
198     glLightfv(GL_LIGHT1, GL_POSITION, light_position1);
199     glEnable(GL_LIGHT1);
200
201     glEnable(GL_LIGHTING);
202
203     // OpenGL Material
204     static GLfloat mat_specular[] = {0.8, 0.8, 0.8, 1.0};     /* Material property. */
205     glMaterialf(GL_FRONT, GL_SHININESS, 32);
206     glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular);
207
208     // automatische Normalisierung
209     glEnable(GL_NORMALIZE);
210    
211     // Tiefen Test aktivieren
212     glEnable(GL_DEPTH_TEST);
213
214     // Blending aktivieren
215     glEnable(GL_BLEND);
216     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
217    
218     // Smooth Schattierung aktivieren
219     glShadeModel(GL_SMOOTH);
220 // glShadeModel(GL_FLAT);
221    
222     // Projection
223     glMatrixMode(GL_PROJECTION);
224     gluPerspective(60.0, 1.0, 2.0, 50.0);   
225    
226     // LookAt tesselieren
227     glMatrixMode(GL_MODELVIEW);
228     gluLookAt(
229         0.0, 0.0, 4.0,  // from (0,0,4)
230         0.0, 0.0, 0.0,  // to (0,0,0)
231         0.0, 1.0, 0.)
// up
232    
233     glRotatef(-25, 0.0, 1.0, 0.0);
234     glClearColor(0.9,0.9,0.9,1.0);
235 }
236
237 void CGWave::onSize(unsigned int newWidth,unsigned int newHeight) {         
238     width_ = newWidth;
239     height_ = newHeight;           
240     glMatrixMode(GL_PROJECTION);
241     glViewport(0, 0, width_ - 1, height_ - 1);       
242     glLoadIdentity();
243     gluPerspective(40.0,float(width_)/float(height_),2.0, 100.0);
244     glMatrixMode(GL_MODELVIEW);     
245 }
246
247 void CGWave::onKey(unsigned char key) {
248     switch (key) {
249     case 27: { exit(0); break; }                       
250     case '+': { zoom_*= 1.1; break; }
251     case '-': { zoom_*= 0.9; break; }
252     case ' ': { run_ = !run_; break; }
253     case 'q': { glEnable(GL_LIGHT0); break; }
254     case 'Q': { glDisable(GL_LIGHT0); break; }
255     case 'c': { culling_ = !culling_; break; }
256     case 'n': { showNormals_ = !showNormals_; break; }
257     case 'p': { periodAnim_ = !periodAnim_; break; }
258     case 'y': { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); break;}
259     case 'x': { glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); break;}
260     case 'l': { lightAnim_ = !lightAnim_; break; }
261     case '1': { buildPatch(1); break; }
262     case '2': { buildPatch(2); break; }
263     case '3': { buildPatch(5); break; }
264     case '4': { buildPatch(10); break; }
265     case '5': { buildPatch(20); break; }
266     case '6': { buildPatch(40); break; }
267     case '7': { buildPatch(50); break; }
268     case '8': { buildPatch(100); break; }
269     case '9': { buildPatch(200); break; } // netter Versuch
270     }
271     onDraw();
272 }
273
274 void CGWave::onIdle() {
275     if(periodAnim_)
276     { // Periodische Wellenbewegung
277         periode_ -= 0.05;
278         if (periode_  < 0 )
279             periode_ += 2*PI;
280     }
281
282     if(lightAnim_)
283     {
284         rot_+=2; // Animierte Lichtquellen
285
286         // slow down rotation
287         double slow_rot = rot_/3;
288         light_position1[0] = 0.5*cos(slow_rot*PI/180.0);
289         light_position1[1] = 0.5;
290         light_position1[2] = 0.5*sin(slow_rot*PI/180.0);
291     }
292  
293     if (run_)  // Simple Rotation
294         glRotatef(.5, 0.0, 1.0, 0.0);
295
296     // Redraw
297     onDraw();
298 }
299
300 void CGWave::onDraw() {
301     glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);               
302
303     if (culling_) glEnable(GL_CULL_FACE);
304
305     drawScene();
306
307     glDisable(GL_CULL_FACE);
308
309     // Nicht vergessen! Front- und Back-Buffer tauschen:
310     swapBuffers();
311 }
312
313 // Hauptprogramm
314 int main(int argc, char* argv[]) {
315     // Erzeuge eine Instanz der Beispiel-Anwendung:
316     CGWave sample;
317
318     cout << "Tastenbelegung:" << endl          << "ESC Programm beenden" << endl          << "Leertaste Objekt drehen" << endl          << "+ Hineinzoomen" << endl          << "- Herauszoomen" << endl          << "n Normalen anzeigen/verbergen" << endl          << "p Wellen animieren an/aus" << endl          << "l Lichtquelle bewegen" << endl          << "q zweite Lichtquelle an" << endl          << "Q zweite Lichtquelle aus" << endl          << "y Drahtgittermodell" << endl          << "x Flaechen ausfuellen" << endl          << "1 bis 9 Tessellationsgrad (1 - ungenau, schnell 9 - sehr exakt, langsam)" << endl;         
319    
320     // Starte die Beispiel-Anwendung:
321     sample.start("Stephan Brumme, 702544", true, 512, 512);
322     return(0);
323 }
324