当前位置:文档之家› 计算机图形学 光照及纹理报告

计算机图形学 光照及纹理报告

《计算机图形学》综合训练项目报告关键代码及界面展示1.源代码//头文件#ifndef GLWIDGET_H#define GLWIDGET_H#include <QtOpenGL>#include <QWidget>class GLWidget : public QGLWidget{Q_OBJECTpublic: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//主函数#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();}//程序主要代码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;//防止一条边为0glViewport(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);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();/*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的图片格式texglGenTextures(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是混合使用}2.界面展示。

相关主题