From: Mikko Rasa Date: Mon, 27 Aug 2007 14:18:07 +0000 (+0000) Subject: Convert GLWindow to use GLX 1.3 X-Git-Tag: 0.9~23 X-Git-Url: http://git.tdb.fi/?p=libs%2Fgui.git;a=commitdiff_plain;h=d39a783c839c08be8ac36a040f4f8b2ee0da8d56 Convert GLWindow to use GLX 1.3 Restructure the code a bit --- diff --git a/source/glwindow.cpp b/source/glwindow.cpp index 3ae5590..6657ea6 100644 --- a/source/glwindow.cpp +++ b/source/glwindow.cpp @@ -15,6 +15,7 @@ namespace Msp { GLDisplayOptions::GLDisplayOptions(): alpha(false), + stencil(false), doublebuffer(true), multisample(0) { } @@ -36,13 +37,14 @@ GLWindow::GLWindow(const DisplayOptions &dopt, const GLDisplayOptions &gl_dopt) GLWindow::~GLWindow() { - glXMakeCurrent(display, 0, 0); + glXMakeContextCurrent(display, 0, 0, 0); + glXDestroyWindow(display, glx_wnd); glXDestroyContext(display, context); } void GLWindow::swap_buffers() { - glXSwapBuffers(display, window); + glXSwapBuffers(display, glx_wnd); } void GLWindow::init() @@ -50,39 +52,72 @@ void GLWindow::init() prepare(); vector attribs; - attribs.push_back(GLX_RGBA); - attribs.push_back(GLX_BUFFER_SIZE); - attribs.push_back(24); + + attribs.push_back(GLX_RENDER_TYPE); + attribs.push_back(GLX_RGBA_BIT); + + attribs.push_back(GLX_DRAWABLE_TYPE); + attribs.push_back(GLX_WINDOW_BIT); + + attribs.push_back(GLX_DEPTH_SIZE); + attribs.push_back(1); + if(gl_options.alpha) { attribs.push_back(GLX_ALPHA_SIZE); attribs.push_back(1); } + + if(gl_options.stencil) + { + attribs.push_back(GLX_STENCIL_SIZE); + attribs.push_back(1); + } + if(gl_options.doublebuffer) + { attribs.push_back(GLX_DOUBLEBUFFER); + attribs.push_back(true); + } + if(gl_options.multisample>0) { attribs.push_back(GLX_SAMPLE_BUFFERS_ARB); attribs.push_back(gl_options.multisample); } - attribs.push_back(0); + + attribs.push_back(None); - XVisualInfo *visual=glXChooseVisual(display, DefaultScreen(display), &attribs.front()); - if(!visual) - throw Exception("Couldn't get a matching GLX visual"); + int count; + GLXFBConfig *config=glXChooseFBConfig(display, DefaultScreen(display), &attribs.front(), &count); + if(!config) + throw Exception("Couldn't get a GLX framebuffer configuration"); - context=glXCreateContext(display, visual, 0, true); + context=glXCreateNewContext(display, config[0], GLX_RGBA_TYPE, 0, true); if(!context) throw Exception("Couldn't create a GLX context"); - create(); + XVisualInfo *vi=glXGetVisualFromFBConfig(display, config[0]); + Handle root=RootWindow(display, vi->screen); + + Colormap cmap=XCreateColormap(display, root, vi->visual, AllocNone); + XSetWindowAttributes attr; + attr.colormap=cmap; + + Handle wnd=XCreateWindow(display, root, 0, 0, options.width, options.height, 0, vi->depth, InputOutput, vi->visual, CWColormap, &attr); + set_window(wnd); + + glx_wnd=glXCreateWindow(display, config[0], wnd, 0); + + glXMakeContextCurrent(display, glx_wnd, glx_wnd, context); - glXMakeCurrent(display, window, context); + XFree(config); } -void GLWindow::on_resize() +void GLWindow::on_event(const XEvent &event) { - glViewport(0, 0, options.width, options.height); + if(event.type==ConfigureNotify) + glViewport(0, 0, options.width, options.height); } } // namespace Msp diff --git a/source/glwindow.h b/source/glwindow.h index 3525439..dd6e59f 100644 --- a/source/glwindow.h +++ b/source/glwindow.h @@ -16,6 +16,7 @@ namespace Msp { struct GLDisplayOptions { bool alpha; + bool stencil; bool doublebuffer; unsigned multisample; @@ -28,6 +29,7 @@ protected: typedef GLXContext Context; GLDisplayOptions gl_options; + GLXWindow glx_wnd; Context context; public: @@ -38,7 +40,7 @@ public: void swap_buffers(); protected: void init(); - virtual void on_resize(); + virtual void on_event(const XEvent &event); }; } // namespace Msp diff --git a/source/window.cpp b/source/window.cpp index b977f6b..5395a00 100644 --- a/source/window.cpp +++ b/source/window.cpp @@ -90,14 +90,15 @@ void Window::prepare() wm_delete_window=XInternAtom(display, "WM_DELETE_WINDOW", true); + /* Throwing from the error handler doesn't work too well and I don't know + how to dig up all the information that Xlib gives by default, so disable + custom error handling for now. */ //XSetErrorHandler(x_error_handler); } -void Window::create() +void Window::set_window(Handle wnd) { - window=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0); - if(!window) - throw Exception("Couldn't create a window"); + window=wnd; XSelectInput(display, window, ButtonPressMask|ButtonReleaseMask|PointerMotionMask|KeyPressMask|KeyReleaseMask|StructureNotifyMask); @@ -107,7 +108,9 @@ void Window::create() void Window::init() { prepare(); - create(); + + Handle wnd=XCreateWindow(display, DefaultRootWindow(display), 0, 0, options.width, options.height, 0, CopyFromParent, InputOutput, CopyFromParent, 0, 0); + set_window(wnd); } void Window::process_event(const XEvent &event) @@ -137,7 +140,6 @@ void Window::process_event(const XEvent &event) case ConfigureNotify: options.width=event.xconfigure.width; options.height=event.xconfigure.height; - on_resize(); signal_resize.emit(options.width, options.height); break; case ClientMessage: @@ -146,6 +148,8 @@ void Window::process_event(const XEvent &event) break; default:; } + + on_event(event); } int Window::x_error_handler(Display *display, XErrorEvent *error) diff --git a/source/window.h b/source/window.h index 34efb7c..0f1dfba 100644 --- a/source/window.h +++ b/source/window.h @@ -45,8 +45,8 @@ protected: Window(); public: - Window(unsigned, unsigned); - Window(const DisplayOptions &); + Window(unsigned w, unsigned h); + Window(const DisplayOptions &dopt); virtual ~Window(); unsigned get_width() const { return options.width; } @@ -56,10 +56,10 @@ public: void tick(); protected: void prepare(); - void create(); + void set_window(Handle wnd); void init(); - void process_event(const XEvent &); - virtual void on_resize() { } + void process_event(const XEvent &event); + virtual void on_event(const XEvent &event) { (void)event; } static int x_error_handler(Display *, XErrorEvent *); };