Haskell GTK,带原语的双缓冲

Haskell GTK,带原语的双缓冲,haskell,gtk,gtk2hs,Haskell,Gtk,Gtk2hs,举一个这样的例子。如何使用gtk和haskell进行2d双缓冲。我想将基本体渲染到屏幕外缓冲区并翻转。此代码仅渲染像素/矩形。我想使用双缓冲方法添加运动 import Graphics.UI.Gtk import Graphics.UI.Gtk.Gdk.GC import Graphics.UI.Gtk hiding (Color, Point, Object) defaultFgColor :: Color defaultFgColor = Color 65535 65535 65535

举一个这样的例子。如何使用gtk和haskell进行2d双缓冲。我想将基本体渲染到屏幕外缓冲区并翻转。此代码仅渲染像素/矩形。我想使用双缓冲方法添加运动

import Graphics.UI.Gtk
import Graphics.UI.Gtk.Gdk.GC
import Graphics.UI.Gtk hiding (Color, Point, Object)

defaultFgColor :: Color
defaultFgColor = Color 65535 65535 65535

defaultBgColor :: Color
defaultBgColor = Color 0 0 0

renderScene d ev = do
    dw     <- widgetGetDrawWindow d
    (w, h) <- widgetGetSize d
    gc     <- gcNew dw
    let fg = Color  (round (65535 * 205))
                    (round (65535 * 0))
                    (round (65535 * 0))
    gcSetValues gc $ newGCValues { foreground = fg }
    drawPoint dw gc (120, 120)
    drawPoint dw gc (22, 22)
    drawRectangle dw gc True 20 20 20 20
    return True

main :: IO ()   
main = do
    initGUI
    window  <- windowNew
    drawing <- drawingAreaNew
    windowSetTitle window "Cells"
    containerAdd window drawing
    let bg = Color  (round (65535 * 205))
                    (round (65535 * 205))
                    (round (65535 * 255))
    widgetModifyBg drawing StateNormal bg
    onExpose drawing (renderScene drawing)

    onDestroy window mainQuit
    windowSetDefaultSize window 800 600
    windowSetPosition window WinPosCenter
    widgetShowAll window
    mainGUI
import Graphics.UI.Gtk
导入Graphics.UI.Gtk.Gdk.GC
导入Graphics.UI.Gtk隐藏(颜色、点、对象)
defaultFgColor::Color
defaultFgColor=Color 65535 65535 65535
defaultBgColor::Color
defaultBgColor=Color 0
renderScene d ev=do

dw这就是我在绘图区域中使用cairo进行绘制并避免 忽隐忽现。尝试将以下代码添加到renderScene函数:

  -- Get the draw window (dw) and its size (w,h)
  -- ...

  regio <- regionRectangle $ Rectangle 0 0 w h
  drawWindowBeginPaintRegion dw regio

  -- Put paiting code here
  -- ..

  drawWindowEndPaint dw
——获取绘图窗口(dw)及其大小(w,h)
-- ...
区域绘图区域->IO布尔
renderScene'pref d=do

dw不妨看看。滚动是在那里实现的,非常接近双缓冲。以下是我认为他们所做工作的简化版本:

prev_surface <- readIORef prevView
win <- widgetGetDrawWindow timelineDrawingArea
renderWithDrawable win $ do

  -- Create new surface based on the old one
  new_surface <- liftIO $ createSimilarSurface [...]
  renderWith new_surface $ do
    setSourceSurface prev_surface off 0
    Cairo.rectangle [...]
    Cairo.fill
    [... render newly exposed stuff ...]
  surfaceFinish new_surface

  -- Save back new view
  liftIO $ writeIORef prevView new_surface

  -- Paint new view
  setSourceSurface new_surface 0 0
  setOperator OperatorSource
  paint

prev_surface你能告诉我,什么东西不适合你吗?这段代码只渲染一个像素。我想用双缓冲的方法添加运动。看起来很有趣。你还有代码吗。我看不到交换。交换发生在drawWindowEndPaint上。根据文档,它“表示最近调用drawWindowBeginPaintRegion创建的备份存储应在屏幕上复制并删除”。我用您可以使用的代码修改了我的原始注释。它画了一个正方形绕着圈转,另一个就躺在那里。如果不使用paintRegions并清除背景(例如,绘制白色矩形),则会看到闪烁。这样,当您调用drawWindowEndPaint时,所有内容都已绘制。
prev_surface <- readIORef prevView
win <- widgetGetDrawWindow timelineDrawingArea
renderWithDrawable win $ do

  -- Create new surface based on the old one
  new_surface <- liftIO $ createSimilarSurface [...]
  renderWith new_surface $ do
    setSourceSurface prev_surface off 0
    Cairo.rectangle [...]
    Cairo.fill
    [... render newly exposed stuff ...]
  surfaceFinish new_surface

  -- Save back new view
  liftIO $ writeIORef prevView new_surface

  -- Paint new view
  setSourceSurface new_surface 0 0
  setOperator OperatorSource
  paint