/* -----------------------------------------------------------------------------
	GSFramework
	Copyright 2001-2013 Emmanuel Julien. All Rights Reserved.
----------------------------------------------------------------------------- */


		#include "core/renderer.h"
		#include "core/camera.h"
		#include "core/raster_font.h"
		#include "sort/sort.h"
		#include "platform_config.h"
		#include "log/log.h"

		using namespace GS::Core;
		using namespace GS::Render;


//------------------------------------------------------------------------------
uint				Renderer::BuildRenderablePrimitiveList(const Camera &view, const Camera &lod_view, GS::Stack <Primitive *> &list, Renderable::Context context) const
{
	uint tested_primitive = 0;

	list.Clear();
	ListForeachPtr(Renderable *, renderable, renderable_list)
		tested_primitive += renderable->GetRenderablePrimitiveList(view, lod_view, list, context, true);

	return tested_primitive;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Camera				*Renderer::GetCamera() const
{	return view_item;	}
void				Renderer::SetCamera(Camera *item)
{
	view_item = item;
	view_registry = item ? &item->registry : NULL;
}
void				Renderer::ApplyCamera()
{
	if	(view_item)
	{
		SetViewMatrix(view_item->GetMatrix(), &view_item->GetInverseMatrix());

		Matrix4 pm;
		view_item->ComputeProjectionMatrix(GetViewport(), pm);
		SetProjectionMatrix(pm);
		
		view_item->ComputeFrustum(view_item->frustum, GetViewport());
		frustum = view_item->frustum;
	}
}
void				Renderer::SetViewRegistry(GS::Registry *registry)
{	view_registry = registry;	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
GS::tVector2 <uint>	Renderer::GetOutputDimensions() const
{
	if	(output_texture)
		return tVector2 <uint> (output_texture->GetWidth(), output_texture->GetHeight());
	return dimensions;
}
float				Renderer::GetOutputAspectRatio() const
{
	if	(output_texture)
		return float(output_texture->GetHeight()) / float(output_texture->GetWidth());
	return output_aspect_ratio > 0 ? output_aspect_ratio : (float)dimensions.y / (float)dimensions.x;
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
void				Renderer::PushRenderable(Renderable *renderable)
{	renderable_list.Add(renderable);	}
void				Renderer::DeleteRenderableList()
{	renderable_list.Clear();	}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
Renderer::Renderer()
{
	output_aspect_ratio = 0;
	global_aspect_ratio = AR_Square;

	default_window = NULL;
	output_window = NULL;

	environment_interface = NULL;

	view_item = NULL;
	view_registry = NULL;
	dimensions.Set(1, 1);

	ipd = 0.0f;

	registry.RegisterMessageListener(this);
}
Renderer::~Renderer()
{
	registry.UnregisterMessageListener(this);
}
//------------------------------------------------------------------------------
