/* gltest - small OpenGL tearing test program
- * Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
- *
- * 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
- * (at your option) 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, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
- */
+* Copyright (C) 2012-2013 Ralf Jung <post@ralfj.de>
+*
+* 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
+* (at your option) 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, write to the Free Software
+* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
+*/
#include "glxbackend.h"
#include "glutil.h"
// attributes for a double buffered framebuffer in RGBA format with at least 4 bits per color
static int configAttribs[] =
{
- GLX_RENDER_TYPE, GLX_RGBA_BIT,
- GLX_DOUBLEBUFFER, True,
- GLX_RED_SIZE, 4,
- GLX_GREEN_SIZE, 4,
- GLX_BLUE_SIZE, 4,
- None
+ GLX_RENDER_TYPE, GLX_RGBA_BIT,
+ GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT,
+ GLX_DOUBLEBUFFER, True,
+ GLX_RED_SIZE, 4,
+ GLX_GREEN_SIZE, 4,
+ GLX_BLUE_SIZE, 4,
+ None
};
#ifdef CON_GL3
// attributes for a GL3 context
static int contextAttribs[] =
{
- GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
- GLX_CONTEXT_MINOR_VERSION_ARB, 0,
- GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
- None
+ GLX_CONTEXT_MAJOR_VERSION_ARB, 3,
+ GLX_CONTEXT_MINOR_VERSION_ARB, 0,
+ GLX_CONTEXT_FLAGS_ARB, GLX_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB,
+ None
};
#endif
VisualID GLXBackend::initialize(Display *display)
{
- if (this->display == NULL) { // this implies that the context is also unitialized
- this->display = display;
- // debugging: show version information
- int glxMajor, glxMinor;
- glXQueryVersion(display, &glxMajor, &glxMinor);
- printf("Using GLX version: %d.%d\n", glxMajor, glxMinor);
- if (glxMajor < 1 || (glxMajor == 1 && glxMinor < 3)) {
- // glXChooseFBConfig and glXCreateNewContext require GLX 1.3
- die("Need at least GLX 1.3 to function properly\n");
- }
- // check for extension-based functions
- funSwapIntervalMesa = (PFNGLXSWAPINTERVALMESAPROC)resolveGLXFunction("GLX_MESA_swap_control", "glXSwapIntervalMESA");
- funSwapIntervalExt = (PFNGLXSWAPINTERVALEXTPROC)resolveGLXFunction("GLX_EXT_swap_control", "glXSwapIntervalEXT");
- funCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)resolveGLXFunction("GLX_ARB_create_context", "glXCreateContextAttribsARB");
- // get the first usable framebuffer configuration
- int count = 0;
- GLXFBConfig *configs = glXChooseFBConfig(display, DefaultScreen(display), configAttribs, &count);
- if (count < 1) {
- die("Failed to choose framebuffer configuration\n");
- }
- config = configs[0];
- XFree(configs);
- }
- // return visual ID
- XVisualInfo *vi = glXGetVisualFromFBConfig(display, config);
- VisualID visualid = vi->visualid;
- XFree(vi);
- return visualid;
+ if (this->display == NULL) { // this implies that the context is also unitialized
+ this->display = display;
+ // debugging: show version information
+ int glxMajor, glxMinor;
+ glXQueryVersion(display, &glxMajor, &glxMinor);
+ printf("Using GLX version: %d.%d\n", glxMajor, glxMinor);
+ if (glxMajor == 1 && glxMinor < 4) {
+ // glXChooseFBConfig and glXCreateNewContext require GLX 1.3; GLX_ARB_create_context requires GLX 1.4
+ die("Need at least GLX 1.4 to function properly\n");
+ }
+ // check for extension-based functions
+ funSwapIntervalMesa = (PFNGLXSWAPINTERVALMESAPROC)resolveGLXFunction("GLX_MESA_swap_control", "glXSwapIntervalMESA");
+ funSwapIntervalExt = (PFNGLXSWAPINTERVALEXTPROC)resolveGLXFunction("GLX_EXT_swap_control", "glXSwapIntervalEXT");
+ funCreateContextAttribsARB = (PFNGLXCREATECONTEXTATTRIBSARBPROC)resolveGLXFunction("GLX_ARB_create_context", "glXCreateContextAttribsARB");
+ // get the first usable framebuffer configuration
+ int count = 0;
+ GLXFBConfig *configs = glXChooseFBConfig(display, DefaultScreen(display), configAttribs, &count);
+ if (count < 1) {
+ die("Failed to choose framebuffer configuration\n");
+ }
+ config = configs[0];
+ XFree(configs);
+ }
+ // return visual ID
+ XVisualInfo *vi = glXGetVisualFromFBConfig(display, config);
+ if (vi== NULL) {
+ die("The GLXFBConfig I got is invalid\n");
+ }
+ VisualID visualid = vi->visualid;
+ XFree(vi);
+ return visualid;
}
bool GLXBackend::haveGLXExtension(const std::string &name)
{
- assert(display != NULL);
- std::string extensions = glXQueryExtensionsString(display, DefaultScreen(display));
- return (std::string(" "+extensions+" ").find(" "+name+" ") != std::string::npos);
+ assert(display != NULL);
+ std::string extensions = glXQueryExtensionsString(display, DefaultScreen(display));
+ return (std::string(" "+extensions+" ").find(" "+name+" ") != std::string::npos);
}
T_proc GLXBackend::resolveGLXFunction(const char *extension, const char *function)
{
- if (!haveGLXExtension(extension)) return NULL;
- T_proc f = glXGetProcAddress((const GLubyte*)function);
- if (f)
- printf("%s is supported, using it for %s\n", extension, function);
- return f;
+ if (!haveGLXExtension(extension)) return NULL;
+ T_proc f = glXGetProcAddress((const GLubyte*)function);
+ if (f)
+ printf("%s is supported, using it for %s\n", extension, function);
+ else
+ printf("%s is supported, but I could not find %s\n", extension, function);
+ return f;
}
void GLXBackend::createContext(Window window)
{
- assert(display != NULL && context == None);
- this->window = window;
- // create context with that window
+ assert(display != NULL && context == None);
+ this->window = window;
+ // create context with that window
#ifdef CON_GL1
- context = glXCreateNewContext(display, config, GLX_RGBA_TYPE, NULL, GL_TRUE);
+ context = glXCreateNewContext(display, config, GLX_RGBA_TYPE, NULL, GL_TRUE);
#else
- if (!funCreateContextAttribsARB) {
- die("Cannot create GL3 context: GLX_ARB_create_context not supported\n");
- }
- context = funCreateContextAttribsARB(display, config, NULL, GL_TRUE, contextAttribs);
+ if (!funCreateContextAttribsARB) {
+ die("Cannot create GL3 context: GLX_ARB_create_context not supported\n");
+ }
+ context = funCreateContextAttribsARB(display, config, NULL, GL_TRUE, contextAttribs);
#endif
- if (!context) {
- die("Error creating context\n");
- }
- glXMakeCurrent(display, window, context);
- assert(glXIsDirect(display, context));
- printf("Using GL version: %s\n", glGetString(GL_VERSION));
- // initialise GL utilities
- resolveFunctionPointers((T_glGetProcAddress)glXGetProcAddress);
+ if (!context) {
+ die("Error creating context\n");
+ }
+ glXMakeCurrent(display, window, context);
+ assert(glXIsDirect(display, context));
+ printf("Using GL version: %s\n", glGetString(GL_VERSION));
+ // initialise GL utilities
+ resolveFunctionPointers((T_glGetProcAddress)glXGetProcAddress);
}
GLXBackend::~GLXBackend()
{
- if (display != NULL) {
- if (context != None) {
- glXMakeCurrent(display, None, NULL);
- glXDestroyContext(display, context);
- }
- }
+ if (display != NULL) {
+ if (context != None) {
+ glXMakeCurrent(display, None, NULL);
+ glXDestroyContext(display, context);
+ }
+ }
}
void GLXBackend::swapBuffers() const
{
- assert(context != None); // this implies the display is also initialized
- glXSwapBuffers(display, window);
+ assert(context != None); // this implies the display is also initialized
+ glXSwapBuffers(display, window);
}
void GLXBackend::setSwapInterval(int i) const
{
- assert(context != None);
- // check if swap interval value is supported
- if (i < 0) {
- die("Cannot set swap interval to %d, must not be negative\n", i);
- }
- // set it
- if (funSwapIntervalExt)
- funSwapIntervalExt(display, window, i);
- else if (funSwapIntervalMesa)
- funSwapIntervalMesa(i);
- else {
- die("At least one of GLX_EXT_swap_control, GLX_MESA_swap_control must be supported by the system\n");
- }
+ assert(context != None);
+ // check if swap interval value is supported
+ if (i < 0) {
+ die("Cannot set swap interval to %d, must not be negative\n", i);
+ }
+ // set it
+ if (funSwapIntervalExt)
+ funSwapIntervalExt(display, window, i);
+ else if (funSwapIntervalMesa)
+ funSwapIntervalMesa(i);
+ else {
+ die("At least one of GLX_EXT_swap_control, GLX_MESA_swap_control must be supported by the system\n");
+ }
}