multisample(0),
forward_compatible(false),
core_profile(false),
- gl_version_major(0),
- gl_version_minor(0)
+ 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, .forward_compatible=%s, .core_profile=%s, .gl_version=%d.%d }",
- opts.alpha, opts.stencil, opts.doublebuffer, opts.multisample, opts.forward_compatible, opts.core_profile, opts.gl_version_major, opts.gl_version_minor))
+ 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)))
{ }
+string unsupported_gl_mode::format_version(const GLOptions &opts)
+{
+ 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):
struct GLOptions
{
+ enum
+ {
+ DEFAULT_VERSION = 0,
+ LATEST_VERSION = 0xFFFFFFFF
+ };
+
bool alpha;
bool stencil;
bool doublebuffer;
public:
unsupported_gl_mode(const GLOptions &);
virtual ~unsupported_gl_mode() throw () { }
+
+private:
+ static std::string format_version(const GLOptions &);
};
public:
GLContext(Window &wnd, const GLOptions &opts = GLOptions());
+ GLContext(Window &wnd, unsigned, unsigned);
private:
void platform_init(const GLOptions &);
public:
#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"
priv->glxwnd = glXCreateWindow(dpy, fb_configs[0], priv->subwnd, 0);
- 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, 0, 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, 0, 0, 0);
+ glXDestroyContext(dpy, probe_context);
+ }
+
vector<int> ctx_attribs;
ctx_attribs.push_back(GLX_RENDER_TYPE);
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);
#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"
SetPixelFormat(dc, pf_index, &pfd);
priv = new Private;
- if(opts.forward_compatible || opts.gl_version_major)
+ if(opts.forward_compatible || opts.gl_version_major!=DEFAULT_VERSION)
{
ContextHandle fake_context = wglCreateContext(dc);
wglMakeCurrent(dc, fake_context);
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)
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(gl_version_major);
ctx_attribs.push_back(WGL_CONTEXT_MINOR_VERSION_ARB);
- ctx_attribs.push_back(opts.gl_version_minor);
+ ctx_attribs.push_back(gl_version_minor);
}
ctx_attribs.push_back(0);