Quote: "Making a shadow with a walking man would be very hard, though. "
Ask and you shall receive... actually this isn't of a walking man but borrows the code I wrote for a DBC challenge to create the shadow of a walking robot. This demo, which I also had submitted in the DBC challenges, demonstrates a texture bump-mapping effect to create a rock like texture and a cartoony tiling texture as well as a moving shadow.
If you dig through the DBC challenges, there's a lot of interesting and even forgotten code.
set display mode 1024,768,32
`set display mode 1600,1200,32
sync on
sync rate 60
rem bump mapping demo
rem by latch
rem 03/03/2011
randomize timer()
autocam off
hide mouse
_main:
gosub _stone
gosub _ground
rem light
color ambient light rgb(80,80,80)
set directional light 0,1,-1,.1
set object specular 1,rgb(64,64,64),4
position camera 500,40,400
point camera 500,20,500
do
turn object right 1,.2
pitch object up 1,.4
cast_shadow(1,2,225.0,0,0.0,-20.0,0.0)
position camera 500,20,500
yrotate camera wrapvalue(camera angle y()-.2)
move camera -50*cos(camera angle y())-75
sync
loop
end
`================================================================
_ground:
imgin=4
imgout=3
blend=1
mem1=1
mem2=2
bmp=1
brightness=32
floor=imgout
create bitmap 4,500,500
ink rgb(rnd(255),rnd(255),rnd(255)),0
spacing=256/4
rem create a tile pattern
box 5,5,250,250
ink 0,0
for x=32 to 224 step 32
for y=32 to 224 step 32
box x,y,x+12,y+12
next y
next x
for n=1 to 4
blur bitmap 4,2
next n
get image imgin,0,0,256,256
sync
rem bump map the tiles
emboss(imgin,imgout,blend,mem1,mem2,bmp,brightness)
rem make a matrix
make matrix 1,1000,1000,25,25
prepare matrix texture 1,floor,1,1
delete bitmap 4
delete image imgin
return
`================================================================
_stone:
imgin=2
imgout=1
blend=1
mem1=1
mem2=2
bmp=1
brightness=64
stone=imgout
rem bumpy surface
for n=1 to 10000
x1=rnd(256)
y1=rnd(256)
c=rnd(255)
ink rgb(c,c,c),0
if rnd(1)
x2=x1+(rnd(100)-50)
y2=y1+(rnd(100)-50)
line x1,y1,x2,y2
else
x2=x1+rnd(10)
y2=y1+rnd(10)
box x1,y1,x2,y2
endif
next n
for n=1 to 3
blur bitmap 0,2
next n
get image imgin,0,0,256,256
sync
rem bumpmap the image
emboss(imgin,imgout,blend,mem1,mem2,bmp,brightness)
rem get rid of border on embossed image
cls
paste image imgout,0,0
get image stone,3,3,253,253,1
sync
rem texture a cube with the image
make object cube 1,25
texture object 1,stone
delete image imgin
rem position the cube
position object 1,500,25,500
return
`================================================================
function emboss(imgin,imgout,blend,mem1,mem2,bmp,brightness)
remstart
by latch
emboss image filter based on code from
http://www.gamedev.net/reference/programming/features/imageproc/page2.asp
This function will create a black n white embossed version of imgin
and save it to imgout. There is the option to blend tbe embossed image
with the original to try and create a bump-map effect.
imgin == the in image - original image number to emboss
imgout == the resulting image after embossing/blending
image number
blend == 0 = do not blend embossed image with original
1 = imgout will be blended embossed and original
image
mem1 == memblock number to hold imgin info for calculations
mem2 == memblock number to hold imgout info for calc
bmp == background bitmap to draw imgout on - deleted
after use. Must not be 0
brightness == value from 0 to 128 to control the level of
gray scale for embossing
remend
rem set up the masking for the embossing effect
if mask=0
restore _mask_data
dim embossfilter(3,3)
for m=0 to 2
for n=0 to 2
read embossfilter(m,n)
next n
next m
mask=1
endif
_mask_data:
data 2,0,0
data 0,-1,0
data 0,0,-1
rem create the memblocks to work with
make memblock from image mem1,imgin
make memblock from image mem2,imgin
sync
rem get the image properties
wid=memblock dword(mem1,0)
hit=memblock dword(mem1,4)
dep=memblock dword(mem1,8)/8
rem create offscreen bitmap
create bitmap bmp,wid+4,hit+4
rem start the embossing
if brightness < 0 then brightness=0
emboss_sum=1
for i=0 to hit-1
for j=0 to wid-1
pos=12+((j+(i*wid))*dep)
b=memblock byte(mem1,pos)
g=memblock byte(mem1,pos+1)
r=memblock byte(mem1,pos+2)
h=255-((r+g+b)/3)
write memblock dword mem2,pos,rgb(h,h,h)
next j
next i
for i=1 to wid-2
for j=1 to hit-2
sumr=0
for k=0 to 2
for l=0 to 2
x1=(i-((3-1)/2))+k
y1=(j-((3-1)/2))+l
pos=12+((x1+(y1*wid))*dep)
c=memblock dword(mem2,pos)
r=rgbr(c)
sumr=sumr+(r*embossfilter(k,l))
next l
next k
sumr=sumr/(emboss_sum)
inc sumr,brightness
if sumr > 255 then sumr=255
if sumr < 0 then sumr=0
rem latches code for blending
r=sumr
g=sumr
b=sumr
if blend
pos=12+((i+(j*wid))*dep)
rem get the colors from the original image
r=memblock byte(mem1,pos+2)
g=memblock byte(mem1,pos+1)
b=memblock byte(mem1,pos)
rem color blending is based on the difference between the least
rem powerful color channel and the gray scale color calculated.
rem I did this because I need to adjust the behavior of this particular embossing
rem algorithm and I needed to manage the darks and lights a little differently.
rem My color management seems to make things a little bumpier in a way I prefer.
if g < r and g < b
dif=sumr-g
else
if b < r
dif=sumr-b
else
dif=sumr-r
endif
endif
r=r+dif
if r < 0 then r=0
if r > 255 then r=255
g=g+dif
if g < 0 then g=0
if g > 255 then g=255
b=b+dif
if b < 0 then b=0
if b > 255 then b=255
endif
ink rgb(r,g,b),0
dot i,j
next j
next i
get image imgout,0,0,wid,hit
sync
rem cleanup
delete bitmap bmp
delete memblock mem1
delete memblock mem2
endfunction imgout
`================================================================
function cast_shadow(obj,shadow,sangle#,shadowimg,posx#,posy#,posz#)
rem by latch
if object exist(shadow) then delete object shadow
rem use obj to build shadow and cast it at angle sangle
rem move the original object to the origin
ox#=object position x(obj)
oy#=object position y(obj)
oz#=object position z(obj)
position object obj,0,0,0
rem create a mesh out of the object
make mesh from object obj,obj
make object shadow,obj,shadowimg
delete mesh obj
rem reposition orignal object
position object obj,ox#,oy#,oz#
rem rotate the shadow on it's y axis to opposite
rem direction of sangle
yang#=wrapvalue(sangle#)
rotate limb shadow,0,0,yang#,0
offset limb shadow,0,0,object size y(shadow)/2.0,0
make mesh from object shadow,shadow
delete object shadow
make object shadow,shadow,shadowimg
delete mesh shadow
rotate object shadow,90,0,wrapvalue(sangle#)
position object shadow,ox#+posx#,oy#+posy#,oz#+posz#
scale object shadow,100,100,.1
ghost object on shadow,1
set object shadow,1,1,0
if shadowimg=0 then color object shadow,rgb(164,164,164)
set object diffuse shadow,0
set object ambient shadow,rgb(255,255,255)
endfunction
Enjoy your day.