]> git.tdb.fi Git - libs/gui.git/blob - source/glcontext.cpp
Bugfixes
[libs/gui.git] / source / glcontext.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 #ifdef WIN32
10 #include <windows.h>
11 #endif
12 #include <GL/gl.h>
13 #include <msp/core/application.h>
14 #include <msp/core/except.h>
15 #include "display.h"
16 #include "glcontext.h"
17 #include "window.h"
18
19 #include <iostream>
20 using namespace std;
21
22 namespace Msp {
23 namespace Graphics {
24
25 GLOptions::GLOptions():
26         alpha(false),
27         stencil(false),
28         doublebuffer(true),
29         multisample(0)
30 { }
31
32
33 GLContext::GLContext(Window &wnd, const GLOptions &opts):
34         display(wnd.get_display()),
35         window(wnd)
36 {
37 #ifdef WIN32
38         HDC dc=GetDC(window.get_handle());
39
40         PIXELFORMATDESCRIPTOR pfd;
41         memset(&pfd, 0, sizeof(pfd));
42
43         pfd.nSize=sizeof(pfd);
44         pfd.nVersion=1;
45         pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
46         if(opts.doublebuffer)
47                 pfd.dwFlags|=PFD_DOUBLEBUFFER;
48         pfd.iPixelType=PFD_TYPE_RGBA;
49         if(opts.alpha)
50                 pfd.cAlphaBits=1;
51         pfd.cDepthBits=1;
52         if(opts.stencil)
53                 pfd.cStencilBits=1;
54
55         int pf_index=ChoosePixelFormat(dc, &pfd);
56         if(!pf_index)
57                 throw Exception("Couldn't find a suitable pixel format");
58         SetPixelFormat(dc, pf_index, &pfd);
59
60         context=wglCreateContext(dc);
61         wglMakeCurrent(dc, context);
62
63         ReleaseDC(window.get_handle(), dc);
64 #else
65         std::vector<int> attribs;
66         
67         attribs.push_back(GLX_RGBA);
68         attribs.push_back(GLX_DEPTH_SIZE);
69         attribs.push_back(1);
70         
71         if(opts.alpha)
72         {
73                 attribs.push_back(GLX_ALPHA_SIZE);
74                 attribs.push_back(1);
75         }
76         
77         if(opts.stencil)
78         {
79                 attribs.push_back(GLX_STENCIL_SIZE);
80                 attribs.push_back(1);
81         }
82         
83         if(opts.doublebuffer)
84                 attribs.push_back(GLX_DOUBLEBUFFER);
85         
86         if(opts.multisample>0)
87         {
88                 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
89                 attribs.push_back(opts.multisample);
90         }
91         
92         attribs.push_back(0);
93
94         ::Display *dpy=display.get_display();
95
96         XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
97         if(!vi)
98                 throw Exception("Couldn't find a suitable GLX visual");
99         context=glXCreateContext(dpy, vi, 0, true);
100
101         XSetWindowAttributes attr;
102         attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
103
104         subwnd=XCreateWindow(dpy, window.get_handle(), 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
105         XMapWindow(display.get_display(), subwnd);
106
107         XFree(vi);
108
109         glXMakeCurrent(dpy, subwnd, context);
110
111         window.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized));
112 #endif
113 }
114
115 GLContext::~GLContext()
116 {
117 #ifdef WIN32
118         wglMakeCurrent(0, 0);
119         wglDeleteContext(context);
120 #else
121         ::Display *dpy=display.get_display();
122
123         glXMakeCurrent(dpy, 0, 0);
124         glXDestroyContext(dpy, context);
125         XDestroyWindow(dpy, subwnd);
126 #endif
127 }
128
129 void GLContext::swap_buffers()
130 {
131 #ifdef WIN32
132         HDC dc=GetDC(window.get_handle());
133         SwapBuffers(dc);
134         ReleaseDC(window.get_handle(), dc);
135 #else
136         glXSwapBuffers(display.get_display(), subwnd);
137 #endif
138 }
139
140 void GLContext::window_resized(unsigned w, unsigned h)
141 {
142 #ifndef WIN32
143         XMoveResizeWindow(display.get_display(), subwnd, 0, 0, w, h);
144 #endif
145         glViewport(0, 0, w, h);
146 }
147
148 } // namespace Graphics
149 } // namespace Msp