• Dear Cerberus X User!

    As we prepare to transition the forum ownership from Mike to Phil (TripleHead GmbH), we need your explicit consent to transfer your user data in accordance with our amended Terms and Rules in order to be compliant with data protection laws.

    Important: If you accept the amended Terms and Rules, you agree to the transfer of your user data to the future forum owner!

    Please read the new Terms and Rules below, check the box to agree, and click "Accept" to continue enjoying your Cerberus X Forum experience. The deadline for consent is April 5, 2024.

    Do not accept the amended Terms and Rules if you do not wish your personal data to be transferred to the future forum owner!

    Accepting ensures:

    - Continued access to your account with a short break for the actual transfer.

    - Retention of your data under the same terms.

    Without consent:

    - You don't have further access to your forum user account.

    - Your account and personal data will be deleted after April 5, 2024.

    - Public posts remain, but usernames indicating real identity will be anonymized. If you disagree with a fictitious name you have the option to contact us so we can find a name that is acceptable to you.

    We hope to keep you in our community and see you on the forum soon!

    All the best

    Your Cerberus X Team

Supersampling but not really

Wingnut

Well-known member
3rd Party Module Dev
Tutorial Author
Joined
Jan 2, 2020
Messages
1,414
I'm trying to change the Tileimage.cxs example to make it possible to do smooth superslow non-integer movements movements without all the normal supersampling stuff like downsampling an enormous image and downsample it down to the screen.

Instead you draw the graphics once to integer coordinates and then to floating coordinates, and it doesn't matter how slow you scroll.
I successfully converted Tileimage.cxs into mojo2 but I'm kinda stuck now.

Included a complete BMX code that shows the technique. The first part of the code creates two tiles of size 66x66 instead of 64x64, as you need padding for this technique.

SetGraphicsDriver GLMax2DDriver() ; Graphics 640,480,0
Local pic:TImage[2] ; pic[0]=CreateImage(66,66,1,FILTEREDIMAGE|DYNAMICIMAGE) ; pic[1]=CreateImage(66,66,1,FILTEREDIMAGE|DYNAMICIMAGE)
Local border:Int=1, width:Int=ImageWidth(pic[0]), height:Int=ImageHeight(pic[0]), x:Int, y:Int, red:Int, green:Int, blue:Int
Local p:TPixmap=LockImage(pic[0],0,True,True)

For y=0 To 65
For x=0 To 65
red=x ; green=y ; blue=x+y
If x=0 Or x=65 Or y=0 Or y=65 Then WritePixel(p,x,y,(red Shl 16) | (green Shl 8) | blue) Else WritePixel(p,x,y,$FF000000 | (red Shl 16) | (green Shl 8) | blue)
Next
Next
UnlockImage(pic[0],0)

p=LockImage(pic[1],0,True,True)
For y=0 To 65
For x=0 To 65
red=255-y ; green=255-(x+y) ; blue=255-x
If x=0 Or x=65 Or y=0 Or y=65 Then WritePixel(p,x,y,(red Shl 16) | (green Shl 8) | blue) Else WritePixel(p,x,y,$FF000000 | (red Shl 16) | (green Shl 8) | blue)
Next
Next
UnlockImage(pic[1],0)

Local id:Int, scrollx:Float=0, scrollspeedx:Float=0.05, scrolly:Float=0, scrollspeedy:Float=0.05

Repeat
Cls

' Draw To Int coords
SetBlend SOLIDBLEND
id=0
Y=-height-height+border*2
While Y<480
X=-width-width+border*2
While X<640
DrawImage pic[id],Int(scrollx+x)+2,Int(scrolly+y)+2
id=(id+1) Mod 2
X:+width-border*2
Wend
Y:+height-border*2
Wend

' Draw to float coords
SetBlend ALPHABLEND
id=0
Y=-height-height+border*2
While Y<480
X=-width-width+border*2
While X<640
DrawImage pic[id],scrollx+x,scrolly+y
id=(id+1) Mod 2
X:+width-border*2
Wend
Y:+height-border*2
Wend

scrollx:+scrollspeedx
scrolly:+scrollspeedy
If scrollx>=width*2-border*4 Then scrollx:-(width*2-border*4)
If scrolly>=height*2-border*4 Then scrolly:-(height*2-border*4)

Flip

Until KeyHit(KEY_ESCAPE) Or AppTerminate()[

Code:
Import mojo2

Function Main()
    New TileImage
End Function

Class TileImage Extends App

Field canvas:Canvas
Field img:Image
Field ix#,iy#
Field scale_width#=1.0,scale_hieght#=1.0

    Method OnCreate()
        SetSwapInterval 1
        SetUpdateRate 0
        img = Image.Load("bg.png",0,0,0)
        canvas=New Canvas
        canvas.SetFont Null
    End Method
   
    Method OnUpdate()
        If KeyDown (KEY_LEFT)
            scale_width = scale_width - 0.1
            If scale_width < 1.0 Then scale_width = 1.0
        Endif
        If KeyDown (KEY_RIGHT)
            scale_width = scale_width + 0.1
        Endif
        If KeyDown (KEY_DOWN)
            scale_hieght = scale_hieght - 0.1
            If scale_hieght < 1.0 Then scale_hieght = 1.0
        Endif
        If KeyDown (KEY_UP)
            scale_hieght = scale_hieght + 0.1
        Endif
    End Method
   
    Method OnRender()
        Local ih=128,iw=128
        Local scale_x#=.99, scale_y#=.99 ' Some browsers like FireFox need a .01 offset to display right
        canvas.Clear
        canvas.PushMatrix
        canvas.Translate DeviceWidth * 0.5, DeviceHeight * 0.5
        canvas.Scale scale_width,scale_hieght
        canvas.Translate -DeviceWidth * 0.5, -DeviceHeight * 0.5
        ix = ix + 1.5
        iy = iy +1
        Tile_Image(img,ix,iy,ih,iw,scale_x,scale_y)
        canvas.PopMatrix
        canvas.PushMatrix
        canvas.Translate 0,0
        canvas.Scale 1,1
        canvas.SetBlendMode BlendMode.Alpha
        canvas.DrawText "Use Arrow Keys to adjust scale.",10,10
        canvas.PopMatrix
        canvas.Flush
    End Method

Method Tile_Image(img:Image,x#,y#,ih,iw,scalex#,scaley#)
    Local w#=iw * scalex
    Local h#=ih * scaley
    Local scissor:Float[]
   
    ' scissor = canvas.GetScissor() ' GetScissor does not exist in mojo2
    scissor[0] = 0
    scissor[1] = 0
    scissor[2] = 1440
    scissor[3] = 900
   
    Local viewport_x = scissor[0]
    Local viewport_y = scissor[1]
    Local viewport_w = scissor[2]
    Local viewport_h = scissor[3]
    Local ox#=viewport_x-w+1
    Local oy#=viewport_y-h+1
    Local px#=x
    Local py#=y
    Local fx#=px-Floor(px)
    Local fy#=py-Floor(py)
    Local tx#=Floor(px)-ox
    Local ty#=Floor(py)-oy
    If tx>=0 tx=tx Mod w + ox Else tx = w - -tx Mod w + ox
    If ty>=0 ty=ty Mod h + oy Else ty = h - -ty Mod h + oy
    Local vr#= viewport_x + viewport_w, vb# = viewport_y + viewport_h
    Local iy#=ty
    While iy<(vb + h)
        Local ix#=tx
        While ix<(vr + w)
            canvas.DrawImage img,ix+fx,iy+fy
            ix=ix+w
        Wend
        iy=iy+h
    Wend
End Method

End Class
 

Attachments

  • bg.png
    bg.png
    27.8 KB · Views: 95
As there is no question asked here, i don't unterstand the problem. Maybe someone else does.
 
How to implement this code in Cerberus?
 
I forgot to include the Mojo2 conversion code. This is the problem, It outputs nothing.
The original BMX is in the spoiler.

Cerberus:
Import mojo2
Import brl.databuffer

Function Main()
    New TileImage
End Function

Class TileImage Extends App

Field canvas:Canvas
Field pic:Image[2]
Field piccanvas:Canvas[2]
Field p:DataBuffer = New DataBuffer(66*66*4)
Field x:Int, y:Int, red:Int, green:Int, blue:Int
Field border:Int=1
Field id:Int
Field scrollx:Float=0
Field scrollspeedx:Float=0.05
Field scrolly:Float=0
Field scrollspeedy:Float=0.05
Field width:Int=66
Field height:Int=66

    Method OnCreate()

        SetSwapInterval 1
        SetUpdateRate 0
        canvas=New Canvas
        
        ' Create two 66 x 66 tiles. They are basically ordinary 64x64 tiles
        ' Each one has a 1-pixel border round them using alpha = 0
        ' ----------------------------------------------------
        pic[0] = New Image(66,66,0,0,0)
        pic[1] = New Image(66,66,0,0,0)       
        piccanvas[0] = New Canvas(pic[0])
        piccanvas[0].Clear
        piccanvas[0].Flush
        piccanvas[1] = New Canvas(pic[1])
        piccanvas[1].Clear
        piccanvas[1].Flush
        
        For y=0 To 65
            For x=0 To 65
                red=x ; green=y ; blue=x+y
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[0].WritePixels 0,0,66,66,p ' Local p:TPixmap = LockImage(pic[0],0,True,True)
        
        For y=0 To 65
            For x=0 To 65
                red=255-y ; green=255-(x+y) ; blue=255-x
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[1].WritePixels 0,0,66,66,p ' Local p:TPixmap = LockImage(pic[0],0,True,True)
        ' ----------------------------------------------------
            
    End Method
    
    Method OnRender()
    
        canvas.Clear
            
        ' Draw To Int coords. This may use alphablend or solidblend.
        id = 0
        y = y - (height-height+border*2)
        While y < 480
            x = x - (width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],Int(scrollx+x)+2,Int(scrolly+y)+2
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        ' Draw to float coords. This must use alphablend.
        id = 0
        y = y - (height-height+border*2)
        While y < 480
            x = x - (width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],scrollx+x,scrolly+y
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        scrollx = scrollx + scrollspeedx
        scrolly = scrolly + scrollspeedy
        If scrollx >= width*2 - border*4 Then scrollx=scrollx - (width*2-border*4)
        If scrolly >= height*2 - border*4 Then scrolly=scrolly - (height*2-border*4)

        canvas.Flush
        
    End Method

End Class
 
Got it almost working now. But it's not doing what it should, I probably uses no-aa flags and the generated colors might be in the wrong order.

Cerberus:
Import mojo2
Import brl.databuffer

Function Main()
    New TileImage
End Function

Class TileImage Extends App

Field canvas:Canvas
Field pic:Image[2]
Field piccanvas:Canvas[2]
Field p:DataBuffer = New DataBuffer(66*66*4)
Field x:Int, y:Int, red:Int, green:Int, blue:Int
Field border:Int=1
Field id:Int
Field scrollx:Float=0
Field scrollspeedx:Float=0.05
Field scrolly:Float=0
Field scrollspeedy:Float=0.05
Field width:Int=66
Field height:Int=66

    Method OnCreate()

        SetSwapInterval 1
        SetUpdateRate 0
        canvas=New Canvas
        
        ' Create two 66 x 66 tiles. They are basically ordinary 64x64 tiles
        ' Each one has a 1-pixel border round them using alpha = 0
        ' ----------------------------------------------------
        pic[0] = New Image(66,66,0,0,0)
        pic[1] = New Image(66,66,0,0,0)       
        piccanvas[0] = New Canvas(pic[0])
        piccanvas[0].Clear
        piccanvas[0].Flush
        piccanvas[1] = New Canvas(pic[1])
        piccanvas[1].Clear
        piccanvas[1].Flush
        
        ' RGBA are wrong
        ' logic in main loop
        
        For y=0 To 65
            For x=0 To 65
                red=x ; green=y ; blue=x+y
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[0].WritePixels 0,0,66,66,p ' Local p:TPixmap = LockImage(pic[0],0,True,True)
        
        For y=0 To 65
            For x=0 To 65
                red=255-y ; green=255-(x+y) ; blue=255-x
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[1].WritePixels 0,0,66,66,p
        ' ----------------------------------------------------
            
    End Method
    
    Method OnRender()
    
        canvas.Clear
        canvas.DrawImage pic[0],0,0
            
        ' Draw To Int coords. This may use alphablend or solidblend.
        id = 0
        y = -(height-height+border*2)
        While y < 480
            x = -(width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],Int(scrollx+x)+2,Int(scrolly+y)+2
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        ' Draw to float coords. This must use alphablend.
        id = 0
        y = -(height-height+border*2)
        While y < 480
            x = -(width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],scrollx+x,scrolly+y
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        scrollx = scrollx + scrollspeedx
        scrolly = scrolly + scrollspeedy
        If scrollx >= width*2 - border*4 Then scrollx=scrollx - (width*2-border*4)
        If scrolly >= height*2 - border*4 Then scrolly=scrolly - (height*2-border*4)

        canvas.Flush
        
    End Method

End Class
 
Getting there..

Cerberus:
Import mojo2
Import brl.databuffer

Function Main()
    New TileImage
End Function

Class TileImage Extends App

Field canvas:Canvas
Field pic:Image[2]
Field p:DataBuffer = New DataBuffer(66*66*4)
Field x:Int, y:Int, red:Int, green:Int, blue:Int
Field border:Int=1
Field id:Int
Field scrollx:Float=0
Field scrollspeedx:Float=0.05
Field scrolly:Float=0
Field scrollspeedy:Float=0.05
Field width:Int=66
Field height:Int=66

    Method OnCreate()

        SetSwapInterval 1
        SetUpdateRate 0
        canvas=New Canvas
        
        ' Create two 66 x 66 tiles. They are basically ordinary 64x64 tiles 
        ' Each one has a 1-pixel border round them using alpha = 0
        ' ----------------------------------------------------
        pic[0] = New Image(66,66,.5,.5,Image.Filter + Image.Mipmap) ' correct x,y handle & AA flags?
        pic[1] = New Image(66,66,.5,.5,Image.Filter + Image.Mipmap) ' correct rgba below?
                
        For y=0 To 65
            For x=0 To 65
                red=x ; green=y ; blue=x+y
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[0].WritePixels 0,0,66,66,p
        
        For y=0 To 65
            For x=0 To 65
                red=255-y ; green=255-(x+y) ; blue=255-x
                If x=0 Or x=65 Or y=0 Or y=65 Then p.PokeInt((0+x+y*66)*4,(red Shl 16) | (green Shl 8) | blue) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (red Shl 16) | (green Shl 8) | blue)
            Next
        Next
        pic[1].WritePixels 0,0,66,66,p
        ' ----------------------------------------------------
            
    End Method
    
    Method OnRender()
    
        canvas.Clear

        ' Draw To Int coords. Solid blend might be a must.
        canvas.SetBlendMode BlendMode.Opaque2
        id = 0
        y = -(height-height+border*2)
        While y < 480
            x = -(width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],Int(scrollx+x)+2,Int(scrolly+y)+2
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        ' Draw to float coords. This must use alphablend.
        canvas.SetBlendMode BlendMode.Alpha
        id = 0
        y = -(height-height+border*2)
        While y < 480
            x = -(width-width+border*2)
            While x < 640
                canvas.DrawImage pic[id],scrollx+x,scrolly+y
                id = (id+1) Mod 2
                x = x + (width-border*2)
            Wend
            y = y + (height-border*2)
        Wend
    
        scrollx = scrollx + scrollspeedx
        scrolly = scrolly + scrollspeedy
        If scrollx >= width*2 - border*4 Then scrollx=scrollx - (width*2-border*4)
        If scrolly >= height*2 - border*4 Then scrolly=scrolly - (height*2-border*4)

        canvas.Flush
        
    End Method

End Class
 

Attachments

  • SCROLLER.png
    SCROLLER.png
    82.7 KB · Views: 116
Last edited:
You can see the problem when you zoom up close, it's not smooth as it should. But I've gone throuhh the code athousand times. I've missed some simple Cerberus detail I'm sure but I can't simply understand what it could be?

Problem.png
 
Another problem is that I noticed now is that desktop compilation becomes black?

I've been working on HTML5 as usual because it compiles quick.
So now the problem is two-fold.

EDIT : MIP flag was the desktop problem, you just take it away everywhere and it works.
 
Just to update you, some progress. Fixed the RGB and the main logic loop.

It's still not working correctly smooth though?

Screenshot 2020-11-15 at 20.08.58.png

Cerberus:
' BMAX ORIGINAL
' https://vimeo.com/user125916371/review/479595046/afe479923e

' CERBERUS CONVERSION
' https://vimeo.com/user125916371/review/479596008/3c0865f8ce

Import mojo2
Import brl.databuffer

Function Main()
New TileImage
End Function

Class TileImage Extends App

Field canvas:Canvas
Field pic:Image[2]
Field p:DataBuffer = New DataBuffer(66*66*4)
Field x:Int, y:Int, red:Int, green:Int, blue:Int
Field border:Int=1
Field id:Int
Field scrollx:Float=0
Field scrollspeedx:Float=0.05
Field scrolly:Float=0
Field scrollspeedy:Float=0.05
Field width:Int=66
Field height:Int=66

Method OnCreate()
Print Int (-1.4)
Print Int (-1.5)
Print Int (-1.6)
Print Int (-1.9)
SetSwapInterval 1
SetUpdateRate 0
canvas=New Canvas

' Create two 66 x 66 tiles. They are basically ordinary 64x64 tiles
' Each one has a 1-pixel border round them using alpha = 0
' ----------------------------------------------------
pic[0] = New Image(66,66,0,0,Image.Filter)
pic[1] = New Image(66,66,0,0,Image.Filter)

For y=0 To 65
For x=0 To 65
red=x ; green=y ; blue=x+y
If (x=0 Or x=65 Or y=0 Or y=65) Then p.PokeInt((0+x+y*66)*4,(blue Shl 16) | (green Shl 8) | red) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (blue Shl 16) | (green Shl 8) | red)
Next
Next
pic[0].WritePixels 0,0,66,66,p

For y=0 To 65
For x=0 To 65
red=255-y ; green=255-(x+y) ; blue=255-x
If (x=0 Or x=65 Or y=0 Or y=65) Then p.PokeInt((0+x+y*66)*4,(blue Shl 16) | (green Shl 8) | red) Else p.PokeInt((0+x+y*66)*4, $FF000000 | (blue Shl 16) | (green Shl 8) | red)
Next
Next
pic[1].WritePixels 0,0,66,66,p
' ----------------------------------------------------

End Method

Method OnRender()

canvas.Clear

' Draw To Int coords. Solid blend might be a must.
canvas.SetBlendMode BlendMode.Opaque2
id = 0
y = -height-height+border*2
While y < 480
x = -width-width+border*2
While x < 640
canvas.DrawImage pic[id],Int(scrollx+x)+2,Int(scrolly+y)+2
id = (id+1) Mod 2
x = x + (width-border*2)
Wend
y = y + (height-border*2)
Wend

' Draw to float coords. This must use alphablend.
canvas.SetBlendMode BlendMode.Alpha
id = 0
y = -height-height+border*2
While y < 480
x = -width-width+border*2
While x < 640
canvas.DrawImage pic[id],scrollx+x,scrolly+y
id = (id+1) Mod 2
x = x + (width-border*2)
Wend
y = y + (height-border*2)
Wend

scrollx = scrollx + scrollspeedx
scrolly = scrolly + scrollspeedy
If scrollx >= (width*2 - border*4) Then scrollx=scrollx - (width*2-border*4)
If scrolly >= (height*2 - border*4) Then scrolly=scrolly - (height*2-border*4)

canvas.Flush

End Method

End Class
 
Last edited:
Back
Top Bottom