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


		#include "squirrel.h"
		#include "binding_helpers.h"
		#include "core/renderer.h"
		#include "core/renderer_toolbox.h"
		#include "core/raster_font.h"
		#include "core/resource_factories.h"
		#include "core/camera.h"
		#include "scene3d/mitem.h"
		#include "script_squirrel/cobject/matrix_decl.h"
		#include <vector>
	#if __PLATFORM_NINTENDO_WII__
		#include "wii_gx/wii_gx.h"
	#endif
		#include "picture/pict.h"
		#include "gpu/gpu_renderer.h"


		using namespace GS;
		using namespace GS::S3D;
		using namespace GS::Script;
		using namespace GS::Render;


//------------------------------------------------------------------------------
SQInteger			RendererRegistrySetKey(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSTRING(key)

	GS::Variant value;

	HSQOBJECT o;
	sq_getstackobj(vm, __SQ_STACKPOS, &o);
	switch (sq_type(o))
	{
		case OT_BOOL:
		{	__SQ_GETBOOL(v)		value = asbool(v);	}	break;
		case OT_INTEGER:
		{	__SQ_GETINT(v)		value = (int)v;		}	break;
		case OT_FLOAT:
		{	__SQ_GETFLOAT(v)	value = v;			}	break;
		case OT_STRING:
		{	__SQ_GETSTRING(s)	value = s;			}	break;

		default:
			break;
	}
	renderer->registry.CreateKey(key, &value);
	__SQ_GETEND
	__SQ_RETURN
}

SQInteger			RendererRegistryGetKey(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSTRING(key)
	__SQ_GETEND

	GS::Variant v;
	if	(NML::Tag *tag = renderer->registry.GetTag(key))
		v = tag->GetValue();
	else
		return sq_throwerror(vm, "Registry key does not exists");

	switch (v.GetType())
	{
		case GS::Variant::VariantBool:		__SQ_RETURNBOOL(v.b_value)
		case GS::Variant::VariantInteger:	__SQ_RETURNINT(v.i_value)
		case GS::Variant::VariantFloat:		__SQ_RETURNFLOAT(v.f_value)
		case GS::Variant::VariantString:	__SQ_RETURNSTRING(v.s_value.c_str())

		default: break;
	}
	return sq_throwerror(vm, "Cannot return this key variant");
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererClearFrame(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETFLOAT(r)
	__SQ_GETFLOAT(g)
	__SQ_GETFLOAT(b)
	__SQ_GETEND
	render->Clear(r, g, b, 1, 10000);
	__SQ_RETURN
}
SQInteger			RendererResetStatistics(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->ResetStatistics();
	__SQ_RETURN
}
SQInteger			RendererGetStatistics(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)

	sq_newtable(vm);

	sq_pushstring(vm, "renderable_drawn", -1);
	sq_pushinteger(vm, render->stats.renderable_drawn);
	sq_newslot(vm, -3, false);

	sq_pushstring(vm, "list_drawn", -1);
	sq_pushinteger(vm, render->stats.list_drawn);
	sq_newslot(vm, -3, false);

	sq_pushstring(vm, "triangle_drawn", -1);
	sq_pushinteger(vm, render->stats.triangle_drawn);
	sq_newslot(vm, -3, false);
	return 1;
}
SQInteger			RendererGetGlobalAspectRatio(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_RETURNFLOAT(render->GetGlobalAspectRatio())
}
SQInteger			RendererSetGlobalAspectRatio(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETFLOAT(ar)
	__SQ_GETEND
	__SQ_RETURNFLOAT(render->SetGlobalAspectRatio(ar))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetOutputTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTRALLOWNULL(texture, Texture, typetag_Texture)
	render->SetOutputTexture(texture);
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			RendererRenderQueue(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->BeginDrawList();
	render->RenderList();
	render->EndDrawList();
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetWorldMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETMATRIX4(m)
	__SQ_GETEND
	render->SetWorldMatrix(m);
	__SQ_RETURN
}
SQInteger			RendererSetIdentityWorldMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererApplyCamera(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->ApplyCamera();
	__SQ_RETURN
}
SQInteger			RendererGetViewMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	if	(render->GetCamera() == NULL)
		return sq_throwerror(vm, "No view item.");
	__SQ_RETURNMATRIX4(render->GetCamera()->GetMatrix())
}
SQInteger			RendererSetViewMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETMATRIX4(m)
	__SQ_GETEND
	render->SetViewMatrix(m);
	__SQ_RETURN
}
SQInteger			RendererSetIdentityViewMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->SetViewMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
	__SQ_RETURN
}
SQInteger			RendererSetViewItemAndApplyView(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(view, MItem, typetag_Item)
	__SQ_GETEND

	if	(view->GetItemType() != Type_Camera)
		return sq_throwerror(vm, "Item is not a camera");
	render->SetCamera((Core::Camera *)(view->GetBaseItem()));
	render->ApplyCamera();

	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetProjectionMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETMATRIX4(m)
	__SQ_GETEND
	render->SetProjectionMatrix(m);
	__SQ_RETURN
}
SQInteger			RendererSetIdentityProjectionMatrix(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->SetProjectionMatrix(Matrix4::IdentityMatrix());
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetAllMatricesToIdentity(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->SetViewMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
	render->SetWorldMatrix(Matrix4::IdentityMatrix(), &Matrix4::IdentityMatrix());
	render->SetProjectionMatrix(Matrix4::IdentityMatrix());
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererGetOutputWindowSize(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	uint w, h;
	render->GetOutputWindow()->GetSize(w, h);
	__SQ_RETURNVECTOR2(Vector2(float(w), float(h)))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererGetOutputDimensions(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	tVector2 <uint>	dimensions = render->GetOutputDimensions();
	__SQ_RETURNVECTOR2(Vector2(float(dimensions.x), float(dimensions.y)))
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetOutputDimensions(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
		__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
		__SQ_GETINT(width)
		__SQ_GETINT(height)

	render->ResizeVideo(width, height);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererSetClipping(HSQUIRRELVM vm)
{
	__SQ_GETSTART(5)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETFLOAT(ox)
	__SQ_GETFLOAT(oy)
	__SQ_GETFLOAT(ex)
	__SQ_GETFLOAT(ey)
	__SQ_GETEND
	tVector2 <uint>	d = render->GetOutputDimensions();
	fRect r(ox * d.x, oy * d.y, ex * d.x, ey * d.y);
	render->SetClippingRect(&r);
	__SQ_RETURN
}
SQInteger			RendererGetViewport(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	tVector2 <uint>	dimensions = render->GetOutputDimensions();
	fRect viewport = render->GetViewport();
	__SQ_RETURNRECT(fRect(viewport.sx / dimensions.x, viewport.sy / dimensions.y, viewport.ex / dimensions.x, viewport.ey / dimensions.y))
}
SQInteger			RendererSetViewport(HSQUIRRELVM vm)
{
	__SQ_GETSTART(5)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETFLOAT(ox)
	__SQ_GETFLOAT(oy)
	__SQ_GETFLOAT(ex)
	__SQ_GETFLOAT(ey)
	__SQ_GETEND
	tVector2 <uint>	d = render->GetOutputDimensions();
	render->SetViewport(fRect(ox * d.x, oy * d.y, ex * d.x, ey * d.y));
	__SQ_RETURN
}
SQInteger			RendererGetScreenViewport(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_RETURNRECT(render->GetViewport())
}
SQInteger			RendererSetScreenViewport(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETFRECT(viewport)
	__SQ_GETEND
	render->SetViewport(viewport);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererDrawTriangle(HSQUIRRELVM vm)
{
	Vector4 vtx[3];
	Color col[3];
	__SQ_GETSTART(9)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTORTOALWAYS(vtx[0])
	__SQ_GETVECTORTOALWAYS(vtx[1])
	__SQ_GETVECTORTOALWAYS(vtx[2])
	__SQ_GETVECTORTOALWAYS(col[0])
	__SQ_GETVECTORTOALWAYS(col[1])
	__SQ_GETVECTORTOALWAYS(col[2])
	__SQ_GETINT(blend)
	__SQ_GETINT(rword)
	__SQ_GETEND
	render->DrawTriangle(1, vtx, 0, col, 0, 0, Core::Material::BlendOperator(blend), Core::Material::RenderWord(rword));
	__SQ_RETURN
}
SQInteger			RendererDrawTriangleTextured(HSQUIRRELVM vm)
{
	Vector4 vtx[3];
	Color col[3];
	Vector2 uv[3];

	__SQ_GETSTART(13)
		__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
		__SQ_GETVECTORTOALWAYS(vtx[0])
		__SQ_GETVECTORTOALWAYS(vtx[1])
		__SQ_GETVECTORTOALWAYS(vtx[2])
		__SQ_GETSAFEPTRALLOWNULL(texture, Texture, typetag_Texture)
	__SQ_GETVECTOR2(uv0);
	uv[0] = uv0;
	__SQ_GETVECTOR2(uv1);
	uv[1] = uv1;
	__SQ_GETVECTOR2(uv2);
	uv[2] = uv2;

//	__SQ_GETUVTO(uv[0])
//	__SQ_GETUVTO(uv[1])
//	__SQ_GETUVTO(uv[2])
	__SQ_GETVECTORTOALWAYS(col[0])
	__SQ_GETVECTORTOALWAYS(col[1])
	__SQ_GETVECTORTOALWAYS(col[2])
	__SQ_GETINT(blend)
	__SQ_GETINT(rword)
	render->DrawTriangle(1, vtx, 0, col, uv, texture, Core::Material::BlendOperator(blend), Core::Material::RenderWord(rword));
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			RendererDrawTriangleShaded(HSQUIRRELVM vm)
{
	Vector4 vtx[3];
	Color col[3];
	Vector2 uv[3];

	__SQ_GETSTART(14)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTORTOALWAYS(vtx[0])
	__SQ_GETVECTORTOALWAYS(vtx[1])
	__SQ_GETVECTORTOALWAYS(vtx[2])
	__SQ_GETSAFEPTRALLOWNULL(texture, Texture, typetag_Texture)
	__SQ_GETUVTO(uv[0])
	__SQ_GETUVTO(uv[1])
	__SQ_GETUVTO(uv[2])
	__SQ_GETVECTORTOALWAYS(col[0])
	__SQ_GETVECTORTOALWAYS(col[1])
	__SQ_GETVECTORTOALWAYS(col[2])
	__SQ_GETINT(blend)
	__SQ_GETINT(rword)
	__SQ_GETSAFEPTR(shader, Shader, typetag_Shader)
	render->DrawTriangle(1, vtx, 0, col, uv, texture, Core::Material::BlendOperator(blend), Core::Material::RenderWord(rword), shader);
	__SQ_GETEND
	__SQ_RETURN
}
SQInteger			RendererDrawCross(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos)
	__SQ_GETEND
	RendererToolbox::DrawCross(*render, pos);
	__SQ_RETURN
}
SQInteger			RendererDrawCrossColored(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos)
	__SQ_GETVECTOR(col)
	__SQ_GETEND
	Color color(col.x, col.y, col.z);
	RendererToolbox::DrawCross(*render, pos, 1, &color);
	__SQ_RETURN
}
SQInteger			RendererDrawLine(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos_a)
	__SQ_GETVECTOR(pos_b)
	__SQ_GETEND
	Vector4 p[2] = { pos_a, pos_b };
	Color c[2] = { Color(1, 1, 1), Color(1, 1, 1) };
	render->DrawLine(1, p, c);
	__SQ_RETURN
}
SQInteger			RendererDrawLineColored(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos_a)
	__SQ_GETVECTOR(pos_b)
	__SQ_GETVECTOR(col)
	__SQ_GETEND
	Vector4 p[2] = { pos_a, pos_b };
	Color c[2] = { col, col };
	render->DrawLine(1, p, c);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
SQInteger			RendererDrawLineEx(HSQUIRRELVM vm)
{
	__SQ_GETSTART(5)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos_a)
	__SQ_GETVECTOR(pos_b)
	__SQ_GETINT(blend)
	__SQ_GETINT(rword)
	__SQ_GETEND
	Vector4 p[2] = { pos_a, pos_b };
	Color c[2] = { Color(1, 1, 1), Color(1, 1, 1) };
	render->DrawLine(1, p, c, (Core::Material::BlendOperator)blend, (Core::Material::RenderWord)rword);
	__SQ_RETURN
}
SQInteger			RendererDrawLineColoredEx(HSQUIRRELVM vm)
{
	__SQ_GETSTART(7)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(pos_a)
	__SQ_GETVECTOR(pos_b)
	__SQ_GETVECTOR(col_a)
	__SQ_GETVECTOR(col_b)
	__SQ_GETINT(blend)
	__SQ_GETINT(rword)
	__SQ_GETEND
	Vector4 p[2] = { pos_a, pos_b };
	Color c[2] = { col_a, col_b };
	render->DrawLine(1, p, c, (Core::Material::BlendOperator)blend, (Core::Material::RenderWord)rword);
	__SQ_RETURN
}
//------------------------------------------------------------------------------

//------------------------------------------------------------------------------
#if		1

SQInteger			RendererSetControlFlag(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETINT(flag)
	__SQ_GETBOOL(set)
	__SQ_GETEND
	__LOG_W__ << "Obsolete function, please use the renderer registry.\n";
	__SQ_RETURN
}
SQInteger			RendererGetControlFlag(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETINT(flag)
	__SQ_GETEND
	__LOG_W__ << "Obsolete function, please use the renderer registry.\n";
	__SQ_RETURNBOOL(false)
}
SQInteger			RendererSetSystemWord(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETINT(flag)
	__SQ_GETBOOL(set)
	__SQ_GETEND
	__LOG_W__ << "Obsolete function, please use the renderer registry.\n";
	__SQ_RETURN
}
SQInteger			RendererGetSystemWord(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETINT(flag)
	__SQ_GETEND
	__LOG_W__ << "Obsolete function, please use the renderer registry.\n";
	__SQ_RETURNBOOL(false)
}

#endif
//------------------------------------------------------------------------------

SQInteger			LoadRasterFont(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(rf, Core::ResourceFactories, typetag_ResourceFactories)
	__SQ_GETSTRING(nml_path)
	__SQ_GETSTRING(map_base_path)
	RasterFont *f = new RasterFont;
	if	(!f || !f->Load(*rf->render, nml_path, map_base_path))
		return sq_throwerror(vm, "Failed to create raster font.");
	__SQ_GETEND
	__SQ_RETURNMANAGEDSAFEPTR(f, typetag_RasterFont)
}
SQInteger			RasterFontGetLineHeight(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(font, RasterFont, typetag_RasterFont)
	__SQ_RETURNFLOAT(font->GetHeight())
}
SQInteger			RasterFontGetBaseline(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(font, RasterFont, typetag_RasterFont)
	__SQ_RETURNFLOAT(font->GetBaseline())
}
SQInteger			RendererRenderQueueReset(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->DeleteRenderableList();
	__SQ_RETURN
}

SQInteger			RendererWrite(HSQUIRRELVM vm)
{
	__SQ_GETSTART(9)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(font, RasterFont, typetag_RasterFont)
	__SQ_GETSTRING(text)
	__SQ_GETFLOAT(x)
	__SQ_GETFLOAT(y)
	__SQ_GETFLOAT(k)
	__SQ_GETBOOL(ar)
	__SQ_GETINT(align)
	__SQ_GETVECTORW(color)

	Renderer::WriterConfig	cfg;
	cfg.correct_ar = asbool(ar);

	Color c(color);
	render->Write(*font, text, x, y, cfg, k, &c, (Renderer::WriterAlignment)align);
	__SQ_GETEND
	__SQ_RETURN
}


SQInteger			RendererWriteMirrored(HSQUIRRELVM vm)
{
	__SQ_GETSTART(9)
		__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
		__SQ_GETSAFEPTR(font, RasterFont, typetag_RasterFont)
		__SQ_GETSTRING(text)
		__SQ_GETFLOAT(x)
		__SQ_GETFLOAT(y)
		__SQ_GETFLOAT(k)
		__SQ_GETBOOL(ar)
		__SQ_GETINT(align)
		__SQ_GETVECTORW(color)

		Renderer::WriterConfig	cfg;
	cfg.correct_ar = asbool(ar);

	Color c(color);
	render->Write(*font, text, x, y, cfg, k, &c, (Renderer::WriterAlignment)align, true);
	__SQ_GETEND
		__SQ_RETURN
}
SQInteger			RendererGrabDisplayToTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(tex, Texture, typetag_Texture)
	__SQ_GETEND
	render->GrabDisplay(tex);
	__SQ_RETURN
}

SQInteger			RendererReadDepthPixels(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	GPU::Renderer *gpu_renderer = dynamic_cast<GPU::Renderer *>(render);

	int w = gpu_renderer->resolve_fbo->depth_texture->GetWidth();
    int h = gpu_renderer->resolve_fbo->depth_texture->GetHeight();

    int count = w * h;

    std::vector<float> buffer(count);
	if(gpu_renderer->gpu_config.enable_aa)
		gpu_renderer->buffer_fbo->ReadDepthPixels(buffer.data());
	else
		gpu_renderer->resolve_fbo->ReadDepthPixels(buffer.data());

	sq_newarray(vm, 0);

    for (int i = 0; i < count; ++i)
    {
        sq_pushfloat(vm, buffer[i]);
        sq_arrayappend(vm, -2);
    }
	return 1;
}

SQInteger			RendererGrabDisplayToPicture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(picture, Picture, typetag_Picture)
	__SQ_GETEND
	render->GrabDisplay(*picture);
	__SQ_RETURN
}

SQInteger			RendererSetClippingPlane(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETVECTOR(p)
	__SQ_GETVECTOR(n)
	__SQ_GETEND
	render->SetClippingPlane(p, n);
	__SQ_RETURN
}
SQInteger			RendererClearClippingPlane(HSQUIRRELVM vm)
{
	__SQ_GETSINGLESAFEPTR(render, Renderer, typetag_Renderer)
	render->ClearClippingPlane();
	__SQ_RETURN
}

SQInteger			RendererTextureUpdate(HSQUIRRELVM vm)
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(t, Texture, typetag_Texture)
	__SQ_GETSAFEPTR(p, Picture, typetag_Picture)
	if	((t->GetWidth() != p->GetWidth()) || (t->GetHeight() != p->GetHeight()))
			t->Create((const char *)p->GetData(), p->GetWidth(), p->GetHeight());
	else	t->Blit((const char *)p->GetData(), p->GetWidth(), p->GetHeight());
	__SQ_GETEND
	__SQ_RETURN
}

//---------------------------------------
SQInteger			RendererSetFullScreen(HSQUIRRELVM vm)
//---------------------------------------
{
	__SQ_GETSTART(2)
	__SQ_GETSAFEPTR(render, Renderer, typetag_Renderer)
	__SQ_GETBOOL(fullscreen)
	__SQ_GETEND
		render->SetFullscreen(fullscreen);
	__SQ_RETURN
}

//------------------------------------------------------------------------------
// Spline and render-to-texture bindings
//------------------------------------------------------------------------------
SQInteger			RendererCreateRenderTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(4)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSTRING(name)
	__SQ_GETINT(width)
	__SQ_GETINT(height)
	__SQ_GETEND

	GPU::Renderer *gpu_renderer = dynamic_cast<GPU::Renderer *>(renderer);
	if (!gpu_renderer)
		return sq_throwerror(vm, "Renderer is not a GPU renderer");

	Render::Texture *tex = gpu_renderer->CreateRenderTexture(name, width, height);
	if (tex)
		__SQ_RETURNSAFEPTR(tex, typetag_Texture)
	else
		return sq_throwerror(vm, "Failed to create render texture");
}

SQInteger			RendererClearTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(6)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(tex, Render::Texture, typetag_Texture)
	__SQ_GETFLOAT(r)
	__SQ_GETFLOAT(g)
	__SQ_GETFLOAT(b)
	__SQ_GETFLOAT(a)
	__SQ_GETEND

	GPU::Renderer *gpu_renderer = dynamic_cast<GPU::Renderer *>(renderer);
	if (!gpu_renderer)
		return sq_throwerror(vm, "Renderer is not a GPU renderer");

	__LOG_W__ << "Received clear with color: " << r << "," << g << "," << b << "," << a << "\n";
	gpu_renderer->ClearTexture(tex, Color(r, g, b, a));

	__SQ_RETURN
}

SQInteger			RendererBlitTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(3)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(dst, Render::Texture, typetag_Texture)
	__SQ_GETSAFEPTR(src, Render::Texture, typetag_Texture)
	__SQ_GETEND

	GPU::Renderer *gpu_renderer = dynamic_cast<GPU::Renderer *>(renderer);
	if (!gpu_renderer)
		return sq_throwerror(vm, "Renderer is not a GPU renderer");

	gpu_renderer->BlitTextureToTexture(src, dst);
	__SQ_RETURN
}

SQInteger			RendererDrawSplineToTexture(HSQUIRRELVM vm)
{
	__SQ_GETSTART(15)
	__SQ_GETSAFEPTR(renderer, Renderer, typetag_Renderer)
	__SQ_GETSAFEPTR(tex, Render::Texture, typetag_Texture)

	__LOG_W__ << "Reading points array...\n";

	GPU::Renderer *gpu_renderer = dynamic_cast<GPU::Renderer *>(renderer);
	if (!gpu_renderer)
		return sq_throwerror(vm, "Renderer is not a GPU renderer");

	__LOG_W__ << "Getting points...\n";

	// Get array of points - manually since it's an array
	HSQOBJECT arr_obj;
	sq_getstackobj(vm, __sq_stackpos, &arr_obj);
	if (sq_type(arr_obj) != OT_ARRAY)
		return sq_throwerror(vm, "Points must be an array");
	__SQ_GETUPDATESTACK

	__LOG_W__ << "Filling points...\n";

	Array<Vector2> points;
	sq_pushobject(vm, arr_obj);
	SQInteger arr_size = sq_getsize(vm, -1);
	points.Allocate((uint)arr_size);

	//__LOG_W__ << "Array size: " << arr_size << "\n";

	for (SQInteger i = 0; i < arr_size; i++)
	{
		sq_pushinteger(vm, i);
		sq_get(vm, -2);

		if (sq_gettype(vm, -1) != OT_ARRAY)
		{
			sq_pop(vm, 2);
			return sq_throwerror(vm, "Each point must be [x,y] array");
		}

		sq_pushinteger(vm, 0);
		sq_get(vm, -2);
		SQFloat x;
		sq_getfloat(vm, -1, &x);
		sq_pop(vm, 1);

		sq_pushinteger(vm, 1);
		sq_get(vm, -2);
		SQFloat y;
		sq_getfloat(vm, -1, &y);
		sq_pop(vm, 2);

		points[(uint)i] = Vector2(x, y);
	}
	sq_pop(vm, 1);

	__LOG_W__ << "Got " << points.GetCount() << " points.\n";

	__SQ_GETFLOAT(width)

	__SQ_GETFLOAT(r)
	__SQ_GETFLOAT(g)
	__SQ_GETFLOAT(b)
	__SQ_GETFLOAT(a)

	__SQ_GETFLOAT(rBorder)
	__SQ_GETFLOAT(gBorder)
	__SQ_GETFLOAT(bBorder)
	__SQ_GETFLOAT(aBorder)

	__SQ_GETFLOAT(borderWidth)

	__SQ_GETFLOAT(margin)

	__SQ_GETBOOL(clear)

	__SQ_GETEND

	if (!tex)
	{
		__LOG_E__ << "ERROR: Texture is NULL!\n";
		return sq_throwerror(vm, "Target texture is null");
	}

	const auto borderColor = Color(rBorder, gBorder, bBorder, aBorder);
	gpu_renderer->DrawSplineToTexture(
		tex,
		points,
		width,
		Color(r, g, b, a),
		16,    // samples per segment
		clear, // don't clear - preserve existing content (composit mode)
		true,   // soft edge
		&borderColor,
		borderWidth,
		margin
	);

	__LOG_W__ << "DrawSplineToTexture call completed successfully!\n";

	__SQ_RETURN
}

//---------------------------------------------------------
void				RegisterRendererBinding(HSQUIRRELVM vm)
//---------------------------------------------------------
{
/*#
	Topic: Renderer
	Type: Renderer
	Type: RasterFont
#*/

/*#
	Section: RendererRegistry
	Desc: Renderer registry functions.
#*/
	/*#
		Func: RendererRegistrySetKey
		Proto: void:Renderer,string key,value
		Desc: Set renderer registry key value.
	#*/
	sq_register(vm, RendererRegistrySetKey, "RendererRegistrySetKey", _SC(".xs."));
	/*#
		Func: RendererRegistryGetKey
		Proto: value:Renderer,string key
		Desc: Get renderer registry key value.
	#*/
	sq_register(vm, RendererRegistryGetKey, "RendererRegistryGetKey", _SC(".xs"));

/*#
	Section: RenderResource
	Desc: Render resource functions
#*/
	/*#
		Func: RendererTextureUpdate
		Proto: void:Texture,Picture
		Desc: Update texture from a picture, valid all changes to the renderer texture memory.
	#*/
	sq_register(vm, RendererTextureUpdate, "RendererTextureUpdate", _SC(".xx"));

/*#
	Section: RenderViewport
	Desc: Viewport functions
#*/
	/*#
		Func: RendererGetGlobalAspectRatio
		Proto: float:void
		Desc: Get renderer global aspect ratio correction.
	#*/
	sq_register(vm, RendererGetGlobalAspectRatio, "RendererGetGlobalAspectRatio", _SC(".x"));
	/*#
		Func: RendererSetGlobalAspectRatio
		Proto: float:float
		Desc: Set renderer global aspect ratio correction, returns the previous value.
	#*/
	sq_register(vm, RendererSetGlobalAspectRatio, "RendererSetGlobalAspectRatio", _SC(".xn"));
	/*#
		Func: RendererSetViewItemAndApplyView
		Proto: void:renderer,item
		Desc: Change view item.
	#*/
	sq_register(vm, RendererSetViewItemAndApplyView, "RendererSetViewItemAndApplyView", _SC(".xx"));

	/*#
		Func: RendererSetWorldMatrix
		Proto: void:Renderer,Matrix4
		Desc: Set the renderer current world matrix.
	#*/
	sq_register(vm, RendererSetWorldMatrix, "RendererSetWorldMatrix", _SC(".xx"));
	/*#
		Func: RendererSetIdentityWorldMatrix
		Proto: void:Renderer
		Desc: Set the renderer current world matrix as the identity matrix.
	#*/
	sq_register(vm, RendererSetIdentityWorldMatrix, "RendererSetIdentityWorldMatrix", _SC(".x"));

	/*#
		Func: RendererApplyCamera
		Proto: void:Renderer
		Desc: Set the renderer view and projection matrices from the current camera.
	#*/
	sq_register(vm, RendererApplyCamera, "RendererApplyCamera", _SC(".x"));
	/*#
		Func: RendererGetViewMatrix
		Proto: Matrix4:Renderer
		Desc: Get the renderer current view matrix.
	#*/
	sq_register(vm, RendererGetViewMatrix, "RendererGetViewMatrix", _SC(".x"));
	/*#
		Func: RendererSetViewMatrix
		Proto: void:Renderer,Matrix4
		Desc: Set the renderer current view matrix.
	#*/
	sq_register(vm, RendererSetViewMatrix, "RendererSetViewMatrix", _SC(".xx"));
	/*#
		Func: RendererSetIdentityViewMatrix
		Proto: void:Renderer
		Desc: Set the renderer current view matrix as the identity matrix.
	#*/
	sq_register(vm, RendererSetIdentityViewMatrix, "RendererSetIdentityViewMatrix", _SC(".x"));
	/*#
		Func: RendererSetProjectionMatrix
		Proto: void:Renderer,Matrix4
		Desc: Set the renderer current projection matrix.
	#*/
	sq_register(vm, RendererSetProjectionMatrix, "RendererSetProjectionMatrix", _SC(".xx"));
	/*#
		Func: RendererSetIdentityProjectionMatrix
		Proto: void:Renderer
		Desc: Set the renderer current projection matrix as the identity matrix.
	#*/
	sq_register(vm, RendererSetIdentityProjectionMatrix, "RendererSetIdentityProjectionMatrix", _SC(".x"));
	/*#
		Func: RendererSetAllMatricesToIdentity
		Proto: void:Renderer
		Desc: Set all renderer drawing matrices to the identity matrix.
	#*/
	sq_register(vm, RendererSetAllMatricesToIdentity, "RendererSetAllMatricesToIdentity", _SC(".x"));

	/*#
		Func: RendererSetClipping
		Proto: void:Renderer renderer,float start_x,float start_y,float end_x,float end_y
		Desc: Set clipping rect in normalized coordinates.
	#*/
	sq_register(vm, RendererSetClipping, "RendererSetClipping", _SC(".xnnnn"));

	/*#
		Func: RendererSetFullScreen
		Proto: void:Renderer renderer,bool
		Desc: Set the fullscreen.
		See: RendererGetOutputDimensions
	#*/
	sq_register(vm, RendererSetFullScreen, "RendererSetFullScreen", _SC(".xb"));
	/*#
		Func: RendererSetScreenViewport
		Proto: void:Renderer renderer,Rect viewport
		Desc: Set the renderer viewport in screen coordinates.
		See: RendererGetOutputDimensions
		Example:
// Set a fullscreen viewport.
local d = RendererGetOutputDimensions(g_render)
RendererSetScreenViewport(g_render, Rect(0, 0, d.x, d.y))
	#*/
	sq_register(vm, RendererSetScreenViewport, "RendererSetScreenViewport", _SC(".xx"));
	/*#
		Func: RendererGetScreenViewport
		Proto: Rect:Renderer renderer
		Desc: Return the current viewport rect in screen coordinates.
		Example:
local viewport = RendererGetScreenViewport(g_render)
print("Viewport size: " + viewport.GetWidth() + "x" + viewport.GetHeight())		// will return the current output dimensions
	#*/
	sq_register(vm, RendererGetViewport, "RendererGetViewport", _SC(".x"));

	/*#
		Func: RendererSetViewport
		Proto: void:Renderer renderer,float start_x,float start_y,float end_x,float end_y
		Desc: Set the renderer viewport in normalized coordinates.
		See: RendererGetOutputDimensions
		Example:
// Set a fullscreen viewport.
RendererSetViewport(g_render, 0, 0, 1, 1)
	#*/
	sq_register(vm, RendererSetViewport, "RendererSetViewport", _SC(".xnnnn"));
	/*#
		Func: RendererGetViewport
		Proto: Rect:Renderer renderer
		Desc: Return the current viewport rectangle in normalized coordinates.
		See: RendererGetOutputDimensions
		Example:
local viewport = RendererGetViewport(g_render)
print("Viewport size: " + viewport.GetWidth() + "x" + viewport.GetHeight())		// default: 1.0x1.0
	#*/
	sq_register(vm, RendererGetViewport, "RendererGetViewport", _SC(".x"));

	/*#
		Func: RendererGetOutputDimensions
		Proto: Vector2:Renderer renderer
		Desc: Get the renderer output dimensions in pixels.
	#*/
	sq_register(vm, RendererGetOutputDimensions, "RendererGetOutputDimensions", _SC(".x"));
	/*#
	Func: RendererSetOutputDimensions
	Proto: void:Renderer renderer, int width, int height
	Desc: Set the renderer output dimensions in pixels.
	#*/
	sq_register(vm, RendererSetOutputDimensions, "RendererSetOutputDimensions", _SC(".xii"));

	/*#
		Func: RendererGetOutputWindowSize
		Proto: Vector2:Renderer renderer
		Desc: Get the renderer output dimensions in pixels.
	#*/
	sq_register(vm, RendererGetOutputWindowSize, "RendererGetOutputWindowSize", _SC(".x"));
	/*#
		Func: RendererSetClippingPlane
		Proto: void:renderer,Vector p,Vector n
		Desc: Set user clipping plane.
	#*/
	sq_register(vm, RendererSetClippingPlane, "RendererSetClippingPlane", _SC(".xxx"));
	/*#
		Func: RendererClearClippingPlane
		Proto: void:renderer
		Desc: Clear the user clipping plane.
	#*/
	sq_register(vm, RendererClearClippingPlane, "RendererClearClippingPlane", _SC(".x"));
	/*#
		Func: RendererClearFrame
		Proto: void:scene,float r,float g,float b
		Desc: Clear viewport with a normalized float color.
	#*/
	sq_register(vm, RendererClearFrame, "RendererClearFrame", _SC(".xnnn"));
	/*#
		Func: RendererSetOutputTexture
		Proto: void:renderer,texture
		Desc: Set output texture.
	#*/
	sq_register(vm, RendererSetOutputTexture, "RendererSetOutputTexture", _SC(".xx"));

/*#
	Section: RenderRender
	Desc: Rendering functions
#*/
	/*#
		Func: RendererRenderQueue
		Proto: void:renderer
		Desc: Render queue.
	#*/
	sq_register(vm, RendererRenderQueue, "RendererRenderQueue", _SC(".x"));
	/*#
		Func: RendererRenderQueueReset
		Proto: void:renderer
		Desc: Empty the renderer render queue.
		Note: This is not done automatically so that you may render several viewpoints using the same render queue.
	#*/
	sq_register(vm, RendererRenderQueueReset, "RendererRenderQueueReset", _SC(".x"));
	/*#
		Func: RendererDrawCross
		Proto: void:renderer,vector origin
		Desc: Draw a 3d cross.
	#*/
	sq_register(vm, RendererDrawCross, "RendererDrawCross", _SC(".xx"));
	/*#
		Func: RendererDrawTriangle
		Proto: void:Renderer,Vector v0,Vector v1,Vector v2,Color c0,Color c1,Color c2,MaterialBlendOperator blend_operator,MaterialRenderWord render_word
		Desc: Draw a triangle.
		Note: The triangle will be transformed by the current world, view and projection matrices.
	#*/
	sq_register(vm, RendererDrawTriangle, "RendererDrawTriangle", _SC(".xxxxxxxii"));
	/*#
		Func: RendererDrawTriangleTextured
		Proto: void:Renderer,Vector v0,Vector v1,Vector v2,Texture,UV uv0,UV uv1,UV uv2,Color c0,Color c1,Color c2,MaterialBlendOperator blend_operator,MaterialRenderWord render_word
		Desc: Draw a textured triangle.
		Note: The triangle will be transformed by the current world, view and projection matrices.
	#*/
	sq_register(vm, RendererDrawTriangleTextured, "RendererDrawTriangleTextured", _SC(".xxxxxxxxxxxii"));
	/*#
		Func: RendererDrawTriangleShaded
		Proto: void:Renderer,Vector v0,Vector v1,Vector v2,Texture,UV uv0,UV uv1,UV uv2,Color c0,Color c1,Color c2,MaterialBlendOperator blend_operator,MaterialRenderWord render_word,Shader shader
		Desc: Draw a triangle using a specific shader.
		Note: The triangle will be transformed by the current world, view and projection matrices.
	#*/
	sq_register(vm, RendererDrawTriangleShaded, "RendererDrawTriangleShaded", _SC(".xxxxxxxxxxxiix"));

	/*#
		Func: RendererDrawLine
		Proto: void:renderer,vector start,vector end
		Desc: Draw a line.
		See: RendererDrawLineEx
		Note: The line will be transformed by the current world, view and projection matrices.
		Example:
// Work in world space, set identity matrix as the world matrix.
RendererSetWorldMatrix(g_renderer, Matrix4())

// Draw single line along the X axis from the origin.
RendererDrawLine(g_render, Vector(0, 0, 0), Vector(1, 0, 0))
	#*/
	sq_register(vm, RendererDrawLine, "RendererDrawLine", _SC(".xxx"));
	/*#
		Func: RendererDrawCrossColored
		Proto: void:renderer,vector origin,color
		Desc: Draw a 3d colored cross.
	#*/
	sq_register(vm, RendererDrawCrossColored, "RendererDrawCrossColored", _SC(".xxx"));
	/*#
		Func: RendererDrawLineColored
		Proto: void:renderer,vector start,vector end,color
		Desc: Draw a colored line.
		See: RendererDrawLineColoredEx
	#*/
	sq_register(vm, RendererDrawLineColored, "RendererDrawLineColored", _SC(".xxxx"));
	/*#
		Func: RendererDrawLineEx
		Proto: void:renderer,vector start,vector end,MaterialBlendOperator blend_operator,MaterialRenderWord render_word
		Desc: Draw a line specifying the blend operator and material render word to use.
	#*/
	sq_register(vm, RendererDrawLineEx, "RendererDrawLineEx", _SC(".xxxii"));
	/*#
		Func: RendererDrawLineColoredEx
		Proto: void:renderer,vector start,vector end,Color start,Color end,MaterialBlendOperator blend_operator,MaterialRenderWord render_word
		Desc: Draw a colored line specifying the blend operator and material render word to use.
	#*/
	sq_register(vm, RendererDrawLineColoredEx, "RendererDrawLineColoredEx", _SC(".xxxxxii"));

/*#
	Section: RenderWriter
	Desc: Raster writer functions
#*/
	/*#
		Func: LoadRasterFont
		Proto: RasterFont:RenderResourceFactory,String description_path,String texture_base_path
		Desc: Load a font for the raster-based renderer writer.
		Note: Raster fonts can be created by using the tool found in the GameStart Editor Tools menu.
		Example:
local raster_font = LoadRasterFont(g_factory, "@core/fonts/profiler_base.nml", "@core/fonts/profiler_base")
	#*/
	sq_register(vm, LoadRasterFont, "LoadRasterFont", _SC(".xss"));
	/*#
		Func: RendererWrite
		Proto: void:renderer,RasterFont font,string text,float x,float y,float scale,bool correct_aspect_ratio,WriterAlign alignment,vector rgba
		Desc: Write a text using the raster-based writer.
		Note: The writer output primitives will be transformed by the current world, view and projection matrices.
		See: LoadRasterFont
		Example:
RendererWrite(g_render, raster_font, "Some text", 0.5, 0.5, 1, true, WriterAlignMiddle, Vector(1, 1, 1))
	#*/
	sq_register(vm, RendererWrite, "RendererWrite", _SC(".xxsnnnbix"));

	/*#
		Func: RendererWriteMirrored
		Proto: void:renderer,RasterFont font,string text,float x,float y,float scale,bool correct_aspect_ratio,WriterAlign alignment,vector rgba
		Desc: Write a text using the raster-based writer.
		Note: The writer output primitives will be transformed by the current world, view and projection matrices.
		See: LoadRasterFont
		Example:
RendererWriteMirrored(g_render, raster_font, "Some text", 0.5, 0.5, 1, true, WriterAlignMiddle, Vector(1, 1, 1))
	#*/
	sq_register(vm, RendererWriteMirrored, "RendererWriteMirrored", _SC(".xxsnnnbix"));
	/*#
		Func: RasterFontGetLineHeight
		Proto: float:RasterFont
		Desc: Return the raster font line height.
	#*/
	sq_register(vm, RasterFontGetLineHeight, "RasterFontGetLineHeight", _SC(".x"));
	/*#
		Func: RasterFontGetBaseline
		Proto: float:RasterFont
		Desc: Return the raster font baseline.
	#*/
	sq_register(vm, RasterFontGetBaseline, "RasterFontGetBaseline", _SC(".x"));

/*#
	Section: RenderObsolete
	Desc: Obsolete functions
#*/

#if	1
	/*#
		Func: RendererSetControlWord
		Proto: void:renderer,RendererControlWord,bool set
		Desc: Set renderer control word.
	#*/
	sq_register(vm, RendererSetControlFlag, "RendererSetControlFlag", _SC(".xib"));
	sq_register(vm, RendererSetControlFlag, "RendererSetControlWord", _SC(".xib"));
	/*#
		Func: RendererGetControlWord
		Proto: bool:renderer,RendererControlWord
		Desc: Get renderer control word.
	#*/
	sq_register(vm, RendererGetControlFlag, "RendererGetControlFlag", _SC(".xi"));
	sq_register(vm, RendererGetControlFlag, "RendererGetControlWord", _SC(".xi"));
	/*#
		Func: RendererSetSystemWord
		Proto: void:Renderer,RendererSystemWord,bool set
		Desc: Set renderer system word.
	#*/
	sq_register(vm, RendererSetSystemWord, "RendererSetSystemWord", _SC(".xib"));
	/*#
		Func: RendererGetSystemWord
		Proto: bool:Renderer,RendererSystemWord
		Desc: Get renderer system word.
	#*/
	sq_register(vm, RendererGetSystemWord, "RendererGetSystemWord", _SC(".xi"));
#endif

/*#
	Section: RenderDebug
	Desc: Debugging functions
#*/
	/*#
		Func: RendererGetStatistics
		Proto: void:renderer
		Desc: Return a renderer statistic object.
	#*/
	sq_register(vm, RendererGetStatistics, "RendererGetStatistics", _SC(".x"));
	/*#
		Func: RendererResetStatistics
		Proto: void:renderer
		Desc: Reset internal statistic object.
	#*/
	sq_register(vm, RendererResetStatistics, "RendererResetStatistics", _SC(".x"));

	/*#
		Func: RendererGrabDisplayToPicture
		Proto: void:Renderer,Picture
		Desc: Grab the renderer frame buffer to a picture.
	#*/
	sq_register(vm, RendererGrabDisplayToPicture, "RendererGrabDisplayToPicture", _SC(".xx"));

	/*#
		Func: RendererGrabDisplayToTexture
		Proto: void:Renderer,Texture
		Desc: Grab the renderer frame buffer to a texture.
	#*/
	sq_register(vm, RendererGrabDisplayToTexture, "RendererGrabDisplayToTexture", _SC(".xx"));
	sq_register(vm, RendererReadDepthPixels, "RendererReadDepthPixels", _SC(".x"));

	sq_pushroottable(vm);

	/*#
		Enum: MaterialBlendOperator
		Values: MaterialBlendNone,MaterialBlendAdd,MaterialBlendAlpha
	#*/
	using Core::Material;

	sq_pushstring(vm, "MaterialBlendNone", -1); sq_pushinteger(vm, Material::Blend_None); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "MaterialBlendAdd", -1); sq_pushinteger(vm, Material::Blend_Add); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "MaterialBlendAlpha", -1); sq_pushinteger(vm, Material::Blend_Alpha); sq_newslot(vm, -3, true);

	/*#
		Enum: MaterialRenderWord
		Values: MaterialRenderNone,MaterialRenderDoubleSided,MaterialRenderNoZWrite,MaterialRenderNoZTest
	#*/
	sq_pushstring(vm, "MaterialRenderNone", -1); sq_pushinteger(vm, Material::Render_None); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "MaterialRenderDoubleSided", -1); sq_pushinteger(vm, Material::Render_DoubleSided); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "MaterialRenderNoZWrite", -1); sq_pushinteger(vm, Material::Render_NoZWrite); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "MaterialRenderNoZTest", -1); sq_pushinteger(vm, Material::Render_NoZTest); sq_newslot(vm, -3, true);

#if	1
	sq_pushstring(vm, "MaterialRenderDefault", -1); sq_pushinteger(vm, Material::Render_None); sq_newslot(vm, -3, true);

	/*#
		Enum: RendererSystemWord
		Values: RenderVSync
	#*/
	sq_pushstring(vm, "RenderVSync", -1); sq_pushinteger(vm, 0); sq_newslot(vm, -3, true);

	/*#
		Enum: RendererControlWord
		Values: RenderMotionBlur,RenderShadowMapping,RenderBloom,RenderDepthOfField
	#*/
	sq_pushstring(vm, "RenderMotionBlur", -1); sq_pushinteger(vm, 0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "RenderShadowMapping", -1); sq_pushinteger(vm, 0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "RenderBloom", -1); sq_pushinteger(vm, 0); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "RenderDepthOfField", -1); sq_pushinteger(vm, 0); sq_newslot(vm, -3, true);
#endif

	/*#
		Enum: WriterAlign
		Values: WriterAlignLeft,WriterAlignRight,WriterAlignMiddle
	#*/
	sq_pushstring(vm, "WriterAlignLeft", -1); sq_pushinteger(vm, Renderer::AlignLeft); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WriterAlignRight", -1); sq_pushinteger(vm, Renderer::AlignRight); sq_newslot(vm, -3, true);
	sq_pushstring(vm, "WriterAlignMiddle", -1); sq_pushinteger(vm, Renderer::AlignMiddle); sq_newslot(vm, -3, true);

/*#
	Section: RendererSpline
	Desc: Spline and render-to-texture functions
#*/
	/*#
		Func: RendererCreateRenderTexture
		Proto: Texture:Renderer,string name,int width,int height
		Desc: Create a new render-target texture (can be rendered to).
	#*/
	sq_register(vm, RendererCreateRenderTexture, "RendererCreateRenderTexture", _SC(".xsii"));
	/*#
		Func: RendererClearTexture
		Proto: void:Renderer,Texture,float r,float g,float b,float a
		Desc: Clear a texture with a solid color (RGBA values 0..1).
	#*/
	sq_register(vm, RendererClearTexture, "RendererClearTexture", _SC(".xxffff"));
	/*#
		Func: RendererBlitTexture
		Proto: void:Renderer,Texture dst,Texture src
		Desc: Copy source texture to destination texture.
	#*/
	sq_register(vm, RendererBlitTexture, "RendererBlitTexture", _SC(".xxx"));
	/*#
		Func: RendererDrawSplineToTexture
		Proto: void:Renderer,Texture,array points,float width,float r,float g,float b,float a,
		       float rBorder,float gBorder,float bBorder,float aBorder,float margin,bool clear
		Desc: Draw an interpolated spline (Catmull-Rom) on a texture with given width (pixels) and color.
		      Points array format: [[x1,y1], [x2,y2], ...] in normalized coords [0..1].
		      Example: RendererDrawSplineToTexture(renderer, tex, [[0.1,0.1], [0.5,0.8], [0.9,0.2]], 10.0, 1.0, 0.0, 0.0, 1.0,
		                                         0.0, 0.0, 0.0, 1.0, 2.0, true)
	#*/
	sq_register(vm, RendererDrawSplineToTexture, "RendererDrawSplineToTexture", _SC(".xxafffffffffffb"));

	sq_pop(vm, 1);
}
