Forgot i had this different version,shows how to add a detail map with set blend mapping on and it smoothes the normals of all the terrain objects so it gets rid of the faceted look.This is the version i use in the spline based race track editor from the wip forums,not even sure if i updated that post with this newer code yet.Hope it helps.
`quick landscape code
`all media generated at runtime
`======================
`P.Parkinson
`======================
`Main Source File
sync on
sync rate 60
autocam off
color backdrop 0, rgb(200,200,255)
set text font "Arial"
set text size 12
set text transparent
set ambient light 0
position camera 255,1000,-255
point camera 0,0,0
position light 0,1000,1000,-5000
set light range 0,2000
text 0,0,"Please Wait":sync:sync
type pointType
x as float
y as float
z as float
nx as float
ny as float
nz as float
num_normals as integer
endtype
global texture_size as integer=512``min 512 but 1024 or 2048 looks alot better but slower to make and 4096 is lovely
global gridSizeX as integer=256``keep these the same
global gridSizeZ as integer=256``keep these the same
global tileSize as integer=32
global max_height as integer=1000
dim land(gridSizeX,gridSizeZ) as pointType
dim temp(4096,4096) as float
dim tex(texture_size,texture_size)
global nx as float
global ny as float
global nz as float
make_landscape_texture()
hmap_fractal(256,0.00001)
for z=0 to gridSizeZ
for x=0 to gridSizeX
land(x,z).x = x*tileSize-(gridSizeX*tileSize/2):land(x,z).y=temp(x,z)*max_height:land(x,z).z = z*tileSize-(gridSizeZ*tileSize/2)
next x
next z
global num_obj as integer
num_obj=build_land()
target=1000
marker=2000
make object cube target,1
hide object target
make object sphere marker,10
color object marker,rgb(255,0,0)
ink rgb(255,255,255),0
position mouse screen width()/2,screen height()/2
dummy=mousemovex()
dummy=mousemovey()
bm=0
`*******main loop********
do
position object target,camera position x(),camera position y(),camera position z()
set object to camera orientation target
move object target,10000
hit=sc_raycast (0,camera position x(),camera position y(),camera position z(),object position x(target),object position y(target),object position z(target),0)
x#=sc_getstaticcollisionx()
y#=sc_getstaticcollisiony()
z#=sc_getstaticcollisionz()
obj=sc_getobjecthit()
if hit>0
position object marker,x#,y#,z#
else
position object marker,object position x(target),object position y(target),object position z(target)
endif
if hit>0 and spacekey() then scorch(x#,y#,z#,obj,sc_getfacehit())
MouseControl(2.0)
text 0,0,"FPS "+str$(screen fps())
text 0,15,"Mouse To Look Around , LMB/RMB to zoom In/Out"
text 0,30,"Space To Paint On Texture"
sync
loop
`*******Functions********
function MouseControl(Speed as float)
xrotate camera camera angle x()+mousemovey()
yrotate camera camera angle y()+mousemovex()
if mouseclick()=1 then move camera Speed
if mouseclick()=2 then move camera (0-Speed)
r=mousemovex()
r=mousemovey()
endfunction
function create_memblockobject(memnum,v)
make memblock memnum,12+(36*v)
write memblock dword memnum,0,338
write memblock dword memnum,4,36
write memblock dword memnum,8,v
endfunction
function create_vertex(memnum,v,vposx#,vposy#,vposz#,color as dword,u#,v#)
write memblock float memnum,v*36+12,vposx#
write memblock float memnum,v*36+16,vposy#
write memblock float memnum,v*36+20,vposz#
write memblock dword memnum,v*36+36,color
write memblock float memnum,v*36+40,u#
write memblock float memnum,v*36+44,v#
endfunction
function set_normal(memnum,v,normalx#,normaly#,normalz#)
write memblock float memnum,v*36+24,normalx#
write memblock float memnum,v*36+28,normaly#
write memblock float memnum,v*36+32,normalz#
endfunction
function build_land()
memblock_size=20*20*6
if memblock exist(10) then delete memblock 10
create_memblockobject(10,memblock_size)
calculate_normals()
obj=1
uv#=1.0/gridSizeX
for lz=0 to 15
for lx=0 to 15
v_num=0
for z=lz*16 to (lz+1)*16-1
for x=lx*16 to (lx+1)*16-1
create_vertex(10,v_num,land(x,z).x,land(x,z).y,land(x,z).z,rgb(255,255,255),x*uv#,z*uv#)
set_normal(10,v_num,land(x,z).nx,land(x,z).ny,land(x,z).nz):inc v_num
create_vertex(10,v_num,land(x,z+1).x,land(x,z+1).y,land(x,z+1).z,rgb(255,255,255),x*uv#,(z+1)*uv#)
set_normal(10,v_num,land(x,z+1).nx,land(x,z+1).ny,land(x,z+1).nz):inc v_num
create_vertex(10,v_num,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,rgb(255,255,255),(x+1)*uv#,(z+1)*uv#)
set_normal(10,v_num,land(x+1,z+1).nx,land(x+1,z+1).ny,land(x+1,z+1).nz):inc v_num
create_vertex(10,v_num,land(x,z).x,land(x,z).y,land(x,z).z,rgb(255,255,255),x*uv#,z*uv#)
set_normal(10,v_num,land(x,z).nx,land(x,z).ny,land(x,z).nz):inc v_num
create_vertex(10,v_num,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,rgb(255,255,255),(x+1)*uv#,(z+1)*uv#)
set_normal(10,v_num,land(x+1,z+1).nx,land(x+1,z+1).ny,land(x+1,z+1).nz):inc v_num
create_vertex(10,v_num,land(x+1,z).x,land(x+1,z).y,land(x+1,z).z,rgb(255,255,255),(x+1)*uv#,z*uv#)
set_normal(10,v_num,land(x+1,z).nx,land(x+1,z).ny,land(x+1,z).nz):inc v_num
next x
next z
make mesh from memblock 1,10
make object obj,1,0
set object texture obj,2,0
texture object obj,0,11
sc_setupcomplexobject obj,0,2
inc obj
next lx
next lz
dec obj
`adds a second set of uv co ordinates to the objects allowing the
`set blend mapping on to work corectly
for l=1 to obj
lock vertexdata for limb l,0
for v=0 to get vertexdata vertex count()-1
set vertexdata uv v,1,get vertexdata u(v,0)*200.0,get vertexdata v(v,0)*200.0
next v
unlock vertexdata
next l
make_detail_texture()
for l=1 to obj
set blend mapping on l,1,20,0,4
next l
endfunction obj
function calculate_normals()
for lz=0 to 15
for lx=0 to 15
for z=lz*16 to (lz+1)*16-1
for x=lx*16 to (lx+1)*16-1
calc_normal(land(x,z).x,land(x,z).y,land(x,z).z,land(x,z+1).x,land(x,z+1).y,land(x,z+1).z,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z)
land(x,z+1).nx=nx:land(x,z+1).ny=ny:land(x,z+1).nz=nz
inc land(x,z+1).num_normals
calc_normal(land(x,z+1).x,land(x,z+1).y,land(x,z+1).z,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,land(x,z).x,land(x,z).y,land(x,z).z)
land(x+1,z+1).nx=nx:land(x+1,z+1).ny=ny:land(x+1,z+1).nz=nz
inc land(x+1,z+1).num_normals
calc_normal(land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,land(x,z).x,land(x,z).y,land(x,z).z,land(x,z+1).x,land(x,z+1).y,land(x,z+1).z)
land(x,z).nx=nx:land(x,z).ny=ny:land(x,z).nz=nz
inc land(x,z).num_normals
calc_normal(land(x,z).x,land(x,z).y,land(x,z).z,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,land(x+1,z).x,land(x+1,z).y,land(x+1,z).z)
land(x+1,z+1).nx=nx:land(x+1,z+1).ny=ny:land(x+1,z+1).nz=nz
inc land(x+1,z+1).num_normals
calc_normal(land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z,land(x+1,z).x,land(x+1,z).y,land(x+1,z).z,land(x,z).x,land(x,z).y,land(x,z).z)
land(x+1,z).nx=nx:land(x+1,z).ny=ny:land(x+1,z).nz=nz
inc land(x+1,z).num_normals
calc_normal(land(x+1,z).x,land(x+1,z).y,land(x+1,z).z,land(x,z).x,land(x,z).y,land(x,z).z,land(x+1,z+1).x,land(x+1,z+1).y,land(x+1,z+1).z)
land(x,z).nx=nx:land(x,z).ny=ny:land(x,z).nz=nz
inc land(x,z).num_normals
next x
next z
next lx
next lz
for lz=0 to gridSizeZ
for lx=0 to gridSizex
land(lx,lz).nx=land(lx,lz).nx/land(lx,lz).num_normals
land(lx,lz).ny=land(lx,lz).ny/land(lx,lz).num_normals
land(lx,lz).nz=land(lx,lz).nz/land(lx,lz).num_normals
next lx
next lz
endfunction
function calc_normal(Ax#,Ay#,Az#,Bx#,By#,Bz#,Cx#,Cy#,Cz#)
ux#=Bx#-Ax#
uy#=By#-Ay#
uz#=Bz#-Az#
vx#=Cx#-Ax#
vy#=Cy#-Ay#
vz#=Cz#-Az#
nx=(uy#*vz#)-(uz#*vy#)
ny=(uz#*vx#)-(ux#*vz#)
nz=(ux#*vy#)-(uy#*vx#)
endfunction
function hmap_fractal(size,n#)
`thanks to who ever did this code,had it so long,and it never fails to work for me
av as float
rn as float:rn=n#
s=size ` units and array size; must be a power of 2
dim a(s,s,1) as float
` do the diamond square algorithm
` paying special attention to wrapping around
c=s
repeat
for z=0 to (s-c) step c
for x=0 to (s-c) step c
av=(a(x,z)+a(x+c,z)+a(x,z+c)+a(x+c,z+c))/4.0
av=av+((-50+rnd(100))/rn)
a(x+(c/2),z+(c/2))=av
next x
next z
w=1
for z=0 to (s-(c/2)) step (c/2)
for x=0 to (s-c) step c
x2=x+(w*(c/2))
av=a(x2,z+(c/2))+a(x2+(c/2),z)
if x2=0
av=av+a(s-(c/2),z)
else
av=av+a(x2-(c/2),z)
endif
if z=0
av=av+a(x2,s-(c/2))
else
av=av+a(x2,z-(c/2))
endif
av=av/4.0
av=av+((-50+rnd(100))/rn)
a(x2,z,0)=av
if x2=0 then a(s,z,0)=av
if z=0 then a(x2,s,0)=av
next x
w=1-w
next z
c=c/2
rn=rn*2.0
until c < 2
`find min/max height
minh#=500000:maxh#=-500000
for z=0 to size
for x=0 to size
a(z,x,0)=a(z,x,0)
if a(x,z,0)<minh# then minh#=a(x,z,0)
if a(x,z,0)>maxh# then maxh#=a(x,z,0)
next x
next z
`update data array and raise it up so the lowest point is>=0 and find new max height then set all heights to 0 to 255 range
maxh#=-500000
for z=0 to size
for x=0 to size
av=a(x,z,0)
if minh#<0 then temp(x,z) = av+abs(minh#)
if minh#>=0 then temp(x,z) = av-minh#
if temp(x,z)>maxh# then maxh#=temp(x,z)
next x
next z
newh#=1.0/maxh#
for z=0 to size
for x=0 to size
temp(x,z)=temp(x,z)*newh#
next x
next z
endfunction
function make_sprite(r#,g#,b#,image_num)
if bitmap exist(1) then delete bitmap 1
create bitmap 1,128,128
set current bitmap 1
set image colorkey 0,0,0
for l=1 to 1000
x=rnd(128)
z=rnd(128)
dot x,z,rgb(r#,g#,b#)
next l
for l=1 to 1000
x=rnd(128)
z=rnd(128)
col#=rnd(30)
r2#=r#+col#
if r2#>255 then r2#=255
if r2#<0 then r2#=0
g2#=g#+col#
if g2#>255 then g2#=255
if g2#<0 then g2#=0
b2#=b#+col#
if b2#>255 then b2#=255
if b2#<0 then b2#=0
dot x,z,rgb(r2#,g2#,b2#)
next l
for l=1 to 100
x=rnd(128)
z=rnd(128)
col#=rnd(50)+50
r2#=col#
g2#=col#
b2#=col#
dot x,z,rgb(r2#,g2#,b2#)
next l
get image image_num,0,0,128,128
set current bitmap 0
endfunction
function make_landscape_texture()
progress_bar("Making Landscape Texture",0)
`sand grass rock
make_sprite(235,180,50,1000):sprite 1,-128,-128,1000
make_sprite(205,128,50,1001):sprite 2,-128,-128,1001
make_sprite(128,50,50,1002):sprite 3,-128,-128,1002
make_sprite(0,200,0,1003):sprite 4,-128,-128,1003
make_sprite(0,128,0,1004):sprite 5,-128,-128,1004
make_sprite(0,50,0,1005):sprite 6,-128,-128,1005
make_sprite(30,30,30,1006):sprite 7,-128,-128,1006
make_sprite(70,70,70,1007):sprite 8,-128,-128,1007
make_sprite(120,120,120,1008):sprite 9,-128,-128,1008
make_sprite(170,170,170,1009):sprite 10,-128,-128,1009
make_sprite(220,220,220,1010):sprite 11,-128,-128,1010
make_sand_texture(1,texture_size)
make_grass_texture(2,texture_size)
make_rock_texture(3,texture_size)
hmap_fractal(texture_size,0.1)
progress_bar("Making Landscape Texture",20)
`transfer ´temp´ array to ´tex´ array
for z=0 to texture_size
for x=0 to texture_size
tex(x,z)=temp(x,z)*255.0
next x
next z
create bitmap 1,texture_size,texture_size
make memblock from bitmap 1,1
delete bitmap 1
pos=12
for y=1 to texture_size
for x=1 to texture_size
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,255
inc pos
next x
next y
make image from memblock 4,1
delete memblock 1
progress_bar("Making Landscape Texture",60)
hmap_fractal(texture_size,0.1)
`transfer ´temp´ array to ´tex´ array
for z=0 to texture_size
for x=0 to texture_size
tex(x,z)=temp(x,z)*255.0
next x
next z
create bitmap 1,texture_size,texture_size
make memblock from bitmap 1,1
delete bitmap 1
pos=12
for y=1 to texture_size
for x=1 to texture_size
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,tex(x,y)
inc pos
write memblock byte 1,pos,255
inc pos
next x
next y
make image from memblock 5,1
delete memblock 1
progress_bar("Making Landscape Texture",80)
blend_images(1,2,4,10,texture_size,texture_size)
blend_images(10,3,5,11,texture_size,texture_size)
delete image 1
delete image 2
delete image 3
delete image 4
delete image 5
delete image 10
endfunction
function progress_bar(text$,p#)
cls
text 1,0,text$
ink rgb(0,0,100),0
box 19,19,121,41
ink rgb(125,125,255),0
box 20,20,20+p#,40
sync
endfunction
function blend_Images( iUpper, iLower, iAlpha, iResult, Width, Height)
`Dont know the author of this but thanks for great piece of code
Local Percent as float
Local UpperBlue as byte
Local UpperGreen as byte
Local UpperRed as byte
Local LowerBlue as byte
Local LowerGreen as byte
Local LowerRed as byte
Local ResultBlue as byte
Local ResultGreen as byte
Local ResultRed as byte
Local mUpper as integer
Local mLower as integer
Local mAlpha as integer
Local mResult as integer
mUpper = find free memblock(1,10)
mLower = find free memblock(11,10)
mAlpha = find free memblock(21,10)
mResult = find free memblock(31,10)
make memblock from image mUpper,iUpper
make memblock from image mLower,iLower
make memblock from image mAlpha,iAlpha
make memblock from image mResult,iUpper
mbSize = get memblock size(mUpper)
for Pos = 12 to mbSize - 12 step 4
Percent = (memblock byte(mAlpha,Pos)/255.0)
UpperBlue = memblock byte(mUpper,Pos+0)
UpperGreen = memblock byte(mUpper,Pos+1)
UpperRed = memblock byte(mUpper,Pos+2)
LowerBlue = memblock byte(mLower,Pos+0)
LowerGreen = memblock byte(mLower,Pos+1)
LowerRed = memblock byte(mLower,Pos+2)
ResultBlue = UpperBlue*(1-Percent)+LowerBlue*Percent
ResultGreen = UpperGreen*(1-Percent)+LowerGreen*Percent
ResultRed = UpperRed*(1-Percent)+LowerRed*Percent
write memblock byte mResult,Pos+0,ResultBlue
write memblock byte mResult,Pos+1,ResultGreen
write memblock byte mResult,Pos+2,ResultRed
write memblock byte mResult,Pos+3,255
next Pos
make image from memblock iResult, mResult
delete memblock mUpper
delete memblock mLower
delete memblock mAlpha
delete memblock mResult
endfunction
function make_sand_texture(img,size)
if bitmap exist(img) then delete bitmap img
create bitmap img,size,size
set current bitmap img
for z=0 to size step 8
for x= 0 to size step 8
num=rnd(100)
if num<33
rotate sprite 1,rnd(90)
paste sprite 1,x,z
endif
if num>=33 and num<66
rotate sprite 2,rnd(90)
paste sprite 2,x,z
endif
if num>=66
rotate sprite 3,rnd(90)
paste sprite 3,x,z
endif
next x
next z
get image img,0,0,size,size
set current bitmap 0
delete bitmap img
endfunction
function make_grass_texture(img,size)
if bitmap exist(img) then delete bitmap img
create bitmap img,size,size
set current bitmap img
for z=0 to size step 8
for x= 0 to size step 8
num=rnd(100)
if num<33
rotate sprite 4,rnd(90)
paste sprite 4,x,z
endif
if num>=33 and num<66
rotate sprite 5,rnd(90)
paste sprite 5,x,z
endif
if num>=66
rotate sprite 6,rnd(90)
paste sprite 6,x,z
endif
next x
next z
get image img,0,0,size,size
set current bitmap 0
delete bitmap img
endfunction
function make_rock_texture(img,size)
if bitmap exist(img) then delete bitmap img
create bitmap img,size,size
set current bitmap img
for z=0 to size step 8
for x= 0 to size step 8
num=rnd(100)
if num<33
rotate sprite 7,rnd(90)
paste sprite 7,x,z
endif
if num>=33 and num<66
rotate sprite 8,rnd(90)
paste sprite 8,x,z
endif
if num>=66
rotate sprite 9,rnd(90)
paste sprite 9,x,z
endif
next x
next z
get image img,0,0,size,size
set current bitmap 0
delete bitmap img
endfunction
function scorch(x#,y#,z#,obj,poly)
lock vertexdata for limb obj,0
vert=poly*3
u1#=get vertexdata u(vert)
v1#=get vertexdata v(vert)
u2#=get vertexdata u(vert+1)
v2#=get vertexdata v(vert+1)
u3#=get vertexdata u(vert+2)
v3#=get vertexdata v(vert+2)
u#=(u1#+u2#+u3#)/3.0
v#=(v1#+v2#+v3#)/3.0
unlock vertexdata
paint_on_image(11,u#,v#,255,0,0)
endfunction
function Distance3D( x1# as float, y1# as float, z1# as float, x2# as float, y2# as float, z2# as float )
distance# = Abs(Sqrt((x1# - x2#) ^ 2 + (y1# - y2#) ^ 2 + (z1# - z2#) ^ 2))
endfunction distance#
function paint_on_image(img,u#,v#,r,g,b)
make memblock from image 1,img
delete image img
x=texture_size*u#
y=texture_size*v#
pos=12+(x+y*texture_size)*4
write memblock byte 1,pos,b
write memblock byte 1,pos+1,g
write memblock byte 1,Pos+2,r
x=texture_size*u#
y=texture_size*v#
inc x
if x<=texture_size
pos=12+(x+y*texture_size)*4
write memblock byte 1,pos,b
write memblock byte 1,pos+1,g
write memblock byte 1,Pos+2,r
endif
x=texture_size*u#
y=texture_size*v#
dec x
if x>=0
pos=12+(x+y*texture_size)*4
write memblock byte 1,pos,b
write memblock byte 1,pos+1,g
write memblock byte 1,Pos+2,r
endif
x=texture_size*u#
y=texture_size*v#
inc y
if y<=texture_size
pos=12+(x+y*texture_size)*4
write memblock byte 1,pos,b
write memblock byte 1,pos+1,g
write memblock byte 1,Pos+2,r
endif
x=texture_size*u#
y=texture_size*v#
dec y
if y>=0
pos=12+(x+y*texture_size)*4
write memblock byte 1,pos,b
write memblock byte 1,pos+1,g
write memblock byte 1,Pos+2,r
endif
make image from memblock img,1
for obj=1 to num_obj
texture object obj,img
next obj
delete memblock 1
endfunction
function make_detail_texture()
cls
box 0,0,64,64,rgb(255,255,255)
for l=0 to 2000
col=rnd(150)
dot rnd(64),rnd(64),rgb(0,100+col,0)
next l
for l=0 to 2000
col=rnd(150)
dot rnd(64),rnd(64),rgb(50+col,col,0)
next l
for l=0 to 4000
col=rnd(150)
dot rnd(64),rnd(64),rgb(col,col,col)
next l
get image 20,0,0,64,64
cls
endfunction
link to the track editor WIP if you missed it
http://forum.thegamecreators.com/?m=forum_view&t=158864&b=8