예제 #1
0
///===========================================================================
void CParticleSystemShape::flushTextures(IDriver &driver, uint selectedTexture)
{
	// if textures are already flushed, no-op
	if (!_CachedTex.empty()) return;
	if (_SharedSystem)
	{
		_SharedSystem->enumTexs(_CachedTex, driver);
	}
	else
	{
		s_PSSMutex.enter();

		// must create an instance just to flush the textures
		CParticleSystem *myInstance = NULL;

		#ifdef PS_FAST_ALLOC
			nlassert(PSBlockAllocator == NULL);
			NLMISC::CContiguousBlockAllocator blockAllocator;
			PSBlockAllocator = &blockAllocator;
			blockAllocator.init(300000); // we release memory just after, and we don't want to fragment the memory, so provide large enough mem
		#endif
		// serialize from the memory stream
		if (!_ParticleSystemProto.isReading()) // we must be sure that we are reading the stream
		{
			_ParticleSystemProto.invert();
		}
		_ParticleSystemProto.resetPtrTable();
		_ParticleSystemProto.seek(0, NLMISC::IStream::begin);
		_ParticleSystemProto.serialPtr(myInstance); // instanciate the system
		#ifdef PS_FAST_ALLOC
			_NumBytesWanted = blockAllocator.getNumAllocatedBytes(); // next allocation will be fast because we know how much memory to allocate
		#endif
		myInstance->enumTexs(_CachedTex, driver);
		// tmp
		/*
		#ifdef NL_DEBUG
			for(uint k = 0; k < myInstance->getNbProcess(); ++k)
			{
				CPSLocated *loc = (CPSLocated *) myInstance->getProcess(k);
				for(uint l = 0; l < loc->getNbBoundObjects(); ++l)
				{
					if (dynamic_cast<CPSCentralGravity *>(loc->getBoundObject(l)))
					{
						nlwarning("PS %s uses central gravity", myInstance->getName().c_str());
						break;
					}
				}
			}
		#endif */
		// sort the process inside the fx
		myInstance->getSortingByEmitterPrecedence(_ProcessOrder);
		delete myInstance;
		#ifdef PS_FAST_ALLOC
			PSBlockAllocator = NULL;
		#endif
		s_PSSMutex.leave();
	}
	for(uint k = 0; k < _CachedTex.size(); ++k)
	{
		//nlinfo(_CachedTex[k]->getShareName().c_str());
		if (_CachedTex[k])
		{
			_CachedTex[k]->setTextureCategory(CPSTextureCategory::get());
			driver.setupTexture(*_CachedTex[k]);
		}
	}
}
예제 #2
0
///===========================================================================
CParticleSystem *CParticleSystemShape::instanciatePS(CScene &scene, NLMISC::CContiguousBlockAllocator *blockAllocator /*= NULL*/)
{
	if (_Sharing && _SharedSystem != NULL) // is sharing enabled, and is a system already instanciated
	{
		return _SharedSystem;
	}

	// avoid prb with concurrent thread (may happen if an instance group containing ps is loaded in background)
	s_PSSMutex.enter();


	#ifdef PS_FAST_ALLOC
		nlassert(PSBlockAllocator == NULL);
		if (blockAllocator)
		{
			// set new allocator for particle system memory
			PSBlockAllocator = blockAllocator;
			blockAllocator->init(_NumBytesWanted); // if size wanted is already known, set it
		}
	#endif

	//NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime();
	// copy the datas
	CParticleSystem *myInstance = NULL;

	// serialize from the memory stream
	if (!_ParticleSystemProto.isReading()) // we must be sure that we are reading the stream
	{
		_ParticleSystemProto.invert();
	}

	_ParticleSystemProto.resetPtrTable();
	_ParticleSystemProto.seek(0, NLMISC::IStream::begin);

//	NLMISC::TTicks start = NLMISC::CTime::getPerformanceTime();
	_ParticleSystemProto.serialPtr(myInstance); // instanciate the system
/*	NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime();
	nlinfo("instanciation time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start)));
*/

	myInstance->setScene(&scene);

	if (_CachedTex.empty() && scene.getDriver())
	{
		//nlinfo("flushing texs");
		// load && cache textures
		myInstance->enumTexs(_CachedTex, *scene.getDriver());
		for(uint k = 0; k < _CachedTex.size(); ++k)
		{
			if (_CachedTex[k])
			{
				_CachedTex[k]->setTextureCategory(CPSTextureCategory::get());
				scene.getDriver()->setupTexture (*(ITexture *)_CachedTex[k]);
			}
		}
	}
	else
	{
		/*
		for(uint k = 0; k < _CachedTex.size(); ++k)
		{
			nlinfo(_CachedTex[k]->getShareName().c_str());
		}
		*/
	}

	// tmp

	if (_Sharing)
	{
		_SharedSystem = myInstance; // set this as the first shared instance
	}

	#ifdef PS_FAST_ALLOC
		if (blockAllocator)
		{
			_NumBytesWanted = blockAllocator->getNumAllocatedBytes(); // now we know the number of wanted bytes, subsequent alloc can be much faster
			PSBlockAllocator = NULL;
		}
	#endif

	s_PSSMutex.leave();

	/*NLMISC::TTicks end = NLMISC::CTime::getPerformanceTime();
	nlinfo("instanciation time = %.2f", (float) (1000 * NLMISC::CTime::ticksToSecond(end - start)));	*/
	return myInstance;
}