Index: trunk/tests/render_test/rl.cc
===================================================================
--- trunk/tests/render_test/rl.cc	(revision 231)
+++ 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();
 
