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