+#include "glcontext.h"
#include <set>
#include <vector>
#include <GL/glx.h>
#include <GL/glxext.h>
+#include <msp/strings/lexicalcast.h>
#include <msp/strings/utils.h>
-#include "glcontext.h"
#include "display_private.h"
#include "window_private.h"
struct GLContext::Private
{
- ContextHandle context;
+ ContextHandle context = nullptr;
// We need to create a window with the chosen visual
- WindowHandle subwnd;
- GLXWindow glxwnd;
+ WindowHandle subwnd = None;
+ GLXWindow glxwnd = None;
};
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);
- priv->glxwnd = glXCreateWindow(dpy, fb_configs[0], priv->subwnd, 0);
+ priv->glxwnd = glXCreateWindow(dpy, fb_configs[0], priv->subwnd, nullptr);
- if(opts.forward_compatible || opts.gl_version_major)
+ if(opts.forward_compatible || opts.gl_version_major!=GLOptions::DEFAULT_VERSION)
{
if(!extensions.count("GLX_ARB_create_context") || !extensions.count("GLX_ARB_get_proc_address"))
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)
+ {
+ ContextHandle probe_context = glXCreateNewContext(dpy, fb_configs[0], GLX_RGBA_TYPE, nullptr, true);
+ glXMakeContextCurrent(dpy, priv->glxwnd, priv->glxwnd, probe_context);
+
+ 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]);
+
+ glXMakeContextCurrent(dpy, None, None, nullptr);
+ glXDestroyContext(dpy, probe_context);
+ }
+
vector<int> ctx_attribs;
ctx_attribs.push_back(GLX_RENDER_TYPE);
ctx_attribs.push_back(GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB);
}
+ if(opts.core_profile)
+ {
+ ctx_attribs.push_back(GLX_CONTEXT_PROFILE_MASK_ARB);
+ ctx_attribs.push_back(GLX_CONTEXT_CORE_PROFILE_BIT_ARB);
+ }
+
if(opts.gl_version_major)
{
ctx_attribs.push_back(GLX_CONTEXT_MAJOR_VERSION_ARB);
- ctx_attribs.push_back(opts.gl_version_major);
+ ctx_attribs.push_back(gl_version_major);
ctx_attribs.push_back(GLX_CONTEXT_MINOR_VERSION_ARB);
- ctx_attribs.push_back(opts.gl_version_minor);
+ ctx_attribs.push_back(gl_version_minor);
}
ctx_attribs.push_back(0);
const GLubyte *name = reinterpret_cast<const GLubyte *>("glXCreateContextAttribsARB");
PFNGLXCREATECONTEXTATTRIBSARBPROC glXCreateContextAttribs = reinterpret_cast<PFNGLXCREATECONTEXTATTRIBSARBPROC>(glXGetProcAddressARB(name));
- priv->context = glXCreateContextAttribs(dpy, fb_configs[0], 0, true, &ctx_attribs[0]);
+ priv->context = glXCreateContextAttribs(dpy, fb_configs[0], nullptr, true, &ctx_attribs[0]);
}
else
- priv->context = glXCreateNewContext(dpy, fb_configs[0], GLX_RGBA_TYPE, 0, true);
+ priv->context = glXCreateNewContext(dpy, fb_configs[0], GLX_RGBA_TYPE, nullptr, true);
XFree(vi);
XFree(fb_configs);
priv = new Private;
priv->glxwnd = 0;
- priv->context = glXCreateContext(dpy, vi, 0, true);
+ priv->context = glXCreateContext(dpy, vi, nullptr, true);
XSetWindowAttributes attr;
attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
if(priv->glxwnd)
{
- glXMakeContextCurrent(dpy, 0, 0, 0);
+ glXMakeContextCurrent(dpy, None, None, nullptr);
glXDestroyWindow(dpy, priv->glxwnd);
}
else
- glXMakeCurrent(dpy, 0, 0);
+ glXMakeCurrent(dpy, None, nullptr);
glXDestroyContext(dpy, priv->context);
XDestroyWindow(dpy, priv->subwnd);
void GLContext::set_swap_interval(unsigned i)
{
const GLubyte *name = reinterpret_cast<const GLubyte *>("glXSwapIntervalEXT");
- PFNGLXSWAPINTERVALEXTPROC func = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress(name));
- if(!func)
+ PFNGLXSWAPINTERVALEXTPROC glXSwapInterval = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress(name));
+ if(!glXSwapInterval)
throw runtime_error("glXSwapIntervalEXT not found");
- func(display.get_private().display, (priv->glxwnd ? priv->glxwnd : priv->subwnd), i);
+ glXSwapInterval(display.get_private().display, (priv->glxwnd ? priv->glxwnd : priv->subwnd), i);
}
void GLContext::swap_buffers()