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"
00053 #include "pipeline.h"
00054
00055 S32 LLDrawPool::sNumDrawPools = 0;
00056
00057
00058
00059
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
00131 void LLDrawPool::beginRenderPass( S32 pass )
00132 {
00133 }
00134
00135
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
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
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
00200 res += facep->renderIndexed();
00201 }
00202 }
00203 return res;
00204 }
00205
00206
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
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
00294
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
00331 BOOL LLFacePool::addFace(LLFace *facep)
00332 {
00333 addFaceReference(facep);
00334 return TRUE;
00335 }
00336
00337
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
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
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 ¶ms = *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 }