src/libUnuk/Win32Window.cpp
Go to the documentation of this file.

    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 }

All Classes Files Functions Variables Typedefs Enumerations Enumerator Defines