![]() |
Unuk 1.0
|
00001 #include <ctime> 00002 #include <iostream> 00003 #include <windows.h> 00004 #include <GL/gl.h> 00005 #include "../Libs/wglext.h" 00006 #include "Win32Window.h" 00007 #include "../Unuk/Game.h" 00008 00009 typedef HGLRC(APIENTRYP PFNWGLCREATECONTEXTATTRIBSARBPROC) (HDC, HGLRC, const int*); 00010 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB = NULL; 00011 00012 Win32Window::Win32Window(HINSTANCE hInstance) { 00013 m_isRunning = false; 00014 m_game = NULL; 00015 m_hinstance = hInstance; 00016 m_lastTime = 0; 00017 } 00018 00019 Win32Window::~Win32Window(void) { 00020 00021 } 00022 00023 bool Win32Window::Create(int width, int height, int bpp, bool fullscreen) { 00024 DWORD dwExStyle; 00025 DWORD dwStyle; 00026 00027 m_isFullscreen = fullscreen; 00028 00029 // Set up the window values. 00030 m_windowRect.left = (long) 0; 00031 m_windowRect.right = (long) width; 00032 m_windowRect.top = (long) 0; 00033 m_windowRect.bottom = (long) height; 00034 00035 // Set up the window class structure. 00036 m_windowClass.cbSize = sizeof(WNDCLASSEX); 00037 m_windowClass.style = CS_HREDRAW | CS_VREDRAW; 00038 m_windowClass.lpfnWndProc = Win32Window::StaticWndProc; // Our static method is the event handler. 00039 m_windowClass.cbClsExtra = 0; 00040 m_windowClass.cbWndExtra = 0; 00041 m_windowClass.hInstance = m_hinstance; 00042 m_windowClass.hIcon = LoadIcon(NULL, IDI_APPLICATION); 00043 m_windowClass.hCurser = LoadCursor(NULL, IDC_ARROW); 00044 m_windowClass.hbrBackground = NULL; 00045 m_windowClass.lpszMenuName = NULL; 00046 m_windowClass.lpszClassName = "Unuk"; 00047 m_windowClass.hIconSm = LoadIcon(NULL, IDI_WINLOGO); 00048 00049 // Register the window class. 00050 if(!RegisterClassEx(&m_windowClass)) { 00051 return false; 00052 } 00053 00054 // We need to change the display mode if we are running fullscreen. 00055 if(m_isFullsceen) { 00056 // This is the device mode. 00057 DEVMODE dmScreenSettings; 00058 memset(&dmScreenSettings, 0, sizeof(smScreenSettings)); 00059 dmScreenSettings.dmSize = sizeof(dmScreenSettings); 00060 00061 // Set the screen width/height/bpp. 00062 dmScreenSettings.dmPelsWidth = width; 00063 dmScreenSettings.dmPelsHeight = height; 00064 dmScreenSettings.dmBitsPerPel = bpp; 00065 dmScreenSettings.dwFields = DM_BITSPERPEL | DM_PELSWIDTH | DM_PELSHEIGHT; 00066 00067 if(ChangeDisplaySettings(&dScreenSettings, CDS_FULLSCREEN) != DISP_CHANGE_SUCCESSFUL) { 00068 // Setting display mode failed, we will switch to windowed mode. 00069 MessageBox(NULL, "Display mode failed", NULL, MB_OK); 00070 m_isFullscreen = false; 00071 } 00072 } 00073 00074 // Check to see if we are still in fullscreen mode. 00075 if(m_fullscreen) { 00076 dwExStyle = WS_EX_APPWINDOW; 00077 dwStyle = WS_POPUP; 00078 ShowCursor(false); 00079 } else { 00080 // fullscreen mode must have failed. 00081 dwExStyle = WS_EX_APPWINDOW | WS_EX_WINDOWEDGE; 00082 dwStyle = WS_OVERLAPPEDWINDOW 00083 } 00084 00085 // Adjusted the window to the requested size. 00086 AdjustWindowRectEx(&m_windowRect, swStyle, false, dwExStyle); 00087 00088 // Now the class is regestered we can finaly create the window. 00089 m_hWnd = CreateWindowEx(NULL, "Unuk", dwStyle | WS_CLIPCHILDREN | WS_CLIPSIBLINGS, 0, 0, 00090 m_windowRect.right - m_windowRect.left, m_windowRect.bottom - m_windowRect.top, 00091 NULL, NULL, m_hinstance, this); 00092 00093 // Let's make sure the window creation went as planned. 00094 if(!m_hWnd) return 0; 00095 00096 m_hdc = GetDC(m_hWnd); 00097 00098 // We know everything is ok, display and update the window now. 00099 ShowWindow(m_hWnd, SW_SHOW); 00100 UpdateWindow(m_hWnd); 00101 00102 m_lastTime = GetTickCount() / 1000.0f; 00103 return true; 00104 } 00105 00106 void Win32Window::Destroy(void) { 00107 // If we are in fullscreen we want to switch back to desktop, and show the mouse cursor. 00108 if(m_isFullscreen) { 00109 ChangeDisplaySettings(NULL, 0); 00110 ShowCursor(true); 00111 } 00112 } 00113 00114 void Win32Window::AttachGame(Game* game) { 00115 m_game = game; 00116 } 00117 00118 bool Win32Window::IsRunning(void) { 00119 return m_isRunning; 00120 } 00121 00122 void Win32Window::ProccessEvents(void) { 00123 MSG msg; 00124 00125 // While there are messages in the queue, store them in msg. 00126 while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) { 00127 // Process the messages one at a time. 00128 TranslateMessage(&msg); 00129 DispatchMessage(&msg); 00130 } 00131 } 00132 00133 void Win32Window::SetupPixelFormat(void) { 00134 int pixelFormat; 00135 00136 PIXELFORMATDESCRIPTOR pfd = { 00137 sizeof(PIXELFORMATDESCRIPTOR), // Size. 00138 1, // Version. 00139 PFD_SUPPORT_OPENGL | // OpenGL window. 00140 PFD_DRAW_TO_WINDOW | // Render to window. 00141 PFD_DOUBLEBUFFER, // Double buffer. 00142 PFD_TYPE_RGBA, // Color type. 00143 32, // Color Depth. 00144 0, 0, 0, 0, 0, 0, // Color bits (ignored). 00145 0, // No alpha buffer. 00146 0, // Alpha bits (ignored). 00147 0, // No accumulation buffer. 00148 0, 0, 0, 0, // Accumulation bits (ignored). 00149 16, // Depth buffer. 00150 0, // No stencil buffer. 00151 0, // No auxiliary buffers. 00152 PFD_MAIN_PLANE, // Main layer. 00153 0, // Reserved. 00154 0, 0, 0, // No layer, visible, damage masks. 00155 }; 00156 00157 pixelFormat = ChoosePixelFormat(m_hdc, &pfd); 00158 SetPixelFormat(m_hdc, pixelFormat, &pfd); 00159 } 00160 00161 LRESULT Win32Window::WndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 00162 switch(uMsg) { 00163 // Create the window. 00164 case WM_CREATE: 00165 m_hdc = GetDC(hWnd); 00166 SetupPixelFormat(); 00167 00168 // Setup the OpenGL version. We want to use 3.0. 00169 int attribs[] = { 00170 WGL_CONTEXT_MAJOR_VERSION_ARB, 3, 00171 WGL_CONTEXT_MINOR_VERSION_ARB, 0, 00172 0 00173 }; 00174 00175 // Create a temporary context so we can get a pointer to the function. 00176 HGLRC tmpContext = wglCreateContext(m_hdc); 00177 // Make it the current. 00178 wglMakeCurrent(m_hdc, tmpContext); 00179 00180 // Get the function pointer. 00181 wglCreateContextAttribsARB = (PFNWGLCCREATECONTEXTATTRIBSARBPROC) wglGetProcAddress("wglCreateContextAttribsARB"); 00182 00183 // If it is NULL, then GL 3.0 is not supported. 00184 if(!wglCreateContextAttribsARB) { 00185 Debug::logger->message("\nOpenGL 3.0 is not supported, falling back to GL 2.1"); 00186 m_hglrc = tmpContext; 00187 } else { 00188 // Create an OpenGL 3.0 context using the new function. 00189 m_hglrc = wglCreateContextAttribsARB(m_hdc, 0, attribs); 00190 // Delete then temp context. 00191 wglDeleteContext(tmpContext); 00192 } 00193 00194 // Make the GL3 context current. 00195 wglMakeCurrent(m_hdc, m_hglrc); 00196 // Our window is now running. 00197 m_isRunning = true; 00198 break; 00199 case WM_DESTROY: 00200 case WM_CLOSE: 00201 wglMakeCurrent(m_hdc, NULL); 00202 wglDeleteContext(m_hglrc); 00203 m_isRunning = false; 00204 PostQuitMessage(0); 00205 return 0; 00206 break; 00207 case WM_SIZE: 00208 // Get the width and height. 00209 int height = HIWORD(lParam); 00210 int width = LOWORD(lParam); 00211 getAttachedExample()->onResize(width, height); 00212 break; 00213 case WM_KEYDOWN: 00214 // If we detect the escape key, then please close the window. 00215 if(wParam == VK_ESCAPE) { 00216 DestroyWindow(m_hwnd); 00217 } 00218 break; 00219 default: 00220 break; 00221 } 00222 return DefWindowProc(hWnd, uMsg, wParam, lParam); 00223 } 00224 00225 LRESULT CALLBACK Win32Window::StaticWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { 00226 Win32Window* window = NULL; 00227 00228 // If we see the create message. 00229 if(uMsg == WM_CREATE) { 00230 // Then get the pointer we stored during create. 00231 window = (Win32Window)(LPCREATESTRUCT)lParam)->lpCreateParams; 00232 // Associate the window pointer with the hWnd for the other events to access. 00233 SetWindowLongPtr(hWnd, GWL_USERDAA, (LONG_PTR)window); 00234 } else { 00235 // If this aint a creation event, then we should have stored a pointer to the window. 00236 window = (Win32Window)GetWindowLongPtr(hWnd, GWL_USERDATA); 00237 if(!window) { 00238 return DefWindowProc(hWnd, uMsg, wParam, lParam); 00239 } 00240 } 00241 // Call our window's member WndProc (allows us to access member variables). 00242 return window->WndProc(hWnd, uMsg, wParam, lParam) 00243 } 00244 00245 float Win32Window::getElapsedSeconds() { 00246 float currentTime = float(GetTickCount()) / 1000.0f; 00247 float seconds = float(currentTime - m_lastTime); 00248 m_lastTime = currentTime; 00249 return seconds; 00250 }