11 #include <msp/core/application.h>
12 #include <msp/core/except.h>
14 #include "glcontext.h"
16 #include "display_priv.h"
21 GLOptions::GLOptions():
31 typedef HGLRC Context;
33 typedef GLXContext Context;
36 struct GLContext::Private
40 // In X11, we need to create a window with the chosen visual
47 GLContext::GLContext(Window &wnd, const GLOptions &opts):
48 display(wnd.get_display()),
55 HDC dc=GetDC(window.get_private().window);
57 PIXELFORMATDESCRIPTOR pfd;
58 memset(&pfd, 0, sizeof(pfd));
60 pfd.nSize=sizeof(pfd);
62 pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
64 pfd.dwFlags|=PFD_DOUBLEBUFFER;
65 pfd.iPixelType=PFD_TYPE_RGBA;
72 int pf_index=ChoosePixelFormat(dc, &pfd);
74 throw Exception("Couldn't find a suitable pixel format");
75 SetPixelFormat(dc, pf_index, &pfd);
77 priv->context=wglCreateContext(dc);
78 wglMakeCurrent(dc, priv->context);
80 ReleaseDC(window.get_private().window, dc);
82 std::vector<int> attribs;
84 attribs.push_back(GLX_RGBA);
85 attribs.push_back(GLX_DEPTH_SIZE);
90 attribs.push_back(GLX_ALPHA_SIZE);
96 attribs.push_back(GLX_STENCIL_SIZE);
100 if(opts.doublebuffer)
101 attribs.push_back(GLX_DOUBLEBUFFER);
103 if(opts.multisample>0)
105 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
106 attribs.push_back(opts.multisample);
109 attribs.push_back(0);
111 ::Display *dpy=display.get_private().display;
113 XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
115 throw Exception("Couldn't find a suitable GLX visual");
116 priv->context=glXCreateContext(dpy, vi, 0, true);
118 XSetWindowAttributes attr;
119 attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
121 priv->subwnd=XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
122 XMapWindow(dpy, priv->subwnd);
126 glXMakeCurrent(dpy, priv->subwnd, priv->context);
131 throw Exception("OpenGL support not compiled in");
134 window.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized));
137 GLContext::~GLContext()
141 wglMakeCurrent(0, 0);
142 wglDeleteContext(priv->context);
144 ::Display *dpy=display.get_private().display;
146 glXMakeCurrent(dpy, 0, 0);
147 glXDestroyContext(dpy, priv->context);
148 XDestroyWindow(dpy, priv->subwnd);
154 void GLContext::swap_buffers()
158 HDC dc=GetDC(window.get_private().window);
160 ReleaseDC(window.get_private().window, dc);
162 glXSwapBuffers(display.get_private().display, priv->subwnd);
167 void GLContext::window_resized(unsigned w, unsigned h)
171 XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h);
173 glViewport(0, 0, w, h);
180 } // namespace Graphics