
--
-- Copyright (C) 2023  <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 pict1obj is 
-- 1-sided version of pictobj

-- maps texture coordinates UV to cover the full extent of a side;
-- thus the whole *.png file is visible

-- pict1obj is a special version of pictobj where only ONE face is drawn
-- This is used for drawing portals on dungeon walls: No,We,So,Ea,Up,Dn
-- according to the integer iwhich = 1..4



procedure initialize( rect: in out pictangle ) is
begin
	rect.vert := new varray;
	rect.txuv := new tarray;
	rect.elem := new earray;
end initialize;

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

procedure finalize( rect: in out pictangle ) is
begin
	vfree( rect.vert );
	tfree( rect.txuv );
	efree( rect.elem );
	--text_io.put_line("rect Free");
end finalize;





-- this initializer is intended for texture images
-- that must not be reversed, EG. when lettering exists.
procedure setrect( rect: pictangle;
xc,yc,zc, xr,yr,zr : float;
iwhich : integer  -- 1=>Z+=no, 2=>X+=we, 3=>Z-=so, 4=>X-=ea
-- 16mar18:  added 5=>Y+=up
-- 20mar18:  added 6=>Y-=dn
) is

	k, j : integer := 0;
	xm,xp, ym,yp, zm,zp: float;
begin

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

if iwhich=5 then
	-- portal on ceiling Y+ ccw (looking Up @ ceiling x+=left, z+=dn
	rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=yp;  rect.vert(k+ 3):=zm; --UL
	rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=yp;  rect.vert(k+ 6):=zp;
	rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zp;
	rect.vert(k+10):=xm;  rect.vert(k+11):=yp;  rect.vert(k+12):=zm;
	k:=k+12;

elsif iwhich=6 then --floor Y- ccw (looking Dn @ floor x+=left, z+=up

	rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zp; --UL
	rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zm; --LL
	rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=ym;  rect.vert(k+ 9):=zm; --LR
	rect.vert(k+10):=xm;  rect.vert(k+11):=ym;  rect.vert(k+12):=zp; --UR
	k:=k+12;


elsif iwhich=1 then
	-- portal on northWall Z+ ccw
	rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zp; --LL
	rect.vert(k+ 4):=xm;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zp;
	rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zp;
	rect.vert(k+10):=xp;  rect.vert(k+11):=yp;  rect.vert(k+12):=zp;
	k:=k+12;

elsif iwhich=3 then
	-- portal on southWall Z- ccw
	rect.vert(k+ 1):=xm;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zm; --LL
	rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zm;
	rect.vert(k+ 7):=xp;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zm;
	rect.vert(k+10):=xm;  rect.vert(k+11):=yp;  rect.vert(k+12):=zm;
	k:=k+12;

elsif iwhich=4 then
	-- portal on eastWall X- cw
	--rect.vert(k+ 1):=xm;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zm;
	--rect.vert(k+ 4):=xm;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zp;
	--rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zp;
	--rect.vert(k+10):=xm;  rect.vert(k+11):=yp;  rect.vert(k+12):=zm;

	-- portal on eastWall X- ccw (5feb17)
	rect.vert(k+ 1):=xm;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zp; --LL
	rect.vert(k+ 4):=xm;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zm;
	rect.vert(k+ 7):=xm;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zm;
	rect.vert(k+10):=xm;  rect.vert(k+11):=yp;  rect.vert(k+12):=zp;
	k:=k+12;

elsif iwhich=2 then
	-- portal on westWall X+ cw
	--rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zp;
	--rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zm;
	--rect.vert(k+ 7):=xp;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zm;
	--rect.vert(k+10):=xp;  rect.vert(k+11):=yp;  rect.vert(k+12):=zp;

	-- portal on westWall X+ ccw (5feb17)
	rect.vert(k+ 1):=xp;  rect.vert(k+ 2):=ym;  rect.vert(k+ 3):=zm; --LL
	rect.vert(k+ 4):=xp;  rect.vert(k+ 5):=ym;  rect.vert(k+ 6):=zp;
	rect.vert(k+ 7):=xp;  rect.vert(k+ 8):=yp;  rect.vert(k+ 9):=zp;
	rect.vert(k+10):=xp;  rect.vert(k+11):=yp;  rect.vert(k+12):=zm;
	k:=k+12;

else
	raise program_error;
end if;


	-- texture UV coords for single face:
		rect.txuv(1):=1.0;  rect.txuv(2):=0.0;
		rect.txuv(3):=0.0;  rect.txuv(4):=0.0;
		rect.txuv(5):=0.0;  rect.txuv(6):=1.0;
		rect.txuv(7):=1.0;  rect.txuv(8):=1.0;

	-- element indices:
		rect.elem(1):=0;
		rect.elem(2):=1;
		rect.elem(3):=2;
		rect.elem(4):=2;
		rect.elem(5):=3;
		rect.elem(6):=0;


end setrect;









--
-- note:  the shaders for these objects must have two 
-- input "layouts", as well as whatever uniforms are needed:
--
-- layout(location=0) in vec3 vertPosName
-- layout(location=1) in vec3 vertRgbName
--
-- ...where their actual names can be whatever is convenient
--

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

procedure draw( rect: pictangle; vertbuff, uvbuff, elembuff : 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);

	-- 1st attribute:  texture UV
	glBindBuffer(gl_array_buffer, uvbuff);
	glBufferData(gl_array_buffer, glsizeiptr(4*nuv), rect.txuv(1)'address, gl_static_draw);
	glEnableVertexAttribArray(1);
	glVertexAttribPointer(1,2,gl_float,gl_false,0, system.null_address);

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

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


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


	glDisableVertexAttribArray(0);
	glDisableVertexAttribArray(1);

end draw;






end pict1obj;

