+#include <vector>
#include <windows.h>
#include <GL/gl.h>
+#include <GL/wglext.h>
+#include <msp/strings/lexicalcast.h>
+#include <msp/strings/utils.h>
#include "glcontext.h"
#include "window_private.h"
+using namespace std;
+
+namespace {
+
+template<typename T>
+T get_proc(const char *name)
+{
+ return reinterpret_cast<T>(reinterpret_cast<void *>(wglGetProcAddress(name)));
+}
+
+}
+
namespace Msp {
namespace Graphics {
SetPixelFormat(dc, pf_index, &pfd);
priv = new Private;
- priv->context = wglCreateContext(dc);
+ if(opts.forward_compatible || opts.gl_version_major!=DEFAULT_VERSION)
+ {
+ ContextHandle fake_context = wglCreateContext(dc);
+ wglMakeCurrent(dc, fake_context);
+
+ PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = get_proc<PFNWGLCREATECONTEXTATTRIBSARBPROC>("wglCreateContextAttribsARB");
+ if(!wglCreateContextAttribs)
+ throw unsupported_gl_mode(opts);
+
+ unsigned gl_version_major = opts.gl_version_major;
+ unsigned gl_version_minor = opts.gl_version_minor;
+ if(opts.gl_version_major==GLOptions::LATEST_VERSION)
+ {
+ const char *gl_ver_ptr = reinterpret_cast<const char *>(glGetString(GL_VERSION));
+ if(!gl_ver_ptr)
+ throw unsupported_gl_mode(opts);
+
+ string gl_ver = gl_ver_ptr;
+ vector<string> parts = split(gl_ver.substr(0, gl_ver.find(' ')), '.');
+
+ gl_version_major = lexical_cast<unsigned>(parts[0]);
+ gl_version_minor = lexical_cast<unsigned>(parts[1]);
+ }
+
+ vector<int> ctx_attribs;
+
+ if(opts.forward_compatible)
+ {
+ ctx_attribs.push_back(WGL_CONTEXT_FLAGS_ARB);
+ ctx_attribs.push_back(WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
+ }
+
+ if(opts.core_profile)
+ {
+ ctx_attribs.push_back(WGL_CONTEXT_PROFILE_MASK_ARB);
+ ctx_attribs.push_back(WGL_CONTEXT_CORE_PROFILE_BIT_ARB);
+ }
+
+ if(opts.gl_version_major)
+ {
+ ctx_attribs.push_back(WGL_CONTEXT_MAJOR_VERSION_ARB);
+ ctx_attribs.push_back(gl_version_major);
+ ctx_attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+ ctx_attribs.push_back(gl_version_minor);
+ }
+
+ ctx_attribs.push_back(0);
+
+ priv->context = wglCreateContextAttribs(dc, 0, &ctx_attribs[0]);
+ if(!priv->context)
+ throw unsupported_gl_mode(opts);
+
+ wglMakeCurrent(0, 0);
+ wglDeleteContext(fake_context);
+ }
+ else
+ priv->context = wglCreateContext(dc);
wglMakeCurrent(dc, priv->context);
ReleaseDC(window.get_private().window, dc);
delete priv;
}
+void GLContext::set_swap_interval(unsigned i)
+{
+ PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = get_proc<PFNWGLSWAPINTERVALEXTPROC>("wglSwapIntervalEXT");
+ if(!wglSwapInterval)
+ throw runtime_error("wglSwapIntervalEXT not found");
+ wglSwapInterval(i);
+}
+
void GLContext::swap_buffers()
{
HDC dc = GetDC(window.get_private().window);
ReleaseDC(window.get_private().window, dc);
}
-void GLContext::window_resized(unsigned w, unsigned h)
+void GLContext::window_resized(unsigned, unsigned)
{ }
} // namespace Graphics