Vector Rendering Library

Community Forums/Showcase/Vector Rendering Library

Michael Reitzenstein(Posted 2003) [#1]
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



BlitzSupport(Posted 2003) [#2]
Works nicely here, though it looks like you took the left/right code out!


Michael Reitzenstein(Posted 2003) [#3]
Oops!

If KeyDown( 203 ) entity\position\x# = entity\position\x# - 0.05


etc...


jfk EO-11110(Posted 2003) [#4]
well done! have a look at my simple 3d engine in the code archives (2D :) ).