Distortion when moving across the screen sprite (Raspberry 4B))

New to FreeBASIC? Post your questions here.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

Does this mean that it is impossible to make code workable using sprites in Linux? Can you use some kind of "crutch"?

Code: Select all

Screenres 800,600,32,2
Screenset 1.0
Dim As Integer i, frames, fps
Dim As Double t
Dim As Uinteger Ptr Background
Background = Imagecreate (800,600, RGBA (64,128, 250, 255))

Dim As Uinteger xspr = 32, yspr = 250 'coordinates of the initial location of the sprite
Dim As Uinteger xspr2 = 64, yspr2 = 100
Dim As Uinteger Ptr MyImage 'Created a pointer to sprite1
Dim As Uinteger Ptr MyImage2 'Created a pointer to sprite2
MyImage = Imagecreate (64,64, RGBA (255, 0, 255, 0)) 'passed to the pointer the address of the created buffer, the buffer is filled with pink
Circle MyImage, (31, 31), 30, RGB (255, 255, 0),,, 1, f 'placed a yellow circle in the buffer

MyImage2 = Imagecreate (64,128, RGBA (255, 0, 255, 0))
Line MyImage2, (0, 0) -Step (63, 127), RGB (200, 255, 0), BF 'draw a light green rectangle

  Do

        Put (0,0), Background, Pset
        Put (xspr, yspr), MyImage, Trans
        xspr = xspr + 3: If (xspr> 735) Then xspr = 0
        Put (xspr2, yspr2), MyImage2, Trans
         xspr2 = xspr2 + 3: If (xspr2> 671) Then xspr2 = 0
        Put (400,450), MyImage2, Pset 'we can place still pictures on the screen
        Put (25,450), MyImage, Trans
        
        Locate 1,85
        Print "fps:" & fps,

    If Int (t) <> Int (Timer) Then
        t = Timer
        fps = frames
        frames = 0
    End If
        frames + = 1
         
       ScreenSync 'Waiting for vertical sync
       Flip 'switch the page
  Loop While Inkey = "" 'exit the loop when any key is pressed

While Inkey <> "": Wend 'Flush the Inkey buffer
Imagedestroy (MyImage) 'deleted the buffer we created
Imagedestroy (MyImage2)
Imagedestroy (Background)
sleep
end
Last edited by PavelUT on Jun 15, 2021 17:33, edited 1 time in total.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

SARG wrote:
PavelUT wrote:[img]I can not insert a picture
[/img]
You have to upload the image somewhere and then put the link between the tags.
Thank you
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by caseih »

PavelUT wrote:Does this mean that it is impossible to make code workable using sprites in Linux? Can you use some kind of "crutch"?
Any library that uses OpenGL to do the compositing to the screen can be pretty smooth. Sprites in SDL work fine. Using FB's graphics library to animate something will always run into this issue with X11 on Linux. Maybe decreasing your redraw rate might hide the issue somewhat. Someday if there's a Wayland version of the FB graphics library, then it will not have this issue.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

caseih wrote:
PavelUT wrote: Someday if there's a Wayland version of the FB graphics library, then it will not have this issue.
Are there really no programmers on the forum who can officially connect Wayland support?
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by caseih »

FreeBASIC is maintained by a very small group of maybe two core volunteer developers. If someone wanted to step up and do it, I'm sure they'd be willing to review such a graphics driver. I note that the documentation says there is an OpenGL backend to the FB graphics library. Perhaps someone more knowledgeable than I can comment on how to use this. If it's as easy as setting a flag (which I tried and failed to do), then it might solve your problem. Perhaps @angros47 can comment. A few years ago he talked about using the FB graphics library on top of OpenGL. Not sure if that was integrated into the official FB tree or if it was just an experimental port only.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

caseih wrote:FreeBASIC is maintained by a very small group of maybe two core volunteer developers. If someone wanted to step up and do it, I'm sure they'd be willing to review such a graphics driver. I note that the documentation says there is an OpenGL backend to the FB graphics library. Perhaps someone more knowledgeable than I can comment on how to use this. If it's as easy as setting a flag (which I tried and failed to do), then it might solve your problem. Perhaps @angros47 can comment. A few years ago he talked about using the FB graphics library on top of OpenGL. Not sure if that was integrated into the official FB tree or if it was just an experimental port only.
Yes, I understand this and really appreciate the enthusiasm of the volunteers supporting the project. But there may still be a volunteer who can use the graphics mode bypassing the X11 driver. It seems to me that without this feature FreeBasic will be imperfect.

Here is my suggestion. Perhaps the X11 driver sends some kind of "now update the screen" signal before updating the screen. If you intercept this signal, then it is possible to synchronize the screen update with ScreenSync (the programmer will prohibit updating until the end of the back buffer drawing.)
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by Imortis »

caseih wrote:He's seeing tearing, which is quite common on X11 on Linux. The top part of the rectangle appears sheared off (offset slightly) from the bottom part of the rectangle, and kind of flickers. The rectangle is being redrawn by FB while X11 is displaying it. This happens because X11 lacks a vertical sync signal. Also X11 is asynchronous, meaning you ask it do draw something and it returns immediately, and draws whenever it can. This was good for the low-powered graphics systems of ancient days, but does not work well for modern video and animation requirements. TThere's really no solution for X11, other than using OpenGL as a backend, which is what libraries like SDL can do. As much as I love X11and its flexibility and ability to operate over a network, there are some significant drawbacks to X11, and this is one of them. Wayland, by contrast, focuses on making everything silky smooth and completely synchronized with the refresh rate of the screen.
PavelUT wrote:Yes, I understand this and really appreciate the enthusiasm of the volunteers supporting the project. But there may still be a volunteer who can use the graphics mode bypassing the X11 driver. It seems to me that without this feature FreeBasic will be imperfect.

Here is my suggestion. Perhaps the X11 driver sends some kind of "now update the screen" signal before updating the screen. If you intercept this signal, then it is possible to synchronize the screen update with ScreenSync (the programmer will prohibit updating until the end of the back buffer drawing.)
That signal you speak of is what a vertical sync signal is. That is exactly what the issue here is. X11 does not seem to have any such signal to hook into.

There is a flag you can use to enable the OpenGL backend. Since you are already calling flip in your code, it should work just fine. I will find the the post for you with info on enabling the backend.
Imortis
Moderator
Posts: 1924
Joined: Jun 02, 2005 15:10
Location: USA
Contact:

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by Imortis »

At the top of your code add:

Code: Select all

#include once "fbgfx.bi"
Using FB
After your screenset command add this:

Code: Select all

Screencontrol SET_GL_2D_MODE, OGL_2D_MANUAL_SYNC
You could also use:

Code: Select all

Screencontrol SET_GL_2D_MODE, OGL_2D_AUTO_SYNC
Which does not require the Flip command to be in place.
dodicat
Posts: 7983
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by dodicat »

Opengl jumps also, I think because you step by 3.

Code: Select all

ScreenRes 800, 600, 32,,2

#include "GL/gl.bi"

Sub setupgl
Dim As Integer xres,yres
Screeninfo xres,yres
glDisable (GL_DEPTH_TEST)
glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA)
glEnable (GL_BLEND)
glEnable (GL_LINE_SMOOTH)
glOrtho 0, xres, yres, 0,-1, 1
glClearColor 0,0,200/255,1
End Sub

setupgl

Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function


sub drawquad(x as integer)
       glBegin(GL_QUADS)
    glcolor3ub 255,255,0
    glVertex2f( x, 80)            'Top right of the quad 
    glVertex2f(x-63, 80)          'Top left of the quad 
    glVertex2f(x-63, 127+80)      ' Bottom left of the quad
    glVertex2f( x, 127+80)        ' Bottom right of the quad 
    glend
      end sub


Dim As Integer x = 0
dim as long fps
   ' Color RGB(255, 128, 0), RGB(0, 0, 200)
    'Cls
Do
        glClear(GL_COLOR_BUFFER_BIT)
        drawquad(x)
    'Cls
   ' Line (x, 80)-Step(63, 127), RGB(255, 255, 0), BF
    x += 3: If (x > 639) Then x = 0
     Flip
     sleep regulate(60,fps)
Loop While Inkey = ""


end
 
I can improve it on windows, step by 1 and triple the framerate
In Linux try without settimer and freetimer maybe.

Code: Select all

SetEnviron("fbgfx=direct2d")
ScreenRes 800, 600, 32,2
Screenset  1,0


declare function settimer       alias "timeBeginPeriod"(as Ulong=1) as long
declare function freetimer      alias "timeEndPeriod"  (as Ulong=1) as long

dim as long refreshrate
dim as string driver
screeninfo ,,,,,refreshrate,driver



Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function

Dim As Integer x = 0
dim as long fps
    Color RGB(255, 128, 0), RGB(0, 0, 200)
    Cls
Do
    Cls
    locate 1
    print driver
    Line (x, 80)-Step(63, 127), RGB(255, 255, 0), BF
    x += 1: If (x > 639) Then x = 0
     Flip
     settimer
     sleep regulate(refreshrate*3,fps)
     freetimer
Loop While Inkey = ""

sleep
end 
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by caseih »

PavelUT wrote:Here is my suggestion. Perhaps the X11 driver sends some kind of "now update the screen" signal before updating the screen. If you intercept this signal, then it is possible to synchronize the screen update with ScreenSync (the programmer will prohibit updating until the end of the back buffer drawing.)
That's not the way X11 works. X11 is completely asynchronous. This worked well historically, but falls down with modern requirements for perfect frame drawing. The only way to get that is to bypass X11, which is what OpenGL does. I noticed when I ran your demo from a windows exe using wine, the animation had no tearing. This is because Wine implements DirectX with OpenGL, so FB drawing using DirectX ends up being smooth even on Linux under X11.

I'm reading the rest of the comments with interest.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

dodicat wrote:Opengl jumps also, I think because you step by 3.

Code: Select all


I can improve it on windows, step by 1 and triple the framerate
In Linux try without settimer and freetimer maybe.
[code]
SetEnviron("fbgfx=direct2d")
ScreenRes 800, 600, 32,2
Screenset  1,0


declare function settimer       alias "timeBeginPeriod"(as Ulong=1) as long
declare function freetimer      alias "timeEndPeriod"  (as Ulong=1) as long

dim as long refreshrate
dim as string driver
screeninfo ,,,,,refreshrate,driver



Function Regulate(Byval MyFps As long,Byref fps As long) As long
    Static As Double timervalue,lastsleeptime,t3,frames
    frames+=1
    If (Timer-t3)>=1 Then t3=Timer:fps=frames:frames=0
    Var sleeptime=lastsleeptime+((1/myfps)-Timer+timervalue)*1000
    If sleeptime<1 Then sleeptime=1
    lastsleeptime=sleeptime
    timervalue=Timer
    Return sleeptime
End Function

Dim As Integer x = 0
dim as long fps
    Color RGB(255, 128, 0), RGB(0, 0, 200)
    Cls
Do
    Cls
    locate 1
    print driver
    Line (x, 80)-Step(63, 127), RGB(255, 255, 0), BF
    x += 1: If (x > 639) Then x = 0
     Flip
     settimer
     sleep regulate(refreshrate*3,fps)
     freetimer
Loop While Inkey = ""

sleep
end 
I have to ask you. You are good with OpenGl. Above, I gave the code of my program with the output of 4 sprites. I have a request for you, rewrite it for me on OpenGl. Will be a model for me. I will be very grateful.
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

dodicat wrote:
I can improve it on windows, step by 1 and triple the framerate
In Linux try without settimer and freetimer maybe.
It seems strange to me. In this case, "high speed" is redrawing 3 pixels to the right. "Slow speed" redraw 1 pixel to the right. And the slower speed really does cause less distortion. WHY? What difference does it make to the video driver, after all, the same picture is being redrawn?
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

caseih wrote:
PavelUT wrote:Here is my suggestion. Perhaps the X11 driver sends some kind of "now update the screen" signal before updating the screen. If you intercept this signal, then it is possible to synchronize the screen update with ScreenSync (the programmer will prohibit updating until the end of the back buffer drawing.)
That's not the way X11 works. X11 is completely asynchronous. This worked well historically, but falls down with modern requirements for perfect frame drawing. The only way to get that is to bypass X11, which is what OpenGL does. I noticed when I ran your demo from a windows exe using wine, the animation had no tearing. This is because Wine implements DirectX with OpenGL, so FB drawing using DirectX ends up being smooth even on Linux under X11.

I'm reading the rest of the comments with interest.
I have posted 2 programs. Have you checked 1 or 2?
PavelUT
Posts: 78
Joined: Jun 14, 2021 14:42

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by PavelUT »

Imortis wrote:At the top of your code add:

Code: Select all

#include once "fbgfx.bi"
Using FB
After your screenset command add this:

Code: Select all

Screencontrol SET_GL_2D_MODE, OGL_2D_MANUAL_SYNC
You could also use:

Code: Select all

Screencontrol SET_GL_2D_MODE, OGL_2D_AUTO_SYNC
Which does not require the Flip command to be in place.
#include once "fbgfx.bi"
Using FB
Screencontrol SET_GL_2D_MODE, OGL_2D_MANUAL_SYNC
Screencontrol SET_GL_2D_MODE, OGL_2D_AUTO_SY
Unfortunately, the gadgets did not help.
Flip switches buffers, which should theoretically cut should reduce distortion
caseih
Posts: 2157
Joined: Feb 26, 2007 5:32

Re: Distortion when moving across the screen sprite (Raspberry 4B))

Post by caseih »

PavelUT wrote:Flip switches buffers, which should theoretically cut should reduce distortion
It won't unless it's timed to happen just before the vertical refresh begins.
Post Reply