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 "RAS_BucketManager.h"
|
||||||
|
|
||||||
|
#include <set>
|
||||||
|
|
||||||
RAS_BucketManager::RAS_BucketManager()
|
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(
|
void RAS_BucketManager::Renderbuckets(
|
||||||
const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
|
const MT_Transform& cameratrans, RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools)
|
||||||
{
|
{
|
||||||
std::vector<RAS_MaterialBucket*>::iterator bucket;
|
BucketList::iterator bucket;
|
||||||
|
|
||||||
rasty->EnableTextures(false);
|
rasty->EnableTextures(false);
|
||||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
||||||
@ -73,33 +108,22 @@ void RAS_BucketManager::Renderbuckets(
|
|||||||
rasty->ClearCachingInfo();
|
rasty->ClearCachingInfo();
|
||||||
|
|
||||||
RAS_MaterialBucket::StartFrame();
|
RAS_MaterialBucket::StartFrame();
|
||||||
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); bucket++)
|
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
|
||||||
{
|
{
|
||||||
(*bucket)->ClearScheduledPolygons();
|
(*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++)
|
|
||||||
(*bucket)->Render(cameratrans,rasty,rendertools);
|
(*bucket)->Render(cameratrans,rasty,rendertools);
|
||||||
|
|
||||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_DISABLED);
|
RenderAlphaBuckets(cameratrans, rasty, rendertools);
|
||||||
|
|
||||||
for (bucket = m_AlphaBuckets.begin(); bucket != m_AlphaBuckets.end(); bucket++)
|
|
||||||
{
|
|
||||||
(*bucket)->Render(cameratrans,rasty,rendertools);
|
|
||||||
}
|
|
||||||
|
|
||||||
rasty->SetDepthMask(RAS_IRasterizer::KX_DEPTHMASK_ENABLED);
|
|
||||||
|
|
||||||
RAS_MaterialBucket::EndFrame();
|
RAS_MaterialBucket::EndFrame();
|
||||||
}
|
}
|
||||||
|
|
||||||
RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material)
|
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++)
|
for (it = m_MaterialBuckets.begin(); it != m_MaterialBuckets.end(); it++)
|
||||||
{
|
{
|
||||||
if (*(*it)->GetPolyMaterial() == *material)
|
if (*(*it)->GetPolyMaterial() == *material)
|
||||||
@ -123,7 +147,7 @@ RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMate
|
|||||||
|
|
||||||
void RAS_BucketManager::RAS_BucketManagerClearAll()
|
void RAS_BucketManager::RAS_BucketManagerClearAll()
|
||||||
{
|
{
|
||||||
std::vector<RAS_MaterialBucket*>::iterator it;
|
BucketList::iterator it;
|
||||||
for (it = m_MaterialBuckets.begin(); it != m_MaterialBuckets.end(); it++)
|
for (it = m_MaterialBuckets.begin(); it != m_MaterialBuckets.end(); it++)
|
||||||
{
|
{
|
||||||
delete (*it);
|
delete (*it);
|
||||||
|
@ -43,13 +43,42 @@
|
|||||||
class RAS_BucketManager
|
class RAS_BucketManager
|
||||||
{
|
{
|
||||||
//GEN_Map<class RAS_IPolyMaterial,class RAS_MaterialBucket*> m_MaterialBuckets;
|
//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:
|
public:
|
||||||
RAS_BucketManager();
|
RAS_BucketManager();
|
||||||
virtual ~RAS_BucketManager();
|
virtual ~RAS_BucketManager();
|
||||||
|
|
||||||
|
void RenderAlphaBuckets(const MT_Transform& cameratrans,
|
||||||
|
RAS_IRasterizer* rasty, RAS_IRenderTools* rendertools);
|
||||||
void Renderbuckets(const MT_Transform & cameratrans,
|
void Renderbuckets(const MT_Transform & cameratrans,
|
||||||
RAS_IRasterizer* rasty,
|
RAS_IRasterizer* rasty,
|
||||||
class RAS_IRenderTools* rendertools);
|
class RAS_IRenderTools* rendertools);
|
||||||
|
@ -154,28 +154,28 @@ void RAS_MaterialBucket::EndFrame()
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
unsigned int RAS_MaterialBucket::NumMeshSlots()
|
||||||
|
|
||||||
void RAS_MaterialBucket::Render(const MT_Transform& cameratrans,
|
|
||||||
RAS_IRasterizer* rasty,
|
|
||||||
RAS_IRenderTools* rendertools)
|
|
||||||
{
|
{
|
||||||
|
return m_meshSlots.size();
|
||||||
|
}
|
||||||
|
|
||||||
if (m_meshSlots.begin()== m_meshSlots.end())
|
RAS_MaterialBucket::T_MeshSlotList::iterator RAS_MaterialBucket::msBegin()
|
||||||
return;
|
{
|
||||||
|
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);
|
rendertools->SetViewMat(cameratrans);
|
||||||
|
|
||||||
rasty->SetMaterial(*m_material);
|
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;
|
bool dolights = m_material->GetDrawingMode()&16;
|
||||||
|
|
||||||
if ((rasty->GetDrawingMode() <= RAS_IRasterizer::KX_SOLID) || !dolights)
|
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());
|
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));
|
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();
|
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());
|
RenderMeshSlot(cameratrans, rasty, rendertools, *it, drawmode);
|
||||||
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");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -95,15 +95,9 @@ inline bool operator <( const KX_MeshSlot& rhs,const KX_MeshSlot& lhs)
|
|||||||
*/
|
*/
|
||||||
class RAS_MaterialBucket
|
class RAS_MaterialBucket
|
||||||
{
|
{
|
||||||
|
public:
|
||||||
typedef std::set<KX_MeshSlot> T_MeshSlotList;
|
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);
|
RAS_MaterialBucket(RAS_IPolyMaterial* mat);
|
||||||
virtual ~RAS_MaterialBucket() {}
|
virtual ~RAS_MaterialBucket() {}
|
||||||
|
|
||||||
@ -127,6 +121,15 @@ public:
|
|||||||
bool color,
|
bool color,
|
||||||
const MT_Vector4& rgbavec);
|
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
|
struct less
|
||||||
{
|
{
|
||||||
bool operator()(const RAS_MaterialBucket* x, const RAS_MaterialBucket* y) const
|
bool operator()(const RAS_MaterialBucket* x, const RAS_MaterialBucket* y) const
|
||||||
@ -136,6 +139,14 @@ public:
|
|||||||
};
|
};
|
||||||
|
|
||||||
typedef set<RAS_MaterialBucket*, less> Set;
|
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
|
#endif //__KX_BUCKET
|
||||||
|
Loading…
Reference in New Issue
Block a user