Single Surface! AHHG!!

Blitz3D Forums/Blitz3D Programming/Single Surface! AHHG!!

Neochrome(Posted 2008) [#1]
Im having trouble with the single surface sprite system!



as you can see in this example! the sprites appear to be in the wrong order!

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

Type layer
	Field mesh
	Field count
	Field spritebank ; pointer to a type just for holding a list of sprites
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 ("fire.png",2+48)

Global 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

;--------------------------------------------------------------------------------------------
HidePointer
While Not KeyHit(1)
	MoveEntity camera,0,0,MouseZSpeed()*10
	mxspd#=MouseXSpeed()*.2
	myspd#=MouseYSpeed()*.2
	MoveMouse GraphicsWidth()/2,GraphicsHeight()/2
	TurnEntity camera,myspd,-mxspd,0

	TransTex(fire,MilliSecs()*0.08)

;virtexnormals 
	UpdateSprites()
	UpdateWorld
	RenderWorld
	Text 0,0,fps()
	Flip 0
Wend
End

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

Function UpdateSprites()
	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#()
			VertexNormal 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#()
			VertexNormal 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#()
			VertexNormal 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#()
			VertexNormal s\surf,s\verti[3],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()


		EndIf
	Next
	UpdateNormals test
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
	EntityBlend l\mesh,1
	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 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
;--------------------------------------------------------------------------------------------

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



HELP ME!!! PLEASE!
this is driving me up the wall :(

Thanks guys


Danny(Posted 2008) [#2]
when you create your own polygons and have alpha blending enabled, then blitz3D decides not to perform Z-sorting anymore. Causing them to near-randomly appear infront/behind each other. The only solution is to manually sort each 'sprite' according to it's distance to the camera - oh joy to the world!

Search the forums for 'alpha sort' or 'Z-sort' and you'll find countless threads and related topics. You probably can find some examples in the code archives as well (not sure though).

Good luck,
D.


Neochrome(Posted 2008) [#3]
there not working :(


Neochrome(Posted 2008) [#4]
Ok, i figured that i need to loop the funciton!

loop

init zorder
update zorder
free zorder

end


THIS WORKED! well enough for what i need anyways :)


Beaker(Posted 2008) [#5]
That doesn't look right. Where is the end of the loop? You shouldn't need to "init zorder" and "free zorder" every loop!


Stevie G(Posted 2008) [#6]
TFormVector -s\s,-s\s,0,camera,0 
			VertexCoords s\surf,s\verti[0],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()
			VertexNormal 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#()
			VertexNormal 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#()
			VertexNormal 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#()
			VertexNormal s\surf,s\verti[3],s\x+TFormedX#(),s\y+TFormedY#(),s\z+TFormedZ#()


You can reduce this to 2 x tformvectors if your quads are always square. Should make it a good bit faster with lots of particles.

p\size = size of particle ( assume square )
;p\Vertex = First vertex of 4 For this quad
;p\Pos = 3d coords of particle
;s = surface of particle mesh

;point quad to face the camera
TFormVector -p\size,0,0, Camera , 0
x1# = TFormedX()
y1# = TFormedY()
z1# = TFormedZ()
TFormVector 0,-p\size,0,Camera, 0
x2# = TFormedX()
y2# = TFormedY()
z2# = TFormedZ()
VertexCoords s, p\Vertex + 0 , p\Pos\x - x1 - x2 , p\Pos\y - y1 - y2 , p\Pos\z - z1 - z2
VertexCoords s, p\Vertex + 1 , p\Pos\x - x1 + x2 , p\Pos\y - y1 + y2 , p\Pos\z - z1 + z2
VertexCoords s, p\Vertex + 2 , p\Pos\x + x1 + x2 , p\Pos\y + y1 + y2 , p\Pos\z + z1 + z2
VertexCoords s, p\Vertex + 3 , p\Pos\x + x1 - x2 , p\Pos\y + y1 - y2 , p\Pos\z + z1 - z2


Also, no reason to be using updatenormals, or even setting each normal for each vertex every frame for that matter. As the quad is pointing to the camera then you can preset each vertex normal to 0,0,-1.

Stevie.


Neochrome(Posted 2008) [#7]
i should need to loop

Init,
Do
Free

but i have to! :(

repeat
initzorder
zorder
freeorder
forever

just ZORDER calling doesn't work :( it works once, but it isn't accurate :(


Beaker(Posted 2008) [#8]
Oh I see. You are animating your mesh. Zorder wasn't designed for that.


Neochrome(Posted 2008) [#9]
i've noticed! lol...
its ok tho... i've found that it works if you create, update, free and do it again

i found that once every 6 or 7 frames is enough.. im not running LOADS of particles so its perfect :)


although it would be cool if i could use a DESIGNED FOR system :)
but this function works well enough ...

is there any memory leaks i should be aware of? i've gone over the code and it looks pretty tight

Thanks again tho Beaker :)


Bobysait(Posted 2008) [#10]
Also, no reason to be using updatenormals, or even setting each normal for each vertex every frame for that matter. As the quad is pointing to the camera then you can preset each vertex normal to 0,0,-1.

Stevie.

As The Layer is setted to EntityFx 1, it just does not need Normal coords at all ^^

whatever, for a SS engine, you'd better use EntityBlend/TextureBlend with LightBlend mode, rather than using an alpha texture.
+> Then, the ZOrder will be preserved.


Stevie G(Posted 2008) [#11]

As The Layer is setted to EntityFx 1, it just does not need Normal coords at all ^^



True, I never noticed that.