forked from bartvdbraak/blender
Depth sorting for alpha mesh objects.
- Mesh Objects are sorted by depth (based on object centre.) Using object centre means the user has control over the sort. - Polygons are not sorted. - Polygons are not split. - O(nlog(n))
This commit is contained in:
parent
2a622e35d4
commit
e78ef29a59
@ -48,7 +48,7 @@
|
||||
|
||||
#include "RAS_BucketManager.h"
|
||||
|
||||
|
||||
#include <set>
|
||||
|
||||
RAS_BucketManager::RAS_BucketManager()
|
||||
{
|
||||
@ -61,10 +61,45 @@ RAS_BucketManager::~RAS_BucketManager()
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RAS_BucketManager::RenderAlphaBuckets(
|
||||
const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
|
||||
{
|
||||
BucketList::iterator bit;
|
||||
std::multiset<alphamesh, backtofront> alphameshset;
|
||||
RAS_MaterialBucket::T_MeshSlotList::iterator mit;
|
||||
|
||||
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit)
|
||||
{
|
||||
(*bit)->ClearScheduledPolygons();
|
||||
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
|
||||
{
|
||||
if ((*mit).m_bVisible)
|
||||
{
|
||||
MT_Point3 pos((*mit).m_OpenGLMatrix[12], (*mit).m_OpenGLMatrix[13], (*mit).m_OpenGLMatrix[14]);
|
||||
alphameshset.insert(alphamesh(MT_dot(cameratrans.getBasis()[2], pos) + cameratrans.getOrigin()[2], mit, *bit));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// It shouldn't be strictly necessary to disable depth writes; but
|
||||
// it is needed for compatibility.
|
||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
|
||||
|
||||
std::multiset< alphamesh, backtofront>::iterator msit = alphameshset.begin();
|
||||
for (; msit != alphameshset.end(); ++msit)
|
||||
{
|
||||
(*msit).m_bucket->RenderMeshSlot(cameratrans, rasty, rendertools, *(*msit).m_ms,
|
||||
(*msit).m_bucket->ActivateMaterial(cameratrans, rasty, rendertools));
|
||||
}
|
||||
|
||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
||||
}
|
||||
|
||||
void RAS_BucketManager::Renderbuckets(
|
||||
const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
|
||||
{
|
||||
std::vector<RAS_MaterialBucket*>::iterator bucket;
|
||||
BucketList::iterator bucket;
|
||||
|
||||
rasty->EnableTextures(false);
|
||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
||||
@ -73,33 +108,22 @@ void RAS_BucketManager::Renderbuckets(
|
||||
rasty->ClearCachingInfo();
|
||||
|
||||
RAS_MaterialBucket::StartFrame();
|
||||
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); bucket++)
|
||||
{
|
||||
(*bucket)->ClearScheduledPolygons();
|
||||
}
|
||||
for (bucket = m_AlphaBuckets.begin(); bucket != m_AlphaBuckets.end(); bucket++)
|
||||
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
|
||||
{
|
||||
(*bucket)->ClearScheduledPolygons();
|
||||
}
|
||||
|
||||
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); bucket++)
|
||||
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
|
||||
(*bucket)->Render(cameratrans,rasty,rendertools);
|
||||
|
||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
|
||||
|
||||
for (bucket = m_AlphaBuckets.begin(); bucket != m_AlphaBuckets.end(); bucket++)
|
||||
{
|
||||
(*bucket)->Render(cameratrans,rasty,rendertools);
|
||||
}
|
||||
|
||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
||||
RenderAlphaBuckets(cameratrans, rasty, rendertools);
|
||||
|
||||
RAS_MaterialBucket::EndFrame();
|
||||
}
|
||||
|
||||
RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material)
|
||||
{
|
||||
std::vector<RAS_MaterialBucket*>::iterator it;
|
||||
BucketList::iterator it;
|
||||
for (it = m_MaterialBuckets.begin(); it != m_MaterialBuckets.end(); it++)
|
||||
{
|
||||
if (*(*it)->GetPolyMaterial() == *material)
|
||||
@ -123,7 +147,7 @@ RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMate
|
||||
|
||||
void RAS_BucketManager::RAS_BucketManagerClearAll()
|
||||
{
|
||||
std::vector<RAS_MaterialBucket*>::iterator it;
|
||||
BucketList::iterator it;
|
||||
for (it = m_MaterialBuckets.begin(); it != m_MaterialBuckets.end(); it++)
|
||||
{
|
||||
delete (*it);
|
||||
|
@ -43,13 +43,42 @@
|
||||
class RAS_BucketManager
|
||||
{
|
||||
//GEN_Map<class RAS_IPolyMaterial,class RAS_MaterialBucket*> m_MaterialBuckets;
|
||||
std::vector<class RAS_MaterialBucket*> m_MaterialBuckets;
|
||||
std::vector<class RAS_MaterialBucket*> m_AlphaBuckets;
|
||||
|
||||
typedef std::vector<class RAS_MaterialBucket*> BucketList;
|
||||
BucketList m_MaterialBuckets;
|
||||
BucketList m_AlphaBuckets;
|
||||
|
||||
/**
|
||||
* struct alphamesh holds a mesh, (m_ms) it's depth, (m_z) and the bucket it came from (m_bucket.)
|
||||
*/
|
||||
struct alphamesh
|
||||
{
|
||||
public:
|
||||
MT_Scalar m_z;
|
||||
RAS_MaterialBucket::T_MeshSlotList::iterator m_ms;
|
||||
RAS_MaterialBucket *m_bucket;
|
||||
alphamesh(MT_Scalar z, RAS_MaterialBucket::T_MeshSlotList::iterator &ms, RAS_MaterialBucket *bucket) :
|
||||
m_z(z),
|
||||
m_ms(ms),
|
||||
m_bucket(bucket)
|
||||
{}
|
||||
};
|
||||
|
||||
struct backtofront
|
||||
{
|
||||
bool operator()(const alphamesh &a, const alphamesh &b)
|
||||
{
|
||||
return a.m_z < b.m_z;
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
public:
|
||||
RAS_BucketManager();
|
||||
virtual ~RAS_BucketManager();
|
||||
|
||||
void RenderAlphaBuckets(const MT_Transform& cameratrans,
|
||||
RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools);
|
||||
void Renderbuckets(const MT_Transform & cameratrans,
|
||||
RAS_IRasterizer* rasty,
|
||||
class RAS_IRenderTools* rendertools);
|
||||
|
@ -154,28 +154,28 @@ void RAS_MaterialBucket::EndFrame()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
|
||||
void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
|
||||
RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools* rendertools)
|
||||
unsigned int RAS_MaterialBucket::NumMeshSlots()
|
||||
{
|
||||
return m_meshSlots.size();
|
||||
}
|
||||
|
||||
if (m_meshSlots.begin()== m_meshSlots.end())
|
||||
return;
|
||||
RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msBegin()
|
||||
{
|
||||
return m_meshSlots.begin();
|
||||
}
|
||||
|
||||
RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msEnd()
|
||||
{
|
||||
return m_meshSlots.end();
|
||||
}
|
||||
|
||||
int RAS_MaterialBucket::ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools *rendertools)
|
||||
{
|
||||
rendertools->SetViewMat(cameratrans);
|
||||
|
||||
rasty->SetMaterial(*m_material);
|
||||
|
||||
if (m_meshSlots.size() >0)
|
||||
{
|
||||
|
||||
rendertools->SetClientObject((*m_meshSlots.begin()).m_clientObj);
|
||||
}
|
||||
|
||||
//printf("RAS_MatBucket::Render: %d m_meshSlots\n", m_meshSlots.size());
|
||||
|
||||
bool dolights = m_material->GetDrawingMode()&16;
|
||||
|
||||
if ((rasty->GetDrawingMode() <= RAS_IRasterizer::KX_SOLID) || !dolights)
|
||||
@ -187,68 +187,91 @@ void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
|
||||
bool bUseLights = rendertools->ProcessLighting(m_material->GetLightLayer());
|
||||
}
|
||||
|
||||
int drawmode = (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ?
|
||||
return (rasty->GetDrawingMode() < RAS_IRasterizer::KX_SOLID ?
|
||||
1: (m_material->UsesTriangles() ? 0 : 2));
|
||||
}
|
||||
|
||||
void RAS_MaterialBucket::RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode)
|
||||
{
|
||||
if (!ms.m_bVisible)
|
||||
return;
|
||||
|
||||
rendertools->SetClientObject(ms.m_clientObj);
|
||||
|
||||
/* __NLA Do the deformation */
|
||||
if (ms.m_pDeformer)
|
||||
ms.m_pDeformer->Apply(m_material);
|
||||
/* End __NLA */
|
||||
|
||||
rendertools->PushMatrix();
|
||||
rendertools->applyTransform(rasty,ms.m_OpenGLMatrix,m_material->GetDrawingMode());
|
||||
|
||||
// Use the text-specific IndexPrimitives for text faces
|
||||
if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT)
|
||||
{
|
||||
rasty->IndexPrimitives_3DText(
|
||||
ms.m_mesh->GetVertexCache(m_material),
|
||||
ms.m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
ms.m_bObjectColor,
|
||||
ms.m_RGBAcolor);
|
||||
|
||||
}
|
||||
// Use the (slower) IndexPrimitives_Ex which can recalc face normals & such
|
||||
// for deformed objects - eventually should be extended to recalc ALL normals
|
||||
else if (ms.m_pDeformer){
|
||||
rasty->IndexPrimitives_Ex(
|
||||
ms.m_mesh->GetVertexCache(m_material),
|
||||
ms.m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
ms.m_bObjectColor,
|
||||
ms.m_RGBAcolor
|
||||
);
|
||||
}
|
||||
// Use the normal IndexPrimitives
|
||||
else
|
||||
{
|
||||
rasty->IndexPrimitives(
|
||||
ms.m_mesh->GetVertexCache(m_material),
|
||||
ms.m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
ms.m_bObjectColor,
|
||||
ms.m_RGBAcolor
|
||||
);
|
||||
}
|
||||
|
||||
rendertools->PopMatrix();
|
||||
}
|
||||
|
||||
void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
|
||||
RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools* rendertools)
|
||||
{
|
||||
if (m_meshSlots.begin()== m_meshSlots.end())
|
||||
return;
|
||||
|
||||
rendertools->SetViewMat(cameratrans);
|
||||
|
||||
rasty->SetMaterial(*m_material);
|
||||
|
||||
if (m_meshSlots.size() >0)
|
||||
{
|
||||
rendertools->SetClientObject((*m_meshSlots.begin()).m_clientObj);
|
||||
}
|
||||
|
||||
int drawmode = ActivateMaterial(cameratrans, rasty, rendertools);
|
||||
|
||||
for (T_MeshSlotList::const_iterator it = m_meshSlots.begin();
|
||||
! (it == m_meshSlots.end());it++)
|
||||
! (it == m_meshSlots.end()); ++it)
|
||||
{
|
||||
//printf("RAS_MatBucket::Render: (%p) %s MeshSlot %s\n", this, it->m_mesh->m_class?"Skin":"Mesh", (const char *)(*it).m_mesh->GetName());
|
||||
if ((*it).m_bVisible)
|
||||
{
|
||||
rendertools->SetClientObject((*it).m_clientObj);
|
||||
|
||||
/* __NLA Do the deformation */
|
||||
if ((*it).m_pDeformer)
|
||||
(*it).m_pDeformer->Apply(m_material);
|
||||
/* End __NLA */
|
||||
|
||||
rendertools->PushMatrix();
|
||||
rendertools->applyTransform(rasty,(*it).m_OpenGLMatrix,m_material->GetDrawingMode());
|
||||
|
||||
// Use the text-specific IndexPrimitives for text faces
|
||||
if (m_material->GetDrawingMode() & RAS_IRasterizer::RAS_RENDER_3DPOLYGON_TEXT)
|
||||
{
|
||||
rasty->IndexPrimitives_3DText(
|
||||
(*it).m_mesh->GetVertexCache(m_material),
|
||||
(*it).m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
(*it).m_bObjectColor,
|
||||
(*it).m_RGBAcolor);
|
||||
|
||||
}
|
||||
// Use the (slower) IndexPrimitives_Ex which can recalc face normals & such
|
||||
// for deformed objects - eventually should be extended to recalc ALL normals
|
||||
else if ((*it).m_pDeformer){
|
||||
rasty->IndexPrimitives_Ex(
|
||||
(*it).m_mesh->GetVertexCache(m_material),
|
||||
(*it).m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
(*it).m_bObjectColor,
|
||||
(*it).m_RGBAcolor
|
||||
);
|
||||
}
|
||||
// Use the normal IndexPrimitives
|
||||
else
|
||||
{
|
||||
rasty->IndexPrimitives(
|
||||
(*it).m_mesh->GetVertexCache(m_material),
|
||||
(*it).m_mesh->GetIndexCache(m_material),
|
||||
drawmode,
|
||||
m_material,
|
||||
rendertools, // needed for textprinting on polys
|
||||
(*it).m_bObjectColor,
|
||||
(*it).m_RGBAcolor
|
||||
);
|
||||
}
|
||||
|
||||
rendertools->PopMatrix();
|
||||
}
|
||||
//printf("gets here\n");
|
||||
RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,15 +95,9 @@ inline bool operator <( const KX_MeshSlot& rhs,const KX_MeshSlot& lhs)
|
||||
*/
|
||||
class RAS_MaterialBucket
|
||||
{
|
||||
public:
|
||||
typedef std::set<KX_MeshSlot> T_MeshSlotList;
|
||||
|
||||
T_MeshSlotList m_meshSlots;
|
||||
bool m_bScheduled;
|
||||
bool m_bModified;
|
||||
RAS_IPolyMaterial* m_material;
|
||||
double* m_pOGLMatrix;
|
||||
|
||||
public:
|
||||
RAS_MaterialBucket(RAS_IPolyMaterial* mat);
|
||||
virtual ~RAS_MaterialBucket() {}
|
||||
|
||||
@ -127,6 +121,15 @@ public:
|
||||
bool color,
|
||||
const MT_Vector4& rgbavec);
|
||||
|
||||
void RenderMeshSlot(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools* rendertools, const KX_MeshSlot &ms, int drawmode);
|
||||
int ActivateMaterial(const MT_Transform& cameratrans, RAS_IRasterizer* rasty,
|
||||
RAS_IRenderTools *rendertools);
|
||||
|
||||
unsigned int NumMeshSlots();
|
||||
T_MeshSlotList::iterator msBegin();
|
||||
T_MeshSlotList::iterator msEnd();
|
||||
|
||||
struct less
|
||||
{
|
||||
bool operator()(const RAS_MaterialBucket* x, const RAS_MaterialBucket* y) const
|
||||
@ -136,6 +139,14 @@ public:
|
||||
};
|
||||
|
||||
typedef set<RAS_MaterialBucket*, less> Set;
|
||||
private:
|
||||
|
||||
T_MeshSlotList m_meshSlots;
|
||||
bool m_bScheduled;
|
||||
bool m_bModified;
|
||||
RAS_IPolyMaterial* m_material;
|
||||
double* m_pOGLMatrix;
|
||||
|
||||
};
|
||||
|
||||
#endif //__KX_BUCKET
|
||||
|
Loading…
Reference in New Issue
Block a user