#include #include "gllandscape.h" #include #include "fbm.h" #ifndef PI #define PI 3.14159 #endif #if defined(Q_CC_MSVC) #pragma warning(disable:4305) // init: truncation from const double to float #pragma warning(disable:4244) // init: truncation from const double to float #endif GLLandscape::GLLandscape( QWidget * parent, const char * name ) : QGLWidget( parent, name ) { mouseButtonDown = FALSE; animationRunning = FALSE; oldX = oldY = oldZ = 0.0; landscape = 0; vertexNormals = 0; normals = 0; wave = 0; wt = 0; cubeRot = 0; createGrid( 50 ); setWireframe( 0 ); } GLLandscape::~GLLandscape() { destroyGrid(); } void GLLandscape::initializeGL() { glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[AxisView].model ); glTranslatef( 0.0, 0.0, -50.0 ); glRotatef( -45, 1, 0, 0 ); glRotatef( -45, 0, 0, 1 ); glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[CurrentView].model ); glGetFloatv( GL_MODELVIEW_MATRIX,(GLfloat *) views[DefaultView].model ); glMatrixMode( GL_PROJECTION ); glLoadIdentity(); /* Use GL utility library function to obtain desired view */ gluPerspective( 60, 1, 1, 250 ); glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[CurrentView].projection ); glGetFloatv( GL_PROJECTION_MATRIX, (GLfloat *)views[DefaultView].projection ); qglClearColor( black ); glDepthFunc( GL_LESS ); calculateVertexNormals(); QImage tex; tex.load("opengl/qtlogo.png"); tex = QGLWidget::convertToGLFormat(tex); // flipped 32bit RGBA glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); initDisplayLists(); } void GLLandscape::resizeGL( int width, int height ) { glViewport( 0, 0, width, height ); } void GLLandscape::paintGL() { QString str; GLboolean lighting; glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); switch ( mode ) { case Wireframe: drawWireframe(); str = tr( "Wireframe" ); break; case Filled: drawFilled(); str = tr( "Flat shaded" ); break; case SmoothShaded: str = tr( "Smooth shaded" ); drawSmoothShaded(); break; case Landscape: drawSmoothShaded(); str = tr( "Landscape" ); break; } glGetBooleanv( GL_LIGHTING, &lighting ); if ( lighting ) glDisable( GL_LIGHTING ); qglColor( white ); renderText(15, height() - 15, str); drawAxis(); drawCube(); if ( lighting ) glEnable( GL_LIGHTING ); } void GLLandscape::drawAxis() { glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(15, 20, 50, 50); glMatrixMode(GL_PROJECTION); glPushMatrix(); glLoadIdentity(); glOrtho(-1.1, 1.1, -1.1, 1.1, 0.1, 10); glTranslatef(0, 0, -1.2); glRotatef(-45, 1, 0, 0); glRotatef(-45, 0, 0, 1); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadMatrixf((GLfloat *) views[AxisView].model); glCallList(axisList); qglColor(white); renderText(1.1f, 0, 0, "x"); renderText(0, 1.1f, 0, "y"); renderText(0, 0, 1.1f, "z"); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); } void GLLandscape::drawCube() { glPushAttrib(GL_ALL_ATTRIB_BITS); glViewport(width()-75, 0, 75, 75); glMatrixMode( GL_PROJECTION ); glPushMatrix(); glLoadIdentity(); glOrtho(-1.1, 1.1, -1.1, 1.1, 0.1, 10); glTranslatef(0, 0, -1.2); glMatrixMode(GL_MODELVIEW); glPushMatrix(); glLoadIdentity(); glRotatef(cubeRot, 1, 0, 0); glRotatef(cubeRot, 0, 1, 0); glRotatef(cubeRot, 0, 0, 1); glTranslatef(-0.5, -0.5, -0.5); glCallList(cubeList); glPopMatrix(); glMatrixMode(GL_PROJECTION); glPopMatrix(); glPopAttrib(); } void GLLandscape::drawWireframe() { qglColor( white ); glBegin( GL_LINES ); { for ( int y = 0; y < (gridSize-1); y++ ) for ( int x = 0; x < (gridSize-1); x++) { glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] ); glVertex3f( x+1-gridHalf, y-gridHalf, landscape[x+1][y] ); glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] ); glVertex3f( x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1] ); glVertex3f( x-gridHalf, y-gridHalf, landscape[x][y] ); glVertex3f( x-gridHalf, y+1-gridHalf, landscape[x][y+1] ); } } glEnd(); glBegin( GL_LINE_STRIP ); { for ( int x = 0; x < gridSize; x++ ) { glVertex3f( x-gridHalf, gridHalf-1, landscape[x][gridSize-1] ); } } glEnd(); glBegin( GL_LINE_STRIP ); { for ( int y = 0; y < gridSize; y++ ) { glVertex3f( gridHalf-1, y-gridHalf, landscape[gridSize-1][y] ); } } glEnd(); } void GLLandscape::drawFilled() { for ( int y = 0; y < gridSize-1; y++ ) for ( int x = 0; x < gridSize-1; x++ ) { qglColor( red ); glBegin( GL_TRIANGLE_STRIP ); { glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]); glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]); glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]); } glEnd(); qglColor( white ); glBegin( GL_TRIANGLE_STRIP ); { glVertex3f(x+1-gridHalf,y-gridHalf, landscape[x+1][y]); glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]); glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]); } glEnd(); } } void GLLandscape::drawSmoothShaded() { if ( mode == SmoothShaded ) { GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 }; GLfloat materialShininess[] = { 128.0 }; GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 }; glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular ); glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient ); glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess ); } else { GLfloat materialAmbient[] = { 0.20, 0.33, 0.20, 0.0 }; GLfloat materialShininess[] = { 1.0 }; GLfloat materialSpecular[] = { 0.1, 0.1, 0.1, 0.1 }; glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular ); glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient ); glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess ); } for ( int y = 0; y < gridSize-1; y++ ) for ( int x = 0; x < gridSize-1; x++ ) { glBegin( GL_POLYGON ); { glNormal3dv(vertexNormals[x][y].n); glVertex3f(x-gridHalf,y-gridHalf,landscape[x][y]); glNormal3dv(vertexNormals[x+1][y].n); glVertex3f(x+1-gridHalf, y-gridHalf, landscape[x+1][y]); glNormal3dv(vertexNormals[x+1][y+1].n); glVertex3f(x+1-gridHalf, y+1-gridHalf, landscape[x+1][y+1]); } glEnd(); glBegin( GL_POLYGON ); { glNormal3dv(vertexNormals[x][y].n); glVertex3f(x-gridHalf,y-gridHalf, landscape[x][y]); glNormal3dv(vertexNormals[x+1][y+1].n); glVertex3f(x+1-gridHalf,y+1-gridHalf, landscape[x+1][y+1]); glNormal3dv(vertexNormals[x][y+1].n); glVertex3f(x-gridHalf,y+1-gridHalf, landscape[x][y+1]); } glEnd(); } // Draw water if ( mode == Landscape ) { GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 }; GLfloat materialShininess[] = { 128.0 }; GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 }; glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular ); glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient ); glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess ); glEnable( GL_BLEND ); glBegin( GL_POLYGON ); { glNormal3f( 0, 0, 1 ); glVertex3f( -gridHalf, -gridHalf, .2 ); glNormal3f( 0, 0, 1 ); glVertex3f( -gridHalf, gridHalf, .2 ); glNormal3f( 0, 0, 1 ); glVertex3f( gridHalf, gridHalf, .2 ); glNormal3f( 0, 0, 1 ); glVertex3f( gridHalf, -gridHalf, .2 ); } glEnd(); glDisable( GL_BLEND ); } } void GLLandscape::setGridSize( int size ) { destroyGrid(); // destroy old grid createGrid( size ); // create new grid initializeGL(); updateGL(); } void GLLandscape::createGrid( int size ) { if ( (size % 2) != 0 ) size++; gridSize = size; gridHalf = gridSize / 2; initFractals = TRUE; landscape = new double*[gridSize]; normals = new gridNormals*[gridSize]; vertexNormals = new avgNormals*[gridSize]; wt = new double*[gridSize]; wave = new double*[gridSize]; for ( int i = 0; i < gridSize; i++ ) { landscape[i] = new double[gridSize]; normals[i] = new gridNormals[gridSize]; vertexNormals[i] = new avgNormals[gridSize]; wt[i] = new double[gridSize]; wave[i] = new double[gridSize]; memset( landscape[i], 0, gridSize*sizeof(double) ); memset( normals[i], 0, gridSize*sizeof(gridNormals) ); memset( vertexNormals[i], 0, gridSize*sizeof(avgNormals) ); memset( wt[i], 0, gridSize*sizeof(double) ); memset( wave[i], 0, gridSize*sizeof(double) ); } } void GLLandscape::destroyGrid() { if ( landscape != NULL ) { for( int i = 0; i < gridSize; i++ ) { delete[] landscape[i]; delete[] normals[i]; delete[] vertexNormals[i]; delete[] wt[i]; delete[] wave[i]; } delete[] landscape; delete[] normals; delete[] vertexNormals; delete[] wt; delete[] wave; } landscape = 0; } void GLLandscape::rotate( GLfloat deg, Axis axis ) { makeCurrent(); glMatrixMode( GL_MODELVIEW ); for ( int i = DefaultView; i <= AxisView; i++ ) { glLoadMatrixf((GLfloat *) views[i].model); if ( axis == XAxis ) glRotatef( deg, 1, 0, 0 ); else if ( axis == YAxis ) glRotatef( deg, 0, 1, 0 ); else glRotatef( deg, 0, 0, 1 ); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[i].model); } glLoadMatrixf((GLfloat *) views[CurrentView].model); } void GLLandscape::rotateX( int deg ) { static int oldDeg = 0; rotate( deg-oldDeg, XAxis ); oldDeg = deg; updateGL(); } void GLLandscape::rotateY( int deg ) { static int oldDeg = 0; rotate( deg-oldDeg, YAxis ); oldDeg = deg; updateGL(); } void GLLandscape::rotateZ( int deg ) { static int oldDeg = 0; rotate( deg-oldDeg, ZAxis ); oldDeg = deg; updateGL(); } void GLLandscape::zoom( int z ) { float zoom; if ( z < 100 ) { zoom = 1 + 4.99 - (z*5.0 / 100.0); } else { z = 200 - z; zoom = z / 100.0; } makeCurrent(); glMatrixMode( GL_MODELVIEW ); // Always scale the original model matrix glLoadMatrixf((GLfloat *) views[DefaultView].model); glScalef( zoom, zoom, zoom ); glGetFloatv(GL_MODELVIEW_MATRIX, (GLfloat *) views[CurrentView].model); updateGL(); } void GLLandscape::resetGrid() { setGridSize( gridSize ); } void GLLandscape::fractalize() { Vector p; double value; double roughness = 0.5; int frequency = 50; p.x = p.y = p.z = 0; // Initialise fbm routine if ( initFractals ) { initFractals = FALSE; value = fBm( p, roughness, 2.0, 8.0, 1 ); } // Fractalize grid for ( int x = 0; x < gridSize; x++ ) { for ( int y = 0; y < gridSize; y++ ) { p.x = (double) x / (101 - frequency); p.y = (double) y / (101 - frequency); p.z = (double) landscape[x][y] / (101 - frequency); value = fBm(p, roughness, 2.0, 8.0, 0); landscape[x][y] += value; } } calculateVertexNormals(); updateGL(); } // // Calculate the vector cross product of v and w, store result in n. // static void crossProduct( double v[3], double w[3], double n[3] ) { n[0] = v[1]*w[2]-w[1]*v[2]; n[1] = w[0]*v[2]-v[0]*w[2]; n[2] = v[0]*w[1]-w[0]*v[1]; } void GLLandscape::calculateVertexNormals() { double len, v[3], v2[3], w[3], w2[3], n[3], n2[3]; // Calculate the surface normals for all polygons in the // height field for ( int i = 0; i < (gridSize-1); i++ ) for ( int k = 0; k < (gridSize-1); k++ ) { /* Lower poly normal */ v[0] = 1; // (i+1)-i v[1] = 0; // k-k v[2] = landscape[i+1][k]-landscape[i][k]; w[0] = 1; // (i+1)-i w[1] = 1; // (k+1)-k w[2] = landscape[i+1][k+1]-landscape[i][k]; crossProduct( v, w, n ); len = sqrt(n[0]*n[0]+n[1]*n[1]+n[2]*n[2]); normals[i][k].l[0] = n[0]/len; normals[i][k].l[1] = n[1]/len; normals[i][k].l[2] = n[2]/len; /* Upper poly normal */ v2[0] = -1.0; // i-(i+1); v2[1] = 0.0; // (k+1)-(k+1); v2[2] = landscape[i][k+1]-landscape[i+1][k+1]; w2[0] = -1.0; // i-(i+1); w2[1] = -1.0; // k-(k+1); w2[2] = landscape[i][k]-landscape[i+1][k+1]; crossProduct( v2, w2, n2 ); len = sqrt(n2[0]*n2[0]+n2[1]*n2[1]+n2[2]*n2[2]); normals[i][k].u[0] = n2[0]/len; normals[i][k].u[1] = n2[1]/len; normals[i][k].u[2] = n2[2]/len; } // Calculate proper vertex normals averageNormals(); } void GLLandscape::averageNormals() { // Calculate the average surface normal for a vertex based on // the normals of the surrounding polygons for ( int i = 0; i < gridSize; i++ ) for ( int k = 0; k < gridSize; k++ ) { if ( i > 0 && k > 0 && i < (gridSize-1) && k < (gridSize-1) ) { // For vertices that are *not* on the edge of the height field for ( int t = 0; t < 3; t++ ) // X, Y and Z components vertexNormals[i][k].n[t] = ( normals[i][k].u[t] + normals[i][k].l[t] + normals[i][k-1].u[t] + normals[i-1][k-1].u[t] + normals[i-1][k-1].l[t] + normals[i-1][k].l[t] )/6.0; } else { // Vertices that are on the edge of the height field require // special attention.. if ( i == 0 && k == 0 ) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = ( normals[i][k].u[t] + normals[i][k].l[t] )/2.0; } else if ( i == gridSize-1 && k == gridSize-1 ) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = ( normals[i][k].u[t] + normals[i][k].l[t] )/2.0; } else if ( i == gridSize-1) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = vertexNormals[i-1][k].n[t]; } else if ( k == gridSize-1 ) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = vertexNormals[i][k-1].n[t]; } else if ( k > 0 ) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = (normals[i][k].u[t] + normals[i][k].l[t] + normals[i][k-1].u[t])/3.0; } else if ( i > 0 ) { for ( int t = 0; t < 3; t++ ) vertexNormals[i][k].n[t] = (normals[i][k].u[t] + normals[i][k].l[t] + normals[i-1][k].l[t])/3.0; } } } } void GLLandscape::setWireframe( int state ) { if ( state != 1 ) { // Enable line antialiasing makeCurrent(); glEnable( GL_LINE_SMOOTH ); glEnable( GL_BLEND ); glDisable( GL_DEPTH_TEST ); glDisable( GL_LIGHTING ); glDisable( GL_NORMALIZE ); glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ); glHint( GL_LINE_SMOOTH_HINT, GL_DONT_CARE ); mode = Wireframe; updateGL(); } } void GLLandscape::setFilled( int state ) { if ( state != 1 ) { makeCurrent(); glEnable( GL_DEPTH_TEST ); glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); glDisable( GL_LIGHTING ); glDisable( GL_NORMALIZE ); mode = Filled; updateGL(); } } void GLLandscape::setSmoothShaded( int state ) { if ( state != 1 ) { makeCurrent(); glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_NORMALIZE ); glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); glShadeModel( GL_SMOOTH ); glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE ); // Setup lighting and material properties GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 }; GLfloat ambient[] = { 0.50, 0.50, 0.50, 0.0 }; GLfloat diffuse[] = { 1.00, 1.00, 1.00, 0.0 }; GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 }; GLfloat materialAmbient[] = { 0.00, 0.00, 1.0, 0.0 }; // GLfloat materialDiffuse[] = { 1.00, 1.00, 1.0, 0.0 }; GLfloat materialShininess[] = { 128.0 }; GLfloat materialSpecular[] = { 1.0, 1.0, 1.0, 0.0 }; glMaterialfv( GL_FRONT, GL_SPECULAR, materialSpecular ); // glMaterialfv( GL_FRONT, GL_DIFFUSE, materialDiffuse ); glMaterialfv( GL_FRONT, GL_AMBIENT, materialAmbient ); glMaterialfv( GL_FRONT, GL_SHININESS, materialShininess ); glLightfv( GL_LIGHT0, GL_POSITION, position ); glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); glLightfv( GL_LIGHT0, GL_SPECULAR, specular ); mode = SmoothShaded; calculateVertexNormals(); updateGL(); } } void GLLandscape::setLandscape( int state ) { if ( state != 1 ) { makeCurrent(); glEnable( GL_DEPTH_TEST ); glEnable( GL_LIGHTING ); glEnable( GL_LIGHT0 ); glEnable( GL_NORMALIZE ); glDisable( GL_LINE_SMOOTH ); glDisable( GL_BLEND ); glShadeModel( GL_SMOOTH ); glLightModeli( GL_LIGHT_MODEL_LOCAL_VIEWER, GL_TRUE ); // Setup lighting and material properties GLfloat position[] = { 15.0, -15.0, 15.0, 0.0 }; GLfloat ambient[] = { 0.50, 0.50, 0.50, 0.0 }; GLfloat diffuse[] = { 1.00, 1.00, 1.00, 0.0 }; GLfloat specular[] = { 1.0, 1.0, 1.0, 0.0 }; glLightfv( GL_LIGHT0, GL_POSITION, position ); glLightfv( GL_LIGHT0, GL_AMBIENT, ambient ); glLightfv( GL_LIGHT0, GL_DIFFUSE, diffuse ); glLightfv( GL_LIGHT0, GL_SPECULAR, specular ); glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR ); mode = Landscape; calculateVertexNormals(); updateGL(); } } void GLLandscape::mousePressEvent( QMouseEvent *e ) { oldPos = e->pos(); mouseButtonDown = TRUE; } void GLLandscape::mouseReleaseEvent( QMouseEvent *e ) { oldPos = e->pos(); mouseButtonDown = FALSE; } void GLLandscape::mouseMoveEvent( QMouseEvent *e ) { GLfloat rx = (GLfloat) (e->x() - oldPos.x()) / width(); GLfloat ry = (GLfloat) (e->y() - oldPos.y()) / height(); if ( e->state() == LeftButton ) { // Left button down - rotate around X and Y axes oldX = 180*ry; oldY = 180*rx; rotate( oldX, XAxis ); rotate( oldY, YAxis ); updateGL(); } else if ( e->state() == RightButton ) { // Right button down - rotate around X and Z axes oldX = 180*ry; oldZ = 180*rx; rotate( oldX, XAxis ); rotate( oldZ, ZAxis ); updateGL(); } oldPos = e->pos(); } void GLLandscape::timerEvent( QTimerEvent *e ) { if (e->timerId() == cubeTimer) { cubeRot += 1; if (!animationRunning) updateGL(); return; } int dx, dy; // disturbance point float s, v, W, t; int i, j; if ( mode == Landscape ) { dx = dy = 0; } else { dx = dy = gridSize >> 1; } W = 0.3; v = -4; // wave speed for ( i = 0; i < gridSize; i++ ) for ( j = 0; j < gridSize; j++ ) { s = sqrt( (double) ( (j - dx) * (j - dx) + (i - dy) * (i - dy) ) ); wt[i][j] += 0.1; t = s / v; if ( mode == Landscape ) { if ( (landscape[i][j] + wave[i][j]) < 0 ) landscape[i][j] -= wave[i][j]; if ( (dy - j != 0) || (dx - i != 0) ) wave[i][j] = (3 * sin( 2 * PI * W * (wt[i][j] + t ))) / (0.2*(sqrt( pow((double)(dx-i), 2) + pow((double)(dy-j), 2))+2)); else wave[i][j] = ( 3 * sin( 2 * PI * W * ( wt[i][j] + t ) ) ); if ( landscape[i][j] + wave[i][j] < 0 ) landscape[i][j] += wave[i][j]; } else { landscape[i][j] -= wave[i][j]; if ( s != 0 ) wave[i][j] = 2 * sin(2 * PI * W * ( wt[i][j] + t )) / (0.2*(s + 2)); else wave[i][j] = 2 * sin( 2 * PI * W * ( wt[i][j] + t ) ); landscape[i][j] += wave[i][j]; } } if ( mode == SmoothShaded || mode == Landscape ) calculateVertexNormals(); updateGL(); } void GLLandscape::toggleWaveAnimation( bool state ) { if (state) { animTimer = startTimer(20); animationRunning = TRUE; } else { killTimer(animTimer); animationRunning = FALSE; } } void GLLandscape::showEvent( QShowEvent * ) { if (animationRunning) animTimer = startTimer(20); cubeTimer = startTimer(50); } void GLLandscape::hideEvent( QHideEvent * ) { if (animationRunning) killTimer(animTimer); killTimer(cubeTimer); } void GLLandscape::initDisplayLists() { // axisList axisList = glGenLists(1); glNewList(axisList, GL_COMPILE); glEnable(GL_LINE_SMOOTH); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glEnable(GL_DEPTH_TEST); glColor3f(1.0, 0.0, 0.0); glBegin(GL_LINES); { glColor3f(1.0, 0.0, 0.0); glVertex3f(-1.0f, 0, 0); // x axis glVertex3f(1.0f, 0, 0); glVertex3f(1.0f, 0, 0); glVertex3f(0.8f, 0.2f, 0); glVertex3f(1.0f, 0, 0); glVertex3f(0.8f, -.2f, 0); glColor3f(0.0, 1.0, 0.0); glVertex3f(0, -1.0f, 0); // y axis glVertex3f(0, 1.0f, 0); glVertex3f(0, 1.0f, 0); glVertex3f(0.2f, 0.8f, 0); glVertex3f(0, 1.0f, 0); glVertex3f(-0.2f, 0.8f, 0); glColor3f(0.5, 0.5, 1.0); glVertex3f(0, 0, -1.0f); // z axis glVertex3f(0, 0, 1.0f); glVertex3f(0, 0, 1.0f); glVertex3f(0, 0.2f, 0.8f); glVertex3f(0, 0, 1.0f); glVertex3f(0,-0.2f, 0.8f); } glEnd(); glEndList(); // cubeList cubeList = glGenLists(1); glNewList(cubeList, GL_COMPILE); glEnable(GL_TEXTURE_2D); glEnable(GL_DEPTH_TEST); glEnable(GL_CULL_FACE); glEnable(GL_BLEND); glBlendFunc(GL_SRC_ALPHA, GL_SRC_COLOR); glBegin( GL_QUADS ); { glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 0.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 0.0, 0.0, 0.0 ); } glEnd(); glDisable(GL_TEXTURE_2D); glEndList(); }