Haskell GTK,带原语的双缓冲
举一个这样的例子。如何使用gtk和haskell进行2d双缓冲。我想将基本体渲染到屏幕外缓冲区并翻转。此代码仅渲染像素/矩形。我想使用双缓冲方法添加运动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
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