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