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.
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