Perspective Parallax

Started by kevin, August 21, 2009, 03:48:35 PM

Previous topic - Next topic

kevin

  Perspective Parallax

 This code creates a parallax (multi layer) effect along the lines of the clever coders challenge #18.   The demo projects the tile sizes to keep the scene in perspective.  So closer planes are larger than the one's further away, the same applies to the planes movement.   Although, in the demo it just scrolls constantly off the timer().    



 
PlayBASIC Code: [Select]
   OpenScreen 800,600,32,2
screenvsync true

sw=GetScreenWidth()
sh=GetScreenHeight()

// Make Scene Graphics
global ProjectionX#=400
global ProjectionY#=400


Layers=10

Type tLayer
Z
image
EndType


Dim Layer(Layers) as tlayer


do

Width=200
Height=Width
DEpth=200

for lp=1 to layers
if Layer(lp).image then DeleteIMage Layer(lp).image
Layer(lp).z=Depth+(250*lp)
Layer(lp).image= Make_Perspective_Block(Width,Height,Layer(lp).z,RndRgb())
next



rendertoscreen
StartTime=Timer()


BackDrop=newimage(sw,sh)
rendertoimage Backdrop
c1=rgb(70,130,100)
c2=rgb(70,130,160)
ypos=sh/2
shadebox 0,0,sw,ypos,c1,c1,c2,c2
shadebox 0,ypos,sw,sh,c2,c2,c1,c1
rendertoscreen


Do

drawimage backdrop,0,0,false

CurrentTime=Timer()

// Ticks since the demo started
TotalTimePast=CurrentTime-StartTime


// Camera Position.
// Here we calc the movement from when the demo started
// each second we're expecting the camera to move 120 on the x axis
// and 30 on the Y axis.. So we take the time past and divide
// that by how many units the object moves within 1 second..
// since the movement is tied to the computers timer, it doesn't matter
// how fast the machine can execute the loop. The only difference
// will be the 'smoothness' to the viewer.

ScrollOffsetSinceDemoStartedX#=(TotalTimePast/(1000/120.0))
ScrollOffsetSinceDemoStartedY#=(TotalTimePast/(1000/30.0))

for lp=layers to 1 step -1

X=(ScrollOffsetSinceDemoStartedX#*ProjectionX#)/Layer(lp).Z
Y=(ScrollOffsetSinceDemoStartedY#*ProjectionY#)/Layer(lp).Z

image=Layer(lp).image
tileimage Image,(sw/2)-X,(sy/2)-Y,true

next


sync
loop Spacekey()



flushkeys
deleteimage Backdrop


loop



Function Make_Perspective_Block(Width,Height,Depth,C1)

w=(Width*ProjectionX#)/Depth
h=(Height*ProjectionY#)/Depth

TempImage=NewFXImage(w,h)
rendertoimage TempImage

cx=Width/2
cy=height/2
boxc 0,0,width,height,true,c1

radius=getdistance2d(0,0,w*0.4,h*0.4)
inkmode 1+2048
for lp=radius to 0 step -2
i=55+(200*(float(lp)/Radius))
circlec w/2,h/2,lp,true,rgb(i,i,i)
next

inkmode 1

// since we're using a full screen tiled grid, we can double the
// size of the tile and make it easier for the GPU's blitter
// to the draw the fragments.

ThisImage=NewImage(w*4,h*4)
rendertoimage ThisImage
TileIMage TempImage,0,0,false

deleteimage TempImage

rendertoscreen
EndFunction ThisImage







kevin

#1
   Here's version that uses Alpha 50 on FX buffers.   Had to write a custom tile image since Tile/DrawImage doesn't support Inkmodes in PB1.64j, but draw rotated image does (limited).    


PlayBASIC Code: [Select]
   OpenScreen 800,600,32,2
screenvsync true

sw=GetScreenWidth()
sh=GetScreenHeight()

// Make Scene Graphics
global ProjectionX#=400
global ProjectionY#=400


Layers=5

Type tLayer
Z
image
EndType


Dim Layer(Layers) as tlayer


do

Width=200
Height=Width
DEpth=200

for lp=1 to layers
if Layer(lp).image then DeleteIMage Layer(lp).image
Layer(lp).z=Depth+(250*lp)
Layer(lp).image= Make_Perspective_Block(Width,Height,Layer(lp).z,RndRgb())
next



rendertoscreen
StartTime=Timer()


BackDrop=newfximage(sw,sh)
rendertoimage Backdrop
c1=rgb(70,130,100)
c2=rgb(70,130,160)
ypos=sh/2
shadebox 0,0,sw,ypos,c1,c1,c2,c2
shadebox 0,ypos,sw,sh,c2,c2,c1,c1
rendertoscreen

Screen=newfximage(sw,sh)


Do

rendertoimage screen
drawimage backdrop,0,0,false

CurrentTime=Timer()

// Ticks since the demo started
TotalTimePast=CurrentTime-StartTime


// Camera Position.
// Here we calc the movement from when the demo started
// each second we're expecting the camera to move 120 on the x axis
// and 30 on the Y axis.. So we take the time past and divide
// that by how many units the object moves within 1 second..
// since the movement is tied to the computers timer, it doesn't matter
// how fast the machine can execute the loop. The only difference
// will be the 'smoothness' to the viewer.

ScrollOffsetSinceDemoStartedX#=(TotalTimePast/(1000/120.0))
ScrollOffsetSinceDemoStartedY#=(TotalTimePast/(1000/30.0))

inkmode 1+32 ;+64
for lp=layers to 1 step -1
X=(ScrollOffsetSinceDemoStartedX#*ProjectionX#)/Layer(lp).Z
Y=(ScrollOffsetSinceDemoStartedY#*ProjectionY#)/Layer(lp).Z
image=Layer(lp).image
CustomTileImage(Image,X,Y,true)
next

rendertoscreen
drawimage screen,0,0,false
sync
loop Spacekey()



flushkeys
deleteimage Backdrop


loop


Function CustomTileImage(ThisImage,Xpos,Ypos,Transparent)

sw=GetSCreenWidth()
sh=GetSCreenHeight()

Width=GetIMageWidth(ThisImage)
Height=GetIMageHeight(ThisIMage)

if Xpos>0 then Xpos=Xpos*-1
if Ypos>0 then Ypos=Ypos*-1

Xpos=mod(Xpos,width)
Ypos=mod(Ypos,height)

x1=Xpos
while X1>0
x1=x1-Width
endwhile

y1=Ypos
while Y1>0
Y1=Y1-Height
endwhile

dec height
for Y=y1 to (y1+Sh*2) step height
for X=x1 to (x1+Sw*2) step width
drawrotatedimage ThisImage,X,Y,angle#,1,1,0,0,Transparent
next
next

EndFunction


Function Make_Perspective_Block(Width,Height,Depth,C1)

w=(Width*ProjectionX#)/Depth
h=(Height*ProjectionY#)/Depth

TempImage=NewFXImage(w,h)
rendertoimage TempImage

cx=Width/2
cy=height/2
boxc 0,0,width,height,true,c1

radius=getdistance2d(0,0,w*0.4,h*0.4)
inkmode 1+2048
for lp=radius to 0 step -2
i=55+(200*(float(lp)/Radius))
circlec w/2,h/2,lp,true,rgb(i,i,i)
next
Login required to view complete source code