summaryrefslogtreecommitdiff
path: root/indra/newview/lldrawpool.cpp
diff options
context:
space:
mode:
authorSteven Bennetts <steve@lindenlab.com>2007-03-02 21:25:50 +0000
committerSteven Bennetts <steve@lindenlab.com>2007-03-02 21:25:50 +0000
commit4dabd9c0472deb49573fdafef2fa413e59703f19 (patch)
tree06c680d6a2047e03838d6548bccd26c7baf9d652 /indra/newview/lldrawpool.cpp
parentd4462963c6ba5db2088723bbedc7b60f1184c594 (diff)
merge release@58699 beta-1-14-0@58707 -> release
Diffstat (limited to 'indra/newview/lldrawpool.cpp')
-rw-r--r--indra/newview/lldrawpool.cpp1261
1 files changed, 221 insertions, 1040 deletions
diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp
index 899d49f380..9ab6c700ab 100644
--- a/indra/newview/lldrawpool.cpp
+++ b/indra/newview/lldrawpool.cpp
@@ -13,7 +13,6 @@
#include "llfasttimer.h"
#include "llviewercontrol.h"
-#include "llagparray.h"
#include "lldrawable.h"
#include "lldrawpoolalpha.h"
#include "lldrawpoolavatar.h"
@@ -24,53 +23,38 @@
#include "lldrawpoolsky.h"
#include "lldrawpoolstars.h"
#include "lldrawpooltree.h"
-#include "lldrawpooltreenew.h"
#include "lldrawpoolterrain.h"
#include "lldrawpoolwater.h"
-#include "lldrawpoolhud.h"
#include "llface.h"
#include "llviewerobjectlist.h" // For debug listing.
-#include "llvotreenew.h"
#include "pipeline.h"
-#include "llagparray.inl"
-
-U32 LLDrawPool::sDataSizes[LLDrawPool::DATA_MAX_TYPES] =
-{
- 12, // DATA_VERTICES
- 8, // DATA_TEX_COORDS0
- 8, // DATA_TEX_COORDS1
- 8, // DATA_TEX_COORDS2
- 8, // DATA_TEX_COORDS3
- 12, // DATA_NORMALS
- 4, // DATA_VERTEX_WEIGHTS,
- 16, // DATA_CLOTHING_WEIGHTS
- 12, // DATA_BINORMALS
- 4, // DATA_COLORS
-};
-
S32 LLDrawPool::sNumDrawPools = 0;
+
+//=============================
+// Draw Pool Implementation
+//=============================
LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
{
LLDrawPool *poolp = NULL;
switch (type)
{
case POOL_SIMPLE:
- poolp = new LLDrawPoolSimple(tex0);
+ poolp = new LLDrawPoolSimple();
break;
case POOL_ALPHA:
poolp = new LLDrawPoolAlpha();
break;
+ case POOL_ALPHA_POST_WATER:
+ poolp = new LLDrawPoolAlphaPostWater();
+ break;
case POOL_AVATAR:
poolp = new LLDrawPoolAvatar();
break;
case POOL_TREE:
poolp = new LLDrawPoolTree(tex0);
break;
- case POOL_TREE_NEW:
- poolp = new LLDrawPoolTreeNew(tex0);
- break;
case POOL_TERRAIN:
poolp = new LLDrawPoolTerrain(tex0);
break;
@@ -80,9 +64,6 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
case POOL_STARS:
poolp = new LLDrawPoolStars();
break;
- case POOL_CLOUDS:
- poolp = new LLDrawPoolClouds();
- break;
case POOL_WATER:
poolp = new LLDrawPoolWater();
break;
@@ -90,10 +71,7 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
poolp = new LLDrawPoolGround();
break;
case POOL_BUMP:
- poolp = new LLDrawPoolBump(tex0);
- break;
- case POOL_HUD:
- poolp = new LLDrawPoolHUD();
+ poolp = new LLDrawPoolBump();
break;
default:
llerrs << "Unknown draw pool type!" << llendl;
@@ -104,183 +82,86 @@ LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
return poolp;
}
-LLDrawPool::LLDrawPool(const U32 type, const U32 data_mask_il, const U32 data_mask_nil)
+LLDrawPool::LLDrawPool(const U32 type)
{
- llassert(data_mask_il & DATA_VERTICES_MASK);
- S32 i;
mType = type;
sNumDrawPools++;
mId = sNumDrawPools;
-
- mDataMaskIL = data_mask_il;
- mDataMaskNIL = data_mask_nil;
-
- U32 cur_mask = 0x01;
- U32 cur_offset = 0;
- for (i = 0; i < DATA_MAX_TYPES; i++)
- {
- mDataOffsets[i] = cur_offset;
- if (cur_mask & mDataMaskIL)
- {
- cur_offset += sDataSizes[i];
- }
- cur_mask <<= 1;
- }
-
- mStride = cur_offset;
-
- mCleanupUnused = FALSE;
+ mVertexShaderLevel = 0;
mIndicesDrawn = 0;
- mRebuildFreq = 128 + rand() % 5;
- mRebuildTime = 0;
- mGeneration = 1;
- mSkippedVertices = 0;
-
- resetDrawOrders();
- resetVertexData(0);
-
- if (gGLManager.mHasATIVAO && !gGLManager.mIsRadeon9700)
- {
- // ATI 8500 doesn't like indices > 15 bit.
- mMaxVertices = DEFAULT_MAX_VERTICES/2;
- }
- else
- {
- mMaxVertices = DEFAULT_MAX_VERTICES;
- }
+}
- // JC: This must happen last, as setUseAGP reads many of the
- // above variables.
- mUseAGP = FALSE;
- setUseAGP(gPipeline.usingAGP());
+LLDrawPool::~LLDrawPool()
+{
- for (i=0; i<NUM_BUCKETS; i++)
- {
- mFreeListGeomHead[i] = -1;
- mFreeListIndHead[i] = -1;
- }
- mVertexShaderLevel = 0;
}
-void LLDrawPool::destroy()
+LLViewerImage *LLDrawPool::getDebugTexture()
{
- if (!mReferences.empty())
- {
- llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
- }
+ return NULL;
}
-
-LLDrawPool::~LLDrawPool()
+//virtual
+void LLDrawPool::beginRenderPass( S32 pass )
{
- destroy();
-
- llassert( gPipeline.findPool( getType(), getTexture() ) == NULL );
}
-BOOL LLDrawPool::setUseAGP(BOOL use_agp)
+//virtual
+void LLDrawPool::endRenderPass( S32 pass )
{
- BOOL ok = TRUE;
- S32 vertex_count = mMemory.count() / mStride;
- if (vertex_count > mMaxVertices && use_agp)
- {
-#ifdef DEBUG_AGP
- llwarns << "Allocating " << vertex_count << " vertices in pool type " << getType() << ", disabling AGP!" << llendl
-#endif
- use_agp = FALSE;
- ok = FALSE;
- }
-
- if (mUseAGP != use_agp)
- {
- mUseAGP = use_agp;
-
- BOOL ok = TRUE;
- ok &= mMemory.setUseAGP(use_agp);
-
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
- {
- ok &= mWeights.setUseAGP(use_agp);
- }
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
- {
- ok &= mClothingWeights.setUseAGP(use_agp);
- }
-
- if (!ok)
- {
- // Disable AGP if any one of these doesn't have AGP, we don't want to try
- // mixing AGP and non-agp arrays in a single pool.
-#ifdef DEBUG_AGP
- llinfos << "Aborting using AGP because set failed on a mem block!" << llendl;
-#endif
- setUseAGP(FALSE);
- ok = FALSE;
- }
- }
- return ok;
+ glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
+ glDisableClientState ( GL_COLOR_ARRAY );
+ glDisableClientState ( GL_NORMAL_ARRAY );
}
-void LLDrawPool::flushAGP()
+U32 LLDrawPool::getTrianglesDrawn() const
{
- mMemory.flushAGP();
-
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
- {
- mWeights.flushAGP();
- }
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
- {
- mClothingWeights.flushAGP();
- }
+ return mIndicesDrawn / 3;
}
-void LLDrawPool::syncAGP()
+void LLDrawPool::resetTrianglesDrawn()
{
- if (!getVertexCount())
- {
- return;
- }
- setUseAGP(gPipeline.usingAGP());
+ mIndicesDrawn = 0;
+}
- BOOL all_agp_on = TRUE;
- mMemory.sync();
- all_agp_on &= mMemory.isAGP();
+void LLDrawPool::addIndicesDrawn(const U32 indices)
+{
+ mIndicesDrawn += indices;
+}
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
- {
- mWeights.sync();
- all_agp_on &= mWeights.isAGP();
- }
+//=============================
+// Face Pool Implementation
+//=============================
+LLFacePool::LLFacePool(const U32 type)
+: LLDrawPool(type)
+{
+ resetDrawOrders();
+}
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
- {
- mClothingWeights.sync();
- all_agp_on &= mClothingWeights.isAGP();
- }
+LLFacePool::~LLFacePool()
+{
+ destroy();
+}
- // Since sometimes AGP allocation is done during syncs, we need
- // to make sure that if AGP allocation fails, we fallback to non-agp.
- if (mUseAGP && !all_agp_on)
+void LLFacePool::destroy()
+{
+ if (!mReferences.empty())
{
-#ifdef DEBUG_AGP
- llinfos << "setUseAGP false because of AGP sync failure!" << llendl;
-#endif
- setUseAGP(FALSE);
+ llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
}
}
-void LLDrawPool::dirtyTexture(const LLViewerImage *imagep)
+void LLFacePool::dirtyTextures(const std::set<LLViewerImage*>& textures)
{
}
-BOOL LLDrawPool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
+BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
{
return TRUE;
}
// static
-S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array)
+S32 LLFacePool::drawLoop(face_array_t& face_list)
{
S32 res = 0;
if (!face_list.empty())
@@ -289,19 +170,15 @@ S32 LLDrawPool::drawLoop(face_array_t& face_list, const U32* index_array)
iter != face_list.end(); iter++)
{
LLFace *facep = *iter;
- if (facep->mSkipRender)
- {
- continue;
- }
- facep->enableLights();
- res += facep->renderIndexed(index_array);
+ //facep->enableLights();
+ res += facep->renderIndexed();
}
}
return res;
}
// static
-S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array, S32 stage)
+S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
{
S32 res = 0;
if (!face_list.empty())
@@ -310,117 +187,30 @@ S32 LLDrawPool::drawLoopSetTex(face_array_t& face_list, const U32* index_array,
iter != face_list.end(); iter++)
{
LLFace *facep = *iter;
- if (facep->mSkipRender)
- {
- continue;
- }
facep->bindTexture(stage);
facep->enableLights();
- res += facep->renderIndexed(index_array);
+ res += facep->renderIndexed();
}
}
return res;
}
-void LLDrawPool::drawLoop()
+void LLFacePool::drawLoop()
{
- const U32* index_array = getRawIndices();
if (!mDrawFace.empty())
{
- mIndicesDrawn += drawLoop(mDrawFace, index_array);
+ mIndicesDrawn += drawLoop(mDrawFace);
}
}
-BOOL LLDrawPool::getVertexStrider(LLStrider<LLVector3> &vertices, const U32 index)
-{
- llassert(mDataMaskIL & LLDrawPool::DATA_VERTICES_MASK);
- vertices = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride);
- vertices.setStride(mStride);
- return TRUE;
-}
-
-BOOL LLDrawPool::getTexCoordStrider(LLStrider<LLVector2> &tex_coords, const U32 index, const U32 pass)
-{
- llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass));
- tex_coords = (LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride);
- tex_coords.setStride(mStride);
- return TRUE;
-}
-
-
-BOOL LLDrawPool::getVertexWeightStrider(LLStrider<F32> &vertex_weights, const U32 index)
-{
- llassert(mDataMaskNIL & LLDrawPool::DATA_VERTEX_WEIGHTS_MASK);
-
- vertex_weights = &mWeights[index];
- vertex_weights.setStride( 0 );
- return TRUE;
-}
-
-BOOL LLDrawPool::getClothingWeightStrider(LLStrider<LLVector4> &clothing_weights, const U32 index)
-{
- llassert(mDataMaskNIL & LLDrawPool::DATA_CLOTHING_WEIGHTS_MASK);
-
- clothing_weights= &mClothingWeights[index];
- clothing_weights.setStride( 0 );
-
- return TRUE;
-}
-
-BOOL LLDrawPool::getNormalStrider(LLStrider<LLVector3> &normals, const U32 index)
-{
- llassert((mDataMaskIL) & LLDrawPool::DATA_NORMALS_MASK);
-
- normals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride);
-
- normals.setStride( mStride );
-
- return TRUE;
-}
-
-
-BOOL LLDrawPool::getBinormalStrider(LLStrider<LLVector3> &binormals, const U32 index)
-{
- llassert((mDataMaskIL) & LLDrawPool::DATA_BINORMALS_MASK);
-
- binormals = (LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride);
-
- binormals.setStride( mStride );
-
- return TRUE;
-}
-
-BOOL LLDrawPool::getColorStrider(LLStrider<LLColor4U> &colors, const U32 index)
-{
- llassert((mDataMaskIL) & LLDrawPool::DATA_COLORS_MASK);
-
- colors = (LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride);
-
- colors.setStride( mStride );
-
- return TRUE;
-}
-
-//virtual
-void LLDrawPool::beginRenderPass( S32 pass )
-{
-}
-
-//virtual
-void LLDrawPool::endRenderPass( S32 pass )
-{
- glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
- glDisableClientState ( GL_COLOR_ARRAY );
- glDisableClientState ( GL_NORMAL_ARRAY );
-}
-void LLDrawPool::renderFaceSelected(LLFace *facep,
+void LLFacePool::renderFaceSelected(LLFace *facep,
LLImageGL *image,
const LLColor4 &color,
const S32 index_offset, const S32 index_count)
{
}
-void LLDrawPool::renderVisibility()
+void LLFacePool::renderVisibility()
{
if (mDrawFace.empty())
{
@@ -506,893 +296,284 @@ void LLDrawPool::renderVisibility()
}
-void LLDrawPool::enqueue(LLFace* facep)
-{
- if (facep->isState(LLFace::BACKLIST))
- {
- mMoveFace.put(facep);
- }
- else
- {
-#if ENABLE_FACE_LINKING
- facep->mSkipRender = FALSE;
- facep->mNextFace = NULL;
-
- if (mDrawFace.size() > 0)
- {
- LLFace* last_face = mDrawFace[mDrawFace.size()-1];
- if (match(last_face, facep))
- {
- last_face->link(facep);
- }
- }
-#endif
- mDrawFace.put(facep);
- }
-}
-
-void LLDrawPool::bindGLVertexPointer()
-{
- mMemory.bindGLVertexPointer(getStride(DATA_VERTICES), mDataOffsets[DATA_VERTICES]);
-}
-
-void LLDrawPool::bindGLTexCoordPointer(const U32 pass)
-{
- mMemory.bindGLTexCoordPointer(getStride(DATA_TEX_COORDS0+pass), mDataOffsets[DATA_TEX_COORDS0+pass]);
-}
-
-void LLDrawPool::bindGLNormalPointer()
-{
- mMemory.bindGLNormalPointer(getStride(DATA_NORMALS), mDataOffsets[DATA_NORMALS]);
-}
-
-void LLDrawPool::bindGLBinormalPointer(S32 index)
-{
- mMemory.bindGLBinormalPointer(index, getStride(DATA_BINORMALS), mDataOffsets[DATA_BINORMALS]);
-}
-
-void LLDrawPool::bindGLColorPointer()
+void LLFacePool::enqueue(LLFace* facep)
{
- mMemory.bindGLColorPointer(getStride(DATA_COLORS), mDataOffsets[DATA_COLORS]);
+ mDrawFace.push_back(facep);
}
-void LLDrawPool::bindGLVertexWeightPointer(S32 index)
-{
- mWeights.bindGLVertexWeightPointer(index, 0, 0);
-}
-
-void LLDrawPool::bindGLVertexClothingWeightPointer(S32 index)
-{
- mClothingWeights.bindGLVertexClothingWeightPointer(index, 0, 0);
-}
-
-
-U32* LLDrawPool::getIndices(S32 index)
-{
- return &mIndices[index];
-}
-
-const LLVector3& LLDrawPool::getVertex(const S32 index)
-{
- llassert(mDataMaskIL & DATA_VERTICES_MASK);
- llassert(index < mMemory.count());
- llassert(mMemory.getMem());
- return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_VERTICES] + index * mStride);
-}
-
-const LLVector2& LLDrawPool::getTexCoord(const S32 index, const U32 pass)
+// virtual
+BOOL LLFacePool::addFace(LLFace *facep)
{
- llassert(mDataMaskIL & (LLDrawPool::DATA_TEX_COORDS0_MASK << pass));
- llassert(index < mMemory.count());
- return *(LLVector2*)(mMemory.getMem() + mDataOffsets[DATA_TEX_COORDS0 + pass] + index * mStride);
+ addFaceReference(facep);
+ return TRUE;
}
-const LLVector3& LLDrawPool::getNormal(const S32 index)
+// virtual
+BOOL LLFacePool::removeFace(LLFace *facep)
{
- llassert(mDataMaskIL & DATA_NORMALS_MASK);
- llassert(index < mMemory.count());
- return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_NORMALS] + index * mStride);
-}
+ removeFaceReference(facep);
-const LLVector3& LLDrawPool::getBinormal(const S32 index)
-{
- llassert(mDataMaskIL & DATA_BINORMALS_MASK);
- llassert(index < mMemory.count());
- return *(LLVector3*)(mMemory.getMem() + mDataOffsets[DATA_BINORMALS] + index * mStride);
-}
+ vector_replace_with_last(mDrawFace, facep);
-const LLColor4U& LLDrawPool::getColor(const S32 index)
-{
- llassert(mDataMaskIL & DATA_COLORS_MASK);
- llassert(index < mMemory.count());
- return *(LLColor4U*)(mMemory.getMem() + mDataOffsets[DATA_COLORS] + index * mStride);
+ return TRUE;
}
-const F32& LLDrawPool::getVertexWeight(const S32 index)
+// Not absolutely sure if we should be resetting all of the chained pools as well - djs
+void LLFacePool::resetDrawOrders()
{
- llassert(mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK);
- llassert(index < mWeights.count());
- llassert(mWeights.getMem());
- return mWeights[index];
+ mDrawFace.resize(0);
}
-const LLVector4& LLDrawPool::getClothingWeight(const S32 index)
+LLViewerImage *LLFacePool::getTexture()
{
- llassert(mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK);
- llassert(index < mClothingWeights.count());
- llassert(mClothingWeights.getMem());
- return mClothingWeights[index];
+ return NULL;
}
-//////////////////////////////////////////////////////////////////////////////
-
-#define USE_FREE_LIST 0
-#define DEBUG_FREELIST 0
-
-struct tFreeListNode
+void LLFacePool::removeFaceReference(LLFace *facep)
{
- U32 count;
- S32 next;
-};
-
-#if DEBUG_FREELIST
-static void check_list(U8 *pool, S32 stride, S32 head, S32 max)
-{
- int count = 0;
-
- while (head >= 0)
+ if (facep->getReferenceIndex() != -1)
{
- tFreeListNode *node = (tFreeListNode *)(pool + head*stride);
- count++;
- if ((count > max) || ((node->count>>20) != 0xabc) || ((node->count&0xfffff) < 2))
- llerrs << "Bad Ind List" << llendl;
- head = node->next;
+ if (facep->getReferenceIndex() != (S32)mReferences.size())
+ {
+ LLFace *back = mReferences.back();
+ mReferences[facep->getReferenceIndex()] = back;
+ back->setReferenceIndex(facep->getReferenceIndex());
+ }
+ mReferences.pop_back();
}
+ facep->setReferenceIndex(-1);
}
-#define CHECK_LIST(x) check_list##x
-#else
-#define CHECK_LIST(x)
-#endif
-// DEBUG!
-void LLDrawPool::CheckIntegrity()
+void LLFacePool::addFaceReference(LLFace *facep)
{
-#if DEBUG_FREELIST
- int bucket;
- for (bucket=0; bucket<NUM_BUCKETS; bucket++)
+ if (-1 == facep->getReferenceIndex())
{
- CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[bucket], mMemory.count() / mStride));
- CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[bucket], mIndices.count()));
+ facep->setReferenceIndex(mReferences.size());
+ mReferences.push_back(facep);
}
-#endif
}
-int LLDrawPool::freeListBucket(U32 count)
+BOOL LLFacePool::verify() const
{
- int bucket;
-
- // llassert(NUM_BUCKETS == 8)
+ BOOL ok = TRUE;
- if (count & ~511) // >= 512
- bucket = 7;
- else if (count & 256) // 256-511
- bucket = 6;
- else if (count & 128)
- bucket = 5;
- else if (count & 64)
- bucket = 4;
- else if (count & 32)
- bucket = 3;
- else if (count & 16)
- bucket = 2;
- else if (count & 8) // 8-15
- bucket = 1;
- else // 0-7
- bucket = 0;
- return bucket;
-}
-
-void remove_node(int nodeidx, int pidx, U8 *membase, int stride, int *head)
-{
- LLDrawPool::FreeListNode *node = (LLDrawPool::FreeListNode *)(membase + nodeidx*stride);
- if (pidx >= 0)
- {
- LLDrawPool::FreeListNode *pnode = (LLDrawPool::FreeListNode *)(membase + pidx*stride);
- pnode->next = node->next;
- }
- else
- {
- *head = node->next;
- }
-}
-
-void LLDrawPool::freeListAddGeom(S32 index, U32 count)
-{
-#if USE_FREE_LIST
- int i;
- U8 *membase = (U8*)mMemory.getMem();
- // See if next block or previous block is free, if so combine them
- for (i=0; i<NUM_BUCKETS; i++)
- {
- int pidx = -1;
- int nodeidx = mFreeListGeomHead[i];
- while(nodeidx >= 0)
- {
- int change = 0;
- FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride);
- int nodecount = node->count & 0xffff;
- // Check for prev block
- if (nodeidx + nodecount == index)
- {
- remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
- // Combine nodes
- index = nodeidx;
- count += nodecount;
- i = 0; // start over ; i = NUM_BUCKETS // done
- change = 1;
- //break;
- }
- // Check for next block
- if (nodeidx == index + count)
- {
- remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
- // Combine nodes
- count += nodecount;
- i = 0; // start over ; i = NUM_BUCKETS // done
- change = 1;
- //break;
- }
- if (change)
- break;
- pidx = nodeidx;
- nodeidx = node->next;
- }
- }
- // Add (extended) block to free list
- if (count >= 2) // need 2 words to store free list (theoreticly mStride could = 4)
+ for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
+ iter != mDrawFace.end(); iter++)
{
- CheckIntegrity();
- if ((index + count)*mStride >= mMemory.count())
+ const LLFace* facep = *iter;
+ if (facep->getPool() != this)
{
- mMemory.shrinkTo(index*mStride);
+ llinfos << "Face in wrong pool!" << llendl;
+ facep->printDebugInfo();
+ ok = FALSE;
}
- else
+ else if (!facep->verify())
{
- int bucket = freeListBucket(count);
- FreeListNode *node = (FreeListNode *)(membase + index*mStride);
- node->count = count | (0xabc<<20);
- node->next = mFreeListGeomHead[bucket];
- mFreeListGeomHead[bucket] = index;
+ ok = FALSE;
}
- CheckIntegrity();
}
-#endif
-}
-void LLDrawPool::freeListAddInd(S32 index, U32 count)
-{
-#if USE_FREE_LIST
- int i;
- const U32 *membase = mIndices.getMem();
- // See if next block or previous block is free, if so combine them
- for (i=0; i<NUM_BUCKETS; i++)
- {
- int pidx = -1;
- int nodeidx = mFreeListIndHead[i];
- while(nodeidx >= 0)
- {
- int change = 0;
- FreeListNode *node = (FreeListNode *)(membase + nodeidx);
- int nodecount = node->count & 0xffff;
- // Check for prev block
- if (nodeidx + nodecount == index)
- {
- remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
- // Combine nodes
- index = nodeidx;
- count += nodecount;
- i = 0; // start over ; i = NUM_BUCKETS // done
- change = 1;
- //break;
- }
- // Check for next block
- if (nodeidx == index + count)
- {
- remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
- // Combine nodes
- count += nodecount;
- i = 0; // start over ; i = NUM_BUCKETS // done
- change = 1;
- //break;
- }
- if (change)
- break;
- pidx = nodeidx;
- nodeidx = node->next;
- }
- }
- // Add (extended) block to free list
- if (count >= 2) // need 2 words to store free list
- {
- CheckIntegrity();
- if (index + count >= mIndices.count())
- {
- mIndices.shrinkTo(index);
- }
- else
- {
- int bucket = freeListBucket(count);
- FreeListNode *node = (FreeListNode *)(membase + index);
- node->count = count | (0xabc<<20);
- node->next = mFreeListIndHead[bucket];
- mFreeListIndHead[bucket] = index;
- }
- CheckIntegrity();
- }
-#endif
+ return ok;
}
-S32 LLDrawPool::freeListFindGeom(U32 count)
+void LLFacePool::printDebugInfo() const
{
-#if USE_FREE_LIST
- int i, nodeidx, pidx;
- int firstbucket = freeListBucket(count);
- U8 *membase = (U8*)mMemory.getMem();
- for (i=firstbucket; i<NUM_BUCKETS; i++)
- {
- pidx = -1;
- nodeidx = mFreeListGeomHead[i];
- CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[i], mMemory.count() / mStride));
- while(nodeidx >= 0)
- {
- FreeListNode *node = (FreeListNode *)(membase + nodeidx*mStride);
- int nodecount = node->count & 0xffff;
- llassert((node->count>>20) == 0xabc);
- if (nodecount >= count)
- {
- remove_node(nodeidx, pidx, membase, mStride, &mFreeListGeomHead[i]);
-#if 1
- if (nodecount > count)
- {
- int leftover = nodecount - count;
- freeListAddGeom(nodeidx + count, leftover);
- }
-#endif
- return nodeidx;
- }
- pidx = nodeidx;
- nodeidx = node->next;
- }
- }
-#endif // USE_FREE_LIST
- return -1;
+ llinfos << "Pool " << this << " Type: " << getType() << llendl;
}
-S32 LLDrawPool::freeListFindInd(U32 count)
+BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
+
+void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
{
-#if USE_FREE_LIST
- int i, nodeidx, pidx;
- int firstbucket = freeListBucket(count);
- U32 *membase = (U32 *)mIndices.getMem();
- for (i=firstbucket; i<NUM_BUCKETS; i++)
+ if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
{
- pidx = -1;
- nodeidx = mFreeListIndHead[i];
- CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[i], mIndices.count()));
- while(nodeidx >= 0)
- {
- FreeListNode *node = (FreeListNode *)(membase + nodeidx);
- int nodecount = node->count & 0xffff;
- llassert((node->count>>20) == 0xabc);
- if (nodecount >= count)
- {
- remove_node(nodeidx, pidx, (U8*)membase, 4, &mFreeListIndHead[i]);
-#if 1
- if (nodecount > count)
- {
- int leftover = nodecount - count;
- freeListAddInd(nodeidx + count, leftover);
- }
-#endif
- return nodeidx;
- }
- pidx = nodeidx;
- nodeidx = node->next;
- }
+ glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV);
}
-#endif // USE_FREE_LIST
- return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-S32 LLDrawPool::reserveGeom(const U32 geom_count)
-{
- LLFastTimer t(LLFastTimer::FTM_GEO_RESERVE);
-
- S32 index;
- index = freeListFindGeom(geom_count);
- if (index < 0)
+ else
{
- index = mMemory.count() / mStride;
- if (!geom_count)
- {
- llwarns << "Attempting to reserve zero bytes!" << llendl;
- return index;
- }
-
- S32 bytes = geom_count * mStride;
-
- if ((index + (S32)geom_count) > (S32)mMaxVertices)
- {
- //
- // Various drivers have issues with the number of indices being greater than a certain number.
- // if you're using AGP. Disable AGP if we've got more vertices than in the pool.
- //
-#ifdef DEBUG_AGP
- llinfos << "setUseAGP false because of large vertex count in reserveGeom" << llendl;
-#endif
- setUseAGP(FALSE);
- }
-
- mMemory.reserve_block(bytes);
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
- {
- mWeights.reserve_block(geom_count);
- }
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
- {
- mClothingWeights.reserve_block(geom_count);
- }
+ glColor4fv(color.mV);
}
- CHECK_LIST(((U8 *)mMemory.getMem(), mStride, mFreeListGeomHead[0], mMemory.count() / mStride));
- return index;
}
-S32 LLDrawPool::reserveInd(U32 indCount)
+void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
{
- S32 index;
- index = freeListFindInd(indCount);
- if (index < 0)
+ if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
{
- index = mIndices.count();
-
- if (indCount)
- {
- mIndices.reserve_block(indCount);
- }
+ glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV);
}
- for (U32 i=0;i<indCount;i++)
+ else
{
- mIndices[index+i]=0;
+ glColor4ubv(color.mV);
}
- CHECK_LIST(((U8 *)mIndices.getMem(), 4, mFreeListIndHead[0], mIndices.count()));
- return index;
}
-S32 LLDrawPool::unReserveGeom(const S32 index, const U32 count)
+void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
{
- if (index < 0 || count == 0)
- return -1;
-
- freeListAddGeom(index, count);
-
-#if 0
- int i;
- S32 bytes,words;
- U32 *memp;
- // Fill mem with bad data (for testing only)
- bytes = count * mStride;
- bytes -= sizeof(FreeListNode);
- memp = (U32*)(mMemory.getMem() + index * mStride);
- memp += sizeof(FreeListNode)>>2;
- words = bytes >> 2;
- for (i=0; i<words; i++)
- *memp++ = 0xffffffff;
-
- words = count; // (sizeof each array is a word)
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
+ if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
{
- memp = (U32*)(&mWeights[index]);
- for (i=0; i<words; i++)
- *memp++ = 0xffffffff;
+ glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a);
}
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
+ else
{
- memp = (U32*)(&mClothingWeights[index]);
- for (i=0; i<count; i++)
- *memp++ = 0xffffffff;
+ glColor4f(r,g,b,a);
}
-#endif
- return -1;
}
-S32 LLDrawPool::unReserveInd(const S32 index, const U32 count)
-{
- if (index < 0 || count == 0)
- return -1;
- freeListAddInd(index, count);
-
-#if 0
- int i;
- U32 *memp = &mIndices[index];
- for (i=0; i<count; i++)
- *memp++ = 0xffffffff;
-#endif
- return -1;
-}
-
-//////////////////////////////////////////////////////////////////////////////
-
-const U32 LLDrawPool::getIndexCount() const
+//=============================
+// Render Pass Implementation
+//=============================
+LLRenderPass::LLRenderPass(const U32 type)
+: LLDrawPool(type)
{
- return mIndices.count();
-}
-const U32 LLDrawPool::getVertexCount() const
-{
- return mMemory.count() / mStride;
}
-const U32 LLDrawPool::getTexCoordCount(U32 pass) const
+LLRenderPass::~LLRenderPass()
{
- return mMemory.count() / mStride;
-}
-
-const U32 LLDrawPool::getNormalCount() const
-{
- return mMemory.count() / mStride;
}
-
-const U32 LLDrawPool::getBinormalCount() const
+LLDrawPool* LLRenderPass::instancePool()
{
- return mMemory.count() / mStride;
-}
-
-const U32 LLDrawPool::getColorCount() const
-{
- return mMemory.count() / mStride;
-}
-
-const U32 LLDrawPool::getVertexWeightCount() const
-{
- return mWeights.count();
+#if LL_RELEASE_FOR_DOWNLOAD
+ llwarns << "Attempting to instance a render pass. Invalid operation." << llendl;
+#else
+ llerrs << "Attempting to instance a render pass. Invalid operation." << llendl;
+#endif
+ return NULL;
}
-// virtual
-BOOL LLDrawPool::addFace(LLFace *facep)
-{
- addFaceReference(facep);
- return TRUE;
+void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
+{
+ std::vector<LLDrawInfo*>& draw_info = group->mDrawMap[type];
+
+ for (std::vector<LLDrawInfo*>::const_iterator k = draw_info.begin(); k != draw_info.end(); ++k)
+ {
+ LLDrawInfo& params = **k;
+ pushBatch(params, mask, texture);
+ }
}
-// virtual
-BOOL LLDrawPool::removeFace(LLFace *facep)
+void LLRenderPass::renderInvisible(U32 mask)
{
- removeFaceReference(facep);
-
- vector_replace_with_last(mDrawFace, facep);
-
- facep->unReserve();
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLGLState::checkClientArrays(mask);
+#endif
- return TRUE;
-}
+ std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE];
-// Not absolutely sure if we should be resetting all of the chained pools as well - djs
-void LLDrawPool::resetDrawOrders()
-{
- mDrawFace.resize(0);
+ U32* indices_pointer = NULL;
+ for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i)
+ {
+ LLDrawInfo& params = **i;
+ params.mVertexBuffer->setBuffer(mask);
+ indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
+ glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
+ GL_UNSIGNED_INT, indices_pointer+params.mOffset);
+ gPipeline.mTrianglesDrawn += params.mCount/3;
+ }
}
-void LLDrawPool::resetIndices(S32 indices_count)
+void LLRenderPass::renderTexture(U32 type, U32 mask)
{
- mIndices.reset(indices_count);
- for (S32 i=0; i<NUM_BUCKETS; i++)
- mFreeListIndHead[i] = -1;
-}
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLGLState::checkClientArrays(mask);
+#endif
-void LLDrawPool::resetVertexData(S32 reserve_count)
-{
- mMemory.reset(reserve_count*mStride);
-
- for (S32 i=0; i<NUM_BUCKETS; i++)
- {
- mFreeListGeomHead[i] = -1;
- }
- if (mDataMaskNIL & DATA_VERTEX_WEIGHTS_MASK)
- {
- mWeights.reset(reserve_count);
- }
+ std::vector<LLDrawInfo*>& draw_info = gPipeline.mRenderMap[type];
- if (mDataMaskNIL & DATA_CLOTHING_WEIGHTS_MASK)
+ for (std::vector<LLDrawInfo*>::iterator i = draw_info.begin(); i != draw_info.end(); ++i)
{
- mClothingWeights.reset(reserve_count);
+ LLDrawInfo& params = **i;
+ pushBatch(params, mask, TRUE);
}
}
-void LLDrawPool::resetAll()
-{
- resetDrawOrders();
- resetVertexData(0);
- mGeneration++;
-
-}
-
-S32 LLDrawPool::rebuild()
+void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
{
- mRebuildTime++;
-
- BOOL needs_rebuild = FALSE;
- S32 rebuild_cost = 0;
-
- if (mUseAGP)
- {
- if (getVertexCount() > 0.75f*DEFAULT_MAX_VERTICES)
- {
- if (mRebuildTime > 8)
- {
- needs_rebuild = TRUE;
- }
-#ifdef DEBUG_AGP
- llwarns << "More than " << DEFAULT_MAX_VERTICES << " in pool type " << (S32)mType << " at rebuild!" << llendl;
-#endif
- }
- }
-
- // rebuild de-allocates 'stale' objects, so we still need to do a rebuild periodically
- if (mRebuildFreq > 0 && mRebuildTime >= mRebuildFreq)
+ if (params.mVertexBuffer.isNull())
{
- needs_rebuild = TRUE;
+ return;
}
- if (needs_rebuild)
+ if (texture)
{
- mGeneration++;
-
- if (mReferences.empty())
+ if (params.mTexture.notNull())
{
- resetIndices(0);
- resetVertexData(0);
- }
- else
- {
- for (std::vector<LLFace*>::iterator iter = mReferences.begin();
- iter != mReferences.end(); iter++)
- {
- LLFace *facep = *iter;
- if (facep->hasGeometry() && !facep->isState(LLFace::BACKLIST | LLFace::SHARED_GEOM))
- {
- facep->backup();
- }
- }
- S32 tot_verts = 0;
- S32 tot_indices = 0;
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *facep = *iter;
- if (facep->isState(LLFace::BACKLIST))
- {
- tot_verts += facep->getGeomCount();
- tot_indices += facep->getIndicesCount();
- }
- }
- for (std::vector<LLFace*>::iterator iter = mMoveFace.begin();
- iter != mMoveFace.end(); iter++)
+ params.mTexture->bind();
+ if (params.mTextureMatrix)
{
- LLFace *facep = *iter;
- if (facep->isState(LLFace::BACKLIST))
- {
- tot_verts += facep->getGeomCount();
- tot_indices += facep->getIndicesCount();
- }
- }
-
- resetIndices(tot_indices);
- flushAGP();
- resetVertexData(tot_verts);
-
- for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- LLFace *facep = *iter;
- llassert(facep->getPool() == this);
- facep->restore();
+ glMatrixMode(GL_TEXTURE);
+ glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
}
+ params.mTexture->addTextureStats(params.mVSize);
}
- mRebuildTime = 0;
- setDirty();
- }
-
- if (!mMoveFace.empty())
- {
- for (std::vector<LLFace*>::iterator iter = mMoveFace.begin();
- iter != mMoveFace.end(); iter++)
- {
- LLFace *facep = *iter;
- facep->restore();
- enqueue(facep);
- }
- setDirty();
- mMoveFace.reset();
- rebuild_cost++;
- }
- return rebuild_cost;
-}
-
-LLViewerImage *LLDrawPool::getTexture()
-{
- return NULL;
-}
-
-LLViewerImage *LLDrawPool::getDebugTexture()
-{
- return NULL;
-}
-
-void LLDrawPool::removeFaceReference(LLFace *facep)
-{
- if (facep->getReferenceIndex() != -1)
- {
- if (facep->getReferenceIndex() != (S32)mReferences.size())
+ else
{
- LLFace *back = mReferences.back();
- mReferences[facep->getReferenceIndex()] = back;
- back->setReferenceIndex(facep->getReferenceIndex());
+ LLImageGL::unbindTexture(0);
}
- mReferences.pop_back();
}
- facep->setReferenceIndex(-1);
-}
+
+ params.mVertexBuffer->setBuffer(mask);
+ U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
+ glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
+ GL_UNSIGNED_INT, indices_pointer+params.mOffset);
+ gPipeline.mTrianglesDrawn += params.mCount/3;
-void LLDrawPool::addFaceReference(LLFace *facep)
-{
- if (-1 == facep->getReferenceIndex())
+ if (params.mTextureMatrix && texture && params.mTexture.notNull())
{
- facep->setReferenceIndex(mReferences.size());
- mReferences.push_back(facep);
+ glLoadIdentity();
+ glMatrixMode(GL_MODELVIEW);
}
}
-U32 LLDrawPool::getTrianglesDrawn() const
+void LLRenderPass::renderActive(U32 type, U32 mask, BOOL texture)
{
- return mIndicesDrawn / 3;
-}
-
-void LLDrawPool::resetTrianglesDrawn()
-{
- mIndicesDrawn = 0;
-}
-
-void LLDrawPool::addIndicesDrawn(const U32 indices)
-{
- mIndicesDrawn += indices;
-}
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLGLState::checkClientArrays(mask);
+#endif
-BOOL LLDrawPool::verify() const
-{
- BOOL ok = TRUE;
- // Verify all indices in the pool are in the right range
- const U32 *indicesp = getRawIndices();
- for (U32 i = 0; i < getIndexCount(); i++)
+ LLSpatialBridge* last_bridge = NULL;
+ glPushMatrix();
+
+ for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i)
{
- if (indicesp[i] > getVertexCount())
+ LLSpatialGroup* group = *i;
+ if (!group->isDead() &&
+ gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
+ group->mDrawMap.find(type) != group->mDrawMap.end())
{
- ok = FALSE;
- llinfos << "Bad index in tree pool!" << llendl;
- }
- }
+ LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition;
+ if (bridge != last_bridge)
+ {
+ glPopMatrix();
+ glPushMatrix();
+ glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
+ last_bridge = bridge;
+ }
- for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
- iter != mDrawFace.end(); iter++)
- {
- const LLFace* facep = *iter;
- if (facep->getPool() != this)
- {
- llinfos << "Face in wrong pool!" << llendl;
- facep->printDebugInfo();
- ok = FALSE;
- }
- else if (!facep->verify())
- {
- ok = FALSE;
+ renderGroup(group,type,mask,texture);
}
}
-
- return ok;
-}
-
-void LLDrawPool::printDebugInfo() const
-{
- llinfos << "Pool " << this << " Type: " << getType() << llendl;
- llinfos << "--------------------" << llendl;
- llinfos << "Vertex count: " << getVertexCount() << llendl;
- llinfos << "Normal count: " << getNormalCount() << llendl;
- llinfos << "Indices count: " << getIndexCount() << llendl;
- llinfos << llendl;
-}
-
-
-S32 LLDrawPool::getMemUsage(const BOOL print)
-{
- S32 mem_usage = 0;
-
- mem_usage += sizeof(this);
-
- // Usage beyond the pipeline allocated data (color and mMemory)
- mem_usage += mIndices.getMax() * sizeof(U32);
- mem_usage += mDrawFace.capacity() * sizeof(LLFace *);
- mem_usage += mMoveFace.capacity() * sizeof(LLFace *);
- mem_usage += mReferences.capacity() * sizeof(LLFace *);
-
- mem_usage += mMemory.getSysMemUsage();
- mem_usage += mWeights.getSysMemUsage();
- mem_usage += mClothingWeights.getSysMemUsage();
-
- return mem_usage;
-}
-
-LLColor3 LLDrawPool::getDebugColor() const
-{
- return LLColor3(0.f, 0.f, 0.f);
-}
-
-void LLDrawPool::setDirty()
-{
- mMemory.setDirty();
- mWeights.setDirty();
- mClothingWeights.setDirty();
-}
-
-BOOL LLDrawPool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
-
-void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4& color)
-{
- if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0)
- {
- glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV);
- }
- else
- {
- glColor4fv(color.mV);
- }
+
+ glPopMatrix();
}
-void LLDrawPool::LLOverrideFaceColor::setColor(const LLColor4U& color)
+void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture)
{
- if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0)
- {
- glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV);
- }
- else
- {
- glColor4ubv(color.mV);
- }
-}
+#if !LL_RELEASE_FOR_DOWNLOAD
+ LLGLState::checkClientArrays(mask);
+#endif
-void LLDrawPool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
-{
- if (mPool->mVertexShaderLevel > 0 && mPool->getMaterialAttribIndex() > 0)
- {
- glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a);
- }
- else
+ for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i)
{
- glColor4f(r,g,b,a);
+ LLSpatialGroup* group = *i;
+ if (!group->isDead() &&
+ gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
+ group->mDrawMap.find(type) != group->mDrawMap.end())
+ {
+ renderGroup(group,type,mask,texture);
+ }
}
}
-
-// virtual
-void LLDrawPool::enableShade()
-{ }
-
-// virtual
-void LLDrawPool::disableShade()
-{ }
-
-// virtual
-void LLDrawPool::setShade(F32 shade)
-{ }