【Qt OpenGL教程】08:混合
来源:互联网 发布:数据库完整性检查 编辑:程序博客网 时间:2024/05/16 00:44
第08课:混合 (参照NeHe)
这次教程中,我们将在纹理映射的基础上加上混合,使它看起来具有透明的效果,当然解释它不是那么容易但代码并不难,希望你喜欢它。
OpenGL中的绝大多数特效都与某些类型的(色彩)混合有关。混色的定义为,将某个像素的颜色和已绘制在屏幕上与其对应的像素颜色相互结合。至于如何结合这两种颜色则依赖于颜色的alpha通道的分量值,以及所用的混色函数。Alpha通常是位于颜色值末尾的第4个颜色组成分量,一般都认为Alpha分量代表材料的透明度。也就是说,alpha值为0.0时所代表的材料是完全透明的,alpha值为1.0时所代表的材料则是完全不透明的。
在OpenGL中实现混色的步骤类似于我们以前提到的OpenGL过程,接着设置公式,并在绘制透明对象时关闭写深度缓存。因为我们想在半透明的图形背后绘制对象,这不是正确的混色方法,但绝大多数时候这种做法在简单的项目中都工作得很好。正确的混色过程应该是先绘制全部非透明场景之后,再绘制透明的图形,并且要按照与深度缓存相反的次序来绘制(先画最远的物体)。
程序运行时效果如下:
下面进入教程:
我们这次将在第07课的基础上修改代码,首先打开myglwidget.h文件,增加一个布尔变量m_Blend来记录是否开启混合,修改后代码如下:
#ifndef MYGLWIDGET_H#define MYGLWIDGET_H#include <QWidget>#include <QGLWidget>class MyGLWidget : public QGLWidget{ Q_OBJECTpublic: explicit MyGLWidget(QWidget *parent = 0); ~MyGLWidget();protected: //对3个纯虚函数的重定义 void initializeGL(); void resizeGL(int w, int h); void paintGL(); void keyPressEvent(QKeyEvent *event); //处理键盘按下事件private: bool fullscreen; //是否全屏显示 QString m_FileName; //图片的路径及文件名 GLuint m_Texture; //储存一个纹理 bool m_Light; //光源的开/关 bool m_Blend; //是否混合 GLfloat m_xRot; //x旋转角度 GLfloat m_yRot; //y旋转角度 GLfloat m_xSpeed; //x旋转速度 GLfloat m_ySpeed; //y旋转速度 GLfloat m_Deep; //深入屏幕的距离};#endif // MYGLWIDGET_H
接下来打开myglwidget.cpp文件,加上声明#include <QTimer>,在构造函数中对增加变量进行初始化并更换图片,使用不同的纹理来绘画立方体,具体修改后代码如下:
MyGLWidget::MyGLWidget(QWidget *parent) : QGLWidget(parent){ fullscreen = false; m_FileName = "D:/QtOpenGL/QtImage/Glass.bmp"; //应根据实际存放图片的路径进行修改 m_Light = false; m_Blend = false; m_xRot = 0.0f; m_yRot = 0.0f; m_xSpeed = 0.0f; m_ySpeed = 0.0f; m_Deep = -5.0f; QTimer *timer = new QTimer(this); //创建一个定时器 //将定时器的计时信号与updateGL()绑定 connect(timer, SIGNAL(timeout()), this, SLOT(updateGL())); timer->start(10); //以10ms为一个计时周期}
然后就要进入重点的混合,其他代码非常简单,并不像解释它时那么麻烦,只需要对initializeGL()作一定的修改,具体代码如下:
void MyGLWidget::initializeGL() //此处开始对OpenGL进行所以设置{ m_Texture = bindTexture(QPixmap(m_FileName)); //载入位图并转换成纹理 glEnable(GL_TEXTURE_2D); //启用纹理映射 glClearColor(0.0f, 0.0f, 0.0f, 0.0f); //黑色背景 glShadeModel(GL_SMOOTH); //启用阴影平滑 glClearDepth(1.0); //设置深度缓存 glEnable(GL_DEPTH_TEST); //启用深度测试 glDepthFunc(GL_LEQUAL); //所作深度测试的类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); //告诉系统对透视进行修正 //下面是光源部分 GLfloat LightAmbient[] = {0.5f, 0.5f, 0.5f, 1.0f}; //环境光参数 GLfloat LightDiffuse[] = {1.0f, 1.0f, 1.0f, 1.0f}; //漫散光参数 GLfloat LightPosition[] = {0.0f, 0.0f, 2.0f, 1.0f}; //光源位置 glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); //设置环境光 glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse); //设置漫射光 glLightfv(GL_LIGHT1, GL_POSITION, LightPosition); //设置光源位置 glEnable(GL_LIGHT1); //启动一号光源 //下面是混合部分 glColor4f(1.0f, 1.0f, 1.0f, 0.5f); //全亮度,50%Alpha混合 glBlendFunc(GL_SRC_ALPHA, GL_ONE); //基于源像素alpah通道值得半透明混合函数}增加了两行代码,第一行以全亮度绘制此物体,并对其进行50%的alpha混合(半透明),当混合选项开启时,次物体将会产生50%的透明效果。第二行设置所采用的混合类型。看,代码真的挺简单的。
最后是键盘控制的代码,具体代码如下:
void MyGLWidget::keyPressEvent(QKeyEvent *event){ switch (event->key()) { case Qt::Key_F1: //F1为全屏和普通屏的切换键 fullscreen = !fullscreen; if (fullscreen) { showFullScreen(); } else { showNormal(); } break; case Qt::Key_Escape: //ESC为退出键 close(); break; case Qt::Key_B: //B为开始关闭混合而对切换键 m_Blend = !m_Blend; if (m_Blend) { glEnable(GL_BLEND); //开启混合 glDisable(GL_DEPTH_TEST); //关闭深度测试 } else { glDisable(GL_BLEND); //关闭混合 glEnable(GL_DEPTH_TEST); //打开深度测试 } break; case Qt::Key_L: //L为开启关闭光源的切换键 m_Light = !m_Light; if (m_Light) { glEnable(GL_LIGHTING); //开启光源 } else { glDisable(GL_LIGHTING); //关闭光源 } break; case Qt::Key_PageUp: //PageUp按下使木箱移向屏幕内部 m_Deep -= 0.1f; break; case Qt::Key_PageDown: //PageDown按下使木箱移向观察者 m_Deep += 0.1f; break; case Qt::Key_Up: //Up按下减少m_xSpeed m_xSpeed -= 0.1f; break; case Qt::Key_Down: //Down按下增加m_xSpeed m_xSpeed += 0.1f; break; case Qt::Key_Right: //Right按下减少m_ySpeed m_ySpeed -= 0.1f; break; case Qt::Key_Left: //Left按下增加m_ySpeed m_ySpeed += 0.1f; break; }}当B键的控制机制与L键相似,但注意到,开启混合时还要关闭深度测试,关闭混合时还要打开深度测试,否则将发现立方体有一些面不见了!
现在就可以运行程序看效果了!
全部教程中需要的资源文件点此下载
0 0
- 【Qt OpenGL教程】08:混合
- Andriod OpenGL 教程 08 - 混合
- OpenGL教程之Alpha混合
- Qt OpenGL教程
- Qt OpenGL教程
- 实现Qt和OpenGL混合渲染
- NeHe OpenGL教程 第八课 混合
- Qt OpenGL教程 (非常详细)
- 【Qt OpenGL教程】04:旋转
- 【Qt OpenGL教程】20:蒙板
- 【Qt OpenGL教程】27:阴影
- Qt OpenGL教程 (非常详细)
- Qt OpenGL教程 (非常详细)
- Qt OpenGL教程 (非常详细)
- OpenGL:混合
- OpenGL混合
- OPENGL混合
- OpenGL混合
- 仿QQ侧滑 添加事件下发
- ss 命令用法
- p1978 Fibonacci数列 3
- 多线程与并发知识点总结
- 程序员几个重要的网站
- 【Qt OpenGL教程】08:混合
- 南邮 OJ 1023 字符串排序
- 怎么用pfSense为你的web服务做负载均衡
- Highcharts中字符串处理方式(1)
- POJ 3080 Blue Jeans(字符串处理函数)
- ROUND 2の Asia - Phuket2013
- 一个非常Nice的透明提示器工具
- awk 两个文件的两个列若相同,合并两个文件
- 225 - Golygons(暴力搜索)