Mercurial > sdl-ios-xcode
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 } |