can this be done with bmax?

BlitzMax Forums/BlitzMax Programming/can this be done with bmax?

Does anybody have an idea how this effect (its a java applet) could be realized (in BlitzMax) ?:

http://www.colliewelt.de/cavalcanti/UntitledFrame-30.htm

Using a stencil buffer you could do something pretty similar, since there isn't really `realistic` refraction of light, you could just have it so that the puddles are a mask of an animation and then you put that into the stencil buffer and then where there are stencil bits you then draw the whole background at an offset, so wherever there are puddles you'll see an offset that simulates some kind of refraction. You could do it in three passes, each overlapping, like a fake emboss effect, with a different offset for each part of the emboss - the hilite edge, the main, and the shadow edge, to create more of a curvature look. At such small scale you probably wont notice it's not real bumpmapped raytracing.

Or do it all manually in a pixmap and use DrawPixmap.

The codelink here had that effect, I think so you might want to check if Drew is about.

Drew used Hugo Elias' routines. They're very easy to follow, and produce an effect just like the one in that applet.

see if you like this, it is not mine, but I converted it to BMAX. Use your own, must be 640x480, png. make shure you are not in debug mode or it will run really slow.

'--------------------------------
'
'         Water Transition
'      640x480
'  Interpolating gradient offsets
'
' 17 January 2005
' By Dafydd Brown aka Tetra / DBF
'
' Modified on 27 January 2006
'--------------------------------


AppTitle = "Water Fun"



	Global divi# = 1.0

	Global MAXDEPTH		= 500
	Global MAXDEPTHD2 	= MAXDEPTH/10
	Global DEPTH		=-MAXDEPTH
	Global VISCOSITY	= 60

	Const gfx_width 	= 640
	Const gfx_height 	= 480

	Const tex_width 	= 640
	Const tex_height 	= 480

	Global dShowDetail = 1

	Global wave_map_width 	= 80	' has To be 640 x 480 ratio
	Global wave_map_height 	= 60	' has To be 640 x 480 ratio

	Global wave_ratio 	= gfx_width / wave_map_width	' has To be 640 x 480 ratio
	Global tex_ratio 	= tex_width / gfx_width			' has To be 640 x 480 ratio
	
	Global frnt		= 1
	Global drpSz	= 2
	
	Global smooth 	= 0
	
	Global lastX	= 100
	Global lastY	= 100

	Global cFPS 	= 0
	Global FPS 		= 0
	Global ttime 	= 0

	Global WaveMap#[wave_map_width,wave_map_height,3]
	Global gradient#[wave_map_width,wave_map_height,2]
	Global textureImg%[tex_width,tex_height]
	Global image:timage
	Global img:TPixmap,pix:TPixmap
	
	
	fs = 0

	Graphics gfx_width,gfx_height,fs
	
	LoadTextureImage("tetratg.png")
	
'------------------------------------------
' Change the detail of the wavemap
'
Function changeWavemapSize(wd,ht) 
  		
		wave_map_width 	= wd	' has To be 640 x 480 ratio
  		wave_map_height = ht	' has To be 640 x 480 ratio
  		wave_ratio 		= gfx_width / wave_map_width ' has To be 640 x 480 ratio
  		
		WaveMap# =  New Float[ wave_map_width, wave_map_height, 3 ]
  		gradient# = New Float[ wave_map_width, wave_map_height, 2 ]
	
End Function


'------------------------------------------
' Load the texture To use
'
Function LoadTextureImage(filename$)

  	image = LoadImage(filename$)
		
  		If ( image )
    		pix=LockImage(image)
			For y = 0 To ImageHeight(image)-1
     			For x = 0 To ImageWidth(image)-1
        			textureImg(x,y) = $ffffffff & ReadPixel( pix,x,y)
      			Next
    		Next

  		Else
    		RuntimeError "Unable to load image "+filename$
  		EndIf
	
	End Function

'------------------------------------------
' Smooth indentation into the wavemap
'
Function indent(x,y,hgt#)

	Local ti

		For i = -drpSz To drpSz 
			
			ti = (x+i) Mod (wave_map_width-1)
			
			If ( ti < 0 ) Then ti=ti+wave_map_width
			
			For j=-drpSz To drpSz
		
				tj=(y+j) Mod (wave_map_height-1)
				If tj<0 Then tj=tj+wave_map_height
				
				WaveMap#(ti,tj,1-frnt) = Rand(hgt#)
			Next
		Next

		For i = x-drpSz To x+drpSz
			For j = y-drpSz To y+drpSz
			
				WaveMap#(i,j,1-frnt)=(WaveMap#(i+1,j,1-frnt)+WaveMap#(i-1,j,1-frnt)+WaveMap#(i,j+1,1-frnt)+WaveMap#(i,j-1,1-frnt))/4.0
			
			Next
		Next	
		
End Function


'------------------------------------------
' Smooth indentation into the wavemap along a line
'
Function indentline( xa, ya, xb, yb )

		If (xa > 4)And(xa < wave_map_width-4)And(ya > 4)And(ya < wave_map_height-4)
		
			If (xb > 4)And(xb < wave_map_width-4)And(yb > 4)And(yb < wave_map_height-4)
			
  				xlen = xb - xa
  				ylen = yb - ya

  				llen# = Sqr(xlen*xlen  + ylen*ylen)

  				xdelta# = xlen / llen
  				ydelta# = ylen / llen

  				bx# = xa
  				by# = ya

  				For ii = 0 To llen
    				indent(bx,by,MAXDEPTH)
    				bx# = bx# + xdelta#
    				by# = by# + ydelta#
  				Next

  			EndIf
		EndIf
		
End Function



'------------------------------------------
' Main Loop
'
While Not KeyDown(KEY_ESCAPE)

	tim = MilliSecs()

	newX=MouseX() 
	newY=MouseY() 
	If KeyHit(KEY_1) changeWavemapSize(20,15)
	If KeyHit(KEY_2) changeWavemapSize(40,30) 
    If KeyHit(KEY_3) changeWavemapSize(80,60) 
    If KeyHit(KEY_4) changeWavemapSize(160,120) 
    If KeyHit(KEY_5) changeWavemapSize(320,240) 
	
	If MouseDown(1)
        indentline(newX / wave_ratio,newY / wave_ratio,lastX / wave_ratio,lastY / wave_ratio)
	EndIf
	UpdateWaveMap#()
	
	If KeyDown(KEY_UP) 
		MAXDEPTH = MAXDEPTH+25
		MAXDEPTHD2 = MAXDEPTH/10
	EndIf
	
	If KeyDown(KEY_DOWN) 
		If MAXDEPTH > 25
			MAXDEPTH = MAXDEPTH-25
			MAXDEPTHD2 = MAXDEPTH/10
		EndIf
	EndIf
	
	If KeyDown(KEY_RIGHT) Then divi# = divi# + 0.05
	If KeyDown(KEY_LEFT) Then divi# = divi# - 0.05
	lastX = newX
	lastY = newY


    If KeyHit(KEY_SPACE) Then dShowDetail = 1 - dShowDetail

    If (dShowDetail = 1)

		SetColor 255,50,0
		DrawText "Fps: "+FPS+" - Max Depth: "+MAXDEPTH+" ratio: "+divi#,10,10
		DrawText "Detail: "+(wave_map_width / 40),10,30
		
	EndIf

	Flip
	Cls
	
	ttime = ttime + (MilliSecs() - tim)
	cFPS = cFPS + 1
	If ttime > 1000
		ttime = 0
		FPS = cFPS
		cFPS = 0
	EndIf

Wend
'
' End Main Loop
'------------------------------------------


'------------------------------------------
' Smooths the wavemap
'
Function smoothit( wf )

	For y = 0 To wave_map_height-1
		WaveMap#( 0,y, wf ) = 0
		WaveMap#( wave_map_width-1,y, wf ) = 0
    Next

    For x = 0 To wave_map_width-1
		WaveMap#( x,0, wf ) = 0
		WaveMap#( x,wave_map_height-1, wf ) = 0
    Next

	For y = 1 To wave_map_height-2
	
        yp1 = y + 1
		ym1 = y - 1
		
		For x = 1 To wave_map_width-2
			xp1 = x + 1
			xm1 = x - 1	
			n# = (WaveMap#(xm1,y,wf)+WaveMap#(xp1,y,wf)+WaveMap#(x,ym1,wf)+WaveMap#(x,yp1,wf))
			n# = n# + (WaveMap#(xm1,ym1,wf)+WaveMap#(xp1,yp1,wf)+WaveMap#(xp1,ym1,wf)+WaveMap#(xm1,yp1,wf))
			WaveMap#( x,y, wf ) = ( WaveMap#( x,y, wf ) + ( n# / 8.0) )/2
		Next
	Next
	
End Function


'------------------------------------------
' Does the wave stuff
'
Function UpdateWaveMap#()
    
	
	
    'get rid of a sticky bug
    For y = 0 To wave_map_height-1
      WaveMap#(0,y,wf) = 0
      WaveMap#(wave_map_width-1,y,wf) = 0
    Next

    'get rid of a sticky bug
    For x = 0 To wave_map_width-1
      WaveMap#(x,0,wf) = 0
      WaveMap#(x,wave_map_height-1,wf) = 0
    Next

	' this is here so that I dont have To write 1 - frnt everywhere I need it
	nfrnt = 1 - frnt

    'distortion map
	For y = 1 To wave_map_height-2
	
		yp1 = y + 1
		ym1 = y - 1
		
		For x = 1 To wave_map_width-2
		
		  xp1 = x + 1
		  xm1 = x - 1
		
		  n#=(WaveMap#(xm1,y,frnt)+WaveMap#(xp1,y,frnt)+WaveMap#(x,ym1,frnt)+WaveMap#(x,yp1,frnt))
		  n# = n# / 2.0
		
		  n# = ( n# - WaveMap#(x,y,nfrnt)  )
		  n# = ( n# - ( n# / VISCOSITY  ) )
		
		  ' Cap wave height
		  If n# > MAXDEPTH Then n# = MAXDEPTH
		  If n# < -MAXDEPTH Then n# = -MAXDEPTH
		
		  WaveMap#( x,y,nfrnt ) = n#
		
		Next	
	Next

	'Calculate texture offsets like bumpmapping
	For y = 1 To wave_map_height-2
			yp1=(y+1)
			ym1=(y-1)
		For x = 1 To wave_map_width-2
			xp1=(x+1)
			xm1=(x-1)
 
			gradient#(x,y,0) = (WaveMap#(xp1  , y    , nfrnt)-WaveMap#(xm1,y,nfrnt)) / divi#
			gradient#(x,y,1) = (WaveMap#(x    , yp1  , nfrnt)-WaveMap#(x,ym1,nfrnt)) / divi#
		Next
	Next
	
	' Smooth out the wave
	' this is required Or it looks really bad
	smoothit(1-frnt)


	' Render the screen using a textured polygon fill routing
	' its a pretty standard polyfill routine
	' that could probably be more optimised For the job
	
	pix = LockImage(image)
	For y = 1 To wave_map_height-2
		yp1=(y+1)
		
		If ( yp1 > wave_map_height - 1 ) Then yp1 = wave_map_height-1

   
		For x = 1 To wave_map_width-2

			xp1 = x + 1
			
			If xp1 > wave_map_width-1 Then xp1 = wave_map_width-1
			
         	tx1 = gradient#( x,y, 0 ) / 4.0
         	ty1 = gradient#( x,y, 1 ) / 4.0
  

 
			xp = x * wave_ratio
			yp = y * wave_ratio

			tx1 = tx1 + xp
			ty1 = ty1 + yp

			tx2 = ((x+1) * wave_ratio) + (gradient#(xp1,y,0) / 4.0)
			ty2 = ((y+1) * wave_ratio) + (gradient#(xp1,y,1) / 4.0)

			vxDeltal# = (gradient#(x,yp1,0) - gradient#(x,y,0)) / wave_ratio
			vyDeltal# = (gradient#(x,yp1,1) - gradient#(x,y,1)) / wave_ratio
			
			lBasex# = gradient#(x,y,0)
			lBasey# = gradient#(x,y,1)

			vxDeltar# = (gradient#(xp1,yp1,0) - gradient#(xp1,y,0)) / wave_ratio
			vyDeltar# = (gradient#(xp1,yp1,1) - gradient#(xp1,y,1)) / wave_ratio
			
			rBasex# = gradient#(xp1,y,0)
			rBasey# = gradient#(xp1,y,1)


			'      \|/--- Make this a 1 To see the size of the polygon
			For j = 0 To wave_ratio-1

				xDelta# =Float(rBasex# - lBasex#)/ Float(wave_ratio)
				xBase# = lBasex#
				
				yDelta# =Float(rBasey# - lBasey#)/ Float(wave_ratio)
				yBase# = lBasey#

				'      \|/--- Make this a 1 To see the size of the polygon
				For i = 0 To wave_ratio-1
					ttx21 = ( xp+i+xBase# ) * tex_ratio
					tty21 = ( yp+j+yBase# ) * tex_ratio
					If ttx21 > tex_width-1 Then ttx21 = tex_width-1
					If tty21 > tex_height-1 Then tty21 = tex_height-1
					If ttx21 < 0 Then ttx21 = 0
					If tty21 < 0 Then tty21 = 0
					
					WritePixel(pix,xp+i,yp+j,textureimg[ttx21, tty21])
					xBase# = xBase# + xDelta#
					yBase# = yBase# + yDelta#   
				Next
				lBasex# = lBasex# + vxDeltal# 
				lBasey# = lBasey# + vyDeltal# 
				rBasex# = rBasex# + vxDeltar# 
				rBasey# = rBasey# + vyDeltar# 
			Next
		Next
	Next
	SetColor 255,255,255
	DrawImage image,0,0	

	

	' swap wave map For update, Very imortant To have this line included
	frnt = 1 - frnt	
	
	SetColor 255,0,0
	Plot MouseX(),MouseY()
	
	End Function


End

the original can be downloaded from here it is in BBASIC:
http://dbfinteractive.com/index.php?topic=578.0

@Jesse: Wow - Your example is great but for inside a game it's unusable because it's very slow :-(

@AngelDaniel: How can I access the stencial buffer in BlitzMax. Do you have links to any examples?

I only know you can do stencil buffer in OpenGL, not sure about DX. you'll have to read the online opengl documentation. red book/blue book.

Otherwise, have a set of pre rendered animations that you overlay.

I don't know. But if you figure it out let me know.

You can do stencil buffer with both apis, you just have to set the flag correctly when creating the graphics context. (default is only backbuffer + depth, but there are other buffers as well. Fredborg create quite some time ago an interesting "light" example using accum buffer for example)

Very nice effect... Too bad that it is so demanding to the computer.

@maverick69 - You know you can change the leve of detail by pressing 1 to 4. Level 1 is the fastest while level 4 is the slowest but you sacrifice details. use arrow keys to set the level of pressure. Sorry for not mentioning that before.

@Dreamora - thanks! I'll look it up. It would be easier if you provide me with a link. lazy me!

never mind Dreamora I found it.