| Today in Physics I was challanged to write a software renderer on my graphics calculator, and this is a (more sophisticated) version of the result. Because the calculator didn't have shades of colours pretty much the only thing you could do on the thing is draw vectors. 
 The calculator takes 5 seconds to render each frame of a cube rotating.
 
 The code is really unfinished, and since I have had no experience of writing any kind of 3D engine I just made everything up as I went along. Use left and right keys to move the object. It's pitch and yaw is modified every frame aleardy.
 
 
 
 
Graphics 1024, 768, 32, 1
SetBuffer BackBuffer( )
Global CameraX#, CameraY#, CameraZ# = -5
Global FOV# = 30.0
Global Graphics_Width = GraphicsWidth( ), Graphics_Height = GraphicsHeight( )
Global Null_Vector.Vector = New Vector
entity.Entity = CreateCube( )
entity2.Entity = CreateObject( )
While Not KeyHit( 1 )
	Render( entity )
	Render( entity2 )
	
	entity\rotation\x# = entity\rotation\x# + 5
	entity2\rotation\x# = entity2\rotation\x# - 1 
	entity\rotation\y# = entity\rotation\y# + 2.5
	entity2\rotation\y# = entity2\rotation\y# - 2.5
	VWait( )
	Flip
	Cls
	
Wend
Type Entity
	Field Position.Vector
	Field Rotation.Vector
	
	Field Vertex_Count
	Field Link_Count
	Field Vertices
	Field Link1, Link2
	
End Type
Type Vertex
	Field Vector.Vector
	Field TempPosition.Vector
	
	Field ProjectedCoords.Vector
	
End Type
Type Vector
	
	Field X#, Y#, Z#
	
End Type
Type Vertex_Stack
	
	Field Vector.Vector
	
End Type
Type Vertex_Link
	
	Field Vertex0, Vertex1
	
End Type
Function CreateObject.Entity( )
	Add_To_Vertex_Stack( -1,  1, -1 )
	Add_To_Vertex_Stack(  1,  1, -1 )
	Add_To_Vertex_Stack( -1,  1,  1 )
	Add_To_Vertex_Stack(  1,  1,  1 )
	
	Add_To_Vertex_Stack( -0.8, -1, -0.8 )
	Add_To_Vertex_Stack(  0.8, -1, -0.8 )
	Add_To_Vertex_Stack( -0.8, -1,  0.8 )
	Add_To_Vertex_Stack(  0.8, -1,  0.8 )
	
	Add_To_Vertex_Stack(  0,  2,  0 )
	
	Vertex_Link( 1, 2 )
	Vertex_Link( 1, 3 )
	Vertex_Link( 3, 4 )
	Vertex_Link( 2, 4 )
	
	Vertex_Link( 5, 6 )
	Vertex_Link( 5, 7 )
	Vertex_Link( 7, 8 )
	Vertex_Link( 6, 8 )
	
	Vertex_Link( 1, 5 )
	Vertex_Link( 2, 6 )
	Vertex_Link( 3, 7 )
	Vertex_Link( 4, 8 )
	
	Vertex_Link( 1, 9 )
	Vertex_Link( 2, 9 )
	Vertex_Link( 3, 9 )
	Vertex_Link( 4, 9 )
	
	
	Return Build_Mesh( )
	
End Function
Function CreateCube.Entity( )
	Add_To_Vertex_Stack( -1,  1, -1 )
	Add_To_Vertex_Stack(  1,  1, -1 )
	Add_To_Vertex_Stack( -1,  1,  1 )
	Add_To_Vertex_Stack(  1,  1,  1 )
	
	Add_To_Vertex_Stack( -1, -1, -1 )
	Add_To_Vertex_Stack(  1, -1, -1 )
	Add_To_Vertex_Stack( -1, -1,  1 )
	Add_To_Vertex_Stack(  1, -1,  1 )
		
	Vertex_Link( 1, 2 )
	Vertex_Link( 1, 3 )
	Vertex_Link( 3, 4 )
	Vertex_Link( 2, 4 )
	
	Vertex_Link( 5, 6 )
	Vertex_Link( 5, 7 )
	Vertex_Link( 7, 8 )
	Vertex_Link( 6, 8 )
	
	Vertex_Link( 1, 5 )
	Vertex_Link( 2, 6 )
	Vertex_Link( 3, 7 )
	Vertex_Link( 4, 8 )	
	
	Return Build_Mesh( )
	
End Function
Function Add_To_Vertex_Stack( X#, Y#, Z# )
	
	Local vs.Vertex_Stack = New Vertex_Stack
	
	vs\Vector = New Vector
	
	vs\Vector\X# = X#
	vs\Vector\Y# = Y#
	vs\Vector\Z# = Z#
	
End Function
	
Function Vertex_Link( v0, v1 )
	Local link.Vertex_Link = New Vertex_Link
	
	link\Vertex0 = v0
	link\Vertex1 = v1
	
End Function
Function Build_Mesh.Entity( )
	Local Entity.Entity = New Entity
	Entity\Position = New Vector
	Entity\Rotation = New Vector
	
	Local Vertex.Vertex
	
	Local Vertex_Count
	Local Vertex_Link_Count
	
	For Vertex_Stack.Vertex_Stack = Each Vertex_Stack
		
		Vertex_Count = Vertex_Count + 1
		
	Next
	
	For Vertex_Link.Vertex_Link = Each Vertex_Link
		
		Vertex_Link_Count = Vertex_Link_Count + 1
		
	Next
	
	Entity\Vertices = CreateBank( 4 * Vertex_Count )
	
	Local Count = 0
	
	For Vertex_Stack.Vertex_Stack = Each Vertex_Stack
		
		Vertex.Vertex = New Vertex
		Vertex\Vector = Vertex_Stack\Vector
		Vertex\ProjectedCoords = New Vector
		Vertex\TempPosition = New Vector
		
		PokeInt( Entity\Vertices, Count * 4, Handle( Vertex ) )
		
		Delete Vertex_Stack
		
		Count = Count + 1
		
	Next
	
	Count = 0
	
	Entity\Link1 = CreateBank( 4 * Vertex_Link_Count )
	Entity\Link2 = CreateBank( 4 * Vertex_Link_Count )
	
	For Vertex_Link.Vertex_Link = Each Vertex_Link
		
		PokeInt( Entity\Link1, Count * 4, PeekInt( Entity\Vertices, ( Vertex_Link\Vertex0 - 1 ) * 4 ) )
		PokeInt( Entity\Link2, Count * 4, PeekInt( Entity\Vertices, ( Vertex_Link\Vertex1 - 1 ) * 4 ) )
		
		Delete Vertex_Link
		
		Count = Count + 1
		
	Next
	
	Entity\Vertex_Count = Vertex_Count
	Entity\Link_Count = Vertex_Link_Count
	
	Return Entity
		
End Function
Function Render( Entity.Entity )
	Local Count
	Local Vertex.Vertex
	
	For Count = 0 To ( Entity\Vertex_Count - 1 )
	
		Vertex.Vertex = Object.Vertex( PeekInt( Entity\Vertices, Count * 4 ) )
		
		Copy_Vector( Vertex\Vector, Vertex\TempPosition )
		
		Rotate_Vector( Vertex\TempPosition, Null, Entity\Rotation )
		
		Add_Vector( Entity\Position, Vertex\TempPosition )
		
		Project( Vertex\TempPosition, Vertex\ProjectedCoords )
	
	Next
	
	For Count = 0 To ( Entity\Link_Count - 1 )
	
		Vertex1.Vertex = Object.Vertex( PeekInt( Entity\Link1, Count * 4 ) )
		Vertex2.Vertex = Object.Vertex( PeekInt( Entity\Link2, Count * 4 ) )
		
		If Vertex1 <> Null And Vertex2 <> Null
		
		;	If Vertex1\Vector\Z# = 1.0 And Vertex2\Vector\Z# = 1.0
			
				Line Vertex1\ProjectedCoords\X#, Vertex1\ProjectedCoords\Y#, Vertex2\ProjectedCoords\X#, Vertex2\ProjectedCoords\Y#
		;		
		;	EndIf
			
		Else
		
			RuntimeError "Link is Null"
		
		EndIf
	
	Next
End Function
Function Project( Vector1.Vector, Vector2.Vector )
	Local X#, Y#, Z#
	
	X# = Vector1\X# - CameraX#
	Y# = Vector1\Y# - CameraY#
	Z# = Vector1\Z# - CameraZ#
	
	Local AngleX# = ATan2( X#, Z# )
	Local AngleY# = ATan2( Y#, Z# )
	Vector2\X# = ( ( AngleX# / FOV ) + 1.0 ) / 2.0 * Float( Graphics_Width )
	Vector2\Y# = ( ( AngleY# / FOV ) + 1.0 ) / 2.0 * Float( Graphics_Height )
	
	Plot Vector2\X#, Vector2\Y#
End Function
Function Copy_Vector( Vector1.Vector, Vector2.Vector )
	
	Vector2\X# = Vector1\X#
	Vector2\Y# = Vector1\Y#
	Vector2\Z# = Vector1\Z#
	
End Function
Function Add_Vector( Vector1.Vector, Vector2.Vector )
	
	Vector2\X# = Vector2\X# + Vector1\X#
	Vector2\Y# = Vector2\Y# + Vector1\Y#
	Vector2\Z# = Vector2\Z# + Vector1\Z#
	
End Function
;rotates vector1 about vector2 by vector3's pitch,yaw,roll
Function Rotate_Vector( Vector1.Vector, Vector2.Vector, Vector3.Vector )
	
	Local PitchAngle#, YawAngle#, RollAngle#
	Local aDist#
	Local bDist#
	
	Local Dist#
	
	PitchAngle# = FindAngle#( Vector1\Y#, Vector1\Z# )
	PitchAngle# = PitchAngle# + Vector3\X#
	
	aDist# = ( Vector1\Y# )
	bDist# = ( Vector1\Z# )
	
	Dist# = Sqr( aDist# * aDist# + bDist# * bDist# )
	
	Vector1\Y# = Dist# * Sin( PitchAngle# )
	Vector1\Z# = Dist# * Cos( PitchAngle# )
	
	
	YawAngle# = FindAngle#( Vector1\X#, Vector1\Z# )
	YawAngle# = YawAngle# + Vector3\Y#
	
	aDist# = ( Vector1\X# )
	bDist# = ( Vector1\Z# )
	
	Dist# = Sqr( aDist# * aDist# + bDist# * bDist# )
	
	Vector1\X# = Dist# * Sin( YawAngle# )
	Vector1\Z# = Dist# * Cos( YawAngle# )
	
End Function
Function FindAngle#( X#, Y# )
	Return ATan2( X#, Y# )
	
End Function
 
 
 |