These functions allow you to easily create water with simple waves controlled by the SIN() and VertexData commands in your game. They require IanM's Matrix1 Plugins (specifically plugin #18). You can create as many water objects as you want.
Uncapped I get around 338FPS at 64 detail and 1680x1050x32 resolution.
Here are the functions:
rem ********************************************************************************
rem COPY ALL OF THE CODE BELOW INTO YOUR GAME AFTER YOUR LOOP TO USE THE FUNCTIONS.
rem ********************************************************************************
Type VDW_Vecs_T
X as float
Y as float
Z as float
Endtype
Function VDW_Setup()
global VDW_SinAng#
DIM VDW_Sin#(360)
for s = 0 to 360
VDW_Sin#(s)=sin(s)
next s
Endfunction
Function VDW_MakeWater(obj as integer,XSize#,ZSize#,Detail)
if Detail>255 then Detail=255
make object plane obj,XSize#,ZSize#,Detail,Detail,274
VertCount=(Detail+1)*(Detail+1)
Endfunction VertCount
Function VDW_NoSinUpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 1 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
vdws=wrapvalue( (p#*360+VDW_SinAng#)*WaveCount )
yp#=WaveHeight#*VDW_Sin#(vdws)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_UpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 0 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
yp#=WaveHeight#*sin((p#*360+VDW_SinAng#)*WaveCount)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_SetWaterWaveOffset(OffsetAngle#)
VDW_SinAng#=OffsetAngle#
Endfunction
Here is how to use them:
Step 1: Copy and paste the functions above into your code after your main loop.
Step 2: Whenever you want to make the water object, call the VDW_MakeWater( Object Number, XSize, ZSize, Detail ) function. This function will return a value, which you should store in a variable for later (see the examples if this is confusing). You can treat this object like any other object, which means you can texture it however you want.
Step 3: In your main loop, to make the water look all wavy you need to call the VDW_UpdateWater( Object Number, Wave Speed, Wave Height, Wave Count, Vertex Count ) function. For the vertex count parameter, just write the variable that you set in Step 2.
That's it! You're ready to have wavy water in your game

.
*****************************
Each Function Explained:
*****************************
VDW_Setup()
***Sets up the system and creates the required global variables/arrays.
Vertex Count (Return Value)=VDW_MakeWater( Object Number, XSize, ZSize, Detail )
***Creats a water object.
*
Vertex Count- This value is returned by the function and it says how many verticies the object has. Store it in a variable for the update function.
-
Object Number- The object number that you want the water object to use.
-
XSize- The size of your water object along the X AXIS.
-
ZSize- The size of your water object along the Z AXIS.
-
Detail- How detailed the water object is. (Controls how many rows/columns of verticies it has). Lower detail means better performance while higher detail means smoother water. 32-64 are decent numbers for this, but play around with it!
VDW_UpdateWater( Object Number, Wave Speed, Wave Height, Wave Count, Vertex Count )
***Updates a water object.
-
Object Number- The object number that you want the water object to use.
-
Wave Speed- The speed at which the waves move through the water. This value is specified in degrees so it is independent of the object's size.
-
Wave Height- The height of the waves. The top of a wave will be at this height and the bottom of the wave will be at negative this height.
-
Wave Count- The number of waves in the water. Waves are evenly spaced.
-
Vertex Count
VDW_NoSinUpdateWater( Object Number, Wave Speed, Wave Height, Wave Count, Vertex Count )
***Same as the VDW_UpdateWater command only it uses a Sin array instead of the Sin() command.
VDW_SetWaterWaveOffset( Offset )
***[This function is not required to make the system work.] Changes the offset of the waves. Use this to manually control the speed of the water waves. Any VDW_UpdateWater() functions called after this will use this value. To make sure no Wave Speed is added to this number when setting it manually, set the Wave Speed to 0 in your VDW_UpateWater() functions.
-
Offset- The angle offset (0-360). The faster you increase this value, the faster the waves will scroll.
Examples:
Main Example:
Rem Project: VertexData Water
Rem ***** Main Source File *****
rem Setup
VSync=1 `Set this to 0 to uncap the FPS and see how fast the game can run.
set display mode desktop width(),desktop height(),32,VSync
sync on
sync rate 0
autocam off
color backdrop rgb(100,100,100)
`Make the ugliest water texture ever
create bitmap 1,256,256
ink rgb(0,0,155),0
box 0,0,128,128
for x = 0 to 255
for y = 0 to 255
b=100+rnd(155)
ink rgb(0,b/2,b),0
box x,y,x+1,y+1
next y
next x
get image 1,0,0,256,256
delete bitmap 1
`Setup the VertexData Water.
VDW_Setup()
`Make a 1000x1000 water plain with 64 rows and columns (detail)
`Parameters: MakeVertexDataWater(Object #, Water X Size, Water Z Size, Detail)
`Detail = # of rows and columns on the object. Lower detail = better performance.
`The value returned is the # of verticies on the object. Just store it in a variable and pass it into the UpdateVertexDataWater() function later on.
vCount=VDW_MakeWater(1,1000,1000,64)
`Texture the water
texture object 1,1
`Tile the texture
scale object texture 1,4,4
`Position the camera to start
xrotate camera 45
move camera -400
`Set movement speed
ms#=20.0
do
`On-screen text
ink rgb(255,255,255),0
set cursor 0,0
print "FPS: ",screen fps()
print "Hold SPACE to float on the water."
`Camera control
move camera ms#*(upkey()-downkey())
rotate camera camera angle x()+mousemovey()/8.0,camera angle y()+mousemovex()/8.0,0
`Update the water
`Parameters: UpdateVertexDataWater(Object #, Wave Speed (0-360), Wave Height, Wave Count/Number of Waves, Vertex Count)
`The Vertex Count is the number returned by the MakeVertexDataWater function.
VDW_UpdateWater(1,0.70,50.0,3,vCount)
`Hold SPACE to float on the water.
if spacekey()
d#=intersect object(1,camera position x(),1000,camera position z(),camera position x(),-1000,camera position z())
if d#=0 then d#=950 `Position at 50 if you aren't on the water at all
position camera camera position x(),1000-d#+5,camera position z()
endif
sync
loop
rem ********************************************************************************
rem COPY ALL OF THE CODE BELOW INTO YOUR GAME AFTER YOUR LOOP TO USE THE FUNCTIONS.
rem ********************************************************************************
Type VDW_Vecs_T
X as float
Y as float
Z as float
Endtype
Function VDW_Setup()
global VDW_SinAng#
DIM VDW_Sin#(360)
for s = 0 to 360
VDW_Sin#(s)=sin(s)
next s
Endfunction
Function VDW_MakeWater(obj as integer,XSize#,ZSize#,Detail)
if Detail>255 then Detail=255
make object plane obj,XSize#,ZSize#,Detail,Detail,274
VertCount=(Detail+1)*(Detail+1)
Endfunction VertCount
Function VDW_NoSinUpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 1 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
vdws=wrapvalue( (p#*360+VDW_SinAng#)*WaveCount )
yp#=WaveHeight#*VDW_Sin#(vdws)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_UpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 0 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
yp#=WaveHeight#*sin((p#*360+VDW_SinAng#)*WaveCount)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_SetWaterWaveOffset(OffsetAngle#)
VDW_SinAng#=OffsetAngle#
Endfunction
Simplest Example:
Rem Project: VertexData Water
Rem ***** Main Source File *****
rem Setup
sync on
sync rate 60
autocam off
VDW_Setup()
vCount=VDW_MakeWater(1,100,100,64)
color object 1,rgb(0,0,255)
rem Zoom out
xrotate camera 45
yrotate camera 45
move camera -100
do
VDW_UpdateWater(1,0.70,1.0,3,vCount)
sync
loop
rem ********************************************************************************
rem COPY ALL OF THE CODE BELOW INTO YOUR GAME AFTER YOUR LOOP TO USE THE FUNCTIONS.
rem ********************************************************************************
Type VDW_Vecs_T
X as float
Y as float
Z as float
Endtype
Function VDW_Setup()
global VDW_SinAng#
DIM VDW_Sin#(360)
for s = 0 to 360
VDW_Sin#(s)=sin(s)
next s
Endfunction
Function VDW_MakeWater(obj as integer,XSize#,ZSize#,Detail)
if Detail>255 then Detail=255
make object plane obj,XSize#,ZSize#,Detail,Detail,274
VertCount=(Detail+1)*(Detail+1)
Endfunction VertCount
Function VDW_NoSinUpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 1 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
vdws=wrapvalue( (p#*360+VDW_SinAng#)*WaveCount )
yp#=WaveHeight#*VDW_Sin#(vdws)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_UpdateWater(obj,WaveSpeed#,WaveHeight#,WaveCount,VertexCount)
inc VDW_SinAng#,WaveSpeed#
lock vertexdata for limb obj,0,1
for o = 0 to VertexCount
p#=o*1.0/VertexCount*1.0
xp#=get vertexdata position x(o)
yp#=WaveHeight#*sin((p#*360+VDW_SinAng#)*WaveCount)
zp#=get vertexdata position z(o)
set vertexdata position o,xp#,yp#,zp#
next o
unlock vertexdata
Endfunction
Function VDW_SetWaterWaveOffset(OffsetAngle#)
VDW_SinAng#=OffsetAngle#
Endfunction
Feel free to expand on them if you like, the concept is actually quite simple

Guns, cinematics, stealth, items and more!