`
tiankefeng0520
  • 浏览: 146882 次
  • 性别: Icon_minigender_1
  • 来自: 长春
社区版块
存档分类
最新评论

OpenGL学习三十三:球面映射

 
阅读更多

(此节内容对应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();
}

 

  • 大小: 65.5 KB
  • 大小: 63.8 KB
  • 大小: 64.4 KB
分享到:
评论

相关推荐

    OPENGL球面映射

    OpenGL球面映射是一种在3D图形编程中广泛使用的纹理映射技术,它允许我们将二维纹理贴在三维模型,特别是球体表面,创造出逼真的视觉效果。这种技术在虚拟现实、天文学模拟、地球仪渲染等领域有着广泛应用。下面将...

    学习OpenGL必备教程nehe_opengl_chs.chm & 全部课程的源程序

    18:二次几何体 19:粒子系统 20:蒙板 21:线的游戏 22:凹凸映射 23:球面映射 24:扩展 25:变形 26:反射 27:影子 28:贝塞尔曲面 29:Blt函数 30:碰撞检测 31:模型加载 32:拾取游戏 33:TGA文件 34:地形 ...

    OpenGL球体绘制与球体贴图

    OpenGL是计算机图形学中的一种广泛应用的编程接口,用于在各种操作系统和硬件上生成二维和三维图像。本主题主要探讨如何使用OpenGL进行球体的绘制以及如何应用贴图技术为球体添加纹理,使得渲染出的球体更加真实。 ...

    opengl实现鱼眼矫正(球面等距模型)

    球面等距模型就是一种常用的校正方法,它通过将图像投影到一个理想的球面上,然后将球面上的点映射回平面上,从而减少或消除畸变。 在实现鱼眼矫正的过程中,有几个关键点需要考虑: 1. **坐标转换**:首先,我们...

    OpenGL球面倒影贴图

    总之,OpenGL球面倒影贴图是利用纹理映射技术模拟真实世界反射的一种方法,通过精心设计的着色器和预处理的环境纹理,可以在3D场景中创造出逼真的反射效果。学习和实践这个技术对于提升3D图形编程能力非常有帮助。

    android OpenGL ES 地球仪绘制——球体绘制及纹理映射——源码

    支持如下: (1)opengl es绘制三角形拼成球体 (2)图片作为纹理映射到整个球面上 (3)双点触控缩放球体 (4)拖动旋转球体

    NeHe OPenGL 英文教程

    - **曲面绘制**:学习如何在OpenGL中绘制经过球面映射的曲面。 #### 二十七、令牌、扩展、剪切测试及TGA加载 本章节涵盖令牌、扩展、剪切测试及TGA文件加载等内容。 **主要内容**: - **令牌技术**:了解令牌的...

    OpenGL中的纹理映射.ppt

    OpenGL中的纹理映射是计算机图形学中的一个重要概念,它用于增强3D模型的表面细节,模拟现实世界中的光照效果。纹理映射通过将纹理图案应用到物体表面,使得原本简单的几何形状看起来更加真实和丰富。 纹理映射的...

    OpenGL.rar_OpenGL 球体_opengl 三维 球体_opengl 三维旋转_opengl 旋转_体绘制

    OpenGL是一种强大的图形库,用于在各种操作系统和硬件平台上创建2D和3D图形。这个"OpenGL.rar"压缩包包含了关于如何使用OpenGL实现...通过学习和理解这段代码,开发者可以深入理解OpenGL如何进行3D图形绘制和交互操作。

    c# opengl 绘制三维球型

    OpenGL是一种强大的图形编程接口,广泛用于创建复杂的3D图形和应用程序。C#是.NET框架下常用的编程语言,而CSGL(C# OpenGL)库则为C#开发者提供了一...深入学习OpenGL和CSGL,你可以创建更加丰富和动态的3D应用程序。

    基于opengl和GLSL的鱼眼全景图

    综上所述,基于OpenGL和GLSL的鱼眼全景图实现涉及到图像处理、3D图形编程和着色器技术等多个方面,通过精心设计的顶点和片段着色器,以及合理的纹理映射,我们可以成功地将二维的全景图转化为具有鱼眼视觉效果的三维...

    OPENGL旋转圆.rar

    3. 纹理映射:使用`glTexImage2D`加载和应用2D纹理,提升3D模型的视觉效果。 4. OpenGL的矩阵操作:通过变换矩阵实现球体的自动旋转,涉及`glRotatef`等函数。 5. Pascal封装的OpenGL接口:`gl.pas`文件提供了Pascal...

    OpenGL下三维模型的显示和自由旋转.pdf

    ### OpenGL下三维模型的显示与自由旋转关键技术解析 #### 一、三维模型数据的读取 在本研究中,为了实现在OpenGL环境下显示并自由旋转三维模型的目标,首先需要解决的问题是如何有效地读取三维模型数据。DXF...

    Opengles2.0地球

    在地球模型中,片段着色器可能使用球面映射或者立方体贴图技术来应用地球纹理,模拟海洋、陆地、云层等不同的地理特征。 4. **纹理映射**:为了使地球看起来真实,通常需要一个地球纹理图像,这可以是一个高分辨率...

    songho opengl教程中的trackball demo

    首先,Trackball算法的核心是将屏幕坐标映射到一个球面上,然后计算鼠标点击和释放时的两个点在球面上的对应位置。这两个点确定了一个球面三角形,通过这个三角形我们可以找到旋转轴和旋转角度。旋转轴是球心与...

    openGL.zip_OpenGL 球体_c++语言画球_opengl界面_三维球体 opengl

    3. **绘制球体**: 要绘制球体,可以使用球面坐标系统,将球体上的每个点映射到笛卡尔坐标系统。这通常涉及到三角网格的生成,将球体表面划分为多个三角形面片。每个面片的顶点坐标可以通过球体半径、经度和纬度计算...

Global site tag (gtag.js) - Google Analytics