HGLRC hRC = NULL;
HDC hDC = NULL;
HWND hWnd = NULL;
HINSTANCE hInstance;
bool keys[256];
bool active = TRUE;
bool fullscreen = TRUE;
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
GLvoid ReSizeGLScene(GLsizei width, GLsizei height)
{
if (height == 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);
glLoadIdentity();
}
int InitGL(GLvoid)
{
glShadeModel(GL_SMOOTH); //设置深度缓存
glClearColor(0.0f, 0.0f, 0.0f, 0.0f);
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST); //启用深度测试
glDepthFunc(GL_LEQUAL); //所作深度测试的类型
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
return TRUE;
}
int DrawGLScene(GLvoid)
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//清除屏幕和深度缓存
glLoadIdentity(); //重置当前的模型观察矩阵
return TRUE;
}
GLvoid KillGLWindow(GLvoid)
{
if (fullscreen)
{
ChangeDisplaySettings(NULL, 0);//如果全屏,切换回桌面
ShowCursor(TRUE);//显示指针
}
if (hRC)//是否拥有OpenGL渲染描述表
{
if (!wglMakeCurrent(NULL, NULL))//是否能释放DC或RC描述表
{
MessageBox(NULL, L"fail to release DC or RC", L"error", MB_OK | MB_ICONINFORMATION);
}
if (!wglDeleteContext(hRC))//能否删除RC
{
MessageBox(NULL, L"fail to release RC", L"error", MB_OK | MB_ICONINFORMATION);
}
hRC = NULL;//RC释放为NULL
}
if (hDC && !ReleaseDC(hWnd, hDC))//能否释放DC
{
MessageBox(NULL, L"fail to release DC",L"error", MB_OK | MB_ICONINFORMATION);
hDC = NULL;
}
if (hWnd && !DestroyWindow(hWnd))//能否销毁窗口
{
MessageBox(NULL, L"fail to destroy window",L"error",MB_OK | MB_ICONINFORMATION);
hWnd = NULL;
}
if (!UnregisterClass("OpenG", hInstance))//能否注销类
{
MessageBox(NULL, L"fail to unregister window class",L"error", MB_OK | MB_ICONINFORMATION);
hInstance = NULL;
}
}
BOOL CreateGLWindow(char* title, int width, int height, int bits, bool fullscreenflag)
{
GLuint PixelFormat;
WNDCLASS wc;
DWORD dwExStyle;
DWORD dwStyle;
RECT WindowRect;//取得矩形的左上角和右下角坐标值
WindowRect.left = (long)0;
WindowRect.right = (long)width;
WindowRect.top = (long)0;
WindowRect.bottom = (long)height;
fullscreen = fullscreenflag;
hInstance = GetModuleHandle(NULL);//取得窗口实例
wc.style = CS_HREDRAW | CS_VREDRAW | CS_OWNDC;//移动时重画,并为窗口取得DC
wc.lpfnWndProc(WNDPROC)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 = "OpenG";
if (!RegisterClass(&wc))//尝试注册窗口类
{
MessageBox(NULL, "注册窗口类失败", "错误", MB_OK | MB_ICONINFORMATION);
return FALSE;
}
if (fullscreen)
{
DEVMODE dmScreenSettings;
memset(&dmScreenSettings, 0, sizeof(dmScreenSettings));//确保内存清空为零
dmScreenSettings.dmSize = sizeof(dmScreenSettings);//devmode结构大小
dmScreenSettings.dmPelsWidth = width;//所选屏幕宽度
dmScreenSettings.dmPelsHeight = height;//所选屏幕高度
dmScreenSettings.dmBitsPerPel = bits;//所选屏幕色彩深度
dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT;
if (ChangeDisplaySettings(&dmScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL)
{
if (MessageBox(NULL, L"全屏模式在当前显卡上设置失败!\n使用窗口模式?", L"确认", MB_YESNO | MB_ICONEXCLAMATION) == IDYES)
{
fullscreen = FALSE;
}
else
{
MessageBox(NULL, L"程序将被关闭", L"错误", 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);//调整窗口达到真正要求的大小
if (!hWnd = CreateWindowEx(dwExStyle,
L"OpenG",
title,
WS_CLIPSIBLINGS | WS_CLIPCHILDREN | dwStyle
, 0, 0,
WindowRect.right - WindowRect.left,
WindowRect.bottom - WindowRect.top,
NULL,
NULL,
hInstance,
NULL))
{
KillGLWindows();
MessageBox(NULL, L"不能创建一个设备描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
static PIXELFORMATDESCRIPTOR pfd =
{
sizeof(PIXELFORMATDESCRIPTOR),//上述格式描述符的大小
1,//版本号
PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
bits,//选定色彩深度
0,0,0,0,0,0,//忽略的色彩位
0,//无Alpha缓存
0,//shift+bit
0,//无累加缓存
0,0,0,0,//忽略聚集位
16,//16位Z-缓存(深度缓存)
0,//无蒙版缓存
0,//无辅助缓存
PFD_MAIN_PLANE,//主绘图层
0,
0,0,0//忽略层遮罩
};
if (!(PixelFormat = ChoosePixelFormat(hDC, &pfd)))//windows找到相应的像素格式?
{
KillGLWindows();//重置显示区
MessageBox(NULL, L"不能设置像素格式",L"错误",MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if (!SetPixelFormat(hDC, PixelFormat, &pfd))//能够设置像素格式吗
{
KillGLWindows();
MessageBox(NULL, L"不能设置像素格式", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if (!(hRC = wglCreateContext(hRC)))
{
KillGLWindows();
MessageBox(NULL, L"不能创建OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
if (!wglMakeCurrent(hDC, hRC))//尝试激活着色描述表
{
KillGLWindows();
MessageBox(NULL, L"不能激活当前OpenGL渲染描述表", L"错误", MB_OK | MB_ICONEXCLAMATION);
return FALSE;
}
ShowWindow(hWnd, SW_SHOW);//显示窗口
SetForegroundWindow(hWnd);//略略提高优先级
SetFocus(hWnd);//设置键盘的焦点至此窗口
ReSizeGLScene(width, height);//设置透视GL屏幕
if (!InitGL())//初始化新建的GL窗口
{
KillGLWindows();
MessageBox(NULL, "", "", MB_OK | MB_ICONEXCLAMATION);
return 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://收到close消息
{
PostQuitMessage(0);//发出退出消息
return 0;
}
case WM_KEYDOWN://有键按下
{
keys[wParam] = TRUE;
return 0;
}
case WM_KEYUP://有键释放
{
keys[wParam] = FALSE;
return 0;
}
case WM_SIZE://调整OpenGL窗口
{
ReSizeGLScene(LOWORD(lParam), HIWORD(lParam));
return 0;
}
return DefWindowProc(hWnd, uMsg, wParam, lParam);
default:
break;
}
}
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow)
{
MSG msg;
BOOL done = FALSE;
if (MessageBox(NULL, L"你想在全屏模式下运行吗", L"设置全屏模式", MB_YESNO | MB_ICONQUESTION) == IDNO)
{
fullscreen = FALSE;
}
if (!CreateGLWindow(L"OpenGL程序框架", 640, 480, 16, fullscreen))
{
return 0;
}
while (!done)
{
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))//有消息在等待吗
{
if (msg.message == WM_QUIT)
{
done = TRUE;
}
else
{
TranslateMessage(&msg);//翻译消息
DispatchMessage(&msg);//发送消息
}
}
else
{
if (active)
{
if (keys[VK_ESCAPE])//ESC按下
{
done = TRUE;
}
else
{
DrawGLScene();
SwapBuffers(hDC);
}
if (keys[VK_F1])//F1按下
{
keys[VK_F1] = FALSE;
KillGLWindow();
fullscreen = !fullscreen;
if (!CreateGLWindow(L"OpenGL程序框架", 640, 480, 16, fullscreen))//重建OpenGL窗口
{
return 0;
}
}
}
}
}
KillGLWindow();
return(msg.wParam);
}
OpenGL_2 OpenGL窗口
最新推荐文章于 2022-12-02 15:06:33 发布