Ocean v2 (shader OpenGL)

Everything related to 3D programming
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 291
Joined: Thu Jul 09, 2015 9:07 am

Ocean v2 (shader OpenGL)

Post by pf shadoko »

[EDIT 28/03/24]
adapted for PB6 (no scripting required, shaders are created in code)


Hi guys,

I made a shader for the waves
you'll see, it's much more realistic.

put on your oilskin

Code: Select all

; Océan v2 - pf Shadoko - 2020
EnableExplicit

DeclareModule ext_3D
	EnableExplicit
	Global inittime
	
	Structure f3
		x.f
		y.f
		z.f
	EndStructure
	
	Structure f2
		x.f
		y.f
	EndStructure
	
	Structure PB_MeshVertexV
		p.f3
		n.f3
		t.f3
		u.f
		v.f
		color.l
	EndStructure
	
	;________________ Lib ________________
	Declare vec3d(*v.f3,vx.f,vy.f,vz.f)
	Declare sub3D(*p.f3,*p1.f3,*p2.f3)
	Declare mul3d(*p1,v.f)
	Declare.f lng3D(*v.f3)    
	Declare norme3d(*v.f3,l.f=1)    
	Declare.f Max(v1.f,v2.f)
	Declare.f Min(v1.f,v2.f)
	Declare.f limite(V.f, i.f, s.f) 
	Declare.i Modi(v,divisor)
	Declare.f interpolarray2d(Array tt.f(2),x.f,y.f) 
	Declare ColorBlend(color1.l, color2.l, blend.f) 
	Declare GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0) 
	Declare Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
	Declare  blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
	Declare Embos2D(Array s.f(2), px.w=0, py.w=0)
	Declare grad2D(Array s.f(2),delta=1)
	Declare  outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
	Declare textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
	Declare textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
	
	;________________ océan ________________
	
	Global oc_mesh,oc_material,oc_txtnm,oc_txtdif,oc_particule,   oc_waveb.f, oc_wavel.f,oc_swell.f, oc_foam.f  
	Global oc_tilesize,oc_tilesize2,oc_prec,oc_tilenb,oc_tilenb1
	Global oc_tn,oc_tn1,oc_tn2
	Declare initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
	Declare freeocean()
	Declare renderocean()
	Declare.f oceanHeight(x.f,z.f)
	Declare oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
	
	;________________ SkyDome2 ________________
	Global skydome_m, skydome_e
	Declare SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
	Declare SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)	
EndDeclareModule 

Module ext_3D
DisableDebugger	
	;{ ============================= biblio
	
	Procedure vec3d(*v.f3,vx.f,vy.f,vz.f)
		*v\x=vx
		*v\y=vy
		*v\z=vz
	EndProcedure
	
	Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
		*p\x=*p1\x-*p2\x
		*p\y=*p1\y-*p2\y
		*p\z=*p1\z-*p2\z
	EndProcedure
	
	Procedure add3d(*p.f3,*p1.f3,*p2.f3)
		*p\x=*p1\x+*p2\x
		*p\y=*p1\y+*p2\y
		*p\z=*p1\z+*p2\z
	EndProcedure
	
	Procedure mul3d(*p1.f3,v.f)
		*p1\x*v
		*p1\y*v
		*p1\z*v
	EndProcedure
	
	Procedure.f lng3D(*v.f3)
		ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
	EndProcedure
	
	Procedure Norme3D(*V.f3,l.f=1)
		Protected.f lm
		lm = l / lng3d(*v)
		*V\x * lm
		*V\y * lm
		*V\z * lm  
	EndProcedure
	
	Procedure.f Max(v1.f,v2.f)
		If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
	EndProcedure
	
	Procedure.f Min(v1.f,v2.f)
		If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
	EndProcedure
	
	Procedure.f limite(V.f, i.f, s.f)
		If V < i :v=i:EndIf
		If V > s :v=s:EndIf
		ProcedureReturn V
	EndProcedure
	
	Procedure.i Modi(v,divisor) 
		ProcedureReturn (V+$10000*divisor) % divisor
	EndProcedure
	
	Procedure.f POM(v.f)
		ProcedureReturn (Random(v*1000)-v*500)/500
	EndProcedure
	
	;##############################################################################################
	
	Procedure CoRBinv(c.l)
		ProcedureReturn  RGBA(Blue(c),Green(c),Red(c),Alpha(c))
	EndProcedure
	
	Procedure ColorBlend(color1.l, color2.l, blend.f)
		Protected r.w,g.w,b.w,a.w
		r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
		g=Green(color1) + (Green(color2) - Green(color1)) * blend
		b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
		a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
		ProcedureReturn  RGBA(r,g,b,a)
	EndProcedure
	
	Procedure GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
		Protected i,j, apos,pos, acol.l,col.l,p,lt.s
		n-1
		Dim pal(n)
		
		Repeat
			apos=pos
			acol=col
			i+1
			lt=StringField(gradient,i,"/"):If lt="":Break:EndIf
			pos=ValF(lt)*n
			p=FindString(lt,",")
			If p
				col=Val(Mid(lt,p+1))
				If inv  :col=CoRBinv(col):EndIf
				If alpha:col | $ff000000:EndIf
			Else
				col=acol
			EndIf
			For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
		ForEver
	EndProcedure
	
	Procedure Array2Dlimit(Array t.f(2),*min.float,*max.float)
		Protected i,j,dx1,dy1
		Protected.f v,smin,smax
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		smax = -1e10
		smin =  1e10
		For j=0 To dy1
			For i=0 To dx1
				v=t(j,i)
				If v<smin : smin=v: EndIf
				If v>smax : smax=v: EndIf
			Next
		Next
		*min\f=smin
		*max\f=smax
	EndProcedure
	
	Procedure Array2Dclamp(Array t.f(2),min.f,max.f)
		Protected i,j,dx1,dy1
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		For j=0 To dy1
			For i=0 To dx1
				t(j,i)=limite(t(j,i),min,max)
			Next
		Next
	EndProcedure
	
	Procedure blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
		If di=0 And dj=0:ProcedureReturn:EndIf
		Protected i,j,k,d,dii,djj,dx,dy,dij,tx.f
		
		dx = ArraySize(s(), 2):di=min(di,dx)
		dy = ArraySize(s(), 1):dj=min(dj,dy)
		Dim d.f(dy,dx)
		dii=di+1
		djj=dj+1
		dij = dii * djj
		
		If loop
			d=dx-dii/2:Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = (i+d) % (dx+1): Next
			d=dx-dii/2:Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = (i+d) % (dy+1): Next    
		Else
			Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = limite(i-1-dii/2, 0, dx): Next
			Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = limite(i-1-djj/2, 0, dy): Next
		EndIf  
		For k=1 To pass
			Dim ty.f(dx)
			For j = 0 To djj - 1: For i = 0 To dx: ty(i) + s(ly(j),i): Next: Next    
			For j = 0 To dy
				For i = 0 To dx: ty(i) + s(ly(djj+j),i) - s(ly(j),i): Next
				tx=0:For i = 0 To dii-1: tx+ty(lx(i)): Next
				For i = 0 To dx: tx + ty(lx(dii+i)) - ty(lx(i) ): d(j,i) = tx / dij: Next
			Next
			CopyArray(d(),s())
		Next
	EndProcedure
	
	Procedure Embos2D(Array s.f(2), px.w=0, py.w=0)
		Protected i,j,dx,dy
		px=1<<Int(Abs(px))*Sign(px)
		py=1<<Int(Abs(py))*Sign(py)
		
		Macro gra(j0,i0,j1,i1)
			t(j0,i0)=Abs(s(j0,i0)-s(j0,i1)+px)+Abs(s(j0,i0)-s(j1,i0)+py)
		EndMacro
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim T.f(dy,dx)
		For j=0 To dy-1
			For i=0 To dx-1
				gra(j,i,j+1,i+1)
			Next
			gra(j,dx,j+1,0)
		Next
		For i = 0 To dx-1
			gra(dy,i,0,i+1)
		Next
		gra(dy,dx,0,0)
		CopyArray(t(),s())
	EndProcedure
	
	Procedure grad2D(Array s.f(2),delta=1)
		Protected i,j,dx,dy
		
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim d.f(dy,dx)
		For j=0 To dy
			For i=0 To dx
				d(j,i)= 4*s(j,i)   -s(j,(i-delta) & dx)-s(j,(i+delta) & dx)-s((j-delta) & dy,i)-s((j+delta) & dy,i)
			Next
		Next
		CopyArray(d(),s())
	EndProcedure
	
	Procedure superpose(Array s.f(2),n.w=1)
		Protected i,j,k,dx,dy,x,y,ii,jj
		
		dy = ArraySize(s(), 1)
		dx = ArraySize(s(), 2)
		Dim T.f(dy,dx)
		For k=1 To n
			x=Random(dx)
			y=Random(dy)
			For j=0 To dy
				For i=0 To dx
					t(i,j)+s((i+x) & dx,(j+y) & dy)
				Next
			Next
		Next
		CopyArray(t(),s())
	EndProcedure
	
	Procedure Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
		Protected i,j,n,d,dd,d3,dx1=dx-1,dy1=dy-1,coef.f=9,den.f=1/(2*coef-2),amp.f=1/$1000
		Dim t(dy1, dx1)
		
		RandomSeed(rnd)
		n = 1<<oinit
		dd=min(dx,dy) / n: If dd<1:dd=1:EndIf
		j=0:While j<dy1:i=0:While i<dx1: t(j,i) = (Random($2000) - $1000)*amp:i+dd:Wend:j+dd:Wend
		While dd > 1
			If onb=0:amp=0:EndIf
			d = dd / 2:d3=d*3:amp/2
			j=d:While j<dy
				i=0:While i<dx
					t(j,i) = (-t((j - d3) & dy1,i) - t((j +d3) & dy1,i) + coef*(t((j - d) & dy1,i) + t((j + d) & dy1,i))) *den + (Random($2000) - $1000)*amp
				i+dd:Wend
			j+dd:Wend
			j=0:While j<dy
				i=d:While i<dx
					t(j,i) = (-t(j,(i - d3) & dx1) - t(j,(i +d3) & dx1) + coef*(t(j,(i - d) & dx1) + t(j,(i + d) & dx1))) *den + (Random($2000) - $1000)*amp
				i+dd:Wend
			j+d:Wend
			dd/2:onb-1
		Wend     
	EndProcedure
	
	Procedure Finterpol(Array F.f(1),profil.s,dmin.f=1,dmax.f=0)
		Protected.l i,j,n,c,ac,rx,   t.s
		Protected.f y,dx,dy,p
		
		rx=ArraySize(f())
		n=CountString(profil,"/")
		Dim s.f2(n)
		For i=0 To n
			t=StringField(profil,i+1,"/")
			s(i)\x=ValF(t)*rx
			s(i)\y=ValF(StringField(t,2,","))*(dmax-dmin)+dmin
		Next  
		
		For j=0 To n-1
			y=s(j)\y
			dx=s(j+1)\x-s(j)\x
			dy=s(j+1)\y-s(j)\y
			p=dy/dx
			ac=c
			While c<=s(j+1)\x
				f(c)=y+p*(c-ac):c+1
			Wend
		Next
	EndProcedure
	
	Procedure outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
		Protected dx1,dy1,i,ii,j,k,xi
		Protected.f smin,smax,sr,tt,x,y0,y1,x0,dminl,dmaxl
		
		dy1 = ArraySize(t(), 1)
		dx1 = ArraySize(t(), 2)
		Array2Dlimit(t(),@smin,@smax)
		sr=smax-smin
		
		Dim conv.f(256)
		Finterpol(conv(),outline,dmin,dmax)
		If smaxl-sminl<>0
			ii=(sminl-smin)/sr*255:For i=0 To ii:conv(i)=conv(ii):Next
			ii=(smaxl-smin)/sr*255:For i=ii To 255:conv(i)=conv(ii):Next
		EndIf
		
		For j=0 To dy1
			For i=0 To dx1
				x=(t(j,i)-smin)/sr*255
				xi=Int(x):x0=x-xi
				y0=conv(xi)
				y1=conv(xi+1)
				t(j,i)=y1*x0+y0*(1-x0)
			Next
		Next
	EndProcedure
	
	Procedure textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
		Protected i,j,n,dx,dy
		Protected.f min,max,r
		
		dx=ArraySize(t(),2)+1
		dy=ArraySize(t(),1)+1
		Dim bmp.l(dy-1,dx-1)
		
		Protected Dim grad.l(0):gradienttoarray(grad(),1024,grad,1)
		Array2Dlimit(t(),@min,@max):r=1023/(max-min)
		For j=0 To dy-1:For i=0 To dx-1:n=(t(j,i)-min)*r:bmp(j,i)=grad(n):Next:Next
		n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
		StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
		
		ProcedureReturn tex
	EndProcedure
	
	Procedure textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
    Protected i,j,nn,dx,dy
    Protected.f h00,h10,h01, max=1/amplitude
    Protected.f3 n
    
    Dim a.f(0,0) :CopyArray(t(),a())
    Select alphavalue
        Case 0:outline2d(a(),0,255)
        Case 1:grad2d(a(),4):Array2Dclamp(a(),-1,0):outline2d(a(),0,255,"0,0/1,1")
    EndSelect
    
    dx=ArraySize(t(),2)+1
    dy=ArraySize(t(),1)+1
    Dim bmp.l(dy-1,dx-1)
    For j=0 To dy-1
        For i=0 To dx-1
            h00=t(j,i)
            h10=t(j,(i+1) % dx)
            h01=t((j+1) % dy,i)
            vec3d(n,h00-h10, max, h00-h01):Norme3D(n,127)
            bmp(j,i)=RGBA(n\y+128,n\z+128,n\x+128,a(j,i))
        Next
    Next  
    nn=CreateTexture(tex,dx,dy):If tex=-1:tex=nn:EndIf
    StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
    ProcedureReturn tex
EndProcedure
	
	Procedure.f interpolarray2d(Array tt.f(2),x.f,y.f)
		Protected.l i0, j0,i1,j1,dx1,dy1
		Protected.f dx, dy
		dx1=ArraySize(tt(),1)
		dy1=ArraySize(tt(),2)
		i0 = Int(X) & dx1:i1=(i0+1) & dx1: dx = X - Int(x)
		j0 = Int(Y) & dy1:j1=(j0+1) & dy1: dy = Y - Int(y)
		ProcedureReturn (((1 - dx) * tt(j0,i0) + dx * tt(j0,i1)) * (1 - dy) + ((1 - dx) * tt(j1,i0) + dx * tt(j1,i1)) * dy)
	EndProcedure
	
	;}===================================================================================================================================================
	
	;{ Océan
	
	Procedure initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
		; tilesize: must be a power of 2 
		; precision : 1-> 1 meters,  2->2 meters, 3->4 meters, 4-> 8 meters...
		; range : distance to the camera where the oocean should be rendered
		; wavebig,wavelittle,swell,foam : value: 0.0 -> 1.0
		; particule : for sea spray
		; heightmap : texture containing the depth. only the red component is used : red=depth*16+128, and clamped between 0 and 255 
		
		Protected i,j,k,r,n,a.f,vert_pg.s,frag_pg.s
		oc_tilesize=tilesize:oc_tilesize2=oc_tilesize/2
		oc_prec=1<<(prec-1)
		oc_tilenb=range/tilesize*2:oc_tilenb1=oc_tilenb-1 
		oc_tn=oc_tilesize/oc_prec:oc_tn1=oc_tn-1:oc_tn2=oc_tn/2
		oc_particule=particule
		
		Global Dim oc_h.f(oc_tn1,oc_tn1)
		Global Dim oc_entity(oc_tilenb1,oc_tilenb1)
		
		Dim t.f(0,0)
		;Waves (noramlmap)
		Noise2d(oc_h(),512,512,0,4)
		outline2d(oc_h(),0,1,"0,0/0.5,1/1,0")
		blur2D(oc_h(),1,1,1)    
		oc_txtnm=textureArraytoNM(-1,oc_h(),16) 
						
		;foam (diffusemap)
		Noise2d(t(),512,512,0,7)
		outline2d(t(),0,1,"0,0/0.2,0.2/0.5,1/0.7,0.2/1,0") 
		oc_txtdif=textureArrayToColor(-1,t()) 
		
vert_pg="%%%%%uniform mat4 P0;//+0%uniform mat4 P16;//+16%uniform vec4 P76;//+76%uniform vec4 P43;//+43 0%uniform vec4 P32;//+32%uniform float P86;//+86 0.01%%uniform sampler2D heightMap;//2%uniform sampler2D normalMapv;//0%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying float owave;%varying float odist;%varying vec2 ouv;%%void main(void)%{%vec4 opos=(P0*gl_Vertex);%vec2 uv=opos.xz/256;%vec2 duv=vec2(P86,0);%vec4 wave=texture2D(normalMapv,uv+duv)+texture2D(normalMapv,uv+0.5-duv)-1;wave.xy*=(P32.x);%float a=uv.y*20-P86*100;%float sweel=sin(a);%opos.y=wave.w*P32.x*4+sweel*P32.z*4;%wave.y-=cos(a)*P32.z*1;%onormal=normalize(wave.xzy);%owave=wave.w;%float height=texture2D(heightMap,uv).r*16-8;%float fond=clamp((height-opos.y)*0.25+1,0,1);%opos.y+=fond*wave.w;%owave=owave+fond*2;%gl_Position=P16*opos;%odist=gl_Position.z;%oviewdir=normalize(P76.xyz-opos.xyz);%olightdir=normalize(P43.xyz-opos.xyz);%ouv=uv*16;%}%%%%%%%%%%%%%%"
frag_pg="%%%%%uniform vec4 P40;//+40 0%uniform vec4 P32;//+32%uniform float P36;//+36%uniform vec4 P31;//+31%uniform vec4 P30;//+30%uniform vec4 water;%uniform vec4 P69;//+69 0%uniform vec4 P70;//+70 0%uniform float P86;//+86 0.01%%uniform sampler2D normalMap;//0%uniform sampler2D diffuseMap;//1%%varying vec3 oviewdir;%varying vec3 olightdir;%varying vec3 onormal;%varying float owave;%varying float odist;%varying vec2 ouv;%%%void main()%{%float f;%vec4 fcolor;%if(P31.z>0){f=min(odist*P31.w,1);fcolor=P30;}%%vec2 duv=vec2(P86*4,0);%vec4 txt=texture2D(normalMap,ouv+duv)+texture2D(normalMap,ouv+0.5-duv)-1;%vec3 tnor=normalize(txt.xyz);%vec3 normal=onormal;normal.xz+=tnor.xy*P32.y*2;%normal=normalize(normal);%float fresnel=1-abs(dot(oviewdir,normal));%float ecume=clamp((txt.w+owave-2+P32.w)*2,0,1);%vec4 color=mix(P69,P70,fresnel*fresnel);%%vec3 halfangle=normalize(olightdir+oviewdir);%float spe=pow(max(dot(halfangle,normal),0),P36);%color+=P40*mix(spe,texture2D(diffuseMap,ouv*4).r,ecume);%%gl_FragColor=mix(color,fcolor,f);%}%%%%%%%%%%%%%%"
CreateShader(1000,vert_pg,frag_pg)
oc_material=CreateShaderMaterial(-1,1000):MaterialShaderTexture(oc_material,TextureID(oc_txtnm),TextureID(oc_txtdif),TextureID(heightmap),0)
		MaterialFilteringMode(oc_material,#PB_Material_Anisotropic,4)
		MaterialShininess(oc_material,64*2)
		SetMaterialAttribute(oc_material,#PB_Material_TAM,#PB_Material_ClampTAM,2)
		oceanset(wavebig,wavelittle,swell,foam,watercolor,skycolor)
		
		For k=0 To 4:r=1<<k
			Dim mv.PB_MeshVertexv(oc_tn/r,oc_tn/r)
			For j=0 To oc_tn/r
				For i=0 To oc_tn/r
					With mv(j,i) 
						vec3d(\p,(i*r-oc_tn2)*oc_prec,pom(8),-(j*r-oc_tn2)*oc_prec)          
						\u=i*r/oc_tn
						\v=j*r/oc_tn
					EndWith
				Next
			Next
			If k=0
				oc_mesh=CreateDataMesh(-1,mv())
			Else
				n=CreateDataMesh(-1,mv())
				AddMeshManualLOD(oc_mesh,n,128 *r)
				SetMeshMaterial(n,MaterialID(oc_material))
			EndIf
		Next
		
		For j=0 To oc_tilenb1
			For i=0 To oc_tilenb1
				oc_entity(j,i)=CreateEntity(-1,MeshID(oc_mesh),MaterialID(oc_material))
			Next
		Next
	EndProcedure
	
	Procedure freeocean()
		Protected i,j
		For j=0 To ArraySize(oc_entity(),1)
			For i=0 To ArraySize(oc_entity(),2)
				FreeEntity(oc_entity(j,i))
			Next
		Next
		FreeMesh(oc_mesh)
		FreeArray(oc_entity())
		FreeMaterial(oc_material)
		FreeTexture(oc_txtnm)
		FreeTexture(oc_txtdif)
	EndProcedure
	
	Procedure.f oceanHeight(x.f,z.f)
		Protected time.f=(ElapsedMilliseconds()-inittime)/1000*0.01, dx.f=time*512
		x*2-0.5
		z*2-0.5
		ProcedureReturn (interpolarray2d(oc_h(),x+dx,z)+interpolarray2d(oc_h(),x+256-dx,z+256)-1)*oc_waveb*4+Sin(z/512*20-time*100)*oc_swell*4
	EndProcedure
	
	Procedure oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
		oc_waveb=wavebig
		oc_wavel=wavelittle
		oc_swell=swell
		oc_foam =foam	
		SetMaterialColor(oc_material,1,RGBA(wavebig*255,wavelittle*255,swell*255,foam*255))
		If watercolor:SetMaterialColor(oc_material,2,watercolor):EndIf
		If skycolor:SetMaterialColor(oc_material,4,skycolor):EndIf
	EndProcedure
	
	Procedure renderocean()
		Protected i,j,  pos.f3
		
		If oc_particule>=0
			pos\x=CameraX(0)+pom(100)+CameraDirectionX(0)*100
			pos\z=CameraZ(0)+pom(100)+CameraDirectionZ(0)*100
			pos\y=oceanHeight(pos\x,pos\z)+1
			If pos\y>0:MoveParticleEmitter(oc_particule,pos\x,pos\y,pos\z,#PB_Absolute):EndIf
		EndIf
		;------------------- tuiles
		Protected da=oc_tilenb*oc_tilesize
		Static api=0,pi=1000,  apj=0,pj=1000,  i0,i1,  j0,j1,  e
		api=pi:pi=(CameraX(0)-da/2)/oc_tilesize:If pi<api:i0=pi:i1=api-1:Else:i0=api+1+oc_tilenb1:i1=pi+oc_tilenb1:EndIf
		apj=pj:pj=(CameraZ(0)-da/2)/oc_tilesize:If pj<apj:j0=pj:j1=apj-1:Else:j0=apj+1+oc_tilenb1:j1=pj+oc_tilenb1:EndIf
		For j=pj To pj+oc_tilenb1
			For i=pi To pi+oc_tilenb1
				If (i>=i0 And i<=i1) Or (j>=j0 And j<=j1)
					MoveEntity(oc_entity(Modi(j,oc_tilenb),Modi(i,oc_tilenb)), i*oc_tilesize+oc_tilesize2,0,j*oc_tilesize+oc_tilesize2,#PB_Absolute)
				EndIf
			Next
		Next 
		
		;------------------- sous / sur l'eau
		If CameraY(0)<oceanHeight(CameraX(0),CameraZ(0))
			Fog($332200,100,0,30)
			MaterialCullingMode(oc_material,#PB_Material_AntiClockWiseCull)
		Else
			Fog($ffaa88,100,0,da/2)
			MaterialCullingMode(oc_material,#PB_Material_ClockWiseCull)
		EndIf       
	EndProcedure
	;}
	
	;{ SkyDome2
	Procedure SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
		If skydome_m:FreeMesh(skydome_m):EndIf
		If skydome_e:FreeEntity(skydome_e):EndIf
		Protected i,j,d=16,icol   ,d1=d-1,d2=d/2,mesh
		Protected.f x,y,z,  xo,yo,  u,v,   ai,aj,  lat,lng, mx  
		Dim t.PB_MeshVertexv(d,d)
		Dim col.l(0)
		
		CreateMaterial(0,0)
		GradientToArray(col(),256,degrade)
		For j=0 To d
			For i=0 To d
				With t(i,j)
					xo=1-i/d2
					yo=1-j/d2
					lng=ATan2(xo,yo)
					mx=max(Abs(xo),Abs(yo))
					\u=(Cos(lng)* mx+1)/2
					\v=(Sin(lng)* mx+1)/2
					lat=mx* #PI/2
					x=Cos(lng)* Sin(lat)*rayon
					z=Sin(lng)* Sin(lat)*rayon
					y=Cos(lat)*hauteur
					vec3d(\p,-x,y,z)
					icol=255*(x+rayon)/(2*rayon)
					\color=$ff000000+col(icol)
				EndWith
			Next
		Next  
		skydome_m=CreateDataMesh(-1,t())
		skydome_e=CreateEntity(-1,MeshID(skydome_m),MaterialID(material))
		DisableMaterialLighting(material,1)
	EndProcedure
	
	Procedure SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)
		Protected layer
		AddMaterialLayer(0,TextureID(txt),#PB_Material_AlphaBlend) 
		layer=CountMaterialLayers(0)-1
		ScaleMaterial(0,scale,scale,layer)
		RotateMaterial(0,angle,#PB_Material_Fixed,layer)
		ScrollMaterial(0,0,scroll,#PB_Material_Animated,layer)
	EndProcedure
	;}
EnableDebugger	
EndModule
;#####################################################################################################################################################

UseModule ext_3d

Procedure texturecolor(tex,dx,dy,rnd=0,f=0,lissage=0,grad.s="0,$000000/1,$ffffffff",outline.s="0,0/1,1")
	Protected Dim t.f(0,0)
	
	Noise2d(t(),dx,dy,rnd,f)
	blur2D(t(),lissage,lissage,2)    
	outline2d(t(),0,1,outline)
	ProcedureReturn textureArrayToColor(tex,t(),grad) 
EndProcedure

Procedure texturenormal(tex,dx,dy,rnd=0,f=0,lissage=0,relief.f=1,outline.s="0,0/1,1",alphavalue=0)
	Protected Dim t.f(0,0)
	
	Noise2d(t(),dx,dy,rnd,f)
	outline2d(t(),0,1,outline)
	blur2D(t(),lissage,lissage,3)    
	ProcedureReturn textureArraytoNM(tex,t(),relief,alphavalue) 
EndProcedure

Procedure menu(waveb.f,wavel.f,swell.f,foam.f)
	Protected p=4
	Macro DT(t1,t2="")
		DrawText(8,p,t1)
		DrawText(100,p,t2)
		p+8+10*Bool(t1>"")
	EndMacro
	CreateSprite(0,240,200,#PB_Sprite_AlphaBlending)
; 	ProcedureReturn
	StartDrawing(SpriteOutput(0))
	DrawingMode(#PB_2DDrawing_AllChannels)
	DrawingFont(FontID(0))
	Box(0,0,240,200,$44000000)
	DrawingMode(#PB_2DDrawing_AllChannels|#PB_2DDrawing_Outlined)
	Box(0,0,240,200,$ffffffff)
	BackColor($44000000)
	FrontColor($ffffffff)
	dt("Moving:")
	dt("Mouse + wheel+ arrow keys")    
	dt("")
	dt("Commandes:")
	dt("[F1] / [F2]","Wave big: "+Str(waveb*100)+"%")
	dt("[F3] / [F4]","Wave little: "+Str(wavel*100)+"%")
	dt("[F5] / [F6]","Swell height: "+Str(swell*100)+"%")
	dt("[F7] / [F8]","foam: "+Str(foam*100)+"%")
	dt("[F11]","Fly/Walk")
	dt("[F12]","Wireframe")
	dt("[Esc]","Quit")
	StopDrawing()
EndProcedure

Procedure main()
	Protected sky,heightmap,seaspray	
	Protected ex,ey,c,v, i,j, fly=1,fdf
	Protected.f MouseX,Mousey,keyx,keyy,keyz,dist,aval, och, waveb,wavel,swell,foam
	
	InitEngine3D():InitSprite():InitKeyboard():InitMouse()
	
	ExamineDesktops()
	ex=DesktopWidth(0)
	ey=DesktopHeight(0)
	OpenWindow(0,0,0,ex,ey,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0))
; 	OpenScreen(ex,ey,32,"")
	LoadFont(0,"arial",11*100/DesktopScaledX(100))
	
	Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
	Parse3DScripts()
	
	;------------------- scene
	
	CreateCamera(0, 0, 0, 100, 100):CameraBackColor(0,$886644)
	MoveCamera(0,0,10,0)
	CameraLookAt(0, 0,10,-10)
	CreateLight(0,$ffffff, 10000, 10000,0)
	AmbientColor($444444)
	
	;---- ilot / island
	Protected di=256,dj=256,di1=di-1,dj1=dj-1,ii,jj,h.f,g.f,   x.f,y.f
	Dim h.f(0,0)
	Dim g.f(0,0)
	Dim t.PB_MeshVertexv(di,dj)
	
	Noise2d(h(),di,dj,0,3):outline2d(h(),0,20,"0,0/0.4,0.4/0.6,0.7/1,1")
	For j=0 To dj1:For i=0 To di1:x=i/di*#PI:y=j/dj*#PI:h(i,j)*Sin(x)*Sin(y)*#PI-8:Next:Next
	CopyArray(h(),g()):Embos2D(g(),0,0):outline2d(g(),0,255)
	
	For j=0 To dj:  jj=j & dj1
		For i=0 To di:ii=i & di1
			h=h(ii,jj)
			g=g(ii,jj)        
			With t(i,j)
				vec3d(\p,i,h,j)
				vec3d(\n,h((i-1) & di1,jj)-h((i+1) & di1,jj),2,h(ii,(j-1) & dj1)-h(ii,(j+1) & dj1)):norme3d(\n)
				\u=i*0.1
				\v=j*0.1
				Select g
					Case 0 To 80:\color=$44556677
					Case 80 To 120:\color=$445599aa
					Default:\color=$4488aadd
				EndSelect
				If h<7:\color | $ff000000 :EndIf
			EndWith
		Next
	Next    
	CreateDataMesh(10,t())
	BuildMeshTangents(10)
	texturecolor (10,1024,1024,0,5,0,"0,$00888888/1,$ffffffff","0,1/0.4,1/0.5,0/0.55,1/1,1")
	texturenormal(11,1024,1024,0,2,0,50,"0,1/0.3,0.4/0.5,0/0.7,0.4/1,1")
	CreateShaderMaterial(10,#PB_Material_BumpShader):MaterialShaderTexture(10,TextureID(10),TextureID(11),0,0)
	MaterialFilteringMode(10,#PB_Material_Anisotropic,4)
	MaterialShininess(10,64):SetMaterialColor(10,4,$ffffff)
	CreateEntity(10,MeshID(10),MaterialID(10))
	;heightmap
	heightmap=CreateTexture(-1,256,256)
	StartDrawing(TextureOutput(heightmap))
	For j=0 To dj1:For i=0 To di1:Plot(i,j,limite(h(i,j)*16+128,0,255)):Next:Next
	StopDrawing()
	
	
	;---- sky / ciel
	sky=texturecolor(-1,512,512,0,3,0,"0,$00ffffff/0.4/0.7,$ffffffff/1,$ff888888")
	SkyDome2(1024,200,0,"0,$ff8800/1,$ff8800")
	SkyDome2AddLayer(sky,0.1,0.04,0)      
	SkyDome2AddLayer(sky,0.2,0.04,90)      
	SkyDome2AddLayer(sky,0.4,0.04,180)      
	
	; Sea spray / embruns
	LoadTexture(4, "water.png")
	CreateMaterial(4, TextureID(4))
	DisableMaterialLighting(4, 1)
	MaterialBlendingMode   (4, #PB_Material_AlphaBlend)
	SetMaterialAttribute(4,#PB_Material_TAM,#PB_Material_ClampTAM)
	
	seaspray=CreateParticleEmitter(-1,8, 2, 8, #PB_Particle_Box)
	ParticleMaterial    (Seaspray, MaterialID(4))
	ParticleSize        (Seaspray, 0.25,0.25):ParticleScaleRate(Seaspray,4)
	ParticleColorFader(Seaspray, 0, 0, 0, -1)
	ParticleEmitterDirection(Seaspray, 0, 0.2, 1)
	ParticleTimeToLive  (Seaspray, 1,1)
	ParticleVelocity(Seaspray, 2,20)
	ParticleAcceleration(Seaspray, 0, -0.1, 0)
	ParticleAngle(Seaspray,-180,180)
	ParticleEmissionRate(Seaspray, 500)
	
	waveb=1
	wavel=0.4
	swell=0.4
	foam=0.6
	
	initocean(128,1,1024,waveb,wavel,swell,foam, $ff332200, $ff886644,Seaspray,heightmap)
	menu(waveb.f,wavel.f,swell.f,foam.f)
	inittime=ElapsedMilliseconds()
	Repeat
		While WindowEvent() :Wend
		ExamineMouse()
		ExamineKeyboard()
		MouseX = -MouseDeltaX() *  0.05
		MouseY = -MouseDeltaY() *  0.05
		Macro param(val,key1,key2)
			aval=val :val +(-KeyboardReleased(key1)+KeyboardReleased(key2))*0.1:val =limite(val ,0.1,1)
			If val <>aval:menu(waveb,wavel,swell,foam):oceanset(waveb,wavel,swell,foam):EndIf
		EndMacro
		param(waveb,#PB_Key_F1,#PB_Key_F2)
		param(wavel,#PB_Key_F3,#PB_Key_F4)
		param(swell,#PB_Key_F5,#PB_Key_F6)
		param(foam ,#PB_Key_F7,#PB_Key_F8)
		If KeyboardReleased(#PB_Key_F11):fly=1-fly:EndIf
		If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
		
		keyx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
		keyz=(-Bool(KeyboardPushed(#PB_Key_Up  ))+Bool(KeyboardPushed(#PB_Key_Down )))*0.5-MouseWheel()*10;-fly*0.2
		RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):dist+(keyz-dist)*0.05:MoveCamera  (0, KeyX, 0, dist)
		If fly=0:och+(oceanHeight(CameraX(0),CameraZ(0))+1-och)*0.2:MoveCamera(0,CameraX(0),och,CameraZ(0),#PB_Absolute):EndIf
		
		renderocean()
		RenderWorld()
		MoveEntity(skydome_e,CameraX(0),  -8,CameraZ(0),#PB_Absolute)
		DisplayTransparentSprite(0,8,8)
		FlipBuffers()
	Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(3)
EndProcedure

main()
Last edited by pf shadoko on Thu Mar 28, 2024 7:50 pm, edited 3 times in total.
User avatar
Jac de Lad
Enthusiast
Enthusiast
Posts: 106
Joined: Wed Jul 15, 2020 7:10 am
Contact:

Re: Ocean v2 (shader OpenGL)

Post by Jac de Lad »

I surely did something wrong: I just see grey triangles, a moving sky and a mountain a bit in the distance.

I copied the files, but don't know what to do to "compile with opengl". I thought this is set in the code?

Edit: I'm on Windows. read in the help about subsystems, ok. Changed the compiler option and the option in the project file. But it didn't help.
Edit2: Got it working. Wow, nice!
Edit3: But worked just once. Then SubSystem("OpenGL") always returns "0".
Edit4: Turning off Kaspersky seems to work right now...
Edit5: Seems to work now, even with Kaspersky on.
Last edited by Jac de Lad on Tue Dec 08, 2020 12:57 pm, edited 1 time in total.
BarryG
Addict
Addict
Posts: 3324
Joined: Thu Apr 18, 2019 8:17 am

Re: Ocean v2 (shader OpenGL)

Post by BarryG »

Looks great! I didn't notice there was a rocky island behind the view at first. Good job!

Is there a way to have those support files located somewhere else? I hate adding files to PureBasic's folder (I like to keep it clean).
User avatar
Psychophanta
Addict
Addict
Posts: 4997
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: Ocean v2 (shader OpenGL)

Post by Psychophanta »

Thanks, great one :!:
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
User avatar
Psychophanta
Addict
Addict
Posts: 4997
Joined: Wed Jun 11, 2003 9:33 pm
Location: Lípetsk, Russian Federation
Contact:

Re: Ocean v2 (shader OpenGL)

Post by Psychophanta »

pf shadoko wrote: because of the opengl/sprite problem, I couldn't display the commands
so:
- mouse+wheel+arrows to move
- [F1] / [F2] : size of the 'big' waves
- [F3] / [F4] : size of the 'small' waves
- [F5] / [F6] : swell
- [F7] / [F8] : foam

put on your oilskin
My best "oilskin" strategy:

Code: Select all

; Océan v2 - pf Shadoko - 2020

EnableExplicit

DeclareModule ext_3D
   EnableExplicit
   Global inittime
   
   Structure f3
      x.f
      y.f
      z.f
   EndStructure
   
   Structure f2
      x.f
      y.f
   EndStructure
   
   Structure PB_MeshVertexV
      p.f3
      n.f3
      t.f3
      u.f
      v.f
      color.l
   EndStructure

   ;________________ Lib ________________
   Declare vec3d(*v.f3,vx.f,vy.f,vz.f)
   Declare sub3D(*p.f3,*p1.f3,*p2.f3)
   Declare mul3d(*p1,v.f)
   Declare.f lng3D(*v.f3)   
   Declare norme3d(*v.f3,l.f=1)   
   Declare.f Max(v1.f,v2.f)
   Declare.f Min(v1.f,v2.f)
   Declare.f limite(V.f, i.f, s.f)
   Declare.i Modi(v,divisor)
   Declare.f interpolarray2d(Array tt.f(2),x.f,y.f)
   Declare ColorBlend(color1.l, color2.l, blend.f)
   Declare GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
   Declare Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
   Declare  blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
   Declare Embos2D(Array s.f(2), px.w=0, py.w=0)
   Declare grad2D(Array s.f(2),delta=1)
   Declare  outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
   Declare textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
   Declare textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
   
   ;________________ océan ________________
   
   Global oc_mesh,oc_material,oc_txtnm,oc_txtdif,oc_particule,   oc_waveb.f, oc_wavel.f,oc_swell.f, oc_foam.f
   Global oc_tilesize,oc_tilesize2,oc_prec,oc_tilenb,oc_tilenb1
   Global oc_tn,oc_tn1,oc_tn2
   Declare initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
   Declare freeocean()
   Declare renderocean()
   Declare.f oceanHeight(x.f,z.f)
   Declare oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
   
   ;________________ SkyDome2 ________________
   Global skydome_m, skydome_e
   Declare SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
   Declare SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)   
EndDeclareModule

Module ext_3D
   
   ;{ ============================= biblio
   
   Procedure vec3d(*v.f3,vx.f,vy.f,vz.f)
      *v\x=vx
      *v\y=vy
      *v\z=vz
   EndProcedure
   
   Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
      *p\x=*p1\x-*p2\x
      *p\y=*p1\y-*p2\y
      *p\z=*p1\z-*p2\z
   EndProcedure
   
   Procedure add3d(*p.f3,*p1.f3,*p2.f3)
      *p\x=*p1\x+*p2\x
      *p\y=*p1\y+*p2\y
      *p\z=*p1\z+*p2\z
   EndProcedure
   
   Procedure mul3d(*p1.f3,v.f)
      *p1\x*v
      *p1\y*v
      *p1\z*v
   EndProcedure
   
   Procedure.f lng3D(*v.f3)
      ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
   EndProcedure
   
   Procedure Norme3D(*V.f3,l.f=1)
      Protected.f lm
      lm = l / lng3d(*v)
      *V\x * lm
      *V\y * lm
      *V\z * lm
   EndProcedure
   
   Procedure.f Max(v1.f,v2.f)
      If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
   EndProcedure
   
   Procedure.f Min(v1.f,v2.f)
      If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
   EndProcedure
   
   Procedure.f limite(V.f, i.f, s.f)
      If V < i :v=i:EndIf
      If V > s :v=s:EndIf
      ProcedureReturn V
   EndProcedure
   
   Procedure.i Modi(v,divisor)
      ProcedureReturn (V+$10000*divisor) % divisor
   EndProcedure
   
   Procedure.f POM(v.f)
      ProcedureReturn (Random(v*1000)-v*500)/500
   EndProcedure
   
   ;##############################################################################################
   
   Procedure CoRBinv(c.l)
      ProcedureReturn  RGBA(Blue(c),Green(c),Red(c),Alpha(c))
   EndProcedure
   
   Procedure ColorBlend(color1.l, color2.l, blend.f)
      Protected r.w,g.w,b.w,a.w
      r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
      g=Green(color1) + (Green(color2) - Green(color1)) * blend
      b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
      a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
      ProcedureReturn  RGBA(r,g,b,a)
   EndProcedure
   
   Procedure GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
      Protected i,j, apos,pos, acol.l,col.l,p,lt.s
      n-1
      Dim pal(n)
     
      Repeat
         apos=pos
         acol=col
         i+1
         lt=StringField(gradient,i,"/"):If lt="":Break:EndIf
         pos=ValF(lt)*n
         p=FindString(lt,",")
         If p
            col=Val(Mid(lt,p+1))
            If inv  :col=CoRBinv(col):EndIf
            If alpha:col | $ff000000:EndIf
         Else
            col=acol
         EndIf
         For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
      ForEver
   EndProcedure
   
   Procedure Array2Dlimit(Array t.f(2),*min.float,*max.float)
      Protected i,j,dx1,dy1
      Protected.f v,smin,smax
     
      dy1 = ArraySize(t(), 1)
      dx1 = ArraySize(t(), 2)
      smax = -1e10
      smin =  1e10
      For j=0 To dy1
         For i=0 To dx1
            v=t(j,i)
            If v<smin : smin=v: EndIf
            If v>smax : smax=v: EndIf
         Next
      Next
      *min\f=smin
      *max\f=smax
   EndProcedure
   
   Procedure Array2Dclamp(Array t.f(2),min.f,max.f)
      Protected i,j,dx1,dy1
     
      dy1 = ArraySize(t(), 1)
      dx1 = ArraySize(t(), 2)
      For j=0 To dy1
         For i=0 To dx1
            t(j,i)=limite(t(j,i),min,max)
         Next
      Next
   EndProcedure
   
   Procedure blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
      If di=0 And dj=0:ProcedureReturn:EndIf
      Protected i,j,k,d,dii,djj,dx,dy,dij,tx.f
     
      dx = ArraySize(s(), 2):di=min(di,dx)
      dy = ArraySize(s(), 1):dj=min(dj,dy)
      Dim d.f(dy,dx)
      dii=di+1
      djj=dj+1
      dij = dii * djj
     
      If loop
         d=dx-dii/2:Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = (i+d) % (dx+1): Next
         d=dx-dii/2:Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = (i+d) % (dy+1): Next   
      Else
         Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = limite(i-1-dii/2, 0, dx): Next
         Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = limite(i-1-djj/2, 0, dy): Next
      EndIf
      For k=1 To pass
         Dim ty.f(dx)
         For j = 0 To djj - 1: For i = 0 To dx: ty(i) + s(ly(j),i): Next: Next   
         For j = 0 To dy
            For i = 0 To dx: ty(i) + s(ly(djj+j),i) - s(ly(j),i): Next
            tx=0:For i = 0 To dii-1: tx+ty(lx(i)): Next
            For i = 0 To dx: tx + ty(lx(dii+i)) - ty(lx(i) ): d(j,i) = tx / dij: Next
         Next
         CopyArray(d(),s())
      Next
   EndProcedure
   
   Procedure Embos2D(Array s.f(2), px.w=0, py.w=0)
      Protected i,j,dx,dy
      px=1<<Int(Abs(px))*Sign(px)
      py=1<<Int(Abs(py))*Sign(py)
     
      Macro gra(j0,i0,j1,i1)
         t(j0,i0)=Abs(s(j0,i0)-s(j0,i1)+px)+Abs(s(j0,i0)-s(j1,i0)+py)
      EndMacro
      dy = ArraySize(s(), 1)
      dx = ArraySize(s(), 2)
      Dim T.f(dy,dx)
      For j=0 To dy-1
         For i=0 To dx-1
            gra(j,i,j+1,i+1)
         Next
         gra(j,dx,j+1,0)
      Next
      For i = 0 To dx-1
         gra(dy,i,0,i+1)
      Next
      gra(dy,dx,0,0)
      CopyArray(t(),s())
   EndProcedure
   
   Procedure grad2D(Array s.f(2),delta=1)
      Protected i,j,dx,dy
     
      dy = ArraySize(s(), 1)
      dx = ArraySize(s(), 2)
      Dim d.f(dy,dx)
      For j=0 To dy
         For i=0 To dx
            d(j,i)= 4*s(j,i)   -s(j,(i-delta) & dx)-s(j,(i+delta) & dx)-s((j-delta) & dy,i)-s((j+delta) & dy,i)
         Next
      Next
      CopyArray(d(),s())
   EndProcedure
   
   Procedure superpose(Array s.f(2),n.w=1)
      Protected i,j,k,dx,dy,x,y,ii,jj
     
      dy = ArraySize(s(), 1)
      dx = ArraySize(s(), 2)
      Dim T.f(dy,dx)
      For k=1 To n
         x=Random(dx)
         y=Random(dy)
         For j=0 To dy
            For i=0 To dx
               t(i,j)+s((i+x) & dx,(j+y) & dy)
            Next
         Next
      Next
      CopyArray(t(),s())
   EndProcedure
   
   Procedure Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
      Protected i,j,n,d,dd,d3,dx1=dx-1,dy1=dy-1,coef.f=9,den.f=1/(2*coef-2),amp.f=1/$1000
      Dim t(dy1, dx1)
     
      RandomSeed(rnd)
      n = 1<<oinit
      dd=min(dx,dy) / n: If dd<1:dd=1:EndIf
      j=0:While j<dy1:i=0:While i<dx1: t(j,i) = (Random($2000) - $1000)*amp:i+dd:Wend:j+dd:Wend
      While dd > 1
         If onb=0:amp=0:EndIf
         d = dd / 2:d3=d*3:amp/2
         j=d:While j<dy
            i=0:While i<dx
               t(j,i) = (-t((j - d3) & dy1,i) - t((j +d3) & dy1,i) + coef*(t((j - d) & dy1,i) + t((j + d) & dy1,i))) *den + (Random($2000) - $1000)*amp
            i+dd:Wend
         j+dd:Wend
         j=0:While j<dy
            i=d:While i<dx
               t(j,i) = (-t(j,(i - d3) & dx1) - t(j,(i +d3) & dx1) + coef*(t(j,(i - d) & dx1) + t(j,(i + d) & dx1))) *den + (Random($2000) - $1000)*amp
            i+dd:Wend
         j+d:Wend
         dd/2:onb-1
      Wend     
   EndProcedure
   
   Procedure Finterpol(Array F.f(1),profil.s,dmin.f=1,dmax.f=0)
      Protected.l i,j,n,c,ac,rx,   t.s
      Protected.f y,dx,dy,p
     
      rx=ArraySize(f())
      n=CountString(profil,"/")
      Dim s.f2(n)
      For i=0 To n
         t=StringField(profil,i+1,"/")
         s(i)\x=ValF(t)*rx
         s(i)\y=ValF(StringField(t,2,","))*(dmax-dmin)+dmin
      Next
     
      For j=0 To n-1
         y=s(j)\y
         dx=s(j+1)\x-s(j)\x
         dy=s(j+1)\y-s(j)\y
         p=dy/dx
         ac=c
         While c<=s(j+1)\x
            f(c)=y+p*(c-ac):c+1
         Wend
      Next
   EndProcedure
   
   Procedure outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
      Protected dx1,dy1,i,ii,j,k,xi
      Protected.f smin,smax,sr,tt,x,y0,y1,x0,dminl,dmaxl
     
      dy1 = ArraySize(t(), 1)
      dx1 = ArraySize(t(), 2)
      Array2Dlimit(t(),@smin,@smax)
      sr=smax-smin
     
      Dim conv.f(256)
      Finterpol(conv(),outline,dmin,dmax)
      If smaxl-sminl<>0
         ii=(sminl-smin)/sr*255:For i=0 To ii:conv(i)=conv(ii):Next
         ii=(smaxl-smin)/sr*255:For i=ii To 255:conv(i)=conv(ii):Next
      EndIf
     
      For j=0 To dy1
         For i=0 To dx1
            x=(t(j,i)-smin)/sr*255
            xi=Int(x):x0=x-xi
            y0=conv(xi)
            y1=conv(xi+1)
            t(j,i)=y1*x0+y0*(1-x0)
         Next
      Next
   EndProcedure
   
   Procedure textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
      Protected i,j,n,dx,dy
      Protected.f min,max,r
     
      dx=ArraySize(t(),2)+1
      dy=ArraySize(t(),1)+1
      Dim bmp.l(dy-1,dx-1)
     
      Protected Dim grad.l(0):gradienttoarray(grad(),1024,grad,1)
      Array2Dlimit(t(),@min,@max):r=1023/(max-min)
      For j=0 To dy-1:For i=0 To dx-1:n=(t(j,i)-min)*r:bmp(j,i)=grad(n):Next:Next
     
      n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
      StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
      ProcedureReturn tex
   EndProcedure
   
   Procedure textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
      Protected i,j,n,dx,dy
      Protected.f h00,h10,h01,x,y,z,l, max=1/amplitude,max2=max*max
      Protected.f3 p
     
      Dim a.f(0,0) :CopyArray(t(),a())
      Select alphavalue
         Case 0:outline2d(a(),0,255)
         Case 1:grad2d(a(),4):Array2Dclamp(a(),-0.4,0):outline2d(a(),0,255,"0,0/1,1")
      EndSelect
     
      dx=ArraySize(t(),2)+1
      dy=ArraySize(t(),1)+1
      Dim bmp.l(dy-1,dx-1)
      For j=0 To dy-1
         For i=0 To dx-1
            h00=t(j,i)
            h10=t(j,(i+1) % dx)
            h01=t((j+1) % dy,i)
            p\x=h00-h10
            p\y=h00-h01
            l=min(p\x*p\x+p\y*p\y,max2)
            p\z=Sqr(max2-l)
            Norme3D(p,127)
            bmp(j,i)=RGBA(p\z+128,p\y+128,p\x+128,a(j,i))
         Next
      Next
      n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
      StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
      ProcedureReturn tex
   EndProcedure
   
   Procedure.f interpolarray2d(Array tt.f(2),x.f,y.f)
      Protected.l i0, j0,i1,j1,dx1,dy1
      Protected.f dx, dy
      dx1=ArraySize(tt(),1)
      dy1=ArraySize(tt(),2)
      i0 = Int(X) & dx1:i1=(i0+1) & dx1: dx = X - Int(x)
      j0 = Int(Y) & dy1:j1=(j0+1) & dy1: dy = Y - Int(y)
      ProcedureReturn (((1 - dx) * tt(j0,i0) + dx * tt(j0,i1)) * (1 - dy) + ((1 - dx) * tt(j1,i0) + dx * tt(j1,i1)) * dy)
   EndProcedure
   
   ;}===================================================================================================================================================
   
   ;{ Océan
   
   Procedure initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
      ; tilesize: must be a power of 2
      ; precision : 1-> 1 meters,  2->2 meters, 3->4 meters, 4-> 8 meters...
      ; range : distance to the camera where the oocean should be rendered
      ; wavebig,wavelittle,swell,foam : value: 0.0 -> 1.0
      ; particule : for sea spray
      ; heightmap : texture containing the depth. only the red component is used : red=depth*16+128, and clamped between 0 and 255
     
      Protected i,j,k,r,n,a.f
      oc_tilesize=tilesize:oc_tilesize2=oc_tilesize/2
      oc_prec=1<<(prec-1)
      oc_tilenb=range/tilesize*2:oc_tilenb1=oc_tilenb-1
      oc_tn=oc_tilesize/oc_prec:oc_tn1=oc_tn-1:oc_tn2=oc_tn/2
      oc_particule=particule
     
      Global Dim oc_h.f(oc_tn1,oc_tn1)
      Global Dim oc_entity(oc_tilenb1,oc_tilenb1)
     
      Dim t.f(0,0)
      ;Waves (noramlmap)
      Noise2d(oc_h(),512,512,0,4)
      outline2d(oc_h(),0,1,"0,0/0.5,1/1,0")
      blur2D(oc_h(),1,1,1)   
      oc_txtnm=textureArraytoNM(-1,oc_h(),16)
      ;foam (diffusemap)
      Noise2d(t(),512,512,0,7)
      outline2d(t(),0,1,"0,0/0.2,0.2/0.5,1/0.7,0.2/1,0")
      oc_txtdif=textureArrayToColor(-1,t())
     
      oc_material=GetScriptMaterial(-1,"ocean"):MaterialTextureAliases(oc_material,TextureID(oc_txtnm),TextureID(oc_txtdif),TextureID(heightmap),0)
      MaterialFilteringMode(oc_material,#PB_Material_Anisotropic,4)
      MaterialShininess(oc_material,64)
      SetMaterialAttribute(oc_material,#PB_Material_TAM,#PB_Material_ClampTAM,2)
      oceanset(wavebig,wavelittle,swell,foam,watercolor,skycolor)
     
      For k=0 To 4:r=1<<k
         Dim mv.PB_MeshVertexv(oc_tn/r,oc_tn/r)
         For j=0 To oc_tn/r
            For i=0 To oc_tn/r
               With mv(j,i)
                  vec3d(\p,(i*r-oc_tn2)*oc_prec,pom(16),-(j*r-oc_tn2)*oc_prec)         
                  \u=i*r/oc_tn
                  \v=j*r/oc_tn
               EndWith
            Next
         Next
         If k=0
            oc_mesh=CreateDataMesh(-1,mv())
         Else
            n=CreateDataMesh(-1,mv())
            AddMeshManualLOD(oc_mesh,n,128 *r)
            SetMeshMaterial(n,MaterialID(oc_material))
         EndIf
      Next
     
      For j=0 To oc_tilenb1
         For i=0 To oc_tilenb1
            oc_entity(j,i)=CreateEntity(-1,MeshID(oc_mesh),MaterialID(oc_material))
         Next
      Next
   EndProcedure
   
   Procedure freeocean()
      Protected i,j
      For j=0 To ArraySize(oc_entity(),1)
         For i=0 To ArraySize(oc_entity(),2)
            FreeEntity(oc_entity(j,i))
         Next
      Next
      FreeMesh(oc_mesh)
      FreeArray(oc_entity())
      FreeMaterial(oc_material)
      FreeTexture(oc_txtnm)
      FreeTexture(oc_txtdif)
   EndProcedure
   
   Procedure.f oceanHeight(x.f,z.f)
      Protected time.f=(ElapsedMilliseconds()-inittime)/1000*0.01, dx.f=time*512
      x*2-0.5
      z*2-0.5
      ProcedureReturn (interpolarray2d(oc_h(),x+dx,z)+interpolarray2d(oc_h(),x+256-dx,z+256)-1)*oc_waveb*4+Sin(z/512*20-time*100)*oc_swell*4
   EndProcedure
   
   Procedure oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
      oc_waveb=wavebig
      oc_wavel=wavelittle
      oc_swell=swell
      oc_foam =foam   
      SetMaterialColor(oc_material,#PB_Material_AmbientColor,RGBA(wavebig*255,wavelittle*255,swell*255,foam*255))
      If watercolor:SetMaterialColor(oc_material,#PB_Material_DiffuseColor,watercolor):EndIf
      If skycolor:SetMaterialColor(oc_material,#PB_Material_SpecularColor,skycolor):EndIf
   EndProcedure
   
   Procedure renderocean()
      Protected i,j,  pos.f3

      ;------------------- tuiles
      Protected da=oc_tilenb*oc_tilesize
      Static api=0,pi=1000,  apj=0,pj=1000,  i0,i1,  j0,j1,  e
      api=pi:pi=(CameraX(0)-da/2)/oc_tilesize:If pi<api:i0=pi:i1=api-1:Else:i0=api+1+oc_tilenb1:i1=pi+oc_tilenb1:EndIf
      apj=pj:pj=(CameraZ(0)-da/2)/oc_tilesize:If pj<apj:j0=pj:j1=apj-1:Else:j0=apj+1+oc_tilenb1:j1=pj+oc_tilenb1:EndIf
      For j=pj To pj+oc_tilenb1
         For i=pi To pi+oc_tilenb1
            If (i>=i0 And i<=i1) Or (j>=j0 And j<=j1)
               MoveEntity(oc_entity(Modi(j,oc_tilenb),Modi(i,oc_tilenb)), i*oc_tilesize+oc_tilesize2,0,j*oc_tilesize+oc_tilesize2,#PB_Absolute)
            EndIf
         Next
      Next
     
      ;------------------- sous / sur l'eau
      If CameraY(0)<oceanHeight(CameraX(0),CameraZ(0))
         Fog($332200,100,0,30)
         MaterialCullingMode(oc_material,#PB_Material_AntiClockWiseCull)
      Else
         Fog($ffaa88,100,0,da/2)
         MaterialCullingMode(oc_material,#PB_Material_ClockWiseCull)
      EndIf       
   EndProcedure
   ;}
   
   ;{ SkyDome2
   Procedure SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
      If skydome_m:FreeMesh(skydome_m):EndIf
      If skydome_e:FreeEntity(skydome_e):EndIf
      Protected i,j,d=16,icol   ,d1=d-1,d2=d/2,mesh
      Protected.f x,y,z,  xo,yo,  u,v,   ai,aj,  lat,lng, mx
      Dim t.PB_MeshVertexv(d,d)
      Dim col.l(0)
     
      DisableDebugger:CreateMaterial(0,0):EnableDebugger
      GradientToArray(col(),256,degrade)
      For j=0 To d
         For i=0 To d
            With t(i,j)
               xo=1-i/d2
               yo=1-j/d2
               lng=ATan2(xo,yo)
               mx=max(Abs(xo),Abs(yo))
               \u=(Cos(lng)* mx+1)/2
               \v=(Sin(lng)* mx+1)/2
               lat=mx* #PI/2
               x=Cos(lng)* Sin(lat)*rayon
               z=Sin(lng)* Sin(lat)*rayon
               y=Cos(lat)*hauteur
               vec3d(\p,-x,y,z)
               icol=255*(x+rayon)/(2*rayon)
               \color=$ff000000+col(icol)
            EndWith
         Next
      Next
      skydome_m=CreateDataMesh(-1,t())
      skydome_e=CreateEntity(-1,MeshID(skydome_m),MaterialID(material))
      DisableMaterialLighting(material,1)
   EndProcedure
   
   Procedure SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)
      Protected layer
      AddMaterialLayer(0,TextureID(txt),#PB_Material_AlphaBlend)
      layer=CountMaterialLayers(0)-1
      ScaleMaterial(0,scale,scale,layer)
      RotateMaterial(0,angle,#PB_Material_Fixed,layer)
      ScrollMaterial(0,0,scroll,#PB_Material_Animated,layer)
   EndProcedure
   ;}
EndModule
;#####################################################################################################################################################

UseModule ext_3d

Procedure texturecolor(tex,dx,dy,rnd=0,f=0,lissage=0,grad.s="0,$000000/1,$ffffffff",outline.s="0,0/1,1")
   Protected Dim t.f(0,0)
   
   Noise2d(t(),dx,dy,rnd,f)
   blur2D(t(),lissage,lissage,2)   
   outline2d(t(),0,1,outline)
   ProcedureReturn textureArrayToColor(tex,t(),grad)
EndProcedure

Procedure texturenormal(tex,dx,dy,rnd=0,f=0,lissage=0,relief.f=1,outline.s="0,0/1,1",alphavalue=0)
   Protected Dim t.f(0,0)
   
   Noise2d(t(),dx,dy,rnd,f)
   outline2d(t(),0,1,outline)
   blur2D(t(),lissage,lissage,3)   
   ProcedureReturn textureArraytoNM(tex,t(),relief,alphavalue)
EndProcedure

Procedure main()
   Protected sky,heightmap,seaspray   
   Protected ex,ey,c,v, i,j, fly.b=1,fdf.b
   Protected.f MouseX,Mousey,keyx,keyy,keyz,dist,aval, och, waveb,wavel,swell,foam,Texto$
  Macro openmenu
    OpenWindow3D(0,20,20,500,320,"detalles",#PB_Window3D_SizeGadget|#PB_Window3D_BorderLess)
    TextGadget3D(0,0,0,500,320,Texto$)
    ShowGUI(122,0,0,1)
  EndMacro
   InitEngine3D():InitSprite():InitKeyboard():InitMouse()
   ExamineDesktops()
   ex=DesktopWidth(0)
   ey=DesktopHeight(0)
   ;OpenWindow(0,0,0,ex,ey,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0))
   OpenScreen(ex,ey,32,"")
   
   Add3DArchive(#PB_Compiler_Home+"Examples\3D\Data\Scripts\MaterialScriptsGeneric", #PB_3DArchive_FileSystem )
   Add3DArchive(#PB_Compiler_Home+"examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
   Add3DArchive(#PB_Compiler_Home+"examples/3d/Data/GUI", #PB_3DArchive_FileSystem)
   Parse3DScripts()
   SetGUITheme3D("","DejaVuSans-10")
  openmenu

   ;------------------- scene
   
   CreateCamera(0, 0, 0, 100, 100):CameraBackColor(0,$332200)
   MoveCamera(0,0,10,0)
   CameraLookAt(0, 0,10,-10)
   CreateLight(0,$ffffff, 10000, 10000,0)
   AmbientColor($444444)
   
   ;---- ilot / island
   Protected di=256,dj=256,di1=di-1,dj1=dj-1,ii,jj,h.f,g.f,x.f,y.f
   Dim h.f(0,0)
   Dim g.f(0,0)
   Dim t.PB_MeshVertexv(di,dj)
   
   Noise2d(h(),di,dj,0,3):outline2d(h(),0,15,"0,0/0.4,0.2/0.5,0.4/0.7,0.9/1,1")
   For j=0 To dj1:For i=0 To di1:x=i/di*#PI:y=j/dj*#PI:h(i,j)*Sin(x)*Sin(y)*#PI-8:Next:Next
   CopyArray(h(),g()):Embos2D(g(),0,0):outline2d(g(),0,255)
   
   For j=0 To dj:  jj=j & dj1
      For i=0 To di:ii=i & di1
         h=h(ii,jj)
         g=g(ii,jj)       
         With t(i,j)
            vec3d(\p,i,h,j)
            vec3d(\n,h((i-1) & di1,jj)-h((i+1) & di1,jj),2,h(ii,(j-1) & dj1)-h(ii,(j+1) & dj1)):norme3d(\n)
            \u=i*0.1
            \v=j*0.1
            Select g
               Case 0 To 80:\color=$22556677
               Case 80 To 120:\color=$225599aa
               Default:\color=$4488aadd
            EndSelect
            If h<7:\color | $CC000000 :EndIf
         EndWith
      Next
   Next   
   CreateDataMesh(10,t())
   BuildMeshTangents(10)
   texturecolor (10,512,512,1,5,0,"0,$ff888888/1,$ffffffff")
   texturenormal(11,512,512,0,2,0,22,"0,1/0.3,0.4/0.5,0/0.7,0.4/1,1")
   GetScriptMaterial(10,"bump"):MaterialTextureAliases(10,TextureID(10),TextureID(11),0,0)
   MaterialFilteringMode(10,#PB_Material_Anisotropic,4)
   MaterialShininess(10,64):SetMaterialColor(10,#PB_Material_SpecularColor,$ffffff)
   CreateEntity(10,MeshID(10),MaterialID(10))
   ;heightmap
   heightmap=CreateTexture(-1,256,256)
   StartDrawing(TextureOutput(heightmap))
   For j=0 To dj1:For i=0 To di1:Plot(i,j,limite(h(i,j)*16+128,0,255)):Next:Next
   StopDrawing()
   
   
   ;---- sky / ciel
   sky=texturecolor(-1,512,512,0,3,0,"0,$00ffffff/0.4/0.7,$ffffffff/1,$ff888888")
   SkyDome2(1024,200,0,"0,$ff4400/1,$ff4400")
   SkyDome2AddLayer(sky,0.1,0.04,0)     
   SkyDome2AddLayer(sky,0.2,0.04,90)     
   SkyDome2AddLayer(sky,0.4,0.04,180)
   
   waveb=0.3
   wavel=0.5
   swell=0.1
   foam=0.4
   
   initocean(128,1,1024,waveb,wavel,swell,foam, $ff332200, $ff886644,Seaspray,heightmap)
   
   inittime=ElapsedMilliseconds()
   Repeat
      ;WindowEvent()
      ExamineMouse()
      ExamineKeyboard()
      MouseX = -MouseDeltaX() *  0.05
      MouseY = -MouseDeltaY() *  0.05
      Macro param(val,key1,key2)
         aval=val:val=limite(val+(KeyboardReleased(key2)-KeyboardReleased(key1))*0.1,0.1,1)
         If val<>aval:oceanset(waveb,wavel,swell,foam):EndIf
      EndMacro
  If KeyboardReleased(#PB_Key_F11)
    If IsWindow3D(0)
      ShowGUI(122,0,0,0)
      FreeGadget3D(#PB_All)
      CloseWindow3D(0)
    Else
      openmenu
    EndIf
  ElseIf IsWindow3D(0)
    Texto$="Moving :"+StrF(dist,2)+#CRLF$
    Texto$+"Mouse + wheel + arrow keys"+#CRLF$+#CRLF$
    Texto$+"Commandes:"+#CRLF$
    Texto$+"F1 / F2 : Wave big: "+Str(waveb*100)+"%"+#CRLF$
    Texto$+"F3 / F4 : Wave little: "+Str(wavel*100)+"%"+#CRLF$
    Texto$+"F5 / F6 : Swell height: "+Str(swell*100)+"%"+#CRLF$
    Texto$+"F7 / F8 : foam: "+Str(foam*100)+"%"+#CRLF$
    Texto$+"F10 : Toggle auto-advance"+#CRLF$
    Texto$+"F11 : Show/Hide this text"+#CRLF$
    Texto$+"F12 : Wireframe"
    SetGadgetText3D(0,Texto$)
  EndIf
      param(waveb,#PB_Key_F1,#PB_Key_F2)
      param(wavel,#PB_Key_F3,#PB_Key_F4)
      param(swell,#PB_Key_F5,#PB_Key_F6)
      param(foam ,#PB_Key_F7,#PB_Key_F8)
      If KeyboardReleased(#PB_Key_F10):fly!1:EndIf
      If KeyboardReleased(#PB_Key_F12):fdf!1:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
     
      keyx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
      keyz=(-Bool(KeyboardPushed(#PB_Key_Up  ))+Bool(KeyboardPushed(#PB_Key_Down )))*0.5-MouseWheel()*10-fly*0.2
      RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):dist+(keyz-dist)*0.05:MoveCamera(0, KeyX, 0, dist)
      If fly=0:och+(oceanHeight(CameraX(0),CameraZ(0))+1-och)*0.2:MoveCamera(0,CameraX(0),och,CameraZ(0),#PB_Absolute):EndIf
     
      renderocean()
      RenderWorld()
      MoveEntity(skydome_e,CameraX(0),-8,CameraZ(0),#PB_Absolute)
      FlipBuffers()
   Until KeyboardPushed(#PB_Key_Escape)
EndProcedure

main()
:wink:

Notice that the gadget3D font can be modified in the file 'DejaVuSans-10.font' located at: "\Examples\3D\Data\GUI",
so the 'menu info window' can be set up much smaller and cool.
http://www.zeitgeistmovie.com

While world=business:world+mafia:Wend
Will never leave this forum until the absolute bugfree PB :mrgreen:
BarryG
Addict
Addict
Posts: 3324
Joined: Thu Apr 18, 2019 8:17 am

Re: Ocean v2 (shader OpenGL)

Post by BarryG »

Psychophanta, that looks phantastic!
dige
Addict
Addict
Posts: 1254
Joined: Wed Apr 30, 2003 8:15 am
Location: Germany
Contact:

Re: Ocean v2 (shader OpenGL)

Post by dige »

Great. Could watch it for hours.. :D
"Daddy, I'll run faster, then it is not so far..."
Fred
Administrator
Administrator
Posts: 16686
Joined: Fri May 17, 2002 4:39 pm
Location: France
Contact:

Re: Ocean v2 (shader OpenGL)

Post by Fred »

Really nice stuff ! You can put this at the top of your code to be sure the opengl subsytem is used on Windows:

Code: Select all

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please use the OpenGL subsystem"
CompilerEndIf
User avatar
Saki
Addict
Addict
Posts: 830
Joined: Sun Apr 05, 2020 11:28 am
Location: Pandora

Re: Ocean v2 (shader OpenGL)

Post by Saki »

Hi, tested on 4K, Sky is OK, all other is everything else is broken.
地球上の平和
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Ocean v2 (shader OpenGL)

Post by DK_PETER »

@pf shadoko

I don't have a problem with sprites using OpenGL.
Both windowed and fullscreen displays the menu sprite. (Using Windows 10)

Anyway. It looks really good! Thanks for sharing as usual. 8)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
pf shadoko
Enthusiast
Enthusiast
Posts: 291
Joined: Thu Jul 09, 2015 9:07 am

Re: Ocean v2 (shader OpenGL)

Post by pf shadoko »

I made an update of the code with windowedscreen to have the menu

@ Fred:
wouldn't it be possible to indicate the Subsystem by a compilation directive ? (I suppose if it was possible...).

@ BarryG :
you can copy the files wherever you want, but you'll have to point Add3DArchive at them.
However, these files will be included in the next version of PB.

@ Psychophanta :
I don't really like the window3D lib, the other solution is to use windowedscreen.

@ Saki :
did you copy the files and compile them in opengl?

@ DK_PETER :
I think you tested the modified code of Psychophanta.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Ocean v2 (shader OpenGL)

Post by DK_PETER »

pf shadoko wrote: @ DK_PETER :
I think you tested the modified code of Psychophanta.
Nope...Sprites works just fine for me.

Windowed code working for me:

Code: Select all

; Océan v2 - pf Shadoko - 2020

EnableExplicit

DeclareModule ext_3D
  EnableExplicit
  Global inittime
  
  Structure f3
    x.f
    y.f
    z.f
  EndStructure
  
  Structure f2
    x.f
    y.f
  EndStructure
  
  Structure PB_MeshVertexV
    p.f3
    n.f3
    t.f3
    u.f
    v.f
    color.l
  EndStructure
  
  ;________________ Lib ________________
  Declare vec3d(*v.f3,vx.f,vy.f,vz.f)
  Declare sub3D(*p.f3,*p1.f3,*p2.f3)
  Declare mul3d(*p1,v.f)
  Declare.f lng3D(*v.f3)   
  Declare norme3d(*v.f3,l.f=1)   
  Declare.f Max(v1.f,v2.f)
  Declare.f Min(v1.f,v2.f)
  Declare.f limite(V.f, i.f, s.f)
  Declare.i Modi(v,divisor)
  Declare.f interpolarray2d(Array tt.f(2),x.f,y.f)
  Declare ColorBlend(color1.l, color2.l, blend.f)
  Declare GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
  Declare Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
  Declare  blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
  Declare Embos2D(Array s.f(2), px.w=0, py.w=0)
  Declare grad2D(Array s.f(2),delta=1)
  Declare  outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
  Declare textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
  Declare textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
  
  ;________________ océan ________________
  
  Global oc_mesh,oc_material,oc_txtnm,oc_txtdif,oc_particule,   oc_waveb.f, oc_wavel.f,oc_swell.f, oc_foam.f 
  Global oc_tilesize,oc_tilesize2,oc_prec,oc_tilenb,oc_tilenb1
  Global oc_tn,oc_tn1,oc_tn2
  Declare initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
  Declare freeocean()
  Declare renderocean()
  Declare.f oceanHeight(x.f,z.f)
  Declare oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
  
  ;________________ SkyDome2 ________________
  Global skydome_m, skydome_e
  Declare SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
  Declare SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)   
EndDeclareModule

Module ext_3D
  
  ;{ ============================= biblio
  Global ev.i
  Procedure vec3d(*v.f3,vx.f,vy.f,vz.f)
    *v\x=vx
    *v\y=vy
    *v\z=vz
  EndProcedure
  
  Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
    *p\x=*p1\x-*p2\x
    *p\y=*p1\y-*p2\y
    *p\z=*p1\z-*p2\z
  EndProcedure
  
  Procedure add3d(*p.f3,*p1.f3,*p2.f3)
    *p\x=*p1\x+*p2\x
    *p\y=*p1\y+*p2\y
    *p\z=*p1\z+*p2\z
  EndProcedure
  
  Procedure mul3d(*p1.f3,v.f)
    *p1\x*v
    *p1\y*v
    *p1\z*v
  EndProcedure
  
  Procedure.f lng3D(*v.f3)
    ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
  EndProcedure
  
  Procedure Norme3D(*V.f3,l.f=1)
    Protected.f lm
    lm = l / lng3d(*v)
    *V\x * lm
    *V\y * lm
    *V\z * lm 
  EndProcedure
  
  Procedure.f Max(v1.f,v2.f)
    If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
  EndProcedure
  
  Procedure.f Min(v1.f,v2.f)
    If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
  EndProcedure
  
  Procedure.f limite(V.f, i.f, s.f)
    If V < i :v=i:EndIf
    If V > s :v=s:EndIf
    ProcedureReturn V
  EndProcedure
  
  Procedure.i Modi(v,divisor)
    ProcedureReturn (V+$10000*divisor) % divisor
  EndProcedure
  
  Procedure.f POM(v.f)
    ProcedureReturn (Random(v*1000)-v*500)/500
  EndProcedure
  
  ;##############################################################################################
  
  Procedure CoRBinv(c.l)
    ProcedureReturn  RGBA(Blue(c),Green(c),Red(c),Alpha(c))
  EndProcedure
  
  Procedure ColorBlend(color1.l, color2.l, blend.f)
    Protected r.w,g.w,b.w,a.w
    r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
    g=Green(color1) + (Green(color2) - Green(color1)) * blend
    b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
    a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
    ProcedureReturn  RGBA(r,g,b,a)
  EndProcedure
  
  Procedure GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
    Protected i,j, apos,pos, acol.l,col.l,p,lt.s
    n-1
    Dim pal(n)
    
    Repeat
      apos=pos
      acol=col
      i+1
      lt=StringField(gradient,i,"/"):If lt="":Break:EndIf
      pos=ValF(lt)*n
      p=FindString(lt,",")
      If p
        col=Val(Mid(lt,p+1))
        If inv  :col=CoRBinv(col):EndIf
        If alpha:col | $ff000000:EndIf
      Else
        col=acol
      EndIf
      For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
    ForEver
  EndProcedure
  
  Procedure Array2Dlimit(Array t.f(2),*min.float,*max.float)
    Protected i,j,dx1,dy1
    Protected.f v,smin,smax
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    smax = -1e10
    smin =  1e10
    For j=0 To dy1
      For i=0 To dx1
        v=t(j,i)
        If v<smin : smin=v: EndIf
        If v>smax : smax=v: EndIf
      Next
    Next
    *min\f=smin
    *max\f=smax
  EndProcedure
  
  Procedure Array2Dclamp(Array t.f(2),min.f,max.f)
    Protected i,j,dx1,dy1
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    For j=0 To dy1
      For i=0 To dx1
        t(j,i)=limite(t(j,i),min,max)
      Next
    Next
  EndProcedure
  
  Procedure blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
    If di=0 And dj=0:ProcedureReturn:EndIf
    Protected i,j,k,d,dii,djj,dx,dy,dij,tx.f
    
    dx = ArraySize(s(), 2):di=min(di,dx)
    dy = ArraySize(s(), 1):dj=min(dj,dy)
    Dim d.f(dy,dx)
    dii=di+1
    djj=dj+1
    dij = dii * djj
    
    If loop
      d=dx-dii/2:Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = (i+d) % (dx+1): Next
      d=dx-dii/2:Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = (i+d) % (dy+1): Next   
    Else
      Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = limite(i-1-dii/2, 0, dx): Next
      Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = limite(i-1-djj/2, 0, dy): Next
    EndIf 
    For k=1 To pass
      Dim ty.f(dx)
      For j = 0 To djj - 1: For i = 0 To dx: ty(i) + s(ly(j),i): Next: Next   
      For j = 0 To dy
        For i = 0 To dx: ty(i) + s(ly(djj+j),i) - s(ly(j),i): Next
        tx=0:For i = 0 To dii-1: tx+ty(lx(i)): Next
        For i = 0 To dx: tx + ty(lx(dii+i)) - ty(lx(i) ): d(j,i) = tx / dij: Next
      Next
      CopyArray(d(),s())
    Next
  EndProcedure
  
  Procedure Embos2D(Array s.f(2), px.w=0, py.w=0)
    Protected i,j,dx,dy
    px=1<<Int(Abs(px))*Sign(px)
    py=1<<Int(Abs(py))*Sign(py)
    
    Macro gra(j0,i0,j1,i1)
      t(j0,i0)=Abs(s(j0,i0)-s(j0,i1)+px)+Abs(s(j0,i0)-s(j1,i0)+py)
    EndMacro
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim T.f(dy,dx)
    For j=0 To dy-1
      For i=0 To dx-1
        gra(j,i,j+1,i+1)
      Next
      gra(j,dx,j+1,0)
    Next
    For i = 0 To dx-1
      gra(dy,i,0,i+1)
    Next
    gra(dy,dx,0,0)
    CopyArray(t(),s())
  EndProcedure
  
  Procedure grad2D(Array s.f(2),delta=1)
    Protected i,j,dx,dy
    
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim d.f(dy,dx)
    For j=0 To dy
      For i=0 To dx
        d(j,i)= 4*s(j,i)   -s(j,(i-delta) & dx)-s(j,(i+delta) & dx)-s((j-delta) & dy,i)-s((j+delta) & dy,i)
      Next
    Next
    CopyArray(d(),s())
  EndProcedure
  
  Procedure superpose(Array s.f(2),n.w=1)
    Protected i,j,k,dx,dy,x,y,ii,jj
    
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim T.f(dy,dx)
    For k=1 To n
      x=Random(dx)
      y=Random(dy)
      For j=0 To dy
        For i=0 To dx
          t(i,j)+s((i+x) & dx,(j+y) & dy)
        Next
      Next
    Next
    CopyArray(t(),s())
  EndProcedure
  
  Procedure Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
    Protected i,j,n,d,dd,d3,dx1=dx-1,dy1=dy-1,coef.f=9,den.f=1/(2*coef-2),amp.f=1/$1000
    Dim t(dy1, dx1)
    
    RandomSeed(rnd)
    n = 1<<oinit
    dd=min(dx,dy) / n: If dd<1:dd=1:EndIf
    j=0:While j<dy1:i=0:While i<dx1: t(j,i) = (Random($2000) - $1000)*amp:i+dd:Wend:j+dd:Wend
    While dd > 1
      If onb=0:amp=0:EndIf
      d = dd / 2:d3=d*3:amp/2
      j=d:While j<dy
        i=0:While i<dx
          t(j,i) = (-t((j - d3) & dy1,i) - t((j +d3) & dy1,i) + coef*(t((j - d) & dy1,i) + t((j + d) & dy1,i))) *den + (Random($2000) - $1000)*amp
        i+dd:Wend
      j+dd:Wend
      j=0:While j<dy
        i=d:While i<dx
          t(j,i) = (-t(j,(i - d3) & dx1) - t(j,(i +d3) & dx1) + coef*(t(j,(i - d) & dx1) + t(j,(i + d) & dx1))) *den + (Random($2000) - $1000)*amp
        i+dd:Wend
      j+d:Wend
      dd/2:onb-1
    Wend     
  EndProcedure
  
  Procedure Finterpol(Array F.f(1),profil.s,dmin.f=1,dmax.f=0)
    Protected.l i,j,n,c,ac,rx,   t.s
    Protected.f y,dx,dy,p
    
    rx=ArraySize(f())
    n=CountString(profil,"/")
    Dim s.f2(n)
    For i=0 To n
      t=StringField(profil,i+1,"/")
      s(i)\x=ValF(t)*rx
      s(i)\y=ValF(StringField(t,2,","))*(dmax-dmin)+dmin
    Next 
    
    For j=0 To n-1
      y=s(j)\y
      dx=s(j+1)\x-s(j)\x
      dy=s(j+1)\y-s(j)\y
      p=dy/dx
      ac=c
      While c<=s(j+1)\x
        f(c)=y+p*(c-ac):c+1
      Wend
    Next
  EndProcedure
  
  Procedure outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
    Protected dx1,dy1,i,ii,j,k,xi
    Protected.f smin,smax,sr,tt,x,y0,y1,x0,dminl,dmaxl
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    Array2Dlimit(t(),@smin,@smax)
    sr=smax-smin
    
    Dim conv.f(256)
    Finterpol(conv(),outline,dmin,dmax)
    If smaxl-sminl<>0
      ii=(sminl-smin)/sr*255:For i=0 To ii:conv(i)=conv(ii):Next
      ii=(smaxl-smin)/sr*255:For i=ii To 255:conv(i)=conv(ii):Next
    EndIf
    
    For j=0 To dy1
      For i=0 To dx1
        x=(t(j,i)-smin)/sr*255
        xi=Int(x):x0=x-xi
        y0=conv(xi)
        y1=conv(xi+1)
        t(j,i)=y1*x0+y0*(1-x0)
      Next
    Next
  EndProcedure
  
  Procedure textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
    Protected i,j,n,dx,dy
    Protected.f min,max,r
    
    dx=ArraySize(t(),2)+1
    dy=ArraySize(t(),1)+1
    Dim bmp.l(dy-1,dx-1)
    
    Protected Dim grad.l(0):gradienttoarray(grad(),1024,grad,1)
    Array2Dlimit(t(),@min,@max):r=1023/(max-min)
    For j=0 To dy-1:For i=0 To dx-1:n=(t(j,i)-min)*r:bmp(j,i)=grad(n):Next:Next
    
    n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
    StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
    ProcedureReturn tex
  EndProcedure
  
  Procedure textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
    Protected i,j,n,dx,dy
    Protected.f h00,h10,h01,x,y,z,l, max=1/amplitude,max2=max*max
    Protected.f3 p
    
    Dim a.f(0,0) :CopyArray(t(),a())
    Select alphavalue
      Case 0:outline2d(a(),0,255)
      Case 1:grad2d(a(),4):Array2Dclamp(a(),-0.4,0):outline2d(a(),0,255,"0,0/1,1")
    EndSelect
    
    dx=ArraySize(t(),2)+1
    dy=ArraySize(t(),1)+1
    Dim bmp.l(dy-1,dx-1)
    For j=0 To dy-1
      For i=0 To dx-1
        h00=t(j,i)
        h10=t(j,(i+1) % dx)
        h01=t((j+1) % dy,i)
        p\x=h00-h10
        p\y=h00-h01
        l=min(p\x*p\x+p\y*p\y,max2)
        p\z=Sqr(max2-l)
        Norme3D(p,127)
        bmp(j,i)=RGBA(p\z+128,p\y+128,p\x+128,a(j,i))
      Next
    Next 
    n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
    StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
    ProcedureReturn tex
  EndProcedure
  
  Procedure.f interpolarray2d(Array tt.f(2),x.f,y.f)
    Protected.l i0, j0,i1,j1,dx1,dy1
    Protected.f dx, dy
    dx1=ArraySize(tt(),1)
    dy1=ArraySize(tt(),2)
    i0 = Int(X) & dx1:i1=(i0+1) & dx1: dx = X - Int(x)
    j0 = Int(Y) & dy1:j1=(j0+1) & dy1: dy = Y - Int(y)
    ProcedureReturn (((1 - dx) * tt(j0,i0) + dx * tt(j0,i1)) * (1 - dy) + ((1 - dx) * tt(j1,i0) + dx * tt(j1,i1)) * dy)
  EndProcedure
  
  ;}===================================================================================================================================================
  
  ;{ Océan
  
  Procedure initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
    ; tilesize: must be a power of 2
    ; precision : 1-> 1 meters,  2->2 meters, 3->4 meters, 4-> 8 meters...
    ; range : distance to the camera where the oocean should be rendered
    ; wavebig,wavelittle,swell,foam : value: 0.0 -> 1.0
    ; particule : for sea spray
    ; heightmap : texture containing the depth. only the red component is used : red=depth*16+128, and clamped between 0 and 255
    
    Protected i,j,k,r,n,a.f
    oc_tilesize=tilesize:oc_tilesize2=oc_tilesize/2
    oc_prec=1<<(prec-1)
    oc_tilenb=range/tilesize*2:oc_tilenb1=oc_tilenb-1
    oc_tn=oc_tilesize/oc_prec:oc_tn1=oc_tn-1:oc_tn2=oc_tn/2
    oc_particule=particule
    
    Global Dim oc_h.f(oc_tn1,oc_tn1)
    Global Dim oc_entity(oc_tilenb1,oc_tilenb1)
    
    Dim t.f(0,0)
    ;Waves (noramlmap)
    Noise2d(oc_h(),512,512,0,4)
    outline2d(oc_h(),0,1,"0,0/0.5,1/1,0")
    blur2D(oc_h(),1,1,1)   
    oc_txtnm=textureArraytoNM(-1,oc_h(),16)
    ;foam (diffusemap)
    Noise2d(t(),512,512,0,7)
    outline2d(t(),0,1,"0,0/0.2,0.2/0.5,1/0.7,0.2/1,0")
    oc_txtdif=textureArrayToColor(-1,t())
    
    oc_material=GetScriptMaterial(-1,"ocean"):MaterialTextureAliases(oc_material,TextureID(oc_txtnm),TextureID(oc_txtdif),TextureID(heightmap),0)
    MaterialFilteringMode(oc_material,#PB_Material_Anisotropic,4)
    MaterialShininess(oc_material,64)
    SetMaterialAttribute(oc_material,#PB_Material_TAM,#PB_Material_ClampTAM,2)
    oceanset(wavebig,wavelittle,swell,foam,watercolor,skycolor)
    
    For k=0 To 4:r=1<<k
      Dim mv.PB_MeshVertexv(oc_tn/r,oc_tn/r)
      For j=0 To oc_tn/r
        For i=0 To oc_tn/r
          With mv(j,i)
            vec3d(\p,(i*r-oc_tn2)*oc_prec,pom(16),-(j*r-oc_tn2)*oc_prec)         
            \u=i*r/oc_tn
            \v=j*r/oc_tn
          EndWith
        Next
      Next
      If k=0
        oc_mesh=CreateDataMesh(-1,mv())
      Else
        n=CreateDataMesh(-1,mv())
        AddMeshManualLOD(oc_mesh,n,128 *r)
        SetMeshMaterial(n,MaterialID(oc_material))
      EndIf
    Next
    
    For j=0 To oc_tilenb1
      For i=0 To oc_tilenb1
        oc_entity(j,i)=CreateEntity(-1,MeshID(oc_mesh),MaterialID(oc_material))
      Next
    Next
  EndProcedure
  
  Procedure freeocean()
    Protected i,j
    For j=0 To ArraySize(oc_entity(),1)
      For i=0 To ArraySize(oc_entity(),2)
        FreeEntity(oc_entity(j,i))
      Next
    Next
    FreeMesh(oc_mesh)
    FreeArray(oc_entity())
    FreeMaterial(oc_material)
    FreeTexture(oc_txtnm)
    FreeTexture(oc_txtdif)
  EndProcedure
  
  Procedure.f oceanHeight(x.f,z.f)
    Protected time.f=(ElapsedMilliseconds()-inittime)/1000*0.01, dx.f=time*512
    x*2-0.5
    z*2-0.5
    ProcedureReturn (interpolarray2d(oc_h(),x+dx,z)+interpolarray2d(oc_h(),x+256-dx,z+256)-1)*oc_waveb*4+Sin(z/512*20-time*100)*oc_swell*4
  EndProcedure
  
  Procedure oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
    oc_waveb=wavebig
    oc_wavel=wavelittle
    oc_swell=swell
    oc_foam =foam   
    SetMaterialColor(oc_material,#PB_Material_AmbientColor,RGBA(wavebig*255,wavelittle*255,swell*255,foam*255))
    If watercolor:SetMaterialColor(oc_material,#PB_Material_DiffuseColor,watercolor):EndIf
    If skycolor:SetMaterialColor(oc_material,#PB_Material_SpecularColor,skycolor):EndIf
  EndProcedure
  
  Procedure renderocean()
    Protected i,j,  pos.f3
    
    If oc_particule>=0
      pos\x=CameraX(0)+pom(100)+CameraDirectionX(0)*100
      pos\z=CameraZ(0)+pom(100)+CameraDirectionZ(0)*100
      pos\y=oceanHeight(pos\x,pos\z)+1
      If pos\y>0:MoveParticleEmitter(oc_particule,pos\x,pos\y,pos\z,#PB_Absolute):EndIf
    EndIf
    ;------------------- tuiles
    Protected da=oc_tilenb*oc_tilesize
    Static api=0,pi=1000,  apj=0,pj=1000,  i0,i1,  j0,j1,  e
    api=pi:pi=(CameraX(0)-da/2)/oc_tilesize:If pi<api:i0=pi:i1=api-1:Else:i0=api+1+oc_tilenb1:i1=pi+oc_tilenb1:EndIf
    apj=pj:pj=(CameraZ(0)-da/2)/oc_tilesize:If pj<apj:j0=pj:j1=apj-1:Else:j0=apj+1+oc_tilenb1:j1=pj+oc_tilenb1:EndIf
    For j=pj To pj+oc_tilenb1
      For i=pi To pi+oc_tilenb1
        If (i>=i0 And i<=i1) Or (j>=j0 And j<=j1)
          MoveEntity(oc_entity(Modi(j,oc_tilenb),Modi(i,oc_tilenb)), i*oc_tilesize+oc_tilesize2,0,j*oc_tilesize+oc_tilesize2,#PB_Absolute)
        EndIf
      Next
    Next
    
    ;------------------- sous / sur l'eau
    If CameraY(0)<oceanHeight(CameraX(0),CameraZ(0))
      Fog($332200,100,0,30)
      MaterialCullingMode(oc_material,#PB_Material_AntiClockWiseCull)
    Else
      Fog($ffaa88,100,0,da/2)
      MaterialCullingMode(oc_material,#PB_Material_ClockWiseCull)
    EndIf       
  EndProcedure
  ;}
  
  ;{ SkyDome2
  Procedure SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
    If skydome_m:FreeMesh(skydome_m):EndIf
    If skydome_e:FreeEntity(skydome_e):EndIf
    Protected i,j,d=16,icol   ,d1=d-1,d2=d/2,mesh
    Protected.f x,y,z,  xo,yo,  u,v,   ai,aj,  lat,lng, mx 
    Dim t.PB_MeshVertexv(d,d)
    Dim col.l(0)
    
    DisableDebugger:CreateMaterial(0,0):EnableDebugger
    GradientToArray(col(),256,degrade)
    For j=0 To d
      For i=0 To d
        With t(i,j)
          xo=1-i/d2
          yo=1-j/d2
          lng=ATan2(xo,yo)
          mx=max(Abs(xo),Abs(yo))
          \u=(Cos(lng)* mx+1)/2
          \v=(Sin(lng)* mx+1)/2
          lat=mx* #PI/2
          x=Cos(lng)* Sin(lat)*rayon
          z=Sin(lng)* Sin(lat)*rayon
          y=Cos(lat)*hauteur
          vec3d(\p,-x,y,z)
          icol=255*(x+rayon)/(2*rayon)
          \color=$ff000000+col(icol)
        EndWith
      Next
    Next 
    skydome_m=CreateDataMesh(-1,t())
    skydome_e=CreateEntity(-1,MeshID(skydome_m),MaterialID(material))
    DisableMaterialLighting(material,1)
  EndProcedure
  
  Procedure SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)
    Protected layer
    AddMaterialLayer(0,TextureID(txt),#PB_Material_AlphaBlend)
    layer=CountMaterialLayers(0)-1
    ScaleMaterial(0,scale,scale,layer)
    RotateMaterial(0,angle,#PB_Material_Fixed,layer)
    ScrollMaterial(0,0,scroll,#PB_Material_Animated,layer)
  EndProcedure
  ;}
EndModule
;#####################################################################################################################################################

UseModule ext_3d

Procedure texturecolor(tex,dx,dy,rnd=0,f=0,lissage=0,grad.s="0,$000000/1,$ffffffff",outline.s="0,0/1,1")
  Protected Dim t.f(0,0)
  
  Noise2d(t(),dx,dy,rnd,f)
  blur2D(t(),lissage,lissage,2)   
  outline2d(t(),0,1,outline)
  ProcedureReturn textureArrayToColor(tex,t(),grad)
EndProcedure

Procedure texturenormal(tex,dx,dy,rnd=0,f=0,lissage=0,relief.f=1,outline.s="0,0/1,1",alphavalue=0)
  Protected Dim t.f(0,0)
  
  Noise2d(t(),dx,dy,rnd,f)
  outline2d(t(),0,1,outline)
  blur2D(t(),lissage,lissage,3)   
  ProcedureReturn textureArraytoNM(tex,t(),relief,alphavalue)
EndProcedure

Procedure menu(waveb.f,wavel.f,swell.f,foam.f)
  ;ProcedureReturn
  Protected p=8
  Macro DT(t1,t2="")
    DrawText(8,p,t1)
    DrawText(120,p,t2)
    p+20
  EndMacro
  CreateSprite(0,300,300)
  StartDrawing(SpriteOutput(0))
  DrawingMode(#PB_2DDrawing_AllChannels)
  DrawingFont(FontID(0))
  Box(0,0,300,300,$44000000)
  DrawingMode(#PB_2DDrawing_AllChannels|#PB_2DDrawing_Outlined)
  Box(0,0,300,300,$ffffffff)
  BackColor($44000000)
  FrontColor($ffffffff)
  dt("Moving:")
  dt("Mouse + wheel+ arrow keys")   
  dt("")
  dt("Commandes:")
  dt("[F1] / [F2]","Wave big: "+Str(waveb*100)+"%")
  dt("[F3] / [F4]","Wave little: ")
  dt("[F5] / [F6]","Swell height: ")
  dt("[F7] / [F8]","foam: ")
  dt("[F12]","Wireframe")
  dt("[Esc]","Quit")
  StopDrawing()
EndProcedure

Procedure main()
  Protected sky,heightmap,seaspray   
  Protected ex,ey,c,v, i,j, fly=1,fdf, ev
  Protected.f MouseX,Mousey,keyx,keyy,keyz,dist,aval, och, waveb,wavel,swell,foam
  
  InitEngine3D():InitSprite():InitKeyboard():InitMouse()
  
  ExamineDesktops()
  ex=DesktopWidth(0)
  ey=DesktopHeight(0)
  OpenWindow(0,0,0,ex,ey,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0))
  OpenWindowedScreen(WindowID(0), 0, 0, ex, ey)
  ;OpenScreen(ex,ey,32,"")
  
  LoadFont(0,"arial",12*100/DesktopScaledX(100))
  
  Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Scripts\MaterialScriptsGeneric", #PB_3DArchive_FileSystem )
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  ;------------------- scene
  
  CreateCamera(0, 0, 0, 100, 100):CameraBackColor(0,$332200)
  MoveCamera(0,0,10,0)
  CameraLookAt(0, 0,10,-10)
  CreateLight(0,$ffffff, 10000, 10000,0)
  AmbientColor($444444)
  
  ;---- ilot / island
  Protected di=256,dj=256,di1=di-1,dj1=dj-1,ii,jj,h.f,g.f,   x.f,y.f
  Dim h.f(0,0)
  Dim g.f(0,0)
  Dim t.PB_MeshVertexv(di,dj)
  
  Noise2d(h(),di,dj,0,3):outline2d(h(),0,15,"0,0/0.4,0.2/0.5,0.4/0.7,0.9/1,1")
  For j=0 To dj1:For i=0 To di1:x=i/di*#PI:y=j/dj*#PI:h(i,j)*Sin(x)*Sin(y)*#PI-8:Next:Next
  CopyArray(h(),g()):Embos2D(g(),0,0):outline2d(g(),0,255)
  
  For j=0 To dj:  jj=j & dj1
    For i=0 To di:ii=i & di1
      h=h(ii,jj)
      g=g(ii,jj)       
      With t(i,j)
        vec3d(\p,i,h,j)
        vec3d(\n,h((i-1) & di1,jj)-h((i+1) & di1,jj),2,h(ii,(j-1) & dj1)-h(ii,(j+1) & dj1)):norme3d(\n)
        \u=i*0.1
        \v=j*0.1
        Select g
          Case 0 To 80:\color=$22556677
          Case 80 To 120:\color=$225599aa
          Default:\color=$4488aadd
        EndSelect
        If h<7:\color | $CC000000 :EndIf
      EndWith
    Next
  Next   
  CreateDataMesh(10,t())
  BuildMeshTangents(10)
  texturecolor (10,512,512,1,5,0,"0,$ff888888/1,$ffffffff")
  texturenormal(11,512,512,0,2,0,22,"0,1/0.3,0.4/0.5,0/0.7,0.4/1,1")
  GetScriptMaterial(10,"bump"):MaterialTextureAliases(10,TextureID(10),TextureID(11),0,0)
  MaterialFilteringMode(10,#PB_Material_Anisotropic,4)
  MaterialShininess(10,64):SetMaterialColor(10,#PB_Material_SpecularColor,$ffffff)
  CreateEntity(10,MeshID(10),MaterialID(10))
  ;heightmap
  heightmap=CreateTexture(-1,256,256)
  StartDrawing(TextureOutput(heightmap))
  For j=0 To dj1:For i=0 To di1:Plot(i,j,limite(h(i,j)*16+128,0,255)):Next:Next
  StopDrawing()
  
  
  ;---- sky / ciel
  sky=texturecolor(-1,512,512,0,3,0,"0,$00ffffff/0.4/0.7,$ffffffff/1,$ff888888")
  SkyDome2(1024,200,0,"0,$ff4400/1,$ff4400")
  SkyDome2AddLayer(sky,0.1,0.04,0)     
  SkyDome2AddLayer(sky,0.2,0.04,90)     
  SkyDome2AddLayer(sky,0.4,0.04,180)     
  
  ; Sea spray / embruns
  LoadTexture(4, "water.png")
  CreateMaterial(4, TextureID(4))
  DisableMaterialLighting(4, 1)
  MaterialBlendingMode   (4, #PB_Material_AlphaBlend)
  SetMaterialAttribute(4,#PB_Material_TAM,#PB_Material_ClampTAM)
  
  seaspray=CreateParticleEmitter(-1,8, 2, 8, #PB_Particle_Box)
  ParticleMaterial    (Seaspray, MaterialID(4))
  ParticleSize        (Seaspray, 0.25,0.25):ParticleScaleRate(Seaspray,4)
  ParticleColorFader(Seaspray, 0, 0, 0, -1)
  ParticleEmitterDirection(Seaspray, 0, 0.2, 1)
  ParticleTimeToLive  (Seaspray, 1,1)
  ParticleVelocity(Seaspray, 2,20)
  ParticleAcceleration(Seaspray, 0, -0.1, 0)
  ParticleAngle(Seaspray,-180,180)
  ParticleEmissionRate(Seaspray, 500)
  
  waveb=1
  wavel=0.4
  swell=0.4
  foam=0.6
  
  
  initocean(128,1,1024,waveb,wavel,swell,foam, $ff332200, $ff886644,Seaspray,heightmap)
  
  inittime=ElapsedMilliseconds()
  
  menu(waveb, wavel, swell, foam)
  
  Repeat
    Repeat : ev = WindowEvent() : Until ev = 0 
    ExamineMouse()
    ExamineKeyboard()
    MouseX = -MouseDeltaX() *  0.05
    MouseY = -MouseDeltaY() *  0.05
    Macro param(val,key1,key2)
      aval=val :val +(-KeyboardReleased(key1)+KeyboardReleased(key2))*0.1:val =limite(val ,0.1,1)
      If val <>aval:menu(waveb,wavel,swell,foam):oceanset(waveb,wavel,swell,foam):EndIf
    EndMacro
    param(waveb,#PB_Key_F1,#PB_Key_F2)
    param(wavel,#PB_Key_F3,#PB_Key_F4)
    param(swell,#PB_Key_F5,#PB_Key_F6)
    param(foam ,#PB_Key_F7,#PB_Key_F8)
    If KeyboardReleased(#PB_Key_F11):fly=1-fly:EndIf
    If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
    
    keyx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
    keyz=(-Bool(KeyboardPushed(#PB_Key_Up  ))+Bool(KeyboardPushed(#PB_Key_Down )))*0.5-MouseWheel()*10;-fly*0.2
    RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):dist+(keyz-dist)*0.05:MoveCamera  (0, KeyX, 0, dist)
    If fly=0:och+(oceanHeight(CameraX(0),CameraZ(0))+1-och)*0.2:MoveCamera(0,CameraX(0),och,CameraZ(0),#PB_Absolute):EndIf
    
    renderocean()
    RenderWorld()
    MoveEntity(skydome_e,CameraX(0),  -8,CameraZ(0),#PB_Absolute)
    If IsSprite(0) = 0 
      Debug "No sprite"
    Else
      DisplayTransparentSprite(0,8,8)
    EndIf
    FlipBuffers()
  Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(3)
EndProcedure

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please use the OpenGL subsystem"
CompilerEndIf
main()

Fullscreen code working for me:

Code: Select all

; Océan v2 - pf Shadoko - 2020

EnableExplicit

DeclareModule ext_3D
  EnableExplicit
  Global inittime
  
  Structure f3
    x.f
    y.f
    z.f
  EndStructure
  
  Structure f2
    x.f
    y.f
  EndStructure
  
  Structure PB_MeshVertexV
    p.f3
    n.f3
    t.f3
    u.f
    v.f
    color.l
  EndStructure
  
  ;________________ Lib ________________
  Declare vec3d(*v.f3,vx.f,vy.f,vz.f)
  Declare sub3D(*p.f3,*p1.f3,*p2.f3)
  Declare mul3d(*p1,v.f)
  Declare.f lng3D(*v.f3)   
  Declare norme3d(*v.f3,l.f=1)   
  Declare.f Max(v1.f,v2.f)
  Declare.f Min(v1.f,v2.f)
  Declare.f limite(V.f, i.f, s.f)
  Declare.i Modi(v,divisor)
  Declare.f interpolarray2d(Array tt.f(2),x.f,y.f)
  Declare ColorBlend(color1.l, color2.l, blend.f)
  Declare GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
  Declare Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
  Declare  blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
  Declare Embos2D(Array s.f(2), px.w=0, py.w=0)
  Declare grad2D(Array s.f(2),delta=1)
  Declare  outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
  Declare textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
  Declare textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
  
  ;________________ océan ________________
  
  Global oc_mesh,oc_material,oc_txtnm,oc_txtdif,oc_particule,   oc_waveb.f, oc_wavel.f,oc_swell.f, oc_foam.f 
  Global oc_tilesize,oc_tilesize2,oc_prec,oc_tilenb,oc_tilenb1
  Global oc_tn,oc_tn1,oc_tn2
  Declare initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
  Declare freeocean()
  Declare renderocean()
  Declare.f oceanHeight(x.f,z.f)
  Declare oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
  
  ;________________ SkyDome2 ________________
  Global skydome_m, skydome_e
  Declare SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
  Declare SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)   
EndDeclareModule

Module ext_3D
  
  ;{ ============================= biblio
  Global ev.i
  Procedure vec3d(*v.f3,vx.f,vy.f,vz.f)
    *v\x=vx
    *v\y=vy
    *v\z=vz
  EndProcedure
  
  Procedure sub3D(*p.f3,*p1.f3,*p2.f3)
    *p\x=*p1\x-*p2\x
    *p\y=*p1\y-*p2\y
    *p\z=*p1\z-*p2\z
  EndProcedure
  
  Procedure add3d(*p.f3,*p1.f3,*p2.f3)
    *p\x=*p1\x+*p2\x
    *p\y=*p1\y+*p2\y
    *p\z=*p1\z+*p2\z
  EndProcedure
  
  Procedure mul3d(*p1.f3,v.f)
    *p1\x*v
    *p1\y*v
    *p1\z*v
  EndProcedure
  
  Procedure.f lng3D(*v.f3)
    ProcedureReturn Sqr(*V\x * *V\x + *V\y * *V\y + *V\z * *V\z)
  EndProcedure
  
  Procedure Norme3D(*V.f3,l.f=1)
    Protected.f lm
    lm = l / lng3d(*v)
    *V\x * lm
    *V\y * lm
    *V\z * lm 
  EndProcedure
  
  Procedure.f Max(v1.f,v2.f)
    If v1>v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
  EndProcedure
  
  Procedure.f Min(v1.f,v2.f)
    If v1<v2:ProcedureReturn v1:Else:ProcedureReturn v2:EndIf
  EndProcedure
  
  Procedure.f limite(V.f, i.f, s.f)
    If V < i :v=i:EndIf
    If V > s :v=s:EndIf
    ProcedureReturn V
  EndProcedure
  
  Procedure.i Modi(v,divisor)
    ProcedureReturn (V+$10000*divisor) % divisor
  EndProcedure
  
  Procedure.f POM(v.f)
    ProcedureReturn (Random(v*1000)-v*500)/500
  EndProcedure
  
  ;##############################################################################################
  
  Procedure CoRBinv(c.l)
    ProcedureReturn  RGBA(Blue(c),Green(c),Red(c),Alpha(c))
  EndProcedure
  
  Procedure ColorBlend(color1.l, color2.l, blend.f)
    Protected r.w,g.w,b.w,a.w
    r=  Red(color1) + (Red(color2)     - Red(color1)) * blend
    g=Green(color1) + (Green(color2) - Green(color1)) * blend
    b= Blue(color1) + (Blue(color2) -   Blue(color1)) * blend
    a=Alpha(color1) + (Alpha(color2) - Alpha(color1)) * blend
    ProcedureReturn  RGBA(r,g,b,a)
  EndProcedure
  
  Procedure GradientToArray(Array pal.l(1),n,gradient.s,inv.b=0,alpha.b=0)
    Protected i,j, apos,pos, acol.l,col.l,p,lt.s
    n-1
    Dim pal(n)
    
    Repeat
      apos=pos
      acol=col
      i+1
      lt=StringField(gradient,i,"/"):If lt="":Break:EndIf
      pos=ValF(lt)*n
      p=FindString(lt,",")
      If p
        col=Val(Mid(lt,p+1))
        If inv  :col=CoRBinv(col):EndIf
        If alpha:col | $ff000000:EndIf
      Else
        col=acol
      EndIf
      For j=apos To pos:pal(j)=ColorBlend(acol,col,(j-apos)/(pos-apos)):Next
    ForEver
  EndProcedure
  
  Procedure Array2Dlimit(Array t.f(2),*min.float,*max.float)
    Protected i,j,dx1,dy1
    Protected.f v,smin,smax
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    smax = -1e10
    smin =  1e10
    For j=0 To dy1
      For i=0 To dx1
        v=t(j,i)
        If v<smin : smin=v: EndIf
        If v>smax : smax=v: EndIf
      Next
    Next
    *min\f=smin
    *max\f=smax
  EndProcedure
  
  Procedure Array2Dclamp(Array t.f(2),min.f,max.f)
    Protected i,j,dx1,dy1
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    For j=0 To dy1
      For i=0 To dx1
        t(j,i)=limite(t(j,i),min,max)
      Next
    Next
  EndProcedure
  
  Procedure blur2D(Array s.f(2),di.w, dj.w,pass=1,loop=1)
    If di=0 And dj=0:ProcedureReturn:EndIf
    Protected i,j,k,d,dii,djj,dx,dy,dij,tx.f
    
    dx = ArraySize(s(), 2):di=min(di,dx)
    dy = ArraySize(s(), 1):dj=min(dj,dy)
    Dim d.f(dy,dx)
    dii=di+1
    djj=dj+1
    dij = dii * djj
    
    If loop
      d=dx-dii/2:Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = (i+d) % (dx+1): Next
      d=dx-dii/2:Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = (i+d) % (dy+1): Next   
    Else
      Dim lx(dx + 2*dii): For i = 0 To dx + 2*dii: lx(i) = limite(i-1-dii/2, 0, dx): Next
      Dim ly(dy + 2*djj): For i = 0 To dy + 2*djj: ly(i) = limite(i-1-djj/2, 0, dy): Next
    EndIf 
    For k=1 To pass
      Dim ty.f(dx)
      For j = 0 To djj - 1: For i = 0 To dx: ty(i) + s(ly(j),i): Next: Next   
      For j = 0 To dy
        For i = 0 To dx: ty(i) + s(ly(djj+j),i) - s(ly(j),i): Next
        tx=0:For i = 0 To dii-1: tx+ty(lx(i)): Next
        For i = 0 To dx: tx + ty(lx(dii+i)) - ty(lx(i) ): d(j,i) = tx / dij: Next
      Next
      CopyArray(d(),s())
    Next
  EndProcedure
  
  Procedure Embos2D(Array s.f(2), px.w=0, py.w=0)
    Protected i,j,dx,dy
    px=1<<Int(Abs(px))*Sign(px)
    py=1<<Int(Abs(py))*Sign(py)
    
    Macro gra(j0,i0,j1,i1)
      t(j0,i0)=Abs(s(j0,i0)-s(j0,i1)+px)+Abs(s(j0,i0)-s(j1,i0)+py)
    EndMacro
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim T.f(dy,dx)
    For j=0 To dy-1
      For i=0 To dx-1
        gra(j,i,j+1,i+1)
      Next
      gra(j,dx,j+1,0)
    Next
    For i = 0 To dx-1
      gra(dy,i,0,i+1)
    Next
    gra(dy,dx,0,0)
    CopyArray(t(),s())
  EndProcedure
  
  Procedure grad2D(Array s.f(2),delta=1)
    Protected i,j,dx,dy
    
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim d.f(dy,dx)
    For j=0 To dy
      For i=0 To dx
        d(j,i)= 4*s(j,i)   -s(j,(i-delta) & dx)-s(j,(i+delta) & dx)-s((j-delta) & dy,i)-s((j+delta) & dy,i)
      Next
    Next
    CopyArray(d(),s())
  EndProcedure
  
  Procedure superpose(Array s.f(2),n.w=1)
    Protected i,j,k,dx,dy,x,y,ii,jj
    
    dy = ArraySize(s(), 1)
    dx = ArraySize(s(), 2)
    Dim T.f(dy,dx)
    For k=1 To n
      x=Random(dx)
      y=Random(dy)
      For j=0 To dy
        For i=0 To dx
          t(i,j)+s((i+x) & dx,(j+y) & dy)
        Next
      Next
    Next
    CopyArray(t(),s())
  EndProcedure
  
  Procedure Noise2d(Array t.f(2), dx.w, dy.w,rnd, oinit.b, onb.b=16)
    Protected i,j,n,d,dd,d3,dx1=dx-1,dy1=dy-1,coef.f=9,den.f=1/(2*coef-2),amp.f=1/$1000
    Dim t(dy1, dx1)
    
    RandomSeed(rnd)
    n = 1<<oinit
    dd=min(dx,dy) / n: If dd<1:dd=1:EndIf
    j=0:While j<dy1:i=0:While i<dx1: t(j,i) = (Random($2000) - $1000)*amp:i+dd:Wend:j+dd:Wend
    While dd > 1
      If onb=0:amp=0:EndIf
      d = dd / 2:d3=d*3:amp/2
      j=d:While j<dy
        i=0:While i<dx
          t(j,i) = (-t((j - d3) & dy1,i) - t((j +d3) & dy1,i) + coef*(t((j - d) & dy1,i) + t((j + d) & dy1,i))) *den + (Random($2000) - $1000)*amp
        i+dd:Wend
      j+dd:Wend
      j=0:While j<dy
        i=d:While i<dx
          t(j,i) = (-t(j,(i - d3) & dx1) - t(j,(i +d3) & dx1) + coef*(t(j,(i - d) & dx1) + t(j,(i + d) & dx1))) *den + (Random($2000) - $1000)*amp
        i+dd:Wend
      j+d:Wend
      dd/2:onb-1
    Wend     
  EndProcedure
  
  Procedure Finterpol(Array F.f(1),profil.s,dmin.f=1,dmax.f=0)
    Protected.l i,j,n,c,ac,rx,   t.s
    Protected.f y,dx,dy,p
    
    rx=ArraySize(f())
    n=CountString(profil,"/")
    Dim s.f2(n)
    For i=0 To n
      t=StringField(profil,i+1,"/")
      s(i)\x=ValF(t)*rx
      s(i)\y=ValF(StringField(t,2,","))*(dmax-dmin)+dmin
    Next 
    
    For j=0 To n-1
      y=s(j)\y
      dx=s(j+1)\x-s(j)\x
      dy=s(j+1)\y-s(j)\y
      p=dy/dx
      ac=c
      While c<=s(j+1)\x
        f(c)=y+p*(c-ac):c+1
      Wend
    Next
  EndProcedure
  
  Procedure outline2d(Array t.f(2),dmin.f,dmax.f,outline.s="0,0/1,1",sminl.f=0,smaxl.f=0)
    Protected dx1,dy1,i,ii,j,k,xi
    Protected.f smin,smax,sr,tt,x,y0,y1,x0,dminl,dmaxl
    
    dy1 = ArraySize(t(), 1)
    dx1 = ArraySize(t(), 2)
    Array2Dlimit(t(),@smin,@smax)
    sr=smax-smin
    
    Dim conv.f(256)
    Finterpol(conv(),outline,dmin,dmax)
    If smaxl-sminl<>0
      ii=(sminl-smin)/sr*255:For i=0 To ii:conv(i)=conv(ii):Next
      ii=(smaxl-smin)/sr*255:For i=ii To 255:conv(i)=conv(ii):Next
    EndIf
    
    For j=0 To dy1
      For i=0 To dx1
        x=(t(j,i)-smin)/sr*255
        xi=Int(x):x0=x-xi
        y0=conv(xi)
        y1=conv(xi+1)
        t(j,i)=y1*x0+y0*(1-x0)
      Next
    Next
  EndProcedure
  
  Procedure textureArrayToColor(tex,Array t.f(2),grad.s="0,$000000/1,$ffffff")
    Protected i,j,n,dx,dy
    Protected.f min,max,r
    
    dx=ArraySize(t(),2)+1
    dy=ArraySize(t(),1)+1
    Dim bmp.l(dy-1,dx-1)
    
    Protected Dim grad.l(0):gradienttoarray(grad(),1024,grad,1)
    Array2Dlimit(t(),@min,@max):r=1023/(max-min)
    For j=0 To dy-1:For i=0 To dx-1:n=(t(j,i)-min)*r:bmp(j,i)=grad(n):Next:Next
    
    n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
    StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
    ProcedureReturn tex
  EndProcedure
  
  Procedure textureArrayToNM(tex,Array t.f(2),amplitude.f,alphavalue=0)
    Protected i,j,n,dx,dy
    Protected.f h00,h10,h01,x,y,z,l, max=1/amplitude,max2=max*max
    Protected.f3 p
    
    Dim a.f(0,0) :CopyArray(t(),a())
    Select alphavalue
      Case 0:outline2d(a(),0,255)
      Case 1:grad2d(a(),4):Array2Dclamp(a(),-0.4,0):outline2d(a(),0,255,"0,0/1,1")
    EndSelect
    
    dx=ArraySize(t(),2)+1
    dy=ArraySize(t(),1)+1
    Dim bmp.l(dy-1,dx-1)
    For j=0 To dy-1
      For i=0 To dx-1
        h00=t(j,i)
        h10=t(j,(i+1) % dx)
        h01=t((j+1) % dy,i)
        p\x=h00-h10
        p\y=h00-h01
        l=min(p\x*p\x+p\y*p\y,max2)
        p\z=Sqr(max2-l)
        Norme3D(p,127)
        bmp(j,i)=RGBA(p\z+128,p\y+128,p\x+128,a(j,i))
      Next
    Next 
    n=CreateTexture(tex,dx,dy):If tex=-1:tex=n:EndIf
    StartDrawing(TextureOutput(tex)):CopyMemory(@bmp(0,0),DrawingBuffer(),dx*dy*4):StopDrawing()
    ProcedureReturn tex
  EndProcedure
  
  Procedure.f interpolarray2d(Array tt.f(2),x.f,y.f)
    Protected.l i0, j0,i1,j1,dx1,dy1
    Protected.f dx, dy
    dx1=ArraySize(tt(),1)
    dy1=ArraySize(tt(),2)
    i0 = Int(X) & dx1:i1=(i0+1) & dx1: dx = X - Int(x)
    j0 = Int(Y) & dy1:j1=(j0+1) & dy1: dy = Y - Int(y)
    ProcedureReturn (((1 - dx) * tt(j0,i0) + dx * tt(j0,i1)) * (1 - dy) + ((1 - dx) * tt(j1,i0) + dx * tt(j1,i1)) * dy)
  EndProcedure
  
  ;}===================================================================================================================================================
  
  ;{ Océan
  
  Procedure initocean(tilesize,prec,range,wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l,skycolor.l,particule=-1,heightmap=-1)
    ; tilesize: must be a power of 2
    ; precision : 1-> 1 meters,  2->2 meters, 3->4 meters, 4-> 8 meters...
    ; range : distance to the camera where the oocean should be rendered
    ; wavebig,wavelittle,swell,foam : value: 0.0 -> 1.0
    ; particule : for sea spray
    ; heightmap : texture containing the depth. only the red component is used : red=depth*16+128, and clamped between 0 and 255
    
    Protected i,j,k,r,n,a.f
    oc_tilesize=tilesize:oc_tilesize2=oc_tilesize/2
    oc_prec=1<<(prec-1)
    oc_tilenb=range/tilesize*2:oc_tilenb1=oc_tilenb-1
    oc_tn=oc_tilesize/oc_prec:oc_tn1=oc_tn-1:oc_tn2=oc_tn/2
    oc_particule=particule
    
    Global Dim oc_h.f(oc_tn1,oc_tn1)
    Global Dim oc_entity(oc_tilenb1,oc_tilenb1)
    
    Dim t.f(0,0)
    ;Waves (noramlmap)
    Noise2d(oc_h(),512,512,0,4)
    outline2d(oc_h(),0,1,"0,0/0.5,1/1,0")
    blur2D(oc_h(),1,1,1)   
    oc_txtnm=textureArraytoNM(-1,oc_h(),16)
    ;foam (diffusemap)
    Noise2d(t(),512,512,0,7)
    outline2d(t(),0,1,"0,0/0.2,0.2/0.5,1/0.7,0.2/1,0")
    oc_txtdif=textureArrayToColor(-1,t())
    
    oc_material=GetScriptMaterial(-1,"ocean"):MaterialTextureAliases(oc_material,TextureID(oc_txtnm),TextureID(oc_txtdif),TextureID(heightmap),0)
    MaterialFilteringMode(oc_material,#PB_Material_Anisotropic,4)
    MaterialShininess(oc_material,64)
    SetMaterialAttribute(oc_material,#PB_Material_TAM,#PB_Material_ClampTAM,2)
    oceanset(wavebig,wavelittle,swell,foam,watercolor,skycolor)
    
    For k=0 To 4:r=1<<k
      Dim mv.PB_MeshVertexv(oc_tn/r,oc_tn/r)
      For j=0 To oc_tn/r
        For i=0 To oc_tn/r
          With mv(j,i)
            vec3d(\p,(i*r-oc_tn2)*oc_prec,pom(16),-(j*r-oc_tn2)*oc_prec)         
            \u=i*r/oc_tn
            \v=j*r/oc_tn
          EndWith
        Next
      Next
      If k=0
        oc_mesh=CreateDataMesh(-1,mv())
      Else
        n=CreateDataMesh(-1,mv())
        AddMeshManualLOD(oc_mesh,n,128 *r)
        SetMeshMaterial(n,MaterialID(oc_material))
      EndIf
    Next
    
    For j=0 To oc_tilenb1
      For i=0 To oc_tilenb1
        oc_entity(j,i)=CreateEntity(-1,MeshID(oc_mesh),MaterialID(oc_material))
      Next
    Next
  EndProcedure
  
  Procedure freeocean()
    Protected i,j
    For j=0 To ArraySize(oc_entity(),1)
      For i=0 To ArraySize(oc_entity(),2)
        FreeEntity(oc_entity(j,i))
      Next
    Next
    FreeMesh(oc_mesh)
    FreeArray(oc_entity())
    FreeMaterial(oc_material)
    FreeTexture(oc_txtnm)
    FreeTexture(oc_txtdif)
  EndProcedure
  
  Procedure.f oceanHeight(x.f,z.f)
    Protected time.f=(ElapsedMilliseconds()-inittime)/1000*0.01, dx.f=time*512
    x*2-0.5
    z*2-0.5
    ProcedureReturn (interpolarray2d(oc_h(),x+dx,z)+interpolarray2d(oc_h(),x+256-dx,z+256)-1)*oc_waveb*4+Sin(z/512*20-time*100)*oc_swell*4
  EndProcedure
  
  Procedure oceanset(wavebig.f,wavelittle.f,swell.f,foam.f,watercolor.l=0,skycolor.l=0)
    oc_waveb=wavebig
    oc_wavel=wavelittle
    oc_swell=swell
    oc_foam =foam   
    SetMaterialColor(oc_material,#PB_Material_AmbientColor,RGBA(wavebig*255,wavelittle*255,swell*255,foam*255))
    If watercolor:SetMaterialColor(oc_material,#PB_Material_DiffuseColor,watercolor):EndIf
    If skycolor:SetMaterialColor(oc_material,#PB_Material_SpecularColor,skycolor):EndIf
  EndProcedure
  
  Procedure renderocean()
    Protected i,j,  pos.f3
    
    If oc_particule>=0
      pos\x=CameraX(0)+pom(100)+CameraDirectionX(0)*100
      pos\z=CameraZ(0)+pom(100)+CameraDirectionZ(0)*100
      pos\y=oceanHeight(pos\x,pos\z)+1
      If pos\y>0:MoveParticleEmitter(oc_particule,pos\x,pos\y,pos\z,#PB_Absolute):EndIf
    EndIf
    ;------------------- tuiles
    Protected da=oc_tilenb*oc_tilesize
    Static api=0,pi=1000,  apj=0,pj=1000,  i0,i1,  j0,j1,  e
    api=pi:pi=(CameraX(0)-da/2)/oc_tilesize:If pi<api:i0=pi:i1=api-1:Else:i0=api+1+oc_tilenb1:i1=pi+oc_tilenb1:EndIf
    apj=pj:pj=(CameraZ(0)-da/2)/oc_tilesize:If pj<apj:j0=pj:j1=apj-1:Else:j0=apj+1+oc_tilenb1:j1=pj+oc_tilenb1:EndIf
    For j=pj To pj+oc_tilenb1
      For i=pi To pi+oc_tilenb1
        If (i>=i0 And i<=i1) Or (j>=j0 And j<=j1)
          MoveEntity(oc_entity(Modi(j,oc_tilenb),Modi(i,oc_tilenb)), i*oc_tilesize+oc_tilesize2,0,j*oc_tilesize+oc_tilesize2,#PB_Absolute)
        EndIf
      Next
    Next
    
    ;------------------- sous / sur l'eau
    If CameraY(0)<oceanHeight(CameraX(0),CameraZ(0))
      Fog($332200,100,0,30)
      MaterialCullingMode(oc_material,#PB_Material_AntiClockWiseCull)
    Else
      Fog($ffaa88,100,0,da/2)
      MaterialCullingMode(oc_material,#PB_Material_ClockWiseCull)
    EndIf       
  EndProcedure
  ;}
  
  ;{ SkyDome2
  Procedure SkyDome2(rayon.f,hauteur.f,material,degrade.s="0,$ffffff/1,$ffffff")
    If skydome_m:FreeMesh(skydome_m):EndIf
    If skydome_e:FreeEntity(skydome_e):EndIf
    Protected i,j,d=16,icol   ,d1=d-1,d2=d/2,mesh
    Protected.f x,y,z,  xo,yo,  u,v,   ai,aj,  lat,lng, mx 
    Dim t.PB_MeshVertexv(d,d)
    Dim col.l(0)
    
    DisableDebugger:CreateMaterial(0,0):EnableDebugger
    GradientToArray(col(),256,degrade)
    For j=0 To d
      For i=0 To d
        With t(i,j)
          xo=1-i/d2
          yo=1-j/d2
          lng=ATan2(xo,yo)
          mx=max(Abs(xo),Abs(yo))
          \u=(Cos(lng)* mx+1)/2
          \v=(Sin(lng)* mx+1)/2
          lat=mx* #PI/2
          x=Cos(lng)* Sin(lat)*rayon
          z=Sin(lng)* Sin(lat)*rayon
          y=Cos(lat)*hauteur
          vec3d(\p,-x,y,z)
          icol=255*(x+rayon)/(2*rayon)
          \color=$ff000000+col(icol)
        EndWith
      Next
    Next 
    skydome_m=CreateDataMesh(-1,t())
    skydome_e=CreateEntity(-1,MeshID(skydome_m),MaterialID(material))
    DisableMaterialLighting(material,1)
  EndProcedure
  
  Procedure SkyDome2AddLayer(txt,scale.f,scroll.f=0,angle.f=0)
    Protected layer
    AddMaterialLayer(0,TextureID(txt),#PB_Material_AlphaBlend)
    layer=CountMaterialLayers(0)-1
    ScaleMaterial(0,scale,scale,layer)
    RotateMaterial(0,angle,#PB_Material_Fixed,layer)
    ScrollMaterial(0,0,scroll,#PB_Material_Animated,layer)
  EndProcedure
  ;}
EndModule
;#####################################################################################################################################################

UseModule ext_3d

Procedure texturecolor(tex,dx,dy,rnd=0,f=0,lissage=0,grad.s="0,$000000/1,$ffffffff",outline.s="0,0/1,1")
  Protected Dim t.f(0,0)
  
  Noise2d(t(),dx,dy,rnd,f)
  blur2D(t(),lissage,lissage,2)   
  outline2d(t(),0,1,outline)
  ProcedureReturn textureArrayToColor(tex,t(),grad)
EndProcedure

Procedure texturenormal(tex,dx,dy,rnd=0,f=0,lissage=0,relief.f=1,outline.s="0,0/1,1",alphavalue=0)
  Protected Dim t.f(0,0)
  
  Noise2d(t(),dx,dy,rnd,f)
  outline2d(t(),0,1,outline)
  blur2D(t(),lissage,lissage,3)   
  ProcedureReturn textureArraytoNM(tex,t(),relief,alphavalue)
EndProcedure

Procedure menu(waveb.f,wavel.f,swell.f,foam.f)
  ;ProcedureReturn
  Protected p=8
  Macro DT(t1,t2="")
    DrawText(8,p,t1)
    DrawText(120,p,t2)
    p+20
  EndMacro
  CreateSprite(0,300,300)
  StartDrawing(SpriteOutput(0))
  DrawingMode(#PB_2DDrawing_AllChannels)
  DrawingFont(FontID(0))
  Box(0,0,300,300,$44000000)
  DrawingMode(#PB_2DDrawing_AllChannels|#PB_2DDrawing_Outlined)
  Box(0,0,300,300,$ffffffff)
  BackColor($44000000)
  FrontColor($ffffffff)
  dt("Moving:")
  dt("Mouse + wheel+ arrow keys")   
  dt("")
  dt("Commandes:")
  dt("[F1] / [F2]","Wave big: "+Str(waveb*100)+"%")
  dt("[F3] / [F4]","Wave little: ")
  dt("[F5] / [F6]","Swell height: ")
  dt("[F7] / [F8]","foam: ")
  dt("[F12]","Wireframe")
  dt("[Esc]","Quit")
  StopDrawing()
EndProcedure

Procedure main()
  Protected sky,heightmap,seaspray   
  Protected ex,ey,c,v, i,j, fly=1,fdf, ev
  Protected.f MouseX,Mousey,keyx,keyy,keyz,dist,aval, och, waveb,wavel,swell,foam
  
  InitEngine3D():InitSprite():InitKeyboard():InitMouse()
  
  ExamineDesktops()
  ex=DesktopWidth(0)
  ey=DesktopHeight(0)
  OpenWindow(0,0,0,ex,ey,"",#PB_Window_BorderLess|#PB_Window_ScreenCentered):OpenWindowedScreen(WindowID(0), 0, 0, WindowWidth(0),WindowHeight(0))
  ;OpenWindowedScreen(WindowID(0), 0, 0, ex, ey)
  OpenScreen(ex,ey,32,"")
  
  LoadFont(0,"arial",12*100/DesktopScaledX(100))
  
  Add3DArchive(#PB_Compiler_Home + "Examples\3D\Data\Scripts\MaterialScriptsGeneric", #PB_3DArchive_FileSystem )
  Add3DArchive(#PB_Compiler_Home + "examples/3d/Data/Textures", #PB_3DArchive_FileSystem)
  Parse3DScripts()
  
  ;------------------- scene
  
  CreateCamera(0, 0, 0, 100, 100):CameraBackColor(0,$332200)
  MoveCamera(0,0,10,0)
  CameraLookAt(0, 0,10,-10)
  CreateLight(0,$ffffff, 10000, 10000,0)
  AmbientColor($444444)
  
  ;---- ilot / island
  Protected di=256,dj=256,di1=di-1,dj1=dj-1,ii,jj,h.f,g.f,   x.f,y.f
  Dim h.f(0,0)
  Dim g.f(0,0)
  Dim t.PB_MeshVertexv(di,dj)
  
  Noise2d(h(),di,dj,0,3):outline2d(h(),0,15,"0,0/0.4,0.2/0.5,0.4/0.7,0.9/1,1")
  For j=0 To dj1:For i=0 To di1:x=i/di*#PI:y=j/dj*#PI:h(i,j)*Sin(x)*Sin(y)*#PI-8:Next:Next
  CopyArray(h(),g()):Embos2D(g(),0,0):outline2d(g(),0,255)
  
  For j=0 To dj:  jj=j & dj1
    For i=0 To di:ii=i & di1
      h=h(ii,jj)
      g=g(ii,jj)       
      With t(i,j)
        vec3d(\p,i,h,j)
        vec3d(\n,h((i-1) & di1,jj)-h((i+1) & di1,jj),2,h(ii,(j-1) & dj1)-h(ii,(j+1) & dj1)):norme3d(\n)
        \u=i*0.1
        \v=j*0.1
        Select g
          Case 0 To 80:\color=$22556677
          Case 80 To 120:\color=$225599aa
          Default:\color=$4488aadd
        EndSelect
        If h<7:\color | $CC000000 :EndIf
      EndWith
    Next
  Next   
  CreateDataMesh(10,t())
  BuildMeshTangents(10)
  texturecolor (10,512,512,1,5,0,"0,$ff888888/1,$ffffffff")
  texturenormal(11,512,512,0,2,0,22,"0,1/0.3,0.4/0.5,0/0.7,0.4/1,1")
  GetScriptMaterial(10,"bump"):MaterialTextureAliases(10,TextureID(10),TextureID(11),0,0)
  MaterialFilteringMode(10,#PB_Material_Anisotropic,4)
  MaterialShininess(10,64):SetMaterialColor(10,#PB_Material_SpecularColor,$ffffff)
  CreateEntity(10,MeshID(10),MaterialID(10))
  ;heightmap
  heightmap=CreateTexture(-1,256,256)
  StartDrawing(TextureOutput(heightmap))
  For j=0 To dj1:For i=0 To di1:Plot(i,j,limite(h(i,j)*16+128,0,255)):Next:Next
  StopDrawing()
  
  
  ;---- sky / ciel
  sky=texturecolor(-1,512,512,0,3,0,"0,$00ffffff/0.4/0.7,$ffffffff/1,$ff888888")
  SkyDome2(1024,200,0,"0,$ff4400/1,$ff4400")
  SkyDome2AddLayer(sky,0.1,0.04,0)     
  SkyDome2AddLayer(sky,0.2,0.04,90)     
  SkyDome2AddLayer(sky,0.4,0.04,180)     
  
  ; Sea spray / embruns
  LoadTexture(4, "water.png")
  CreateMaterial(4, TextureID(4))
  DisableMaterialLighting(4, 1)
  MaterialBlendingMode   (4, #PB_Material_AlphaBlend)
  SetMaterialAttribute(4,#PB_Material_TAM,#PB_Material_ClampTAM)
  
  seaspray=CreateParticleEmitter(-1,8, 2, 8, #PB_Particle_Box)
  ParticleMaterial    (Seaspray, MaterialID(4))
  ParticleSize        (Seaspray, 0.25,0.25):ParticleScaleRate(Seaspray,4)
  ParticleColorFader(Seaspray, 0, 0, 0, -1)
  ParticleEmitterDirection(Seaspray, 0, 0.2, 1)
  ParticleTimeToLive  (Seaspray, 1,1)
  ParticleVelocity(Seaspray, 2,20)
  ParticleAcceleration(Seaspray, 0, -0.1, 0)
  ParticleAngle(Seaspray,-180,180)
  ParticleEmissionRate(Seaspray, 500)
  
  waveb=1
  wavel=0.4
  swell=0.4
  foam=0.6
  
  
  initocean(128,1,1024,waveb,wavel,swell,foam, $ff332200, $ff886644,Seaspray,heightmap)
  
  inittime=ElapsedMilliseconds()
  
  menu(waveb, wavel, swell, foam)
  
  Repeat
    ;Repeat : ev = WindowEvent() : Until ev = 0 
    ExamineMouse()
    ExamineKeyboard()
    MouseX = -MouseDeltaX() *  0.05
    MouseY = -MouseDeltaY() *  0.05
    Macro param(val,key1,key2)
      aval=val :val +(-KeyboardReleased(key1)+KeyboardReleased(key2))*0.1:val =limite(val ,0.1,1)
      If val <>aval:menu(waveb,wavel,swell,foam):oceanset(waveb,wavel,swell,foam):EndIf
    EndMacro
    param(waveb,#PB_Key_F1,#PB_Key_F2)
    param(wavel,#PB_Key_F3,#PB_Key_F4)
    param(swell,#PB_Key_F5,#PB_Key_F6)
    param(foam ,#PB_Key_F7,#PB_Key_F8)
    If KeyboardReleased(#PB_Key_F11):fly=1-fly:EndIf
    If KeyboardReleased(#PB_Key_F12):fdf=1-fdf:If fdf:CameraRenderMode(0,#PB_Camera_Wireframe):Else:CameraRenderMode(0,#PB_Camera_Textured):EndIf:EndIf
    
    keyx=(-Bool(KeyboardPushed(#PB_Key_Left))+Bool(KeyboardPushed(#PB_Key_Right)))*0.5
    keyz=(-Bool(KeyboardPushed(#PB_Key_Up  ))+Bool(KeyboardPushed(#PB_Key_Down )))*0.5-MouseWheel()*10;-fly*0.2
    RotateCamera(0, MouseY, MouseX, 0, #PB_Relative):dist+(keyz-dist)*0.05:MoveCamera  (0, KeyX, 0, dist)
    If fly=0:och+(oceanHeight(CameraX(0),CameraZ(0))+1-och)*0.2:MoveCamera(0,CameraX(0),och,CameraZ(0),#PB_Absolute):EndIf
    
    renderocean()
    RenderWorld()
    MoveEntity(skydome_e,CameraX(0),  -8,CameraZ(0),#PB_Absolute)
    If IsSprite(0) = 0 
      Debug "No sprite"
    Else
      DisplayTransparentSprite(0,8,8)
    EndIf
    FlipBuffers()
  Until KeyboardPushed(#PB_Key_Escape) Or MouseButton(3)
EndProcedure

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please use the OpenGL subsystem"
CompilerEndIf

main()
Even this simple one works for me:

Code: Select all

InitEngine3D()
InitSprite()
InitKeyboard()

CompilerIf #PB_Compiler_OS = #PB_OS_Windows And Subsystem("OpenGL") = #False
  CompilerError "Please use the OpenGL subsystem"
CompilerEndIf

Global w.i, h.i, e.i

ExamineDesktops()
w = DesktopWidth(0) / DesktopResolutionX() : h = DesktopHeight(0) / DesktopResolutionY()
OpenWindow(0, 0, 0, w , h , "Sprite test", #PB_Window_SystemMenu)
OpenWindowedScreen(WindowID(0), 0, 0, w * DesktopResolutionX(), h * DesktopResolutionY())
CreateCamera(0, 0, 0, 100, 100)

CreateCube(0, 0.2)
CreateTexture(0, 200, 200, "Blaa")
StartDrawing(TextureOutput(0))
Box( 0, 0, 200, 200, $85F82B)
Box(4, 4, 192, 192, $0)
StopDrawing()

CreateMaterial(0, TextureID(0))
MaterialBlendingMode(0, #PB_Material_Add)
AddMaterialLayer(0, TextureID(0), #PB_Material_Add)
MaterialCullingMode(0, #PB_Material_NoCulling)

CreateEntity(0, MeshID(0), MaterialID(0), 0, 0, -1.5)

CreateSprite(0, 200, 200)
StartDrawing(SpriteOutput(0))
DrawingMode(#PB_2DDrawing_AlphaBlend)
Box(0, 0, 200, 50, $FF85F8EA)
DrawingMode(#PB_2DDrawing_Transparent)
DrawText(10, 10, "WORKING SPRITE", $FF8551EA)
StopDrawing()

Repeat
  
  Repeat
    ev = WindowEvent()
  Until ev = 0
  
  ExamineKeyboard()
  RotateEntity(0, 0.1, 0.1, 0.1, #PB_Relative)
  
  RenderWorld()
  If IsSprite(0)
    DisplayTransparentSprite(0, 0, 0)
  EndIf
  
  FlipBuffers()
  
Until KeyboardPushed(#PB_Key_Escape)
Windows 10 Pro - 64 bit
But I still get the erratic mouse movement behavior in WindowedScreen mode, though. :lol:
Fullscreen is smoth as silk.
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Ocean v2 (shader OpenGL)

Post by DK_PETER »

Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
User avatar
Paul
PureBasic Expert
PureBasic Expert
Posts: 1252
Joined: Fri Apr 25, 2003 4:34 pm
Location: Canada
Contact:

Re: Ocean v2 (shader OpenGL)

Post by Paul »

DK_PETER wrote: Windows 10 Pro - 64 bit
But I still get the erratic mouse movement behavior in WindowedScreen mode, though. :lol:
Fullscreen is smoth as silk.
I find mouse controls for 3D stuff are completely screwed up on my system (4k monitor) unless I turn on "DPI Aware" when I compile, then all controls are smooth.
Image Image
User avatar
DK_PETER
Addict
Addict
Posts: 898
Joined: Sat Feb 19, 2011 10:06 am
Location: Denmark
Contact:

Re: Ocean v2 (shader OpenGL)

Post by DK_PETER »

Paul wrote:
DK_PETER wrote: Windows 10 Pro - 64 bit
But I still get the erratic mouse movement behavior in WindowedScreen mode, though. :lol:
Fullscreen is smoth as silk.
I find mouse controls for 3D stuff are completely screwed up on my system (4k monitor) unless I turn on "DPI Aware" when I compile, then all controls are smooth.
4K monitor here too. :)
Current configurations:
Ubuntu 20.04/64 bit - Window 10 64 bit
Intel 6800K, GeForce Gtx 1060, 32 gb ram.
Amd Ryzen 9 5950X, GeForce 3070, 128 gb ram.
Post Reply