Index: /trunk/tests/gui_test/gui.frag
===================================================================
--- /trunk/tests/gui_test/gui.frag	(revision 127)
+++ /trunk/tests/gui_test/gui.frag	(revision 127)
@@ -0,0 +1,9 @@
+#version 120
+varying vec4 f_color;
+varying vec2 f_tcoord;
+uniform sampler2D tex;
+ 
+void main(void) {
+	vec4 texture = texture2D(tex,f_tcoord);
+	gl_FragColor = f_color * texture;
+}
Index: /trunk/tests/gui_test/gui.vert
===================================================================
--- /trunk/tests/gui_test/gui.vert	(revision 127)
+++ /trunk/tests/gui_test/gui.vert	(revision 127)
@@ -0,0 +1,13 @@
+#version 120
+attribute vec2 coord;
+attribute vec2 tcoord;
+attribute vec4 color;
+uniform mat4 projection;
+varying vec4 f_color;
+varying vec2 f_tcoord;
+
+void main(void) {
+	f_color  = color;
+	f_tcoord = tcoord;
+	gl_Position = projection * vec4( coord.x, coord.y, 0.0, 1.0 );
+}
Index: /trunk/tests/gui_test/gui_test.lua
===================================================================
--- /trunk/tests/gui_test/gui_test.lua	(revision 127)
+++ /trunk/tests/gui_test/gui_test.lua	(revision 127)
@@ -0,0 +1,7 @@
+project "nv_gui_test"
+	kind "ConsoleApp"
+	files { "nv_gui_test.cc" }
+	includedirs { "../../" }
+	targetname "nv_gui_test"
+	links { "nv" }
+ 
Index: /trunk/tests/gui_test/nv_gui_test.cc
===================================================================
--- /trunk/tests/gui_test/nv_gui_test.cc	(revision 127)
+++ /trunk/tests/gui_test/nv_gui_test.cc	(revision 127)
@@ -0,0 +1,121 @@
+#include <nv/gl/gl_device.hh>
+#include <nv/gui/gui_environment.hh>
+#include <nv/logging.hh>
+#include <nv/logger.hh>
+#include <cstdlib> // rand
+#include <ctime> // time
+
+class application
+{
+public:
+	application();
+	bool initialize();
+	bool run();
+	void kill_window();
+	void spawn_window();
+	void recolor_window();
+	~application();
+protected:
+	nv::device* m_device;
+	nv::window* m_window;
+	nv::clear_state m_clear_state;
+	nv::gui::environment* m_guienv;
+	std::vector<nv::gui::element*>   m_windows;
+};
+
+application::application()
+{
+	m_device = new nv::gl_device();
+	m_window = m_device->create_window( 800, 600 );
+	m_clear_state.buffers = nv::clear_state::COLOR_AND_DEPTH_BUFFER;
+	m_guienv = new nv::gui::environment( m_window );
+	m_guienv->load_style( "test.style.lua" );
+}
+
+bool application::initialize()
+{
+	return true;
+}
+
+bool application::run()
+{
+	int keypress = 0;
+
+	while(!keypress) 
+	{
+		m_guienv->update();
+
+		m_window->get_context()->clear( m_clear_state );
+		m_guienv->draw();
+		m_window->swap_buffers();
+
+		nv::io_event event;
+		while(m_window->poll_event(event)) 
+		{      
+			switch (event.type) 
+			{
+			case nv::EV_QUIT:
+				keypress = 1;
+				break;
+			case nv::EV_KEY:
+				if (event.key.pressed)
+				{
+					switch (event.key.code) 
+					{
+					case nv::KEY_N      : spawn_window(); break;
+					case nv::KEY_K      : kill_window(); break;
+					case nv::KEY_ESCAPE : keypress = 1; break;
+					}
+				}
+				break;
+			}
+		}
+	}
+	return true;
+}
+
+void application::spawn_window()
+{
+	glm::ivec2 a( std::rand() % 600, std::rand() % 400 );
+	glm::ivec2 b( std::rand() % 200 + 40, std::rand() % 200 + 40 );
+	nv::gui::element* e = new nv::gui::element( m_guienv, nv::rectangle(a).dim(b) );
+	e->set_class( "window" );
+	e->set_text("Window "+nv::to_string(m_windows.size()+1) );
+	m_guienv->add_child( e );
+	NV_LOG( nv::LOG_INFO, "Spawn (" << a.x << "," << a.y << "x" << b.x << "," << b.y << ")" );
+	m_windows.push_back( e );
+}
+
+void application::kill_window()
+{
+	if ( m_windows.size() == 0 ) return;
+	size_t index = rand() % m_windows.size();
+	delete m_windows[ index ];
+	m_windows.erase( m_windows.begin() + index );
+}
+
+application::~application()
+{
+	m_windows.clear();
+	delete m_window;
+	delete m_device;
+}
+
+int main(int, char* [])
+{
+	std::srand((unsigned int) std::time(0) );
+	nv::logger log(nv::LOG_TRACE);
+	log.add_sink( new nv::log_file_sink("log.txt"), nv::LOG_TRACE );
+	log.add_sink( new nv::log_console_sink(), nv::LOG_TRACE );
+	
+	NV_LOG( nv::LOG_NOTICE, "Logging started" );
+	application app;
+	if ( app.initialize() )
+	{
+		app.run();
+	}
+	NV_LOG( nv::LOG_NOTICE, "Logging stopped" );
+
+	return 0;
+}
+
Index: /trunk/tests/gui_test/premake4.lua
===================================================================
--- /trunk/tests/gui_test/premake4.lua	(revision 127)
+++ /trunk/tests/gui_test/premake4.lua	(revision 127)
@@ -0,0 +1,27 @@
+solution "nv_gui_test"
+	configurations { "debug", "release" }
+
+  	language "C++"
+	flags { "ExtraWarnings", "NoPCH" }
+
+	configuration "gmake"	
+		buildoptions "-std=c++11"
+
+	configuration "debug"
+		defines { "DEBUG" }
+		flags { "Symbols", "StaticRuntime" }
+		objdir (_ACTION.."/debug")
+
+	configuration "release"
+		defines { "NDEBUG" }
+		flags { "Optimize", "StaticRuntime" }
+		objdir (_ACTION.."/release")
+
+	dofile("gui_test.lua")
+	dofile("../../nv.lua")
+
+if _ACTION == "clean" then
+	for action in premake.action.each() do
+		os.rmdir(action.trigger)
+	end
+end
Index: /trunk/tests/gui_test/test.style.lua
===================================================================
--- /trunk/tests/gui_test/test.style.lua	(revision 127)
+++ /trunk/tests/gui_test/test.style.lua	(revision 127)
@@ -0,0 +1,11 @@
+default = {
+	text_size          = 12,
+	text_font          = "aero.ttf",
+	text_color         = { 0.5, 0.5, 1.0, 1.0 },
+	background_color   = { 0.2, 0.2, 0.2, 1.0 },
+
+	window = {
+		border = 2,
+		border_color = { 0.2, 0.2, 0.4, 1.0 },
+	}
+}
