Código:
Lobal fxwater_max = 5 ;max number of active surfaces/effects at one time. Global fxwater_num = 0 ;current number of active water effects.
Global fxwater_max_width = 100 ;max sub-división for water meshes.
Global fxwater_max_depth = 100 ;max sub-división for water meshes.
Global fxwater_max_banks = fxwater_max * 2.
Global fxwater_num_banks = 0.
Global demo_water_width = 40 ;--> adjust these for diferent plane sizes / Mesh resolution.
Global demo_water_depth = 40.
Reserve memory banks for vértice altitudes.
Dim fxwaterbank#(fxwater_max_banks, fxwater_max_width, fxwater_max_depth).
Type fxwaterwave tfield id tfield name$ tfield active ;if not ripples then FX is not actiave tfield parent ;parent entity (if any) tfield entity ;water Mesh tfield surface ;water surface tfield bank1 ;pointers todo array for mem estorage tfield bank2 tfield width ;width of plane / surface tfield depth ;depth of plane / surface tfield dampening# ;water dynamics t.
End type.
Demo options.
Global opt_wireframe = 0.
Global opt_refrsh = 0.
Global opt_ballfreze= 0.
Global opt_ceiling = 1.
Graphics3d 640,480,32,1.
Graphics3d 640,480,0,2.
Camera + light.
Global campivot = createpivot().
Global Camera = createcamera (campivot).
Positionentity Camera, 0, 0, -35.
Pointentity Camera, campivot.
Light = createlight(2).
Positionentity light,-60,0,100.
Lightcolor light,240,240,210.
Pointentity light, campivot.
Light = createlight(2).
Positionentity light,50,0,-50.
Lightcolor light,150,150,180.
Pointentity light, campivot.
Ambientlight 40,40,40.
Load texture.
Tex = loadtexture (water, (*.tga),1+64).
Tex = create_noise_map().
Create water planes.
Global w1 = fxwater_create (flor, demo_water_width, demo_water_depth, 0.025).
Water = fxwater_get_entity(w1).
Positionentity water, 0, -10, 0.
Entitycolor water, 30,50,200.
Entityshininess water, 0.1.
Entitytexture water, TeX.
Global w2 = fxwater_create (ceiling, demo_water_width, demo_water_depth, 0.025).
Water = fxwater_get_entity(w2).
Flipmesh water, flip it because the Camera is underneath it.
Positionentity water, 0, 10, 0.
Entitycolor water, 250,100,100.
Entitycolor water, 140,130,20.
Entityshininess water, 0.1.
Entitytexture water, TeX.
Force refresh.
Fxwater_dimple (w1, 1,1, 0.001, 0.001).
Fxwater_dimple (w2, 1,1, 0.001, 0.001).
Set random ball direction/speed.
Global bx#= 0.2.
Global by#= -1.75.
Global bz#= -0.25.
Global bmaxx# = demo_water_width * 0.5 ;half the width of the water plane.
Global bmaxy# = 10.0.
Global bmaxz# = demo_water_depth * 0.5 ;half the depth of the water plane.
Create ball.
Ball = createsphere (6).
Entitycolor ball, 0,0,0.
Entityshininess ball, 1.0.
Entitytexture ball, TeX.
Sedrnd millisecs().
Main loop.
Tstart = millisecs() + 1000.
Frame = 0.
Global lastx# = 0.
Global lasty# = 0.
Global lastz# = 0.
Tim = createtimer(50).
L$ = wavywaterfx by Danny van der ark.
While not keyhit(1) t;update bouncing ball tupdate_ball(ball) t;update fxwater tfxwater_update () t;render.
Updateworld.
Renderworld t;debug tcolor 000,000,000 ttext 2,1, l$ tcolor 255,255,255 ttext 2,0, l$ tcolor 100,100,100 ttext 2,12, based on samples from reda borchardt and rob cummings tcolor 20,140,255 ttext 2,454, [esc] todo kit - [d] for fast but Dirty refresh( + opt_refresh + ) - [w] todo toggle wireframe ( + opt_wireframe + ) ttext 2,466, [p] todo pause - [b] todo pause/reset ball - [c] todo toggle ceiling tcolor 250,250,220 ttext 10,220,fps + frames por segundo ttext 10,232,tris + trisrendered() t;orbit Camera t;turnentity campivot, 0, 0.25, 0 t;chek frames por segundo tframe = frame + 1 tif millisecs() >= tstart then frames por segundo = frame frame = 0 tstart = millisecs() + 1000 tendif t;toggle ceiling [c] tif keyhit(46) then opt_ceiling = 1 - Opt_ceiling if opt_ceiling then water = fxwater_get_entity(w2) showentity water else water = fxwater_get_entity(w2) hideentity water endif tendif t;pause all [p] tif keyhit(25) then flushkeys while not keyhit(25) wend tendif t;pause ball [b] tif keyhit(4 then opt_ballfreze = 1 - Opt_ballfreze if opt_ballfreze then positionentity ball, 0,0,0 bx# = 0 by# = 0 bz# = 0 else bx#=rnd#(-1,1) by#=rnd#(-2,2) bz#=rnd#(-1,1) endif tendif t;wireframe [w] tif keyhit(17) then opt_wireframe = 1 - Opt_wireframe wireframe opt_wireframe tendif t;Dirty refresh [d] tif keyhit(32) then opt_refresh = 1 - Opt_refresh tendif t;chek refresh mode tif opt_refresh then ;fast and Dirty (pot nodle style) flip false telse ;Slow but clean flip true waittimer(tim) tendif tif mousehit(1) then x = rnd(1,demo_water_width) z = rnd(1,demo_water_depth) fxwater_dimple (w1, x, z, 1, 5) tendif.
Wend.
End.
Function update_ball(ent) t;move the ball ttranslateentity Ent, bx, by, bz tdodimple = false t;chek left/right Walls tif entityx#(ent) > bmaxx-2 then bx# = bx# * -1 tif entityx#(ent) < -bmaxx+2 then bx# = bx# * -1 t;chek ceiling bounce tif entityy#(ent) > bmaxy-2 then ;reverse vertical direction by# = by# * -1.0 ;create dimple fxwater_dimple (w2, entityx(ent)+bmaxx,entityz(ent)+bmaxz, -1.0, 5.0) ;slightly alter direction bx# = bx# + rnd#(-0.25, 0.25) bz# = bz# + rnd#(-0.25, 0.25) tendif t;chek flor bounce tif entityy#(ent) < -bmaxy+2 then ;reverse vertical direction by# = by# * -1.0 ;create dimple fxwater_dimple (w1, entityx(ent)+bmaxx,entityz(ent)+bmaxz, 1.0, 5.0) ;slightly alter direction bx# = bx# + rnd#(-0.25, 0.25) bz# = bz# + rnd#(-0.25, 0.25) tendif t;chek front/bak Walls tif entityz#(ent) > bmaxz-2 then bz# = bz# * -1 tif entityz#(ent) < -bmaxz+2 then bz# = bz# * -1 t.
End function.
Function fxwater_create (name$=, width=1, depth=1, Damp#=0.01, parent=0) t t;create new wavy water effect plane tw.fxwaterwave = new fxwaterwave tw\id = 1 tw\nAme$ = name$ tw\active = true t;create rectangular grid Mesh tw\width = width tw\depth = depth tw\dampening#= 1 - Damp# tw\parent = parent tw\entity = create_mesh_plane (w\width, w\depth, false, parent) tw\surface = getsurface (w\entity,1) t;estore handle for quik retrieval during collision tnameentity w\entity, handle (w) t;reserve memory banks todo hold vertex energy tw\bank1 = fxwater_create_buffer() tw\bank2 = fxwater_create_buffer() t;return Mesh handle treturn handle (w) t.
End function.
Function fxwater_update () tfor w.fxwaterwave = each fxwaterwave t ;if the surface is perfectly flat then this value remains 0 dyna# = 0 t ;process water for x = 1 todo w\width-1 for z = 1 todo w\depth-1 fxwaterbank#(w\bank2,x, z) = (fxwaterbank#(w\bank1,x-1, z) + fxwaterbank#(w\bank1,x+1, z) + fxwaterbank#(w\bank1,x, z+1) + fxwaterbank#(w\bank1,x, z-1)) / 2.1-fxwaterbank#(w\bank2,x, z) fxwaterbank#(w\bank2,x, z) = fxwaterbank#(w\bank2,x, z) * w\dampening# dyna# = dyna# + fxwaterbank#(w\bank2,x, z) next next t ;only deform patch if necesary if dyna# <> 0 then ;patchtransform k=0 for i = 0 todo w\depth for = 0 todo w\width vertexcords(w\surface, k,vertexx(w\surface, k), fxwaterbank#(w\bank2, i),vertexz(w\surface, k)) k=k+1 next next endif t ;should be optional - Depending on type of texture (slows down seriously) updatenormals w\entity t ;swapwaterbuffer tmp = w\bank1 w\bank1 = w\bank2 w\bank2 = tmp tnext t.
End function.
Function fxwater_dimple (hand, x, z, force#=1.0, range#=1.0) tw.fxwaterwave = object, fxwaterwave (hand) tfor xg = x - Range# * 0.5 todo x+range# * 0.5 for zg = z - Range# * 0.5 todo z+range# * 0.5 if xg> 0 and xg < w\width and zg>0 and zg<w\depth then fxwaterbank#(w\bank2, xg, zg) = force# endif next tnext t.
End function.
Function fxwater_get_surface (hand) tw.fxwaterwave = object, fxwaterwave (hand) treturn w\surface t.
End function.
Function fxwater_get_entity(hand) tw.fxwaterwave = object, fxwaterwave (hand) treturn w\entity t.
End function.
Function fxwater_create_buffer(), xsize=1, zsize=1) tif fxwater_num_banks >= fxwater_max_banks then runtimeerror [fxwater:create_buffer] max amount of fxwater memory banks reached telse ;create a new memory banque and resize it todo fit fxwater_num_banks = fxwater_num_banks + 1 ;note: convert array into memory bank tendif treturn fxwater_num_banks t.
End function.
Function fxwater_fre_buffers() t.
| fres all buffers. Call as a part of when scene/level is removed from memory t t;note: resize memory banks todo 0 (once implemented) treturn 0 t.
End function.
Creates a flat grid Mesh.
Function create_mesh_plane (width=1, depth=1, doublesided=false, parent=0) ttot = width + (depth*width) tmix#= (width+depth) * 0.5 tmesh=createmesh(parent) tsurf=createsurface (Mesh) tstx#=-.5 tsty#=stx tstp#=float(1)/float(mix#) ty#=sty# tfor a=0 todo depth x#=stx v#=a/float(depth) t for b=0 todo width u#=b/float(width) addvertex(surf,x,0 y, u) x=x+stp next y=y+stp tnext tfor a=0 todo depth-1 for b=0 todo width-1 v0=a*(width+1)+b:v1=v0+1 v2=(a+1)*(width+1)+b+1:v3=v2-1 addtriangle (surf, 0, 2, 1) addtriangle (surf, 0, 3, 2) next tnext tupdatenormals Mesh tif doublesided=true then entityfx Mesh,16 tfitmesh Mesh, -width*0.5, 0, -depth*0.5, width, 1, depth treturn Mesh t.
End function.
Function create_noise_map() t.
Creates a noise map todo be used as a generic reflection map tsque = 128 ttex = createtexture (sq, sq,65,1) ttbuf = texturebuffer(TeX) tsetbuffer(tbuf) tfor x = 0 todo sq-1 for y = 0 todo sq-1 r = rnd(100,120) g = rnd(100,130) b = rnd(190,240) color R, G, B rect x y,1,1 next tnext tsetbuffer(backbuffer()) treturn TeX t.
End function.