OpenGL_2 OpenGL窗口

来源:互联网 发布:自动生成条形码软件 编辑:程序博客网 时间:2024/05/21 21:35
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;//移动时重画,并为窗口取得DCwc.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+bit0,//无累加缓存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);}