Code: Select all
EnableExplicit
; <<<<<<<<<<<<<<<<<<<<<
; <<<< <<<<
; <<<< Enums <<<<
; <<<< <<<<
; <<<<<<<<<<<<<<<<<<<<<
#Width = 513
#Height = 513
; <<<<<<<<<<<<<<<<<<<
; <<<< <<<<
; <<<< Map <<<<
; <<<< <<<<
; <<<<<<<<<<<<<<<<<<<
Procedure MapHeightGet ( Array Map ( 2 ) , X , Y )
If X => 1 And X <= #Width
If Y => 1 And Y <= #Height
ProcedureReturn Map ( X , Y )
EndIf
EndIf
EndProcedure
Procedure MapHeightSet ( Array Map ( 2 ) , X , Y , Value )
If Value < 0
Value = 0
ElseIf Value > 255
Value = 255
EndIf
If X => 1 And X <= #Width
If Y => 1 And Y <= #Height
Map ( X , Y ) = Value
EndIf
EndIf
EndProcedure
Procedure MapDrawGrayscale ( Array Map ( 2 ) , Image )
Protected X , Y , Color
If StartDrawing ( ImageOutput ( Image ) )
For Y = 1 To #Height
For X = 1 To #Width
Color = MapHeightGet ( Map ( ) , X , Y )
Plot ( X , Y , RGB ( Color , Color , Color ) )
Next
Next
StopDrawing ( )
EndIf
EndProcedure
Procedure MapDrawColor ( Array Map ( 2 ) , Image )
Protected X , Y , Z , Color
If StartDrawing ( ImageOutput ( Image ) )
For Y = 1 To #Height
For X = 1 To #Width
Z = MapHeightGet ( Map ( ) , X , Y )
Select Z
; Water
Case 0 To 15 : Color = RGB ( 0 , 0 , 100 )
Case 16 To 31 : Color = RGB ( 0 , 0 , 120 )
Case 32 To 63 : Color = RGB ( 0 , 0 , 140 )
; Beach
Case 64 To 70 : Color = RGB ( 64 , 95 , 134 )
Case 71 To 95 : Color = RGB ( 128 , 190 , 128 )
Case 96 To 127 : Color = RGB ( 140 , 210 , 140 )
; Lowland
Case 128 To 159 : Color = RGB ( 160 , 210 , 140 )
Case 160 To 180 : Color = RGB ( 180 , 210 , 140 )
Case 181 To 199 : Color = RGB ( 190 , 220 , 150 )
; Hills
Case 200 To 219 : Color = RGB ( 185 , 185 , 130 )
Case 220 To 229 : Color = RGB ( 182 , 177 , 130 )
Case 230 To 239 : Color = RGB ( 180 , 170 , 130 )
; Mountains
Case 240 To 244 : Color = RGB ( 215 , 215 , 215 )
Case 245 To 249 : Color = RGB ( 230 , 230 , 230 )
Case 250 To 253 : Color = RGB ( 250 , 250 , 250 )
Case 254 To 255 : Color = RGB ( 255 , 255 , 255 )
EndSelect
Plot ( X , Y , Color )
Next
Next
StopDrawing ( )
EndIf
EndProcedure
; <<<<<<<<<<<<<<<<<<<<<<<<<
; <<<< <<<<
; <<<< Heightmap <<<<
; <<<< <<<<
; <<<<<<<<<<<<<<<<<<<<<<<<<
Procedure HeightmapInvert ( Array Map ( 2 ) )
Protected X , Y
For Y = 1 To #Height
For X = 1 To #Width
MapHeightSet ( Map ( ) , X , Y , 255 - MapHeightGet ( Map ( ) , X , Y ) )
Next
Next
EndProcedure
Procedure HeightmapBlur ( Array Map ( 2 ) )
Protected X , CX
Protected Y , CY
Protected Z
For Y = 3 To #Height - 4
For X = 3 To #Width - 4
For CY = Y - 2 To Y + 2
For CX = X - 2 To X + 2
Z + MapHeightGet ( Map ( ) , CX , CY )
Next
Next
MapHeightSet ( Map ( ) , X , Y , Z / 25 )
Z = 0
Next
Next
EndProcedure
Procedure HeightmapNoise ( Array Map ( 2 ) , Amount , Intensity )
Protected X
Protected Y
Protected Z
Protected Q
Protected Alpha . f
Protected Omega . f
If Amount < 0
Amount = 0
ElseIf Amount > 255
Amount = 255
EndIf
If Intensity < 0
Intensity = 0
ElseIf Intensity > 255
Intensity = 255
EndIf
Alpha = Intensity
Omega = 255 - Alpha
For Y = 1 To #Height
For X = 1 To #Width
If Random ( 255 ) < Amount
Z = MapHeightGet ( Map ( ) , X , Y )
Q = Z + ( Intensity - Random ( Intensity ) )
If Q < 0
Q = 0
ElseIf Q > 255
Q = 255
EndIf
Z = ( Z * Alpha + Q * Omega ) / 256
MapHeightSet ( Map ( ) , X , Y , Z )
EndIf
Next
Next
EndProcedure
Procedure HeightmapNormalize ( Array Map ( 2 ) , Threshold , Amount . f )
Protected X
Protected Y
Protected Z
If Amount < 0.0
Amount = 0.0
ElseIf Amount > 1.0
Amount = 1.0
EndIf
If Threshold < 0
Threshold = 0
ElseIf Threshold > 255
Threshold = 255
EndIf
For Y = 1 To #Height
For X = 1 To #Width
Z = MapHeightGet ( Map ( ) , X , Y )
If Z > Threshold
Z - ( Z - Threshold ) * Amount
ElseIf Z < Threshold
Z + ( Threshold - Z ) * Amount
EndIf
If Z < 0
Z = 0
ElseIf Z > 255
Z = 255
EndIf
MapHeightSet ( Map ( ) , X , Y , Z )
Next
Next
EndProcedure
Procedure HeightmapDivider ( Array Map ( 2 ) , X . f , Y . f , Width . f , Height . f , C1 . f , C2 . f , C3 . f , C4 . f )
Protected Edge1 . f
Protected Edge2 . f
Protected Edge3 . f
Protected Edge4 . f
Protected Middle . f
Protected NewWidth . f = Width / 2
Protected NewHeight . f = Height / 2
Protected Displacement . f
Protected Weight . f
If Width > 2 Or Height > 2
Displacement = ( Random ( 1 ) - 0.5 ) * ( ( NewWidth + NewHeight ) / ( #Width + #Height ) * 3 )
Middle = ( C1 + C2 + C3 + C4 ) / 4 + Displacement
Edge1 = ( C1 + C2 ) / 2
Edge2 = ( C2 + C3 ) / 2
Edge3 = ( C3 + C4 ) / 2
Edge4 = ( C4 + C1 ) / 2
If Middle < 0.0
Middle = 0.0
ElseIf Middle > 1.0
Middle = 1.0
EndIf
HeightmapDivider ( Map ( ) , X , Y , NewWidth , NewHeight , C1 , Edge1 , Middle , Edge4 )
HeightmapDivider ( Map ( ) , X + NewWidth , Y , NewWidth , NewHeight , Edge1 , C2 , Edge2 , Middle )
HeightmapDivider ( Map ( ) , X + NewWidth , Y + NewHeight , NewWidth , NewHeight , Middle , Edge2 , C3 , Edge3 )
HeightmapDivider ( Map ( ) , X , Y + NewHeight , NewWidth , NewHeight , Edge4 , Middle , Edge3 , C4 )
Else
Weight = ( C1 + C2 + C3 + C4 ) / 4
MapHeightSet ( Map ( ) , Int ( X ) , Int ( Y ) , Weight * 255 )
EndIf
EndProcedure
Procedure HeightmapCreate ( Array Map ( 2 ) )
Protected Width = ArraySize ( Map ( ) , 1 )
Protected Height = ArraySize ( Map ( ) , 2 )
Protected C1 . f = Random ( 1 )
Protected C2 . f = Random ( 1 )
Protected C3 . f = Random ( 1 )
Protected C4 . f = Random ( 1 )
HeightmapDivider ( Map ( ) , 1 , 1 , Width , Height , C1 , C2 , C3 , C4 )
EndProcedure
; <<<<<<<<<<<<<<<<<<<<
; <<<< <<<<
; <<<< Main <<<<
; <<<< <<<<
; <<<<<<<<<<<<<<<<<<<<
DisableExplicit
Dim Map ( #Width , #Height )
HeightmapCreate ( Map ( ) )
CreateImage ( 0 , #Width , #Height )
OpenWindow ( 0 , 0 , 0 , #Width , #Height , "Heightmap" , #PB_Window_SystemMenu | #PB_Window_ScreenCentered )
Mode = #True
MapDrawColor ( Map ( ) , 0 )
ImageGadget ( 0 , WindowWidth ( 0 ) / 2 - ImageWidth ( 0 ) / 2 , WindowHeight ( 0 ) / 2 - ImageHeight ( 0 ) / 2 , 0 , 0 , ImageID ( 0 ) )
AddKeyboardShortcut ( 0 , #PB_Shortcut_Return , 0 )
AddKeyboardShortcut ( 0 , #PB_Shortcut_1 , 1 )
AddKeyboardShortcut ( 0 , #PB_Shortcut_2 , 2 )
AddKeyboardShortcut ( 0 , #PB_Shortcut_N , 3 ) ; Normalize
AddKeyboardShortcut ( 0 , #PB_Shortcut_Z , 4 ) ; Noise
AddKeyboardShortcut ( 0 , #PB_Shortcut_B , 5 ) ; Blur
AddKeyboardShortcut ( 0 , #PB_Shortcut_I , 6 ) ; Invert
Repeat
Event = WaitWindowEvent ( )
If Event = #PB_Event_Menu
Select EventMenu ( )
Case 0
HeightmapCreate ( Map ( ) )
Draw = #True
Case 1
Mode = #False
Draw = #True
Case 2
Mode = #True
Draw = #True
Case 3
HeightmapNormalize ( Map ( ) , 160 , 0.05 )
Draw = #True
Case 4
HeightmapNoise ( Map ( ) , 128 , 2 )
Draw = #True
Case 5
HeightmapBlur ( Map ( ) )
Draw = #True
Case 6
HeightmapInvert ( Map ( ) )
Draw = #True
EndSelect
If Draw
If Mode
MapDrawColor ( Map ( ) , 0 )
Else
MapDrawGrayscale ( Map ( ) , 0 )
EndIf
Draw = #False
EndIf
SetGadgetState ( 0 , ImageID ( 0 ) )
EndIf
Until Event = #PB_Event_CloseWindow
Edit: Updated the code to add more functionality, you can now add noise, invert, blur and normalize the heightmap, by using Z, I, B, and N -keys.