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