bmx-ng / sdl.mod

SDL backend for BlitzMax
7 stars 6 forks source link

GL2SDLMax2D always uses VSync #19

Closed GWRon closed 5 years ago

GWRon commented 5 years ago

Taken from the sdl.mod-sample and enhanced to have a (simple) fps counter:

SuperStrict

Framework sdl.gl2sdlmax2d
SetGraphicsDriver GL2Max2DDriver()

rem
Framework Brl.StandardIO
Import brl.glmax2D
SetGraphicsDriver GLMax2DDriver()
endrem

Global _g:TGraphics = Graphics(800, 600, 0)

global timesRendered:int = 0
global secondGone:int
global loopBeginTime:int = 0
global lastLoopTime:int
global currentFPS:int = 0

While Not AppTerminate() And Not KeyDown(key_escape)
    loopBeginTime = Millisecs()
    secondGone :+ lastLooptime
    if secondGone > 1000
        currentFPS = timesRendered
        secondGone = 0
        timesRendered = 0
    endif

    Cls

    If KeyHit(KEY_SPACE) And _g
        Print "reset graphics"
        CloseGraphics(_g)
        _g = Graphics(800, 600, 0)
    EndIf

    DrawText "FPS:" + currentFPS, 20, 50
    DrawOval(MouseX()-10, MouseY()-10, 20,20)
    Flip 0
    timesRendered :+ 1

    lastLoopTime = Millisecs() - loopBeginTime
Wend

End

Regardless of what you put to Flip it always uses the hertz you use on the screen -> vsync. Using another graphics driver (see Rem ... End Rem) and you get the desired "not limited" fps (in my case its 13.000 but it does not matter).

GWRon commented 5 years ago

sdlgraphics.mod/sdlgraphics.bmx has this:

        If glFlags Then
            SDL_GL_SetSwapInterval(-1)

            context.context = context.window.GLCreateContext()
        End If

https://wiki.libsdl.org/SDL_GL_SetSwapInterval states that SDL_GL_SetSwapInterval adjusts the current context. Here it seems that the context get's created afterwards ?

-> switched lines (and set interval to 0 ...) and ... bamm, got 10.000 frames per second.

The "Flip" there does call the SDL_GL_SetSwapInterval too - but why isn't it working? There is a pretty simple answer: SDL's swapInterval uses "-1" for adaptive vsync, "1" for vsync and "0" for immediate. While BlitzMax' Flip is "0" for "as soon as possible", "1" for vsync and "-1" for immediate/as-fast-as-possible (exception if the graphics context wasn't created withthe Graphics command)

GWRon commented 5 years ago

Another tiny bug is there:

    Method Flip( sync:Int )
        'bbSDLGraphicsFlip sync
        If Not _currentContext Then
            Return
        End If

        If sync <> _currentContext.sync Then
            _currentContext.sync = sync
            If _currentContext.context Then
                _currentContext.context.SetSwapInterval(sync)
            End If
        End If

        If _currentContext.context Then
            _currentContext.window.GLSwap()
        End If
    End Method

That context.sync property is only filled in this method call. And only if it differs from the initial state. So if the initial state was 0 while the interval was defined as -1 during creation, it would not change to 0 if you called Flip(0) as the state seems to be unchanged.

-> either set the context.sync to the default one defined during creation -> or do additional checks during flip if something changed.

GWRon commented 5 years ago

Added a commit - I've choosen option 1 (context.sync-property set on creation). And I switched flag-set as it sets the current context's swap interval.

I also noted down what the incoming flip-sync values mean (just in case that it changes somewhen).