Mojo2 screen scrolling using SetCameraMatrix()


Tweet monkey-x code-archives effects
(Posted 5 months ago) RonTek

A modified version of Marks 'Renderer' demo (just save it in his modules/mojo2/bananas/rendererdemo folder) which uses SetCameraMatrix() to move the camera view around (in this case side scrolling) the renderer scene.

Author: Richard Betson

'----------------------------------------------------------
' A modified version of Mark Sibly's Renderer demo
' using SetCameraMatrix() to simulate screen scrolling.
'----------------------------------------------------------

'very simple demo of using Renderer for >4 lights + shadows.


Import mojo2
Import monkey

Global NUM_LIGHTS:=5


'create an orthographics projection matrix
Function Mat4Ortho:Float[]( left:Float,right:Float,bottom:Float,top:Float,znear:Float,zfar:Float )

    Local w:=right-left,h:=top-bottom,d:=zfar-znear

    Return [ 2.0/w,0,0,0, 0,2.0/h,0,0, 0,0,2.0/d,0, -(right+left)/w,-(top+bottom)/h,-(zfar+znear)/d,1 ]
End

Class MyLightA Implements ILight

    'note: x,y,z,w go in last 4 components of matrix...
    Field matrix:=[1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,-60.0,1.0]
    Field color:=[0.5,0.5,0.5,1.0]
    Field range:=1000.0

    'implement ILight interface...
    '
    Method LightMatrix:Float[]()
        Return matrix
    End

    Method LightType:Int()
        Return 1
    End

    Method LightColor:Float[]()
        Return color
    End

    Method LightRange:Float()
        Return range
    End

    Method LightImage:Image()
        Return Null
    End

End



Class MyLayerA Extends DrawList Implements ILayer

    Field lights:=New Stack<MyLightA>
    Field layerMatrix:=[1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 0.0,0.0,0.0,1.0]
    Field layerFogColor:=[0.0,0.0,0.0,0.0]

    'implement ILayer interface...
    '
    Method LayerMatrix:Float[]()
        Return layerMatrix
    End

    Method LayerFogColor:Float[]()
        Return layerFogColor
    End

    Method LayerLightMaskImage:Image()
        Return Null
    End

    Method EnumLayerLights:Void( lights:Stack<ILight> )
        For Local light:=Eachin Self.lights
            lights.Push light
        Next
    End

    Method OnRenderLayer:Void( drawLists:Stack<DrawList> )
        drawLists.Push Self
    End

End



Class Test
    Field _rend:Renderer
    Field _layer:MyLayerA

    Method AddScene(tile:Image,renderer:Renderer,layer0:MyLayerA)

        For Local i:=0 Until NUM_LIGHTS
            Self._layer.lights.Push(New MyLightA)
        Next

        For Local x:=0 To 1280 Step 128
            For Local y:=0 Until 640 Step 128   
                Self._layer.DrawImage tile,x-50,y
            Next
        Next
        Self._rend.Layers.Push layer0
    End Method

    Method SetRenderer(render:Renderer)
        Self._rend=render
    End Method

    Method SetLayer(layer:MyLayerA)
        Self._layer=layer
    End Method

    Method MyRenderer(renderer:Renderer)
        renderer.Render()
    End Method

End Class


Class MyApp Extends App
Field rtime,rframes,rfps
    Field tile:Image
    Field shadowCaster:ShadowCaster
    Field renderer:Renderer'=New Renderer
    Field layer0:MyLayerA'=New MyLayerA
    Field rimage:Image
    Field canvas:Canvas'=New Canvas
    'Field weird:=New DrawList
    Field test:Test=New Test

    Method OnCreate()
        Self.canvas=New Canvas

        'create renderer
        renderer=New Renderer
        renderer.SetViewport( 0,0,DeviceWidth,DeviceHeight )
        renderer.SetProjectionMatrix( Mat4Ortho( 0,DeviceWidth,0,DeviceHeight,-1,1 ) )
        renderer.SetAmbientLight( [0.21,0.1,0.1,1.0] )

        'load some gfx
        tile=Image.Load( "t3.png",0,0 ,Image.Filter|Image.Mipmap,Shader.MatteShader()  )

        'create layer 0
        layer0=New MyLayerA


        'create simple rect shadow caster
        shadowCaster=New ShadowCaster
        shadowCaster.SetVertices( [0.0,0.0, 32.0,0.0, 32.0,32.0, 0.0,32.0] )

        'draw some shadow casters
        For Local x:=100 Until 640 Step 220

            For Local y:=60 Until 480 Step 180

                layer0.SetColor 1,1,0
                layer0.DrawRect x+150,y-16,32,32
                layer0.SetColor 1,1,1

                layer0.AddShadowCaster shadowCaster,x+150,y-16
            Next
        Next

        'add layer to renderer      
        renderer.Layers.Push layer0

        test.SetRenderer(renderer)
        test.SetLayer(layer0)
        test.AddScene(tile,renderer,layer0)

    End


    Global cc:Float
    Method OnRender()


        rframes+=1
        Local e=Millisecs-rtime
        If e>=1000
            rfps=rframes
            rframes=0
            rtime+=e
        Endif

        cc=cc+1
        renderer.SetCameraMatrix([1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 500+(Sin(cc)*100),0.0,0.0,1.0])
        'canvas.SetViewMatrix([1.0,0.0,0.0,0.0, 0.0,1.0,0.0,0.0, 0.0,0.0,1.0,0.0, 100.0,0.0,0.0,1.0])
            'renderer.SetProjectionMatrix( Mat4Ortho( 0,DeviceWidth,0,DeviceHeight,-1,1+ ) )
        canvas.Clear(.4,0,0)

        'move lights around a bit
        For Local i:=0 Until NUM_LIGHTS
            Local light:=layer0.lights.Get(i)
            Local radius:=120.0
            Local an:=(i*360.0/NUM_LIGHTS)+(Millisecs/50.0)
            light.matrix[12]=150+Cos( an )*radius+320
            light.matrix[13]=Sin( an )*radius+240
        Next

        'render scene
        test.MyRenderer(renderer)


        Self.canvas.SetColor(1,1,1)
        Self.canvas.DrawText("FPS-> "+rfps,550,10)
        Self.canvas.Flush() 
    End
End

Function Main()

    New MyApp

End

Reply To Topic (minimum 10 characters)

Please log in to reply