Code archives/3D Graphics - Misc/Terragen terrain loader
This code has been declared by its author to be Public Domain code.
Download source code
| |||||
| Creates a Blitz terrain from a Terragen map. It's currently hard-coded for Terragen 0.8.44 maps -- see source for lots of disclaimers :) To use it... · Get Terragen from PlanetSide; · Install and run it; · In the Landscape view, click on 'Generate Terrain'; · In the new window, click 'Generate Terrain', then 'Close'; · Click the number box below the map image (says "7680 metres" to start with); · In the new window, choose 129 (128 x 128 map), 257 (256 x 256) or 513 (512 x 512), then OK; · Click 'Save', and save your .ter file wherever you want; · In your Blitz3D program, use blah = LoadTerragenTerrain () to load the terrain as 'blah'... · Ta-da! Now go play with Terragen's renderer instead :) | |||||
; -----------------------------------------------------------------------------
; Terragen map (.ter) loader...
; -----------------------------------------------------------------------------
; Works only with maps created by Terragen 0.8.44 -- not guaranteed to work
; with later maps, or ".ter" maps created with other tools! Yes, it's nasty
; ol' hard-codin' time...
; -----------------------------------------------------------------------------
; james @ hi - toro . com
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; Demo -- use CURSORS plus A and Z...
; -----------------------------------------------------------------------------
Graphics3D 640, 480
cam = CreateCamera ()
CameraClsColor cam, 64, 96, 128
CameraRange cam, 0.1, 9000
light = CreateLight ()
TurnEntity light, 0, -45, 0
terrain = LoadTerragenMap ("blah.ter", 5000, 1, True) ; CHANGE NAME OF TERRAIN FILE!
PositionEntity cam, 0, TerrainY (terrain, 0, 0, 0) + 250, 0
TurnEntity cam, 20, -45, 0
Repeat
If KeyDown (203) TurnEntity cam, 0, 1, 0, 1
If KeyDown (205) TurnEntity cam, 0, -1, 0, 1
If KeyDown (200) TurnEntity cam, 1, 0, 0
If KeyDown (208) TurnEntity cam, -1, 0, 0
If KeyDown (30) MoveEntity cam, 0, 0, 10
If KeyDown (44) MoveEntity cam, 0, 0, -10
UpdateWorld
RenderWorld
Flip
Until KeyHit (1)
End
; -----------------------------------------------------------------------------
; LoadTerragenMap (terr$, [detail, scaler#, autotex, texwidth, texheight])
; -----------------------------------------------------------------------------
; Loads a Terragen (0.8.44) terrain map and returns a Blitz terrain handle...
; -----------------------------------------------------------------------------
; -----------------------------------------------------------------------------
; Required parameters...
; -----------------------------------------------------------------------------
; terr$ -- a Terragen [0.8.44] terrain file (.ter)
; -----------------------------------------------------------------------------
; Optional parameters...
; -----------------------------------------------------------------------------
; detail -- terrain detail (see TerrainDetail commands docs)
; scaler# -- amount to scale resulting terrain by
; autotex -- True to apply crude texturing
; texwidth -- over-ride texture width
; texheight -- over-ride texture height
; Regarding the last two -- textures default to the size of the map (eg.
; 256 x 256, 512 x 512, etc). If you over-ride the texture size, make sure
; it's SMALLER than the map or it'll screw up! You must set both -- best
; to use the same value for width AND height...
; -----------------------------------------------------------------------------
; Examples:
; -----------------------------------------------------------------------------
; terrain = LoadTerragenMap ("blah.ter")
; terrain = LoadTerragenMap ("blah.ter", 5000, 0.25, False)
; terrain = LoadTerragenMap ("blah.ter", 2000, 1, True, 64, 64)
Function LoadTerragenMap (terr$, detail = 2000, scaler# = 1.0, autotex = False, texwidth = 0, texheight = 0)
tbuffer = GraphicsBuffer () ; Store current buffer in case we write to texture...
total = FileSize (terr$) ; Total size of file
ter = ReadFile (terr$)
If ter
; "Let's parse!" -- Sandra Bullock in forthcoming hi-tech action/hacking movie...
; -------------------------------------------------------------------------
; Terragen .ter identifier...
; -------------------------------------------------------------------------
For b = 1 To 16
terrinfo$ = terrinfo$ + Chr (ReadByte (ter))
Next
If terrinfo$ <> "TERRAGENTERRAIN "
RuntimeError "Not a Terragen terrain file!"
EndIf
; -------------------------------------------------------------------------
; Size...
; -------------------------------------------------------------------------
For b = 1 To 4
sizeinfo$ = sizeinfo$ + Chr (ReadByte (ter))
Next
If sizeinfo$ <> "SIZE"
RuntimeError "File corrupt in SIZE section!"
EndIf
size = ReadInt (ter)
; -------------------------------------------------------------------------
; X Points...
; -------------------------------------------------------------------------
For b = 1 To 4
xinfo$ = xinfo$ + Chr (ReadByte (ter))
Next
If xinfo$ <> "XPTS"
RuntimeError "File corrupt in XPTS section!"
EndIf
xpts = ReadInt (ter)
; -------------------------------------------------------------------------
; Y Points...
; -------------------------------------------------------------------------
For b = 1 To 4
yinfo$ = yinfo$ + Chr (ReadByte (ter))
Next
If yinfo$ <> "YPTS"
RuntimeError "File corrupt in YPTS section!"
EndIf
ypts = ReadInt (ter)
; -------------------------------------------------------------------------
; Scale...
; -------------------------------------------------------------------------
For b = 1 To 4
scaleinfo$ = scaleinfo$ + Chr (ReadByte (ter))
Next
If scaleinfo$ <> "SCAL"
RuntimeError "File corrupt in SCAL section!"
EndIf
xscale# = ReadFloat (ter)
yscale# = ReadFloat (ter)
zscale# = ReadFloat (ter)
terrain = CreateTerrain (xpts - 1)
If terrain = 0 Then RuntimeError "Doh @ CreateTerrain!"
TerrainDetail terrain, 5000, True
; -------------------------------------------------------------------------
; Planet radius...
; -------------------------------------------------------------------------
For b = 1 To 4
cradinfo$ = cradinfo$ + Chr (ReadByte (ter))
Next
If cradinfo$ <> "CRAD"
RuntimeError "File corrupt in CRAD section!"
EndIf
crad# = ReadFloat (ter)
; -------------------------------------------------------------------------
; Curved terrain ("CRVM")... switches between 1 and 0, but uses 4 bytes...?
; -------------------------------------------------------------------------
For b = 1 To 4
crvminfo$ = crvminfo$ + Chr (ReadByte (ter))
Next
If crvminfo$ <> "CRVM"
RuntimeError "File corrupt in CRVM section!"
EndIf
crvm = ReadInt (ter)
; -------------------------------------------------------------------------
; Altitude data in 16-bit words...
; -------------------------------------------------------------------------
For b = 1 To 4
altwinfo$ = altwinfo$ + Chr (ReadByte (ter))
Next
If altwinfo$ <> "ALTW"
RuntimeError "File corrupt in ALTW section!"
EndIf
hscale = ReadShort (ter)
hbase = ReadShort (ter)
; -------------------------------------------------------------------------
; Automatically create texture (if requested)...
; -------------------------------------------------------------------------
If autotex
If (texwidth = 0) Or (texheight = 0)
texwidth = xpts - 1
texheight = ypts - 1
EndIf
tex = CreateTexture (texwidth, texheight)
If tex
divx# = (xpts - 1) / TextureWidth (tex)
divy# = (ypts - 1) / TextureHeight (tex)
SetBuffer TextureBuffer (tex)
EndIf
EndIf
; Start position for linear data traversal...
xpt = 1
ypt = ypts
; -------------------------------------------------------------------------
; Main data...
; -------------------------------------------------------------------------
While Not Eof (ter)
height = ReadShort (ter)
newheight# = (height / 65536.0) - 0.5 ; Blitz'll wrap the values (they're wrong :)
If tex
; Draw to texture... don't ask what all this means. Dunno.
rgb = (255 - ((newheight + 0.5) * 127)) / 2
Color rgb * 0.65, rgb * 0.85, rgb * 0.45
Plot (xpt - 1) / divx, (ypt - 1) / divy
EndIf
count = count + 1 ; Data byte count...
If FilePos (ter) > (total - 7) Then Exit ; Reached end of data...
; Traversing the linear data...
xpt = xpt + 1: If xpt > xpts Then xpt = 1: ypt = ypt - 1
; Applying the data...
ModifyTerrain terrain, xpt - 2, ypts - (ypt - 2), newheight
Wend
; -------------------------------------------------------------------------
; Two null characters...? Too lazy to check the docs now (which I only found AFTER figuring the format out!)
; -------------------------------------------------------------------------
ReadByte (ter)
ReadByte (ter)
; -------------------------------------------------------------------------
; End of file marker ("EOF ")...
; -------------------------------------------------------------------------
For b = 1 To 4
eofinfo$ = eofinfo$ + Chr (ReadByte (ter))
Next
If eofinfo$ <> "EOF "
RuntimeError "File corrupt in EOF[ ] section!"
EndIf
CloseFile ter
EndIf
If tex
ScaleTexture tex, xpts - 1, ypts - 1
EntityTexture terrain, tex
EndIf
TerrainDetail terrain, detail, True
TerrainShading terrain, True
ScaleEntity terrain, scaler * xscale, scaler * hscale * yscale, scaler * zscale
SetBuffer tbuffer
Return terrain
End Function |
Comments
None.
Code Archives Forum