single surface - not quite pixel perfect?

Blitz3D Forums/Blitz3D Programming/single surface - not quite pixel perfect?

Have fun, and do what ya can to fix any bugs/memory leaks I might have left in when I dropped working on this. I've been a bit too busy with work to keep it up!

(On first glance, 'SpriteSource_Create()' is the erea I neglected to finalize.)

Global Cam
	
Type SpriteSource
	
	Field Mesh%, Surf%
	Field Texture%
	Field Frames%, FramesPerRow%
	Field Animated%
	
	Field RefImage%
	
End Type

Function SpriteSource_Create%(Camera%, File$, FramesPerRow% = -1)

	viewwidth=GraphicsWidth()
	viewheight=GraphicsHeight()
	
	S.SpriteSource = New SpriteSource
	
	magic=CreatePivot(Camera) 
	NameEntity(magic,"pixiespace")
	aspect#=Float(viewheight)/viewwidth
	PositionEntity magic,-1,aspect,1 
	scale#=2.0/viewwidth 
	ScaleEntity magic,scale,-scale,-scale 
	magic=CreatePivot(magic)
	
	S\Mesh = CreateMesh(Magic)
	EntityFX(S\Mesh, 2)
	S\Surf = CreateSurface(S\Mesh)
	PositionEntity S\Mesh, -.5, .5, 0
	
	S\Texture = LoadTexture(File, 4)
	S\RefImage = LoadImage(File)
	
	If S\Texture <> 0 Then
		EntityTexture S\Mesh, S\Texture
		If FramesPerRow <> -1 And FramesPerRow > 0 Then
			S\FramesPerRow = FramesPerRow
			S\Animated = True	
		EndIf
	EndIf
	
	Return Handle(S)
	
End Function

Function SpriteSource_SetAnimation%(Source%, FramesPerRow%)

	S.SpriteSource = Object.SpriteSource(Source)
	S\FramesPerRow = FramesPerRow
	S\Animated = True

End Function

Function SpriteSource_CacheSprites(Source%, W%, H%, Count%)
	
	S.SpriteSource = Object.SpriteSource(Source)
	If S = Null Then Return 
		
	For CS = 1 To Count
		
		Sprite_Create%(Source, W, H)
		
	Next
	
End Function

Function SpriteSource_AvailSprite(Source%)

	For S.Sprite = Each Sprite
		If S\Source = Object.SpriteSource(Source) And S\Draw = False Then
			Return Handle(S)
		EndIf
	Next

End Function

Type Sprite

	Field Source.SpriteSource
	Field VertRef%
	Field TriRef%
	
	Field Draw%
	
	Field DrawX%, DrawY%
	Field Width%, Height%
	
	Field HandleX%, HandleY%
	
	Field RotAngle%, OffsetAngle%
	
	Field CurFrameColumn#, CurFrame#, AnimTime%, AnimTimeMax%
	Field Animated%
	
	Field Active%
	
End Type

Function Sprite_Create%(Source%, W%, H%)
	
	S.Sprite = New Sprite
	S\Source = Object.SpriteSource(Source)
	
	If W = 0 Or H = 0 Then
		S\Width = ImageWidth(S\Source\RefImage)
		S\Height = ImageWidth(S\Source\RefImage)
	Else
		S\Width = W
		S\Height = H	
	EndIf
	
	Sprite_CreateQuad(S)

	Return Handle(S)
	
End Function

Function Sprite_Animate(Sprite%, Time%)
	
	S.Sprite = Object.Sprite(Sprite)
	If S\Source\Animated = True
		S\AnimTimeMax = Time%
		S\AnimTime = Time
		S\Animated = True
	EndIf
	
End Function

Function Sprite_Draw(Sprite, X, Y)
	
	S.Sprite = Object.Sprite(Sprite)
	
	S\Draw = True
	S\DrawX = X
	S\DrawY = Y
	
End Function

Function Sprite_Update(Delta# = 1.0)
	
	For S.Sprite = Each Sprite
		If S\Draw = True Then
			If S\Source\Animated = True
				S\AnimTime = S\AnimTime - 1
				If S\AnimTime = 0 Then
					S\AnimTime = S\AnimTimeMax
					
					S\CurFrame = S\CurFrame + 1
					If S\CurFrame = S\Source\FramesPerRow
						S\CurFrame = 0
						
						S\CurFrameColumn = S\CurFrameColumn + 1
						If S\CurFrameColumn = S\Source\FramesPerRow
							S\CurFrameColumn = 0
						EndIf
					EndIf
	
					Dims# = .5;1.0 / (S\Source\FramesPerRow)					
					SU# = Dims * S\CurFrame
					SV# = Dims * S\CurFrameColumn
								
					VertexTexCoords(S\Source\Surf, S\VertRef, SU, SV)
					VertexTexCoords(S\Source\Surf, S\VertRef+1, SU+Dims, SV)
					VertexTexCoords(S\Source\Surf, S\VertRef+2, SU, SV+Dims)
					VertexTexCoords(S\Source\Surf, S\VertRef+3, SU+Dims, SV+Dims)
				EndIf
			EndIf			
			
			S\Draw = False
		EndIf
	Next
	
End Function

Function Sprite_RenderAll()

	For S.Sprite = Each Sprite
		If S\Draw = True Then

			;Top or "rear" vertices
			Mag# = Sqr(S\Width*S\Width + S\Height*S\Height)*.5 

			CosVal# = Cos(S\RotAngle+S\OffsetAngle)
			SinVal# = Sin(S\RotAngle+S\OffsetAngle)
			
			Atan2Val# = ATan2(S\Height, S\Width)
			
			VX# = (Cos((S\RotAngle+S\OffsetAngle) - Atan2Val)*Mag) + S\DrawX
			VY# = (Sin((S\RotAngle+S\OffsetAngle) - Atan2Val)*Mag) + S\DrawY			
			VertexCoords(S\Source\Surf, S\VertRef+1, VX , VY, 0)

			VX# = (Cos((S\RotAngle+S\OffsetAngle) + Atan2Val)*Mag) + S\DrawX
			VY# = (Sin((S\RotAngle+S\OffsetAngle) + Atan2Val)*Mag) + S\DrawY			
			VertexCoords(S\Source\Surf, S\VertRef+3, VX , VY, 0)


			VX# = (Cos((S\RotAngle+S\OffsetAngle+180) - Atan2Val)*Mag) + S\DrawX
			VY# = (Sin((S\RotAngle+S\OffsetAngle+180) - Atan2Val)*Mag) + S\DrawY			
			VertexCoords(S\Source\Surf, S\VertRef+2, VX , VY, 0)


			VX# = (Cos((S\RotAngle+S\OffsetAngle+180) + Atan2Val)*Mag) + S\DrawX
			VY# = (Sin((S\RotAngle+S\OffsetAngle+180) + Atan2Val)*Mag) + S\DrawY			
			VertexCoords(S\Source\Surf, S\VertRef, VX , VY, 0)
		
		ElseIf S\Draw = False Then
			VX# = -100
			
			VertexCoords(S\Source\Surf, S\VertRef+1, VX , VY, 0)	
			VertexCoords(S\Source\Surf, S\VertRef+3, VX , VY, 0)	
			VertexCoords(S\Source\Surf, S\VertRef+2, VX , VY, 0)	
			VertexCoords(S\Source\Surf, S\VertRef, VX , VY, 0)			 
								
		EndIf
	Next

End Function

Function Sprite_CreateQuad(S.Sprite)

	V1 = AddVertex(S\Source\Surf, 0, 0, 0, 0, 0)
	V2 = AddVertex(S\Source\Surf, 0, 0, 0, 1, 0)
	V3 = AddVertex(S\Source\Surf, 0, 0, 0, 0, 1)
	V4 = AddVertex(S\Source\Surf, 0, 0, 0, 1, 1)
	
;	VertexColor S\Source\Surf, V1, 255, 0, 0
;	VertexColor S\Source\Surf, V2, 0, 255, 0
;	VertexColor S\Source\Surf, V3, 0, 0, 255
;	VertexColor S\Source\Surf, V4, 255, 255, 255	
	S\VertRef = V1
	
	T1 = AddTriangle(S\Source\Surf, V1, V2, V3)
	AddTriangle(S\Source\Surf, V3, V2, V4)
	
End Function