]> git.tdb.fi Git - libs/gui.git/blobdiff - source/graphics/glcontext.cpp
Add support for using the latest available OpenGL version
[libs/gui.git] / source / graphics / glcontext.cpp
index b71383063c05d6edb036959e8034349897bff228..ec073cb79c2c9928fc6dece00604807f2aa540dc 100644 (file)
@@ -1,19 +1,9 @@
-#include <vector>
-#ifdef WIN32
-#include <windows.h>
-#endif
-#ifdef WITH_OPENGL
-#include <GL/gl.h>
-#ifndef WIN32
-#include <GL/glx.h>
-#endif
-#endif
-#include <msp/core/application.h>
+#include <stdexcept>
 #include <msp/strings/format.h>
-#include "display.h"
 #include "glcontext.h"
 #include "window.h"
-#include "display_priv.h"
+
+using namespace std;
 
 namespace Msp {
 namespace Graphics {
@@ -22,166 +12,58 @@ GLOptions::GLOptions():
        alpha(false),
        stencil(false),
        doublebuffer(true),
-       multisample(0)
+       multisample(0),
+       forward_compatible(false),
+       core_profile(false),
+       gl_version_major(DEFAULT_VERSION),
+       gl_version_minor(DEFAULT_VERSION)
 { }
 
 
 unsupported_gl_mode::unsupported_gl_mode(const GLOptions &opts):
-       runtime_error(format("{ .alpha=%s, .stencil=%s, .doublebuffer=%s, .multisample=%d }",
-               opts.alpha, opts.stencil, opts.doublebuffer, opts.multisample))
+       runtime_error(format("{ .alpha=%s, .stencil=%s, .doublebuffer=%s, .multisample=%d, .forward_compatible=%s, .core_profile=%s, .gl_version=%s }",
+               opts.alpha, opts.stencil, opts.doublebuffer, opts.multisample, opts.forward_compatible, opts.core_profile, format_version(opts)))
 { }
 
-
-#ifdef WITH_OPENGL
-#ifdef WIN32
-typedef HGLRC Context;
-#else
-typedef GLXContext Context;
-#endif
-
-struct GLContext::Private
+string unsupported_gl_mode::format_version(const GLOptions &opts)
 {
-       Context context;
-#ifndef WIN32
-       // In X11, we need to create a window with the chosen visual
-       WindowHandle subwnd;
-#endif
-};
-#endif
+       if(opts.gl_version_major==GLOptions::LATEST_VERSION)
+               return "LATEST";
+       else if(opts.gl_version_major==GLOptions::DEFAULT_VERSION)
+               return "DEFAULT";
+       else
+               return format("%d.%d", opts.gl_version_major, opts.gl_version_minor);
+}
+
 
 
 GLContext::GLContext(Window &wnd, const GLOptions &opts):
        display(wnd.get_display()),
        window(wnd)
 {
-#ifdef WITH_OPENGL
-       priv = new Private;
-
-#ifdef WIN32
-       HDC dc = GetDC(window.get_private().window);
-
-       PIXELFORMATDESCRIPTOR pfd;
-       memset(&pfd, 0, sizeof(pfd));
-
-       pfd.nSize = sizeof(pfd);
-       pfd.nVersion = 1;
-       pfd.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
-       if(opts.doublebuffer)
-               pfd.dwFlags |= PFD_DOUBLEBUFFER;
-       pfd.iPixelType = PFD_TYPE_RGBA;
-       if(opts.alpha)
-               pfd.cAlphaBits = 1;
-       pfd.cDepthBits = 1;
-       if(opts.stencil)
-               pfd.cStencilBits = 1;
-
-       int pf_index = ChoosePixelFormat(dc, &pfd);
-       if(!pf_index)
-               throw unsupported_gl_mode(opts);
-       SetPixelFormat(dc, pf_index, &pfd);
-
-       priv->context = wglCreateContext(dc);
-       wglMakeCurrent(dc, priv->context);
-
-       ReleaseDC(window.get_private().window, dc);
-#else
-       std::vector<int> attribs;
-       
-       attribs.push_back(GLX_RGBA);
-       attribs.push_back(GLX_DEPTH_SIZE);
-       attribs.push_back(1);
-       
-       if(opts.alpha)
-       {
-               attribs.push_back(GLX_ALPHA_SIZE);
-               attribs.push_back(1);
-       }
-       
-       if(opts.stencil)
-       {
-               attribs.push_back(GLX_STENCIL_SIZE);
-               attribs.push_back(1);
-       }
-       
-       if(opts.doublebuffer)
-               attribs.push_back(GLX_DOUBLEBUFFER);
-       
-       if(opts.multisample>0)
-       {
-               attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
-               attribs.push_back(opts.multisample);
-       }
-       
-       attribs.push_back(0);
-
-       ::Display *dpy = display.get_private().display;
-
-       XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
-       if(!vi)
-               throw unsupported_gl_mode(opts);
-       priv->context = glXCreateContext(dpy, vi, 0, true);
-
-       XSetWindowAttributes attr;
-       attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
-
-       priv->subwnd = XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
-       XMapWindow(dpy, priv->subwnd);
-
-       XFree(vi);
-
-       glXMakeCurrent(dpy, priv->subwnd, priv->context);
-#endif
-#else
-       (void)wnd;
-       (void)opts;
-       throw runtime_error("no OpenGL support");
-#endif
+       platform_init(opts);
 
        window.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized));
 }
 
-GLContext::~GLContext()
+#ifndef WITH_OPENGL
+void GLContext::platform_init(const GLOptions &)
 {
-#ifdef WITH_OPENGL
-#ifdef WIN32
-       wglMakeCurrent(0, 0);
-       wglDeleteContext(priv->context);
-#else
-       ::Display *dpy = display.get_private().display;
-
-       glXMakeCurrent(dpy, 0, 0);
-       glXDestroyContext(dpy, priv->context);
-       XDestroyWindow(dpy, priv->subwnd);
-#endif
-       delete priv;
-#endif
+       throw runtime_error("no OpenGL support");
 }
 
+GLContext::~GLContext()
+{ }
+
+void GLContext::set_swap_interval(unsigned)
+{ }
+
 void GLContext::swap_buffers()
-{
-#ifdef WITH_OPENGL
-#ifdef WIN32
-       HDC dc = GetDC(window.get_private().window);
-       SwapBuffers(dc);
-       ReleaseDC(window.get_private().window, dc);
-#else
-       glXSwapBuffers(display.get_private().display, priv->subwnd);
-#endif
-#endif
-}
+{ }
 
-void GLContext::window_resized(unsigned w, unsigned h)
-{
-#ifdef WITH_OPENGL
-#ifndef WIN32
-       XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h);
-#endif
-       glViewport(0, 0, w, h);
-#else
-       (void)w;
-       (void)h;
+void GLContext::window_resized(unsigned, unsigned)
+{ }
 #endif
-}
 
 } // namespace Graphics
 } // namespace Msp