[bmx] Max2D Stack by N [ 1+ years ago ]

Started by BlitzBot, June 29, 2017, 00:28:38

Previous topic - Next topic

BlitzBot

Title : Max2D Stack
Author : N
Posted : 1+ years ago

Description : Wrote one of these for my engine's 2D system, so I figured I'd let those of you who don't use it (everyone but me) have the same option for managing 2D state(s).

One of the handier things these can be used for are sprite systems that have parent/child relationships that inherit transformations and such.  E.g.,
Type Sprite
   
    Field children:TList = New TList
   
    Method Draw( )
        Push2D( )
       
        ' Change some stuff with the state in here, like scale or rotation or blend mode or something
       
        ' Call this before drawing the image
        State.Update( ) ' <- Applies any changes in the current state
       
        For Local i:Sprite = EachIn children
            i.Draw( )
        Next
       
        Pop2D( )
        ' Back to normal
    End Method
   
End Type


Code :
Code (blitzmax) Select
Strict

Global State:State2D = New State2D

Function Push2D( )
    State = State.Push( )
End Function

Function Pop2D( )
    State = State.Pop( )
End Function

Type State2D
    Const CF_TRANSFORM = 0
    Const CF_BLEND = 1
    Const CF_VIEWPORT = 2
    Const CF_HANDLE = 3
    Const CF_ORIGIN = 4
    Const CF_ALPHA = 5
    Const CF_COLOR = 6
    Const CF_CLSCOLOR = 7
   
    Field _pred:State2D
    Field sx#=1, sy#=1
    Field rot#
    Field r%,g%,b%,a#
    Field ox#, oy#
    Field hx#, hy#
    Field vx%, vy%, vw%, vh%
    Field blend_% = SOLIDBLEND
    Field cr%, cg%, cb%
    Field cf[]=[1,1,1,1,1,1,1,1]
   
    ' Does not copy its predecessor
    Method Clone:State2D( )
        Local s:State2D = New State2D
        MemCopy( Varptr s.sx, Varptr sx, 76 )
        s.cf = cf[..]
        Return s
    End Method
   
    ' Creates a copy of the top state (Self prior to Push()ing) and sets self as its predecessor
    Method Push:State2D( )
        Local s:State2D = Clone( )
        s._pred = Self
        Return s
    End Method
   
    Method Pop:State2D( )
        Assert _pred,"State2D error: stack underflow"
        Local p:State2D = _pred
        _pred = Null
        p.Bind( )
        Return p
    End Method
   
    Method Scale( x#, y# )
        sx :* x
        sy :* y
        cf[CF_TRANSFORM]=True
    End Method
   
    Method Rotate( r# )
        rot :+ r
        cf[CF_TRANSFORM]=True
    End Method
   
    Method ScaleAbsolute( x#, y# )
        sx = x
        sy = y
        cf[CF_TRANSFORM]=True
    End Method
   
    Method Rotation( r# )
        rot = r
        cf[CF_TRANSFORM]=True
    End Method
   
    Method Color( r%, g%, b% )
        Self.r = r
        Self.g = g
        Self.b = b
        cf[CF_COLOR]=True
    End Method
   
    Method Alpha( a# )
        Self.a = a
        cf[CF_ALPHA]=True
    End Method
   
    Method ClearColor( r%, g%, b% )
        cr = r
        cg = g
        cb = b
        cf[CF_CLSCOLOR]=True
    End Method
   
    Method Handle( hx#, hy# )
        Self.hx = hx
        Self.hy = hy
        cf[CF_HANDLE]=True
    End Method
   
    Method Viewport( x%, y%, w%, h% )
        vx = x
        vy = y
        vw = w
        vh = h
        cf[CF_VIEWPORT]=True
    End Method
   
    Method Blend( b% )
        blend_ = b
        cf[CF_BLEND]=True
    End Method
   
    Method Origin( ox#, oy# )
        Self.ox = ox
        Self.oy = oy
        cf[CF_ORIGIN]=True
    End Method
   
    Method MoveOrigin( ox_#, oy_# )
        Self.ox :+ ox_
        Self.oy :+ oy_
        cf[CF_ORIGIN]=True
    End Method
   
    Method Identity( )
        sx = 1
        sy = 1
        rot = 0
       
        r = 255
        g = 255
        b = 255
       
        a = 1
       
        ox = 0
        oy = 0
       
        hx = 0
        hy = 0
       
        vx = 0
        vy = 0
        vw = GraphicsWidth( )
        vh = GraphicsHeight( )
       
        blend_ = SOLIDBLEND
       
        cr = 0
        cg = 0
        cb = 0
       
        cf = [1,1,1,1,1,1,1,1]
    End Method
   
    Method Bind( )
        Update( True )
    End Method
   
    Method Update( Force=0 )
        If cf[CF_ORIGIN] Or Force Then SetOrigin( ox, oy )
        If cf[CF_HANDLE] Or Force Then SetHandle( hx, hy )
        If cf[CF_TRANSFORM] Or Force Then SetTransform( rot, sx, sy )
        If cf[CF_VIEWPORT] Or Force Then SetViewport( vx, vy, vw, vh )
        If cf[CF_COLOR] Or Force Then SetColor( r, g, b )
        If cf[CF_ALPHA] Or Force Then SetAlpha( a )
        If cf[CF_BLEND] Or Force Then SetBlend( blend_ )
        If cf[CF_CLSCOLOR] Or Force Then SetClsColor( cr, cg, cb )
        cf = [0,0,0,0,0,0,0,0]
    End Method
End Type


Comments : none...