NeHe 系列教程之十四:雾
英文教程地址:lesson16
本课展示产生雾。
相关变量和函数定义:
namespace {
bool gp;
GLuint fogMode[] = { GL_EXP, GL_EXP2, GL_LINEAR };
GLuint fogfilter = 0;
GLfloat fogColor[4]= {0.5f, 0.5f, 0.5f, 1.0f}; // Fog Color
bool light; // Lighting ON / OFF
bool lp; // L Pressed?
bool fp; // F Pressed?
GLfloat xrot; // X Rotation
GLfloat yrot; // Y Rotation
GLfloat xspeed; // X Rotation Speed
GLfloat yspeed; // Y Rotation Speed
GLfloat z=-5.0f; // Depth Into The Screen
GLfloat LightAmbient[]= { 0.5f, 0.5f, 0.5f, 1.0f }; // Ambient Light Values ( NEW )
GLfloat LightDiffuse[]= { 1.0f, 1.0f, 1.0f, 1.0f }; // Diffuse Light Values ( NEW )
GLfloat LightPosition[]= { 0.0f, 0.0f, 2.0f, 1.0f }; // Light Position ( NEW )
GLuint filter; // Which Filter To Use
GLuint texture[3]; // Storage for 3 textures
QVector<QVector3D> vertices;
QVector<QVector2D> texCoords;
QVector<QVector3D> normals;
void makeObject()
{
vertices<<QVector3D(-1.0f, -1.0f, 1.0f)<<QVector3D(1.0f, -1.0f, 1.0f)<<QVector3D(1.0f, 1.0f, 1.0f)<<QVector3D(-1.0f, 1.0f, 1.0f)
<<QVector3D(-1.0f, -1.0f, -1.0f)<<QVector3D(-1.0f, 1.0f, -1.0f)<<QVector3D(1.0f, 1.0f, -1.0f)<<QVector3D(1.0f, -1.0f, -1.0f)
<<QVector3D(-1.0f, 1.0f, -1.0f)<<QVector3D(-1.0f, 1.0f, 1.0f)<<QVector3D(1.0f, 1.0f, 1.0f)<<QVector3D(1.0f, 1.0f, -1.0f)
<<QVector3D(-1.0f, -1.0f, -1.0f)<<QVector3D(1.0f, -1.0f, -1.0f)<<QVector3D(1.0f, -1.0f, 1.0f)<<QVector3D(-1.0f, -1.0f, 1.0f)
<<QVector3D(1.0f, -1.0f, -1.0f)<<QVector3D(1.0f, 1.0f, -1.0f)<<QVector3D(1.0f, 1.0f, 1.0f)<<QVector3D(1.0f, -1.0f, 1.0f)
<<QVector3D(-1.0f, -1.0f, -1.0f)<<QVector3D(-1.0f, -1.0f, 1.0f)<<QVector3D(-1.0f, 1.0f, 1.0f)<<QVector3D(-1.0f, 1.0f, -1.0f);
texCoords<<QVector2D(0.0f, 0.0f)<<QVector2D(1.0f, 0.0f)<<QVector2D(1.0f, 1.0f)<<QVector2D(0.0f, 1.0f)
<<QVector2D(1.0f, 0.0f)<<QVector2D(1.0f, 1.0f)<<QVector2D(0.0f, 1.0f)<<QVector2D(0.0f, 0.0f)
<<QVector2D(0.0f, 1.0f)<<QVector2D(0.0f, 0.0f)<<QVector2D(1.0f, 0.0f)<<QVector2D(1.0f, 1.0f)
<<QVector2D(1.0f, 1.0f)<<QVector2D(0.0f, 1.0f)<<QVector2D(0.0f, 0.0f)<<QVector2D(1.0f, 0.0f)
<<QVector2D(1.0f, 0.0f)<<QVector2D(1.0f, 1.0f)<<QVector2D(0.0f, 1.0f)<<QVector2D(0.0f, 0.0f)
<<QVector2D(0.0f, 0.0f)<<QVector2D(1.0f, 0.0f)<<QVector2D(1.0f, 1.0f)<<QVector2D(0.0f, 1.0f);
normals<<QVector3D(0.0f, 0.0f, 1.0f)<<QVector3D(0.0f, 0.0f, 1.0f)<<QVector3D(0.0f, 0.0f, 1.0f)<<QVector3D(0.0f, 0.0f, 1.0f)
<<QVector3D(0.0f, 0.0f,-1.0f)<<QVector3D(0.0f, 0.0f,-1.0f)<<QVector3D(0.0f, 0.0f,-1.0f)<<QVector3D(0.0f, 0.0f,-1.0f)
<<QVector3D(0.0f, 1.0f, 0.0f)<<QVector3D(0.0f, 1.0f, 0.0f)<<QVector3D(0.0f, 1.0f, 0.0f)<<QVector3D(0.0f, 1.0f, 0.0f)
<<QVector3D(0.0f, -1.0f, 0.0f)<<QVector3D(0.0f, -1.0f, 0.0f)<<QVector3D(0.0f, -1.0f, 0.0f)<<QVector3D(0.0f, -1.0f, 0.0f)
<<QVector3D(1.0f, 0.0f, 0.0f)<<QVector3D(1.0f, 0.0f, 0.0f)<<QVector3D(1.0f, 0.0f, 0.0f)<<QVector3D(1.0f, 0.0f, 0.0f)
<<QVector3D(-1.0f, 0.0f, 0.0f)<<QVector3D(-1.0f, 0.0f, 0.0f)<<QVector3D(-1.0f, 0.0f, 0.0f)<<QVector3D(-1.0f, 0.0f, 0.0f);
glVertexPointer(3, GL_FLOAT, 0, vertices.constData());
glTexCoordPointer(2, GL_FLOAT, 0, texCoords.constData());
glNormalPointer(GL_FLOAT, 0, normals.constData());
}
void drawObject()
{
glEnableClientState(GL_VERTEX_ARRAY);
glEnableClientState(GL_TEXTURE_COORD_ARRAY);
glEnableClientState(GL_NORMAL_ARRAY);
glBindTexture(GL_TEXTURE_2D, texture[filter]);
glDrawArrays(GL_QUADS, 0, vertices.size());
glDisableClientState(GL_VERTEX_ARRAY);
glDisableClientState(GL_TEXTURE_COORD_ARRAY);
glDisableClientState(GL_NORMAL_ARRAY);
}
}
初始化:
void MyGLWidget::initializeGL()
{
makeObject();
loadTextures();
glEnable(GL_TEXTURE_2D); // Enable Texture Mapping
glShadeModel(GL_SMOOTH); // Enables Smooth Shading
glClearColor(0.5f,0.5f,0.5f,1.0f); // Black Background
glClearDepth(1.0f); // Depth Buffer Setup
glEnable(GL_DEPTH_TEST); // Enables Depth Testing
glDepthFunc(GL_LEQUAL); // The Type Of Depth Test To Do
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST); // Really Nice Perspective Calculations
glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient); // Setup The Ambient Light
glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);
glLightfv(GL_LIGHT1, GL_POSITION,LightPosition); // Position The Light
glEnable(GL_LIGHT1); // Enable Light One
glFogi(GL_FOG_MODE, fogMode[fogfilter]); // Fog Mode
glFogfv(GL_FOG_COLOR, fogColor); // Set Fog Color
glFogf(GL_FOG_DENSITY, 0.35f); // How Dense Will The Fog Be
glHint(GL_FOG_HINT, GL_DONT_CARE); // Fog Hint Value
glFogf(GL_FOG_START, 1.0f); // Fog Start Depth
glFogf(GL_FOG_END, 5.0f); // Fog End Depth
glEnable(GL_FOG); // Enables GL_FOG
}
按键处理:
void MyGLWidget::keyPressEvent(QKeyEvent *e)
{
switch (e->key()) {
case Qt::Key_I:
if (!fp) {
fp = true;
filter += 1;
if (filter > 2)
filter = 0;
}
break;
case Qt::Key_G:
if (!gp) {
gp = true;
fogfilter += 1;
if (fogfilter > 2)
fogfilter = 0;
glFogi (GL_FOG_MODE, fogMode[fogfilter]);
}
break;
case Qt::Key_F:
fullscreen = !fullscreen;
if (fullscreen) {
showFullScreen();
} else {
resize(640, 480);
showNormal();
}
break;
case Qt::Key_L:
if (!lp) {
lp=true; // lp Becomes TRUE
light=!light; // Toggle Light TRUE/FALSE
if (!light) // If Not Light
{
glDisable(GL_LIGHTING); // Disable Lighting
}
else // Otherwise
{
glEnable(GL_LIGHTING); // Enable Lighting
}
}
break;
case Qt::Key_PageUp:
z -= 0.02f;
break;
case Qt::Key_PageDown:
z += 0.02f;
break;
case Qt::Key_Up:
xspeed -= 0.01f;
break;
case Qt::Key_Down:
xspeed += 0.01f;
break;
case Qt::Key_Right:
yspeed += 0.01f;
break;
case Qt::Key_Left:
yspeed -= 0.01f;
break;
case Qt::Key_Escape:
QMessageBox::StandardButton reply;
reply = QMessageBox::question(NULL, "NeHe",
"Do you want to exit?",
QMessageBox::Yes | QMessageBox::No,
QMessageBox::Yes);
if (reply == QMessageBox::Yes) {
qApp->quit();
}
break;
default:
QGLWidget::keyPressEvent(e);
break;
}
}
运行效果: