summaryrefslogtreecommitdiff
path: root/src/utils/glxhelper.cpp
diff options
context:
space:
mode:
authorAndrei Karas <akaras@inbox.ru>2014-06-23 23:18:36 +0300
committerAndrei Karas <akaras@inbox.ru>2014-06-24 00:38:16 +0300
commit34279cbb4ea6506c3d64a62e20cd97643999ce61 (patch)
tree834f737ba88af9b718ab2097e77f9953afcaa586 /src/utils/glxhelper.cpp
parenta1521294fda5b8b5bba3e7b512573bfcbc4c7fbe (diff)
downloadplus-34279cbb4ea6506c3d64a62e20cd97643999ce61.tar.gz
plus-34279cbb4ea6506c3d64a62e20cd97643999ce61.tar.bz2
plus-34279cbb4ea6506c3d64a62e20cd97643999ce61.tar.xz
plus-34279cbb4ea6506c3d64a62e20cd97643999ce61.zip
Add manual OpenGL context creation.
For SDL2 set attributes for context version. For SDL1.2 in X11 create own context. For SDL1.2 and other platforms not implimented for now. Also try fallback if need to older context versions.
Diffstat (limited to 'src/utils/glxhelper.cpp')
-rw-r--r--src/utils/glxhelper.cpp120
1 files changed, 120 insertions, 0 deletions
diff --git a/src/utils/glxhelper.cpp b/src/utils/glxhelper.cpp
new file mode 100644
index 000000000..1fedeb9c6
--- /dev/null
+++ b/src/utils/glxhelper.cpp
@@ -0,0 +1,120 @@
+/*
+ * The ManaPlus Client
+ * Copyright (C) 2014 The ManaPlus Developers
+ *
+ * This file is part of The ManaPlus Client.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "utils/glxhelper.h"
+
+#if defined(USE_OPENGL) && defined(USE_X11)
+
+#include "logger.h"
+
+#include "render/mglx.h"
+#include "render/mglxtypes.h"
+
+#include "utils/stringutils.h"
+
+#include "debug.h"
+
+static int ErrorHandler(Display *d A_UNUSED, XErrorEvent *e A_UNUSED)
+{
+ return 0;
+}
+
+void *GlxHelper::createContext(unsigned int window,
+ void *const display0,
+ const int major,
+ const int minor)
+{
+ Display *const display = static_cast<Display*>(display0);
+ XSync(display, false);
+ int (*handler) (Display *, XErrorEvent *) = XSetErrorHandler(ErrorHandler);
+ void *context = mglXGetCurrentContext();
+ if (!mglXGetCurrentContext
+ || !mglXCreateContextAttribs
+ || !mglXChooseFBConfig)
+ {
+ logger->log("Cant change context, functions in driver "
+ "not implimented");
+ XSetErrorHandler(handler);
+ return context;
+ }
+ if (!context)
+ {
+ logger->log("Cant change context, because current "
+ "context not created");
+ XSetErrorHandler(handler);
+ return context;
+ }
+ int glxAttribs[] =
+ {
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_RED_SIZE, 3,
+ GLX_GREEN_SIZE, 3,
+ GLX_BLUE_SIZE, 2,
+ GLX_DOUBLEBUFFER, 1,
+ 0
+ };
+
+ int fbcount = 0;
+ GLXFBConfig *framebuffer_config = mglXChooseFBConfig(display,
+ DefaultScreen(display),
+ glxAttribs,
+ &fbcount);
+
+ if (!framebuffer_config || !fbcount)
+ {
+ logger->log("No correct fb profile found");
+ XSetErrorHandler(handler);
+ return nullptr;
+ }
+
+ int attribs[] =
+ {
+ GLX_CONTEXT_MAJOR_VERSION_ARB, major,
+ GLX_CONTEXT_MINOR_VERSION_ARB, minor,
+ GLX_CONTEXT_PROFILE_MASK_ARB, 0x01, // core profile
+ 0, 0
+ };
+
+ void *const context2 = mglXCreateContextAttribs(display,
+ framebuffer_config[0], context, true, attribs);
+ if (!context2)
+ {
+ logger->log("context %d.%d creation failed", major, minor);
+ XSetErrorHandler(handler);
+ return nullptr;
+ }
+
+ XSync(display, false);
+ XSetErrorHandler(handler);
+
+ if (!mglXMakeCurrent(display, window, context2))
+ {
+ mglXDestroyContext(display, context2);
+ logger->log("make current context %d.%d failed", major, minor);
+ return nullptr;
+ }
+
+// do not delete SDL context, because on exit it will crash
+// mglXDestroyContext(display, context);
+ logger->log("Context for %d.%d created", major, minor);
+ return context2;
+}
+
+#endif // defined(USE_OPENGL) && defined(USE_X11)