Hello, I made a 2D shadow casting algorithm after i found the needed triangle drawing algorithm.
The shadows behave a bit strange and I can't find the problem, because all functions works great if I use them separately, but if i put them together.. this happens:
Working code:
rem
rem AGK Application
rem
rem A Wizard Did It!
global ResolutionWidth
global ResolutionHeight
ResolutionWidth=800
ResolutionHeight=600
setvirtualresolution(ResolutionWidth,ResolutionHeight)
setsyncrate(0,0)
//[1]LightImageID=loadimage("Light.png")
//LightSpriteID=createsprite(LightImageID)
//setspritescale(LightSpriteID,0.5,0.5)
//TempLightImageID=CreateRenderImage(ResolutionWidth,ResolutionHeight,0,0)
//TempLightSpriteID=createsprite(TempLightImageID)
global LightMemblock
type GridData
Solid
Visible
endtype
global MaxGridWidth
global MaxGridHeight
global GridSize
MaxGridWidth=50
MaxGridHeight=50
GridSize=10
LightRange=100
dim Grid[MaxGridWidth,MaxGridHeight] as GridData
for GridX=1 to MaxGridWidth
for GridY=1 to MaxGridHeight
if Random(1,10)=1 then Grid[GridX,GridY].Solid=1
next GridY
next GridX
WallColor=makecolor(0,0,255)
do
print(screenfps())
LightPosX=getpointerx()
LightPosY=getpointery()
//LightMemblock=creatememblockfromimage(LightImage)
//setrendertoimage(TempLightImageID,0)
//clearscreen()
//drawsprite(LightSpriteID)
//*************Draw the Light or use [1]LightImageID=loadimage("Light.png") + [2]setspritepositionbyoffset(LightSpriteID,LightPosX,LightPosY)
for i=1 to 255
Color=makecolor(i,i,i)
DrawEllipse(LightPosX,LightPosY,256-i,256-i,Color,Color,1)
next i
//*************
LineOfSight(LightPosX,LightPosY,LightRange)
//
//drawline(0,0,ResolutionWidth,ResolutionHeight,makecolor(255,0,0),makecolor(0,0,255))
//TempLightImage=createimagefrommemblock(LightMemblock)
//deletememblock(LightMemblock)
//setrendertoscreen()
//clearscreen()
//setspriteimage(TempLightSpriteID,TempLightImageID)
//drawsprite(TempLightSpriteID)
//[2]setspritepositionbyoffset(LightSpriteID,LightPosX,LightPosY)
for GridX=1 to MaxGridWidth
for GridY=1 to MaxGridHeight
if Grid[GridX,GridY].Solid=1 then drawbox(GridX*GridSize,GridY*GridSize,GridSize+GridX*GridSize,GridSize+GridY*GridSize,WallColor,WallColor,WallColor,WallColor,1)
next GridY
next GridX
sync()
loop
function LineOfSight(LightPosX,LightPosY,LightRange)
GridRange=LightRange/GridSize
LightX=LightPosX/GridSize
LightY=LightPosY/GridSize
for GridX=LightX-GridRange to LightX+GridRange
for GridY=LightY-GridRange to LightY+GridRange
if GridX>=1 and GridX<=MaxGridWidth and GridY>=1 and GridY<=MaxGridHeight
if Grid[GridX,GridY].Solid=1
GridPosX=0.5*GridSize+GridX*GridSize
GridPosY=0.5*GridSize+GridY*GridSize
DistX=GridPosX-LightPosX
DistY=GridPosY-LightPosY
Box(GridPosX-0.5*GridSize,GridPosY-0.5*GridSize,GridPosX+0.5*GridSize,GridPosY+0.5*GridSize)
//Dist#=sqrt(DistX*DistX+DistY*DistY)
Dist#=DistX*DistX+DistY*DistY
if Dist#<=LightRange*LightRange
if GridPosX-0.5*GridSize>=LightPosX
if GridPosY-0.5*GridSize>=LightPosY
Corner1X=GridPosX-0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX+0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
else
if GridPosY+0.5*GridSize<=LightPosY
Corner1X=GridPosX+0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX-0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
else
Corner1X=GridPosX-0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX-0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
endif
endif
else
if GridPosX+0.5*GridSize<=LightPosX
if GridPosY-0.5*GridSize>=LightPosY
Corner1X=GridPosX+0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX-0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
else
if GridPosY+0.5*GridSize<=LightPosY
Corner1X=GridPosX-0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX+0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
else
Corner1X=GridPosX+0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX+0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
endif
endif
else
if GridPosY-0.5*GridSize<=LightPosY
Corner1X=GridPosX-0.5*GridSize
Corner1Y=GridPosY+0.5*GridSize
Corner2X=GridPosX+0.5*GridSize
Corner2Y=GridPosY+0.5*GridSize
else
Corner1X=GridPosX+0.5*GridSize
Corner1Y=GridPosY-0.5*GridSize
Corner2X=GridPosX-0.5*GridSize
Corner2Y=GridPosY-0.5*GridSize
endif
endif
endif
Dist1X=Corner1X-LightPosX
Dist1Y=Corner1Y-LightPosY
Dist2X=Corner2X-LightPosX
Dist2Y=Corner2Y-LightPosY
Dist1#=sqrt(Dist1X*Dist1X+Dist1Y*Dist1Y)
//Dist2#=sqrt(Dist1X*Dist1X+Dist1Y*Dist1Y)
LightDir1X#=Dist1X/Dist1#
LightDir1Y#=Dist1Y/Dist1#
LightDir2X#=Dist2X/Dist1#
LightDir2Y#=Dist2Y/Dist1#
Corner3X=Corner1X+LightDir1X#*LightRange
Corner3Y=Corner1Y+LightDir1Y#*LightRange
Corner4X=Corner2X+LightDir2X#*LightRange
Corner4Y=Corner2Y+LightDir2Y#*LightRange
//drawline(Corner1X-LightPosX+256,Corner1Y-LightPosY+256,Corner3X-LightPosX+256,Corner3Y-LightPosY+256,makecolor(0,255,0),makecolor(0,255,0))
//drawline(Corner2X-LightPosX+256,Corner2Y-LightPosY+256,Corner4X-LightPosX+256,Corner4Y-LightPosY+256,makecolor(0,255,0),makecolor(0,255,0))
//FilledTriangle(Corner1X-LightPosX+256,Corner1Y-LightPosY+256,Corner4X-LightPosX+256,Corner4Y-LightPosY+256,Corner3X-LightPosX+256,Corner3Y-LightPosY+256)
//FilledTriangle(Corner2X-LightPosX+256,Corner2Y-LightPosY+256,Corner4X-LightPosX+256,Corner4Y-LightPosY+256,Corner1X-LightPosX+256,Corner1Y-LightPosY+256)
FilledTriangle(Corner1X,Corner1Y,Corner4X,Corner4Y,Corner3X,Corner3Y)
FilledTriangle(Corner2X,Corner2Y,Corner4X,Corner4Y,Corner1X,Corner1Y)
drawline(Corner1X,Corner1Y,Corner3X,Corner3Y,makecolor(0,255,0),makecolor(0,255,0))
drawline(Corner2X,Corner2Y,Corner4X,Corner4Y,makecolor(0,255,0),makecolor(0,255,0))
endif
endif
endif
next GridY
next GridX
endfunction
function FilledTriangle(x0,y0,x1,y1,x2,y2)
if (x0=x1 and x1=x2) or (y0=y1 and y1=y2) then exitfunction
// i think here is thomething wrong
if y1<y0
ty=y1
tx=x1
y1=y0
x1=x0
y0=ty
x0=tx
endif
if y2<y0
ty=y2
tx=x2
y2=y0
x2=x0
y0=ty
x0=ty
endif
if y2<y1
ty=y2
tx=x2
y2=y1
x2=x1
y1=ty
x1=tx
endif
if y0=y1
FlatTopTriangle(x0,y0,x1,y1,x2,y2)
else
if y1=y2
FlatBottomTriangle(x0,y0,x1,y1,x2,y2)
else
NewX=x0+((((y1+0.0)-y0)*((x2+0.0)-x0))/((y2+0.0)-y0))+0.5
FlatBottomTriangle(x0,y0,x1,y1,NewX,y1)
FlatTopTriangle(x1,y1,NewX,y1,x2,y2)
endif
endif
endfunction
function FlatBottomTriangle(x0,y0,x1,y1,x2,y2)
dxy_left as float
dxy_right as float
xs as float
xe as float
y as integer
if x2>x1
tx=x1
x1=x2
x2=tx
endif
dxy_left=((x2+0.0)-x0)/((y2+0.0)-y0)
dxy_right=((x1+0.0)-x0)/((y1+0.0)-y0)
xs=x0+0.5
xe=x0+1.0
for y=y0 to y1
//Line(xs,xe,y)
drawLine(xs,y,xe,y,0,0,0)
xs=xs+dxy_left
xe=xe+dxy_right
next y
endfunction
function FlatTopTriangle(x0,y0,x1,y1,x2,y2)
dxy_left as float
dxy_right as float
xs as float
xe as float
y as integer
if x1<x0
tx=x0
x0=x1
x1=tx
endif
dxy_left=((x2+0.0)-x0)/((y2+0.0)-y0)
dxy_right=((x2+0.0)-x1)/((y2+0.0)-y1)
xs=x0+0.5
xe=x1+1.0
for y=y0 to y2
//Line(xs,xe,y)
drawLine(xs,y,xe,y,0,0,0)
xs=xs+dxy_left
xe=xe+dxy_right
next y
endfunction
function Line(x0,x1,y)
for x=x0 to x1
Offset=(4*((y*256)+x))+12
if x>0 and x<256 and y>0 and y<256 then setMemblockInt(LightMemblock,Offset,0)
next x
endfunction
function Box(x1,y1,x2,y2)
for x=x1 to x2
drawLine(x,y1,x,y2,0,0,0)
next x
endfunction
Thank you in advance.
Maybe you could help me render the shadows into an image and blend them with other lights too.
</div>