⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 balloon.cpp

📁 《Visual C/C++图形图像与游戏编程典型实例解析》配套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
 /* This Code Was Created By Fatima Ahmed 2003 */
/* 该程序代码来自网络www.codeguru.com中,由Fatima Ahmed编写,kent翻译注释 2003年10月20日*/
/* 程序主要是用来配合文章的解释所做注释 */

#include <windows.h>		// Windows头文件
#include <stdio.h>			// 标准输入输出头文件
#include <gl\gl.h>			// OpenGL库
#include <gl\glu.h>			// OpenGL实用库
#include <gl\glaux.h>		// OpenGL辅助库

HDC			hDC=NULL;		// 全局GDI设备上下文
HGLRC		hRC=NULL;		// 全局渲染上下文
HWND		hWnd=NULL;		// 窗口句柄
HINSTANCE	hInstance;		// 应用程序实例句柄


GLUquadricObj	*q;	

bool	keys[256];			// 记录键盘按钮数组
bool	active=TRUE;		// 窗口活动标记,缺省为TRUE
bool	fullscreen=TRUE;	// 全屏标记,缺省设置为TRUE
bool	light;				// 光照开关变量
bool	lp;					// L 键按钮
bool	fp;					// F 键按钮
bool	gp;					// G 键按钮


GLfloat	xrot;				// X 轴旋转
GLfloat	yrot;				// Y 轴旋转
GLfloat xspeed;				// X 轴旋转速度
GLfloat yspeed;				// Y 轴旋转速度
GLfloat	z=-5.0f;			// 屏幕深度
GLfloat	height=  2.0f;		// 球体的高度

static GLfloat LightPos[] = {4.0f, 4.0f, 6.0f, 1.0f};	// 光源点位置

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	fogMode[]= { GL_EXP, GL_EXP2, GL_LINEAR };	// 三种舞化效果数组(文章中有解释)
GLuint	fogfilter = 0;								// 当前雾化效果
GLfloat	fogColor[4] = {0.5f,0.5f,0.5f,0.0f};		// 雾颜色

GLuint	filter;				// 滤波类型变量
GLuint	texture[3];			// 纹理图象数组
GLuint	texture1[1];

LRESULT	CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);	// 声明窗口过程

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 LoadGLTextures()									// 加载图象并转换成纹理贴图
{
	int Status=FALSE;									// 状态指示器,初始为FALSE

	AUX_RGBImageRec *TextureImage[1];					// 给纹理图象创建存储空间
	AUX_RGBImageRec *TextureImageball[1];				// 给纹理图象创建存储空间

	memset(TextureImage,0,sizeof(void *)*1);           	// 指针初始为空

	// 装载位图, 并检查错误, 如位图不存在则返回
	if (TextureImage[0]=LoadBMP("Crate.bmp"))
	{
		Status=TRUE;									// 装入位图后状态设置为TRUE

		glGenTextures(3, &texture[0]);					// 创建三个滤波纹理

		// 创建Nearest过滤纹理
		glBindTexture(GL_TEXTURE_2D, texture[0]);
		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[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// 创建Linear滤波纹理
		glBindTexture(GL_TEXTURE_2D, texture[1]);
		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[0]->sizeX, TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);

		// 创建MipMapped纹理
		glBindTexture(GL_TEXTURE_2D, texture[2]);
		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[0]->sizeX, TextureImage[0]->sizeY, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);
	}

	memset(TextureImageball,0,sizeof(void *)*1);			// 指针附值空
    if (TextureImageball[0]=LoadBMP("multicolour.bmp"))
	{   
		Status=TRUE;									// 状态设置为TRUE
		glGenTextures(1, &texture1[0]);					// 创建纹理
			glBindTexture(GL_TEXTURE_2D, texture1[0]);
			glTexImage2D(GL_TEXTURE_2D, 0, 3, TextureImageball[0]->sizeX, TextureImageball[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImageball[0]->data);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
			glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
	}
		
			if (TextureImage[0])						// 如果纹理存在
			{
				if (TextureImage[0]->data)				// 如果纹理图象存在
				{
					free(TextureImage[0]->data);		// 释放纹理图象内存
				}
				free(TextureImage[0]);					// 释放图象结构信息
			}

			if (TextureImageball[0])					// 如果纹理存在
			{
				if (TextureImageball[0]->data)			// 如果纹理图象存在
				{
					free(TextureImageball[0]->data);	// 释放纹理图象内存
				}
				free(TextureImageball[0]);				// 释放图象结构信息
			}
	
	
	return Status;				
}

GLvoid ReSizeGLScene(GLsizei width, GLsizei height)		// 虫设置和初始化GL窗口
{
	if (height==0)										// 预防分母出现0的情况
	{
		height=1;										
	}

	glViewport(0,0,width,height);						// 重新安排视图窗口

	glMatrixMode(GL_PROJECTION);						// 选择影射矩阵
	glLoadIdentity();									// 影射矩阵

	// 计算屏幕的高宽比例
	gluPerspective(45.0f,(GLfloat)width/(GLfloat)height,0.1f,100.0f);

	glMatrixMode(GL_MODELVIEW);							// 选择Modelview矩阵
	glLoadIdentity();									// 重新安排Modelview矩阵
}

int InitGL(GLvoid)										// OPENGL初始设置函数
{
	if (!LoadGLTextures())								// 调用纹理安装函数
	{
		return FALSE;									// 装载不成功则返回
	}

	glEnable(GL_TEXTURE_2D);							// 激活纹理影射
	glShadeModel(GL_SMOOTH);							// 激活光滑阴影
	glClearColor(0.2f, 0.7f, 0.9f, 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);								// 激活光源1

	q = gluNewQuadric();								// 绘制球体
	gluQuadricNormals(q, GL_SMOOTH);					// 产生光滑
	gluQuadricTexture(q, GL_TRUE);						// 激活曲面纹理坐标参照

	glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);	// 设置球体影射
	glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);	// 设置球体影射

	glFogi(GL_FOG_MODE, fogMode[fogfilter]);			// 雾模式
	glFogfv(GL_FOG_COLOR, fogColor);					// 设置雾的颜色
	glFogf(GL_FOG_DENSITY, 0.0f);						// 控制雾的密度
	glHint(GL_FOG_HINT, GL_DONT_CARE);					// 确定雾的渲染方式
	glFogf(GL_FOG_START, 1.0f);							// 雾的开始深度
	glFogf(GL_FOG_END, 5.0f);							// 确定了雾的结束离屏幕有多近
	glEnable(GL_FOG);									// 激活雾效果
	
	return TRUE;										// 初始化成功返回真
}

void DrawObject()										// 绘制气球球体
{
	glTranslatef(0.0f,1.5f,0.0f);
	glColor3f(1.0f, 1.0f, 1.0f);						// 设置成白色
	//glBindTexture(GL_TEXTURE_2D, texture1[0]);			// Select Texture 0 (1)
	gluSphere(q, 1.0f, 32, 16);							// 绘制球体

	glBindTexture(GL_TEXTURE_2D, texture1[0]);			// 设置纹理
	glColor4f(1.0f, 1.0f, 1.0f, 0.4f);					// 设置成白色,40%透明效果(融合)
	glEnable(GL_BLEND);									// 启动融合操作
	glBlendFunc(GL_SRC_ALPHA, GL_ONE);					// 指定混合的属性
	glEnable(GL_TEXTURE_GEN_S);							// 起用球体纹理影射
	glEnable(GL_TEXTURE_GEN_T);							// 起用球体纹理影射
	
	gluSphere(q, 1.0f, 32, 16);							// 用新的纹理来绘制第二个球体球体
														// 将产生多维纹理效果
	glDisable(GL_TEXTURE_GEN_S);						// 取消球体纹理影射
	glDisable(GL_TEXTURE_GEN_T);						// 取消球体纹理影射
	glDisable(GL_BLEND);								// 取消混合
}

void Drawhold()
{
	glBindTexture(GL_TEXTURE_2D, texture[0]);

	glBegin(GL_QUADS);
		// 正前面
		glNormal3f( 0.0f, 0.0f, 1.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f,  0.5f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, -0.5f,  0.5f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f,  0.5f,  0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f,  0.5f,  0.5f);
		// 后面
		glNormal3f( 0.0f, 0.0f,-1.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f,  0.5f, -0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5f,  0.5f, -0.5f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
		
		// 底面
		glNormal3f( 0.0f,-1.0f, 0.0f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5f, -0.5f,  0.5f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f,  0.5f);
		// 右面
		glNormal3f( 1.0f, 0.0f, 0.0f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f( 0.5f, -0.5f, -0.5f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f( 0.5f,  0.5f, -0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f( 0.5f,  0.5f,  0.5f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f( 0.5f, -0.5f,  0.5f);
		// 左面
		glNormal3f(-1.0f, 0.0f, 0.0f);
		glTexCoord2f(0.0f, 0.0f); glVertex3f(-0.5f, -0.5f, -0.5f);
		glTexCoord2f(1.0f, 0.0f); glVertex3f(-0.5f, -0.5f,  0.5f);
		glTexCoord2f(1.0f, 1.0f); glVertex3f(-0.5f,  0.5f,  0.5f);
		glTexCoord2f(0.0f, 1.0f); glVertex3f(-0.5f,  0.5f, -0.5f);
	glEnd();

}
int DrawGLScene(GLvoid)									// 图形绘制函数
{
	glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);	// 清除屏幕及深度
	glLoadIdentity();									// 重新安排视图
	glTranslatef(-0.9f,-0.9f,z);

	glRotatef(xrot,1.0f,0.0f,0.0f);
	glRotatef(yrot,0.0f,1.0f,0.0f);

	glTranslatef(0.0f, height, 0.0f);					// 根据高度来定位球体对象

	Drawhold();
	DrawObject();
	xrot+=xspeed;
	yrot+=yspeed;
	
	
	return TRUE;										 
}

void keyspressed()										// 响应按键操作
{
	if (keys['L'] && !lp)
	{
		lp=TRUE;
		light=!light;
		if (!light)
		{
			glDisable(GL_LIGHTING);
		}
		else
		{
			glEnable(GL_LIGHTING);
		}
	}
		if (!keys['L'])
		{
			lp=FALSE;
		}
	if (keys['F'] && !fp)
	{
		fp=TRUE;
		filter+=1;
		if (filter>2)
		{
			filter=0;
		}
	}
		if (!keys['F'])
		{
			fp=FALSE;
		}
	if (keys[VK_PRIOR])
		{
			height+=0.02f;
		}
	if (keys[VK_NEXT])
		{
			height-=0.02f;
		}
	if (keys['X'])
		{
			z-=0.02f;
		}
	if (keys['Z'])
		{
			z+=0.02f;
		}
	if (keys[VK_UP])
		{
			xspeed-=0.01f;
		}
	if (keys[VK_DOWN])
		{
			xspeed+=0.01f;
		}
	if (keys[VK_RIGHT])
		{
			yspeed+=0.01f;
		}
	if (keys[VK_LEFT])
		{
			yspeed-=0.01f;
		}
	if (keys['G'] && !gp)
		{
			gp=TRUE;
			fogfilter+=1;
			if (fogfilter>2)
			{
				fogfilter=0;
			}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -