I've written this code:
Rem Project: Kuub
sync on
sync rate 60
set display mode 800,600,32
set window on
rem create arrays for perlin generator
dim s#(15,2)
dim r#(63,63,63)
xsize = 16
ysize = 16
seed$ = "1"
heightmult = 2
desc$ = "Kuub 0.01"
if xsize > screen width()
xsize = screen width()
endif
if ysize > screen height()
ysize = screen height()
endif
rem create bitmap 1,xsize,ysize
rem make memblock from bitmap 1,1
make memblock 1,(xsize*ysize) + 3
rem multisampling controller
multi = 1
milti = multi - 1
malt# = multi ^ 2
malt# = 1 / malt#
rem get the base sizes
xsize# = xsize * multi
ysize# = ysize * multi
rem get the scalers
xscaler# = 360
yscaler# = 180
xscaler# = xscaler# / xsize#
yscaler# = yscaler# / ysize#
width# = 2
rem piece details
pxs = xsize - 1
pys = ysize - 1
xof = 0
yof = 0
sync
text 2,1,desc$
center text screen width()/2,screen height()/4,"Please wait while a new world is being generated... (" + STR$(xsize) + "x" + STR$(ysize) + ")"
sync
prepare_perlin(ASC(seed$),0.5)
rem loop the y position
for x = 0 to pxs step 1
rem prepare screen for drawing
rem loop the x
for y = 0 to pys step 1
rem reset colours
g = 0
b = 0
rem get the scaled sizes
xp = (x + xof) * multi
yp = (y + yof) * multi
rem do the multisampling
for a = 0 to milti
rem get the baring around the sphere
ba# = xp + a
ba# = (ba# + 0.5) * xscaler#
xp# = cos(ba#)
zp# = sin(ba#)
for s = 0 to milti
rem get the pitch around the sphere
pa# = yp + s
pa# = ((pa# + 0.5) * yscaler#)
po# = sin(pa#) * width#
rem get the positions in the space
x# = (xp# * po#) + 5
y# = (cos(pa#) * width#) + 5
z# = (zp# * po#) + 5
rem get the perlin result for that part
h = int(perl(x#,y#,z#,8) * 255)
rem cap the value
if h => 255 then h = 255
if h <= 0 then h = 0
rem add appropriate colour
if h => 136
inc g,h
else
inc b,h
endif
rem failsafe quit
if spacekey() then end
next s
next a
rem scale down the colours
g = g * malt#
b = b * malt#
location = (y * x) + 3
write memblock dword 1, location, rgb(0,g,b)
next y
next x
make image from memblock 1,1
make object sphere 1,1,32,64
texture object 1,1
rem backdrop on
rem color backdrop 0
ink rgb(255,255,255),0
do
text 2,1,desc$ + " running at " + str$(screen fps()) + " fps"
control camera using arrowkeys 0,0.1,1
turn object left 1,0.5
if spacekey()
set object wireframe 1,1
else
set object wireframe 1,0
endif
sync
loop
end
rem function to prepare data for perlin noise
function prepare_perlin(seed,persistance#)
rem set the seed value
randomize seed
rem create seed data
for x = 0 to 63
for y = 0 to 63
for z = 0 to 63
z# = rnd(10000)
r#(x,y,z) = (z# * 0.0001)
next z
next y
next z
rem prepare octave data
for z = 0 to 15
rem work out the frequence of the octave
s#(z,0) = 2 ^ z
rem get the amplitude
s#(z,1) = persistance# ^ z
rem work out the maximum amplitude of
s#(z,2) = 0
for x = 0 to z
inc s#(z,2),s#(x,1)
next x
s#(z,2) = 1 / s#(z,2)
next z
endfunction
rem function to get the random value of a co-ordinate
function vil(x,y,z)
rem control edges
if x < 0 then x = x - (int((x / 64) - 1) * 64) else x = x - (int(x/64) * 64)
if y < 0 then y = y - (int((y / 64) - 1) * 64) else y = y - (int(y/64) * 64)
if z < 0 then z = z - (int((z / 64) - 1) * 64) else z = z - (int(z/64) * 64)
rem get the number
v# = r#(x,y,z)
endfunction v#
rem return an integer as a floating point
function flo(a)
b# = a
endfunction b#
rem function to turn a straight 0 - 1 into a sine curved 0 - 1
function sine(v#)
rem perform the change
v# = (1 - cos(v# * 180)) * 0.5
endfunction v#
rem perlin function
function perl(x#,y#,z#,octaves)
rem make sure the pass value is zerod
h# = 0
rem shift octaves down to input works from 1 but system works from 0
dec octaves,1
rem make sue octaves are an ecceptable value
if octaves <= 0 then octaves = 0
if octaves => 15 then octaves = 15
rem loop the octaves
for oct = 0 to octaves
rem grab the frequency and amplitude for this
fre# = s#(oct,0)
amp# = s#(oct,1)
rem convert the co-ordinates into steps
x = int(x# * fre#)
y = int(y# * fre#)
z = int(z# * fre#)
rem get the inbetween co-ords
xb# = sine((x# * fre#) - flo(x))
yb# = sine((y# * fre#) - flo(y))
zb# = sine((z# * fre#) - flo(z))
xa# = 1 - xb#
ya# = 1 - yb#
za# = 1 - zb#
rem get the values for the 8 corners
v000# = vil(x,y,z) * xa# * ya# * za#
v100# = vil(x+1,y,z) * xb# * ya# * za#
v010# = vil(x,y+1,z) * xa# * yb# * za#
v001# = vil(x,y,z+1) * xa# * ya# * zb#
v101# = vil(x+1,y,z+1) * xb# * ya# * zb#
v110# = vil(x+1,y+1,z) * xb# * yb# * za#
v011# = vil(x,y+1,z+1) * xa# * yb# * zb#
v111# = vil(x+1,y+1,z+1) * xb# * yb# * zb#
rem add it on
inc h#,(v000# + v100# + v010# + v001# + v101# + v110# + v011# + v111#) * amp#
next oct
rem scale it down
h# = h# * s#(octaves,2)
endfunction h#
And at first, it just drew the picture to the screen but this limited the image size to the window size. Now im trying to write it to a memblock, and it appears the game just freezes. The please wait doesn't even show up anymore!
Edit: I've updated the code a bit, i now use make memblock instead of create memblock from bitmap, but now the whole texture ends up being black.
Edit2: Oops! I'm such a idiot, i forgot to write the width height and depth to the memblock! For those interested, this is the final code for creating the memblock:
pixels = xsize*ysize
bytes = 4+4+4+(pixels*4)
bytePos = 0
make memblock 1,bytes
width = (0<<24) + (0<<16) + (0<<8) + xsize
height = (0<<24) + (0<<16) + (0<<8) + ysize
depth = (0<<24) + (0<<16) + (0<<8) + 32
rem write image info
write memblock dword 1,bytePos,width : inc bytePos,4
write memblock dword 1,bytePos,height : inc bytePos,4
write memblock dword 1,bytePos,depth : inc bytePos,4
Edit3: New question, i'm creating my terrain out of create cube id,1's, and i need a way to determine if a cube is visible or not, I was thinking dont create the cube if there are blocks on all sides of it (left right front back up down), because when i just draw all cubes my game takes up 200mb of memory with a 64x64x10 map.
Rem Project: Kuub
sync on
sync rate 60
set display mode 800,600,32
set window on
rem create arrays for perlin generator
dim s#(15,2)
dim r#(63,63,63)
xsize = 32
ysize = 32
seed$ = "1"
heightmult = 2
desc$ = "Kuub 0.02"
objects = 8 rem This keeps track of object ids
rem Prepare our memblock
pixels = xsize*ysize
bytes = 4+4+4+(pixels*4)
bytePos = 0
make memblock 1,bytes
width = (0<<24) + (0<<16) + (0<<8) + xsize
height = (0<<24) + (0<<16) + (0<<8) + ysize
depth = (0<<24) + (0<<16) + (0<<8) + 32
write memblock dword 1,bytePos,width : inc bytePos,4
write memblock dword 1,bytePos,height : inc bytePos,4
write memblock dword 1,bytePos,depth : inc bytePos,4
rem multisampling controller
multi = 1
milti = multi - 1
malt# = multi ^ 2
malt# = 1 / malt#
rem get the base sizes
xsize# = xsize * multi
ysize# = ysize * multi
rem get the scalers
xscaler# = 360
yscaler# = 180
xscaler# = xscaler# / xsize#
yscaler# = yscaler# / ysize#
width# = 2
rem piece details
pxs = xsize - 1
pys = ysize - 1
xof = 0
yof = 0
sync
text 2,1,desc$
center text screen width()/2,screen height()/4,"Please wait while a new world is being generated... (" + STR$(xsize) + "x" + STR$(ysize) + ")"
sync
prepare_perlin(ASC(seed$),0.5)
rem loop the y position
for x = 0 to pxs step 1
rem prepare screen for drawing
rem loop the x
for y = 0 to pys step 1
rem reset colours
g = 0
b = 0
rem get the scaled sizes
xp = (x + xof) * multi
yp = (y + yof) * multi
rem do the multisampling
for a = 0 to milti
rem get the baring around the sphere
ba# = xp + a
ba# = (ba# + 0.5) * xscaler#
xp# = cos(ba#)
zp# = sin(ba#)
for s = 0 to milti
rem get the pitch around the sphere
pa# = yp + s
pa# = ((pa# + 0.5) * yscaler#)
po# = sin(pa#) * width#
rem get the positions in the space
x# = (xp# * po#) + 5
y# = (cos(pa#) * width#) + 5
z# = (zp# * po#) + 5
rem get the perlin result for that part
h = int(perl(x#,y#,z#,8) * 10)
rem cap the value
if h => 255 then h = 255
if h <= 0 then h = 0
rem add appropriate colour
if h => 136
inc g,h
else
inc b,h
endif
rem failsafe quit
if spacekey() then end
next s
next a
rem scale down the colours
g = g * malt#
b = b * malt#
rem location = (4*((y*xsize)+x))+12
rem write memblock dword 1, location, rgb(0,g,b)
h = roundval(h)
make_stack(x,y,h)
next y
next x
backdrop on
color backdrop 0
do
text 2,1,desc$ + " running at " + str$(screen fps()) + " fps"
control camera using arrowkeys 0,0.1,1
sync
loop
end
function roundval(n#)
rem Store n as an integer, discarding the fraction.
n = n#
rem Adding n to itself reveals whether it should be rounded up or down:
rem Two halves make a whole, so fractions of at least 0.5 will be rounded up,
rem whereas two lesser fractions combined will fail to produce a whole number and therefore be rounded down.
inc n#,n#
rem This subtraction takes the integer value of n from the sum of 2n and discards the fraction by storing the
rem result in an integer variable. Now we see why the above addition was so important, because now all we
rem have left is an integer, so either n was rounded up or it's fraction wasn't large enough to do so.
n = n#-n
rem The function works for negative numbers too because we only ever talk in terms of n, so if n is negative, the addition and subtraction of n is also negative.
endfunction n
rem function to create a stack of blocks
function make_stack(xpos,ypos,height)
for i = 0 to height
id = FREE_OBJECT()
make object cube id,1
position object id,xpos,i,ypos
color object id,rgb(rnd(255),rnd(255),rnd(255))
next i
endfunction
function FREE_OBJECT()
repeat
inc objects
until object exist(objects) = 0
endfunction objects
rem function to prepare data for perlin noise
function prepare_perlin(seed,persistance#)
rem set the seed value
randomize seed
rem create seed data
for x = 0 to 63
for y = 0 to 63
for z = 0 to 63
z# = rnd(10000)
r#(x,y,z) = (z# * 0.0001)
next z
next y
next z
rem prepare octave data
for z = 0 to 15
rem work out the frequence of the octave
s#(z,0) = 2 ^ z
rem get the amplitude
s#(z,1) = persistance# ^ z
rem work out the maximum amplitude of
s#(z,2) = 0
for x = 0 to z
inc s#(z,2),s#(x,1)
next x
s#(z,2) = 1 / s#(z,2)
next z
endfunction
rem function to get the random value of a co-ordinate
function vil(x,y,z)
rem control edges
if x < 0 then x = x - (int((x / 64) - 1) * 64) else x = x - (int(x/64) * 64)
if y < 0 then y = y - (int((y / 64) - 1) * 64) else y = y - (int(y/64) * 64)
if z < 0 then z = z - (int((z / 64) - 1) * 64) else z = z - (int(z/64) * 64)
rem get the number
v# = r#(x,y,z)
endfunction v#
rem return an integer as a floating point
function flo(a)
b# = a
endfunction b#
rem function to turn a straight 0 - 1 into a sine curved 0 - 1
function sine(v#)
rem perform the change
v# = (1 - cos(v# * 180)) * 0.5
endfunction v#
rem perlin function
function perl(x#,y#,z#,octaves)
rem make sure the pass value is zerod
h# = 0
rem shift octaves down to input works from 1 but system works from 0
dec octaves,1
rem make sue octaves are an ecceptable value
if octaves <= 0 then octaves = 0
if octaves => 15 then octaves = 15
rem loop the octaves
for oct = 0 to octaves
rem grab the frequency and amplitude for this
fre# = s#(oct,0)
amp# = s#(oct,1)
rem convert the co-ordinates into steps
x = int(x# * fre#)
y = int(y# * fre#)
z = int(z# * fre#)
rem get the inbetween co-ords
xb# = sine((x# * fre#) - flo(x))
yb# = sine((y# * fre#) - flo(y))
zb# = sine((z# * fre#) - flo(z))
xa# = 1 - xb#
ya# = 1 - yb#
za# = 1 - zb#
rem get the values for the 8 corners
v000# = vil(x,y,z) * xa# * ya# * za#
v100# = vil(x+1,y,z) * xb# * ya# * za#
v010# = vil(x,y+1,z) * xa# * yb# * za#
v001# = vil(x,y,z+1) * xa# * ya# * zb#
v101# = vil(x+1,y,z+1) * xb# * ya# * zb#
v110# = vil(x+1,y+1,z) * xb# * yb# * za#
v011# = vil(x,y+1,z+1) * xa# * yb# * zb#
v111# = vil(x+1,y+1,z+1) * xb# * yb# * zb#
rem add it on
inc h#,(v000# + v100# + v010# + v001# + v101# + v110# + v011# + v111#) * amp#
next oct
rem scale it down
h# = h# * s#(octaves,2)
endfunction h#
...