diff --git a/examples/00-helloworld/helloworld.cpp b/examples/00-helloworld/helloworld.cpp
index c78feec6..61b6f82e 100644
--- a/examples/00-helloworld/helloworld.cpp
+++ b/examples/00-helloworld/helloworld.cpp
@@ -14,7 +14,7 @@ void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
@@ -45,6 +45,9 @@ int _main_(int _argc, char** _argv)
 		// Advance to next frame. Rendering thread will be kicked to 
 		// process submitted rendering primitives.
 		bgfx::frame();
+
+		extern void emscripten_yield();
+		emscripten_yield();
 	}
 
 	// Shutdown bgfx.
diff --git a/examples/01-cubes/cubes.cpp b/examples/01-cubes/cubes.cpp
index 5c70af6c..ca6f697a 100644
--- a/examples/01-cubes/cubes.cpp
+++ b/examples/01-cubes/cubes.cpp
@@ -90,17 +90,16 @@ static const bgfx::Memory* load(const char* _filePath)
 	return NULL;
 }
 
-static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
+static const bgfx::Memory* loadShader(const char* _name)
 {
 	char filePath[512];
 	shaderFilePath(filePath, _name);
-	BX_UNUSED(_default);
 	return load(filePath);
 }
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
diff --git a/examples/01-cubes/makefile b/examples/01-cubes/makefile
index 900aad91..3d8f5374 100644
--- a/examples/01-cubes/makefile
+++ b/examples/01-cubes/makefile
@@ -7,3 +7,10 @@ BGFX_DIR=../..
 RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
 
 include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/01-cubes/varying.def.sc b/examples/01-cubes/varying.def.sc
index a1490b97..09ee1273 100644
--- a/examples/01-cubes/varying.def.sc
+++ b/examples/01-cubes/varying.def.sc
@@ -1,4 +1,4 @@
 vec4 v_color0    : COLOR0    = vec4(1.0, 0.0, 0.0, 1.0);
 
 vec3 a_position  : POSITION;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
diff --git a/examples/01-cubes/vs_cubes.sc b/examples/01-cubes/vs_cubes.sc
index c6c90901..d17dc4e6 100644
--- a/examples/01-cubes/vs_cubes.sc
+++ b/examples/01-cubes/vs_cubes.sc
@@ -1,4 +1,4 @@
-$input a_position, a_color
+$input a_position, a_color0
 $output v_color0
 
 /*
@@ -11,5 +11,5 @@ $output v_color0
 void main()
 {
 	gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
-	v_color0 = a_color;
+	v_color0 = a_color0;
 }
diff --git a/examples/02-metaballs/makefile b/examples/02-metaballs/makefile
index 900aad91..3d8f5374 100644
--- a/examples/02-metaballs/makefile
+++ b/examples/02-metaballs/makefile
@@ -7,3 +7,10 @@ BGFX_DIR=../..
 RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
 
 include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/02-metaballs/metaballs.cpp b/examples/02-metaballs/metaballs.cpp
index 7d95298c..5fdfc0f1 100644
--- a/examples/02-metaballs/metaballs.cpp
+++ b/examples/02-metaballs/metaballs.cpp
@@ -75,11 +75,10 @@ static const bgfx::Memory* load(const char* _filePath)
 	return NULL;
 }
 
-static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
+static const bgfx::Memory* loadShader(const char* _name)
 {
 	char filePath[512];
 	shaderFilePath(filePath, _name);
-	BX_UNUSED(_default);
 	return load(filePath);
 }
 
@@ -500,7 +499,7 @@ uint32_t triangulate(uint8_t* _result, uint32_t _stride, const float* __restrict
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
diff --git a/examples/02-metaballs/varying.def.sc b/examples/02-metaballs/varying.def.sc
index 9c054574..6e25c36a 100644
--- a/examples/02-metaballs/varying.def.sc
+++ b/examples/02-metaballs/varying.def.sc
@@ -3,4 +3,4 @@ vec4 v_color0    : COLOR0    = vec4(1.0, 0.0, 0.0, 1.0);
 
 vec3 a_position  : POSITION;
 vec3 a_normal    : NORMAL;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
diff --git a/examples/02-metaballs/vs_metaballs.sc b/examples/02-metaballs/vs_metaballs.sc
index 278cf9bf..8a54fb83 100644
--- a/examples/02-metaballs/vs_metaballs.sc
+++ b/examples/02-metaballs/vs_metaballs.sc
@@ -1,4 +1,4 @@
-$input a_position, a_normal, a_color
+$input a_position, a_normal, a_color0
 $output v_normal, v_color0
 
 /*
@@ -12,5 +12,5 @@ void main()
 {
 	gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
 	v_normal = mul(u_model, vec4(a_normal, 0.0) ).xyz;
-	v_color0 = a_color;
+	v_color0 = a_color0;
 }
diff --git a/examples/03-raymarch/makefile b/examples/03-raymarch/makefile
index 900aad91..3d8f5374 100644
--- a/examples/03-raymarch/makefile
+++ b/examples/03-raymarch/makefile
@@ -7,3 +7,10 @@ BGFX_DIR=../..
 RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
 
 include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/03-raymarch/raymarch.cpp b/examples/03-raymarch/raymarch.cpp
index e9d4686e..51359f38 100644
--- a/examples/03-raymarch/raymarch.cpp
+++ b/examples/03-raymarch/raymarch.cpp
@@ -65,11 +65,10 @@ static const bgfx::Memory* load(const char* _filePath)
 	return NULL;
 }
 
-static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
+static const bgfx::Memory* loadShader(const char* _name)
 {
 	char filePath[512];
 	shaderFilePath(filePath, _name);
-	BX_UNUSED(_default);
 	return load(filePath);
 }
 
@@ -179,7 +178,7 @@ void renderScreenSpaceQuad(uint32_t _view, bgfx::ProgramHandle _program, float _
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
@@ -231,9 +230,9 @@ int _main_(int _argc, char** _argv)
 	s_PosColorTexCoord0Decl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
 	s_PosColorTexCoord0Decl.end();  
 
-	bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::ConstantType::Uniform1f);
-	bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::ConstantType::Uniform4x4fv);
-	bgfx::UniformHandle u_lightDir = bgfx::createUniform("u_lightDir", bgfx::ConstantType::Uniform3fv);
+	bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
+	bgfx::UniformHandle u_mtx = bgfx::createUniform("u_mtx", bgfx::UniformType::Uniform4x4fv);
+	bgfx::UniformHandle u_lightDir = bgfx::createUniform("u_lightDir", bgfx::UniformType::Uniform3fv);
 
 	bgfx::ProgramHandle raymarching = loadProgram("vs_raymarching", "fs_raymarching");
 
diff --git a/examples/03-raymarch/varying.def.sc b/examples/03-raymarch/varying.def.sc
index 803835f8..fc051911 100644
--- a/examples/03-raymarch/varying.def.sc
+++ b/examples/03-raymarch/varying.def.sc
@@ -2,5 +2,5 @@ vec4 v_color0    : COLOR0    = vec4(1.0, 0.0, 0.0, 1.0);
 vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
 
 vec3 a_position  : POSITION;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
 vec2 a_texcoord0 : TEXCOORD0;
diff --git a/examples/03-raymarch/vs_raymarching.sc b/examples/03-raymarch/vs_raymarching.sc
index a832c83e..d7b39a4c 100644
--- a/examples/03-raymarch/vs_raymarching.sc
+++ b/examples/03-raymarch/vs_raymarching.sc
@@ -1,4 +1,4 @@
-$input a_position, a_color, a_texcoord0
+$input a_position, a_color0, a_texcoord0
 $output v_color0, v_texcoord0
 
 /*
@@ -11,6 +11,6 @@ $output v_color0, v_texcoord0
 void main()
 {
 	gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
-	v_color0 = a_color;
+	v_color0 = a_color0;
 	v_texcoord0 = a_texcoord0;
 }
diff --git a/examples/04-mesh/makefile b/examples/04-mesh/makefile
index 900aad91..3d8f5374 100644
--- a/examples/04-mesh/makefile
+++ b/examples/04-mesh/makefile
@@ -7,3 +7,10 @@ BGFX_DIR=../..
 RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
 
 include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/04-mesh/mesh.cpp b/examples/04-mesh/mesh.cpp
index a8dd3529..4f651f15 100644
--- a/examples/04-mesh/mesh.cpp
+++ b/examples/04-mesh/mesh.cpp
@@ -54,11 +54,10 @@ static const bgfx::Memory* load(const char* _filePath)
 	return NULL;
 }
 
-static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
+static const bgfx::Memory* loadShader(const char* _name)
 {
 	char filePath[512];
 	shaderFilePath(filePath, _name);
-	BX_UNUSED(_default);
 	return load(filePath);
 }
 
@@ -102,7 +101,7 @@ struct Mesh
 
 			if (ctmGetInteger(ctm, CTM_HAS_NORMALS) )
 			{
-				m_decl.add(bgfx::Attrib::Normal, 3, bgfx::AttribType::Float, true);
+				m_decl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true);
 			}
 
 			if (0 < ctmGetInteger(ctm, CTM_UV_MAP_COUNT) )
@@ -152,10 +151,10 @@ struct Mesh
 
 				if (NULL != normals)
 				{
-					float* nxyz = (float*)&data[normalOffset];
-					nxyz[0] = normals[0];
-					nxyz[1] = normals[1];
-					nxyz[2] = normals[2];
+					uint8_t* nxyz = (uint8_t*)&data[normalOffset];
+					nxyz[0] = uint8_t(normals[0]*127.0f + 128.0f);
+					nxyz[1] = uint8_t(normals[1]*127.0f + 128.0f);
+					nxyz[2] = uint8_t(normals[2]*127.0f + 128.0f);
 					normals += 3;
 				}
 
@@ -195,7 +194,7 @@ struct Mesh
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
@@ -240,7 +239,7 @@ int _main_(int _argc, char** _argv)
 		break;
 	}
 
-	bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::ConstantType::Uniform1f);
+	bgfx::UniformHandle u_time = bgfx::createUniform("u_time", bgfx::UniformType::Uniform1f);
 
 	bgfx::ProgramHandle program = loadProgram("vs_mesh", "fs_mesh");
 
diff --git a/examples/04-mesh/varying.def.sc b/examples/04-mesh/varying.def.sc
index f18fe1db..b7b399dd 100644
--- a/examples/04-mesh/varying.def.sc
+++ b/examples/04-mesh/varying.def.sc
@@ -5,6 +5,6 @@ vec3 v_pos       : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
 vec3 v_view      : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
 
 vec3 a_position  : POSITION;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
 vec2 a_texcoord0 : TEXCOORD0;
 vec3 a_normal    : NORMAL;
diff --git a/examples/04-mesh/vs_mesh.sc b/examples/04-mesh/vs_mesh.sc
index 739274a1..dedddedc 100644
--- a/examples/04-mesh/vs_mesh.sc
+++ b/examples/04-mesh/vs_mesh.sc
@@ -17,12 +17,15 @@ void main()
 	float sx = sin(pos.x*32.0+u_time*4.0)*0.5+0.5;
 	float cy = cos(pos.y*32.0+u_time*4.0)*0.5+0.5;
 	vec3 displacement = vec3(sx, cy, sx*cy);
-	pos = pos + a_normal*displacement*vec3(0.06, 0.06, 0.06);
+	vec3 normal = a_normal.xyz*2.0 - 1.0;
+
+	pos = pos + normal*displacement*vec3(0.06, 0.06, 0.06);
 
 	gl_Position = mul(u_modelViewProj, vec4(pos, 1.0) );
 	v_pos = gl_Position.xyz;
 	v_view = mul(u_modelView, vec4(pos, 1.0) ).xyz;
-	v_normal = mul(u_modelView, vec4(a_normal, 0.0) ).xyz;
+
+	v_normal = mul(u_modelView, vec4(normal, 0.0) ).xyz;
 
 	float len = length(displacement)*0.4+0.6;
 	v_color0 = vec4(len, len, len, 1.0);
diff --git a/examples/05-instancing/instancing.cpp b/examples/05-instancing/instancing.cpp
index a8b00177..221f11cc 100644
--- a/examples/05-instancing/instancing.cpp
+++ b/examples/05-instancing/instancing.cpp
@@ -90,17 +90,16 @@ static const bgfx::Memory* load(const char* _filePath)
 	return NULL;
 }
 
-static const bgfx::Memory* loadShader(const char* _name, const char* _default = NULL)
+static const bgfx::Memory* loadShader(const char* _name)
 {
 	char filePath[512];
 	shaderFilePath(filePath, _name);
-	BX_UNUSED(_default);
 	return load(filePath);
 }
 
 int _main_(int _argc, char** _argv)
 {
-	bgfx::init(BX_PLATFORM_WINDOWS, fatalCb);
+	bgfx::init(fatalCb);
 	bgfx::reset(1280, 720);
 
 	// Enable debug text.
diff --git a/examples/05-instancing/makefile b/examples/05-instancing/makefile
index 900aad91..3d8f5374 100644
--- a/examples/05-instancing/makefile
+++ b/examples/05-instancing/makefile
@@ -7,3 +7,10 @@ BGFX_DIR=../..
 RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
 
 include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/05-instancing/varying.def.sc b/examples/05-instancing/varying.def.sc
index 7a1bc5dc..77ab0393 100644
--- a/examples/05-instancing/varying.def.sc
+++ b/examples/05-instancing/varying.def.sc
@@ -1,7 +1,7 @@
 vec4 v_color0    : COLOR0    = vec4(1.0, 0.0, 0.0, 1.0);
 
 vec3 a_position  : POSITION;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
 vec4 i_data0     : TEXCOORD3;
 vec4 i_data1     : TEXCOORD4;
 vec4 i_data2     : TEXCOORD5;
diff --git a/examples/05-instancing/vs_instancing.sc b/examples/05-instancing/vs_instancing.sc
index 62223595..e50e0b5c 100644
--- a/examples/05-instancing/vs_instancing.sc
+++ b/examples/05-instancing/vs_instancing.sc
@@ -1,4 +1,4 @@
-$input a_position, a_color, i_data0, i_data1, i_data2, i_data3, i_data4
+$input a_position, a_color0, i_data0, i_data1, i_data2, i_data3, i_data4
 $output v_color0
 
 /*
@@ -18,5 +18,5 @@ void main()
 
 	vec4 worldPos = instMul(model, vec4(a_position, 1.0) );
 	gl_Position = mul(u_viewProj, worldPos);
-	v_color0 = a_color*i_data4;
+	v_color0 = a_color0*i_data4;
 }
diff --git a/examples/06-bump/bump.cpp b/examples/06-bump/bump.cpp
new file mode 100644
index 00000000..ac993e0e
--- /dev/null
+++ b/examples/06-bump/bump.cpp
@@ -0,0 +1,477 @@
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include <bgfx.h>
+#include <bx/bx.h>
+#include <bx/countof.h>
+#include <bx/timer.h>
+#include "../common/dbg.h"
+#include "../common/math.h"
+
+#include <stdio.h>
+#include <string.h>
+
+void fatalCb(bgfx::Fatal::Enum _code, const char* _str)
+{
+	DBG("%x: %s", _code, _str);
+}
+
+struct PosNormalTangentTexcoordVertex
+{
+	float m_x;
+	float m_y;
+	float m_z;
+	uint32_t m_normal;
+	uint32_t m_tangent;
+	float m_u;
+	float m_v;
+};
+
+static bgfx::VertexDecl s_PosNormalTangentTexcoordDecl;
+
+uint32_t packUint32(uint8_t _x, uint8_t _y, uint8_t _z, uint8_t _w)
+{
+	union
+	{
+		uint32_t ui32;
+		uint8_t arr[4];
+	} un;
+
+	un.arr[0] = _x;
+	un.arr[1] = _y;
+	un.arr[2] = _z;
+	un.arr[3] = _w;
+
+	return un.ui32;
+}
+
+void unpackUint32(uint8_t _result[4], uint32_t _packed)
+{
+	union
+	{
+		uint32_t ui32;
+		uint8_t arr[4];
+	} un;
+
+	un.ui32	= _packed;
+	_result[0] = un.arr[0];
+	_result[1] = un.arr[1];
+	_result[2] = un.arr[2];
+	_result[3] = un.arr[3];
+}
+
+uint32_t packF4u(float _x, float _y = 0.0f, float _z = 0.0f, float _w = 0.0f)
+{
+	const uint8_t xx = uint8_t(_x*127.0f + 128.0f);
+	const uint8_t yy = uint8_t(_y*127.0f + 128.0f);
+	const uint8_t zz = uint8_t(_z*127.0f + 128.0f);
+	const uint8_t ww = uint8_t(_w*127.0f + 128.0f);
+	return packUint32(xx, yy, zz, ww);
+}
+
+void unpackF4u(float _result[3], uint32_t _packed)
+{
+	uint8_t unpacked[4];
+	unpackUint32(unpacked, _packed);
+	_result[0] = (float(unpacked[0]) - 128.0f)/127.0f;
+	_result[1] = (float(unpacked[1]) - 128.0f)/127.0f;
+	_result[2] = (float(unpacked[2]) - 128.0f)/127.0f;
+	_result[3] = (float(unpacked[3]) - 128.0f)/127.0f;
+}
+
+static PosNormalTangentTexcoordVertex s_cubeVertices[24] =
+{
+	{-1.0f,  1.0f,  1.0f, packF4u( 0.0f,  0.0f,  1.0f), 0, 0.0f, 0.0f },
+	{ 1.0f,  1.0f,  1.0f, packF4u( 0.0f,  0.0f,  1.0f), 0, 1.0f, 0.0f },
+	{-1.0f, -1.0f,  1.0f, packF4u( 0.0f,  0.0f,  1.0f), 0, 0.0f, 1.0f },
+	{ 1.0f, -1.0f,  1.0f, packF4u( 0.0f,  0.0f,  1.0f), 0, 1.0f, 1.0f },
+	{-1.0f,  1.0f, -1.0f, packF4u( 0.0f,  0.0f, -1.0f), 0, 0.0f, 0.0f },
+	{ 1.0f,  1.0f, -1.0f, packF4u( 0.0f,  0.0f, -1.0f), 0, 1.0f, 0.0f },
+	{-1.0f, -1.0f, -1.0f, packF4u( 0.0f,  0.0f, -1.0f), 0, 0.0f, 1.0f },
+	{ 1.0f, -1.0f, -1.0f, packF4u( 0.0f,  0.0f, -1.0f), 0, 1.0f, 1.0f },
+	{-1.0f,  1.0f,  1.0f, packF4u( 0.0f,  1.0f,  0.0f), 0, 0.0f, 0.0f },
+	{ 1.0f,  1.0f,  1.0f, packF4u( 0.0f,  1.0f,  0.0f), 0, 1.0f, 0.0f },
+	{-1.0f,  1.0f, -1.0f, packF4u( 0.0f,  1.0f,  0.0f), 0, 0.0f, 1.0f },
+	{ 1.0f,  1.0f, -1.0f, packF4u( 0.0f,  1.0f,  0.0f), 0, 1.0f, 1.0f },
+	{-1.0f, -1.0f,  1.0f, packF4u( 0.0f, -1.0f,  0.0f), 0, 0.0f, 0.0f },
+	{ 1.0f, -1.0f,  1.0f, packF4u( 0.0f, -1.0f,  0.0f), 0, 1.0f, 0.0f },
+	{-1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f,  0.0f), 0, 0.0f, 1.0f },
+	{ 1.0f, -1.0f, -1.0f, packF4u( 0.0f, -1.0f,  0.0f), 0, 1.0f, 1.0f },
+	{ 1.0f, -1.0f,  1.0f, packF4u( 1.0f,  0.0f,  0.0f), 0, 0.0f, 0.0f },
+	{ 1.0f,  1.0f,  1.0f, packF4u( 1.0f,  0.0f,  0.0f), 0, 1.0f, 0.0f },
+	{ 1.0f, -1.0f, -1.0f, packF4u( 1.0f,  0.0f,  0.0f), 0, 0.0f, 1.0f },
+	{ 1.0f,  1.0f, -1.0f, packF4u( 1.0f,  0.0f,  0.0f), 0, 1.0f, 1.0f },
+	{-1.0f, -1.0f,  1.0f, packF4u(-1.0f,  0.0f,  0.0f), 0, 0.0f, 0.0f },
+	{-1.0f,  1.0f,  1.0f, packF4u(-1.0f,  0.0f,  0.0f), 0, 1.0f, 0.0f },
+	{-1.0f, -1.0f, -1.0f, packF4u(-1.0f,  0.0f,  0.0f), 0, 0.0f, 1.0f },
+	{-1.0f,  1.0f, -1.0f, packF4u(-1.0f,  0.0f,  0.0f), 0, 1.0f, 1.0f },
+};
+
+static const uint16_t s_cubeIndices[36] =
+{
+	 0,  2,  1,
+	 1,  2,  3,
+	 4,  5,  6,
+	 5,  7,  6,
+
+	 8, 10,  9,
+	 9, 10, 11,
+    12, 13, 14,
+	13, 15, 14,
+
+	16, 18, 17,
+	17, 18, 19,
+	20, 21, 22,
+	21, 23, 22,
+};
+
+static const char* s_shaderPath = NULL;
+
+static void shaderFilePath(char* _out, const char* _name)
+{
+	strcpy(_out, s_shaderPath);
+	strcat(_out, _name);
+	strcat(_out, ".bin");
+}
+
+long int fsize(FILE* _file)
+{
+	long int pos = ftell(_file);
+	fseek(_file, 0L, SEEK_END);
+	long int size = ftell(_file);
+	fseek(_file, pos, SEEK_SET);
+	return size;
+}
+
+static const bgfx::Memory* load(const char* _filePath)
+{
+	FILE* file = fopen(_filePath, "rb");
+	if (NULL != file)
+	{
+		uint32_t size = (uint32_t)fsize(file);
+		const bgfx::Memory* mem = bgfx::alloc(size+1);
+		size_t ignore = fread(mem->data, 1, size, file);
+		BX_UNUSED(ignore);
+		fclose(file);
+		mem->data[mem->size-1] = '\0';
+		return mem;
+	}
+
+	return NULL;
+}
+
+static const bgfx::Memory* loadShader(const char* _name)
+{
+	char filePath[512];
+	shaderFilePath(filePath, _name);
+	return load(filePath);
+}
+
+static const bgfx::Memory* loadTexture(const char* _name)
+{
+	char filePath[512];
+	strcpy(filePath, "textures/");
+	strcat(filePath, _name);
+	return load(filePath);
+}
+
+template<typename Ty>
+void calcTangents(const uint16_t* _indices, uint32_t _numIndices, Ty* _vertices, uint16_t _numVertices)
+{
+	float* tangents = new float[6*_numVertices];
+	memset(tangents, 0, 6*_numVertices*sizeof(float) );
+
+	float* tan = tangents;
+	for (uint32_t ii = 0, num = _numIndices/3; ii < num; ++ii)
+	{
+		const uint16_t* indices = &_indices[ii*3];
+		const Ty& v0 = _vertices[indices[0] ];
+		const Ty& v1 = _vertices[indices[1] ];
+		const Ty& v2 = _vertices[indices[2] ];
+
+		const float bax = v1.m_x - v0.m_x;
+		const float bay = v1.m_y - v0.m_y;
+		const float baz = v1.m_z - v0.m_z;
+		const float bau = v1.m_u - v0.m_u;
+		const float bav = v1.m_v - v0.m_v;
+
+		const float cax = v2.m_x - v0.m_x;
+		const float cay = v2.m_y - v0.m_y;
+		const float caz = v2.m_z - v0.m_z;
+		const float cau = v2.m_u - v0.m_u;
+		const float cav = v2.m_v - v0.m_v;
+
+		const float det = (bau * cav - bav * cau);
+		const float invDet = 1.0f / det;
+
+		const float tx = (bax * cav - cax * bav) * invDet;
+		const float ty = (bay * cav - cay * bav) * invDet;
+		const float tz = (baz * cav - caz * bav) * invDet;
+
+		const float bx = (cax * bau - bax * cau) * invDet;
+		const float by = (cay * bau - bay * cau) * invDet;
+		const float bz = (caz * bau - baz * cau) * invDet;
+
+		for (uint32_t jj = 0; jj < 3; ++jj)
+		{
+			float* tanu = &tangents[indices[jj]*6];
+			float* tanv = &tanu[3];
+			tanu[0] += tx;
+			tanu[1] += ty;
+			tanu[2] += tz;
+
+			tanv[0] += bx;
+			tanv[1] += by;
+			tanv[2] += bz;
+		}
+	}
+
+	for (uint32_t ii = 0; ii < _numVertices; ++ii)
+	{
+		Ty& v0 = _vertices[ii];
+		const float* tanu = &tangents[ii*6];
+		const float* tanv = &tangents[ii*6 + 3];
+
+		float normal[3];
+		unpackF4u(normal, v0.m_normal);
+		float ndt = vec3Dot(normal, tanu);
+
+		float nxt[3];
+		vec3Cross(nxt, normal, tanu);
+
+		float tmp[3];
+		tmp[0] = tanu[0] - normal[0] * ndt;
+		tmp[1] = tanu[1] - normal[1] * ndt;
+		tmp[2] = tanu[2] - normal[2] * ndt;
+
+		float tangent[3];
+		vec3Norm(tangent, tmp);
+
+		float tw = vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f;
+		v0.m_tangent = packF4u(tangent[0], tangent[1], tangent[2], tw);
+	}
+}
+
+int _main_(int _argc, char** _argv)
+{
+	bgfx::init(fatalCb);
+	bgfx::reset(1280, 720);
+
+	// Enable debug text.
+	bgfx::setDebug(BGFX_DEBUG_TEXT);
+
+	// Set view 0 default viewport.
+	bgfx::setViewRect(0, 0, 0, 1280, 720);
+
+	// Set view 0 clear state.
+	bgfx::setViewClear(0
+		, BGFX_CLEAR_COLOR_BIT|BGFX_CLEAR_DEPTH_BIT
+		, 0x303030ff
+		, 1.0f
+		, 0
+		);
+
+	// Setup root path for binary shaders. Shader binaries are different 
+	// for each renderer.
+	switch (bgfx::getRendererType() )
+	{
+	case bgfx::RendererType::Null:
+	case bgfx::RendererType::Direct3D9:
+		s_shaderPath = "shaders/dx9/";
+		break;
+
+	case bgfx::RendererType::Direct3D11:
+		s_shaderPath = "shaders/dx11/";
+		break;
+
+	case bgfx::RendererType::OpenGL:
+		s_shaderPath = "shaders/glsl/";
+		break;
+
+	case bgfx::RendererType::OpenGLES2:
+	case bgfx::RendererType::OpenGLES3:
+		s_shaderPath = "shaders/gles/";
+		break;
+	}
+
+	// Create vertex stream declaration.
+	s_PosNormalTangentTexcoordDecl.begin();
+	s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float);
+	s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Normal, 4, bgfx::AttribType::Uint8, true);
+	s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::Tangent, 4, bgfx::AttribType::Uint8, true);
+	s_PosNormalTangentTexcoordDecl.add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float);
+	s_PosNormalTangentTexcoordDecl.end();
+
+	const bgfx::Memory* mem;
+
+	calcTangents(s_cubeIndices, countof(s_cubeIndices), s_cubeVertices, countof(s_cubeVertices) );
+
+	// Create static vertex buffer.
+	mem = bgfx::makeRef(s_cubeVertices, sizeof(s_cubeVertices) );
+	bgfx::VertexBufferHandle vbh = bgfx::createVertexBuffer(mem, s_PosNormalTangentTexcoordDecl);
+
+	// Create static index buffer.
+	mem = bgfx::makeRef(s_cubeIndices, sizeof(s_cubeIndices) );
+	bgfx::IndexBufferHandle ibh = bgfx::createIndexBuffer(mem);
+
+	// Create texture sampler uniforms.
+	bgfx::UniformHandle u_texColor = bgfx::createUniform("u_texColor", bgfx::UniformType::Uniform1iv);
+	bgfx::UniformHandle u_texNormal = bgfx::createUniform("u_texNormal", bgfx::UniformType::Uniform1iv);
+
+	uint16_t numLights = 4;
+	bgfx::UniformHandle u_lightPosRadius = bgfx::createUniform("u_lightPosRadius", bgfx::UniformType::Uniform4fv, numLights);
+	bgfx::UniformHandle u_lightRgbInnerR = bgfx::createUniform("u_lightRgbInnerR", bgfx::UniformType::Uniform4fv, numLights);
+
+	// Load vertex shader.
+	mem = loadShader("vs_bump");
+	bgfx::VertexShaderHandle vsh = bgfx::createVertexShader(mem);
+
+	// Load fragment shader.
+	mem = loadShader("fs_bump");
+	bgfx::FragmentShaderHandle fsh = bgfx::createFragmentShader(mem);
+
+	// Create program from shaders.
+	bgfx::ProgramHandle program = bgfx::createProgram(vsh, fsh);
+
+	// We can destroy vertex and fragment shader here since
+	// their reference is kept inside bgfx after calling createProgram.
+	// Vertex and fragment shader will be destroyed once program is^
+	// destroyed.
+	bgfx::destroyVertexShader(vsh);
+	bgfx::destroyFragmentShader(fsh);
+
+	// Load diffuse texture.
+	mem = loadTexture("fieldstone-rgba.dds");
+	bgfx::TextureHandle texture_rgba = bgfx::createTexture(mem);
+
+	// Load normal texture.
+	mem = loadTexture("fieldstone-n.dds");
+	bgfx::TextureHandle texture_n = bgfx::createTexture(mem);
+
+	while (true)
+	{
+		// This dummy draw call is here to make sure that view 0 is cleared
+		// if no other draw calls are submitted to view 0.
+		bgfx::submit(0);
+
+		int64_t now = bx::getHPCounter();
+		static int64_t last = now;
+		const int64_t frameTime = now - last;
+		last = now;
+		const double freq = double(bx::getHPFrequency() );
+		const double toMs = 1000.0/freq;
+
+		float time = (float)(now/freq);
+
+		// Use debug font to print information about this example.
+		bgfx::dbgTextClear();
+		bgfx::dbgTextPrintf(0, 1, 0x4f, "bgfx/examples/06-bump");
+		bgfx::dbgTextPrintf(0, 2, 0x6f, "Description: Loading textures.");
+		bgfx::dbgTextPrintf(0, 3, 0x0f, "Frame: % 7.3f[ms]", double(frameTime)*toMs);
+
+		float at[3] = { 0.0f, 0.0f, 0.0f };
+		float eye[3] = { 0.0f, 0.0f, -7.0f };
+		
+		float view[16];
+		float proj[16];
+		mtxLookAt(view, eye, at);
+		mtxProj(proj, 60.0f, 16.0f/9.0f, 0.1f, 100.0f);
+
+		float lightPosRadius[4][4];
+		for (uint32_t ii = 0; ii < numLights; ++ii)
+		{
+			lightPosRadius[ii][0] = sin( (time*(0.1f + ii*0.17f) + float(ii*M_PI_2)*1.37f ) )*3.0f;
+			lightPosRadius[ii][1] = cos( (time*(0.2f + ii*0.29f) + float(ii*M_PI_2)*1.49f ) )*3.0f;
+			lightPosRadius[ii][2] = -2.5f;
+			lightPosRadius[ii][3] = 3.0f;
+		}
+
+		bgfx::setUniform(u_lightPosRadius, lightPosRadius, numLights);
+
+		float lightRgbInnerR[4][4] =
+		{
+			1.0f, 0.7f, 0.2f, 0.8f,
+			0.7f, 0.2f, 1.0f, 0.8f,
+			0.2f, 1.0f, 0.7f, 0.8f,
+			1.0f, 0.4f, 0.2f, 0.8f,
+		};
+
+		bgfx::setUniform(u_lightRgbInnerR, lightRgbInnerR, numLights);
+
+		// Set view and projection matrix for view 0.
+		bgfx::setViewTransform(0, view, proj);
+
+		const uint16_t instanceStride = 64;
+		const bgfx::InstanceDataBuffer* idb = bgfx::allocInstanceDataBuffer(9, instanceStride);
+		if (NULL != idb)
+		{
+			uint8_t* data = idb->data;
+
+			// Write instance data for 3x3 cubes.
+			for (uint32_t yy = 0; yy < 3; ++yy)
+			{
+				for (uint32_t xx = 0; xx < 3; ++xx)
+				{
+					float* mtx = (float*)data;
+					mtxRotateXY(mtx, time*0.023f + xx*0.21f, time*0.03f + yy*0.37f);
+					mtx[12] = -3.0f + float(xx)*3.0f;
+					mtx[13] = -3.0f + float(yy)*3.0f;
+					mtx[14] = 0.0f;
+
+					float* color = (float*)&data[64];
+					color[0] = sin(time+float(xx)/11.0f)*0.5f+0.5f;
+					color[1] = cos(time+float(yy)/11.0f)*0.5f+0.5f;
+					color[2] = sin(time*3.0f)*0.5f+0.5f;
+					color[3] = 1.0f;
+
+					data += instanceStride;
+				}
+			}
+
+			uint16_t numInstances = (data - idb->data)/instanceStride;
+
+			// Set vertex and fragment shaders.
+			bgfx::setProgram(program);
+
+			// Set vertex and index buffer.
+			bgfx::setVertexBuffer(vbh);
+			bgfx::setIndexBuffer(ibh);
+
+			// Set instance data buffer.
+			bgfx::setInstanceDataBuffer(idb, numInstances);
+
+			// Bind textures.
+			bgfx::setTexture(0, u_texColor, texture_rgba);
+			bgfx::setTexture(1, u_texNormal, texture_n);
+
+			// Set render states.
+			bgfx::setState(BGFX_STATE_RGB_WRITE
+				|BGFX_STATE_DEPTH_WRITE
+				|BGFX_STATE_DEPTH_TEST_LESS
+				);
+
+			// Submit primitive for rendering to view 0.
+			bgfx::submit(0);
+		}
+
+		// Advance to next frame. Rendering thread will be kicked to 
+		// process submitted rendering primitives.
+		bgfx::frame();
+	}
+
+	// Cleanup.
+	bgfx::destroyIndexBuffer(ibh);
+	bgfx::destroyVertexBuffer(vbh);
+	bgfx::destroyProgram(program);
+	bgfx::destroyTexture(texture_rgba);
+	bgfx::destroyTexture(texture_n);
+	bgfx::destroyUniform(u_texColor);
+	bgfx::destroyUniform(u_texNormal);
+
+	// Shutdown bgfx.
+	bgfx::shutdown();
+
+	return 0;
+}
diff --git a/examples/06-bump/fieldstone-n.tga b/examples/06-bump/fieldstone-n.tga
new file mode 100644
index 00000000..6290f527
Binary files /dev/null and b/examples/06-bump/fieldstone-n.tga differ
diff --git a/examples/06-bump/fieldstone-rgba.tga b/examples/06-bump/fieldstone-rgba.tga
new file mode 100644
index 00000000..8acafae2
Binary files /dev/null and b/examples/06-bump/fieldstone-rgba.tga differ
diff --git a/examples/06-bump/fs_bump.sc b/examples/06-bump/fs_bump.sc
new file mode 100644
index 00000000..a5824bd6
--- /dev/null
+++ b/examples/06-bump/fs_bump.sc
@@ -0,0 +1,82 @@
+$input v_wpos, v_view, v_normal, v_tangent, v_texcoord0
+
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "../common/common.sh"
+
+SAMPLER2D(u_texColor, 0);
+SAMPLER2D(u_texNormal, 1);
+uniform vec4 u_lightPosRadius[4];
+uniform vec4 u_lightRgbInnerR[4];
+
+vec2 blinn(vec3 _lightDir, vec3 _normal, vec3 _viewDir)
+{
+	float ndotl = dot(_normal, _lightDir);
+	vec3 reflected = _lightDir - 2.0*ndotl*_normal; // reflect(_lightDir, _normal);
+	float rdotv = dot(reflected, _viewDir);
+	return vec2(ndotl, rdotv);
+}
+
+float fresnel(float _ndotl, float _bias, float _pow)
+{
+	float facing = (1.0 - _ndotl);
+	return max(_bias + (1.0 - _bias) * pow(facing, _pow), 0.0);
+}
+
+vec4 lit(float _ndotl, float _rdotv, float _m)
+{
+	float diff = max(0.0, _ndotl);
+	float spec = step(0.0, _ndotl) * max(0.0, _rdotv * _m);
+	return vec4(1.0, diff, spec, 1.0);
+}
+
+vec4 powRgba(vec4 _rgba, float _pow)
+{
+	vec4 result;
+	result.xyz = pow(_rgba.xyz, vec3_splat(_pow) );
+	result.w = _rgba.w;
+	return result;
+}
+
+vec4 toLinear(vec4 _rgba)
+{
+	return powRgba(_rgba, 2.2);
+}
+
+vec4 toGamma(vec4 _rgba)
+{
+	return powRgba(_rgba, 1.0/2.2);
+}
+
+vec3 calcLight(int _idx, mat3 _tbn, vec3 _wpos, vec3 _normal, vec3 _view)
+{
+	vec3 lp = u_lightPosRadius[_idx].xyz - _wpos;
+	float attn = 1.0 - smoothstep(u_lightRgbInnerR[_idx].w, 1.0, length(lp) / u_lightPosRadius[_idx].w);
+	vec3 lightDir = mul(_tbn, normalize(lp) );
+	vec2 bln = blinn(lightDir, _normal, _view);
+	vec4 lc = lit(bln.x, bln.y, 1.0);
+	vec3 rgb = u_lightRgbInnerR[_idx].xyz*max(0.0, saturate(lc.y) ) * attn;
+	return rgb;
+}
+
+void main()
+{
+	mat3 tbn = mat3(v_tangent, cross(v_normal, v_tangent), v_normal);
+
+	vec3 normal = normalize(2.0*texture2D(u_texNormal, v_texcoord0).xyz-1.0);
+
+	vec3 lightColor;
+	lightColor =  calcLight(0, tbn, v_wpos, normal, v_view);
+	lightColor += calcLight(1, tbn, v_wpos, normal, v_view);
+	lightColor += calcLight(2, tbn, v_wpos, normal, v_view);
+	lightColor += calcLight(3, tbn, v_wpos, normal, v_view);
+
+	vec4 color = toLinear(texture2D(u_texColor, v_texcoord0) );
+
+	gl_FragColor.xyz = max(vec3_splat(0.05), lightColor.xyz)*color.xyz; // + fres*pow(lc.z, 128.0); //normal.xyz; //color.xyz; //*normal;
+	gl_FragColor.w = 1.0;
+	gl_FragColor = toGamma(gl_FragColor);
+}
diff --git a/examples/06-bump/makefile b/examples/06-bump/makefile
new file mode 100644
index 00000000..3d8f5374
--- /dev/null
+++ b/examples/06-bump/makefile
@@ -0,0 +1,16 @@
+#
+# Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+# License: http://www.opensource.org/licenses/BSD-2-Clause
+#
+
+BGFX_DIR=../..
+RUNTIME_DIR=$(BGFX_DIR)/examples/runtime
+
+include $(BGFX_DIR)/premake/shader.mk
+
+rebuild:
+	@make -s --no-print-directory TARGET=0 clean all
+	@make -s --no-print-directory TARGET=1 clean all
+	@make -s --no-print-directory TARGET=2 clean all
+	@make -s --no-print-directory TARGET=3 clean all
+	@make -s --no-print-directory TARGET=4 clean all
diff --git a/examples/06-bump/varying.def.sc b/examples/06-bump/varying.def.sc
new file mode 100644
index 00000000..2913d9a6
--- /dev/null
+++ b/examples/06-bump/varying.def.sc
@@ -0,0 +1,14 @@
+vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
+vec3 v_wpos      : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
+vec3 v_view      : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
+vec3 v_normal    : NORMAL    = vec3(0.0, 0.0, 1.0);
+vec3 v_tangent   : TANGENT   = vec3(1.0, 0.0, 0.0);
+
+vec3 a_position  : POSITION;
+vec3 a_normal    : NORMAL;
+vec3 a_tangent   : TANGENT;
+vec2 a_texcoord0 : TEXCOORD0;
+vec4 i_data0     : TEXCOORD4;
+vec4 i_data1     : TEXCOORD5;
+vec4 i_data2     : TEXCOORD6;
+vec4 i_data3     : TEXCOORD7;
diff --git a/examples/06-bump/vs_bump.sc b/examples/06-bump/vs_bump.sc
new file mode 100644
index 00000000..48aceee5
--- /dev/null
+++ b/examples/06-bump/vs_bump.sc
@@ -0,0 +1,41 @@
+$input a_position, a_normal, a_tangent, a_texcoord0, i_data0, i_data1, i_data2, i_data3
+$output v_wpos, v_view, v_normal, v_tangent, v_texcoord0
+
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#include "../common/common.sh"
+
+void main()
+{
+	mat4 model;
+	model[0] = i_data0;
+	model[1] = i_data1;
+	model[2] = i_data2;
+	model[3] = i_data3;
+
+	vec3 wpos = instMul(model, vec4(a_position, 1.0) ).xyz;
+	gl_Position = mul(u_viewProj, vec4(wpos, 1.0) );
+	
+	vec3 normal = a_normal * 2.0f - 1.0f;
+	vec3 wnormal = instMul(model, vec4(normal, 0.0) ).xyz;
+
+	vec3 tangent = a_tangent * 2.0f - 1.0f;
+	vec3 wtangent = instMul(model, vec4(tangent.xyz, 0.0) ).xyz;
+
+	vec3 viewNormal = normalize(mul(u_view, vec4(wnormal, 0.0) ).xyz);
+	vec3 viewTangent = normalize(mul(u_view, vec4(wtangent, 0.0) ).xyz);
+	mat3 tbn = mat3(viewTangent, cross(viewNormal, viewTangent), viewNormal);
+
+	v_wpos = wpos;
+
+	vec3 view = -mul(u_view, vec4(wpos, 1.0) ).xyz;
+	v_view = mul(tbn, view);
+
+	v_normal = viewNormal;
+	v_tangent = viewTangent;
+
+	v_texcoord0 = a_texcoord0;
+}
diff --git a/examples/common/varying.def.sc b/examples/common/varying.def.sc
deleted file mode 100644
index f18fe1db..00000000
--- a/examples/common/varying.def.sc
+++ /dev/null
@@ -1,10 +0,0 @@
-vec4 v_color0    : COLOR0    = vec4(1.0, 0.0, 0.0, 1.0);
-vec3 v_normal    : NORMAL    = vec3(0.0, 0.0, 1.0);
-vec2 v_texcoord0 : TEXCOORD0 = vec2(0.0, 0.0);
-vec3 v_pos       : TEXCOORD1 = vec3(0.0, 0.0, 0.0);
-vec3 v_view      : TEXCOORD2 = vec3(0.0, 0.0, 0.0);
-
-vec3 a_position  : POSITION;
-vec4 a_color     : COLOR0;
-vec2 a_texcoord0 : TEXCOORD0;
-vec3 a_normal    : NORMAL;
diff --git a/examples/runtime/shaders/dx11/fs_bump.bin b/examples/runtime/shaders/dx11/fs_bump.bin
new file mode 100644
index 00000000..7ffd8b16
Binary files /dev/null and b/examples/runtime/shaders/dx11/fs_bump.bin differ
diff --git a/examples/runtime/shaders/dx11/fs_cubes.bin b/examples/runtime/shaders/dx11/fs_cubes.bin
index 9e1a0eac..96fcba26 100644
Binary files a/examples/runtime/shaders/dx11/fs_cubes.bin and b/examples/runtime/shaders/dx11/fs_cubes.bin differ
diff --git a/examples/runtime/shaders/dx11/fs_instancing.bin b/examples/runtime/shaders/dx11/fs_instancing.bin
index 9e1a0eac..96fcba26 100644
Binary files a/examples/runtime/shaders/dx11/fs_instancing.bin and b/examples/runtime/shaders/dx11/fs_instancing.bin differ
diff --git a/examples/runtime/shaders/dx11/fs_mesh.bin b/examples/runtime/shaders/dx11/fs_mesh.bin
index b3a94b9f..36d0e7e5 100644
Binary files a/examples/runtime/shaders/dx11/fs_mesh.bin and b/examples/runtime/shaders/dx11/fs_mesh.bin differ
diff --git a/examples/runtime/shaders/dx11/fs_metaballs.bin b/examples/runtime/shaders/dx11/fs_metaballs.bin
index d6f9f05c..3b820921 100644
Binary files a/examples/runtime/shaders/dx11/fs_metaballs.bin and b/examples/runtime/shaders/dx11/fs_metaballs.bin differ
diff --git a/examples/runtime/shaders/dx11/fs_raymarching.bin b/examples/runtime/shaders/dx11/fs_raymarching.bin
index a23511c2..1f56054b 100644
Binary files a/examples/runtime/shaders/dx11/fs_raymarching.bin and b/examples/runtime/shaders/dx11/fs_raymarching.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_bump.bin b/examples/runtime/shaders/dx11/vs_bump.bin
new file mode 100644
index 00000000..0e8bc9a0
Binary files /dev/null and b/examples/runtime/shaders/dx11/vs_bump.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_cubes.bin b/examples/runtime/shaders/dx11/vs_cubes.bin
index 63fa4141..2fd2d2db 100644
Binary files a/examples/runtime/shaders/dx11/vs_cubes.bin and b/examples/runtime/shaders/dx11/vs_cubes.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_instancing.bin b/examples/runtime/shaders/dx11/vs_instancing.bin
index a6c6be13..a4b7c425 100644
Binary files a/examples/runtime/shaders/dx11/vs_instancing.bin and b/examples/runtime/shaders/dx11/vs_instancing.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_mesh.bin b/examples/runtime/shaders/dx11/vs_mesh.bin
index 73f518c6..a23d5340 100644
Binary files a/examples/runtime/shaders/dx11/vs_mesh.bin and b/examples/runtime/shaders/dx11/vs_mesh.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_metaballs.bin b/examples/runtime/shaders/dx11/vs_metaballs.bin
index 928c6966..31f7a317 100644
Binary files a/examples/runtime/shaders/dx11/vs_metaballs.bin and b/examples/runtime/shaders/dx11/vs_metaballs.bin differ
diff --git a/examples/runtime/shaders/dx11/vs_raymarching.bin b/examples/runtime/shaders/dx11/vs_raymarching.bin
index 043939c9..7b7d5ab4 100644
Binary files a/examples/runtime/shaders/dx11/vs_raymarching.bin and b/examples/runtime/shaders/dx11/vs_raymarching.bin differ
diff --git a/examples/runtime/shaders/dx9/fs_bump.bin b/examples/runtime/shaders/dx9/fs_bump.bin
new file mode 100644
index 00000000..6cfb60d0
Binary files /dev/null and b/examples/runtime/shaders/dx9/fs_bump.bin differ
diff --git a/examples/runtime/shaders/dx9/vs_bump.bin b/examples/runtime/shaders/dx9/vs_bump.bin
new file mode 100644
index 00000000..88382b8a
Binary files /dev/null and b/examples/runtime/shaders/dx9/vs_bump.bin differ
diff --git a/examples/runtime/shaders/dx9/vs_mesh.bin b/examples/runtime/shaders/dx9/vs_mesh.bin
index 35b7db4a..22ae1514 100644
Binary files a/examples/runtime/shaders/dx9/vs_mesh.bin and b/examples/runtime/shaders/dx9/vs_mesh.bin differ
diff --git a/examples/runtime/shaders/gles/fs_bump.bin b/examples/runtime/shaders/gles/fs_bump.bin
new file mode 100644
index 00000000..16a53b6a
Binary files /dev/null and b/examples/runtime/shaders/gles/fs_bump.bin differ
diff --git a/examples/runtime/shaders/gles/vs_bump.bin b/examples/runtime/shaders/gles/vs_bump.bin
new file mode 100644
index 00000000..d80c1728
Binary files /dev/null and b/examples/runtime/shaders/gles/vs_bump.bin differ
diff --git a/examples/runtime/shaders/gles/vs_cubes.bin b/examples/runtime/shaders/gles/vs_cubes.bin
index cf0dae0c..8852fe25 100644
Binary files a/examples/runtime/shaders/gles/vs_cubes.bin and b/examples/runtime/shaders/gles/vs_cubes.bin differ
diff --git a/examples/runtime/shaders/gles/vs_instancing.bin b/examples/runtime/shaders/gles/vs_instancing.bin
index be3c2945..694886a1 100644
Binary files a/examples/runtime/shaders/gles/vs_instancing.bin and b/examples/runtime/shaders/gles/vs_instancing.bin differ
diff --git a/examples/runtime/shaders/gles/vs_mesh.bin b/examples/runtime/shaders/gles/vs_mesh.bin
index d0530497..e68de896 100644
Binary files a/examples/runtime/shaders/gles/vs_mesh.bin and b/examples/runtime/shaders/gles/vs_mesh.bin differ
diff --git a/examples/runtime/shaders/gles/vs_metaballs.bin b/examples/runtime/shaders/gles/vs_metaballs.bin
index 1c4e22a3..4889e741 100644
Binary files a/examples/runtime/shaders/gles/vs_metaballs.bin and b/examples/runtime/shaders/gles/vs_metaballs.bin differ
diff --git a/examples/runtime/shaders/gles/vs_raymarching.bin b/examples/runtime/shaders/gles/vs_raymarching.bin
index a4f2dd24..a3d1ac14 100644
Binary files a/examples/runtime/shaders/gles/vs_raymarching.bin and b/examples/runtime/shaders/gles/vs_raymarching.bin differ
diff --git a/examples/runtime/shaders/glsl/fs_bump.bin b/examples/runtime/shaders/glsl/fs_bump.bin
new file mode 100644
index 00000000..f3ccd023
Binary files /dev/null and b/examples/runtime/shaders/glsl/fs_bump.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_bump.bin b/examples/runtime/shaders/glsl/vs_bump.bin
new file mode 100644
index 00000000..2de04a44
Binary files /dev/null and b/examples/runtime/shaders/glsl/vs_bump.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_cubes.bin b/examples/runtime/shaders/glsl/vs_cubes.bin
index 5ba478cc..ebd20cfe 100644
Binary files a/examples/runtime/shaders/glsl/vs_cubes.bin and b/examples/runtime/shaders/glsl/vs_cubes.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_instancing.bin b/examples/runtime/shaders/glsl/vs_instancing.bin
index 7dc59ffe..a425235d 100644
Binary files a/examples/runtime/shaders/glsl/vs_instancing.bin and b/examples/runtime/shaders/glsl/vs_instancing.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_mesh.bin b/examples/runtime/shaders/glsl/vs_mesh.bin
index 1d181bb5..d1772ea5 100644
Binary files a/examples/runtime/shaders/glsl/vs_mesh.bin and b/examples/runtime/shaders/glsl/vs_mesh.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_metaballs.bin b/examples/runtime/shaders/glsl/vs_metaballs.bin
index ef36031a..4c0cff6f 100644
Binary files a/examples/runtime/shaders/glsl/vs_metaballs.bin and b/examples/runtime/shaders/glsl/vs_metaballs.bin differ
diff --git a/examples/runtime/shaders/glsl/vs_raymarching.bin b/examples/runtime/shaders/glsl/vs_raymarching.bin
index a176305c..38bd7361 100644
Binary files a/examples/runtime/shaders/glsl/vs_raymarching.bin and b/examples/runtime/shaders/glsl/vs_raymarching.bin differ
diff --git a/examples/runtime/textures/fieldstone-n.dds b/examples/runtime/textures/fieldstone-n.dds
new file mode 100644
index 00000000..a09bc818
Binary files /dev/null and b/examples/runtime/textures/fieldstone-n.dds differ
diff --git a/examples/runtime/textures/fieldstone-rgba.dds b/examples/runtime/textures/fieldstone-rgba.dds
new file mode 100644
index 00000000..e64a0332
Binary files /dev/null and b/examples/runtime/textures/fieldstone-rgba.dds differ
diff --git a/include/bgfx.h b/include/bgfx.h
index 47c05972..e4874847 100644
--- a/include/bgfx.h
+++ b/include/bgfx.h
@@ -189,6 +189,7 @@ namespace bgfx
 		{
 			Position = 0,
 			Normal,
+			Tangent,
 			Color0,
 			Color1,
 			Indices,
@@ -283,7 +284,7 @@ namespace bgfx
 		VertexBufferHandle handle;
 	};
 
-	struct ConstantType
+	struct UniformType
 	{
 		enum Enum
 		{
@@ -327,7 +328,7 @@ namespace bgfx
 	RendererType::Enum getRendererType();
 
 	///
-	void init(bool _createRenderThread = true, FatalFn _fatal = NULL, ReallocFn _realloc = NULL, FreeFn _free = NULL, CacheFn _cache = NULL);
+	void init(FatalFn _fatal = NULL, ReallocFn _realloc = NULL, FreeFn _free = NULL, CacheFn _cache = NULL);
 
 	///
 	void shutdown();
@@ -365,10 +366,10 @@ namespace bgfx
 	///
 	void setDebug(uint32_t _debug);
 
-	///
+	/// Clear internal debug text buffer.
 	void dbgTextClear(uint8_t _attr = 0, bool _small = false);
 
-	///
+	/// Print into internal debug text buffer.
 	void dbgTextPrintf(uint16_t _x, uint16_t _y, uint8_t _attr, const char* _format, ...);
 
 	///
@@ -471,49 +472,57 @@ namespace bgfx
 	void destroyRenderTarget(RenderTargetHandle _handle);
 
 	///
-	UniformHandle createUniform(const char* _name, ConstantType::Enum _type, uint16_t _num = 1);
+	UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num = 1);
 
 	///
 	void destroyUniform(UniformHandle _handle);
 
-	///
+	/// Set view rectangle. Draw primitive outside view will be clipped.
 	void setViewRect(uint8_t _id, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
 
 	///
 	void setViewRectMask(uint32_t _viewMask, uint16_t _x, uint16_t _y, uint16_t _width, uint16_t _height);
 
-	///
+	/// Set view clear flags.
 	void setViewClear(uint8_t _id, uint8_t _flags, uint32_t _rgba = 0x000000ff, float _depth = 1.0f, uint8_t _stencil = 0);
 
 	///
 	void setViewClearMask(uint32_t _viewMask, uint8_t _flags, uint32_t _rgba = 0x000000ff, float _depth = 1.0f, uint8_t _stencil = 0);
 
-	///
+	/// Set view into sequential mode. Draw calls will be sorted in the same
+	/// order in which submit calls were called.
 	void setViewSeq(uint8_t _id, bool _enabled);
 
 	///
 	void setViewSeqMask(uint32_t _viewMask, bool _enabled);
 
-	///
+	/// Set view render target. View without render target draws primitives
+	/// into default backbuffer.
 	void setViewRenderTarget(uint8_t _id, RenderTargetHandle _handle);
 
 	///
 	void setViewRenderTargetMask(uint32_t _viewMask, RenderTargetHandle _handle);
 
-	///
+	/// Set view view and projection matrices, all draw primitives in this
+	/// view will use these matrices.
 	void setViewTransform(uint8_t _id, const void* _view, const void* _proj, uint8_t _other = 0xff);
 
 	///
 	void setViewTransformMask(uint32_t _viewMask, const void* _view, const void* _proj, uint8_t _other = 0xff);
 
-	///
+	/// Set render states for draw primitive.
+	///   BGFX_STATE_*
 	void setState(uint64_t _state);
 
+	/// Set model matrix for draw primitive. If it is not called model will
+	/// be rendered with identity model matrix.
 	///
+	/// Returns index into matrix cache in case the same model matrix has to
+	/// be used for other draw primitive call.
 	uint32_t setTransform(const void* _mtx, uint16_t _num = 1);
 
-	///
-	void setTransform(uint32_t _cache = 0, uint16_t _num = 1);
+	/// Set model matrix from matrix cache for draw primitive.
+	void setTransform(uint32_t _cache, uint16_t _num = 1);
 
 	///
 	void setUniform(UniformHandle _handle, const void* _value, uint16_t _num = 1);
@@ -543,7 +552,7 @@ namespace bgfx
 	void setVertexBuffer(const TransientVertexBuffer* _vb, uint32_t _numVertices = UINT32_MAX);
 
 	///
-	void setInstanceDataBuffer(const InstanceDataBuffer* _idb);
+	void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num = UINT16_MAX);
 
 	///
 	void setProgram(ProgramHandle _handle);
diff --git a/premake/example-05-instancing.lua b/premake/example-05-instancing.lua
index 3a354473..ba92b795 100644
--- a/premake/example-05-instancing.lua
+++ b/premake/example-05-instancing.lua
@@ -4,15 +4,9 @@ project "example-05-instancing"
 
 	debugdir (BGFX_DIR .. "examples/runtime/")
 
-	defines {
-		"OPENCTM_STATIC",
-		"OPENCTM_NO_CPP",
-	}
-
 	includedirs {
 		BGFX_DIR .. "../bx/include",
 		BGFX_DIR .. "include",
-		BGFX_DIR .. "3rdparty/openctm/lib",
 	}
 
 	files {
@@ -24,7 +18,6 @@ project "example-05-instancing"
 
 	links {
 		"bgfx",
-		"openctm",
 	}
 
 	configuration { "emscripten" }
diff --git a/premake/example-06-bump.lua b/premake/example-06-bump.lua
new file mode 100644
index 00000000..9d3ded55
--- /dev/null
+++ b/premake/example-06-bump.lua
@@ -0,0 +1,36 @@
+project "example-06-bump"
+	uuid "ffb23e6c-167b-11e2-81df-94c4dd6a022f"
+	kind "WindowedApp"
+
+	debugdir (BGFX_DIR .. "examples/runtime/")
+
+	includedirs {
+		BGFX_DIR .. "../bx/include",
+		BGFX_DIR .. "include",
+	}
+
+	files {
+		BGFX_DIR .. "examples/common/**.cpp",
+		BGFX_DIR .. "examples/common/**.h",
+		BGFX_DIR .. "examples/06-bump/**.cpp",
+		BGFX_DIR .. "examples/06-bump/**.h",
+	}
+
+	links {
+		"bgfx",
+	}
+
+	configuration { "nacl" }
+		targetextension ".nexe"
+
+	configuration { "nacl", "Release" }
+		postbuildcommands {
+			"@echo Stripping symbols.",
+			"@$(NACL)/bin/x86_64-nacl-strip -s \"$(TARGET)\""
+		}
+
+	configuration { "linux" }
+		links {
+			"GL",
+			"pthread",
+		}
diff --git a/premake/premake4.lua b/premake/premake4.lua
index 80cde35a..4f573186 100644
--- a/premake/premake4.lua
+++ b/premake/premake4.lua
@@ -153,7 +153,6 @@ configuration { "mingw" }
 	defines { "WIN32" }
 	includedirs { BX_DIR .. "include/compat/mingw" }
 	buildoptions {
-		"-std=c++0x",
 		"-U__STRICT_ANSI__",
 		"-Wunused-value",
 		"-fdata-sections",
@@ -164,6 +163,11 @@ configuration { "mingw" }
 		"-Wl,--gc-sections",
 	}
 
+configuration { "*.cpp", "mingw" }
+	buildoptions {
+		"-std=c++0x"
+	}
+
 configuration { "x32", "mingw" }
 	targetdir (BGFX_BUILD_DIR .. "win32_mingw" .. "/bin")
 	objdir (BGFX_BUILD_DIR .. "win32_mingw" .. "/obj")
@@ -178,7 +182,6 @@ configuration { "x64", "mingw" }
 
 configuration { "linux" }
 	buildoptions {
-		"-std=c++0x",
 		"-U__STRICT_ANSI__",
 		"-Wunused-value",
 		"-mfpmath=sse", -- force SSE to get 32-bit and 64-bit builds deterministic.
@@ -188,6 +191,11 @@ configuration { "linux" }
 		"-Wl,--gc-sections",
 	}
 
+configuration { "*.cpp", "linux" }
+	buildoptions {
+		"-std=c++0x"
+	}
+
 configuration { "linux", "x32" }
 	targetdir (BGFX_BUILD_DIR .. "linux32_gcc" .. "/bin")
 	objdir (BGFX_BUILD_DIR .. "linux32_gcc" .. "/obj")
@@ -217,7 +225,6 @@ configuration { "nacl" }
 	defines { "_BSD_SOURCE=1", "_POSIX_C_SOURCE=199506", "_XOPEN_SOURCE=600" }
 	includedirs { BX_DIR .. "include/compat/nacl" }
 	buildoptions {
-		"-std=c++0x",
 		"-U__STRICT_ANSI__",
 		"-pthread",
 		"-fno-stack-protector",
@@ -233,6 +240,11 @@ configuration { "nacl" }
 		"-Wl,--gc-sections",
 	}
 
+configuration { "*.cpp", "nacl" }
+	buildoptions {
+		"-std=c++0x"
+	}
+
 configuration { "x32", "nacl" }
 	targetdir (BGFX_BUILD_DIR .. "nacl-x86" .. "/bin")
 	objdir (BGFX_BUILD_DIR .. "nacl-x86" .. "/obj")
@@ -271,3 +283,4 @@ dofile "example-02-metaballs.lua"
 dofile "example-03-raymarch.lua"
 dofile "example-04-mesh.lua"
 dofile "example-05-instancing.lua"
+dofile "example-06-bump.lua"
diff --git a/premake/shader.mk b/premake/shader.mk
index de365e44..31c6e7db 100644
--- a/premake/shader.mk
+++ b/premake/shader.mk
@@ -64,12 +64,12 @@ ASM = $(VS_ASM) $(FS_ASM)
 
 $(BUILD_INTERMEDIATE_DIR)/vs_%.bin : vs_%.sc
 	@echo [$(<)]
-	@$(SHADERC) $(VS_FLAGS) --type vertex --depends -o $(@) -f $(<)
+	@$(SHADERC) $(VS_FLAGS) --type vertex --depends -o $(@) -f $(<) --disasm
 	@cp $(@) $(BUILD_OUTPUT_DIR)/$(@F)
 
 $(BUILD_INTERMEDIATE_DIR)/fs_%.bin : fs_%.sc
 	@echo [$(<)]
-	@$(SHADERC) $(FS_FLAGS) --type fragment --depends -o $(@) -f $(<)
+	@$(SHADERC) $(FS_FLAGS) --type fragment --depends -o $(@) -f $(<) --disasm
 	@cp $(@) $(BUILD_OUTPUT_DIR)/$(@F)
 
 .PHONY: all
diff --git a/premake/shaderc.lua b/premake/shaderc.lua
index b471d17c..98b6242b 100644
--- a/premake/shaderc.lua
+++ b/premake/shaderc.lua
@@ -10,11 +10,16 @@ project "shaderc"
 			GLSL_OPTIMIZER .. "src/glsl/msvc",
 		}
 
-	configuration { "windows" }
+	configuration { "windows", "vs*" }
 		includedirs {
 			GLSL_OPTIMIZER .. "include/c99",
 		}
 
+	configuration { "windows" }
+		includedirs {
+			"$(DXSDK_DIR)/include",
+		}
+
 		links {
 			"d3dx9",
 			"d3dcompiler",
@@ -23,6 +28,12 @@ project "shaderc"
 
 	configuration {}
 
+	defines { -- fcpp
+		"NINCLUDE=64",
+		"NWORK=65536",
+		"NBUFF=65536",
+	}
+
 	includedirs {
 		BGFX_DIR .. "../bx/include",
 
diff --git a/src/bgfx.cpp b/src/bgfx.cpp
index 4a9bf316..757f6051 100644
--- a/src/bgfx.cpp
+++ b/src/bgfx.cpp
@@ -517,7 +517,7 @@ namespace bgfx
 #endif // BGFX_CONFIG_RENDERER_
 	}
 
-	void init(bool _createRenderThread, FatalFn _fatal, ReallocFn _realloc, FreeFn _free, CacheFn _cache)
+	void init(FatalFn _fatal, ReallocFn _realloc, FreeFn _free, CacheFn _cache)
 	{
 		if (NULL != _fatal)
 		{
@@ -537,7 +537,9 @@ namespace bgfx
 		}
 
 		s_threadIndex = BGFX_MAIN_THREAD_MAGIC;
-		s_ctx.init(_createRenderThread);
+
+		// On NaCl renderer is on the main thread.
+		s_ctx.init(!BX_PLATFORM_NACL);
 	}
 
 	void shutdown()
@@ -669,7 +671,7 @@ namespace bgfx
 #endif // BGFX_CONFIG_DEBUG
 	}
 
-	const uint32_t g_constantTypeSize[ConstantType::Count] =
+	const uint32_t g_uniformTypeSize[UniformType::Count] =
 	{
 		sizeof(int32_t),
 		sizeof(float),
@@ -683,14 +685,14 @@ namespace bgfx
 		4*4*sizeof(float),
 	};
 
-	void ConstantBuffer::writeUniform(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
+	void ConstantBuffer::writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
 	{
 		uint32_t opcode = encodeOpcode(_type, _loc, _num, true);
 		write(opcode);
-		write(_value, g_constantTypeSize[_type]*_num);
+		write(_value, g_uniformTypeSize[_type]*_num);
 	}
 
-	void ConstantBuffer::writeUniformRef(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
+	void ConstantBuffer::writeUniformRef(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num)
 	{
 		uint32_t opcode = encodeOpcode(_type, _loc, _num, false);
 		write(opcode);
@@ -722,7 +724,7 @@ namespace bgfx
 		{
 #	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
 			m_renderThread = CreateThread(NULL, 16<<10, renderThread, NULL, 0, NULL);
-#	elif BX_PLATFORM_LINUX
+#	elif BX_PLATFORM_POSIX
 			pthread_create(&m_renderThread, NULL, renderThread, NULL);
 #	endif // BX_PLATFORM_
 		}
@@ -770,7 +772,7 @@ namespace bgfx
 #	if BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360
 			WaitForSingleObject(m_renderThread, INFINITE);
 			m_renderThread = NULL;
-#	elif BX_PLATFORM_LINUX
+#	elif BX_PLATFORM_POSIX
 			pthread_join(m_renderThread, NULL);
 			m_renderThread = 0;
 #	endif // BX_PLATFORM_*
@@ -1085,7 +1087,7 @@ namespace bgfx
 		s_ctx.destroyRenderTarget(_handle);
 	}
 
-	UniformHandle createUniform(const char* _name, ConstantType::Enum _type, uint16_t _num)
+	UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
 	{
 		return s_ctx.createUniform(_name, _type, _num);
 	}
@@ -1211,9 +1213,9 @@ namespace bgfx
 		s_ctx.m_submit->setVertexBuffer(_vb, _numVertices);
 	}
 
-	void setInstanceDataBuffer(const InstanceDataBuffer* _idb)
+	void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)
 	{
-		s_ctx.m_submit->setInstanceDataBuffer(_idb);
+		s_ctx.m_submit->setInstanceDataBuffer(_idb, _num);
 	}
 
 	void setProgram(ProgramHandle _handle)
diff --git a/src/bgfx_p.h b/src/bgfx_p.h
index edfa51f5..01c3c097 100644
--- a/src/bgfx_p.h
+++ b/src/bgfx_p.h
@@ -179,7 +179,7 @@ namespace bgfx
 		const Memory* m_mem;
 	};
 
-	extern const uint32_t g_constantTypeSize[ConstantType::Count];
+	extern const uint32_t g_uniformTypeSize[UniformType::Count];
 	extern FatalFn g_fatal;
 	extern ReallocFn g_realloc;
 	extern FreeFn g_free;
@@ -696,9 +696,9 @@ namespace bgfx
 		uint16_t m_flags;
 	};
 	
-	struct Constant
+	struct Uniform
 	{
-		ConstantType::Enum m_type;
+		UniformType::Enum m_type;
 		uint16_t m_num;
 	};
 
@@ -733,7 +733,7 @@ namespace bgfx
 			g_free(_constantBuffer);
 		}
 
-		static uint32_t encodeOpcode(ConstantType::Enum _type, uint16_t _loc, uint16_t _num, uint16_t _copy)
+		static uint32_t encodeOpcode(UniformType::Enum _type, uint16_t _loc, uint16_t _num, uint16_t _copy)
 		{
 			uint32_t opcode = 0;
 
@@ -752,7 +752,7 @@ namespace bgfx
 			return opcode;
 		}
 
-		static void decodeOpcode(uint32_t _opcode, ConstantType::Enum& _type, uint16_t& _loc, uint16_t& _num, uint16_t& _copy)
+		static void decodeOpcode(uint32_t _opcode, UniformType::Enum& _type, uint16_t& _loc, uint16_t& _num, uint16_t& _copy)
 		{
 			uint32_t copy;
 			uint32_t num;
@@ -767,7 +767,7 @@ namespace bgfx
 			loc = _opcode&CONSTANT_OPCODE_LOC_MASK;
 			_opcode >>= CONSTANT_OPCODE_LOC_BITS;
 
-			_type = (ConstantType::Enum)(_opcode&CONSTANT_OPCODE_TYPE_MASK);
+			_type = (UniformType::Enum)(_opcode&CONSTANT_OPCODE_TYPE_MASK);
 			_opcode >>= CONSTANT_OPCODE_TYPE_BITS;
 
 			_copy = (uint16_t)copy;
@@ -822,12 +822,12 @@ namespace bgfx
 
 		void finish()
 		{
-			write(ConstantType::End);
+			write(UniformType::End);
 			m_pos = 0;
 		}
 
-		void writeUniform(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
-		void writeUniformRef(ConstantType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
+		void writeUniform(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
+		void writeUniformRef(UniformType::Enum _type, uint16_t _loc, const void* _value, uint16_t _num = 1);
 		void commit();
 
 	private:
@@ -878,9 +878,9 @@ namespace bgfx
  			return NULL;
  		}
 
-		const UniformInfo& reg(const char* _name, const void* _data, UniformFn _func = NULL)
+		const UniformInfo& add(const char* _name, const void* _data, UniformFn _func = NULL)
 		{
-			UniformHashMap::const_iterator it = m_uniforms.find(_name);
+			UniformHashMap::iterator it = m_uniforms.find(_name);
 			if (it == m_uniforms.end() )
 			{
 				UniformInfo info;
@@ -1141,13 +1141,13 @@ namespace bgfx
 			g_free(const_cast<TransientVertexBuffer*>(_vb) );
 		}
 
-		void setInstanceDataBuffer(const InstanceDataBuffer* _idb)
+		void setInstanceDataBuffer(const InstanceDataBuffer* _idb, uint16_t _num)
 		{
 #if BGFX_CONFIG_RENDERER_OPENGLES2
 #else
  			m_state.m_instanceDataOffset = _idb->offset;
 			m_state.m_instanceDataStride = _idb->stride;
-			m_state.m_numInstances = _idb->num;
+			m_state.m_numInstances = uint16_min(_idb->num, _num);
 			m_state.m_instanceDataBuffer = _idb->handle;
 			g_free(const_cast<InstanceDataBuffer*>(_idb) );
 #endif // BGFX_CONFIG_RENDERER_OPENGLES
@@ -1227,7 +1227,7 @@ namespace bgfx
 			return offset;
 		}
 
-		void writeConstant(ConstantType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
+		void writeConstant(UniformType::Enum _type, UniformHandle _handle, const void* _value, uint16_t _num)
 		{
 			m_constantBuffer->writeUniform(_type, _handle.idx, _value, _num);
 		}
@@ -1517,7 +1517,7 @@ namespace bgfx
 
 #if BX_PLATFORM_WINDOWS || BX_PLATFORM_XBOX360
 	DWORD WINAPI renderThread(LPVOID _arg);
-#elif BX_PLATFORM_LINUX
+#elif BX_PLATFORM_POSIX
 	void* renderThread(void*);
 #endif // BX_PLATFORM_
 
@@ -2092,15 +2092,15 @@ namespace bgfx
 			m_submit->free(_handle);
 		}
 
-		UniformHandle createUniform(const char* _name, ConstantType::Enum _type, uint16_t _num)
+		UniformHandle createUniform(const char* _name, UniformType::Enum _type, uint16_t _num)
 		{
 			BX_CHECK(PredefinedUniform::Count == nameToPredefinedUniformEnum(_name), "%s is predefined uniform name.", _name);
 
 			UniformHandle handle = { m_uniformHandle.alloc() };
 
-			Constant& constant = m_constant[handle.idx];
-			constant.m_type = _type;
-			constant.m_num = _num;
+			Uniform& uniform = m_uniform[handle.idx];
+			uniform.m_type = _type;
+			uniform.m_num = _num;
 
 			CommandBuffer& cmdbuf = getCommandBuffer(CommandBuffer::CreateUniform);
 			cmdbuf.write(handle);
@@ -2127,9 +2127,9 @@ namespace bgfx
 
 		void setUniform(UniformHandle _handle, const void* _value, uint16_t _num)
 		{
-			Constant& constant = m_constant[_handle.idx];
-			BX_CHECK(constant.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, constant.m_num);
-			m_submit->writeConstant(constant.m_type, _handle, _value, uint16_min(constant.m_num, _num) );
+			Uniform& uniform = m_uniform[_handle.idx];
+			BX_CHECK(uniform.m_num >= _num, "Truncated uniform update. %d (max: %d)", _num, uniform.m_num);
+			m_submit->writeConstant(uniform.m_type, _handle, _value, uint16_min(uniform.m_num, _num) );
 		}
 
 		void setUniform(ProgramHandle /*_program*/, UniformHandle /*_handle*/, const void* /*_value*/)
@@ -2356,7 +2356,7 @@ namespace bgfx
 		void rendererDestroyTexture(TextureHandle _handle);
 		void rendererCreateRenderTarget(RenderTargetHandle _handle, uint16_t _width, uint16_t _height, uint32_t _flags, uint32_t _textureFlags);
 		void rendererDestroyRenderTarget(RenderTargetHandle _handle);
-		void rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name);
+		void rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name);
 		void rendererDestroyUniform(UniformHandle _handle);
 		void rendererSaveScreenShot(Memory* _mem);
 		void rendererUpdateUniform(uint16_t _loc, const void* _data, uint32_t _size);
@@ -2368,19 +2368,19 @@ namespace bgfx
 			{
 				uint32_t opcode = _constantBuffer->read();
 
-				if (ConstantType::End == opcode)
+				if (UniformType::End == opcode)
 				{
 					break;
 				}
 
-				ConstantType::Enum type;
+				UniformType::Enum type;
 				uint16_t loc;
 				uint16_t num;
 				uint16_t copy;
 				ConstantBuffer::decodeOpcode(opcode, type, loc, num, copy);
 
 				const char* data;
-				uint32_t size = g_constantTypeSize[type]*num;
+				uint32_t size = g_uniformTypeSize[type]*num;
 				data = _constantBuffer->read(size);
 				rendererUpdateUniform(loc, data, size);
 			}
@@ -2726,7 +2726,7 @@ namespace bgfx
 						UniformHandle handle;
 						_cmdbuf.read(handle);
 
-						ConstantType::Enum type;
+						UniformType::Enum type;
 						_cmdbuf.read(type);
 
 						uint16_t num;
@@ -2875,7 +2875,7 @@ namespace bgfx
 		RenderTargetHandle m_rt[BGFX_CONFIG_MAX_VIEWS];
 		Clear m_clear[BGFX_CONFIG_MAX_VIEWS];
 		Rect m_rect[BGFX_CONFIG_MAX_VIEWS];
-		Constant m_constant[BGFX_CONFIG_MAX_UNIFORMS];
+		Uniform m_uniform[BGFX_CONFIG_MAX_UNIFORMS];
 		uint16_t m_seq[BGFX_CONFIG_MAX_VIEWS];
 		uint16_t m_seqMask[BGFX_CONFIG_MAX_VIEWS];
 
diff --git a/src/bgfx_shader.sh b/src/bgfx_shader.sh
index b820a908..14771734 100644
--- a/src/bgfx_shader.sh
+++ b/src/bgfx_shader.sh
@@ -13,20 +13,56 @@
 #	define dFdy ddy
 
 #	if BGFX_SHADER_LANGUAGE_HLSL > 3
+struct BgfxSampler2D
+{
+	SamplerState m_sampler;
+	Texture2D m_texture;
+};
+
+vec4 bgfxTexture2D(BgfxSampler2D _sampler, vec2 _coord)
+{
+	return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
+}
+
+struct BgfxSampler3D
+{
+	SamplerState m_sampler;
+	Texture3D m_texture;
+};
+
+vec4 bgfxTexture3D(BgfxSampler3D _sampler, vec3 _coord)
+{
+	return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
+}
+
+struct BgfxSamplerCube
+{
+	SamplerState m_sampler;
+	TextureCube m_texture;
+};
+
+vec4 bgfxTextureCube(BgfxSamplerCube _sampler, vec3 _coord)
+{
+	return _sampler.m_texture.Sample(_sampler.m_sampler, _coord);
+}
+
 #		define SAMPLER2D(_name, _reg) \
-					uniform SamplerState _name ## Sampler : register(s[_reg]); \
-					uniform Texture2D _name : register(t[_reg])
-#		define texture2D(_name, _coord) _name.Sample(_name ## Sampler, _coord)
+			uniform SamplerState _name ## Sampler : register(s[_reg]); \
+			uniform Texture2D _name ## Texture : register(t[_reg]); \
+			static BgfxSampler2D _name = { _name ## Sampler, _name ## Texture }
+#		define texture2D(_name, _coord) bgfxTexture2D(_name, _coord)
 
 #		define SAMPLER3D(_name, _reg) \
-					uniform SamplerState _name : register(s[_reg]) \
-					uniform Texture3D _name : register(t[_reg])
-#		define texture3D(_name, _coord) _name.Sample(_name ## Sampler, _coord)
+			uniform SamplerState _name ## Sampler : register(s[_reg]); \
+			uniform Texture3D _name ## Texture : register(t[_reg]); \
+			static BgfxSampler3D _name = { _name ## Sampler, _name ## Texture }
+#		define texture3D(_name, _coord) bgfxTexture3D(_name, _coord)
 
 #		define SAMPLERCUBE(_name, _reg) \
-					uniform SamplerState _name ## Sampler : register(s[_reg]); \
-					uniform TextureCube _name : register(t[_reg])
-#		define textureCube(_name, _coord) _name.Sample(_name ## Sampler, _coord)
+			uniform SamplerState _name ## Sampler : register(s[_reg]); \
+			uniform TextureCube _name ## Texture : register(t[_reg]); \
+			static BgfxSamplerCube _name = { _name ## Sampler, _name ## Texture }
+#		define textureCube(_name, _coord) bgfxTextureCube(_name, _coord)
 #	else
 #		define SAMPLER2D(_name, _reg) uniform sampler2D _name : register(s ## _reg)
 #		define texture2D tex2D
@@ -45,8 +81,9 @@ vec4 instMul(mat4 _mtx, vec4 _vec)
 	return mul(_vec, _mtx);
 }
 #elif BGFX_SHADER_LANGUAGE_GLSL
-#	define frac fract
-#	define lerp mix
+#	define atan2(_x, _y) atan(_x, _y)
+#	define frac(_x) fract(_x)
+#	define lerp(_x, _y, _t) mix(_x, _y, _t)
 #	define mul(_a, _b) ( (_a) * (_b) )
 #	define saturate(_x) clamp(_x, 0.0, 1.0)
 #	define SAMPLER2D(_name, _reg) uniform sampler2D _name
diff --git a/src/common.sh b/src/common.sh
index 0ae6ab27..8463b8a1 100644
--- a/src/common.sh
+++ b/src/common.sh
@@ -16,6 +16,4 @@ uniform mat4 u_modelViewProj;
 uniform mat4 u_modelViewProjX;
 uniform mat4 u_viewProjX;
 
-SAMPLER2D(u_texColor, 0);
-
 #endif // __SHADER_COMMON_H__
diff --git a/src/config.h b/src/config.h
index 8701aac2..39cf7834 100644
--- a/src/config.h
+++ b/src/config.h
@@ -14,34 +14,45 @@
 	&& !defined(BGFX_CONFIG_RENDERER_NULL)
 
 #	ifndef BGFX_CONFIG_RENDERER_DIRECT3D9
-#		define BGFX_CONFIG_RENDERER_DIRECT3D9 (BX_PLATFORM_WINDOWS|BX_PLATFORM_XBOX360)
+#		define BGFX_CONFIG_RENDERER_DIRECT3D9 (0 \
+					| BX_PLATFORM_WINDOWS \
+					| BX_PLATFORM_XBOX360 \
+					)
 #	endif // BGFX_CONFIG_RENDERER_DIRECT3D9
 
 #	ifndef BGFX_CONFIG_RENDERER_DIRECT3D11
-#		define BGFX_CONFIG_RENDERER_DIRECT3D11 0
+#		define BGFX_CONFIG_RENDERER_DIRECT3D11 (0 \
+					)
 #	endif // BGFX_CONFIG_RENDERER_DIRECT3D11
 
 #	ifndef BGFX_CONFIG_RENDERER_OPENGL
-#		define BGFX_CONFIG_RENDERER_OPENGL (BX_PLATFORM_LINUX|BX_PLATFORM_OSX)
+#		define BGFX_CONFIG_RENDERER_OPENGL (0 \
+					| BX_PLATFORM_LINUX \
+					| BX_PLATFORM_OSX \
+					)
 #	endif // BGFX_CONFIG_RENDERER_OPENGL
 
 #	ifndef BGFX_CONFIG_RENDERER_OPENGLES2
-#		define BGFX_CONFIG_RENDERER_OPENGLES2 (BX_PLATFORM_EMSCRIPTEN \
-					|BX_PLATFORM_NACL \
-					|BX_PLATFORM_ANDROID \
-					|BX_PLATFORM_IOS)
+#		define BGFX_CONFIG_RENDERER_OPENGLES2 (0 \
+					| BX_PLATFORM_EMSCRIPTEN \
+					| BX_PLATFORM_NACL \
+					| BX_PLATFORM_ANDROID \
+					| BX_PLATFORM_IOS \
+					)
 #	endif // BGFX_CONFIG_RENDERER_OPENGLES2
 
 #	ifndef BGFX_CONFIG_RENDERER_OPENGLES3
-#		define BGFX_CONFIG_RENDERER_OPENGLES3 0
+#		define BGFX_CONFIG_RENDERER_OPENGLES3 (0 \
+					)
 #	endif // BGFX_CONFIG_RENDERER_OPENGLES3
 
 #	ifndef BGFX_CONFIG_RENDERER_NULL
-#		define BGFX_CONFIG_RENDERER_NULL (!(BGFX_CONFIG_RENDERER_DIRECT3D9 \
-					|BGFX_CONFIG_RENDERER_DIRECT3D11 \
-					|BGFX_CONFIG_RENDERER_OPENGL \
-					|BGFX_CONFIG_RENDERER_OPENGLES2 \
-					|BGFX_CONFIG_RENDERER_OPENGLES3 \
+#		define BGFX_CONFIG_RENDERER_NULL (!(0 \
+					| BGFX_CONFIG_RENDERER_DIRECT3D9 \
+					| BGFX_CONFIG_RENDERER_DIRECT3D11 \
+					| BGFX_CONFIG_RENDERER_OPENGL \
+					| BGFX_CONFIG_RENDERER_OPENGLES2 \
+					| BGFX_CONFIG_RENDERER_OPENGLES3 \
 					) )
 #	endif // BGFX_CONFIG_RENDERER_NULL
 #endif // !defined...
diff --git a/src/fs_clear_dx11.bin.h b/src/fs_clear_dx11.bin.h
index d2662ee6..47959dbf 100644
--- a/src/fs_clear_dx11.bin.h
+++ b/src/fs_clear_dx11.bin.h
@@ -1,38 +1,38 @@
-static const uint8_t fs_clear_dx11[553] =
+static const uint8_t fs_clear_dx11[554] =
 {
-	0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x14, 0x02, 0x44, 0x58, 0x42, 0x43, 0xda, 0x0f, 0xc3, 0x91, 0x70, 0x6f, 0xd4, 0x7b, // ....DXBC....po.{
-	0xeb, 0xe0, 0x21, 0x07, 0x79, 0xd8, 0x54, 0xd4, 0x01, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, 0x00, // ..!.y.T.........
-	0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ....4...........
-	0x34, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, 0x00, 0x00, // 4...x...RDEFp...
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, // ............<...
-	0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, // ........<...RD11
-	0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, // <....... ...(...
-	0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, // $...........Micr
-	0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, // osoft (R) HLSL S
-	0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, // hader Compiler 9
-	0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, // .29.952.3111....
-	0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ISGNL...........
-	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // 8...............
-	0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........D.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, // ................
-	0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, // SV_POSITION.COLO
-	0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // R...OSGN,.......
-	0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .... ...........
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, // ............SV_T
-	0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x3c, 0x00, 0x00, 0x00, // ARGET...SHEX<...
-	0x50, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x62, 0x10, 0x00, 0x03, // P.......j...b...
-	0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, // ........e.... ..
-	0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // ....6.... ......
-	0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, // F.......>...STAT
-	0x94, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x14, 0x02, 0x44, 0x58, 0x42, 0x43, 0xda, 0x0f, 0xc3, 0x91, 0x70, 0x6f, 0xd4, // .....DXBC....po.
+	0x7b, 0xeb, 0xe0, 0x21, 0x07, 0x79, 0xd8, 0x54, 0xd4, 0x01, 0x00, 0x00, 0x00, 0x14, 0x02, 0x00, // {..!.y.T........
+	0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // .....4..........
+	0x00, 0x34, 0x01, 0x00, 0x00, 0x78, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, 0x00, // .4...x...RDEFp..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, // .............<..
+	0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, // .........<...RD1
+	0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, // 1<....... ...(..
+	0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, // .$...........Mic
+	0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, // rosoft (R) HLSL 
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, // Shader Compiler 
+	0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, // 9.29.952.3111...
+	0xab, 0x49, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, // .ISGNL..........
+	0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .8..............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........D......
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, // ................
+	0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, // .SV_POSITION.COL
+	0x4f, 0x52, 0x00, 0xab, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // OR...OSGN,......
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ..... ..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, // .............SV_
+	0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x3c, 0x00, 0x00, // TARGET...SHEX<..
+	0x00, 0x50, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x62, 0x10, 0x00, // .P.......j...b..
+	0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, // .........e.... .
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // .....6.... .....
+	0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, // .F.......>...STA
+	0x54, 0x94, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // T...............
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                           // .........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                     // ..........
 };
diff --git a/src/fs_debugfont.sc b/src/fs_debugfont.sc
index 2261fabe..bfbf96b7 100644
--- a/src/fs_debugfont.sc
+++ b/src/fs_debugfont.sc
@@ -7,6 +7,8 @@ $input v_color0, v_color1, v_texcoord0
 
 #include "common.sh"
 
+SAMPLER2D(u_texColor, 0);
+
 void main()
 {
 	vec4 color = lerp(v_color1, v_color0, texture2D(u_texColor, v_texcoord0).xxxx);
diff --git a/src/fs_debugfont_dx11.bin.h b/src/fs_debugfont_dx11.bin.h
index 4d083fff..aa93167a 100644
--- a/src/fs_debugfont_dx11.bin.h
+++ b/src/fs_debugfont_dx11.bin.h
@@ -1,61 +1,61 @@
-static const uint8_t fs_debugfont_dx11[913] =
+static const uint8_t fs_debugfont_dx11[922] =
 {
-	0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x7c, 0x03, 0x44, 0x58, 0x42, 0x43, 0xd3, 0x76, 0x1b, 0xcc, 0x1f, 0xe1, 0xf5, 0xdf, // ..|.DXBC.v......
-	0xf3, 0xe2, 0xb1, 0x53, 0x82, 0xc1, 0xcf, 0x87, 0x01, 0x00, 0x00, 0x00, 0x7c, 0x03, 0x00, 0x00, // ...S........|...
-	0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x08, 0x01, 0x00, 0x00, 0x94, 0x01, 0x00, 0x00, // ....4...........
-	0xc8, 0x01, 0x00, 0x00, 0xe0, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xcc, 0x00, 0x00, 0x00, // ........RDEF....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, // ............<...
-	0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0x99, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, // ............RD11
-	0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, // <....... ...(...
-	0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, 0x00, // $...........|...
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, 0x00, // ................
-	0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, // ................
-	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x74, 0x65, // ............u_te
-	0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x75, 0x5f, // xColorSampler.u_
-	0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, // texColor.Microso
-	0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, // ft (R) HLSL Shad
-	0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, // er Compiler 9.29
-	0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, // .952.3111...ISGN
-	0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, // ............h...
-	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....t...........
-	0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, // ............t...
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ................
-	0x0f, 0x0f, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ....z...........
-	0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, // ............SV_P
-	0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, // OSITION.COLOR.TE
-	0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, // XCOORD..OSGN,...
-	0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........ .......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, // ................
-	0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, 0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, // SV_TARGET...SHEX
-	0x10, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, // ....P...D...j...
-	0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, // Z....`......X...
-	0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, // .p......UU..b...
-	0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, // ........b.......
-	0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, // ....b...2.......
-	0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, // e.... ......h...
-	0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, 0x8b, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, // ....E.......CU..
-	0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, // ........F.......
-	0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // F~.......`......
-	0x00, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, // ............F...
-	0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x80, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ....F...A.......
-	0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, // 2...............
-	0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, // ....F.......F...
-	0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, 0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ....1...........
-	0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, 0x81, 0x80, 0x80, 0x3b, // :........@.....;
-	0x0d, 0x00, 0x04, 0x03, 0x0a, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, // ............6...
-	0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // . ......F.......
-	0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, // >...STAT........
-	0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x84, 0x03, 0x44, 0x58, 0x42, 0x43, 0x7f, 0x04, 0x32, 0xab, 0xf6, 0xa8, 0x90, // .....DXBC..2....
+	0xe5, 0x2c, 0xd4, 0x3b, 0xd7, 0xa9, 0x89, 0x79, 0xfd, 0x01, 0x00, 0x00, 0x00, 0x84, 0x03, 0x00, // .,.;...y........
+	0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x10, 0x01, 0x00, 0x00, 0x9c, 0x01, 0x00, // .....4..........
+	0x00, 0xd0, 0x01, 0x00, 0x00, 0xe8, 0x02, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0xd4, 0x00, 0x00, // .........RDEF...
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, // .............<..
+	0x00, 0x00, 0x05, 0xff, 0xff, 0x00, 0x91, 0x00, 0x00, 0xa0, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, // .............RD1
+	0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, // 1<....... ...(..
+	0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x7c, 0x00, 0x00, // .$...........|..
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x8e, 0x00, 0x00, // ................
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, // ................
+	0xff, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0d, 0x00, 0x00, 0x00, 0x75, 0x5f, 0x74, // .............u_t
+	0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x53, 0x61, 0x6d, 0x70, 0x6c, 0x65, 0x72, 0x00, 0x75, // exColorSampler.u
+	0x5f, 0x74, 0x65, 0x78, 0x43, 0x6f, 0x6c, 0x6f, 0x72, 0x54, 0x65, 0x78, 0x74, 0x75, 0x72, 0x65, // _texColorTexture
+	0x00, 0x4d, 0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, // .Microsoft (R) H
+	0x4c, 0x53, 0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, // LSL Shader Compi
+	0x6c, 0x65, 0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, // ler 9.29.952.311
+	0x31, 0x00, 0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x84, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, // 1....ISGN.......
+	0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // .....h..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, // .............t..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................
+	0x00, 0x0f, 0x0f, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .....t..........
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x7a, 0x00, 0x00, // .............z..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // ................
+	0x00, 0x03, 0x03, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, // .....SV_POSITION
+	0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, // .COLOR.TEXCOORD.
+	0xab, 0x4f, 0x53, 0x47, 0x4e, 0x2c, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, // .OSGN,..........
+	0x00, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // . ..............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x54, 0x41, 0x52, 0x47, // .........SV_TARG
+	0x45, 0x54, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x10, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, // ET...SHEX....P..
+	0x00, 0x44, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5a, 0x00, 0x00, 0x03, 0x00, 0x60, 0x10, // .D...j...Z....`.
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x58, 0x18, 0x00, 0x04, 0x00, 0x70, 0x10, 0x00, 0x00, 0x00, 0x00, // .....X....p.....
+	0x00, 0x55, 0x55, 0x00, 0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, // .UU..b..........
+	0x00, 0x62, 0x10, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x62, 0x10, 0x00, // .b...........b..
+	0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, // .2.......e.... .
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x02, 0x02, 0x00, 0x00, 0x00, 0x45, 0x00, 0x00, // .....h.......E..
+	0x8b, 0xc2, 0x00, 0x00, 0x80, 0x43, 0x55, 0x15, 0x00, 0x12, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // .....CU.........
+	0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x7e, 0x10, 0x00, 0x00, 0x00, 0x00, // .F.......F~.....
+	0x00, 0x00, 0x60, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, // ..`.............
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, // .....F.......F..
+	0x80, 0x41, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x09, 0xf2, 0x00, 0x10, // .A.......2......
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x06, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, // .............F..
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x31, 0x00, 0x00, // .....F.......1..
+	0x07, 0x12, 0x00, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3a, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, // .........:......
+	0x00, 0x01, 0x40, 0x00, 0x00, 0x81, 0x80, 0x80, 0x3b, 0x0d, 0x00, 0x04, 0x03, 0x0a, 0x00, 0x10, // ..@.....;.......
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, // .....6.... .....
+	0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, // .F.......>...STA
+	0x54, 0x94, 0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // T...............
+	0x00, 0x04, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00,                                                                                           // .
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                     // ..........
 };
diff --git a/src/renderer_d3d11.cpp b/src/renderer_d3d11.cpp
index 16a1550b..c83a4e32 100644
--- a/src/renderer_d3d11.cpp
+++ b/src/renderer_d3d11.cpp
@@ -102,6 +102,7 @@ namespace bgfx
 	{
 		{ "POSITION",     0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 		{ "NORMAL",       0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
+		{ "TANGENT",      0, DXGI_FORMAT_R32G32B32_FLOAT, 0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 		{ "COLOR",        0, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 		{ "COLOR",        1, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
 		{ "BLENDINDICES", 0, DXGI_FORMAT_R8G8B8A8_UINT,   0, D3D11_APPEND_ALIGNED_ELEMENT, D3D11_INPUT_PER_VERTEX_DATA, 0 },
@@ -324,8 +325,8 @@ namespace bgfx
 
 			for (uint32_t ii = 0; ii < PredefinedUniform::Count; ++ii)
 			{
-				m_predefinedUniforms[ii].create(ConstantType::Uniform4x4fv, 1, false);
-				m_uniformReg.reg(getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
+				m_predefinedUniforms[ii].create(UniformType::Uniform4x4fv, 1, false);
+				m_uniformReg.add(getPredefinedUniformName(PredefinedUniform::Enum(ii) ), &m_predefinedUniforms[ii]);
 			}
 
 			postReset();
@@ -773,8 +774,8 @@ namespace bgfx
 		Texture m_textures[BGFX_CONFIG_MAX_TEXTURES];
 		VertexDecl m_vertexDecls[BGFX_CONFIG_MAX_VERTEX_DECLS];
 		RenderTarget m_renderTargets[BGFX_CONFIG_MAX_RENDER_TARGETS];
-		Uniform m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
-		Uniform m_predefinedUniforms[PredefinedUniform::Count];
+		UniformBuffer m_uniforms[BGFX_CONFIG_MAX_UNIFORMS];
+		UniformBuffer m_predefinedUniforms[PredefinedUniform::Count];
 		UniformRegistry m_uniformReg;
 		
 		StateCacheT<ID3D11BlendState> m_blendStateCache;
@@ -911,12 +912,12 @@ namespace bgfx
 		{
 			uint32_t opcode = read();
 
-			if (ConstantType::End == opcode)
+			if (UniformType::End == opcode)
 			{
 				break;
 			}
 
-			ConstantType::Enum type;
+			UniformType::Enum type;
 			uint16_t loc;
 			uint16_t num;
 			uint16_t copy;
@@ -925,7 +926,7 @@ namespace bgfx
 			const char* data;
 			if (copy)
 			{
-				data = read(g_constantTypeSize[type]*num);
+				data = read(g_uniformTypeSize[type]*num);
 			}
 			else
 			{
@@ -933,8 +934,8 @@ namespace bgfx
 			}
 
 #define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
-		case ConstantType::_uniform: \
-		case ConstantType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
+		case UniformType::_uniform: \
+		case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
 			{ \
 				s_renderCtx.setShaderConstant(type, loc, data, num); \
 			} \
@@ -952,7 +953,7 @@ namespace bgfx
 				CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
 				CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
 
-			case ConstantType::End:
+			case UniformType::End:
 				break;
 
 			default:
@@ -1183,13 +1184,13 @@ namespace bgfx
 			else
 			{
 				const UniformInfo* info = s_renderCtx.m_uniformReg.find(name);
-				Uniform* uniform = info != NULL ? (Uniform*)info->m_data : NULL;
+				UniformBuffer* uniform = info != NULL ? (UniformBuffer*)info->m_data : NULL;
 
 				if (NULL != uniform)
 				{
 					kind = "user";
 					data = uniform->m_data;
-					m_constantBuffer->writeUniformRef( (ConstantType::Enum)(type|fragmentBit), regIndex, data, regCount);
+					m_constantBuffer->writeUniformRef( (UniformType::Enum)(type|fragmentBit), regIndex, data, regCount);
 				}
 			}
 
@@ -1607,9 +1608,9 @@ namespace bgfx
 		s_renderCtx.m_textureStage.m_sampler[_stage] = m_sampler;
 	}
 
-	void Uniform::create(ConstantType::Enum _type, uint16_t _num, bool _alloc)
+	void UniformBuffer::create(UniformType::Enum _type, uint16_t _num, bool _alloc)
 	{
-		uint32_t size = BX_ALIGN_16(g_constantTypeSize[_type]*_num);
+		uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num);
 		if (_alloc)
 		{
 			m_data = g_realloc(NULL, size);
@@ -1626,7 +1627,7 @@ namespace bgfx
 		DX_CHECK(s_renderCtx.m_device->CreateBuffer(&desc, NULL, &m_ptr) );
 	}
 
-	void Uniform::destroy()
+	void UniformBuffer::destroy()
 	{
 		if (NULL != m_data)
 		{
@@ -1769,10 +1770,10 @@ namespace bgfx
 		s_renderCtx.m_renderTargets[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
+	void Context::rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name)
 	{
 		s_renderCtx.m_uniforms[_handle.idx].create(_type, _num);
-		s_renderCtx.m_uniformReg.reg(_name, &s_renderCtx.m_uniforms[_handle.idx]);
+		s_renderCtx.m_uniformReg.add(_name, &s_renderCtx.m_uniforms[_handle.idx]);
 	}
 
 	void Context::rendererDestroyUniform(UniformHandle _handle)
diff --git a/src/renderer_d3d11.h b/src/renderer_d3d11.h
index f3fc20d8..fb23f4df 100644
--- a/src/renderer_d3d11.h
+++ b/src/renderer_d3d11.h
@@ -108,15 +108,15 @@ namespace bgfx
 		bool m_dynamic;
 	};
 
-	struct Uniform
+	struct UniformBuffer
 	{
-		Uniform()
+		UniformBuffer()
 			: m_ptr(NULL)
 			, m_data(NULL)
 		{
 		}
 
-		void create(ConstantType::Enum _type, uint16_t _num, bool _alloc = true);
+		void create(UniformType::Enum _type, uint16_t _num, bool _alloc = true);
 		void destroy();
 
 		ID3D11Buffer* m_ptr;
diff --git a/src/renderer_d3d9.cpp b/src/renderer_d3d9.cpp
index 22512b5f..1760ec47 100644
--- a/src/renderer_d3d9.cpp
+++ b/src/renderer_d3d9.cpp
@@ -844,6 +844,7 @@ namespace bgfx
 	{
 		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION,     0 },
 		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL,       0 },
+		{ 0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TANGENT,      0 },
 		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        0 },
 		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR,        1 },
 		{ 0, 0, D3DDECLTYPE_UBYTE4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_BLENDINDICES, 0 },
@@ -1041,7 +1042,7 @@ namespace bgfx
 				{
 					kind = "user";
 					data = info->m_data;
-					m_constantBuffer->writeUniformRef( (ConstantType::Enum)(type|fragmentBit), regIndex, data, regCount);
+					m_constantBuffer->writeUniformRef( (UniformType::Enum)(type|fragmentBit), regIndex, data, regCount);
 				}
 			}
 
@@ -1589,12 +1590,12 @@ namespace bgfx
 		{
 			uint32_t opcode = read();
 
-			if (ConstantType::End == opcode)
+			if (UniformType::End == opcode)
 			{
 				break;
 			}
 
-			ConstantType::Enum type;
+			UniformType::Enum type;
 			uint16_t loc;
 			uint16_t num;
 			uint16_t copy;
@@ -1603,7 +1604,7 @@ namespace bgfx
 			const char* data;
 			if (copy)
 			{
-				data = read(g_constantTypeSize[type]*num);
+				data = read(g_uniformTypeSize[type]*num);
 			}
 			else
 			{
@@ -1611,14 +1612,14 @@ namespace bgfx
 			}
 
 #define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
-		case ConstantType::_uniform: \
+		case UniformType::_uniform: \
 		{ \
 			_type* value = (_type*)data; \
 			s_renderCtx.m_device->SetVertexShaderConstant##_dxsuffix(loc, value, num); \
 		} \
 		break; \
 		\
-		case ConstantType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
+		case UniformType::_uniform|BGFX_UNIFORM_FRAGMENTBIT: \
 		{ \
 			_type* value = (_type*)data; \
 			s_renderCtx.m_device->SetPixelShaderConstant##_dxsuffix(loc, value, num); \
@@ -1637,7 +1638,7 @@ namespace bgfx
 			CASE_IMPLEMENT_UNIFORM(Uniform3x3fv, Matrix3fv, F, float);
 			CASE_IMPLEMENT_UNIFORM(Uniform4x4fv, Matrix4fv, F, float);
 
-			case ConstantType::End:
+			case UniformType::End:
 				break;
 
 			default:
@@ -1843,13 +1844,13 @@ namespace bgfx
 		s_renderCtx.m_renderTargets[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
+	void Context::rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name)
 	{
-		uint32_t size = BX_ALIGN_16(g_constantTypeSize[_type]*_num);
+		uint32_t size = BX_ALIGN_16(g_uniformTypeSize[_type]*_num);
 		void* data = g_realloc(NULL, size);
 		memset(data, 0, size);
 		s_renderCtx.m_uniforms[_handle.idx] = data;
-		s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
+		s_renderCtx.m_uniformReg.add(_name, s_renderCtx.m_uniforms[_handle.idx]);
 	}
 
 	void Context::rendererDestroyUniform(UniformHandle _handle)
diff --git a/src/renderer_gl.cpp b/src/renderer_gl.cpp
index 1ae35dc2..39ade1ec 100644
--- a/src/renderer_gl.cpp
+++ b/src/renderer_gl.cpp
@@ -453,7 +453,6 @@ namespace bgfx
 
 		void saveScreenShot(Memory* _mem)
 		{
-#if BGFX_CONFIG_RENDERER_OPENGL
 			void* data = g_realloc(NULL, m_resolution.m_width*m_resolution.m_height*4);
 			glReadPixels(0, 0, m_resolution.m_width, m_resolution.m_height, GL_RGBA, GL_UNSIGNED_BYTE, data);
 
@@ -468,7 +467,6 @@ namespace bgfx
 
 			saveTga( (const char*)_mem->data, m_resolution.m_width, m_resolution.m_height, m_resolution.m_width*4, data, false, true);
 			g_free(data);
-#endif // BGFX_CONFIG_RENDERER_OPENGL
 		}
 
 		void init()
@@ -666,7 +664,8 @@ namespace bgfx
 	{
 		"a_position",
 		"a_normal",
-		"a_color",
+		"a_tangent",
+		"a_color0",
 		"a_color1",
 		"a_indices",
 		"a_weight",
@@ -825,30 +824,30 @@ namespace bgfx
 		return "UNKNOWN GLENUM!";
 	}
 
-	ConstantType::Enum convertGlType(GLenum _type)
+	UniformType::Enum convertGlType(GLenum _type)
 	{
 		switch (_type)
 		{
 		case GL_FLOAT:
-			return ConstantType::Uniform1fv;
+			return UniformType::Uniform1fv;
 
 		case GL_FLOAT_VEC2:
-			return ConstantType::Uniform2fv;
+			return UniformType::Uniform2fv;
 
 		case GL_FLOAT_VEC3:
-			return ConstantType::Uniform3fv;
+			return UniformType::Uniform3fv;
 
 		case GL_FLOAT_VEC4:
-			return ConstantType::Uniform4fv;
+			return UniformType::Uniform4fv;
 
 		case GL_FLOAT_MAT2:
 			break;
 
 		case GL_FLOAT_MAT3:
-			return ConstantType::Uniform3x3fv;
+			return UniformType::Uniform3x3fv;
 
 		case GL_FLOAT_MAT4:
-			return ConstantType::Uniform4x4fv;
+			return UniformType::Uniform4x4fv;
 
 // 		case GL_FLOAT_MAT2x3:
 // 		case GL_FLOAT_MAT2x4:
@@ -864,10 +863,10 @@ namespace bgfx
 // 		case GL_SAMPLER_3D:
 // 		case GL_SAMPLER_1D_SHADOW:
 // 		case GL_SAMPLER_2D_SHADOW:
-			return ConstantType::Uniform1iv;
+			return UniformType::Uniform1iv;
 		};
 
-		return ConstantType::End;
+		return UniformType::End;
 	}
 
 	void Program::create(const Shader& _vsh, const Shader& _fsh)
@@ -1032,7 +1031,7 @@ namespace bgfx
 				if (NULL != info)
 				{
 					data = info->m_data;
-					ConstantType::Enum type = convertGlType(gltype);
+					UniformType::Enum type = convertGlType(gltype);
 					m_constantBuffer->writeUniformRef(type, loc, data, num);
 					BX_TRACE("store %s %p", name, data);
 				}
@@ -1643,12 +1642,12 @@ namespace bgfx
 		{
 			uint32_t opcode = read();
 
-			if (ConstantType::End == opcode)
+			if (UniformType::End == opcode)
 			{
 				break;
 			}
 
-			ConstantType::Enum type;
+			UniformType::Enum type;
 			uint16_t loc;
 			uint16_t num;
 			uint16_t copy;
@@ -1657,7 +1656,7 @@ namespace bgfx
 			const char* data;
 			if (copy)
 			{
-				data = read(g_constantTypeSize[type]*num);
+				data = read(g_uniformTypeSize[type]*num);
 			}
 			else
 			{
@@ -1665,7 +1664,7 @@ namespace bgfx
 			}
 
 #define CASE_IMPLEMENT_UNIFORM(_uniform, _glsuffix, _dxsuffix, _type) \
-		case ConstantType::_uniform: \
+		case UniformType::_uniform: \
 			{ \
 				_type* value = (_type*)data; \
 				GL_CHECK(glUniform##_glsuffix(loc, num, value) ); \
@@ -1673,7 +1672,7 @@ namespace bgfx
 			break;
 			
 #define CASE_IMPLEMENT_UNIFORM_T(_uniform, _glsuffix, _dxsuffix, _type) \
-		case ConstantType::_uniform: \
+		case UniformType::_uniform: \
 			{ \
 				_type* value = (_type*)data; \
 				GL_CHECK(glUniform##_glsuffix(loc, num, GL_FALSE, value) ); \
@@ -1700,7 +1699,7 @@ namespace bgfx
 			CASE_IMPLEMENT_UNIFORM_T(Uniform3x3fv, Matrix3fv, F, float);
 			CASE_IMPLEMENT_UNIFORM_T(Uniform4x4fv, Matrix4fv, F, float);
 
-			case ConstantType::End:
+			case UniformType::End:
 				break;
 
 			default:
@@ -2004,13 +2003,13 @@ namespace bgfx
 		s_renderCtx.m_renderTargets[_handle.idx].destroy();
 	}
 
-	void Context::rendererCreateUniform(UniformHandle _handle, ConstantType::Enum _type, uint16_t _num, const char* _name)
+	void Context::rendererCreateUniform(UniformHandle _handle, UniformType::Enum _type, uint16_t _num, const char* _name)
 	{
-		uint32_t size = g_constantTypeSize[_type]*_num;
+		uint32_t size = g_uniformTypeSize[_type]*_num;
 		void* data = g_realloc(NULL, size);
 		memset(data, 0, size);
 		s_renderCtx.m_uniforms[_handle.idx] = data;
-		s_renderCtx.m_uniformReg.reg(_name, s_renderCtx.m_uniforms[_handle.idx]);
+		s_renderCtx.m_uniformReg.add(_name, s_renderCtx.m_uniforms[_handle.idx]);
 	}
 
 	void Context::rendererDestroyUniform(UniformHandle _handle)
diff --git a/src/renderer_null.cpp b/src/renderer_null.cpp
index 4ce3ce05..f6ec85e6 100644
--- a/src/renderer_null.cpp
+++ b/src/renderer_null.cpp
@@ -140,7 +140,7 @@ namespace bgfx
 	{
 	}
 
-	void Context::rendererCreateUniform(UniformHandle /*_handle*/, ConstantType::Enum /*_type*/, uint16_t /*_num*/, const char* /*_name*/)
+	void Context::rendererCreateUniform(UniformHandle /*_handle*/, UniformType::Enum /*_type*/, uint16_t /*_num*/, const char* /*_name*/)
 	{
 	}
 
diff --git a/src/varying.def.sc b/src/varying.def.sc
index c957f50e..1cfa631e 100644
--- a/src/varying.def.sc
+++ b/src/varying.def.sc
@@ -5,6 +5,6 @@ vec3 v_normal    : TEXCOORD1 = vec3(0.0, 1.0, 0.0);
 
 vec3 a_position  : POSITION;
 vec3 a_normal    : NORMAL0;
-vec4 a_color     : COLOR0;
+vec4 a_color0    : COLOR0;
 vec4 a_color1    : COLOR1;
 vec2 a_texcoord0 : TEXCOORD0;
diff --git a/src/vs_clear.sc b/src/vs_clear.sc
index 5b321c5f..53f340d0 100644
--- a/src/vs_clear.sc
+++ b/src/vs_clear.sc
@@ -1,4 +1,4 @@
-$input a_position, a_color
+$input a_position, a_color0
 $output v_color0
 
 /*
@@ -11,5 +11,5 @@ $output v_color0
 void main()
 {
 	gl_Position = vec4(a_position, 1.0);
-	v_color0 = a_color;
+	v_color0 = a_color0;
 }
diff --git a/src/vs_clear_dx11.bin.h b/src/vs_clear_dx11.bin.h
index 1773f427..20112fb2 100644
--- a/src/vs_clear_dx11.bin.h
+++ b/src/vs_clear_dx11.bin.h
@@ -1,44 +1,44 @@
-static const uint8_t vs_clear_dx11[649] =
+static const uint8_t vs_clear_dx11[650] =
 {
-	0xff, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x74, 0x02, 0x44, 0x58, 0x42, 0x43, 0x9f, 0x90, 0x55, 0x9a, 0x15, 0xd7, 0x4d, 0x46, // ..t.DXBC..U...MF
-	0x12, 0x19, 0x32, 0x30, 0xa7, 0xfd, 0x7a, 0x83, 0x01, 0x00, 0x00, 0x00, 0x74, 0x02, 0x00, 0x00, // ..20..z.....t...
-	0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, 0x00, // ....4...........
-	0x50, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, 0x00, 0x00, // P.......RDEFp...
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, // ............<...
-	0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, // ........<...RD11
-	0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, // <....... ...(...
-	0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, 0x72, // $...........Micr
-	0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, 0x53, // osoft (R) HLSL S
-	0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, 0x39, // hader Compiler 9
-	0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, 0xab, // .29.952.3111....
-	0x49, 0x53, 0x47, 0x4e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // ISGNH...........
-	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // 8...............
-	0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........A.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, // ................
-	0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0xab, // POSITION.COLOR..
-	0x4f, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, // OSGNL...........
-	0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, // 8...............
-	0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ........D.......
-	0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, // ................
-	0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, // SV_POSITION.COLO
-	0x52, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x80, 0x00, 0x00, 0x00, 0x50, 0x00, 0x01, 0x00, // R...SHEX....P...
-	0x20, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, 0x00, //  ...j..._...r...
-	0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ...._...........
-	0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // g.... ..........
-	0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, // e.... ......6...
-	0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, // r ......F.......
-	0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, 0x00, // 6.... .......@..
-	0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, // ...?6.... ......
-	0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, // F.......>...STAT
-	0x94, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x74, 0x02, 0x44, 0x58, 0x42, 0x43, 0x9f, 0x90, 0x55, 0x9a, 0x15, 0xd7, 0x4d, // ...t.DXBC..U...M
+	0x46, 0x12, 0x19, 0x32, 0x30, 0xa7, 0xfd, 0x7a, 0x83, 0x01, 0x00, 0x00, 0x00, 0x74, 0x02, 0x00, // F..20..z.....t..
+	0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0xac, 0x00, 0x00, 0x00, 0xfc, 0x00, 0x00, // .....4..........
+	0x00, 0x50, 0x01, 0x00, 0x00, 0xd8, 0x01, 0x00, 0x00, 0x52, 0x44, 0x45, 0x46, 0x70, 0x00, 0x00, // .P.......RDEFp..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, // .............<..
+	0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x52, 0x44, 0x31, // .........<...RD1
+	0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, 0x00, 0x00, 0x28, 0x00, 0x00, // 1<....... ...(..
+	0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x4d, 0x69, 0x63, // .$...........Mic
+	0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, 0x20, // rosoft (R) HLSL 
+	0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, 0x20, // Shader Compiler 
+	0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, 0xab, // 9.29.952.3111...
+	0xab, 0x49, 0x53, 0x47, 0x4e, 0x48, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, // .ISGNH..........
+	0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .8..............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x41, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........A......
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, // ................
+	0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, // .POSITION.COLOR.
+	0xab, 0x4f, 0x53, 0x47, 0x4e, 0x4c, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, // .OSGNL..........
+	0x00, 0x38, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, // .8..............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x44, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // .........D......
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, // ................
+	0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, // .SV_POSITION.COL
+	0x4f, 0x52, 0x00, 0xab, 0xab, 0x53, 0x48, 0x45, 0x58, 0x80, 0x00, 0x00, 0x00, 0x50, 0x00, 0x01, // OR...SHEX....P..
+	0x00, 0x20, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, 0x10, // . ...j..._...r..
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, 0x00, // ....._..........
+	0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, // .g.... .........
+	0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, // .e.... ......6..
+	0x05, 0x72, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x12, 0x10, 0x00, 0x00, 0x00, 0x00, // .r ......F......
+	0x00, 0x36, 0x00, 0x00, 0x05, 0x82, 0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x40, 0x00, // .6.... .......@.
+	0x00, 0x00, 0x00, 0x80, 0x3f, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, 0x00, // ....?6.... .....
+	0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, // .F.......>...STA
+	0x54, 0x94, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // T...............
+	0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                           // .........
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,                                     // ..........
 };
diff --git a/src/vs_debugfont.sc b/src/vs_debugfont.sc
index e319d5ea..650b10f9 100644
--- a/src/vs_debugfont.sc
+++ b/src/vs_debugfont.sc
@@ -1,4 +1,4 @@
-$input a_position, a_color, a_color1, a_texcoord0
+$input a_position, a_color0, a_color1, a_texcoord0
 $output v_color0, v_color1, v_texcoord0
 
 /*
@@ -12,6 +12,6 @@ void main()
 {
 	gl_Position = mul(u_modelViewProj, vec4(a_position, 1.0) );
 	v_texcoord0 = a_texcoord0;
-	v_color0 = a_color;
+	v_color0 = a_color0;
 	v_color1 = a_color1;
 }
diff --git a/src/vs_debugfont_dx11.bin.h b/src/vs_debugfont_dx11.bin.h
index 0482e352..5dfbefe3 100644
--- a/src/vs_debugfont_dx11.bin.h
+++ b/src/vs_debugfont_dx11.bin.h
@@ -1,96 +1,96 @@
-static const uint8_t vs_debugfont_dx11[1475] =
+static const uint8_t vs_debugfont_dx11[1476] =
 {
-	0xff, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, // ................
-	0xc0, 0x01, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, // ...u_modelViewPr
-	0x6f, 0x6a, 0x09, 0x00, 0x00, 0x01, 0x40, 0x00, 0x98, 0x05, 0x44, 0x58, 0x42, 0x43, 0x46, 0xbf, // oj....@...DXBCF.
-	0xfc, 0xa7, 0xce, 0x2a, 0xea, 0x90, 0xbc, 0x31, 0x32, 0x0a, 0x66, 0x1f, 0xa2, 0x34, 0x01, 0x00, // ...*...12.f..4..
-	0x00, 0x00, 0x98, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x88, 0x02, // ..........4.....
-	0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x9c, 0x03, 0x00, 0x00, 0xfc, 0x04, 0x00, 0x00, 0x52, 0x44, // ..............RD
-	0x45, 0x46, 0x4c, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, 0x00, // EFL.......h.....
-	0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x18, 0x02, // ..<.............
-	0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, 0x00, // ..RD11<....... .
-	0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, // ..(...$.........
-	0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, 0x5c, 0x00, // ..$Globals......
-	0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, 0x00, // ..............@.
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xcc, 0x01, // ................
-	0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, // ..@...@.........
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, 0x00, // ..............@.
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xdf, 0x01, // ................
-	0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, // ......@.........
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, 0x00, // ..............@.
-	0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfb, 0x01, // ................
-	0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, // ..@...@.........
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, 0x00, // ..............@.
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, // ................
-	0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, 0x5f, // ..............u_
-	0x76, 0x69, 0x65, 0x77, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x00, 0x03, 0x00, // view.float4x4...
-	0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, 0x01, // ................
-	0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, 0x6d, // ..u_viewProj.u_m
-	0x6f, 0x64, 0x65, 0x6c, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, // odel.u_modelView
-	0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, // .u_modelViewProj
-	0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, // .u_modelViewProj
-	0x58, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x4d, 0x69, // X.u_viewProjX.Mi
-	0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, 0x4c, // crosoft (R) HLSL
-	0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, 0x72, //  Shader Compiler
-	0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, 0xab, //  9.29.952.3111..
-	0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, // ..ISGN..........
-	0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..h.............
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........q.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x0f, // ................
-	0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..q.............
-	0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........w.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x03, // ................
-	0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, // ..POSITION.COLOR
-	0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x84, 0x00, // .TEXCOORD.OSGN..
-	0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, // ..........h.....
-	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, 0x00, // ................
-	0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..t.............
-	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, 0x00, // ..........t.....
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x00, // ................
-	0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, // ..z.............
-	0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, 0x53, // ..........SV_POS
-	0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, 0x43, // ITION.COLOR.TEXC
-	0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x45, 0x58, 0x58, 0x01, 0x00, 0x00, 0x50, 0x00, // OORD..SHEXX...P.
-	0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x59, 0x00, 0x00, 0x04, 0x46, 0x8e, // ..V...j...Y...F.
-	0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, 0x10, //  ........._...r.
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, 0x00, // ......_.........
-	0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, 0x00, // .._..........._.
-	0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, 0x20, // ..2.......g.... 
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, // ..........e.... 
-	0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x02, 0x00, // ......e.... ....
-	0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, 0x00, // ..e...2 ......h.
-	0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, // ......8.........
-	0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..V.......F. ...
-	0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, // ......2.........
-	0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, 0x10, // ..F. ...........
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, 0x00, // ......F.......2.
-	0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..........F. ...
-	0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, // ..............F.
-	0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf2, 0x20, 0x10, 0x00, 0x00, 0x00, // ........... ....
-	0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, // ..F.......F. ...
-	0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, 0x00, // ......6.... ....
-	0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, // ..F.......6.... 
-	0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, 0x00, // ......F.......6.
-	0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, 0x00, // ..2 ......F.....
-	0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x08, 0x00, // ..>...STAT......
-	0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0xff, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, // ................
+	0x00, 0xc0, 0x01, 0x0f, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, // ....u_modelViewP
+	0x72, 0x6f, 0x6a, 0x09, 0x00, 0x00, 0x01, 0x04, 0x00, 0x98, 0x05, 0x44, 0x58, 0x42, 0x43, 0x46, // roj........DXBCF
+	0xbf, 0xfc, 0xa7, 0xce, 0x2a, 0xea, 0x90, 0xbc, 0x31, 0x32, 0x0a, 0x66, 0x1f, 0xa2, 0x34, 0x01, // ....*...12.f..4.
+	0x00, 0x00, 0x00, 0x98, 0x05, 0x00, 0x00, 0x05, 0x00, 0x00, 0x00, 0x34, 0x00, 0x00, 0x00, 0x88, // ...........4....
+	0x02, 0x00, 0x00, 0x10, 0x03, 0x00, 0x00, 0x9c, 0x03, 0x00, 0x00, 0xfc, 0x04, 0x00, 0x00, 0x52, // ...............R
+	0x44, 0x45, 0x46, 0x4c, 0x02, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x01, // DEFL.......h....
+	0x00, 0x00, 0x00, 0x3c, 0x00, 0x00, 0x00, 0x00, 0x05, 0xfe, 0xff, 0x00, 0x91, 0x00, 0x00, 0x18, // ...<............
+	0x02, 0x00, 0x00, 0x52, 0x44, 0x31, 0x31, 0x3c, 0x00, 0x00, 0x00, 0x18, 0x00, 0x00, 0x00, 0x20, // ...RD11<....... 
+	0x00, 0x00, 0x00, 0x28, 0x00, 0x00, 0x00, 0x24, 0x00, 0x00, 0x00, 0x0c, 0x00, 0x00, 0x00, 0x00, // ...(...$........
+	0x00, 0x00, 0x00, 0x5c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x24, 0x47, 0x6c, 0x6f, 0x62, 0x61, 0x6c, 0x73, 0x00, 0xab, 0xab, 0xab, 0x5c, // ...$Globals.....
+	0x00, 0x00, 0x00, 0x07, 0x00, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0xc0, 0x01, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x98, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x40, // ...............@
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xcc, // ................
+	0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, // ...@...@........
+	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xd7, 0x01, 0x00, 0x00, 0x80, 0x00, 0x00, 0x00, 0x40, // ...............@
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xdf, // ................
+	0x01, 0x00, 0x00, 0xc0, 0x00, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, // .......@........
+	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xeb, 0x01, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x40, // ...............@
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xfb, // ................
+	0x01, 0x00, 0x00, 0x40, 0x01, 0x00, 0x00, 0x40, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, // ...@...@........
+	0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x0c, 0x02, 0x00, 0x00, 0x80, 0x01, 0x00, 0x00, 0x40, // ...............@
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa8, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xff, // ................
+	0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, 0x00, 0x00, 0x00, 0x00, 0x75, // ...............u
+	0x5f, 0x76, 0x69, 0x65, 0x77, 0x00, 0x66, 0x6c, 0x6f, 0x61, 0x74, 0x34, 0x78, 0x34, 0x00, 0x03, // _view.float4x4..
+	0x00, 0x03, 0x00, 0x04, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x9f, // ................
+	0x01, 0x00, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x00, 0x75, 0x5f, // ...u_viewProj.u_
+	0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, // model.u_modelVie
+	0x77, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, // w.u_modelViewPro
+	0x6a, 0x00, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, // j.u_modelViewPro
+	0x6a, 0x58, 0x00, 0x75, 0x5f, 0x76, 0x69, 0x65, 0x77, 0x50, 0x72, 0x6f, 0x6a, 0x58, 0x00, 0x4d, // jX.u_viewProjX.M
+	0x69, 0x63, 0x72, 0x6f, 0x73, 0x6f, 0x66, 0x74, 0x20, 0x28, 0x52, 0x29, 0x20, 0x48, 0x4c, 0x53, // icrosoft (R) HLS
+	0x4c, 0x20, 0x53, 0x68, 0x61, 0x64, 0x65, 0x72, 0x20, 0x43, 0x6f, 0x6d, 0x70, 0x69, 0x6c, 0x65, // L Shader Compile
+	0x72, 0x20, 0x39, 0x2e, 0x32, 0x39, 0x2e, 0x39, 0x35, 0x32, 0x2e, 0x33, 0x31, 0x31, 0x31, 0x00, // r 9.29.952.3111.
+	0xab, 0xab, 0xab, 0x49, 0x53, 0x47, 0x4e, 0x80, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, // ...ISGN.........
+	0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...h............
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x07, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x00, // ...........q....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x0f, 0x00, 0x00, 0x71, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...q............
+	0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x00, 0x00, 0x77, 0x00, 0x00, 0x00, 0x00, // ...........w....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, // ................
+	0x03, 0x00, 0x00, 0x50, 0x4f, 0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, // ...POSITION.COLO
+	0x52, 0x00, 0x54, 0x45, 0x58, 0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0x4f, 0x53, 0x47, 0x4e, 0x84, // R.TEXCOORD.OSGN.
+	0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x68, 0x00, 0x00, 0x00, 0x00, // ...........h....
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...t............
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x74, 0x00, 0x00, 0x00, 0x01, // ...........t....
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00, 0x0f, // ................
+	0x00, 0x00, 0x00, 0x7a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, // ...z............
+	0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x03, 0x0c, 0x00, 0x00, 0x53, 0x56, 0x5f, 0x50, 0x4f, // ...........SV_PO
+	0x53, 0x49, 0x54, 0x49, 0x4f, 0x4e, 0x00, 0x43, 0x4f, 0x4c, 0x4f, 0x52, 0x00, 0x54, 0x45, 0x58, // SITION.COLOR.TEX
+	0x43, 0x4f, 0x4f, 0x52, 0x44, 0x00, 0xab, 0x53, 0x48, 0x45, 0x58, 0x58, 0x01, 0x00, 0x00, 0x50, // COORD..SHEXX...P
+	0x00, 0x01, 0x00, 0x56, 0x00, 0x00, 0x00, 0x6a, 0x08, 0x00, 0x01, 0x59, 0x00, 0x00, 0x04, 0x46, // ...V...j...Y...F
+	0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x14, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0x72, // . ........._...r
+	0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x01, // ......._........
+	0x00, 0x00, 0x00, 0x5f, 0x00, 0x00, 0x03, 0xf2, 0x10, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x5f, // ..._..........._
+	0x00, 0x00, 0x03, 0x32, 0x10, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x67, 0x00, 0x00, 0x04, 0xf2, // ...2.......g....
+	0x20, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, //  ..........e....
+	0x20, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0xf2, 0x20, 0x10, 0x00, 0x02, //  ......e.... ...
+	0x00, 0x00, 0x00, 0x65, 0x00, 0x00, 0x03, 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x68, // ...e...2 ......h
+	0x00, 0x00, 0x02, 0x01, 0x00, 0x00, 0x00, 0x38, 0x00, 0x00, 0x08, 0xf2, 0x00, 0x10, 0x00, 0x00, // .......8........
+	0x00, 0x00, 0x00, 0x56, 0x15, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // ...V.......F. ..
+	0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x32, 0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, // .......2........
+	0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x06, // ...F. ..........
+	0x10, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x32, // .......F.......2
+	0x00, 0x00, 0x0a, 0xf2, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // ...........F. ..
+	0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, 0xa6, 0x1a, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, // ...............F
+	0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xf2, 0x20, 0x10, 0x00, 0x00, // ............ ...
+	0x00, 0x00, 0x00, 0x46, 0x0e, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x46, 0x8e, 0x20, 0x00, 0x00, // ...F.......F. ..
+	0x00, 0x00, 0x00, 0x13, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, 0x20, 0x10, 0x00, 0x01, // .......6.... ...
+	0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x01, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x05, 0xf2, // ...F.......6....
+	0x20, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x46, 0x1e, 0x10, 0x00, 0x02, 0x00, 0x00, 0x00, 0x36, //  ......F.......6
+	0x00, 0x00, 0x05, 0x32, 0x20, 0x10, 0x00, 0x03, 0x00, 0x00, 0x00, 0x46, 0x10, 0x10, 0x00, 0x03, // ...2 ......F....
+	0x00, 0x00, 0x00, 0x3e, 0x00, 0x00, 0x01, 0x53, 0x54, 0x41, 0x54, 0x94, 0x00, 0x00, 0x00, 0x08, // ...>...STAT.....
+	0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x02, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x03, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
 	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // ................
-	0x00, 0x00, 0x00,                                                                               // ...
+	0x00, 0x00, 0x00, 0x00,                                                                         // ....
 };
diff --git a/src/vs_debugfont_glsl.bin.h b/src/vs_debugfont_glsl.bin.h
index 0ce2c8ab..6bbeb7d2 100644
--- a/src/vs_debugfont_glsl.bin.h
+++ b/src/vs_debugfont_glsl.bin.h
@@ -1,4 +1,4 @@
-static const uint8_t vs_debugfont_glsl[464] =
+static const uint8_t vs_debugfont_glsl[466] =
 {
 	0x23, 0x69, 0x66, 0x64, 0x65, 0x66, 0x20, 0x47, 0x4c, 0x5f, 0x45, 0x53, 0x0a, 0x70, 0x72, 0x65, // #ifdef GL_ES.pre
 	0x63, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x20, 0x68, 0x69, 0x67, 0x68, 0x70, 0x20, 0x66, 0x6c, 0x6f, // cision highp flo
@@ -14,19 +14,20 @@ static const uint8_t vs_debugfont_glsl[464] =
 	0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, // oord0;.attribute
 	0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, //  vec4 a_color1;.
 	0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x61, // attribute vec4 a
-	0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, 0x74, // _color;.attribut
-	0x65, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // e vec3 a_positio
-	0x6e, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, 0x0a, // n;.void main ().
-	0x7b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // {.  vec4 tmpvar_
-	0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, 0x20, // 1;.  tmpvar_1.w 
-	0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, // = 1.0;.  tmpvar_
-	0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, // 1.xyz = a_positi
-	0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, 0x6f, // on;.  gl_Positio
-	0x6e, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, 0x77, // n = (u_modelView
-	0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x29, // Proj * tmpvar_1)
-	0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x20, // ;.  v_texcoord0 
-	0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, 0x20, // = a_texcoord0;. 
-	0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x63, 0x6f, //  v_color0 = a_co
-	0x6c, 0x6f, 0x72, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x20, // lor;.  v_color1 
-	0x3d, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, 0x7d, 0x0a, 0x0a, 0x00, // = a_color1;.}...
+	0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x61, 0x74, 0x74, 0x72, 0x69, 0x62, 0x75, // _color0;.attribu
+	0x74, 0x65, 0x20, 0x76, 0x65, 0x63, 0x33, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, 0x69, // te vec3 a_positi
+	0x6f, 0x6e, 0x3b, 0x0a, 0x76, 0x6f, 0x69, 0x64, 0x20, 0x6d, 0x61, 0x69, 0x6e, 0x20, 0x28, 0x29, // on;.void main ()
+	0x0a, 0x7b, 0x0a, 0x20, 0x20, 0x76, 0x65, 0x63, 0x34, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, // .{.  vec4 tmpvar
+	0x5f, 0x31, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, 0x2e, 0x77, // _1;.  tmpvar_1.w
+	0x20, 0x3d, 0x20, 0x31, 0x2e, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, //  = 1.0;.  tmpvar
+	0x5f, 0x31, 0x2e, 0x78, 0x79, 0x7a, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x70, 0x6f, 0x73, 0x69, 0x74, // _1.xyz = a_posit
+	0x69, 0x6f, 0x6e, 0x3b, 0x0a, 0x20, 0x20, 0x67, 0x6c, 0x5f, 0x50, 0x6f, 0x73, 0x69, 0x74, 0x69, // ion;.  gl_Positi
+	0x6f, 0x6e, 0x20, 0x3d, 0x20, 0x28, 0x75, 0x5f, 0x6d, 0x6f, 0x64, 0x65, 0x6c, 0x56, 0x69, 0x65, // on = (u_modelVie
+	0x77, 0x50, 0x72, 0x6f, 0x6a, 0x20, 0x2a, 0x20, 0x74, 0x6d, 0x70, 0x76, 0x61, 0x72, 0x5f, 0x31, // wProj * tmpvar_1
+	0x29, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, // );.  v_texcoord0
+	0x20, 0x3d, 0x20, 0x61, 0x5f, 0x74, 0x65, 0x78, 0x63, 0x6f, 0x6f, 0x72, 0x64, 0x30, 0x3b, 0x0a, //  = a_texcoord0;.
+	0x20, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x63, //   v_color0 = a_c
+	0x6f, 0x6c, 0x6f, 0x72, 0x30, 0x3b, 0x0a, 0x20, 0x20, 0x76, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, // olor0;.  v_color
+	0x31, 0x20, 0x3d, 0x20, 0x61, 0x5f, 0x63, 0x6f, 0x6c, 0x6f, 0x72, 0x31, 0x3b, 0x0a, 0x7d, 0x0a, // 1 = a_color1;.}.
+	0x0a, 0x00,                                                                                     // ..
 };
diff --git a/tools/bin/shaderc.exe b/tools/bin/shaderc.exe
index 33534936..d38c4035 100644
Binary files a/tools/bin/shaderc.exe and b/tools/bin/shaderc.exe differ
diff --git a/tools/shaderc.cpp b/tools/shaderc.cpp
index 7a610426..142f7440 100644
--- a/tools/shaderc.cpp
+++ b/tools/shaderc.cpp
@@ -1,1819 +1,1876 @@
-/*
- * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
- * License: http://www.opensource.org/licenses/BSD-2-Clause
- */
-
-#define SHADERC_DEBUG 0
-
-#define NOMINMAX
-#include <stdio.h>
-#include <stdint.h>
-#include <stdlib.h>
-#include <string.h>
-#include <string>
-#include <vector>
-#include <unordered_map>
-
+/*
+ * Copyright 2011-2012 Branimir Karadzic. All rights reserved.
+ * License: http://www.opensource.org/licenses/BSD-2-Clause
+ */
+
+#ifndef SHADERC_DEBUG
+#	define SHADERC_DEBUG 0
+#endif // SHADERC_DEBUG
+
+#define NOMINMAX
+#include <alloca.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+#include <string>
+#include <vector>
+#include <unordered_map>
+
 namespace std { namespace tr1 {} using namespace tr1; } // namespace std
-
-#define MAX_TAGS 256
-extern "C"
-{
-#include <fpp.h>
-} // extern "C"
-
-#if SHADERC_DEBUG
-#	define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
-#endif // DEBUG
-
-#define BX_NAMESPACE 1
-#include <bx/bx.h>
-
-#if BX_PLATFORM_LINUX
-#	include <stdarg.h>
-
-#	define _stricmp strcasecmp
-#	define _snprintf snprintf
-#endif // BX_PLATFORM_LINUX
-
-#include <bx/commandline.h>
-#include <bx/countof.h>
-#include <bx/endian.h>
-#include <bx/uint32_t.h>
-
-#include "glsl_optimizer.h"
-
-#if BX_PLATFORM_WINDOWS
-#	include <d3dx9.h>
-#	include <d3dcompiler.h>
-#endif // BX_PLATFORM_WINDOWS
-
-long int fsize(FILE* _file)
-{
-	long int pos = ftell(_file);
-	fseek(_file, 0L, SEEK_END);
-	long int size = ftell(_file);
-	fseek(_file, pos, SEEK_SET);
-	return size;
-}
-
-struct Attrib
-{
-	enum Enum
-	{
-		Position = 0,
-		Normal,
-		Color0,
-		Color1,
-		Indices,
-		Weight,
-		TexCoord0,
-		TexCoord1,
-		TexCoord2,
-		TexCoord3,
-		TexCoord4,
-		TexCoord5,
-		TexCoord6,
-		TexCoord7,
-
-		Count,
-	};
-};
-
-struct RemapInputSemantic
-{
-	Attrib::Enum m_attr;
-	const char* m_name;
-	uint8_t m_index;
-};
-
-static const RemapInputSemantic s_remapInputSemantic[Attrib::Count+1] =
-{
-	{ Attrib::Position,  "POSITION",     0 },
-	{ Attrib::Normal,    "NORMAL",       0 },
-	{ Attrib::Color0,    "COLOR",        0 },
-	{ Attrib::Color1,    "COLOR",        1 },
-	{ Attrib::Indices,   "BLENDINDICES", 0 },
-	{ Attrib::Weight,    "BLENDWEIGHT",  0 },
-	{ Attrib::TexCoord0, "TEXCOORD",     0 },
-	{ Attrib::TexCoord1, "TEXCOORD",     1 },
-	{ Attrib::TexCoord2, "TEXCOORD",     2 },
-	{ Attrib::TexCoord3, "TEXCOORD",     3 },
-	{ Attrib::TexCoord4, "TEXCOORD",     4 },
-	{ Attrib::TexCoord5, "TEXCOORD",     5 },
-	{ Attrib::TexCoord6, "TEXCOORD",     6 },
-	{ Attrib::TexCoord7, "TEXCOORD",     7 },
-	{ Attrib::Count,     "",             0 },
-};
-
-const RemapInputSemantic& findInputSemantic(const char* _name, uint8_t _index)
-{
-	for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
-	{
-		const RemapInputSemantic& ris = s_remapInputSemantic[ii];
-		if (0 == strcmp(ris.m_name, _name)
-		&&  ris.m_index == _index)
-		{
-			return ris;
-		}
-	}
-
-	return s_remapInputSemantic[Attrib::Count];
-}
-
-struct ConstantType
-{
-	enum Enum
-	{
-		Uniform1i,
-		Uniform1f,
-		End,
-
-		Uniform1iv,
-		Uniform1fv,
-		Uniform2fv,
-		Uniform3fv,
-		Uniform4fv,
-		Uniform3x3fv,
-		Uniform4x4fv,
-
-		Count,
-		TypeMask = 0x7f,
-		FragmentBit = 0x80
-	};
-};
-
-static const char* s_constantTypeName[ConstantType::Count] =
-{
-	"int",
-	"float",
-	NULL,
-	"int",
-	"float",
-	"float2",
-	"float3",
-	"float4",
-	"float3x3",
-	"float4x4",
-};
-
-struct Uniform
-{
-	std::string name;
-	ConstantType::Enum type;
-	uint8_t num;
-	uint16_t regIndex;
-	uint16_t regCount;
-};
-typedef std::vector<Uniform> UniformArray;
-
-#if BX_PLATFORM_WINDOWS
-struct ConstRemapDx9
-{
-	ConstantType::Enum id;
-	D3DXPARAMETER_CLASS paramClass;
-	D3DXPARAMETER_TYPE paramType;
-	uint32_t paramBytes;
-};
-
-static const ConstRemapDx9 s_constRemapDx9[7] =
-{
-	{ ConstantType::Uniform1iv,   D3DXPC_SCALAR,         D3DXPT_INT,    4 },
-	{ ConstantType::Uniform1fv,   D3DXPC_SCALAR,         D3DXPT_FLOAT,  4 },
-	{ ConstantType::Uniform2fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT,  8 },
-	{ ConstantType::Uniform3fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 12 },
-	{ ConstantType::Uniform4fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 16 },
-	{ ConstantType::Uniform3x3fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 36 },
-	{ ConstantType::Uniform4x4fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 64 },
-};
-
-ConstantType::Enum findConstantTypeDx9(const D3DXCONSTANT_DESC& constDesc)
-{
-	uint32_t count = sizeof(s_constRemapDx9)/sizeof(ConstRemapDx9);
-	for (uint32_t ii = 0; ii < count; ++ii)
-	{
-		const ConstRemapDx9& remap = s_constRemapDx9[ii];
-
-		if (remap.paramClass == constDesc.Class
-		&&  remap.paramType == constDesc.Type
-		&&  (constDesc.Bytes%remap.paramBytes) == 0)
-		{
-			return remap.id;
-		}
-	}
-
-	return ConstantType::Count;
-}
-
-static uint32_t s_optimizationLevelDx9[4] =
-{
-	D3DXSHADER_OPTIMIZATION_LEVEL0,
-	D3DXSHADER_OPTIMIZATION_LEVEL1,
-	D3DXSHADER_OPTIMIZATION_LEVEL2,
-	D3DXSHADER_OPTIMIZATION_LEVEL3,
-};
-
-struct ConstRemapDx11
-{
-	ConstantType::Enum id;
-	D3D_SHADER_VARIABLE_CLASS paramClass;
-	D3D_SHADER_VARIABLE_TYPE paramType;
-	uint32_t paramBytes;
-};
-
-static const ConstRemapDx11 s_constRemapDx11[7] =
-{
-	{ ConstantType::Uniform1iv,   D3D_SVC_SCALAR,         D3D_SVT_INT,    4 },
-	{ ConstantType::Uniform1fv,   D3D_SVC_SCALAR,         D3D_SVT_FLOAT,  4 },
-	{ ConstantType::Uniform2fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT,  8 },
-	{ ConstantType::Uniform3fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT, 12 },
-	{ ConstantType::Uniform4fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT, 16 },
-	{ ConstantType::Uniform3x3fv, D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 36 },
-	{ ConstantType::Uniform4x4fv, D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 64 },
-};
-
-ConstantType::Enum findConstantTypeDx11(const D3D11_SHADER_TYPE_DESC& constDesc, uint32_t _size)
-{
-	uint32_t count = sizeof(s_constRemapDx11)/sizeof(ConstRemapDx9);
-	for (uint32_t ii = 0; ii < count; ++ii)
-	{
-		const ConstRemapDx11& remap = s_constRemapDx11[ii];
-
-		if (remap.paramClass == constDesc.Class
-		&&  remap.paramType == constDesc.Type
-		&&  remap.paramBytes == _size)
-		{
-			return remap.id;
-		}
-	}
-
-	return ConstantType::Count;
-}
-
-static uint32_t s_optimizationLevelDx11[4] =
-{
-	D3DCOMPILE_OPTIMIZATION_LEVEL0,
-	D3DCOMPILE_OPTIMIZATION_LEVEL1,
-	D3DCOMPILE_OPTIMIZATION_LEVEL2,
-	D3DCOMPILE_OPTIMIZATION_LEVEL3,
-};
-#endif // BX_PLATFORM_WINDOWS
-
-class IStreamWriter
-{
-public:
-	virtual ~IStreamWriter() = 0;
-	virtual bool open() = 0;
-	virtual void close() = 0;
-	virtual void writef(const char* _format, ...) = 0;
-	virtual void write(const char* _str) = 0;
-	virtual void write(const void* _data, size_t _size) = 0;
-
-	template<typename Ty>
-	void write(Ty _value)
-	{
-		write(&_value, sizeof(Ty) );
-	}
-
-	void writeString(const char* _str)
-	{
-		uint16_t len = (uint16_t)strlen(_str);
-		write(len);
-		write(_str);
-		char term = '\0';
-		write(term);
-	}
-};
-
-IStreamWriter::~IStreamWriter()
-{
-}
-
-class FileWriter : public IStreamWriter
-{
-public:
-	FileWriter(const char* _filePath, bool _bigEndian = false)
-		: m_filePath(_filePath)
-		, m_file(NULL)
-		, m_bigEndian(_bigEndian)
-	{
-	}
-
-	~FileWriter()
-	{
-	}
-
-	bool open()
-	{
-		BX_CHECK(NULL == m_file, "Still open!");
-
-		m_file = fopen(m_filePath.c_str(), "wb");
-		return NULL != m_file;
-	}
-
-	void close()
-	{
-		if (NULL != m_file)
-		{
-			fclose(m_file);
-			m_file = NULL;
-		}
-	}
-
-	void writef(const char* _format, ...)
-	{
-		if (NULL != m_file)
-		{
-			va_list argList;
-			va_start(argList, _format);
-
-			char temp[2048];
-			int len = vsnprintf(temp, sizeof(temp), _format, argList);
-			fwrite(temp, len, 1, m_file);
-
-			va_end(argList);
-		}
-	}
-
-	void write(const char* _str)
-	{
-		if (NULL != m_file)
-		{
-			fwrite(_str, strlen(_str), 1, m_file);
-		}
-	}
-
-	void write(const void* _data, size_t _size)
-	{
-		if (NULL != m_file)
-		{
-			fwrite(_data, _size, 1, m_file);
-		}
-	}
-
-private:
-	std::string m_filePath;
-	FILE* m_file;
-	bool m_bigEndian;
-};
-
-class Bin2cStream : public IStreamWriter
-{
-public:
-	Bin2cStream(const char* _filePath, const char* _name)
-		: m_filePath(_filePath)
-		, m_name(_name)
-		, m_file(NULL)
-	{
-	}
-
-	~Bin2cStream()
-	{
-	}
-
-	bool open()
-	{
-		BX_CHECK(NULL == m_file, "Still open!");
-
-		m_file = fopen(m_filePath.c_str(), "wb");
-		return NULL != m_file;
-	}
-
-	void close()
-	{
-		if (NULL != m_file)
-		{
-#define HEX_DUMP_WIDTH 16
-#define HEX_DUMP_SPACE_WIDTH 96
-#define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
-			const uint8_t* data = &m_buffer[0];
-			uint32_t size = m_buffer.size();
-
-			fprintf(m_file, "static const uint8_t %s[%d] =\n{\n", m_name.c_str(), size);
-
-			if (NULL != data)
-			{
-				char hex[HEX_DUMP_SPACE_WIDTH+1];
-				char ascii[HEX_DUMP_WIDTH+1];
-				uint32_t hexPos = 0;
-				uint32_t asciiPos = 0;
-				for (uint32_t ii = 0; ii < size; ++ii)
-				{
-					_snprintf(&hex[hexPos], sizeof(hex)-hexPos, "0x%02x, ", data[asciiPos]);
-					hexPos += 6;
-
-					ascii[asciiPos] = isprint(data[asciiPos]) && data[asciiPos] != '\\' ? data[asciiPos] : '.';
-					asciiPos++;
-
-					if (HEX_DUMP_WIDTH == asciiPos)
-					{
-						ascii[asciiPos] = '\0';
-						fprintf(m_file, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
-						data += asciiPos;
-						hexPos = 0;
-						asciiPos = 0;
-					}
-				}
-
-				if (0 != asciiPos)
-				{
-					ascii[asciiPos] = '\0';
-					fprintf(m_file, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
-				}
-			}
-
-			fprintf(m_file, "};\n");
-#undef HEX_DUMP_WIDTH
-#undef HEX_DUMP_SPACE_WIDTH
-#undef HEX_DUMP_FORMAT
-
-			fclose(m_file);
-			m_file = NULL;
-		}
-	}
-
-	void writef(const char* _format, ...)
-	{
-		va_list argList;
-		va_start(argList, _format);
-
-		char temp[2048];
-		int len = vsnprintf(temp, sizeof(temp), _format, argList);
-		m_buffer.insert(m_buffer.end(), temp, temp+len);
-
-		va_end(argList);
-	}
-
-	void write(const char* _str)
-	{
-		m_buffer.insert(m_buffer.end(), _str, _str+strlen(_str) );
-	}
-
-	void write(const void* _data, size_t _size)
-	{
-		const char* data = (const char*)_data;
-		m_buffer.insert(m_buffer.end(), data, data+_size);
-	}
-
-private:
-	std::string m_filePath;
-	std::string m_name;
-	typedef std::vector<uint8_t> Buffer;
-	Buffer m_buffer;
-	FILE* m_file;
-};
-
-struct Varying
-{
-	std::string m_name;
-	std::string m_type;
-	std::string m_init;
-	std::string m_semantics;
-};
-
-typedef std::unordered_map<std::string, Varying> VaryingMap;
-
-class File 
-{
-public:
-	File(const char* _filePath)
-		: m_data(NULL)
-	{
-		FILE* file = fopen(_filePath, "r");
-		if (NULL != file)
-		{
-			m_size = fsize(file);
-			m_data = new char[m_size+1];
-			m_size = fread(m_data, 1, m_size, file);
-			m_data[m_size] = '\0';
-			fclose(file);
-		}
-	}
-
-	~File()
-	{
-		delete [] m_data;
-	}
-
-	const char* getData() const
-	{
-		return m_data;
-	}
-
-	long int getSize() const
-	{
-		return m_size;
-	}
-
-private:
-	char* m_data;
-	long int m_size;
-};
-
-const char* strnl(const char* _str)
-{
-	const char* eol = strstr(_str, "\n\r");
-	if (NULL != eol)
-	{
-		return eol + 2;
-	}
-
-	eol = strstr(_str, "\n");
-	if (NULL != eol)
-	{
-		return eol + 1;
-	}
-
-	return eol + strlen(_str);
-}
-
-const char* streol(const char* _str)
-{
-	const char* eol = strstr(_str, "\n\r");
-	if (NULL != eol)
-	{
-		return eol;
-	}
-
-	eol = strstr(_str, "\n");
-	if (NULL != eol)
-	{
-		return eol;
-	}
-
-	return eol + strlen(_str);
-}
-
-const char* strws(const char* _str)
-{
-	for (; isspace(*_str); ++_str);
-	return _str;
-}
-
-const char* strnws(const char* _str)
-{
-	for (; !isspace(*_str); ++_str);
-	return _str;
-}
-
-const char* strword(const char* _str)
-{
-	for (char ch = *_str++; isalnum(ch) || '_' == ch; ch = *_str++);
-	return _str-1;
-}
-
-const char* strmb(const char* _str, char _open, char _close)
-{
-	int count = 0;
-	for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++)
-	{
-		if (ch == _open)
-		{
-			count++;
-		}
-		else if (ch == _close)
-		{
-			count--;
-			if (0 == count)
-			{
-				return _str-1;
-			}
-		}
-	}
-
-	return NULL;
-}
-
-void strins(char* _str, const char* _insert)
-{
-	size_t len = strlen(_insert);
-	memmove(&_str[len], _str, strlen(_str) );
-	memcpy(_str, _insert, len);
-}
-
-class LineReader
-{
-public:
-	LineReader(const char* _str)
-		: m_str(_str)
-		, m_pos(0)
-		, m_size( (uint32_t)strlen(_str) )
-	{
-	}
-
-	std::string getLine()
-	{
-		const char* str = &m_str[m_pos];
-		skipLine();
-
-		const char* eol = &m_str[m_pos];
-
-		std::string tmp;
-		tmp.assign(str, eol-str);
-		return tmp;
-	}
-
-	bool isEof() const
-	{
-		return m_str[m_pos] == '\0';
-	}
-
-private:
-	void skipLine()
-	{
-		const char* str = &m_str[m_pos];
-		const char* nl = strnl(str);
-		m_pos += (uint32_t)(nl - str);
-	}
-
-	const char* m_str;
-	uint32_t m_pos;
-	uint32_t m_size;
-};
-
-void printCode(const char* _code)
-{
-	fprintf(stderr, "Code:\n---\n");
-
-	LineReader lr(_code);
-	for (uint32_t line =  1; !lr.isEof(); ++line)
-	{
-		fprintf(stderr, "%3d: %s", line, lr.getLine().c_str() );
-	}
-
-	fprintf(stderr, "---\n");
-}
-
-bool compileGLSLShader(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
-{
-	const glslopt_shader_type type = tolower(_cmdLine.findOption('\0', "type")[0]) == 'f' ? kGlslOptShaderFragment : kGlslOptShaderVertex;
-
-	glslopt_ctx* ctx = glslopt_initialize(false);
-
-	glslopt_shader* shader = glslopt_optimize(ctx, type, _code.c_str(), 0); 
-
-	if( !glslopt_get_status(shader) )
-	{
-		printCode(_code.c_str() );
-		fprintf(stderr, "Error: %s\n", glslopt_get_log(shader) );
-		glslopt_cleanup(ctx);
-		return false;
-	}
-
-	const char* optimizedShader = glslopt_get_output(shader);
-
-	const char* profile = _cmdLine.findOption('p');
-	if (NULL == profile)
-	{
-		_stream.write("#ifdef GL_ES\n");
-		_stream.write("precision highp float;\n");
-		_stream.write("#endif // GL_ES\n\n");
-	}
-	else
-	{
-		_stream.writef("#version %s\n\n", profile);
-	}
-
-	_stream.write(optimizedShader, strlen(optimizedShader) );
-	uint8_t nul = 0;
-	_stream.write(nul);
-
-	glslopt_cleanup(ctx);
-
-	return true;
-}
-
-bool compileHLSLShaderDx9(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
-{
-#if BX_PLATFORM_WINDOWS
-	const char* profile = _cmdLine.findOption('p');
-	if (NULL == profile)
-	{
-		printf("Shader profile must be specified.\n");
-		return false;
-	}
-
-	bool bigEndian = _cmdLine.hasArg('\0', "xbox360");
-
-	uint32_t flags = 0;
-	flags |= _cmdLine.hasArg('\0', "debug") ? D3DXSHADER_DEBUG : 0;
-	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DXSHADER_AVOID_FLOW_CONTROL : 0;
-	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DXSHADER_NO_PRESHADER : 0;
-	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DXSHADER_PARTIALPRECISION : 0;
-	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DXSHADER_PREFER_FLOW_CONTROL : 0;
-	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY : 0;
-	
-	bool werror = _cmdLine.hasArg('\0', "Werror");
-
-	uint32_t optimization = 3;
-	if (_cmdLine.hasArg(optimization, 'O') )
-	{
-		optimization = bx::uint32_min(optimization, countof(s_optimizationLevelDx9)-1);
-		flags |= s_optimizationLevelDx9[optimization];
-	}
-	else
-	{
-		flags |= D3DXSHADER_SKIPOPTIMIZATION;
-	}
-
-	BX_TRACE("Profile: %s", profile);
-	BX_TRACE("Flags: 0x%08x", flags);
-	BX_TRACE("Big Endian: %s", bigEndian?"true":"false");
-
-	LPD3DXBUFFER code;
-	LPD3DXBUFFER errorMsg;
-	LPD3DXCONSTANTTABLE constantTable;
-
-	HRESULT hr = D3DXCompileShader(_code.c_str()
-		, _code.size()
-		, NULL
-		, NULL
-		, "main"
-		, profile
-		, flags
-		, &code
-		, &errorMsg
-		, &constantTable
-		);
-	if (FAILED(hr)
-	||  werror && NULL != errorMsg)
-	{
-		printCode(_code.c_str() );
-		fprintf(stderr, "Error: 0x%08x %s\n", hr, errorMsg->GetBufferPointer() );
-		return false;
-	}
-
-	D3DXCONSTANTTABLE_DESC desc;
-	hr = constantTable->GetDesc(&desc);
-	if (FAILED(hr) )
-	{
-		fprintf(stderr, "Error 0x%08x\n", hr);
-		return false;
-	}
-
-	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
-	BX_TRACE("Num constants: %d", desc.Constants);
-	BX_TRACE("#   cl ty RxC   S  By Name");
-
-	UniformArray uniforms;
-
-	for (uint32_t ii = 0; ii < desc.Constants; ++ii)
-	{
-		D3DXHANDLE handle = constantTable->GetConstant(NULL, ii);
-		D3DXCONSTANT_DESC constDesc;
-		uint32_t count;
-		constantTable->GetConstantDesc(handle, &constDesc, &count);
-		BX_TRACE("%3d %2d %2d [%dx%d] %d %3d %s[%d] c%d (%d)"
-			, ii
-			, constDesc.Class
-			, constDesc.Type
-			, constDesc.Rows
-			, constDesc.Columns
-			, constDesc.StructMembers
-			, constDesc.Bytes
-			, constDesc.Name
-			, constDesc.Elements
-			, constDesc.RegisterIndex
-			, constDesc.RegisterCount
-			);
-
-		ConstantType::Enum type = findConstantTypeDx9(constDesc);
-		if (ConstantType::Count != type)
-		{
-			Uniform un;
-			un.name = '$' == constDesc.Name[0] ? constDesc.Name+1 : constDesc.Name;
-			un.type = type;
-			un.num = constDesc.Elements;
-			un.regIndex = constDesc.RegisterIndex;
-			un.regCount = constDesc.RegisterCount;
-			uniforms.push_back(un);
-		}
-	}
-
-	uint16_t count = (uint16_t)uniforms.size();
-	_stream.write(count);
-
-	uint32_t fragmentBit = profile[0] == 'p' ? ConstantType::FragmentBit : 0;
-	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
-	{
-		const Uniform& un = *it;
-		uint8_t nameSize = (uint8_t)un.name.size();
-		_stream.write(nameSize);
-		_stream.write(un.name.c_str(), nameSize);
-		_stream.write<uint8_t>(un.type|fragmentBit);
-		_stream.write(un.num);
-		_stream.write(un.regIndex);
-		_stream.write(un.regCount);
-
-		BX_TRACE("%s, %s, %d, %d, %d"
-			, un.name.c_str()
-			, s_constantTypeName[un.type]
-			, un.num
-			, un.regIndex
-			, un.regCount
-			);
-	}
-
-	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
-	_stream.write(shaderSize);
-	_stream.write(code->GetBufferPointer(), shaderSize);
-	uint8_t nul = 0;
-	_stream.write(nul);
-
-	if (NULL != code)
-	{
-		code->Release();
-	}
-
-	if (NULL != errorMsg)
-	{
-		errorMsg->Release();
-	}
-
-	if (NULL != constantTable)
-	{
-		constantTable->Release();
-	}
-
-	return true;
-#else
-	fprintf(stderr, "HLSL compiler is not supported on this platform.\n");
-	return false;
-#endif // BX_PLATFORM_WINDOWS
-}
-
-bool compileHLSLShaderDx11(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
-{
-#if BX_PLATFORM_WINDOWS
-	const char* profile = _cmdLine.findOption('p');
-	if (NULL == profile)
-	{
-		printf("Shader profile must be specified.\n");
-		return false;
-	}
-
-	bool bigEndian = _cmdLine.hasArg('\0', "xbox360");
-
-	uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
-	flags |= _cmdLine.hasArg('\0', "debug") ? D3DCOMPILE_DEBUG : 0;
-	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0;
-	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0;
-	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0;
-	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0;
-	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0;
-
-	bool werror = _cmdLine.hasArg('\0', "Werror");
-
-	if (werror)
-	{
-		flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
-	}
-
-	uint32_t optimization = 3;
-	if (_cmdLine.hasArg(optimization, 'O') )
-	{
-		optimization = bx::uint32_min(optimization, countof(s_optimizationLevelDx11)-1);
-		flags |= s_optimizationLevelDx11[optimization];
-	}
-	else
-	{
-		flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
-	}
-
-	BX_TRACE("Profile: %s", profile);
-	BX_TRACE("Flags: 0x%08x", flags);
-	BX_TRACE("Big Endian: %s", bigEndian?"true":"false");
-
-	ID3DBlob* code;
-	ID3DBlob* errorMsg;
-
-	HRESULT hr = D3DCompile(_code.c_str()
-		, _code.size()
-		, NULL
-		, NULL
-		, NULL
-		, "main"
-		, profile
-		, flags
-		, 0
-		, &code
-		, &errorMsg
-		);
-	if (FAILED(hr)
-	||  werror && NULL != errorMsg)
-	{
-		printCode(_code.c_str() );
-		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x %s\n", hr, errorMsg->GetBufferPointer() );
-		errorMsg->Release();
-		return false;
-	}
-
-	UniformArray uniforms;
-
-	ID3D11ShaderReflection* reflect = NULL;
-	hr = D3DReflect(code->GetBufferPointer()
-		, code->GetBufferSize()
-		, IID_ID3D11ShaderReflection
-		, (void**)&reflect
-		);
-	if (FAILED(hr) )
-	{
-		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", hr);
-		return false;
-	}
-
-	D3D11_SHADER_DESC desc;
-	hr = reflect->GetDesc(&desc);
-	if (FAILED(hr) )
-	{
-		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", hr);
-		return false;
-	}
-
-	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
-	BX_TRACE("Num constant buffers: %d", desc.ConstantBuffers);
-
-	BX_TRACE("Input:");
-	uint8_t attrMask[Attrib::Count];
-	memset(attrMask, 0, sizeof(attrMask) );
-
-	for (uint32_t ii = 0; ii < desc.InputParameters; ++ii)
-	{
-		D3D11_SIGNATURE_PARAMETER_DESC spd;
-		reflect->GetInputParameterDesc(ii, &spd);
-		BX_TRACE("\t%2d: %s%d, %d, %d, %x, %d"
-			, ii
-			, spd.SemanticName
-			, spd.SemanticIndex
-			, spd.SystemValueType
-			, spd.ComponentType
-			, spd.Mask
-			, spd.Register
-			);
-
-		const RemapInputSemantic& ris = findInputSemantic(spd.SemanticName, spd.SemanticIndex);
-		if (ris.m_attr != Attrib::Count)
-		{
-			attrMask[ris.m_attr] = 0xff;
-		}
-	}
-
-	_stream.write(attrMask, sizeof(attrMask) );
-
-	BX_TRACE("Output:");
-	for (uint32_t ii = 0; ii < desc.OutputParameters; ++ii)
-	{
-		D3D11_SIGNATURE_PARAMETER_DESC spd;
-		reflect->GetOutputParameterDesc(ii, &spd);
-		BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType);
-	}
-
-	uint16_t size = 0;
-
-	for (uint32_t ii = 0; ii < bx::uint32_min(1, desc.ConstantBuffers); ++ii)
-	{
-		ID3D11ShaderReflectionConstantBuffer* cbuffer = reflect->GetConstantBufferByIndex(ii);
-		D3D11_SHADER_BUFFER_DESC bufferDesc;
-		hr = cbuffer->GetDesc(&bufferDesc);
-
-		size = (uint16_t)bufferDesc.Size;
-
-		if (SUCCEEDED(hr) )
-		{
-			BX_TRACE("%s, %d, vars %d, size %d"
-				, bufferDesc.Name
-				, bufferDesc.Type
-				, bufferDesc.Variables
-				, bufferDesc.Size
-				);
-
-			for (uint32_t jj = 0; jj < bufferDesc.Variables; ++jj)
-			{
-				ID3D11ShaderReflectionVariable* var = cbuffer->GetVariableByIndex(jj);
-				ID3D11ShaderReflectionType* type = var->GetType();
-				D3D11_SHADER_VARIABLE_DESC varDesc;
-				hr = var->GetDesc(&varDesc);
-				if (SUCCEEDED(hr) )
-				{
-					D3D11_SHADER_TYPE_DESC constDesc;
-					hr = type->GetDesc(&constDesc);
-					if (SUCCEEDED(hr) )
-					{
-						ConstantType::Enum type = findConstantTypeDx11(constDesc, varDesc.Size);
-
-						if (ConstantType::Count != type
-						&&  0 != (varDesc.uFlags & D3D_SVF_USED) )
-						{
-							Uniform un;
-							un.name = varDesc.Name;
-							un.type = type;
-							un.num = constDesc.Elements;
-							un.regIndex = varDesc.StartOffset;
-							un.regCount = varDesc.Size;
-							uniforms.push_back(un);
-
-							BX_TRACE("\t%s, %d, size %d, flags 0x%08x, %d"
-								, varDesc.Name
-								, varDesc.StartOffset
-								, varDesc.Size
-								, varDesc.uFlags
-								, type
-								);
-						}
-					}
-				}
-			}
-		}
-	}
-
-	BX_TRACE("Bound:");
-	for (uint32_t ii = 0; ii < desc.BoundResources; ++ii)
-	{
-		D3D11_SHADER_INPUT_BIND_DESC bindDesc;
-
-		hr = reflect->GetResourceBindingDesc(ii, &bindDesc);
-		if (SUCCEEDED(hr) )
-		{
-//			if (bindDesc.Type == D3D_SIT_SAMPLER)
-			{
-				BX_TRACE("\t%s, %d, %d, %d"
-					, bindDesc.Name
-					, bindDesc.Type
-					, bindDesc.BindPoint
-					, bindDesc.BindCount
-					);
-			}
-		}
-	}
-
-	uint16_t count = (uint16_t)uniforms.size();
-	_stream.write(count);
-
-	_stream.write(size);
-
-	uint32_t fragmentBit = profile[0] == 'p' ? ConstantType::FragmentBit : 0;
-	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
-	{
-		const Uniform& un = *it;
-		uint8_t nameSize = (uint8_t)un.name.size();
-		_stream.write(nameSize);
-		_stream.write(un.name.c_str(), nameSize);
-		_stream.write<uint8_t>(un.type|fragmentBit);
-		_stream.write(un.num);
-		_stream.write(un.regIndex);
-		_stream.write(un.regCount);
-
-		BX_TRACE("%s, %s, %d, %d, %d"
-			, un.name.c_str()
-			, s_constantTypeName[un.type]
-			, un.num
-			, un.regIndex
-			, un.regCount
-			);
-	}
-
-	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
-	_stream.write(shaderSize);
-	_stream.write(code->GetBufferPointer(), shaderSize);
-	uint8_t nul = 0;
-	_stream.write(nul);
-
-	if (NULL != reflect)
-	{
-		reflect->Release();
-	}
-
-	if (NULL != errorMsg)
-	{
-		errorMsg->Release();
-	}
-
-	code->Release();
-
-	return true;
-#else
-	fprintf(stderr, "HLSL compiler is not supported on this platform.\n");
-	return false;
-#endif // BX_PLATFORM_WINDOWS
-}
-
-struct Preprocessor
-{
-	Preprocessor(const char* _filePath)
-		: m_tagptr(m_tags)
-		, m_scratchPos(0)
-		, m_fgetsPos(0)
-	{
-		m_tagptr->tag = FPPTAG_USERDATA;
-		m_tagptr->data = this;
-		m_tagptr++;
-
-		m_tagptr->tag = FPPTAG_DEPENDS;
-		m_tagptr->data = (void*)fppDepends;
-		m_tagptr++; 
-
-		m_tagptr->tag = FPPTAG_INPUT;
-		m_tagptr->data = (void*)fppInput;
-		m_tagptr++; 
-
-		m_tagptr->tag = FPPTAG_OUTPUT;
-		m_tagptr->data = (void*)fppOutput;
-		m_tagptr++;
-
-		m_tagptr->tag = FPPTAG_ERROR;
-		m_tagptr->data = (void*)fppError;
-		m_tagptr++;
-
-		m_tagptr->tag = FPPTAG_IGNOREVERSION;
-		m_tagptr->data = (void*)0;
-		m_tagptr++;
-
-		m_tagptr->tag = FPPTAG_LINE;
-		m_tagptr->data = (void*)0;
-		m_tagptr++;
-
-		m_tagptr->tag = FPPTAG_INPUT_NAME;
-		m_tagptr->data = scratch(_filePath);
-		m_tagptr++;
-
-		m_default = "#define lowp\n#define mediump\n#define highp\n";
-	}
-
-	void setDefine(const char* _define)
-	{
-		m_tagptr->tag = FPPTAG_DEFINE;
-		m_tagptr->data = scratch(_define);
-		m_tagptr++;
-	}
-
-	void setDefaultDefine(const char* _name)
-	{
-		char temp[1024];
-		_snprintf(temp, countof(temp)
-			, "#ifndef %s\n"
-			  "#	define %s 0\n"
-			  "#endif // %s\n"
-			  "\n"
-			, _name
-			, _name
-			, _name
-			);
-
-		m_default += temp;
-	}
-
-	void writef(const char* _format, ...)
-	{
-		va_list argList;
-		va_start(argList, _format);
-
-		char temp[2048];
-		int len = vsnprintf(temp, sizeof(temp), _format, argList);
-		m_default += temp;
-
-		va_end(argList);
-	}
-
-	void addDependency(const char* _fileName)
-	{
-		m_depends += " \\\n ";
-		m_depends += _fileName;
-	}
-
-	bool run(const char* _input)
-	{
-		m_fgetsPos = 0;
-
-		m_input = m_default;
-		m_input += _input;
-
-		fppTag* tagptr = m_tagptr;
-
-		tagptr->tag = FPPTAG_END;
-		tagptr->data = 0;
-		tagptr++;
-
-		int result = fppPreProcess(m_tags);
-
-		return 0 == result;
-	}
-
-	char* fgets(char* _buffer, int _size)
-	{
-		int ii = 0;
-		for (char ch = m_input[m_fgetsPos]; m_fgetsPos < m_input.size() && ii < _size-1; ch = m_input[++m_fgetsPos])
-		{
-			_buffer[ii++] = ch;
-
-			if (ch == '\n' || ii == _size)
-			{
-				_buffer[ii] = '\0';
-				m_fgetsPos++;
-				return _buffer;
-			}
-		}
-
-		return NULL;
-	}
-
-	static void fppDepends(char* _fileName, void* _userData)
-	{
-		Preprocessor* thisClass = (Preprocessor*)_userData;
-		thisClass->addDependency(_fileName);
-	}
-
-	static char* fppInput(char* _buffer, int _size, void* _userData)
-	{
-		Preprocessor* thisClass = (Preprocessor*)_userData;
-		return thisClass->fgets(_buffer, _size);
-	}
-
-	static void fppOutput(int _ch, void* _userData)
-	{
-		Preprocessor* thisClass = (Preprocessor*)_userData;
-		thisClass->m_preprocessed += _ch;
-	}
-
-	static void fppError(void* _userData, char* _format, va_list _vargs)
-	{
-		vfprintf(stderr, _format, _vargs);
-	}
-
-	char* scratch(const char* _str)
-	{
-		char* result = &m_scratch[m_scratchPos];
-		strcpy(result, _str);
-		m_scratchPos += strlen(_str)+1;
-
-		return result;
-	}
-
-	fppTag m_tags[MAX_TAGS];
-	fppTag* m_tagptr;
-
-	std::string m_depends;
-	std::string m_default;
-	std::string m_input;
-	std::string m_preprocessed;
-	char m_scratch[16<<10];
-	uint32_t m_scratchPos;
-	uint32_t m_fgetsPos;
-};
-
-const char* baseName(const char* _filePath)
-{
-	const char* bs = strrchr(_filePath, '\\');
-	const char* fs = strrchr(_filePath, '/');
-	const char* column = strrchr(_filePath, ':');
-	const char* basename = std::max(std::max(bs, fs), column);
-	if (NULL != basename)
-	{
-		return basename+1;
-	}
-
-	return _filePath;
-}
-
-// OpenGL #version Features Direct3D Features Shader Model
-// 2.1    120      vf       9.0      vf       2.0
-// 3.0    130
-// 3.1    140
-// 3.2    150      vgf
-// 3.3    330               10.0     vgf      4.0
-// 4.0    400      vhdgf
-// 4.1    410
-// 4.2    420               11.0     vhdgf    5.0
-
-int main(int _argc, const char* _argv[])
-{
-	CommandLine cmdLine(_argc, _argv);
-
-	const char* filePath = cmdLine.findOption('f');
-	if (NULL == filePath)
-	{
-		fprintf(stderr, "Shader file name must be specified.\n");
-		return EXIT_FAILURE;
-	}
-
-	const char* outFilePath = cmdLine.findOption('o');
-	if (NULL == outFilePath)
-	{
-		fprintf(stderr, "Output file name must be specified.\n");
-		return EXIT_FAILURE;
-	}
-
-	const char* type = cmdLine.findOption('\0', "type");
-	if (NULL == type)
-	{
-		fprintf(stderr, "Must specify shader type.");
-		return EXIT_FAILURE;
-	}
-
-	const char* platform = cmdLine.findOption('\0', "platform");
-	if (NULL == platform)
-	{
-		fprintf(stderr, "Must specify platform.\n");
-		return EXIT_FAILURE;
-	}
-
-	uint32_t hlsl = 2;
-	const char* profile = cmdLine.findOption('p');
-	if (NULL != profile)
-	{
-		if (0 == strncmp(&profile[1], "s_3", 3) )
-		{
-			hlsl = 3;
-		}
-		else if (0 == strncmp(&profile[1], "s_4", 3) )
-		{
-			hlsl = 4;
-		}
-		else if (0 == strncmp(&profile[1], "s_5", 3) )
-		{
-			hlsl = 5;
-		}
-	}
-
-	const char* bin2c = NULL;
-	if (cmdLine.hasArg("bin2c") )
-	{
-		bin2c = cmdLine.findOption("bin2c");
-		if (NULL == bin2c)
-		{
-			bin2c = baseName(outFilePath);
-			uint32_t len = strlen(bin2c);
-			char* temp = (char*)alloca(len+1);
-			for (char *out = temp; *bin2c != '\0';)
-			{
-				char ch = *bin2c++;
-				if (isalnum(ch) )
-				{
-					*out++ = ch;
-				}
-				else
-				{
-					*out++ = '_';
-				}
-			}
-			temp[len] = '\0';
-
-			bin2c = temp;
-		}
-	}
-
-	bool depends = cmdLine.hasArg("depends");
-	bool preprocessOnly = cmdLine.hasArg("preprocess");
-
-	Preprocessor preprocessor(filePath);
-
-	preprocessor.setDefaultDefine("BX_PLATFORM_ANDROID");
-	preprocessor.setDefaultDefine("BX_PLATFORM_IOS");
-	preprocessor.setDefaultDefine("BX_PLATFORM_LINUX");
-	preprocessor.setDefaultDefine("BX_PLATFORM_NACL");
-	preprocessor.setDefaultDefine("BX_PLATFORM_OSX");
-	preprocessor.setDefaultDefine("BX_PLATFORM_WINDOWS");
-	preprocessor.setDefaultDefine("BX_PLATFORM_XBOX360");
-	preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_GLSL");
-	preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_HLSL");
-	preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_FRAGMENT");
-	preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_VERTEX");
-
-	bool glsl = false;
-
-	if (0 == _stricmp(platform, "android") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_ANDROID=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
-		glsl = true;
-	}
-	else if (0 == _stricmp(platform, "ios") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_IOS=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
-		glsl = true;
-	}
-	else if (0 == _stricmp(platform, "linux") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_IOS=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
-		glsl = true;
-	}
-	else if (0 == _stricmp(platform, "nacl") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_NACL=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
-		glsl = true;
-	}
-	else if (0 == _stricmp(platform, "osx") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_OSX=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
-		glsl = true;
-	}
-	else if (0 == _stricmp(platform, "windows") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_WINDOWS=1");
-		char temp[256];
-		_snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_HLSL=%d", hlsl);
-		preprocessor.setDefine(temp);
-	}
-	else if (0 == _stricmp(platform, "xbox360") )
-	{
-		preprocessor.setDefine("BX_PLATFORM_XBOX360=1");
-		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_HLSL=3");
-	}
-	else
-	{
-		fprintf(stderr, "Unknown platform %s?!", platform);
-		return EXIT_FAILURE;
-	}
-
-	preprocessor.setDefine("M_PI=3.1415926535897932384626433832795");
-
-	bool fragment = false;
-	switch (tolower(type[0]) )
-	{
-	case 'f':
-		preprocessor.setDefine("BGFX_SHADER_TYPE_FRAGMENT=1");
-		fragment = true;
-		break;
-
-	case 'v':
-		preprocessor.setDefine("BGFX_SHADER_TYPE_VERTEX=1");
-		break;
-
-	default:
-		fprintf(stderr, "Unknown type: %s?!", type);
-		return EXIT_FAILURE;
-	}
-
-	FILE* file = fopen(filePath, "r");
-	if (NULL != file)
-	{
-		VaryingMap varyingMap;
-
-		File attribdef("varying.def.sc");
-		const char* parse = attribdef.getData();
-		while (NULL != parse
-		   &&  *parse != '\0')
-		{
-			parse = strws(parse);
-			const char* eol = strchr(parse, ';');
-			if (NULL != eol)
-			{
-				const char* type = parse;
-				const char* name = parse = strws(strword(parse) );
-				const char* column = parse = strws(strword(parse) );
-				const char* semantics = parse = strws(strnws(parse) );
-				const char* assign = parse = strws(strword(parse) );
-				const char* init = parse = strws(strnws(parse) );
-
-				if (type < eol
-				&&  name < eol
-				&&  column < eol
-				&&  ':' == *column
-				&&  semantics < eol)
-				{
-					Varying var;
-					var.m_type.assign(type, strword(type)-type);
-					var.m_name.assign(name, strword(name)-name);
-					var.m_semantics.assign(semantics, strword(semantics)-semantics);
-
-					if (assign < eol
-					&&  '=' == *assign
-					&&  init < eol)
-					{
-						var.m_init.assign(init, eol-init);
-					}
-
-					varyingMap.insert(std::make_pair(var.m_name, var) );
-				}
-
-				parse = eol + 1;
-			}
-		}
-
-		const size_t padding = 16;
-		long int size = fsize(file);
- 		char* data = new char[size+padding];
- 		size = fread(data, 1, size, file);
-		memset(&data[size], 0, padding);
-		fclose(file);
-
-		typedef std::vector<std::string> InOut;
-		InOut shaderInputs;
-		InOut shaderOutputs;
-
-		const char* input = data;
-		while (input[0] == '$')
-		{
-			const char* str = input+1;
-			const char* eol = streol(str);
-			const char* nl = strnl(eol);
-			input = nl;
-
-			if (0 == strncmp(str, "input", 5) )
-			{
-				str += 5;
-				str = strws(str);
-
-				if (str < eol)
-				{
-					const char* delim;
-					do
-					{
-						delim = strpbrk(str, " ,");
-						if (NULL != delim)
-						{
-							delim = delim > eol ? eol : delim;
-							std::string token;
-							token.assign(str, delim-str);
-							shaderInputs.push_back(token);
-							str = strws(delim + 1);
-						}
-					}
-					while (delim < eol && NULL != delim);
-				}
-			}
-			else if (0 == strncmp(str, "output", 6) )
-			{
-				str += 6;
-				str = strws(str);
-
-				if (str < eol)
-				{
-					const char* delim;
-					do
-					{
-						delim = strpbrk(str, " ,");
-						if (NULL != delim)
-						{
-							delim = delim > eol ? eol : delim;
-							std::string token;
-							token.assign(str, delim-str);
-							shaderOutputs.push_back(token);
-							str = strws(delim + 1);
-						}
-					}
-					while (delim < eol && NULL != delim);
-				}
-			}
-		}
-
-		if (glsl)
-		{
-			for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
-			{
-				VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-				if (varyingIt != varyingMap.end() )
-				{
-					const Varying& var = varyingIt->second;
-					const char* name = var.m_name.c_str();
-					if (0 == strncmp(name, "a_", 2)
-					||  0 == strncmp(name, "i_", 2) )
-					{
-						preprocessor.writef("attribute %s %s;\n", var.m_type.c_str(), name);
-					}
-					else
-					{
-						preprocessor.writef("varying %s %s;\n", var.m_type.c_str(), name);
-					}
-				}
-			}
-
-			for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
-			{
-				VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-				if (varyingIt != varyingMap.end() )
-				{
-					const Varying& var = varyingIt->second;
-					preprocessor.writef("varying %s %s;\n", var.m_type.c_str(), var.m_name.c_str() );
-				}
-			}
-		}
-		else
-		{
-			preprocessor.writef(
-					"#define lowp\n"
-					"#define mediump\n"
-					"#define highp\n"
-					"#define vec2 float2\n"
-					"#define vec3 float3\n"
-					"#define vec4 float4\n"
-					"#define mat2 float2x2\n"
-					"#define mat3 float3x3\n"
-					"#define mat4 float4x4\n"
-				);
-
-			char* entry = strstr(data, "void main()");
-			if (NULL != entry)
-			{
-				entry[4] = '_';
-
-				if (fragment)
-				{
-					preprocessor.writef("#define void_main() \\\n");
-					preprocessor.writef("\tvoid main(vec4 gl_FragCoord : SV_POSITION \\\n");
-					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
-					{
-						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-						if (varyingIt != varyingMap.end() )
-						{
-							const Varying& var = varyingIt->second;
-							preprocessor.writef("\t, %s %s : %s \\\n", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
-						}
-					}
-
-					preprocessor.writef(
-						", out vec4 gl_FragColor : SV_TARGET \\\n"
-						);
-
-					if (NULL != strstr(data, "gl_FragDepth") )
-					{
-						preprocessor.writef(
-							", out float gl_FragDepth : SV_DEPTH \\\n"
-							);
-					}
-
-					preprocessor.writef(
-						")\n"
-						);
-				}
-				else
-				{
-					const char* brace = strstr(entry, "{");
-					if (NULL != brace)
-					{
-						const char* end = strmb(brace, '{', '}');
-						if (NULL != end)
-						{
-							strins(const_cast<char*>(end), "__RETURN__;\n");
-						}
-					}
-
-					preprocessor.writef(
-						"struct Output\n"
-						"{\n"
-						"\tvec4 gl_Position : SV_POSITION;\n"
-						"#define gl_Position _varying_.gl_Position\n"
-						);
-					for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
-					{
-						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-						if (varyingIt != varyingMap.end() )
-						{
-							const Varying& var = varyingIt->second;
-							preprocessor.writef("\t%s %s : %s;\n", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
-							preprocessor.writef("#define %s _varying_.%s\n", var.m_name.c_str(), var.m_name.c_str() );
-						}
-					}
-					preprocessor.writef(
-						"};\n"
-						);
-
-					preprocessor.writef("#define void_main() \\\n");
-					preprocessor.writef("Output main(");
-					bool first = true;
-					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
-					{
-						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-						if (varyingIt != varyingMap.end() )
-						{
-							const Varying& var = varyingIt->second;
-							preprocessor.writef("%s%s %s : %s\\\n", first ? "" : "\t, ", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
-							first = false;
-						}
-					}
-					preprocessor.writef(
-						") \\\n"
-						"{ \\\n"
-						"\tOutput _varying_;"
-						);
-
-					for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
-					{
-						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
-						if (varyingIt != varyingMap.end() )
-						{
-							const Varying& var = varyingIt->second;
-							preprocessor.writef(" \\\n\t%s = %s;", var.m_name.c_str(), var.m_init.c_str() );
-						}
-					}
-
-					preprocessor.writef(
-						"\n#define __RETURN__ \\\n"
-						"\t} \\\n"
-						"\treturn _varying_"
-						);
-				}
-			}
-		}
-
-		if (preprocessor.run(input) )
-		{
-			BX_TRACE("Input file: %s", filePath);
-			BX_TRACE("Output file: %s", outFilePath);
-
-			if (preprocessOnly)
-			{
-				FileWriter stream(outFilePath);
-
-				if (!stream.open() )
-				{
-					fprintf(stderr, "Unable to open output file '%s'.", outFilePath);
-					return false;
-				}
-
-				if (glsl)
-				{
-					const char* profile = cmdLine.findOption('p');
-					if (NULL == profile)
-					{
-						stream.write("#ifdef GL_ES\n");
-						stream.write("precision highp float;\n");
-						stream.write("#endif // GL_ES\n\n");
-					}
-					else
-					{
-						stream.writef("#version %s\n\n", profile);
-					}
-				}
-				stream.write(preprocessor.m_preprocessed.c_str(), preprocessor.m_preprocessed.size() );
-				stream.close();
-
-				return EXIT_SUCCESS;
-			}
-
-			bool compiled = false;
-
-			{
-				IStreamWriter* stream = NULL;
-
-				if (NULL != bin2c)
-				{
-					stream = new Bin2cStream(outFilePath, bin2c);
-				}
-				else
-				{
-					stream = new FileWriter(outFilePath);
-				}
-
-				if (!stream->open() )
-				{
-					fprintf(stderr, "Unable to open output file '%s'.", outFilePath);
-					return false;
-				}
-
-				if (glsl)
-				{
-					compiled = compileGLSLShader(cmdLine, preprocessor.m_preprocessed, *stream);
-				}
-				else
-				{
-					if (hlsl > 3)
-					{
-						compiled = compileHLSLShaderDx11(cmdLine, preprocessor.m_preprocessed, *stream);
-					}
-					else
-					{
-						compiled = compileHLSLShaderDx9(cmdLine, preprocessor.m_preprocessed, *stream);
-					}
-				}
-
-#if SHADERC_DEBUG
-				stream->writeString(filePath);
-#endif // SHADERC_DEBUG
-
-				stream->close();
-				delete stream;
-			}
-
-			if (compiled)
-			{
-				if (depends)
-				{
-					std::string ofp = outFilePath;
-					ofp += ".d";
-					FileWriter stream(ofp.c_str() );
-					if (stream.open() )
-					{
-						stream.write(outFilePath);
-						stream.write(":");
-						stream.write(preprocessor.m_depends.c_str() );
-						stream.write("\n");
-						stream.close();
-					}
-				}
-
-				return EXIT_SUCCESS;
-			}
-		}
-
-		delete [] data;
-	}
-
-	remove(outFilePath);
-
-	fprintf(stderr, "Failed to build shader.\n");
-	return EXIT_FAILURE;
-}
+
+#define MAX_TAGS 256
+extern "C"
+{
+#include <fpp.h>
+} // extern "C"
+
+#if SHADERC_DEBUG
+#	define BX_TRACE(_format, ...) fprintf(stderr, "" _format "\n", ##__VA_ARGS__)
+#endif // DEBUG
+
+#define BX_NAMESPACE 1
+#include <bx/bx.h>
+
+#if BX_PLATFORM_LINUX
+#	include <stdarg.h>
+
+#	define _stricmp strcasecmp
+#	define _snprintf snprintf
+#endif // BX_PLATFORM_LINUX
+
+#include <bx/commandline.h>
+#include <bx/countof.h>
+#include <bx/endian.h>
+#include <bx/uint32_t.h>
+
+#include "glsl_optimizer.h"
+
+#if BX_PLATFORM_WINDOWS
+#	if BX_COMPILER_GCC
+#		include <sal.h>
+#	endif // BX_COMPILER_GCC
+#	include <d3dx9.h>
+#	include <d3dcompiler.h>
+#endif // BX_PLATFORM_WINDOWS
+
+long int fsize(FILE* _file)
+{
+	long int pos = ftell(_file);
+	fseek(_file, 0L, SEEK_END);
+	long int size = ftell(_file);
+	fseek(_file, pos, SEEK_SET);
+	return size;
+}
+
+struct Attrib
+{
+	enum Enum
+	{
+		Position = 0,
+		Normal,
+		Tangent,
+		Color0,
+		Color1,
+		Indices,
+		Weight,
+		TexCoord0,
+		TexCoord1,
+		TexCoord2,
+		TexCoord3,
+		TexCoord4,
+		TexCoord5,
+		TexCoord6,
+		TexCoord7,
+
+		Count,
+	};
+};
+
+struct RemapInputSemantic
+{
+	Attrib::Enum m_attr;
+	const char* m_name;
+	uint8_t m_index;
+};
+
+static const RemapInputSemantic s_remapInputSemantic[Attrib::Count+1] =
+{
+	{ Attrib::Position,  "POSITION",     0 },
+	{ Attrib::Normal,    "NORMAL",       0 },
+	{ Attrib::Tangent,   "TANGENT",      0 },
+	{ Attrib::Color0,    "COLOR",        0 },
+	{ Attrib::Color1,    "COLOR",        1 },
+	{ Attrib::Indices,   "BLENDINDICES", 0 },
+	{ Attrib::Weight,    "BLENDWEIGHT",  0 },
+	{ Attrib::TexCoord0, "TEXCOORD",     0 },
+	{ Attrib::TexCoord1, "TEXCOORD",     1 },
+	{ Attrib::TexCoord2, "TEXCOORD",     2 },
+	{ Attrib::TexCoord3, "TEXCOORD",     3 },
+	{ Attrib::TexCoord4, "TEXCOORD",     4 },
+	{ Attrib::TexCoord5, "TEXCOORD",     5 },
+	{ Attrib::TexCoord6, "TEXCOORD",     6 },
+	{ Attrib::TexCoord7, "TEXCOORD",     7 },
+	{ Attrib::Count,     "",             0 },
+};
+
+const RemapInputSemantic& findInputSemantic(const char* _name, uint8_t _index)
+{
+	for (uint32_t ii = 0; ii < Attrib::Count; ++ii)
+	{
+		const RemapInputSemantic& ris = s_remapInputSemantic[ii];
+		if (0 == strcmp(ris.m_name, _name)
+		&&  ris.m_index == _index)
+		{
+			return ris;
+		}
+	}
+
+	return s_remapInputSemantic[Attrib::Count];
+}
+
+struct ConstantType
+{
+	enum Enum
+	{
+		Uniform1i,
+		Uniform1f,
+		End,
+
+		Uniform1iv,
+		Uniform1fv,
+		Uniform2fv,
+		Uniform3fv,
+		Uniform4fv,
+		Uniform3x3fv,
+		Uniform4x4fv,
+
+		Count,
+		TypeMask = 0x7f,
+		FragmentBit = 0x80
+	};
+};
+
+static const char* s_constantTypeName[ConstantType::Count] =
+{
+	"int",
+	"float",
+	NULL,
+	"int",
+	"float",
+	"float2",
+	"float3",
+	"float4",
+	"float3x3",
+	"float4x4",
+};
+
+struct Uniform
+{
+	std::string name;
+	ConstantType::Enum type;
+	uint8_t num;
+	uint16_t regIndex;
+	uint16_t regCount;
+};
+typedef std::vector<Uniform> UniformArray;
+
+#if BX_PLATFORM_WINDOWS
+struct ConstRemapDx9
+{
+	ConstantType::Enum id;
+	D3DXPARAMETER_CLASS paramClass;
+	D3DXPARAMETER_TYPE paramType;
+	uint32_t paramBytes;
+};
+
+static const ConstRemapDx9 s_constRemapDx9[7] =
+{
+	{ ConstantType::Uniform1iv,   D3DXPC_SCALAR,         D3DXPT_INT,    4 },
+	{ ConstantType::Uniform1fv,   D3DXPC_SCALAR,         D3DXPT_FLOAT,  4 },
+	{ ConstantType::Uniform2fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT,  8 },
+	{ ConstantType::Uniform3fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 12 },
+	{ ConstantType::Uniform4fv,   D3DXPC_VECTOR,         D3DXPT_FLOAT, 16 },
+	{ ConstantType::Uniform3x3fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 36 },
+	{ ConstantType::Uniform4x4fv, D3DXPC_MATRIX_COLUMNS, D3DXPT_FLOAT, 64 },
+};
+
+ConstantType::Enum findConstantTypeDx9(const D3DXCONSTANT_DESC& constDesc)
+{
+	uint32_t count = sizeof(s_constRemapDx9)/sizeof(ConstRemapDx9);
+	for (uint32_t ii = 0; ii < count; ++ii)
+	{
+		const ConstRemapDx9& remap = s_constRemapDx9[ii];
+
+		if (remap.paramClass == constDesc.Class
+		&&  remap.paramType == constDesc.Type
+		&&  (constDesc.Bytes%remap.paramBytes) == 0)
+		{
+			return remap.id;
+		}
+	}
+
+	return ConstantType::Count;
+}
+
+static uint32_t s_optimizationLevelDx9[4] =
+{
+	D3DXSHADER_OPTIMIZATION_LEVEL0,
+	D3DXSHADER_OPTIMIZATION_LEVEL1,
+	D3DXSHADER_OPTIMIZATION_LEVEL2,
+	D3DXSHADER_OPTIMIZATION_LEVEL3,
+};
+
+struct ConstRemapDx11
+{
+	ConstantType::Enum id;
+	D3D_SHADER_VARIABLE_CLASS paramClass;
+	D3D_SHADER_VARIABLE_TYPE paramType;
+	uint32_t paramBytes;
+};
+
+static const ConstRemapDx11 s_constRemapDx11[7] =
+{
+	{ ConstantType::Uniform1iv,   D3D_SVC_SCALAR,         D3D_SVT_INT,    4 },
+	{ ConstantType::Uniform1fv,   D3D_SVC_SCALAR,         D3D_SVT_FLOAT,  4 },
+	{ ConstantType::Uniform2fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT,  8 },
+	{ ConstantType::Uniform3fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT, 12 },
+	{ ConstantType::Uniform4fv,   D3D_SVC_VECTOR,         D3D_SVT_FLOAT, 16 },
+	{ ConstantType::Uniform3x3fv, D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 36 },
+	{ ConstantType::Uniform4x4fv, D3D_SVC_MATRIX_COLUMNS, D3D_SVT_FLOAT, 64 },
+};
+
+ConstantType::Enum findConstantTypeDx11(const D3D11_SHADER_TYPE_DESC& constDesc, uint32_t _size)
+{
+	uint32_t count = sizeof(s_constRemapDx11)/sizeof(ConstRemapDx9);
+	for (uint32_t ii = 0; ii < count; ++ii)
+	{
+		const ConstRemapDx11& remap = s_constRemapDx11[ii];
+
+		if (remap.paramClass == constDesc.Class
+		&&  remap.paramType == constDesc.Type
+		&&  (_size%remap.paramBytes) == 0)
+		{
+			return remap.id;
+		}
+	}
+
+	return ConstantType::Count;
+}
+
+static uint32_t s_optimizationLevelDx11[4] =
+{
+	D3DCOMPILE_OPTIMIZATION_LEVEL0,
+	D3DCOMPILE_OPTIMIZATION_LEVEL1,
+	D3DCOMPILE_OPTIMIZATION_LEVEL2,
+	D3DCOMPILE_OPTIMIZATION_LEVEL3,
+};
+#endif // BX_PLATFORM_WINDOWS
+
+class IStreamWriter
+{
+public:
+	virtual ~IStreamWriter() = 0;
+	virtual bool open() = 0;
+	virtual void close() = 0;
+	virtual void writef(const char* _format, ...) = 0;
+	virtual void write(const char* _str) = 0;
+	virtual void write(const void* _data, size_t _size) = 0;
+
+	template<typename Ty>
+	void write(Ty _value)
+	{
+		write(&_value, sizeof(Ty) );
+	}
+
+	void writeString(const char* _str)
+	{
+		uint16_t len = (uint16_t)strlen(_str);
+		write(len);
+		write(_str);
+		char term = '\0';
+		write(term);
+	}
+};
+
+IStreamWriter::~IStreamWriter()
+{
+}
+
+class FileWriter : public IStreamWriter
+{
+public:
+	FileWriter(const char* _filePath, bool _bigEndian = false)
+		: m_filePath(_filePath)
+		, m_file(NULL)
+		, m_bigEndian(_bigEndian)
+	{
+	}
+
+	~FileWriter()
+	{
+	}
+
+	bool open()
+	{
+		BX_CHECK(NULL == m_file, "Still open!");
+
+		m_file = fopen(m_filePath.c_str(), "wb");
+		return NULL != m_file;
+	}
+
+	void close()
+	{
+		if (NULL != m_file)
+		{
+			fclose(m_file);
+			m_file = NULL;
+		}
+	}
+
+	void writef(const char* _format, ...)
+	{
+		if (NULL != m_file)
+		{
+			va_list argList;
+			va_start(argList, _format);
+
+			char temp[2048];
+			int len = vsnprintf(temp, sizeof(temp), _format, argList);
+			fwrite(temp, len, 1, m_file);
+
+			va_end(argList);
+		}
+	}
+
+	void write(const char* _str)
+	{
+		if (NULL != m_file)
+		{
+			fwrite(_str, strlen(_str), 1, m_file);
+		}
+	}
+
+	void write(const void* _data, size_t _size)
+	{
+		if (NULL != m_file)
+		{
+			fwrite(_data, _size, 1, m_file);
+		}
+	}
+
+private:
+	std::string m_filePath;
+	FILE* m_file;
+	bool m_bigEndian;
+};
+
+class Bin2cStream : public IStreamWriter
+{
+public:
+	Bin2cStream(const char* _filePath, const char* _name)
+		: m_filePath(_filePath)
+		, m_name(_name)
+		, m_file(NULL)
+	{
+	}
+
+	~Bin2cStream()
+	{
+	}
+
+	bool open()
+	{
+		BX_CHECK(NULL == m_file, "Still open!");
+
+		m_file = fopen(m_filePath.c_str(), "wb");
+		return NULL != m_file;
+	}
+
+	void close()
+	{
+		if (NULL != m_file)
+		{
+#define HEX_DUMP_WIDTH 16
+#define HEX_DUMP_SPACE_WIDTH 96
+#define HEX_DUMP_FORMAT "%-" BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "." BX_STRINGIZE(HEX_DUMP_SPACE_WIDTH) "s"
+			const uint8_t* data = &m_buffer[0];
+			uint32_t size = m_buffer.size();
+
+			fprintf(m_file, "static const uint8_t %s[%d] =\n{\n", m_name.c_str(), size);
+
+			if (NULL != data)
+			{
+				char hex[HEX_DUMP_SPACE_WIDTH+1];
+				char ascii[HEX_DUMP_WIDTH+1];
+				uint32_t hexPos = 0;
+				uint32_t asciiPos = 0;
+				for (uint32_t ii = 0; ii < size; ++ii)
+				{
+					_snprintf(&hex[hexPos], sizeof(hex)-hexPos, "0x%02x, ", data[asciiPos]);
+					hexPos += 6;
+
+					ascii[asciiPos] = isprint(data[asciiPos]) && data[asciiPos] != '\\' ? data[asciiPos] : '.';
+					asciiPos++;
+
+					if (HEX_DUMP_WIDTH == asciiPos)
+					{
+						ascii[asciiPos] = '\0';
+						fprintf(m_file, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
+						data += asciiPos;
+						hexPos = 0;
+						asciiPos = 0;
+					}
+				}
+
+				if (0 != asciiPos)
+				{
+					ascii[asciiPos] = '\0';
+					fprintf(m_file, "\t" HEX_DUMP_FORMAT "// %s\n", hex, ascii);
+				}
+			}
+
+			fprintf(m_file, "};\n");
+#undef HEX_DUMP_WIDTH
+#undef HEX_DUMP_SPACE_WIDTH
+#undef HEX_DUMP_FORMAT
+
+			fclose(m_file);
+			m_file = NULL;
+		}
+	}
+
+	void writef(const char* _format, ...)
+	{
+		va_list argList;
+		va_start(argList, _format);
+
+		char temp[2048];
+		int len = vsnprintf(temp, sizeof(temp), _format, argList);
+		m_buffer.insert(m_buffer.end(), temp, temp+len);
+
+		va_end(argList);
+	}
+
+	void write(const char* _str)
+	{
+		m_buffer.insert(m_buffer.end(), _str, _str+strlen(_str) );
+	}
+
+	void write(const void* _data, size_t _size)
+	{
+		const char* data = (const char*)_data;
+		m_buffer.insert(m_buffer.end(), data, data+_size);
+	}
+
+private:
+	std::string m_filePath;
+	std::string m_name;
+	typedef std::vector<uint8_t> Buffer;
+	Buffer m_buffer;
+	FILE* m_file;
+};
+
+struct Varying
+{
+	std::string m_name;
+	std::string m_type;
+	std::string m_init;
+	std::string m_semantics;
+};
+
+typedef std::unordered_map<std::string, Varying> VaryingMap;
+
+class File 
+{
+public:
+	File(const char* _filePath)
+		: m_data(NULL)
+	{
+		FILE* file = fopen(_filePath, "r");
+		if (NULL != file)
+		{
+			m_size = fsize(file);
+			m_data = new char[m_size+1];
+			m_size = fread(m_data, 1, m_size, file);
+			m_data[m_size] = '\0';
+			fclose(file);
+		}
+	}
+
+	~File()
+	{
+		delete [] m_data;
+	}
+
+	const char* getData() const
+	{
+		return m_data;
+	}
+
+	long int getSize() const
+	{
+		return m_size;
+	}
+
+private:
+	char* m_data;
+	long int m_size;
+};
+
+const char* strnl(const char* _str)
+{
+	const char* eol = strstr(_str, "\n\r");
+	if (NULL != eol)
+	{
+		return eol + 2;
+	}
+
+	eol = strstr(_str, "\n");
+	if (NULL != eol)
+	{
+		return eol + 1;
+	}
+
+	return eol + strlen(_str);
+}
+
+const char* streol(const char* _str)
+{
+	const char* eol = strstr(_str, "\n\r");
+	if (NULL != eol)
+	{
+		return eol;
+	}
+
+	eol = strstr(_str, "\n");
+	if (NULL != eol)
+	{
+		return eol;
+	}
+
+	return eol + strlen(_str);
+}
+
+const char* strws(const char* _str)
+{
+	for (; isspace(*_str); ++_str);
+	return _str;
+}
+
+const char* strnws(const char* _str)
+{
+	for (; !isspace(*_str); ++_str);
+	return _str;
+}
+
+const char* strword(const char* _str)
+{
+	for (char ch = *_str++; isalnum(ch) || '_' == ch; ch = *_str++);
+	return _str-1;
+}
+
+const char* strmb(const char* _str, char _open, char _close)
+{
+	int count = 0;
+	for (char ch = *_str++; ch != '\0' && count >= 0; ch = *_str++)
+	{
+		if (ch == _open)
+		{
+			count++;
+		}
+		else if (ch == _close)
+		{
+			count--;
+			if (0 == count)
+			{
+				return _str-1;
+			}
+		}
+	}
+
+	return NULL;
+}
+
+void strins(char* _str, const char* _insert)
+{
+	size_t len = strlen(_insert);
+	memmove(&_str[len], _str, strlen(_str) );
+	memcpy(_str, _insert, len);
+}
+
+class LineReader
+{
+public:
+	LineReader(const char* _str)
+		: m_str(_str)
+		, m_pos(0)
+		, m_size( (uint32_t)strlen(_str) )
+	{
+	}
+
+	std::string getLine()
+	{
+		const char* str = &m_str[m_pos];
+		skipLine();
+
+		const char* eol = &m_str[m_pos];
+
+		std::string tmp;
+		tmp.assign(str, eol-str);
+		return tmp;
+	}
+
+	bool isEof() const
+	{
+		return m_str[m_pos] == '\0';
+	}
+
+private:
+	void skipLine()
+	{
+		const char* str = &m_str[m_pos];
+		const char* nl = strnl(str);
+		m_pos += (uint32_t)(nl - str);
+	}
+
+	const char* m_str;
+	uint32_t m_pos;
+	uint32_t m_size;
+};
+
+void printCode(const char* _code)
+{
+	fprintf(stderr, "Code:\n---\n");
+
+	LineReader lr(_code);
+	for (uint32_t line =  1; !lr.isEof(); ++line)
+	{
+		fprintf(stderr, "%3d: %s", line, lr.getLine().c_str() );
+	}
+
+	fprintf(stderr, "---\n");
+}
+
+void writeFile(const char* _filePath, void* _data, uint32_t _size)
+{
+	FILE* file = fopen(_filePath, "wb");
+	if (NULL != file)
+	{
+		fwrite(_data, 1, _size, file);
+		fclose(file);
+	}
+}
+
+bool compileGLSLShader(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
+{
+	const glslopt_shader_type type = tolower(_cmdLine.findOption('\0', "type")[0]) == 'f' ? kGlslOptShaderFragment : kGlslOptShaderVertex;
+
+	glslopt_ctx* ctx = glslopt_initialize(false);
+
+	glslopt_shader* shader = glslopt_optimize(ctx, type, _code.c_str(), 0); 
+
+	if( !glslopt_get_status(shader) )
+	{
+		printCode(_code.c_str() );
+		fprintf(stderr, "Error: %s\n", glslopt_get_log(shader) );
+		glslopt_cleanup(ctx);
+		return false;
+	}
+
+	const char* optimizedShader = glslopt_get_output(shader);
+
+	const char* profile = _cmdLine.findOption('p');
+	if (NULL == profile)
+	{
+		_stream.write("#ifdef GL_ES\n");
+		_stream.write("precision highp float;\n");
+		_stream.write("#endif // GL_ES\n\n");
+	}
+	else
+	{
+		_stream.writef("#version %s\n\n", profile);
+	}
+
+	_stream.write(optimizedShader, strlen(optimizedShader) );
+	uint8_t nul = 0;
+	_stream.write(nul);
+
+	glslopt_cleanup(ctx);
+
+	return true;
+}
+
+bool compileHLSLShaderDx9(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
+{
+#if BX_PLATFORM_WINDOWS
+	const char* profile = _cmdLine.findOption('p');
+	if (NULL == profile)
+	{
+		printf("Shader profile must be specified.\n");
+		return false;
+	}
+
+	bool bigEndian = _cmdLine.hasArg('\0', "xbox360");
+
+	uint32_t flags = 0;
+	flags |= _cmdLine.hasArg('\0', "debug") ? D3DXSHADER_DEBUG : 0;
+	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DXSHADER_AVOID_FLOW_CONTROL : 0;
+	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DXSHADER_NO_PRESHADER : 0;
+	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DXSHADER_PARTIALPRECISION : 0;
+	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DXSHADER_PREFER_FLOW_CONTROL : 0;
+	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DXSHADER_ENABLE_BACKWARDS_COMPATIBILITY : 0;
+	
+	bool werror = _cmdLine.hasArg('\0', "Werror");
+
+	uint32_t optimization = 3;
+	if (_cmdLine.hasArg(optimization, 'O') )
+	{
+		optimization = bx::uint32_min(optimization, countof(s_optimizationLevelDx9)-1);
+		flags |= s_optimizationLevelDx9[optimization];
+	}
+	else
+	{
+		flags |= D3DXSHADER_SKIPOPTIMIZATION;
+	}
+
+	BX_TRACE("Profile: %s", profile);
+	BX_TRACE("Flags: 0x%08x", flags);
+	BX_TRACE("Big Endian: %s", bigEndian?"true":"false");
+
+	LPD3DXBUFFER code;
+	LPD3DXBUFFER errorMsg;
+	LPD3DXCONSTANTTABLE constantTable;
+
+	HRESULT hr = D3DXCompileShader(_code.c_str()
+		, _code.size()
+		, NULL
+		, NULL
+		, "main"
+		, profile
+		, flags
+		, &code
+		, &errorMsg
+		, &constantTable
+		);
+	if (FAILED(hr)
+	||  werror && NULL != errorMsg)
+	{
+		printCode(_code.c_str() );
+		fprintf(stderr, "Error: 0x%08x %s\n", hr, errorMsg->GetBufferPointer() );
+		return false;
+	}
+
+	D3DXCONSTANTTABLE_DESC desc;
+	hr = constantTable->GetDesc(&desc);
+	if (FAILED(hr) )
+	{
+		fprintf(stderr, "Error 0x%08x\n", hr);
+		return false;
+	}
+
+	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
+	BX_TRACE("Num constants: %d", desc.Constants);
+	BX_TRACE("#   cl ty RxC   S  By Name");
+
+	UniformArray uniforms;
+
+	for (uint32_t ii = 0; ii < desc.Constants; ++ii)
+	{
+		D3DXHANDLE handle = constantTable->GetConstant(NULL, ii);
+		D3DXCONSTANT_DESC constDesc;
+		uint32_t count;
+		constantTable->GetConstantDesc(handle, &constDesc, &count);
+		BX_TRACE("%3d %2d %2d [%dx%d] %d %3d %s[%d] c%d (%d)"
+			, ii
+			, constDesc.Class
+			, constDesc.Type
+			, constDesc.Rows
+			, constDesc.Columns
+			, constDesc.StructMembers
+			, constDesc.Bytes
+			, constDesc.Name
+			, constDesc.Elements
+			, constDesc.RegisterIndex
+			, constDesc.RegisterCount
+			);
+
+		ConstantType::Enum type = findConstantTypeDx9(constDesc);
+		if (ConstantType::Count != type)
+		{
+			Uniform un;
+			un.name = '$' == constDesc.Name[0] ? constDesc.Name+1 : constDesc.Name;
+			un.type = type;
+			un.num = constDesc.Elements;
+			un.regIndex = constDesc.RegisterIndex;
+			un.regCount = constDesc.RegisterCount;
+			uniforms.push_back(un);
+		}
+	}
+
+	uint16_t count = (uint16_t)uniforms.size();
+	_stream.write(count);
+
+	uint32_t fragmentBit = profile[0] == 'p' ? ConstantType::FragmentBit : 0;
+	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
+	{
+		const Uniform& un = *it;
+		uint8_t nameSize = (uint8_t)un.name.size();
+		_stream.write(nameSize);
+		_stream.write(un.name.c_str(), nameSize);
+		_stream.write<uint8_t>(un.type|fragmentBit);
+		_stream.write(un.num);
+		_stream.write(un.regIndex);
+		_stream.write(un.regCount);
+
+		BX_TRACE("%s, %s, %d, %d, %d"
+			, un.name.c_str()
+			, s_constantTypeName[un.type]
+			, un.num
+			, un.regIndex
+			, un.regCount
+			);
+	}
+
+	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
+	_stream.write(shaderSize);
+	_stream.write(code->GetBufferPointer(), shaderSize);
+	uint8_t nul = 0;
+	_stream.write(nul);
+
+	if (_cmdLine.hasArg('\0', "disasm") )
+	{
+		LPD3DXBUFFER disasm;
+		D3DXDisassembleShader( (const DWORD*)code->GetBufferPointer()
+			, false
+			, NULL
+			, &disasm
+			);
+
+		if (NULL != disasm)
+		{
+			std::string ofp = _cmdLine.findOption('o');
+			ofp += ".disasm";
+
+			writeFile(ofp.c_str(), disasm->GetBufferPointer(), disasm->GetBufferSize() );
+			disasm->Release();
+		}
+	}
+
+	if (NULL != code)
+	{
+		code->Release();
+	}
+
+	if (NULL != errorMsg)
+	{
+		errorMsg->Release();
+	}
+
+	if (NULL != constantTable)
+	{
+		constantTable->Release();
+	}
+
+	return true;
+#else
+	fprintf(stderr, "HLSL compiler is not supported on this platform.\n");
+	return false;
+#endif // BX_PLATFORM_WINDOWS
+}
+
+bool compileHLSLShaderDx11(CommandLine& _cmdLine, const std::string& _code, IStreamWriter& _stream)
+{
+#if BX_PLATFORM_WINDOWS
+	const char* profile = _cmdLine.findOption('p');
+	if (NULL == profile)
+	{
+		printf("Shader profile must be specified.\n");
+		return false;
+	}
+
+	bool bigEndian = _cmdLine.hasArg('\0', "xbox360");
+
+	uint32_t flags = D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY;
+	flags |= _cmdLine.hasArg('\0', "debug") ? D3DCOMPILE_DEBUG : 0;
+	flags |= _cmdLine.hasArg('\0', "avoid-flow-control") ? D3DCOMPILE_AVOID_FLOW_CONTROL : 0;
+	flags |= _cmdLine.hasArg('\0', "no-preshader") ? D3DCOMPILE_NO_PRESHADER : 0;
+	flags |= _cmdLine.hasArg('\0', "partial-precision") ? D3DCOMPILE_PARTIAL_PRECISION : 0;
+	flags |= _cmdLine.hasArg('\0', "prefer-flow-control") ? D3DCOMPILE_PREFER_FLOW_CONTROL : 0;
+	flags |= _cmdLine.hasArg('\0', "backwards-compatibility") ? D3DCOMPILE_ENABLE_BACKWARDS_COMPATIBILITY : 0;
+
+	bool werror = _cmdLine.hasArg('\0', "Werror");
+
+	if (werror)
+	{
+		flags |= D3DCOMPILE_WARNINGS_ARE_ERRORS;
+	}
+
+	uint32_t optimization = 3;
+	if (_cmdLine.hasArg(optimization, 'O') )
+	{
+		optimization = bx::uint32_min(optimization, countof(s_optimizationLevelDx11)-1);
+		flags |= s_optimizationLevelDx11[optimization];
+	}
+	else
+	{
+		flags |= D3DCOMPILE_SKIP_OPTIMIZATION;
+	}
+
+	BX_TRACE("Profile: %s", profile);
+	BX_TRACE("Flags: 0x%08x", flags);
+	BX_TRACE("Big Endian: %s", bigEndian?"true":"false");
+
+	ID3DBlob* code;
+	ID3DBlob* errorMsg;
+
+	HRESULT hr = D3DCompile(_code.c_str()
+		, _code.size()
+		, NULL
+		, NULL
+		, NULL
+		, "main"
+		, profile
+		, flags
+		, 0
+		, &code
+		, &errorMsg
+		);
+	if (FAILED(hr)
+	||  werror && NULL != errorMsg)
+	{
+		printCode(_code.c_str() );
+		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x %s\n", hr, (char*)errorMsg->GetBufferPointer() );
+		errorMsg->Release();
+		return false;
+	}
+
+	UniformArray uniforms;
+
+	ID3D11ShaderReflection* reflect = NULL;
+	hr = D3DReflect(code->GetBufferPointer()
+		, code->GetBufferSize()
+		, IID_ID3D11ShaderReflection
+		, (void**)&reflect
+		);
+	if (FAILED(hr) )
+	{
+		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", hr);
+		return false;
+	}
+
+	D3D11_SHADER_DESC desc;
+	hr = reflect->GetDesc(&desc);
+	if (FAILED(hr) )
+	{
+		fprintf(stderr, BX_FILE_LINE_LITERAL "Error: 0x%08x\n", hr);
+		return false;
+	}
+
+	BX_TRACE("Creator: %s 0x%08x", desc.Creator, desc.Version);
+	BX_TRACE("Num constant buffers: %d", desc.ConstantBuffers);
+
+	BX_TRACE("Input:");
+	uint8_t attrMask[Attrib::Count];
+	memset(attrMask, 0, sizeof(attrMask) );
+
+	for (uint32_t ii = 0; ii < desc.InputParameters; ++ii)
+	{
+		D3D11_SIGNATURE_PARAMETER_DESC spd;
+		reflect->GetInputParameterDesc(ii, &spd);
+		BX_TRACE("\t%2d: %s%d, %d, %d, %x, %d"
+			, ii
+			, spd.SemanticName
+			, spd.SemanticIndex
+			, spd.SystemValueType
+			, spd.ComponentType
+			, spd.Mask
+			, spd.Register
+			);
+
+		const RemapInputSemantic& ris = findInputSemantic(spd.SemanticName, spd.SemanticIndex);
+		if (ris.m_attr != Attrib::Count)
+		{
+			attrMask[ris.m_attr] = 0xff;
+		}
+	}
+
+	_stream.write(attrMask, sizeof(attrMask) );
+
+	BX_TRACE("Output:");
+	for (uint32_t ii = 0; ii < desc.OutputParameters; ++ii)
+	{
+		D3D11_SIGNATURE_PARAMETER_DESC spd;
+		reflect->GetOutputParameterDesc(ii, &spd);
+		BX_TRACE("\t%2d: %s%d, %d, %d", ii, spd.SemanticName, spd.SemanticIndex, spd.SystemValueType, spd.ComponentType);
+	}
+
+	uint16_t size = 0;
+
+	for (uint32_t ii = 0; ii < bx::uint32_min(1, desc.ConstantBuffers); ++ii)
+	{
+		ID3D11ShaderReflectionConstantBuffer* cbuffer = reflect->GetConstantBufferByIndex(ii);
+		D3D11_SHADER_BUFFER_DESC bufferDesc;
+		hr = cbuffer->GetDesc(&bufferDesc);
+
+		size = (uint16_t)bufferDesc.Size;
+
+		if (SUCCEEDED(hr) )
+		{
+			BX_TRACE("%s, %d, vars %d, size %d"
+				, bufferDesc.Name
+				, bufferDesc.Type
+				, bufferDesc.Variables
+				, bufferDesc.Size
+				);
+
+			for (uint32_t jj = 0; jj < bufferDesc.Variables; ++jj)
+			{
+				ID3D11ShaderReflectionVariable* var = cbuffer->GetVariableByIndex(jj);
+				ID3D11ShaderReflectionType* type = var->GetType();
+				D3D11_SHADER_VARIABLE_DESC varDesc;
+				hr = var->GetDesc(&varDesc);
+				if (SUCCEEDED(hr) )
+				{
+					D3D11_SHADER_TYPE_DESC constDesc;
+					hr = type->GetDesc(&constDesc);
+					if (SUCCEEDED(hr) )
+					{
+						ConstantType::Enum type = findConstantTypeDx11(constDesc, varDesc.Size);
+
+						if (ConstantType::Count != type
+						&&  0 != (varDesc.uFlags & D3D_SVF_USED) )
+						{
+							Uniform un;
+							un.name = varDesc.Name;
+							un.type = type;
+							un.num = constDesc.Elements;
+							un.regIndex = varDesc.StartOffset;
+							un.regCount = BX_ALIGN_16(varDesc.Size)/16;
+							uniforms.push_back(un);
+
+							BX_TRACE("\t%s, %d, size %d, flags 0x%08x, %d"
+								, varDesc.Name
+								, varDesc.StartOffset
+								, varDesc.Size
+								, varDesc.uFlags
+								, type
+								);
+						}
+					}
+				}
+			}
+		}
+	}
+
+	BX_TRACE("Bound:");
+	for (uint32_t ii = 0; ii < desc.BoundResources; ++ii)
+	{
+		D3D11_SHADER_INPUT_BIND_DESC bindDesc;
+
+		hr = reflect->GetResourceBindingDesc(ii, &bindDesc);
+		if (SUCCEEDED(hr) )
+		{
+//			if (bindDesc.Type == D3D_SIT_SAMPLER)
+			{
+				BX_TRACE("\t%s, %d, %d, %d"
+					, bindDesc.Name
+					, bindDesc.Type
+					, bindDesc.BindPoint
+					, bindDesc.BindCount
+					);
+			}
+		}
+	}
+
+	uint16_t count = (uint16_t)uniforms.size();
+	_stream.write(count);
+
+	_stream.write(size);
+
+	uint32_t fragmentBit = profile[0] == 'p' ? ConstantType::FragmentBit : 0;
+	for (UniformArray::const_iterator it = uniforms.begin(); it != uniforms.end(); ++it)
+	{
+		const Uniform& un = *it;
+		uint8_t nameSize = (uint8_t)un.name.size();
+		_stream.write(nameSize);
+		_stream.write(un.name.c_str(), nameSize);
+		_stream.write<uint8_t>(un.type|fragmentBit);
+		_stream.write(un.num);
+		_stream.write(un.regIndex);
+		_stream.write(un.regCount);
+
+		BX_TRACE("%s, %s, %d, %d, %d"
+			, un.name.c_str()
+			, s_constantTypeName[un.type]
+			, un.num
+			, un.regIndex
+			, un.regCount
+			);
+	}
+
+	uint16_t shaderSize = (uint16_t)code->GetBufferSize();
+	_stream.write(shaderSize);
+	_stream.write(code->GetBufferPointer(), shaderSize);
+	uint8_t nul = 0;
+	_stream.write(nul);
+
+	if (_cmdLine.hasArg('\0', "disasm") )
+	{
+		ID3DBlob* disasm;
+		D3DDisassemble(code->GetBufferPointer()
+			, code->GetBufferSize()
+			, 0
+			, NULL
+			, &disasm
+			);
+
+		if (NULL != disasm)
+		{
+			std::string ofp = _cmdLine.findOption('o');
+			ofp += ".disasm";
+
+			writeFile(ofp.c_str(), disasm->GetBufferPointer(), disasm->GetBufferSize() );
+			disasm->Release();
+		}
+	}
+
+	if (NULL != reflect)
+	{
+		reflect->Release();
+	}
+
+	if (NULL != errorMsg)
+	{
+		errorMsg->Release();
+	}
+
+	code->Release();
+
+	return true;
+#else
+	fprintf(stderr, "HLSL compiler is not supported on this platform.\n");
+	return false;
+#endif // BX_PLATFORM_WINDOWS
+}
+
+struct Preprocessor
+{
+	Preprocessor(const char* _filePath)
+		: m_tagptr(m_tags)
+		, m_scratchPos(0)
+		, m_fgetsPos(0)
+	{
+		m_tagptr->tag = FPPTAG_USERDATA;
+		m_tagptr->data = this;
+		m_tagptr++;
+
+		m_tagptr->tag = FPPTAG_DEPENDS;
+		m_tagptr->data = (void*)fppDepends;
+		m_tagptr++; 
+
+		m_tagptr->tag = FPPTAG_INPUT;
+		m_tagptr->data = (void*)fppInput;
+		m_tagptr++; 
+
+		m_tagptr->tag = FPPTAG_OUTPUT;
+		m_tagptr->data = (void*)fppOutput;
+		m_tagptr++;
+
+		m_tagptr->tag = FPPTAG_ERROR;
+		m_tagptr->data = (void*)fppError;
+		m_tagptr++;
+
+		m_tagptr->tag = FPPTAG_IGNOREVERSION;
+		m_tagptr->data = (void*)0;
+		m_tagptr++;
+
+		m_tagptr->tag = FPPTAG_LINE;
+		m_tagptr->data = (void*)0;
+		m_tagptr++;
+
+		m_tagptr->tag = FPPTAG_INPUT_NAME;
+		m_tagptr->data = scratch(_filePath);
+		m_tagptr++;
+
+		m_default = "#define lowp\n#define mediump\n#define highp\n";
+	}
+
+	void setDefine(const char* _define)
+	{
+		m_tagptr->tag = FPPTAG_DEFINE;
+		m_tagptr->data = scratch(_define);
+		m_tagptr++;
+	}
+
+	void setDefaultDefine(const char* _name)
+	{
+		char temp[1024];
+		_snprintf(temp, countof(temp)
+			, "#ifndef %s\n"
+			  "#	define %s 0\n"
+			  "#endif // %s\n"
+			  "\n"
+			, _name
+			, _name
+			, _name
+			);
+
+		m_default += temp;
+	}
+
+	void writef(const char* _format, ...)
+	{
+		va_list argList;
+		va_start(argList, _format);
+
+		char temp[2048];
+		int len = vsnprintf(temp, sizeof(temp), _format, argList);
+		m_default += temp;
+
+		va_end(argList);
+	}
+
+	void addDependency(const char* _fileName)
+	{
+		m_depends += " \\\n ";
+		m_depends += _fileName;
+	}
+
+	bool run(const char* _input)
+	{
+		m_fgetsPos = 0;
+
+		m_input = m_default;
+		m_input += _input;
+
+		fppTag* tagptr = m_tagptr;
+
+		tagptr->tag = FPPTAG_END;
+		tagptr->data = 0;
+		tagptr++;
+
+		int result = fppPreProcess(m_tags);
+
+		return 0 == result;
+	}
+
+	char* fgets(char* _buffer, int _size)
+	{
+		int ii = 0;
+		for (char ch = m_input[m_fgetsPos]; m_fgetsPos < m_input.size() && ii < _size-1; ch = m_input[++m_fgetsPos])
+		{
+			_buffer[ii++] = ch;
+
+			if (ch == '\n' || ii == _size)
+			{
+				_buffer[ii] = '\0';
+				m_fgetsPos++;
+				return _buffer;
+			}
+		}
+
+		return NULL;
+	}
+
+	static void fppDepends(char* _fileName, void* _userData)
+	{
+		Preprocessor* thisClass = (Preprocessor*)_userData;
+		thisClass->addDependency(_fileName);
+	}
+
+	static char* fppInput(char* _buffer, int _size, void* _userData)
+	{
+		Preprocessor* thisClass = (Preprocessor*)_userData;
+		return thisClass->fgets(_buffer, _size);
+	}
+
+	static void fppOutput(int _ch, void* _userData)
+	{
+		Preprocessor* thisClass = (Preprocessor*)_userData;
+		thisClass->m_preprocessed += _ch;
+	}
+
+	static void fppError(void* _userData, char* _format, va_list _vargs)
+	{
+		vfprintf(stderr, _format, _vargs);
+	}
+
+	char* scratch(const char* _str)
+	{
+		char* result = &m_scratch[m_scratchPos];
+		strcpy(result, _str);
+		m_scratchPos += strlen(_str)+1;
+
+		return result;
+	}
+
+	fppTag m_tags[MAX_TAGS];
+	fppTag* m_tagptr;
+
+	std::string m_depends;
+	std::string m_default;
+	std::string m_input;
+	std::string m_preprocessed;
+	char m_scratch[16<<10];
+	uint32_t m_scratchPos;
+	uint32_t m_fgetsPos;
+};
+
+const char* baseName(const char* _filePath)
+{
+	const char* bs = strrchr(_filePath, '\\');
+	const char* fs = strrchr(_filePath, '/');
+	const char* column = strrchr(_filePath, ':');
+	const char* basename = std::max(std::max(bs, fs), column);
+	if (NULL != basename)
+	{
+		return basename+1;
+	}
+
+	return _filePath;
+}
+
+// OpenGL #version Features Direct3D Features Shader Model
+// 2.1    120      vf       9.0      vf       2.0
+// 3.0    130
+// 3.1    140
+// 3.2    150      vgf
+// 3.3    330               10.0     vgf      4.0
+// 4.0    400      vhdgf
+// 4.1    410
+// 4.2    420               11.0     vhdgf    5.0
+
+int main(int _argc, const char* _argv[])
+{
+	CommandLine cmdLine(_argc, _argv);
+
+	const char* filePath = cmdLine.findOption('f');
+	if (NULL == filePath)
+	{
+		fprintf(stderr, "Shader file name must be specified.\n");
+		return EXIT_FAILURE;
+	}
+
+	const char* outFilePath = cmdLine.findOption('o');
+	if (NULL == outFilePath)
+	{
+		fprintf(stderr, "Output file name must be specified.\n");
+		return EXIT_FAILURE;
+	}
+
+	const char* type = cmdLine.findOption('\0', "type");
+	if (NULL == type)
+	{
+		fprintf(stderr, "Must specify shader type.");
+		return EXIT_FAILURE;
+	}
+
+	const char* platform = cmdLine.findOption('\0', "platform");
+	if (NULL == platform)
+	{
+		fprintf(stderr, "Must specify platform.\n");
+		return EXIT_FAILURE;
+	}
+
+	uint32_t hlsl = 2;
+	const char* profile = cmdLine.findOption('p');
+	if (NULL != profile)
+	{
+		if (0 == strncmp(&profile[1], "s_3", 3) )
+		{
+			hlsl = 3;
+		}
+		else if (0 == strncmp(&profile[1], "s_4", 3) )
+		{
+			hlsl = 4;
+		}
+		else if (0 == strncmp(&profile[1], "s_5", 3) )
+		{
+			hlsl = 5;
+		}
+	}
+
+	const char* bin2c = NULL;
+	if (cmdLine.hasArg("bin2c") )
+	{
+		bin2c = cmdLine.findOption("bin2c");
+		if (NULL == bin2c)
+		{
+			bin2c = baseName(outFilePath);
+			uint32_t len = strlen(bin2c);
+			char* temp = (char*)alloca(len+1);
+			for (char *out = temp; *bin2c != '\0';)
+			{
+				char ch = *bin2c++;
+				if (isalnum(ch) )
+				{
+					*out++ = ch;
+				}
+				else
+				{
+					*out++ = '_';
+				}
+			}
+			temp[len] = '\0';
+
+			bin2c = temp;
+		}
+	}
+
+	bool depends = cmdLine.hasArg("depends");
+	bool preprocessOnly = cmdLine.hasArg("preprocess");
+
+	Preprocessor preprocessor(filePath);
+
+	preprocessor.setDefaultDefine("BX_PLATFORM_ANDROID");
+	preprocessor.setDefaultDefine("BX_PLATFORM_IOS");
+	preprocessor.setDefaultDefine("BX_PLATFORM_LINUX");
+	preprocessor.setDefaultDefine("BX_PLATFORM_NACL");
+	preprocessor.setDefaultDefine("BX_PLATFORM_OSX");
+	preprocessor.setDefaultDefine("BX_PLATFORM_WINDOWS");
+	preprocessor.setDefaultDefine("BX_PLATFORM_XBOX360");
+	preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_GLSL");
+	preprocessor.setDefaultDefine("BGFX_SHADER_LANGUAGE_HLSL");
+	preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_FRAGMENT");
+	preprocessor.setDefaultDefine("BGFX_SHADER_TYPE_VERTEX");
+
+	bool glsl = false;
+
+	if (0 == _stricmp(platform, "android") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_ANDROID=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
+		glsl = true;
+	}
+	else if (0 == _stricmp(platform, "ios") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_IOS=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
+		glsl = true;
+	}
+	else if (0 == _stricmp(platform, "linux") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_IOS=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
+		glsl = true;
+	}
+	else if (0 == _stricmp(platform, "nacl") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_NACL=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
+		glsl = true;
+	}
+	else if (0 == _stricmp(platform, "osx") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_OSX=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_GLSL=1");
+		glsl = true;
+	}
+	else if (0 == _stricmp(platform, "windows") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_WINDOWS=1");
+		char temp[256];
+		_snprintf(temp, sizeof(temp), "BGFX_SHADER_LANGUAGE_HLSL=%d", hlsl);
+		preprocessor.setDefine(temp);
+	}
+	else if (0 == _stricmp(platform, "xbox360") )
+	{
+		preprocessor.setDefine("BX_PLATFORM_XBOX360=1");
+		preprocessor.setDefine("BGFX_SHADER_LANGUAGE_HLSL=3");
+	}
+	else
+	{
+		fprintf(stderr, "Unknown platform %s?!", platform);
+		return EXIT_FAILURE;
+	}
+
+	preprocessor.setDefine("M_PI=3.1415926535897932384626433832795");
+
+	bool fragment = false;
+	switch (tolower(type[0]) )
+	{
+	case 'f':
+		preprocessor.setDefine("BGFX_SHADER_TYPE_FRAGMENT=1");
+		fragment = true;
+		break;
+
+	case 'v':
+		preprocessor.setDefine("BGFX_SHADER_TYPE_VERTEX=1");
+		break;
+
+	default:
+		fprintf(stderr, "Unknown type: %s?!", type);
+		return EXIT_FAILURE;
+	}
+
+	FILE* file = fopen(filePath, "r");
+	if (NULL != file)
+	{
+		VaryingMap varyingMap;
+
+		File attribdef("varying.def.sc");
+		const char* parse = attribdef.getData();
+		while (NULL != parse
+		   &&  *parse != '\0')
+		{
+			parse = strws(parse);
+			const char* eol = strchr(parse, ';');
+			if (NULL != eol)
+			{
+				const char* type = parse;
+				const char* name = parse = strws(strword(parse) );
+				const char* column = parse = strws(strword(parse) );
+				const char* semantics = parse = strws(strnws(parse) );
+				const char* assign = parse = strws(strword(parse) );
+				const char* init = parse = strws(strnws(parse) );
+
+				if (type < eol
+				&&  name < eol
+				&&  column < eol
+				&&  ':' == *column
+				&&  semantics < eol)
+				{
+					Varying var;
+					var.m_type.assign(type, strword(type)-type);
+					var.m_name.assign(name, strword(name)-name);
+					var.m_semantics.assign(semantics, strword(semantics)-semantics);
+
+					if (assign < eol
+					&&  '=' == *assign
+					&&  init < eol)
+					{
+						var.m_init.assign(init, eol-init);
+					}
+
+					varyingMap.insert(std::make_pair(var.m_name, var) );
+				}
+
+				parse = eol + 1;
+			}
+		}
+
+		const size_t padding = 16;
+		long int size = fsize(file);
+ 		char* data = new char[size+padding];
+ 		size = fread(data, 1, size, file);
+		memset(&data[size], 0, padding);
+		fclose(file);
+
+		typedef std::vector<std::string> InOut;
+		InOut shaderInputs;
+		InOut shaderOutputs;
+
+		const char* input = data;
+		while (input[0] == '$')
+		{
+			const char* str = input+1;
+			const char* eol = streol(str);
+			const char* nl = strnl(eol);
+			input = nl;
+
+			if (0 == strncmp(str, "input", 5) )
+			{
+				str += 5;
+				str = strws(str);
+
+				if (str < eol)
+				{
+					const char* delim;
+					do
+					{
+						delim = strpbrk(str, " ,");
+						if (NULL != delim)
+						{
+							delim = delim > eol ? eol : delim;
+							std::string token;
+							token.assign(str, delim-str);
+							shaderInputs.push_back(token);
+							str = strws(delim + 1);
+						}
+					}
+					while (delim < eol && NULL != delim);
+				}
+			}
+			else if (0 == strncmp(str, "output", 6) )
+			{
+				str += 6;
+				str = strws(str);
+
+				if (str < eol)
+				{
+					const char* delim;
+					do
+					{
+						delim = strpbrk(str, " ,");
+						if (NULL != delim)
+						{
+							delim = delim > eol ? eol : delim;
+							std::string token;
+							token.assign(str, delim-str);
+							shaderOutputs.push_back(token);
+							str = strws(delim + 1);
+						}
+					}
+					while (delim < eol && NULL != delim);
+				}
+			}
+		}
+
+		if (glsl)
+		{
+			for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
+			{
+				VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+				if (varyingIt != varyingMap.end() )
+				{
+					const Varying& var = varyingIt->second;
+					const char* name = var.m_name.c_str();
+					if (0 == strncmp(name, "a_", 2)
+					||  0 == strncmp(name, "i_", 2) )
+					{
+						preprocessor.writef("attribute %s %s;\n", var.m_type.c_str(), name);
+					}
+					else
+					{
+						preprocessor.writef("varying %s %s;\n", var.m_type.c_str(), name);
+					}
+				}
+			}
+
+			for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
+			{
+				VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+				if (varyingIt != varyingMap.end() )
+				{
+					const Varying& var = varyingIt->second;
+					preprocessor.writef("varying %s %s;\n", var.m_type.c_str(), var.m_name.c_str() );
+				}
+			}
+		}
+		else
+		{
+			preprocessor.writef(
+					"#define lowp\n"
+					"#define mediump\n"
+					"#define highp\n"
+					"#define vec2 float2\n"
+					"#define vec3 float3\n"
+					"#define vec4 float4\n"
+					"#define mat2 float2x2\n"
+					"#define mat3 float3x3\n"
+					"#define mat4 float4x4\n"
+				);
+
+			char* entry = strstr(data, "void main()");
+			if (NULL != entry)
+			{
+				entry[4] = '_';
+
+				if (fragment)
+				{
+					preprocessor.writef("#define void_main() \\\n");
+					preprocessor.writef("\tvoid main(vec4 gl_FragCoord : SV_POSITION \\\n");
+					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
+					{
+						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+						if (varyingIt != varyingMap.end() )
+						{
+							const Varying& var = varyingIt->second;
+							preprocessor.writef("\t, %s %s : %s \\\n", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
+						}
+					}
+
+					preprocessor.writef(
+						", out vec4 gl_FragColor : SV_TARGET \\\n"
+						);
+
+					if (NULL != strstr(data, "gl_FragDepth") )
+					{
+						preprocessor.writef(
+							", out float gl_FragDepth : SV_DEPTH \\\n"
+							);
+					}
+
+					preprocessor.writef(
+						")\n"
+						);
+				}
+				else
+				{
+					const char* brace = strstr(entry, "{");
+					if (NULL != brace)
+					{
+						const char* end = strmb(brace, '{', '}');
+						if (NULL != end)
+						{
+							strins(const_cast<char*>(end), "__RETURN__;\n");
+						}
+					}
+
+					preprocessor.writef(
+						"struct Output\n"
+						"{\n"
+						"\tvec4 gl_Position : SV_POSITION;\n"
+						"#define gl_Position _varying_.gl_Position\n"
+						);
+					for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
+					{
+						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+						if (varyingIt != varyingMap.end() )
+						{
+							const Varying& var = varyingIt->second;
+							preprocessor.writef("\t%s %s : %s;\n", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
+							preprocessor.writef("#define %s _varying_.%s\n", var.m_name.c_str(), var.m_name.c_str() );
+						}
+					}
+					preprocessor.writef(
+						"};\n"
+						);
+
+					preprocessor.writef("#define void_main() \\\n");
+					preprocessor.writef("Output main(");
+					bool first = true;
+					for (InOut::const_iterator it = shaderInputs.begin(), itEnd = shaderInputs.end(); it != itEnd; ++it)
+					{
+						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+						if (varyingIt != varyingMap.end() )
+						{
+							const Varying& var = varyingIt->second;
+							preprocessor.writef("%s%s %s : %s\\\n", first ? "" : "\t, ", var.m_type.c_str(), var.m_name.c_str(), var.m_semantics.c_str() );
+							first = false;
+						}
+					}
+					preprocessor.writef(
+						") \\\n"
+						"{ \\\n"
+						"\tOutput _varying_;"
+						);
+
+					for (InOut::const_iterator it = shaderOutputs.begin(), itEnd = shaderOutputs.end(); it != itEnd; ++it)
+					{
+						VaryingMap::const_iterator varyingIt = varyingMap.find(*it);
+						if (varyingIt != varyingMap.end() )
+						{
+							const Varying& var = varyingIt->second;
+							preprocessor.writef(" \\\n\t%s = %s;", var.m_name.c_str(), var.m_init.c_str() );
+						}
+					}
+
+					preprocessor.writef(
+						"\n#define __RETURN__ \\\n"
+						"\t} \\\n"
+						"\treturn _varying_"
+						);
+				}
+			}
+		}
+
+		if (preprocessor.run(input) )
+		{
+			BX_TRACE("Input file: %s", filePath);
+			BX_TRACE("Output file: %s", outFilePath);
+
+			if (preprocessOnly)
+			{
+				FileWriter stream(outFilePath);
+
+				if (!stream.open() )
+				{
+					fprintf(stderr, "Unable to open output file '%s'.", outFilePath);
+					return false;
+				}
+
+				if (glsl)
+				{
+					const char* profile = cmdLine.findOption('p');
+					if (NULL == profile)
+					{
+						stream.write("#ifdef GL_ES\n");
+						stream.write("precision highp float;\n");
+						stream.write("#endif // GL_ES\n\n");
+					}
+					else
+					{
+						stream.writef("#version %s\n\n", profile);
+					}
+				}
+				stream.write(preprocessor.m_preprocessed.c_str(), preprocessor.m_preprocessed.size() );
+				stream.close();
+
+				return EXIT_SUCCESS;
+			}
+
+			bool compiled = false;
+
+			{
+				IStreamWriter* stream = NULL;
+
+				if (NULL != bin2c)
+				{
+					stream = new Bin2cStream(outFilePath, bin2c);
+				}
+				else
+				{
+					stream = new FileWriter(outFilePath);
+				}
+
+				if (!stream->open() )
+				{
+					fprintf(stderr, "Unable to open output file '%s'.", outFilePath);
+					return false;
+				}
+
+				if (glsl)
+				{
+					compiled = compileGLSLShader(cmdLine, preprocessor.m_preprocessed, *stream);
+				}
+				else
+				{
+					if (hlsl > 3)
+					{
+						compiled = compileHLSLShaderDx11(cmdLine, preprocessor.m_preprocessed, *stream);
+					}
+					else
+					{
+						compiled = compileHLSLShaderDx9(cmdLine, preprocessor.m_preprocessed, *stream);
+					}
+				}
+
+#if SHADERC_DEBUG
+				stream->writeString(filePath);
+#endif // SHADERC_DEBUG
+
+				stream->close();
+				delete stream;
+			}
+
+			if (compiled)
+			{
+				if (depends)
+				{
+					std::string ofp = outFilePath;
+					ofp += ".d";
+					FileWriter stream(ofp.c_str() );
+					if (stream.open() )
+					{
+						stream.write(outFilePath);
+						stream.write(":");
+						stream.write(preprocessor.m_depends.c_str() );
+						stream.write("\n");
+						stream.close();
+					}
+				}
+
+				return EXIT_SUCCESS;
+			}
+		}
+
+		delete [] data;
+	}
+
+	remove(outFilePath);
+
+	fprintf(stderr, "Failed to build shader.\n");
+	return EXIT_FAILURE;
+}