le relief est codé dans chaque pixel....
Vous pouvez diriger la lampe avec les fleches et la souris....
Dites moi ce que vous en pensez... chez moi ça tourne a 30 fps.
Mais j'éspère pouvoir encore améliorer cela. Quand je pense que mon premier code je tournais a 1FPS et que l'éclairage était moins beau...Y a du progres...
Code : Tout sélectionner
If InitSprite() = 0 Or InitKeyboard()=0 Or InitMouse()=0 Or InitSprite3D()=0
MessageRequester("Error","DirectX 7+ is needed.",0)
EndIf
Global ScreenWidth.l,ScreenHeight.l
ScreenWidth=640
ScreenHeight=480
Enumeration
#Screen
#Map
#Mask
#Buffer
EndEnumeration
;#PI = 3.14159265
Procedure.f winkel(x1.f,y1.f,x2.f,y2.f)
a.f = x2-x1
b.f = y2-y1
c.f = Sqr(a*a+b*b)
winkel.f = ACos(a/c)*57.29577
If y1 < y2 : winkel=360-winkel : EndIf
ProcedureReturn winkel
EndProcedure
Procedure.f GradToDeg(Ang.l)
ProcedureReturn 9*Ang/10
EndProcedure
Procedure.f RadToDeg(Ang.l)
ProcedureReturn 180*Ang/#PI
EndProcedure
Procedure.f DegToGrad(Ang.l)
ProcedureReturn 10*Ang/9
EndProcedure
Procedure.f RadToGrad(Ang.l)
ProcedureReturn 200*Ang/#PI
EndProcedure
Procedure.f DegToRad(Ang.l)
ProcedureReturn Ang*#PI/180
EndProcedure
Procedure.f GradToRad(Ang.l)
ProcedureReturn Ang*#PI/200
EndProcedure
;Constante
#Rad=#PI/180
Structure Surface
*Address.l
Pitch.l
PixelFormat.l
Width.l
Height.l
EndStructure
Global Dim Buffer(640,480)
Global Dim Surface.Surface(10)
Global Dim CosTable.f(73000)
Global Dim SinTable.f(73000)
For z=0 To 72000
CosTable(z)=Cos(z/100*#Rad)
SinTable(z)=Sin(z/100*#Rad)
Next
;IncludeFile("2d.pb")
OpenScreen(ScreenWidth, ScreenHeight, 32, "Aliens")
UsePNGImageDecoder()
TransparentSpriteColor(#PB_Default,RGB(255,0,255))
LoadSprite(1,"image.png")
;LoadSprite(2,"body.bmp",#PB_Sprite_Texture)
;CreateSprite3D(2, 2)
CreateSprite(3,640,480)
CreateSprite(4,32,32)
StartDrawing(SpriteOutput(4))
Line(0,0,32,32,RGB(255,255,255))
Line(0,32,32,-32,RGB(255,255,255))
StopDrawing()
;Initialisation des différentes surfaces
StartDrawing(ScreenOutput())
Surface(#Screen)\Address=DrawingBuffer()
Surface(#Screen)\Pitch=DrawingBufferPitch()
Surface(#Screen)\PixelFormat=DrawingBufferPixelFormat()
Surface(#Screen)\Width=ScreenWidth
Surface(#Screen)\Height=ScreenHeight
StopDrawing()
StartDrawing(SpriteOutput(1))
Surface(#Map)\Address=DrawingBuffer()
Surface(#Map)\Pitch=DrawingBufferPitch()
Surface(#Map)\PixelFormat=DrawingBufferPixelFormat()
Surface(#Map)\Width=SpriteWidth(1)
Surface(#Map)\Height=SpriteHeight(1)
StopDrawing()
StartDrawing(SpriteOutput(3))
Surface(#Buffer)\Address=DrawingBuffer()
Surface(#Buffer)\Pitch=DrawingBufferPitch()
Surface(#Buffer)\PixelFormat=DrawingBufferPixelFormat()
Surface(#Buffer)\Width=SpriteWidth(3)
Surface(#Buffer)\Height=SpriteHeight(3)
StopDrawing()
Procedure Light(LightX.l,LightY.l,Angle.l,Anglef.l,Puissance.l,Color.l)
If Angle-Anglef<0:Angle=Angle+360:EndIf
If Angle+Anglef>720:Angle=Angle-360:EndIf
Dim MemPlot.b(640,480) ; Un petit tableau pour verifier si la pixel au coordonée x et y du faisceau lumineux a déjà été traité
For i = -Anglef To Anglef Step 1
a.f=(i/3+Angle)
f.l=0
For p = 0 To Puissance
;Calcul des coordonées X et Y a traité
X = LightX + p * CosTable(Int(a*100));Cos(a*#Rad) ;
Y = LightY + p * SinTable(Int(a*100));Sin(a*#Rad);
If X>0 And X<Surface(#Buffer)\Width And Y>0 And Y<Surface(#Buffer)\Height
;On verifie si on tombe sur un obstacle: col=0,0,0 pas d'obstacte / col=255,255,255 il y a un obstacle
col=PeekL(Surface(#Map)\Address+x*4+Surface(#Map)\Pitch*y)
Obstacle=(col & %11 )
If Obstacle=0 Or f<10 ;Si il n'ya pas d'obstacle alors on trace (col=0) / si f>0 c'est qu'on a trouvé un obstacle mais il faut l'illuminé
If Obstacle>0 Or f>0:f=f+1:EndIf ;Si on a trouvé un obstacle on l'illumine
; si cette pixel n'a pas été traité on la traite
;On verifie qu'on est bien dans les limites
If MemPlot(X,Y)=0
;Je mémorise que cette pixel a été traité pour ce faisceau là
MemPlot(X,Y)=1
;Je prélève la couleur dans le buffer au cas ou une autre source lumineuse serait déjà dans le coin
colb=Buffer(X,Y);PeekL(Surface(#Buffer)\Address+x*4+Surface(#Map)\Pitch*y)
;Je prend la couleur dans le decor
;col=PeekL(Surface(#Map)\Address+x*4+Surface(#Map)\Pitch*y)
If f=0 Or Obstacle=0
;si on a pas encore trouvé d'obstacle alors on calcul l'éclairage
;lightlevel=(Puissance-p)*255/Puissance
lightlevel=(((Puissance-p-10)*200/Puissance+(250*(Anglef-Abs(i))/Anglef))/2)-50;ça donne la forme de la luminosité
Else
;si on a trouvé un obstacle on calcul l'illumination de cet objet
lightlevel=255-(f*255/10)
EndIf
;il faut qu'il y est un minimum d'éclairage pour aller plus loin
If lightlevel>1 And lightlevel<256
;Calcul de la couleur de la pixem
red=(Red(col)*Red(Color)*lightlevel)/65536
green=(Green(col)*Green(Color)*lightlevel)/65536
blue=(Blue(col)*Blue(Color)*lightlevel)/65536
;col=RGB(red,green,blue)
;Melange de faisceau lumineux si il y a besoin
If colb>0
If Red(colb)>red:red=Red(colb):Else:red=red:EndIf
If Green(colb)>green:green=Green(colb):Else:green=green:EndIf
If Blue(colb)>blue:blue=Blue(colb):Else:blue=blue:EndIf
EndIf
col=RGB(red,green,blue)
;Hop on affiche dans le buffer le pixel
Buffer(X,Y)=col
PokeL(Surface(#Buffer)\Address+x*4+Surface(#Buffer)\Pitch*y,col)
EndIf
EndIf
Else
Break;
EndIf
EndIf
Next p
Next i
EndProcedure
gx=320
gy=200
Repeat
ExamineMouse()
ExamineKeyboard()
ga=winkel(gx,MouseY(),MouseX(),gy)
UseBuffer(3)
ClearScreen(0)
If Time=0:Time=ElapsedMilliseconds():EndIf
t.l=(ElapsedMilliseconds()-Time)
Time=ElapsedMilliseconds()
An=An+(40*t/100)
If An>360:An=An-360:EndIf
Light(250,250,A,45,150,RGB(255,255,255))
Light(gx,gy,ga,90,90,RGB(255,255,255))
Light(200,240,An+180,10,150,RGB(100,100,255))
Light(200,240,An,10,150,RGB(100,100,255))
A=A+1
If A>360:A=A-360:EndIf
If KeyboardPushed(#PB_Key_Up) And gy>0:gy-1:EndIf
If KeyboardPushed(#PB_Key_Down) And gy<480:gy+1:EndIf
If KeyboardPushed(#PB_Key_Right) And gx<640:gx+1:EndIf
If KeyboardPushed(#PB_Key_Left) And gx>0:gx-1:EndIf
Delay(1)
If Val(FormatDate("%ss", Date()))=sek
FPS+1
Else
FPS$=Str(FPS)
Time$=Str(ElapsedMilliseconds()-Elapsetime)
FPS=0
EndIf
sek=Val(FormatDate("%ss", Date()))
;Affichage
;UseBuffer(3)
;Start3D()
;RotateSprite3D(2, ga, 0)
;DisplaySprite3D(2, gx, gy, 255)
;Stop3D()
UseBuffer(-1)
DisplaySprite(3,0,0)
DisplaySprite(4,MouseX()-16,MouseY()-16)
Dim Buffer(640,480)
StartDrawing(ScreenOutput())
DrawingMode(1)
FrontColor(RGB(255,255,255))
DrawText(100,1,"FPS: "+FPS$+" Time:"+Time$+" Angle:"+Str(ga))
Elapsetime=ElapsedMilliseconds()
StopDrawing()
FlipBuffers(0)
Until KeyboardPushed(#PB_Key_Escape)
End