Index: trunk/tests/md3_test/md3_test.cc
===================================================================
--- trunk/tests/md3_test/md3_test.cc	(revision 231)
+++ trunk/tests/md3_test/md3_test.cc	(revision 239)
@@ -18,5 +18,4 @@
 #include <nv/time.hh>
 #include <nv/string.hh>
-#include <nv/interface/mesh.hh>
 #include <glm/gtx/rotate_vector.hpp>
 #include <glm/gtc/matrix_access.hpp>
@@ -43,5 +42,6 @@
 		{
 			NV_PROFILE("create_mesh_data");
-			m_data      = loader->release_mesh_data();
+			m_mesh_data = loader->release_mesh_data();
+			m_tag_map   = loader->create_tag_map();
 		}
 		delete loader;
@@ -50,7 +50,7 @@
 			NV_PROFILE("create_mesh");
 			if ( GPU_ANIMATION )
-				m_mesh      = new nv::keyframed_mesh_gpu( window->get_context(), m_data, program );
+				m_mesh      = new nv::keyframed_mesh_gpu( window->get_context(), m_mesh_data, m_tag_map, program );
 			else
-				m_mesh      = new nv::keyframed_mesh_cpu( window->get_context(), m_data );
+				m_mesh      = new nv::keyframed_mesh_cpu( window->get_context(), m_mesh_data, m_tag_map );
 		}
 
@@ -67,7 +67,8 @@
 	}
 
-	void update( nv::uint32 ms )
+	void update( nv::uint32 ms, nv::program* program )
 	{
 		m_mesh->update( ms );
+		m_mesh->update( program );
 	}
 
@@ -79,24 +80,15 @@
 	}
 
-	void draw( nv::context* c, nv::program* program, nv::render_state& rstate, const glm::mat4& m, const glm::mat4& v, const glm::mat4& p )
-	{
-		NV_PROFILE( "mesh-draw" );
-		glm::mat4 mv = v * m;
-		program->set_opt_uniform( "nv_m_modelview", mv );
-		program->set_opt_uniform( "nv_m_normal", glm::transpose(glm::inverse(glm::mat3(mv))) );
-		program->set_uniform( "matrix_mvp", p * mv );
-		
-		c->draw( rstate, program, m_mesh );
-	}
-
 	~mesh_part()
 	{
-		delete m_data;
+		delete m_tag_map;
+		delete m_mesh_data;
 		delete m_mesh;
 	}
 
 private:
-	nv::mesh_data*           m_data;
-	nv::keyframed_mesh*      m_mesh;
+	nv::tag_map*        m_tag_map;
+	nv::mesh_data*      m_mesh_data;
+	nv::keyframed_mesh* m_mesh;
 };
 
@@ -113,6 +105,8 @@
 	nv::texture2d*    m_diffuse;
 	nv::texture2d*    m_diffuse_weapon;
+
 	nv::clear_state   m_clear_state;
 	nv::render_state  m_render_state;
+	nv::scene_state   m_scene_state;
 
 	mesh_part* m_torso;
@@ -120,5 +114,5 @@
 	mesh_part* m_head;
 	mesh_part* m_weapon;
-	nv::program*      m_program;
+	nv::program* m_program;
 };
 
@@ -182,6 +176,6 @@
 		ticks      = m_device->get_ticks();
 		nv::uint32 elapsed = ticks - last_ticks;
-		m_torso->update( elapsed );
-		m_legs->update( elapsed );
+		m_torso->update( elapsed, m_program );
+		m_legs->update( elapsed, m_program );
 		{
 			NV_PROFILE( "clear" );
@@ -197,13 +191,11 @@
 			glm::vec3 eye = glm::rotate( source, (ticks / 20.f), glm::vec3( 0.0,1.0,0.0 ) );
 
-			view       = glm::lookAt(eye + move, glm::vec3(0.0f, 0.0f, 0.0f) + move, glm::vec3(0.0, 1.0, 0.0));
-			projection = glm::perspective(60.0f, 1.0f*800.0f/600.0f, 0.1f, 1000.0f);
+			m_scene_state.get_camera().set_lookat(eye + move, glm::vec3(0.0f, 0.0f, 0.0f) + move, glm::vec3(0.0, 1.0, 0.0));
+			m_scene_state.get_camera().set_perspective(60.0f, 1.0f*800.0f/600.0f, 0.1f, 1000.0f);
 
 			m_diffuse->bind( 0 );
-			m_program->set_opt_uniform( "nv_m_projection", projection );
 			m_program->set_uniform( "light_position", glm::vec3(120.0, 120.0, 0) );
 			m_program->set_uniform( "light_diffuse",  glm::vec4(1.0,1.0,1.0,1.0) );
 			m_program->set_uniform( "light_specular", glm::vec4(1.0,1.0,1.0,1.0) );
-			m_program->set_uniform( "diffuse", 0 );
 		}
 
@@ -211,16 +203,21 @@
 			NV_PROFILE( "draw" );
 			glm::mat4 model      = glm::mat4(1.0f);
-			m_legs->draw( m_window->get_context(), m_program, m_render_state, model, view, projection );
+
+			m_scene_state.set_model( model );
+			m_window->get_context()->draw( m_render_state, m_scene_state, m_program, m_legs->get_mesh() );
 
 			//model = m_legs->get_transform( "tag_torso", last_legs_frame, legs_frame, legs_interpolate );
 			model = m_legs->get_transform( "tag_torso" );
-			m_torso->draw( m_window->get_context(), m_program, m_render_state, model, view, projection );
+			m_scene_state.set_model( model );
+			m_window->get_context()->draw( m_render_state, m_scene_state, m_program, m_torso->get_mesh() );
 
 			glm::mat4 head = model * m_torso->get_transform( "tag_head" ); //, last_torso_frame, torso_frame, torso_interpolate );
-			m_head->draw( m_window->get_context(), m_program, m_render_state, head, view, projection );
+			m_scene_state.set_model( head );
+			m_window->get_context()->draw( m_render_state, m_scene_state, m_program, m_head->get_mesh() );
 
 			glm::mat4 weapon = model * m_torso->get_transform( "tag_weapon" ); //, last_torso_frame, torso_frame, torso_interpolate );
+			m_scene_state.set_model( weapon );
 			m_diffuse_weapon->bind( 0 );
-			m_weapon->draw( m_window->get_context(), m_program, m_render_state, weapon, view, projection );
+			m_window->get_context()->draw( m_render_state, m_scene_state, m_program, m_weapon->get_mesh() );
 
 		}
