Die Liste enthält nun die relativen Koordinaten zur Lichtquelle wo eine Ecke ist.
Ich weiß leider nicht genau wie du die "Ecken hinter den Ecken" bestimmst, sodass alles glatt liegt, aber ich denke mal mit dem neuen Code kannst du mehr anfangen:
DisplayLight() nimmt nun die Ecken-Liste und sortiert sie nach Winkeln.
Damit alles gedeckt ist, sollten dann immer zwei gleiche Winkel als doppelpack kommen, sodass dann die Liste um 1 verschoben wird sodass die Dreicke entstehen.
Was noch zu beachten wäre, wäre wenn es zu wenige Ecken gibt, dass dann die Dreicke zu "flach" sind, sodass du selbst noch Ecken "im Unendlichen" hinzufügen musst. Ich vermute mal, auf dieses Problem bist du auch bei deinen Schatten schon gestoßen, wenn die Lichtquelle zu dicht am Objekt liegt richtig ?^^
Code: Alles auswählen
Structure DX9Vertex
X.f
Y.f
Z.f
Rhw.f
Color.l
Tu.f
Tv.f
EndStructure
Structure DX9
TexRes.i
Vertice.DX9Vertex[4]
TmpVertice.DX9Vertex[4]
Width.l
Height.l
RealWidth.l
RealHeight.l
Angle.f
Transformed.l
EndStructure
Structure Corner
X.f
Y.f
EndStructure
Structure CornerSort
*Corner.Corner
Angle.f
EndStructure
Procedure DisplayLightCone(Sprite3D.i, X.f, Y.f, X1.f, Y1.f, X2.f, Y2.f, MaxLength.f=386.0)
Protected *DX9.DX9 = IsSprite3D(Sprite3D)
With *DX9
\Transformed = 1
\Vertice[0]\X = X
\Vertice[0]\Y = Y
\Vertice[0]\Tu = 0.5
\Vertice[0]\Tv = 0.5
\Vertice[3]\X = X
\Vertice[3]\Y = Y
\Vertice[3]\Tu = 0.5
\Vertice[3]\Tv = 0.5
\Vertice[1]\X = X+X1
\Vertice[1]\Y = Y+Y1
\Vertice[2]\X = X+X2
\Vertice[2]\Y = Y+Y2
\Vertice[1]\Tu = 0.5+X1/MaxLength*0.5
\Vertice[1]\Tv = 0.5+Y1/MaxLength*0.5
\Vertice[2]\Tu = 0.5+X2/MaxLength*0.5
\Vertice[2]\Tv = 0.5+Y2/MaxLength*0.5
DisplaySprite3D(Sprite3D, 0, 0)
EndWith
EndProcedure
Procedure DisplayLight(Sprite3D.i, X.f, Y.f, List Corner.Corner(), MaxLength.f=386.0)
Protected *Corner1.Corner, *Corner2.Corner
Protected NewList CornerSort.CornerSort()
; Allen Ecken einen Winkel geben
ForEach Corner()
AddElement(CornerSort())
CornerSort()\Corner = @Corner()
CornerSort()\Angle = ATan2(Corner()\X, Corner()\Y)
Next
; Sortieren
SortStructuredList(CornerSort(), #PB_Sort_Ascending, OffsetOf(CornerSort\Angle), #PB_Sort_Float)
; Verschieben und Anzeigen
LastElement(CornerSort())
*Corner1 = CornerSort()\Corner
ResetList(CornerSort())
While NextElement(CornerSort())
*Corner2 = CornerSort()\Corner
DisplayLightCone(Sprite3D, X, Y, *Corner1\X, *Corner1\Y, *Corner2\X, *Corner2\Y, MaxLength)
NextElement(CornerSort())
*Corner1 = CornerSort()\Corner
Wend
EndProcedure
InitSprite()
InitSprite3D()
Enumeration
#Window
#Sprite
#Sprite3D
EndEnumeration
OpenWindow(#Window, 0, 0, 800, 600, "ScreenTitle", #PB_Window_SystemMenu|#PB_Window_ScreenCentered)
OpenWindowedScreen(WindowID(#Window), 0, 0, WindowWidth(#Window), WindowHeight(#Window), 0, 0, 0)
CreateSprite(#Sprite, 256, 256, #PB_Sprite_Texture)
StartDrawing(SpriteOutput(#Sprite))
For R = 127 To 1 Step -1
Gray = Pow(1-r/127.0, 2)*255
Circle(128, 128, R, RGB(Gray, Gray, Gray))
Next
StopDrawing()
CreateSprite3D(#Sprite3D, #Sprite)
NewList Corner.Corner()
RandomSeed(15)
For I = 0 To 9
Angle.f = Radian(Random(359))
AddElement(Corner())
Radius1.f = Random(256)+128
Corner()\X = Cos(Angle)*Radius1
Corner()\Y = Sin(Angle)*Radius1
AddElement(Corner())
Radius2.f = Random(256)+128
Corner()\X = Cos(Angle)*Radius2
Corner()\Y = Sin(Angle)*Radius2
Next
Repeat
Repeat
Select WindowEvent()
Case #PB_Event_CloseWindow
End
Case #Null
Break
EndSelect
ForEver
ClearScreen(0)
StartDrawing(ScreenOutput())
For X = 0 To 799
Line(X,0,1,600,RGB(X*128/799,0,128-X*128/799))
Next
StopDrawing()
If Start3D()
Sprite3DBlendingMode(5,2)
DisplayLight(#Sprite3D, 400, 300, Corner())
Stop3D()
EndIf
FlipBuffers()
Until WindowEvent() = #PB_Event_CloseWindow