
--
-- Copyright (C) 2020  <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;



package body tunnelobj is -- for rectangular textured interiors

-- this variation is intended only for long narrow tunnel rooms
-- AND has no walls at ends of tunnel.



procedure initialize( rm: in out room ) is
begin
	rm.vert := new varray;
	rm.elem := new earray;
end initialize;

procedure vfree is new unchecked_deallocation(varray,vap);
procedure efree is new unchecked_deallocation(earray,eap);

procedure finalize( rm: in out room ) is
begin
	vfree( rm.vert );
	efree( rm.elem );
	--text_io.put_line("room Free");
end finalize;







procedure setorect( rm: room;  xc,yc,zc, xr,yr,zr : float ) is

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

	e, k, j : integer := 0;
	jj : glushort;

	longy, longz, longx : boolean := false;

begin
	xm  := xc-xr;
	xp  := xc+xr;
	ym  := yc-yr;
	yp  := yc+yr;
	zm  := zc-zr;
	zp  := zc+zr;


	if yr>xr and yr>zr then --dropping from ceiling
		longy:=true;
	elsif zr>xr then 
		longz:=true;
	else           
		longx:=true;
	end if;



if longx or longy then

	-- front
	rm.vert(k+ 1):=xm;  rm.vert(k+ 2):=ym;  rm.vert(k+ 3):=zp;
	rm.vert(k+ 4):=xm;  rm.vert(k+ 5):=yp;  rm.vert(k+ 6):=zp;
	rm.vert(k+ 7):=xp;  rm.vert(k+ 8):=yp;  rm.vert(k+ 9):=zp;
	rm.vert(k+10):=xp;  rm.vert(k+11):=ym;  rm.vert(k+12):=zp;
	k:=k+12;

end if;


if not longy then
	-- top
	rm.vert(k+ 1):=xm;  rm.vert(k+ 2):=yp;  rm.vert(k+ 3):=zp;
	rm.vert(k+ 4):=xm;  rm.vert(k+ 5):=yp;  rm.vert(k+ 6):=zm;
	rm.vert(k+ 7):=xp;  rm.vert(k+ 8):=yp;  rm.vert(k+ 9):=zm;
	rm.vert(k+10):=xp;  rm.vert(k+11):=yp;  rm.vert(k+12):=zp;
	k:=k+12;

end if;


if longx or longy then

	-- back
	rm.vert(k+ 1):=xp;  rm.vert(k+ 2):=ym;  rm.vert(k+ 3):=zm;
	rm.vert(k+ 4):=xp;  rm.vert(k+ 5):=yp;  rm.vert(k+ 6):=zm;
	rm.vert(k+ 7):=xm;  rm.vert(k+ 8):=yp;  rm.vert(k+ 9):=zm;
	rm.vert(k+10):=xm;  rm.vert(k+11):=ym;  rm.vert(k+12):=zm;
	k:=k+12;

end if;



if not longy then

	-- bottom
	rm.vert(k+ 1):=xm;  rm.vert(k+ 2):=ym;  rm.vert(k+ 3):=zm;
	rm.vert(k+ 4):=xm;  rm.vert(k+ 5):=ym;  rm.vert(k+ 6):=zp;
	rm.vert(k+ 7):=xp;  rm.vert(k+ 8):=ym;  rm.vert(k+ 9):=zp;
	rm.vert(k+10):=xp;  rm.vert(k+11):=ym;  rm.vert(k+12):=zm;
	k:=k+12;

end if;



if longz or longy then

	-- right
	rm.vert(k+ 1):=xm;  rm.vert(k+ 2):=ym;  rm.vert(k+ 3):=zm;
	rm.vert(k+ 4):=xm;  rm.vert(k+ 5):=yp;  rm.vert(k+ 6):=zm;
	rm.vert(k+ 7):=xm;  rm.vert(k+ 8):=yp;  rm.vert(k+ 9):=zp;
	rm.vert(k+10):=xm;  rm.vert(k+11):=ym;  rm.vert(k+12):=zp;
	k:=k+12;


	-- left
	rm.vert(k+ 1):=xp;  rm.vert(k+ 2):=ym;  rm.vert(k+ 3):=zp;
	rm.vert(k+ 4):=xp;  rm.vert(k+ 5):=yp;  rm.vert(k+ 6):=zp;
	rm.vert(k+ 7):=xp;  rm.vert(k+ 8):=yp;  rm.vert(k+ 9):=zm;
	rm.vert(k+10):=xp;  rm.vert(k+11):=ym;  rm.vert(k+12):=zm;
	k:=k+12;

end if;



	-- element indices:
	e:=0;
	for i in 0..3 loop
		jj:=glushort(i*4);
		j := i*6;
		rm.elem(j+1):=jj+0;
		rm.elem(j+2):=jj+1;
		rm.elem(j+3):=jj+2;
		rm.elem(j+4):=jj+2;
		rm.elem(j+5):=jj+3;
		rm.elem(j+6):=jj+0;
		e:=e+6;
	end loop;


	--myassert( k=48 );
	--myassert( e=24 );

end setorect;



--
-- 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 names can be whatever is convenient
--
use gl;
use glext;
use glext.binding;
use gl.binding;

procedure draw( rm: room;  vertbuff, elembuff : gluint ) is
	nv, ne : integer;
begin

	nv:=nvert; --48;
	ne:=nelm; --24;

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

	-- element indices:
	glBindBuffer(gl_element_array_buffer, elembuff);
	glBufferData(gl_element_array_buffer, glsizeiptr(2*ne), rm.elem(1)'address, gl_static_draw);

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

	glDrawElements( gl_triangles, glint(nv), gl_unsigned_short, system.null_address );

	glDisableVertexAttribArray(0);

end draw;



end tunnelobj;

