source: trunk/examples/demo/opengl/gllandscape.cpp@ 203

Last change on this file since 203 was 160, checked in by dmik, 19 years ago

Imported table and iconview modules and a bunch of dependent examples from the official release 3.3.1 from Trolltech.

  • Property svn:keywords set to Id
File size: 24.4 KB
Line 
1#include <qimage.h>
2#include "gllandscape.h"
3
4
5#include <math.h>
6
7#include "fbm.h"
8
9#ifndef PI
10#define PI 3.14159
11#endif
12
13#if defined(Q_CC_MSVC)
14#pragma warning(disable:4305) // init: truncation from const double to float
15#pragma warning(disable:4244) // init: truncation from const double to float
16#endif
17
18GLLandscape::GLLandscape( QWidget * parent, const char * name )
19 : QGLWidget( parent, name )
20{
21 mouseButtonDown = FALSE;
22 animationRunning = FALSE;
23 oldX = oldY = oldZ = 0.0;
24 landscape = 0;
25 vertexNormals = 0;
26 normals = 0;
27 wave = 0;
28 wt = 0;
29 cubeRot = 0;
30 createGrid( 50 );
31 setWireframe( 0 );
32}
33
34GLLandscape::~GLLandscape()
35{
36 destroyGrid();
37}
38
39void GLLandscape::initializeGL()
40{
41 glMatrixMode( GL_MODELVIEW );
42 glLoadIdentity();
43 glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[AxisView].model );
44
45 glTranslatef( 0.0, 0.0, -50.0 );
46 glRotatef( -45, 1, 0, 0 );
47 glRotatef( -45, 0, 0, 1 );
48 glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[CurrentView].model );
49 glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[DefaultView].model );
50
51 glMatrixMode( GL_PROJECTION );
52 glLoadIdentity();
53 /* Use GL utility library function to obtain desired view */
54 gluPerspective( 60, 1, 1, 250 );
55 glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[CurrentView].projection );
56 glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[DefaultView].projection );
57
58 qglClearColor( black );
59 glDepthFunc( GL_LESS );
60 calculateVertexNormals();
61
62 QImage tex;
63 tex.load("opengl/qtlogo.png");
64 tex = QGLWidget::convertToGLFormat(tex); // flipped 32bit RGBA
65 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
66 glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
67 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
68 glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0,
69 GL_RGBA, GL_UNSIGNED_BYTE, tex.bits());
70 initDisplayLists();
71}
72
73void GLLandscape::resizeGL( int width, int height )
74{
75 glViewport( 0, 0, width, height );
76}
77
78void GLLandscape::paintGL()
79{
80 QString str;
81 GLboolean lighting;
82 glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
83 switch ( mode ) {
84 case Wireframe:
85 drawWireframe();
86 str = tr( "Wireframe" );
87 break;
88 case Filled:
89 drawFilled();
90 str = tr( "Flat shaded" );
91 break;
92 case SmoothShaded:
93 str = tr( "Smooth shaded" );
94 drawSmoothShaded();
95 break;
96 case Landscape:
97 drawSmoothShaded();
98 str = tr( "Landscape" );
99 break;
100 }
101 glGetBooleanv( GL_LIGHTING, &lighting );
102 if ( lighting )
103 glDisable( GL_LIGHTING );
104 qglColor( white );
105 renderText(15, height() - 15, str);
106 drawAxis();
107 drawCube();
108 if ( lighting )
109 glEnable( GL_LIGHTING );
110}
111
112void GLLandscape::drawAxis()
113{
114 glPushAttrib(GL_ALL_ATTRIB_BITS);
115 glViewport(15, 20, 50, 50);
116 glMatrixMode(GL_PROJECTION);
117 glPushMatrix();
118 glLoadIdentity();
119 glOrtho(-1.1, 1.1, -1.1, 1.1, 0.1, 10);
120 glTranslatef(0, 0, -1.2);
121 glRotatef(-45, 1, 0, 0);
122 glRotatef(-45, 0, 0, 1);
123 glMatrixMode(GL_MODELVIEW);
124 glPushMatrix();
125 glLoadMatrixf((GLfloat *) views[AxisView].model);
126
127 glCallList(axisList);
128 qglColor(white);
129 renderText(1.1f, 0, 0, "x");
130 renderText(0, 1.1f, 0, "y");
131 renderText(0, 0, 1.1f, "z");
132
133 glPopMatrix();
134 glMatrixMode(GL_PROJECTION);
135 glPopMatrix();
136 glPopAttrib();
137}
138
139void GLLandscape::drawCube()
140{
141 glPushAttrib(GL_ALL_ATTRIB_BITS);
142 glViewport(width()-75, 0, 75, 75);
143 glMatrixMode( GL_PROJECTION );
144 glPushMatrix();
145 glLoadIdentity();
146 glOrtho(-1.1, 1.1, -1.1, 1.1, 0.1, 10);
147 glTranslatef(0, 0, -1.2);
148 glMatrixMode(GL_MODELVIEW);
149 glPushMatrix();
150 glLoadIdentity();
151 glRotatef(cubeRot, 1, 0, 0);
152 glRotatef(cubeRot, 0, 1, 0);
153 glRotatef(cubeRot, 0, 0, 1);
154 glTranslatef(-0.5, -0.5, -0.5);
155
156 glCallList(cubeList);
157
158 glPopMatrix();
159 glMatrixMode(GL_PROJECTION);
160 glPopMatrix();
161 glPopAttrib();
162}
163
164void GLLandscape::drawWireframe()
165{
166 qglColor( white );
167 glBegin( GL_LINES );
168 {
169 for ( int y = 0; y < (gridSize-1); y++ )
170 for ( int x = 0; x < (gridSize-1); x++) {
171 glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
172 glVertex3f( x+1-gridHalf, y-gridHalf, landscape[x+1][y] );
173 glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
174 glVertex3f( x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1] );
175
176 glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] );
177 glVertex3f( x-gridHalf, y+1-gridHalf, landscape[x][y+1] );
178 }
179 }
180 glEnd();
181 glBegin( GL_LINE_STRIP );
182 {
183 for ( int x = 0; x < gridSize; x++ ) {
184 glVertex3f( x-gridHalf, gridHalf-1, landscape[x][gridSize-1] );
185 }
186 }
187 glEnd();
188 glBegin( GL_LINE_STRIP );
189 {
190 for ( int y = 0; y < gridSize; y++ ) {
191 glVertex3f( gridHalf-1, y-gridHalf, landscape[gridSize-1][y] );
192 }
193 }
194 glEnd();
195}
196
197void GLLandscape::drawFilled()
198{
199 for ( int y = 0; y < gridSize-1; y++ )
200 for ( int x = 0; x < gridSize-1; x++ ) {
201 qglColor( red );
202 glBegin( GL_TRIANGLE_STRIP );
203 {
204 glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]);
205 glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]);
206 glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
207 }
208 glEnd();
209 qglColor( white );
210 glBegin( GL_TRIANGLE_STRIP );
211 {
212 glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]);
213 glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]);
214 glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
215 }
216 glEnd();
217 }
218}
219
220void GLLandscape::drawSmoothShaded()
221{
222 if ( mode == SmoothShaded ) {
223 GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 };
224 GLfloat materialShininess[] = { 128.0 };
225 GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 };
226
227 glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
228 glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
229 glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
230 } else {
231 GLfloat materialAmbient[] = { 0.20, 0.33, 0.20, 0.0 };
232 GLfloat materialShininess[] = { 1.0 };
233 GLfloat materialSpecular[] = { 0.1, 0.1, 0.1, 0.1 };
234
235 glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
236 glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
237 glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
238 }
239
240 for ( int y = 0; y < gridSize-1; y++ )
241 for ( int x = 0; x < gridSize-1; x++ ) {
242 glBegin( GL_POLYGON );
243 {
244 glNormal3dv(vertexNormals[x][y].n);
245 glVertex3f(x-gridHalf,y-gridHalf,landscape[x][y]);
246
247 glNormal3dv(vertexNormals[x+1][y].n);
248 glVertex3f(x+1-gridHalf, y-gridHalf, landscape[x+1][y]);
249
250 glNormal3dv(vertexNormals[x+1][y+1].n);
251 glVertex3f(x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1]);
252 }
253 glEnd();
254
255 glBegin( GL_POLYGON );
256 {
257 glNormal3dv(vertexNormals[x][y].n);
258 glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]);
259
260 glNormal3dv(vertexNormals[x+1][y+1].n);
261 glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]);
262
263 glNormal3dv(vertexNormals[x][y+1].n);
264 glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]);
265 }
266 glEnd();
267 }
268
269 // Draw water
270 if ( mode == Landscape ) {
271 GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 };
272 GLfloat materialShininess[] = { 128.0 };
273 GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 };
274
275 glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
276 glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
277 glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
278
279 glEnable( GL_BLEND );
280 glBegin( GL_POLYGON );
281 {
282 glNormal3f( 0, 0, 1 );
283 glVertex3f( -gridHalf, -gridHalf, .2 );
284 glNormal3f( 0, 0, 1 );
285 glVertex3f( -gridHalf, gridHalf, .2 );
286 glNormal3f( 0, 0, 1 );
287 glVertex3f( gridHalf, gridHalf, .2 );
288 glNormal3f( 0, 0, 1 );
289 glVertex3f( gridHalf, -gridHalf, .2 );
290
291 }
292 glEnd();
293 glDisable( GL_BLEND );
294 }
295}
296
297void GLLandscape::setGridSize( int size )
298{
299 destroyGrid(); // destroy old grid
300 createGrid( size ); // create new grid
301 initializeGL();
302 updateGL();
303}
304
305void GLLandscape::createGrid( int size )
306{
307 if ( (size % 2) != 0 )
308 size++;
309 gridSize = size;
310 gridHalf = gridSize / 2;
311 initFractals = TRUE;
312 landscape = new double*[gridSize];
313 normals = new gridNormals*[gridSize];
314 vertexNormals = new avgNormals*[gridSize];
315 wt = new double*[gridSize];
316 wave = new double*[gridSize];
317 for ( int i = 0; i < gridSize; i++ ) {
318 landscape[i] = new double[gridSize];
319 normals[i] = new gridNormals[gridSize];
320 vertexNormals[i] = new avgNormals[gridSize];
321 wt[i] = new double[gridSize];
322 wave[i] = new double[gridSize];
323
324 memset( landscape[i], 0, gridSize*sizeof(double) );
325 memset( normals[i], 0, gridSize*sizeof(gridNormals) );
326 memset( vertexNormals[i], 0, gridSize*sizeof(avgNormals) );
327 memset( wt[i], 0, gridSize*sizeof(double) );
328 memset( wave[i], 0, gridSize*sizeof(double) );
329 }
330}
331
332void GLLandscape::destroyGrid()
333{
334 if ( landscape != NULL ) {
335 for( int i = 0; i < gridSize; i++ ) {
336 delete[] landscape[i];
337 delete[] normals[i];
338 delete[] vertexNormals[i];
339 delete[] wt[i];
340 delete[] wave[i];
341 }
342 delete[] landscape;
343 delete[] normals;
344 delete[] vertexNormals;
345 delete[] wt;
346 delete[] wave;
347 }
348 landscape = 0;
349}
350
351void GLLandscape::rotate( GLfloat deg, Axis axis )
352{
353 makeCurrent();
354 glMatrixMode( GL_MODELVIEW );
355 for ( int i = DefaultView; i <= AxisView; i++ ) {
356 glLoadMatrixf((GLfloat *) views[i].model);
357 if ( axis == XAxis )
358 glRotatef( deg, 1, 0, 0 );
359 else if ( axis == YAxis )
360 glRotatef( deg, 0, 1, 0 );
361 else
362 glRotatef( deg, 0, 0, 1 );
363 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[i].model);
364 }
365 glLoadMatrixf((GLfloat *) views[CurrentView].model);
366}
367
368void GLLandscape::rotateX( int deg )
369{
370 static int oldDeg = 0;
371
372 rotate( deg-oldDeg, XAxis );
373 oldDeg = deg;
374 updateGL();
375}
376
377void GLLandscape::rotateY( int deg )
378{
379 static int oldDeg = 0;
380
381 rotate( deg-oldDeg, YAxis );
382 oldDeg = deg;
383 updateGL();
384}
385
386void GLLandscape::rotateZ( int deg )
387{
388 static int oldDeg = 0;
389
390 rotate( deg-oldDeg, ZAxis );
391 oldDeg = deg;
392 updateGL();
393}
394
395void GLLandscape::zoom( int z )
396{
397 float zoom;
398 if ( z < 100 ) {
399 zoom = 1 + 4.99 - (z*5.0 / 100.0);
400 } else {
401 z = 200 - z;
402 zoom = z / 100.0;
403 }
404 makeCurrent();
405 glMatrixMode( GL_MODELVIEW );
406 // Always scale the original model matrix
407 glLoadMatrixf((GLfloat *) views[DefaultView].model);
408 glScalef( zoom, zoom, zoom );
409 glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[CurrentView].model);
410 updateGL();
411}
412
413void GLLandscape::resetGrid()
414{
415 setGridSize( gridSize );
416}
417
418void GLLandscape::fractalize()
419{
420 Vector p;
421 double value;
422 double roughness = 0.5;
423 int frequency = 50;
424
425 p.x = p.y = p.z = 0;
426 // Initialise fbm routine
427 if ( initFractals ) {
428 initFractals = FALSE;
429 value = fBm( p, roughness, 2.0, 8.0, 1 );
430 }
431
432 // Fractalize grid
433 for ( int x = 0; x < gridSize; x++ ) {
434 for ( int y = 0; y < gridSize; y++ ) {
435 p.x = (double) x / (101 - frequency);
436 p.y = (double) y / (101 - frequency);
437 p.z = (double) landscape[x][y] / (101 - frequency);
438 value = fBm(p, roughness, 2.0, 8.0, 0);
439 landscape[x][y] += value;
440 }
441 }
442 calculateVertexNormals();
443 updateGL();
444}
445
446
447//
448// Calculate the vector cross product of v and w, store result in n.
449//
450static void crossProduct( double v[3], double w[3], double n[3] )
451{
452 n[0] = v[1]*w[2]-w[1]*v[2];
453 n[1] = w[0]*v[2]-v[0]*w[2];
454 n[2] = v[0]*w[1]-w[0]*v[1];
455}
456
457void GLLandscape::calculateVertexNormals()
458{
459 double len, v[3], v2[3], w[3], w2[3], n[3], n2[3];
460
461 // Calculate the surface normals for all polygons in the
462 // height field
463 for ( int i = 0; i < (gridSize-1); i++ )
464 for ( int k = 0; k < (gridSize-1); k++ ) {
465 /* Lower poly normal */
466 v[0] = 1; // (i+1)-i
467 v[1] = 0; // k-k
468 v[2] = landscape[i+1][k]-landscape[i][k];
469 w[0] = 1; // (i+1)-i
470 w[1] = 1; // (k+1)-k
471 w[2] = landscape[i+1][k+1]-landscape[i][k];
472 crossProduct( v, w, n );
473 len = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]);
474 normals[i][k].l[0] = n[0]/len;
475 normals[i][k].l[1] = n[1]/len;
476 normals[i][k].l[2] = n[2]/len;
477
478 /* Upper poly normal */
479 v2[0] = -1.0; // i-(i+1);
480 v2[1] = 0.0; // (k+1)-(k+1);
481 v2[2] = landscape[i][k+1]-landscape[i+1][k+1];
482 w2[0] = -1.0; // i-(i+1);
483 w2[1] = -1.0; // k-(k+1);
484 w2[2] = landscape[i][k]-landscape[i+1][k+1];
485 crossProduct( v2, w2, n2 );
486 len = sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]);
487 normals[i][k].u[0] = n2[0]/len;
488 normals[i][k].u[1] = n2[1]/len;
489 normals[i][k].u[2] = n2[2]/len;
490 }
491
492 // Calculate proper vertex normals
493 averageNormals();
494}
495
496void GLLandscape::averageNormals()
497{
498 // Calculate the average surface normal for a vertex based on
499 // the normals of the surrounding polygons
500 for ( int i = 0; i < gridSize; i++ )
501 for ( int k = 0; k < gridSize; k++ ) {
502 if ( i > 0 && k > 0 && i < (gridSize-1) && k < (gridSize-1) ) {
503 // For vertices that are *not* on the edge of the height field
504 for ( int t = 0; t < 3; t++ ) // X, Y and Z components
505 vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
506 normals[i][k].l[t] +
507 normals[i][k-1].u[t] +
508 normals[i-1][k-1].u[t] +
509 normals[i-1][k-1].l[t] +
510 normals[i-1][k].l[t] )/6.0;
511 } else {
512 // Vertices that are on the edge of the height field require
513 // special attention..
514 if ( i == 0 && k == 0 ) {
515 for ( int t = 0; t < 3; t++ )
516 vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
517 normals[i][k].l[t] )/2.0;
518 } else if ( i == gridSize-1 && k == gridSize-1 ) {
519 for ( int t = 0; t < 3; t++ )
520 vertexNormals[i][k].n[t] = ( normals[i][k].u[t] +
521 normals[i][k].l[t] )/2.0;
522 } else if ( i == gridSize-1) {
523 for ( int t = 0; t < 3; t++ )
524 vertexNormals[i][k].n[t] = vertexNormals[i-1][k].n[t];
525 } else if ( k == gridSize-1 ) {
526 for ( int t = 0; t < 3; t++ )
527 vertexNormals[i][k].n[t] = vertexNormals[i][k-1].n[t];
528 } else if ( k > 0 ) {
529 for ( int t = 0; t < 3; t++ )
530 vertexNormals[i][k].n[t] = (normals[i][k].u[t] +
531 normals[i][k].l[t] +
532 normals[i][k-1].u[t])/3.0;
533 } else if ( i > 0 ) {
534 for ( int t = 0; t < 3; t++ )
535 vertexNormals[i][k].n[t] = (normals[i][k].u[t] +
536 normals[i][k].l[t] +
537 normals[i-1][k].l[t])/3.0;
538 }
539 }
540 }
541}
542
543void GLLandscape::setWireframe( int state )
544{
545 if ( state != 1 ) {
546 // Enable line antialiasing
547 makeCurrent();
548 glEnable( GL_LINE_SMOOTH );
549 glEnable( GL_BLEND );
550 glDisable( GL_DEPTH_TEST );
551 glDisable( GL_LIGHTING );
552 glDisable( GL_NORMALIZE );
553
554 glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
555 glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE );
556
557 mode = Wireframe;
558 updateGL();
559 }
560}
561
562void GLLandscape::setFilled( int state )
563{
564 if ( state != 1 ) {
565 makeCurrent();
566 glEnable( GL_DEPTH_TEST );
567 glDisable( GL_LINE_SMOOTH );
568 glDisable( GL_BLEND );
569 glDisable( GL_LIGHTING );
570 glDisable( GL_NORMALIZE );
571
572 mode = Filled;
573 updateGL();
574 }
575}
576
577void GLLandscape::setSmoothShaded( int state )
578{
579 if ( state != 1 ) {
580 makeCurrent();
581 glEnable( GL_DEPTH_TEST );
582 glEnable( GL_LIGHTING );
583 glEnable( GL_LIGHT0 );
584 glEnable( GL_NORMALIZE );
585 glDisable( GL_LINE_SMOOTH );
586 glDisable( GL_BLEND );
587
588 glShadeModel( GL_SMOOTH );
589 glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
590
591 // Setup lighting and material properties
592 GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 };
593 GLfloat ambient[] = { 0.50, 0.50, 0.50, 0.0 };
594 GLfloat diffuse[] = { 1.00, 1.00, 1.00, 0.0 };
595 GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 };
596 GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 };
597 // GLfloat materialDiffuse[] = { 1.00, 1.00, 1.0, 0.0 };
598 GLfloat materialShininess[] = { 128.0 };
599 GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 };
600
601 glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular );
602 // glMaterialfv( GL_FRONT, GL_DIFFUSE, materialDiffuse );
603 glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient );
604 glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess );
605
606 glLightfv( GL_LIGHT0, GL_POSITION, position );
607 glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
608 glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
609 glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
610
611 mode = SmoothShaded;
612 calculateVertexNormals();
613 updateGL();
614 }
615}
616
617void GLLandscape::setLandscape( int state )
618{
619 if ( state != 1 ) {
620 makeCurrent();
621 glEnable( GL_DEPTH_TEST );
622 glEnable( GL_LIGHTING );
623 glEnable( GL_LIGHT0 );
624 glEnable( GL_NORMALIZE );
625 glDisable( GL_LINE_SMOOTH );
626 glDisable( GL_BLEND );
627
628 glShadeModel( GL_SMOOTH );
629 glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE );
630
631 // Setup lighting and material properties
632 GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 };
633 GLfloat ambient[] = { 0.50, 0.50, 0.50, 0.0 };
634 GLfloat diffuse[] = { 1.00, 1.00, 1.00, 0.0 };
635 GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 };
636
637 glLightfv( GL_LIGHT0, GL_POSITION, position );
638 glLightfv( GL_LIGHT0, GL_AMBIENT, ambient );
639 glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse );
640 glLightfv( GL_LIGHT0, GL_SPECULAR, specular );
641
642 glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR );
643
644 mode = Landscape;
645 calculateVertexNormals();
646 updateGL();
647 }
648}
649
650void GLLandscape::mousePressEvent( QMouseEvent *e )
651{
652 oldPos = e->pos();
653 mouseButtonDown = TRUE;
654}
655
656void GLLandscape::mouseReleaseEvent( QMouseEvent *e )
657{
658 oldPos = e->pos();
659 mouseButtonDown = FALSE;
660}
661
662void GLLandscape::mouseMoveEvent( QMouseEvent *e )
663{
664 GLfloat rx = (GLfloat) (e->x() - oldPos.x()) / width();
665 GLfloat ry = (GLfloat) (e->y() - oldPos.y()) / height();
666
667 if ( e->state() == LeftButton ) {
668 // Left button down - rotate around X and Y axes
669 oldX = 180*ry;
670 oldY = 180*rx;
671 rotate( oldX, XAxis );
672 rotate( oldY, YAxis );
673 updateGL();
674 } else if ( e->state() == RightButton ) {
675 // Right button down - rotate around X and Z axes
676 oldX = 180*ry;
677 oldZ = 180*rx;
678 rotate( oldX, XAxis );
679 rotate( oldZ, ZAxis );
680 updateGL();
681 }
682 oldPos = e->pos();
683}
684
685void GLLandscape::timerEvent( QTimerEvent *e )
686{
687 if (e->timerId() == cubeTimer) {
688 cubeRot += 1;
689 if (!animationRunning)
690 updateGL();
691 return;
692 }
693
694 int dx, dy; // disturbance point
695 float s, v, W, t;
696 int i, j;
697
698 if ( mode == Landscape ) {
699 dx = dy = 0;
700 } else {
701 dx = dy = gridSize >> 1;
702 }
703 W = 0.3;
704 v = -4; // wave speed
705
706 for ( i = 0; i < gridSize; i++ )
707 for ( j = 0; j < gridSize; j++ )
708 {
709 s = sqrt( (double) ( (j - dx) * (j - dx) + (i - dy) * (i - dy) ) );
710 wt[i][j] += 0.1;
711 t = s / v;
712
713 if ( mode == Landscape ) {
714 if ( (landscape[i][j] + wave[i][j]) < 0 )
715 landscape[i][j] -= wave[i][j];
716 if ( (dy - j != 0) || (dx - i != 0) )
717 wave[i][j] = (3 * sin( 2 * PI * W * (wt[i][j] + t ))) /
718 (0.2*(sqrt( pow((double)(dx-i), 2) + pow((double)(dy-j), 2))+2));
719 else
720 wave[i][j] = ( 3 * sin( 2 * PI * W * ( wt[i][j] + t ) ) );
721 if ( landscape[i][j] + wave[i][j] < 0 )
722 landscape[i][j] += wave[i][j];
723
724 } else {
725 landscape[i][j] -= wave[i][j];
726
727 if ( s != 0 )
728 wave[i][j] = 2 * sin(2 * PI * W * ( wt[i][j] + t )) /
729 (0.2*(s + 2));
730 else
731 wave[i][j] = 2 * sin( 2 * PI * W * ( wt[i][j] + t ) );
732 landscape[i][j] += wave[i][j];
733 }
734
735 }
736 if ( mode == SmoothShaded || mode == Landscape )
737 calculateVertexNormals();
738 updateGL();
739}
740
741void GLLandscape::toggleWaveAnimation( bool state )
742{
743 if (state) {
744 animTimer = startTimer(20);
745 animationRunning = TRUE;
746 } else {
747 killTimer(animTimer);
748 animationRunning = FALSE;
749 }
750}
751
752void GLLandscape::showEvent( QShowEvent * )
753{
754 if (animationRunning)
755 animTimer = startTimer(20);
756 cubeTimer = startTimer(50);
757}
758
759void GLLandscape::hideEvent( QHideEvent * )
760{
761 if (animationRunning)
762 killTimer(animTimer);
763 killTimer(cubeTimer);
764}
765
766void GLLandscape::initDisplayLists()
767{
768 // axisList
769 axisList = glGenLists(1);
770 glNewList(axisList, GL_COMPILE);
771
772 glEnable(GL_LINE_SMOOTH);
773 glEnable(GL_BLEND);
774 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
775 glEnable(GL_DEPTH_TEST);
776 glColor3f(1.0, 0.0, 0.0);
777 glBegin(GL_LINES);
778 {
779 glColor3f(1.0, 0.0, 0.0);
780 glVertex3f(-1.0f, 0, 0); // x axis
781 glVertex3f(1.0f, 0, 0);
782
783 glVertex3f(1.0f, 0, 0);
784 glVertex3f(0.8f, 0.2f, 0);
785 glVertex3f(1.0f, 0, 0);
786 glVertex3f(0.8f, -.2f, 0);
787
788 glColor3f(0.0, 1.0, 0.0);
789 glVertex3f(0, -1.0f, 0); // y axis
790 glVertex3f(0, 1.0f, 0);
791
792 glVertex3f(0, 1.0f, 0);
793 glVertex3f(0.2f, 0.8f, 0);
794 glVertex3f(0, 1.0f, 0);
795 glVertex3f(-0.2f, 0.8f, 0);
796
797 glColor3f(0.5, 0.5, 1.0);
798 glVertex3f(0, 0, -1.0f); // z axis
799 glVertex3f(0, 0, 1.0f);
800
801 glVertex3f(0, 0, 1.0f);
802 glVertex3f(0, 0.2f, 0.8f);
803 glVertex3f(0, 0, 1.0f);
804 glVertex3f(0,-0.2f, 0.8f);
805 }
806 glEnd();
807
808 glEndList();
809
810 // cubeList
811 cubeList = glGenLists(1);
812 glNewList(cubeList, GL_COMPILE);
813
814 glEnable(GL_TEXTURE_2D);
815 glEnable(GL_DEPTH_TEST);
816 glEnable(GL_CULL_FACE);
817 glEnable(GL_BLEND);
818 glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR);
819
820 glBegin( GL_QUADS );
821 {
822 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
823 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 );
824 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 );
825 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 );
826 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 );
827 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 0.0 );
828 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 0.0 );
829 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
830
831 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 );
832 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
833 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
834 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
835 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
836 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
837 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
838 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 );
839
840 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
841 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 );
842 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 );
843 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, 1.0 );
844 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, 1.0 );
845 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 0.0, 0.0 );
846 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 0.0, 0.0 );
847 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
848
849 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 );
850 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 1.0, 0.0 );
851 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 1.0, 0.0 );
852 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
853 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
854 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
855 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
856 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 );
857
858 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 );
859 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
860 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 );
861 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
862 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 );
863 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 );
864 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 );
865 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 );
866
867 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
868 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 );
869 glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 );
870 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
871 glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 );
872 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 0.0, 1.0 );
873 glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 0.0, 1.0 );
874 glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 );
875 }
876 glEnd();
877 glDisable(GL_TEXTURE_2D);
878
879 glEndList();
880}
Note: See TracBrowser for help on using the repository browser.