📄 gllandscape.cpp
字号:
#include "gllandscape.h"#include <math.h>#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#endifGLLandscape::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; createGrid( 50 ); setWireframe( 0 );}GLLandscape::~GLLandscape(){ destroyGrid();}void GLLandscape::initializeGL(){ glMatrixMode( GL_MODELVIEW ); glLoadIdentity(); 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();}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 ); if ( lighting ) { glEnable( GL_LIGHTING ); }}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 = 0; i < 2; 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();}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -