Code archives/3D Graphics - Misc/Sprites Substitute

This code has been declared by its author to be Public Domain code.

Download source code

Sprites Substitute by jfk EO-111102010
Overrides Sprite Functions. See comments in Code.
Updated Version, some (hopefully all) bugs fixed. Still little diffrences from the behaviour of "real" sprites, read comments in code!
EDIT: yet another bugfix, probably not the last one.

Note: these quad based sprites will act diffrent when attached as a child to a parent mesh. EG: when a real sprite is attached to a mesh, applying an EntitypickMode recursively to the parent will not make a real sprite pickable (since its EntityClass is not "Mesh"), but it will do so with a Quadbased substitute Sprite. Another example: Copyentity will not copy a real Sprite that was parented to a mesh that is copied (at least I think so :) ), but it will copy a substitute Sprite that was parented to the mesh. These unintentional copies of pseudo sprites will not be registered like the ones in CreateSprite or Loadsprite and therefor be out of control.
; As there has been an increasing amount of issues with sprites, I tried to write a substitute that emulates Sprites, using a simple
; Quad Mesh and an Update Function. The Functions will override the Blitz Functions, by using the same name, so replacing the use of 
; original Sprites in Sourcecode is easy. Don't forget the Init Part and the Update Function Call.
; When you use FreeEntity with such a Quadbased Sprite, you first need to call ReleaseSprite(entity), to remove
; the Sprite from the update list. That's it.

; please note there is still a problem with parents of sprites that will be scaled:
; while original sprites were not affected, these replacement sprites made of quads will be,
; so you should assign them to patents only after the parents were scaled, or do temporary
; unparent the quads while their parents are scaled. 



Graphics3D 800,600,32,2
SetBuffer BackBuffer()

; init sprite substitute ----------------------
Global ps_c=0, ps_max=10000
Dim pseudo_sprites(ps_max),ps_vmode(ps_max)
; end of init sprite substitute --------------



camera=CreateCamera()

;from docs: SpriteViewModes
;1: fixed (sprite always faces camera - Default) 
;2: free (sprite is independent of camera) 
;3: upright1 (sprite always faces camera, but rolls with camera as well, unlike mode no.1) 
;4: upright2 (sprite always remains upright. Gives a 'billboard' effect. Good For trees, spectators etc.) 


s1a=CreateSprite(camera) ; testing default mode (1) parented to camera, aka HUD element
ScaleSprite s1a,0.5,0.1
TranslateEntity s1a,-.45,.5,1
; using default view mode: 1

s1b=CreateSprite() ; testing default mode 1
TranslateEntity s1b,0,0,4 
EntityColor s1b,255,0,0
; using default view mode: 1


s2=CreateSprite() ; testing mode 2 
TranslateEntity s2,-2,1,4
EntityColor s2,0,255,0
SpriteViewMode s2,2


s3=CreateSprite() ; testing mode 3
TranslateEntity s3,2,1,4
EntityColor s3,0,0,255
SpriteViewMode s3,3


s4=CreateSprite() ; testing mode 4
;s4=LoadSprite("test_mask.bmp",4)
TranslateEntity s4,-3,1,3.9
EntityColor s4,255,0,255
SpriteViewMode s4,4



CameraRange camera,0.05,100
TurnEntity camera,-25,0,0

HandleSprite s2, -1,-1

;releasesprite(s3) ; seems to work
;FreeEntity s3

While KeyHit(1)=0
 TurnEntity s2,0,0,0.7
 TurnEntity camera,0,1,0
 UpdateSubstSprites(camera) ; update Rotation of Subst Sprites
 RenderWorld()
 VWait
 Flip 0
Wend
WaitKey()
End





; Sprite Substitute Functions --------------------------------------------------------------------------------------------
Function UpdateSubstSprites(camera)
 Local i
 For i=0 To ps_c-1
   If ps_vmode(i)=1 ; face to camera
    RotateEntity pseudo_sprites(i),EntityPitch(camera,1),EntityYaw(camera,1),EntityRoll(pseudo_sprites(i),1),1
   EndIf
   ;If ps_vmode(i)=2 ; free!
   ;EndIf
   If ps_vmode(i)=3
    RotateEntity pseudo_sprites(i),EntityPitch(camera,1),EntityYaw(camera,1),EntityRoll(pseudo_sprites(i),1),1
   EndIf
   If ps_vmode(i)=4
    RotateEntity pseudo_sprites(i),EntityPitch(pseudo_sprites(i),1),EntityYaw(camera,1),EntityRoll(camera,1),1
   EndIf
 Next
End Function

Function CreateSprite(parent=0)
 Local quad
 quad=CreateQuad4Sprite()
 If parent<>0 Then
  EntityParent quad,parent
  PositionEntity quad,EntityX(parent,1),EntityY(parent,1),EntityZ(parent,1),1
 Else
  PositionEntity quad,0,0,0,1
 EndIf
 EntityColor quad,255,255,255
 EntityFX quad,1 Or 16
 pseudo_sprites(ps_c)= quad
 ps_vmode(ps_c)=1
 If ps_c<ps_max Then ps_c=ps_c+1
 Return quad
End Function


Function LoadSprite(texfil$, flags=0,parent=0)
 Local tex, quad
 If ((flags And 2)=2) And ((flags And 1)=0) Then flags=flags Or 1 ; prevent crash by alpha bug
 tex=LoadTexture(texfil$,flags)
 If tex=0 Then tex=CreateTexture(4,4,0) ; then again, lets be a bit error tolerant :)
 quad=CreateQuad4Sprite()
 EntityTexture quad,tex
 If parent<>0 Then
  EntityParent quad,parent
  PositionEntity quad,EntityX(parent,1),EntityY(parent,1),EntityZ(parent,1),1
 Else
  PositionEntity quad,0,0,0,1
 EndIf
 EntityFX quad,1 Or 16
 pseudo_sprites(ps_c)= quad
 ps_vmode(ps_c)=1
 If ps_c<ps_max Then ps_c=ps_c+1
 Return quad
End Function


Function HandleSprite(ent,x#,y#) ; seems to work now, looks kind of hacked ...
 surf=GetSurface(ent,1)
 x=-x
 y=-y
 VertexCoords surf,0,-1+x#,1+y#,0 
 VertexCoords surf,1,1+x#,1+y#,0 
 VertexCoords surf,2,-1+x#,-1+y#,0 
 VertexCoords surf,3,1+x#,-1+y#,0 
End Function



Function RotateSprite(ent,a#)
 RotateEntity ent,EntityPitch(ent,0), EntityYaw(ent,0),a#,0 ; 
End Function

Function ScaleSprite(ent,w#,h#)
 ScaleEntity ent,w#,h#,0.001 ; for some reason I cannot use zero for the depth, it hides the HUD sprite.
End Function


Function SpriteViewMode(ent, vmode)
 Local i
 For i=0 To ps_c-1
  If pseudo_sprites(i)=ent
   ps_vmode(i)=vmode
  EndIf
 Next
End Function


Function CreateQuad4Sprite()
 Local mesh%,surf%,v1%,v2%,v3%,v4%
 mesh=CreateMesh()
 surf=CreateSurface(mesh)
 v1=AddVertex(surf,-1,1,0,0,0)
 v2=AddVertex(surf,1,1,0,1,0)
 v3=AddVertex(surf,-1,-1,0,0,1)
 v4=AddVertex(surf,1,-1,0,1,1)
 VertexColor surf,v1,255,255,255,1.0
 VertexColor surf,v3,255,255,255,1.0
 VertexColor surf,v2,255,255,255,1.0
 VertexColor surf,v4,255,255,255,1.0
 AddTriangle(surf,0,1,2)
 AddTriangle(surf,3,2,1)
 Return mesh
End Function


Function ReleaseSprite(ent)
 Local i,i2
 For i=0 To ps_c-1
  If pseudo_sprites(i)=ent
   For i2=i To ps_c-1 
    pseudo_sprites(i2)=pseudo_sprites(i2+1)
    ps_vmode(i2)=ps_vmode(i2+1)
   Next
   ps_c=ps_c-1
   Exit
  EndIf
 Next
End Function

; End of Sprite Substitute Functions --------------------------------------------------------------------------------------------

Comments

Xaron2011
Great, just great! :) Incredible useful for Windows 7 systems.


Code Archives Forum