Jump to content

Water animation code


Josh
 Share

Recommended Posts

This BlitzMax program is what I used to make the default water animation in Leadwerks:

SuperStrict

Framework brl.pixmap
Import brl.pngloader
Import brl.random
Import brl.jpgloader
Import BRL.FileSystem
Import brl.standardio

Local size:Int=512
Local outname:String="water1"

Local pixmap:TPixmap=LoadPixmap("water_frame01_normal.png")

size=pixmap.width

Local buffer1:Float[size,size]
Local buffer2:Float[size,size]

For Local x:Int=0 To size-1
	For Local y:Int=0 To size-1
		Local i:Int=pixmap.ReadPixel(x,y)
		Local c:Byte[4]
		MemCopy c,Varptr i,4
		buffer1[x,y]=c[0]/255.0
		buffer2[x,y]=c[0]/255.0
	Next
Next

Const frames:Int=128

Local frame:TPixmap[frames*3/2]

CreateDir "Frames"

For Local i:Int=0 To frame.length-1
	Update buffer1,buffer2,size
	Update buffer2,buffer1,size	
	
	frame[i]=CreatePixmap(size,size,PF_RGBA8888)
	For Local x:Int=0 To size-1
		For Local y:Int=0 To size-1
			Local r:Int=buffer1[x,y]*255.0+0.5
			If r>255 r=255
			If r<0 r=0
			Local c:Byte[4]
			c[0]=r
			c[1]=r
			c[2]=r
			c[3]=255			
			Local clr:Int
			MemCopy Varptr clr,c,4
			frame[i].WritePixel(x,y,clr)
		Next
	Next
Next

For Local i:Int=frames/2 To frames*3/2-1
	Local n:Int=i-frames/2
	
	If i>frames
		Mix(frame[i],frame[i-frames],1.0-(n-frames/2)/Float(frames/2))
	EndIf
	
	Local h:Float=0.5
	
	'If n<10
	'	SavePixmapPNG PixmapFilterDot3(frame[i],h),"Frames/"+outname+"_0"+n+".png"	
	'Else
		SavePixmapPNG PixmapFilterDot3(frame[i],h),"Frames/"+outname+"_"+n+".png"
	'EndIf
Next

Function Mix(pixmap0:TPixmap,pixmap1:TPixmap,m:Float)
	For Local x:Int=0 To pixmap0.width-1
		For Local y:Int=0 To pixmap0.height-1
			Local c0:Byte[4]
			Local c1:Byte[4]
			Local color0:Int,color1:Int
			color0=pixmap0.ReadPixel(x,y)
			MemCopy c0,Varptr color0,4
			color1=pixmap1.ReadPixel(x,y)
			MemCopy c1,Varptr color1,4
			c0[0]=c1[0]*(1.0-m)+c0[0]*m
			c0[1]=c1[1]*(1.0-m)+c0[1]*m
			c0[2]=c1[2]*(1.0-m)+c0[2]*m
			c0[3]=c1[3]*(1.0-m)+c0[3]*m
			MemCopy Varptr color0,c0,4
			pixmap0.WritePixel x,y,color0
		Next
	Next
EndFunction

Function Update(buffer1:Float[,],buffer2:Float[,],size:Int)
	Local damping:Float=1.0
	For Local x:Int=0 To size-1
		For Local y:Int=0 To size-1
			Local Smoothed:Float = 0
			Smoothed :+ Read(buffer1,x-1,y-1,size)
			Smoothed :+ Read(buffer1,x+0,y-1,size)
			Smoothed :+ Read(buffer1,x+1,y-1,size)
			Smoothed :+ Read(buffer1,x-1,y+0,size)
			Smoothed :+ Read(buffer1,x+1,y+0,size)
			Smoothed :+ Read(buffer1,x-1,y+1,size)
			Smoothed :+ Read(buffer1,x+0,y+1,size)
			Smoothed :+ Read(buffer1,x+1,y+1,size)			
			Smoothed :/ 8.0
			' + Read(buffer1,x+1,y,size) + Read(buffer1,x,y-1,size) + Read(buffer1,x,y+1,size)) / 4.0
			Local velocity:Float=-Buffer2[x,y]
			Local damping:Float=1.0
            Buffer2[x,y] = Smoothed*2.0 + velocity
			Buffer2[x,y] :* Damping;
		Next
	Next
EndFunction

Function Read:Float(buffer:Float[,],x:Int,y:Int,size:Int)
	If x<0 x=size+x
	If y<0 y=size+y
	If x>size-1 x=x-size
	If y>size-1 y=y-size
	Return buffer[x,y]
EndFunction

Function ReadHeight:Float(pixmap:TPixmap,x:Int,y:Int)
	Local hue:Int,r:Int,g:Int,b:Int
	While x<0
		x:+pixmap.width
	Wend
	While x>pixmap.width-1
		x:-pixmap.width
	Wend
	While y<0
		y:+pixmap.height
	Wend
	While y>pixmap.height-1
		y:-pixmap.height
	Wend
	hue=ReadPixel(pixmap,x,y)
	r=(hue & $00FF0000) Shr 16
	g=(hue & $0000FF00) Shr 8
	b=(hue & $000000FF)
	Return Float(r)*0.3+Float(g)*0.59+Float(b)*0.11
EndFunction

Function PixmapFilterDot3:TPixmap(pixmap:TPixmap,height#=1.0,parallax:Int=0)
	Local lp:Int,rp:Int,tp:Int,bp:Int
	Local bumpmap:TPixmap
	Local vx#,vy#,vz#,m#
	Local tl#,bl#,ml#,tr#,mr#,br#,mm#,bm#,tm#
	Local isq2#,sum#,al#,ar#,at#,ab#,r:Int,g:Int,b:Int,a:Int,x:Int,y:Int
	Local format:Int
	
	If parallax
		bumpmap=CreatePixmap(pixmap.width,pixmap.height,PF_RGBA8888)
	Else
		bumpmap=CreatePixmap(pixmap.width,pixmap.height,PF_RGB888)	
	EndIf
	
	For x=0 To pixmap.width-1
		For y=0 To pixmap.height-1
			
			lp=x-1
			rp=x+1
			tp=y-1
			bp=y+1
			If lp<0 lp=pixmap.width-1
			If lp>pixmap.width-1 lp=0
			If rp<0 rp=pixmap.width-1
			If rp>pixmap.width-1 rp=0
			If tp<0 tp=pixmap.width-1
			If tp>pixmap.height-1 tp=0
			If bp<0 bp=pixmap.width-1
			If bp>pixmap.height-1 bp=0
			
			tl#=ReadHeight(pixmap,x-1,y-1)
			tm#=ReadHeight(pixmap,x,y-1)
			tr#=ReadHeight(pixmap,x+1,y-1)
			ml#=ReadHeight(pixmap,x-1,y)
			mm#=ReadHeight(pixmap,x,y)
			mr#=ReadHeight(pixmap,x+1,y)
			bl#=ReadHeight(pixmap,x-1,y+1)
			bm#=ReadHeight(pixmap,x,y+1)
			br#=ReadHeight(pixmap,x+1,y+1)
			
			vx#=0.0
			vy#=0.0
			vz#=1.0
			
			isq2#=1.0/Sqr(2.0)
			sum#=1.0+isq2+isq2
			
			al#=(tl*isq2+ml+bl*isq2)/sum
			ar#=(tr*isq2+mr+br*isq2)/sum
			at#=(tl*isq2+tm+tr*isq2)/sum
			ab#=(bl*isq2+bm+br*isq2)/sum			

			vx#=(al-ar)/255.0
			vy#=(at-ab)/255.0
			m=Max(0,vx*vx+vy*vy)
			m=Min(m,1.0)

			vz=Sqr(1.0-m) 
			
			If height<>0.0
				vz:*height
				m#=Sqr(vx*vx+vy*vy+vz*vz)
				vx:/m
				vy:/m
				vz:/m
			EndIf
			
			r=vx*127.5+127.5+0.5'0.5 added for rounding
			g=vy*127.5+127.5+0.5
			b=vz*127.5+127.5+0.5
			a=mm'store height value in alpha channel
			
			r=Min(r,255)
			r=Max(r,0)
			g=Min(g,255)
			g=Max(g,0)
			b=Min(b,255)
			b=Max(b,0)
			
			WritePixel bumpmap,x,y,b+(g Shl 8)+(r Shl 16)+(a Shl 24)
		Next
	Next
	Return bumpmap
EndFunction

Seed image:

water_frame01_normal.png.efe294d737a96ca05c4dbb6c7aedf72b.png

I also uploaded it here:

 

 

  • Like 2
  • Thanks 1

My job is to make tools you love, with the features you want, and performance you can't live without.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

 Share

×
×
  • Create New...