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

📄 balloon.cpp

📁 《Visual C/C++图形图像与游戏编程典型实例解析》配套源代码
💻 CPP
📖 第 1 页 / 共 2 页
字号:
			glFogi (GL_FOG_MODE, fogMode[fogfilter]);	// 雾化模式
		}
		if (!keys['G'])
		{
			gp=FALSE;
		}
}

GLvoid KillGLWindow(GLvoid)								// 销毁GL窗口
{
	if (fullscreen)										// 在全屏幕模式
	{
		ChangeDisplaySettings(NULL,0);					// 如果是,则返回窗口系统
		ShowCursor(TRUE);								// 显示鼠标
	}

	if (hRC)											// 如果存在渲染上下文
	{
		if (!wglMakeCurrent(NULL,NULL))					// 确信是否可以释放DC和RC
		{
			MessageBox(NULL,"释放设备上下文和渲染上下问失败.","关闭错误",MB_OK | MB_ICONINFORMATION);
		}

		if (!wglDeleteContext(hRC))						// 确信可以释放渲染上下文
		{
			MessageBox(NULL,"释放渲染上下文失败","关闭错误",MB_OK | MB_ICONINFORMATION);
		}
		hRC=NULL;										
	}

	if (hDC && !ReleaseDC(hWnd,hDC))					// 确信是否可以释放设备上下文
	{
		MessageBox(NULL,"释放设备上下文失败.","关闭错误",MB_OK | MB_ICONINFORMATION);
		hDC=NULL;										
	}

	if (hWnd && !DestroyWindow(hWnd))					// 确信
	{
		MessageBox(NULL,"不能释放句柄hWnd.","关闭错误",MB_OK | MB_ICONINFORMATION);
		hWnd=NULL;									
	}

	if (!UnregisterClass("OpenGL",hInstance))			// 反注册窗口类
	{
		MessageBox(NULL,"不能反注册窗口类.","关闭错误",MB_OK | MB_ICONINFORMATION);
		hInstance=NULL;								
	}
}

/*	该函数创建OpenGL窗口,其参数说明如下					*
 *	title			- 标题信息			                	*
 *	width			- 宽度信息                              *
 *	height			- 高度信息		                    	*
 *	bits			- 颜色的位数 (8/16/24/32)		     	*
 *	fullscreenflag	- 全屏显示标记 (TRUE) 或窗口标记(FALSE) */
 
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
	GLuint		PixelFormat;			// Holds The Results After Searching For A Match
	WNDCLASS	wc;						// 窗口类结构
	DWORD		dwExStyle;				// 窗口扩展风格
	DWORD		dwStyle;				// 窗口风格
	RECT		WindowRect;				// 存储矩形的左上角和右下角的值
	WindowRect.left=(long)0;			// 左值为0
	WindowRect.right=(long)width;		// 右值为请求的值width
	WindowRect.top=(long)0;				// 上值为0
	WindowRect.bottom=(long)height;		// 下值为请求的值height

	fullscreen=fullscreenflag;			// 设置全屏幕标记

	hInstance			= GetModuleHandle(NULL);				// 获取窗口句柄
	wc.style			= CS_HREDRAW | CS_VREDRAW | CS_OWNDC;	// Redraw On Size, And Own DC For Window.
	wc.lpfnWndProc		= (WNDPROC) WndProc;					// 过程函数句柄消息
	wc.cbClsExtra		= 0;									// 无其他窗口数据
	wc.cbWndExtra		= 0;									// 无其他窗口数据
	wc.hInstance		= hInstance;							// 设置句柄信息
	wc.hIcon			= LoadIcon(NULL, IDI_WINLOGO);			// 装入缺省图标
	wc.hCursor			= LoadCursor(NULL, IDC_ARROW);			// 加入尖头光标
	wc.hbrBackground	= NULL;									// 无特别的背景颜色需求
	wc.lpszMenuName		= NULL;									// 无需菜单显示
	wc.lpszClassName	= "OpenGL";								// 设置类的名称

	if (!RegisterClass(&wc))									// 注册窗口类
	{
		MessageBox(NULL,"窗口类注册失败.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;											// 返回FALSE
	}
	
	if (fullscreen)												// 是否全屏幕显示
	{
		DEVMODE dmScreenSettings;								// 设备模式结构定义
		memset(&dmScreenSettings,0,sizeof(dmScreenSettings));	// 设置内存段为空值
		dmScreenSettings.dmSize=sizeof(dmScreenSettings);		// 设备模式结构定义的大小
		dmScreenSettings.dmPelsWidth	= width;				// 确定屏幕宽度
		dmScreenSettings.dmPelsHeight	= height;				// 设置屏幕高度
		dmScreenSettings.dmBitsPerPel	= bits;					// 设定象素的位数
		dmScreenSettings.dmFields=DM_BITSPERPEL|DM_PELSWIDTH|DM_PELSHEIGHT;

		// 得到设置的模式. 注意: CDS_FULLSCREEN 消除了状态栏等.
		if (ChangeDisplaySettings(&dmScreenSettings,CDS_FULLSCREEN)!=DISP_CHANGE_SUCCESSFUL)
		{
			// 如果设置失败, 提供两个选项.  退出或者使用窗口模式.
			if (MessageBox(NULL,"给定的显示模式显示卡不能支持. 请使用窗口模式?","三维绘制",MB_YESNO|MB_ICONEXCLAMATION)==IDYES)
			{
				fullscreen=FALSE;		// 选择为窗口模式,Fullscreen = FALSE
			}
			else
			{
				// 弹出消息框来告诉使用者,程序结束了.
				MessageBox(NULL,"程序即将关闭.","错误",MB_OK|MB_ICONSTOP);
				return FALSE;							
			}
		}
	}

	if (fullscreen)												// 确认是否还在全屏幕状态下
	{
		dwExStyle=WS_EX_APPWINDOW;								// 窗口扩展风格
		dwStyle=WS_POPUP;										// 窗口风格
		ShowCursor(FALSE);										// 隐藏鼠标
	}
	else
	{
		dwExStyle=WS_EX_APPWINDOW | WS_EX_WINDOWEDGE;			// 窗口扩展风格
		dwStyle=WS_OVERLAPPEDWINDOW;							// 窗口风格
	}

	AdjustWindowRectEx(&WindowRect, dwStyle, FALSE, dwExStyle);		// 调准Windows的大小

	// Create The Window
	if (!(hWnd=CreateWindowEx(	dwExStyle,							// 窗口扩展风格
								"OpenGL",							// 类名称
								title,								// 窗口标题
								dwStyle |							// 窗口风格
								WS_CLIPSIBLINGS |					// 必须的窗口风格
								WS_CLIPCHILDREN,					// 必须的窗口风格
								0, 0,								// 窗口位置
								WindowRect.right-WindowRect.left,	// 计算窗口宽度
								WindowRect.bottom-WindowRect.top,	// 计算窗口高度
								NULL,								// 无父窗口
								NULL,								// 无菜单
								hInstance,							// 实例句柄
								NULL)))								// 不传送任何参数给消息WM_CREATE
	{
		KillGLWindow();								// 失败的话,则重置窗口
		MessageBox(NULL,"窗口创建错误.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回FALSE
	}

	static	PIXELFORMATDESCRIPTOR pfd=				// pfd 格式描述符
	{
		sizeof(PIXELFORMATDESCRIPTOR),				// 象素格式描述符大小
		1,											// 版本号
		PFD_DRAW_TO_WINDOW |						// 格式必须支持窗口系统
		PFD_SUPPORT_OPENGL |						// 格式必须支持OpenGL
		PFD_DOUBLEBUFFER,							// 必须支持双缓冲
		PFD_TYPE_RGBA,								// 需要RGBA格式
		bits,										// 设置屏幕深度
		0, 0, 0, 0, 0, 0,							// 忽略颜色位数
		0,											// 无Alpha缓冲
		0,											// 忽略转移位
		0,											// 无积累缓冲
		0, 0, 0, 0,									// 忽略积累位数
		16,											// 16位Z-缓冲(深度缓冲)  
		0,											// 无摸板缓冲
		0,											// 无辅助缓冲
		PFD_MAIN_PLANE,								// 主绘制层
		0,											// 保留参数
		0, 0, 0										// 忽略层罩
	};
	
	if (!(hDC=GetDC(hWnd)))							// 判断是否获得设备上下文
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"不能创建GL 设备上下文.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	if (!(PixelFormat=ChoosePixelFormat(hDC,&pfd)))	// 判断窗口是否发现匹配的象素格式?
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"不能发现匹配象素格式.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	if(!SetPixelFormat(hDC,PixelFormat,&pfd))		// 是否可以设定象素格式?
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"不能设置象素格式.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	if (!(hRC=wglCreateContext(hDC)))				// 确定是否能够创建渲染上下文?
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"不能创建GL渲染上下文.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	if(!wglMakeCurrent(hDC,hRC))					// 激活渲染上下文
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"不能激活GL渲染上下文.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	ShowWindow(hWnd,SW_SHOW);						// 显示窗口
	SetForegroundWindow(hWnd);						// 提高些许优先权
	SetFocus(hWnd);									// 使窗口得到输入焦点
	ReSizeGLScene(width, height);					// 设置透视GL屏幕

	if (!InitGL())									// 初始化新建立GL窗口屏幕
	{
		KillGLWindow();								// 重置显示
		MessageBox(NULL,"初始化失败.","错误",MB_OK|MB_ICONEXCLAMATION);
		return FALSE;								// 返回 FALSE
	}

	return TRUE;									// 成功
}

LRESULT CALLBACK WndProc(	HWND	hWnd,			// 窗口句柄
							UINT	uMsg,			// 窗口消息
							WPARAM	wParam,			// 附加窗口消息
							LPARAM	lParam)			// 附加窗口消息
{
	switch (uMsg)									// 检查窗口消息
	{
		case WM_ACTIVATE:							// 检测当前活动消息
		{
			if (!HIWORD(wParam))					// 检查地位信息
			{
				active=TRUE;						// 程序处于活动状态
			}
			else
			{
				active=FALSE;						// 程序不处于活动状态
			}

			return 0;								// 返回到消息循环
		}

		case WM_SYSCOMMAND:							// 截获系统命令
		{
			switch (wParam)							// 检测系统调用
			{
				case SC_SCREENSAVE:					// 屏幕保护试图启动?
				case SC_MONITORPOWER:				// 显示器试图进入节能状态?
				return 0;							// 防止上两个事件的发生
			}
			break;									// 退出
		}

		case WM_CLOSE:								// 判断是否是关闭程序消息?
		{
			PostQuitMessage(0);						// 发送退出消息
			return 0;								// 跳出
		}

		case WM_KEYDOWN:							// 判断是否按下某一键?
		{
			keys[wParam] = TRUE;					// 如果释放则设定为TRUE
			return 0;								// 跳出
		}

		case WM_KEYUP:								// 释放按键?
		{
			keys[wParam] = FALSE;					// 如果释放则设定为FALSE
			return 0;								// 跳出
		}

		case WM_SIZE:								// 重置窗口大小
		{
			ReSizeGLScene(LOWORD(lParam),HIWORD(lParam));  // 低位=Width, 高位=Height
			return 0;								// 跳出
		}
	}

	// 所有的其他的消息使用函数DefWindowProc来处理
	return DefWindowProc(hWnd,uMsg,wParam,lParam);
}

int WINAPI WinMain(	HINSTANCE	hInstance,			// 实例
					HINSTANCE	hPrevInstance,		// 前句柄
					LPSTR		lpCmdLine,			// 命令行参数
					int			nCmdShow)			// 窗口显示状态
{
	MSG		msg;									// 查消息结构
	BOOL	done=FALSE;								// Bool 变量来确定是否退出消息循环

	// 询问用户使用何钟模式进行显示
	if (MessageBox(NULL,"使用全屏幕显示?", "开始全屏幕显示吗?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullscreen=FALSE;							// 窗口模式
	}

	// Create Our OpenGL Window
	if (!CreateGLWindow("纹理, 雾化, 光照和键盘操作编程初步",640,480,16,fullscreen))
	{
		return 0;									// 如果没有创建窗口则退出
	}

	while(!done)									// 当done=FALSE时,继续循环
	{
		if (PeekMessage(&msg,NULL,0,0,PM_REMOVE))	// 判断是否有消息在等待?
		{
			if (msg.message==WM_QUIT)				// 是否收到退出消息?
			{
				done=TRUE;							// 如果是则done=TRUE
			}
			else									// 如果否, 处理窗口消息
			{
				TranslateMessage(&msg);				// 解释消息
				DispatchMessage(&msg);				// 分派消息
			}
		}
		else										// 如果没有消息
		{
			// 绘制场景.  利用DrawGLScene()监测ESC键和退出消息
			if ((active && !DrawGLScene()) || keys[VK_ESCAPE])	// 活动?  是否收到退出消息?
			{
				done=TRUE;							// ESC键或者DrawGLScene告知一退出消息
			}
			else									// 不是退出时间则继续处理下面……
			{
				SwapBuffers(hDC);					// 交换缓冲区 (双缓冲)
				keyspressed();
				if (keys[VK_F1])						// 判断是否按下F1键?
				{
					keys[VK_F1]=FALSE;					// 如果是则使得该键不起作用
					KillGLWindow();						// 清楚当前窗口
					fullscreen=!fullscreen;				// 变换两种窗口模式
					// Recreate Our OpenGL Window
					if (!CreateGLWindow("纹理, 雾化, 光照和键盘操作编程初步",640,480,16,fullscreen))
					{
						return 0;						// Quit If Window Was Not Created
					}
				}
			}
		}
	}

	// 关闭
	KillGLWindow();									// 毁掉窗口
	return (msg.wParam);							// 退出程序
}

⌨️ 快捷键说明

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