OpenGL入门12——雾

来源:互联网 发布:单片机公司有哪些 编辑:程序博客网 时间:2024/06/04 20:22

1、雾根据混合因子把雾颜色与源片断的颜色进行混合。

雾方程有三个:一次指数型、二次指数型、线性型

使用glFog*设置雾属性

2、RGBA模式下,按照下面方式使用雾因子f计算最终的雾颜色:

C = fCi + (1-f)Cf;

其中Ci表示源片断的RGBA值,Cf表示用GL_FOG_COLOR分配的雾颜色值。


3、默认情况下,雾方程式中的雾坐标z,是根据观察点和片断的距离自动计算产生的,但是也可以为每个顶点指定雾坐标,z值应该是正的,表示视觉坐标的距离,应该避免使用负值来表示雾坐标,因为使用负的雾坐标可能会计算出奇怪的颜色。

在几何图元的内部,雾坐标可能由每个片断插值而得。

如果使用”显示雾坐标“,即通过glFogi( GL_FOG_COORD_SRC, x);其中x可以是GL_FOG_COORD 或GL_FOG_COORDINATE_EXT, 在前后移动观察点时,并不会转换雾坐标,顶点的颜色不受影响;

如果不使用显式雾坐标,即通过glFogi( GL_FOG_COORD_SRC, y); 其中y可以是GL_FRAGMENT_DEPTH或者GL_FRAGMENT_DEPTH_EXT,在移动观察点时会极大地影响由计算所产生的雾颜色。

测试程序1:雾效果

#include "stdafx.h"#include <windows.h>#include <glew.h>#include <freeglut.h>#pragma comment(lib, "glew32d.lib")#pragma comment(lib, "freeglut.lib")static GLint fogMode;void init(){GLfloat position[] = { 0.5, 0.5, 3.0, 0.0 };glEnable( GL_DEPTH_TEST );glLightfv( GL_LIGHT0, GL_POSITION, position );glEnable( GL_LIGHT0 );{GLfloat mat[3] = {0.1745, 0.01175, 0.01175};glMaterialfv( GL_FRONT, GL_AMBIENT, mat );mat[0] = 0.61424;mat[1] = 0.04136;mat[2] = 0.04136;glMaterialfv( GL_FRONT, GL_DIFFUSE , mat );mat[0] = 0.727811;mat[1] = 0.626959;mat[2] = 0.626959;glMaterialfv( GL_FRONT, GL_SPECULAR, mat);glMaterialf( GL_FRONT, GL_SHININESS, 0.6*128.0);}glEnable( GL_FOG );{GLfloat fogColor[4] = { 0.5, 0.5, 0.5, 1.0};fogMode = GL_EXP;glFogi( GL_FOG_MODE, fogMode );   //设置使用哪个雾方程,线性、一次指数、二次指数glFogfv( GL_FOG_COLOR, fogColor);  //设置雾颜色glFogf( GL_FOG_DENSITY, 0.5);  //设置雾浓度glHint( GL_FOG_HINT, GL_DONT_CARE ); //设置雾,显示质量优先? 还是速度优先? 还是不关心?glFogf( GL_FOG_START, 1.0);glFogf( GL_FOG_END, 5.0);}glClearColor( 0.5, 0.5, 0.5, 1.0);}static void renderSphere( GLfloat x, GLfloat y, GLfloat z){glPushMatrix();glTranslatef( x, y, z);glutSolidSphere( 0.4, 16, 16);glPopMatrix();}void display(){glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );renderSphere( -2, -0.5, -1.0);renderSphere( -1, -0.5, -2.0);renderSphere( 0, -0.5, -3.0);renderSphere( 1, -0.5, -4.0);renderSphere( 2, -0.5, -5.0);glFlush();}void reshape( int w, int h){glViewport(0, 0, (GLsizei)w, (GLsizei)h );glMatrixMode( GL_PROJECTION );glLoadIdentity();if( w < h)glOrtho( -2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);elseglOrtho( -2.5*(GLfloat)w/(GLfloat)h, 2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);glMatrixMode( GL_MODELVIEW );glLoadIdentity();}void keyboard( unsigned char key, int x, int y){switch( key ){case 'f':case 'F':if( fogMode == GL_EXP ){fogMode = GL_EXP2;printf( "Fog mode id GL_EXP2 \n ");}else if( fogMode == GL_EXP2 ){fogMode = GL_LINEAR;printf( "Fog mode is GL_LINEAR \n");}else if( fogMode == GL_LINEAR ){fogMode = GL_EXP;printf( "Fog mode is GL_EXP \n");}glFogi( GL_FOG_MODE, fogMode );glutPostRedisplay();break;case 'Q':exit( 0 );break;default:break;}}int main(int argc, char* argv[]){glutInit( &argc, argv);glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH );glutInitWindowSize( 500, 500);glutInitWindowPosition( 100, 100);glutCreateWindow( argv[0]);glewInit();init();glutReshapeFunc( reshape );glutKeyboardFunc( keyboard );glutDisplayFunc( display );glutMainLoop();return 0;}

测试程序2:雾坐标

#include "stdafx.h"#include <windows.h>#include <glew.h>#include <freeglut.h>#pragma comment(lib, "glew32d.lib")#pragma comment(lib, "freeglut.lib")static GLint fogMode;static GLfloat f1,f2,f3;void init(){GLfloat fogColor[4] = {0.0, 0.25, 0.25, 1.0};f1 = 1.0f;f2 = 5.0f;f3 = 10.0f;glEnable( GL_FOG );{GLfloat fogColor[4] = { 0.5, 0.5, 0.5, 1.0};fogMode = GL_EXP;glFogi( GL_FOG_MODE, fogMode );   //设置使用哪个雾方程,线性、一次指数、二次指数glFogfv( GL_FOG_COLOR, fogColor);  //设置雾颜色glFogf( GL_FOG_DENSITY, 0.5);  //设置雾浓度glHint( GL_FOG_HINT, GL_DONT_CARE ); //设置雾,显示质量优先? 还是速度优先? 还是不关心?glFogi( GL_FOG_COORD_SRC, GL_FOG_COORD );}glClearColor( 0.0, 0.25, 0.25, 1.0);}void display(){glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );glColor3f( 1.0f, 0.75f, 0.0f);glBegin( GL_TRIANGLES );glFogCoordf( f1 );glVertex3f( 2.0f, -2.0f, 0.0f);glFogCoordf( f2 );glVertex3f( -2.0f, 0.0f, -5.0f);glFogCoordf( f3);glVertex3f( 0.0f, 2.0f, -10.0f);glEnd();glFlush();}void reshape( int w, int h){glViewport(0, 0, (GLsizei)w, (GLsizei)h );glMatrixMode( GL_PROJECTION );glLoadIdentity();if( w < h)glOrtho( -2.5, 2.5, -2.5*(GLfloat)h/(GLfloat)w, 2.5*(GLfloat)h/(GLfloat)w, -10.0, 10.0);elseglOrtho( -2.5*(GLfloat)w/(GLfloat)h, 2.5*(GLfloat)w/(GLfloat)h, -2.5, 2.5, -10.0, 10.0);glMatrixMode( GL_MODELVIEW );glLoadIdentity();}void keyboard( unsigned char key, int x, int y){switch( key ){case 'c':glFogi( GL_FOG_COORD_SRC, GL_FRAGMENT_DEPTH/*GL_FRAGMENT_DEPTH_EXT*/ );glutPostRedisplay();break;case 'C':glFogi( GL_FOG_COORD_SRC, /*GL_FOG_COORD*/ GL_FOG_COORDINATE_EXT);glutPostRedisplay();break;case '1':f1 = f1 + 0.25;glutPostRedisplay();break;case '2':f2 = f2 + 0.25;glutPostRedisplay();break;case '3':f3 = f3 + 0.25;glutPostRedisplay();break;case '8':if( f2>0.25){f2 = f2-0.25;glutPostRedisplay();}break;case '0':if( f3>0.25){f3 = f3-0.25;glutPostRedisplay();}break;case 'b':glMatrixMode( GL_MODELVIEW );glTranslatef( 0.0, 0.0,-0.25);glutPostRedisplay();break;case 'f':glMatrixMode( GL_MODELVIEW );glTranslatef( 0.0, 0.0,0.25);glutPostRedisplay();break;case 'Q':exit( 0 );break;default:break;}}int main(int argc, char* argv[]){glutInit( &argc, argv);glutInitDisplayMode( GLUT_SINGLE | GLUT_RGBA | GLUT_DEPTH );glutInitWindowSize( 500, 500);glutInitWindowPosition( 100, 100);glutCreateWindow( argv[0]);glewInit();init();glutReshapeFunc( reshape );glutKeyboardFunc( keyboard );glutDisplayFunc( display );glutMainLoop();return 0;}


0 0
原创粉丝点击