QT5 Opengl (八,绘制雾的效果)
2016-04-08 23:22
387 查看
概要
效果图
第一种样式的雾
第二种样式的雾
第三种样式的雾
深度比较低的雾
淡红色的雾
在原来基础上加的代码
重点解析
![](http://img.blog.csdn.net/20160408230150758)
![](http://img.blog.csdn.net/20160408230248338)
![](http://img.blog.csdn.net/20160408230326198)
![](http://img.blog.csdn.net/20160408230415808)
![](http://img.blog.csdn.net/20160408230453198)
.cpp文件
效果图
第一种样式的雾
第二种样式的雾
第三种样式的雾
深度比较低的雾
淡红色的雾
在原来基础上加的代码
重点解析
概要
在一些场景里面,我们有时雾要一些雾的衬托,这样就会让场景看起来更真实一点。这篇文章就是主要讲怎么绘制出雾的效果。效果图
第一种样式的雾
第二种样式的雾
第三种样式的雾
深度比较低的雾
淡红色的雾
在原来基础上加的代码
.h文件#ifndef OPENGLWIDGET_H #define OPENGLWIDGET_H #include <QtOpenGL> class OpenglWidget : public QGLWidget { public: OpenglWidget(QWidget* parent = 0); protected: void initConnection(); void initializeGL(); void initWidget(); void paintGL(); void resizeGL(int width, int height); void loadGLTextures(); void keyPressEvent( QKeyEvent *e ); private slots: private: GLfloat m_rotateTriangle; GLfloat m_rotateRectangle; GLfloat m_x; GLfloat m_y; GLfloat m_z; GLuint textur[3]; GLfloat m_zoom; GLfloat m_xSpeed; GLfloat m_ySpeed; GLfloat m_zSpeed; bool m_openLight; GLuint m_choiceTexture; bool m_mixTogether; GLuint m_fog; }; #endif // OPENGLWIDGET_H
.cpp文件
#include "openglwidget.h" GLfloat lightAmbient[4] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat lightDiffuse[4] = { 1.0, 1.0, 1.0, 1.0 }; GLfloat lightPosition[4] = { 0.0, 0.0, 2.0, 1.0 }; GLuint fogMode[3] = { GL_EXP, GL_EXP2, GL_LINEAR }; //GLfloat fogColor[4] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat fogColor[4] = { 0.2, 0, 0, 1.0 }; OpenglWidget::OpenglWidget(QWidget* parent) :QGLWidget(parent), m_rotateTriangle(0), m_rotateRectangle(0), m_x(0), m_y(0), m_z(0), m_zoom(-6), m_xSpeed(10), m_ySpeed(10), m_zSpeed(10), m_choiceTexture(0), m_openLight(false), m_mixTogether(false), m_fog(0) { initWidget(); } void OpenglWidget::initializeGL() { loadGLTextures(); glEnable( GL_TEXTURE_2D ); glShadeModel( GL_SMOOTH ); // glClearColor( 0.0, 0.0, 0.0, 0.5 ); glClearColor( 0.5, 0.5, 0.5, 1 ); glClearDepth( 1.0 ); glEnable( GL_DEPTH_TEST ); glDepthFunc( GL_LEQUAL ); glHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ); glLightfv( GL_LIGHT1, GL_AMBIENT, lightAmbient ); glLightfv( GL_LIGHT1, GL_DIFFUSE, lightDiffuse ); glLightfv( GL_LIGHT1, GL_POSITION, lightPosition ); glEnable( GL_LIGHT1 ); glFogi( GL_FOG_MODE, fogMode[m_fog] ); glFogfv( GL_FOG_COLOR, fogColor ); glFogf( GL_FOG_DENSITY, 0.2 ); glHint( GL_FOG_HINT, GL_NICEST ); glFogf( GL_FOG_START, -3.0 ); glFogf( GL_FOG_END, 6.0 ); glEnable( GL_FOG ); glColor4f(1, 1, 1, 0.5); glBlendFunc( GL_SRC_ALPHA, GL_ONE ); } void OpenglWidget::initWidget() { setGeometry( 400, 200, 640, 480 ); setWindowTitle(tr("opengl demo")); } void OpenglWidget::paintGL() { glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef( -1.5, 0.0, m_zoom ); glRotatef( m_x, 1.0, 0.0, 0.0 ); glRotatef( m_y, 0.0, 1.0, 0.0 ); glRotatef( m_z, 0.0, 0.0, 1.0 ); glBindTexture( GL_TEXTURE_2D, textur[m_choiceTexture] ); glBegin( GL_QUADS ); glNormal3f( 0.0, 0.0, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.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, 1.0 ); glNormal3f( 0.0, 0.0, -1.0 ); glTexCoord2f( 1.0, 0.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, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glNormal3f( 0.0, 1.0, 0.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( -1.0, 1.0, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( 1.0, 1.0, 1.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( 1.0, 1.0, -1.0 ); glNormal3f( 0.0, -1.0, 0.0 ); glTexCoord2f( 1.0, 1.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 0.0, 1.0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1.0, 0.0 ); glVertex3f( -1.0, -1.0, 1.0 ); glNormal3f( 1.0, 0.0, 0.0 ); glTexCoord2f( 1.0, 0.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, 1.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( 1.0, -1.0, 1.0 ); glNormal3f( -1.0, 0.0, 0.0 ); glTexCoord2f( 0.0, 0.0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1.0, 0.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, -1.0 ); glEnd(); glLoadIdentity(); glTranslatef( 1.5, 0.0, m_zoom ); glRotatef( m_x, 1.0, 0.0, 0.0 ); glRotatef( m_y, 0.0, 1.0, 0.0 ); glRotatef( m_z, 0.0, 0.0, 1.0 ); glBegin(GL_TRIANGLES); //三棱柱四面贴图 glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( 1, -1, 1 ); glTexCoord2f( 1, 0 ); glVertex3f( -1, -1, 1 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 0, 1, 0 ); glTexCoord2f( 0, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, 1.0 ); //三棱柱底面贴图 glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 1, 0 ); glVertex3f( 1.0, -1.0, -1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0, 1 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 1, 1 ); glVertex3f( 1.0, -1.0, 1.0 ); glTexCoord2f( 0, 1 ); glVertex3f( -1.0, -1.0, 1.0 ); glTexCoord2f( 0, 0 ); glVertex3f( -1.0, -1.0, -1.0 ); glEnd(); m_x += m_xSpeed; m_y += m_ySpeed; m_z += m_zSpeed; } void OpenglWidget::resizeGL(int width, int height) { if(0 == height) { height = 1; } glViewport(0, 0, (GLint)width, (GLint)height); glMatrixMode(GL_PROJECTION); glLoadIdentity(); // gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0); GLdouble aspectRatio = (GLfloat)width/(GLfloat)height; GLdouble zNear = 0.1; GLdouble zFar = 100.0; GLdouble rFov = 45.0 * 3.14159265 / 180.0; glFrustum( -zNear * tan( rFov / 2.0 ) * aspectRatio, zNear * tan( rFov / 2.0 ) * aspectRatio, -zNear * tan( rFov / 2.0 ), zNear * tan( rFov / 2.0 ), zNear, zFar ); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void OpenglWidget::loadGLTextures() { QImage tex; QImage buf; if ( !buf.load(":/images/dog.png")) { qWarning( "load image failed!" ); QImage dummy( 128, 128, QImage::Format_RGB32 ); dummy.fill( Qt::red); buf = dummy; } tex = QGLWidget::convertToGLFormat( buf ); glGenTextures( 3, &textur[0] ); //纹理一 glBindTexture( GL_TEXTURE_2D, textur[0] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); //纹理二 glBindTexture( GL_TEXTURE_2D, textur[1] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); //纹理三 glBindTexture( GL_TEXTURE_2D, textur[2] ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST_MIPMAP_NEAREST ); //gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); glTexImage2D( GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits() ); } void OpenglWidget::keyPressEvent( QKeyEvent *e ) { switch ( e->key() ) { case Qt::Key_L: m_openLight = !m_openLight; if ( !m_openLight ) { glDisable( GL_LIGHTING ); } else { glEnable( GL_LIGHTING ); } updateGL(); break; case Qt::Key_F: m_choiceTexture += 1;; if ( m_choiceTexture > 2 ) { m_choiceTexture = 0; } updateGL(); break; case Qt::Key_W: m_zoom -= (GLfloat)0.2; updateGL(); break; case Qt::Key_S: m_zoom += (GLfloat)0.2; updateGL(); break; case Qt::Key_Up: m_xSpeed -= 1; updateGL(); break; case Qt::Key_Down: m_xSpeed += 1; updateGL(); break; case Qt::Key_Right: m_ySpeed += 1; updateGL(); break; case Qt::Key_Left: m_ySpeed -= 1; updateGL(); break; case Qt::Key_A: m_zSpeed += 1; updateGL(); break; case Qt::Key_D: m_zSpeed -= 1; updateGL(); break; case Qt::Key_M: m_mixTogether = !m_mixTogether; if ( m_mixTogether ) { glEnable( GL_BLEND ); glDisable( GL_DEPTH_TEST ); } else { glDisable( GL_BLEND ); glEnable( GL_DEPTH_TEST ); } updateGL(); break; case Qt::Key_G: m_fog += 1;; if ( m_fog > 2 ){ m_fog = 0; } glFogi( GL_FOG_MODE, fogMode[m_fog] ); updateGL(); break; case Qt::Key_Escape: close(); break; } }
重点解析
相对于原来的代码, 有关雾的代码主要有:在.h文件里面添加了一个雾的种类的变量。 GLuint m_fog; 在.cpp文件里面设置了雾的种类和颜色 GLuint fogMode[3] = { GL_EXP, GL_EXP2, GL_LINEAR }; //GLfloat fogColor[4] = { 0.5, 0.5, 0.5, 1.0 }; GLfloat fogColor[4] = { 0.2, 0, 0, 1.0 }; 在initializeGL()函数里面设置了场景的背景色彩为灰色 glClearColor( 0.5, 0.5, 0.5, 1 ); glFogi( GL_FOG_MODE, fogMode[m_fog] ); //选择雾的样式,这里默认为第一种GL_EXP glFogfv( GL_FOG_COLOR, fogColor ); //设置雾的颜色 glFogf( GL_FOG_DENSITY, 0.2 ); //设置雾的浓度 glHint( GL_FOG_HINT, GL_NICEST ); //选择渲染效果 glFogf( GL_FOG_START, -3.0 ); glFogf( GL_FOG_END, 6.0 ); //雾开始与结束的位置 glEnable( GL_FOG ); //允许雾的使用 case Qt::Key_G: m_fog += 1;; if ( m_fog > 2 ){ m_fog = 0; } glFogi( GL_FOG_MODE, fogMode[m_fog] ); updateGL(); break; //这里添加了键盘事件,用来选择不同样式的雾。 所以雾的效果,还是主要靠调用opengl的接口。
相关文章推荐
- Qt实现简易天气预报(解析的是json数据)
- QT写的贪吃蛇
- QT中通过HTTP URL获取并保存网页上的图片
- Qt学习笔记之图片的上下左右移动
- 解决Qt5 Creator无法切换输入法(fcitx),Ubuntu中不能使用搜狗输入法录入汉字问题
- C#改变LInqToSQL的引用地址,读取config的数据库字符串
- OK335xS Qt network hacking
- QT5 OpenGL(七, 透明度设置)
- 在HI3531上移植和运行QT4.8.6
- windows 下QT5.5+vs2013开发环境搭建
- Qt使用数据库(2)
- QT在Label上画矩形
- QT官网文档网址
- PCL+Qt+VS可视化点云(二)出现 no override found for ‘vtkRenderWindow’错误解决方法
- Qt之主窗口背景图片动态拉伸
- Qt使用VS编译时“转到COFF期间失败”解决方法
- Qt QLineEdit 限制输入类型以及大小Int 和double
- 编译 arm 版的qt
- qt绘图
- Qt制作贪吃蛇游戏