cgv
Loading...
Searching...
No Matches
gl_context_win32.cxx
1#include "gl_context.h"
2#ifdef WIN32
3#include <windows.h>
4#include <Tchar.h>
5#include <cgv/utils/convert.h>
6#include <iostream>
7
8using namespace cgv::utils;
9
10namespace cgv {
11 namespace render {
12 namespace gl {
13
14typedef std::basic_string<_TCHAR> tstring;
15
16struct win32_gl_context : public gl_context
17{
18 // pointer to modul instance
19 HINSTANCE hinst;
20 // handle of window instance
21 HWND hwnd;
22 // device context
23 HDC hdc;
24 //
25 HGLRC glc;
26 //
27 unsigned int width;
28 //
29 unsigned int height;
30
31 // Function prototypes.
32 //static int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int);
33 static LRESULT CALLBACK MainWndProc(HWND, UINT, WPARAM, LPARAM);
34
35 bool init_application();
36 bool ensure_init_application();
37 bool init_instance(const tstring& title, int);
38 bool set_pixel_format();
39 bool create(const std::string& title, bool show);
40
41 win32_gl_context(unsigned int w = -1, unsigned int h = -1);
42 ~win32_gl_context();
43
45 RenderPass get_render_pass() const { return RP_NONE; }
47 RenderPassFlags get_render_pass_flags() const { return RPF_NONE; }
49 void render_pass(RenderPass render_pass = RP_MAIN,
50 RenderPassFlags render_pass_flags = RPF_ALL) {}
52 RenderPassFlags get_default_render_pass_flags() const { return RPF_NONE; }
54 void set_default_render_pass_flags(RenderPassFlags) { }
56 bool in_render_process() const { return false; }
58 bool is_created() const { return true; }
60 bool is_current() const { return true; }
62 bool make_current() const;
64 void clear_current() const;
65
67
69 unsigned int get_width() const { return width; }
71 unsigned int get_height() const { return height; }
73 void resize(unsigned int width, unsigned int height) { }
75 void set_bg_color(float r, float g, float b, float a) {}
77 void post_redraw() {}
79 void force_redraw() {}
80 void attach_depth_buffer(bool) {}
81 void attach_alpha_buffer(bool) {}
82 void attach_stencil_buffer(bool) {}
83 bool is_stereo_buffer_supported() const { return false; }
84 void attach_stereo_buffer(bool) {}
85 void attach_accumulation_buffer(bool) {}
86 void attach_multi_sample_buffer(bool) {}
87
91 void enable_font_face(cgv::media::font::font_face_ptr font_face, float font_size) {}
93 float get_current_font_size() const { return 12; }
95 cgv::media::font::font_face_ptr get_current_font_face() const { return cgv::media::font::font_face_ptr();
96 }
98
99 std::ostream& output_stream() { return std::cout; }
100};
101
102/* Application entry point.
103int WINAPI WinMain(HINSTANCE hinstance, HINSTANCE hPrevInstance,
104 LPSTR lpCmdLine, int nCmdShow)
105{
106 MSG msg;
107
108 if (!InitApplication(hinstance))
109 return FALSE;
110
111 if (!InitInstance(hinstance, nCmdShow))
112 return FALSE;
113
114 BOOL fGotMessage;
115 while ((fGotMessage = GetMessage(&msg, (HWND) NULL, 0, 0)) != 0 && fGotMessage != -1)
116 {
117 TranslateMessage(&msg);
118 DispatchMessage(&msg);
119 }
120 return (int)msg.wParam;
121 UNREFERENCED_PARAMETER(lpCmdLine);
122}
123*/
124
125bool win32_gl_context::init_application()
126{
127 WNDCLASSEX wcx;
128 // Fill in the window class structure with parameters
129 // that describe the main window.
130 wcx.cbSize = sizeof(wcx); // size of structure
131 wcx.style = CS_HREDRAW |
132 CS_VREDRAW; // redraw if size changes
133 wcx.lpfnWndProc = MainWndProc; // points to window procedure
134 wcx.cbClsExtra = 0; // no extra class memory
135 wcx.cbWndExtra = 0; // no extra window memory
136 wcx.hInstance = hinst; // handle to instance
137 wcx.hIcon = LoadIcon(NULL,
138 IDI_APPLICATION); // predefined app. icon
139 wcx.hCursor = LoadCursor(NULL,
140 IDC_ARROW); // predefined arrow
141 wcx.hbrBackground = NULL; // white background brush
142 wcx.lpszMenuName = _T("MainMenu"); // name of menu resource
143 wcx.lpszClassName = _T("MainWClass"); // name of window class
144 wcx.hIconSm = NULL;
145
146 // Register the window class.
147
148 ATOM atom = RegisterClassEx(&wcx);
149 return atom != NULL;
150}
151
152bool win32_gl_context::init_instance(const tstring& title, int nCmdShow)
153{
154 // Create the main window.
155 hwnd = CreateWindow(
156 _T("MainWClass"), // name of window class
157 title.c_str(), // title-bar string
158 WS_OVERLAPPEDWINDOW, // top-level window
159 CW_USEDEFAULT, // default horizontal position
160 CW_USEDEFAULT, // default vertical position
161 width == -1 ? CW_USEDEFAULT : width, // default width
162 height == -1 ? CW_USEDEFAULT : height, // default height
163 (HWND) NULL, // no owner window
164 (HMENU) NULL, // use class menu
165 hinst, // handle to application instance
166 (LPVOID) NULL); // no window-creation data
167
168 if (!hwnd)
169 return false;
170 // Show the window and send a WM_PAINT message to the window
171 // procedure.
172 ShowWindow(hwnd, nCmdShow);
173 UpdateWindow(hwnd);
174 return true;
175}
176
177LRESULT CALLBACK win32_gl_context::MainWndProc(
178 HWND hwnd, // handle to window
179 UINT uMsg, // message identifier
180 WPARAM wParam, // first message parameter
181 LPARAM lParam) // second message parameter
182{
183 switch (uMsg)
184 {
185 case WM_CREATE:
186 // Initialize the window.
187 return 0;
188
189 case WM_PAINT:
190 // Paint the window's client area.
191 return 0;
192
193 case WM_SIZE:
194 // Set the size and position of the window.
195 return 0;
196
197 case WM_DESTROY:
198 // Clean up window-specific data objects.
199 return 0;
200
201 //
202 // Process other messages.
203 //
204
205 default:
206 return DefWindowProc(hwnd, uMsg, wParam, lParam);
207 }
208 return 0;
209}
210
211
212bool win32_gl_context::make_current() const
213{
214 if (glc == NULL)
215 return false;
216 if (!wglMakeCurrent(hdc,glc)) {
217 DWORD error = GetLastError();
218 std::cerr << "failed to make current [hdc=" << hdc << ", glc=" << glc << "] with error " << error << std::endl;
219 return false;
220 }
221 return true;
222}
223
224void win32_gl_context::clear_current() const
225{
226 wglMakeCurrent(NULL,NULL);
227}
228
229win32_gl_context::win32_gl_context(unsigned int w, unsigned int h)
230{
231 width = w;
232 height = h;
233 hinst = NULL;
234 hwnd = NULL;
235 hdc = NULL;
236 glc = NULL;
237}
238
239win32_gl_context::~win32_gl_context()
240{
241 wglMakeCurrent(NULL,NULL);
242 DestroyWindow(hwnd);
243 hinst = NULL;
244 hwnd = NULL;
245 hdc = NULL;
246 glc = NULL;
247}
248
249bool win32_gl_context::set_pixel_format()
250{
251 PIXELFORMATDESCRIPTOR pfd = {
252 sizeof(PIXELFORMATDESCRIPTOR), // size of this pfd
253 1, // version number
254 PFD_DRAW_TO_WINDOW | // support window
255 PFD_SUPPORT_OPENGL | // support OpenGL
256 PFD_DOUBLEBUFFER, // double buffered
257 PFD_TYPE_RGBA, // RGBA type
258 24, // 24-bit color depth
259 0, 0, 0, 0, 0, 0, // color bits ignored
260 0, // no alpha buffer
261 0, // shift bit ignored
262 0, // no accumulation buffer
263 0, 0, 0, 0, // accum bits ignored
264 32, // 32-bit z-buffer
265 0, // no stencil buffer
266 0, // no auxiliary buffer
267 PFD_MAIN_PLANE, // main layer
268 0, // reserved
269 0, 0, 0 // layer masks ignored
270 };
271 int iPixelFormat;
272
273 // get the best available match of pixel format for the device context
274 iPixelFormat = ChoosePixelFormat(hdc, &pfd);
275
276 // make that the pixel format of the device context
277 return SetPixelFormat(hdc, iPixelFormat, &pfd) == TRUE;
278}
279
280bool win32_gl_context::ensure_init_application()
281{
282 static bool is_initialized = false;
283 static bool result = false;
284 if (!is_initialized) {
285 result = init_application();
286 is_initialized = true;
287 }
288 return result;
289}
290
291bool win32_gl_context::create(const std::string& title, bool show)
292{
293 hinst = GetModuleHandle(NULL);
294 if (!ensure_init_application()) {
295 std::cout << "failed to init application" << std::endl;
296 return false;
297 }
298#ifdef _UNICODE
299 if (!init_instance(str2wstr(title), show ? SW_SHOW : SW_HIDE)) {
300#else
301 if (!init_instance(title, show ? SW_SHOW : SW_HIDE)) {
302#endif
303 std::cout << "failed to init instance" << std::endl;
304 return false;
305 }
306 hdc = GetDC(hwnd);
307 if (hdc == NULL) {
308 std::cout << "failed to get DC" << std::endl;
309 return false;
310 }
311 if (!set_pixel_format()) {
312 std::cout << "failed to choose pixel format" << std::endl;
313 return false;
314 }
315 glc = wglCreateContext(hdc);
316 if (glc == NULL) {
317 std::cout << "failed to create gl context" << std::endl;
318 return false;
319 }
320 return true;
321}
322
323context* create_win32_gl_context(RenderAPI api, unsigned int w, unsigned int h,
324 const std::string& title, bool show)
325{
326 if (api != RA_OPENGL)
327 return 0;
328 win32_gl_context* ctx_ptr = new win32_gl_context(w,h);
329 if (!ctx_ptr->create(title, show) || !ctx_ptr->make_current() || !ensure_glew_initialized()) {
330 delete ctx_ptr;
331 return 0;
332 }
333 return ctx_ptr;
334}
335
336 }
337
338context_factory_registration create_win32_gl_context_registration(gl::create_win32_gl_context);
339
340 }
341}
342
343
344#endif
data::ref_ptr< font_face > font_face_ptr
always use this ref counted pointer to store font faces
Definition font.h:52
bool ensure_glew_initialized()
initialize glew in the first call to this function and always return whether this was successful
Definition gl.cxx:19
RenderAPI
enumeration of rendering APIs which can be queried from the context
Definition context.h:70
RenderPass
Enumeration of different render passes, which can be queried from the context and used to specify a n...
Definition context.h:77
@ RP_NONE
no renderpass
Definition context.h:78
RenderPassFlags
available flags that can be queried from the context and set for a new render pass
Definition context.h:93
@ RPF_NONE
no frame initialization is performed
Definition context.h:94
namespace that holds tools that dont fit any other namespace
the cgv namespace
Definition print.h:11