]> git.tdb.fi Git - libs/gui.git/commitdiff
Convert GLWindow to use GLX 1.3
authorMikko Rasa <tdb@tdb.fi>
Mon, 27 Aug 2007 14:18:07 +0000 (14:18 +0000)
committerMikko Rasa <tdb@tdb.fi>
Mon, 27 Aug 2007 14:18:07 +0000 (14:18 +0000)
Restructure the code a bit

source/glwindow.cpp
source/glwindow.h
source/window.cpp
source/window.h

index 3ae559050a406dcdfe6aeddb43925d9fa612a050..6657ea623bbbadf8cb5864546602bab1db2d2c97 100644 (file)
@@ -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<int> 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
index 35254391de81390a0a0db5090175aaf5726a0885..dd6e59fd62105dd1667b73901d6e5c3bd4065f27 100644 (file)
@@ -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
index b977f6bc97ac89cbd7af1e81d02f125593f3de02..5395a00535c3aa2c4ee41797b0d71b6513aaacf1 100644 (file)
@@ -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)
index 34efb7ce888a04d399e918bbab778a8dbdc25663..0f1dfbaf8c18ca343fbe617c6808ddfc52f800f7 100644 (file)
@@ -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 *);
 };