]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/wgl/glcontext.cpp
Fix compile errors from function casts in wgl
[libs/gui.git] / source / graphics / wgl / glcontext.cpp
index 964dea2b7fba92a66815b7d84e89254c0c840880..68088970ac13cab32cd856a2a23980d838ad3bf7 100644 (file)
@@ -1,8 +1,22 @@
+#include <vector>
 #include <windows.h>
 #include <GL/gl.h>
+#include <GL/wglext.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 {
 
@@ -16,8 +30,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 +52,49 @@ 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)
+       {
+               ContextHandle fake_context = wglCreateContext(dc);
+               wglMakeCurrent(dc, fake_context);
+
+               PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribs = get_proc<PFNWGLCREATECONTEXTATTRIBSARBPROC>("wglCreateContextAttribsARB");
+               if(!wglCreateContextAttribs)
+                       throw unsupported_gl_mode(opts);
+
+               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(opts.gl_version_major);
+                       ctx_attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
+                       ctx_attribs.push_back(opts.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 +108,14 @@ GLContext::~GLContext()
        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);
@@ -61,10 +123,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