lldrawpool.cpp

Go to the documentation of this file.
00001 
00032 #include "llviewerprecompiledheaders.h"
00033 
00034 #include "lldrawpool.h"
00035 
00036 #include "llfasttimer.h"
00037 #include "llviewercontrol.h"
00038 
00039 #include "lldrawable.h"
00040 #include "lldrawpoolalpha.h"
00041 #include "lldrawpoolavatar.h"
00042 #include "lldrawpoolbump.h"
00043 #include "lldrawpoolclouds.h"
00044 #include "lldrawpoolground.h"
00045 #include "lldrawpoolsimple.h"
00046 #include "lldrawpoolsky.h"
00047 #include "lldrawpoolstars.h"
00048 #include "lldrawpooltree.h"
00049 #include "lldrawpoolterrain.h"
00050 #include "lldrawpoolwater.h"
00051 #include "llface.h"
00052 #include "llviewerobjectlist.h" // For debug listing.
00053 #include "pipeline.h"
00054 
00055 S32 LLDrawPool::sNumDrawPools = 0;
00056 
00057 
00058 //=============================
00059 // Draw Pool Implementation
00060 //=============================
00061 LLDrawPool *LLDrawPool::createPool(const U32 type, LLViewerImage *tex0)
00062 {
00063         LLDrawPool *poolp = NULL;
00064         switch (type)
00065         {
00066         case POOL_SIMPLE:
00067                 poolp = new LLDrawPoolSimple();
00068                 break;
00069         case POOL_GLOW:
00070                 poolp = new LLDrawPoolGlow();
00071                 break;
00072         case POOL_ALPHA:
00073                 poolp = new LLDrawPoolAlpha();
00074                 break;
00075         case POOL_ALPHA_POST_WATER:
00076                 poolp = new LLDrawPoolAlphaPostWater();
00077                 break;
00078         case POOL_AVATAR:
00079                 poolp = new LLDrawPoolAvatar();
00080                 break;
00081         case POOL_TREE:
00082                 poolp = new LLDrawPoolTree(tex0);
00083                 break;
00084         case POOL_TERRAIN:
00085                 poolp = new LLDrawPoolTerrain(tex0);
00086                 break;
00087         case POOL_SKY:
00088                 poolp = new LLDrawPoolSky();
00089                 break;
00090         case POOL_STARS:
00091                 poolp = new LLDrawPoolStars();
00092                 break;
00093         case POOL_WATER:
00094                 poolp = new LLDrawPoolWater();
00095                 break;
00096         case POOL_GROUND:
00097                 poolp = new LLDrawPoolGround();
00098                 break;
00099         case POOL_BUMP:
00100                 poolp = new LLDrawPoolBump();
00101                 break;
00102         default:
00103                 llerrs << "Unknown draw pool type!" << llendl;
00104                 return NULL;
00105         }
00106 
00107         llassert(poolp->mType == type);
00108         return poolp;
00109 }
00110 
00111 LLDrawPool::LLDrawPool(const U32 type)
00112 {
00113         mType = type;
00114         sNumDrawPools++;
00115         mId = sNumDrawPools;
00116         mVertexShaderLevel = 0;
00117         mIndicesDrawn = 0;
00118 }
00119 
00120 LLDrawPool::~LLDrawPool()
00121 {
00122 
00123 }
00124 
00125 LLViewerImage *LLDrawPool::getDebugTexture()
00126 {
00127         return NULL;
00128 }
00129 
00130 //virtual
00131 void LLDrawPool::beginRenderPass( S32 pass )
00132 {
00133 }
00134 
00135 //virtual
00136 void LLDrawPool::endRenderPass( S32 pass )
00137 {
00138         glDisableClientState ( GL_TEXTURE_COORD_ARRAY );
00139         glDisableClientState ( GL_COLOR_ARRAY );
00140         glDisableClientState ( GL_NORMAL_ARRAY );
00141 }
00142 
00143 U32 LLDrawPool::getTrianglesDrawn() const
00144 {
00145         return mIndicesDrawn / 3;
00146 }
00147 
00148 void LLDrawPool::resetTrianglesDrawn()
00149 {
00150         mIndicesDrawn = 0;
00151 }
00152 
00153 void LLDrawPool::addIndicesDrawn(const U32 indices)
00154 {
00155         mIndicesDrawn += indices;
00156 }
00157 
00158 //=============================
00159 // Face Pool Implementation
00160 //=============================
00161 LLFacePool::LLFacePool(const U32 type)
00162 : LLDrawPool(type)
00163 {
00164         resetDrawOrders();
00165 }
00166 
00167 LLFacePool::~LLFacePool()
00168 {
00169         destroy();
00170 }
00171 
00172 void LLFacePool::destroy()
00173 {
00174         if (!mReferences.empty())
00175         {
00176                 llinfos << mReferences.size() << " references left on deletion of draw pool!" << llendl;
00177         }
00178 }
00179 
00180 void LLFacePool::dirtyTextures(const std::set<LLViewerImage*>& textures)
00181 {
00182 }
00183 
00184 BOOL LLFacePool::moveFace(LLFace *face, LLDrawPool *poolp, BOOL copy_data)
00185 {
00186         return TRUE;
00187 }
00188 
00189 // static
00190 S32 LLFacePool::drawLoop(face_array_t& face_list)
00191 {
00192         S32 res = 0;
00193         if (!face_list.empty())
00194         {
00195                 for (std::vector<LLFace*>::iterator iter = face_list.begin();
00196                          iter != face_list.end(); iter++)
00197                 {
00198                         LLFace *facep = *iter;
00199                         //facep->enableLights();
00200                         res += facep->renderIndexed();
00201                 }
00202         }
00203         return res;
00204 }
00205 
00206 // static
00207 S32 LLFacePool::drawLoopSetTex(face_array_t& face_list, S32 stage)
00208 {
00209         S32 res = 0;
00210         if (!face_list.empty())
00211         {
00212                 for (std::vector<LLFace*>::iterator iter = face_list.begin();
00213                          iter != face_list.end(); iter++)
00214                 {
00215                         LLFace *facep = *iter;
00216                         facep->bindTexture(stage);
00217                         facep->enableLights();
00218                         res += facep->renderIndexed();
00219                 }
00220         }
00221         return res;
00222 }
00223 
00224 void LLFacePool::drawLoop()
00225 {
00226         if (!mDrawFace.empty())
00227         {
00228                 mIndicesDrawn += drawLoop(mDrawFace);
00229         }
00230 }
00231 
00232 void LLFacePool::renderFaceSelected(LLFace *facep, 
00233                                                                         LLImageGL *image, 
00234                                                                         const LLColor4 &color,
00235                                                                         const S32 index_offset, const S32 index_count)
00236 {
00237 }
00238 
00239 void LLFacePool::renderVisibility()
00240 {
00241         if (mDrawFace.empty())
00242         {
00243                 return;
00244         }
00245 
00246         // SJB: Note: This may be broken now. If you need it, fix it :)
00247         
00248         glLineWidth(1.0);
00249         glMatrixMode(GL_PROJECTION);
00250         glPushMatrix();
00251         glLoadIdentity();
00252         glMatrixMode(GL_MODELVIEW);
00253         glPushMatrix();
00254         glLoadIdentity();
00255 
00256         glTranslatef(-0.4f,-0.3f,0);
00257 
00258         float table[7][3] = { 
00259                 { 1,0,0 },
00260                 { 0,1,0 },
00261                 { 1,1,0 },
00262                 { 0,0,1 },
00263                 { 1,0,1 },
00264                 { 0,1,1 },
00265                 { 1,1,1 }
00266         };
00267 
00268         glColor4f(0,0,0,0.5);
00269         glBegin(GL_POLYGON);
00270         glVertex3f(-0.5f,-0.5f,1.0f);
00271         glVertex3f(+0.5f,-0.5f,1.0f);
00272         glVertex3f(+0.5f,+0.5f,1.0f);
00273         glVertex3f(-0.5f,+0.5f,1.0f);
00274         glVertex3f(-0.5f,-0.5f,1.0f);
00275         glEnd();
00276         
00277         for (std::vector<LLFace*>::iterator iter = mDrawFace.begin();
00278                  iter != mDrawFace.end(); iter++)
00279         {
00280                 LLFace *face = *iter;
00281 
00282                 S32 geom_count = face->getGeomCount();
00283                 for (S32 j=0;j<geom_count;j++)
00284                 {
00285                         LLVector3 p1;
00286                         LLVector3 p2;
00287 
00288                         intptr_t p = ((intptr_t)face*13) % 7;
00289                         F32 r = table[p][0];
00290                         F32 g = table[p][1];
00291                         F32 b = table[p][2];
00292 
00293                         //p1.mV[1] = y;
00294                         //p2.mV[1] = y;
00295 
00296                         p1.mV[2] = 1.0;
00297                         p2.mV[2] = 1.0;
00298 
00299                         glColor4f(r,g,b,0.5f);
00300 
00301                         glBegin(GL_LINE_STRIP);
00302                         glVertex3fv(p1.mV);
00303                         glVertex3fv(p2.mV);
00304                         glEnd();
00305 
00306                 }               
00307         }
00308 
00309         glColor4f(1,1,1,1);
00310         glBegin(GL_LINE_STRIP);
00311         glVertex3f(-0.5f,-0.5f,1.0f);
00312         glVertex3f(+0.5f,-0.5f,1.0f);
00313         glVertex3f(+0.5f,+0.5f,1.0f);
00314         glVertex3f(-0.5f,+0.5f,1.0f);
00315         glVertex3f(-0.5f,-0.5f,1.0f);
00316         glEnd();
00317 
00318         glPopMatrix();
00319         glMatrixMode(GL_PROJECTION);
00320         glPopMatrix();
00321         glMatrixMode(GL_MODELVIEW);
00322 
00323 }
00324 
00325 void LLFacePool::enqueue(LLFace* facep)
00326 {
00327         mDrawFace.push_back(facep);
00328 }
00329 
00330 // virtual
00331 BOOL LLFacePool::addFace(LLFace *facep)
00332 {
00333         addFaceReference(facep);
00334         return TRUE;
00335 }
00336 
00337 // virtual
00338 BOOL LLFacePool::removeFace(LLFace *facep)
00339 {
00340         removeFaceReference(facep);
00341 
00342         vector_replace_with_last(mDrawFace, facep);
00343 
00344         return TRUE;
00345 }
00346 
00347 // Not absolutely sure if we should be resetting all of the chained pools as well - djs
00348 void LLFacePool::resetDrawOrders()
00349 {
00350         mDrawFace.resize(0);
00351 }
00352 
00353 LLViewerImage *LLFacePool::getTexture()
00354 {
00355         return NULL;
00356 }
00357 
00358 void LLFacePool::removeFaceReference(LLFace *facep)
00359 {
00360         if (facep->getReferenceIndex() != -1)
00361         {
00362                 if (facep->getReferenceIndex() != (S32)mReferences.size())
00363                 {
00364                         LLFace *back = mReferences.back();
00365                         mReferences[facep->getReferenceIndex()] = back;
00366                         back->setReferenceIndex(facep->getReferenceIndex());
00367                 }
00368                 mReferences.pop_back();
00369         }
00370         facep->setReferenceIndex(-1);
00371 }
00372 
00373 void LLFacePool::addFaceReference(LLFace *facep)
00374 {
00375         if (-1 == facep->getReferenceIndex())
00376         {
00377                 facep->setReferenceIndex(mReferences.size());
00378                 mReferences.push_back(facep);
00379         }
00380 }
00381 
00382 BOOL LLFacePool::verify() const
00383 {
00384         BOOL ok = TRUE;
00385         
00386         for (std::vector<LLFace*>::const_iterator iter = mDrawFace.begin();
00387                  iter != mDrawFace.end(); iter++)
00388         {
00389                 const LLFace* facep = *iter;
00390                 if (facep->getPool() != this)
00391                 {
00392                         llinfos << "Face in wrong pool!" << llendl;
00393                         facep->printDebugInfo();
00394                         ok = FALSE;
00395                 }
00396                 else if (!facep->verify())
00397                 {
00398                         ok = FALSE;
00399                 }
00400         }
00401 
00402         return ok;
00403 }
00404 
00405 void LLFacePool::printDebugInfo() const
00406 {
00407         llinfos << "Pool " << this << " Type: " << getType() << llendl;
00408 }
00409 
00410 BOOL LLFacePool::LLOverrideFaceColor::sOverrideFaceColor = FALSE;
00411 
00412 void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4& color)
00413 {
00414         if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
00415         {
00416                 glVertexAttrib4fvARB(mPool->getMaterialAttribIndex(), color.mV);
00417         }
00418         else
00419         {
00420                 glColor4fv(color.mV);
00421         }
00422 }
00423 
00424 void LLFacePool::LLOverrideFaceColor::setColor(const LLColor4U& color)
00425 {
00426         if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
00427         {
00428                 glVertexAttrib4ubvARB(mPool->getMaterialAttribIndex(), color.mV);
00429         }
00430         else
00431         {
00432                 glColor4ubv(color.mV);
00433         }
00434 }
00435 
00436 void LLFacePool::LLOverrideFaceColor::setColor(F32 r, F32 g, F32 b, F32 a)
00437 {
00438         if (mPool->getVertexShaderLevel() > 0 && mPool->getMaterialAttribIndex() > 0)
00439         {
00440                 glVertexAttrib4fARB(mPool->getMaterialAttribIndex(), r,g,b,a);
00441         }
00442         else
00443         {
00444                 glColor4f(r,g,b,a);
00445         }
00446 }
00447 
00448 
00449 //=============================
00450 // Render Pass Implementation
00451 //=============================
00452 LLRenderPass::LLRenderPass(const U32 type)
00453 : LLDrawPool(type)
00454 {
00455 
00456 }
00457 
00458 LLRenderPass::~LLRenderPass()
00459 {
00460 
00461 }
00462 
00463 LLDrawPool* LLRenderPass::instancePool()
00464 {
00465 #if LL_RELEASE_FOR_DOWNLOAD
00466         llwarns << "Attempting to instance a render pass.  Invalid operation." << llendl;
00467 #else
00468         llerrs << "Attempting to instance a render pass.  Invalid operation." << llendl;
00469 #endif
00470         return NULL;
00471 }
00472 
00473 void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture)
00474 {                                       
00475         LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type];
00476         
00477         for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) 
00478         {
00479                 LLDrawInfo *pparams = *k;
00480                 if (pparams) {
00481                         pushBatch(*pparams, mask, texture);
00482                 }
00483         }
00484 }
00485 
00486 void LLRenderPass::renderInvisible(U32 mask)
00487 {
00488 #if !LL_RELEASE_FOR_DOWNLOAD
00489         LLGLState::checkClientArrays(mask);
00490 #endif
00491         
00492         LLSpatialGroup::drawmap_elem_t& draw_info = gPipeline.mRenderMap[LLRenderPass::PASS_INVISIBLE]; 
00493 
00494         for (LLSpatialGroup::drawmap_elem_t::iterator i = draw_info.begin(); i != draw_info.end(); ++i) 
00495         {
00496                 
00497                 LLDrawInfo *pparams = *i;
00498                 if (pparams && pparams->mVertexBuffer.notNull()) {
00499                         LLDrawInfo &params = *pparams;
00500 
00501                         params.mVertexBuffer->setBuffer(mask);
00502                         U32 *indices_pointer =
00503                                 (U32 *) params.mVertexBuffer->getIndicesPointer();
00504                         glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd,
00505                                                                 params.mCount, GL_UNSIGNED_INT,
00506                                                                 indices_pointer + params.mOffset);
00507                         gPipeline.mTrianglesDrawn += params.mCount / 3;
00508                 }
00509         }
00510 }
00511 
00512 void LLRenderPass::renderTexture(U32 type, U32 mask)
00513 {
00514 #if !LL_RELEASE_FOR_DOWNLOAD
00515         LLGLState::checkClientArrays(mask);
00516 #endif
00517 
00518         LLSpatialGroup::drawmap_elem_t& draw_info = gPipeline.mRenderMap[type]; 
00519 
00520         for (LLSpatialGroup::drawmap_elem_t::iterator i = draw_info.begin(); i != draw_info.end(); ++i) 
00521         {
00522                 LLDrawInfo* pparams = *i;
00523                 if (pparams) {
00524                         pushBatch(*pparams, mask, TRUE);
00525                 }
00526         }
00527 }
00528 
00529 void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture)
00530 {
00531         if (texture)
00532         {
00533                 if (params.mTexture.notNull())
00534                 {
00535                         params.mTexture->bind();
00536                         if (params.mTextureMatrix)
00537                         {
00538                                 glMatrixMode(GL_TEXTURE);
00539                                 glLoadMatrixf((GLfloat*) params.mTextureMatrix->mMatrix);
00540                         }
00541                         params.mTexture->addTextureStats(params.mVSize);
00542                 }
00543                 else
00544                 {
00545                         LLImageGL::unbindTexture(0);
00546                 }
00547         }
00548 
00549         if (params.mVertexBuffer.notNull())
00550         {
00551                 params.mVertexBuffer->setBuffer(mask);
00552                 U32* indices_pointer = (U32*) params.mVertexBuffer->getIndicesPointer();
00553                 glDrawRangeElements(GL_TRIANGLES, params.mStart, params.mEnd, params.mCount,
00554                                                         GL_UNSIGNED_INT, indices_pointer+params.mOffset);
00555                 gPipeline.mTrianglesDrawn += params.mCount/3;
00556         }
00557 
00558         if (params.mTextureMatrix && texture && params.mTexture.notNull())
00559         {
00560                 glLoadIdentity();
00561                 glMatrixMode(GL_MODELVIEW);
00562         }
00563 }
00564 
00565 void LLRenderPass::renderActive(U32 type, U32 mask, BOOL texture)
00566 {
00567 #if !LL_RELEASE_FOR_DOWNLOAD
00568         LLGLState::checkClientArrays(mask);
00569 #endif
00570 
00571         LLSpatialBridge* last_bridge = NULL;
00572         glPushMatrix();
00573         
00574         for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mActiveGroups.begin(); i != gPipeline.mActiveGroups.end(); ++i)
00575         {
00576                 LLSpatialGroup* group = *i;
00577                 if (!group->isDead() &&
00578                         gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
00579                         group->mDrawMap.find(type) != group->mDrawMap.end())
00580                 {
00581                         LLSpatialBridge* bridge = (LLSpatialBridge*) group->mSpatialPartition;
00582                         if (bridge != last_bridge)
00583                         {
00584                                 glPopMatrix();
00585                                 glPushMatrix();
00586                                 glMultMatrixf((F32*) bridge->mDrawable->getRenderMatrix().mMatrix);
00587                                 last_bridge = bridge;
00588                         }
00589 
00590                         renderGroup(group,type,mask,texture);
00591                 }
00592         }
00593         
00594         glPopMatrix();
00595 }
00596 
00597 void LLRenderPass::renderStatic(U32 type, U32 mask, BOOL texture)
00598 {
00599 #if !LL_RELEASE_FOR_DOWNLOAD
00600         LLGLState::checkClientArrays(mask);
00601 #endif
00602 
00603         for (LLSpatialGroup::sg_vector_t::iterator i = gPipeline.mVisibleGroups.begin(); i != gPipeline.mVisibleGroups.end(); ++i)
00604         {
00605                 LLSpatialGroup* group = *i;
00606                 if (!group->isDead() &&
00607                         gPipeline.hasRenderType(group->mSpatialPartition->mDrawableType) &&
00608                         group->mDrawMap.find(type) != group->mDrawMap.end())
00609                 {
00610                         renderGroup(group,type,mask,texture);
00611                 }
00612         }
00613 }

Generated on Thu Jul 1 06:08:25 2010 for Second Life Viewer by  doxygen 1.4.7