how to animate picture without making it flicker using wxWidgets in erlang?

萝らか妹 提交于 2019-12-09 04:34:30

I have solved this in both windows and linux doing the following:

in the init function: create a bitmap of the expected size, and a memoryDC form it:

Bitmap = wxBitmap:new(W,H),
MemoryDC = wxMemoryDC:new(Bitmap),
...

I also define an area where to put the bitmap and I connect it to some event, at least paint:

Panel = wxPanel:new(Board, [{size,{W,H}}]),
wxPanel:connect(Panel, paint, [callback]),
wxPanel:connect(Panel, left_up, []),
wxPanel:connect(Panel, right_down, []),
wxPanel:connect(Panel, middle_down, []),

I use to store the modification request in a list which will be processed later.

then I use an external event to refresh the screen, that trigger window refresh The option {eraseBackground,false} is very important to avoid flickering:

do_refresh(Cb,Z,PMa,PFe,PM,BMa,BFe,BM,P,MemoryDC) ->
    wx:batch(fun ()  ->
        Cb1 = lists:reverse(Cb),
        [cell(MemoryDC,PMa,PFe,PM,BMa,BFe,BM,State,Cell,Sex,Z) || {State,Cell,Sex} <- Cb1],
        wxWindow:refresh(P,[{eraseBackground,false}])
    end).

I use this external event for 2 reasons:

  • have a regular refresh rate that I master
  • allow many processes to update independently the bitmap (storing the request in the list)

I use an external timer which call a refresh function which collect the list of modification asked by other processes, execute them in order in the memoryDC, and then trigs the paint event using the window:refresh/2 function. The whole function is executed in a batch to improve performances.

And in the redraw event I simply "blit" the panel (note that this function can refresh a part of the panel to reduce the execution time, I didn't use this optimization at first, and the result was fast and smooth enough so I kept my initial code) :

handle_sync_event(#wx{event = #wxPaint{}}, _wxObj, #state{panel=Panel, memoryDC=MDC, w=W, h=H}) ->
    redraw(Panel,MDC,W,H).

redraw(Panel, MemoryDC, W, H) ->
    DC = wxPaintDC:new(Panel),  
    wxDC:blit(DC,{0,0},{W,H},MemoryDC,{0,0}),
    wxPaintDC:destroy(DC).

It seems to be required to create and destroy the PaintDC.

This code do not manage the resize of the window (no sense in my application), but it should be easy to extend.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!