Here's my initial attempt. It first generates a colour scale to be used to generate a texturemap based on a perlin noise generated heightmap. It then creates an advanced terrain and some water.
This is only an initial attempt, I've yet to include large terrains, and features. (Such as trees, rocks, ect.)
Space will show you the height and texturemaps, and enter will generate a new terrain.
Set Display Mode 800, 600, 32
Sync On : Sync Rate 0 : Sync
Dim TextureLookup( 256 ) As DWord
Do
GenerateHeightScale()
Det = MakeDetailMap()
Wat = MakeWaterImg()
Seed = Timer()
Noise = GenerateNoise( Seed, 256, 7, 1 ) : Save Image "Height.png", Noise
Col = MakeColourMap( Noise )
Ter = CreateTerrain( "Height.png", Col, Det )
Water = GetBlankObjNo()
Make Object Plain Water, 1536, 1536, 25, 25
Position Object Water, 0, 48, 0
Texture Object Water, Wat
Ghost Object On Water : Fade Object Water, 50
While Not ReturnKey()
OldX# = CurveValue( XPos#, Camera Position X(), 300 )
OldZ# = CurveValue( ZPos#, Camera Position Z(), 300 )
XPos# = 512 * Sin( Wrapvalue( Timer() * 0.00625 ) ) : ZPos# = 512 * Cos( Wrapvalue( Timer() * 0.0125 ) )
CamY# = Get Terrain Ground Height( Ter, OldX#, OldZ# )
PointY# = Get Terrain Ground Height( Ter, XPos#, ZPos# )
Position Camera OldX#, CamY# + 10.0, OldZ# : Point Camera XPos#, PointY# + 10.0, ZPos#
XRotate Object Water, ( 0.5 * Sin( Wrapvalue( Timer() * 0.025 ) ) )
ZRotate Object Water, ( 0.5 * Sin( Wrapvalue( Timer() * 0.05 ) ) )
If Spacekey()
Paste Image Noise, 0, 20
Paste Image Col, 256, 20
EndIf
Text 0, 0, Str$( Seed )
Sync
EndWhile
Delete Image Noise
Delete Image Col
Delete Image Wat
Destroy Terrain Ter
Set Display Mode 800, 600, 32
Loop
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function MakeWaterImg()
Bmp = GetBlankBmpNo()
Create Bitmap Bmp, 256, 256
Set Current Bitmap Bmp
Ink Rgb( 0, 0, 255 ), 0
Box 0, 0, 256, 256
Sync
Wat = GetBlankImgNo()
Get Image Wat, 0, 0, 256, 256, 1
Set Current Bitmap 0
Delete Bitmap Bmp
EndFunction Wat
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
`Convert matrix to plain.......
Function MakeColourMap( Img )
Bmp = GetBlankBmpNo()
Create Bitmap Bmp, 256, 256
Set Current Bitmap Bmp
Cls
Paste Image Img, 0, 0
For Y = 0 To 255
For X = 0 To 255
Dot X, Y, TextureLookup( RgbR( Point( X, Y ) ) )
Next X
Next Y
Sync
Col = GetBlankImgNo()
Get Image Col, 0, 0, 256, 256
Set Current Bitmap 0
Delete Bitmap Bmp
EndFunction Col
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function MakeDetailMap()
Bmp = GetBlankBmpNo()
Create Bitmap Bmp, 256, 256
Set Current Bitmap Bmp
Set Bitmap Format 21
Ink Rgb( 128, 128, 128 ), 0
Box 0, 0, 256, 256
Sync
Det = GetBlankImgNo()
Get Image Det, 0, 0, 256, 256, 1
Set Current Bitmap 0
Delete Bitmap Bmp
EndFunction Det
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function CreateTerrain( Height$, Col, Det )
Width = GetImageWidth( Col )
Ter = GetBlankObjNo()
Make Object Terrain Ter ` create the terrain object
Set Terrain Heightmap Ter, Height$ ` set the heightmap
Set Terrain Scale Ter, 6, 0.6, 6 ` set the scale
Set Terrain Split Ter, 16 ` split value by 16 * 16
Set Terrain Tiling Ter, 4 ` detail map tiling
Set Terrain Light Ter, 0.15, -1, 0, 0.75, 0.75, 0.75, 0.5 ` light - xdir, ydir, zdir, red, green, blue, intensity
Set Terrain Texture Ter, Col, Det ` base and detail texture
Build Terrain Ter ` finally build the terrain
Delete File Height$
Position Object Ter, 0.0 - ( ( Width * 6.0 ) / 2.0 ), 0.0, 0.0 - ( ( Width * 6.0 ) / 2.0 )
EndFunction Ter
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetBlankImgNo()
For Num = 1 To 65500
If Image Exist( Num ) = 0
ExitFunction Num
EndIf
Next Num
EndFunction 0
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetBlankObjNo()
For Num = 1 To 65500
If Object Exist( Num ) = 0
ExitFunction Num
EndIf
Next Num
EndFunction 0
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetBlankBmpNo()
For Num = 1 To 32
If Bitmap Exist( Num ) = 0
ExitFunction Num
EndIf
Next Num
EndFunction 0
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetBlankSprNo()
For Num = 1 To 65500
If Sprite Exist( Num ) = 0
ExitFunction Num
EndIf
Next Num
EndFunction 0
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetImageWidth( ImgNo )
Spr = GetBlankSprNo()
Sprite Spr, 0, 0, ImgNo
Width = Sprite Width( Spr )
Delete Sprite Spr
EndFunction Width
`============================================================================================================================
`============================================================================================================================
`============================================================================================================================
Function GetImageHeight( ImgNo )
Spr = GetBlankSprNo()
Sprite Spr, 0, 0, ImgNo
Height = Sprite Height(Spr)
Delete Sprite Spr
EndFunction Height
`Perlin Noise Courtesy of Dark Coder ;) ()
Function GenerateNoise( Seed, startingRes, totalOctaves, Sampling )
Randomize Seed
If startingRes > 512 Then startingRes = 512
If totalOctaves > 8 Then totalOctaves = 8
// Generate noise for all octaves
for octaveID = 1 to totalOctaves
memblockID = octaveID
octaveRes = startingRes / 2 ^ (octaveID - 1)
Make Memblock memblockID, octaveRes * octaveRes * 4 // A single float
for x = 0 to octaveRes - 1
for y = 0 to octaveRes - 1
Write Memblock Float memblockID, ( x + y * octaveRes ) * 4, ( Rnd(2000) - 1000 ) * 0.001
next
next
next
// add all layers together
memblockID = totalOctaves + 1
Make Memblock memblockID, 12 + startingRes * startingRes * 4
Write Memblock DWord memblockID, 0, startingRes
Write Memblock DWord memblockID, 4, startingRes
Write Memblock DWord memblockID, 8, 32
minHeight# = -1.9
maxHeight# = 1.9
minInv# = -minHeight#
heightRange# = maxHeight# - minHeight#
_255DivRange# = 255.0 / heightRange#
sResReciprocal# = 1.0 / (startingRes)
for x = 0 to startingRes - 1
for y = 0 to startingRes - 1
x# = x * sResReciprocal#
y# = y * sResReciprocal#
height# = 0.0
Strength# = 1.0
`height# = Memblock Float( 1, ( x + y * startingRes ) * 4 )
for OctaveID = totalOctaves to 1 step -1
`for OctaveID = 7 to 7 step -1
octaveRes = startingRes / 2 ^ (octaveID - 1)
// Store the float pixel we are over on the current octave
memblockX# = x# * octaveRes
memblockY# = y# * octaveRes
// Store the int version for pixel sampling
memblockX = memblockX#
memblockY = memblockY#
// Get the local offset
memblockX# = memblockX# mod 1.0
memblockY# = memblockY# mod 1.0
If Sampling = 1
`BiCubic Sampling
sample1# = Sample( OctaveID, memblockX - 1, memblockY - 1, octaveRes )
sample2# = Sample( OctaveID, memblockX , memblockY - 1, octaveRes )
sample3# = Sample( OctaveID, memblockX + 1, memblockY - 1, octaveRes )
sample4# = Sample( OctaveID, memblockX + 2, memblockY - 1, octaveRes )
mHeight1# = CubicInterpolate( sample1#, sample2#, sample3#, sample4#, memblockX# )
sample1# = Sample( OctaveID, memblockX - 1, memblockY , octaveRes )
sample2# = Sample( OctaveID, memblockX , memblockY , octaveRes )
sample3# = Sample( OctaveID, memblockX + 1, memblockY , octaveRes )
sample4# = Sample( OctaveID, memblockX + 2, memblockY , octaveRes )
mHeight2# = CubicInterpolate( sample1#, sample2#, sample3#, sample4#, memblockX# )
sample1# = Sample( OctaveID, memblockX - 1, memblockY + 1, octaveRes )
sample2# = Sample( OctaveID, memblockX , memblockY + 1, octaveRes )
sample3# = Sample( OctaveID, memblockX + 1, memblockY + 1, octaveRes )
sample4# = Sample( OctaveID, memblockX + 2, memblockY + 1, octaveRes )
mHeight3# = CubicInterpolate( sample1#, sample2#, sample3#, sample4#, memblockX# )
sample1# = Sample( OctaveID, memblockX - 1, memblockY + 2, octaveRes )
sample2# = Sample( OctaveID, memblockX , memblockY + 2, octaveRes )
sample3# = Sample( OctaveID, memblockX + 1, memblockY + 2, octaveRes )
sample4# = Sample( OctaveID, memblockX + 2, memblockY + 2, octaveRes )
mHeight4# = CubicInterpolate( sample1#, sample2#, sample3#, sample4#, memblockX# )
mHeight# = CubicInterpolate( mHeight1#, mHeight2#, mHeight3#, mHeight4#, memblockY# )
Else
`BiLinear Sampling
sample1# = Sample( OctaveID, memblockX , memblockY, octaveRes )
sample2# = Sample( OctaveID, memblockX + 1, memblockY, octaveRes )
mHeightX# = Linear_Interpolate( sample1#, sample2#, memblockX# )
sample1# = Sample( OctaveID, memblockX , memblockY + 1, octaveRes)
sample2# = Sample( OctaveID, memblockX + 1, memblockY + 1, octaveRes)
mHeightY# = Linear_Interpolate( sample1#, sample2#, memblockX# )
mHeight# = Linear_Interpolate( mHeightX#, mHeightY#, memblockY# )
EndIf
height# = height# + mHeight# * Strength#
Strength# = Strength# * 0.5
next
height = (height# + minInv#) * _255DivRange#
if height > 255 then height = 255
if height < 0 then height = 0
Write Memblock Byte memblockID, 12 + ( x + y * startingRes ) * 4 , height // B
Write Memblock Byte memblockID, 12 + ( x + y * startingRes ) * 4 + 1, height // G
Write Memblock Byte memblockID, 12 + ( x + y * startingRes ) * 4 + 2, height // R
Write Memblock Byte memblockID, 12 + ( x + y * startingRes ) * 4 + 3, 255 // A
next
next
// Create image
Img = GetBlankImgNo()
Make Image From Memblock Img, memblockID
For octaveID = 1 to totalOctaves
Delete Memblock octaveID
Next octaveID
Delete Memblock totalOctaves + 1
Cls
EndFunction Img
Function Sample( memblockID, x, y, memblockRes )
if x < 0 then x = x + memblockRes
if y < 0 then y = y + memblockRes
if x > memblockRes-1 then x = x - memblockRes
if y > memblockRes-1 then y = y - memblockRes
returnValue# = Memblock Float( memblockID, ( x + y * memblockRes ) * 4 )
Endfunction returnValue#
Function Linear_Interpolate( a as float, b as float, x as float )
returnValue# = a * (1.0 - x) + b * x
Endfunction returnValue#
Function CubicInterpolate( aMinOne as float, a as float, b as float, bAddOne as float, acrossAB as float )
P as float
Q as float
R as float
S as float
P = (bAddOne - b) - (aMinOne - a)
Q = (aMinOne - a) - P
R = b - aMinOne
S = a
returnValue# = P * acrossAB ^ 3 + Q * acrossAB ^ 2 + R * acrossAB + S
EndFunction returnValue#
Function GenerateHeightScale()
Restore TextureColours:
For Y = 0 To 255
Read TextureLookup( Y )
Next Y
EndFunction
TextureColours:
Data 4278190215, 4278190216, 4278190472, 4278190729, 4278256522, 4278257035, 4278323084, 4278389134, 4278389903, 4278390929
Data 4278457235, 4278523798, 4278590361, 4278656923, 4278789278, 4278790305, 4278857381, 4278989479, 4279056555, 4279123630
Data 4279255986, 4279323062, 4279390138, 4279522493, 4279589569, 4279656644, 4279723464, 4279856075, 4279923150, 4279989970
Data 4280122325, 4280123608, 4280255964, 4280322782, 4280389088, 4280390372, 4280456933, 4280588520, 4280589290, 4280655851
Data 4280721901, 4280722415, 4280722927, 4280788464, 4280723441, 4280789233, 4280723441, 4280788977, 4280920303, 4280986094
Data 4281182701, 4281314282, 4281576679, 4281839331, 4282167520, 4282429916, 4282823640, 4283217619, 4283677133, 4284070856
Data 4284530370, 4284989884, 4285514933, 4286039984, 4286499497, 4286959011, 4287484060, 4288009110, 4288534160, 4288993674
Data 4289453188, 4289977982, 4290371960, 4290765939, 4291225199, 4291553386, 4291881829, 4292209762, 4292472415, 4292734811
Data 4292931673, 4293128790, 4293194325, 4293260117, 4293325652, 4293325651, 4293325652, 4293260116, 4293194579, 4293129043
Data 4292997714, 4292866641, 4292735569, 4292604240, 4292473167, 4292210766, 4292014413, 4291817291, 4291555146, 4291293001
Data 4291030599, 4290702917, 4290440516, 4290112834, 4289784896, 4289391422, 4289129021, 4288735546, 4288407865, 4288014390
Data 4287620916, 4287227698, 4286899760, 4286440750, 4286112811, 4285719337, 4285326119, 4284932645, 4284539171, 4284211489
Data 4283818015, 4283424541, 4283031066, 4282637593, 4282309911, 4281981972, 4281654035, 4281391889, 4280998416, 4280736014
Data 4280408332, 4280211466, 4279949065, 4279686920, 4279490311, 4279227910, 4279096837, 4278965764, 4278768899, 4278637826
Data 4278572289, 4278441217, 4278375681, 4278310144, 4278244608, 4278244352, 4278244352, 4278244353, 4278309632, 4278244097
Data 4278309376, 4278374657, 4278374402, 4278504962, 4278504962, 4278569731, 4278634756, 4278700037, 4278764805, 4278829830
Data 4278960647, 4279025416, 4279090185, 4279155210, 4279285515, 4279350284, 4279480844, 4279545614, 4279610638, 4279740943
Data 4279871248, 4279936017, 4280001043, 4280131348, 4280261652, 4280260886, 4280391446, 4280456471, 4280586776, 4280586521
Data 4280717082, 4280782106, 4280847131, 4280912156, 4280911900, 4280977180, 4281042461, 4281042206, 4281041949, 4281107230
Data 4281107229, 4281107230, 4281172766, 4281107230, 4281107230, 4281172767, 4281172767, 4281238559, 4281238560, 4281304353
Data 4281369889, 4281435427, 4281500964, 4281501221, 4281632294, 4281698343, 4281763881, 4281829419, 4281960748, 4282026542
Data 4282157871, 4282289202, 4282420531, 4282551861, 4282682936, 4282814266, 4282945596, 4283076926, 4283208513, 4283405380
Data 4283536709, 4283733577, 4283799371, 4283996494, 4284127825, 4284324691, 4284521558, 4284718425, 4284850012, 4285046878
Data 4285244002, 4285440869, 4285637736, 4285769067, 4285966190, 4286163057, 4286360180, 4286491255, 4286885245, 4287345029
Data 4287804813, 4288329877, 4288789660, 4289249188, 4289708715, 4290102706, 4290496696, 4290824894, 4291087555, 4291416008
Data 4291612875, 4291809998, 4291941329, 4292137939, 4292138452, 4292138196
*Edit* Oh yeah, uses an IanM plugin. Hope this is allowed!
My signature is NOT a moderator plaything! Stop changing it!