I started making one for one of my games ... this is about as far as I got. Not very versatile but was really just a test and as you can see all letters are low poly and made in-code. I've since settled for a simpler pixel perfect system but this may be of some use .....
Graphics3D 800,600,16,1
Global CAMERA = CreateCamera() : PositionEntity CAMERA, 0, 0, -100
CameraClsColor Camera,50,75,150
Global LIGHT = CreateLight() : RotateEntity LIGHT, 30,-45,0
Global LETTERS = MESHpivot()
Dim Grid( 4, 6 )
Const C_Front = 1
Const C_Rear = 4
Const C_Left = 8
Const C_Right = 2
Const C_Top = 16
Const C_Bottom = 32
Global P1, P2, P3, P4
FONTcreate()
TEST = FONTcreatepara("THE QUICK BROWN", "FOX JUMPS OVER", "THE LAZY DOG" )
YAW = 0
PITCH = 0
While Not KeyDown(1)
YAW = YAW + KeyDown(205) - KeyDown(203 )
PITCH = PITCH + KeyDown( 200 ) - KeyDown(208 )
RotateEntity TEST, PITCH, YAW, 0
RenderWorld()
Text 0,0,TrisRendered()
Flip
Wend
;===================================================
;===================================================
;===================================================
Function FONTcreatepara( t1$, t2$, t3$ , T4$="")
Mesh = CreateMesh()
Tmp = FONTcreateword( t1$, 1.0 )
AddMesh Tmp, Mesh : FreeEntity Tmp
Tmp = FONTcreateword( t2$, .5 )
PositionMesh tmp, 0, -14 , 0
AddMesh Tmp, Mesh : FreeEntity Tmp
Tmp = FONTcreateword( t3$, .75 )
PositionMesh tmp, 0, -28 , 0
AddMesh Tmp, Mesh : FreeEntity Tmp
Tmp = FONTcreateword( t4$, .5 )
PositionMesh tmp, 0, -42 , 0
AddMesh Tmp, Mesh : FreeEntity Tmp
MESHcenter( Mesh )
EntityFX Mesh, 2+4
Return Mesh
End Function
;===================================================
;===================================================
;===================================================
Function FONTcreateword( t$ , Scale#=1.0 )
mesh = CreateMesh()
For l = 1 To Len( t$ )
c$ = Mid$( t$ , l , 1 )
If c$<>" "
copy = CopyMesh( FindChild( LETTERS , c$ ) )
ScaleMesh copy, Scale, Scale, Scale*5.0
RotateMesh copy, Rnd(-15,15 ), Rnd(-15,15) ,Rnd(-15,15)
PositionMesh copy , l * 8.0 * Scale , 0, 0
AddMesh copy, mesh : FreeEntity copy
EndIf
Next
MESHcenter( mesh )
EntityFX mesh, 2+4
Return mesh
End Function
;===================================================
;===================================================
;===================================================
Function FONTcreate()
;V shape
P1 = CreateMesh()
s = CreateSurface( p1 )
v0 = AddVertex( s, -1,1,1 )
v1 = AddVertex( s, 1,1,1 )
v2 = AddVertex( s, -.9, 0, 1 )
v3 = AddVertex( s, 1,-1,1 )
v4 = AddVertex( s, -1,-1,1 )
v5 = AddVertex( s, -1,1,-1 )
v6 = AddVertex( s, 1,1,-1 )
v7 = AddVertex( s, -.9, 0, -1 )
v8 = AddVertex( s, 1,-1,-1 )
v9 = AddVertex( s, -1,-1,-1 )
AddTriangle s, v0, v4, v2
AddTriangle s, v0,v2,v1
AddTriangle s, v2,v4,v3
AddTriangle s, v5,v6,v7
AddTriangle s, v5,v7,v9
AddTriangle s, v9,v7,v8
AddTriangle s, v6,v1,v2
AddTriangle s, v2,v7,v6
AddTriangle s, v7,v2,v3
AddTriangle s, v3,v8,v7
AddTriangle s, v8,v3,v1
AddTriangle s, v1,v6,v8
p1 = MESHunweld( p1 )
MESHnormals( p1 )
HideEntity p1
;Triangle shape
P2 = CreateMesh()
s = CreateSurface( P2 )
v0 = AddVertex( s , -1, 1, 1 )
v1 = AddVertex( s, 1, 1, 1 )
v2 = AddVertex( s, 1,-1,1 )
v3 = AddVertex( s, -1,-1,1 )
v4 = AddVertex( s , -1, 1, -1 )
v5 = AddVertex( s, 1, 1, -1 )
v6 = AddVertex( s, 1,-1,-1 )
v7 = AddVertex( s, -1, -1, -1 )
AddTriangle s, v1, v0, v3
AddTriangle s, v7, v4, v5
AddTriangle s, v1,v3,v7
AddTriangle s, v7,v5,v1
AddTriangle s, v0,v1,v5
AddTriangle s, v5,v4,v0
AddTriangle s, v3,v0,v4
AddTriangle s, v4,v7,v3
p2 = MESHunweld( p2 )
MESHnormals( p2 )
HideEntity p2
;inside triangle
P3 = CreateMesh()
s = CreateSurface( P3 )
v0 = AddVertex( s , -1, 1, 1 )
v1 = AddVertex( s, 1, 1, 1 )
v2 = AddVertex( s, 1,-1,1 )
v3 = AddVertex( s, -1,-1,1 )
v4 = AddVertex( s , -1, 1, -1 )
v5 = AddVertex( s, 1, 1, -1 )
v6 = AddVertex( s, 1,-1,-1 )
v7 = AddVertex( s, -1, -1, -1 )
AddTriangle s, v2,v1,v5
AddTriangle s, v5,v6,v2
AddTriangle s, v3,v2,v6
AddTriangle s, v6,v7,v3
p3 = MESHunweld( p3 )
MESHnormals( p3 )
HideEntity p3
;point
P4 = CreateMesh()
s = CreateSurface( P4 )
v0 = AddVertex( s, -1,1,1 )
v1 = AddVertex( s, 1,0 , 1 )
v2 = AddVertex( s, -1,-1,1 )
v3 = AddVertex( s, -1,1,-1 )
v4 = AddVertex( s, 1,0 , -1 )
v5 = AddVertex( s, -1,-1,-1 )
AddTriangle s, v0, v2, v1
AddTriangle s, v3, v4, v5
AddTriangle s, v0,v1,v4
AddTriangle s, v4, v3, v0
AddTriangle s, v1, v2, v5
AddTriangle s, v5, v4, v1
p4 = MESHunweld( p4 )
MESHnormals( p4 )
; PositionEntity p4, 0, 0, -90
HideEntity p4
;inside point
P5 = CreateMesh()
s = CreateSurface( P5 )
v0 = AddVertex( s, -1,1,1 )
v1 = AddVertex( s, 1,1 , 1 )
v2 = AddVertex( s, 1,-1,1 )
v3 = AddVertex( s, -1,-1,1 )
v4 = AddVertex( s, -1,1,-1 )
v5 = AddVertex( s, 1,1 , -1 )
v6 = AddVertex( s, 1,-1,-1 )
v7 = AddVertex( s, -1,-1,-1 )
AddTriangle s, v1,v0, v4
AddTriangle s, v4, v5, v1
AddTriangle s, v7, v3, v2
AddTriangle s, v2, v6, v7
p5 = MESHunweld( p5 )
MESHnormals( p5 )
HideEntity p5
Restore DATAletters
Read No
For l = 0 To No-1
For y= 1 To 5
For x =1 To 3
Read Grid( x, y )
Next
Next
Mesh = CreateMesh( LETTERS )
NameEntity Mesh , Chr$( 48 + l )
For y = 1 To 5
For x = 1 To 3
If Grid( x, y ) > 0
Flag = 0
Flag = Flag + C_Left * ( Grid( x-1, y ) > 0 )
Flag = Flag + C_Right * ( Grid( x+1, y ) > 0 )
Flag = Flag + C_Top * ( Grid( x, y-1 ) > 0 )
Flag = Flag + C_Bottom * ( Grid( x, y+1 ) > 0 )
Select Grid( x, y )
Case 1
Tmp = MESHcull( CreateCube() , Flag )
Case 2, 3, 4, 5
Tmp = CopyMesh( P1 )
Tmp = MESHcull( Tmp, C_Left )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 2 ) * 90
Case 6, 7, 8, 9
Tmp = CopyMesh( P2 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 6 ) * 90
Tmp = MESHcull( Tmp , Flag )
Case 10,11,12,13
Tmp = CopyMesh( P1 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 10 ) * 90
Case 14,15,16,17
Tmp = CopyMesh( P4 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 14 ) * 90
Case 18,19,20,21
Tmp = CopyMesh( P2 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 18 ) * 90
Tmp = MESHcull( Tmp, Flag )
Copy = MESHcull( CopyMesh( P3 ) , C_Top )
RotateMesh Copy, 0, 0, ( Grid( x, y ) - 18 ) * 90
AddMesh copy, tmp : FreeEntity copy
Case 22,23,24,25
Tmp = CopyMesh( P2 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 22 ) * 90
Tmp = MESHcull( Tmp, Flag )
Copy = MESHcull( CopyMesh( P3 ) , C_Left )
RotateMesh Copy, 0, 0, ( Grid( x, y ) - 22 ) * 90
AddMesh copy, tmp : FreeEntity copy
Case 26,27,28,29
Tmp = CopyMesh( P4 )
RotateMesh Tmp, 0,0, ( Grid( x, y ) - 26 ) * 90
Copy = CopyMesh( P5 )
RotateMesh Copy, 0, 0, ( Grid( x, y ) - 26 ) * 90
AddMesh copy, tmp : FreeEntity copy
End Select
PositionMesh tmp, (x-2)*2 , -(y-3)*2 , 0
AddMesh tmp,Mesh
FreeEntity tmp
EndIf
Next
Next
MESHnormals( Mesh )
s = GetSurface( Mesh , 1 )
For v= 0 To CountVertices(s) - 1
If VertexNZ( s, v ) < -.5
VertexColor s, v, 250,250,0
Else
VertexColor s, v, 250,50,50
EndIf
Next
HideEntity Mesh
Next
FreeEntity P1
FreeEntity P2
FreeEntity P3
FreeEntity P4
End Function
;===================================================
;===================================================
;===================================================
Function MESHpivot()
mesh = CreateMesh()
s = CreateSurface( mesh )
NameEntity mesh, "ROOT"
Return mesh
End Function
;===================================================
;===================================================
;===================================================
Function MESHunweld( Mesh , clip0=False )
Copy = CreateMesh()
ns = CreateSurface( Copy )
For su = 1 To CountSurfaces( Mesh )
s = GetSurface( Mesh , su )
For t = 0 To CountTriangles( s ) - 1
v0 = TriangleVertex( s, t, 0 )
v1 = TriangleVertex( s, t, 1 )
v2 = TriangleVertex( s, t, 2 )
If clip0 = False Or ( VertexY( s, v0 ) <>0 Or VertexY( s, v1) <> 0 Or VertexY( s, v2 ) <> 0 )
Nv0 = AddVertex( ns , VertexX( s , v0 ) , VertexY( s, v0 ) , VertexZ( s, v0 ) )
Nv1 = AddVertex( ns , VertexX( s , v1 ) , VertexY( s, v1 ) , VertexZ( s, v1 ) )
Nv2 = AddVertex( ns , VertexX( s , v2 ) , VertexY( s, v2 ) , VertexZ( s, v2 ) )
VertexColor ns, Nv0 , VertexRed( s, v0 ) , VertexGreen( s, v0 ) , VertexBlue( s, v0 )
VertexColor ns, Nv1 , VertexRed( s, v1 ) , VertexGreen( s, v1 ) , VertexBlue( s, v1 )
VertexColor ns, Nv2 , VertexRed( s, v2 ) , VertexGreen( s, v2 ) , VertexBlue( s, v2 )
AddTriangle ns , Nv0 , Nv1 , Nv2
EndIf
Next
Next
FreeEntity mesh
Return Copy
End Function
;====================================================
;====================================================
;====================================================
Function MESHcenter( mesh )
sx# = MeshWidth( mesh )
sy# = MeshHeight( mesh )
sz# = MeshDepth( mesh )
FitMesh mesh , -sx*.5, -sy*.5 , -sz*.5 , sx, sy, sz
Return mesh
End Function
;===================================================
;===================================================
;===================================================
Function MESHnormals( mesh )
For l = 1 To CountSurfaces(mesh )
s = GetSurface( mesh , l )
;calculate normals for flatshading
For t = 0 To CountTriangles( s )-1
v0 = TriangleVertex( s, t, 0 )
v1 = TriangleVertex( s, t, 1 )
v2 = TriangleVertex( s, t, 2 )
ax# = VertexX( s, v1 ) - VertexX( s, v0 )
ay# = VertexY( s, v1 ) - VertexY( s, v0 )
az# = VertexZ( s, v1 ) - VertexZ( s, v0 )
bx# = VertexX( s, v2 ) - VertexX( s, v1 )
by# = VertexY( s, v2 ) - VertexY( s, v1 )
bz# = VertexZ( s, v2 ) - VertexZ( s, v1 )
Nx# = ( ay * bz ) - ( az * by )
Ny# = ( az * bx ) - ( ax * bz )
Nz# = ( ax * by ) - ( ay * bx )
Ns# = Sqr( Nx * Nx + Ny*Ny + Nz*Nz )
Nx = LIMIT( Nx / Ns, -1,1 )
Ny = LIMIT( Ny / Ns, -1, 1 )
Nz = LIMIT( Nz / Ns, -1, 1 )
For v = v0 To v2
VertexNormal s, v, Nx, Ny, Nz
Next
Next
Next
End Function
;===================================================
;===================================================
;===================================================
Function MESHcull( Mesh , Flags = 0 )
If Flags = 0 Return Mesh
s = GetSurface( Mesh , 1 )
Copy = CreateMesh()
Cs = CreateSurface( Copy )
For t = 0 To CountTriangles( s )-1
;calculate triangle normal
v0 = TriangleVertex( s, t, 0 )
v1 = TriangleVertex( s, t, 1 )
v2 = TriangleVertex( s, t, 2 )
ax# = VertexX( s, v1 ) - VertexX( s, v0 )
ay# = VertexY( s, v1 ) - VertexY( s, v0 )
az# = VertexZ( s, v1 ) - VertexZ( s, v0 )
bx# = VertexX( s, v2 ) - VertexX( s, v1 )
by# = VertexY( s, v2 ) - VertexY( s, v1 )
bz# = VertexZ( s, v2 ) - VertexZ( s, v1 )
Nx# = ( ay * bz ) - ( az * by )
Ny# = ( az * bx ) - ( ax * bz )
Nz# = ( ax * by ) - ( ay * bx )
Ns# = Sqr( Nx * Nx + Ny*Ny + Nz*Nz )
Nx = Nx / Ns
Ny = Ny / Ns
Nz = Nz / Ns
OK = True
For l = 0 To 5
Flag = 2^l
If ( Flags And Flag) = Flag
;determine plane normal
Select Flag
Case C_Front px# = 0 : py# = 0 : pz# = 1
Case C_Rear px# = 0 : py# = 0 : pz# = -1
Case C_Left px# = -1 : py# = 0 : pz# = 0
Case C_Right px# = 1 : py# = 0 : pz# = 0
Case C_Top px# = 0 : py# = 1 : pz# = 0
Case C_Bottom px# = 0 : py# = -1 : pz# = 0
End Select
If Nx = Px And Ny = Py And Nz = Pz OK = False
EndIf
Next
If OK
nv0 = AddVertex( Cs, VertexX( s , v0 ) , VertexY( s, v0 ) , VertexZ( s, v0 ) )
nv1 = AddVertex( Cs, VertexX( s , v1 ) , VertexY( s, v1 ) , VertexZ( s, v1 ) )
nv2 = AddVertex( Cs, VertexX( s , v2 ) , VertexY( s, v2 ) , VertexZ( s, v2 ) )
VertexNormal Cs , nv0 , Nx, Ny, Nz
VertexNormal Cs , nv1 , Nx, Ny, Nz
VertexNormal Cs , nv2 , Nx, Ny, Nz
AddTriangle( Cs , nv0, nv1, nv2 )
EndIf
Next
FreeEntity mesh
Return copy
End Function
;===================================================
;===================================================
;===================================================
Function LIMIT#( q#, lo#, hi# )
If q < lo q = lo
If q > hi q = hi
Return q
End Function
.DATAletters
Data 26+17
;0
Data 1,1,1
Data 1,0,1
Data 1,0,1
Data 1,0,1
Data 1,1,1
;1
Data 0,1,0
Data 0,1,0
Data 0,1,0
Data 0,1,0
Data 0,1,0
;2
Data 1,1,1
Data 0,0,1
Data 1,1,1
Data 1,0,0
Data 1,1,1
;3
Data 1,1,1
Data 0,0,1
Data 1,1,1
Data 0,0,1
Data 1,1,1
;4
Data 1,0,0
Data 1,0,0
Data 1,1,1
Data 0,1,0
Data 0,1,0
;5
Data 1,1,1
Data 1,0,0
Data 1,1,1
Data 0,0,1
Data 1,1,1
;6
Data 1,1,1
Data 1,0,0
Data 1,1,1
Data 1,0,1
Data 1,1,1
;7
Data 1,1,1
Data 0,0,1
Data 0,0,1
Data 0,0,1
Data 0,0,1
;8
Data 1,1,1
Data 1,0,1
Data 1,1,1
Data 1,0,1
Data 1,1,1
;9
Data 1,1,1
Data 1,0,1
Data 1,1,1
Data 0,0,1
Data 0,0,1
;:
Data 0,0,0
Data 0,1,0
Data 0,0,0
Data 0,1,0
Data 0,0,0
;;
Data 0,0,8
Data 0,8,1
Data 8,1,6
Data 1,6,0
Data 6,0,0
;<
Data 0,8,1
Data 8,1,6
Data 1,2,0
Data 9,1,7
Data 0,9,1
;=
Data 0,0,0
Data 0,0,0
Data 0,1,0
Data 0,0,0
Data 0,0,0
;>
Data 1,7,0
Data 9,1,7
Data 0,4,1
Data 8,1,6
Data 1,6,0
;?
Data 16,1,7
Data 0,4,1
Data 0,1,6
Data 0,0,0
Data 0,1,0
;@
Data 0,15,0
Data 8,1,7
Data 1,1,1
Data 0,1,0
Data 0,1,0
;A
Data 8,1,7
Data 1,13,1
Data 1,1,1
Data 1,0,1
Data 17,0,17
;B
Data 1,1,7
Data 1,12,1
Data 1,1,2
Data 1,12,1
Data 1,1,6
;C
Data 8,1,14
Data 1,0,0
Data 1,0,0
Data 1,0,0
Data 9,1,14
;D
Data 1,1,7
Data 1,25,1
Data 1,0,1
Data 1,20,1
Data 1,1,6
;E
Data 8,1,14
Data 1,0,0
Data 1,1,14
Data 1,0,0
Data 9,1,14
;F
Data 8,1,14
Data 1,0,0
Data 1,1,14
Data 1,0,0
Data 17,0,0
;G
Data 8,1,14
Data 1,0,0
Data 1,0,15
Data 1,0,1
Data 9,1,6
;H
Data 15,0,15
Data 1,0,1
Data 1,1,1
Data 1,0,1
Data 17,0,17
;I
Data 16,1,14
Data 0,1,0
Data 0,1,0
Data 0,1,0
Data 16,1,14
;J
Data 0,0,15
Data 0,0,1
Data 0,0,1
Data 15,0,1
Data 9,1,6
;K
Data 15,0,8
Data 1,20,1
Data 1,1,2
Data 1,25,1
Data 17,0,9
;L
Data 15,0,0
Data 1,0,0
Data 1,0,0
Data 1,0,0
Data 9,1,14
;M
Data 8,3,7
Data 1,1,1
Data 1,29,1
Data 1,0,1
Data 17,0,17
;N
Data 8,1,7
Data 1,5,1
Data 1,0,1
Data 1,0,1
Data 17,0,17
;O
Data 8,1,7
Data 1,5,1
Data 1,0,1
Data 1,3,1
Data 9,1,6
;P
Data 1,1,7
Data 1,12,1
Data 1,1,6
Data 1,0,0
Data 17,0,0
;Q
Data 8,1,7
Data 1,5,1
Data 1,3,1
Data 9,1,6
Data 0,9,7
;R
Data 1,1,7
Data 1,12,1
Data 1,1,2
Data 1,5,1
Data 1,0,9
;S
Data 8,1,14
Data 1,2,0
Data 9,1,7
Data 0,4,1
Data 16,1,6
;T
Data 1,1,1
Data 0,1,0
Data 0,1,0
Data 0,1,0
Data 0,17,0
;U
Data 15,0,15
Data 1,0,1
Data 1,0,1
Data 1,3,1
Data 9,1,6
;V
Data 15,0,15
Data 1,0,1
Data 1,3,1
Data 9,1,6
Data 0,17,0
;W
Data 15,0,15
Data 1,0,1
Data 1,27,1
Data 1,1,1
Data 9,5,6
;X
Data 7,0,8
Data 1,3,1
Data 4,1,2
Data 1,5,1
Data 6,0,9
;Y
Data 7,0,8
Data 1,3,1
Data 9,1,6
Data 0,1,0
Data 0,17,0
;Z
Data 16,1,7
Data 0,4,1
Data 8,1,6
Data 1,2,0
Data 9,1,14