Welcome to mirror list, hosted at ThFree Co, Russian Federation.

git.blender.org/blender.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrecht Van Lommel <brechtvanlommel@pandora.be>2008-07-29 19:48:31 +0400
committerBrecht Van Lommel <brechtvanlommel@pandora.be>2008-07-29 19:48:31 +0400
commit908337bee11f6b55c34a5880ea241b3975c35287 (patch)
tree2f7385f97634b852f81687e7643f214dcf3b25c4 /source/gameengine/Rasterizer
parentb0c513e83a638533b117d8b14b169b4fdd7a0369 (diff)
Game Engine: alpha blending and sorting
======================================= Alpha blending + sorting was revised, to fix bugs and get it to work more predictable. * A new per texture face "Sort" setting defines if the face is alpha sorted or not, instead of abusing the "ZTransp" setting as it did before. * Existing files are converted to hopefully match the old behavior as much as possible with a version patch. * On new meshes the Sort flag is disabled by the default, to avoid unexpected and hard to find slowdowns. * Alpha sorting for faces was incredibly slow. Sorting faces in a mesh with 600 faces lowered the framerate from 200 to 70 fps in my test.. the sorting there case goes about 15x faster now, but it is still advised to use Clip Alpha if possible instead of regular Alpha. * There still various limitations in the alpha sorting code, I've added some comments to the code about this. Some docs at the bottom of the page: http://www.blender.org/development/current-projects/changes-since-246/realtime-glsl-materials/ Merged some fixes from the apricot branch, most important change is that tangents are now exactly the same as the rest of Blender, instead of being computed in the game engine with a different algorithm. Also, the subversion was bumped to 1.
Diffstat (limited to 'source/gameengine/Rasterizer')
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.cpp43
-rw-r--r--source/gameengine/Rasterizer/RAS_BucketManager.h3
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp14
-rw-r--r--source/gameengine/Rasterizer/RAS_IPolygonMaterial.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_IRasterizer.h10
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.cpp24
-rw-r--r--source/gameengine/Rasterizer/RAS_MaterialBucket.h7
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.cpp186
-rw-r--r--source/gameengine/Rasterizer/RAS_MeshObject.h29
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp48
-rw-r--r--source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h9
-rw-r--r--source/gameengine/Rasterizer/RAS_Polygon.cpp18
12 files changed, 202 insertions, 199 deletions
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.cpp b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
index b4492ca03a9..82bdce44519 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.cpp
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.cpp
@@ -94,7 +94,6 @@ void RAS_BucketManager::RenderAlphaBuckets(
const MT_Scalar cam_origin = cameratrans.getOrigin()[2];
for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit)
{
- (*bit)->ClearScheduledPolygons();
for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit)
{
if ((*mit).m_bVisible)
@@ -133,28 +132,15 @@ void RAS_BucketManager::Renderbuckets(
rasty->ClearCachingInfo();
RAS_MaterialBucket::StartFrame();
- for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
- {
- (*bucket)->ClearScheduledPolygons();
- }
for (bucket = m_MaterialBuckets.begin(); bucket != m_MaterialBuckets.end(); ++bucket)
- {
- RAS_IPolyMaterial *tmp = (*bucket)->GetPolyMaterial();
- if(tmp->IsZSort() || tmp->GetFlag() &RAS_FORCEALPHA )
- rasty->SetAlphaTest(true);
- else
- rasty->SetAlphaTest(false);
-
(*bucket)->Render(cameratrans,rasty,rendertools);
- }
- rasty->SetAlphaTest(false);
RenderAlphaBuckets(cameratrans, rasty, rendertools);
RAS_MaterialBucket::EndFrame();
}
-RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
+RAS_MaterialBucket* RAS_BucketManager::FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated)
{
bucketCreated = false;
BucketList::iterator it;
@@ -172,7 +158,7 @@ RAS_MaterialBucket* RAS_BucketManager::RAS_BucketManagerFindBucket(RAS_IPolyMate
RAS_MaterialBucket *bucket = new RAS_MaterialBucket(material);
bucketCreated = true;
- if (bucket->IsTransparant())
+ if (bucket->IsAlpha())
m_AlphaBuckets.push_back(bucket);
else
m_MaterialBuckets.push_back(bucket);
@@ -195,3 +181,28 @@ void RAS_BucketManager::RAS_BucketManagerClearAll()
m_MaterialBuckets.clear();
m_AlphaBuckets.clear();
}
+
+void RAS_BucketManager::ReleaseDisplayLists()
+{
+ BucketList::iterator bit;
+ RAS_MaterialBucket::T_MeshSlotList::iterator mit;
+
+ for (bit = m_MaterialBuckets.begin(); bit != m_MaterialBuckets.end(); ++bit) {
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ if(mit->m_DisplayList) {
+ mit->m_DisplayList->Release();
+ mit->m_DisplayList = NULL;
+ }
+ }
+ }
+
+ for (bit = m_AlphaBuckets.begin(); bit != m_AlphaBuckets.end(); ++bit) {
+ for (mit = (*bit)->msBegin(); mit != (*bit)->msEnd(); ++mit) {
+ if(mit->m_DisplayList) {
+ mit->m_DisplayList->Release();
+ mit->m_DisplayList = NULL;
+ }
+ }
+ }
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_BucketManager.h b/source/gameengine/Rasterizer/RAS_BucketManager.h
index 010478b1d5b..08b67ed022f 100644
--- a/source/gameengine/Rasterizer/RAS_BucketManager.h
+++ b/source/gameengine/Rasterizer/RAS_BucketManager.h
@@ -58,8 +58,9 @@ public:
RAS_IRasterizer* rasty,
class RAS_IRenderTools* rendertools);
- RAS_MaterialBucket* RAS_BucketManagerFindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
+ RAS_MaterialBucket* FindBucket(RAS_IPolyMaterial * material, bool &bucketCreated);
+ void ReleaseDisplayLists();
private:
void RAS_BucketManagerClearAll();
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
index 31bdd8638c2..4ee06d96603 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.cpp
@@ -39,7 +39,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
int tilexrep,
int tileyrep,
int mode,
- bool transparant,
+ int transp,
+ bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
@@ -51,7 +52,8 @@ RAS_IPolyMaterial::RAS_IPolyMaterial(const STR_String& texname,
m_tilexrep(tilexrep),
m_tileyrep(tileyrep),
m_drawingmode (mode),
- m_transparant(transparant),
+ m_transp(transp),
+ m_alpha(alpha),
m_zsort(zsort),
m_lightlayer(lightlayer),
m_bIsTriangle(bIsTriangle),
@@ -74,6 +76,7 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_multimode == lhs.m_multimode &&
this->m_flag == lhs.m_flag &&
this->m_drawingmode == lhs.m_drawingmode &&
+ this->m_transp == lhs.m_transp &&
this->m_lightlayer == lhs.m_lightlayer &&
this->m_texturename.hash() == lhs.m_texturename.hash() &&
this->m_materialname.hash() == lhs.m_materialname.hash()
@@ -85,7 +88,8 @@ bool RAS_IPolyMaterial::Equals(const RAS_IPolyMaterial& lhs) const
this->m_tile == lhs.m_tile &&
this->m_tilexrep == lhs.m_tilexrep &&
this->m_tileyrep == lhs.m_tileyrep &&
- this->m_transparant == lhs.m_transparant &&
+ this->m_transp == lhs.m_transp &&
+ this->m_alpha == lhs.m_alpha &&
this->m_zsort == lhs.m_zsort &&
this->m_drawingmode == lhs.m_drawingmode &&
this->m_bIsTriangle == lhs.m_bIsTriangle &&
@@ -109,9 +113,9 @@ int RAS_IPolyMaterial::GetLightLayer() const
return m_lightlayer;
}
-bool RAS_IPolyMaterial::IsTransparant() const
+bool RAS_IPolyMaterial::IsAlpha() const
{
- return m_transparant;
+ return m_alpha || m_zsort;
}
bool RAS_IPolyMaterial::IsZSort() const
diff --git a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
index 6d90d260a23..8fc53e6b038 100644
--- a/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
+++ b/source/gameengine/Rasterizer/RAS_IPolygonMaterial.h
@@ -52,7 +52,7 @@ enum MaterialProps
RAS_AUTOGEN =128,
RAS_NORMAL =256,
RAS_DEFMULTI =512,
- RAS_FORCEALPHA =1024
+ RAS_BLENDERGLSL =1024
};
/**
@@ -67,7 +67,8 @@ protected:
int m_tile;
int m_tilexrep,m_tileyrep;
int m_drawingmode; // tface->mode
- bool m_transparant;
+ int m_transp;
+ bool m_alpha;
bool m_zsort;
int m_lightlayer;
bool m_bIsTriangle;
@@ -102,7 +103,8 @@ public:
int tilexrep,
int tileyrep,
int mode,
- bool transparant,
+ int transp,
+ bool alpha,
bool zsort,
int lightlayer,
bool bIsTriangle,
@@ -132,7 +134,7 @@ public:
virtual bool Equals(const RAS_IPolyMaterial& lhs) const;
bool Less(const RAS_IPolyMaterial& rhs) const;
int GetLightLayer() const;
- bool IsTransparant() const;
+ bool IsAlpha() const;
bool IsZSort() const;
bool UsesTriangles() const;
unsigned int hash() const;
diff --git a/source/gameengine/Rasterizer/RAS_IRasterizer.h b/source/gameengine/Rasterizer/RAS_IRasterizer.h
index d4a9177a85d..9e03212283e 100644
--- a/source/gameengine/Rasterizer/RAS_IRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_IRasterizer.h
@@ -372,10 +372,6 @@ public:
virtual void SetAmbientColor(float red, float green, float blue)=0;
virtual void SetAmbient(float factor)=0;
- /**
- * Sets alpha testing
- */
- virtual void SetAlphaTest(bool enable)=0;
/**
* Sets a polygon offset. z depth will be: z1 = mult*z0 + add
@@ -398,8 +394,10 @@ public:
virtual void DisableMotionBlur()=0;
virtual float GetMotionBlurValue()=0;
- virtual int GetMotionBlurState()=0;
- virtual void SetMotionBlurState(int newstate)=0;
+ virtual int GetMotionBlurState()=0;
+ virtual void SetMotionBlurState(int newstate)=0;
+
+ virtual void SetBlendingMode(int blendmode)=0;
};
#endif //__RAS_IRASTERIZER
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
index e295d69e48e..0015b6a251f 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.cpp
@@ -76,26 +76,11 @@ KX_MeshSlot::~KX_MeshSlot()
RAS_MaterialBucket::RAS_MaterialBucket(RAS_IPolyMaterial* mat)
:m_bModified(true)
{
- m_bScheduled=true;
m_material = mat;
}
-void RAS_MaterialBucket::SchedulePolygons(int drawingmode)
-{
- m_bScheduled = true;
-}
-
-
-
-void RAS_MaterialBucket::ClearScheduledPolygons()
-{
- m_bScheduled = false;
-}
-
-
-
RAS_IPolyMaterial* RAS_MaterialBucket::GetPolyMaterial() const
{
return m_material;
@@ -134,9 +119,14 @@ void RAS_MaterialBucket::MarkVisibleMeshSlot(KX_MeshSlot& ms,
(*it).m_RGBAcolor= rgbavec;
}
-bool RAS_MaterialBucket::IsTransparant() const
+bool RAS_MaterialBucket::IsAlpha() const
+{
+ return (m_material->IsAlpha());
+}
+
+bool RAS_MaterialBucket::IsZSort() const
{
- return (m_material->IsTransparant());
+ return (m_material->IsZSort());
}
diff --git a/source/gameengine/Rasterizer/RAS_MaterialBucket.h b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
index 13d8a53714a..4eef889c533 100644
--- a/source/gameengine/Rasterizer/RAS_MaterialBucket.h
+++ b/source/gameengine/Rasterizer/RAS_MaterialBucket.h
@@ -125,11 +125,9 @@ public:
class RAS_IRasterizer* rasty,
class RAS_IRenderTools* rendertools);
- void SchedulePolygons(int drawingmode);
- void ClearScheduledPolygons();
-
RAS_IPolyMaterial* GetPolyMaterial() const;
- bool IsTransparant() const;
+ bool IsAlpha() const;
+ bool IsZSort() const;
static void StartFrame();
static void EndFrame();
@@ -162,7 +160,6 @@ public:
private:
T_MeshSlotList m_meshSlots;
- bool m_bScheduled;
bool m_bModified;
RAS_IPolyMaterial* m_material;
double* m_pOGLMatrix;
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.cpp b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
index 5087f62500e..9c0460aad2d 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.cpp
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.cpp
@@ -203,7 +203,6 @@ void RAS_MeshObject::DebugColor(unsigned int abgr)
void RAS_MeshObject::SetVertexColor(RAS_IPolyMaterial* mat,MT_Vector4 rgba)
{
- RAS_TexVert* vertex = NULL;
const vecVertexArray & vertexvec = GetVertexCache(mat);
for (vector<KX_VertexArray*>::const_iterator it = vertexvec.begin(); it != vertexvec.end(); ++it)
@@ -220,22 +219,17 @@ void RAS_MeshObject::SchedulePoly(const KX_VertexIndex& idx,
int numverts,
RAS_IPolyMaterial* mat)
{
- //int indexpos = m_IndexArrayCount[idx.m_vtxarray];
- //m_IndexArrayCount[idx.m_vtxarray] = indexpos + 3;
-
KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[0]);
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[1]);
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[2]);
- if (!mat->UsesTriangles()) //if (!m_bUseTriangles)
- {
- //m_IndexArrayCount[idx.m_vtxarray] = indexpos+4;
+
+ if (!mat->UsesTriangles())
ao->m_IndexArrayCache1[idx.m_vtxarray]->push_back(idx.m_indexarray[3]);
- }
}
-
void RAS_MeshObject::ScheduleWireframePoly(const KX_VertexIndex& idx,
int numverts,
int edgecode,
@@ -422,7 +416,6 @@ void RAS_MeshObject::Bucketize(double* oglmatrix,
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
- bucket->SchedulePolygons(0);
// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
bucket->SetMeshSlot(ms);
}
@@ -447,7 +440,6 @@ void RAS_MeshObject::MarkVisible(double* oglmatrix,
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
RAS_MaterialBucket* bucket = *it;
- bucket->SchedulePolygons(0);
// KX_ArrayOptimizer* oa = GetArrayOptimizer(bucket->GetPolyMaterial());
bucket->MarkVisibleMeshSlot(ms,visible,useObjectColor,rgbavec);
}
@@ -466,7 +458,6 @@ void RAS_MeshObject::RemoveFromBuckets(double* oglmatrix,
{
RAS_MaterialBucket* bucket = *it;
// RAS_IPolyMaterial* polymat = bucket->GetPolyMaterial();
- bucket->SchedulePolygons(0);
//KX_ArrayOptimizer* oa = GetArrayOptimizer(polymat);
bucket->RemoveMeshSlot(ms);
}
@@ -585,31 +576,36 @@ void RAS_MeshObject::UpdateMaterialList()
struct RAS_MeshObject::polygonSlot
{
- float m_z;
- RAS_Polygon *m_poly;
-
- polygonSlot(float z, RAS_Polygon* poly) :
- m_z(z),
- m_poly(poly)
- {}
- /**
- * pnorm and pval form the plane equation that the distance from is used to
- * sort against.
- */
- polygonSlot(const MT_Vector3 &pnorm, const MT_Scalar &pval, RAS_MeshObject *mesh, RAS_Polygon* poly) :
- m_poly(poly)
+ float m_z;
+ int m_index[4];
+
+ polygonSlot() {}
+
+ /* pnorm is the normal from the plane equation that the distance from is
+ * used to sort again. */
+ void get(const KX_VertexArray& vertexarray, const KX_IndexArray& indexarray,
+ int offset, int nvert, const MT_Vector3& pnorm)
{
- const KX_VertexIndex &base = m_poly->GetIndexBase();
- RAS_TexVert *vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[0], poly->GetMaterial()->GetPolyMaterial());
- m_z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
-
- for(int i = 1; i < m_poly->VertexCount(); i++)
- {
- vert = mesh->GetVertex(base.m_vtxarray, base.m_indexarray[i], poly->GetMaterial()->GetPolyMaterial());
- float z = MT_dot(pnorm, vert->getLocalXYZ()) + pval;
- m_z += z;
+ MT_Vector3 center(0, 0, 0);
+ int i;
+
+ for(i=0; i<nvert; i++) {
+ m_index[i] = indexarray[offset+i];
+ center += vertexarray[m_index[i]].getLocalXYZ();
}
- m_z /= m_poly->VertexCount();
+
+ /* note we don't divide center by the number of vertices, since all
+ * polygons have the same number of vertices, and that we leave out
+ * the 4-th component of the plane equation since it is constant. */
+ m_z = MT_dot(pnorm, center);
+ }
+
+ void set(KX_IndexArray& indexarray, int offset, int nvert)
+ {
+ int i;
+
+ for(i=0; i<nvert; i++)
+ indexarray[offset+i] = m_index[i];
}
};
@@ -629,100 +625,100 @@ struct RAS_MeshObject::fronttoback
}
};
-
void RAS_MeshObject::SortPolygons(const MT_Transform &transform)
{
+ // Limitations: sorting is quite simple, and handles many
+ // cases wrong, partially due to polygons being sorted per
+ // bucket.
+ //
+ // a) mixed triangles/quads are sorted wrong
+ // b) mixed materials are sorted wrong
+ // c) more than 65k faces are sorted wrong
+ // d) intersecting objects are sorted wrong
+ // e) intersecting polygons are sorted wrong
+ //
+ // a) can be solved by making all faces either triangles or quads
+ // if they need to be z-sorted. c) could be solved by allowing
+ // larger buckets, b) and d) cannot be solved easily if we want
+ // to avoid excessive state changes while drawing. e) would
+ // require splitting polygons.
+
if (!m_zsort)
return;
-
+
// Extract camera Z plane...
const MT_Vector3 pnorm(transform.getBasis()[2]);
- const MT_Scalar pval = transform.getOrigin()[2];
-
- unsigned int numpolys = m_Polygons.size();
- std::multiset<polygonSlot, backtofront> alphapolyset;
- std::multiset<polygonSlot, fronttoback> solidpolyset;
-
- for (unsigned int p = 0; p < numpolys; p++)
- {
- RAS_Polygon* poly = m_Polygons[p];
- if (poly->IsVisible())
- {
- if (poly->GetMaterial()->GetPolyMaterial()->IsTransparant())
- {
- alphapolyset.insert(polygonSlot(pnorm, pval, this, poly));
- } else {
- solidpolyset.insert(polygonSlot(pnorm, pval, this, poly));
- }
- }
- }
-
- // Clear current array data.
+ // unneeded: const MT_Scalar pval = transform.getOrigin()[2];
+
for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
{
- vector<KX_IndexArray*> *indexcache = &GetArrayOptimizer((*it)->GetPolyMaterial())->m_IndexArrayCache1;
- for (vector<KX_IndexArray*>::iterator iit = indexcache->begin(); iit != indexcache->end(); ++iit)
- (*iit)->clear();
- }
+ if(!(*it)->IsZSort())
+ continue;
- std::multiset<polygonSlot, fronttoback>::iterator sit = solidpolyset.begin();
- for (; sit != solidpolyset.end(); ++sit)
- SchedulePoly((*sit).m_poly->GetVertexIndexBase(), (*sit).m_poly->VertexCount(), (*sit).m_poly->GetMaterial()->GetPolyMaterial());
-
- std::multiset<polygonSlot, backtofront>::iterator ait = alphapolyset.begin();
- for (; ait != alphapolyset.end(); ++ait)
- SchedulePoly((*ait).m_poly->GetVertexIndexBase(), (*ait).m_poly->VertexCount(), (*ait).m_poly->GetMaterial()->GetPolyMaterial());
+ RAS_IPolyMaterial *mat = (*it)->GetPolyMaterial();
+ KX_ArrayOptimizer* ao = GetArrayOptimizer(mat);
+
+ vecIndexArrays& indexarrays = ao->m_IndexArrayCache1;
+ vecVertexArray& vertexarrays = ao->m_VertexArrayCache1;
+ unsigned int i, j, nvert = (mat->UsesTriangles())? 3: 4;
+
+ for(i=0; i<indexarrays.size(); i++) {
+ KX_IndexArray& indexarray = *indexarrays[i];
+ KX_VertexArray& vertexarray = *vertexarrays[i];
+
+ unsigned int totpoly = indexarray.size()/nvert;
+ vector<polygonSlot> slots(totpoly);
+
+ /* get indices and z into temporary array */
+ for(j=0; j<totpoly; j++)
+ slots[j].get(vertexarray, indexarray, j*nvert, nvert, pnorm);
+
+ /* sort (stable_sort might be better, if flickering happens?) */
+ sort(slots.begin(), slots.end(), backtofront());
+
+ /* get indices from temporary array again */
+ for(j=0; j<totpoly; j++)
+ slots[j].set(indexarray, j*nvert, nvert);
+ }
+ }
}
-void RAS_MeshObject::SchedulePolygons(const MT_Transform &transform, int drawingmode)
+void RAS_MeshObject::SchedulePolygons(int drawingmode)
{
-// int nummaterials = m_materials.size();
- int i;
-
if (m_bModified)
{
- for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
- {
- RAS_MaterialBucket* bucket = *it;
+ int i, numpolys = m_Polygons.size();
- bucket->SchedulePolygons(drawingmode);
- if (bucket->GetPolyMaterial()->IsZSort())
+ for (RAS_MaterialBucket::Set::iterator it = m_materials.begin();it!=m_materials.end();++it)
+ if ((*it)->IsZSort())
m_zsort = true;
- }
-
- int numpolys = m_Polygons.size();
- if ((drawingmode > RAS_IRasterizer::KX_BOUNDINGBOX) &&
- (drawingmode < RAS_IRasterizer::KX_SOLID))
+ if (drawingmode == RAS_IRasterizer::KX_WIREFRAME)
{
for (i=0;i<numpolys;i++)
{
RAS_Polygon* poly = m_Polygons[i];
if (poly->IsVisible())
- ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode()
- ,poly->GetMaterial()->GetPolyMaterial());
+ ScheduleWireframePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetEdgeCode(),
+ poly->GetMaterial()->GetPolyMaterial());
}
m_zsort = false;
}
else
{
- if (!m_zsort)
+ for (i=0;i<numpolys;i++)
{
- for (i=0;i<numpolys;i++)
- {
- RAS_Polygon* poly = m_Polygons[i];
- if (poly->IsVisible())
- {
- SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),poly->GetMaterial()->GetPolyMaterial());
- }
- }
+ RAS_Polygon* poly = m_Polygons[i];
+ if (poly->IsVisible())
+ SchedulePoly(poly->GetVertexIndexBase(),poly->VertexCount(),
+ poly->GetMaterial()->GetPolyMaterial());
}
}
m_bModified = false;
-
m_MeshMod = true;
}
}
+
diff --git a/source/gameengine/Rasterizer/RAS_MeshObject.h b/source/gameengine/Rasterizer/RAS_MeshObject.h
index 44ad508d1e8..99806666fa6 100644
--- a/source/gameengine/Rasterizer/RAS_MeshObject.h
+++ b/source/gameengine/Rasterizer/RAS_MeshObject.h
@@ -137,6 +137,18 @@ class RAS_MeshObject
struct backtofront;
struct fronttoback;
+ void SchedulePoly(
+ const KX_VertexIndex& idx,
+ int numverts,
+ RAS_IPolyMaterial* mat
+ );
+
+ void ScheduleWireframePoly(
+ const KX_VertexIndex& idx,
+ int numverts,
+ int edgecode,
+ RAS_IPolyMaterial* mat
+ );
protected:
enum { BUCKET_MAX_INDICES = 65535 };//2048};//8192};
@@ -196,10 +208,7 @@ public:
*/
void SortPolygons(const MT_Transform &transform);
- void SchedulePolygons(
- const MT_Transform &transform,
- int drawingmode
- );
+ void SchedulePolygons(int drawingmode);
void ClearArrayData();
@@ -216,19 +225,7 @@ public:
int numverts,
RAS_IPolyMaterial* polymat
);
-
- void SchedulePoly(
- const KX_VertexIndex& idx,
- int numverts,
- RAS_IPolyMaterial* mat
- );
- void ScheduleWireframePoly(
- const KX_VertexIndex& idx,
- int numverts,
- int edgecode,
- RAS_IPolyMaterial* mat
- );
// find (and share) or add vertices
// for some speedup, only the last 20 added vertices are searched for equality
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
index dcc36bf5a39..1dcc6e70934 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.cpp
@@ -67,6 +67,7 @@ RAS_OpenGLRasterizer::RAS_OpenGLRasterizer(RAS_ICanvas* canvas)
m_motionblurvalue(-1.0),
m_texco_num(0),
m_attrib_num(0),
+ m_last_blendmode(0),
m_materialCachingInfo(0)
{
m_viewmatrix.Identity();
@@ -171,6 +172,8 @@ bool RAS_OpenGLRasterizer::Init()
m_ambg = 0.0f;
m_ambb = 0.0f;
+ SetBlendingMode(0);
+
glClearColor(m_redback,m_greenback,m_blueback,m_alphaback);
glColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
@@ -189,18 +192,6 @@ void RAS_OpenGLRasterizer::SetAmbientColor(float red, float green, float blue)
}
-void RAS_OpenGLRasterizer::SetAlphaTest(bool enable)
-{
- if (enable)
- {
- glEnable(GL_ALPHA_TEST);
- glAlphaFunc(GL_GREATER, 0.6f);
- }
- else glDisable(GL_ALPHA_TEST);
-}
-
-
-
void RAS_OpenGLRasterizer::SetAmbient(float factor)
{
float ambient[] = { m_ambr*factor, m_ambg*factor, m_ambb*factor, 1.0f };
@@ -353,6 +344,8 @@ bool RAS_OpenGLRasterizer::BeginFrame(int drawingmode, double time)
glEnable (GL_CULL_FACE);
}
+ SetBlendingMode(0);
+
glShadeModel(GL_SMOOTH);
m_2DCanvas->BeginFrame();
@@ -1389,3 +1382,34 @@ void RAS_OpenGLRasterizer::DisableMotionBlur()
m_motionblur = 0;
m_motionblurvalue = -1.0;
}
+
+void RAS_OpenGLRasterizer::SetBlendingMode(int blendmode)
+{
+ if(blendmode == m_last_blendmode)
+ return;
+
+ if(blendmode == 0) {
+ glDisable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ }
+ else if(blendmode == 1) {
+ glBlendFunc(GL_ONE, GL_ONE);
+ glEnable(GL_BLEND);
+ glDisable(GL_ALPHA_TEST);
+ }
+ else if(blendmode == 2) {
+ glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+ glEnable(GL_BLEND);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.0f);
+ }
+ else if(blendmode == 4) {
+ glDisable(GL_BLEND);
+ glEnable(GL_ALPHA_TEST);
+ glAlphaFunc(GL_GREATER, 0.5f);
+ }
+
+ m_last_blendmode = blendmode;
+}
+
diff --git a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
index 0d54552db05..02056cce446 100644
--- a/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
+++ b/source/gameengine/Rasterizer/RAS_OpenGLRasterizer/RAS_OpenGLRasterizer.h
@@ -99,6 +99,7 @@ protected:
TexCoGen m_attrib[RAS_MAX_ATTRIB];
int m_texco_num;
int m_attrib_num;
+ int m_last_blendmode;
/** Stores the caching information for the last material activated. */
RAS_IPolyMaterial::TCachingInfo m_materialCachingInfo;
@@ -142,8 +143,6 @@ public:
virtual void SetFocalLength(const float focallength);
virtual float GetFocalLength();
- virtual void SetAlphaTest(bool enable);
-
virtual void SwapBuffers();
virtual void IndexPrimitives(
const vecVertexArray& vertexarrays,
@@ -282,8 +281,8 @@ public:
virtual void EnableMotionBlur(float motionblurvalue);
virtual void DisableMotionBlur();
virtual float GetMotionBlurValue(){return m_motionblurvalue;};
- virtual int GetMotionBlurState(){return m_motionblur;};
- virtual void SetMotionBlurState(int newstate)
+ virtual int GetMotionBlurState(){return m_motionblur;};
+ virtual void SetMotionBlurState(int newstate)
{
if(newstate<0)
m_motionblur = 0;
@@ -292,6 +291,8 @@ public:
else
m_motionblur = newstate;
};
+
+ virtual void SetBlendingMode(int blendmode);
};
#endif //__RAS_OPENGLRASTERIZER
diff --git a/source/gameengine/Rasterizer/RAS_Polygon.cpp b/source/gameengine/Rasterizer/RAS_Polygon.cpp
index 852c94def3f..b74cb9cfcac 100644
--- a/source/gameengine/Rasterizer/RAS_Polygon.cpp
+++ b/source/gameengine/Rasterizer/RAS_Polygon.cpp
@@ -37,24 +37,6 @@
#include "RAS_Polygon.h"
-/*
-RAS_TexVert* RAS_Polygon::GetVertex(int index)
-{
- if (m_bucket)
- return m_bucket->GetVertex(m_vertexindexbase.m_vtxarray, m_vertexindexbase.m_indexarray[index]);
- else
- return NULL;
-}
-*/
-
-/*void RAS_Polygon::Bucketize(double* oglmatrix)
-{
- //Transform(trans);
- if (m_bucket)
- m_bucket->AddPolygon(this,oglmatrix);
-}
-*/
-
RAS_Polygon::RAS_Polygon(RAS_MaterialBucket* bucket,
bool visible,
int numverts,