예제 #1
0
void RAS_BucketManager::OrderBuckets(const MT_Transform& cameratrans, BucketList& buckets, vector<sortedmeshslot>& slots, bool alpha)
{
	BucketList::iterator bit;
	list<RAS_MeshSlot>::iterator mit;
	size_t size = 0, i = 0;

	/* Camera's near plane equation: pnorm.dot(point) + pval,
	 * but we leave out pval since it's constant anyway */
	const MT_Vector3 pnorm(cameratrans.getBasis()[2]);

	for (bit = buckets.begin(); bit != buckets.end(); ++bit)
	{
		SG_DList::iterator<RAS_MeshSlot> mit((*bit)->GetActiveMeshSlots());
		for(mit.begin(); !mit.end(); ++mit)
			size++;
	}

	slots.resize(size);

	for (bit = buckets.begin(); bit != buckets.end(); ++bit)
	{
		RAS_MaterialBucket* bucket = *bit;
		RAS_MeshSlot* ms;
		// remove the mesh slot form the list, it culls them automatically for next frame
		while((ms = bucket->GetNextActiveMeshSlot())) {
			slots[i++].set(ms, bucket, pnorm);
		}
	}
		
	if(alpha)
		sort(slots.begin(), slots.end(), backtofront());
	else
		sort(slots.begin(), slots.end(), fronttoback());
}
예제 #2
0
/* frees the bucket, only used when freeing scenes */
void RAS_BucketManager::RemoveMaterial(RAS_IPolyMaterial * mat)
{
	BucketList::iterator bit, bitp;
	list<RAS_MeshSlot>::iterator mit;
	int i;


	for(i=0; i<m_SolidBuckets.size(); i++) {
		RAS_MaterialBucket *bucket = m_SolidBuckets[i];
		if (mat == bucket->GetPolyMaterial()) {
			m_SolidBuckets.erase(m_SolidBuckets.begin()+i);
			delete bucket;
			i--;
		}
	}

	for(int i=0; i<m_AlphaBuckets.size(); i++) {
		RAS_MaterialBucket *bucket = m_AlphaBuckets[i];
		if (mat == bucket->GetPolyMaterial()) {
			m_AlphaBuckets.erase(m_AlphaBuckets.begin()+i);
			delete bucket;
			i--;
		}
	}
}
예제 #3
0
void KX_FontObject::AddMeshUser()
{
	m_meshUser = new RAS_TextUser(m_pClient_info);

	// set the part of the mesh slot that never change
	float *fl = GetOpenGLMatrixPtr()->getPointer();
	m_meshUser->SetMatrix(fl);

	RAS_BucketManager *bucketManager = GetScene()->GetBucketManager();
	bool created = false;
	RAS_MaterialBucket *bucket = bucketManager->FindBucket(GetTextMaterial(), created);

	// If the material bucket is just created then we add a new mesh slot.
	if (created) {
		RAS_TexVertFormat format;
		format.uvSize = 1;
		format.colorSize = 1;
		bucket->NewMesh(NULL, NULL, format);
	}

	/* We copy the original mesh slot which is at the begin of the list, if it's not the case it
	 * doesn't matter as the mesh slot are all similar exepted their mesh user pointer which is
	 * set to NULL in copy. By copying instead of adding a mesh slot we reuse the same display
	 * array bucket.
	 */
	RAS_MeshSlot *ms = bucket->CopyMesh(*bucket->msBegin());
	ms->SetMeshUser(m_meshUser);
	ms->SetDeformer(NULL);
	m_meshUser->AddMeshSlot(ms);
}
예제 #4
0
void RAS_BucketManager::RenderBasicBuckets(const MT_Transform& cameratrans, RAS_IRasterizer *rasty, RAS_BucketManager::BucketType bucketType)
{
	BucketList& solidBuckets = m_buckets[bucketType];
	for (BucketList::iterator bit = solidBuckets.begin(); bit != solidBuckets.end(); ++bit) {
		RAS_MaterialBucket *bucket = *bit;
		bucket->RenderMeshSlots(cameratrans, rasty);
	}
}
예제 #5
0
void RAS_BucketManager::RenderSolidBuckets(
	const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
{
	BucketList::iterator bit;

	rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);

	for (bit = m_SolidBuckets.begin(); bit != m_SolidBuckets.end(); ++bit) {
#if 1
		RAS_MaterialBucket* bucket = *bit;
		RAS_MeshSlot* ms;
		// remove the mesh slot form the list, it culls them automatically for next frame
		while((ms = bucket->GetNextActiveMeshSlot()))
		{
			rendertools->SetClientObject(rasty, ms->m_clientObj);
			while (bucket->ActivateMaterial(cameratrans, rasty, rendertools))
				bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *ms);

			// make this mesh slot culled automatically for next frame
			// it will be culled out by frustrum culling
			ms->SetCulled(true);
		}
#else
		list<RAS_MeshSlot>::iterator mit;
		for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
			if (mit->IsCulled())
				continue;

			rendertools->SetClientObject(rasty, mit->m_clientObj);

			while ((*bit)->ActivateMaterial(cameratrans, rasty, rendertools))
				(*bit)->RenderMeshSlot(cameratrans, rasty, rendertools, *mit);

			// make this mesh slot culled automatically for next frame
			// it will be culled out by frustrum culling
			mit->SetCulled(true);
		}
#endif
	}
	
	/* this code draws meshes order front-to-back instead to reduce overdraw.
	 * it turned out slower due to much material state switching, a more clever
	 * algorithm might do better. */
#if 0
	vector<sortedmeshslot> slots;
	vector<sortedmeshslot>::iterator sit;

	OrderBuckets(cameratrans, m_SolidBuckets, slots, false);

	for(sit=slots.begin(); sit!=slots.end(); ++sit) {
		rendertools->SetClientObject(rasty, sit->m_ms->m_clientObj);

		while(sit->m_bucket->ActivateMaterial(cameratrans, rasty, rendertools))
			sit->m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(sit->m_ms));
	}
#endif
}
예제 #6
0
void RAS_BucketManager::ReleaseMaterials(RAS_IPolyMaterial *mat)
{
	BucketList& buckets = m_buckets[ALL_BUCKET];
	for (BucketList::iterator it = buckets.begin(), end = buckets.end(); it != end; ++it) {
		RAS_MaterialBucket *bucket = *it;
		if (mat == NULL || (mat == bucket->GetPolyMaterial())) {
			bucket->GetPolyMaterial()->ReleaseMaterial();
		}
	}
}
예제 #7
0
void RAS_BucketManager::ReleaseDisplayLists(RAS_IPolyMaterial *mat)
{
	BucketList& buckets = m_buckets[ALL_BUCKET];
	for (BucketList::iterator it = buckets.begin(), end = buckets.end(); it != end; ++it) {
		RAS_MaterialBucket *bucket = *it;
		if (bucket->GetPolyMaterial() != mat && mat) {
			continue;
		}
		RAS_DisplayArrayBucketList& displayArrayBucketList = bucket->GetDisplayArrayBucketList();
		for (RAS_DisplayArrayBucketList::iterator dit = displayArrayBucketList.begin(), dend = displayArrayBucketList.end();
		     dit != dend; ++dit)
		{
			(*dit)->DestructStorageInfo();
		}
	}
}
예제 #8
0
RAS_MaterialBucket *RAS_BucketManager::FindBucket(RAS_IPolyMaterial *material, bool &bucketCreated)
{
	bucketCreated = false;

	BucketList& buckets = m_buckets[ALL_BUCKET];
	for (BucketList::iterator it = buckets.begin(), end = buckets.end(); it != end; ++it) {
		RAS_MaterialBucket *bucket = *it;
		if (bucket->GetPolyMaterial() == material) {
			return bucket;
		}
	}

	RAS_MaterialBucket *bucket = new RAS_MaterialBucket(material);
	bucketCreated = true;

	const bool useinstancing = material->UseInstancing();
	if (!material->OnlyShadow()) {
		if (material->IsAlpha()) {
			if (material->IsAlphaDepth()) {
				m_buckets[useinstancing ? ALPHA_DEPTH_INSTANCING_BUCKET : ALPHA_DEPTH_BUCKET].push_back(bucket);
			}
			else {
				m_buckets[useinstancing ? ALPHA_INSTANCING_BUCKET : ALPHA_BUCKET].push_back(bucket);
			}
		}
		else {
			m_buckets[useinstancing ? SOLID_INSTANCING_BUCKET : SOLID_BUCKET].push_back(bucket);
		}
	}
	if (material->CastsShadows()) {
		if (material->IsAlphaShadow()) {
			m_buckets[useinstancing ? ALPHA_SHADOW_INSTANCING_BUCKET : ALPHA_SHADOW_BUCKET].push_back(bucket);
		}
		else {
			m_buckets[useinstancing ? SOLID_SHADOW_INSTANCING_BUCKET : SOLID_SHADOW_BUCKET].push_back(bucket);
		}
	}
	if (material->IsText()) {
		m_buckets[TEXT_BUCKET].push_back(bucket);
	}

	// Used to free the bucket.
	m_buckets[ALL_BUCKET].push_back(bucket);
	return bucket;
}
예제 #9
0
/* frees the bucket, only used when freeing scenes */
void RAS_BucketManager::RemoveMaterial(RAS_IPolyMaterial *mat)
{
	for (unsigned short i = 0; i < NUM_BUCKET_TYPE; ++i) {
		BucketList& buckets = m_buckets[i];
		for (BucketList::iterator it = buckets.begin(); it != buckets.end();) {
			RAS_MaterialBucket *bucket = *it;
			if (mat == bucket->GetPolyMaterial()) {
				it = buckets.erase(it);
				if (i == ALL_BUCKET) {
					delete bucket;
				}
			}
			else {
				++it;
			}
		}
	}
}
예제 #10
0
RAS_MaterialBucket* RAS_BucketManager::FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
{
	BucketList::iterator it;

	bucketCreated = false;

	for (it = m_SolidBuckets.begin(); it != m_SolidBuckets.end(); it++)
		if (*(*it)->GetPolyMaterial() == *material)
			return *it;
	
	for (it = m_AlphaBuckets.begin(); it != m_AlphaBuckets.end(); it++)
		if (*(*it)->GetPolyMaterial() == *material)
			return *it;
	
	RAS_MaterialBucket *bucket = new RAS_MaterialBucket(material);
	bucketCreated = true;

	if (bucket->IsAlpha())
		m_AlphaBuckets.push_back(bucket);
	else
		m_SolidBuckets.push_back(bucket);
	
	return bucket;
}
예제 #11
0
void RAS_BucketManager::RenderSortedBuckets(const MT_Transform& cameratrans, RAS_IRasterizer *rasty, RAS_BucketManager::BucketType bucketType)
{
	std::vector<sortedmeshslot> slots;
	std::vector<sortedmeshslot>::iterator sit;

	OrderBuckets(cameratrans, bucketType, slots, true, rasty);
	// Discard if there's no mesh slots.
	if (slots.size() == 0) {
		return;
	}

	// The last display array and material bucket used to avoid double calls.
	RAS_DisplayArrayBucket *lastDisplayArrayBucket = NULL;
	RAS_MaterialBucket *lastMaterialBucket = NULL;

	bool matactivated = false;

	for (sit = slots.begin(); sit != slots.end(); ++sit) {
		RAS_MaterialBucket *bucket = sit->m_bucket;
		RAS_DisplayArrayBucket *displayArrayBucket = sit->m_ms->m_displayArrayBucket;

		/* Unbind display array here before unset material to use the proper
		 * number of attributs in storage unbind since this variable is
		 * global and mutated by all material during its activation.
		 */
		if (displayArrayBucket != lastDisplayArrayBucket && lastDisplayArrayBucket) {
			rasty->UnbindPrimitives(lastDisplayArrayBucket);
		}
		if (bucket != lastMaterialBucket) {
			if (matactivated) {
				lastMaterialBucket->DesactivateMaterial(rasty);
			}
			matactivated = bucket->ActivateMaterial(rasty);
			lastMaterialBucket = bucket;
		}

		/* Bind the new display array here after material activation to use
		 * proper attributs numbers, same as display array unbind before.
		 */
		if (displayArrayBucket != lastDisplayArrayBucket) {
			rasty->BindPrimitives(displayArrayBucket);
			lastDisplayArrayBucket = displayArrayBucket;
		}

		bucket->RenderMeshSlot(cameratrans, rasty, sit->m_ms);
	}

	// Always unbind VBO or VA before unset the material to use the correct material attributs.
	rasty->UnbindPrimitives(lastDisplayArrayBucket);

	if (matactivated) {
		lastMaterialBucket->DesactivateMaterial(rasty);
	}
}