]> git.tdb.fi Git - libs/gui.git/blob - source/glwindow.cpp
303d542a28585ae2574b896ca6ea39fe38db1956
[libs/gui.git] / source / glwindow.cpp
1 /* $Id$
2
3 This file is part of libmspgbase
4 Copyright © 2007 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
6 */
7
8 #include <vector>
9 #include <msp/core/except.h>
10 #include "glwindow.h"
11
12 using namespace std;
13
14 namespace Msp {
15
16 GLDisplayOptions::GLDisplayOptions():
17         alpha(false),
18         stencil(false),
19         doublebuffer(true),
20         multisample(0)
21 { }
22
23
24 GLWindow::GLWindow(unsigned w, unsigned h)
25 {
26         options.width=w;
27         options.height=h;
28         init();
29 }
30
31 GLWindow::GLWindow(const DisplayOptions &dopt, const GLDisplayOptions &gl_dopt)
32 {
33         options=dopt;
34         gl_options=gl_dopt;
35         init();
36 }
37
38 GLWindow::~GLWindow()
39 {
40         glXMakeContextCurrent(display, 0, 0, 0);
41         glXDestroyWindow(display, glx_wnd);
42         glXDestroyContext(display, context);
43 }
44
45 void GLWindow::swap_buffers()
46 {
47         glXSwapBuffers(display, glx_wnd);
48 }
49
50 void GLWindow::init()
51 {
52         prepare();
53
54         vector<int> attribs;
55         
56         attribs.push_back(GLX_RENDER_TYPE);
57         attribs.push_back(GLX_RGBA_BIT);
58         
59         attribs.push_back(GLX_DRAWABLE_TYPE);
60         attribs.push_back(GLX_WINDOW_BIT);
61         
62         attribs.push_back(GLX_DEPTH_SIZE);
63         attribs.push_back(1);
64         
65         if(gl_options.alpha)
66         {
67                 attribs.push_back(GLX_ALPHA_SIZE);
68                 attribs.push_back(1);
69         }
70         
71         if(gl_options.stencil)
72         {
73                 attribs.push_back(GLX_STENCIL_SIZE);
74                 attribs.push_back(1);
75         }
76         
77         if(gl_options.doublebuffer)
78         {
79                 attribs.push_back(GLX_DOUBLEBUFFER);
80                 attribs.push_back(true);
81         }
82         
83         if(gl_options.multisample>0)
84         {
85                 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
86                 attribs.push_back(gl_options.multisample);
87         }
88         
89         attribs.push_back(None);
90
91         int count;
92         GLXFBConfig *config=glXChooseFBConfig(display, DefaultScreen(display), &attribs.front(), &count);
93         if(!config)
94                 throw Exception("Couldn't get a GLX framebuffer configuration");
95
96         context=glXCreateNewContext(display, config[0], GLX_RGBA_TYPE, 0, true);
97         if(!context)
98                 throw Exception("Couldn't create a GLX context");
99
100         XVisualInfo *vi=glXGetVisualFromFBConfig(display, config[0]);
101         Handle root=RootWindow(display, vi->screen);
102
103         Colormap cmap=XCreateColormap(display, root, vi->visual, AllocNone);
104         XSetWindowAttributes attr;
105         attr.colormap=cmap;
106
107         Handle wnd=XCreateWindow(display, root, 0, 0, options.width, options.height, 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
108         set_window(wnd);
109
110         glx_wnd=glXCreateWindow(display, config[0], wnd, 0);
111
112         glXMakeContextCurrent(display, glx_wnd, glx_wnd, context);
113
114         XFree(config);
115 }
116
117 void GLWindow::on_event(const XEvent &event)
118 {
119         if(event.type==ConfigureNotify)
120                 glViewport(0, 0, options.width, options.height);
121 }
122
123 } // namespace Msp