2013-08-29 69 views
1

我的情況是這樣的。我編寫了一個代碼,用於檢查一組窗口的內容是否有資格進行交換(即在重新調整大小事件後,所有重新繪製都在所述窗口及其所有子窗口上成功執行)。如果條件滿足,我爲所述窗口及其所有子項執行glXSwapBuffers調用。我的目標是允許一個無閃爍的大小調整系統。孩子的窗戶以瓦片方式排列,並且不重疊。在他們之間,這個功能似乎起作用。然而,我的問題與父母一起出現。在重新調整尺寸的過程中,其內容會閃爍。到目前爲止,這是我實施的。glXSwapbuffers似乎沒有交換(?)

  1. 所有事件(如ConfigureNotify或Expose)都已根據需要進行了壓縮。
  2. 窗口background_pixmap被設置爲None。
  3. 瞭解只要生成Expose事件,窗口背景內容就會丟失。隨着每次重畫的完成,我始終將完成的重繪副本保留在我自己分配的緩衝區中。 (既不是pixmap也不是fbo,但現在就足夠了。)

我對每次調用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); 
     } 
    } 
} 

其中......應該服務的內容總是在調用交換之前恢復。可悲的是,在實施過程中並未出現這種情況。從上面的代碼中,我通過輸出緩衝區中應該包含的內容來進行調試。

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. 交換後的後臺緩衝區的圖片輸出按照預期填充了清除的顏色。因此,glReadPixel在被調用Front緩衝區時可能會滯後於它的執行,因爲一些發現的有關intel系統的bug似乎只是一次暗示。
  3. 交換後前端緩衝區的圖片輸出顯示大部分爲黑色僞像(每個圖形前我的窗口顏色總是被清除爲其他顏色)。

是否有其他合理的解釋爲什麼交換緩衝區,似乎不交換緩衝區?我還應該考慮其他路線來實現無閃爍重新調整大小嗎?我讀過一篇文章,建議使用WinGravity,但恐怕我還沒有完全理解它。

回答

0

如果你的windows有一個背景pixmap集,那麼在每次調整大小的步驟中,它們都會在實際的OpenGL重繪開始之前得到填充。這是閃爍的一個來源。另一個問題是glXSwapBuffers沒有被同步到垂直回掃。您可以使用glXSwapInterval進行設置。

因此,無閃爍調整大小的兩件事:設置一個無背景像素圖並啓用glXSwapBuffers同步到垂直回掃(交換間隔1)。

+0

背景pixmap已經設置爲None,所以我想我可以嘗試設置垂直回掃。有沒有辦法檢查它是否正在執行?有人說這取決於司機的決定。有人說設置opengl環境,然後,當然,還有glXSwapInterval。我曾經檢查過我的NVDia設置以允許垂直回掃,但我不確定它是否真正起作用,因爲窗口仍然閃爍。 – null

+0

@ S.Aymerich:被告知的真相我認爲你是嚴重過分複雜的事情。保持簡單和簡潔:一旦完成繪製到窗口,只需調用glXSwapBuffers。無論如何你都應該重畫,不要擔心表演。 – datenwolf

+0

就是這樣,@datenwolf。令人遺憾的事實是,當執行任何重新調整大小事件(在其兄弟姐妹或其父母上)時,顯示的子窗口會受到很大影響。 – null