Exemplo n.º 1
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
}
Exemplo n.º 2
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);
	}
}