OpenGL入门12——雾

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);
	else
		glOrtho( -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);
	else
		glOrtho( -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;
}


Python的OpenGL库是一个用于渲染图形和实现3D图形应用的强大工具。如果你是一个初学者,以下是一些学习OpenGL的指南: 1. 学习基本的计算机图形学概念:在深入学习OpenGL之前,了解一些基本的计算机图形学概念是很重要的。你可以学习像坐标系、向量、矩阵变换等基础知识。 2. 学习Python语言基础:作为一个初学者,你需要先掌握Python的基本语法和编程概念。这将帮助你更好地理解和使用OpenGL库。 3. 安装OpenGL库:在开始之前,你需要确保你的计算机上已经安装了OpenGL库。你可以使用pip来安装PyOpenGL库。 4. 学习OpenGL的核心知识:一旦你准备好了,可以开始学习OpenGL的核心知识,如顶点缓冲对象(VBO)、着色器(programs)、着色器语言(GLSL)等。掌握这些基本概念对于理解和使用OpenGL非常重要。 5. 编写简单的OpenGL程序:接下来,你可以开始编写一些简单的OpenGL程序来实践所学的知识。你可以从简单的绘制一些基本图形开始,然后逐渐扩展到更复杂的场景和效果。 6. 学习OpenGL的高级特性:一旦你熟悉了OpenGL的基本知识,你可以探索一些更高级的主题,如光照、纹理映射、深度测试、投影等。这将帮助你创建更逼真和交互式的3D图形应用。 7. 参考文档和教程:除了上述的自学方法外,你还可以参考一些优秀的OpenGL文档和教程。一些推荐的资源包括OpenGL官方文档、PyOpenGL官方文档、学习OpenGL的在线教程等。 记住,学习OpenGL需要时间和实践。通过不断地编写代码和实验,你将逐渐掌握OpenGL的技能并创建出令人惊叹的图形应用。祝你好运!
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值