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


		#include "gpu/gpu_triangle_batch.h"
		#include "gpu/gpu_renderer.h"

		using namespace GS;
		using namespace GS::GPU;


//------------------------------------------------------------------------------
void				TriangleBatch::Flush()
{
	if	(batch_triangle_count > 0)
		renderer.DrawTriangle(batch_triangle_count, batch_vtx, batch_idx, batch_col, batch_uv, batch_t, batch_blend_op, batch_render_word);

	batch_triangle_count = 0;
	batch_attrib_offset = 0;
}
void				TriangleBatch::DrawTriangle(uint triangle_count, uint attrib_count, const Vector4 *vtx, const ushort *idx, const Color *col, const Vector2 *uv, const Render::Texture *t, Core::Material::BlendOperator blend_op, Core::Material::RenderWord render_word)
{
	bool batch_broken = (batch_triangle_count == 0) || (batch_t != t) || (batch_blend_op != blend_op) || (batch_render_word != render_word);

	if	(batch_triangle_count + triangle_count > batch_max_triangle_count)
		batch_broken = true;

	if	(batch_broken)
		Flush();

	// Transfer and fix-up indices.
	for (uint n = 0; n < triangle_count; ++n)
	{
		batch_idx[batch_triangle_count * 3 + 0] = (ushort)(idx[n * 3 + 0] + batch_attrib_offset);
		batch_idx[batch_triangle_count * 3 + 1] = (ushort)(idx[n * 3 + 1] + batch_attrib_offset);
		batch_idx[batch_triangle_count * 3 + 2] = (ushort)(idx[n * 3 + 2] + batch_attrib_offset);
		++batch_triangle_count;
	}

	// Transfer attributes.
	Memory::Copy(&batch_vtx[batch_attrib_offset], vtx, sizeof(Vector4) * attrib_count);
	Memory::Copy(&batch_col[batch_attrib_offset], col, sizeof(Color) * attrib_count);
	Memory::Copy(&batch_uv[batch_attrib_offset], uv, sizeof(Vector2) * attrib_count);
	batch_attrib_offset += attrib_count;

	batch_render_word = render_word;
	batch_blend_op = blend_op;
	batch_t = t;
}
//------------------------------------------------------------------------------

TriangleBatch::TriangleBatch(Renderer &r, uint max) : renderer(r)
{
	batch_t = NULL;
	batch_render_word = Core::Material::Render_None;
	batch_blend_op = Core::Material::Blend_None;

	batch_max_triangle_count = max;
	batch_triangle_count = 0;
	batch_attrib_offset = 0;

	batch_idx.Allocate(3 * batch_max_triangle_count);
	batch_vtx.Allocate(3 * batch_max_triangle_count);
	batch_col.Allocate(3 * batch_max_triangle_count);
	batch_uv.Allocate(3 * batch_max_triangle_count);
}
