Re: Drawing3D - Draw-Befehle für 3D-Szenen
Verfasst: 25.12.2017 09:21
				
				Öm, soweit ich mich erinnere ... nein.
Aber ich bin natürlich offen für Vorschläge
			Aber ich bin natürlich offen für Vorschläge
Das deutsche PureBasic-Forum
https://www.purebasic.fr/german/
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
ForEverCode: 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
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
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