
--
-- 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 interfaces.c;
use type interfaces.c.unsigned_short;


with ada.finalization;
with unchecked_deallocation;

with text_io;  use text_io;



package body rectxfineobj is -- for untextured rectangular exterior




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

procedure vfree is new unchecked_deallocation(varray,vap);

procedure finalize( rect: in out rectfine ) is
begin
	vfree( rect.vert );
end finalize;



procedure myassert( condition : boolean;  flag: integer:=0 ) is
begin
  if condition=false then
  		put("ASSERTION Failed!  ");
		if flag /= 0 then
			put_line( "rectxfineobj @ " & integer'image(flag) );
		end if;
		new_line;
  		raise program_error;
  end if;
end myassert;




procedure setrect( rect: rectfine ) is

	use interfaces.c;

	xm,xp,ym,yp,zm,zp: float;

	ee, eebase, t, k : integer := 0;

	di0,dj0,di1,dj1 : float;

	--fn : constant float := float(nperedge);
	dn : constant gldouble := gldouble(nperedge);

	xc,yc,zc : constant float := 0.0;
	xr,yr,zr : constant float := 1.0;

begin

	xm  := xc-xr;
	xp  := xc+xr;

	ym  := yc-yr;
	yp  := yc+yr;

	zm  := zc-zr; -- -1.0
	zp  := zc+zr; -- +1.0




for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- left (east=X-) ccw exterior normal
	rect.vert(k+ 1):=xm;  rect.vert(k+ 2):=ym+di0;  rect.vert(k+ 3):=zm+dj0;
	rect.vert(k+ 4):=xm;  rect.vert(k+ 5):=ym+di0;  rect.vert(k+ 6):=zm+dj1;
	rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=ym+di1;  rect.vert(k+ 9):=zm+dj1;

	rect.vert(k+10):=xm;  rect.vert(k+11):=ym+di1;  rect.vert(k+12):=zm+dj1;
	rect.vert(k+13):=xm;  rect.vert(k+14):=ym+di1;  rect.vert(k+15):=zm+dj0;
	rect.vert(k+16):=xm;  rect.vert(k+17):=ym+di0;  rect.vert(k+18):=zm+dj0;

	k:=k+18;

end loop;
end loop;



for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- right (west=X+) ccw exterior normal
	rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=ym+di0;  rect.vert(k+ 3):=zm+dj1;
	rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=ym+di0;  rect.vert(k+ 6):=zm+dj0;
	rect.vert(k+ 7):=xp;  rect.vert(k+ 8):=ym+di1;  rect.vert(k+ 9):=zm+dj0;

	rect.vert(k+10):=xp;  rect.vert(k+11):=ym+di1;  rect.vert(k+12):=zm+dj0;
	rect.vert(k+13):=xp;  rect.vert(k+14):=ym+di1;  rect.vert(k+15):=zm+dj1;
	rect.vert(k+16):=xp;  rect.vert(k+17):=ym+di0;  rect.vert(k+18):=zm+dj1;

	k:=k+18;

end loop;
end loop;




for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- bottom (Y-) ccw exterior normal
	rect.vert(k+ 1):=xm+di0;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zm+dj0;
	rect.vert(k+ 4):=xm+di1;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zm+dj0;
	rect.vert(k+ 7):=xm+di1;  rect.vert(k+ 8):=ym;  rect.vert(k+ 9):=zm+dj1;

	rect.vert(k+10):=xm+di1;  rect.vert(k+11):=ym;  rect.vert(k+12):=zm+dj1;
	rect.vert(k+13):=xm+di0;  rect.vert(k+14):=ym;  rect.vert(k+15):=zm+dj1;
	rect.vert(k+16):=xm+di0;  rect.vert(k+17):=ym;  rect.vert(k+18):=zm+dj0;

	k:=k+18;

end loop;
end loop;




for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- top (Y+) ccw exterior normal
	rect.vert(k+ 1):=xm+di0;  rect.vert(k+ 2):=yp;  rect.vert(k+ 3):=zm+dj1;
	rect.vert(k+ 4):=xm+di1;  rect.vert(k+ 5):=yp;  rect.vert(k+ 6):=zm+dj1;
	rect.vert(k+ 7):=xm+di1;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zm+dj0;

	rect.vert(k+10):=xm+di1;  rect.vert(k+11):=yp;  rect.vert(k+12):=zm+dj0;
	rect.vert(k+13):=xm+di0;  rect.vert(k+14):=yp;  rect.vert(k+15):=zm+dj0;
	rect.vert(k+16):=xm+di0;  rect.vert(k+17):=yp;  rect.vert(k+18):=zm+dj1;

	k:=k+18;

end loop;
end loop;




for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- back (south=Z-) ccw exterior normal
	rect.vert(k+ 1):=xm+di1;  rect.vert(k+ 2):=ym+dj0;  rect.vert(k+ 3):=zm;
	rect.vert(k+ 4):=xm+di0;  rect.vert(k+ 5):=ym+dj0;  rect.vert(k+ 6):=zm;
	rect.vert(k+ 7):=xm+di0;  rect.vert(k+ 8):=ym+dj1;  rect.vert(k+ 9):=zm;

	rect.vert(k+10):=xm+di0;  rect.vert(k+11):=ym+dj1;  rect.vert(k+12):=zm;
	rect.vert(k+13):=xm+di1;  rect.vert(k+14):=ym+dj1;  rect.vert(k+15):=zm;
	rect.vert(k+16):=xm+di1;  rect.vert(k+17):=ym+dj0;  rect.vert(k+18):=zm;

	k:=k+18;

end loop;
end loop;




for i in 1..nperedge loop
for j in 1..nperedge loop

	di0:=2.0*float(gldouble(i-1)/dn);
	dj0:=2.0*float(gldouble(j-1)/dn);
	di1:=2.0*float(gldouble(i)/dn);
	dj1:=2.0*float(gldouble(j)/dn);

	-- front (north=Z+) ccw exterior normal
	rect.vert(k+ 1):=xm+di0;  rect.vert(k+ 2):=ym+dj0;  rect.vert(k+ 3):=zp; --1
	rect.vert(k+ 4):=xm+di1;  rect.vert(k+ 5):=ym+dj0;  rect.vert(k+ 6):=zp; --2
	rect.vert(k+ 7):=xm+di1;  rect.vert(k+ 8):=ym+dj1;  rect.vert(k+ 9):=zp; --3

	rect.vert(k+10):=xm+di1;  rect.vert(k+11):=ym+dj1;  rect.vert(k+12):=zp; --3
	rect.vert(k+13):=xm+di0;  rect.vert(k+14):=ym+dj1;  rect.vert(k+15):=zp; --4
	rect.vert(k+16):=xm+di0;  rect.vert(k+17):=ym+dj0;  rect.vert(k+18):=zp; --1

	k:=k+18;

end loop;
end loop;





myassert(k=nvert,1);


end setrect;



use gl;
use glext;
use glext.binding;
use gl.binding;

procedure draw( rect: rectfine; vertbuff : gluint ) is
begin

	-- 0th attribute:  vertices
	glBindBuffer(gl_array_buffer, vertbuff);
	glBufferData(gl_array_buffer, glsizeiptr(4*nvert), rect.vert(1)'address, gl_static_draw);
	glEnableVertexAttribArray(0);
	glVertexAttribPointer(0,3,gl_float,gl_false,0, system.null_address);

	glEnable(gl_blend);
	glBlendFunc(gl_src_alpha, gl_one_minus_src_alpha);

	glDrawArrays(gl_triangles, 0, glint(nvert));

	glDisableVertexAttribArray(0);

end draw;






end rectxfineobj;

