comparison EXCLUDE/GLTSF/src/Window.cpp @ 4730:6032ada8b9e5

Adding GLTSF (somewhat based on SFML, no actual TSF code yet)
author dewyatt
date Tue, 25 May 2010 18:53:09 -0400
parents
children 0c7c67d4e6ee
comparison
equal deleted inserted replaced
4464:fa77a6429698 4730:6032ada8b9e5
1 #include "Window.hpp"
2
3 #pragma comment(lib, "opengl32.lib")
4
5 const wchar_t *Window::Window_Class_Name = L"GLTSF";
6
7 Window::Window() : my_Handle(0),
8 my_Device_Context(0),
9 my_GL_Context(0),
10 my_Class_Registered(false),
11 my_Listener(0)
12 {
13
14 }
15
16 Window::~Window()
17 {
18 Finalize();
19 }
20
21 void Window::Initialize(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
22 {
23 Finalize();
24
25 my_Video_Mode = Mode;
26 if (!my_Video_Mode.Is_Valid())
27 throw std::runtime_error("Invalid video mode");
28
29 my_Fullscreen = Fullscreen;
30 Register_Class();
31 Create_Window(Title, Mode, Fullscreen);
32 }
33
34 void Window::Finalize()
35 {
36 Destroy_Window();
37 Unregister_Class();
38 }
39
40 void Window::Set_Listener(Window_Listener *Listener)
41 {
42 my_Listener = Listener;
43 }
44
45 void Window::Register_Class()
46 {
47 WNDCLASSEXW Window_Class = {0};
48 Window_Class.cbSize = sizeof(Window_Class);
49 Window_Class.style = 0;
50 Window_Class.lpfnWndProc = &Window::Window_Procedure;
51 Window_Class.cbClsExtra = 0;
52 Window_Class.cbWndExtra = 0;
53 Window_Class.hInstance = GetModuleHandle(NULL);
54 Window_Class.hIcon = NULL;
55 Window_Class.hCursor = NULL;
56 Window_Class.hbrBackground = NULL;
57 Window_Class.lpszMenuName = NULL;
58 Window_Class.lpszClassName = Window_Class_Name;
59 Window_Class.hIconSm = NULL;
60 if (0 == RegisterClassExW(&Window_Class))
61 throw std::runtime_error("Failed to register window class");
62
63 my_Class_Registered = true;
64 }
65
66 void Window::Unregister_Class()
67 {
68 if (my_Class_Registered)
69 {
70 if (0 == UnregisterClassW(Window_Class_Name, GetModuleHandle(NULL)))
71 printf("Warning: Failed to unregister window class\n");
72
73 my_Class_Registered = false;
74 }
75 }
76
77 void Window::Create_Window(const std::wstring &Title, const Video_Mode &Mode, bool Fullscreen)
78 {
79 HDC Screen_DC = GetDC(NULL);
80 int Left = (GetDeviceCaps(Screen_DC, HORZRES) - my_Video_Mode.Width) / 2;
81 int Top = (GetDeviceCaps(Screen_DC, VERTRES) - my_Video_Mode.Height) / 2;
82 int Width = my_Video_Mode.Width;
83 int Height = my_Video_Mode.Height;
84 ReleaseDC(NULL, Screen_DC);
85
86 DWORD Style = WS_OVERLAPPEDWINDOW;
87 if (!my_Fullscreen)
88 {
89 RECT Rect = {0, 0, Width, Height};
90 AdjustWindowRect(&Rect, Style, false);
91 Width = Rect.right - Rect.left;
92 Height = Rect.bottom - Rect.top;
93 }
94 my_Handle = CreateWindowW(Window_Class_Name, Title.c_str(), Style, Left, Top, Width, Height, NULL, NULL, GetModuleHandle(NULL), this);
95 if (!my_Handle)
96 throw std::runtime_error("Failed to create window");
97
98 if (Fullscreen)
99 Switch_To_Fullscreen(Mode);
100
101 Create_Context(Mode);
102
103 RECT Rect = {0};
104 GetClientRect(my_Handle, &Rect);
105 //TODO: ...
106 }
107
108 void Window::Destroy_Window()
109 {
110 Destroy_Context();
111 if (my_Handle)
112 {
113 DestroyWindow(my_Handle);
114 my_Handle = 0;
115
116 if (my_Fullscreen)
117 ChangeDisplaySettings(NULL, 0);
118 }
119 }
120
121 void Window::Create_Context(const Video_Mode &Mode)
122 {
123 my_Device_Context = GetDC(my_Handle);
124 if (!my_Device_Context)
125 throw std::runtime_error("Failed to get device context");
126
127 PIXELFORMATDESCRIPTOR Pixel_Descriptor = {0};
128 Pixel_Descriptor.nSize = sizeof(Pixel_Descriptor);
129 Pixel_Descriptor.nVersion = 1;
130 Pixel_Descriptor.iLayerType = PFD_MAIN_PLANE;
131 Pixel_Descriptor.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER;
132 Pixel_Descriptor.iPixelType = PFD_TYPE_RGBA;
133 Pixel_Descriptor.cColorBits = static_cast<BYTE>(Mode.Bits_Per_Pixel);
134 Pixel_Descriptor.cDepthBits = 24;
135 Pixel_Descriptor.cStencilBits = 8;
136 Pixel_Descriptor.cAlphaBits = Mode.Bits_Per_Pixel == 32 ? 8 : 0;
137
138 int Best_Format = ChoosePixelFormat(my_Device_Context, &Pixel_Descriptor);
139 if (0 == Best_Format)
140 throw std::runtime_error("Failed to find suitable pixel format");
141
142 PIXELFORMATDESCRIPTOR Actual_Format = {0};
143 Actual_Format.nSize = sizeof(Actual_Format);
144 Actual_Format.nVersion = 1;
145 DescribePixelFormat(my_Device_Context, Best_Format, sizeof(Actual_Format), &Actual_Format);
146 if (!SetPixelFormat(my_Device_Context, Best_Format, &Actual_Format))
147 throw std::runtime_error("Failed to set device pixel format");
148
149 my_GL_Context = wglCreateContext(my_Device_Context);
150 if (!my_GL_Context)
151 throw std::runtime_error("Failed to create OpenGL context");
152
153 wglMakeCurrent(my_Device_Context, my_GL_Context);
154 }
155
156 void Window::Destroy_Context()
157 {
158 if (my_GL_Context)
159 {
160 wglDeleteContext(my_GL_Context);
161 my_GL_Context = 0;
162 }
163 if (my_Device_Context)
164 {
165 ReleaseDC(my_Handle, my_Device_Context);
166 my_Device_Context = 0;
167 }
168 }
169
170 void Window::Switch_To_Fullscreen(const Video_Mode &Mode)
171 {
172 DEVMODE Device_Mode = {0};
173 Device_Mode.dmSize = sizeof(Device_Mode);
174 Device_Mode.dmPelsWidth = Mode.Width;
175 Device_Mode.dmPelsHeight = Mode.Height;
176 Device_Mode.dmBitsPerPel = Mode.Bits_Per_Pixel;
177 Device_Mode.dmFields = DM_PELSWIDTH | DM_PELSHEIGHT | DM_BITSPERPEL;
178
179 if (DISP_CHANGE_SUCCESSFUL != ChangeDisplaySettings(&Device_Mode, CDS_FULLSCREEN))
180 throw std::runtime_error("Failed to change to fullscreen mode");
181
182 SetWindowLong(my_Handle, GWL_STYLE, WS_POPUP | WS_CLIPCHILDREN | WS_CLIPSIBLINGS);
183 SetWindowLong(my_Handle, GWL_EXSTYLE, WS_EX_APPWINDOW);
184
185 SetWindowPos(my_Handle, HWND_TOP, 0, 0, Mode.Width, Mode.Height, SWP_FRAMECHANGED);
186 }
187
188 LRESULT CALLBACK Window::Window_Procedure(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
189 {
190 switch (Message)
191 {
192 case WM_CREATE:
193 {
194 LONG This = reinterpret_cast<LONG>(reinterpret_cast<CREATESTRUCT *>(lParam)->lpCreateParams);
195 SetWindowLongPtr(Handle, GWLP_USERDATA, This);
196 return 0;
197 }
198 break;
199 case WM_DESTROY:
200 PostQuitMessage(0);
201 return 0;
202 break;
203 default:
204 {
205 Window* Win = reinterpret_cast<Window *>(GetWindowLongPtr(Handle, GWLP_USERDATA));
206 if (Win)
207 return Win->Handle_Message(Handle, Message, wParam, lParam);
208 }
209 break;
210 }
211 return DefWindowProcW(Handle, Message, wParam, lParam);
212 }
213
214 #define Call_Listener(x)\
215 if (my_Listener) my_Listener->x
216
217 LRESULT Window::Handle_Message(HWND Handle, UINT Message, WPARAM wParam, LPARAM lParam)
218 {
219 switch (Message)
220 {
221 case WM_CLOSE:
222 Call_Listener(On_Close());
223 break;
224 case WM_KEYDOWN:
225 Call_Listener(On_Key_Down(wParam));
226 break;
227 case WM_KEYUP:
228 Call_Listener(On_Key_Up(wParam));
229 break;
230 default:
231 return DefWindowProcW(Handle, Message, wParam, lParam);
232 break;
233 }
234 return 0;
235 }
236
237 void Window::Show()
238 {
239 if (my_Handle)
240 ShowWindow(my_Handle, SW_SHOW);
241 }
242
243 void Window::Hide()
244 {
245 if (my_Handle)
246 ShowWindow(my_Handle, SW_HIDE);
247 }
248
249 void Window::Update()
250 {
251 MSG Message = {0};
252 while (PeekMessageW(&Message, NULL, 0, 0, PM_REMOVE))
253 {
254 TranslateMessage(&Message);
255 DispatchMessageW(&Message);
256 }
257 }
258
259 void Window::Display()
260 {
261 if (my_Device_Context && my_GL_Context)
262 SwapBuffers(my_Device_Context);
263 }