Drawing3D - Draw-Befehle für 3D-Szenen

Du brauchst Grafiken, gute Programme oder Leute die dir helfen? Frag hier.
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6994
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von STARGÅTE »

Öm, soweit ich mich erinnere ... nein.
Aber ich bin natürlich offen für Vorschläge
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Benutzeravatar
Kurzer
Beiträge: 1614
Registriert: 25.04.2006 17:29
Wohnort: Nähe Hamburg

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von Kurzer »

Hallo Startgate,
kannst Du den link in deinem Ursprungspost noch auf die aktuellste Version anpassen?
Momentan lädt man sich damit eine Version herunter die noch nicht auf Module umgebaut ist.

Gruß Kurzer

btw: beeindruckendes Include! :allright:
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.02 x64, OS: Win 7 Pro x64 & Win 11 x64, Desktopscaling: 125%, CPU: I7 6500, RAM: 16 GB, GPU: Intel Graphics HD 520
Useralter in 2023: 56 Jahre.
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von ccode_new »

Hallo STARGÅTE,

deine Drawing3D-Funktionen gefallen mir.

Aber ich finde es schöner mit OpenGL.

Ich werde mir da selber etwas basteln.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6994
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von STARGÅTE »

Weil ich gerade dein OpenGL Code gesehen habe ...
Klar wäre OpenGL "eine" Möglichkeit. Ich hatte aber absichtlich auf externe Befehle verzichtet, weil ich ein paar Sachen unbedingt ermöglichen wollte, z.B. das richtiges z-sortieren von Pixeln mit Alpha-Channel.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
ccode_new
Beiträge: 1214
Registriert: 27.11.2016 18:13
Wohnort: Erzgebirge

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von ccode_new »

Hallöchen Meister STARGÅTE,

dein Code ist ja auch gut so wie er ist.

Alles hat seine Berechtigung und seinen Nutzen.

Ich habe bis jetzt auch noch nichts wirklich mit nativen OpenGl (gl, glu, glx, glut, ...) gemacht. Bis vor kurzer Zeit hatte ich noch nie etwas mit dem OpenGl-Gadget von PureBasic gemacht.

Ich habe mich seit dem im Forum geposteten Problem, mit dem statischen Linken von Glut, näher mit nativen OpenGl beschäftigt und bisher eigentlich nur kleine 2D und 3D Beispiele probiert.

Ich möchte damit aber gerne eine kleine 2D/3D Zeichenengine erstellen.

Hierbei würde ich auch erstmal bei OpenGl 2.1 bleiben und nicht mit OpenGl 4.5 arbeiten.

Vielleicht kommt auch noch ein bisschen OpenCl und OpenAl hinzu.

Wobei ich andere native Soundlösungen OpenAl vorziehe.

Und ich finde es eigentlich ganz Cool.

OpenGl ist schön Plattformunabhängig und hat viele tolle Möglichkeiten im 2D und 3D Bereich.

Außerdem habe ich mit dem OpenGl-Gadget keine Mausprobleme und es unterstützt auch sehr gut Touchscreens.
Betriebssysteme: div. Windows, Linux, Unix - Systeme

no Keyboard, press any key
no mouse, you need a cat
Michael Vogel
Beiträge: 71
Registriert: 16.03.2006 11:20

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von Michael Vogel »

Großartige Sache, das könnte man ja beispielsweise verwenden, um Möbel zu zeichnen...
Allerdings komme ich mit den Objektparametern nicht ganz klar, ein 60cm tiefer Kasten auf der Koordinate 0 und ein 40cm tiefer Kasten auf der Koordinate 20 sollten doch bündig abschließen, mache ich da etwas falsch?

Update: Oh, habe gerade bemerkt, dass scheinbar der erste Punkt den Objektmittelpunkt angibt, das werde ich wohl anpassen...

Code: Alles auswählen

XIncludeFile "3D-Library.pb"

Enumeration
	#Window
	#Gadget
EndEnumeration

Procedure DrawBoxWithBorder(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000)

	Drawing3DMode(#Drawing3D_Default)
	DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q)

	Drawing3DMode(#Drawing3D_Outline)
	DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, BorderColor.q)

EndProcedure

OpenWindow(#Window, 0, 0, 500, 500, "Cube with lines", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))

If StartDrawing3D(CanvasOutput(#Gadget))
	Drawing3DRotation(30,320,0, #PB_Absolute)
	Drawing3DPosition(-100, 0, -500)
	Drawing3DLight(0.5, 1, 1, $20FFFFFF)
	Drawing3DMode(#Drawing3D_Default)
	Drawing3DBackground($FFE0E0E0)
	Drawing3DLight(1, 1, 1, $40FFFFFF)
	DrawBoxWithBorder(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(63,0,10, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(189,0,20, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)
	StopDrawing3D()


EndIf

Repeat
	Select WaitWindowEvent()
	Case #PB_Event_CloseWindow
		End
	EndSelect
ForEver
Zur Sicherheit nochmals der ganze Code - inklusive der Bibliothek:

Code: Alles auswählen

; Define 3D-Library (Include File)

	EnableExplicit

	Structure Drawing3D_Color
		Red.f
		Green.f
		Blue.f
		Alpha.f
	EndStructure

	Structure Drawing3D_Vector
		X.f
		Y.f
		StructureUnion
			Z.f
			InvZ.f
		EndStructureUnion
	EndStructure

	Structure Drawing3D_Vertex Extends Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Matrix
		A11.f : A12.f : A13.f
		A21.f : A22.f : A23.f
		A31.f : A32.f : A33.f
	EndStructure

	Structure Drawing3D_Pixel
		Color.Drawing3D_Color
		Distance.f
		*PreviousPixel.Drawing3D_Pixel
	EndStructure

	Structure Drawing3D_Box
		Vertex.Drawing3D_Vertex[8]
	EndStructure

	Structure Drawing3D_Plane
		Vertex.Drawing3D_Vertex[4]
	EndStructure

	Structure Drawing3D_Triangle
		Vertex.Drawing3D_Vertex[3]
	EndStructure

	Structure Drawing3D_Line
		Vertex.Drawing3D_Vertex[2]
	EndStructure

	Structure Drawing3D_Light
		Direction.Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Cluster
		Type.i
		Position.Drawing3D_Vector
		Orientation.Drawing3D_Matrix
		List		Triangle.Drawing3D_Triangle()
		List		*Cluster.Drawing3D_Cluster()
	EndStructure

	; Structure Drawing3D_Object
	; 	StructureUnion
	; 		Type.i
	; 		Cluster.Drawing3D_Cluster
	; 		Line.Drawing3D_Line
	; 		Triangle.Drawing3D_Triangle
	; 	EndStructureUnion
	; EndStructure

	Structure Drawing3D_Image
		Number.i
		Array Pixel.Drawing3D_Color(0,0)
		Width.i
		Height.i
	EndStructure

	Structure Drawing3DInclude
		Array		*PixelIndex.Drawing3D_Pixel(0, 0) ; Index der Pixel für schnelleren Zugriff
		List		Pixel.Drawing3D_Pixel()           ; Liste aller zu zeichnenden Pixel
		List		Cluster.Drawing3D_Cluster()
		List		Light.Drawing3D_Light()           ; Liste aller Lichtquellen
		*CurrentCluster.Drawing3D_Cluster
		Orientation.Drawing3D_Matrix              ; Orientierung der Szene
		Position.Drawing3D_Vector                 ; Position der Kamera
		Background.Drawing3D_Color                ; Hintergrundfarbe
		MainCluster.Drawing3D_Cluster
		MaxX.i
		MaxY.i
		CenterX.i
		CenterY.i
		Distance.f
		RotX.f
		RotY.f
		RotZ.f
		CurrentColor.Drawing3D_Color[3]
		*CurrentImage3D.Drawing3D_Image
		List		Image3D.Drawing3D_Image()
		Array	*Image3DID.Drawing3D_Image(0)
		Mode.i
	EndStructure


	Global Drawing3DInclude.Drawing3DInclude


	#Drawing3D_NoColor = $100000000


	Enumeration
		;#Drawing3D_FrontOnly =
		#Drawing3D_Default = %000
		#Drawing3D_Outline = %001
	EndEnumeration





	;- Private: General
	Procedure.f Drawing3D_Min(Value1.f, Value2.f, Value3.f=1e30)
		If Value3 < Value2
			If Value3 < Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 < Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	Procedure.f Drawing3D_Max(Value1.f, Value2.f, Value3.f=-1e30)
		If Value3 > Value2
			If Value3 > Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 > Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure

	;- Private: Color
	Procedure.i Drawing3D_SetColor(*Use.Drawing3D_Color, Color.l)
		Protected Factor.f = Alpha(Color) / 255 / 255
		*Use\Alpha = Alpha(Color) / 255
		*Use\Red   = Red(Color) * Factor
		*Use\Green = Green(Color) * Factor
		*Use\Blue  = Blue(Color) * Factor
		ProcedureReturn *Use
	EndProcedure
	Procedure.l Drawing3D_GetColor(*Source.Drawing3D_Color)
		Protected Factor.f, A, R, G, B
		If *Source\Alpha
			Factor = 255.0/*Source\Alpha
			A = *Source\Alpha*255
			R = *Source\Red*Factor
			G = *Source\Green*Factor
			B = *Source\Blue*Factor
			ProcedureReturn R|G<<8|B<<16|A<<24
		Else
			ProcedureReturn 0
		EndIf
	EndProcedure
	Procedure Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
		Protected InvAlpha.f = 1.0 - *Source\Alpha
		*Use\Red   * InvAlpha + *Source\Red
		*Use\Green * InvAlpha + *Source\Green
		*Use\Blue  * InvAlpha + *Source\Blue
		*Use\Alpha * InvAlpha + *Source\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_NormalizeColor(*Use.Drawing3D_Color)
		Protected Max.f = Drawing3D_Max(*Use\Red, *Use\Green, *Use\Blue)
		If Max > 1
			*Use\Red / Max
			*Use\Green / Max
			*Use\Blue / Max
		EndIf
		*Use\Red * *Use\Alpha
		*Use\Green * *Use\Alpha
		*Use\Blue * *Use\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_ColorMix(*Color.Drawing3D_Color, Factor1.f, Factor2.f, Factor3.f)
		Protected *C1.Drawing3D_Color = Drawing3DInclude\CurrentColor[0]
		Protected *C2.Drawing3D_Color = Drawing3DInclude\CurrentColor[1]
		Protected *C3.Drawing3D_Color = Drawing3DInclude\CurrentColor[2]
		*Color\Alpha = *C1\Alpha*Factor1 + *C2\Alpha*Factor2 + *C3\Alpha*Factor3
		*Color\Red   = *C1\Red  *Factor1 + *C2\Red  *Factor2 + *C3\Red  *Factor3
		*Color\Green = *C1\Green*Factor1 + *C2\Green*Factor2 + *C3\Green*Factor3
		*Color\Blue  = *C1\Blue *Factor1 + *C2\Blue *Factor2 + *C3\Blue *Factor3
	EndProcedure
	Procedure.i Drawing3D_ImageColor(*Color.Drawing3D_Color, X.f, Y.f)
		Protected *Image3D.Drawing3D_Image = Drawing3DInclude\CurrentImage3D
		Protected FX.f = Mod(X**Image3D\Width+0.5, 1.0)
		Protected FY.f = Mod(Y**Image3D\Height+0.5, 1.0)
		Protected PixelX0.i = X * *Image3D\Width  - 0.5 - FX
		Protected PixelY0.i = Y * *Image3D\Height - 0.5 - FY
		Protected PixelX1.i = X * *Image3D\Width  + 0.5 - FX
		Protected PixelY1.i = Y * *Image3D\Height + 0.5 - FY
		If PixelX0 < 0 : PixelX0 = 0 : EndIf
		If PixelY0 < 0 : PixelY0 = 0 : EndIf
		If PixelX1 > *Image3D\Width-1 : PixelX1 = *Image3D\Width-1 : EndIf
		If PixelY1 > *Image3D\Height-1 : PixelY1 = *Image3D\Height-1 : EndIf
		Protected *C00.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY0)
		Protected *C10.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY0)
		Protected *C01.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY1)
		Protected *C11.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY1)
		*Color\Alpha = *C00\Alpha*(1-FX)*(1-FY) + *C10\Alpha*(FX)*(1-FY) + *C01\Alpha*(1-FX)*(FY) + *C11\Alpha*(FX)*(FY)
		*Color\Red   = *C00\Red  *(1-FX)*(1-FY) + *C10\Red  *(FX)*(1-FY) + *C01\Red  *(1-FX)*(FY) + *C11\Red  *(FX)*(FY)
		*Color\Green = *C00\Green*(1-FX)*(1-FY) + *C10\Green*(FX)*(1-FY) + *C01\Green*(1-FX)*(FY) + *C11\Green*(FX)*(FY)
		*Color\Blue  = *C00\Blue *(1-FX)*(1-FY) + *C10\Blue *(FX)*(1-FY) + *C01\Blue *(1-FX)*(FY) + *C11\Blue *(FX)*(FY)
	EndProcedure

	;- Private: Math
	Procedure.i Drawing3D_Vector(*Use.Drawing3D_Vector, X.f, Y.f, Z.f)
		*Use\X = X
		*Use\Y = Y
		*Use\Z = Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Length(*Source.Drawing3D_Vector)
		ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
	EndProcedure
	Procedure.i Drawing3D_Normalize(*Use.Drawing3D_Vector)
		Protected Length.f = Drawing3D_Length(*Use)
		If Length
			*Use\X / Length
			*Use\Y / Length
			*Use\Z / Length
		EndIf
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Copy(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X = *Source\X
		*Use\Y = *Source\Y
		*Use\Z = *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Add(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X + *Source\X
		*Use\Y + *Source\Y
		*Use\Z + *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Subtract(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X - *Source\X
		*Use\Y - *Source\Y
		*Use\Z - *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Cross(*Use.Drawing3D_Vector, *Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		*Use\X = *Source1\Y * *Source2\Z - *Source1\Z * *Source2\Y
		*Use\Y = *Source1\Z * *Source2\X - *Source1\X * *Source2\Z
		*Use\Z = *Source1\X * *Source2\Y - *Source1\Y * *Source2\X
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Scalar(*Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		ProcedureReturn *Source1\X * *Source2\X + *Source1\Y * *Source2\Y + *Source1\Z * *Source2\Z
	EndProcedure
	Procedure.i Drawing3D_Rotate(*Use.Drawing3D_Vector, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Vector
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Vector))
		*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
		*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
		*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Orientation(*Use.Drawing3D_Matrix, RotationX.f, RotationY.f, RotationZ.f)
		Protected CosZ.f = Cos(RotationZ), CosY.f = Cos(RotationY), CosX.f = Cos(RotationX)
		Protected SinZ.f = Sin(RotationZ), SinY.f = Sin(RotationY), SinX.f = Sin(RotationX)
		*Use\A11 =  CosY*CosZ                : *Use\A12 = -CosY*SinZ                : *Use\A13 =  SinY
		*Use\A21 =  SinX*SinY*CosZ+CosX*SinZ : *Use\A22 = -SinX*SinY*SinZ+CosX*CosZ : *Use\A23 = -SinX*CosY
		*Use\A31 = -CosX*SinY*CosZ+SinX*SinZ : *Use\A32 =  CosX*SinY*SinZ+SinX*CosZ : *Use\A33 =  CosX*CosY
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Multiply(*Use.Drawing3D_Matrix, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Matrix
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Matrix))
		With *Use
			\A11 = Buffer\A11 * *Source\A11 + Buffer\A12 * *Source\A21 + Buffer\A13 * *Source\A31
			\A12 = Buffer\A11 * *Source\A12 + Buffer\A12 * *Source\A22 + Buffer\A13 * *Source\A32
			\A13 = Buffer\A11 * *Source\A13 + Buffer\A12 * *Source\A23 + Buffer\A13 * *Source\A33
			\A21 = Buffer\A21 * *Source\A11 + Buffer\A22 * *Source\A21 + Buffer\A23 * *Source\A31
			\A22 = Buffer\A21 * *Source\A12 + Buffer\A22 * *Source\A22 + Buffer\A23 * *Source\A32
			\A23 = Buffer\A21 * *Source\A13 + Buffer\A22 * *Source\A23 + Buffer\A23 * *Source\A33
			\A31 = Buffer\A31 * *Source\A11 + Buffer\A32 * *Source\A21 + Buffer\A33 * *Source\A31
			\A32 = Buffer\A31 * *Source\A12 + Buffer\A32 * *Source\A22 + Buffer\A33 * *Source\A32
			\A33 = Buffer\A31 * *Source\A13 + Buffer\A32 * *Source\A23 + Buffer\A33 * *Source\A33
		EndWith
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Projection(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		If *Source\Z
			*Use\InvZ = 1 / *Source\Z
			*Use\X = - *Source\X * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterX
			*Use\Y =   *Source\Y * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterY
		EndIf
		ProcedureReturn *Use
	EndProcedure

	;- Private: Drawing
	Procedure Drawing3D_AddPixel(X.i, Y.i, Distance.f)

		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		If Distance < 0
			*Pixel = AddElement(Drawing3DInclude\Pixel())
			*OldPixel = Drawing3DInclude\PixelIndex(X, Y)
			If *OldPixel
				If Distance > *OldPixel\Distance
					*Pixel\PreviousPixel = *OldPixel
					Drawing3DInclude\PixelIndex(X, Y) = *Pixel
				Else
					While *OldPixel\PreviousPixel And *OldPixel\PreviousPixel\Distance > Distance
						*OldPixel = *OldPixel\PreviousPixel
					Wend
					*Pixel\PreviousPixel = *OldPixel\PreviousPixel
					*OldPixel\PreviousPixel = *Pixel
				EndIf
			Else
				Drawing3DInclude\PixelIndex(X, Y) = *Pixel
			EndIf
			*Pixel\Distance = Distance
		EndIf

		ProcedureReturn *Pixel

	EndProcedure
	Procedure Drawing3D_DrawTriangle(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex, *Vertex2.Drawing3D_Vertex, Texture.i=0)

		Protected Triangle.Drawing3D_Triangle
		Protected LightFactor.f, N.i

		With Triangle

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Drawing3D_Projection(\Vertex[2], *Vertex2) : \Vertex[2]\Color = *Vertex2\Color

			Protected X.i, Y.i
			Protected DX21.f = \Vertex[2]\X-\Vertex[1]\X, DY21.f = \Vertex[2]\Y-\Vertex[1]\Y
			Protected DX02.f = \Vertex[0]\X-\Vertex[2]\X, DY02.f = \Vertex[0]\Y-\Vertex[2]\Y
			Protected DX10.f = \Vertex[1]\X-\Vertex[0]\X, DY10.f = \Vertex[1]\Y-\Vertex[0]\Y
			Protected L1.f, L2.f, L3.f

			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), Drawing3DInclude\MaxY)

			Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Color.Drawing3D_Color, Norm.Drawing3D_Vector, V1.Drawing3D_Vector, V2.Drawing3D_Vector

			Protected T.f = 1.0 / (-DY21*DX02 + DX21*DY02)
			Protected Distance.f, Brightness.f, Q1.f, Q2.f

			;If T< 0 : ProcedureReturn 0 : EndIf

			If Texture = 0
				For N = 0 To 2
					\Vertex[N]\Color\Red / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Green / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Blue / \Vertex[N]\Color\Alpha
					Drawing3D_Copy(V1, *Vertex1) : Drawing3D_Subtract(V1, *Vertex0)
					Drawing3D_Copy(V2, *Vertex2) : Drawing3D_Subtract(V2, *Vertex0)
					Drawing3D_Normalize(Drawing3D_Cross(Norm, V2, V1))
					ForEach Drawing3DInclude\Light()
						LightFactor = Drawing3D_Scalar(Norm, Drawing3DInclude\Light()\Direction)*Sign(T)
						If LightFactor > 0
							\Vertex[N]\Color\Red   + LightFactor*Drawing3DInclude\Light()\Color\Red
							\Vertex[N]\Color\Green + LightFactor*Drawing3DInclude\Light()\Color\Green
							\Vertex[N]\Color\Blue  + LightFactor*Drawing3DInclude\Light()\Color\Blue
						EndIf
					Next
					Drawing3D_NormalizeColor(\Vertex[N]\Color)
					Drawing3DInclude\CurrentColor[N] = \Vertex[N]\Color
				Next
			EndIf

			For Y = YA To YB
				Q1 = DX21*(Y-\Vertex[2]\Y)
				Q2 = DX02*(Y-\Vertex[2]\Y)
				*Pixel = #Null
				For X = XA To XB
					L1 = ( -DY21*(X-\Vertex[2]\X) + Q1 ) * T
					L2 = ( -DY02*(X-\Vertex[2]\X) + Q2 ) * T
					L3 = 1.0 - L1 - L2
					If L1 >= 0.0 And L2 >= 0.0 And L3 >= 0.0
						Distance = 1.0 / ( L1*\Vertex[0]\InvZ + L2*\Vertex[1]\InvZ + L3*\Vertex[2]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							If Drawing3DInclude\CurrentImage3D
								If Texture = 1
									Drawing3D_ImageColor(*Pixel\Color, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
								Else
									Drawing3D_ImageColor(*Pixel\Color, 1.0-L2*\Vertex[1]\InvZ*Distance, 1.0-L3*\Vertex[2]\InvZ*Distance)
								EndIf
							Else
								Drawing3D_ColorMix(*Pixel\Color, L1*\Vertex[0]\InvZ*Distance, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
							EndIf
						EndIf
					ElseIf *Pixel
						Break
					EndIf
				Next
			Next

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawLine(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex)

		Protected Line.Drawing3D_Line, Distance.f
		Protected X.i, Y.i, Length.f, Position.f
		Protected Visible.f, Q.Drawing3D_Vector, R.Drawing3D_Vector, Cross.Drawing3D_Vector
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		With Line

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X)-1, 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X)+1, Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y)-1, 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y)+2, Drawing3DInclude\MaxY)
			Drawing3D_Copy(R, \Vertex[1])
			Drawing3D_Subtract(R, \Vertex[0])
			Length = Drawing3D_Length(R)
			Drawing3DInclude\CurrentColor[0] = \Vertex[0]\Color
			Drawing3DInclude\CurrentColor[1] = \Vertex[1]\Color

			For Y = YA To YB
				*Pixel = #Null
				For X = XA To XB
					Drawing3D_Vector(Q, X, Y, 0)
					Drawing3D_Subtract(Q, \Vertex[0])
					Drawing3D_Cross(Cross, Q, R)
					Position = Drawing3D_Scalar(Q, R) / Length
					Visible = 1 - Drawing3D_Length(Cross) / Length
					If Position >= 0 And Position <= Length And Visible > 0
						Distance = 1.0 / ( (1-Position/Length)*\Vertex[0]\InvZ + (Position/Length)*\Vertex[1]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							Drawing3D_ColorMix(*Pixel\Color, (1-Position/Length)*\Vertex[0]\InvZ*Distance*Visible, (Position/Length)*\Vertex[1]\InvZ*Distance*Visible, 0)
						EndIf
					EndIf
					If *Pixel And Visible < -1
						Break
					EndIf
				Next
			Next

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawPoint(*Vertex.Drawing3D_Vertex)

		Protected Vertex.Drawing3D_Vertex, Distance.f
		Protected X.i, Y.i
		Protected Visible.f
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Nothing.Drawing3D_Color

		Drawing3D_Projection(Vertex, *Vertex) : Vertex\Color = *Vertex\Color
		Protected XA.i = Drawing3D_Max(Vertex\X-1, 0)
		Protected XB.i = Drawing3D_Min(Vertex\X+1, Drawing3DInclude\MaxX)
		Protected YA.i = Drawing3D_Max(Vertex\Y-1, 0)
		Protected YB.i = Drawing3D_Min(Vertex\Y+1, Drawing3DInclude\MaxY)

		Drawing3DInclude\CurrentColor[0] = Vertex\Color
		For Y = YA To YB
			For X = XA To XB
				Visible = 1 - Sqr((X-Vertex\X)*(X-Vertex\X)+(Y-Vertex\Y)*(Y-Vertex\Y))
				If Visible > 0
					Distance = 1.0 / Vertex\InvZ
					*Pixel = Drawing3D_AddPixel(X, Y, Distance)
					If *Pixel
						Drawing3D_ColorMix(*Pixel\Color, Visible, 0, 0)
					EndIf
				EndIf
			Next
		Next

	EndProcedure

	;- Cluster (unfertig)
	Procedure.i CreateCluster3D()
		Protected *Cluster.Drawing3D_Cluster = AddElement(Drawing3DInclude\Cluster())
		Drawing3DInclude\CurrentCluster = *Cluster
		ProcedureReturn *Cluster
	EndProcedure
	Procedure CloseCluster3D()
	EndProcedure
	Procedure DrawCluster3D(*Cluster.Drawing3D_Cluster, X.f, Y.f, Z.f, Pitch.f=0.0, Yaw.f=0.0, Roll.f=0.0)
	EndProcedure

	;- Image3D
	Procedure.i Image3DID(Image3D.i)

		If Image3D & ~$FFFF
			ProcedureReturn Image3D
		Else
			ProcedureReturn Drawing3DInclude\Image3DID(Image3D)
		EndIf

	EndProcedure
	Procedure.i FreeImage3D(Image3D.i)

		Protected *Image3D.Drawing3D_Image = Image3DID(Image3D)

		With *Image3D

			If Not \Number & ~$FFFF
				Drawing3DInclude\Image3DID(\Number) = #Null
			EndIf

			ChangeCurrentElement(Drawing3DInclude\Image3D(), *Image3D)
			DeleteElement(Drawing3DInclude\Image3D())

		EndWith

	EndProcedure
	Procedure CreateImage3D(Image3D.i, Image.i)

		Protected *Image3D.Drawing3D_Image
		Protected X.i, Y.i

		If Image3D = #PB_Any
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = *Image3D
		ElseIf Not Image3D & ~$FFFF
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = Image3D
			If ArraySize(Drawing3DInclude\Image3DID()) < Image3D
				ReDim Drawing3DInclude\Image3DID(Image3D)
			ElseIf Drawing3DInclude\Image3DID(Image3D)
				FreeImage3D(Drawing3DInclude\Image3DID(Image3D))
			EndIf
			Drawing3DInclude\Image3DID(Image3D) = *Image3D
		Else
			ProcedureReturn #Null
		EndIf

		With *Image3D
			\Width  = ImageWidth(Image)
			\Height = ImageHeight(Image)
			Dim \Pixel(\Width-1, \Height-1)
			If StartDrawing(ImageOutput(Image))
				DrawingMode(#PB_2DDrawing_AllChannels)
				Select ImageDepth(Image, #PB_Image_InternalDepth)
				Case 24
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y)|$FF000000)
						Next
					Next
				Case 32
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y))
						Next
					Next
				EndSelect
				StopDrawing()
			EndIf
		EndWith

	EndProcedure

	;- Drawing
	Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
		; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle

		With Drawing3DInclude

			If StartDrawing(Output)

				DrawingMode(#PB_2DDrawing_AllChannels)

				\MaxX = OutputWidth()-1
				\MaxY = OutputHeight()-1
				\CenterX = OutputWidth()/2
				\CenterY = OutputHeight()/2
				\Distance = OutputHeight()/Tan(Radian(FieldOfView)*0.5)
				Drawing3D_Vector(Drawing3DInclude\Position, 0, 0, \Distance)

				If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY
					Dim \PixelIndex(\MaxX, \MaxY)
				Else
					FillMemory(@\PixelIndex(0,0), SizeOf(Integer)*(\MaxX+1)*(\MaxY+1))
				EndIf
				ClearList(\Pixel())
				ClearList(\Light())
				ClearStructure(\MainCluster, Drawing3D_Cluster)

				ProcedureReturn #True

			EndIf

		EndWith

	EndProcedure
	Procedure StopDrawing3D()
		; Schließt eine Drawing3D-Umgebung und rendert die Szene

		Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
		Protected Color.Drawing3D_Color
		Protected X.i, Y.i

		For Y = 0 To Drawing3DInclude\MaxY
			For X = 0 To Drawing3DInclude\MaxX
				*Pixel = Drawing3DInclude\PixelIndex(X, Y)
				If *Pixel
					While *Pixel\PreviousPixel
						Drawing3D_AlphaBlend(*Pixel\PreviousPixel\Color, *Pixel\Color)
						*Pixel = *Pixel\PreviousPixel
					Wend
					Color = Drawing3DInclude\Background
					Plot(X, Y, Drawing3D_GetColor(Drawing3D_AlphaBlend(Color, *Pixel)))
				EndIf
			Next
		Next

		StopDrawing()

	EndProcedure
	Procedure Drawing3DMode(Mode.i)
		; Ändert den Zeichenmodus

		Drawing3DInclude\Mode = Mode

	EndProcedure
	Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Position der Szene

		Protected Vector.Drawing3D_Vector

		If Mode = #PB_Relative
			Drawing3D_Vector(Vector, -X, -Y, -Z)
			Drawing3D_Add(Drawing3DInclude\Position, Vector)
		Else
			Drawing3D_Vector(Drawing3DInclude\Position, -X, -Y, -Z)
		EndIf

	EndProcedure
	Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Orientierung der Szene

		Protected Rotation.Drawing3D_Matrix

		If Mode = #PB_Relative
			Drawing3DInclude\RotX+RotationX
			Drawing3DInclude\RotY+RotationY
			Drawing3DInclude\RotZ+RotationZ
			Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
			Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
			Drawing3DInclude\Orientation = Rotation
		Else
			Drawing3DInclude\RotX=RotationX
			Drawing3DInclude\RotY=RotationY
			Drawing3DInclude\RotZ=RotationZ
			Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		EndIf

	EndProcedure
	Procedure Drawing3DBackground(Color.l=$FF000000)
		; Setzt den Szenenhintergrund

		Box(0, 0, OutputWidth(), OutputHeight(), Color)
		Drawing3D_SetColor(Drawing3DInclude\Background, Color)

	EndProcedure
	Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
		; Setzt ein Licht in die Szene

		Protected *Light.Drawing3D_Light = AddElement(Drawing3DInclude\Light())

		With *Light
			Drawing3D_Vector(\Direction, DirectionX, DirectionY, DirectionZ)
			Drawing3D_Normalize(\Direction)
			Drawing3D_SetColor(\Color, Color)
		EndWith

		ProcedureReturn *Light

	EndProcedure
	Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.q)
		; Zeichnet einen Punkt in die Szene

		Protected Vertex.Drawing3D_Vertex

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_SetColor(Vertex\Color, Color)
		Drawing3D_Rotate(Vertex, Drawing3DInclude\Orientation)
		Drawing3D_Subtract(Vertex, Drawing3DInclude\Position)
		Drawing3D_DrawPoint(Vertex)

	EndProcedure
	Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
		; Zeichnet eine Linie in die Szene

		Protected Line.Drawing3D_Line
		Protected N.i

		Drawing3D_Vector(Line\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Line\Vertex[1], X2, Y2, Z2)
		Drawing3D_SetColor(Line\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color2)
		EndIf
		For N = 0 To 1
			Drawing3D_Rotate(Line\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Line\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawLine(Line\Vertex[0], Line\Vertex[1])

	EndProcedure
	Procedure DrawTriangle3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor)
		; Zeichnet ein Dreieck in die Szene

		Protected Triangle.Drawing3D_Triangle
		Protected N.i

		Drawing3D_Vector(Triangle\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Triangle\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Triangle\Vertex[2], X3, Y3, Z3)
		Drawing3D_SetColor(Triangle\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color3)
		EndIf
		For N = 0 To 2
			Drawing3D_Rotate(Triangle\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Triangle\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Triangle\Vertex[0], Triangle\Vertex[1])
			Drawing3D_DrawLine(Triangle\Vertex[1], Triangle\Vertex[2])
			Drawing3D_DrawLine(Triangle\Vertex[2], Triangle\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Triangle\Vertex[0], Triangle\Vertex[1], Triangle\Vertex[2])
		EndIf

	EndProcedure
	Procedure DrawPlane3D(X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f, RotationY.f, RotationZ.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor, Color4.q=#Drawing3D_NoColor)
		; Zeichnet eine Ebene in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_SetColor(Plane\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color3)
		EndIf
		If Color4 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color4)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Plane\Vertex[0], Plane\Vertex[1])
			Drawing3D_DrawLine(Plane\Vertex[1], Plane\Vertex[3])
			Drawing3D_DrawLine(Plane\Vertex[3], Plane\Vertex[2])
			Drawing3D_DrawLine(Plane\Vertex[2], Plane\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2])
			Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1])
		EndIf
	EndProcedure
	Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q)
		; Zeichnet einen Quader in die Szene

		Protected Box.Drawing3D_Box
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Box\Vertex[0], -Width*0.5,  Height*0.5,  Depth*0.5)
		Drawing3D_Vector(Box\Vertex[1],  Width*0.5,  Height*0.5,  Depth*0.5)
		Drawing3D_Vector(Box\Vertex[2], -Width*0.5, -Height*0.5,  Depth*0.5)
		Drawing3D_Vector(Box\Vertex[3],  Width*0.5, -Height*0.5,  Depth*0.5)
		Drawing3D_Vector(Box\Vertex[4], -Width*0.5,  Height*0.5, -Depth*0.5)
		Drawing3D_Vector(Box\Vertex[5],  Width*0.5,  Height*0.5, -Depth*0.5)
		Drawing3D_Vector(Box\Vertex[6], -Width*0.5, -Height*0.5, -Depth*0.5)
		Drawing3D_Vector(Box\Vertex[7],  Width*0.5, -Height*0.5, -Depth*0.5)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 7
			Drawing3D_SetColor(Box\Vertex[N]\Color, Color)
			Drawing3D_Rotate(Box\Vertex[N], Orientation)
			Drawing3D_Add(Box\Vertex[N], Vertex)
			Drawing3D_Rotate(Box\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Box\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[1])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[6], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[2])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[5], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[4])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[3], Box\Vertex[7])
		Else
			Drawing3D_DrawTriangle(Box\Vertex[0], Box\Vertex[1], Box\Vertex[2])
			Drawing3D_DrawTriangle(Box\Vertex[3], Box\Vertex[2], Box\Vertex[1])
			Drawing3D_DrawTriangle(Box\Vertex[5], Box\Vertex[4], Box\Vertex[7])
			Drawing3D_DrawTriangle(Box\Vertex[6], Box\Vertex[7], Box\Vertex[4])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[5], Box\Vertex[3])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[3], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[0], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[6], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[5], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[0], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[3], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[6], Box\Vertex[3])
		EndIf

	EndProcedure
	Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
		; Zeichnet ein Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawTranformedImage3D(Image3D.i, X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, X4.f, Y4.f, Z4.f)
		; Zeichnet ein verzerrtes Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Plane\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Plane\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Plane\Vertex[2], X3, Y3, Z3)
		Drawing3D_Vector(Plane\Vertex[3], X4, Y4, Z4)
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawBoxWithBorder3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000)

		Drawing3DMode(#Drawing3D_Default)
		DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q)

		Drawing3DMode(#Drawing3D_Outline)
		DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, BorderColor.q)

	EndProcedure

	Drawing3D_Orientation(Drawing3DInclude\Orientation, 0, 0, 0)


; EndDefine

; Define Demonstration

	#WX=900
	#WY=600
	#WZ=300
	#WW=#WX+20

	CompilerIf #PB_Compiler_IsMainFile

		Enumeration
			#Window
			#Canvas
			#ListViewGadget
			#RotateZero
			#RotateX
			#RotateY
			#RotateZ
			#Image
			#Image3D
			#ButtonGadget
			#RealImage
		EndEnumeration


		Procedure UpdateRotationGadgets()

			With Drawing3DInclude
				SetGadgetState(#RotateX,\RotX)
				SetGadgetState(#RotateY,\RotY)
				SetGadgetState(#RotateZ,\RotZ)
			EndWith

		EndProcedure
		Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)

			Static MouseX.i, MouseY.i

			; **********************************
			Protected Distance.f = 500
			; **********************************
			Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f
			Protected Dim Y.f(40, 40)
			Protected Dim Color.l(40, 40)
			Protected Time1.q, Time2.q, Frequency.q
			Protected rx.f,ry.f,rz.f

			QueryPerformanceFrequency_(@Frequency)
			QueryPerformanceCounter_(@Time1)

			If Image
				StartDrawing3D(ImageOutput(Image))
				Drawing3DBackground($00FFFFFF)
			Else
				StartDrawing3D(CanvasOutput(Gadget))
				Drawing3DBackground($FFFFFFFF)
				Distance * Pow(1.1, GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta))
				If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
					rx=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15
					ry=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15
					Drawing3DRotation(Radian(rx),Radian(ry),0, #PB_Relative)
					UpdateRotationGadgets()
				EndIf
				MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
				MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
			EndIf

			; **********************************
			Drawing3DPosition(-100, 0, -Distance)
			; **********************************

			Select GetGadgetState(#ListViewGadget)

			Case 0
				DrawPlane3D(0, 0, 0, 340, 200,  0,  0,  0, $80FF0000)
				DrawPlane3D(0, 0, 0, 340, 200, 90, 90,  0, $800000FF)
				DrawPlane3D(0, 0, 0, 340, 200, 90,  0, 90, $8000FF00)

			Case 1
				Drawing3DMode(#Drawing3D_Outline)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
				Drawing3DMode(#Drawing3D_Default)

			Case 2
				Drawing3DLight(1, 0, 0, $FFFFFF00)
				Drawing3DLight(-1, 0, 0, $FF00FFFF)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)

			Case 3
				Drawing3DLight(0.5, 1, 1, $FFFFFFFF)
				DrawBox3D(0, 0, 0, 100, 200, 300, 0, 0, 0, $C000C060)
				DrawBox3D(0, 0, 0, 100, 200, 300, 30, 45, 15, $C08000C0)

			Case 4
				Drawing3DLight(0.5, 1, -1, $FFFFFFFF)
				DrawTriangle3D(-100, 100, 100, 100, 100, -100, 100, -100, 100, $FF00C000, $FFC00000, $FF0000C0)
				DrawTriangle3D(-100, 100, 100, 100, -100, 100, -100, -100, -100, $FF00C000, $FF0000C0, $FF00C0C0)
				DrawTriangle3D(-100, 100, 100, -100, -100, -100, 100, 100, -100, $FF00C000, $FF00C0C0, $FFC00000)
				DrawTriangle3D(100, -100, 100, 100, 100, -100, -100, -100, -100, $FF0000C0, $FFC00000, $FF00C0C0)
				DrawLine3D(90, -90, -90, -90, -90, 90, $FF00C000, $FFC00000)
				DrawLine3D(-90, -90, 90, -90, 90, -90, $FFC00000, $FF0000C0)
				DrawLine3D(-90, 90, -90, 90, -90, -90, $FF0000C0, $FF00C000)
				DrawLine3D(90, -90, -90, 90, 90, 90, $FF00C000, $FF00C0C0)
				DrawLine3D(-90, -90, 90, 90, 90, 90, $FFC00000, $FF00C0C0)
				DrawLine3D(-90, 90, -90, 90, 90, 90, $FF0000C0, $FF00C0C0)

			Case 5
				DrawImage3D(#Image3D, 0, 0, 0, 400, 400, 0, 0, 0)

			Case 6
				RandomSeed(1)
				For Y = -100 To 100
					For X = -100 To 100
						Z = Random(100)-50
						DrawPoint3D(X, Y, Z, $FF000000)
					Next
				Next

			Case 7
				Drawing3DLight(0.5, 1, 1, $40FFFFFF)
				DrawBox3D(0, 0, 0, 100, 30, 30, 0, 0, 0, $FF404040)
				DrawBox3D(-75, 0, 0, 50, 30, 30, 0, 0, 0, $FF808000)
				DrawBox3D(75, 0, 0, 50, 30, 30, 0, 0, 0, $FF000080)

				RandomSeed(5)
				For N = 1 To 50
					Phi = Random(359)
					R = Random(100)+30
					For W = 0 To 359 Step 5
						R1 = (1-Cos(Radian(W)))*R
						R2 = (1-Cos(Radian(W+5)))*R
						DrawLine3D(-Sin(Radian(W))*R*2, R1*Sin(Radian(Phi)), R1*Cos(Radian(Phi)), -Sin(Radian(W+5))*R*2, R2*Sin(Radian(Phi)), R2*Cos(Radian(Phi)), RGBA(255*W/360, 255*(360-W)/360, 255*(360-W)/360, 192))
					Next
				Next

			Case 8
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				For Z = -20 To 20
					For X = -20 To 20
						Y(X+20,Z+20) = Exp(-X*X/100-Z*Z/100)*(X+Z/4)/5
						If Y(X+20,Z+20) < 0
							Color(X+20,Z+20) = RGBA(0, 128+128*Y(X+20,Z+20), -255*Y(X+20,Z+20), 255)
						Else
							Color(X+20,Z+20) = RGBA(255*Y(X+20,Z+20), 128+128*Y(X+20,Z+20), 0, 255)
						EndIf
						Y(X+20,Z+20) * 200
					Next
				Next
				For Z = -20 To 19
					For X = -20 To 19
						DrawTriangle3D(X*10, Y(X+20,Z+20), Z*10, (X+1)*10, Y(X+21,Z+20), Z*10, X*10, Y(X+20,Z+21), (Z+1)*10, Color(X+20,Z+20), Color(X+21,Z+20), Color(X+20,Z+21))
						DrawTriangle3D((X+1)*10, Y(X+21,Z+21), (Z+1)*10, X*10, Y(X+20,Z+21), (Z+1)*10, (X+1)*10, Y(X+21,Z+20), Z*10, Color(X+21,Z+21), Color(X+20,Z+21), Color(X+21,Z+20))
					Next
				Next

			Case 9
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				Drawing3DMode(#Drawing3D_Default)
				Drawing3DBackground($FFE0E0E0)
				Drawing3DLight(1, 1, 1, $40FFFFFF)
				DrawBoxWithBorder3D(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
				DrawBoxWithBorder3D(63,0,10, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)
				DrawBoxWithBorder3D(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
				DrawBoxWithBorder3D(189,0,20, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)

			EndSelect

			StopDrawing3D()

			QueryPerformanceCounter_(@Time2)
			;SetWindowTitle(#Window, StrF((Time2-Time1)/Frequency*1000,3))

		EndProcedure

		UsePNGImageDecoder()
		UsePNGImageEncoder()

		CatchImage(#Image, ?Image)
		CreateImage3D(#Image3D, #Image)

		OpenWindow(#Window, 0, 0, #WX+#WZ+30, #WY+20, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
		CanvasGadget(#Canvas, 10, 10, #WX, #WY, #PB_Canvas_Border|#PB_Canvas_Keyboard)
		FrameGadget(#PB_Any, #WW, 10, #WZ, 190, "Szenenauswahl")
		ListViewGadget(#ListViewGadget, #WW+10, 30, #WZ-20, 160)
		AddGadgetItem(#ListViewGadget, -1, "Drei sich durchdringende Flächen")
		AddGadgetItem(#ListViewGadget, -1, "Würfel aus Linien")
		AddGadgetItem(#ListViewGadget, -1, "Belichteter Würfel")
		AddGadgetItem(#ListViewGadget, -1, "Zwei durchdringende Quader")
		AddGadgetItem(#ListViewGadget, -1, "Tetraeder mit verschiedenen Eckfarben")
		AddGadgetItem(#ListViewGadget, -1, "Texturfläche")
		AddGadgetItem(#ListViewGadget, -1, "Punkte")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: Magnet & Feldlinien")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: 3D-Funktion")
		AddGadgetItem(#ListViewGadget, -1, "Spielwiese")
		SetGadgetState(#ListViewGadget, 9)
		TextGadget(#PB_Any, #WW, 210, 290, 40, "drag object to rotate the scene, mouse wheel zooms")

		ButtonGadget(#RotateZero,#WW,250,100,30,"Reset")
		TrackBarGadget(#RotateX, #WW, 300, #WZ,20,0,360)
		TrackBarGadget(#RotateY, #WW, 330, #WZ,20,0,360)
		TrackBarGadget(#RotateZ, #WW, 360, #WZ,20,0,360)

		ButtonGadget(#ButtonGadget,#WW, 580, 120, 30, "Save Image...")

		Drawing3DRotation(10,300,0)
		UpdateRotationGadgets()
		UpdateCanvasGadget(#Canvas)

		Define FileName.s

		Repeat

			Select WaitWindowEvent()

			Case #PB_Event_CloseWindow
				End

			Case #PB_Event_Gadget
				Define e.i
				e=EventGadget()
				Select e
				Case #Canvas, #ListViewGadget
					UpdateCanvasGadget(#Canvas)

				Case #RotateZero
					Drawing3DRotation(0,0,0, #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					UpdateRotationGadgets()

				Case #RotateX To #RotateZ
					Drawing3DRotation(GetGadgetState(#RotateX),GetGadgetState(#RotateY),GetGadgetState(#RotateZ), #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					;UpdateRotationGadgets()
					Debug Drawing3DInclude\RotX

				Case #ButtonGadget
					CreateImage(#RealImage, 600, 600, 32|#PB_Image_Transparent)
					UpdateCanvasGadget(#Canvas, #RealImage)
					FileName = SaveFileRequester("Save", "", "*.png|*.PNG", 1)
					If FileName
						SaveImage(#RealImage, FileName, #PB_ImagePlugin_PNG)
					EndIf
				EndSelect

			EndSelect

		ForEver


		DataSection
			Image:
			IncludeBinary "Image.png"
		EndDataSection

	CompilerEndIf

; EndDefine
Benutzeravatar
STARGÅTE
Kommando SG1
Beiträge: 6994
Registriert: 01.11.2005 13:34
Wohnort: Glienicke
Kontaktdaten:

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von STARGÅTE »

Hallo Michael Vogel,

schön zu hören, dass das Include trotz allen 3D-Möglichkeiten die es sonst gibt noch Beliebtheit erfährt.
Im übrigen gibt es auf der Startseite auch n "neue" Version Drawing3D_20141109.zip, die als Modul included wird.
(Habe den Link korrigiert)

Die Frage hast du dir ja selbst beantwortet.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Michael Vogel
Beiträge: 71
Registriert: 16.03.2006 11:20

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von Michael Vogel »

Hi Stargåte,
danke für den aktualisierten Link - die Modulversion liefert bei mir allerdings andere Ergebnisse als die ursprüngliche Version (keine Linienglättung).

Ich wollte ja das vorige Posting mit meiner Frage auch gleich wieder löschen, ab das ging nicht, deshalb die Selbstantwort :)

Und weil es mir ohnehin schon ein wenig entglitten ist, werfe ich hier auch den aktualisierten Code (mit der adaptierten Version für DrawBox3D sowie DrawBoxWithBorder3D mit 'absoluter' oder 'gemittelter' Positionierung) gleich nach...

Code: Alles auswählen

; Define 3D-Library (Include File)

	EnableExplicit

	Structure Drawing3D_Color
		Red.f
		Green.f
		Blue.f
		Alpha.f
	EndStructure

	Structure Drawing3D_Vector
		X.f
		Y.f
		StructureUnion
			Z.f
			InvZ.f
		EndStructureUnion
	EndStructure

	Structure Drawing3D_Vertex Extends Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Matrix
		A11.f : A12.f : A13.f
		A21.f : A22.f : A23.f
		A31.f : A32.f : A33.f
	EndStructure

	Structure Drawing3D_Pixel
		Color.Drawing3D_Color
		Distance.f
		*PreviousPixel.Drawing3D_Pixel
	EndStructure

	Structure Drawing3D_Box
		Vertex.Drawing3D_Vertex[8]
	EndStructure

	Structure Drawing3D_Plane
		Vertex.Drawing3D_Vertex[4]
	EndStructure

	Structure Drawing3D_Triangle
		Vertex.Drawing3D_Vertex[3]
	EndStructure

	Structure Drawing3D_Line
		Vertex.Drawing3D_Vertex[2]
	EndStructure

	Structure Drawing3D_Light
		Direction.Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Cluster
		Type.i
		Position.Drawing3D_Vector
		Orientation.Drawing3D_Matrix
		List		Triangle.Drawing3D_Triangle()
		List		*Cluster.Drawing3D_Cluster()
	EndStructure

	; Structure Drawing3D_Object
	; 	StructureUnion
	; 		Type.i
	; 		Cluster.Drawing3D_Cluster
	; 		Line.Drawing3D_Line
	; 		Triangle.Drawing3D_Triangle
	; 	EndStructureUnion
	; EndStructure

	Structure Drawing3D_Image
		Number.i
		Array Pixel.Drawing3D_Color(0,0)
		Width.i
		Height.i
	EndStructure

	Structure Drawing3DInclude
		Array		*PixelIndex.Drawing3D_Pixel(0, 0) ; Index der Pixel für schnelleren Zugriff
		List		Pixel.Drawing3D_Pixel()           ; Liste aller zu zeichnenden Pixel
		List		Cluster.Drawing3D_Cluster()
		List		Light.Drawing3D_Light()           ; Liste aller Lichtquellen
		*CurrentCluster.Drawing3D_Cluster
		Orientation.Drawing3D_Matrix              ; Orientierung der Szene
		Position.Drawing3D_Vector                 ; Position der Kamera
		Background.Drawing3D_Color                ; Hintergrundfarbe
		MainCluster.Drawing3D_Cluster
		MaxX.i
		MaxY.i
		CenterX.i
		CenterY.i
		Distance.f
		RotX.f
		RotY.f
		RotZ.f
		CurrentColor.Drawing3D_Color[3]
		*CurrentImage3D.Drawing3D_Image
		List		Image3D.Drawing3D_Image()
		Array	*Image3DID.Drawing3D_Image(0)
		Mode.i
	EndStructure


	Global Drawing3DInclude.Drawing3DInclude


	#Drawing3D_NoColor = $100000000


	Enumeration
		;#Drawing3D_FrontOnly =
		#Drawing3D_Default = %000
		#Drawing3D_Outline = %001
	EndEnumeration

	Enumeration
		#Drawing3D_Centered
		#Drawing3D_Absolute
	EndEnumeration

	;- Private: General
	Procedure.f Drawing3D_Min(Value1.f, Value2.f, Value3.f=1e30)
		If Value3 < Value2
			If Value3 < Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 < Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	Procedure.f Drawing3D_Max(Value1.f, Value2.f, Value3.f=-1e30)
		If Value3 > Value2
			If Value3 > Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 > Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure

	;- Private: Color
	Procedure.i Drawing3D_SetColor(*Use.Drawing3D_Color, Color.l)
		Protected Factor.f = Alpha(Color) / 255 / 255
		*Use\Alpha = Alpha(Color) / 255
		*Use\Red   = Red(Color) * Factor
		*Use\Green = Green(Color) * Factor
		*Use\Blue  = Blue(Color) * Factor
		ProcedureReturn *Use
	EndProcedure
	Procedure.l Drawing3D_GetColor(*Source.Drawing3D_Color)
		Protected Factor.f, A, R, G, B
		If *Source\Alpha
			Factor = 255.0/*Source\Alpha
			A = *Source\Alpha*255
			R = *Source\Red*Factor
			G = *Source\Green*Factor
			B = *Source\Blue*Factor
			ProcedureReturn R|G<<8|B<<16|A<<24
		Else
			ProcedureReturn 0
		EndIf
	EndProcedure
	Procedure Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
		Protected InvAlpha.f = 1.0 - *Source\Alpha
		*Use\Red   * InvAlpha + *Source\Red
		*Use\Green * InvAlpha + *Source\Green
		*Use\Blue  * InvAlpha + *Source\Blue
		*Use\Alpha * InvAlpha + *Source\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_NormalizeColor(*Use.Drawing3D_Color)
		Protected Max.f = Drawing3D_Max(*Use\Red, *Use\Green, *Use\Blue)
		If Max > 1
			*Use\Red / Max
			*Use\Green / Max
			*Use\Blue / Max
		EndIf
		*Use\Red * *Use\Alpha
		*Use\Green * *Use\Alpha
		*Use\Blue * *Use\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_ColorMix(*Color.Drawing3D_Color, Factor1.f, Factor2.f, Factor3.f)
		Protected *C1.Drawing3D_Color = Drawing3DInclude\CurrentColor[0]
		Protected *C2.Drawing3D_Color = Drawing3DInclude\CurrentColor[1]
		Protected *C3.Drawing3D_Color = Drawing3DInclude\CurrentColor[2]
		*Color\Alpha = *C1\Alpha*Factor1 + *C2\Alpha*Factor2 + *C3\Alpha*Factor3
		*Color\Red   = *C1\Red  *Factor1 + *C2\Red  *Factor2 + *C3\Red  *Factor3
		*Color\Green = *C1\Green*Factor1 + *C2\Green*Factor2 + *C3\Green*Factor3
		*Color\Blue  = *C1\Blue *Factor1 + *C2\Blue *Factor2 + *C3\Blue *Factor3
	EndProcedure
	Procedure.i Drawing3D_ImageColor(*Color.Drawing3D_Color, X.f, Y.f)
		Protected *Image3D.Drawing3D_Image = Drawing3DInclude\CurrentImage3D
		Protected FX.f = Mod(X**Image3D\Width+0.5, 1.0)
		Protected FY.f = Mod(Y**Image3D\Height+0.5, 1.0)
		Protected PixelX0.i = X * *Image3D\Width  - 0.5 - FX
		Protected PixelY0.i = Y * *Image3D\Height - 0.5 - FY
		Protected PixelX1.i = X * *Image3D\Width  + 0.5 - FX
		Protected PixelY1.i = Y * *Image3D\Height + 0.5 - FY
		If PixelX0 < 0 : PixelX0 = 0 : EndIf
		If PixelY0 < 0 : PixelY0 = 0 : EndIf
		If PixelX1 > *Image3D\Width-1 : PixelX1 = *Image3D\Width-1 : EndIf
		If PixelY1 > *Image3D\Height-1 : PixelY1 = *Image3D\Height-1 : EndIf
		Protected *C00.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY0)
		Protected *C10.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY0)
		Protected *C01.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY1)
		Protected *C11.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY1)
		*Color\Alpha = *C00\Alpha*(1-FX)*(1-FY) + *C10\Alpha*(FX)*(1-FY) + *C01\Alpha*(1-FX)*(FY) + *C11\Alpha*(FX)*(FY)
		*Color\Red   = *C00\Red  *(1-FX)*(1-FY) + *C10\Red  *(FX)*(1-FY) + *C01\Red  *(1-FX)*(FY) + *C11\Red  *(FX)*(FY)
		*Color\Green = *C00\Green*(1-FX)*(1-FY) + *C10\Green*(FX)*(1-FY) + *C01\Green*(1-FX)*(FY) + *C11\Green*(FX)*(FY)
		*Color\Blue  = *C00\Blue *(1-FX)*(1-FY) + *C10\Blue *(FX)*(1-FY) + *C01\Blue *(1-FX)*(FY) + *C11\Blue *(FX)*(FY)
	EndProcedure

	;- Private: Math
	Procedure.i Drawing3D_Vector(*Use.Drawing3D_Vector, X.f, Y.f, Z.f)
		*Use\X = X
		*Use\Y = Y
		*Use\Z = Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Length(*Source.Drawing3D_Vector)
		ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
	EndProcedure
	Procedure.i Drawing3D_Normalize(*Use.Drawing3D_Vector)
		Protected Length.f = Drawing3D_Length(*Use)
		If Length
			*Use\X / Length
			*Use\Y / Length
			*Use\Z / Length
		EndIf
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Copy(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X = *Source\X
		*Use\Y = *Source\Y
		*Use\Z = *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Add(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X + *Source\X
		*Use\Y + *Source\Y
		*Use\Z + *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Subtract(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X - *Source\X
		*Use\Y - *Source\Y
		*Use\Z - *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Cross(*Use.Drawing3D_Vector, *Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		*Use\X = *Source1\Y * *Source2\Z - *Source1\Z * *Source2\Y
		*Use\Y = *Source1\Z * *Source2\X - *Source1\X * *Source2\Z
		*Use\Z = *Source1\X * *Source2\Y - *Source1\Y * *Source2\X
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Scalar(*Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		ProcedureReturn *Source1\X * *Source2\X + *Source1\Y * *Source2\Y + *Source1\Z * *Source2\Z
	EndProcedure
	Procedure.i Drawing3D_Rotate(*Use.Drawing3D_Vector, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Vector
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Vector))
		*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
		*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
		*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Orientation(*Use.Drawing3D_Matrix, RotationX.f, RotationY.f, RotationZ.f)
		Protected CosZ.f = Cos(RotationZ), CosY.f = Cos(RotationY), CosX.f = Cos(RotationX)
		Protected SinZ.f = Sin(RotationZ), SinY.f = Sin(RotationY), SinX.f = Sin(RotationX)
		*Use\A11 =  CosY*CosZ                : *Use\A12 = -CosY*SinZ                : *Use\A13 =  SinY
		*Use\A21 =  SinX*SinY*CosZ+CosX*SinZ : *Use\A22 = -SinX*SinY*SinZ+CosX*CosZ : *Use\A23 = -SinX*CosY
		*Use\A31 = -CosX*SinY*CosZ+SinX*SinZ : *Use\A32 =  CosX*SinY*SinZ+SinX*CosZ : *Use\A33 =  CosX*CosY
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Multiply(*Use.Drawing3D_Matrix, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Matrix
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Matrix))
		With *Use
			\A11 = Buffer\A11 * *Source\A11 + Buffer\A12 * *Source\A21 + Buffer\A13 * *Source\A31
			\A12 = Buffer\A11 * *Source\A12 + Buffer\A12 * *Source\A22 + Buffer\A13 * *Source\A32
			\A13 = Buffer\A11 * *Source\A13 + Buffer\A12 * *Source\A23 + Buffer\A13 * *Source\A33
			\A21 = Buffer\A21 * *Source\A11 + Buffer\A22 * *Source\A21 + Buffer\A23 * *Source\A31
			\A22 = Buffer\A21 * *Source\A12 + Buffer\A22 * *Source\A22 + Buffer\A23 * *Source\A32
			\A23 = Buffer\A21 * *Source\A13 + Buffer\A22 * *Source\A23 + Buffer\A23 * *Source\A33
			\A31 = Buffer\A31 * *Source\A11 + Buffer\A32 * *Source\A21 + Buffer\A33 * *Source\A31
			\A32 = Buffer\A31 * *Source\A12 + Buffer\A32 * *Source\A22 + Buffer\A33 * *Source\A32
			\A33 = Buffer\A31 * *Source\A13 + Buffer\A32 * *Source\A23 + Buffer\A33 * *Source\A33
		EndWith
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Projection(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		If *Source\Z
			*Use\InvZ = 1 / *Source\Z
			*Use\X = - *Source\X * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterX
			*Use\Y =   *Source\Y * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterY
		EndIf
		ProcedureReturn *Use
	EndProcedure

	;- Private: Drawing
	Procedure Drawing3D_AddPixel(X.i, Y.i, Distance.f)

		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		If Distance < 0
			*Pixel = AddElement(Drawing3DInclude\Pixel())
			*OldPixel = Drawing3DInclude\PixelIndex(X, Y)
			If *OldPixel
				If Distance > *OldPixel\Distance
					*Pixel\PreviousPixel = *OldPixel
					Drawing3DInclude\PixelIndex(X, Y) = *Pixel
				Else
					While *OldPixel\PreviousPixel And *OldPixel\PreviousPixel\Distance > Distance
						*OldPixel = *OldPixel\PreviousPixel
					Wend
					*Pixel\PreviousPixel = *OldPixel\PreviousPixel
					*OldPixel\PreviousPixel = *Pixel
				EndIf
			Else
				Drawing3DInclude\PixelIndex(X, Y) = *Pixel
			EndIf
			*Pixel\Distance = Distance
		EndIf

		ProcedureReturn *Pixel

	EndProcedure
	Procedure Drawing3D_DrawTriangle(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex, *Vertex2.Drawing3D_Vertex, Texture.i=0)

		Protected Triangle.Drawing3D_Triangle
		Protected LightFactor.f, N.i

		With Triangle

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Drawing3D_Projection(\Vertex[2], *Vertex2) : \Vertex[2]\Color = *Vertex2\Color

			Protected X.i, Y.i
			Protected DX21.f = \Vertex[2]\X-\Vertex[1]\X, DY21.f = \Vertex[2]\Y-\Vertex[1]\Y
			Protected DX02.f = \Vertex[0]\X-\Vertex[2]\X, DY02.f = \Vertex[0]\Y-\Vertex[2]\Y
			Protected DX10.f = \Vertex[1]\X-\Vertex[0]\X, DY10.f = \Vertex[1]\Y-\Vertex[0]\Y
			Protected L1.f, L2.f, L3.f

			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), Drawing3DInclude\MaxY)

			Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Color.Drawing3D_Color, Norm.Drawing3D_Vector, V1.Drawing3D_Vector, V2.Drawing3D_Vector

			Protected T.f = 1.0 / (-DY21*DX02 + DX21*DY02)
			Protected Distance.f, Brightness.f, Q1.f, Q2.f

			;If T< 0 : ProcedureReturn 0 : EndIf

			If Texture = 0
				For N = 0 To 2
					\Vertex[N]\Color\Red / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Green / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Blue / \Vertex[N]\Color\Alpha
					Drawing3D_Copy(V1, *Vertex1) : Drawing3D_Subtract(V1, *Vertex0)
					Drawing3D_Copy(V2, *Vertex2) : Drawing3D_Subtract(V2, *Vertex0)
					Drawing3D_Normalize(Drawing3D_Cross(Norm, V2, V1))
					ForEach Drawing3DInclude\Light()
						LightFactor = Drawing3D_Scalar(Norm, Drawing3DInclude\Light()\Direction)*Sign(T)
						If LightFactor > 0
							\Vertex[N]\Color\Red   + LightFactor*Drawing3DInclude\Light()\Color\Red
							\Vertex[N]\Color\Green + LightFactor*Drawing3DInclude\Light()\Color\Green
							\Vertex[N]\Color\Blue  + LightFactor*Drawing3DInclude\Light()\Color\Blue
						EndIf
					Next
					Drawing3D_NormalizeColor(\Vertex[N]\Color)
					Drawing3DInclude\CurrentColor[N] = \Vertex[N]\Color
				Next
			EndIf

			For Y = YA To YB
				Q1 = DX21*(Y-\Vertex[2]\Y)
				Q2 = DX02*(Y-\Vertex[2]\Y)
				*Pixel = #Null
				For X = XA To XB
					L1 = ( -DY21*(X-\Vertex[2]\X) + Q1 ) * T
					L2 = ( -DY02*(X-\Vertex[2]\X) + Q2 ) * T
					L3 = 1.0 - L1 - L2
					If L1 >= 0.0 And L2 >= 0.0 And L3 >= 0.0
						Distance = 1.0 / ( L1*\Vertex[0]\InvZ + L2*\Vertex[1]\InvZ + L3*\Vertex[2]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							If Drawing3DInclude\CurrentImage3D
								If Texture = 1
									Drawing3D_ImageColor(*Pixel\Color, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
								Else
									Drawing3D_ImageColor(*Pixel\Color, 1.0-L2*\Vertex[1]\InvZ*Distance, 1.0-L3*\Vertex[2]\InvZ*Distance)
								EndIf
							Else
								Drawing3D_ColorMix(*Pixel\Color, L1*\Vertex[0]\InvZ*Distance, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
							EndIf
						EndIf
					ElseIf *Pixel
						Break
					EndIf
				Next
			Next

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawLine(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex)

		Protected Line.Drawing3D_Line, Distance.f
		Protected X.i, Y.i, Length.f, Position.f
		Protected Visible.f, Q.Drawing3D_Vector, R.Drawing3D_Vector, Cross.Drawing3D_Vector
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		With Line

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X)-1, 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X)+1, Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y)-1, 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y)+2, Drawing3DInclude\MaxY)
			Drawing3D_Copy(R, \Vertex[1])
			Drawing3D_Subtract(R, \Vertex[0])
			Length = Drawing3D_Length(R)
			Drawing3DInclude\CurrentColor[0] = \Vertex[0]\Color
			Drawing3DInclude\CurrentColor[1] = \Vertex[1]\Color

			For Y = YA To YB
				*Pixel = #Null
				For X = XA To XB
					Drawing3D_Vector(Q, X, Y, 0)
					Drawing3D_Subtract(Q, \Vertex[0])
					Drawing3D_Cross(Cross, Q, R)
					Position = Drawing3D_Scalar(Q, R) / Length
					Visible = 1 - Drawing3D_Length(Cross) / Length
					If Position >= 0 And Position <= Length And Visible > 0
						Distance = 1.0 / ( (1-Position/Length)*\Vertex[0]\InvZ + (Position/Length)*\Vertex[1]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							Drawing3D_ColorMix(*Pixel\Color, (1-Position/Length)*\Vertex[0]\InvZ*Distance*Visible, (Position/Length)*\Vertex[1]\InvZ*Distance*Visible, 0)
						EndIf
					EndIf
					If *Pixel And Visible < -1
						Break
					EndIf
				Next
			Next

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawPoint(*Vertex.Drawing3D_Vertex)

		Protected Vertex.Drawing3D_Vertex, Distance.f
		Protected X.i, Y.i
		Protected Visible.f
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Nothing.Drawing3D_Color

		Drawing3D_Projection(Vertex, *Vertex) : Vertex\Color = *Vertex\Color
		Protected XA.i = Drawing3D_Max(Vertex\X-1, 0)
		Protected XB.i = Drawing3D_Min(Vertex\X+1, Drawing3DInclude\MaxX)
		Protected YA.i = Drawing3D_Max(Vertex\Y-1, 0)
		Protected YB.i = Drawing3D_Min(Vertex\Y+1, Drawing3DInclude\MaxY)

		Drawing3DInclude\CurrentColor[0] = Vertex\Color
		For Y = YA To YB
			For X = XA To XB
				Visible = 1 - Sqr((X-Vertex\X)*(X-Vertex\X)+(Y-Vertex\Y)*(Y-Vertex\Y))
				If Visible > 0
					Distance = 1.0 / Vertex\InvZ
					*Pixel = Drawing3D_AddPixel(X, Y, Distance)
					If *Pixel
						Drawing3D_ColorMix(*Pixel\Color, Visible, 0, 0)
					EndIf
				EndIf
			Next
		Next

	EndProcedure

	;- Cluster (unfertig)
	Procedure.i CreateCluster3D()
		Protected *Cluster.Drawing3D_Cluster = AddElement(Drawing3DInclude\Cluster())
		Drawing3DInclude\CurrentCluster = *Cluster
		ProcedureReturn *Cluster
	EndProcedure
	Procedure CloseCluster3D()
	EndProcedure
	Procedure DrawCluster3D(*Cluster.Drawing3D_Cluster, X.f, Y.f, Z.f, Pitch.f=0.0, Yaw.f=0.0, Roll.f=0.0)
	EndProcedure

	;- Image3D
	Procedure.i Image3DID(Image3D.i)

		If Image3D & ~$FFFF
			ProcedureReturn Image3D
		Else
			ProcedureReturn Drawing3DInclude\Image3DID(Image3D)
		EndIf

	EndProcedure
	Procedure.i FreeImage3D(Image3D.i)

		Protected *Image3D.Drawing3D_Image = Image3DID(Image3D)

		With *Image3D

			If Not \Number & ~$FFFF
				Drawing3DInclude\Image3DID(\Number) = #Null
			EndIf

			ChangeCurrentElement(Drawing3DInclude\Image3D(), *Image3D)
			DeleteElement(Drawing3DInclude\Image3D())

		EndWith

	EndProcedure
	Procedure CreateImage3D(Image3D.i, Image.i)

		Protected *Image3D.Drawing3D_Image
		Protected X.i, Y.i

		If Image3D = #PB_Any
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = *Image3D
		ElseIf Not Image3D & ~$FFFF
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = Image3D
			If ArraySize(Drawing3DInclude\Image3DID()) < Image3D
				ReDim Drawing3DInclude\Image3DID(Image3D)
			ElseIf Drawing3DInclude\Image3DID(Image3D)
				FreeImage3D(Drawing3DInclude\Image3DID(Image3D))
			EndIf
			Drawing3DInclude\Image3DID(Image3D) = *Image3D
		Else
			ProcedureReturn #Null
		EndIf

		With *Image3D
			\Width  = ImageWidth(Image)
			\Height = ImageHeight(Image)
			Dim \Pixel(\Width-1, \Height-1)
			If StartDrawing(ImageOutput(Image))
				DrawingMode(#PB_2DDrawing_AllChannels)
				Select ImageDepth(Image, #PB_Image_InternalDepth)
				Case 24
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y)|$FF000000)
						Next
					Next
				Case 32
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y))
						Next
					Next
				EndSelect
				StopDrawing()
			EndIf
		EndWith

	EndProcedure

	;- Drawing
	Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
		; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle

		With Drawing3DInclude

			If StartDrawing(Output)

				DrawingMode(#PB_2DDrawing_AllChannels)

				\MaxX = OutputWidth()-1
				\MaxY = OutputHeight()-1
				\CenterX = OutputWidth()/2
				\CenterY = OutputHeight()/2
				\Distance = OutputHeight()/Tan(Radian(FieldOfView)*0.5)
				Drawing3D_Vector(Drawing3DInclude\Position, 0, 0, \Distance)

				If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY
					Dim \PixelIndex(\MaxX, \MaxY)
				Else
					FillMemory(@\PixelIndex(0,0), SizeOf(Integer)*(\MaxX+1)*(\MaxY+1))
				EndIf
				ClearList(\Pixel())
				ClearList(\Light())
				ClearStructure(\MainCluster, Drawing3D_Cluster)

				ProcedureReturn #True

			EndIf

		EndWith

	EndProcedure
	Procedure StopDrawing3D()
		; Schließt eine Drawing3D-Umgebung und rendert die Szene

		Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
		Protected Color.Drawing3D_Color
		Protected X.i, Y.i

		For Y = 0 To Drawing3DInclude\MaxY
			For X = 0 To Drawing3DInclude\MaxX
				*Pixel = Drawing3DInclude\PixelIndex(X, Y)
				If *Pixel
					While *Pixel\PreviousPixel
						Drawing3D_AlphaBlend(*Pixel\PreviousPixel\Color, *Pixel\Color)
						*Pixel = *Pixel\PreviousPixel
					Wend
					Color = Drawing3DInclude\Background
					Plot(X, Y, Drawing3D_GetColor(Drawing3D_AlphaBlend(Color, *Pixel)))
				EndIf
			Next
		Next

		StopDrawing()

	EndProcedure
	Procedure Drawing3DMode(Mode.i)
		; Ändert den Zeichenmodus

		Drawing3DInclude\Mode = Mode

	EndProcedure
	Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Position der Szene

		Protected Vector.Drawing3D_Vector

		If Mode = #PB_Relative
			Drawing3D_Vector(Vector, -X, -Y, -Z)
			Drawing3D_Add(Drawing3DInclude\Position, Vector)
		Else
			Drawing3D_Vector(Drawing3DInclude\Position, -X, -Y, -Z)
		EndIf

	EndProcedure
	Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Orientierung der Szene

		Protected Rotation.Drawing3D_Matrix

		If Mode = #PB_Relative
			Drawing3DInclude\RotX+RotationX
			Drawing3DInclude\RotY+RotationY
			Drawing3DInclude\RotZ+RotationZ
			Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
			Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
			Drawing3DInclude\Orientation = Rotation
		Else
			Drawing3DInclude\RotX=RotationX
			Drawing3DInclude\RotY=RotationY
			Drawing3DInclude\RotZ=RotationZ
			Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		EndIf

	EndProcedure
	Procedure Drawing3DBackground(Color.l=$FF000000)
		; Setzt den Szenenhintergrund

		Box(0, 0, OutputWidth(), OutputHeight(), Color)
		Drawing3D_SetColor(Drawing3DInclude\Background, Color)

	EndProcedure
	Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
		; Setzt ein Licht in die Szene

		Protected *Light.Drawing3D_Light = AddElement(Drawing3DInclude\Light())

		With *Light
			Drawing3D_Vector(\Direction, DirectionX, DirectionY, DirectionZ)
			Drawing3D_Normalize(\Direction)
			Drawing3D_SetColor(\Color, Color)
		EndWith

		ProcedureReturn *Light

	EndProcedure
	Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.q)
		; Zeichnet einen Punkt in die Szene

		Protected Vertex.Drawing3D_Vertex

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_SetColor(Vertex\Color, Color)
		Drawing3D_Rotate(Vertex, Drawing3DInclude\Orientation)
		Drawing3D_Subtract(Vertex, Drawing3DInclude\Position)
		Drawing3D_DrawPoint(Vertex)

	EndProcedure
	Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
		; Zeichnet eine Linie in die Szene

		Protected Line.Drawing3D_Line
		Protected N.i

		Drawing3D_Vector(Line\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Line\Vertex[1], X2, Y2, Z2)
		Drawing3D_SetColor(Line\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color2)
		EndIf
		For N = 0 To 1
			Drawing3D_Rotate(Line\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Line\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawLine(Line\Vertex[0], Line\Vertex[1])

	EndProcedure
	Procedure DrawTriangle3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor)
		; Zeichnet ein Dreieck in die Szene

		Protected Triangle.Drawing3D_Triangle
		Protected N.i

		Drawing3D_Vector(Triangle\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Triangle\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Triangle\Vertex[2], X3, Y3, Z3)
		Drawing3D_SetColor(Triangle\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color3)
		EndIf
		For N = 0 To 2
			Drawing3D_Rotate(Triangle\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Triangle\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Triangle\Vertex[0], Triangle\Vertex[1])
			Drawing3D_DrawLine(Triangle\Vertex[1], Triangle\Vertex[2])
			Drawing3D_DrawLine(Triangle\Vertex[2], Triangle\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Triangle\Vertex[0], Triangle\Vertex[1], Triangle\Vertex[2])
		EndIf

	EndProcedure
	Procedure DrawPlane3D(X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f, RotationY.f, RotationZ.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor, Color4.q=#Drawing3D_NoColor)
		; Zeichnet eine Ebene in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_SetColor(Plane\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color3)
		EndIf
		If Color4 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color4)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Plane\Vertex[0], Plane\Vertex[1])
			Drawing3D_DrawLine(Plane\Vertex[1], Plane\Vertex[3])
			Drawing3D_DrawLine(Plane\Vertex[3], Plane\Vertex[2])
			Drawing3D_DrawLine(Plane\Vertex[2], Plane\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2])
			Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1])
		EndIf
	EndProcedure
	Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q, Mode.i=#Drawing3D_Centered)
		; Zeichnet einen Quader in die Szene

		Protected Box.Drawing3D_Box
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		If Mode=#Drawing3D_Absolute
			Drawing3D_Vector(Box\Vertex[0],	0,	Height,	Depth)
			Drawing3D_Vector(Box\Vertex[1],	Width,Height,	Depth)
			Drawing3D_Vector(Box\Vertex[2], 0, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[3],  Width, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[4], 0,  Height, 0)
			Drawing3D_Vector(Box\Vertex[5],  Width,  Height, 0)
			Drawing3D_Vector(Box\Vertex[6], 0, 0, 0)
			Drawing3D_Vector(Box\Vertex[7],  Width, 0, 0)
		Else
			Drawing3D_Vector(Box\Vertex[0], -Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[1],  Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[2], -Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[3],  Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[4], -Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[5],  Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[6], -Width*0.5, -Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[7],  Width*0.5, -Height*0.5, -Depth*0.5)
		EndIf

		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 7
			Drawing3D_SetColor(Box\Vertex[N]\Color, Color)
			Drawing3D_Rotate(Box\Vertex[N], Orientation)
			Drawing3D_Add(Box\Vertex[N], Vertex)
			Drawing3D_Rotate(Box\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Box\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[1])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[6], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[2])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[5], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[4])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[3], Box\Vertex[7])
		Else
			Drawing3D_DrawTriangle(Box\Vertex[0], Box\Vertex[1], Box\Vertex[2])
			Drawing3D_DrawTriangle(Box\Vertex[3], Box\Vertex[2], Box\Vertex[1])
			Drawing3D_DrawTriangle(Box\Vertex[5], Box\Vertex[4], Box\Vertex[7])
			Drawing3D_DrawTriangle(Box\Vertex[6], Box\Vertex[7], Box\Vertex[4])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[5], Box\Vertex[3])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[3], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[0], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[6], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[5], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[0], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[3], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[6], Box\Vertex[3])
		EndIf

	EndProcedure
	Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
		; Zeichnet ein Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawTranformedImage3D(Image3D.i, X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, X4.f, Y4.f, Z4.f)
		; Zeichnet ein verzerrtes Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Plane\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Plane\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Plane\Vertex[2], X3, Y3, Z3)
		Drawing3D_Vector(Plane\Vertex[3], X4, Y4, Z4)
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawBoxWithBorder3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)

		Drawing3DMode(#Drawing3D_Default)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, SurfaceColor, Mode)

		Drawing3DMode(#Drawing3D_Outline)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, BorderColor, Mode)

	EndProcedure

	Drawing3D_Orientation(Drawing3DInclude\Orientation, 0, 0, 0)


; EndDefine

; Define Demonstration

	#WX=1040
	#WY=800
	#WZ=300
	#WW=#WX+20

	CompilerIf #PB_Compiler_IsMainFile

		Enumeration
			#Window
			#Canvas
			#ListViewGadget
			#RotateZero
			#RotateX
			#RotateY
			#RotateZ
			#Image
			#Image3D
			#ButtonGadget
			#RealImage
		EndEnumeration


		Procedure UpdateRotationGadgets()

			With Drawing3DInclude
				SetGadgetState(#RotateX,\RotX)
				SetGadgetState(#RotateY,\RotY)
				SetGadgetState(#RotateZ,\RotZ)
			EndWith

		EndProcedure
		Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)

			Static MouseX.i, MouseY.i

			; **********************************
			Protected Distance.f = 500
			; **********************************

			Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f
			Protected Dim Y.f(40, 40)
			Protected Dim Color.l(40, 40)
			Protected Time1.q, Time2.q, Frequency.q
			Protected rx.f,ry.f,rz.f

			QueryPerformanceFrequency_(@Frequency)
			QueryPerformanceCounter_(@Time1)

			If Image
				StartDrawing3D(ImageOutput(Image))
				Drawing3DBackground($00FFFFFF)
			Else
				StartDrawing3D(CanvasOutput(Gadget))
				Drawing3DBackground($FFFFFFFF)
				Distance * Pow(1.1, GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta))
				If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
					rx=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15
					ry=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15
					Drawing3DRotation(Radian(rx),Radian(ry),0, #PB_Relative)
					UpdateRotationGadgets()
				EndIf
				MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
				MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
			EndIf

			; **********************************
			Drawing3DPosition(-100, -100, -Distance)
			; **********************************

			Select GetGadgetState(#ListViewGadget)

			Case 0
				DrawPlane3D(0, 0, 0, 340, 200,  0,  0,  0, $80FF0000)
				DrawPlane3D(0, 0, 0, 340, 200, 90, 90,  0, $800000FF)
				DrawPlane3D(0, 0, 0, 340, 200, 90,  0, 90, $8000FF00)

			Case 1
				Drawing3DMode(#Drawing3D_Outline)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
				Drawing3DMode(#Drawing3D_Default)

			Case 2
				Drawing3DLight(1, 0, 0, $FFFFFF00)
				Drawing3DLight(-1, 0, 0, $FF00FFFF)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)

			Case 3
				Drawing3DLight(0.5, 1, 1, $FFFFFFFF)
				DrawBox3D(0, 0, 0, 100, 200, 300, 0, 0, 0, $C000C060)
				DrawBox3D(0, 0, 0, 100, 200, 300, 30, 45, 15, $C08000C0)

			Case 4
				Drawing3DLight(0.5, 1, -1, $FFFFFFFF)
				DrawTriangle3D(-100, 100, 100, 100, 100, -100, 100, -100, 100, $FF00C000, $FFC00000, $FF0000C0)
				DrawTriangle3D(-100, 100, 100, 100, -100, 100, -100, -100, -100, $FF00C000, $FF0000C0, $FF00C0C0)
				DrawTriangle3D(-100, 100, 100, -100, -100, -100, 100, 100, -100, $FF00C000, $FF00C0C0, $FFC00000)
				DrawTriangle3D(100, -100, 100, 100, 100, -100, -100, -100, -100, $FF0000C0, $FFC00000, $FF00C0C0)
				DrawLine3D(90, -90, -90, -90, -90, 90, $FF00C000, $FFC00000)
				DrawLine3D(-90, -90, 90, -90, 90, -90, $FFC00000, $FF0000C0)
				DrawLine3D(-90, 90, -90, 90, -90, -90, $FF0000C0, $FF00C000)
				DrawLine3D(90, -90, -90, 90, 90, 90, $FF00C000, $FF00C0C0)
				DrawLine3D(-90, -90, 90, 90, 90, 90, $FFC00000, $FF00C0C0)
				DrawLine3D(-90, 90, -90, 90, 90, 90, $FF0000C0, $FF00C0C0)

			Case 5
				DrawImage3D(#Image3D, 0, 0, 0, 400, 400, 0, 0, 0)

			Case 6
				RandomSeed(1)
				For Y = -100 To 100
					For X = -100 To 100
						Z = Random(100)-50
						DrawPoint3D(X, Y, Z, $FF000000)
					Next
				Next

			Case 7
				Drawing3DLight(0.5, 1, 1, $40FFFFFF)
				DrawBox3D(0, 0, 0, 100, 30, 30, 0, 0, 0, $FF404040)
				DrawBox3D(-75, 0, 0, 50, 30, 30, 0, 0, 0, $FF808000)
				DrawBox3D(75, 0, 0, 50, 30, 30, 0, 0, 0, $FF000080)

				RandomSeed(5)
				For N = 1 To 50
					Phi = Random(359)
					R = Random(100)+30
					For W = 0 To 359 Step 5
						R1 = (1-Cos(Radian(W)))*R
						R2 = (1-Cos(Radian(W+5)))*R
						DrawLine3D(-Sin(Radian(W))*R*2, R1*Sin(Radian(Phi)), R1*Cos(Radian(Phi)), -Sin(Radian(W+5))*R*2, R2*Sin(Radian(Phi)), R2*Cos(Radian(Phi)), RGBA(255*W/360, 255*(360-W)/360, 255*(360-W)/360, 192))
					Next
				Next

			Case 8
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				For Z = -20 To 20
					For X = -20 To 20
						Y(X+20,Z+20) = Exp(-X*X/100-Z*Z/100)*(X+Z/4)/5
						If Y(X+20,Z+20) < 0
							Color(X+20,Z+20) = RGBA(0, 128+128*Y(X+20,Z+20), -255*Y(X+20,Z+20), 255)
						Else
							Color(X+20,Z+20) = RGBA(255*Y(X+20,Z+20), 128+128*Y(X+20,Z+20), 0, 255)
						EndIf
						Y(X+20,Z+20) * 200
					Next
				Next
				For Z = -20 To 19
					For X = -20 To 19
						DrawTriangle3D(X*10, Y(X+20,Z+20), Z*10, (X+1)*10, Y(X+21,Z+20), Z*10, X*10, Y(X+20,Z+21), (Z+1)*10, Color(X+20,Z+20), Color(X+21,Z+20), Color(X+20,Z+21))
						DrawTriangle3D((X+1)*10, Y(X+21,Z+21), (Z+1)*10, X*10, Y(X+20,Z+21), (Z+1)*10, (X+1)*10, Y(X+21,Z+20), Z*10, Color(X+21,Z+21), Color(X+20,Z+21), Color(X+21,Z+20))
					Next
				Next

			Case 9
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				Drawing3DMode(#Drawing3D_Default)
				Drawing3DBackground($FFE0E0E0)
				Drawing3DLight(1, 1, 1, $40FFFFFF)
				; unten
				DrawBoxWithBorder3D(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,0,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; mittig
				DrawBoxWithBorder3D(0,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,51,0, 62,25,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; links/rechts
				DrawBoxWithBorder3D(0,77,0, 62,130,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,77,0, 62,130,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; oben
				DrawBoxWithBorder3D(0,208,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; Platten
				DrawBoxWithBorder3D(62,77,0, 1,181,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,207,0, 125,1,42, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,76,0, 125,1,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,0,40, 1,76,20, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,76,0, 1,131,40, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				
				
				; Achsen
				DrawLine3D(0,0,0, 100,0,0, $FF000000)
				DrawLine3D(0,0,0, 0,100,0, $FF000000)
				DrawLine3D(0,0,0, 0,0,100, $FF000000)

			EndSelect

			StopDrawing3D()

			QueryPerformanceCounter_(@Time2)
			;SetWindowTitle(#Window, StrF((Time2-Time1)/Frequency*1000,3))

		EndProcedure

		UsePNGImageDecoder()
		UsePNGImageEncoder()

		CatchImage(#Image, ?Image)
		CreateImage3D(#Image3D, #Image)

		OpenWindow(#Window, 0, 0, #WX+#WZ+30, #WY+20, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
		CanvasGadget(#Canvas, 10, 10, #WX, #WY, #PB_Canvas_Border|#PB_Canvas_Keyboard)
		FrameGadget(#PB_Any, #WW, 10, #WZ, 190, "Szenenauswahl")
		ListViewGadget(#ListViewGadget, #WW+10, 30, #WZ-20, 160)
		AddGadgetItem(#ListViewGadget, -1, "Drei sich durchdringende Flächen")
		AddGadgetItem(#ListViewGadget, -1, "Würfel aus Linien")
		AddGadgetItem(#ListViewGadget, -1, "Belichteter Würfel")
		AddGadgetItem(#ListViewGadget, -1, "Zwei durchdringende Quader")
		AddGadgetItem(#ListViewGadget, -1, "Tetraeder mit verschiedenen Eckfarben")
		AddGadgetItem(#ListViewGadget, -1, "Texturfläche")
		AddGadgetItem(#ListViewGadget, -1, "Punkte")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: Magnet & Feldlinien")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: 3D-Funktion")
		AddGadgetItem(#ListViewGadget, -1, "Spielwiese")
		SetGadgetState(#ListViewGadget, 9)
		TextGadget(#PB_Any, #WW, 210, 290, 40, "drag object to rotate the scene, mouse wheel zooms")

		ButtonGadget(#RotateZero,#WW,250,100,30,"Reset")
		TrackBarGadget(#RotateX, #WW, 300, #WZ,20,0,360)
		TrackBarGadget(#RotateY, #WW, 330, #WZ,20,0,360)
		TrackBarGadget(#RotateZ, #WW, 360, #WZ,20,0,360)

		ButtonGadget(#ButtonGadget,#WW, 580, 120, 30, "Save Image...")

		; **********************************
		Drawing3DRotation(10,330,0)
		; **********************************

		UpdateRotationGadgets()
		UpdateCanvasGadget(#Canvas)

		Define FileName.s

		Repeat

			Select WaitWindowEvent()

			Case #PB_Event_CloseWindow
				End

			Case #PB_Event_Gadget
				Define e.i
				e=EventGadget()
				Select e
				Case #Canvas, #ListViewGadget
					UpdateCanvasGadget(#Canvas)

				Case #RotateZero
					Drawing3DRotation(0,0,0, #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					UpdateRotationGadgets()

				Case #RotateX To #RotateZ
					Drawing3DRotation(GetGadgetState(#RotateX),GetGadgetState(#RotateY),GetGadgetState(#RotateZ), #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					;UpdateRotationGadgets()
					Debug Drawing3DInclude\RotX

				Case #ButtonGadget
					CreateImage(#RealImage, 600, 600, 32|#PB_Image_Transparent)
					UpdateCanvasGadget(#Canvas, #RealImage)
					FileName = SaveFileRequester("Save", "", "*.png|*.PNG", 1)
					If FileName
						SaveImage(#RealImage, FileName, #PB_ImagePlugin_PNG)
					EndIf
				EndSelect

			EndSelect

		ForEver

		DataSection
			Image:
			IncludeBinary "Image.png"
		EndDataSection

	CompilerEndIf

; EndDefine
Michael Vogel
Beiträge: 71
Registriert: 16.03.2006 11:20

Re: Drawing3D - Draw-Befehle für 3D-Szenen

Beitrag von Michael Vogel »

Noch ein kleiner Nachschlag - vielleicht könnte die Verwendung der Vektorgrafikbibliothek zu einen wahren Geschwindigkeitsrausch verhelfen :lol:

Auch wenn man mit diesem Ansatz kaum an die wunderbaren Überschneidungen des Originalcodes herankommen kann, könnte damit beispielsweise ein brauchbarer Baukasten etwa zum Gestalten von Inneneinrichtungen (Kästen, Möbel etc.) geschaffen werden.

Im folgenden wurden nur einige wenige Zeilen angepasst, das Ergebnis ist zwar noch recht bescheiden, allerdings benötigt ein Bildschirm-Update nun wenige Millisekunden...

Code: Alles auswählen

Global huch
Global t1,t2,t3,t4,t5,t6,t7,t8,t9

; Define 3D-Library (Include File)

	EnableExplicit

	Structure Drawing3D_Color
		Red.f
		Green.f
		Blue.f
		Alpha.f
	EndStructure

	Structure Drawing3D_Vector
		X.f
		Y.f
		StructureUnion
			Z.f
			InvZ.f
		EndStructureUnion
	EndStructure

	Structure Drawing3D_Vertex Extends Drawing3D_Vector
		Color.Drawing3D_Color
		BorderColor.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Matrix
		A11.f : A12.f : A13.f
		A21.f : A22.f : A23.f
		A31.f : A32.f : A33.f
	EndStructure

	Structure Drawing3D_Pixel
		Color.Drawing3D_Color
		Distance.f
		*PreviousPixel.Drawing3D_Pixel
	EndStructure

	Structure Drawing3D_Box
		Vertex.Drawing3D_Vertex[8]
	EndStructure

	Structure Drawing3D_Plane
		Vertex.Drawing3D_Vertex[4]
	EndStructure

	Structure Drawing3D_Triangle
		Vertex.Drawing3D_Vertex[3]
	EndStructure

	Structure Drawing3D_Line
		Vertex.Drawing3D_Vertex[2]
	EndStructure

	Structure Drawing3D_Light
		Direction.Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure

	Structure Drawing3D_Cluster
		Type.i
		Position.Drawing3D_Vector
		Orientation.Drawing3D_Matrix
		List		Triangle.Drawing3D_Triangle()
		List		*Cluster.Drawing3D_Cluster()
	EndStructure

	; Structure Drawing3D_Object
	; 	StructureUnion
	; 		Type.i
	; 		Cluster.Drawing3D_Cluster
	; 		Line.Drawing3D_Line
	; 		Triangle.Drawing3D_Triangle
	; 	EndStructureUnion
	; EndStructure

	Structure Drawing3D_Image
		Number.i
		Array Pixel.Drawing3D_Color(0,0)
		Width.i
		Height.i
	EndStructure

	Structure Drawing3DInclude
		Array		*PixelIndex.Drawing3D_Pixel(0, 0) ; Index der Pixel für schnelleren Zugriff
		List		Pixel.Drawing3D_Pixel()           ; Liste aller zu zeichnenden Pixel
		List		Cluster.Drawing3D_Cluster()
		List		Light.Drawing3D_Light()           ; Liste aller Lichtquellen
		*CurrentCluster.Drawing3D_Cluster
		Orientation.Drawing3D_Matrix              ; Orientierung der Szene
		Position.Drawing3D_Vector                 ; Position der Kamera
		Background.Drawing3D_Color                ; Hintergrundfarbe
		MainCluster.Drawing3D_Cluster
		MaxX.i
		MaxY.i
		CenterX.i
		CenterY.i
		Distance.f
		RotX.f
		RotY.f
		RotZ.f
		CurrentColor.Drawing3D_Color[3]
		*CurrentImage3D.Drawing3D_Image
		List		Image3D.Drawing3D_Image()
		Array	*Image3DID.Drawing3D_Image(0)
		Mode.i
	EndStructure


	Global Drawing3DInclude.Drawing3DInclude


	#Drawing3D_NoColor = $100000000


	Enumeration
		;#Drawing3D_FrontOnly =
		#Drawing3D_Outline=	%0001
		#Drawing3D_Default=	%0010
		#Drawing3D_Filled=	%0010
	EndEnumeration

	Enumeration
		#Drawing3D_Centered
		#Drawing3D_Absolute
	EndEnumeration

	;- Private: General
	Procedure.f Drawing3D_Min(Value1.f, Value2.f, Value3.f=1e30)
		If Value3 < Value2
			If Value3 < Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 < Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	Procedure.f Drawing3D_Max(Value1.f, Value2.f, Value3.f=-1e30)
		If Value3 > Value2
			If Value3 > Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 > Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure

	;- Private: Color
	Procedure.i Drawing3D_SetColor(*Use.Drawing3D_Color, Color.l)
		Protected Factor.f = Alpha(Color) / 255 / 255
		*Use\Alpha = Alpha(Color) / 255
		*Use\Red   = Red(Color) * Factor
		*Use\Green = Green(Color) * Factor
		*Use\Blue  = Blue(Color) * Factor
		ProcedureReturn *Use
	EndProcedure
	Procedure.l Drawing3D_GetColor(*Source.Drawing3D_Color)
		Protected Factor.f, A, R, G, B
		If *Source\Alpha
			Factor = 255.0/*Source\Alpha
			A = *Source\Alpha*255
			R = *Source\Red*Factor
			G = *Source\Green*Factor
			B = *Source\Blue*Factor
			ProcedureReturn R|G<<8|B<<16|A<<24
		Else
			ProcedureReturn 0
		EndIf
	EndProcedure
	Procedure Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
		Protected InvAlpha.f = 1.0 - *Source\Alpha
		*Use\Red   * InvAlpha + *Source\Red
		*Use\Green * InvAlpha + *Source\Green
		*Use\Blue  * InvAlpha + *Source\Blue
		*Use\Alpha * InvAlpha + *Source\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_NormalizeColor(*Use.Drawing3D_Color)
		Protected Max.f = Drawing3D_Max(*Use\Red, *Use\Green, *Use\Blue)
		If Max > 1
			*Use\Red / Max
			*Use\Green / Max
			*Use\Blue / Max
		EndIf
		*Use\Red * *Use\Alpha
		*Use\Green * *Use\Alpha
		*Use\Blue * *Use\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_ColorMix(*Color.Drawing3D_Color, Factor1.f, Factor2.f, Factor3.f)
		Protected *C1.Drawing3D_Color = Drawing3DInclude\CurrentColor[0]
		Protected *C2.Drawing3D_Color = Drawing3DInclude\CurrentColor[1]
		Protected *C3.Drawing3D_Color = Drawing3DInclude\CurrentColor[2]
		*Color\Alpha = *C1\Alpha*Factor1 + *C2\Alpha*Factor2 + *C3\Alpha*Factor3
		*Color\Red   = *C1\Red  *Factor1 + *C2\Red  *Factor2 + *C3\Red  *Factor3
		*Color\Green = *C1\Green*Factor1 + *C2\Green*Factor2 + *C3\Green*Factor3
		*Color\Blue  = *C1\Blue *Factor1 + *C2\Blue *Factor2 + *C3\Blue *Factor3
	EndProcedure
	Procedure.i Drawing3D_ImageColor(*Color.Drawing3D_Color, X.f, Y.f)
		Protected *Image3D.Drawing3D_Image = Drawing3DInclude\CurrentImage3D
		Protected FX.f = Mod(X**Image3D\Width+0.5, 1.0)
		Protected FY.f = Mod(Y**Image3D\Height+0.5, 1.0)
		Protected PixelX0.i = X * *Image3D\Width  - 0.5 - FX
		Protected PixelY0.i = Y * *Image3D\Height - 0.5 - FY
		Protected PixelX1.i = X * *Image3D\Width  + 0.5 - FX
		Protected PixelY1.i = Y * *Image3D\Height + 0.5 - FY
		If PixelX0 < 0 : PixelX0 = 0 : EndIf
		If PixelY0 < 0 : PixelY0 = 0 : EndIf
		If PixelX1 > *Image3D\Width-1 : PixelX1 = *Image3D\Width-1 : EndIf
		If PixelY1 > *Image3D\Height-1 : PixelY1 = *Image3D\Height-1 : EndIf
		Protected *C00.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY0)
		Protected *C10.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY0)
		Protected *C01.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY1)
		Protected *C11.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY1)
		*Color\Alpha = *C00\Alpha*(1-FX)*(1-FY) + *C10\Alpha*(FX)*(1-FY) + *C01\Alpha*(1-FX)*(FY) + *C11\Alpha*(FX)*(FY)
		*Color\Red   = *C00\Red  *(1-FX)*(1-FY) + *C10\Red  *(FX)*(1-FY) + *C01\Red  *(1-FX)*(FY) + *C11\Red  *(FX)*(FY)
		*Color\Green = *C00\Green*(1-FX)*(1-FY) + *C10\Green*(FX)*(1-FY) + *C01\Green*(1-FX)*(FY) + *C11\Green*(FX)*(FY)
		*Color\Blue  = *C00\Blue *(1-FX)*(1-FY) + *C10\Blue *(FX)*(1-FY) + *C01\Blue *(1-FX)*(FY) + *C11\Blue *(FX)*(FY)
	EndProcedure

	;- Private: Math
	Procedure.i Drawing3D_Vector(*Use.Drawing3D_Vector, X.f, Y.f, Z.f)
		*Use\X = X
		*Use\Y = Y
		*Use\Z = Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Length(*Source.Drawing3D_Vector)
		ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
	EndProcedure
	Procedure.i Drawing3D_Normalize(*Use.Drawing3D_Vector)
		Protected Length.f = Drawing3D_Length(*Use)
		If Length
			*Use\X / Length
			*Use\Y / Length
			*Use\Z / Length
		EndIf
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Copy(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X = *Source\X
		*Use\Y = *Source\Y
		*Use\Z = *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Add(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X + *Source\X
		*Use\Y + *Source\Y
		*Use\Z + *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Subtract(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X - *Source\X
		*Use\Y - *Source\Y
		*Use\Z - *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Cross(*Use.Drawing3D_Vector, *Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		*Use\X = *Source1\Y * *Source2\Z - *Source1\Z * *Source2\Y
		*Use\Y = *Source1\Z * *Source2\X - *Source1\X * *Source2\Z
		*Use\Z = *Source1\X * *Source2\Y - *Source1\Y * *Source2\X
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Scalar(*Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		ProcedureReturn *Source1\X * *Source2\X + *Source1\Y * *Source2\Y + *Source1\Z * *Source2\Z
	EndProcedure
	Procedure.i Drawing3D_Rotate(*Use.Drawing3D_Vector, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Vector
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Vector))
		*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
		*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
		*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Orientation(*Use.Drawing3D_Matrix, RotationX.f, RotationY.f, RotationZ.f)
		Protected CosZ.f = Cos(RotationZ), CosY.f = Cos(RotationY), CosX.f = Cos(RotationX)
		Protected SinZ.f = Sin(RotationZ), SinY.f = Sin(RotationY), SinX.f = Sin(RotationX)
		*Use\A11 =  CosY*CosZ                : *Use\A12 = -CosY*SinZ                : *Use\A13 =  SinY
		*Use\A21 =  SinX*SinY*CosZ+CosX*SinZ : *Use\A22 = -SinX*SinY*SinZ+CosX*CosZ : *Use\A23 = -SinX*CosY
		*Use\A31 = -CosX*SinY*CosZ+SinX*SinZ : *Use\A32 =  CosX*SinY*SinZ+SinX*CosZ : *Use\A33 =  CosX*CosY
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Multiply(*Use.Drawing3D_Matrix, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Matrix
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Matrix))
		With *Use
			\A11 = Buffer\A11 * *Source\A11 + Buffer\A12 * *Source\A21 + Buffer\A13 * *Source\A31
			\A12 = Buffer\A11 * *Source\A12 + Buffer\A12 * *Source\A22 + Buffer\A13 * *Source\A32
			\A13 = Buffer\A11 * *Source\A13 + Buffer\A12 * *Source\A23 + Buffer\A13 * *Source\A33
			\A21 = Buffer\A21 * *Source\A11 + Buffer\A22 * *Source\A21 + Buffer\A23 * *Source\A31
			\A22 = Buffer\A21 * *Source\A12 + Buffer\A22 * *Source\A22 + Buffer\A23 * *Source\A32
			\A23 = Buffer\A21 * *Source\A13 + Buffer\A22 * *Source\A23 + Buffer\A23 * *Source\A33
			\A31 = Buffer\A31 * *Source\A11 + Buffer\A32 * *Source\A21 + Buffer\A33 * *Source\A31
			\A32 = Buffer\A31 * *Source\A12 + Buffer\A32 * *Source\A22 + Buffer\A33 * *Source\A32
			\A33 = Buffer\A31 * *Source\A13 + Buffer\A32 * *Source\A23 + Buffer\A33 * *Source\A33
		EndWith
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Projection(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		If *Source\Z
			*Use\InvZ = 1 / *Source\Z
			*Use\X = - *Source\X * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterX
			*Use\Y =   *Source\Y * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterY
		EndIf
		ProcedureReturn *Use
	EndProcedure

	;- Private: Drawing
	Procedure Drawing3D_AddPixel(X.i, Y.i, Distance.f)

		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		If Distance < 0
			*Pixel = AddElement(Drawing3DInclude\Pixel())
			*OldPixel = Drawing3DInclude\PixelIndex(X, Y)
			If *OldPixel
				If Distance > *OldPixel\Distance
					*Pixel\PreviousPixel = *OldPixel
					Drawing3DInclude\PixelIndex(X, Y) = *Pixel
				Else
					While *OldPixel\PreviousPixel And *OldPixel\PreviousPixel\Distance > Distance
						*OldPixel = *OldPixel\PreviousPixel
					Wend
					*Pixel\PreviousPixel = *OldPixel\PreviousPixel
					*OldPixel\PreviousPixel = *Pixel
				EndIf
			Else
				Drawing3DInclude\PixelIndex(X, Y) = *Pixel
			EndIf
			*Pixel\Distance = Distance
		EndIf

		ProcedureReturn *Pixel

	EndProcedure
	Procedure Drawing3D_DrawTriangle(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex, *Vertex2.Drawing3D_Vertex, Texture.i=0)

		Protected Triangle.Drawing3D_Triangle
		Protected LightFactor.f, N.i

		With Triangle

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Drawing3D_Projection(\Vertex[2], *Vertex2) : \Vertex[2]\Color = *Vertex2\Color

			Protected X.i, Y.i
			Protected DX21.f = \Vertex[2]\X-\Vertex[1]\X, DY21.f = \Vertex[2]\Y-\Vertex[1]\Y
			Protected DX02.f = \Vertex[0]\X-\Vertex[2]\X, DY02.f = \Vertex[0]\Y-\Vertex[2]\Y
			Protected DX10.f = \Vertex[1]\X-\Vertex[0]\X, DY10.f = \Vertex[1]\Y-\Vertex[0]\Y
			Protected L1.f, L2.f, L3.f

			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), Drawing3DInclude\MaxY)


			VectorSourceColor($80ff8080)
			VectorSourceColor($ff000000|\Vertex[0]\Color)
			MovePathCursor(\Vertex[0]\X,\Vertex[0]\Y)
			AddPathLine(\Vertex[1]\X,\Vertex[1]\Y)
			AddPathLine(\Vertex[2]\X,\Vertex[2]\Y)
			ClosePath()
			FillPath()

			If huch

				Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Color.Drawing3D_Color, Norm.Drawing3D_Vector, V1.Drawing3D_Vector, V2.Drawing3D_Vector

				Protected T.f = 1.0 / (-DY21*DX02 + DX21*DY02)
				Protected Distance.f, Brightness.f, Q1.f, Q2.f

				;If T< 0 : ProcedureReturn 0 : EndIf

				If Texture = 0
					For N = 0 To 2
						\Vertex[N]\Color\Red / \Vertex[N]\Color\Alpha
						\Vertex[N]\Color\Green / \Vertex[N]\Color\Alpha
						\Vertex[N]\Color\Blue / \Vertex[N]\Color\Alpha
						Drawing3D_Copy(V1, *Vertex1) : Drawing3D_Subtract(V1, *Vertex0)
						Drawing3D_Copy(V2, *Vertex2) : Drawing3D_Subtract(V2, *Vertex0)
						Drawing3D_Normalize(Drawing3D_Cross(Norm, V2, V1))
						ForEach Drawing3DInclude\Light()
							LightFactor = Drawing3D_Scalar(Norm, Drawing3DInclude\Light()\Direction)*Sign(T)
							If LightFactor > 0
								\Vertex[N]\Color\Red   + LightFactor*Drawing3DInclude\Light()\Color\Red
								\Vertex[N]\Color\Green + LightFactor*Drawing3DInclude\Light()\Color\Green
								\Vertex[N]\Color\Blue  + LightFactor*Drawing3DInclude\Light()\Color\Blue
							EndIf
						Next
						Drawing3D_NormalizeColor(\Vertex[N]\Color)
						Drawing3DInclude\CurrentColor[N] = \Vertex[N]\Color
					Next
				EndIf

				For Y = YA To YB
					Q1 = DX21*(Y-\Vertex[2]\Y)
					Q2 = DX02*(Y-\Vertex[2]\Y)
					*Pixel = #Null
					For X = XA To XB
						L1 = ( -DY21*(X-\Vertex[2]\X) + Q1 ) * T
						L2 = ( -DY02*(X-\Vertex[2]\X) + Q2 ) * T
						L3 = 1.0 - L1 - L2
						If L1 >= 0.0 And L2 >= 0.0 And L3 >= 0.0
							Distance = 1.0 / ( L1*\Vertex[0]\InvZ + L2*\Vertex[1]\InvZ + L3*\Vertex[2]\InvZ )
							*Pixel = Drawing3D_AddPixel(X, Y, Distance)
							If *Pixel
								If Drawing3DInclude\CurrentImage3D
									If Texture = 1
										Drawing3D_ImageColor(*Pixel\Color, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
									Else
										Drawing3D_ImageColor(*Pixel\Color, 1.0-L2*\Vertex[1]\InvZ*Distance, 1.0-L3*\Vertex[2]\InvZ*Distance)
									EndIf
								Else
									Drawing3D_ColorMix(*Pixel\Color, L1*\Vertex[0]\InvZ*Distance, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
								EndIf
							EndIf
						ElseIf *Pixel
							Break
						EndIf
					Next
				Next
			EndIf

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawLine(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex)

		Protected Line.Drawing3D_Line, Distance.f
		Protected X.i, Y.i, Length.f, Position.f
		Protected Visible.f, Q.Drawing3D_Vector, R.Drawing3D_Vector, Cross.Drawing3D_Vector
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel

		With Line

			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\BorderColor = *Vertex0\BorderColor
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\BorderColor = *Vertex1\BorderColor
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X)-1, 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X)+1, Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y)-1, 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y)+2, Drawing3DInclude\MaxY)
			Drawing3D_Copy(R, \Vertex[1])
			Drawing3D_Subtract(R, \Vertex[0])
			Length = Drawing3D_Length(R)
			Drawing3DInclude\CurrentColor[0] = \Vertex[0]\BorderColor
			Drawing3DInclude\CurrentColor[1] = \Vertex[1]\BorderColor

			;DrawVectorLine(
			VectorSourceColor($ff000000|*Pixel\Color)
			;MovePathCursor(xa,ya)
			;AddPathLine(xb,yb)
			MovePathCursor(\Vertex[0]\X,\Vertex[0]\Y)
			AddPathLine(\Vertex[1]\X,\Vertex[1]\Y)
			StrokePath(1)

			If huch
				For Y = YA To YB
					*Pixel = #Null
					For X = XA To XB
						Drawing3D_Vector(Q, X, Y, 0)
						Drawing3D_Subtract(Q, \Vertex[0])
						Drawing3D_Cross(Cross, Q, R)
						Position = Drawing3D_Scalar(Q, R) / Length
						Visible = 1 - Drawing3D_Length(Cross) / Length
						If Position >= 0 And Position <= Length And Visible > 0
							Distance = 1.0 / ( (1-Position/Length)*\Vertex[0]\InvZ + (Position/Length)*\Vertex[1]\InvZ )
							*Pixel = Drawing3D_AddPixel(X, Y, Distance)
							If *Pixel
								;Drawing3D_ColorMix(*Pixel\Color, (1-Position/Length)*\Vertex[0]\InvZ*Distance*Visible, (Position/Length)*\Vertex[1]\InvZ*Distance*Visible, 0)
							EndIf
						EndIf
						If *Pixel And Visible < -1
							Break
						EndIf
					Next
				Next
			EndIf

		EndWith

	EndProcedure
	Procedure Drawing3D_DrawPoint(*Vertex.Drawing3D_Vertex)

		Protected Vertex.Drawing3D_Vertex, Distance.f
		Protected X.i, Y.i
		Protected Visible.f
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Nothing.Drawing3D_Color

		Drawing3D_Projection(Vertex, *Vertex) : Vertex\Color = *Vertex\Color
		Protected XA.i = Drawing3D_Max(Vertex\X-1, 0)
		Protected XB.i = Drawing3D_Min(Vertex\X+1, Drawing3DInclude\MaxX)
		Protected YA.i = Drawing3D_Max(Vertex\Y-1, 0)
		Protected YB.i = Drawing3D_Min(Vertex\Y+1, Drawing3DInclude\MaxY)

		Drawing3DInclude\CurrentColor[0] = Vertex\Color
		For Y = YA To YB
			For X = XA To XB
				Visible = 1 - Sqr((X-Vertex\X)*(X-Vertex\X)+(Y-Vertex\Y)*(Y-Vertex\Y))
				If Visible > 0
					Distance = 1.0 / Vertex\InvZ
					*Pixel = Drawing3D_AddPixel(X, Y, Distance)
					If *Pixel
						Drawing3D_ColorMix(*Pixel\Color, Visible, 0, 0)
					EndIf
				EndIf
			Next
		Next

	EndProcedure

	;- Cluster (unfertig)
	Procedure.i CreateCluster3D()
		Protected *Cluster.Drawing3D_Cluster = AddElement(Drawing3DInclude\Cluster())
		Drawing3DInclude\CurrentCluster = *Cluster
		ProcedureReturn *Cluster
	EndProcedure
	Procedure CloseCluster3D()
	EndProcedure
	Procedure DrawCluster3D(*Cluster.Drawing3D_Cluster, X.f, Y.f, Z.f, Pitch.f=0.0, Yaw.f=0.0, Roll.f=0.0)
	EndProcedure

	;- Image3D
	Procedure.i Image3DID(Image3D.i)

		If Image3D & ~$FFFF
			ProcedureReturn Image3D
		Else
			ProcedureReturn Drawing3DInclude\Image3DID(Image3D)
		EndIf

	EndProcedure
	Procedure.i FreeImage3D(Image3D.i)

		Protected *Image3D.Drawing3D_Image = Image3DID(Image3D)

		With *Image3D

			If Not \Number & ~$FFFF
				Drawing3DInclude\Image3DID(\Number) = #Null
			EndIf

			ChangeCurrentElement(Drawing3DInclude\Image3D(), *Image3D)
			DeleteElement(Drawing3DInclude\Image3D())

		EndWith

	EndProcedure
	Procedure CreateImage3D(Image3D.i, Image.i)

		Protected *Image3D.Drawing3D_Image
		Protected X.i, Y.i

		If Image3D = #PB_Any
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = *Image3D
		ElseIf Not Image3D & ~$FFFF
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = Image3D
			If ArraySize(Drawing3DInclude\Image3DID()) < Image3D
				ReDim Drawing3DInclude\Image3DID(Image3D)
			ElseIf Drawing3DInclude\Image3DID(Image3D)
				FreeImage3D(Drawing3DInclude\Image3DID(Image3D))
			EndIf
			Drawing3DInclude\Image3DID(Image3D) = *Image3D
		Else
			ProcedureReturn #Null
		EndIf

		With *Image3D
			\Width  = ImageWidth(Image)
			\Height = ImageHeight(Image)
			Dim \Pixel(\Width-1, \Height-1)
			If StartDrawing(ImageOutput(Image))
				DrawingMode(#PB_2DDrawing_AllChannels)
				Select ImageDepth(Image, #PB_Image_InternalDepth)
				Case 24
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y)|$FF000000)
						Next
					Next
				Case 32
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y))
						Next
					Next
				EndSelect
				StopDrawing()
			EndIf
		EndWith

	EndProcedure

	;- Drawing
	Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
		; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle

		With Drawing3DInclude

			If StartVectorDrawing(CanvasVectorOutput(Output))


				;DrawingMode(#PB_2DDrawing_AllChannels)

				\MaxX = VectorOutputWidth()-1
				\MaxY = VectorOutputHeight()-1
				\CenterX = VectorOutputWidth()/2
				\CenterY = VectorOutputHeight()/2
				\Distance = VectorOutputHeight()/Tan(Radian(FieldOfView)*0.5)
				Drawing3D_Vector(Drawing3DInclude\Position, 0, 0, \Distance)

				If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY
					Dim \PixelIndex(\MaxX, \MaxY)
				Else
					FillMemory(@\PixelIndex(0,0), SizeOf(Integer)*(\MaxX+1)*(\MaxY+1))
				EndIf
				ClearList(\Pixel())
				ClearList(\Light())
				ClearStructure(\MainCluster, Drawing3D_Cluster)

				ProcedureReturn #True

			EndIf

		EndWith

	EndProcedure
	Procedure StopDrawing3D()
		; Schließt eine Drawing3D-Umgebung und rendert die Szene

		Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
		Protected Color.Drawing3D_Color
		Protected X.i, Y.i

		If huch
			For Y = 0 To Drawing3DInclude\MaxY
				For X = 0 To Drawing3DInclude\MaxX
					*Pixel = Drawing3DInclude\PixelIndex(X, Y)
					If *Pixel
						While *Pixel\PreviousPixel
							Drawing3D_AlphaBlend(*Pixel\PreviousPixel\Color, *Pixel\Color)
							*Pixel = *Pixel\PreviousPixel
						Wend
						Color = Drawing3DInclude\Background
						Plot(X, Y, Drawing3D_GetColor(Drawing3D_AlphaBlend(Color, *Pixel)))
					EndIf
				Next
			Next
		EndIf
		StopVectorDrawing()

	EndProcedure
	Procedure Drawing3DMode(Mode.i)
		; Ändert den Zeichenmodus

		Drawing3DInclude\Mode = Mode

	EndProcedure
	Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Position der Szene

		Protected Vector.Drawing3D_Vector

		If Mode = #PB_Relative
			Drawing3D_Vector(Vector, -X, -Y, -Z)
			Drawing3D_Add(Drawing3DInclude\Position, Vector)
		Else
			Drawing3D_Vector(Drawing3DInclude\Position, -X, -Y, -Z)
		EndIf

	EndProcedure
	Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Orientierung der Szene

		Protected Rotation.Drawing3D_Matrix

		If Mode = #PB_Relative
			Drawing3DInclude\RotX+RotationX
			Drawing3DInclude\RotY+RotationY
			Drawing3DInclude\RotZ+RotationZ
			Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
			Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
			Drawing3DInclude\Orientation = Rotation
		Else
			Drawing3DInclude\RotX=RotationX
			Drawing3DInclude\RotY=RotationY
			Drawing3DInclude\RotZ=RotationZ
			Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		EndIf

	EndProcedure
	Procedure Drawing3DBackground(Color.l=$FF000000)
		; Setzt den Szenenhintergrund

		VectorSourceColor(Color)
		FillVectorOutput()
		Drawing3D_SetColor(Drawing3DInclude\Background, Color)

	EndProcedure
	Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
		; Setzt ein Licht in die Szene

		Protected *Light.Drawing3D_Light = AddElement(Drawing3DInclude\Light())

		With *Light
			Drawing3D_Vector(\Direction, DirectionX, DirectionY, DirectionZ)
			Drawing3D_Normalize(\Direction)
			Drawing3D_SetColor(\Color, Color)
		EndWith

		ProcedureReturn *Light

	EndProcedure
	Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.q)
		; Zeichnet einen Punkt in die Szene

		Protected Vertex.Drawing3D_Vertex

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_SetColor(Vertex\Color, Color)
		Drawing3D_Rotate(Vertex, Drawing3DInclude\Orientation)
		Drawing3D_Subtract(Vertex, Drawing3DInclude\Position)
		Drawing3D_DrawPoint(Vertex)

	EndProcedure
	Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
		; Zeichnet eine Linie in die Szene

		Protected Line.Drawing3D_Line
		Protected N.i

		Drawing3D_Vector(Line\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Line\Vertex[1], X2, Y2, Z2)
		Drawing3D_SetColor(Line\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color2)
		EndIf
		For N = 0 To 1
			Drawing3D_Rotate(Line\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Line\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawLine(Line\Vertex[0], Line\Vertex[1])

	EndProcedure
	Procedure DrawTriangle3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor)
		; Zeichnet ein Dreieck in die Szene

		Protected Triangle.Drawing3D_Triangle
		Protected N.i

		Drawing3D_Vector(Triangle\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Triangle\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Triangle\Vertex[2], X3, Y3, Z3)
		Drawing3D_SetColor(Triangle\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color3)
		EndIf
		For N = 0 To 2
			Drawing3D_Rotate(Triangle\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Triangle\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Triangle\Vertex[0], Triangle\Vertex[1])
			Drawing3D_DrawLine(Triangle\Vertex[1], Triangle\Vertex[2])
			Drawing3D_DrawLine(Triangle\Vertex[2], Triangle\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Triangle\Vertex[0], Triangle\Vertex[1], Triangle\Vertex[2])
		EndIf

	EndProcedure
	Procedure DrawPlane3D(X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f, RotationY.f, RotationZ.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor, Color4.q=#Drawing3D_NoColor)
		; Zeichnet eine Ebene in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_SetColor(Plane\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color3)
		EndIf
		If Color4 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color4)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Plane\Vertex[0], Plane\Vertex[1])
			Drawing3D_DrawLine(Plane\Vertex[1], Plane\Vertex[3])
			Drawing3D_DrawLine(Plane\Vertex[3], Plane\Vertex[2])
			Drawing3D_DrawLine(Plane\Vertex[2], Plane\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2])
			Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1])
		EndIf
	EndProcedure
	Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)
		; Zeichnet einen Quader in die Szene

		Protected Box.Drawing3D_Box
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3D_Vector(Vertex, X, Y, Z)
		If Mode=#Drawing3D_Absolute
			Drawing3D_Vector(Box\Vertex[0],	0,	Height,	Depth)
			Drawing3D_Vector(Box\Vertex[1],	Width,Height,	Depth)
			Drawing3D_Vector(Box\Vertex[2], 0, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[3],  Width, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[4], 0,  Height, 0)
			Drawing3D_Vector(Box\Vertex[5],  Width,  Height, 0)
			Drawing3D_Vector(Box\Vertex[6], 0, 0, 0)
			Drawing3D_Vector(Box\Vertex[7],  Width, 0, 0)
		Else
			Drawing3D_Vector(Box\Vertex[0], -Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[1],  Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[2], -Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[3],  Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[4], -Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[5],  Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[6], -Width*0.5, -Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[7],  Width*0.5, -Height*0.5, -Depth*0.5)
		EndIf

		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 7
			Drawing3D_SetColor(Box\Vertex[N]\Color, Color)
			Drawing3D_SetColor(Box\Vertex[N]\BorderColor, BorderColor)
			Drawing3D_Rotate(Box\Vertex[N], Orientation)
			Drawing3D_Add(Box\Vertex[N], Vertex)
			Drawing3D_Rotate(Box\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Box\Vertex[N], Drawing3DInclude\Position)
		Next

		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[1])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[6], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[2])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[5], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[4])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[3], Box\Vertex[7])
		EndIf
		If Drawing3DInclude\Mode & #Drawing3D_Filled
			Drawing3D_DrawTriangle(Box\Vertex[0], Box\Vertex[1], Box\Vertex[2])
			Drawing3D_DrawTriangle(Box\Vertex[3], Box\Vertex[2], Box\Vertex[1])
			Drawing3D_DrawTriangle(Box\Vertex[5], Box\Vertex[4], Box\Vertex[7])
			Drawing3D_DrawTriangle(Box\Vertex[6], Box\Vertex[7], Box\Vertex[4])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[5], Box\Vertex[3])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[3], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[0], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[6], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[5], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[0], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[3], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[6], Box\Vertex[3])
		EndIf

	EndProcedure
	Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
		; Zeichnet ein Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawTranformedImage3D(Image3D.i, X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, X4.f, Y4.f, Z4.f)
		; Zeichnet ein verzerrtes Bild (Image3D) in die Szene

		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i

		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)

		Drawing3D_Vector(Plane\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Plane\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Plane\Vertex[2], X3, Y3, Z3)
		Drawing3D_Vector(Plane\Vertex[3], X4, Y4, Z4)
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next

		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)

		Drawing3DInclude\CurrentImage3D = #Null

	EndProcedure
	Procedure DrawBoxWithBorder3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)

		Drawing3DMode(#Drawing3D_Default | #Drawing3D_Outline)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, SurfaceColor, BorderColor, Mode)

		;Drawing3DMode(#Drawing3D_Outline)
		;DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, BorderColor, Mode)

	EndProcedure

	Drawing3D_Orientation(Drawing3DInclude\Orientation, 0, 0, 0)


; EndDefine
; Define Demonstration

	#WX=1040
	#WY=800
	#WZ=300
	#WW=#WX+20

	CompilerIf #PB_Compiler_IsMainFile

		Enumeration
			#Window
			#Canvas
			#ListViewGadget
			#RotateZero
			#RotateX
			#RotateY
			#RotateZ
			#Image
			#Image3D
			#ButtonGadget
			#RealImage
		EndEnumeration


		Procedure UpdateRotationGadgets()

			With Drawing3DInclude
				SetGadgetState(#RotateX,\RotX)
				SetGadgetState(#RotateY,\RotY)
				SetGadgetState(#RotateZ,\RotZ)
			EndWith

		EndProcedure
		Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)

			t1=ElapsedMilliseconds()

			Static MouseX.i, MouseY.i

			; **********************************
			Protected Distance.f = 500
			; **********************************

			Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f
			Protected Dim Y.f(40, 40)
			Protected Dim Color.l(40, 40)
			Protected Time1.q, Time2.q, Frequency.q
			Protected rx.f,ry.f,rz.f

			QueryPerformanceFrequency_(@Frequency)
			QueryPerformanceCounter_(@Time1)

			If Image
				StartDrawing3D(ImageOutput(Image))
				Drawing3DBackground($00FFFFFF)
			Else
				StartDrawing3D(Gadget)
				Drawing3DBackground($FFFFFFFF)
				Debug "clear"
				Distance * Pow(1.1, GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta))
				If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
					rx=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15
					ry=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15
					Drawing3DRotation(Radian(rx),Radian(ry),0, #PB_Relative)
					UpdateRotationGadgets()
				EndIf
				MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
				MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
			EndIf

			; **********************************
			Drawing3DPosition(-100, -100, -Distance)
			; **********************************

			Select GetGadgetState(#ListViewGadget)

			Case 0
				DrawPlane3D(0, 0, 0, 340, 200,  0,  0,  0, $80FF0000)
				DrawPlane3D(0, 0, 0, 340, 200, 90, 90,  0, $800000FF)
				DrawPlane3D(0, 0, 0, 340, 200, 90,  0, 90, $8000FF00)

			Case 1
				Drawing3DMode(#Drawing3D_Outline)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
				Drawing3DMode(#Drawing3D_Default)

			Case 2
				Drawing3DLight(1, 0, 0, $FFFFFF00)
				Drawing3DLight(-1, 0, 0, $FF00FFFF)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)

			Case 3
				Drawing3DLight(0.5, 1, 1, $FFFFFFFF)
				DrawBox3D(0, 0, 0, 100, 200, 300, 0, 0, 0, $C000C060)
				DrawBox3D(0, 0, 0, 100, 200, 300, 30, 45, 15, $C08000C0)

			Case 4
				Drawing3DLight(0.5, 1, -1, $FFFFFFFF)
				DrawTriangle3D(-100, 100, 100, 100, 100, -100, 100, -100, 100, $FF00C000, $FFC00000, $FF0000C0)
				DrawTriangle3D(-100, 100, 100, 100, -100, 100, -100, -100, -100, $FF00C000, $FF0000C0, $FF00C0C0)
				DrawTriangle3D(-100, 100, 100, -100, -100, -100, 100, 100, -100, $FF00C000, $FF00C0C0, $FFC00000)
				DrawTriangle3D(100, -100, 100, 100, 100, -100, -100, -100, -100, $FF0000C0, $FFC00000, $FF00C0C0)
				DrawLine3D(90, -90, -90, -90, -90, 90, $FF00C000, $FFC00000)
				DrawLine3D(-90, -90, 90, -90, 90, -90, $FFC00000, $FF0000C0)
				DrawLine3D(-90, 90, -90, 90, -90, -90, $FF0000C0, $FF00C000)
				DrawLine3D(90, -90, -90, 90, 90, 90, $FF00C000, $FF00C0C0)
				DrawLine3D(-90, -90, 90, 90, 90, 90, $FFC00000, $FF00C0C0)
				DrawLine3D(-90, 90, -90, 90, 90, 90, $FF0000C0, $FF00C0C0)

			Case 5
				DrawImage3D(#Image3D, 0, 0, 0, 400, 400, 0, 0, 0)

			Case 6
				RandomSeed(1)
				For Y = -100 To 100
					For X = -100 To 100
						Z = Random(100)-50
						DrawPoint3D(X, Y, Z, $FF000000)
					Next
				Next

			Case 7
				Drawing3DLight(0.5, 1, 1, $40FFFFFF)
				DrawBox3D(0, 0, 0, 100, 30, 30, 0, 0, 0, $FF404040)
				DrawBox3D(-75, 0, 0, 50, 30, 30, 0, 0, 0, $FF808000)
				DrawBox3D(75, 0, 0, 50, 30, 30, 0, 0, 0, $FF000080)

				RandomSeed(5)
				For N = 1 To 50
					Phi = Random(359)
					R = Random(100)+30
					For W = 0 To 359 Step 5
						R1 = (1-Cos(Radian(W)))*R
						R2 = (1-Cos(Radian(W+5)))*R
						DrawLine3D(-Sin(Radian(W))*R*2, R1*Sin(Radian(Phi)), R1*Cos(Radian(Phi)), -Sin(Radian(W+5))*R*2, R2*Sin(Radian(Phi)), R2*Cos(Radian(Phi)), RGBA(255*W/360, 255*(360-W)/360, 255*(360-W)/360, 192))
					Next
				Next

			Case 8
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				For Z = -20 To 20
					For X = -20 To 20
						Y(X+20,Z+20) = Exp(-X*X/100-Z*Z/100)*(X+Z/4)/5
						If Y(X+20,Z+20) < 0
							Color(X+20,Z+20) = RGBA(0, 128+128*Y(X+20,Z+20), -255*Y(X+20,Z+20), 255)
						Else
							Color(X+20,Z+20) = RGBA(255*Y(X+20,Z+20), 128+128*Y(X+20,Z+20), 0, 255)
						EndIf
						Y(X+20,Z+20) * 200
					Next
				Next
				For Z = -20 To 19
					For X = -20 To 19
						DrawTriangle3D(X*10, Y(X+20,Z+20), Z*10, (X+1)*10, Y(X+21,Z+20), Z*10, X*10, Y(X+20,Z+21), (Z+1)*10, Color(X+20,Z+20), Color(X+21,Z+20), Color(X+20,Z+21))
						DrawTriangle3D((X+1)*10, Y(X+21,Z+21), (Z+1)*10, X*10, Y(X+20,Z+21), (Z+1)*10, (X+1)*10, Y(X+21,Z+20), Z*10, Color(X+21,Z+21), Color(X+20,Z+21), Color(X+21,Z+20))
					Next
				Next

			Case 9
				t2=ElapsedMilliseconds()
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				Drawing3DMode(#Drawing3D_Default)
				Drawing3DBackground($FFE0E0E0)
				Drawing3DLight(1, 1, 1, $40FFFFFF)
				; unten
				DrawBoxWithBorder3D(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,0,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; mittig
				DrawBoxWithBorder3D(0,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,51,0, 62,25,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)

				t3=ElapsedMilliseconds()
				; links/rechts
				DrawBoxWithBorder3D(0,77,0, 62,130,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,77,0, 62,130,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; oben
				DrawBoxWithBorder3D(0,208,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; Platten
				DrawBoxWithBorder3D(62,77,0, 1,181,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,207,0, 125,1,42, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,76,0, 125,1,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,0,40, 1,76,20, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,76,0, 1,131,40, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)

				; Achsen
				DrawLine3D(0,0,0, 100,0,0, $FF000000)
				DrawLine3D(0,0,0, 0,100,0, $FF000000)
				DrawLine3D(0,0,0, 0,0,100, $FF000000)

				t4=ElapsedMilliseconds()

			EndSelect

			StopDrawing3D()

			QueryPerformanceCounter_(@Time2)
			;SetWindowTitle(#Window, StrF((Time2-Time1)/Frequency*1000,3))

		EndProcedure

		UsePNGImageDecoder()
		UsePNGImageEncoder()

		CatchImage(#Image, ?Image)
		CreateImage3D(#Image3D, #Image)

		OpenWindow(#Window, 0, 0, #WX+#WZ+30, #WY+20, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
		CanvasGadget(#Canvas, 10, 10, #WX, #WY, #PB_Canvas_Border|#PB_Canvas_Keyboard)
		FrameGadget(#PB_Any, #WW, 10, #WZ, 190, "Szenenauswahl")
		ListViewGadget(#ListViewGadget, #WW+10, 30, #WZ-20, 160)
		AddGadgetItem(#ListViewGadget, -1, "Drei sich durchdringende Flächen")
		AddGadgetItem(#ListViewGadget, -1, "Würfel aus Linien")
		AddGadgetItem(#ListViewGadget, -1, "Belichteter Würfel")
		AddGadgetItem(#ListViewGadget, -1, "Zwei durchdringende Quader")
		AddGadgetItem(#ListViewGadget, -1, "Tetraeder mit verschiedenen Eckfarben")
		AddGadgetItem(#ListViewGadget, -1, "Texturfläche")
		AddGadgetItem(#ListViewGadget, -1, "Punkte")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: Magnet & Feldlinien")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: 3D-Funktion")
		AddGadgetItem(#ListViewGadget, -1, "Spielwiese")
		SetGadgetState(#ListViewGadget, 9)

		ButtonGadget(#RotateZero,#WW,250,100,30,"Reset")
		TrackBarGadget(#RotateX, #WW, 300, #WZ,20,0,360)
		TrackBarGadget(#RotateY, #WW, 330, #WZ,20,0,360)
		TrackBarGadget(#RotateZ, #WW, 360, #WZ,20,0,360)

		ButtonGadget(#ButtonGadget,#WW, 580, 120, 30, "Save Image...")
		TextGadget(#PB_Any, #WW, 210, 290, 40, "drag object to rotate the scene, mouse wheel zooms")

		; **********************************
		Drawing3DRotation(10,330,0)
		; **********************************

		UpdateRotationGadgets()
		UpdateCanvasGadget(#Canvas)

		;MessageRequester("Timer",Str(t2-t1)+#CRLF$+Str(t3-t2)+#CRLF$+Str(t4-t3)+#CRLF$+Str(t4-t1))


		Define FileName.s

		Repeat

			Select WaitWindowEvent()

			Case #PB_Event_CloseWindow
				End

			Case #PB_Event_Gadget
				Define e.i
				e=EventGadget()
				Select e
				Case #Canvas, #ListViewGadget
					UpdateCanvasGadget(#Canvas)

				Case #RotateZero
					Drawing3DRotation(0,0,0, #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					UpdateRotationGadgets()

				Case #RotateX To #RotateZ
					Drawing3DRotation(GetGadgetState(#RotateX),GetGadgetState(#RotateY),GetGadgetState(#RotateZ), #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					;UpdateRotationGadgets()

				Case #ButtonGadget
					CreateImage(#RealImage, 600, 600, 32|#PB_Image_Transparent)
					UpdateCanvasGadget(#Canvas, #RealImage)
					FileName = SaveFileRequester("Save", "", "*.png|*.PNG", 1)
					If FileName
						SaveImage(#RealImage, FileName, #PB_ImagePlugin_PNG)
					EndIf
				EndSelect

			EndSelect

		ForEver


		DataSection
			Image:
			IncludeBinary "Image.png"
		EndDataSection

	CompilerEndIf

; EndDefine
Antworten