
--
-- Copyright (C) 2022  <fastrgv@gmail.com>
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You may read the full text of the GNU General Public License
-- at <http://www.gnu.org/licenses/>.
--

with system;
with gl, gl.binding, gl.pointers;
with glu, glu.binding, glu.pointers;
with glext, glext.binding, glext.pointers;


with ada.finalization;
with unchecked_deallocation;


	with text_io;


package body circsurfobj is -- for round reflective water





procedure initialize( cs: in out circsurf ) is
begin
	cs.vert := new varray;
end initialize;

procedure vfree is new unchecked_deallocation(varray,vap);

procedure finalize( cs: in out circsurf ) is
begin
	vfree( cs.vert );
	--text_io.put_line("circsurf Free");
end finalize;



function sqr( x:float ) return float is
begin
	return x*x;
end sqr;





procedure setround( cs: in out circsurf;  xc,zc,rr : float ) is

	rr2 : constant float := rr*rr;

	xm : float := xc-rr;
	xp : float := xc+rr;
	zm : float := zc-rr;
	zp : float := zc+rr;

	k : integer := 0;

	dx : constant float := (xp-xm)/fn;
	dz : constant float := (zp-zm)/fn;

	xmm,xpp,zmm,zpp, fi,fj : float;
	t1,t2,t3,t4 : boolean;

begin

	cs.nv:=0;

	for i in 0..n-1 loop
	fi := float(i);
	for j in 0..n-1 loop
	fj := float(j);

		xmm := xm + fi*dx;
		xpp := xmm + dx;
		zmm := zm + fj*dz;
		zpp := zmm + dz;

		t1 := (  sqr(xmm-xc) + sqr(zpp-zc)  < rr2 );
		t2 := (  sqr(xpp-xc) + sqr(zpp-zc)  < rr2 );
		t3 := (  sqr(xpp-xc) + sqr(zmm-zc)  < rr2 );
		t4 := (  sqr(xmm-xc) + sqr(zmm-zc)  < rr2 );

		k := 0;
		if t1 then k:=k+1; end if;
		if t2 then k:=k+1; end if;
		if t3 then k:=k+1; end if;
		if t4 then k:=k+1; end if;

		if( k=3 ) then

			if t1 then
				cs.vert(cs.nv+1):=xmm;
				cs.vert(cs.nv+2):=0.0;
				cs.vert(cs.nv+3):=zpp;
				cs.nv:=cs.nv+3;
			end if;

			if t2 then
				cs.vert(cs.nv+1):=xpp;
				cs.vert(cs.nv+2):=0.0;
				cs.vert(cs.nv+3):=zpp;
				cs.nv:=cs.nv+3;
			end if;

			if t3 then
				cs.vert(cs.nv+1):=xpp;
				cs.vert(cs.nv+2):=0.0;
				cs.vert(cs.nv+3):=zmm;
				cs.nv:=cs.nv+3;
			end if;

			if t4 then
				cs.vert(cs.nv+1):=xmm;
				cs.vert(cs.nv+2):=0.0;
				cs.vert(cs.nv+3):=zmm;
				cs.nv:=cs.nv+3;
			end if;

		elsif( k=4 ) then

			cs.vert(cs.nv+1):=xmm;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zpp;
			cs.nv:=cs.nv+3;

			cs.vert(cs.nv+1):=xpp;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zpp;
			cs.nv:=cs.nv+3;

			cs.vert(cs.nv+1):=xpp;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zmm;
			cs.nv:=cs.nv+3;


			cs.vert(cs.nv+1):=xmm;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zpp;
			cs.nv:=cs.nv+3;

			cs.vert(cs.nv+1):=xpp;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zmm;
			cs.nv:=cs.nv+3;

			cs.vert(cs.nv+1):=xmm;
			cs.vert(cs.nv+2):=0.0;
			cs.vert(cs.nv+3):=zmm;
			cs.nv:=cs.nv+3;

		end if; --k=4

	end loop; --j
	end loop; --i

end setround;





-- note:  the shaders for these objects must have one
-- input "layout", as well as whatever uniforms are needed:
--
-- layout(location=0) in vec3 vertPosName
--
-- ...where their actual name can be whatever is cocs.nvenient
--

use gl;
use glext;
use glext.binding;
procedure draw( cs: circsurf;  vertbuff : gluint ) is
begin

	glBindBuffer(gl_array_buffer, vertbuff);
	glBufferData(gl_array_buffer, glsizeiptr(4*cs.nv), cs.vert(1)'address, gl_static_draw);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0,3,gl_float,gl_false,0, system.null_address);

	gl.binding.glDrawArrays( gl_triangles, 0, glint(cs.nv) );

	glDisableVertexAttribArray(0);

end draw;


end circsurfobj;

