博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
OpenGL学习三十三:球面映射
阅读量:4213 次
发布时间:2019-05-26

本文共 7964 字,大约阅读时间需要 26 分钟。

(此节内容对应NEHE教程第23课)

把环境纹理包裹在你的3D模型上,让它看起来象反射了周围的场景一样。

球体环境映射是一个创建快速金属反射效果的方法
首先,你需要一幅球体环境映射图,用来把它映射到球体上。在Photoshop中打开一幅图并选择所有的像素,创建它的一个复制。
接着,我们把图像变为2的幂次方大小,一般为128x128或256x256。
最后使用扭曲(distort)滤镜,并应用球体效果。然后把它保存为Reflect.bmp文件。
如右图上面的为背景的图片,下面为经过球面滤镜处理过的,用于进行球面贴图的纹理
对于球面映射往往我们希望背景图片是不变的,前面球面是可以转动的,因此适当的PUSH 与POP 视图模型 可以带到效果

 

                     原始图片                                                处理后图片                                       合成后效果

 

#include "header.h"int		part1;				int		part2;				int		p1=0;				int		p2=1;				GLfloat	xrot;				GLfloat	yrot;				GLfloat xspeed;				GLfloat yspeed;				GLfloat	z=-10.0f;			GLUquadricObj *quadratic;	GLfloat LightAmbient[]=		{ 0.5f, 0.5f, 0.5f, 1.0f };GLfloat LightDiffuse[]=		{ 1.0f, 1.0f, 1.0f, 1.0f };GLfloat LightPosition[]=	{ 0.0f, 0.0f, 2.0f, 1.0f };GLuint	filter;			GLuint	texture[6];			GLuint  object=1;			AUX_RGBImageRec *LoadBMP(char *Filename)				{	FILE *File=NULL;										if (!Filename)											{		return NULL;									}	File=fopen(Filename,"r");								if (File)												{		fclose(File);										return auxDIBImageLoad(Filename);					}	return NULL;										}int loop=0;int LoadGLTextures()									{	int Status=FALSE;										AUX_RGBImageRec *TextureImage[2];						memset(TextureImage,0,sizeof(void *)*2);           		if ((TextureImage[0]=LoadBMP("Data/BG.bmp")) &&		(TextureImage[1]=LoadBMP("Data/Reflect.bmp")))	{		Status=TRUE;											glGenTextures(6, &texture[0]);							for ( loop=0; loop<2; loop++)		{		// Create Nearest Filtered Texture			glBindTexture(GL_TEXTURE_2D, texture[loop]);	// Gen Tex 0 and 1			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);			// Create Linear Filtered Texture			glBindTexture(GL_TEXTURE_2D, texture[loop+2]);	// Gen Tex 2 and 3 4			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);			// Create MipMapped Texture			glBindTexture(GL_TEXTURE_2D, texture[loop+4]);	// Gen Tex 4 and 5			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);			gluBuild2DMipmaps(GL_TEXTURE_2D, 3, TextureImage[loop]->sizeX, TextureImage[loop]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[loop]->data);		}		for (loop=0; loop<2; loop++)		{	        if (TextureImage[loop])								    {			        if (TextureImage[loop]->data)							    {					        free(TextureImage[loop]->data);						}					free(TextureImage[loop]);							}		}	}	return Status;										}GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		{	if (height==0)											{		height=1;											}	glViewport(0,0,width,height);							glMatrixMode(GL_PROJECTION);							glLoadIdentity();										// Calculate The Aspect Ratio Of The Window	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);	glMatrixMode(GL_MODELVIEW);								glLoadIdentity();									}int InitGL(void)										{	if (!LoadGLTextures())									{		return FALSE;										}	glEnable(GL_TEXTURE_2D);								glShadeModel(GL_SMOOTH);							glClearColor(0.0f, 0.0f, 0.0f, 0.5f);					glClearDepth(1.0f);										glEnable(GL_DEPTH_TEST);								glDepthFunc(GL_LEQUAL);									glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);		glLightfv(GL_LIGHT1, GL_AMBIENT, LightAmbient);			glLightfv(GL_LIGHT1, GL_DIFFUSE, LightDiffuse);			glLightfv(GL_LIGHT1, GL_POSITION,LightPosition);		glEnable(GL_LIGHT1);									quadratic=gluNewQuadric();								gluQuadricNormals(quadratic, GLU_SMOOTH);				gluQuadricTexture(quadratic, GL_TRUE);					glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP); 	return TRUE;										}void glDrawCube(){		glBegin(GL_QUADS);		// Front Face		glNormal3f( 0.0f, 0.0f, 0.5f);		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);		// Back Face		glNormal3f( 0.0f, 0.0f,-0.5f);		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);		// Top Face		glNormal3f( 0.0f, 0.5f, 0.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f,  1.0f,  1.0f);		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f,  1.0f,  1.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);		// Bottom Face		glNormal3f( 0.0f,-0.5f, 0.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f, -1.0f, -1.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f, -1.0f, -1.0f);		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);		// Right Face		glNormal3f( 0.5f, 0.0f, 0.0f);		glTexCoord2f(1.0f, 0.0f); glVertex3f( 1.0f, -1.0f, -1.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f( 1.0f,  1.0f, -1.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f( 1.0f,  1.0f,  1.0f);		glTexCoord2f(0.0f, 0.0f); glVertex3f( 1.0f, -1.0f,  1.0f);		// Left Face		glNormal3f(-0.5f, 0.0f, 0.0f);		glTexCoord2f(0.0f, 0.0f); glVertex3f(-1.0f, -1.0f, -1.0f);		glTexCoord2f(1.0f, 0.0f); glVertex3f(-1.0f, -1.0f,  1.0f);		glTexCoord2f(1.0f, 1.0f); glVertex3f(-1.0f,  1.0f,  1.0f);		glTexCoord2f(0.0f, 1.0f); glVertex3f(-1.0f,  1.0f, -1.0f);	glEnd();}void DrawGLScene(void)									{	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);		glLoadIdentity();										glTranslatef(0.0f,0.0f,z);	glEnable(GL_TEXTURE_GEN_S);							glEnable(GL_TEXTURE_GEN_T);							glBindTexture(GL_TEXTURE_2D, texture[filter+(filter+1)]);	glPushMatrix();	glRotatef(xrot,1.0f,0.0f,0.0f);	glRotatef(yrot,0.0f,1.0f,0.0f);	switch(object)	{	case 0:		glDrawCube();		break;	case 1:		glTranslatef(0.0f,0.0f,-1.5f);							gluCylinder(quadratic,1.0f,1.0f,3.0f,32,32);			break;	case 2:		gluSphere(quadratic,1.3f,32,32);						break;	case 3:		glTranslatef(0.0f,0.0f,-1.5f);							gluCylinder(quadratic,1.0f,0.0f,3.0f,32,32);			break;	};	glPopMatrix();	glDisable(GL_TEXTURE_GEN_S);	glDisable(GL_TEXTURE_GEN_T);	glBindTexture(GL_TEXTURE_2D, texture[filter*2]);		glPushMatrix();		glTranslatef(0.0f, 0.0f, -24.0f);		glBegin(GL_QUADS);			glNormal3f( 0.0f, 0.0f, 1.0f);			glTexCoord2f(0.0f, 0.0f); glVertex3f(-13.3f, -10.0f,  10.0f);			glTexCoord2f(1.0f, 0.0f); glVertex3f( 13.3f, -10.0f,  10.0f);			glTexCoord2f(1.0f, 1.0f); glVertex3f( 13.3f,  10.0f,  10.0f);			glTexCoord2f(0.0f, 1.0f); glVertex3f(-13.3f,  10.0f,  10.0f);		glEnd();	glPopMatrix();	xrot+=xspeed;	yrot+=yspeed;	glFlush();}void rotate(){	glutPostRedisplay();}void keyboard(unsigned char key,int x,int y){	switch (key)	{	case 'L':		glEnable(GL_LIGHTING);		glutPostRedisplay();		break;	case 'l':		glDisable(GL_LIGHTING);		glutPostRedisplay();		break;	case ' ':		object++;		if(object>5)			object=0;		glutPostRedisplay();		break;	case 'F':		filter+=1;		if (filter>2)		{			filter=0;		}			glutPostRedisplay();		break;	case 'W':		yspeed+=0.01f;			glutIdleFunc(rotate);		break;	case 'S':		yspeed-=0.01f;			glutIdleFunc(rotate);		break;	case 'A':		xspeed+=0.01f;			glutIdleFunc(rotate);		break;	case 'D':		xspeed-=0.01f;			glutIdleFunc(rotate);		break;	case 'Z':		z-=0.01f;			glutIdleFunc(rotate);		break;	case 'X':		z+=0.01f;			glutIdleFunc(rotate);		break;	case 'R':		glutIdleFunc(NULL);		break;	}}int main(int argc,char **argv){	glutInit(&argc,argv);	glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB|GLUT_DEPTH);	glutInitWindowSize(800,600);	glutInitWindowPosition(100,100);	glutCreateWindow("球面映射");	InitGL();	glutDisplayFunc(DrawGLScene);	glutKeyboardFunc(keyboard);	glutReshapeFunc(ReSizeGLScene);	glutMainLoop();}

转载地址:http://ifumi.baihongyu.com/

你可能感兴趣的文章
AtomicInteger源码解析
查看>>
CopyOnWriteArraySet源码学习
查看>>
ThreadLocal学习笔记
查看>>
用talib实现基于emv的简易量化投资策略
查看>>
LongAdder源码解析
查看>>
Talib学习笔记(二)- 价格指数学习
查看>>
CAS机制是什么?
查看>>
Semaphore源码解析
查看>>
ConcurrentLinkedDeque源码解析
查看>>
ReentrantLock源码解析
查看>>
StampedLock源码解析
查看>>
ReentrantReadWriteLock源码解析
查看>>
springboot源码解析(四)
查看>>
CompletionService实践
查看>>
YApi在Window上离线安装笔记
查看>>
Mysql学习笔记(十三)查看mysql日志
查看>>
JVM垃圾回收相关知识笔记
查看>>
Curator学习笔记(一)- 读写锁
查看>>
第一次炒股小记
查看>>
《redis in action》ZSet相关命令
查看>>