X-Git-Url: http://git.tdb.fi/?a=blobdiff_plain;f=source%2Fgraphics%2Fwgl%2Fglcontext.cpp;h=b0f685b582a835e38b9639073c6da8564b855e32;hb=be455be47a214f8fba1224ef1fb4158a073bc4e3;hp=964dea2b7fba92a66815b7d84e89254c0c840880;hpb=8926837f7e81d0007d8cb94db701c4845a0a01a3;p=libs%2Fgui.git diff --git a/source/graphics/wgl/glcontext.cpp b/source/graphics/wgl/glcontext.cpp index 964dea2..b0f685b 100644 --- a/source/graphics/wgl/glcontext.cpp +++ b/source/graphics/wgl/glcontext.cpp @@ -1,8 +1,24 @@ +#include #include #include +#include +#include +#include #include "glcontext.h" #include "window_private.h" +using namespace std; + +namespace { + +template +T get_proc(const char *name) +{ + return reinterpret_cast(reinterpret_cast(wglGetProcAddress(name))); +} + +} + namespace Msp { namespace Graphics { @@ -16,8 +32,6 @@ struct GLContext::Private void GLContext::platform_init(const GLOptions &opts) { - priv = new Private; - HDC dc = GetDC(window.get_private().window); PIXELFORMATDESCRIPTOR pfd; @@ -40,7 +54,64 @@ void GLContext::platform_init(const GLOptions &opts) throw unsupported_gl_mode(opts); SetPixelFormat(dc, pf_index, &pfd); - priv->context = wglCreateContext(dc); + priv = new Private; + if(opts.forward_compatible || opts.gl_version_major!=DEFAULT_VERSION) + { + ContextHandle fake_context = wglCreateContext(dc); + wglMakeCurrent(dc, fake_context); + + PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = get_proc("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(glGetString(GL_VERSION)); + if(!gl_ver_ptr) + throw unsupported_gl_mode(opts); + + string gl_ver = gl_ver_ptr; + vector parts = split(gl_ver.substr(0, gl_ver.find(' ')), '.'); + + gl_version_major = lexical_cast(parts[0]); + gl_version_minor = lexical_cast(parts[1]); + } + + vector 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); @@ -54,6 +125,14 @@ GLContext::~GLContext() delete priv; } +void GLContext::set_swap_interval(unsigned i) +{ + PFNWGLSWAPINTERVALEXTPROC wglSwapInterval = get_proc("wglSwapIntervalEXT"); + if(!wglSwapInterval) + throw runtime_error("wglSwapIntervalEXT not found"); + wglSwapInterval(i); +} + void GLContext::swap_buffers() { HDC dc = GetDC(window.get_private().window); @@ -61,10 +140,8 @@ void GLContext::swap_buffers() ReleaseDC(window.get_private().window, dc); } -void GLContext::window_resized(unsigned w, unsigned h) -{ - glViewport(0, 0, w, h); -} +void GLContext::window_resized(unsigned, unsigned) +{ } } // namespace Graphics } // namespace Msp