mikymod před 12 roky
rodič
revize
70faac88d9
5 změnil soubory, kde provedl 482 přidání a 138 odebrání
  1. 0 130
      engine/Gui.cpp
  2. 260 0
      engine/gui/Gui.cpp
  3. 33 8
      engine/gui/Gui.h
  4. 100 0
      engine/gui/GuiRect.h
  5. 89 0
      engine/gui/GuiTriangle.h

+ 0 - 130
engine/Gui.cpp

@@ -1,130 +0,0 @@
-/*
-Copyright (c) 2013 Daniele Bartolini, Michele Rossi
-Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
-
-Permission is hereby granted, free of charge, to any person
-obtaining a copy of this software and associated documentation
-files (the "Software"), to deal in the Software without
-restriction, including without limitation the rights to use,
-copy, modify, merge, publish, distribute, sublicense, and/or sell
-copies of the Software, and to permit persons to whom the
-Software is furnished to do so, subject to the following
-conditions:
-
-The above copyright notice and this permission notice shall be
-included in all copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
-EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
-OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
-NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
-HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
-WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
-FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
-OTHER DEALINGS IN THE SOFTWARE.
-*/
-
-#include "Gui.h"
-#include "Assert.h"
-#include "Renderer.h"
-#include "Vector3.h"
-#include "Vector2.h"
-#include "GuiResource.h"
-#include "RenderWorld.h"
-
-namespace crown
-{
-
-static const char* default_vertex =
-	"uniform mat4      	u_model;"
-	"uniform mat4      	u_model_view_projection;"
-
-	"attribute vec4    	a_position;"
-	"attribute vec4    	a_normal;"
-	"attribute vec2    	a_tex_coord0;"
-	"attribute vec4    	a_color;"
-
-	"varying vec2		tex_coord0;"
-	"varying vec4		color;"
-
-	"void main(void)"
-	"{"
-	"	tex_coord0 = a_tex_coord0;"
-	"   color = a_color;"
-	"	gl_Position = u_model_view_projection * a_position;"
-	"}";
-
-static const char* default_fragment =
-	"varying vec2            tex_coord0;"
-	"varying vec4            color;"
-
-	"uniform sampler2D  u_albedo_0;"
-
-	"void main(void)"
-	"{"
-	"	gl_FragColor = color;"
-	"}";
-
-//-----------------------------------------------------------------------------
-Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
-	: m_render_world(render_world)
-	, m_resource(gr)
-	, m_r(r)
-{
-	Vector2 size = m_resource->gui_size();
-	// orthographic projection
-	m_projection.build_projection_ortho_rh(0, size.x, size.y, 0, -0.01f, 100.0f);
-
-	// pose
-	Vector3 pos = m_resource->gui_position();
-	m_pose.load_identity();
-	m_pose.set_translation(pos);
-
-	m_default_vs = m_r.create_shader(ShaderType::VERTEX, default_vertex);
-	m_default_fs = m_r.create_shader(ShaderType::FRAGMENT, default_fragment);
-	m_default_program = m_r.create_gpu_program(m_default_vs, m_default_fs);
-}
-
-//-----------------------------------------------------------------------------
-Gui::~Gui()
-{
-	m_r.destroy_gpu_program(m_default_program);
-	m_r.destroy_shader(m_default_fs);
-	m_r.destroy_shader(m_default_vs);
-}
-
-//-----------------------------------------------------------------------------
-void Gui::move(const Vector3& pos)
-{
-	m_pose.load_identity();
-	m_pose.set_translation(pos);
-}
-
-//-----------------------------------------------------------------------------
-void Gui::render(Renderer& r, UniformId uniform)
-{
-	Vector2 size = m_resource->gui_size();
-
-	r.set_layer_view(1, Matrix4x4::IDENTITY);
-	r.set_layer_projection(1, m_projection);
-	r.set_layer_viewport(1, m_pose.translation().x, m_pose.translation().y, size.x, size.y);
-	r.set_program(m_default_program);
-	r.set_state(STATE_DEPTH_WRITE | STATE_COLOR_WRITE | STATE_ALPHA_WRITE | STATE_CULL_CW | STATE_PRIMITIVE_LINES);	
-	r.set_pose(m_pose);
-
-	// draw gui's rects
-	r.set_vertex_buffer(m_resource->rect_vertex_buffer());
-	r.set_index_buffer(m_resource->rect_index_buffer());
-	r.commit(1);
-
-	r.set_program(m_default_program);
-	r.set_state(STATE_DEPTH_WRITE | STATE_COLOR_WRITE | STATE_ALPHA_WRITE | STATE_CULL_CW | STATE_PRIMITIVE_LINES);	
-	r.set_pose(m_pose);
-
-	// draw gui's triangles
-	r.set_vertex_buffer(m_resource->triangle_vertex_buffer());
-	r.set_index_buffer(m_resource->triangle_index_buffer());
-	r.commit(1);
-}
-
-} // namespace crown

+ 260 - 0
engine/gui/Gui.cpp

@@ -0,0 +1,260 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#include "Gui.h"
+#include "Assert.h"
+#include "Renderer.h"
+#include "Vector3.h"
+#include "Vector2.h"
+#include "GuiResource.h"
+#include "RenderWorld.h"
+#include "RendererTypes.h"
+#include "Vector3.h"
+#include "Vector2.h"
+#include "Color4.h"
+
+#include "GuiRect.h"
+#include "GuiTriangle.h"
+
+
+namespace crown
+{
+
+ShaderId			gui_default_vs;
+ShaderId			gui_default_fs;
+ShaderId			gui_texture_fs;
+GPUProgramId		gui_default_program;
+GPUProgramId		gui_texture_program;
+UniformId			gui_albedo_0;
+
+static const char* default_vertex =
+	"uniform mat4      	u_model;"
+	"uniform mat4      	u_model_view_projection;"
+
+	"attribute vec4    	a_position;"
+	"attribute vec2    	a_tex_coord0;"
+	"attribute vec4    	a_color;"
+
+	"varying vec2		tex_coord0;"
+	"varying vec4		color;"
+
+	"void main(void)"
+	"{"
+	"	tex_coord0 = a_tex_coord0;"
+	"   color = a_color;"
+	"	gl_Position = u_model_view_projection * a_position;"
+	"}";
+
+static const char* default_fragment =
+	"varying vec4            color;"
+
+	"void main(void)"
+	"{"
+	"	gl_FragColor = color;"
+	"}";
+
+static const char* texture_fragment = 
+	"varying vec2       tex_coord0;"
+	"varying vec4       color;"
+
+	"uniform sampler2D  u_albedo_0;"
+
+	"void main(void)"
+	"{"
+	"	gl_FragColor = texture2D(u_albedo_0, tex_coord0);"
+	"}";
+
+//-----------------------------------------------------------------------------
+Gui::Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r)
+	: m_render_world(render_world)
+	, m_resource(gr)
+	, m_r(r)
+	, m_rect_pool(default_allocator(), MAX_GUI_RECTS, sizeof(GuiRect), CE_ALIGNOF(GuiRect))
+	, m_triangle_pool(default_allocator(), MAX_GUI_TRIANGLES, sizeof(GuiTriangle), CE_ALIGNOF(GuiTriangle))
+{
+	// orthographic projection
+	Vector2 size = m_resource->gui_size();
+	m_projection.build_projection_ortho_rh(0, size.x, size.y, 0, -0.01f, 100.0f);
+
+	// pose
+	Vector3 pos = m_resource->gui_position();
+	m_pose.load_identity();
+	m_pose.set_translation(pos);
+
+	// FIXME FIXME FIXME -- Shaders init should not be here
+	gui_default_vs = m_r.create_shader(ShaderType::VERTEX, default_vertex);
+	gui_default_fs = m_r.create_shader(ShaderType::FRAGMENT, default_fragment);
+	gui_texture_fs = m_r.create_shader(ShaderType::FRAGMENT, texture_fragment);
+	gui_default_program = m_r.create_gpu_program(gui_default_vs, gui_default_fs);
+	gui_texture_program = m_r.create_gpu_program(gui_default_vs, gui_texture_fs);
+	gui_albedo_0 = m_r.create_uniform("u_albedo_0", UniformType::INTEGER_1, 1);
+
+	// Gui's rects creation
+	for (uint32_t i = 0; i < m_resource->num_rects(); i++)
+	{
+		GuiRectData data = m_resource->get_rect(i);
+		Vector3 pos(data.position[0], data.position[1], data.position[2]);
+		Vector2 size(data.size[0], data.size[1]);
+		Color4 color(data.color[0], data.color[1], data.color[2], data.color[3]);
+	
+		create_rect(pos, size, color);	
+	}
+
+	for (uint32_t i = 0; i < m_resource->num_triangles(); i++)
+	{
+		GuiTriangleData data = m_resource->get_triangle(i);
+		Vector2 p1(data.points[0], data.points[1]);
+		Vector2 p2(data.points[2], data.points[3]);
+		Vector2 p3(data.points[4], data.points[5]);
+		Color4 color(data.color[0], data.color[1], data.color[2], data.color[3]);
+
+		create_triangle(p1, p2, p3, color);
+	}
+}
+
+//-----------------------------------------------------------------------------
+Gui::~Gui()
+{
+	for (uint32_t i = 0; i < m_resource->num_rects(); i++)
+	{
+		CE_DELETE(m_rect_pool, m_rects[i]);
+	}
+
+	for (uint32_t i = 0; i < m_resource->num_triangles(); i++)
+	{
+		CE_DELETE(m_triangle_pool, m_triangles[i]);
+	}
+
+	m_r.destroy_uniform(gui_albedo_0);
+	m_r.destroy_gpu_program(gui_texture_program);
+	m_r.destroy_gpu_program(gui_default_program);
+	m_r.destroy_shader(gui_texture_fs);
+	m_r.destroy_shader(gui_default_fs);
+	m_r.destroy_shader(gui_default_vs);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::move(const Vector3& pos)
+{
+	m_pose.load_identity();
+	m_pose.set_translation(pos);
+}
+
+//-----------------------------------------------------------------------------
+GuiRectId Gui::create_rect(const Vector3& pos, const Vector2& size, const Color4& color)
+{
+	GuiRect* rect = CE_NEW(m_rect_pool, GuiRect)(m_r, pos, size, color);
+	return m_rects.create(rect);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::update_rect(GuiRectId id, const Vector3& pos, const Vector2& size, const Color4& color)
+{
+	CE_ASSERT(m_rects.has(id), "GuiRect does not exists");
+
+	GuiRect* rect = m_rects.lookup(id);
+	rect->update(pos, size, color);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::destroy_rect(GuiRectId id)
+{
+	CE_ASSERT(m_rects.has(id), "GuiRect does not exist");
+
+	GuiRect* rect = m_rects.lookup(id);
+	CE_DELETE(m_rect_pool, rect);
+	m_rects.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+GuiTriangleId Gui::create_triangle(const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color)
+{
+	GuiTriangle* triangle = CE_NEW(m_triangle_pool, GuiTriangle)(m_r, p1, p2, p3, color);
+	return m_triangles.create(triangle);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::update_triangle(GuiTriangleId id, const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color)
+{
+	CE_ASSERT(m_triangles.has(id), "GuiTriangle does not exists");
+
+	GuiTriangle* triangle = m_triangles.lookup(id);
+	triangle->update(p1, p2, p3, color);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::destroy_triangle(GuiTriangleId id)
+{
+	CE_ASSERT(m_triangles.has(id), "Guitriangle does not exist");
+
+	GuiTriangle* triangle = m_triangles.lookup(id);
+	CE_DELETE(m_triangle_pool, triangle);
+	m_triangles.destroy(id);
+}
+
+//-----------------------------------------------------------------------------
+void Gui::render()
+{
+	Vector2 size = m_resource->gui_size();
+
+	m_r.set_layer_view(1, Matrix4x4::IDENTITY);
+	m_r.set_layer_projection(1, m_projection);
+	m_r.set_layer_viewport(1, m_pose.translation().x, m_pose.translation().y, size.x, size.y);
+
+	// Render all Rects
+	for (uint32_t i = 0; i < m_rects.size(); i++)
+	{
+		m_r.set_program(gui_default_program);
+		m_r.set_state(STATE_DEPTH_WRITE 
+		| STATE_COLOR_WRITE
+		| STATE_ALPHA_WRITE
+		| STATE_CULL_CW
+		| STATE_PRIMITIVE_LINES
+		| STATE_BLEND_EQUATION_ADD 
+		| STATE_BLEND_FUNC(STATE_BLEND_FUNC_SRC_ALPHA, STATE_BLEND_FUNC_ONE_MINUS_SRC_ALPHA));
+		m_r.set_pose(m_pose);
+
+		m_rects[i]->render();
+	}
+
+	// Render all Triangles
+	for (uint32_t i = 0; i < m_triangles.size(); i++)
+	{
+		m_r.set_program(gui_default_program);
+		m_r.set_state(STATE_DEPTH_WRITE 
+		| STATE_COLOR_WRITE
+		| STATE_ALPHA_WRITE
+		| STATE_CULL_CW
+		| STATE_PRIMITIVE_LINES
+		| STATE_BLEND_EQUATION_ADD 
+		| STATE_BLEND_FUNC(STATE_BLEND_FUNC_SRC_ALPHA, STATE_BLEND_FUNC_ONE_MINUS_SRC_ALPHA));
+		m_r.set_pose(m_pose);
+
+		m_triangles[i]->render();
+	}
+}
+
+} // namespace crown

+ 33 - 8
engine/Gui.h → engine/gui/Gui.h

@@ -27,27 +27,50 @@ OTHER DEALINGS IN THE SOFTWARE.
 #pragma once
 #pragma once
 
 
 #include "Matrix4x4.h"
 #include "Matrix4x4.h"
-#include "RendererTypes.h"
+#include "IdTable.h"
+#include "IdArray.h"
+#include "PoolAllocator.h"
+#include "Vector2.h"
+
+#define MAX_GUI_RECTS 64
+#define MAX_GUI_TRIANGLES 64
+#define MAX_GUI_IMAGES 64
 
 
 namespace crown
 namespace crown
 {
 {
 
 
-typedef Id MaterialId;
 typedef Id UniformId;
 typedef Id UniformId;
-typedef Id VertexBufferId;
-typedef Id IndexBufferId;
+typedef Id GuiRectId;
+typedef Id GuiTriangleId;
+typedef Id GuiImageId;
 
 
 struct Renderer;
 struct Renderer;
 struct RenderWorld;
 struct RenderWorld;
 struct Vector3;
 struct Vector3;
 struct GuiResource;
 struct GuiResource;
+struct GuiRect;
+struct GuiTriangle;
+struct GuiImage;
+struct Vector3;
+struct Vector2;
+struct Color4;
 
 
 struct Gui
 struct Gui
 {
 {
 						Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r);
 						Gui(RenderWorld& render_world, GuiResource* gr, Renderer& r);
 						~Gui();
 						~Gui();
+
 	void				move(const Vector3& pos);
 	void				move(const Vector3& pos);
-	void				render(Renderer& r, UniformId uniform);
+
+	GuiRectId			create_rect(const Vector3& pos, const Vector2& size, const Color4& color);
+	void				update_rect(GuiRectId id, const Vector3& pos, const Vector2& size, const Color4& color);
+	void				destroy_rect(GuiRectId id);
+
+	GuiTriangleId		create_triangle(const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color);
+	void				update_triangle(GuiTriangleId id, const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color);
+	void				destroy_triangle(GuiTriangleId id);
+
+	void				render();
 
 
 public:
 public:
 
 
@@ -58,9 +81,11 @@ public:
 	Matrix4x4			m_projection;
 	Matrix4x4			m_projection;
 	Matrix4x4			m_pose;
 	Matrix4x4			m_pose;
 
 
-	ShaderId			m_default_vs;
-	ShaderId			m_default_fs;
-	GPUProgramId		m_default_program;
+	PoolAllocator		m_rect_pool;
+	PoolAllocator		m_triangle_pool;
+
+	IdArray<MAX_GUI_RECTS, GuiRect*> m_rects;
+	IdArray<MAX_GUI_TRIANGLES, GuiTriangle*> m_triangles;
 };
 };
 
 
 } // namespace crown
 } // namespace crown

+ 100 - 0
engine/gui/GuiRect.h

@@ -0,0 +1,100 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Matrix4x4.h"
+#include "RendererTypes.h"
+#include "Renderer.h"
+
+namespace crown
+{
+
+struct Vector3;
+struct Vector2;
+struct Color4;
+
+struct GuiRect
+{
+	//-------------------------------------------------------------------------
+	GuiRect(Renderer& r, const Vector3& pos, const Vector2& size, const Color4& color)
+		: m_r(r)
+	{
+		update(pos, size, color);
+
+		m_vb = m_r.create_vertex_buffer(4, VertexFormat::P2_C4, m_vertices);
+		m_ib = m_r.create_index_buffer(8, m_indices);
+	}
+
+	//-------------------------------------------------------------------------
+	~GuiRect()
+	{
+		m_r.destroy_index_buffer(m_ib);
+		m_r.destroy_vertex_buffer(m_vb);
+	}
+
+	//-------------------------------------------------------------------------
+	void update(const Vector3& pos, const Vector2& size, const Color4& color)
+	{
+		m_vertices[0] = pos.x; m_vertices[1] = pos.y;
+		m_vertices[2] = color.r; m_vertices[3] = color.g;
+		m_vertices[4] = color.b; m_vertices[5] = color.a;
+		m_vertices[6] = pos.x + size.x; m_vertices[7] = pos.y;
+		m_vertices[8] = color.r; m_vertices[9] = color.g;
+		m_vertices[10] = color.b; m_vertices[11] = color.a;
+		m_vertices[12] = pos.x + size.x; m_vertices[13] = pos.y - size.y;
+		m_vertices[14] = color.r; m_vertices[15] = color.g;
+		m_vertices[16] = color.b; m_vertices[17] = color.a;
+		m_vertices[18] = pos.x; m_vertices[19] = pos.y - size.y;
+		m_vertices[20] = color.r; m_vertices[21] = color.g;
+		m_vertices[22] = color.b; m_vertices[23] = color.a;
+
+		m_indices[0] = 0; m_indices[1] = 1;
+		m_indices[2] = 1; m_indices[3] = 2;
+		m_indices[4] = 2; m_indices[5] = 3;
+		m_indices[6] = 3; m_indices[7] = 0;
+	}
+
+	//-------------------------------------------------------------------------
+	void render()
+	{
+		m_r.set_vertex_buffer(m_vb);
+		m_r.set_index_buffer(m_ib);
+		m_r.commit(1);
+	}
+
+public:
+
+	Renderer& m_r;
+
+	float m_vertices[6*4];
+	uint16_t m_indices[2*4];
+
+	VertexBufferId m_vb;
+	IndexBufferId m_ib;
+};
+
+} // namespace crown

+ 89 - 0
engine/gui/GuiTriangle.h

@@ -0,0 +1,89 @@
+/*
+Copyright (c) 2013 Daniele Bartolini, Michele Rossi
+Copyright (c) 2012 Daniele Bartolini, Simone Boscaratto
+
+Permission is hereby granted, free of charge, to any person
+obtaining a copy of this software and associated documentation
+files (the "Software"), to deal in the Software without
+restriction, including without limitation the rights to use,
+copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the
+Software is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice shall be
+included in all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
+OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
+HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
+WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
+OTHER DEALINGS IN THE SOFTWARE.
+*/
+
+#pragma once
+
+#include "Matrix4x4.h"
+#include "RendererTypes.h"
+
+namespace crown
+{
+
+struct GuiTriangle
+{
+	GuiTriangle(Renderer& r, const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color)
+		: m_r(r)
+	{
+		update(p1, p2, p3, color);
+
+		m_vb = m_r.create_vertex_buffer(3, VertexFormat::P2_C4, m_vertices);
+		m_ib = m_r.create_index_buffer(6, m_indices);
+	}
+
+	~GuiTriangle()
+	{
+		m_r.destroy_vertex_buffer(m_vb);
+		m_r.destroy_index_buffer(m_ib);
+	}
+
+	void update(const Vector2& p1, const Vector2& p2, const Vector2& p3, const Color4& color)
+	{
+		m_vertices[0] = p1.x; m_vertices[1] = p1.y;
+		m_vertices[2] = color.r; m_vertices[3] = color.g;
+		m_vertices[4] = color.b; m_vertices[5] = color.a;
+
+		m_vertices[6] = p2.x; m_vertices[7] = p2.y;
+		m_vertices[8] = color.r; m_vertices[9] = color.g;
+		m_vertices[10] = color.b; m_vertices[11] = color.a;
+
+		m_vertices[12] = p3.x; m_vertices[13] = p3.y;
+		m_vertices[14] = color.r; m_vertices[15] = color.g;
+		m_vertices[16] = color.b; m_vertices[17] = color.a;
+
+		m_indices[0] = 0; m_indices[1] = 1;
+		m_indices[2] = 1; m_indices[3] = 2;
+		m_indices[4] = 2; m_indices[5] = 0;
+	}
+
+	void render()
+	{
+		m_r.set_vertex_buffer(m_vb);
+		m_r.set_index_buffer(m_ib);
+		m_r.commit(1);		
+	}
+
+public:
+
+	Renderer& m_r;
+
+	float m_vertices[6*3];
+	uint16_t m_indices[2*3];
+
+	VertexBufferId m_vb;
+	IndexBufferId m_ib;
+};
+
+} // namespace crown