monkey2 icon indicating copy to clipboard operation
monkey2 copied to clipboard

Weird jumping/flickering sprites problem

Open DruggedBunny opened this issue 7 years ago • 13 comments

Hi Mark,

Bit of an odd one I've run into while trying to convert my rocket smoke from cubes to sprites, sort of narrowed it down to the sample below.

In short, I'm firing a stream of physics-controlled particles that cycles through white, yellow, orange, red, black, then fade out. It should look like this (extreme debug version using cubes):

particles

However, when using sprites, they start out correctly, then once a few of them are active at once, they start to flicker and jump.

You should be able to see it in the code below. Note that the class is duplicated, just that one uses cubes, other uses sprites.

Hold Space for a constant stream and note the cubes are fine, but the sprites start jumping and flickering. With short taps, the sprites are also OK, but held for a little longer, they start to mess up. (Tap Enter for single particles and note they only screw up if tapped rapidly.)

Thought it was some sort of alpha problem, but replacing alpha with a dummy variable (leaving entity alpha at 1.0 throughout) does the same thing.


Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

' ---------------------- SPRITE version ----------------------

Class RocketParticle_Sprite Extends Behaviour

	Public
	
		Function Create:RocketParticle_Sprite (parent:Entity, thrust:Vec3f, size:Float = 0.5, fadeout:Float = 0.95)

'Game.MainCamera.CameraDistance = 4.0
			'RocketParticle.SpriteInit ()
			
			Local sprite:Sprite = New Sprite (New SpriteMaterial (), parent)
		
				Cast <SpriteMaterial> (sprite.Material).ColorFactor = Color.White
				
				'sprite.Move (Rnd (-0.1, 0.1), Rnd (-2.1, -2.5), Rnd (-0.1, 0.1))
				
				sprite.Move (0.0, -2.1, 0.0)
				
				sprite.Parent				= Null
				sprite.Scale				= New Vec3f (size, size, 0.0)
				sprite.Alpha				= 1.0
				
			Local sp:RocketParticle_Sprite			= New RocketParticle_Sprite (sprite)
			
				sp.thrust					= thrust
				sp.update_fader				= fadeout
			
				sp.TMP_fake_alpha = 1.0
				
			Return sp
			
		End

	Private
	
		Method New (entity:Entity)
		
			Super.New (entity)

			AddInstance ()
			
		End

		Method OnStart () Override

			Local collider:BoxCollider	= Entity.AddComponent <BoxCollider> () ' Unexpected: Collider needs to be added BEFORE applying impulse!

			Local body:RigidBody		= Entity.AddComponent <RigidBody> ()
' No Boxf!
				body.Mass				= 0.01
				body.Restitution		= 0.5
				body.Friction			= 0.1
	
				body.CollisionMask		= 0'COLL_NOTHING
			
				body.ApplyImpulse (thrust)
			
				thrust					= Null ' Don't need to keep temp Vec3f object
				
		End
		
		Method OnUpdate (elapsed:Float) Override
			
		'		Print Int (color_change * 5.0)
				
'				Cast <Sprite> (Entity).Material = SpriteMat [Int (Entity.Alpha * 5.0)] ' There are 5 sprite materials

'				Local sm:SpriteMaterial = Cast <SpriteMaterial> (Cast <Sprite> (Entity).Material)

				Local cs:Sprite	= Cast <Sprite> (Entity)
				Local sm:SpriteMaterial	= Cast <SpriteMaterial> (cs.Material)

'				Local cs:Model	= Cast <Model> (Entity)
'				Local sm:PbrMaterial	= Cast <PbrMaterial> (cs.Material)
				
				Select Int (color_change * 5.0) ' There are 5 sprite materials
					Case 0
						sm.ColorFactor = Color.Black
					Case 1
						sm.ColorFactor = Color.Red
					Case 2
						sm.ColorFactor = Color.Orange
					Case 3
						sm.ColorFactor = Color.Yellow
					Case 4
						sm.ColorFactor = Color.White
				End
				
				If sm.ColorFactor = Color.Black
					Entity.Alpha = Entity.Alpha * 0.975 ' TODO: Needs adjusting for framerate!
					'TMP_fake_alpha = TMP_fake_alpha * 0.975
				Else
					color_change = color_change * update_fader ' TODO: Needs adjusting for framerate!
				End
				
				' Slow particle down (air resistance)... very dependent on start speed and alpha fade amount...
				
				Entity.GetComponent <RigidBody> ().LinearDamping = (1.0 - color_change)' * 0.95 ' Trial and error!
				
				'If TMP_fake_alpha < 0.075'
				If Entity.Alpha < 0.075
					Entity.Destroy ()
				Endif
			
		End
	
		' Rocket thrust level -- need to temp-store here as OnStart can't be passed custom params!
		
		Field thrust:Vec3f
		Field update_fader:Float
		Field color_change:Float = 0.99
		
		Field TMP_fake_alpha:Float
End

' ---------------------- MESH version ----------------------

Class RocketParticle_Mesh Extends Behaviour

	Public
	
		Function Create:RocketParticle_Mesh (parent:Entity, thrust:Vec3f, size:Float = 0.5, fadeout:Float = 0.95)

'Game.MainCamera.CameraDistance = 4.0
			'RocketParticle.SpriteInit ()
			
'			Local sprite:Sprite = New Sprite (New SpriteMaterial (), rocket.RocketModel)
			Local sprite:Model = Model.CreateBox (New Boxf (-0.5, -0.5, -0.5, 0.5, 0.5, 0.5), 1, 1, 1, New PbrMaterial (Color.White), parent)'New Sprite (New SpriteMaterial (), rocket.RocketModel)
		
'				Cast <SpriteMaterial> (sprite.Material).ColorFactor = Color.White
				
				'sprite.Move (Rnd (-0.1, 0.1), Rnd (-2.1, -2.5), Rnd (-0.1, 0.1))
				
				sprite.Move (0.0, -2.1, 0.0)
				
				sprite.Parent				= Null
				sprite.Scale				= New Vec3f (size, size, size)
				sprite.Alpha				= 1.0
				
			Local sp:RocketParticle_Mesh			= New RocketParticle_Mesh (sprite)
			
				sp.thrust					= thrust
				sp.update_fader				= fadeout

				sp.TMP_fake_alpha = 1.0
			
			Return sp
			
		End

	Private
	
		Method New (entity:Entity)
		
			Super.New (entity)

			AddInstance ()
			
		End

		Method OnStart () Override

			Local collider:BoxCollider	= Entity.AddComponent <BoxCollider> () ' Unexpected: Collider needs to be added BEFORE applying impulse!

			Local body:RigidBody		= Entity.AddComponent <RigidBody> ()
' No Boxf!
				body.Mass				= 0.01
				body.Restitution		= 0.5
				body.Friction			= 0.1
	
				body.CollisionMask		= 0'COLL_NOTHING
			
				body.ApplyImpulse (thrust)
			
				thrust					= Null ' Don't need to keep temp Vec3f object
				
		End
		
		Method OnUpdate (elapsed:Float) Override
			
		'		Print Int (color_change * 5.0)
				
'				Cast <Sprite> (Entity).Material = SpriteMat [Int (Entity.Alpha * 5.0)] ' There are 5 sprite materials

'				Local sm:SpriteMaterial = Cast <SpriteMaterial> (Cast <Sprite> (Entity).Material)

'				Local cs:Sprite	= Cast <Sprite> (Entity)
'				Local sm:SpriteMaterial	= Cast <SpriteMaterial> (cs.Material)

				Local cs:Model	= Cast <Model> (Entity)
				Local sm:PbrMaterial	= Cast <PbrMaterial> (cs.Material)
				
				Select Int (color_change * 5.0) ' There are 5 sprite materials
					Case 0
						sm.ColorFactor = Color.Black
					Case 1
						sm.ColorFactor = Color.Red
					Case 2
						sm.ColorFactor = Color.Orange
					Case 3
						sm.ColorFactor = Color.Yellow
					Case 4
						sm.ColorFactor = Color.White
				End
				
				If sm.ColorFactor = Color.Black
					Entity.Alpha = Entity.Alpha * 0.975 ' TODO: Needs adjusting for framerate!
				'	TMP_fake_alpha = TMP_fake_alpha * 0.975
				Else
					color_change = color_change * update_fader ' TODO: Needs adjusting for framerate!
				End
				
				' Slow particle down (air resistance)... very dependent on start speed and alpha fade amount...
				
				Entity.GetComponent <RigidBody> ().LinearDamping = (1.0 - color_change)' * 0.95 ' Trial and error!
				
				'If TMP_fake_alpha < 0.075'
				If Entity.Alpha < 0.075
					Entity.Destroy ()
				Endif
			
		End
	
		' Rocket thrust level -- need to temp-store here as OnStart can't be passed custom params!
		
		Field thrust:Vec3f
		Field update_fader:Float
		Field color_change:Float = 0.99
		
		Field TMP_fake_alpha:Float
End

Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	Field _ground:Model
	
	Field pivot0:Pivot
	Field pivot1:Pivot
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		_camera.Rotate (-25, 0, 0)
			
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		'create ground
		Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
		Local groundMaterial:=New PbrMaterial( Color.Lime )
		_ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
		_ground.CastsShadow=False
		
		pivot0 = New Pivot
		pivot0.Move (-3, 7.5, 0)
		
		pivot1 = New Pivot
		pivot1.Move (3, 7.5, 0)
		
	End
	
	Method OnRender( canvas:Canvas ) Override

		Local spread:Float = 0.025

		If Keyboard.KeyHit (Key.Enter)
			RocketParticle_Mesh.Create (pivot0, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
			RocketParticle_Sprite.Create (pivot1, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
		Endif
	
		If Keyboard.KeyDown (Key.Space)
			For Local loop:Int = 1 To 1
				RocketParticle_Mesh.Create (pivot0, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
				RocketParticle_Sprite.Create (pivot1, New Vec3f (Rnd (-spread, spread), 0.1, Rnd (-spread, spread)))
			Next
		Endif

		If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
		RequestRender()
		_scene.Update()
		_camera.Render( canvas )
		canvas.DrawText( "FPS="+App.FPS,0,0 )
		canvas.DrawText( "SPACE: Stream of particles",0,20 )
		canvas.DrawText( "ENTER: Single particles",0,40 )
		canvas.DrawText( "RocketParticle_Mesh on left",0,80 )
		canvas.DrawText( "RocketParticle_Sprite on right",0,100 )
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

DruggedBunny avatar Oct 14 '18 19:10 DruggedBunny

Tried a non-physics version, and this doesn't suffer from the same problem, though it does (possibly related?) have a weird colour-changing effect on cycling the alpha, which may be another bug:

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..

Const RadDivider:Float = Pi / 180.0

Function Degrees:Float (radian:Float)
	Return radian * RadDivider
End

Class MovingSprite
	Field sprite:Sprite
End

Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	Field _ground:Model

	Field list:List <MovingSprite>
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		'create ground
		Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
		Local groundMaterial:=New PbrMaterial( Color.Lime )
		_ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
		_ground.CastsShadow=False
		
		list = New List <MovingSprite>
		
		For Local loop:Int = 1 To 1000
			Local ms:MovingSprite = New MovingSprite
			ms.sprite = New Sprite (New SpriteMaterial)
			Cast <SpriteMaterial> (ms.sprite.Material).ColorFactor = Color.Rnd ()
			ms.sprite.Move (Rnd (-10, 10), Rnd (-10, 10), Rnd (-10, 10))
			ms.sprite.Rotate (Rnd (-180, 180), Rnd (-180, 180), Rnd (-180, 180))
			list.Add (ms)
		Next
		
	End
	
	Method OnRender( canvas:Canvas ) Override
	
		For Local ms:MovingSprite = Eachin list
			ms.sprite.Move (Sin (Degrees (Millisecs ())) * 0.1, Cos (Degrees (Millisecs ())) * 0.1, Sin (Degrees (Millisecs ())) * 0.1)
			ms.sprite.Alpha = Sin (Degrees (Millisecs () * 0.1))
		Next
	
		If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
		RequestRender()
		_scene.Update()
		_camera.Render( canvas )
		canvas.DrawText( "FPS="+App.FPS,0,0 )
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

DruggedBunny avatar Oct 14 '18 19:10 DruggedBunny

Nice bug!

Fix is now up in develop branch...

A quick hint: instead of creating a new material for each sprite, you should try to share materials as much as possible. If each sprite has its own material, the renderer is forced to render sprites one-by-one instead of batching them for bulk rendering.

I've also added a SpriteMode.Fixed for using sprites to draw plain quads.

Haven't looked at the related material bug yet...

On Mon, Oct 15, 2018 at 8:51 AM DruggedBunny [email protected] wrote:

Tried a non-physics version, and this doesn't suffer from the same problem, though it does (possibly related?) have a weird colour-changing effect on cycling the alpha, which may be another bug:

Namespace myapp3d

#Import "" #Import "" #Import ""

Using std.. Using mojo.. Using mojo3d..

Const RadDivider:Float = Pi / 180.0

Function Degrees:Float (radian:Float) Return radian * RadDivider End

Class MovingSprite Field sprite:Sprite End

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light Field _ground:Model

Field list:List <MovingSprite>

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0
  
  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )
  
  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )
  
  'create ground
  Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
  Local groundMaterial:=New PbrMaterial( Color.Lime )
  _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
  _ground.CastsShadow=False
  
  list = New List <MovingSprite>
  
  For Local loop:Int = 1 To 1000
  	Local ms:MovingSprite = New MovingSprite
  	ms.sprite = New Sprite (New SpriteMaterial)
  	Cast <SpriteMaterial> (ms.sprite.Material).ColorFactor = Color.Rnd ()
  	ms.sprite.Move (Rnd (-10, 10), Rnd (-10, 10), Rnd (-10, 10))
  	ms.sprite.Rotate (Rnd (-180, 180), Rnd (-180, 180), Rnd (-180, 180))
  	list.Add (ms)
  Next

End

Method OnRender( canvas:Canvas ) Override

  For Local ms:MovingSprite = Eachin list
  	ms.sprite.Move (Sin (Degrees (Millisecs ())) * 0.1, Cos (Degrees (Millisecs ())) * 0.1, Sin (Degrees (Millisecs ())) * 0.1)
  	ms.sprite.Alpha = Sin (Degrees (Millisecs () * 0.1))
  Next

  If Keyboard.KeyHit (Key.Escape) Then App.Terminate ()
  RequestRender()
  _scene.Update()
  _camera.Render( canvas )
  canvas.DrawText( "FPS="+App.FPS,0,0 )

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-429656733, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QvLF7IiBGBprOG2cLf50nRNCdIyZks5uk5XOgaJpZM4XbTCg .

blitz-research avatar Oct 20 '18 02:10 blitz-research

Working great, thanks, Mark. Just updated my project if you want to see it. Particle effect needs some work still, but the sprites look to be working perfect.

I'll mess about and try getting global sprite materials working -- the ExplosionParticle uses a fixed array of 5 materials, but I think I ended up with one material per sprite in RocketParticle while fiddling with workarounds!

(I can't remember if I could change the colour of individual particles using just one material but think I'm doing some weird stuff at the moment anyway... )

Thanks again!

DruggedBunny avatar Oct 20 '18 19:10 DruggedBunny

Remembered why I was creating a material per-sprite (on trying to re-implement reassigning each sprite's material, as it 'cools', from an array of five flame-colour materials, ie. White, Yellow, Orange, Red, Black):

ie. sprite.Material = MatArray [heat_level] ' MatArray:SpriteMaterial

(I think this may be the "related material bug" you were referring to?)

DruggedBunny avatar Oct 21 '18 15:10 DruggedBunny

Actually, I was talking about the Mesh.CreateRect issue, which is fixed now.

Remembered why I was creating a material per-sprite (on trying to reassign each sprite's material as it 'cooled' from an array of five flame-colour materials, ie. White, Yellow, Orange, Red, Black):

If you are only using solid colors, it's still more efficient to use Entity.Color instead of a different material for each color.

On Mon, Oct 22, 2018 at 4:50 AM DruggedBunny [email protected] wrote:

Reopened #434 https://github.com/blitz-research/monkey2/issues/434.

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#event-1916712558, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3Qpa2K_DiKSD6wDrV7ofyeNg_wmGFks5unJfNgaJpZM4XbTCg .

blitz-research avatar Oct 21 '18 21:10 blitz-research

I'll delve in again tomorrow (and will try the quad fix, though I don't really need it now), but from memory, using a single SpriteMaterial and trying to change the colour affected all sprites at once -- I assumed Entity.Color was changing the colour of the single material. Will try again tomorrow...

Many thanks!

DruggedBunny avatar Oct 21 '18 22:10 DruggedBunny

Using a single SpriteMaterial and trying to change the colour affected all sprites at once

Yes, this is correct, but I meant changing the Entity.Color. This only works if you're not using a texture though.

On Mon, Oct 22, 2018 at 11:44 AM DruggedBunny [email protected] wrote:

I'll delve in again tomorrow (and will try the quad fix, though I don't really need it now), but from memory, using a single SpriteMaterial and trying to change the colour affected all sprites at once -- I assumed Entity.Color was changing the colour of the single material. Will try again tomorrow...

Many thanks!

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-431710711, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3Qq_XJziB_6NidiB89IZkXrdSUY4Xks5unPjOgaJpZM4XbTCg .

blitz-research avatar Oct 21 '18 23:10 blitz-research

OK, I'd assumed sprites'/entities' colours/alphas were controlled via a default material that I had to create.

However, there seem to be problems relating to creating sprites with no material, possibly relating to having a parent, too -- the example below crashes for me at _camera.Render. (Switch to the "FAILS" New Sprite line using no material -- left working here just for reference.)

Interestingly, in my game, I've updated my explosion particle code like this, and it doesn't crash, despite having no material!

			Local sprite:Sprite = New Sprite (rocket.RocketModel) ' Just a Model
		
				' sprite.Parent				= Null

... but if I enable sprite.Parent = Null it crashes. The sprites are created with the rocket Model as parent for positioning, then 'freed' via parent = Null to operate independently under physics control.

(Interestingly, I get 'attempt to invoke method on null instance' in debug mode, but it doesn't highlight the line in Ted2Go.)

I can't reproduce this parenting part in my sample below!

Will upload the current rocket source if needed, but perhaps getting the sample below to work will just fix it.

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..


Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	Field _ground:Model
	Field _sprite:Sprite
	
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		'create ground
		Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
		Local groundMaterial:=New PbrMaterial( Color.Lime )
		_ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
		_ground.CastsShadow=False
		
		Local spmat:SpriteMaterial = New SpriteMaterial ()

		' FAILS:
		
'		_sprite = New Sprite (_camera)
		
		' WORKS:
		
		_sprite = New Sprite (spmat, _camera)

		_sprite.Move (0, 0, 5)

		If _sprite = Null Then Print "Null" ' Fine

	End
	
	Method OnRender( canvas:Canvas ) Override
		
		Print "Requesting render..."
		RequestRender()
		Print "Updating scene..."
		_scene.Update()
		Print "Rendering scene..."				' Boom AFTER this!
		_camera.Render( canvas )
		Print "Drawing text..."
		canvas.DrawText( "FPS="+App.FPS,0,0 )
		Print "OnRender complete"
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

DruggedBunny avatar Oct 23 '18 01:10 DruggedBunny

Ok, fixed missing default material in develop.

On Tue, Oct 23, 2018 at 2:42 PM DruggedBunny [email protected] wrote:

OK, I'd assumed sprites'/entities' colours/alphas were controlled via a default material that I had to create.

However, there seem to be problems relating to creating sprites with no material, possibly relating to having a parent, too -- this crashes for me at _camera.Render if you switch to the "FAILS" New Sprite line with no material (left working line here just for reference).

Interestingly, in my game, I've updated my explosion particle code like this, and it doesn't crash, despite having no material!

  	Local sprite:Sprite = New Sprite (rocket.RocketModel) ' Just a Model

' sprite.Parent = Null

... but if I enable sprite.Parent = Null it crashes. (Interestingly, I get 'attempt to invoke method on null instance' in debug mode, but it doesn't highlight the line in Ted2Go.)

I can't reproduce this parenting part in my sample below! The sprites are created with the rocket Model as parent for positioning, then 'freed' via parent = Null to operate independently under physics control.

Namespace myapp3d

#Import "" #Import "" #Import ""

Using std.. Using mojo.. Using mojo3d..

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light Field _ground:Model Field _sprite:Sprite

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = New Color( 0.2, 0.6, 1.0 )
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0
  
  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )
  
  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )
  
  'create ground
  Local groundBox:=New Boxf( -100,-1,-100,100,0,100 )
  Local groundMaterial:=New PbrMaterial( Color.Lime )
  _ground=Model.CreateBox( groundBox,1,1,1,groundMaterial )
  _ground.CastsShadow=False
  
  Local spmat:SpriteMaterial = New SpriteMaterial ()

  ' FAILS:

' _sprite = New Sprite (_camera)

  ' WORKS:
  
  _sprite = New Sprite (spmat, _camera)

  _sprite.Move (0, 0, 5)

  If _sprite = Null Then Print "Null" ' Fine

End

Method OnRender( canvas:Canvas ) Override

  Print "Requesting render..."
  RequestRender()
  Print "Updating scene..."
  _scene.Update()
  Print "Rendering scene..."				' Boom AFTER this!
  _camera.Render( canvas )
  Print "Drawing text..."
  canvas.DrawText( "FPS="+App.FPS,0,0 )
  Print "OnRender complete"

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-432054239, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QmEkBYBRXDcwFA5gB1twL3FQV1owks5unnPzgaJpZM4XbTCg .

blitz-research avatar Nov 09 '18 20:11 blitz-research

Thanks, Mark... but there's something wrong with sprite colours now, when using default material!

It's like only colours with an element of red get shown (I think), and of those, the colours are weirdly stripped of something... here, for example, Color.Orange sprites are shown in magenta, under:

	Method OnRender( canvas:Canvas ) Override
		
		Local copy:Sprite = sprite.Copy ()
		
			copy.Color = Color.Orange' White

Color.Blue and Color.Green simply don't appear.

Demo below...

Namespace myapp3d

#Import "<std>"
#Import "<mojo>"
#Import "<mojo3d>"

Using std..
Using mojo..
Using mojo3d..


Class MyWindow Extends Window
	
	Field _scene:Scene
	Field _camera:Camera
	Field _light:Light
	
	Field sprite:Sprite
	
	Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )
		
		Super.New( title,width,height,flags )
	End
	
	Method OnCreateWindow() Override
		
		'create (current) scene
		_scene=New Scene
		_scene.ClearColor = Color.Black
		_scene.AmbientLight = _scene.ClearColor * 0.25
		_scene.FogColor = _scene.ClearColor
		_scene.FogNear = 1.0
		_scene.FogFar = 200.0
		
		'create camera
		_camera=New Camera( Self )
		_camera.AddComponent<FlyBehaviour>()
		_camera.Move( 0,2.5,-5 )
		
		'create light
		_light=New Light
		_light.CastsShadow=True
		_light.Rotate( 45, 45, 0 )
		
		sprite = New Sprite ()
		
	End
	
	Method OnRender( canvas:Canvas ) Override
		
		Local copy:Sprite = sprite.Copy ()
		
			copy.Color = Color.Orange' White
'			Print copy.Color
			Local size:Float = Rnd (0.1, 2.0)
			copy.Scale = New Vec3f (size, size, 1.0)
			copy.Move (Rnd (-100.0, 100.0), Rnd (-100.0, 100.0), Rnd (50.0, 150.0))
		
		RequestRender()
		_scene.Update()
		_camera.Render( canvas )
		canvas.DrawText( "FPS="+App.FPS,0,0 )
	End
	
End

Function Main()

	New AppInstance
	
	New MyWindow
	
	App.Run()
End

Try Color.Rnd (), too -- it produces random RGBs (shown by Print), but only the sprites in a range best described as Barratts Fruit Salad gets shown!

DruggedBunny avatar Nov 10 '18 18:11 DruggedBunny

Mmm, lollies look good.

Should be fixed now in develop - I messed up the new Color.ToRGBA stuff, this is always a bit trickier than it seems!

On Sun, Nov 11, 2018 at 7:22 AM DruggedBunny [email protected] wrote:

Thanks, Mark... but there's something wrong with sprite colours now, when using default material!

It's like only colours with an element of red get shown (I think), and of those, the colours are weirdly stripped of something (red??)... here, for example, Color.Orange sprites are shown in magenta, under:

Method OnRender( canvas:Canvas ) Override

  Local copy:Sprite = sprite.Copy ()
  
  	copy.Color = Color.Orange' White

Demo below...

Namespace myapp3d

#Import "" #Import "" #Import ""

Using std.. Using mojo.. Using mojo3d..

Class MyWindow Extends Window

Field _scene:Scene Field _camera:Camera Field _light:Light

Field sprite:Sprite

Method New( title:String="Simple mojo3d app",width:Int=640,height:Int=480,flags:WindowFlags=WindowFlags.Resizable )

  Super.New( title,width,height,flags )

End

Method OnCreateWindow() Override

  'create (current) scene
  _scene=New Scene
  _scene.ClearColor = Color.Black
  _scene.AmbientLight = _scene.ClearColor * 0.25
  _scene.FogColor = _scene.ClearColor
  _scene.FogNear = 1.0
  _scene.FogFar = 200.0
  
  'create camera
  _camera=New Camera( Self )
  _camera.AddComponent<FlyBehaviour>()
  _camera.Move( 0,2.5,-5 )
  
  'create light
  _light=New Light
  _light.CastsShadow=True
  _light.Rotate( 45, 45, 0 )
  
  sprite = New Sprite ()

End

Method OnRender( canvas:Canvas ) Override

  Local copy:Sprite = sprite.Copy ()
  
  	copy.Color = Color.Orange' White

' Print copy.Color Local size:Float = Rnd (0.1, 2.0) copy.Scale = New Vec3f (size, size, 1.0) copy.Move (Rnd (-100.0, 100.0), Rnd (-100.0, 100.0), Rnd (50.0, 150.0))

  RequestRender()
  _scene.Update()
  _camera.Render( canvas )
  canvas.DrawText( "FPS="+App.FPS,0,0 )

End

End

Function Main()

New AppInstance

New MyWindow

App.Run() End

Try Color.Rnd (), too -- it produces random RGBs (shown by Print), but only the sprites in a range best described as Barratts Fruit Salad gets shown!

https://camo.githubusercontent.com/cab65a824e87578b812a81545021b537738b4e6b/687474703a2f2f636172742e6372616e6368732d737765657473686f702e636f2e756b2f696d616765732f70726f64756374732f66727569745f73616c61645f63686577732e6a7067

— You are receiving this because you commented. Reply to this email directly, view it on GitHub https://github.com/blitz-research/monkey2/issues/434#issuecomment-437605355, or mute the thread https://github.com/notifications/unsubscribe-auth/ADU3QtWTQU6L1X-S35QCPU2ksxTHwhuGks5utxlugaJpZM4XbTCg .

blitz-research avatar Nov 10 '18 21:11 blitz-research

That's looking spot-on now with my rocket particles using default material -- thanks!

I did a little experiment, leaving a plain sprite (Copy'd from a master sprite) when deleting each particle, and with default material I can now hit 10,000 sprites leaving a cool 3D trail through the sky at 60 FPS. (You'll notice 52 fps here -- it's pretty much dead-on 10k when it starts to drop.)

EDIT: Latest update includes this stuff.

10ktrail

Couple of mostly-unrelated queries if you get chance...

  1. While trying to make things framerate-independent, I think I've got the hang of OnUpdate's elapsed parameter, but for non-physics entities that I also want to move/rotate/fade out framerate-independently, I've thought that I could really use Scene's elapsed value -- could that be made accessible, or would it make no sense to use that outside of Behaviour's OnUpdate methods?

  2. Totally unrelated: I noticed btCompoundShape had been started at some point, and I believe this is what I would need to stop my rocket rotating awkwardly about its (conical) base when landing -- the idea being to attach a cuboid shape (below the cone) whose corners fit the four fin positions, hence making it only tip in the four resulting directions. Just one for the wishlist! (It would also allow bolt-on rocket engines a-la Kerbal Space Program, quadcopter-drone simulation, etc.)

DruggedBunny avatar Nov 11 '18 00:11 DruggedBunny

Can be closed.

seyhajin avatar Jun 04 '19 15:06 seyhajin