Qt_OpenGL:光照纹理滤波色彩混合小测
2014-12-08 20:46
513 查看
Qt_OpenGL:光照纹理滤波色彩混合小测
此测试程序包含了光照、纹理滤波和色彩融合等知识点。
//.h
//.cpp
//main.cpp
//运行截图:
![](http://img.blog.csdn.net/20141208205641966?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwMjcwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20141208205702937?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwMjcwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20141208205718844?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwMjcwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20141208205728562?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwMjcwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
![](http://img.blog.csdn.net/20141208205742291?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvdTAxMDAwMjcwNA==/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)
此测试程序包含了光照、纹理滤波和色彩融合等知识点。
//.h
#ifndef GLWIDGET_H #define GLWIDGET_H #include <QtOpenGL> #include <QWidget> class GLWidget : public QGLWidget { Q_OBJECT public: explicit GLWidget(QGLWidget *parent = 0); ~GLWidget(); protected: void initializeGL(); void paintGL(); void resizeGL(int width, int height); void keyPressEvent(QKeyEvent *e); void loadTextures(); bool fullscreen; GLuint texture[3]; private: float rotate_angle; float zoom; float rotate_speed; int filter; bool light; bool blend; }; #endif // GLWIDGET_H
//.cpp
<pre name="code" class="cpp"><pre name="code" class="cpp">#include "glwidget.h" #include <QtGui> #include <QtCore> #include <QtOpenGL> #include <glut.h> static const GLfloat light_ambient[4]={0.5, 0.5, 0.5, 1.0}; static const GLfloat light_diffuse[4]={1.0, 1.0, 1.0, 1.0}; static const GLfloat light_position[4]={0.0, 0.0, 2.0, 0.0}; GLWidget::GLWidget(QGLWidget *parent) : QGLWidget(parent) { // setCaption("The Opengl for Qt Framework"); fullscreen = false; rotate_angle = 0.0; zoom = -5.0; rotate_speed = 3.0; filter = 0; light = false; blend = false; } void GLWidget::initializeGL() { setGeometry(300, 150, 500, 500);//设置窗口初始位置和大小 loadTextures(); glEnable(GL_TEXTURE_2D);//允许采用2D纹理技术 glShadeModel(GL_SMOOTH);//设置阴影平滑模式 glClearColor(0.0, 0.0, 0.0, 0);//改变窗口的背景颜色,不过我这里貌似设置后并没有什么效果 glClearDepth(1.0);//设置深度缓存 glEnable(GL_DEPTH_TEST);//允许深度测试 glDepthFunc(GL_LEQUAL);//设置深度测试类型 glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);//进行透视校正 /*opengl中支持8个光源,即GL_LIGHT0~GL_LIGHT7*/ glLightfv(GL_LIGHT1, GL_AMBIENT, light_ambient);//指定光源1的环境光参数 glLightfv(GL_LIGHT1, GL_DIFFUSE, light_diffuse);//指定光源1的漫射光参数 glLightfv(GL_LIGHT1, GL_POSITION, light_position);//指定光源1的位置 glEnable(GL_LIGHT1);//允许光源1的使用 // glEnable(GL_LIGHTING);//我们还需要启动总光源开关,默认的时候不开,后面的L键来控制开启和关闭 glColor4f(1.0, 1.0, 1.0, 0.5);//后面的步骤都是以全亮绘制物体,并且50%的透明度 glBlendFunc(GL_SRC_ALPHA, GL_ONE); } void GLWidget::paintGL() { //glClear()函数在这里就是对initializeGL()函数中设置的颜色和缓存深度等起作用 glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); /*下面开始画立方体,并对其进行纹理映射*/ glLoadIdentity(); glTranslatef(0.0, 0.0, zoom); glRotatef(rotate_angle, -0.4f, 0.4f, -1.0f); glBindTexture(GL_TEXTURE_2D, texture[filter]);//这句代码一定要,因为在initializeGL()函数中已绑定一个固定的纹理目标了 glBegin(GL_QUADS); //上顶面 glNormal3f(0.0, 1.0, 0.0);//该函数指定是法线的方向为向量(x, y, z)方向,在使用光源且对空间物体进行纹理映射时, //每个面都需要指定其法线的方向,否则会出现各种意外的结果。 glTexCoord2f(0.0, 1.0);//将2D的纹理坐标映射到3D的空间物体表面上 glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 1.0f, -1.0f); //下顶面 glNormal3f(0.0, -1.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, -1.0f, -1.0f); //正前面 glNormal3f(0.0, 0.0, 1.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 1.0f, 1.0f); //右侧面 glNormal3f(1.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(1.0f, 1.0f, -1.0f); //背后面 glNormal3f(0.0, 0.0, -1.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(1.0f, 1.0f, -1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(1.0f, -1.0f, -1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(-1.0f, -1.0f, -1.0f); //左侧面 glNormal3f(-1.0, 0.0, 0.0); glTexCoord2f(0.0, 1.0); glVertex3f(-1.0f, 1.0f, -1.0f); glTexCoord2f(0.0, 0.0); glVertex3f(-1.0f, -1.0f, -1.0f); glTexCoord2f(1.0, 0.0); glVertex3f(-1.0f, -1.0f, 1.0f); glTexCoord2f(1.0, 1.0); glVertex3f(-1.0f, 1.0f, 1.0f); glEnd(); rotate_angle += rotate_speed; } void GLWidget::resizeGL(int width, int height) { if(0 == height) height = 1;//防止一条边为0 glViewport(0, 0, (GLint)width, (GLint)height);//重置当前视口,本身不是重置窗口的,只不过是这里被Qt给封装好了 glMatrixMode(GL_PROJECTION);//选择投影矩阵 glLoadIdentity();//重置选择好的投影矩阵 gluPerspective(45.0, (GLfloat)width/(GLfloat)height, 0.1, 100.0);//建立透视投影矩阵 glMatrixMode(GL_MODELVIEW);//以下2句和上面出现的解释一样 glLoadIdentity(); } void GLWidget::keyPressEvent(QKeyEvent *e) { switch(e->key()) { /*L键位开启光照的开关*/ case Qt::Key_L: light = !light; if(!light) glDisable(GL_LIGHTING); else glEnable(GL_LIGHTING); updateGL(); break; /*B键位选择是否采用色彩融合*/ case Qt::Key_B: blend = !blend; if(blend) { glEnable(GL_BLEND); glDisable(GL_DEPTH_TEST); } else { glDisable(GL_BLEND); glEnable(GL_DEPTH_TEST); } updateGL(); break; /*F键位选择纹理滤波的方式*/ case Qt::Key_F: filter += 1; if(filter > 2) filter = 0; updateGL(); break; /*PageUp键为将木箱移到屏幕内部方向*/ case Qt::Key_PageUp: zoom -= 0.2; updateGL(); break; /*PageDown键为将木箱移到屏幕外部方向*/ case Qt::Key_PageDown: zoom += 0.2; updateGL(); break; /*Up键为加快立方体旋转的速度*/ case Qt::Key_Up: rotate_speed += 1.0; updateGL(); break; /*Down键为减慢立方体旋转的速度*/ case Qt::Key_Down: rotate_speed -= 1.0; updateGL(); break; /*F1键为全屏和普通屏显示切换键*/ case Qt::Key_F1: fullscreen = !fullscreen; if(fullscreen) showFullScreen(); else { setGeometry(300, 150, 500, 500); showNormal(); } updateGL(); break; /*Ese为退出程序键*/ case Qt::Key_Escape: close(); } } /*加载纹理*/ void GLWidget::loadTextures() { QImage tex, buf; if(!buf.load(":resources/c.jpg")) // if(!buf.load(":resources/c.jpg")) { qWarning("Cannot open the image..."); QImage dummy(128, 128, QImage::Format_RGB32);//当没找到所需打开的图片时,创建一副128*128大小,深度为32位的位图 dummy.fill(Qt::green); buf = dummy; } tex = convertToGLFormat(buf);//将Qt图片的格式buf转换成opengl的图片格式tex glGenTextures(3, &texture[0]);//开辟3个纹理内存,索引指向texture[0] /*建立第一个纹理*/ glBindTexture(GL_TEXTURE_2D, texture[0]); glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); /*建立第二个纹理*/ glBindTexture(GL_TEXTURE_2D, texture[1]); glTexImage2D(GL_TEXTURE_2D, 0, 3, tex.width(), tex.height(), 0, GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); /*建立第三个纹理*/ glBindTexture(GL_TEXTURE_2D, texture[2]); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGB, tex.width(), tex.height(), GL_RGBA, GL_UNSIGNED_BYTE, tex.bits()); //该函数对所加载的纹理像素没有要求是2的n次方,可以是任意的像素 glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR_MIPMAP_NEAREST); //mipmap方式是当物体很远时,也能保留很好的细节,所以它的运算量很大,速度很慢,这里GL_LINEAR_MIPMAP_NEAREST是混合使用 } GLWidget::~GLWidget() { }
//main.cpp
#include "glwidget.h" #include <QApplication> #include <QGraphicsView> #include <QGraphicsScene> #include <QGraphicsItem> int main(int argc, char *argv[]) { QApplication a(argc, argv); GLWidget w; w.show(); return a.exec(); }
//运行截图:
相关文章推荐
- OpenGL_Qt学习笔记之_06(纹理滤波、光照和色彩融合)
- OpenGL_Qt学习笔记之_06(纹理滤波、光照和色彩融合)
- Qt下的OpenGL 编程(5)光照和纹理滤波
- Qt下的OpenGL 编程(5)光照和纹理滤波
- Qt下的OpenGL 编程(5)光照和纹理滤波
- Qt下的OpenGL 编程(5)光照和纹理滤波
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整) 转自http://www.cnblogs.com/tiandsp/archive/2012/01/23/2329049.html
- opengl纹理,光照,glColor4f(),混合
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整)
- opengl纹理,光照,glColor4f(),混合
- OpenGL学习笔记 (7) —— 三种不同的纹理滤波方式,光照和键盘控制
- opengl纹理,光照,glColor4f(),混合
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整) 复制代码
- OpenGL3D图形、旋转、纹理、键盘移动、光照、滤波、透明(完整)
- Qt OpenGL----纹理贴图
- Qt_OpenGL:纹理映射小测
- OpenGL——材质、光照与混合
- 【Qt OpenGL教程】07:光照和键盘控制
- Qt openGL 使用QImage 生成二维纹理
- [OPENGL]纹理,材质,光照