News:

Masm32 SDK description, downloads and other helpful links
Message to All Guests
NB: Posting URL's See here: Posted URL Change

Main Menu

vertical retrace in GDI

Started by avcaballero, April 02, 2013, 03:20:15 AM

Previous topic - Next topic

avcaballero

Hello there! Does anyone know if is there any way for vertical retrace waiting in GDI?

Tedd

I don't think so. DirectX does allow you to, though.

If it's avoid flicker: draw onto a memory-DC and then BitBlt once you've finished all drawing; also make sure repaint isn't erasing the window contents (only redraw what changes, and nothing more.)
Potato2

Siekmanski

If your goal is smooth animation then you can use QueryPerformanceCounter.
Just calculate the time between screen updates and use that time to multiply with your routine update speed.

Here is an example:

Call InitTimer once at the start of your program.
Call Update_frame for every screen update.


.const
QPinteger struct
    Low32bit    dd ?
    High32bit   dd ?
QPinteger ends

.data?
align8
FrameTimeOld    QPinteger <?>
FrameTimeNew    QPinteger <?>
TicksPerSecond  QPinteger <?>

TicksPerSecondReciprocal real4 ?
FrameTimeDelta           real4 ?
RoutineTimer             real4 ? ; our calculated screen update time

.data
float1          dd    3F800000h ; == 1.0f
RoutineSpeed    real4 0.1f      ; your routine update speed

.code

InitTimer proc
    invoke   QueryPerformanceCounter,addr FrameTimeOld
    invoke   QueryPerformanceFrequency,addr TicksPerSecond
    movss    xmm0,float1
    cvtsi2ss xmm1,TicksPerSecond.Low32bit
    divss    xmm0,xmm1
    movss    TicksPerSecondReciprocal,xmm0
    ret
InitTimer endp


Update_frame proc
    invoke   QueryPerformanceCounter,addr FrameTimeNew
    mov      eax,FrameTimeNew.Low32bit
    mov      ecx,eax
    sub      eax, FrameTimeOld.Low32bit
    mov      FrameTimeOld.Low32bit,ecx
    cvtsi2ss xmm0,eax
    mulss    xmm0,TicksPerSecondReciprocal
    movss    FrameTimeDelta,xmm0 ; FramesPerSecond == 1 / FrameTimeDelta

    mulss    xmm0,RoutineSpeed
    movss    RoutineTimer,xmm0
    ret
Update_frame endp



Just an example where I use this piece of timer code:

(press F1 to toggle fullscreen)
Creative coders use backward thinking techniques as a strategy.

avcaballero

* PlasmaWF02.asm. The original. Of course, it has double buffering, and I don't allow the system redraw the window in every refreshing:
[...]
mov       [wc.hbrBackground], 0
[...]
invoke    InvalidateRect, [hWnd], NULL, NULL
[...]

Nevertheless it produces flickering, especially noticeable when I run it on W7 ... now, on WXP they don't seem very different from each other... I will probe them later in W7...

* PlasmaWF02c.asm. In WM_TIMER, before update I do "sleep 10" in the hope that the system don't go faster than the program....

* PlasmaWF02d.asm. I follow Siekmanski tip (thank you for that)

Thank you

jj2007

Can't see any difference on Win7-32...

@Siekmanski: Is the granularity of QPC sufficient to achieve an effect?

Siekmanski

Quote@Siekmanski: Is the granularity of QPC sufficient to achieve an effect?

If you mean that I only use the low 32 bit returned from QueryPerformanceCounter then yes.
Its sufficient to do smooth animations.

( sorry if I misunderstood, English is not my native language  :biggrin:)
Creative coders use backward thinking techniques as a strategy.