Index: trunk/tests/objload_test/objload_test.cc
===================================================================
--- trunk/tests/objload_test/objload_test.cc	(revision 237)
+++ trunk/tests/objload_test/objload_test.cc	(revision 238)
@@ -32,6 +32,5 @@
 	nv::vertex_array* m_va;
 	nv::program*      m_program;
-	nv::mesh_data_old* m_mesh;
-	nv::uint32        m_count;
+	nv::mesh_data*    m_mesh;
 };
 
@@ -64,8 +63,15 @@
 	nv::c_file_system fs;
 	nv::stream* mesh_file = fs.open( "mesh.obj" );
-	nv::mesh_loader* loader = new nv::obj_loader();
+
+// 		nv::mesh_loader* loader = new nv::obj_loader();
+// 		loader->load( *mesh_file );
+// 		nv::mesh_data_old* mesh = loader->release_mesh_data();
+// 		m_count = loader->get_size();
+// 		delete mesh_file;
+// 		delete loader;
+
+	nv::wavefront_loader* loader = new nv::wavefront_loader();
 	loader->load( *mesh_file );
 	m_mesh = loader->release_mesh_data();
-	m_count = loader->get_size();
 	delete mesh_file;
 	delete loader;
@@ -73,12 +79,7 @@
 	m_program = m_device->create_program( nv::slurp( "obj.vert" ), nv::slurp( "obj.frag" ) );
 
-	nv::vertex_buffer* vb = nullptr;
-	m_va = m_device->create_vertex_array();
-	vb = m_device->create_vertex_buffer( nv::STATIC_DRAW, m_mesh->get_vertex_count() * sizeof( nv::vec3 ), m_mesh->get_positions().data() );
-	m_va->add_vertex_buffer( nv::slot::POSITION, vb, nv::FLOAT, 3 );
-	vb = m_device->create_vertex_buffer( nv::STATIC_DRAW, m_mesh->get_vertex_count() * sizeof( nv::vec3 ), m_mesh->get_normals().data() );
-	m_va->add_vertex_buffer( nv::slot::NORMAL, vb, nv::FLOAT, 3 );
-	vb = m_device->create_vertex_buffer( nv::STATIC_DRAW, m_mesh->get_vertex_count() * sizeof( nv::vec2 ), m_mesh->get_texcoords().data() );
-	m_va->add_vertex_buffer( nv::slot::TEXCOORD, vb, nv::FLOAT, 2 );
+//	nv::vertex_buffer* vb = nullptr;
+	m_va = m_device->create_vertex_array( m_mesh, nv::STATIC_DRAW );
+
 	return true;
 }
@@ -113,5 +114,5 @@
 		m_program->set_uniform( "diffuse", 0 );
 		m_program->set_uniform( "specular", 1 );
-		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_count * 3 );
+		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_program, m_va, m_mesh->get_count() );
 		m_window->swap_buffers();
 
@@ -147,6 +148,6 @@
 application::~application()
 {
+	delete m_mesh;
 	delete m_program;
-	delete m_mesh;
 	delete m_diffuse;
 	delete m_specular;
Index: trunk/tests/render_test/box.frag
===================================================================
--- trunk/tests/render_test/box.frag	(revision 237)
+++ trunk/tests/render_test/box.frag	(revision 238)
@@ -4,5 +4,5 @@
 varying vec3 f_material;
 varying float f_diffuse_value;
-uniform sampler2D tex;
+uniform sampler2D nv_t_diffuse;
 uniform vec3 light;
  
@@ -16,7 +16,7 @@
 
 	if (secondary)
-		gl_FragColor = texture2D(tex, vec2((fract(f_coord.z - f_coord.x) + modulus ), ( fract(-f_coord.y) + remmod) )  / 16.0);
+		gl_FragColor = texture2D(nv_t_diffuse, vec2((fract(f_coord.z - f_coord.x) + modulus ), ( fract(-f_coord.y) + remmod) )  / 16.0);
 	else
-		gl_FragColor = texture2D(tex, vec2((fract(f_coord.z) + modulus ), ( fract(f_coord.x) + remmod) )  / 16.0);
+		gl_FragColor = texture2D(nv_t_diffuse, vec2((fract(f_coord.z) + modulus ), ( fract(f_coord.x) + remmod) )  / 16.0);
 	gl_FragColor = vec4( gl_FragColor.xyz * (f_diffuse_value + 0.4), 1.0 );
 }
Index: trunk/tests/render_test/box.vert
===================================================================
--- trunk/tests/render_test/box.vert	(revision 237)
+++ trunk/tests/render_test/box.vert	(revision 238)
@@ -1,21 +1,22 @@
 #version 120
-attribute vec3 coords;
-attribute vec3 material;
+attribute vec3 nv_position;
+attribute vec3 nv_color;
+uniform mat4 nv_m_mvp;
+
 varying vec3 f_coord;
 varying vec3 f_normal;
 varying vec3 f_material;
 varying float f_diffuse_value;
-uniform mat4 matrix_mvp;
 uniform vec3 light;
 
 void main(void) {
 	f_normal = vec3(0,0,0);
-	f_normal[int(abs(material.y)-1)] = sign( material.y );
+	f_normal[int(abs(nv_color.y)-1)] = sign( nv_color.y );
 	vec3 vnormal  = normalize(f_normal);
-	vec3 vlight   = normalize(light - coords);
+	vec3 vlight   = normalize(light - nv_position);
 	float diffuse = max(dot(vlight, vnormal), 0.0);
 	f_diffuse_value = diffuse;
-	f_coord = coords;
-	f_material = material;
-	gl_Position = matrix_mvp * vec4(coords, 1.0);
+	f_coord = nv_position;
+	f_material = nv_color;
+	gl_Position = nv_m_mvp * vec4(nv_position, 1.0);
 }
Index: trunk/tests/render_test/char.frag
===================================================================
--- trunk/tests/render_test/char.frag	(revision 237)
+++ trunk/tests/render_test/char.frag	(revision 238)
@@ -2,5 +2,5 @@
 varying vec3 f_coord;
 varying vec3 f_material;
-uniform sampler2D tex;
+uniform sampler2D nv_t_diffuse;
  
 void main(void) {
@@ -9,6 +9,6 @@
 	float modulus = w - remmod * 16;
 
-	gl_FragColor = texture2D(tex, vec2((fract(f_coord.x) + modulus ), ( fract(f_coord.z) + remmod) )  / 16.0);
+	gl_FragColor = texture2D(nv_t_diffuse, vec2((fract(f_coord.x) + modulus ), ( fract(f_coord.z) + remmod) )  / 16.0);
 
-//	gl_FragColor = texture2D(tex, vec2((fract(f_coord.z - f_coord.x) + modulus ), ( fract(-f_coord.y) + remmod) )  / 16.0);
+//	gl_FragColor = texture2D(nv_t_diffuse, vec2((fract(f_coord.z - f_coord.x) + modulus ), ( fract(-f_coord.y) + remmod) )  / 16.0);
 }
Index: trunk/tests/render_test/char.vert
===================================================================
--- trunk/tests/render_test/char.vert	(revision 237)
+++ trunk/tests/render_test/char.vert	(revision 238)
@@ -1,13 +1,14 @@
 #version 120
-attribute vec3 coords;
-attribute vec3 material;
+attribute vec3 nv_position;
+attribute vec3 nv_color;
+uniform mat4 nv_m_mvp;
+
 varying vec3 f_coord;
 varying vec3 f_material;
-uniform mat4 matrix_mvp;
 uniform vec3 pos;
 
 void main(void) {
-	f_coord = coords;
-	f_material = material;
-	gl_Position = matrix_mvp * vec4(coords + pos, 1.0);
+	f_coord = nv_position;
+	f_material = nv_color;
+	gl_Position = nv_m_mvp * vec4(nv_position + pos, 1.0);
 }
Index: trunk/tests/render_test/rl.cc
===================================================================
--- trunk/tests/render_test/rl.cc	(revision 237)
+++ trunk/tests/render_test/rl.cc	(revision 238)
@@ -67,6 +67,8 @@
 	nv::window* m_window;
 	nv::texture2d* m_texture;
-	nv::clear_state m_clear_state;
+
+	nv::clear_state  m_clear_state;
 	nv::render_state m_render_state;
+	nv::scene_state  m_scene_state;
 
 	nv::program* m_char_program;
@@ -75,4 +77,13 @@
 	nv::vertex_array* m_box_va;
 	unsigned int m_count;
+};
+
+struct vtx
+{
+	nv::i8vec3 position;
+	nv::i8vec3 color;
+
+	vtx( const nv::i8vec3& a_position, const nv::i8vec3& a_color )
+		: position( a_position ), color( a_color ) {}
 };
 
@@ -99,24 +110,20 @@
 {
 	{ // CHARACTER
-		nv::mesh cmesh;
-		nv::vertex_attribute<nv::i8vec3>::list& vtx = cmesh.add_attribute<nv::i8vec3>("coords")->get();
-		nv::vertex_attribute<nv::i8vec3>::list& mat = cmesh.add_attribute<nv::i8vec3>("material")->get();
+		std::vector< vtx > v;
 		int m = 16;	int x = 0; int y = 0; int h = 0;
-		vtx.emplace_back( x,   h, y );  
-		vtx.emplace_back( x,   h, y+1 );
-		vtx.emplace_back( x+1, h, y+1 );
-		vtx.emplace_back( x+1, h, y+1 );
-		vtx.emplace_back( x+1, h, y );  
-		vtx.emplace_back( x,   h, y );  
-		mat.insert( mat.end(), 6, nv::i8vec3( m, 1, 0 ) );
+		nv::i8vec3 mt( m, 1, 0 );
+		v.emplace_back( nv::i8vec3( x,   h, y ), mt );  
+		v.emplace_back( nv::i8vec3( x,   h, y+1 ), mt );
+		v.emplace_back( nv::i8vec3( x+1, h, y+1 ), mt );
+		v.emplace_back( nv::i8vec3( x+1, h, y+1 ), mt );
+		v.emplace_back( nv::i8vec3( x+1, h, y ), mt );  
+		v.emplace_back( nv::i8vec3( x,   h, y ), mt );  
 		m_char_program = m_device->create_program( nv::slurp( "char.vert" ), nv::slurp( "char.frag" ) );
-		m_char_va      = m_device->create_vertex_array( &cmesh, &(m_char_program->get_attributes()), nv::STATIC_DRAW );
+		m_char_va      = m_device->create_vertex_array( v, nv::STATIC_DRAW );
 	}
 
 	{ // WORLD
-		nv::mesh wmesh;
-		nv::vertex_attribute<nv::i8vec3>::list& vtx = wmesh.add_attribute<nv::i8vec3>("coords")->get();
-		nv::vertex_attribute<nv::i8vec3>::list& mat = wmesh.add_attribute<nv::i8vec3>("material")->get();
-
+		std::vector< vtx > v;
+		nv::i8vec3 mt;
 		for (int i = 0; i < size_x * size_y; ++i )
 		{
@@ -124,11 +131,11 @@
 			int y = i / size_x;
 
-			vtx.emplace_back( x,   height[i], y   ); 
-			vtx.emplace_back( x,   height[i], y+1 ); 
-			vtx.emplace_back( x+1, height[i], y+1 ); 
-			vtx.emplace_back( x+1, height[i], y+1 ); 
-			vtx.emplace_back( x+1, height[i], y );   
-			vtx.emplace_back( x,   height[i], y );   
-			mat.insert( mat.end(), 6, nv::i8vec3( map[i], 2, 0 ) );
+			mt = nv::i8vec3( map[i], 2, 0 );
+			v.emplace_back( nv::i8vec3( x,   height[i], y   ), mt );
+			v.emplace_back( nv::i8vec3( x,   height[i], y+1 ), mt );
+			v.emplace_back( nv::i8vec3( x+1, height[i], y+1 ), mt );
+			v.emplace_back( nv::i8vec3( x+1, height[i], y+1 ), mt );
+			v.emplace_back( nv::i8vec3( x+1, height[i], y ), mt );
+			v.emplace_back( nv::i8vec3( x,   height[i], y ), mt );
 
 			if (i > 0 && height[i-1] != height[i])
@@ -139,11 +146,11 @@
 				{
 					m_count += 6;
-					vtx.emplace_back( x, h,     y );   
-					vtx.emplace_back( x, h,     y+1 ); 
-					vtx.emplace_back( x, h+dir, y+1 ); 
-					vtx.emplace_back( x, h+dir, y+1 ); 
-					vtx.emplace_back( x, h+dir, y );   
-					vtx.emplace_back( x, h,     y );   
-					mat.insert( mat.end(), 6, nv::i8vec3( m, -dir, 0 ) );
+					mt = nv::i8vec3( m, -dir, 0 );
+					v.emplace_back( nv::i8vec3( x, h,     y ), mt );
+					v.emplace_back( nv::i8vec3( x, h,     y+1 ), mt );
+					v.emplace_back( nv::i8vec3( x, h+dir, y+1 ), mt );
+					v.emplace_back( nv::i8vec3( x, h+dir, y+1 ), mt );
+					v.emplace_back( nv::i8vec3( x, h+dir, y ), mt );
+					v.emplace_back( nv::i8vec3( x, h,     y ), mt );
 				}
 			}
@@ -155,12 +162,12 @@
 				for ( int h = height[i-size_x]; h != height[i]; h = h + dir )
 				{
-					vtx.emplace_back( x,   h,     y ); 
-					vtx.emplace_back( x,   h+dir, y ); 
-					vtx.emplace_back( x+1, h+dir, y ); 
-
-					vtx.emplace_back( x+1, h+dir, y ); 
-					vtx.emplace_back( x+1, h,     y ); 
-					vtx.emplace_back( x,   h,     y ); 
-					mat.insert( mat.end(), 6, nv::i8vec3( m, -3*dir, 0 ) );
+					mt = nv::i8vec3( m, -3*dir, 0 );
+					v.emplace_back( nv::i8vec3( x,   h,     y ), mt );
+					v.emplace_back( nv::i8vec3( x,   h+dir, y ), mt );
+					v.emplace_back( nv::i8vec3( x+1, h+dir, y ), mt );
+
+					v.emplace_back( nv::i8vec3( x+1, h+dir, y ), mt );
+					v.emplace_back( nv::i8vec3( x+1, h,     y ), mt );
+					v.emplace_back( nv::i8vec3( x,   h,     y ), mt );
 				}
 			}
@@ -168,7 +175,7 @@
 		}
 
-		m_count       = vtx.size();
+		m_count       = v.size();
 		m_box_program = m_device->create_program( nv::slurp( "box.vert" ), nv::slurp( "box.frag" ) );
-		m_box_va      = m_device->create_vertex_array( &wmesh, &(m_box_program->get_attributes()), nv::STATIC_DRAW );
+		m_box_va      = m_device->create_vertex_array( v, nv::STATIC_DRAW );
 	}
 
@@ -181,24 +188,18 @@
 
 	glm::vec3 move( 0, 0, 0 );
+	m_scene_state.get_camera().set_perspective(25.0f, 1.0f*800.0f/600.0f, 0.1f, 100.0f);
 
 	while(!keypress) 
 	{
+		m_scene_state.set_model( glm::translate(glm::mat4(1.0f), glm::vec3(-8.5, 0.0, -8.0)) );
+		m_scene_state.get_camera().set_lookat(glm::vec3(0.0, 20.0, 5.0) + move, glm::vec3(0.0, 4.0, 0.0) + move, glm::vec3(0.0, 1.0, 0.0));
+
 		m_window->get_context()->clear( m_clear_state );
-
-		glm::mat4 model = glm::translate(glm::mat4(1.0f), glm::vec3(-8.5, 0.0, -8.0));
-		glm::mat4 view  = glm::lookAt(glm::vec3(0.0, 20.0, 5.0) + move, glm::vec3(0.0, 4.0, 0.0) + move, glm::vec3(0.0, 1.0, 0.0));
-		glm::mat4 projection = glm::perspective(25.0f, 1.0f*800.0f/600.0f, 0.1f, 100.0f);
-		glm::mat4 mv         = view * model;
-
 		m_texture->bind( 0 );
-		m_box_program->set_uniform( "matrix_mvp", projection * mv );
 		m_box_program->set_uniform( "light", glm::vec3(8.5, 4.5, 6.5) + move );
-		m_box_program->set_uniform( "tex", 0 );
-		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_box_program, m_box_va, m_count );
-
-		m_char_program->set_uniform( "matrix_mvp", projection * mv );
+		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_scene_state, m_box_program, m_box_va, m_count );
+
 		m_char_program->set_uniform( "pos", move + glm::vec3( 8, 4.1, 6 ) );
-		m_char_program->set_uniform( "tex", 0 );
-		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_char_program, m_char_va, 6 );
+		m_window->get_context()->draw( nv::TRIANGLES, m_render_state, m_scene_state, m_char_program, m_char_va, 6 );
 		m_window->swap_buffers();
 
