3 This file is part of libmspgbase
4 Copyright © 2007-2008 Mikko Rasa, Mikkosoft Productions
5 Distributed under the LGPL
18 #include <msp/core/application.h>
19 #include <msp/core/except.h>
21 #include "glcontext.h"
23 #include "display_priv.h"
28 GLOptions::GLOptions():
38 typedef HGLRC Context;
40 typedef GLXContext Context;
43 struct GLContext::Private
47 // In X11, we need to create a window with the chosen visual
54 GLContext::GLContext(Window &wnd, const GLOptions &opts):
55 display(wnd.get_display()),
62 HDC dc=GetDC(window.get_private().window);
64 PIXELFORMATDESCRIPTOR pfd;
65 memset(&pfd, 0, sizeof(pfd));
67 pfd.nSize=sizeof(pfd);
69 pfd.dwFlags=PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL;
71 pfd.dwFlags|=PFD_DOUBLEBUFFER;
72 pfd.iPixelType=PFD_TYPE_RGBA;
79 int pf_index=ChoosePixelFormat(dc, &pfd);
81 throw Exception("Couldn't find a suitable pixel format");
82 SetPixelFormat(dc, pf_index, &pfd);
84 priv->context=wglCreateContext(dc);
85 wglMakeCurrent(dc, priv->context);
87 ReleaseDC(window.get_private().window, dc);
89 std::vector<int> attribs;
91 attribs.push_back(GLX_RGBA);
92 attribs.push_back(GLX_DEPTH_SIZE);
97 attribs.push_back(GLX_ALPHA_SIZE);
103 attribs.push_back(GLX_STENCIL_SIZE);
104 attribs.push_back(1);
107 if(opts.doublebuffer)
108 attribs.push_back(GLX_DOUBLEBUFFER);
110 if(opts.multisample>0)
112 attribs.push_back(GLX_SAMPLE_BUFFERS_ARB);
113 attribs.push_back(opts.multisample);
116 attribs.push_back(0);
118 ::Display *dpy=display.get_private().display;
120 XVisualInfo *vi=glXChooseVisual(dpy, DefaultScreen(dpy), &attribs.front());
122 throw Exception("Couldn't find a suitable GLX visual");
123 priv->context=glXCreateContext(dpy, vi, 0, true);
125 XSetWindowAttributes attr;
126 attr.colormap=XCreateColormap(dpy, DefaultRootWindow(dpy), vi->visual, AllocNone);
128 priv->subwnd=XCreateWindow(dpy, window.get_private().window, 0, 0, window.get_width(), window.get_height(), 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr);
129 XMapWindow(dpy, priv->subwnd);
133 glXMakeCurrent(dpy, priv->subwnd, priv->context);
138 throw Exception("OpenGL support not compiled in");
141 window.signal_resize.connect(sigc::mem_fun(this, &GLContext::window_resized));
144 GLContext::~GLContext()
148 wglMakeCurrent(0, 0);
149 wglDeleteContext(priv->context);
151 ::Display *dpy=display.get_private().display;
153 glXMakeCurrent(dpy, 0, 0);
154 glXDestroyContext(dpy, priv->context);
155 XDestroyWindow(dpy, priv->subwnd);
161 void GLContext::swap_buffers()
165 HDC dc=GetDC(window.get_private().window);
167 ReleaseDC(window.get_private().window, dc);
169 glXSwapBuffers(display.get_private().display, priv->subwnd);
174 void GLContext::window_resized(unsigned w, unsigned h)
178 XMoveResizeWindow(display.get_private().display, priv->subwnd, 0, 0, w, h);
180 glViewport(0, 0, w, h);
187 } // namespace Graphics