Saving a terrain made in blitz...Again

Blitz3D Forums/Blitz3D Beginners Area/Saving a terrain made in blitz...Again

I know I posted this problem a while back and tried some of your suggestions the best I could, so now I have this
terrain maker working and it saves a terrain but it saves
it with out any terrain detail. Neos wrote a function for me(thank you Neos) to save terains but it is just saving a flat plane. I don't have a clue why its not saving correctly. One thing I can say is that the saved terain does carry some of the detail just none of the hight changes. In other words it saves as a plain, but when viewed in wireframe mode I can see that it is adding vertices where the hills should be. I will try to put some screen shots in my next post but for now here is the code. Please help?
; ModifyTerrain Example
; ---------------------

Graphics3D 640,480
SetBuffer BackBuffer()
SeedRnd MilliSecs()

;Dim b3d_stack(100)
;Global b3dfile,b3d_tos


terra_size=64 ; initial size of terrain, and no. of grids segments, along each  side
x_scale=10 ; x scale of terrain
y_scale=50 ; y scale of terrain
z_scale=10 ; z scale of terrain
marker_x=terra_size/2 ; initial x position of marker
marker_z=terra_size/2 ; initial z position of marker
Global camangle





Global camera=CreateCamera()
PositionEntity camera,(terra_size*x_scale)/2,50,0 ; position wherever; just  try and get good view of terrain!
RotateEntity camera,30,0,0 ; again, try and get good view of terrain

lite=CreateLight(3)
RotateEntity lite,90,0,0
; Create terrain
Global terra=CreateTerrain(terra_size)
ScaleEntity terra,x_scale,y_scale,z_scale
 


;change texture button
cycle_tex = 3

;wall_texrure.bmp
;wall_tex = LoadTexture("data/wall_texture.bmp")
wall_tex = LoadTexture("_tex/wetanglebrickII.bmp")

EntityTexture terra,wall_tex
 

; Texture terrain
glassgrid_tex=LoadTexture("_tex/crossgrid.bmp")
;EntityTexture terra,grass_tex
;EntityAlpha terra,.5
brownstone_tex=LoadTexture("_tex/steelpannelgrid.bmp")
wetanglestone_tex=LoadTexture("_tex/wetanglebrickII.bmp")

; Create marker
 markerI=CreateSphere()
Global marker=markerI
ScaleEntity marker,1,1,1
EntityColor marker,255,0,0
	;Data marker_x
	;Data marker_y
	; Create array
; texture terrain-1.jpg
terrainA = LoadTexture("_tex/terrain-1.jpg")
ScaleTexture terrainA,4,4 
PointEntity lite,marker

Dim nums(9)


; Fill each element with a random number
For i = 0 To 9
nums(i) = Rand(1,10)
nums(i) = nums(i) + 1
Next

Global tracknum#
Global 	varX=Rnd(1,5)
Global	varY=Rnd(1,5)
Global	varZ=Rnd(1,5)
Global Markercube
 Markercube = LoadMesh("_tex/Dir_Box.b3d")
;RotateEntity Markercube,90,0,0
RotateEntity Markercube,0,0,90
ScaleEntity MarkerCube,.5,.5,.5 
;ScaleEntity Markercube,4.75,1,4.75
EntityColor MarkerCube,100,0,50
EntityAlpha MarkerCube,.5
Global Mode
Mode = 0
	
vertex_morph=True

leavelight = 0
cam_turn_speed=0
; Set initial uv scale values
u_scale#=1
v_scale#=1

;start of mainloopVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVVv
While Not KeyDown(1)

;entity free flight mode a second camera?




;light mode l key
If KeyHit (38) = True  Then leavelight = leavelight+ 1
If leavelight => 3 leavelight = 1
 If leavelight = 1 Then
	PositionEntity lite,EntityX(marker),EntityY(marker)+20,EntityZ(marker)+20
;PointEntity lite,marker
    End If 
 ;If leavelight = 2 Then
	

If KeyHit(74) Then ; press + to randomly change the 'cone' of light 
LightConeAngles lite, Rand(120),Rand(120)
LightRange lite,Rnd(1000,2000)
PointEntity lite,marker

End If


If KeyHit(79) Then 
LightColor lite,Rnd(-255,255),Rnd(-255,255),Rnd(-255,255)
;EntityColor marker,
End If
 
;check for change of texture

If KeyHit(78) = True Then cycle_tex = cycle_tex + 1
If cycle_tex > 5 Then cycle_tex = 1
		If cycle_tex = 1 Then EntityTexture terra,wall_tex 
		;If cycle_tex = 1 Then EntityAlpha terra,.5
		
		If cycle_tex = 2 Then EntityTexture terra,glassgrid_tex
		;If cycle_tex = 2 Then EntityAlpha terra,.5
		 
        If cycle_tex = 3 Then EntityTexture terra,terrainA
		;If cycle_tex = 3 Then EntityAlpha terra,1
		
		If cycle_tex = 4 Then EntityTexture terra,brownstone_tex
		If cycle_tex = 4 Then EntityAlpha terra,1
		If cycle_tex = 4 Then ScaleTexture brownstone_tex,2,2
		;up on numberpad = 72
		;down on mumberpad = 80
		;left on numberpad = 75
		;right on mumberpad = 77 
				If KeyDown( 80 )=True Then u_scale#=u_scale#-0.01 
				If KeyDown( 72 )=True Then u_scale#=u_scale#+0.01 
				If KeyDown( 75 )=True Then v_scale#=v_scale#-0.01 
				If KeyDown( 77 )=True Then v_scale#=v_scale#+0.01 

		; Scale texture 
		If cycle_tex = 4 Then ScaleTexture brownstone_tex,u_scale#,v_scale# 
		If cycle_tex = 1 Then ScaleTexture wall_tex,u_scale#,v_scale# 
 

		;If cycle_text = 5 Then EntityTexture terra,wetanglestone_tex
 		;If cycle_tex = 5 Then EntityAlpha terra,1
		;If cycle_tex = 5 Then ScaleTexture wetanglestone_tex,u_scale#,v_scale# 





;If KeyHit(78)=True Then 

; Change marker position values depending on cursor key pressed
If KeyDown(205)=True Then marker_x=marker_x+1
If KeyDown(203)=True Then marker_x=marker_x-1
If KeyDown(208)=True Then marker_z=marker_z-1
If KeyDown(200)=True Then marker_z=marker_z+1

If KeyHit(2) Then 
camangle = camangle + 1 
End If
If camangle => 6 Then camangle = 1
 
		
 
updatePosition(camera) 
;TurnEntity camera,0,0,cam_turn_speed
;if key hit spacebar then remember current marker position for manipulation
;call it marked point m_point
	
If KeyHit(57)=True Then 
	

	;markpoint
	
;startpoint
Gosub startData
Read somthing$ 
tracknum#=0+1


;Restore startData 
 
EndIf
 
	

;different efects
;different efects ;random terrain
If KeyHit(59) Then
Mode = 1
;get 3 random variables from a function
marker_Vars()
terra_detail=4000 

End If

If KeyHit(60)= True  Then enable=1-enable 

; Enable/disable wireframe rendering 
WireFrame enable 


 

If Mode = 3  Then

PositionEntity MarkerCube,EntityX(marker)-1.1,EntityY(marker)+1,EntityZ(marker)-.6
EndIf


; Get terrain height at marker position
marker_y#=TerrainHeight(terra,marker_x,marker_z)

; If A pressed then increase marker_y value and modify terrain
If KeyDown(30)=True
	If marker_y#<1 Then marker_y#=marker_y#+0.005
		If Mode = 0 Then
			ModifyTerrain terra,marker_x,marker_z,marker_y#
		EndIf

EndIf
If KeyHit(59)=True Then
 Mode = 1
EndIf
If KeyHit(60) = True Then
 Mode = 2
EndIf
If KeyHit(61) = True Then 
 Mode = 3
EndIf 
If KeyHit(62)=True Then
 Mode = 4
EndIf
If KeyHit(63)=True Then
 Mode = 5
EndIf
If Mode = 1 Then 
; Position marker, taking into account x, y and z scales of terrain
EntityColor marker,0,255,0
PositionEntity marker,marker_x*x_scale,marker_y#*y_scale,marker_z*z_scale

End If



If Mode = 3 Then
	EntityColor marker,255,0,0
	ModifyTerrain terra,marker_x,marker_z,marker_y#
	ModifyTerrain terra,marker_x-1,marker_z-1,marker_y#
	ModifyTerrain terra,marker_x-1,marker_z,marker_y#
	ModifyTerrain terra,marker_x,marker_z-1,marker_y#
EndIf
	
If Mode = 4 Then
	EntityColor marker,255,0,0
	ModifyTerrain terra,marker_x,marker_z,marker_y#
	ModifyTerrain terra,marker_x+1,marker_z+1,marker_y#
	ModifyTerrain terra,marker_x+1,marker_z,marker_y#
	ModifyTerrain terra,marker_x,marker_z+1,marker_y#
EndIf

If Mode = 5 Then
	EntityColor marker,255,0,0
	ModifyTerrain terra,marker_x,marker_z,marker_y#
	ModifyTerrain terra,marker_x-1,marker_z-1,marker_y#
	ModifyTerrain terra,marker_x-1,marker_z,marker_y#
	ModifyTerrain terra,marker_x,marker_z-1,marker_y#

	ModifyTerrain terra,marker_x,marker_z,marker_y#
	ModifyTerrain terra,marker_x+1,marker_z+1,marker_y#
	ModifyTerrain terra,marker_x+1,marker_z,marker_y#
	ModifyTerrain terra,marker_x,marker_z+1,marker_y#









EndIf








; If Z pressed then decrease marker_y value and modify terrain
If KeyDown(44)=True
If marker_y#>0 Then marker_y#=marker_y#-0.005
ModifyTerrain terra,marker_x,marker_z,marker_y#

EndIf

If KeyHit(28) Then
 ;Include "saveterrain.bb"
 ;Include "b3dfile.bb"
SaveTerrain( terra, filename$ )



End If
; Save the screen when player pushes F10

If KeyHit(10) Then
SaveBuffer(FrontBuffer(),"terain.bmp")

End If 

; Position marker, taking into account x, y and z scales of terrain
PositionEntity marker,marker_x*x_scale,marker_y#*y_scale,marker_z*z_scale


RenderWorld
Color 150,150,200
Text 0,0,"Use cursor keys to move marker over the terrain"
Text 0,20,"Press A or Z to alter height of terrain at marker's position"
Text 0,40,"Terrain Height: "+ marker_y
Text 0,60,somthing$ + marker_y
Text 0,70,(varX) 
Text 0,90,"Drawing_Mode :"+ Mode
Text 0,100,"cycle_tex" + cycle_tex
Text 400,0,"camangle ;" + camangle
Text 400,70,"leavelight" + leavelight
Text 0,120,"marker xyz: x: " +EntityX(marker)+" y: "+ EntityY(marker)+" z: "+EntityZ(marker)
Text 0,140,"MarkerCube xyz: x: " +EntityX(MarkerCube)+" y: "+ EntityY(MarkerCube)+" z: "+EntityZ(MarkerCube)


Flip

Wend

End
.startData
	Data 1 + "Tips? Press spacebare to see a small set of instructions."
	Data 2 + "keypresses; f1-f5 are drawing modes. + = changetexture "
	Data 3 + "- = change lightconeangle,shift = change camera angle"
	Data 4 + "f = toggle free light mode, esc = exit,1 on numberpad = changelightcolor"
	Data 5 + "control c= toggle freeflight mode or drawing mode." 
	Data 6 + "It just takes 1 tool to rule! F9 to save"
	Data 7 + " for now on data statments shoud be numberd"
	Data 8 + " need to figure out how to save a terrain made with this program"
	Data 9 + "marker placed"
	
Function updatePosition(camera) 

 
If camangle=1 Then 
PositionEntity camera,EntityX(marker),60,EntityZ(marker)-60
If camangle=1 Then PointEntity camera,marker
 
EndIf 
If camangle = 2 Then 
PositionEntity camera,EntityX(marker),120,EntityZ(marker) 
If camangle=2 Then PointEntity camera,marker

End If
If camangle = 3 Then
PositionEntity camera,EntityX(marker)-60,80,EntityZ(marker)-60
If camangle=3 Then PointEntity camera,marker
 
End If
If camangle = 4 Then
PositionEntity camera,EntityX(marker)-30,80,EntityZ(marker)
If camangle=4 Then PointEntity camera,marker
 
End If
If camangle = 5 Then
cam_speed = cam_speed + 1
 
	PositionEntity camera,EntityX(marker),80,EntityZ(marker) + cam_speed
 ;RotateEntity camera,0,-180,0

;PointEntity camera,marker
	 
 

End If
 
End Function

Function marker_Vars()

	varX=Rnd(1,20)
	varY=Rnd(1,3)
	varZ=Rnd(1,20)
	
	
End Function

;Function makebox()
;Mode = 3
;PositionEntity MarkerCube,EntityX(marker)+15,EntityY(marker),EntityZ(marker)+15
;End Function
;
;b3d file utils to be included
; this function provided by Neos on the blitz forums
Function SaveTerrain( terra ,filename$);xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
If terra = 0 Return False

	sze = TerrainSize(terra)	; width of terrain
	img = CreateImage(sze, sze)	; Create image used for heightmap

	buff = GraphicsBuffer()
	SetBuffer ImageBuffer(img)

	For x = 0 To (sze - 1)
		For y = 0 To (sze - 1)
			
			hgt# = Floor(TerrainHeight#(terra, x, y))
			Color hgt#, hgt#, hgt#
			Plot x, y
		Next
	Next

	SetBuffer buff

	SaveBuffer (ImageBuffer(img), "myterrain2.b3d")

	Return True

	
End Function



This code will run now I have disabled the texures and model
so you all can run it and check it out. It looks a lot better when its textured. If you want to run it here are the
official docs...
Do this first!
Press 1 on keypad to fix camera to the marker position.
arrow keys to move marker and camera
a and z to raise or lower terrain
f1 - f5 to change modes
f1 free roming mode (lets you move around without changing
the terrain.)
f2 wireframe veiw
f3 - f5 changes different drawing styles
1 on keypad again changes camera views
L = light position at marker position
- on numberpad to change lightrange and coneangles
1 on numberpad to change light color (randomly)
space bar for general help instructions (not finished yet but works 8 times)
esc to quit

The code still doesn't work, as your still loading them.

So basically, you saving your terrain, then loading it back in, but the mesh loads in as a flat plain?

I assume that's what your wanting, is to convert a terrain, into a mesh?

The Terrain starts as a flat plane When I begin the program.
Then I raise various points in the terrain to make it look like trenches or hills or whatever, what I want is to save the end result of the terrain as untextured landscape, not nessesarily a mesh. A hightmap would be better. Right now
Neos's function saves a.......somthin witch I can veiw in another program I made last night. The problem is its truncating the land scape when I save, (just in the saved version) so when I load it into another program all I get is a flat plain again. I want the landscape.
One interesting fact, is that the saved terrain does have a lot of extra vertices, wher the hills should be You Know what I meen?
In flat plane you only have 4 vertises right?

"So basically, you saving your terrain, then loading it back in, but the mesh loads in as a flat plain?"
Yes but I am not loading it back into the above program
just another one I made for viewing it. Heres that one.
Graphics3D 640,480
SetBuffer BackBuffer()
Global camera=CreateCamera()
lite=CreateLight(3)
RotateEntity lite,90,0,0
Global terra
glassgrid_tex=LoadTexture("_tex/crossgrid.bmp")
terra = LoadTerrain("myterrain2.b3d")
;EntityTexture terra,glassgrid_tex
PositionEntity terra,0,-20,0
PositionEntity camera, EntityX(terra)+20,EntityY(terra)+10,EntityZ(terra)-10
While Not KeyDown(1)
If KeyHit(57) = True Then enable=1-enable 
WireFrame enable 
 


RenderWorld

Flip

Wend

End


So, is this just to tough or impossible to do?
Is that why I can't seam to get many responces?

Am I excomunicated?
Is anyone out there?
Is it a laim question and I should already have it figured out?

Has anyone tried it out? If not Please do so now cuz it's cool.
I know probably bin done before, but not by me.

So can I get a Whomp-Whomp???

I think that the TerrainHeight() command returns values between 0 and 1, so in your save terrain function you need to multiple it with 255 to get a useable color out of it, Only a guess though:
Anyway try changing the line:
hgt# = Floor(TerrainHeight#(terra, x, y))

To:
hgt# = Floor(TerrainHeight#(terra, x, y))*255

Hope this helps.

I added that line and it works better but still not propper.
Now instead of saving it as a flat plain it is at least saving it with some of the terrain detail but only 1 unit
high. I found a save terrain funcion in the code archives
and it does the exact same thing.

.

A heightmap is grayscale with a range from 0-255, but when loaded with the "loadterrain" command is converted to values between 0-1. That is why if you are saving a terrain out as a heightmap you need to multiply by 255 as Jeppe expained.

When you have loaded the terrain then use the "scaleentity" command to set the scale of the terrain. The Y value determines how high the hills and how low the valleys.

I hope that helps somewhat.

Yep that helped lots. So it finaly works!
Also you just awnswered another queston I just posted.

Thanks all.

You're welcome. I'm glad that it helped, I wasn't sure it was what you were looking for.