News:

Building a 3D Ray Tracer  By stevmjon

Main Menu

PlayBasicFX Screen Shot Updates

Started by kevin, February 16, 2007, 11:45:46 AM

Previous topic - Next topic

kevin

#15
Sprite Perspective

  The following pic's are an extension of the previous entity demos, but this time the sprites are rotating in 3D (XYZ) and being projected and rendered in perspective.




load3Dimage "animal.jpg",1
load3Dimage "particle_white.bmp",2



CreateSprite 1
positionspritexyz 1,400,300,1000
SpriteDrawmode 1,2
SpriteImage 1,1
centerspritehandle 1


SpriteVertexQuantity 1,8
SpriteFaceQuantity 1,8

PokeSpriteVertex 1, 4, 200,0,0
PokeSpriteVertex 1, 5, 300,0,0
PokeSpriteVertex 1, 6, 300,300,0
PokeSpriteVertex 1, 7, 200,300,0

PokeSpriteFaceVerts 1,1,4
PokeSpriteface 1,1,0,4,0,0,$ffff00
PokeSpriteface 1,1,1,5,1,0,$ffff00
PokeSpriteface 1,1,2,6,1,1,$ffffff
PokeSpriteface 1,1,3,7,0,1,$ff00ff



max=1000
For lp=0 to max
me= MakeParticleSprite(2,rnd(800),rnd(600),rndrange(15,25))

positionspritexyz me,rndrange(-800,800),_
rndrange(-800,800),_
rndrange(200,5000)

facecount=facecount+getSpriteFaceQuantity(me)
next



;' SetFps 30

Do
Cls 200

For lp=1 to max
TurnspriteXYZ lp,0.1*(lp/100),0.2,0.15
angle2#=angle#+(lp*5)
SpriteAlphaLevel lp,cosnewvalue(0.5,angle2#,0.5)

z#=GetSpriteZ(lp)-1

if z#<200
z#=5000
endif
PositionspriteZ lp,z#

drawsprite lp
next

; DrawOrderedSprites
; drawallsprites

ink $ffffff
; Scalesprite 2,1+cos(angle#)



f=fps()
print f
angle#=angle#+1
print Screen3dstate()
print FaceCount
print FaceCount*f
Sync
loop 



Function MakeParticleSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)

SpriteDrawMode ThisSprite, 2+16

SpriteVertexQuantity thisSprite,(Points)*4
SpriteFaceQuantity thisSprite,(Points)
angleStep#=360.0/points
size=32

For lp=0 to points-1
angle#=wrapangle(angle#,anglestep#)
Radius#=100
SetVerts(ThisSprite,VertexOffset,Angle#,Radius#,Size,wrapangle(angle#,-45))
SetFace(ThisSprite,ThisFace,VertexOffset,RndRgb())
VertexOffset=VertexOffset+4
inc thisface
next
EndFUnction ThisSPrite


Psub SetVerts(ThisSprite,VertexOffset,Angle#,Radius,Size,Rotation)
CenterX#=CosNewValue(0,angle#,Radius)
CenterY#=SinNewValue(0,angle#,Radius)
For lp=0 to 3
X#=CosNewValue(CenterX#,Rotation,Size)
Y#=SinNewValue(CenterY#,Rotation,Size)
PokeSpriteVertex ThisSprite,VertexOffset+lp,X#,y#,z#
Rotation=wrapangle(Rotation,90)
next
EndPsub


Psub SetFace(ThisSprite,ThisFace,VertexOffset,ThisColour)
PokeSpriteFaceVerts ThisSprite,ThisFace,4
PokeSpriteface ThisSprite,ThisFace,0,VertexOffset+0,0,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,VertexOffset+1,1,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,VertexOffset+2,1,1,ThisColour
PokeSpriteface ThisSprite,ThisFace,3,VertexOffset+3,0,1,ThisColour
EndPsub



NOTE: I doubt this code will functin the same in future versions (versions above PB1.68c) as the pespective calc's are currently hard coded into the mesh translation.

kevin


These are some higher poly count versions.

kevin

#17
Sprites as Terrains perhaps ?

   The following thrown together picture is rendering something resembling a test scene.  In the scene we have a scrolling tiled animal images,  500 alpha addition/rotating perspective sprites entities plus a sprite built into something more like a terrain segment.





load3Dimage "animal.jpg",1
load3Dimage "particle_white.bmp",2
load3Dimage "face.jpg",3
scaleimage 3,2048,2048,1   ; << Huge TEXTURE SIZE



CreateSprite 1
positionspritexyz 1,400,300,1000
SpriteDrawmode 1,2
SpriteImage 1,1
centerspritehandle 1


SpriteVertexQuantity 1,8
SpriteFaceQuantity 1,8

PokeSpriteVertex 1, 4, 200,0,0
PokeSpriteVertex 1, 5, 300,0,0
PokeSpriteVertex 1, 6, 300,300,0
PokeSpriteVertex 1, 7, 200,300,0

PokeSpriteFaceVerts 1,1,4
PokeSpriteface 1,1,0,4,0,0,$ffff00
PokeSpriteface 1,1,1,5,1,0,$ffff00
PokeSpriteface 1,1,2,6,1,1,$ffffff
PokeSpriteface 1,1,3,7,0,1,$ff00ff



max=1000
For lp=0 to max

me= MakeParticleSprite(2,rnd(800),rnd(600),rndrange(10,25))
facecount=facecount+(getSpriteFaceQuantity(me)*2)

positionspritexyz me,rndrange(-1000,1000),_
rndrange(-1000,1000),_
rndrange(150,10000)

SpriteRotationMode me,1
next



terrain= MakePlainSprite(3,rnd(800),rnd(600),64)
SpriteRotationMode terrain,1
positionspritexyz terrain,0,00,10500
spritehandle terrain,0,0
turnspritexyz terrain,30,0,0

TerrainFacecount=getSpriteFaceQuantity(Terrain)

facecount=(facecount)+getSpriteFaceQuantity(Terrain)


Do
tileImage 1,ix,-100,false
ix=mod(ix+1,getimagewidth(1))

For lp=1 to max+2
TurnSpriteXYZ lp,1.11*(lp/(1.0*max)),0,1

z#=GetSpriteZ(lp)-100
if z#<150
z#=10000
endif
PositionspriteZ lp,z#
next

turnspriteXyz terrain,0,0.1,0

DrawAllSprites

ink $ffffff

setcursor 0,0

f=fps()
print f
angle#=angle#+1
print Screen3dstate()
print FaceCount
print FaceCount*f
print TerrainFacecount

Sync
loop 



Function MakeParticleSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)

SpriteDrawMode ThisSprite, 2+16

SpriteVertexQuantity thisSprite,(Points)*4
SpriteFaceQuantity thisSprite,(Points)
angleStep#=360.0/points
size=32

For lp=0 to points-1
angle#=wrapangle(angle#,anglestep#)
Radius#=100
SetVerts(ThisSprite,VertexOffset,Angle#,Radius#,Size,wrapangle(angle#,-45))
SetFace(ThisSprite,ThisFace,VertexOffset,RndRgb())
VertexOffset=VertexOffset+4
inc thisface
next
EndFUnction ThisSPrite


Psub SetVerts(ThisSprite,VertexOffset,Angle#,Radius,Size,Rotation)
CenterX#=CosNewValue(0,angle#,Radius)
CenterY#=SinNewValue(0,angle#,Radius)
For lp=0 to 3
X#=CosNewValue(CenterX#,Rotation,Size)
Y#=SinNewValue(CenterY#,Rotation,Size)
PokeSpriteVertex ThisSprite,VertexOffset+lp,X#,y#,z#
Rotation=wrapangle(Rotation,90)
next
EndPsub


Psub SetFace(ThisSprite,ThisFace,VertexOffset,ThisColour)
PokeSpriteFaceVerts ThisSprite,ThisFace,4
PokeSpriteface ThisSprite,ThisFace,0,VertexOffset+0,0,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,VertexOffset+1,1,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,VertexOffset+2,1,1,ThisColour
PokeSpriteface ThisSprite,ThisFace,3,VertexOffset+3,0,1,ThisColour
EndPsub





Function MakePlainSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)
SpriteDrawMode ThisSprite, 2

SpriteTransparent ThisSprite,on
turnspritexyz thissprite,00,00,00

Points2=(points+1)

Dim Matrix#(POints2,points2)

RadomizeHeightMap(Matrix#(),10000)
SmoothHeightMap(Matrix#(),4)

SpriteVertexQuantity thisSprite,(Points2*POints2)
SpriteFaceQuantity thisSprite,(Points2*Points2)*2


Size=512
HandleX#=-(((points+1.0)/2.0)*size)
HandleZ#=-(((points+1.0)/2.0)*size)

; init vertex
for Ylp=0 to Points
Zpos#=ylp*Size
for Xlp=0 to Points
Xpos#=Xlp*Size
ThisVertex=(Ylp*(points+1))+xlp
ypos#=Matrix#(xlp,ylp)
PokeSpriteVertex ThisSprite,ThisVertex,Xpos#+HandleX#,1000+Ypos#,Zpos#+HandleZ#
next
next

ThisColour=rgb(255,255,255)

; init faces  (UV points U=X in texture space,  V = Y in texture space)
TUstep#=1.0/(points+1)
Tvstep#=1.0/(points+1)

For Ylp=0 to points-1
For Xlp=0 to points-1

CurrentVertexRow =(Ylp*(points+1))+Xlp
NextVertexRow =CurrentVertexRow+(points+1)

PokeSpriteFaceVerts ThisSprite,ThisFace,3

u1#=Xlp*TUstep#
v1#=Ylp*TVstep#

u2#=(Xlp+1)*TUstep#
v2#=Ylp*TVstep#

u3#=(Xlp+1)*TUstep#
v3#=(Ylp+1)*TVstep#

u4#=(Xlp+0)*TUstep#
v4#=(Ylp+1)*TVstep#

PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,CurrentVertexRow+1 ,u2#,v2#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow+1 ,u3#,v3#,ThisColour

inc ThisFace

PokeSpriteFaceVerts ThisSprite,ThisFace,3
PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,NextVertexRow+1 ,u3#,v3#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow ,u4#,v4#,ThisColour
inc ThisFace

next
next

EndFUnction ThisSPrite




` *=----------------------------------------------------------------=*
`                        >> Randomize HeightMap Array <<
` *=----------------------------------------------------------------=*


Function RadomizeHeightMap(Matrix#(),Height)
Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)
For Zlp=1 to Depth-2
For Xlp=1 to Width-2
Matrix#(xlp,zlp)=rnd#(Height)
next xlp
next zlp
Endfunction


` *=----------------------------------------------------------------=*
`                    >> Average Matrix Height <<
` *=----------------------------------------------------------------=*





Function SmoothHeightMap(Matrix#(),passes)

Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)

Dim Temp_HeightMap_Yvalues#(Width,Depth)

For ThisPass=0 To Passes

CopyArray Matrix#(),Temp_HeightMap_Yvalues#()
For Zlp=1 to Depth-1

ZlpF=zlp-1
ZlpB=zlp+1
Width2=Width-1

For Xlp=1 to Width2
xlpL=Xlp-1
xlpR=Xlp+1

yb#=Temp_HeightMap_Yvalues#(xlp,zlp)
yt#=Temp_HeightMap_Yvalues#(xlp,zlpF)
yb#=Temp_HeightMap_Yvalues#(xlp,zlpB)
yl#=Temp_HeightMap_Yvalues#(xlpL,zlp)
yr#=Temp_HeightMap_Yvalues#(xlpR,zlp)

ytl#=Temp_HeightMap_Yvalues#(xlpL,zlpF)
ytr#=Temp_HeightMap_Yvalues#(xlpR,zlpF)
ybl#=Temp_HeightMap_Yvalues#(xlpL,zlpB)
ybr#=Temp_HeightMap_Yvalues#(xlpR,zlpB)

matrix#(xlp,zlp)=(yb#+yt#+yb#+yL#+yr#+ytl#+ytr#+ybl#+ybr#)/9

next xlp
next zlp

next ThisPass
unDim Temp_HeightMap_Yvalues#()

endfunction



Note: This code as written for the PB 1.68 alpha's, it's unlikely to work in future versions of PB.

kevin

#18
    Perspective Sprite Terrain

   This shot creates a 3D terrain using a single entity sprite. The Sprite scene is being rendered with a new test command DrawPerspectiveSprites. Currently this test command requires the user to build and pass in a camera (viewer) structure, since that's the easiest way to test it. In the future it'll just be built in.



Type PBposition
x#,y#,z#
EndType

Type PBProjection
x#,y#
EndType

Type PBCamera
Status
pos as PBPosition
angle as PBPosition
scale as PBPosition
RotationMode
ProjectionMode
Projection as PBProjection
ViewPoint as PBPosition
EndType

  Dim Camera as PBCamera Pointer
  Camera = new PBCamera


Camera.pos.X=0 
Camera.pos.y=0 
Camera.pos.z=0
Camera.Projection.x=400.0
Camera.Projection.Y=300.0
Camera.ViewPoint.X=GetScreenWidth()/2.0 
Camera.ViewPoint.y=GetScreenHeight()/2.0 




load3Dimage "animal.jpg",1
load3Dimage "particle_white.bmp",2
load3Dimage "face.jpg",3
; load3Dimage "particle_white.bmp",3
; scaleimage 3,256,256,1
; scaleimage 2,1024,1024,1
scaleimage 3,2048,2048,1



CreateSprite 1
positionspritexyz 1,400,300,1000
SpriteDrawmode 1,2
SpriteImage 1,1
centerspritehandle 1


SpriteVertexQuantity 1,8
SpriteFaceQuantity 1,8

PokeSpriteVertex 1, 4, 200,0,0
PokeSpriteVertex 1, 5, 300,0,0
PokeSpriteVertex 1, 6, 300,300,0
PokeSpriteVertex 1, 7, 200,300,0

PokeSpriteFaceVerts 1,1,4
PokeSpriteface 1,1,0,4,0,0,$ffff00
PokeSpriteface 1,1,1,5,1,0,$ffff00
PokeSpriteface 1,1,2,6,1,1,$ffffff
PokeSpriteface 1,1,3,7,0,1,$ff00ff


max=100
For lp=0 to max

; if lp<(Max/2)
; me= MakePlainSprite(3,rnd(800),rnd(600),32)
; else
me= MakeParticleSprite(2,rnd(800),rnd(600),rndrange(10,25))
facecount=facecount+(getSpriteFaceQuantity(me)*2)
; endif
;
positionspritexyz me,rndrange(-1000,1000),_
rndrange(-1000,1000),_
rndrange(150,10000)

SpriteRotationMode me,0
; SpriteHandle me,0,0
next

terrain= MakePlainSprite(3,rnd(800),rnd(600),50)
SpriteRotationMode terrain,1
positionspritexyz terrain,0,2000,10500
spritehandle terrain,0,0
turnspritexyz terrain,30,0,0

TerrainFacecount=getSpriteFaceQuantity(Terrain)

facecount=(facecount)+getSpriteFaceQuantity(Terrain)


Do
Cls 200
; tileImage 1,ix,-100,false
ix=mod(ix+1,getimagewidth(1))

For lp=1 to max+2
TurnSpriteXYZ lp,1.11*(lp/(1.0*max)),0,1

z#=GetSpriteZ(lp)-100
if z#<150
z#=10000
endif
PositionspriteZ lp,z#
next

turnspriteXyz terrain,0,0.1,0

; DrawOrderedSprites
; drawallsprites
DrawPerspectiveSprites Camera

ink $ffffff
; Scalesprite 1,1+cos(angle#)


if LeftKey() Then Camera.Pos.X=Camera.Pos.X-10
if RightKey() Then Camera.Pos.X=Camera.Pos.X+10


setcursor 0,0

f=fps()
print f
angle#=angle#+1
; print Screen3dstate()
print FaceCount
print FaceCount*f
print TerrainFacecount
; print getspritex(1)
; print getspritey(1)
print Camera.pos.x
print Camera.pos.y
print Camera.Projection.x
print Camera.Projection.y

Sync
loop 



Function MakeParticleSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)

SpriteDrawMode ThisSprite, 2+16

SpriteVertexQuantity thisSprite,(Points)*4
SpriteFaceQuantity thisSprite,(Points)
angleStep#=360.0/points
size=32

For lp=0 to points-1
angle#=wrapangle(angle#,anglestep#)
Radius#=100
SetVerts(ThisSprite,VertexOffset,Angle#,Radius#,Size,wrapangle(angle#,-45))
SetFace(ThisSprite,ThisFace,VertexOffset,RndRgb())
VertexOffset=VertexOffset+4
inc thisface
next
EndFUnction ThisSPrite


Psub SetVerts(ThisSprite,VertexOffset,Angle#,Radius,Size,Rotation)
CenterX#=CosNewValue(0,angle#,Radius)
CenterY#=SinNewValue(0,angle#,Radius)
For lp=0 to 3
X#=CosNewValue(CenterX#,Rotation,Size)
Y#=SinNewValue(CenterY#,Rotation,Size)
PokeSpriteVertex ThisSprite,VertexOffset+lp,X#,y#,z#
Rotation=wrapangle(Rotation,90)
next
EndPsub


Psub SetFace(ThisSprite,ThisFace,VertexOffset,ThisColour)
PokeSpriteFaceVerts ThisSprite,ThisFace,4
PokeSpriteface ThisSprite,ThisFace,0,VertexOffset+0,0,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,VertexOffset+1,1,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,VertexOffset+2,1,1,ThisColour
PokeSpriteface ThisSprite,ThisFace,3,VertexOffset+3,0,1,ThisColour
EndPsub





Function MakePlainSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)
SpriteDrawMode ThisSprite, 2

SpriteTransparent ThisSprite,on
turnspritexyz thissprite,00,00,00

Points2=(points+1)

Dim Matrix#(POints2,points2)

RadomizeHeightMap(Matrix#(),15000)
SmoothHeightMap(Matrix#(),3)

SpriteVertexQuantity thisSprite,(Points2*POints2)
SpriteFaceQuantity thisSprite,(Points2*Points2)*2


Size=1024
HandleX#=-(((points+1.0)/2.0)*size)
HandleZ#=-(((points+1.0)/2.0)*size)

; init vertex
for Ylp=0 to Points
Zpos#=ylp*Size
for Xlp=0 to Points
Xpos#=Xlp*Size
ThisVertex=(Ylp*(points+1))+xlp
ypos#=Matrix#(xlp,ylp)*-1
PokeSpriteVertex ThisSprite,ThisVertex,Xpos#+HandleX#,2000+Ypos#,Zpos#+HandleZ#
next
next

ThisColour=rgb(255,255,255)

; init faces  (UV points U=X in texture space,  V = Y in texture space)
TUstep#=1.0/(points+1)
Tvstep#=1.0/(points+1)

For Ylp=0 to points-1
For Xlp=0 to points-1

CurrentVertexRow =(Ylp*(points+1))+Xlp
NextVertexRow =CurrentVertexRow+(points+1)

PokeSpriteFaceVerts ThisSprite,ThisFace,3

u1#=Xlp*TUstep#
v1#=Ylp*TVstep#

u2#=(Xlp+1)*TUstep#
v2#=Ylp*TVstep#

u3#=(Xlp+1)*TUstep#
v3#=(Ylp+1)*TVstep#

u4#=(Xlp+0)*TUstep#
v4#=(Ylp+1)*TVstep#

PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,CurrentVertexRow+1 ,u2#,v2#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow+1 ,u3#,v3#,ThisColour

inc ThisFace

PokeSpriteFaceVerts ThisSprite,ThisFace,3
PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,NextVertexRow+1 ,u3#,v3#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow ,u4#,v4#,ThisColour
inc ThisFace

next
next

EndFUnction ThisSPrite




` *=----------------------------------------------------------------=*
`                        >> Randomize HeightMap Array <<
` *=----------------------------------------------------------------=*


Function RadomizeHeightMap(Matrix#(),Height)
Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)
For Zlp=1 to Depth-2
For Xlp=1 to Width-2
Matrix#(xlp,zlp)=rnd#(Height)
next xlp
next zlp
Endfunction


` *=----------------------------------------------------------------=*
`                    >> Average Matrix Height <<
` *=----------------------------------------------------------------=*





Function SmoothHeightMap(Matrix#(),passes)

Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)

Dim Temp_HeightMap_Yvalues#(Width,Depth)

For ThisPass=0 To Passes

CopyArray Matrix#(),Temp_HeightMap_Yvalues#()
For Zlp=1 to Depth-1

ZlpF=zlp-1
ZlpB=zlp+1
Width2=Width-1

For Xlp=1 to Width2
xlpL=Xlp-1
xlpR=Xlp+1

yb#=Temp_HeightMap_Yvalues#(xlp,zlp)
yt#=Temp_HeightMap_Yvalues#(xlp,zlpF)
yb#=Temp_HeightMap_Yvalues#(xlp,zlpB)
yl#=Temp_HeightMap_Yvalues#(xlpL,zlp)
yr#=Temp_HeightMap_Yvalues#(xlpR,zlp)

ytl#=Temp_HeightMap_Yvalues#(xlpL,zlpF)
ytr#=Temp_HeightMap_Yvalues#(xlpR,zlpF)
ybl#=Temp_HeightMap_Yvalues#(xlpL,zlpB)
ybr#=Temp_HeightMap_Yvalues#(xlpR,zlpB)

matrix#(xlp,zlp)=(yb#+yt#+yb#+yL#+yr#+ytl#+ytr#+ybl#+ybr#)/9

next xlp
next zlp

next ThisPass
unDim Temp_HeightMap_Yvalues#()

endfunction




kevin

#19
  Perspective Sprite Terrain #2
   
   This shot is logical extension of the previous example and demos a more updated edition of rendering pipeline.  This time we not only have the sprite terrain object  we also have 3000 sprite entities objects  as well.  Giving us 100K polygons scene and approximately a 3 million polygon fill rate.




Type PBposition
x#,y#,z#
EndType

Type PBProjection
x#,y#
EndType

Type PBCamera
Status
pos as PBPosition
angle as PBPosition
scale as PBPosition
RotationMode
ProjectionMode
Projection as PBProjection
ViewPoint as PBPosition
EndType

  Dim Camera as PBCamera Pointer
  Camera = new PBCamera


Camera.pos.X=0 
Camera.pos.y=0 
Camera.pos.z=0
Camera.Projection.x=400.0
Camera.Projection.Y=300.0
Camera.ViewPoint.X=GetScreenWidth()/2.0 
Camera.ViewPoint.y=GetScreenHeight()/2.0 




load3Dimage "animal.jpg",1
load3Dimage "particle_white.bmp",2
load3Dimage "face.jpg",3
; load3Dimage "particle_white.bmp",3
; scaleimage 3,256,256,1
; scaleimage 2,1024,1024,1
scaleimage 3,2048,2048,1



CreateSprite 1
positionspritexyz 1,400,300,1000
SpriteDrawmode 1,2
SpriteImage 1,1
centerspritehandle 1


SpriteVertexQuantity 1,8
SpriteFaceQuantity 1,8

PokeSpriteVertex 1, 4, 200,0,0
PokeSpriteVertex 1, 5, 300,0,0
PokeSpriteVertex 1, 6, 300,300,0
PokeSpriteVertex 1, 7, 200,300,0

PokeSpriteFaceVerts 1,1,4
PokeSpriteface 1,1,0,4,0,0,$ffff00
PokeSpriteface 1,1,1,5,1,0,$ffff00
PokeSpriteface 1,1,2,6,1,1,$ffffff
PokeSpriteface 1,1,3,7,0,1,$ff00ff


max=3000

For lp=0 to max
me= MakeParticleSprite(2,rnd(800),rnd(600),rndrange(10,25))
facecount=facecount+(getSpriteFaceQuantity(me)*2)

positionspritexyz me,rndrange(-1000,1000),_
rndrange(-1000,1000),_
rndrange(150,10000)
SpriteRotationMode me,1
next

terrain= MakePlainSprite(3,rnd(800),rnd(600),25)
SpriteRotationMode terrain,1
positionspritexyz terrain,0,2000,20500
spritehandle terrain,0,0
turnspritexyz terrain,30,0,0

TerrainFacecount=getSpriteFaceQuantity(Terrain)

facecount=(facecount)+getSpriteFaceQuantity(Terrain)



Do
Cls rgb(30,40,140)
ix=mod(ix+1,getimagewidth(1))

For lp=1 to max+2
TurnSpriteXYZ lp,1.11*(lp/(1.0*max)),0,1

z#=GetSpriteZ(lp)-100
if z#<150
z#=10000
endif
PositionspriteZ lp,z#
next

TurnspriteXyz terrain,0,0.1,0

; DrawOrderedSprites
; drawallsprites
DrawPerspectiveSprites Camera

ink $ffffff

if LeftKey() Then Camera.Pos.X=Camera.Pos.X-10
if RightKey() Then Camera.Pos.X=Camera.Pos.X+10
if upKey() Then Camera.Pos.z=Camera.Pos.z+10
if downKey() Then Camera.Pos.z=Camera.Pos.z-10

setcursor 0,0

f=fps()
print f
angle#=angle#+1
print FaceCount
print FaceCount*f
print TerrainFacecount
print Camera.pos.x
print Camera.pos.y
print Camera.Projection.x
print Camera.Projection.y

Sync
loop 



Function MakeParticleSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)

SpriteDrawMode ThisSprite, 2+16

SpriteVertexQuantity thisSprite,(Points)*4
SpriteFaceQuantity thisSprite,(Points)
angleStep#=360.0/points
size=32

For lp=0 to points-1
angle#=wrapangle(angle#,anglestep#)
Radius#=100
SetVerts(ThisSprite,VertexOffset,Angle#,Radius#,Size,wrapangle(angle#,-45))
SetFace(ThisSprite,ThisFace,VertexOffset,RndRgb())
VertexOffset=VertexOffset+4
inc thisface
next
EndFUnction ThisSPrite


Psub SetVerts(ThisSprite,VertexOffset,Angle#,Radius,Size,Rotation)
CenterX#=CosNewValue(0,angle#,Radius)
CenterY#=SinNewValue(0,angle#,Radius)
For lp=0 to 3
X#=CosNewValue(CenterX#,Rotation,Size)
Y#=SinNewValue(CenterY#,Rotation,Size)
PokeSpriteVertex ThisSprite,VertexOffset+lp,X#,y#,z#
Rotation=wrapangle(Rotation,90)
next
EndPsub


Psub SetFace(ThisSprite,ThisFace,VertexOffset,ThisColour)
PokeSpriteFaceVerts ThisSprite,ThisFace,4
PokeSpriteface ThisSprite,ThisFace,0,VertexOffset+0,0,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,VertexOffset+1,1,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,VertexOffset+2,1,1,ThisColour
PokeSpriteface ThisSprite,ThisFace,3,VertexOffset+3,0,1,ThisColour
EndPsub





Function MakePlainSprite(ThisIMage,Xpos#,Ypos#,points)

ThisSprite=NewSprite(Xpos#,Ypos#,ThisIMage)
SpriteDrawMode ThisSprite, 2+8

SpriteTransparent ThisSprite,on
turnspritexyz thissprite,00,00,00

Points2=(points+1)

Dim Matrix#(POints2,points2)

RadomizeHeightMap(Matrix#(),15000)
SmoothHeightMap(Matrix#(),3)

SpriteVertexQuantity thisSprite,(Points2*POints2)
SpriteFaceQuantity thisSprite,(Points2*Points2)*2


Size=2048
HandleX#=-(((points+1.0)/2.0)*size)
HandleZ#=-(((points+1.0)/2.0)*size)

; init vertex
for Ylp=0 to Points
Zpos#=ylp*Size
for Xlp=0 to Points
Xpos#=Xlp*Size
ThisVertex=(Ylp*(points+1))+xlp
ypos#=Matrix#(xlp,ylp)*-1
PokeSpriteVertex ThisSprite,ThisVertex,Xpos#+HandleX#,2000+Ypos#,Zpos#+HandleZ#
next
next

ThisColour=rgb(255,255,255)

; init faces  (UV points U=X in texture space,  V = Y in texture space)
TUstep#=1.0/(points+1)
Tvstep#=1.0/(points+1)

For Ylp=0 to points-1
For Xlp=0 to points-1

CurrentVertexRow =(Ylp*(points+1))+Xlp
NextVertexRow =CurrentVertexRow+(points+1)

PokeSpriteFaceVerts ThisSprite,ThisFace,3

u1#=Xlp*TUstep#
v1#=Ylp*TVstep#

u2#=(Xlp+1)*TUstep#
v2#=Ylp*TVstep#

u3#=(Xlp+1)*TUstep#
v3#=(Ylp+1)*TVstep#

u4#=(Xlp+0)*TUstep#
v4#=(Ylp+1)*TVstep#

PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,CurrentVertexRow+1 ,u2#,v2#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow+1 ,u3#,v3#,ThisColour

inc ThisFace

PokeSpriteFaceVerts ThisSprite,ThisFace,3
PokeSpriteface ThisSprite,ThisFace,0,CurrentVertexRow+0 ,u1#,v1#,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,NextVertexRow+1 ,u3#,v3#,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,NextVertexRow ,u4#,v4#,ThisColour
inc ThisFace

next
next

EndFUnction ThisSPrite




` *=----------------------------------------------------------------=*
`                        >> Randomize HeightMap Array <<
` *=----------------------------------------------------------------=*


Function RadomizeHeightMap(Matrix#(),Height)
Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)
For Zlp=1 to Depth-2
For Xlp=1 to Width-2
Matrix#(xlp,zlp)=rnd#(Height)
next xlp
next zlp
Endfunction


` *=----------------------------------------------------------------=*
`                    >> Average Matrix Height <<
` *=----------------------------------------------------------------=*





Function SmoothHeightMap(Matrix#(),passes)

Width=getarrayelements(Matrix#(),1)
Depth=getarrayelements(Matrix#(),2)

Dim Temp_HeightMap_Yvalues#(Width,Depth)

For ThisPass=0 To Passes

CopyArray Matrix#(),Temp_HeightMap_Yvalues#()
For Zlp=1 to Depth-1

ZlpF=zlp-1
ZlpB=zlp+1
Width2=Width-1

For Xlp=1 to Width2
xlpL=Xlp-1
xlpR=Xlp+1

yb#=Temp_HeightMap_Yvalues#(xlp,zlp)
yt#=Temp_HeightMap_Yvalues#(xlp,zlpF)
yb#=Temp_HeightMap_Yvalues#(xlp,zlpB)
yl#=Temp_HeightMap_Yvalues#(xlpL,zlp)
yr#=Temp_HeightMap_Yvalues#(xlpR,zlp)

ytl#=Temp_HeightMap_Yvalues#(xlpL,zlpF)
ytr#=Temp_HeightMap_Yvalues#(xlpR,zlpF)
ybl#=Temp_HeightMap_Yvalues#(xlpL,zlpB)
ybr#=Temp_HeightMap_Yvalues#(xlpR,zlpB)

matrix#(xlp,zlp)=(yb#+yt#+yb#+yL#+yr#+ytl#+ytr#+ybl#+ybr#)/9

next xlp
next zlp

next ThisPass
unDim Temp_HeightMap_Yvalues#()

endfunction



kevin

#20
  Perspective Sprite Terrain #3 (3D version)

     This is another logical step forward from the previous demo. Except this time rather than viewing the sprite space down the Z axis (which can be Z rotated now also), we can view the sprites from any vantage point within 3d space.   Which is a crude was of saying this gives now gives PB basic 3D support.
         

kevin


kevin

#22
  Particle Sprites

     This rather basic looking picture shows the introduction of the Particle manager.  Currently the manager is only loosely attached to the sprite system.  So loosely in fact the actual drawing/emitting functionality is hacked into draw sprite frame work.  Obviously, that's just for test purposes however.

     Particles Sprites will be attached to sprites face controls.  You'll either init their behavior from built in emitter types or pass them a control structure where you'll set the required fields. Probably both, not sure yet.   At the moment each particle has it's own position,  speed,  rotation, time, colour etc etc  but that will expand over time. 

     In this picture we have 50 sprites each emitting a max of 250 particles.    Please Note: The particles are rendered as Dots here for demonstration purposes only. 

kevin

#23
Particle Sprites Cont

  In this shot we're still seeing the particles being rendered as circles&dots in this case, but the engine frame work in now  embedded into PB.  This means that the user can now create / add and update the particle sprites.   






Type PBposition
x#,y#,z#
EndType

; -------------------------------------------------------------------------------
; >> PB Particle Structure <<
; -------------------------------------------------------------------------------

Type PB_Particle_Modifier
Mode
x#,y#,z#
Accel as PBPosition
Min as PBPosition
Max as PBPosition
endtype



Type PB_Particle
TypeID

FrameCounter
MaxFrameCounter

Pos as PBPosition

Speed as  PB_Particle_Modifier
Force as  PB_Particle_Modifier
Scale as  PB_Particle_Modifier

Angle as PBPosition
Colour
EndType


Dim Part as PB_Particle POinter
Part = new PB_Particle


load3dimage "D:\Play_Basic\PlayBasic\Projects\GFX\ship.bmp",100
max=50

For lp=1 to max

Spr=lp
CreateParticleSprite lp,250
PositionSprite lp,rnd(800),rnd(600)
SpriteImage lp,100
SpriteHandle Spr,GetIMageWidth(100)/-2,GetImageHeight(100)*-0.78
PositionSpriteZ spr,10
SpriteDrawmode spr,2
next


Do
cls rgb(20,40,100)
Print Fps()
 
PositionSprite Spr,MouseX(),MouseY()


Part.FrameCounter=0
Part.MaxFrameCounter=100
Part.Pos.z=10
Part.Colour=rndRgb()

Lockbuffer
For lp=1 to Max
Xpos#=getSpriteX(lp)
Ypos#=getSpriteY(lp)
Part.Pos.x=Xpos#
Part.Pos.y=Ypos#

Angle#=GetSpriteAngle(lp)+70+Rnd(40)
Part.Speed.X=CosRadius(Angle#,2)
Part.Speed.Y=SinRadius(Angle#,2)

AddSpriteParticle lp,Part

UpdateSpriteParticles lp
turnSprite lp,0.1

next
unlockbuffer
  DrawOrderedSprites
Sync
loop





  Note:  This code is presented as a sample only. While compatiblele with the PlayBasic V1.68h alpha, it's unlikely to work in future editions.



kevin

#24
Particle Sprites Cont

   In this pair of shots you can see that particle->mesh creation has been implemented.  Shot one has a single 1000 particle sprite, where shot #2 has 10 of them on screen. 

   Each particle has it's own local speed & force modifiers.   but you'll also be able to set the size / UV mapping + rotation of each particle (2D&3D).   

   With rotation, the particle fragments can spin locally.  This will make for some very interesting results.  The down side of lots of contols is that Initializing particles becomes a little more complex, plus there's more overhead per particle.    But it'll certainly be worth the effort.





;setfps 75

Type PBposition
x#,y#,z#
EndType


; -------------------------------------------------------------------------------
; >> PB Particle Structure <<
; -------------------------------------------------------------------------------

Type PB_Particle_Modifier
Mode
x#,y#,z#
Accel as PBPosition
Min as PBPosition
Max as PBPosition
endtype



Type PB_Particle
TypeID

FrameCounter
MaxFrameCounter

Pos as PBPosition

Speed as  PB_Particle_Modifier
Force as  PB_Particle_Modifier
Scale as  PB_Particle_Modifier

Angle as PBPosition

Colour
EndType


Dim Part as PB_Particle POinter
Part = new PB_Particle


load3dimage "LENS03.JPG",100
scaleimage 100,32,32,1

max=10

Dim ColourTable(Max)

NumbOfParticles=1000

For lp=1 to max
Spr=lp
CreateParticleSprite lp,NumbOfParticles
PositionSprite lp,0,0 ;rnd(400),rnd(300)

SpriteImage lp,100 ;+(lp&1)
PositionSpriteZ spr,10
SpriteDrawmode spr,2+16
ColourTable(lp)=rndrgb()

SpriteFAceQuantity lp,NumbOfParticles ;+100

For ThisPart=0 to NumbOfParticles
SetFace(lp,ThisPart,ThisPart*4,rndrgb())
next thispart
next


Do

Cls rgb(20,40,60)

Print Fps()
 

For lp=1 to max

Edges=rndRange(5,10)

Part.FrameCounter =0
Part.MaxFrameCounter =200
Part.Pos.z =10
Part.Colour =ColourTable(lp)

AngleStep#=360.0/Edges
BaseAngle#=rnd(360) ;GetSpriteAngle(lp)+70+Rnd(40)




Part.Force.X =0.0
Part.Force.Y =0.0
Part.Force.Z =0.0

SetPos(Part.Force.Accel,0,0.015,0)
SetPos(Part.Force.Max,0,20,0)
SetPos(Part.Force.Min,0,0,0)

MaxSpeed#=15
Part.Speed.Min.X =-(MaxSpeed#/2)
Part.Speed.Min.Y =-MaxSpeed#

Part.Speed.Max.X =MaxSpeed#/2
Part.Speed.Max.Y =MaxSpeed#




For MakeParts=0 to Edges-1

Part.Colour=rndrgb()

angle#=rnd#(360)
Xpos#=mousex()
Ypos#=Mousey()
Part.Pos.x=Xpos#
Part.Pos.Y=Ypos#

Speed#=rndrange#(1,6)

Part.Speed.X=CosRadius(Angle#,Speed#)
Part.Speed.Y=SinRadius(Angle#,Speed#)

Angle2#=angle#+180
Speed2#=Speed#/Part.MaxFrameCounter
Part.Speed.Accel.X=CosRadius(Angle2#,Speed2#)
Part.Speed.Accel.Y=SinRadius(Angle2#,Speed2#)

AddSpriteParticle lp,Part
next

; circle GetSpriteX(lp),GetSpriteY(lp),50,0


UpdateSpriteParticles lp

next

  DrawOrderedSprites
FaceCount=0  
For lp=1 to Max
FaceCount=FaceCount+GetSpritefaceQuantity(lp)
  next
 
  print FaceCount
 
 
Sync
loop


Function SetPos(me as PBposition Pointer,x#,y#,z#)
me.x=x#
me.y=y#
me.z=z#
EndFunction



Psub SetFace(ThisSprite,ThisFace,VertexOffset,ThisColour)
PokeSpriteFaceVerts ThisSprite,ThisFace,4
PokeSpriteface ThisSprite,ThisFace,0,VertexOffset+0,0,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,1,VertexOffset+1,1,0,ThisColour
PokeSpriteface ThisSprite,ThisFace,2,VertexOffset+2,1,1,ThisColour
PokeSpriteface ThisSprite,ThisFace,3,VertexOffset+3,0,1,ThisColour
EndPsub




Note:  This is sample code written for the current PB1.68h alpha, it's highly unlikely to the work in the future editions.



kevin

Particle Sprites Cont #4

  This new shot shows that particles can be locally coloured, locally rotated (3D XYZ) and scaled. Since they have scaling, then we don't really need modifiers for the size. You'll have to init the scale/size of the particle though (otherwise you won't see it!).   Particle size doesn't necessarily have to correspondent with the image dimensions however.


kevin


kevin

#27
  Here's another pic, this time I'm messing around with Scale + Rotation + Speed + Force modifiers. 

kevin

  Particles in 3D

     These shots view the particle sprite in 3D space.  The first shot is taken from deep inside the volume and the second is from far outside of it.



kevin

#29
Particle Sprites Cont - UV Mapping

   In this shot you can see that each individual particle can be UV mapped.  You could use this to store various textures on the same surface, or when exploding an image.   Here it's just randomly assigning each face some UV coords though.