]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/wgl/glcontext.cpp
68088970ac13cab32cd856a2a23980d838ad3bf7
[libs/gui.git] / source / graphics / wgl / glcontext.cpp
1 #include <vector>
2 #include <windows.h>
3 #include <GL/gl.h>
4 #include <GL/wglext.h>
5 #include "glcontext.h"
6 #include "window_private.h"
7
8 using namespace std;
9
10 namespace {
11
12 template<typename T>
13 T get_proc(const char *name)
14 {
15         return reinterpret_cast<T>(reinterpret_cast<void *>(wglGetProcAddress(name)));
16 }
17
18 }
19
20 namespace Msp {
21 namespace Graphics {
22
23 typedef HGLRC ContextHandle;
24
25 struct GLContext::Private
26 {
27         ContextHandle context;
28 };
29
30
31 void GLContext::platform_init(const GLOptions &opts)
32 {
33         HDC dc = GetDC(window.get_private().window);
34
35         PIXELFORMATDESCRIPTOR pfd;
36         memset(&pfd, 0, sizeof(pfd));
37
38         pfd.nSize = sizeof(pfd);
39         pfd.nVersion = 1;
40         pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
41         if(opts.doublebuffer)
42                 pfd.dwFlags |= PFD_DOUBLEBUFFER;
43         pfd.iPixelType = PFD_TYPE_RGBA;
44         if(opts.alpha)
45                 pfd.cAlphaBits = 1;
46         pfd.cDepthBits = 1;
47         if(opts.stencil)
48                 pfd.cStencilBits = 1;
49
50         int pf_index = ChoosePixelFormat(dc, &pfd);
51         if(!pf_index)
52                 throw unsupported_gl_mode(opts);
53         SetPixelFormat(dc, pf_index, &pfd);
54
55         priv = new Private;
56         if(opts.forward_compatible || opts.gl_version_major)
57         {
58                 ContextHandle fake_context = wglCreateContext(dc);
59                 wglMakeCurrent(dc, fake_context);
60
61                 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = get_proc<PFNWGLCREATECONTEXTATTRIBSARBPROC>("wglCreateContextAttribsARB");
62                 if(!wglCreateContextAttribs)
63                         throw unsupported_gl_mode(opts);
64
65                 vector<int> ctx_attribs;
66
67                 if(opts.forward_compatible)
68                 {
69                         ctx_attribs.push_back(WGL_CONTEXT_FLAGS_ARB);
70                         ctx_attribs.push_back(WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
71                 }
72
73                 if(opts.core_profile)
74                 {
75                         ctx_attribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
76                         ctx_attribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
77                 }
78
79                 if(opts.gl_version_major)
80                 {
81                         ctx_attribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
82                         ctx_attribs.push_back(opts.gl_version_major);
83                         ctx_attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
84                         ctx_attribs.push_back(opts.gl_version_minor);
85                 }
86
87                 ctx_attribs.push_back(0);
88
89                 priv->context = wglCreateContextAttribs(dc, 0, &ctx_attribs[0]);
90                 if(!priv->context)
91                         throw unsupported_gl_mode(opts);
92
93                 wglMakeCurrent(0, 0);
94                 wglDeleteContext(fake_context);
95         }
96         else
97                 priv->context = wglCreateContext(dc);
98         wglMakeCurrent(dc, priv->context);
99
100         ReleaseDC(window.get_private().window, dc);
101 }
102
103 GLContext::~GLContext()
104 {
105         wglMakeCurrent(0, 0);
106         wglDeleteContext(priv->context);
107
108         delete priv;
109 }
110
111 void GLContext::set_swap_interval(unsigned i)
112 {
113         PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = get_proc<PFNWGLSWAPINTERVALEXTPROC>("wglSwapIntervalEXT");
114         if(!wglSwapInterval)
115                 throw runtime_error("wglSwapIntervalEXT not found");
116         wglSwapInterval(i);
117 }
118
119 void GLContext::swap_buffers()
120 {
121         HDC dc = GetDC(window.get_private().window);
122         SwapBuffers(dc);
123         ReleaseDC(window.get_private().window, dc);
124 }
125
126 void GLContext::window_resized(unsigned, unsigned)
127 { }
128
129 } // namespace Graphics
130 } // namespace Msp