]> git.tdb.fi Git - libs/gui.git/blob - source/graphics/glx/glcontext.cpp
Add support for swap interval control
[libs/gui.git] / source / graphics / glx / glcontext.cpp
1 #include <vector>
2 #include <GL/gl.h>
3 #include <GL/glx.h>
4 #include "glcontext.h"
5 #include "display_private.h"
6 #include "window_private.h"
7
8 using namespace std;
9
10 namespace Msp {
11 namespace Graphics {
12
13 typedef GLXContext ContextHandle;
14
15 struct GLContext::Private
16 {
17         ContextHandle context;
18         // We need to create a window with the chosen visual
19         WindowHandle subwnd;
20 };
21
22
23 void GLContext::platform_init(const GLOptions &opts)
24 {
25         vector<int> attribs;
26
27         attribs.push_back(GLX_RGBA);
28         attribs.push_back(GLX_DEPTH_SIZE);
29         attribs.push_back(1);
30
31         if(opts.alpha)
32         {
33                 attribs.push_back(GLX_ALPHA_SIZE);
34                 attribs.push_back(1);
35         }
36
37         if(opts.stencil)
38         {
39                 attribs.push_back(GLX_STENCIL_SIZE);
40                 attribs.push_back(1);
41         }
42
43         if(opts.doublebuffer)
44                 attribs.push_back(GLX_DOUBLEBUFFER);
45
46         if(opts.multisample>0)
47         {
48                 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
49                 attribs.push_back(1);
50                 attribs.push_back(GLX_SAMPLES_ARB);
51                 attribs.push_back(opts.multisample);
52         }
53
54         attribs.push_back(0);
55
56         DisplayHandle dpy = display.get_private().display;
57
58         XVisualInfo *vi = glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
59         if(!vi)
60                 throw unsupported_gl_mode(opts);
61
62         priv = new Private;
63         priv->context = glXCreateContext(dpy, vi, 0, true);
64
65         XSetWindowAttributes attr;
66         attr.colormap = XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
67
68         priv->subwnd = XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
69         XMapWindow(dpy, priv->subwnd);
70
71         XFree(vi);
72
73         glXMakeCurrent(dpy, priv->subwnd, priv->context);
74 }
75
76 GLContext::~GLContext()
77 {
78         DisplayHandle dpy = display.get_private().display;
79
80         glXMakeCurrent(dpy, 0, 0);
81         glXDestroyContext(dpy, priv->context);
82         XDestroyWindow(dpy, priv->subwnd);
83
84         delete priv;
85 }
86
87 void GLContext::set_swap_interval(unsigned i)
88 {
89         const GLubyte *name = reinterpret_cast<const GLubyte *>("glXSwapIntervalEXT");
90         PFNGLXSWAPINTERVALEXTPROC func = reinterpret_cast<PFNGLXSWAPINTERVALEXTPROC>(glXGetProcAddress(name));
91         if(!func)
92                 throw runtime_error("glXSwapIntervalEXT not found");
93         func(display.get_private().display, priv->subwnd, i);
94 }
95
96 void GLContext::swap_buffers()
97 {
98         glXSwapBuffers(display.get_private().display, priv->subwnd);
99 }
100
101 void GLContext::window_resized(unsigned w, unsigned h)
102 {
103         XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h);
104 }
105
106 } // namespace Graphics
107 } // namespace Msp