7841bbe584aeceb3d8c43747a20a8e9694df931b
[gltest.git] / glxbackend.cpp
1 #include "glxbackend.h"
2
3 #include <stdio.h>
4 #include <assert.h>
5 #include <stdlib.h>
6 #include <GL/glxext.h>
7 #include <string>
8
9 /* attributes for a double buffered visual in RGBA format with at least
10 * 4 bits per color */                       
11 static int attrList[] =                                             
12 {                                                                      
13         GLX_RGBA, GLX_DOUBLEBUFFER,
14         GLX_RED_SIZE, 4,                                                   
15         GLX_GREEN_SIZE, 4,                                                 
16         GLX_BLUE_SIZE, 4,
17         None                                                               
18 };
19
20 VisualID GLXBackend::initialize(Display *display)
21 {
22         if (this->display == NULL) { // this implies that the context is also unitialized
23                 this->display = display;
24                 // debugging: show version information
25                 int glxMajor, glxMinor;
26                 glXQueryVersion(display, &glxMajor, &glxMinor);
27                 printf("Using GLX version %d.%d\n", glxMajor, glxMinor);
28                 // check for swap control functions
29                 const char *extensions = glXQueryExtensionsString(display, DefaultScreen(display));
30                 if (std::string(extensions).find("GLX_MESA_swap_control") != std::string::npos) {
31                         funSwapIntervalMesa = (PFNGLXSWAPINTERVALMESAPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalMESA");
32                         if (funSwapIntervalMesa) printf("glXSwapIntervalMESA is present\n");
33                 }
34                 else {
35                         funSwapIntervalMesa = 0;
36                 }
37                 if (std::string(extensions).find("GLX_EXT_swap_control") != std::string::npos) {
38                         funSwapIntervalExt = (PFNGLXSWAPINTERVALEXTPROC)glXGetProcAddress((const GLubyte*)"glXSwapIntervalEXT");
39                         if (funSwapIntervalExt) printf("glXSwapIntervalEXT is present\n");
40                 }
41                 else {
42                         funSwapIntervalExt = 0;
43                 }
44                 // get the visual
45                 vi = glXChooseVisual(display, DefaultScreen(display), attrList);
46         }
47         return vi->visualid;
48 }
49
50 void GLXBackend::createContext(Window window)
51 {
52         assert(display != NULL && context == None);
53         this->window = window;
54         // create context with that window
55         context = glXCreateContext(display, vi, 0, GL_TRUE);                             
56         glXMakeCurrent(display, window, context);                                      
57         assert(glXIsDirect(display, context));
58 }
59
60 GLXBackend::~GLXBackend()
61 {
62         if (display != NULL) {
63                 if (context != None) {
64                         glXMakeCurrent(display, None, NULL);
65                         glXDestroyContext(display, context);
66                 }
67                 XFree(vi);
68         }
69 }
70
71 void GLXBackend::swapBuffers() const
72 {
73         assert(context != None); // this implies the display is also initialized
74         glXSwapBuffers(display, window);
75 }
76
77 void GLXBackend::setSwapInterval(int i) const
78 {
79         assert(context != None);
80         if (funSwapIntervalExt)
81                 funSwapIntervalExt(display, window, i);
82         else if (funSwapIntervalMesa)
83                 funSwapIntervalMesa(i);
84         else {
85                 fprintf(stderr, "At least one of glXSwapIntervalMESA, glXSwapIntervalEXT must be provided by the system\n");
86                 abort();
87         }
88 }