Single surface help !

Blitz3D Forums/Blitz3D Programming/Single surface help !

Hi :)

Here is the code i have find : But i need two stuff

- Delete a sprite
- Hide a sprite

Anybody can help me ?

Global fpsindex#,fpstime#,fpsfold_millisecs#,fpsfps#,time,xyzturn

Type layer
	Field mesh
	Field count
	Field spritebank ; bank of sprites up to count
End Type

Type sprite
	Field x#,y#,z#
	Field r,g,b
	Field s#,a#
	Field verti[3]
	Field surf
End Type

;--------------------------------------------------------------------------------------------
Graphics3D 640,480,16,2
SetBuffer BackBuffer()
Global camera=CreateCamera()
CameraRange camera,1,9000
light=CreateLight(2)
PositionEntity light,1000,1000,-1000
;--------------------------------------------------------------------------------------------
fire=LoadTexture ("C:\Program Files\Blitz3D\samples\RobCummings\Bumpy\glow.bmp",2+48)

test=CreateLayer()
EntityTexture test,fire

;For i=0 To 1000
;	temp = AddSprite(test)
;	PositionSprite temp,Rnd(-500,500),Rnd(-500,500),Rnd(-500,500)
;Next

temp1 = AddSprite(test)
PositionSprite temp1,0,0,50

temp2 = AddSprite(test)
PositionSprite temp2,20,0,50



;--------------------------------------------------------------------------------------------
HidePointer
While Not KeyHit(1)


	;TransTex(fire,MilliSecs()*0.08)
	UpdateSprites()
	
	; Get the timer value
	T=MilliSecs() 
	
	; Mouse Look, every 25ms
	Time1=mouselook(camera,T,Time1,25)

	If MouseHit(1) Then
		AlphaSprite(temp1,0.1)
		AlphaSprite(temp2,0.1)
	EndIf
	
	; Movement
	If KeyDown(17) Then MoveEntity camera,0,0,1  ;W
	If KeyDown(31) Then MoveEntity camera,0,0,-1 ;S
	If KeyDown(30) Then MoveEntity camera,-1,0,0 ;A
	If KeyDown(32) Then MoveEntity camera,1,0,0  ;D

	UpdateWorld
	RenderWorld
	Text 0,0,fps()


	Flip 0
Wend
End

;--------------------------------------------------------------------------------------------

Function UpdateSprites()
;	For l.layer=Each layer
;		surf=GetSurface(l\mesh,1)
		
;		For i=0 To l\count-1
	
;			s.sprite = Object.sprite( PeekInt(l\spritebank,i*4) )


		For s.sprite=Each sprite
			TFormPoint s\x,s\y,s\z,0,camera
			
			If TFormedZ#()>0
					
				TFormVector -s\s,-s\s,0,camera,0 
				VertexCoords s\surf,s\verti[0],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()
				
				TFormVector s\s,-s\s,0,camera,0 
				VertexCoords s\surf,s\verti[1],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()

				TFormVector -s\s,s\s,0,camera,0 
				VertexCoords s\surf,s\verti[2],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()
	
				TFormVector s\s,s\s,0,camera,0 
				VertexCoords s\surf,s\verti[3],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()
			
			EndIf
		Next
			
;	Next
End Function

;--------------------------------------------------------------------------------------------

Function CreateLayer()
	l.layer=New layer	
	l\mesh=CreateMesh() : surf=CreateSurface(l\mesh)
;	l\spritebank=CreateBank()
	NameEntity l\mesh,Handle(l)
	EntityColor l\mesh,255,255,255
	EntityFX l\mesh,1+32
	EntityBlend l\mesh,3
	Return l\mesh
End Function

;--------------------------------------------------------------------------------------------

Function AddSprite(mesh)
	l.layer=Object.layer(EntityName(mesh))
	surf=GetSurface(l\mesh,1)
;	l\count=l\count+1
	;ResizeBank l\spritebank,l\count*4
	
	;create a new sprite
	s.sprite=New sprite
	
	s\verti[0]=AddVertex(surf,0,0,0,0,1) ;topleft
	s\verti[1]=AddVertex(surf,0,0,0,1,1) ;topright
	s\verti[2]=AddVertex(surf,0,0,0,0,0) ;bottomleft
	s\verti[3]=AddVertex(surf,0,0,0,1,0) ;bottomright
	
	AddTriangle(surf,s\verti[1],s\verti[2],s\verti[3])
	AddTriangle(surf,s\verti[2],s\verti[1],s\verti[0])
	s\s=10 : s\a=1
	s\r=255 : s\g=255 : s\b=255
	s\x=0 : s\y=0 : s\z=0
	s\surf=surf
	
	;put the new sprite into the bank
;PokeInt l\spritebank,(l\count*4)-4,Handle(s)
	Return Handle(s)
End Function
;--------------------------------------------------------------------------------------------

Function AlphaSprite(sprite,Alpha#)
	s.sprite = Object.sprite(sprite)
	
	VertexColor s\surf,s\verti[0],s\r,s\g,s\b,Alpha#
	VertexColor s\surf,s\verti[1],s\r,s\g,s\b,Alpha#
	VertexColor s\surf,s\verti[2],s\r,s\g,s\b,Alpha#
	VertexColor s\surf,s\verti[3],s\r,s\g,s\b,Alpha#
End Function

;--------------------------------------------------------------------------------------------
Function PositionSprite(sprite,x#,y#,z#)
	s.sprite = Object.sprite(sprite)
	s\x=x
	s\y=y
	s\z=z
End Function

;--------------------------------------------------------------------------------------------

Function fps()
	fpsindex=fpsindex+1
	fpstime=fpstime+MilliSecs()-fpsfold_millisecs
	If fpstime=>1000
		fpsfps=fpsindex
		fpstime=0
		fpsindex=0
	EndIf
	fpsfold_millisecs=MilliSecs()
	Return fpsfps
End Function

;--------------------------------------------------------------------------------------------

Function TransTex(texture,angle#,scale#=1)
	ScaleTexture texture,scale,scale
	RotateTexture texture,angle#
	x#=Cos(angle)/scale/2
	y#=Sin(angle)/scale/2
	PositionTexture texture,(x-.5)-y,(y-.5)+x
End Function



;--------------------------------------------
; M O U S E L O O K
;
; Parms: 
; Cam   - Camera
; T     - Current timer
; Time1 - Last time event ran
; Freq  - How often in milliseconds this function runs
Function Mouselook(Cam,T,Time1,Freq)

If T > Time1 + Freq Then
	Time1=T
	
	If MouseDown(2) Then 

		TurnEntity cam,MouseYSpeed(),-MouseXSpeed(),0
		RotateEntity cam,EntityPitch(cam), EntityYaw(cam),0
		MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

	EndIf
EndIf
Return Time1

End Function



Well, i think in a single surface code, you shouldn't really try and delete sprites. Since, you will need to re-build the entire surfaces again. Best to just hide it and mark it for non-use, until you need to spawn a new sprite.

As for hiding a sprite, simply get all the four verticex and use vertex alpha on them, via the vertexcolor command :o)

I have try to make this function but don't work :(

I haite single surface system :/

Function AlphaSprite(sprite,Alpha#)
s.sprite = Object.sprite(sprite)

VertexColor s\surf,s\verti[0],s\r,s\g,s\b,Alpha#
VertexColor s\surf,s\verti[1],s\r,s\g,s\b,Alpha#
VertexColor s\surf,s\verti[2],s\r,s\g,s\b,Alpha#
VertexColor s\surf,s\verti[3],s\r,s\g,s\b,Alpha#
End Function

I have find it's the entityfx the problem :/ must be 2+32

Oh yeah, you must have that to enable the vertex alpha. Sorry ^_^

You should simply position the unused sprite outside the camera range.

Even when not visible vertex alpha 0 quads seems to slow down quite a bit when directly in front of the camera. Strange I know but this is what I've experienced.

Stevie

Ok many thanks :)

Or you can simply place all the vertices for the quad/sprite at a single point and it will not appear, or you could move them out of the view of the camera (behind).

Filax, now the z-order is all messed up by using flag 2! =(

Ok :)

REMOVE THIS

Remove what?

filax did you get the z-order thing fixed?

you might want to test alpha based hiding - im pretty sure
when i looked at this a while back - it only worked when you
used entity alpha - vertex alpha does not prevent the data
being processed..which results in card processing & rejecting
or whatever it does with alpha 0 triangles..
Worst case - the card blends the quad triangles - wasting
gfx processor time on unseen geom..
Also transparent surfaces are subject to sorting..another
slow down..
I very much doubt that mark has a mechanism built in to
determine if all the verts have alpha 0!

the simplest solution as stated above - move the quad to
some insane position - far outside of the view range..
this will result in it being culled..quick n easy..


- dont assume anything ;)

It won't be culled. Single surface renders everything in that mesh no matter where it is. I've tried it and the Tris count does not go down.

Chroma - b3d will report the tri as being rendered yes..
but infact the card will cull it..b3d reports all the tris in a
mesh..when the mesh is in view..it does not and cannot
determine which tris are culled by the card without
intensive software processing..
When tris are rendered they will be clipped by the gfx
card based on the viewing frustrum...per tri..
Dont confuse whats going on in software with whats going
on in hardware..

Well that's excellent news then. That means if you want to hide a single surface quad then you could place it at say -50000 on the y axis and it would not be drawn correct?

assuming the tri/quad is not within the viewing frustrum, it
will be culled by the hardware - so yes...

for large complicated meshes leaving this to gfx card is not
a good idea - blitz uses bounding volumes to ensure that
only meshes in view are sent to gfx card for drawing..the
card then determines which tris will be rendered..

Keeping this in mind - one single single surface for all your
particles may not be a good idea - instead you might
want to consider clusters - consider the max number
particles needed for your fx + create single surface
groups. When you alter the position of one quad in
mesh..the entire mesh is uploaded to the card..nastey..
this is not good, to be fair this will happen only once
per render when you are using a single mesh to store
your particles. BUT..if the number particles is too high,
you will cause a stall. Not that this wont happen with
clusters..but you lessen the chances of the stall, you
probably wont be using all the clusters at the same time.

Note:- you dont need to have create all your quads
for a surface before you start - adding tris isnt
expensive..3 points are uploaded..
editing vertex data causes the entire surface/mesh
to be uploaded..this can be expensive..

you might want to try clusters vs one large surface..

Good advice. May even have a seperate surface for each emittor or area, depending on the particle count.

A good way to make sure the quad is out of view, is to take the cameras position and place the quad behind it, or just outside the camera views range, as long as your co-ords are relative to the cameras, to be doubly sure your camera won't see the hidden particles. I wasn't actually aware that the vertex alpha didn't stop the quad from being rendered. Thanks :o)

Good advice. May even have a seperate surface for each emittor or area, depending on the particle count.

A good way to make sure the quad is out of view, is to take the cameras position and place the quad behind it, or just outside the camera view range, as long as your co-ords are relative to the cameras, to be doubly sure your camera won't see the hidden particles. I wasn't actually aware that the vertex alpha didn't stop the quad from being rendered. Thanks :o)

Hi !

Thanks for reply's guys ! i have get a good french single
surface library here is the code : But i have alway my
Zorder problem :( i have try sort method from code archive
(fredborg etc) but nothing work with this library ???

If anybody can help me ? i'll give a TerraEd pro licence
to the guy wo can solve Zorder problem :)

Here is the particle sprite used :


; --------------------------
; Create SSE layer
; --------------------------
Type SSE_Layer
	Field Surface
	Field Mesh
	Field Parent
	Field Effect
	Field Blend
End Type

; ---------------------------
; Create SSE emiter
; ---------------------------
Type SSE_Emitter
	Field Pivot
	
	Field Px#
	Field Py#
	Field Pz#
End Type

; --------------------------
; Create SSE entity
; --------------------------
Type SSE_Entity
	Field Surface
	Field Parent
	
	Field Px#
	Field Py#
	Field Pz#
	
	Field Rotate_Z#
	
	Field Scale_X#
	Field Scale_Y#
	
	Field Move_x#
	Field Move_y#
	Field Move_z#
	
	Field Red
	Field Green
	Field Blue
	
	Field Alpha#
	
	Field Show
	Field Draw

	Field UV_Ud#
	Field UV_Uf#
	Field UV_Vd#
	Field UV_Vf#
End Type

; --------------------
; Create a layer
; --------------------
Function SSE_CreateLayer(Texture$,Blend=3)
	L.SSE_Layer=New SSE_Layer

	L\Mesh=CreateMesh()
	L\Surface=CreateSurface(L\Mesh)
	L\Parent=0

	L\Effect=1+2+8+16+32
	L\Blend=Blend

	EntityFX L\Mesh,L\Effect
	EntityBlend L\Mesh,L\Blend

	Local_Texture=LoadTexture (Texture$,1+2+256)
	EntityTexture L\Mesh,Local_Texture,0,0
	FreeTexture Local_Texture

	Return Handle(L)
End Function

; -----------------------------------------------
; Retrieve the surface from a layer
; -----------------------------------------------
Function SSE_GetLayerSurface(layer)
	L.SSE_Layer=Object.SSE_Layer(layer)
	Return L\Surface
End Function

; --------------------------------------------
; Retrieve the mesh from a layer
; --------------------------------------------
Function SSE_GetLayerMesh(layer)
	L.SSE_Layer=Object.SSE_Layer(layer)
	Return L\Mesh
End Function

; ---------------------------------
; Create an SSE particle
; ---------------------------------
Function SSE_CreateParticule(Surface,Parent=False,ScaleX#=1,ScaleY#=1,Blend=3,Alpha#=1,Red=255,Green=255,Blue=255)
	SSE_Particle.SSE_Entity=New SSE_Entity
	SSE_Particle\Surface=Surface
	
	SSE_Particle\Show=1
	SSE_Particle\Draw=0
	
	SSE_Particle\Px#=0.0
	SSE_Particle\Py#=0.0
	SSE_Particle\Pz#=0.0
		
	SSE_Particle\Rotate_Z#=0.0
	
	SSE_Particle\Scale_X#=ScaleX#
	SSE_Particle\Scale_Y#=ScaleY#
	
	SSE_Particle\Red=Red
	SSE_Particle\Green=Green
	SSE_Particle\Blue=Blue
	SSE_Particle\Alpha#=Alpha#
	
	SSE_Particle\UV_Ud#=0.0
	SSE_Particle\UV_Uf#=1.0
	SSE_Particle\UV_Vd#=0.0
	SSE_Particle\UV_Vf#=1.0

	SSE_Particle\Parent=Parent
		
	Return Handle(SSE_Particle)
End Function

; -----------------------
; Get a particle X
; -----------------------
Function SSE_GetParticuleX#(Part)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	Return SSE_Particle\Px#
End Function

; -----------------------
; Get a particle Y
; -----------------------
Function SSE_GetParticuleY#(Part)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	Return SSE_Particle\Py#
End Function

; -----------------------
; Get a particle Z
; -----------------------
Function SSE_GetParticuleZ#(Part)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	Return SSE_Particle\Pz#
End Function

; --------------------------
; Position a particle
; --------------------------
Function SSE_PositionParticule(Part,Px#,Py#,pz#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Px#=Px#
	SSE_Particle\Py#=Py#
	SSE_Particle\Pz#=Pz#
End Function

; ---------------------------
; Translate a particle
; ---------------------------
Function SSE_TranslateParticule(Part,tx#,ty#,tz#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Px#=SSE_Particle\Px#+tx#
	SSE_Particle\Py#=SSE_Particle\Py#+ty#
	SSE_Particle\Pz#=SSE_Particle\Pz#+tz#
End Function

; ---------------------
; Move a particle
; ---------------------
Function SSE_MoveParticule(Part,Px#,Py#,Pz#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	
	SSE_Particle\Px#=SSE_Particle\Px#+ ( Px#*Cos(SSE_Particle\Move_y#)*Cos(SSE_Particle\Move_z#) -Pz#*Sin(SSE_Particle\Move_y#) -Py#*Sin(SSE_Particle\Move_z#) )
	SSE_Particle\Py#=SSE_Particle\Py#+ ( PY#*Cos(SSE_Particle\Move_x#)*Cos(SSE_Particle\Move_z#) -Pz#*Sin(SSE_Particle\Move_x#) -Px#*Sin(SSE_Particle\Move_z#) )
	SSE_Particle\Pz#=SSE_Particle\Pz#+ ( Pz#*Cos(SSE_Particle\Move_y#)*Cos(SSE_Particle\Move_x#) -Px#*Sin(SSE_Particle\Move_y#) -Py#*Sin(SSE_Particle\Move_x#) )
End Function

; ----------------------
; Scale a particle
; ----------------------
Function SSE_ScaleParticule(Part,Scale_X#,Scale_Y#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Scale_X#=Scale_X#
	SSE_Particle\Scale_Y#=Scale_Y#
End Function

; --------------------
; Roll a particle
; --------------------
Function SSE_Turn2DParticule(Part,Rotate_Z#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Rotate_Z#=Rotate_Z#+SSE_Particle\Rotate_Z#
End Function

; --------------------------
; Rotate Z a particle
; --------------------------
Function SSE_Rotate2DParticule(Part,Rotate_Z#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Rotate_Z#=Rotate_Z#
End Function

; ------------------------------
; Rotate XYZ a particle
; ------------------------------
Function SSE_RotateParticule(Part,Rotate_X#,Rotate_Y#,Rotate_Z#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Move_X#=Rotate_X#
	SSE_Particle\Move_Y#=Rotate_Y#
	SSE_Particle\Move_Z#=Rotate_Z#
End Function

; --------------------
; Turn a particle
; --------------------
Function SSE_TurnParticule(Part,Rotate_X#,Rotate_Y#,Rotate_Z#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Move_x#=Rotate_X#+SSE_Particle\Move_x#
	SSE_Particle\Move_y#=Rotate_Y#+SSE_Particle\Move_y#
	SSE_Particle\Move_z#=Rotate_Z#+SSE_Particle\Move_z#
End Function

; ---------------------
; Free a particle
; ---------------------
Function SSE_FreeParticule(Part)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	Delete SSE_Particle
End Function

; ---------------------
; Color a particle
; ---------------------
Function SSE_ParticuleColor(Part,Red,Green,Blue)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Red=Red
	SSE_Particle\Green=Green
	SSE_Particle\Blue=Blue
End Function

; --------------------
; Particle alpha
; --------------------
Function SSE_ParticuleAlpha(Part,Alpha#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\Alpha#=Alpha#
End Function

; ------------------
; Particle hide
; ------------------
Function SSE_HideParticule(Part,State)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)

	Select State
	Case True
		SSE_Particle\Show=0
	Case False 
		SSE_Particle\Show=1
	End Select
End Function

; ----------------------------------------
; Define manualy particle UV
; ----------------------------------------
Function SSE_SetParticleUV(Part,UV_Ud#,UV_Uf#,UV_Vd#,UV_Vf#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	SSE_Particle\UV_Ud#=UV_Ud#
	SSE_Particle\UV_Uf#=UV_Uf#
	SSE_Particle\UV_Vd#=UV_Vd#
	SSE_Particle\UV_Vf#=UV_Vf#
End Function

; ---------------------------------------------------------------------------------------------
; You can from a strip picture, define a piece of picture via number
; ---------------------------------------------------------------------------------------------
Function SSE_SetUVMatrix(Part,Size_X=1,Size_Y=1,Value=0)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	
	If Value>((Size_X*Size_Y)-1) Then 
		Return 0
	Else 
		Local_Z#=Ceil((Value+1)/Float(Size_X))-1
		
		If Size_X>1 Then
			SSE_Particle\UV_Vd#=Local_Z#/Float(Size_Y)
			SSE_Particle\UV_Vf#=(Local_Z#+1)/Float(Size_Y)
		Else
			SSE_Particle\UV_Vd#=0.0
			SSE_Particle\UV_Vf#=1.0
		EndIf
		
		If Size_Y>1 Then
			SSE_Particle\UV_Ud#=(Value Mod Size_X)/Float(Size_X)
			SSE_Particle\UV_Uf#=(1+(Value Mod Size_X))/Float(Size_X)
		Else
			SSE_Particle\UV_Ud#=0.0
			SSE_Particle\UV_Uf#=1.0
		EndIf
	
		Return True
	EndIf
End Function

; -----------------------------------------------------------------------------------------------------------------
; Same from above but only for lines strip image, example with a 128*64 texture
;
; MyLayer2=SSE_CreateLayer("Particle.png")
; Surface2=SSE_GetLayerSurface(MyLayer2)
;
; Pivot2=CreatePivot() : PositionEntity pivot2,150,0,0
;
; For i=0 To 100
;	Temp3=SSE_CreateParticule(Surface2,pivot2)
;	SSE_PositionParticule(Temp3,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100))
;	SSE_ScaleParticule(Temp3,20,20)
;	SSE_ParticuleColor(Temp3,Rnd(255),Rnd(255),Rnd(255))
;	SSE_SetUVLine(Temp3,2,1,Rand(0,1)) ; swap between image 1 and 2
; Next
; -----------------------------------------------------------------------------------------------------------------
Function SSE_SetUVLine(Part,Size_X,Size_Y,Value#)
	SSE_Particle.SSE_Entity=Object.SSE_Entity(Part)
	
	If (Size_X>1 And Size_Y>1) Then
		Return -1
	Else If Value#>((Size_X*Size_Y)-1)Then
		Return 0
	EndIf
	
	If Size_X>1 Then
		SSE_Particle\UV_Ud#=Value#/Float(Size_X)
		SSE_Particle\UV_Uf#=(Value#+1)/Float(Size_X)
		SSE_Particle\UV_Vd#=0.0
		SSE_Particle\UV_Vf#=1.0
	Else
		SSE_Particle\UV_Ud#=0.0
		SSE_Particle\UV_Uf#=1.0
		SSE_Particle\UV_Vd#=Value#/Float(Size_Y)
		SSE_Particle\UV_Vf#=(Value#+1)/Float(Size_Y)
	EndIf
	
	Return 1
End Function


; ----------------------------------
; Refresh particle system
; ----------------------------------
Function SSE_RefreshParticule(camera,zoom#=1)
	For L.SSE_Layer=Each SSE_Layer
		Local_Number=0
		
		ClearSurface L\Surface;on nettoie la Surface viser
	
		For SSE_Particle.SSE_Entity=Each SSE_Entity
	
			If  SSE_Particle\Show=1 And SSE_Particle\Surface=L\Surface Then 
				SSE_Particle\Draw=0
	
				If (SSE_Particle\parent=0) Then
						
				Local_X#=SSE_Particle\Px#
				Local_Y#=SSE_Particle\Py#
				Local_Z#=SSE_Particle\Pz#
			Else
				TFormPoint SSE_Particle\Px#,SSE_Particle\Py#,SSE_Particle\Pz#,SSE_Particle\Parent,0
				
				Local_X#=TFormedX()
				Local_Y#=TFormedY()
				Local_Z#=TFormedZ()
			EndIf
				
				
				Scale_X#=SSE_Particle\Scale_X#
				Scale_Y#=SSE_Particle\Scale_Y#
					
				Rotate_Z#=SSE_Particle\Rotate_Z#
				
				TFormPoint Local_X#,Local_Y#,Local_Z#,0,camera
				
				If TFormedZ#()>0 Then ;verifie que la Particule se trouve devant la camera
					
					If TFormedX#()<TFormedZ#()/zoom# And TFormedX#()>-TFormedZ#()/zoom# And TFormedY#()<TFormedZ#()*.75/zoom# And TFormedY#()>-TFormedZ#()*.75/zoom# Then
						SSE_Particle\Draw=1
					Else
						;on teste la position des 4 vertices, si l'un deux, est visible, on dessine
						For p=0 To 3
							Local_Dx#=TFormedX#()+Scale_X#*(Cos(45+90*p + Rotate_Z#)/Cos(45))
							Local_Dy#=TFormedY#()+Scale_Y#*(Sin(45+90*p + Rotate_Z#)/Cos(45))	
							
							If Local_Dx#<TFormedZ#()/zoom# And Local_Dx#>-TFormedZ#()/zoom# And Local_Dy#<TFormedZ#()*.7/zoom# And Local_Dy#>-TFormedZ#()*.7/zoom# Then
								SSE_Particle\Draw=1
								Exit
							EndIf
						Next
						
					EndIf
					
						
				EndIf
				
							
				
				If SSE_Particle\Draw=1 Then
					Local_Tfx#=TFormedX#();savegarde de la position centrale
					Local_Tfy#=TFormedY#()
					Local_Tfz#=TFormedZ#()
									
					For p=0 To 3
						Select p
							Case 0
								Local_U#=SSE_Particle\UV_Uf#
								Local_V#=SSE_Particle\UV_Vd#
							Case 1
								Local_U#=SSE_Particle\UV_Ud#
								Local_V#=SSE_Particle\UV_Vd#
							Case 2
								Local_U#=SSE_Particle\UV_Ud#
								Local_V#=SSE_Particle\UV_Vf#
							Case 3
								Local_U#=SSE_Particle\UV_Uf#
								Local_V#=SSE_Particle\UV_Vf#
						End Select
						
						Local_Dx#=Scale_X#*(Cos(45+90*p + Rotate_Z#)/Cos(45))
						Local_Dy#=Scale_Y#*(Sin(45+90*p + Rotate_Z#)/Cos(45))	
						
						TFormPoint Local_Tfx#+Local_Dx#,Local_Tfy#+Local_Dy#,Local_Tfz#,camera,0
			
						AddVertex(SSE_Particle\Surface,TFormedX#(),TFormedY#(),TFormedZ#(),Local_U#,Local_V#)
						VertexColor(SSE_Particle\Surface,p+Local_Number,SSE_Particle\Red,SSE_Particle\Green,SSE_Particle\Blue,SSE_Particle\Alpha#) 	
					Next
	
					AddTriangle(SSE_Particle\Surface,1+Local_Number,0+Local_Number,2+Local_Number)
					AddTriangle(SSE_Particle\Surface,2+Local_Number,0+Local_Number,3+Local_Number)
					
					Local_Number=Local_Number+4
				EndIf
			
				
			EndIf

Next

	Next


	
	Return Local_Number/4
End Function


And an example with Zorder problem :

;=====================================================================
;Module "Single Surface"
;Pour BlitzKlan (http://blitzklan.free.fr)
;Par GIGNOPS (gignops@...) modifs par Filax
;Ce module sert à gerer une Scale_Ysteme de Particule en single Surface
;V1.0 05/05/2005
;======================================================================

Global fpsindex#,fpstime#,fpsfold_millisecs#,fpsfps#,time,xyzturn

Include "SSEngine.bb"

Graphics3D 1024,768,32,0
SetBuffer BackBuffer()


Global camera=CreateCamera()
CameraRange camera,1,9000
PositionEntity camera,0,0,-100

light=CreateLight(2)
PositionEntity light,100,100,100



MyLayer1=SSE_CreateLayer("Particle.png",1)
Surface1=SSE_GetLayerSurface(MyLayer1)
DebugLog "> : "+Surface1

pivot1=CreatePivot()
PositionEntity pivot1,-250,0,0

For i=0 To 1000
Temp3=SSE_CreateParticule(Surface1,pivot1)
SSE_PositionParticule(Temp3,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100))
SSE_ScaleParticule(Temp3,5,5)
SSE_ParticuleColor(Temp3,Rnd(255),Rnd(255),Rnd(255))
SSE_SetUVLine(Temp3,3,1,0)
Next


pivot2=CreatePivot() : PositionEntity pivot2,250,0,0

For i=0 To 1000
	Temp3=SSE_CreateParticule(Surface1,pivot2)
	SSE_PositionParticule(Temp3,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100))
	SSE_ScaleParticule(Temp3,10,10)
	SSE_ParticuleColor(Temp3,Rnd(255),Rnd(255),Rnd(255))
	SSE_SetUVLine(Temp3,3,1,1)
Next

pivot3=CreatePivot() : PositionEntity pivot3,500,0,0

For i=0 To 1000
	Temp3=SSE_CreateParticule(Surface1,pivot3)
	SSE_PositionParticule(Temp3,Rnd(-100,100),Rnd(-100,100),Rnd(-100,100))
	SSE_ScaleParticule(Temp3,10,10)
	SSE_ParticuleColor(Temp3,Rnd(255),Rnd(255),Rnd(255))
	SSE_SetUVLine(Temp3,3,1,2)
Next



While Not KeyHit(1)

SSE_RefreshParticule(camera,1)

mouselook(camera)
	TurnEntity pivot1,0.1,0.1,0.1
	TurnEntity pivot2,-0.1,0.1,0.1

	If MouseHit(3) Then

	EndIf
	
	If KeyDown(17) Then MoveEntity camera,0,0,1  ;W
	If KeyDown(31) Then MoveEntity camera,0,0,-1 ;S
	If KeyDown(30) Then MoveEntity camera,-1,0,0 ;A
	If KeyDown(32) Then MoveEntity camera,1,0,0  ;D
	
	UpdateWorld
	RenderWorld

	Text 10,10,fps()
	Flip 0
Wend

End

Function fps()
	fpsindex=fpsindex+1
	fpstime=fpstime+MilliSecs()-fpsfold_millisecs
	If fpstime=>1000
		fpsfps=fpsindex
		fpstime=0
		fpsindex=0
	EndIf
	fpsfold_millisecs=MilliSecs()
	Return fpsfps
End Function



;--------------------------------------------
; M O U S E L O O K
;
; Parms: 
; Cam   - Camera
; T     - Current timer
; Time1 - Last time event ran
; Freq  - How often in milliseconds this function runs
Function Mouselook(Cam)


	
	If MouseDown(2) Then 

		TurnEntity cam,MouseYSpeed(),-MouseXSpeed(),0
		RotateEntity cam,EntityPitch(cam), EntityYaw(cam),0
		MoveMouse GraphicsWidth()/2,GraphicsHeight()/2

	EndIf



End Function


> Delete a sprite
> Hide a sprite

I switched to rebuilding the mesh each frame. Didn't notice any performance issues and I didn't have to worry about hiding\removing sprites. Nor did I have to set a maximum number of sprites (other than the limit to the number of triangle in a surface).

Any idea for Zorder problem ? (sprite behind other's) ?

Hi filax
I don't have the time to check all of the thread so I am not sure if this is your solution:
My single surface system (Quads) works like that...
a) load Quads
b) scale them
c) position them (xy & z)
d) show them
Now in the loop when one Quad shall move in front of the other...
scale it proportional to the z-distance while positioning it
Function QuadImagePosition(THdl,x#,y#,z#)
	iscale#=z/512.0
	qs.QuadImage=Object.QuadImage(THdl)
	ScaleEntity qs\mesh, iscale#*qs\scalex#, iscale#*qs\scaley#, 1.0
	PositionEntity qs\mesh, 10000+x#*iscale#-(512*iscale#), -y#*iscale#+(384*iscale#), z#, True
End Function

Function QuadImageScaleXY#(THdl,xy#,Relative=False)
	qs.QuadImage=Object.QuadImage(THdl)
	If Relative=True
		qs\ScaleX#=qs\ScaleX#*xy#
		qs\ScaleY#=qs\ScaleY#*xy#
	Else
		qs\ScaleX#=xy#
		qs\ScaleY#=xy#
	EndIf
	iscale#=qs\z#/512.0
	ScaleEntity qs\mesh, iscale#*qs\ScaleX#, iscale#*qs\ScaleY#, 1.0
	Return qs\ScaleY#
End Function

That I add 10000 to x# has the reason, that my surface system is positioned to be viewed by a second camera unseen from the main camera ...
So I have a 3D-scenery and the animated Quads are always in front of it...
This Quad-System is 1024x768 pixelperfect
For more info, if you have questions or want to check the complete Quad System, email me (am not so often checking in here anymore)

?? Sorry i don't understand, my problem come from my
sprite Zorder, there are refresh from the order creation !

I think a solution is to sort the sprite list with a method
to sort them with a distance => camera (addfirst & addlast)
but all my tests are bugged :( if anybody can help me with
this, i'll give to the winner a TerraEd Pro :)

Your Function AddSprite above is nearly the same as my Function QuadCreate ...
So what you are using are not typical Sprites but Single Surfaces ... or Quads or Billboards (or whatever you may call them)
And it doesn't help to make a list order without changing each z-distance ... because if they are all on the same z-distance they look scrambled anyway, because they overlap and partly flicker depending on the camera angle...
You only need to change the z-distance for each Quad (Sprite). Quads which should appear behind others are futher away - no Quad should have the same z-distance. But then the size they appear on the screen is changing as well ... as further away as smaller they are and you have to react on that by scaling them bigger as further they are away.
That's what my Functions do ... they scale depending on the screen resolution (in the example functions 1024x786) .. so in the end they are always pixel perfect in size and position... and the z-distance quasi is the z-order

Hi :)

Thanks for reply ! But, if i understand your function
your quad are made with a function, and this function
return a 'mesh' (like a sprite) and i can't use this
because in a particle engine imagine you have 8000 quad
entity ! Under my lib you have only one mesh with dynamic
vertex and triangle creation, it's not the same thing !
i have only one entity ! All my vertex are stored under
the list, imo the solution is to sort the list from the
distance between my vertex => camera ?? Maybe i'm wrong ?
but i become crazy with this stuff :/

Hi filax

Under my lib you have only one mesh with dynamic vertex and triangle creation, it's not the same thing !

It looks the same thing to me...

All my vertex are stored under the list, imo the solution is to sort the list from the distance between my vertex => camera ?? Maybe i'm wrong ?
but i become crazy with this stuff :/

There is no difference if the surfaces are one mesh or several meshes ... besides the performance is much better if they are connected to one mesh as it is in the case you mention.
The solution stays the same. No extra sorting needed - just changing z-distance between each vertex to camera and position them after a pseudo-x-y-scaling.
The only difference is, you need (4 times ?) more calculations instead of the two in my function - but this is nearly not measurable fast and should cause no problem.
Its worth a try I'd say.