www.pudn.com > 3DSLoader.rar > GLWindow.cpp
//======================================================== /** * @file GLWindows.h * * 项目描述: 3DS文件载入 * 文件描述: 程序窗口类 * 适用平台: Windows98/2000/NT/XP * * 作者: WWBOSS * 电子邮件: wwboss123@gmail.com * 创建日期: 2006-09-13 * 修改日期: 2006-10-10 * */ //======================================================== #include "GLWindow.h" /**< 包含GLwindows.h头文件 */ #include/**< 包含OpenGL头文件 */ #include /** 构造函数 */ GLWindow::GLWindow() { m_WindowPosX = 0; /**< 窗口的左上角的X位置 */ m_WindowPosY = 0; /**< 窗口的左上角的Y位置 */ m_WindowWidth = 800; /**< 窗口的宽度 */ m_WindowHeight = 600; /**< 窗口的高度 */ m_ScreenWidth = 1024; /**< 全屏的宽度 */ m_ScreenHeight = 768; /**< 全屏的高度 */ m_BitsPerPixel = 16; /**< 颜色位深 */ m_IsFullScreen = false; /**< 不使用全屏 */ m_hWnd = 0; m_hDC = 0; m_hRC = 0; } /** 返回窗口的大小 */ int GLWindow::GetWidth() { if (m_IsFullScreen == true) { return m_ScreenWidth; } else { return m_WindowWidth; } } int GLWindow::GetHeight() { if (m_IsFullScreen == true) { return m_ScreenHeight; } else { return m_WindowHeight; } } /** 设置窗口的大小 */ void GLWindow::SetWidth(int width) { if (m_IsFullScreen == true) { m_ScreenWidth = width; } else { m_WindowWidth = width; } } void GLWindow::SetHeight(int height) { if (m_IsFullScreen == true) { m_ScreenHeight = height; } else { m_WindowHeight = height; } } /** 返回窗口左上角的位置 */ int GLWindow::GetPosX() { if (m_IsFullScreen == false) { return m_WindowPosX; } return 0; } int GLWindow::GetPosY() { if (m_IsFullScreen == false) { return m_WindowPosY; } return 0; } /** 设置窗口左上角的位置 */ void GLWindow::SetPosX(int x) { if (m_IsFullScreen == false) { m_WindowPosX = x; } } void GLWindow::SetPosY(int y) { if (m_IsFullScreen == false) { m_WindowPosY = y; } } /** 当窗口大小改变时,通知OpenGL调整大小 */ void GLWindow::ReshapeGL() { GLsizei width = GetWidth(); GLsizei height = GetHeight(); glViewport(0, 0, width, height); /**< 重新设置视口 */ glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0f, (GLfloat)width / (GLfloat)height, 1.0f, 4000.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } /** 改变窗口的显示设置 */ bool GLWindow::ChangeScreenSetting() { DEVMODE dmScreenSettings; /**< 设备模式 */ ZeroMemory(&dmScreenSettings, sizeof(DEVMODE)); /**< 清零结构 */ dmScreenSettings.dmSize = sizeof(DEVMODE); /**< 结构大小 */ dmScreenSettings.dmPelsWidth = GetWidth(); /**< 设置宽度 */ dmScreenSettings.dmPelsHeight = GetHeight(); /**< 设置高度 */ dmScreenSettings.dmBitsPerPel = m_BitsPerPixel; /**< 设置位深度 */ //dmScreenSettings.dmDisplayFrequency = 75; /**< 设置屏幕刷新率 */ dmScreenSettings.dmFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT ;//| DM_DISPLAYFREQUENCY; /// 改变显示模式 if (ChangeDisplaySettings(&dmScreenSettings, 0) != DISP_CHANGE_SUCCESSFUL) { return false; /**< 如果失败,返回false */ } return true; /**< 成功返回 */ } /** 创建windows窗口 */ bool GLWindow::Create(const char * window_title,const char * class_name,bool fullscreen, HINSTANCE h_instance, LPVOID lpParam) { m_IsFullScreen = fullscreen; int nX=0; int nY=0; PIXELFORMATDESCRIPTOR pfd = /**< 设置像素描述结构 */ { sizeof(PIXELFORMATDESCRIPTOR), /**< 像素描述结构的大小 */ 1, /**< 版本号 */ PFD_DRAW_TO_WINDOW | /**< 缓存区的输出显示在一个窗口中 */ PFD_SUPPORT_OPENGL | /**< 缓存区支持OpenGL绘图 */ PFD_STEREO | /**< 颜色缓存区是立体缓存 */ PFD_DOUBLEBUFFER, /**< 颜色缓存区是双缓存 */ PFD_TYPE_RGBA, /**< 使用RGBA颜色格式 */ m_BitsPerPixel, /**< 颜色缓存区中颜色值所占的位深 */ 0, 0, 0, 0, 0, 0, /**< 使用默认的颜色设置 */ 0, /**< 无Alpha缓存 */ 0, /**< 颜色缓存区中alpha成分的移位计数 */ 0, /**< 无累计缓存区 */ 0, 0, 0, 0, /**< 累计缓存区无移位 */ 32, /**< 32位深度缓存 */ 0, /**< 无蒙版缓存 */ 0, /**< 无辅助缓存区 */ PFD_MAIN_PLANE, /**< 必须为PFD_MAIN_PLANE,设置为主绘图层 */ 0, /**< 表示OpenGL实现所支持的上层或下层平面的数量 */ 0, 0, 0 /**< 过时,已不再使用 */ }; DWORD windowStyle = WS_OVERLAPPEDWINDOW & ~WS_SIZEBOX & ~WS_MAXIMIZEBOX; /**< 定义我们窗口类型,使用常规设定,去掉最大化按钮,并不能改变窗体大小 */ DWORD windowExtendedStyle = WS_EX_APPWINDOW; if (m_IsFullScreen == true) /**< 如果为全屏模式,尝试转化为全屏模式 */ { if (ChangeScreenSetting() == false) { /**< 全屏模式转换失败,弹出对话框提示,并尝试窗口模式 */ MessageBox(HWND_DESKTOP, "模式转换失败.\n在窗口模式下运行.", "Error", MB_OK | MB_ICONEXCLAMATION); m_IsFullScreen = false; /**< 设置为窗口模式 */ } else /**< 如果为窗口模式 */ { ShowCursor(false); /**< 隐藏鼠标 */ windowStyle = WS_POPUP; /**< 设置窗口模式为顶层窗口 */ windowExtendedStyle |= WS_EX_TOPMOST; } } /// 调整我们窗口的大小,使其客户区的大小为我们设置的大小 RECT windowRect = {GetPosX(), GetPosY(), GetPosX() + GetWidth(), GetPosY() + GetHeight()}; if (m_IsFullScreen == false) /**< 在窗口模式下使用 */ { windowExtendedStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; /**< 使窗口具有3D外观 */ int wid = GetSystemMetrics(SM_CXSCREEN); /**< 获取当前屏幕宽 */ int hei = GetSystemMetrics(SM_CYSCREEN); /**< 获取当前屏幕高 */ nX = (wid - GetWidth()) / 2; /**< 计算窗口居中用 */ nY = (hei - GetHeight()) / 2; /// 调整我们窗口的大小,使其客户区的大小为我们设置的大小 AdjustWindowRectEx(&windowRect, windowStyle, 0, windowExtendedStyle); /// 判断窗口的左上角是否隐藏在桌面外 if (windowRect.left < 0) /**< 如果窗口X坐标为负,移动坐标到0处,并调整窗口的位置 */ { windowRect.right -= windowRect.left; windowRect.left = 0; } if (windowRect.top < 0) /**< 如果窗口Y坐标为负,移动坐标到0处,并调整窗口的位置 */ { windowRect.bottom -= windowRect.top; windowRect.top = 0; } } /// 创建窗口 m_hWnd = CreateWindowEx(windowExtendedStyle, /**< 窗口的扩展风格 */ class_name, /**< 窗口的类名 */ window_title, /**< 窗口标题 */ windowStyle, /**< 窗口的风格 */ nX,nY, /**< 窗口的左上角位置 */ windowRect.right - windowRect.left, /**< 窗口的宽度 */ windowRect.bottom - windowRect.top, /**< 窗口的高度 */ HWND_DESKTOP, /**< 窗口的父窗口为桌面 */ 0, /**< 无菜单 */ h_instance, /**< 传入窗口的实例句柄 */ lpParam); /**< 传入程序类参数 */ while (m_hWnd != 0) /**< 窗口是否创建成功 */ { m_hDC = GetDC(m_hWnd); /**< 返回窗口的设备描述表 */ if (m_hDC == 0) /**< 如果为空 */ { /**< 失败 */ break; } GLuint PixelFormat = ChoosePixelFormat(m_hDC, &pfd); /**< 查找一个兼容的像素格式 */ if (PixelFormat == 0) /**< 如果没找到 */ { /**< 失败 */ break; } if (SetPixelFormat(m_hDC, PixelFormat, &pfd) == false) /**< 设置像素格式 */ { /**< 失败 */ break; } m_hRC = wglCreateContext(m_hDC); /**< 创建OpenGL的渲染描述表 */ if (m_hRC == 0) /**< 如果为空 */ { /**< 失败 */ break; } if (wglMakeCurrent(m_hDC, m_hRC) == false) /**< 设置当前的OpenGL的渲染对象为当前的窗口 */ { /**< 失败 */ break; } ShowWindow(m_hWnd, SW_NORMAL); /**< 显示窗口 */ ReshapeGL(); /**< 告诉OpenGL调整窗口大小 */ return true; /**< 成功返回 */ } Destroy(); /**< 释放资源 */ return false; /**< 返回失败 */ } /** 删除OpenGL窗口 */ void GLWindow::Destroy() { if (m_hWnd != 0) /**< 窗口句柄是否存在 */ { if (m_hDC != 0) /**< 窗口设备描述表是否存在 */ { wglMakeCurrent(m_hDC, 0); /**< 设置当前的OpenGL的渲染对象为空NULL */ if (m_hRC != 0) /**< OpenGL的渲染描述表是否存在 */ { wglDeleteContext(m_hRC); /**< 释放OpenGL的渲染描述表 */ m_hRC = 0; /**< 设置OpenGL的渲染描述表为0 */ } ReleaseDC(m_hWnd, m_hDC); /**< 释放窗口的设备描述表 */ m_hDC = 0; /**< 设置窗口的设备描述表为0 */ } DestroyWindow(m_hWnd); /**< 删除窗口 */ m_hWnd = 0; /**< 设置窗口句柄为0 */ } if (m_IsFullScreen) /**< 如果为全屏模式,在程序结束后,变换到窗口模式,并显示鼠标 */ { ChangeDisplaySettings(NULL, 0); /**< 变换到窗口模式 */ ShowCursor(true); /**< 显示鼠标 */ } }