Drawing3D - Draw-Befehle für 3D-Szenen
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Ö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
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
						Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Hallo Startgate,
kannst Du den link in deinem Ursprungspost noch auf die aktuellste Version anpassen?
Momentan lädt man sich damit eine Version herunter die noch nicht auf Module umgebaut ist.
Gruß Kurzer
btw: beeindruckendes Include!
			
			
									
									kannst Du den link in deinem Ursprungspost noch auf die aktuellste Version anpassen?
Momentan lädt man sich damit eine Version herunter die noch nicht auf Module umgebaut ist.
Gruß Kurzer
btw: beeindruckendes Include!
"Never run a changing system!" | "Unterhalten sich zwei Alleinunterhalter... Paradox, oder?"
PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
						PB 6.12 x64, OS: Win 11 24H2 x64, Desktopscaling: 150%, CPU: I7 12700 H, RAM: 32 GB, GPU: Intel(R) Iris(R) Xe Graphics | NVIDIA GeForce RTX 3070
Useralter in 2025: 57 Jahre.
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Absolut genial  
 
PureBasic sollte das übernehmen
			
			
									
									
						PureBasic sollte das übernehmen
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Hallo STARGÅTE,
deine Drawing3D-Funktionen gefallen mir.
Aber ich finde es schöner mit OpenGL.
Ich werde mir da selber etwas basteln.
			
			
									
									deine Drawing3D-Funktionen gefallen mir.
Aber ich finde es schöner mit OpenGL.
Ich werde mir da selber etwas basteln.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
						no Keyboard, press any key
no mouse, you need a cat
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Weil ich gerade dein OpenGL Code gesehen habe ...
Klar wäre OpenGL "eine" Möglichkeit. Ich hatte aber absichtlich auf externe Befehle verzichtet, weil ich ein paar Sachen unbedingt ermöglichen wollte, z.B. das richtiges z-sortieren von Pixeln mit Alpha-Channel.
			
			
									
									Klar wäre OpenGL "eine" Möglichkeit. Ich hatte aber absichtlich auf externe Befehle verzichtet, weil ich ein paar Sachen unbedingt ermöglichen wollte, z.B. das richtiges z-sortieren von Pixeln mit Alpha-Channel.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
						Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Hallöchen Meister STARGÅTE,
dein Code ist ja auch gut so wie er ist.
Alles hat seine Berechtigung und seinen Nutzen.
Ich habe bis jetzt auch noch nichts wirklich mit nativen OpenGl (gl, glu, glx, glut, ...) gemacht. Bis vor kurzer Zeit hatte ich noch nie etwas mit dem OpenGl-Gadget von PureBasic gemacht.
Ich habe mich seit dem im Forum geposteten Problem, mit dem statischen Linken von Glut, näher mit nativen OpenGl beschäftigt und bisher eigentlich nur kleine 2D und 3D Beispiele probiert.
Ich möchte damit aber gerne eine kleine 2D/3D Zeichenengine erstellen.
Hierbei würde ich auch erstmal bei OpenGl 2.1 bleiben und nicht mit OpenGl 4.5 arbeiten.
Vielleicht kommt auch noch ein bisschen OpenCl und OpenAl hinzu.
Wobei ich andere native Soundlösungen OpenAl vorziehe.
Und ich finde es eigentlich ganz Cool.
OpenGl ist schön Plattformunabhängig und hat viele tolle Möglichkeiten im 2D und 3D Bereich.
Außerdem habe ich mit dem OpenGl-Gadget keine Mausprobleme und es unterstützt auch sehr gut Touchscreens.
			
			
									
									dein Code ist ja auch gut so wie er ist.
Alles hat seine Berechtigung und seinen Nutzen.
Ich habe bis jetzt auch noch nichts wirklich mit nativen OpenGl (gl, glu, glx, glut, ...) gemacht. Bis vor kurzer Zeit hatte ich noch nie etwas mit dem OpenGl-Gadget von PureBasic gemacht.
Ich habe mich seit dem im Forum geposteten Problem, mit dem statischen Linken von Glut, näher mit nativen OpenGl beschäftigt und bisher eigentlich nur kleine 2D und 3D Beispiele probiert.
Ich möchte damit aber gerne eine kleine 2D/3D Zeichenengine erstellen.
Hierbei würde ich auch erstmal bei OpenGl 2.1 bleiben und nicht mit OpenGl 4.5 arbeiten.
Vielleicht kommt auch noch ein bisschen OpenCl und OpenAl hinzu.
Wobei ich andere native Soundlösungen OpenAl vorziehe.
Und ich finde es eigentlich ganz Cool.
OpenGl ist schön Plattformunabhängig und hat viele tolle Möglichkeiten im 2D und 3D Bereich.
Außerdem habe ich mit dem OpenGl-Gadget keine Mausprobleme und es unterstützt auch sehr gut Touchscreens.
Betriebssysteme: div. Windows, Linux, Unix - Systeme
no Keyboard, press any key
no mouse, you need a cat
						no Keyboard, press any key
no mouse, you need a cat
- 
				Michael Vogel
 - Beiträge: 72
 - Registriert: 16.03.2006 11:20
 
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Großartige Sache, das könnte man ja beispielsweise verwenden, um Möbel zu zeichnen...
Allerdings komme ich mit den Objektparametern nicht ganz klar, ein 60cm tiefer Kasten auf der Koordinate 0 und ein 40cm tiefer Kasten auf der Koordinate 20 sollten doch bündig abschließen, mache ich da etwas falsch?
Update: Oh, habe gerade bemerkt, dass scheinbar der erste Punkt den Objektmittelpunkt angibt, das werde ich wohl anpassen...
Zur Sicherheit nochmals der ganze Code - inklusive der Bibliothek:
			
			
									
									
						Allerdings komme ich mit den Objektparametern nicht ganz klar, ein 60cm tiefer Kasten auf der Koordinate 0 und ein 40cm tiefer Kasten auf der Koordinate 20 sollten doch bündig abschließen, mache ich da etwas falsch?
Update: Oh, habe gerade bemerkt, dass scheinbar der erste Punkt den Objektmittelpunkt angibt, das werde ich wohl anpassen...
Code: Alles auswählen
XIncludeFile "3D-Library.pb"
Enumeration
	#Window
	#Gadget
EndEnumeration
Procedure DrawBoxWithBorder(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000)
	Drawing3DMode(#Drawing3D_Default)
	DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q)
	Drawing3DMode(#Drawing3D_Outline)
	DrawBox3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, BorderColor.q)
EndProcedure
OpenWindow(#Window, 0, 0, 500, 500, "Cube with lines", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
CanvasGadget(#Gadget, 0, 0, WindowWidth(#Window), WindowHeight(#Window))
If StartDrawing3D(CanvasOutput(#Gadget))
	Drawing3DRotation(30,320,0, #PB_Absolute)
	Drawing3DPosition(-100, 0, -500)
	Drawing3DLight(0.5, 1, 1, $20FFFFFF)
	Drawing3DMode(#Drawing3D_Default)
	Drawing3DBackground($FFE0E0E0)
	Drawing3DLight(1, 1, 1, $40FFFFFF)
	DrawBoxWithBorder(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(63,0,10, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000)
	DrawBoxWithBorder(189,0,20, 62,50,40, 0,0,0, $FFFFFFFF,$80000000)
	StopDrawing3D()
EndIf
Repeat
	Select WaitWindowEvent()
	Case #PB_Event_CloseWindow
		End
	EndSelect
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
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Hallo Michael Vogel,
schön zu hören, dass das Include trotz allen 3D-Möglichkeiten die es sonst gibt noch Beliebtheit erfährt.
Im übrigen gibt es auf der Startseite auch n "neue" Version Drawing3D_20141109.zip, die als Modul included wird.
(Habe den Link korrigiert)
Die Frage hast du dir ja selbst beantwortet.
			
			
									
									schön zu hören, dass das Include trotz allen 3D-Möglichkeiten die es sonst gibt noch Beliebtheit erfährt.
Im übrigen gibt es auf der Startseite auch n "neue" Version Drawing3D_20141109.zip, die als Modul included wird.
(Habe den Link korrigiert)
Die Frage hast du dir ja selbst beantwortet.
PB 6.01 ― Win 10, 21H2 ― Ryzen 9 3900X, 32 GB ― NVIDIA GeForce RTX 3080 ― Vivaldi 6.0 ― www.unionbytes.de
Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
						Aktuelles Projekt: Lizard - Skriptsprache für symbolische Berechnungen und mehr
- 
				Michael Vogel
 - Beiträge: 72
 - Registriert: 16.03.2006 11:20
 
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Hi Stargåte,
danke für den aktualisierten Link - die Modulversion liefert bei mir allerdings andere Ergebnisse als die ursprüngliche Version (keine Linienglättung).
Ich wollte ja das vorige Posting mit meiner Frage auch gleich wieder löschen, ab das ging nicht, deshalb die Selbstantwort
Und weil es mir ohnehin schon ein wenig entglitten ist, werfe ich hier auch den aktualisierten Code (mit der adaptierten Version für DrawBox3D sowie DrawBoxWithBorder3D mit 'absoluter' oder 'gemittelter' Positionierung) gleich nach...
			
			
									
									
						danke für den aktualisierten Link - die Modulversion liefert bei mir allerdings andere Ergebnisse als die ursprüngliche Version (keine Linienglättung).
Ich wollte ja das vorige Posting mit meiner Frage auch gleich wieder löschen, ab das ging nicht, deshalb die Selbstantwort
Und weil es mir ohnehin schon ein wenig entglitten ist, werfe ich hier auch den aktualisierten Code (mit der adaptierten Version für DrawBox3D sowie DrawBoxWithBorder3D mit 'absoluter' oder 'gemittelter' Positionierung) gleich nach...
Code: Alles auswählen
; Define 3D-Library (Include File)
	EnableExplicit
	Structure Drawing3D_Color
		Red.f
		Green.f
		Blue.f
		Alpha.f
	EndStructure
	Structure Drawing3D_Vector
		X.f
		Y.f
		StructureUnion
			Z.f
			InvZ.f
		EndStructureUnion
	EndStructure
	Structure Drawing3D_Vertex Extends Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure
	Structure Drawing3D_Matrix
		A11.f : A12.f : A13.f
		A21.f : A22.f : A23.f
		A31.f : A32.f : A33.f
	EndStructure
	Structure Drawing3D_Pixel
		Color.Drawing3D_Color
		Distance.f
		*PreviousPixel.Drawing3D_Pixel
	EndStructure
	Structure Drawing3D_Box
		Vertex.Drawing3D_Vertex[8]
	EndStructure
	Structure Drawing3D_Plane
		Vertex.Drawing3D_Vertex[4]
	EndStructure
	Structure Drawing3D_Triangle
		Vertex.Drawing3D_Vertex[3]
	EndStructure
	Structure Drawing3D_Line
		Vertex.Drawing3D_Vertex[2]
	EndStructure
	Structure Drawing3D_Light
		Direction.Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure
	Structure Drawing3D_Cluster
		Type.i
		Position.Drawing3D_Vector
		Orientation.Drawing3D_Matrix
		List		Triangle.Drawing3D_Triangle()
		List		*Cluster.Drawing3D_Cluster()
	EndStructure
	; Structure Drawing3D_Object
	; 	StructureUnion
	; 		Type.i
	; 		Cluster.Drawing3D_Cluster
	; 		Line.Drawing3D_Line
	; 		Triangle.Drawing3D_Triangle
	; 	EndStructureUnion
	; EndStructure
	Structure Drawing3D_Image
		Number.i
		Array Pixel.Drawing3D_Color(0,0)
		Width.i
		Height.i
	EndStructure
	Structure Drawing3DInclude
		Array		*PixelIndex.Drawing3D_Pixel(0, 0) ; Index der Pixel für schnelleren Zugriff
		List		Pixel.Drawing3D_Pixel()           ; Liste aller zu zeichnenden Pixel
		List		Cluster.Drawing3D_Cluster()
		List		Light.Drawing3D_Light()           ; Liste aller Lichtquellen
		*CurrentCluster.Drawing3D_Cluster
		Orientation.Drawing3D_Matrix              ; Orientierung der Szene
		Position.Drawing3D_Vector                 ; Position der Kamera
		Background.Drawing3D_Color                ; Hintergrundfarbe
		MainCluster.Drawing3D_Cluster
		MaxX.i
		MaxY.i
		CenterX.i
		CenterY.i
		Distance.f
		RotX.f
		RotY.f
		RotZ.f
		CurrentColor.Drawing3D_Color[3]
		*CurrentImage3D.Drawing3D_Image
		List		Image3D.Drawing3D_Image()
		Array	*Image3DID.Drawing3D_Image(0)
		Mode.i
	EndStructure
	Global Drawing3DInclude.Drawing3DInclude
	#Drawing3D_NoColor = $100000000
	Enumeration
		;#Drawing3D_FrontOnly =
		#Drawing3D_Default = %000
		#Drawing3D_Outline = %001
	EndEnumeration
	Enumeration
		#Drawing3D_Centered
		#Drawing3D_Absolute
	EndEnumeration
	;- Private: General
	Procedure.f Drawing3D_Min(Value1.f, Value2.f, Value3.f=1e30)
		If Value3 < Value2
			If Value3 < Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 < Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	Procedure.f Drawing3D_Max(Value1.f, Value2.f, Value3.f=-1e30)
		If Value3 > Value2
			If Value3 > Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 > Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	;- Private: Color
	Procedure.i Drawing3D_SetColor(*Use.Drawing3D_Color, Color.l)
		Protected Factor.f = Alpha(Color) / 255 / 255
		*Use\Alpha = Alpha(Color) / 255
		*Use\Red   = Red(Color) * Factor
		*Use\Green = Green(Color) * Factor
		*Use\Blue  = Blue(Color) * Factor
		ProcedureReturn *Use
	EndProcedure
	Procedure.l Drawing3D_GetColor(*Source.Drawing3D_Color)
		Protected Factor.f, A, R, G, B
		If *Source\Alpha
			Factor = 255.0/*Source\Alpha
			A = *Source\Alpha*255
			R = *Source\Red*Factor
			G = *Source\Green*Factor
			B = *Source\Blue*Factor
			ProcedureReturn R|G<<8|B<<16|A<<24
		Else
			ProcedureReturn 0
		EndIf
	EndProcedure
	Procedure Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
		Protected InvAlpha.f = 1.0 - *Source\Alpha
		*Use\Red   * InvAlpha + *Source\Red
		*Use\Green * InvAlpha + *Source\Green
		*Use\Blue  * InvAlpha + *Source\Blue
		*Use\Alpha * InvAlpha + *Source\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_NormalizeColor(*Use.Drawing3D_Color)
		Protected Max.f = Drawing3D_Max(*Use\Red, *Use\Green, *Use\Blue)
		If Max > 1
			*Use\Red / Max
			*Use\Green / Max
			*Use\Blue / Max
		EndIf
		*Use\Red * *Use\Alpha
		*Use\Green * *Use\Alpha
		*Use\Blue * *Use\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_ColorMix(*Color.Drawing3D_Color, Factor1.f, Factor2.f, Factor3.f)
		Protected *C1.Drawing3D_Color = Drawing3DInclude\CurrentColor[0]
		Protected *C2.Drawing3D_Color = Drawing3DInclude\CurrentColor[1]
		Protected *C3.Drawing3D_Color = Drawing3DInclude\CurrentColor[2]
		*Color\Alpha = *C1\Alpha*Factor1 + *C2\Alpha*Factor2 + *C3\Alpha*Factor3
		*Color\Red   = *C1\Red  *Factor1 + *C2\Red  *Factor2 + *C3\Red  *Factor3
		*Color\Green = *C1\Green*Factor1 + *C2\Green*Factor2 + *C3\Green*Factor3
		*Color\Blue  = *C1\Blue *Factor1 + *C2\Blue *Factor2 + *C3\Blue *Factor3
	EndProcedure
	Procedure.i Drawing3D_ImageColor(*Color.Drawing3D_Color, X.f, Y.f)
		Protected *Image3D.Drawing3D_Image = Drawing3DInclude\CurrentImage3D
		Protected FX.f = Mod(X**Image3D\Width+0.5, 1.0)
		Protected FY.f = Mod(Y**Image3D\Height+0.5, 1.0)
		Protected PixelX0.i = X * *Image3D\Width  - 0.5 - FX
		Protected PixelY0.i = Y * *Image3D\Height - 0.5 - FY
		Protected PixelX1.i = X * *Image3D\Width  + 0.5 - FX
		Protected PixelY1.i = Y * *Image3D\Height + 0.5 - FY
		If PixelX0 < 0 : PixelX0 = 0 : EndIf
		If PixelY0 < 0 : PixelY0 = 0 : EndIf
		If PixelX1 > *Image3D\Width-1 : PixelX1 = *Image3D\Width-1 : EndIf
		If PixelY1 > *Image3D\Height-1 : PixelY1 = *Image3D\Height-1 : EndIf
		Protected *C00.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY0)
		Protected *C10.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY0)
		Protected *C01.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY1)
		Protected *C11.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY1)
		*Color\Alpha = *C00\Alpha*(1-FX)*(1-FY) + *C10\Alpha*(FX)*(1-FY) + *C01\Alpha*(1-FX)*(FY) + *C11\Alpha*(FX)*(FY)
		*Color\Red   = *C00\Red  *(1-FX)*(1-FY) + *C10\Red  *(FX)*(1-FY) + *C01\Red  *(1-FX)*(FY) + *C11\Red  *(FX)*(FY)
		*Color\Green = *C00\Green*(1-FX)*(1-FY) + *C10\Green*(FX)*(1-FY) + *C01\Green*(1-FX)*(FY) + *C11\Green*(FX)*(FY)
		*Color\Blue  = *C00\Blue *(1-FX)*(1-FY) + *C10\Blue *(FX)*(1-FY) + *C01\Blue *(1-FX)*(FY) + *C11\Blue *(FX)*(FY)
	EndProcedure
	;- Private: Math
	Procedure.i Drawing3D_Vector(*Use.Drawing3D_Vector, X.f, Y.f, Z.f)
		*Use\X = X
		*Use\Y = Y
		*Use\Z = Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Length(*Source.Drawing3D_Vector)
		ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
	EndProcedure
	Procedure.i Drawing3D_Normalize(*Use.Drawing3D_Vector)
		Protected Length.f = Drawing3D_Length(*Use)
		If Length
			*Use\X / Length
			*Use\Y / Length
			*Use\Z / Length
		EndIf
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Copy(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X = *Source\X
		*Use\Y = *Source\Y
		*Use\Z = *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Add(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X + *Source\X
		*Use\Y + *Source\Y
		*Use\Z + *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Subtract(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X - *Source\X
		*Use\Y - *Source\Y
		*Use\Z - *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Cross(*Use.Drawing3D_Vector, *Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		*Use\X = *Source1\Y * *Source2\Z - *Source1\Z * *Source2\Y
		*Use\Y = *Source1\Z * *Source2\X - *Source1\X * *Source2\Z
		*Use\Z = *Source1\X * *Source2\Y - *Source1\Y * *Source2\X
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Scalar(*Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		ProcedureReturn *Source1\X * *Source2\X + *Source1\Y * *Source2\Y + *Source1\Z * *Source2\Z
	EndProcedure
	Procedure.i Drawing3D_Rotate(*Use.Drawing3D_Vector, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Vector
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Vector))
		*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
		*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
		*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Orientation(*Use.Drawing3D_Matrix, RotationX.f, RotationY.f, RotationZ.f)
		Protected CosZ.f = Cos(RotationZ), CosY.f = Cos(RotationY), CosX.f = Cos(RotationX)
		Protected SinZ.f = Sin(RotationZ), SinY.f = Sin(RotationY), SinX.f = Sin(RotationX)
		*Use\A11 =  CosY*CosZ                : *Use\A12 = -CosY*SinZ                : *Use\A13 =  SinY
		*Use\A21 =  SinX*SinY*CosZ+CosX*SinZ : *Use\A22 = -SinX*SinY*SinZ+CosX*CosZ : *Use\A23 = -SinX*CosY
		*Use\A31 = -CosX*SinY*CosZ+SinX*SinZ : *Use\A32 =  CosX*SinY*SinZ+SinX*CosZ : *Use\A33 =  CosX*CosY
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Multiply(*Use.Drawing3D_Matrix, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Matrix
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Matrix))
		With *Use
			\A11 = Buffer\A11 * *Source\A11 + Buffer\A12 * *Source\A21 + Buffer\A13 * *Source\A31
			\A12 = Buffer\A11 * *Source\A12 + Buffer\A12 * *Source\A22 + Buffer\A13 * *Source\A32
			\A13 = Buffer\A11 * *Source\A13 + Buffer\A12 * *Source\A23 + Buffer\A13 * *Source\A33
			\A21 = Buffer\A21 * *Source\A11 + Buffer\A22 * *Source\A21 + Buffer\A23 * *Source\A31
			\A22 = Buffer\A21 * *Source\A12 + Buffer\A22 * *Source\A22 + Buffer\A23 * *Source\A32
			\A23 = Buffer\A21 * *Source\A13 + Buffer\A22 * *Source\A23 + Buffer\A23 * *Source\A33
			\A31 = Buffer\A31 * *Source\A11 + Buffer\A32 * *Source\A21 + Buffer\A33 * *Source\A31
			\A32 = Buffer\A31 * *Source\A12 + Buffer\A32 * *Source\A22 + Buffer\A33 * *Source\A32
			\A33 = Buffer\A31 * *Source\A13 + Buffer\A32 * *Source\A23 + Buffer\A33 * *Source\A33
		EndWith
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Projection(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		If *Source\Z
			*Use\InvZ = 1 / *Source\Z
			*Use\X = - *Source\X * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterX
			*Use\Y =   *Source\Y * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterY
		EndIf
		ProcedureReturn *Use
	EndProcedure
	;- Private: Drawing
	Procedure Drawing3D_AddPixel(X.i, Y.i, Distance.f)
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel
		If Distance < 0
			*Pixel = AddElement(Drawing3DInclude\Pixel())
			*OldPixel = Drawing3DInclude\PixelIndex(X, Y)
			If *OldPixel
				If Distance > *OldPixel\Distance
					*Pixel\PreviousPixel = *OldPixel
					Drawing3DInclude\PixelIndex(X, Y) = *Pixel
				Else
					While *OldPixel\PreviousPixel And *OldPixel\PreviousPixel\Distance > Distance
						*OldPixel = *OldPixel\PreviousPixel
					Wend
					*Pixel\PreviousPixel = *OldPixel\PreviousPixel
					*OldPixel\PreviousPixel = *Pixel
				EndIf
			Else
				Drawing3DInclude\PixelIndex(X, Y) = *Pixel
			EndIf
			*Pixel\Distance = Distance
		EndIf
		ProcedureReturn *Pixel
	EndProcedure
	Procedure Drawing3D_DrawTriangle(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex, *Vertex2.Drawing3D_Vertex, Texture.i=0)
		Protected Triangle.Drawing3D_Triangle
		Protected LightFactor.f, N.i
		With Triangle
			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Drawing3D_Projection(\Vertex[2], *Vertex2) : \Vertex[2]\Color = *Vertex2\Color
			Protected X.i, Y.i
			Protected DX21.f = \Vertex[2]\X-\Vertex[1]\X, DY21.f = \Vertex[2]\Y-\Vertex[1]\Y
			Protected DX02.f = \Vertex[0]\X-\Vertex[2]\X, DY02.f = \Vertex[0]\Y-\Vertex[2]\Y
			Protected DX10.f = \Vertex[1]\X-\Vertex[0]\X, DY10.f = \Vertex[1]\Y-\Vertex[0]\Y
			Protected L1.f, L2.f, L3.f
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), Drawing3DInclude\MaxY)
			Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Color.Drawing3D_Color, Norm.Drawing3D_Vector, V1.Drawing3D_Vector, V2.Drawing3D_Vector
			Protected T.f = 1.0 / (-DY21*DX02 + DX21*DY02)
			Protected Distance.f, Brightness.f, Q1.f, Q2.f
			;If T< 0 : ProcedureReturn 0 : EndIf
			If Texture = 0
				For N = 0 To 2
					\Vertex[N]\Color\Red / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Green / \Vertex[N]\Color\Alpha
					\Vertex[N]\Color\Blue / \Vertex[N]\Color\Alpha
					Drawing3D_Copy(V1, *Vertex1) : Drawing3D_Subtract(V1, *Vertex0)
					Drawing3D_Copy(V2, *Vertex2) : Drawing3D_Subtract(V2, *Vertex0)
					Drawing3D_Normalize(Drawing3D_Cross(Norm, V2, V1))
					ForEach Drawing3DInclude\Light()
						LightFactor = Drawing3D_Scalar(Norm, Drawing3DInclude\Light()\Direction)*Sign(T)
						If LightFactor > 0
							\Vertex[N]\Color\Red   + LightFactor*Drawing3DInclude\Light()\Color\Red
							\Vertex[N]\Color\Green + LightFactor*Drawing3DInclude\Light()\Color\Green
							\Vertex[N]\Color\Blue  + LightFactor*Drawing3DInclude\Light()\Color\Blue
						EndIf
					Next
					Drawing3D_NormalizeColor(\Vertex[N]\Color)
					Drawing3DInclude\CurrentColor[N] = \Vertex[N]\Color
				Next
			EndIf
			For Y = YA To YB
				Q1 = DX21*(Y-\Vertex[2]\Y)
				Q2 = DX02*(Y-\Vertex[2]\Y)
				*Pixel = #Null
				For X = XA To XB
					L1 = ( -DY21*(X-\Vertex[2]\X) + Q1 ) * T
					L2 = ( -DY02*(X-\Vertex[2]\X) + Q2 ) * T
					L3 = 1.0 - L1 - L2
					If L1 >= 0.0 And L2 >= 0.0 And L3 >= 0.0
						Distance = 1.0 / ( L1*\Vertex[0]\InvZ + L2*\Vertex[1]\InvZ + L3*\Vertex[2]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							If Drawing3DInclude\CurrentImage3D
								If Texture = 1
									Drawing3D_ImageColor(*Pixel\Color, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
								Else
									Drawing3D_ImageColor(*Pixel\Color, 1.0-L2*\Vertex[1]\InvZ*Distance, 1.0-L3*\Vertex[2]\InvZ*Distance)
								EndIf
							Else
								Drawing3D_ColorMix(*Pixel\Color, L1*\Vertex[0]\InvZ*Distance, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
							EndIf
						EndIf
					ElseIf *Pixel
						Break
					EndIf
				Next
			Next
		EndWith
	EndProcedure
	Procedure Drawing3D_DrawLine(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex)
		Protected Line.Drawing3D_Line, Distance.f
		Protected X.i, Y.i, Length.f, Position.f
		Protected Visible.f, Q.Drawing3D_Vector, R.Drawing3D_Vector, Cross.Drawing3D_Vector
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel
		With Line
			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X)-1, 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X)+1, Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y)-1, 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y)+2, Drawing3DInclude\MaxY)
			Drawing3D_Copy(R, \Vertex[1])
			Drawing3D_Subtract(R, \Vertex[0])
			Length = Drawing3D_Length(R)
			Drawing3DInclude\CurrentColor[0] = \Vertex[0]\Color
			Drawing3DInclude\CurrentColor[1] = \Vertex[1]\Color
			For Y = YA To YB
				*Pixel = #Null
				For X = XA To XB
					Drawing3D_Vector(Q, X, Y, 0)
					Drawing3D_Subtract(Q, \Vertex[0])
					Drawing3D_Cross(Cross, Q, R)
					Position = Drawing3D_Scalar(Q, R) / Length
					Visible = 1 - Drawing3D_Length(Cross) / Length
					If Position >= 0 And Position <= Length And Visible > 0
						Distance = 1.0 / ( (1-Position/Length)*\Vertex[0]\InvZ + (Position/Length)*\Vertex[1]\InvZ )
						*Pixel = Drawing3D_AddPixel(X, Y, Distance)
						If *Pixel
							Drawing3D_ColorMix(*Pixel\Color, (1-Position/Length)*\Vertex[0]\InvZ*Distance*Visible, (Position/Length)*\Vertex[1]\InvZ*Distance*Visible, 0)
						EndIf
					EndIf
					If *Pixel And Visible < -1
						Break
					EndIf
				Next
			Next
		EndWith
	EndProcedure
	Procedure Drawing3D_DrawPoint(*Vertex.Drawing3D_Vertex)
		Protected Vertex.Drawing3D_Vertex, Distance.f
		Protected X.i, Y.i
		Protected Visible.f
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Nothing.Drawing3D_Color
		Drawing3D_Projection(Vertex, *Vertex) : Vertex\Color = *Vertex\Color
		Protected XA.i = Drawing3D_Max(Vertex\X-1, 0)
		Protected XB.i = Drawing3D_Min(Vertex\X+1, Drawing3DInclude\MaxX)
		Protected YA.i = Drawing3D_Max(Vertex\Y-1, 0)
		Protected YB.i = Drawing3D_Min(Vertex\Y+1, Drawing3DInclude\MaxY)
		Drawing3DInclude\CurrentColor[0] = Vertex\Color
		For Y = YA To YB
			For X = XA To XB
				Visible = 1 - Sqr((X-Vertex\X)*(X-Vertex\X)+(Y-Vertex\Y)*(Y-Vertex\Y))
				If Visible > 0
					Distance = 1.0 / Vertex\InvZ
					*Pixel = Drawing3D_AddPixel(X, Y, Distance)
					If *Pixel
						Drawing3D_ColorMix(*Pixel\Color, Visible, 0, 0)
					EndIf
				EndIf
			Next
		Next
	EndProcedure
	;- Cluster (unfertig)
	Procedure.i CreateCluster3D()
		Protected *Cluster.Drawing3D_Cluster = AddElement(Drawing3DInclude\Cluster())
		Drawing3DInclude\CurrentCluster = *Cluster
		ProcedureReturn *Cluster
	EndProcedure
	Procedure CloseCluster3D()
	EndProcedure
	Procedure DrawCluster3D(*Cluster.Drawing3D_Cluster, X.f, Y.f, Z.f, Pitch.f=0.0, Yaw.f=0.0, Roll.f=0.0)
	EndProcedure
	;- Image3D
	Procedure.i Image3DID(Image3D.i)
		If Image3D & ~$FFFF
			ProcedureReturn Image3D
		Else
			ProcedureReturn Drawing3DInclude\Image3DID(Image3D)
		EndIf
	EndProcedure
	Procedure.i FreeImage3D(Image3D.i)
		Protected *Image3D.Drawing3D_Image = Image3DID(Image3D)
		With *Image3D
			If Not \Number & ~$FFFF
				Drawing3DInclude\Image3DID(\Number) = #Null
			EndIf
			ChangeCurrentElement(Drawing3DInclude\Image3D(), *Image3D)
			DeleteElement(Drawing3DInclude\Image3D())
		EndWith
	EndProcedure
	Procedure CreateImage3D(Image3D.i, Image.i)
		Protected *Image3D.Drawing3D_Image
		Protected X.i, Y.i
		If Image3D = #PB_Any
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = *Image3D
		ElseIf Not Image3D & ~$FFFF
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = Image3D
			If ArraySize(Drawing3DInclude\Image3DID()) < Image3D
				ReDim Drawing3DInclude\Image3DID(Image3D)
			ElseIf Drawing3DInclude\Image3DID(Image3D)
				FreeImage3D(Drawing3DInclude\Image3DID(Image3D))
			EndIf
			Drawing3DInclude\Image3DID(Image3D) = *Image3D
		Else
			ProcedureReturn #Null
		EndIf
		With *Image3D
			\Width  = ImageWidth(Image)
			\Height = ImageHeight(Image)
			Dim \Pixel(\Width-1, \Height-1)
			If StartDrawing(ImageOutput(Image))
				DrawingMode(#PB_2DDrawing_AllChannels)
				Select ImageDepth(Image, #PB_Image_InternalDepth)
				Case 24
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y)|$FF000000)
						Next
					Next
				Case 32
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y))
						Next
					Next
				EndSelect
				StopDrawing()
			EndIf
		EndWith
	EndProcedure
	;- Drawing
	Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
		; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle
		With Drawing3DInclude
			If StartDrawing(Output)
				DrawingMode(#PB_2DDrawing_AllChannels)
				\MaxX = OutputWidth()-1
				\MaxY = OutputHeight()-1
				\CenterX = OutputWidth()/2
				\CenterY = OutputHeight()/2
				\Distance = OutputHeight()/Tan(Radian(FieldOfView)*0.5)
				Drawing3D_Vector(Drawing3DInclude\Position, 0, 0, \Distance)
				If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY
					Dim \PixelIndex(\MaxX, \MaxY)
				Else
					FillMemory(@\PixelIndex(0,0), SizeOf(Integer)*(\MaxX+1)*(\MaxY+1))
				EndIf
				ClearList(\Pixel())
				ClearList(\Light())
				ClearStructure(\MainCluster, Drawing3D_Cluster)
				ProcedureReturn #True
			EndIf
		EndWith
	EndProcedure
	Procedure StopDrawing3D()
		; Schließt eine Drawing3D-Umgebung und rendert die Szene
		Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
		Protected Color.Drawing3D_Color
		Protected X.i, Y.i
		For Y = 0 To Drawing3DInclude\MaxY
			For X = 0 To Drawing3DInclude\MaxX
				*Pixel = Drawing3DInclude\PixelIndex(X, Y)
				If *Pixel
					While *Pixel\PreviousPixel
						Drawing3D_AlphaBlend(*Pixel\PreviousPixel\Color, *Pixel\Color)
						*Pixel = *Pixel\PreviousPixel
					Wend
					Color = Drawing3DInclude\Background
					Plot(X, Y, Drawing3D_GetColor(Drawing3D_AlphaBlend(Color, *Pixel)))
				EndIf
			Next
		Next
		StopDrawing()
	EndProcedure
	Procedure Drawing3DMode(Mode.i)
		; Ändert den Zeichenmodus
		Drawing3DInclude\Mode = Mode
	EndProcedure
	Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Position der Szene
		Protected Vector.Drawing3D_Vector
		If Mode = #PB_Relative
			Drawing3D_Vector(Vector, -X, -Y, -Z)
			Drawing3D_Add(Drawing3DInclude\Position, Vector)
		Else
			Drawing3D_Vector(Drawing3DInclude\Position, -X, -Y, -Z)
		EndIf
	EndProcedure
	Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Orientierung der Szene
		Protected Rotation.Drawing3D_Matrix
		If Mode = #PB_Relative
			Drawing3DInclude\RotX+RotationX
			Drawing3DInclude\RotY+RotationY
			Drawing3DInclude\RotZ+RotationZ
			Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
			Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
			Drawing3DInclude\Orientation = Rotation
		Else
			Drawing3DInclude\RotX=RotationX
			Drawing3DInclude\RotY=RotationY
			Drawing3DInclude\RotZ=RotationZ
			Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		EndIf
	EndProcedure
	Procedure Drawing3DBackground(Color.l=$FF000000)
		; Setzt den Szenenhintergrund
		Box(0, 0, OutputWidth(), OutputHeight(), Color)
		Drawing3D_SetColor(Drawing3DInclude\Background, Color)
	EndProcedure
	Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
		; Setzt ein Licht in die Szene
		Protected *Light.Drawing3D_Light = AddElement(Drawing3DInclude\Light())
		With *Light
			Drawing3D_Vector(\Direction, DirectionX, DirectionY, DirectionZ)
			Drawing3D_Normalize(\Direction)
			Drawing3D_SetColor(\Color, Color)
		EndWith
		ProcedureReturn *Light
	EndProcedure
	Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.q)
		; Zeichnet einen Punkt in die Szene
		Protected Vertex.Drawing3D_Vertex
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_SetColor(Vertex\Color, Color)
		Drawing3D_Rotate(Vertex, Drawing3DInclude\Orientation)
		Drawing3D_Subtract(Vertex, Drawing3DInclude\Position)
		Drawing3D_DrawPoint(Vertex)
	EndProcedure
	Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
		; Zeichnet eine Linie in die Szene
		Protected Line.Drawing3D_Line
		Protected N.i
		Drawing3D_Vector(Line\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Line\Vertex[1], X2, Y2, Z2)
		Drawing3D_SetColor(Line\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color2)
		EndIf
		For N = 0 To 1
			Drawing3D_Rotate(Line\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Line\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawLine(Line\Vertex[0], Line\Vertex[1])
	EndProcedure
	Procedure DrawTriangle3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor)
		; Zeichnet ein Dreieck in die Szene
		Protected Triangle.Drawing3D_Triangle
		Protected N.i
		Drawing3D_Vector(Triangle\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Triangle\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Triangle\Vertex[2], X3, Y3, Z3)
		Drawing3D_SetColor(Triangle\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color3)
		EndIf
		For N = 0 To 2
			Drawing3D_Rotate(Triangle\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Triangle\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Triangle\Vertex[0], Triangle\Vertex[1])
			Drawing3D_DrawLine(Triangle\Vertex[1], Triangle\Vertex[2])
			Drawing3D_DrawLine(Triangle\Vertex[2], Triangle\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Triangle\Vertex[0], Triangle\Vertex[1], Triangle\Vertex[2])
		EndIf
	EndProcedure
	Procedure DrawPlane3D(X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f, RotationY.f, RotationZ.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor, Color4.q=#Drawing3D_NoColor)
		; Zeichnet eine Ebene in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_SetColor(Plane\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color3)
		EndIf
		If Color4 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color4)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Plane\Vertex[0], Plane\Vertex[1])
			Drawing3D_DrawLine(Plane\Vertex[1], Plane\Vertex[3])
			Drawing3D_DrawLine(Plane\Vertex[3], Plane\Vertex[2])
			Drawing3D_DrawLine(Plane\Vertex[2], Plane\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2])
			Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1])
		EndIf
	EndProcedure
	Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q, Mode.i=#Drawing3D_Centered)
		; Zeichnet einen Quader in die Szene
		Protected Box.Drawing3D_Box
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3D_Vector(Vertex, X, Y, Z)
		If Mode=#Drawing3D_Absolute
			Drawing3D_Vector(Box\Vertex[0],	0,	Height,	Depth)
			Drawing3D_Vector(Box\Vertex[1],	Width,Height,	Depth)
			Drawing3D_Vector(Box\Vertex[2], 0, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[3],  Width, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[4], 0,  Height, 0)
			Drawing3D_Vector(Box\Vertex[5],  Width,  Height, 0)
			Drawing3D_Vector(Box\Vertex[6], 0, 0, 0)
			Drawing3D_Vector(Box\Vertex[7],  Width, 0, 0)
		Else
			Drawing3D_Vector(Box\Vertex[0], -Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[1],  Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[2], -Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[3],  Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[4], -Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[5],  Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[6], -Width*0.5, -Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[7],  Width*0.5, -Height*0.5, -Depth*0.5)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 7
			Drawing3D_SetColor(Box\Vertex[N]\Color, Color)
			Drawing3D_Rotate(Box\Vertex[N], Orientation)
			Drawing3D_Add(Box\Vertex[N], Vertex)
			Drawing3D_Rotate(Box\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Box\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[1])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[6], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[2])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[5], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[4])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[3], Box\Vertex[7])
		Else
			Drawing3D_DrawTriangle(Box\Vertex[0], Box\Vertex[1], Box\Vertex[2])
			Drawing3D_DrawTriangle(Box\Vertex[3], Box\Vertex[2], Box\Vertex[1])
			Drawing3D_DrawTriangle(Box\Vertex[5], Box\Vertex[4], Box\Vertex[7])
			Drawing3D_DrawTriangle(Box\Vertex[6], Box\Vertex[7], Box\Vertex[4])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[5], Box\Vertex[3])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[3], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[0], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[6], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[5], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[0], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[3], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[6], Box\Vertex[3])
		EndIf
	EndProcedure
	Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
		; Zeichnet ein Bild (Image3D) in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)
		Drawing3DInclude\CurrentImage3D = #Null
	EndProcedure
	Procedure DrawTranformedImage3D(Image3D.i, X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, X4.f, Y4.f, Z4.f)
		; Zeichnet ein verzerrtes Bild (Image3D) in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)
		Drawing3D_Vector(Plane\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Plane\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Plane\Vertex[2], X3, Y3, Z3)
		Drawing3D_Vector(Plane\Vertex[3], X4, Y4, Z4)
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)
		Drawing3DInclude\CurrentImage3D = #Null
	EndProcedure
	Procedure DrawBoxWithBorder3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)
		Drawing3DMode(#Drawing3D_Default)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, SurfaceColor, Mode)
		Drawing3DMode(#Drawing3D_Outline)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, BorderColor, Mode)
	EndProcedure
	Drawing3D_Orientation(Drawing3DInclude\Orientation, 0, 0, 0)
; EndDefine
; Define Demonstration
	#WX=1040
	#WY=800
	#WZ=300
	#WW=#WX+20
	CompilerIf #PB_Compiler_IsMainFile
		Enumeration
			#Window
			#Canvas
			#ListViewGadget
			#RotateZero
			#RotateX
			#RotateY
			#RotateZ
			#Image
			#Image3D
			#ButtonGadget
			#RealImage
		EndEnumeration
		Procedure UpdateRotationGadgets()
			With Drawing3DInclude
				SetGadgetState(#RotateX,\RotX)
				SetGadgetState(#RotateY,\RotY)
				SetGadgetState(#RotateZ,\RotZ)
			EndWith
		EndProcedure
		Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)
			Static MouseX.i, MouseY.i
			; **********************************
			Protected Distance.f = 500
			; **********************************
			Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f
			Protected Dim Y.f(40, 40)
			Protected Dim Color.l(40, 40)
			Protected Time1.q, Time2.q, Frequency.q
			Protected rx.f,ry.f,rz.f
			QueryPerformanceFrequency_(@Frequency)
			QueryPerformanceCounter_(@Time1)
			If Image
				StartDrawing3D(ImageOutput(Image))
				Drawing3DBackground($00FFFFFF)
			Else
				StartDrawing3D(CanvasOutput(Gadget))
				Drawing3DBackground($FFFFFFFF)
				Distance * Pow(1.1, GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta))
				If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
					rx=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15
					ry=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15
					Drawing3DRotation(Radian(rx),Radian(ry),0, #PB_Relative)
					UpdateRotationGadgets()
				EndIf
				MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
				MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
			EndIf
			; **********************************
			Drawing3DPosition(-100, -100, -Distance)
			; **********************************
			Select GetGadgetState(#ListViewGadget)
			Case 0
				DrawPlane3D(0, 0, 0, 340, 200,  0,  0,  0, $80FF0000)
				DrawPlane3D(0, 0, 0, 340, 200, 90, 90,  0, $800000FF)
				DrawPlane3D(0, 0, 0, 340, 200, 90,  0, 90, $8000FF00)
			Case 1
				Drawing3DMode(#Drawing3D_Outline)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
				Drawing3DMode(#Drawing3D_Default)
			Case 2
				Drawing3DLight(1, 0, 0, $FFFFFF00)
				Drawing3DLight(-1, 0, 0, $FF00FFFF)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
			Case 3
				Drawing3DLight(0.5, 1, 1, $FFFFFFFF)
				DrawBox3D(0, 0, 0, 100, 200, 300, 0, 0, 0, $C000C060)
				DrawBox3D(0, 0, 0, 100, 200, 300, 30, 45, 15, $C08000C0)
			Case 4
				Drawing3DLight(0.5, 1, -1, $FFFFFFFF)
				DrawTriangle3D(-100, 100, 100, 100, 100, -100, 100, -100, 100, $FF00C000, $FFC00000, $FF0000C0)
				DrawTriangle3D(-100, 100, 100, 100, -100, 100, -100, -100, -100, $FF00C000, $FF0000C0, $FF00C0C0)
				DrawTriangle3D(-100, 100, 100, -100, -100, -100, 100, 100, -100, $FF00C000, $FF00C0C0, $FFC00000)
				DrawTriangle3D(100, -100, 100, 100, 100, -100, -100, -100, -100, $FF0000C0, $FFC00000, $FF00C0C0)
				DrawLine3D(90, -90, -90, -90, -90, 90, $FF00C000, $FFC00000)
				DrawLine3D(-90, -90, 90, -90, 90, -90, $FFC00000, $FF0000C0)
				DrawLine3D(-90, 90, -90, 90, -90, -90, $FF0000C0, $FF00C000)
				DrawLine3D(90, -90, -90, 90, 90, 90, $FF00C000, $FF00C0C0)
				DrawLine3D(-90, -90, 90, 90, 90, 90, $FFC00000, $FF00C0C0)
				DrawLine3D(-90, 90, -90, 90, 90, 90, $FF0000C0, $FF00C0C0)
			Case 5
				DrawImage3D(#Image3D, 0, 0, 0, 400, 400, 0, 0, 0)
			Case 6
				RandomSeed(1)
				For Y = -100 To 100
					For X = -100 To 100
						Z = Random(100)-50
						DrawPoint3D(X, Y, Z, $FF000000)
					Next
				Next
			Case 7
				Drawing3DLight(0.5, 1, 1, $40FFFFFF)
				DrawBox3D(0, 0, 0, 100, 30, 30, 0, 0, 0, $FF404040)
				DrawBox3D(-75, 0, 0, 50, 30, 30, 0, 0, 0, $FF808000)
				DrawBox3D(75, 0, 0, 50, 30, 30, 0, 0, 0, $FF000080)
				RandomSeed(5)
				For N = 1 To 50
					Phi = Random(359)
					R = Random(100)+30
					For W = 0 To 359 Step 5
						R1 = (1-Cos(Radian(W)))*R
						R2 = (1-Cos(Radian(W+5)))*R
						DrawLine3D(-Sin(Radian(W))*R*2, R1*Sin(Radian(Phi)), R1*Cos(Radian(Phi)), -Sin(Radian(W+5))*R*2, R2*Sin(Radian(Phi)), R2*Cos(Radian(Phi)), RGBA(255*W/360, 255*(360-W)/360, 255*(360-W)/360, 192))
					Next
				Next
			Case 8
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				For Z = -20 To 20
					For X = -20 To 20
						Y(X+20,Z+20) = Exp(-X*X/100-Z*Z/100)*(X+Z/4)/5
						If Y(X+20,Z+20) < 0
							Color(X+20,Z+20) = RGBA(0, 128+128*Y(X+20,Z+20), -255*Y(X+20,Z+20), 255)
						Else
							Color(X+20,Z+20) = RGBA(255*Y(X+20,Z+20), 128+128*Y(X+20,Z+20), 0, 255)
						EndIf
						Y(X+20,Z+20) * 200
					Next
				Next
				For Z = -20 To 19
					For X = -20 To 19
						DrawTriangle3D(X*10, Y(X+20,Z+20), Z*10, (X+1)*10, Y(X+21,Z+20), Z*10, X*10, Y(X+20,Z+21), (Z+1)*10, Color(X+20,Z+20), Color(X+21,Z+20), Color(X+20,Z+21))
						DrawTriangle3D((X+1)*10, Y(X+21,Z+21), (Z+1)*10, X*10, Y(X+20,Z+21), (Z+1)*10, (X+1)*10, Y(X+21,Z+20), Z*10, Color(X+21,Z+21), Color(X+20,Z+21), Color(X+21,Z+20))
					Next
				Next
			Case 9
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				Drawing3DMode(#Drawing3D_Default)
				Drawing3DBackground($FFE0E0E0)
				Drawing3DLight(1, 1, 1, $40FFFFFF)
				; unten
				DrawBoxWithBorder3D(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,0,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; mittig
				DrawBoxWithBorder3D(0,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,51,0, 62,25,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; links/rechts
				DrawBoxWithBorder3D(0,77,0, 62,130,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,77,0, 62,130,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; oben
				DrawBoxWithBorder3D(0,208,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; Platten
				DrawBoxWithBorder3D(62,77,0, 1,181,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,207,0, 125,1,42, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,76,0, 125,1,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,0,40, 1,76,20, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,76,0, 1,131,40, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				
				
				; Achsen
				DrawLine3D(0,0,0, 100,0,0, $FF000000)
				DrawLine3D(0,0,0, 0,100,0, $FF000000)
				DrawLine3D(0,0,0, 0,0,100, $FF000000)
			EndSelect
			StopDrawing3D()
			QueryPerformanceCounter_(@Time2)
			;SetWindowTitle(#Window, StrF((Time2-Time1)/Frequency*1000,3))
		EndProcedure
		UsePNGImageDecoder()
		UsePNGImageEncoder()
		CatchImage(#Image, ?Image)
		CreateImage3D(#Image3D, #Image)
		OpenWindow(#Window, 0, 0, #WX+#WZ+30, #WY+20, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
		CanvasGadget(#Canvas, 10, 10, #WX, #WY, #PB_Canvas_Border|#PB_Canvas_Keyboard)
		FrameGadget(#PB_Any, #WW, 10, #WZ, 190, "Szenenauswahl")
		ListViewGadget(#ListViewGadget, #WW+10, 30, #WZ-20, 160)
		AddGadgetItem(#ListViewGadget, -1, "Drei sich durchdringende Flächen")
		AddGadgetItem(#ListViewGadget, -1, "Würfel aus Linien")
		AddGadgetItem(#ListViewGadget, -1, "Belichteter Würfel")
		AddGadgetItem(#ListViewGadget, -1, "Zwei durchdringende Quader")
		AddGadgetItem(#ListViewGadget, -1, "Tetraeder mit verschiedenen Eckfarben")
		AddGadgetItem(#ListViewGadget, -1, "Texturfläche")
		AddGadgetItem(#ListViewGadget, -1, "Punkte")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: Magnet & Feldlinien")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: 3D-Funktion")
		AddGadgetItem(#ListViewGadget, -1, "Spielwiese")
		SetGadgetState(#ListViewGadget, 9)
		TextGadget(#PB_Any, #WW, 210, 290, 40, "drag object to rotate the scene, mouse wheel zooms")
		ButtonGadget(#RotateZero,#WW,250,100,30,"Reset")
		TrackBarGadget(#RotateX, #WW, 300, #WZ,20,0,360)
		TrackBarGadget(#RotateY, #WW, 330, #WZ,20,0,360)
		TrackBarGadget(#RotateZ, #WW, 360, #WZ,20,0,360)
		ButtonGadget(#ButtonGadget,#WW, 580, 120, 30, "Save Image...")
		; **********************************
		Drawing3DRotation(10,330,0)
		; **********************************
		UpdateRotationGadgets()
		UpdateCanvasGadget(#Canvas)
		Define FileName.s
		Repeat
			Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #PB_Event_Gadget
				Define e.i
				e=EventGadget()
				Select e
				Case #Canvas, #ListViewGadget
					UpdateCanvasGadget(#Canvas)
				Case #RotateZero
					Drawing3DRotation(0,0,0, #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					UpdateRotationGadgets()
				Case #RotateX To #RotateZ
					Drawing3DRotation(GetGadgetState(#RotateX),GetGadgetState(#RotateY),GetGadgetState(#RotateZ), #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					;UpdateRotationGadgets()
					Debug Drawing3DInclude\RotX
				Case #ButtonGadget
					CreateImage(#RealImage, 600, 600, 32|#PB_Image_Transparent)
					UpdateCanvasGadget(#Canvas, #RealImage)
					FileName = SaveFileRequester("Save", "", "*.png|*.PNG", 1)
					If FileName
						SaveImage(#RealImage, FileName, #PB_ImagePlugin_PNG)
					EndIf
				EndSelect
			EndSelect
		ForEver
		DataSection
			Image:
			IncludeBinary "Image.png"
		EndDataSection
	CompilerEndIf
; EndDefine
- 
				Michael Vogel
 - Beiträge: 72
 - Registriert: 16.03.2006 11:20
 
Re: Drawing3D - Draw-Befehle für 3D-Szenen
Noch ein kleiner Nachschlag - vielleicht könnte die Verwendung der Vektorgrafikbibliothek zu einen wahren Geschwindigkeitsrausch verhelfen  
 
Auch wenn man mit diesem Ansatz kaum an die wunderbaren Überschneidungen des Originalcodes herankommen kann, könnte damit beispielsweise ein brauchbarer Baukasten etwa zum Gestalten von Inneneinrichtungen (Kästen, Möbel etc.) geschaffen werden.
Im folgenden wurden nur einige wenige Zeilen angepasst, das Ergebnis ist zwar noch recht bescheiden, allerdings benötigt ein Bildschirm-Update nun wenige Millisekunden...
			
			
									
									
						Auch wenn man mit diesem Ansatz kaum an die wunderbaren Überschneidungen des Originalcodes herankommen kann, könnte damit beispielsweise ein brauchbarer Baukasten etwa zum Gestalten von Inneneinrichtungen (Kästen, Möbel etc.) geschaffen werden.
Im folgenden wurden nur einige wenige Zeilen angepasst, das Ergebnis ist zwar noch recht bescheiden, allerdings benötigt ein Bildschirm-Update nun wenige Millisekunden...
Code: Alles auswählen
Global huch
Global t1,t2,t3,t4,t5,t6,t7,t8,t9
; Define 3D-Library (Include File)
	EnableExplicit
	Structure Drawing3D_Color
		Red.f
		Green.f
		Blue.f
		Alpha.f
	EndStructure
	Structure Drawing3D_Vector
		X.f
		Y.f
		StructureUnion
			Z.f
			InvZ.f
		EndStructureUnion
	EndStructure
	Structure Drawing3D_Vertex Extends Drawing3D_Vector
		Color.Drawing3D_Color
		BorderColor.Drawing3D_Color
	EndStructure
	Structure Drawing3D_Matrix
		A11.f : A12.f : A13.f
		A21.f : A22.f : A23.f
		A31.f : A32.f : A33.f
	EndStructure
	Structure Drawing3D_Pixel
		Color.Drawing3D_Color
		Distance.f
		*PreviousPixel.Drawing3D_Pixel
	EndStructure
	Structure Drawing3D_Box
		Vertex.Drawing3D_Vertex[8]
	EndStructure
	Structure Drawing3D_Plane
		Vertex.Drawing3D_Vertex[4]
	EndStructure
	Structure Drawing3D_Triangle
		Vertex.Drawing3D_Vertex[3]
	EndStructure
	Structure Drawing3D_Line
		Vertex.Drawing3D_Vertex[2]
	EndStructure
	Structure Drawing3D_Light
		Direction.Drawing3D_Vector
		Color.Drawing3D_Color
	EndStructure
	Structure Drawing3D_Cluster
		Type.i
		Position.Drawing3D_Vector
		Orientation.Drawing3D_Matrix
		List		Triangle.Drawing3D_Triangle()
		List		*Cluster.Drawing3D_Cluster()
	EndStructure
	; Structure Drawing3D_Object
	; 	StructureUnion
	; 		Type.i
	; 		Cluster.Drawing3D_Cluster
	; 		Line.Drawing3D_Line
	; 		Triangle.Drawing3D_Triangle
	; 	EndStructureUnion
	; EndStructure
	Structure Drawing3D_Image
		Number.i
		Array Pixel.Drawing3D_Color(0,0)
		Width.i
		Height.i
	EndStructure
	Structure Drawing3DInclude
		Array		*PixelIndex.Drawing3D_Pixel(0, 0) ; Index der Pixel für schnelleren Zugriff
		List		Pixel.Drawing3D_Pixel()           ; Liste aller zu zeichnenden Pixel
		List		Cluster.Drawing3D_Cluster()
		List		Light.Drawing3D_Light()           ; Liste aller Lichtquellen
		*CurrentCluster.Drawing3D_Cluster
		Orientation.Drawing3D_Matrix              ; Orientierung der Szene
		Position.Drawing3D_Vector                 ; Position der Kamera
		Background.Drawing3D_Color                ; Hintergrundfarbe
		MainCluster.Drawing3D_Cluster
		MaxX.i
		MaxY.i
		CenterX.i
		CenterY.i
		Distance.f
		RotX.f
		RotY.f
		RotZ.f
		CurrentColor.Drawing3D_Color[3]
		*CurrentImage3D.Drawing3D_Image
		List		Image3D.Drawing3D_Image()
		Array	*Image3DID.Drawing3D_Image(0)
		Mode.i
	EndStructure
	Global Drawing3DInclude.Drawing3DInclude
	#Drawing3D_NoColor = $100000000
	Enumeration
		;#Drawing3D_FrontOnly =
		#Drawing3D_Outline=	%0001
		#Drawing3D_Default=	%0010
		#Drawing3D_Filled=	%0010
	EndEnumeration
	Enumeration
		#Drawing3D_Centered
		#Drawing3D_Absolute
	EndEnumeration
	;- Private: General
	Procedure.f Drawing3D_Min(Value1.f, Value2.f, Value3.f=1e30)
		If Value3 < Value2
			If Value3 < Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 < Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	Procedure.f Drawing3D_Max(Value1.f, Value2.f, Value3.f=-1e30)
		If Value3 > Value2
			If Value3 > Value1
				ProcedureReturn Value3
			Else
				ProcedureReturn Value1
			EndIf
		ElseIf Value2 > Value1
			ProcedureReturn Value2
		Else
			ProcedureReturn Value1
		EndIf
	EndProcedure
	;- Private: Color
	Procedure.i Drawing3D_SetColor(*Use.Drawing3D_Color, Color.l)
		Protected Factor.f = Alpha(Color) / 255 / 255
		*Use\Alpha = Alpha(Color) / 255
		*Use\Red   = Red(Color) * Factor
		*Use\Green = Green(Color) * Factor
		*Use\Blue  = Blue(Color) * Factor
		ProcedureReturn *Use
	EndProcedure
	Procedure.l Drawing3D_GetColor(*Source.Drawing3D_Color)
		Protected Factor.f, A, R, G, B
		If *Source\Alpha
			Factor = 255.0/*Source\Alpha
			A = *Source\Alpha*255
			R = *Source\Red*Factor
			G = *Source\Green*Factor
			B = *Source\Blue*Factor
			ProcedureReturn R|G<<8|B<<16|A<<24
		Else
			ProcedureReturn 0
		EndIf
	EndProcedure
	Procedure Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
		Protected InvAlpha.f = 1.0 - *Source\Alpha
		*Use\Red   * InvAlpha + *Source\Red
		*Use\Green * InvAlpha + *Source\Green
		*Use\Blue  * InvAlpha + *Source\Blue
		*Use\Alpha * InvAlpha + *Source\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_NormalizeColor(*Use.Drawing3D_Color)
		Protected Max.f = Drawing3D_Max(*Use\Red, *Use\Green, *Use\Blue)
		If Max > 1
			*Use\Red / Max
			*Use\Green / Max
			*Use\Blue / Max
		EndIf
		*Use\Red * *Use\Alpha
		*Use\Green * *Use\Alpha
		*Use\Blue * *Use\Alpha
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_ColorMix(*Color.Drawing3D_Color, Factor1.f, Factor2.f, Factor3.f)
		Protected *C1.Drawing3D_Color = Drawing3DInclude\CurrentColor[0]
		Protected *C2.Drawing3D_Color = Drawing3DInclude\CurrentColor[1]
		Protected *C3.Drawing3D_Color = Drawing3DInclude\CurrentColor[2]
		*Color\Alpha = *C1\Alpha*Factor1 + *C2\Alpha*Factor2 + *C3\Alpha*Factor3
		*Color\Red   = *C1\Red  *Factor1 + *C2\Red  *Factor2 + *C3\Red  *Factor3
		*Color\Green = *C1\Green*Factor1 + *C2\Green*Factor2 + *C3\Green*Factor3
		*Color\Blue  = *C1\Blue *Factor1 + *C2\Blue *Factor2 + *C3\Blue *Factor3
	EndProcedure
	Procedure.i Drawing3D_ImageColor(*Color.Drawing3D_Color, X.f, Y.f)
		Protected *Image3D.Drawing3D_Image = Drawing3DInclude\CurrentImage3D
		Protected FX.f = Mod(X**Image3D\Width+0.5, 1.0)
		Protected FY.f = Mod(Y**Image3D\Height+0.5, 1.0)
		Protected PixelX0.i = X * *Image3D\Width  - 0.5 - FX
		Protected PixelY0.i = Y * *Image3D\Height - 0.5 - FY
		Protected PixelX1.i = X * *Image3D\Width  + 0.5 - FX
		Protected PixelY1.i = Y * *Image3D\Height + 0.5 - FY
		If PixelX0 < 0 : PixelX0 = 0 : EndIf
		If PixelY0 < 0 : PixelY0 = 0 : EndIf
		If PixelX1 > *Image3D\Width-1 : PixelX1 = *Image3D\Width-1 : EndIf
		If PixelY1 > *Image3D\Height-1 : PixelY1 = *Image3D\Height-1 : EndIf
		Protected *C00.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY0)
		Protected *C10.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY0)
		Protected *C01.Drawing3D_Color = *Image3D\Pixel(PixelX0, PixelY1)
		Protected *C11.Drawing3D_Color = *Image3D\Pixel(PixelX1, PixelY1)
		*Color\Alpha = *C00\Alpha*(1-FX)*(1-FY) + *C10\Alpha*(FX)*(1-FY) + *C01\Alpha*(1-FX)*(FY) + *C11\Alpha*(FX)*(FY)
		*Color\Red   = *C00\Red  *(1-FX)*(1-FY) + *C10\Red  *(FX)*(1-FY) + *C01\Red  *(1-FX)*(FY) + *C11\Red  *(FX)*(FY)
		*Color\Green = *C00\Green*(1-FX)*(1-FY) + *C10\Green*(FX)*(1-FY) + *C01\Green*(1-FX)*(FY) + *C11\Green*(FX)*(FY)
		*Color\Blue  = *C00\Blue *(1-FX)*(1-FY) + *C10\Blue *(FX)*(1-FY) + *C01\Blue *(1-FX)*(FY) + *C11\Blue *(FX)*(FY)
	EndProcedure
	;- Private: Math
	Procedure.i Drawing3D_Vector(*Use.Drawing3D_Vector, X.f, Y.f, Z.f)
		*Use\X = X
		*Use\Y = Y
		*Use\Z = Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Length(*Source.Drawing3D_Vector)
		ProcedureReturn Sqr(*Source\X * *Source\X + *Source\Y * *Source\Y + *Source\Z * *Source\Z)
	EndProcedure
	Procedure.i Drawing3D_Normalize(*Use.Drawing3D_Vector)
		Protected Length.f = Drawing3D_Length(*Use)
		If Length
			*Use\X / Length
			*Use\Y / Length
			*Use\Z / Length
		EndIf
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Copy(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X = *Source\X
		*Use\Y = *Source\Y
		*Use\Z = *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Add(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X + *Source\X
		*Use\Y + *Source\Y
		*Use\Z + *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Subtract(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		*Use\X - *Source\X
		*Use\Y - *Source\Y
		*Use\Z - *Source\Z
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Cross(*Use.Drawing3D_Vector, *Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		*Use\X = *Source1\Y * *Source2\Z - *Source1\Z * *Source2\Y
		*Use\Y = *Source1\Z * *Source2\X - *Source1\X * *Source2\Z
		*Use\Z = *Source1\X * *Source2\Y - *Source1\Y * *Source2\X
		ProcedureReturn *Use
	EndProcedure
	Procedure.f Drawing3D_Scalar(*Source1.Drawing3D_Vector, *Source2.Drawing3D_Vector)
		ProcedureReturn *Source1\X * *Source2\X + *Source1\Y * *Source2\Y + *Source1\Z * *Source2\Z
	EndProcedure
	Procedure.i Drawing3D_Rotate(*Use.Drawing3D_Vector, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Vector
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Vector))
		*Use\X = Buffer\X**Source\A11 + Buffer\Y**Source\A12 + Buffer\Z**Source\A13
		*Use\Y = Buffer\X**Source\A21 + Buffer\Y**Source\A22 + Buffer\Z**Source\A23
		*Use\Z = Buffer\X**Source\A31 + Buffer\Y**Source\A32 + Buffer\Z**Source\A33
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Orientation(*Use.Drawing3D_Matrix, RotationX.f, RotationY.f, RotationZ.f)
		Protected CosZ.f = Cos(RotationZ), CosY.f = Cos(RotationY), CosX.f = Cos(RotationX)
		Protected SinZ.f = Sin(RotationZ), SinY.f = Sin(RotationY), SinX.f = Sin(RotationX)
		*Use\A11 =  CosY*CosZ                : *Use\A12 = -CosY*SinZ                : *Use\A13 =  SinY
		*Use\A21 =  SinX*SinY*CosZ+CosX*SinZ : *Use\A22 = -SinX*SinY*SinZ+CosX*CosZ : *Use\A23 = -SinX*CosY
		*Use\A31 = -CosX*SinY*CosZ+SinX*SinZ : *Use\A32 =  CosX*SinY*SinZ+SinX*CosZ : *Use\A33 =  CosX*CosY
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Multiply(*Use.Drawing3D_Matrix, *Source.Drawing3D_Matrix)
		Protected Buffer.Drawing3D_Matrix
		CopyMemory(*Use, @Buffer, SizeOf(Drawing3D_Matrix))
		With *Use
			\A11 = Buffer\A11 * *Source\A11 + Buffer\A12 * *Source\A21 + Buffer\A13 * *Source\A31
			\A12 = Buffer\A11 * *Source\A12 + Buffer\A12 * *Source\A22 + Buffer\A13 * *Source\A32
			\A13 = Buffer\A11 * *Source\A13 + Buffer\A12 * *Source\A23 + Buffer\A13 * *Source\A33
			\A21 = Buffer\A21 * *Source\A11 + Buffer\A22 * *Source\A21 + Buffer\A23 * *Source\A31
			\A22 = Buffer\A21 * *Source\A12 + Buffer\A22 * *Source\A22 + Buffer\A23 * *Source\A32
			\A23 = Buffer\A21 * *Source\A13 + Buffer\A22 * *Source\A23 + Buffer\A23 * *Source\A33
			\A31 = Buffer\A31 * *Source\A11 + Buffer\A32 * *Source\A21 + Buffer\A33 * *Source\A31
			\A32 = Buffer\A31 * *Source\A12 + Buffer\A32 * *Source\A22 + Buffer\A33 * *Source\A32
			\A33 = Buffer\A31 * *Source\A13 + Buffer\A32 * *Source\A23 + Buffer\A33 * *Source\A33
		EndWith
		ProcedureReturn *Use
	EndProcedure
	Procedure.i Drawing3D_Projection(*Use.Drawing3D_Vector, *Source.Drawing3D_Vector)
		If *Source\Z
			*Use\InvZ = 1 / *Source\Z
			*Use\X = - *Source\X * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterX
			*Use\Y =   *Source\Y * Drawing3DInclude\Distance * *Use\InvZ + Drawing3DInclude\CenterY
		EndIf
		ProcedureReturn *Use
	EndProcedure
	;- Private: Drawing
	Procedure Drawing3D_AddPixel(X.i, Y.i, Distance.f)
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel
		If Distance < 0
			*Pixel = AddElement(Drawing3DInclude\Pixel())
			*OldPixel = Drawing3DInclude\PixelIndex(X, Y)
			If *OldPixel
				If Distance > *OldPixel\Distance
					*Pixel\PreviousPixel = *OldPixel
					Drawing3DInclude\PixelIndex(X, Y) = *Pixel
				Else
					While *OldPixel\PreviousPixel And *OldPixel\PreviousPixel\Distance > Distance
						*OldPixel = *OldPixel\PreviousPixel
					Wend
					*Pixel\PreviousPixel = *OldPixel\PreviousPixel
					*OldPixel\PreviousPixel = *Pixel
				EndIf
			Else
				Drawing3DInclude\PixelIndex(X, Y) = *Pixel
			EndIf
			*Pixel\Distance = Distance
		EndIf
		ProcedureReturn *Pixel
	EndProcedure
	Procedure Drawing3D_DrawTriangle(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex, *Vertex2.Drawing3D_Vertex, Texture.i=0)
		Protected Triangle.Drawing3D_Triangle
		Protected LightFactor.f, N.i
		With Triangle
			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\Color = *Vertex0\Color
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\Color = *Vertex1\Color
			Drawing3D_Projection(\Vertex[2], *Vertex2) : \Vertex[2]\Color = *Vertex2\Color
			Protected X.i, Y.i
			Protected DX21.f = \Vertex[2]\X-\Vertex[1]\X, DY21.f = \Vertex[2]\Y-\Vertex[1]\Y
			Protected DX02.f = \Vertex[0]\X-\Vertex[2]\X, DY02.f = \Vertex[0]\Y-\Vertex[2]\Y
			Protected DX10.f = \Vertex[1]\X-\Vertex[0]\X, DY10.f = \Vertex[1]\Y-\Vertex[0]\Y
			Protected L1.f, L2.f, L3.f
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X, \Vertex[2]\X), Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y, \Vertex[2]\Y), Drawing3DInclude\MaxY)
			VectorSourceColor($80ff8080)
			VectorSourceColor($ff000000|\Vertex[0]\Color)
			MovePathCursor(\Vertex[0]\X,\Vertex[0]\Y)
			AddPathLine(\Vertex[1]\X,\Vertex[1]\Y)
			AddPathLine(\Vertex[2]\X,\Vertex[2]\Y)
			ClosePath()
			FillPath()
			If huch
				Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Color.Drawing3D_Color, Norm.Drawing3D_Vector, V1.Drawing3D_Vector, V2.Drawing3D_Vector
				Protected T.f = 1.0 / (-DY21*DX02 + DX21*DY02)
				Protected Distance.f, Brightness.f, Q1.f, Q2.f
				;If T< 0 : ProcedureReturn 0 : EndIf
				If Texture = 0
					For N = 0 To 2
						\Vertex[N]\Color\Red / \Vertex[N]\Color\Alpha
						\Vertex[N]\Color\Green / \Vertex[N]\Color\Alpha
						\Vertex[N]\Color\Blue / \Vertex[N]\Color\Alpha
						Drawing3D_Copy(V1, *Vertex1) : Drawing3D_Subtract(V1, *Vertex0)
						Drawing3D_Copy(V2, *Vertex2) : Drawing3D_Subtract(V2, *Vertex0)
						Drawing3D_Normalize(Drawing3D_Cross(Norm, V2, V1))
						ForEach Drawing3DInclude\Light()
							LightFactor = Drawing3D_Scalar(Norm, Drawing3DInclude\Light()\Direction)*Sign(T)
							If LightFactor > 0
								\Vertex[N]\Color\Red   + LightFactor*Drawing3DInclude\Light()\Color\Red
								\Vertex[N]\Color\Green + LightFactor*Drawing3DInclude\Light()\Color\Green
								\Vertex[N]\Color\Blue  + LightFactor*Drawing3DInclude\Light()\Color\Blue
							EndIf
						Next
						Drawing3D_NormalizeColor(\Vertex[N]\Color)
						Drawing3DInclude\CurrentColor[N] = \Vertex[N]\Color
					Next
				EndIf
				For Y = YA To YB
					Q1 = DX21*(Y-\Vertex[2]\Y)
					Q2 = DX02*(Y-\Vertex[2]\Y)
					*Pixel = #Null
					For X = XA To XB
						L1 = ( -DY21*(X-\Vertex[2]\X) + Q1 ) * T
						L2 = ( -DY02*(X-\Vertex[2]\X) + Q2 ) * T
						L3 = 1.0 - L1 - L2
						If L1 >= 0.0 And L2 >= 0.0 And L3 >= 0.0
							Distance = 1.0 / ( L1*\Vertex[0]\InvZ + L2*\Vertex[1]\InvZ + L3*\Vertex[2]\InvZ )
							*Pixel = Drawing3D_AddPixel(X, Y, Distance)
							If *Pixel
								If Drawing3DInclude\CurrentImage3D
									If Texture = 1
										Drawing3D_ImageColor(*Pixel\Color, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
									Else
										Drawing3D_ImageColor(*Pixel\Color, 1.0-L2*\Vertex[1]\InvZ*Distance, 1.0-L3*\Vertex[2]\InvZ*Distance)
									EndIf
								Else
									Drawing3D_ColorMix(*Pixel\Color, L1*\Vertex[0]\InvZ*Distance, L2*\Vertex[1]\InvZ*Distance, L3*\Vertex[2]\InvZ*Distance)
								EndIf
							EndIf
						ElseIf *Pixel
							Break
						EndIf
					Next
				Next
			EndIf
		EndWith
	EndProcedure
	Procedure Drawing3D_DrawLine(*Vertex0.Drawing3D_Vertex, *Vertex1.Drawing3D_Vertex)
		Protected Line.Drawing3D_Line, Distance.f
		Protected X.i, Y.i, Length.f, Position.f
		Protected Visible.f, Q.Drawing3D_Vector, R.Drawing3D_Vector, Cross.Drawing3D_Vector
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel
		With Line
			Drawing3D_Projection(\Vertex[0], *Vertex0) : \Vertex[0]\BorderColor = *Vertex0\BorderColor
			Drawing3D_Projection(\Vertex[1], *Vertex1) : \Vertex[1]\BorderColor = *Vertex1\BorderColor
			Protected XA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\X, \Vertex[1]\X)-1, 0)
			Protected XB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\X, \Vertex[1]\X)+1, Drawing3DInclude\MaxX)
			Protected YA.i = Drawing3D_Max(Drawing3D_Min(\Vertex[0]\Y, \Vertex[1]\Y)-1, 0)
			Protected YB.i = Drawing3D_Min(Drawing3D_Max(\Vertex[0]\Y, \Vertex[1]\Y)+2, Drawing3DInclude\MaxY)
			Drawing3D_Copy(R, \Vertex[1])
			Drawing3D_Subtract(R, \Vertex[0])
			Length = Drawing3D_Length(R)
			Drawing3DInclude\CurrentColor[0] = \Vertex[0]\BorderColor
			Drawing3DInclude\CurrentColor[1] = \Vertex[1]\BorderColor
			;DrawVectorLine(
			VectorSourceColor($ff000000|*Pixel\Color)
			;MovePathCursor(xa,ya)
			;AddPathLine(xb,yb)
			MovePathCursor(\Vertex[0]\X,\Vertex[0]\Y)
			AddPathLine(\Vertex[1]\X,\Vertex[1]\Y)
			StrokePath(1)
			If huch
				For Y = YA To YB
					*Pixel = #Null
					For X = XA To XB
						Drawing3D_Vector(Q, X, Y, 0)
						Drawing3D_Subtract(Q, \Vertex[0])
						Drawing3D_Cross(Cross, Q, R)
						Position = Drawing3D_Scalar(Q, R) / Length
						Visible = 1 - Drawing3D_Length(Cross) / Length
						If Position >= 0 And Position <= Length And Visible > 0
							Distance = 1.0 / ( (1-Position/Length)*\Vertex[0]\InvZ + (Position/Length)*\Vertex[1]\InvZ )
							*Pixel = Drawing3D_AddPixel(X, Y, Distance)
							If *Pixel
								;Drawing3D_ColorMix(*Pixel\Color, (1-Position/Length)*\Vertex[0]\InvZ*Distance*Visible, (Position/Length)*\Vertex[1]\InvZ*Distance*Visible, 0)
							EndIf
						EndIf
						If *Pixel And Visible < -1
							Break
						EndIf
					Next
				Next
			EndIf
		EndWith
	EndProcedure
	Procedure Drawing3D_DrawPoint(*Vertex.Drawing3D_Vertex)
		Protected Vertex.Drawing3D_Vertex, Distance.f
		Protected X.i, Y.i
		Protected Visible.f
		Protected *Pixel.Drawing3D_Pixel, *OldPixel.Drawing3D_Pixel, Nothing.Drawing3D_Color
		Drawing3D_Projection(Vertex, *Vertex) : Vertex\Color = *Vertex\Color
		Protected XA.i = Drawing3D_Max(Vertex\X-1, 0)
		Protected XB.i = Drawing3D_Min(Vertex\X+1, Drawing3DInclude\MaxX)
		Protected YA.i = Drawing3D_Max(Vertex\Y-1, 0)
		Protected YB.i = Drawing3D_Min(Vertex\Y+1, Drawing3DInclude\MaxY)
		Drawing3DInclude\CurrentColor[0] = Vertex\Color
		For Y = YA To YB
			For X = XA To XB
				Visible = 1 - Sqr((X-Vertex\X)*(X-Vertex\X)+(Y-Vertex\Y)*(Y-Vertex\Y))
				If Visible > 0
					Distance = 1.0 / Vertex\InvZ
					*Pixel = Drawing3D_AddPixel(X, Y, Distance)
					If *Pixel
						Drawing3D_ColorMix(*Pixel\Color, Visible, 0, 0)
					EndIf
				EndIf
			Next
		Next
	EndProcedure
	;- Cluster (unfertig)
	Procedure.i CreateCluster3D()
		Protected *Cluster.Drawing3D_Cluster = AddElement(Drawing3DInclude\Cluster())
		Drawing3DInclude\CurrentCluster = *Cluster
		ProcedureReturn *Cluster
	EndProcedure
	Procedure CloseCluster3D()
	EndProcedure
	Procedure DrawCluster3D(*Cluster.Drawing3D_Cluster, X.f, Y.f, Z.f, Pitch.f=0.0, Yaw.f=0.0, Roll.f=0.0)
	EndProcedure
	;- Image3D
	Procedure.i Image3DID(Image3D.i)
		If Image3D & ~$FFFF
			ProcedureReturn Image3D
		Else
			ProcedureReturn Drawing3DInclude\Image3DID(Image3D)
		EndIf
	EndProcedure
	Procedure.i FreeImage3D(Image3D.i)
		Protected *Image3D.Drawing3D_Image = Image3DID(Image3D)
		With *Image3D
			If Not \Number & ~$FFFF
				Drawing3DInclude\Image3DID(\Number) = #Null
			EndIf
			ChangeCurrentElement(Drawing3DInclude\Image3D(), *Image3D)
			DeleteElement(Drawing3DInclude\Image3D())
		EndWith
	EndProcedure
	Procedure CreateImage3D(Image3D.i, Image.i)
		Protected *Image3D.Drawing3D_Image
		Protected X.i, Y.i
		If Image3D = #PB_Any
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = *Image3D
		ElseIf Not Image3D & ~$FFFF
			*Image3D = AddElement(Drawing3DInclude\Image3D())
			*Image3D\Number = Image3D
			If ArraySize(Drawing3DInclude\Image3DID()) < Image3D
				ReDim Drawing3DInclude\Image3DID(Image3D)
			ElseIf Drawing3DInclude\Image3DID(Image3D)
				FreeImage3D(Drawing3DInclude\Image3DID(Image3D))
			EndIf
			Drawing3DInclude\Image3DID(Image3D) = *Image3D
		Else
			ProcedureReturn #Null
		EndIf
		With *Image3D
			\Width  = ImageWidth(Image)
			\Height = ImageHeight(Image)
			Dim \Pixel(\Width-1, \Height-1)
			If StartDrawing(ImageOutput(Image))
				DrawingMode(#PB_2DDrawing_AllChannels)
				Select ImageDepth(Image, #PB_Image_InternalDepth)
				Case 24
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y)|$FF000000)
						Next
					Next
				Case 32
					For Y = \Height-1 To 0 Step -1
						For X = \Width-1 To 0 Step -1
							Drawing3D_SetColor(\Pixel(X, Y), Point(X, Y))
						Next
					Next
				EndSelect
				StopDrawing()
			EndIf
		EndWith
	EndProcedure
	;- Drawing
	Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
		; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle
		With Drawing3DInclude
			If StartVectorDrawing(CanvasVectorOutput(Output))
				;DrawingMode(#PB_2DDrawing_AllChannels)
				\MaxX = VectorOutputWidth()-1
				\MaxY = VectorOutputHeight()-1
				\CenterX = VectorOutputWidth()/2
				\CenterY = VectorOutputHeight()/2
				\Distance = VectorOutputHeight()/Tan(Radian(FieldOfView)*0.5)
				Drawing3D_Vector(Drawing3DInclude\Position, 0, 0, \Distance)
				If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY
					Dim \PixelIndex(\MaxX, \MaxY)
				Else
					FillMemory(@\PixelIndex(0,0), SizeOf(Integer)*(\MaxX+1)*(\MaxY+1))
				EndIf
				ClearList(\Pixel())
				ClearList(\Light())
				ClearStructure(\MainCluster, Drawing3D_Cluster)
				ProcedureReturn #True
			EndIf
		EndWith
	EndProcedure
	Procedure StopDrawing3D()
		; Schließt eine Drawing3D-Umgebung und rendert die Szene
		Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
		Protected Color.Drawing3D_Color
		Protected X.i, Y.i
		If huch
			For Y = 0 To Drawing3DInclude\MaxY
				For X = 0 To Drawing3DInclude\MaxX
					*Pixel = Drawing3DInclude\PixelIndex(X, Y)
					If *Pixel
						While *Pixel\PreviousPixel
							Drawing3D_AlphaBlend(*Pixel\PreviousPixel\Color, *Pixel\Color)
							*Pixel = *Pixel\PreviousPixel
						Wend
						Color = Drawing3DInclude\Background
						Plot(X, Y, Drawing3D_GetColor(Drawing3D_AlphaBlend(Color, *Pixel)))
					EndIf
				Next
			Next
		EndIf
		StopVectorDrawing()
	EndProcedure
	Procedure Drawing3DMode(Mode.i)
		; Ändert den Zeichenmodus
		Drawing3DInclude\Mode = Mode
	EndProcedure
	Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Position der Szene
		Protected Vector.Drawing3D_Vector
		If Mode = #PB_Relative
			Drawing3D_Vector(Vector, -X, -Y, -Z)
			Drawing3D_Add(Drawing3DInclude\Position, Vector)
		Else
			Drawing3D_Vector(Drawing3DInclude\Position, -X, -Y, -Z)
		EndIf
	EndProcedure
	Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
		; Definiert oder ändert die Orientierung der Szene
		Protected Rotation.Drawing3D_Matrix
		If Mode = #PB_Relative
			Drawing3DInclude\RotX+RotationX
			Drawing3DInclude\RotY+RotationY
			Drawing3DInclude\RotZ+RotationZ
			Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
			Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
			Drawing3DInclude\Orientation = Rotation
		Else
			Drawing3DInclude\RotX=RotationX
			Drawing3DInclude\RotY=RotationY
			Drawing3DInclude\RotZ=RotationZ
			Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		EndIf
	EndProcedure
	Procedure Drawing3DBackground(Color.l=$FF000000)
		; Setzt den Szenenhintergrund
		VectorSourceColor(Color)
		FillVectorOutput()
		Drawing3D_SetColor(Drawing3DInclude\Background, Color)
	EndProcedure
	Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
		; Setzt ein Licht in die Szene
		Protected *Light.Drawing3D_Light = AddElement(Drawing3DInclude\Light())
		With *Light
			Drawing3D_Vector(\Direction, DirectionX, DirectionY, DirectionZ)
			Drawing3D_Normalize(\Direction)
			Drawing3D_SetColor(\Color, Color)
		EndWith
		ProcedureReturn *Light
	EndProcedure
	Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.q)
		; Zeichnet einen Punkt in die Szene
		Protected Vertex.Drawing3D_Vertex
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_SetColor(Vertex\Color, Color)
		Drawing3D_Rotate(Vertex, Drawing3DInclude\Orientation)
		Drawing3D_Subtract(Vertex, Drawing3DInclude\Position)
		Drawing3D_DrawPoint(Vertex)
	EndProcedure
	Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
		; Zeichnet eine Linie in die Szene
		Protected Line.Drawing3D_Line
		Protected N.i
		Drawing3D_Vector(Line\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Line\Vertex[1], X2, Y2, Z2)
		Drawing3D_SetColor(Line\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Line\Vertex[1]\Color, Color2)
		EndIf
		For N = 0 To 1
			Drawing3D_Rotate(Line\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Line\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawLine(Line\Vertex[0], Line\Vertex[1])
	EndProcedure
	Procedure DrawTriangle3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor)
		; Zeichnet ein Dreieck in die Szene
		Protected Triangle.Drawing3D_Triangle
		Protected N.i
		Drawing3D_Vector(Triangle\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Triangle\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Triangle\Vertex[2], X3, Y3, Z3)
		Drawing3D_SetColor(Triangle\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Triangle\Vertex[2]\Color, Color3)
		EndIf
		For N = 0 To 2
			Drawing3D_Rotate(Triangle\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Triangle\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Triangle\Vertex[0], Triangle\Vertex[1])
			Drawing3D_DrawLine(Triangle\Vertex[1], Triangle\Vertex[2])
			Drawing3D_DrawLine(Triangle\Vertex[2], Triangle\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Triangle\Vertex[0], Triangle\Vertex[1], Triangle\Vertex[2])
		EndIf
	EndProcedure
	Procedure DrawPlane3D(X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f, RotationY.f, RotationZ.f, Color1.q, Color2.q=#Drawing3D_NoColor, Color3.q=#Drawing3D_NoColor, Color4.q=#Drawing3D_NoColor)
		; Zeichnet eine Ebene in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_SetColor(Plane\Vertex[0]\Color, Color1)
		If Color2 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[1]\Color, Color2)
		EndIf
		If Color3 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[2]\Color, Color3)
		EndIf
		If Color4 = #Drawing3D_NoColor
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color1)
		Else
			Drawing3D_SetColor(Plane\Vertex[3]\Color, Color4)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Plane\Vertex[0], Plane\Vertex[1])
			Drawing3D_DrawLine(Plane\Vertex[1], Plane\Vertex[3])
			Drawing3D_DrawLine(Plane\Vertex[3], Plane\Vertex[2])
			Drawing3D_DrawLine(Plane\Vertex[2], Plane\Vertex[0])
		Else
			Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2])
			Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1])
		EndIf
	EndProcedure
	Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)
		; Zeichnet einen Quader in die Szene
		Protected Box.Drawing3D_Box
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3D_Vector(Vertex, X, Y, Z)
		If Mode=#Drawing3D_Absolute
			Drawing3D_Vector(Box\Vertex[0],	0,	Height,	Depth)
			Drawing3D_Vector(Box\Vertex[1],	Width,Height,	Depth)
			Drawing3D_Vector(Box\Vertex[2], 0, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[3],  Width, 0,  Depth)
			Drawing3D_Vector(Box\Vertex[4], 0,  Height, 0)
			Drawing3D_Vector(Box\Vertex[5],  Width,  Height, 0)
			Drawing3D_Vector(Box\Vertex[6], 0, 0, 0)
			Drawing3D_Vector(Box\Vertex[7],  Width, 0, 0)
		Else
			Drawing3D_Vector(Box\Vertex[0], -Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[1],  Width*0.5,  Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[2], -Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[3],  Width*0.5, -Height*0.5,  Depth*0.5)
			Drawing3D_Vector(Box\Vertex[4], -Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[5],  Width*0.5,  Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[6], -Width*0.5, -Height*0.5, -Depth*0.5)
			Drawing3D_Vector(Box\Vertex[7],  Width*0.5, -Height*0.5, -Depth*0.5)
		EndIf
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 7
			Drawing3D_SetColor(Box\Vertex[N]\Color, Color)
			Drawing3D_SetColor(Box\Vertex[N]\BorderColor, BorderColor)
			Drawing3D_Rotate(Box\Vertex[N], Orientation)
			Drawing3D_Add(Box\Vertex[N], Vertex)
			Drawing3D_Rotate(Box\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Box\Vertex[N], Drawing3DInclude\Position)
		Next
		If Drawing3DInclude\Mode & #Drawing3D_Outline
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[1])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[6], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[2])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[3])
			Drawing3D_DrawLine(Box\Vertex[4], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[5], Box\Vertex[7])
			Drawing3D_DrawLine(Box\Vertex[0], Box\Vertex[4])
			Drawing3D_DrawLine(Box\Vertex[1], Box\Vertex[5])
			Drawing3D_DrawLine(Box\Vertex[2], Box\Vertex[6])
			Drawing3D_DrawLine(Box\Vertex[3], Box\Vertex[7])
		EndIf
		If Drawing3DInclude\Mode & #Drawing3D_Filled
			Drawing3D_DrawTriangle(Box\Vertex[0], Box\Vertex[1], Box\Vertex[2])
			Drawing3D_DrawTriangle(Box\Vertex[3], Box\Vertex[2], Box\Vertex[1])
			Drawing3D_DrawTriangle(Box\Vertex[5], Box\Vertex[4], Box\Vertex[7])
			Drawing3D_DrawTriangle(Box\Vertex[6], Box\Vertex[7], Box\Vertex[4])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[5], Box\Vertex[3])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[3], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[0], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[6], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[4], Box\Vertex[5], Box\Vertex[0])
			Drawing3D_DrawTriangle(Box\Vertex[1], Box\Vertex[0], Box\Vertex[5])
			Drawing3D_DrawTriangle(Box\Vertex[2], Box\Vertex[3], Box\Vertex[6])
			Drawing3D_DrawTriangle(Box\Vertex[7], Box\Vertex[6], Box\Vertex[3])
		EndIf
	EndProcedure
	Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
		; Zeichnet ein Bild (Image3D) in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)
		Drawing3D_Vector(Vertex, X, Y, Z)
		Drawing3D_Vector(Plane\Vertex[0], -Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[1],  Width*0.5,  Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[2], -Width*0.5, -Height*0.5, 0)
		Drawing3D_Vector(Plane\Vertex[3],  Width*0.5, -Height*0.5, 0)
		Drawing3D_Orientation(Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Orientation)
			Drawing3D_Add(Plane\Vertex[N], Vertex)
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)
		Drawing3DInclude\CurrentImage3D = #Null
	EndProcedure
	Procedure DrawTranformedImage3D(Image3D.i, X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, X3.f, Y3.f, Z3.f, X4.f, Y4.f, Z4.f)
		; Zeichnet ein verzerrtes Bild (Image3D) in die Szene
		Protected Plane.Drawing3D_Plane
		Protected Orientation.Drawing3D_Matrix, Vertex.Drawing3D_Vector
		Protected N.i
		Drawing3DInclude\CurrentImage3D = Image3DID(Image3D)
		Drawing3D_Vector(Plane\Vertex[0], X1, Y1, Z1)
		Drawing3D_Vector(Plane\Vertex[1], X2, Y2, Z2)
		Drawing3D_Vector(Plane\Vertex[2], X3, Y3, Z3)
		Drawing3D_Vector(Plane\Vertex[3], X4, Y4, Z4)
		For N = 0 To 3
			Drawing3D_Rotate(Plane\Vertex[N], Drawing3DInclude\Orientation)
			Drawing3D_Subtract(Plane\Vertex[N], Drawing3DInclude\Position)
		Next
		Drawing3D_DrawTriangle(Plane\Vertex[0], Plane\Vertex[1], Plane\Vertex[2], 1)
		Drawing3D_DrawTriangle(Plane\Vertex[3], Plane\Vertex[2], Plane\Vertex[1], -1)
		Drawing3DInclude\CurrentImage3D = #Null
	EndProcedure
	Procedure DrawBoxWithBorder3D(X.f,Y.f,Z.f, Width.f,Height.f,Depth.f, RotationX.f,RotationY.f,RotationZ.f, SurfaceColor.q, BorderColor.q=$FF000000, Mode.i=#Drawing3D_Centered)
		Drawing3DMode(#Drawing3D_Default | #Drawing3D_Outline)
		DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, SurfaceColor, BorderColor, Mode)
		;Drawing3DMode(#Drawing3D_Outline)
		;DrawBox3D(X.f,Y.f,Z.f, Width,Height,Depth, RotationX,RotationY,RotationZ, BorderColor, Mode)
	EndProcedure
	Drawing3D_Orientation(Drawing3DInclude\Orientation, 0, 0, 0)
; EndDefine
; Define Demonstration
	#WX=1040
	#WY=800
	#WZ=300
	#WW=#WX+20
	CompilerIf #PB_Compiler_IsMainFile
		Enumeration
			#Window
			#Canvas
			#ListViewGadget
			#RotateZero
			#RotateX
			#RotateY
			#RotateZ
			#Image
			#Image3D
			#ButtonGadget
			#RealImage
		EndEnumeration
		Procedure UpdateRotationGadgets()
			With Drawing3DInclude
				SetGadgetState(#RotateX,\RotX)
				SetGadgetState(#RotateY,\RotY)
				SetGadgetState(#RotateZ,\RotZ)
			EndWith
		EndProcedure
		Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)
			t1=ElapsedMilliseconds()
			Static MouseX.i, MouseY.i
			; **********************************
			Protected Distance.f = 500
			; **********************************
			Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f
			Protected Dim Y.f(40, 40)
			Protected Dim Color.l(40, 40)
			Protected Time1.q, Time2.q, Frequency.q
			Protected rx.f,ry.f,rz.f
			QueryPerformanceFrequency_(@Frequency)
			QueryPerformanceCounter_(@Time1)
			If Image
				StartDrawing3D(ImageOutput(Image))
				Drawing3DBackground($00FFFFFF)
			Else
				StartDrawing3D(Gadget)
				Drawing3DBackground($FFFFFFFF)
				Debug "clear"
				Distance * Pow(1.1, GetGadgetAttribute(Gadget, #PB_Canvas_WheelDelta))
				If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton
					rx=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15
					ry=(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15
					Drawing3DRotation(Radian(rx),Radian(ry),0, #PB_Relative)
					UpdateRotationGadgets()
				EndIf
				MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
				MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
			EndIf
			; **********************************
			Drawing3DPosition(-100, -100, -Distance)
			; **********************************
			Select GetGadgetState(#ListViewGadget)
			Case 0
				DrawPlane3D(0, 0, 0, 340, 200,  0,  0,  0, $80FF0000)
				DrawPlane3D(0, 0, 0, 340, 200, 90, 90,  0, $800000FF)
				DrawPlane3D(0, 0, 0, 340, 200, 90,  0, 90, $8000FF00)
			Case 1
				Drawing3DMode(#Drawing3D_Outline)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
				Drawing3DMode(#Drawing3D_Default)
			Case 2
				Drawing3DLight(1, 0, 0, $FFFFFF00)
				Drawing3DLight(-1, 0, 0, $FF00FFFF)
				DrawBox3D(0, 0, 0, 200, 200, 200, 0, 0, 0, $FF000000)
			Case 3
				Drawing3DLight(0.5, 1, 1, $FFFFFFFF)
				DrawBox3D(0, 0, 0, 100, 200, 300, 0, 0, 0, $C000C060)
				DrawBox3D(0, 0, 0, 100, 200, 300, 30, 45, 15, $C08000C0)
			Case 4
				Drawing3DLight(0.5, 1, -1, $FFFFFFFF)
				DrawTriangle3D(-100, 100, 100, 100, 100, -100, 100, -100, 100, $FF00C000, $FFC00000, $FF0000C0)
				DrawTriangle3D(-100, 100, 100, 100, -100, 100, -100, -100, -100, $FF00C000, $FF0000C0, $FF00C0C0)
				DrawTriangle3D(-100, 100, 100, -100, -100, -100, 100, 100, -100, $FF00C000, $FF00C0C0, $FFC00000)
				DrawTriangle3D(100, -100, 100, 100, 100, -100, -100, -100, -100, $FF0000C0, $FFC00000, $FF00C0C0)
				DrawLine3D(90, -90, -90, -90, -90, 90, $FF00C000, $FFC00000)
				DrawLine3D(-90, -90, 90, -90, 90, -90, $FFC00000, $FF0000C0)
				DrawLine3D(-90, 90, -90, 90, -90, -90, $FF0000C0, $FF00C000)
				DrawLine3D(90, -90, -90, 90, 90, 90, $FF00C000, $FF00C0C0)
				DrawLine3D(-90, -90, 90, 90, 90, 90, $FFC00000, $FF00C0C0)
				DrawLine3D(-90, 90, -90, 90, 90, 90, $FF0000C0, $FF00C0C0)
			Case 5
				DrawImage3D(#Image3D, 0, 0, 0, 400, 400, 0, 0, 0)
			Case 6
				RandomSeed(1)
				For Y = -100 To 100
					For X = -100 To 100
						Z = Random(100)-50
						DrawPoint3D(X, Y, Z, $FF000000)
					Next
				Next
			Case 7
				Drawing3DLight(0.5, 1, 1, $40FFFFFF)
				DrawBox3D(0, 0, 0, 100, 30, 30, 0, 0, 0, $FF404040)
				DrawBox3D(-75, 0, 0, 50, 30, 30, 0, 0, 0, $FF808000)
				DrawBox3D(75, 0, 0, 50, 30, 30, 0, 0, 0, $FF000080)
				RandomSeed(5)
				For N = 1 To 50
					Phi = Random(359)
					R = Random(100)+30
					For W = 0 To 359 Step 5
						R1 = (1-Cos(Radian(W)))*R
						R2 = (1-Cos(Radian(W+5)))*R
						DrawLine3D(-Sin(Radian(W))*R*2, R1*Sin(Radian(Phi)), R1*Cos(Radian(Phi)), -Sin(Radian(W+5))*R*2, R2*Sin(Radian(Phi)), R2*Cos(Radian(Phi)), RGBA(255*W/360, 255*(360-W)/360, 255*(360-W)/360, 192))
					Next
				Next
			Case 8
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				For Z = -20 To 20
					For X = -20 To 20
						Y(X+20,Z+20) = Exp(-X*X/100-Z*Z/100)*(X+Z/4)/5
						If Y(X+20,Z+20) < 0
							Color(X+20,Z+20) = RGBA(0, 128+128*Y(X+20,Z+20), -255*Y(X+20,Z+20), 255)
						Else
							Color(X+20,Z+20) = RGBA(255*Y(X+20,Z+20), 128+128*Y(X+20,Z+20), 0, 255)
						EndIf
						Y(X+20,Z+20) * 200
					Next
				Next
				For Z = -20 To 19
					For X = -20 To 19
						DrawTriangle3D(X*10, Y(X+20,Z+20), Z*10, (X+1)*10, Y(X+21,Z+20), Z*10, X*10, Y(X+20,Z+21), (Z+1)*10, Color(X+20,Z+20), Color(X+21,Z+20), Color(X+20,Z+21))
						DrawTriangle3D((X+1)*10, Y(X+21,Z+21), (Z+1)*10, X*10, Y(X+20,Z+21), (Z+1)*10, (X+1)*10, Y(X+21,Z+20), Z*10, Color(X+21,Z+21), Color(X+20,Z+21), Color(X+21,Z+20))
					Next
				Next
			Case 9
				t2=ElapsedMilliseconds()
				Drawing3DLight(0.5, 1, 1, $20FFFFFF)
				Drawing3DMode(#Drawing3D_Default)
				Drawing3DBackground($FFE0E0E0)
				Drawing3DLight(1, 1, 1, $40FFFFFF)
				; unten
				DrawBoxWithBorder3D(0,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,0,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,0,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; mittig
				DrawBoxWithBorder3D(0,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,51,0, 62,25,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,51,0, 62,25,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				t3=ElapsedMilliseconds()
				; links/rechts
				DrawBoxWithBorder3D(0,77,0, 62,130,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,77,0, 62,130,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; oben
				DrawBoxWithBorder3D(0,208,0, 62,50,60, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(63,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(126,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(189,208,0, 62,50,40, 0,0,0, $FFFFFFFF,$80000000,#Drawing3D_Absolute)
				; Platten
				DrawBoxWithBorder3D(62,77,0, 1,181,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,207,0, 125,1,42, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(62,76,0, 125,1,60, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,0,40, 1,76,20, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				DrawBoxWithBorder3D(188,76,0, 1,131,40, 0,0,0, $FF5090B0,$80000000,#Drawing3D_Absolute)
				; Achsen
				DrawLine3D(0,0,0, 100,0,0, $FF000000)
				DrawLine3D(0,0,0, 0,100,0, $FF000000)
				DrawLine3D(0,0,0, 0,0,100, $FF000000)
				t4=ElapsedMilliseconds()
			EndSelect
			StopDrawing3D()
			QueryPerformanceCounter_(@Time2)
			;SetWindowTitle(#Window, StrF((Time2-Time1)/Frequency*1000,3))
		EndProcedure
		UsePNGImageDecoder()
		UsePNGImageEncoder()
		CatchImage(#Image, ?Image)
		CreateImage3D(#Image3D, #Image)
		OpenWindow(#Window, 0, 0, #WX+#WZ+30, #WY+20, "", #PB_Window_MinimizeGadget|#PB_Window_ScreenCentered)
		CanvasGadget(#Canvas, 10, 10, #WX, #WY, #PB_Canvas_Border|#PB_Canvas_Keyboard)
		FrameGadget(#PB_Any, #WW, 10, #WZ, 190, "Szenenauswahl")
		ListViewGadget(#ListViewGadget, #WW+10, 30, #WZ-20, 160)
		AddGadgetItem(#ListViewGadget, -1, "Drei sich durchdringende Flächen")
		AddGadgetItem(#ListViewGadget, -1, "Würfel aus Linien")
		AddGadgetItem(#ListViewGadget, -1, "Belichteter Würfel")
		AddGadgetItem(#ListViewGadget, -1, "Zwei durchdringende Quader")
		AddGadgetItem(#ListViewGadget, -1, "Tetraeder mit verschiedenen Eckfarben")
		AddGadgetItem(#ListViewGadget, -1, "Texturfläche")
		AddGadgetItem(#ListViewGadget, -1, "Punkte")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: Magnet & Feldlinien")
		AddGadgetItem(#ListViewGadget, -1, "Anwendungsbeispiel: 3D-Funktion")
		AddGadgetItem(#ListViewGadget, -1, "Spielwiese")
		SetGadgetState(#ListViewGadget, 9)
		ButtonGadget(#RotateZero,#WW,250,100,30,"Reset")
		TrackBarGadget(#RotateX, #WW, 300, #WZ,20,0,360)
		TrackBarGadget(#RotateY, #WW, 330, #WZ,20,0,360)
		TrackBarGadget(#RotateZ, #WW, 360, #WZ,20,0,360)
		ButtonGadget(#ButtonGadget,#WW, 580, 120, 30, "Save Image...")
		TextGadget(#PB_Any, #WW, 210, 290, 40, "drag object to rotate the scene, mouse wheel zooms")
		; **********************************
		Drawing3DRotation(10,330,0)
		; **********************************
		UpdateRotationGadgets()
		UpdateCanvasGadget(#Canvas)
		;MessageRequester("Timer",Str(t2-t1)+#CRLF$+Str(t3-t2)+#CRLF$+Str(t4-t3)+#CRLF$+Str(t4-t1))
		Define FileName.s
		Repeat
			Select WaitWindowEvent()
			Case #PB_Event_CloseWindow
				End
			Case #PB_Event_Gadget
				Define e.i
				e=EventGadget()
				Select e
				Case #Canvas, #ListViewGadget
					UpdateCanvasGadget(#Canvas)
				Case #RotateZero
					Drawing3DRotation(0,0,0, #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					UpdateRotationGadgets()
				Case #RotateX To #RotateZ
					Drawing3DRotation(GetGadgetState(#RotateX),GetGadgetState(#RotateY),GetGadgetState(#RotateZ), #PB_Absolute)
					UpdateCanvasGadget(#Canvas)
					;UpdateRotationGadgets()
				Case #ButtonGadget
					CreateImage(#RealImage, 600, 600, 32|#PB_Image_Transparent)
					UpdateCanvasGadget(#Canvas, #RealImage)
					FileName = SaveFileRequester("Save", "", "*.png|*.PNG", 1)
					If FileName
						SaveImage(#RealImage, FileName, #PB_ImagePlugin_PNG)
					EndIf
				EndSelect
			EndSelect
		ForEver
		DataSection
			Image:
			IncludeBinary "Image.png"
		EndDataSection
	CompilerEndIf
; EndDefine