--------------------
-- resource setup

-- load the resources we need
local t33 = model.load("t33.f3d")
local mtl = material.load("t33small.tga.sess3.mtl")
local shd = mtl:getshader()

local userv = shader.getparamid(shd,"user_v")
local userf = shader.getparamid(shd,"user_f")

local mrtmtl  = material.load("mrtcombine.mtl")
local mrtlay0 = mrtmtl:gettexcontrol("layer0")
local mrtlay1 = mrtmtl:gettexcontrol("layer1")
local mrtshd  = mrtmtl:getshader()
local mrtuser = mrtshd:getparamid("userctrl")

-- parameter binding
if (userv) then
	function vp(...)
		local args = {...}
		local x,y,z,w = shd:param(userv)
		if (#args < 1) then return x,y,z,w end
		
		shd:param(userv,args[1] or x,args[2] or y,args[3] or z,args[4] or w)
	end
end

if (userf) then
	function fp(...)
		local args = {...}
		local x,y,z,w = shd:param(userf)
		if (#args < 1) then return x,y,z,w end
		
		shd:param(userf,args[1] or x,args[2] or y,args[3] or z,args[4] or w)
	end
end


-------------------
-- basic scene


if (true) then
	-- create the textures for render-to-texture
	-- GL_NV_texture_rectangle
	local texlay0 = texture.createfullwindow("layer0")
	local texlay1 = texture.createfullwindow("layer1")

	-- create the fbo (GL_EXT_framebuffer_object)
	--
	-- glGenFramebuffersEXT(1,&fbo->glID);
	fbo = renderfbo.new(32,32,true)
	
	-- create the rbo
	--
	-- glGenRenderbuffersEXT(1,&rb->glID);
	-- glBindRenderbufferEXT(GL_RENDERBUFFER_EXT, rb->glID);
	-- glRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH24_STENCIL8_EXT, w, h);
	--
	-- GL_EXT_packed_depth_stencil
	rbo = renderbuffer.new(textype.depthstencil(),32,32,true)
	
	-- customized renderloop for MRT
	view = l3dset.get(0):getdefaultview()
	view:rcmdempty()
	
	-- enable fbo
	--
	-- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,fbo->glID);
	local rc = rcmdfbobind.new()
	rc:setup(fbo)
	view:rcmdadd(rc)
	
	-- bind textures to fbo
	--
	-- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_RECTANGLE_NV,tex->glID);
	-- glFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT1_EXT, GL_TEXTURE_RECTANGLE_NV,tex->glID);
	local rc = rcmdfbotex.new()
	rc:color(0,texlay0)
	rc:color(1,texlay1)
	view:rcmdadd(rc)
	
	-- bind renderbuffer to fbo
	--
	-- glFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT,rb->glID);
	local rc = rcmdfborb.new()
	rc:depth(rbo)
	view:rcmdadd(rc)
	
	-- set in which colortargets is drawn
	-- GL_ARB_draw_buffers
	--
	-- GLenum targets[2] = {GL_COLOR_ATTACHMENT0_EXT,
	--						GL_COLOR_ATTACHMENT1_EXT};
	-- glDrawBuffersARB(2,targets);
	local rc = rcmdfbodrawto.new()
	rc:setup(0,1)
	view:rcmdadd(rc)
	
	-- fill in default drawing
	view = UtilFunctions.simplerenderqueue(view,true)
	view.rClear:colorvalue(0.0,0.0,0.0,0.0) 
	
	-- at the end, disable fbo
	-- glBindFramebufferEXT(GL_FRAMEBUFFER_EXT,0);
	view:rcmdadd(rcmdfbooff.new())
	
	-- render fullscreen quad with combine shader
	local rc = rcmddraw2dmesh.new()
	rc:matsurface(mrtmtl)
	rc:moTexcontrol(mrtlay0,texlay0)
	rc:moTexcontrol(mrtlay1,texlay1)
	rc:autosize(-1)
	view:rcmdadd(rc)
	
	-- a final error check
	fboerrtype,fboerrmsg = l3dlist.fbotest()

	if (fboerrtype) then
		print(fboerrmsg)
		if (fboerrtype > 0) then
			-- revert
			view = UtilFunctions.simplerenderqueue(view)
		end
	end

else
	view = UtilFunctions.simplerenderqueue()
	view.rClear:colorvalue(0.0,0.0,0.0,0) 
end


-- as we want more than one ship lets use a function
function makespaceship(pos,specctrl)
	local actor = actornode.new("t33",unpack(pos))
	
	actor.l3d = l3dmodel.new("t33",t33)
	actor.l3d:linkinterface(actor)
	actor.spos = pos
	
	-- for all meshids 
	for i=1,t33:meshcount() do
		-- create a meshid 
		local mid = t33:meshid(i-1)	-- meshid indices start at 0
		-- assign material to l3dmodel's mesh
		actor.l3d:matsurface(mid,mtl)
	end
	-- always set Renderflags AFTER material assignments
	actor.l3d:rfLitSun(true)
	
	return actor
end

-- lets create some spaceships
spaceships = {}
table.insert(spaceships,makespaceship({0,15,0},{1,1,1,8}))

sun = actornode.new("sun",100,-100,500)
sun.light = l3dlight.new("sun")
sun.light:ambient(.1,.05,.0,1)
sun.light:linkinterface(sun)
sun.light:makesun()


-- rotation of object
-- A simple user input system for rotation
local cx,cy = 0,0
local pdx,pdy,pdz = 0,0,0
function rotit ()
	local x,y = input.mousepos() -- mouse
	x,y = -y,-x
	
	local l,r = input.ismousedown(0),input.ismousedown(1)
	if not l and not r then -- if no mousebutton is pressed...
		cx,cy = x,y -- set reference coordinate to the mouse position
	end
	local dx,dy,dz = l and (cx-x) or 0, cy-y,r and (cx-x) or 0
	  -- dx,dy,dz is now a direction vector
	dx,dy,dz = dx*.01, dy*.01, dz*.01 -- smaller numbers now
	pdx,pdy,pdz = pdx*.9+dx*.1, pdy*.9+dy*.1, pdz*.9+dz*.1
	dx,dy,dz = pdx,pdy,pdz -- dampen the vector with previous one
	
	for i,actor in ipairs(spaceships) do
		actor.rx,actor.ry,actor.rz = -- set rotation info for the actor
			(actor.rx or 0) + dx, (actor.ry or 0)+dy, (actor.rz or 0)+dz
		actor:rotdeg(actor.rx,actor.ry,actor.rz)
		actor:pos(unpack(actor.spos)) -- position/rotation update
	end
end

Timer.set("tutorial",rotit,20)
-- rotit is now called every 20 milliseconds
