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