Page 1 of 1

PB->SB conversion

Posted: Wed Sep 30, 2026 4:56 pm
by erlend
Trying to convert Stargåte\s Drawing3D to Spiderbasic, for fun actually, but it has become a real problem :-(
It does run (at least this modified code should run on PB and SB), meaning rotating with mousedown and movement
rotates it and wheel zoom works, but color on drawn objects is allways black.

I do believe it has to do with som reference pointer stuff on the color side of it, but I can\t find it.

Code: Select all

EnableExplicit

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

Structure Drawing3D_Vector
	X.f
	Y.f
	Z.f
	InvZ.f
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_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
	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
;  	If IsNaN(*Use\Red)
;  	  Debug "hmm"
;  	EndIf  
	*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 IsNaN(*Source\Red)
;  	  Debug "hmm"
;  	EndIf
	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.i Drawing3D_AlphaBlend(*Use.Drawing3D_Color, *Source.Drawing3D_Color)
	Protected InvAlpha.f = 1.0 - *Source\Alpha
; 	If IsNaN(*Use\Red)
; 	  Debug "hmm"
;   EndIf
	*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 
	Buffer\X = *Use\X
	Buffer\Y = *Use\Y
	Buffer\Z = *Use\Z
	Buffer\InvZ = *Use\InvZ
	*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
	Buffer\A11 = *Use\A11
	Buffer\A12 = *Use\A12
	Buffer\A13 = *Use\A13
	Buffer\A21 = *Use\A21
	Buffer\A22 = *Use\A22
	Buffer\A23 = *Use\A23
	Buffer\A31 = *Use\A31
	Buffer\A32 = *Use\A32
	Buffer\A33 = *Use\A33 
	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

; Öffnet eine Drawing3D-Umgebung für die Drawing3D-Befehle
Procedure StartDrawing3D(Output.i, FieldOfView.f=75)
  Protected x.i, y.i
  
	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)
			
			;Removed the memory stuff as it is not present in Spiderbasic
			If ArraySize(\PixelIndex(), 1) <> \MaxX Or ArraySize(\PixelIndex(), 2) <> \MaxY 
				Dim \PixelIndex(\MaxX, \MaxY)
			Else
			  FreeArray(\PixelIndex())
			  Dim \PixelIndex(\MaxX, \MaxY)		  
			EndIf
			
			ClearList(\Pixel())
			ClearList(\Light())
			ClearStructure(\MainCluster, Drawing3D_Cluster)
			
			ProcedureReturn #True
			
		EndIf
		
	EndWith
	
EndProcedure

; Schließt eine Drawing3D-Umgebung und rendert die Szene
Procedure StopDrawing3D()
	
	Protected *Pixel.Drawing3D_Pixel, *PreviousPixel.Drawing3D_Pixel
	Protected *Color.Drawing3D_Color
	Protected *Use.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
				*Use = Drawing3D_AlphaBlend(*Color, *Pixel)
				Plot(X, Y, Drawing3D_GetColor(*Use))
			EndIf
		Next
	Next
	
	StopDrawing()
	
EndProcedure

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

; Definiert oder ändert die Position der Szene
Procedure Drawing3DPosition(X.f, Y.f, Z.f, Mode.i=#PB_Absolute)
	
	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

; Definiert oder ändert die Orientierung der Szene
Procedure Drawing3DRotation(RotationX.f, RotationY.f, RotationZ.f, Mode.i=#PB_Absolute)
	
	Protected Rotation.Drawing3D_Matrix
	
	If Mode = #PB_Relative
		Drawing3D_Orientation(Rotation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
		Drawing3D_Multiply(Rotation, Drawing3DInclude\Orientation)
		Drawing3DInclude\Orientation = Rotation
	Else
		Drawing3D_Orientation(Drawing3DInclude\Orientation, Radian(RotationX), Radian(RotationY), Radian(RotationZ))
	EndIf
	
EndProcedure

; Setzt den Szenenhintergrund
Procedure Drawing3DBackground(Color.l=$FF000000)
	
	Box(0, 0, OutputWidth(), OutputHeight(), Color)
	Drawing3D_SetColor(Drawing3DInclude\Background, Color)
	
EndProcedure

; Setzt ein Licht in die Szene
Procedure Drawing3DLight(DirectionX.f, DirectionY.f, DirectionZ.f, Color.l)
	
	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

; Zeichnet einen Punkt in die Szene
Procedure DrawPoint3D(X.f, Y.f, Z.f, Color.l)
	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

; Zeichnet eine Linie in die Szene
Procedure DrawLine3D(X1.f, Y1.f, Z1.f, X2.f, Y2.f, Z2.f, Color1.q, Color2.q=#Drawing3D_NoColor)
	Protected *Line.Drawing3D_Line, 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

; Zeichnet ein Dreieck in die Szene
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)
	
	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

; Zeichnet eine Ebene in die Szene
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)
	
	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

; Zeichnet einen Quader in die Szene
Procedure DrawBox3D(X.f, Y.f, Z.f, Width.f, Height.f, Depth.f, RotationX.f, RotationY.f, RotationZ.f, Color.q)
	
	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

; Zeichnet ein Bild (Image3D) in die Szene
Procedure DrawImage3D(Image3D.i, X.f, Y.f, Z.f, Width.f, Height.f, RotationX.f=0, RotationY.f=0, RotationZ.f=0)
	
	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

; Zeichnet ein verzerrtes Bild (Image3D) in die Szene
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)
	
	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

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

Enumeration
	#Window
	#Gadget
	#ListViewGadget
	#Image
	#Image3D
	#ButtonGadget
	#RealImage
EndEnumeration

Global Distance.f = 700

Procedure UpdateCanvasGadget(Gadget, Image.i=#Null)
	;Shared Distance
	Static MouseX.i, MouseY.i
	Protected X.i, Y.i, Z.i, N, W.i, R.i, Phi.i, R1.f, R2.f, Dim Y.f(40, 40), Dim Color.l(40, 40)
	Protected Time1.q, Time2.q, Frequency.q
	Protected mode.i
	mode = 3
	If Image
		StartDrawing3D(ImageOutput(Image))
		Drawing3DBackground($00FFFFFF)
	Else
	  If IsGadget(Gadget)
	  StartDrawing3D(CanvasOutput(Gadget))
		Drawing3DBackground($FFFFFFFF)
		If GetGadgetAttribute(Gadget, #PB_Canvas_Buttons) & #PB_Canvas_LeftButton  
			Drawing3DRotation(Radian(GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)-MouseY)*15, Radian(GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)-MouseX)*15, 0, #PB_Relative)
		EndIf
		MouseY = GetGadgetAttribute(Gadget, #PB_Canvas_MouseY)
		MouseX = GetGadgetAttribute(Gadget, #PB_Canvas_MouseX)
		EndIf
	EndIf
	
	Drawing3DPosition(0, 0, -Distance)
	
	Select mode
			
		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, $FF00FFFF)
				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
			
	EndSelect
	StopDrawing3D()
EndProcedure

Define i.i 
CreateImage(#Image, 100,100,24)
StartDrawing(ImageOutput(#Image))
For i=0 To 100
  Box(Random(100),Random(100),Random(20),Random(20),RGBA(Random(255),Random(255),Random(255),255))  
Next
StopDrawing()
CreateImage3D(#Image3D, #Image)

Procedure GadgetEventRecieved()
  UpdateCanvasGadget(#Gadget)
EndProcedure
Procedure ResizeWindowEvent()
  ResizeGadget(#Gadget, 0,0, WindowWidth(#Window), WindowHeight(#Window))  
EndProcedure
Procedure CloseWindowEvent()
  Debug "Closing window: " + EventWindow()
  CloseWindow(EventWindow()) ; Close the specific window
EndProcedure
Procedure Zoom()
  Shared Distance  
  Distance * Pow(1.1, GetGadgetAttribute(EventGadget(), #PB_Canvas_WheelDelta))
	;Debug Distance
EndProcedure

OpenWindow(#Window, 0, 0, 600, 600, "", #PB_Window_ScreenCentered|#PB_Window_SizeGadget)
CanvasGadget(#Gadget, 0, 0, 600, 600, #PB_Canvas_Border|#PB_Canvas_Keyboard)
Drawing3DRotation(30, 30, 0)
BindEvent(#PB_Event_SizeWindow, @ResizeWindowEvent())
BindGadgetEvent(#Gadget,@GadgetEventRecieved())
BindEvent(#PB_Event_CloseWindow, @CloseWindowEvent())
BindGadgetEvent(#Gadget,@Zoom(),#PB_EventType_MouseWheel)

CompilerIf #PB_Compiler_OS<>#PB_OS_Web  
Repeat
  ev=WaitWindowEvent()
Until ev=#PB_Event_CloseWindow
CompilerEndIf
BR
Erlend