Hello,
Been playing with the idea of LOD lately and I love big/endless worlds so used the vertexdata commands to have an automatically updating terrain mesh with different levels of detail further from the camera. Significantly reduces the number of vertices needed for big terrains (i.e. 512x512, 1024x1024) and gives great speed.
As yet to add height, texturing and normalisation to the code but should be very simple.
look with mouse and move forward/back with LMB/RMB. Hope it is informative. Will post updates soon.
` LOD Terrain
` setup
sync on: sync rate 0
autocam off:set camera range 1,100000
` LOD terrain data
global LODT_levels
global LODT_size
global LODT_tsize#
global LODT_obj
LODT_size=512
LODT_tsize#=100
LODT_obj=1
LODT_levels=5
dim LODT_dist(LODT_levels)
` define distances
LODT_dist(1)=10
LODT_dist(2)=30
LODT_dist(3)=40
LODT_dist(4)=80
LODT_dist(5)=600
` make LOD terrain mesh
LODT_make_terrain()
set object cull LODT_obj,0
set object wireframe LODT_obj,1
position camera -100,100,-100:point camera 600,0,600
` loop
do
position mouse 20,20
set cursor 0,0:print screen fps()
ax#=wrapvalue(ax#+mousemovey())
ay#=wrapvalue(ay#+mousemovex())
rotate camera ax#,ay#,0
if mouseclick()=1 then move camera 20
if mouseclick()=2 then move camera -20
if it>60 then LODT_update(camera position x(), camera position z()): it=0
inc it
sync
loop
` LOD_terrain functions
` make LOD terrain mesh
function LODT_make_terrain()
` free mem
mem=0
repeat:inc mem:until memblock exist(mem)=0
` free mesh
mesh=0
repeat:inc mesh:until mesh exist(mesh)=0
` polys count
dim minx(LODT_levels)
dim maxx(LODT_levels)
dim minz(LODT_levels)
dim maxz(LODT_levels)
polys=0
px=int(LODT_size/2)
pz=px
for n=1 to LODT_levels
` define min/max
minx(n)=px-LODT_dist(n)
maxx(n)=px+LODT_dist(n)
minz(n)=pz-LODT_dist(n)
maxz(n)=pz+LODT_dist(n)
` fit
nstep=(2^(n-1))
minx(n)=int(minx(n)/(2*nstep))*nstep*2
maxx(n)=int(maxx(n)/(2*nstep))*nstep*2+nstep
minz(n)=int(minz(n)/(2*nstep))*nstep*2
maxz(n)=int(maxz(n)/(2*nstep))*nstep*2+nstep
` limit min/max
if minx(n)<0 then minx(n)=0
if maxx(n)>LODT_size then maxx(n)=LODT_size
if minz(n)<0 then minz(n)=0
if maxz(n)>LODT_size then maxz(n)=LODT_size
` count
for x=minx(n) to maxx(n) step nstep
for z=minz(n) to maxz(n) step nstep
` check flag
flag=0
if n=1
polys=polys+2
else
if x<minx(n-1) or x>=maxx(n-1) or z<minz(n-1) or z>=maxz(n-1) then polys=polys+2
endif
next z
next x
next n
` undim
undim minx(0)
undim maxx(0)
undim minz(0)
undim maxz(0)
` make memblock
`polys=2*LODT_size^2
LODT_verts=polys*3
size=(polys*36*3)+12
make memblock mem,size
write memblock dword mem,0,338
write memblock dword mem,4,36
write memblock dword mem,8,polys*3
` make mesh from memblock
make mesh from memblock mesh,mem
` set memblock data pos
p=0
` position vertices
lock vertexdata for mesh mesh
for x=1 to LODT_size
for z=1 to LODT_size
` 1
pos=p
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,0,1
` 2
pos=p+1
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,1,0
` 3
pos=p+2
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,1,1
` 4
pos=p+3
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,0,1
` 5
pos=p+4
set vertexdata position pos,(x-1)*tsx#,0.000,(z)*tsz#
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,0,0
` 6
pos=p+5
set vertexdata normals pos,0,1,0
set vertexdata diffuse pos,rgb(255,255,255)
set vertexdata uv pos,1,0
p=p+6
next z
next x
` end
unlock vertexdata
` object
make object LODT_obj,mesh,0
endfunction
` update LOD terrain
function LODT_update(px#,pz#)
` temporary max min
dim minx(LODT_levels)
dim maxx(LODT_levels)
dim minz(LODT_levels)
dim maxz(LODT_levels)
` define position in tiles
px=int(px#/LODT_tsize#)
pz=int(pz#/LODT_tsize#)
` define basevertex var
pos=0
` make flag
flag=0
` loop through levels
lock vertexdata for limb LODT_obj,0
for n=1 to LODT_levels
` define min/max
minx(n)=px-LODT_dist(n)
maxx(n)=px+LODT_dist(n)
minz(n)=pz-LODT_dist(n)
maxz(n)=pz+LODT_dist(n)
` fit
nstep=(2^(n-1))
minx(n)=int(minx(n)/(2*nstep))*nstep*2
maxx(n)=int(maxx(n)/(2*nstep))*nstep*2+nstep
minz(n)=int(minz(n)/(2*nstep))*nstep*2
maxz(n)=int(maxz(n)/(2*nstep))*nstep*2+nstep
` limit min/max
if minx(n)<0 then minx(n)=0
if maxx(n)>LODT_size then maxx(n)=LODT_size
if minz(n)<0 then minz(n)=0
if maxz(n)>LODT_size then maxz(n)=LODT_size
` make
for x=minx(n) to maxx(n) step nstep
for z=minz(n) to maxz(n) step nstep
` check flag
flag=0
if n=1
flag=1
else
if x<minx(n-1) or x>=maxx(n-1) or z<minz(n-1) or z>=maxz(n-1) then flag=1
endif
` make a tile
if flag=1
x#=0+x*LODT_tsize#:z#=0+z*LODT_tsize#
`y#=10*n
set vertexdata position pos+0,x#,y#,z#
set vertexdata position pos+1,x#,y#,z#+LODT_tsize#*nstep
set vertexdata position pos+2,x#+LODT_tsize#*nstep,y#,z#+LODT_tsize#*nstep
set vertexdata position pos+3,x#,y#,z#
set vertexdata position pos+4,x#+LODT_tsize#*nstep,y#,z#+LODT_tsize#*nstep
set vertexdata position pos+5,x#+LODT_tsize#*nstep,y#,z#
inc pos,6
endif
next z
next x
next n
` hide the rest
repeat
`set vertexdata position pos,0,-200000,0
inc pos,1
until pos>LODT_verts
` end
unlock vertexdata
` undim
undim minx(0)
undim maxx(0)
undim minz(0)
undim maxz(0)
endfunction