6 #include <msp/strings/lexicalcast.h>
7 #include <msp/strings/utils.h>
8 #include "window_private.h"
15 T get_proc(const char *name)
17 return reinterpret_cast<T>(reinterpret_cast<void *>(wglGetProcAddress(name)));
25 typedef HGLRC ContextHandle;
27 struct GLContext::Private
29 ContextHandle context = nullptr;
33 void GLContext::platform_init(const GLOptions &opts)
35 HDC dc = GetDC(window.get_private().window);
37 PIXELFORMATDESCRIPTOR pfd;
38 memset(&pfd, 0, sizeof(pfd));
40 pfd.nSize = sizeof(pfd);
42 pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
44 pfd.dwFlags |= PFD_DOUBLEBUFFER;
45 pfd.iPixelType = PFD_TYPE_RGBA;
52 int pf_index = ChoosePixelFormat(dc, &pfd);
54 throw unsupported_gl_mode(opts);
55 SetPixelFormat(dc, pf_index, &pfd);
58 if(opts.forward_compatible || opts.gl_version_major!=GLOptions::DEFAULT_VERSION)
60 ContextHandle fake_context = wglCreateContext(dc);
61 wglMakeCurrent(dc, fake_context);
63 PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = get_proc<PFNWGLCREATECONTEXTATTRIBSARBPROC>("wglCreateContextAttribsARB");
64 if(!wglCreateContextAttribs)
65 throw unsupported_gl_mode(opts);
67 unsigned gl_version_major = opts.gl_version_major;
68 unsigned gl_version_minor = opts.gl_version_minor;
69 if(opts.gl_version_major==GLOptions::LATEST_VERSION)
71 const char *gl_ver_ptr = reinterpret_cast<const char *>(glGetString(GL_VERSION));
73 throw unsupported_gl_mode(opts);
75 string gl_ver = gl_ver_ptr;
76 vector<string> parts = split(gl_ver.substr(0, gl_ver.find(' ')), '.');
78 gl_version_major = lexical_cast<unsigned>(parts[0]);
79 gl_version_minor = lexical_cast<unsigned>(parts[1]);
82 vector<int> ctx_attribs;
84 if(opts.forward_compatible)
86 ctx_attribs.push_back(WGL_CONTEXT_FLAGS_ARB);
87 ctx_attribs.push_back(WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
92 ctx_attribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
93 ctx_attribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
96 if(opts.gl_version_major)
98 ctx_attribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
99 ctx_attribs.push_back(gl_version_major);
100 ctx_attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
101 ctx_attribs.push_back(gl_version_minor);
104 ctx_attribs.push_back(0);
106 priv->context = wglCreateContextAttribs(dc, 0, &ctx_attribs[0]);
108 throw unsupported_gl_mode(opts);
110 wglMakeCurrent(nullptr, nullptr);
111 wglDeleteContext(fake_context);
114 priv->context = wglCreateContext(dc);
115 wglMakeCurrent(dc, priv->context);
117 ReleaseDC(window.get_private().window, dc);
120 GLContext::~GLContext()
122 wglMakeCurrent(nullptr, nullptr);
123 wglDeleteContext(priv->context);
128 void GLContext::set_swap_interval(unsigned i)
130 PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = get_proc<PFNWGLSWAPINTERVALEXTPROC>("wglSwapIntervalEXT");
132 throw runtime_error("wglSwapIntervalEXT not found");
136 void GLContext::swap_buffers()
138 HDC dc = GetDC(window.get_private().window);
140 ReleaseDC(window.get_private().window, dc);
143 void GLContext::window_resized(unsigned, unsigned)
146 } // namespace Graphics