glXSwapbuffers似乎没有交换(?)

时间:2013-08-29 16:34:46

标签: c opengl x11 double-buffering glx

我的情况是这样的。我编写了一个代码,检查了一组窗口,如果它们的内容有资格被交换(这是在重新调整大小事件后,所有重绘都在所述窗口及其所有子项上成功执行)。如果满足条件,我会对所述窗口及其所有子项执行glXSwapBuffers调用。我的目标是允许一个闪烁的自由调整系统。子窗口以平铺方式排列,并且不重叠。在它们之间,功能似乎起作用。然而,我的问题出现在父母身上。在重新调整大小的某个时候,其内容会闪烁。到目前为止,这是我实施的内容。

  1. 所有事件(如ConfigureNotify或Expose)都已根据需要进行了压缩。
  2. 窗口background_pixmap设置为None。
  3. 了解每当生成Expose事件时,窗口背景内容都将丢失。每次重绘完成后,我总是将完成的重绘副本保存在我自己分配的缓冲区中。 (既不是pixmap也不是fbo,但现在就足够了。)
  4. 每次调用glXSwapBuffers()的逻辑就是这个。

    void window_swap( Window *win ) {
        Window *child;
        if ( win ) {
            for ( child=win->child; child; child=child->next )
                window_swap( child );
    
            if ( isValidForSwap( win ) ) {
                glXMakeCurrent( dpy, win->drawable, win->ctx );
                glDrawBuffer( GL_BACK );
                RedrawWindowFromBuffer( win, win->backing_store );
                glXSwapBuffers( dpy, win->drawable );
            }
        }
    }
    

    哪个...应该服务,内容总是在调用swap之前恢复。可悲的是,在实施过程中并没有出现这种情况。从上面的代码中,我通过输出缓冲区中应该包含的内容来进行调试以进行调整。

    void window_swap( Window *win ) {
        if ( win ) {
            if ( isValidForSwap( win ) ) {
    
                glXMakeCurrent( dpy, win->drawable, win->ctx );
    
                glDrawBuffer( GL_BACK );
                OutputWindowBuffer( "back.jpg", GL_BACK );
                RedrawWindowFromBuffer( win, win->backing_store );
    
                glXSwapBuffers( dpy, win->drawable );
    
                glDrawBuffer( GL_BACK );
                glClearColor( 1.0, 1.0, 1.0, 1.0 );
                glClear( GL_COLOR_BUFFER_BIT );
    
                OutputWindowBuffer( "front_after.jpg", GL_FRONT );
                OutputWindowBuffer( "back_after.jpg", GL_BACK );
            }
        }
    }
    

    函数OutputWindowBuffer()使用标准glReadPixel()来读取缓冲区内容,然后将其作为图像输出。要读取的缓冲区由传递给函数的参数决定。我在输出图片中发现的是这个。

    1. RedrawWindowFromBuffer()之后的后台缓冲区的图片输出是预期的。
    2. 交换后的后缓冲区的图像输出填充了预期的清除颜色。因此,当调用Front缓冲区时,glReadPixel的执行可能不会落后,因为一些关于intel系统的漏洞似乎建议一次。
    3. 交换后前缓冲区的图片输出主要显示黑色瑕疵(我的窗口的颜色在每张图纸之前总是被清除为其他颜色)。
    4. 是否有其他合理的解释为什么交换缓冲区,似乎没有交换缓冲区?是否有其他路线我应该考虑实施无闪烁的重新调整大小?我读过一篇建议使用WinGravity的文章,但我恐怕还不太了解它。

1 个答案:

答案 0 :(得分:0)

如果您的窗口设置了背景像素图,那么在实际的OpenGL重绘开始之前,在每个调整大小的步骤中,它们都会被填充。这是闪烁的一个来源。另一个问题是glXSwapBuffers没有与垂直回扫同步。您可以使用glXSwapInterval设置它。

因此,无闪烁大小调整要做的两件事:设置一个nil背景像素图并启用glXSwapBuffers同步到垂直回扫(交换间隔1)。