📄 balloon.cpp
字号:
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 + -