第23课:球面映射 (参照NeHe)
这次教程中,我们将学会如何把环境纹理包裹在我们的3D模型上,让它看起来像反射了周围的景象一样,我们把这种纹理映射的方式称为球体映射。球体映射是一种创建金属反射效果的方法,虽然它并不像真实世界里那么精确,但效果还是很不错的!
红宝书中,球体映射的定义为,把一幅位于无限远的图像映射到球面上。当然我们需要自己来创建一幅球体环境映射图,方法如下:
打开Photoshop,并在Photoshop中打开我们要转换成球体环境映射图的原图,选择所有的像素点,创建它的一个复制。接着我们把图像变为2的幂次方大小,一般为128×128或256×256.最后使用扭曲滤镜,并应用球体效果,然后把得到的图像保存为 *.bmp文件(PS:我给大家的资源文件中球体映射图是处理好的了,命名为Reflect.bmp)。
程序运行时效果如下:
下面进入教程:
我们这次将在第18课的基础上修改代码,这次相比前两次简单太多了,我只会对代码的变化作出解释。首先打开myglwidget.h文件,将类声明更改如下:
#ifndef MYGLWIDGET_H
#define MYGLWIDGET_H
#include <QWidget>
#include <QGLWidget>
class GLUquadric;
class MyGLWidget : public QGLWidget
{
Q_OBJECT
public:
explicit MyGLWidget(QWidget *parent = 0);
~MyGLWidget();
protected:
//对3个纯虚函数的重定义
void initializeGL();
void resizeGL(int w, int h);
void paintGL();
void keyPressEvent(QKeyEvent *event); //处理键盘按下事件
private:
void glDrawCube(); //绘制立方体
private:
bool fullscreen; //是否全屏显示
QString m_FileName[2]; //图片的路径及文件名
GLuint m_Texture[2]; //储存两个纹理
bool m_Light; //光源的开/关
GLfloat m_xRot; //x旋转角度
GLfloat m_yRot; //y旋转角度
GLfloat m_xSpeed; //x旋转速度
GLfloat m_ySpeed; //y旋转速度
GLfloat m_Deep; //深入屏幕的距离
GLUquadric *m_Quadratic; //二次几何体
GLuint m_Object; //绘制对象标示符
};
#endif // MYGLWIDGET_H
由于我们程序的背景图和用于纹理映射的图并不是同一张(后者是PS处理过的那张),所以我们需要储存两个不同的纹理,m_FileName和m_Texture就都变成长度为2的数组啦。然后我们删掉了m_Part1、m_Part2、m_P1、m_P2等变量,由于我们后面的绘制过程并不打算绘制圆盘和部分圆盘,这是因为它们绘制出来的映射效果并不好,所以我就不绘制它们了。
接下来,我们需要打开myglwidget.cpp,对构造函数进行修改(更