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 }
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); } }