Index: trunk/src/engine/particle_engine.cc
===================================================================
--- trunk/src/engine/particle_engine.cc	(revision 498)
+++ trunk/src/engine/particle_engine.cc	(revision 499)
@@ -470,5 +470,5 @@
 }
 
-nv::particle_system nv::particle_engine::create_system( const string_view& id )
+nv::particle_system nv::particle_engine::create_system( const string_view& id, particle_system_group group )
 {
 	auto it = m_names.find( id );
@@ -480,5 +480,5 @@
 	particle_system result = m_systems.create();
 	particle_system_info* info = m_systems.get( result );
-
+	info->group = group;
 	info->data     = data;
 	uint32 ecount = data->emmiter_count;
@@ -496,25 +496,40 @@
 	info->count = 0;
 	info->particles = new particle[ data->quota ];
-	info->quads     = new particle_quad[ data->quota ];
-
+	info->last_update = m_last_update;
+
+	return result;
+}
+
+void nv::particle_engine::prepare( particle_system_group group )
+{
+	particle_system_group_info* info = m_groups.get( group );
+	if ( info )
+	{
+		info->count = 0;
+	}
+}
+
+void nv::particle_engine::draw( particle_system_group group, const render_state& rs, const scene_state& ss )
+{
+	particle_system_group_info* info = m_groups.get( group );
+	if ( info )
+	{
+		m_context->draw( nv::TRIANGLES, rs, ss, info->local ? m_program_local : m_program_world, info->vtx_array, info->count * 6, 0 );
+	}
+}
+
+nv::particle_system_group nv::particle_engine::create_group( uint32 max_particles )
+{
+	particle_system_group result     = m_groups.create();
+	particle_system_group_info* info = m_groups.get( result );
+	info->local = false;
+	info->count = 0;
+	info->quota = max_particles;
+	info->vtx_buffer = m_device->create_buffer( VERTEX_BUFFER, STREAM_DRAW, info->quota * sizeof( particle_quad )/*, info->quads_[0].data*/ );
 	vertex_array_desc desc;
-	info->vtx_buffer = m_device->create_buffer( VERTEX_BUFFER, STREAM_DRAW, data->quota * 6 * sizeof( particle_vtx ), info->quads[0].data );
 	desc.add_vertex_buffers< particle_vtx >( info->vtx_buffer, true );
 	info->vtx_array = m_context->create_vertex_array( desc );
-	info->last_update = m_last_update;
-	info->test = false;
-//	result->m_own_va      = true;
-//	result->m_offset      = 0;
-
+	info->quads     = new particle_quad[info->quota];
 	return result;
-}
-
-void nv::particle_engine::draw( particle_system system, const render_state& rs, const scene_state& ss )
-{
-	particle_system_info* info = m_systems.get( system );
-	if ( info )
-	{
-		m_context->draw( nv::TRIANGLES, rs, ss, info->data->local ?  m_program_local : m_program_world, info->vtx_array, info->count * 6 );
-	}
 }
 
@@ -537,4 +552,6 @@
 	while ( m_systems.size() > 0 )
 		release( m_systems.get_handle( 0 ) );
+	while ( m_groups.size() > 0 )
+		release( m_groups.get_handle( 0 ) );
 	m_emmiters.clear();
 	m_affectors.clear();
@@ -551,22 +568,33 @@
 	{
 		delete[] info->particles;
+		m_systems.destroy( system );
+	}
+}
+
+void nv::particle_engine::release( particle_system_group group )
+{
+	particle_system_group_info* info = m_groups.get( group );
+	if ( info )
+	{
 		delete[] info->quads;
-		//if ( system->own_va ) 
 		m_context->release( info->vtx_array );
-		m_systems.destroy( system );
-	}
-}
-
-void nv::particle_engine::update( particle_system system, const scene_state& s, uint32 ms )
+		m_groups.destroy( group );
+	}
+}
+
+void nv::particle_engine::update( const scene_state& s, uint32 ms )
+{
+	m_last_update += ms;
+	m_view_matrix  = s.get_view();
+	m_model_matrix = s.get_model();
+	m_camera_pos   = s.get_camera().get_position();
+	m_inv_view_dir = math::normalize(-s.get_camera().get_direction());
+}
+
+void nv::particle_engine::update( particle_system system )
 {
 	particle_system_info* info = m_systems.get( system );
-	m_last_update += ms;
 	if ( info )
 	{
-		m_view_matrix  = s.get_view();
-		m_model_matrix = s.get_model();
-		m_camera_pos   = s.get_camera().get_position();
-		m_inv_view_dir = math::normalize(-s.get_camera().get_direction());
-
 		update_emmiters( info, m_last_update );
 		destroy_particles( info, m_last_update );
@@ -575,5 +603,4 @@
 
 		generate_data( info );
-		m_context->update( info->vtx_buffer, info->quads, /*system->m_offset*sizeof(particle_quad)*/ 0, info->count*sizeof(particle_quad) );
 	}
 }
@@ -585,15 +612,6 @@
 	{
 		vec2 texcoords[4] = { a, vec2( b.x, a.y ), vec2( a.x, b.y ), b };
-
-		for ( uint32 i = 0; i < info->data->quota; ++i )
-		{
-			particle_quad& rdata   = info->quads[i];
-			rdata.data[0].texcoord = texcoords[0];
-			rdata.data[1].texcoord = texcoords[1];
-			rdata.data[2].texcoord = texcoords[2];
-			rdata.data[3].texcoord = texcoords[3];
-			rdata.data[4].texcoord = texcoords[2];
-			rdata.data[5].texcoord = texcoords[1];
-		}
+		for ( uint32 i = 0; i < 4; ++i )
+			info->texcoords[i] = texcoords[i];
 	}
 }
@@ -601,4 +619,13 @@
 void nv::particle_engine::generate_data( particle_system_info* info )
 {
+//  	void* rawptr = m_context->map_buffer( info->vtx_buffer, nv::WRITE_UNSYNCHRONIZED, offset, info->count*sizeof( particle_quad ) );
+//  	particle_quad* quads = reinterpret_cast<particle_quad*>( rawptr );
+
+	particle_system_group_info* group = m_groups.get( info->group );
+	if ( !info )
+	{
+		return;
+	}
+
 	vec2 lb     = vec2( -0.5f, -0.5f );
 	vec2 rt     = vec2( 0.5f, 0.5f );
@@ -634,8 +661,17 @@
 	vec3 pdir( 0.0f, 1.0f, 0.0f );
 
+	vec2 texcoords[4] =
+	{
+		info->texcoords[0],
+		info->texcoords[1],
+		info->texcoords[2],
+		info->texcoords[3],
+	};
+
 	for ( uint32 i = 0; i < info->count; ++i )
 	{
 		const particle& pdata = info->particles[i];
-		particle_quad& rdata  = info->quads[i];
+//		particle_quad& rdata  = quads[i];
+		particle_quad& rdata  = group->quads[i + group->count];
 
 		vec3 view_dir( m_inv_view_dir );
@@ -676,17 +712,25 @@
 		rdata.data[0].position = pdata.position + s0;
 		rdata.data[0].color    = pdata.color;
+		rdata.data[0].texcoord = texcoords[0];
 
 		rdata.data[1].position = pdata.position + s1;
 		rdata.data[1].color    = pdata.color;
+		rdata.data[1].texcoord = texcoords[1];
 
 		rdata.data[2].position = pdata.position + s2;
 		rdata.data[2].color    = pdata.color;
+		rdata.data[2].texcoord = texcoords[2];
 
 		rdata.data[3].position = pdata.position + s3;
 		rdata.data[3].color    = pdata.color;
+		rdata.data[3].texcoord = texcoords[3];
 
 		rdata.data[4] = rdata.data[2];
 		rdata.data[5] = rdata.data[1];
 	}
+//	m_context->unmap_buffer( info->vtx_buffer );
+
+	m_context->update( group->vtx_buffer, group->quads, group->count*sizeof(particle_quad), info->count*sizeof( particle_quad ) );
+	group->count += info->count;
 }
 
