aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r--linden/indra/newview/llvovolume.cpp781
1 files changed, 450 insertions, 331 deletions
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index 7b151e8..607bb42 100644
--- a/linden/indra/newview/llvovolume.cpp
+++ b/linden/indra/newview/llvovolume.cpp
@@ -17,7 +17,8 @@
17 * There are special exceptions to the terms and conditions of the GPL as 17 * There are special exceptions to the terms and conditions of the GPL as
18 * it is applied to this Source Code. View the full text of the exception 18 * it is applied to this Source Code. View the full text of the exception
19 * in the file doc/FLOSS-exception.txt in this software distribution, or 19 * in the file doc/FLOSS-exception.txt in this software distribution, or
20 * online at http://secondlifegrid.net/programs/open_source/licensing/flossexception 20 * online at
21 * http://secondlifegrid.net/programs/open_source/licensing/flossexception
21 * 22 *
22 * By copying, modifying or distributing this software, you acknowledge 23 * By copying, modifying or distributing this software, you acknowledge
23 * that you have read and understood your obligations described above, 24 * that you have read and understood your obligations described above,
@@ -408,7 +409,7 @@ BOOL LLVOVolume::idleUpdate(LLAgent &agent, LLWorld &world, const F64 &time)
408void LLVOVolume::updateTextures(LLAgent &agent) 409void LLVOVolume::updateTextures(LLAgent &agent)
409{ 410{
410 const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds 411 const F32 TEXTURE_AREA_REFRESH_TIME = 5.f; // seconds
411 if (mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME) 412 if (mDrawable.notNull() && mTextureUpdateTimer.getElapsedTimeF32() > TEXTURE_AREA_REFRESH_TIME)
412 { 413 {
413 if (mDrawable->isVisible()) 414 if (mDrawable->isVisible())
414 { 415 {
@@ -467,17 +468,6 @@ void LLVOVolume::updateTextures()
467 468
468 F32 old_size = face->getVirtualSize(); 469 F32 old_size = face->getVirtualSize();
469 470
470 if (face->getPoolType() == LLDrawPool::POOL_ALPHA)
471 {
472
473 if (LLPipeline::sFastAlpha &&
474 vsize < MIN_ALPHA_SIZE && old_size > MIN_ALPHA_SIZE ||
475 vsize > MIN_ALPHA_SIZE && old_size < MIN_ALPHA_SIZE)
476 {
477 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_COLOR, FALSE);
478 }
479 }
480
481 if (face->mTextureMatrix != NULL) 471 if (face->mTextureMatrix != NULL)
482 { 472 {
483 if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE || 473 if (vsize < MIN_TEX_ANIM_SIZE && old_size > MIN_TEX_ANIM_SIZE ||
@@ -663,7 +653,8 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline)
663 } 653 }
664 654
665 updateRadius(); 655 updateRadius();
666 mDrawable->updateDistance(*LLViewerCamera::getInstance()); 656 bool force_update = true; // avoid non-alpha mDistance update being optimized away
657 mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update);
667 658
668 return mDrawable; 659 return mDrawable;
669} 660}
@@ -1281,13 +1272,28 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color)
1281 1272
1282S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) 1273S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
1283{ 1274{
1284 S32 res = LLViewerObject::setTEColor(te, color); 1275 S32 retval = 0;
1285 if (res) 1276 const LLTextureEntry *tep = getTE(te);
1277 if (!tep)
1286 { 1278 {
1287 gPipeline.markTextured(mDrawable); 1279 llwarns << "No texture entry for te " << (S32)te << ", object " << mID << llendl;
1288 mFaceMappingChanged = TRUE;
1289 } 1280 }
1290 return res; 1281 else if (color != tep->getColor())
1282 {
1283 if (color.mV[3] != tep->getColor().mV[3])
1284 {
1285 gPipeline.markTextured(mDrawable);
1286 }
1287 retval = LLPrimitive::setTEColor(te, color);
1288 if (mDrawable.notNull() && retval)
1289 {
1290 // These should only happen on updates which are not the initial update.
1291 mDrawable->setState(LLDrawable::REBUILD_COLOR);
1292 dirtyMesh();
1293 }
1294 }
1295
1296 return retval;
1291} 1297}
1292 1298
1293S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) 1299S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap)
@@ -1312,6 +1318,17 @@ S32 LLVOVolume::setTETexGen(const U8 te, const U8 texgen)
1312 return res; 1318 return res;
1313} 1319}
1314 1320
1321S32 LLVOVolume::setTEMediaTexGen(const U8 te, const U8 media)
1322{
1323 S32 res = LLViewerObject::setTEMediaTexGen(te, media);
1324 if (res)
1325 {
1326 gPipeline.markTextured(mDrawable);
1327 mFaceMappingChanged = TRUE;
1328 }
1329 return res;
1330}
1331
1315S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny) 1332S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny)
1316{ 1333{
1317 S32 res = LLViewerObject::setTEShiny(te, shiny); 1334 S32 res = LLViewerObject::setTEShiny(te, shiny);
@@ -1334,6 +1351,17 @@ S32 LLVOVolume::setTEFullbright(const U8 te, const U8 fullbright)
1334 return res; 1351 return res;
1335} 1352}
1336 1353
1354S32 LLVOVolume::setTEBumpShinyFullbright(const U8 te, const U8 bump)
1355{
1356 S32 res = LLViewerObject::setTEBumpShinyFullbright(te, bump);
1357 if (res)
1358 {
1359 gPipeline.markTextured(mDrawable);
1360 mFaceMappingChanged = TRUE;
1361 }
1362 return res;
1363}
1364
1337S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) 1365S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags)
1338{ 1366{
1339 S32 res = LLViewerObject::setTEMediaFlags(te, media_flags); 1367 S32 res = LLViewerObject::setTEMediaFlags(te, media_flags);
@@ -1391,11 +1419,11 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
1391 1419
1392void LLVOVolume::updateTEData() 1420void LLVOVolume::updateTEData()
1393{ 1421{
1394 if (mDrawable.notNull()) 1422 /*if (mDrawable.notNull())
1395 { 1423 {
1396 mFaceMappingChanged = TRUE; 1424 mFaceMappingChanged = TRUE;
1397 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE); 1425 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE);
1398 } 1426 }*/
1399} 1427}
1400 1428
1401//---------------------------------------------------------------------------- 1429//----------------------------------------------------------------------------
@@ -1823,7 +1851,9 @@ F32 LLVOVolume::getBinRadius()
1823 { 1851 {
1824 LLFace* face = mDrawable->getFace(i); 1852 LLFace* face = mDrawable->getFace(i);
1825 if (face->getPoolType() == LLDrawPool::POOL_ALPHA && 1853 if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
1826 (!LLPipeline::sFastAlpha || face->getVirtualSize() > MIN_ALPHA_SIZE)) 1854 (!LLPipeline::sFastAlpha ||
1855 face->getFaceColor().mV[3] != 1.f ||
1856 !face->getTexture()->getIsAlphaMask()))
1827 { 1857 {
1828 alpha_wrap = TRUE; 1858 alpha_wrap = TRUE;
1829 break; 1859 break;
@@ -1848,14 +1878,20 @@ F32 LLVOVolume::getBinRadius()
1848 } 1878 }
1849 else if (mDrawable->isStatic()) 1879 else if (mDrawable->isStatic())
1850 { 1880 {
1851 if (mDrawable->getRadius() < 2.0f) 1881 /*if (mDrawable->getRadius() < 2.0f)
1852 { 1882 {
1853 radius = 16.f; 1883 radius = 16.f;
1854 } 1884 }
1855 else 1885 else
1856 { 1886 {
1857 radius = llmax(mDrawable->getRadius(), 32.f); 1887 radius = llmax(mDrawable->getRadius(), 32.f);
1858 } 1888 }*/
1889
1890 radius = (((S32) mDrawable->getRadius())/2+1)*8;
1891 }
1892 else if (mDrawable->getVObj()->isAttachment())
1893 {
1894 radius = (((S32) (mDrawable->getRadius()*4)+1))*2;
1859 } 1895 }
1860 else 1896 else
1861 { 1897 {
@@ -2139,6 +2175,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2139 glow = (U8) (facep->getTextureEntry()->getGlow() * 255); 2175 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
2140 } 2176 }
2141 2177
2178 if (facep->mVertexBuffer.isNull())
2179 {
2180 llerrs << "WTF?" << llendl;
2181 }
2182
2142 if (idx >= 0 && 2183 if (idx >= 0 &&
2143 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && 2184 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer &&
2144 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && 2185 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -2157,6 +2198,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2157 draw_vec[idx]->mEnd += facep->getGeomCount(); 2198 draw_vec[idx]->mEnd += facep->getGeomCount();
2158 draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); 2199 draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
2159 validate_draw_info(*draw_vec[idx]); 2200 validate_draw_info(*draw_vec[idx]);
2201 update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
2202 update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
2160 } 2203 }
2161 else 2204 else
2162 { 2205 {
@@ -2172,6 +2215,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2172 draw_info->mTextureMatrix = tex_mat; 2215 draw_info->mTextureMatrix = tex_mat;
2173 draw_info->mModelMatrix = model_mat; 2216 draw_info->mModelMatrix = model_mat;
2174 draw_info->mGlowColor.setVec(0,0,0,glow); 2217 draw_info->mGlowColor.setVec(0,0,0,glow);
2218 if (type == LLRenderPass::PASS_ALPHA)
2219 { //for alpha sorting
2220 facep->setDrawInfo(draw_info);
2221 }
2222 draw_info->mExtents[0] = facep->mExtents[0];
2223 draw_info->mExtents[1] = facep->mExtents[1];
2175 validate_draw_info(*draw_info); 2224 validate_draw_info(*draw_info);
2176 } 2225 }
2177} 2226}
@@ -2195,89 +2244,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2195 2244
2196 group->mLastUpdateViewAngle = group->mViewAngle; 2245 group->mLastUpdateViewAngle = group->mViewAngle;
2197 2246
2198 if (!group->isState(LLSpatialGroup::GEOM_DIRTY | 2247 if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
2199 LLSpatialGroup::ALPHA_DIRTY))
2200 { 2248 {
2201 if (group->isState(LLSpatialGroup::MESH_DIRTY)) 2249 if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
2202 { 2250 {
2203 S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
2204
2205 group->mBuilt = 1.f;
2206 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); 2251 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
2207
2208 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); 2252 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
2209 2253
2210 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2254 rebuildMesh(group);
2211 {
2212 LLDrawable* drawablep = *drawable_iter;
2213
2214 if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
2215 {
2216 continue;
2217 }
2218
2219 if (drawablep->isState(LLDrawable::REBUILD_ALL))
2220 {
2221 LLVOVolume* vobj = drawablep->getVOVolume();
2222 vobj->preRebuild();
2223 LLVolume* volume = vobj->getVolume();
2224 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2225 {
2226 LLFace* face = drawablep->getFace(i);
2227 if (face && face->mVertexBuffer.notNull())
2228 {
2229 face->getGeometryVolume(*volume, face->getTEOffset(),
2230 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
2231 }
2232 }
2233
2234 drawablep->clearState(LLDrawable::REBUILD_ALL);
2235 }
2236 }
2237
2238 //unmap all the buffers
2239 for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
2240 {
2241 LLSpatialGroup::buffer_list_t& list = i->second;
2242 for (LLSpatialGroup::buffer_list_t::iterator j = list.begin(); j != list.end(); ++j)
2243 {
2244 LLVertexBuffer* buffer = *j;
2245 if (buffer->isLocked())
2246 {
2247 buffer->setBuffer(0);
2248 }
2249 }
2250 }
2251
2252 // don't forget alpha
2253 if( group != NULL &&
2254 !group->mVertexBuffer.isNull() &&
2255 group->mVertexBuffer->isLocked())
2256 {
2257 group->mVertexBuffer->setBuffer(0);
2258 }
2259
2260 //if not all buffers are unmapped
2261 if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
2262 {
2263 llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
2264 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2265 {
2266 LLDrawable* drawablep = *drawable_iter;
2267 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2268 {
2269 LLFace* face = drawablep->getFace(i);
2270 if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked())
2271 {
2272 face->mVertexBuffer->setBuffer(0) ;
2273 }
2274 }
2275 }
2276 }
2277
2278 group->clearState(LLSpatialGroup::MESH_DIRTY);
2279 } 2255 }
2280
2281 return; 2256 return;
2282 } 2257 }
2283 2258
@@ -2290,15 +2265,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2290 2265
2291 mFaceList.clear(); 2266 mFaceList.clear();
2292 2267
2268 std::vector<LLFace*> fullbright_faces;
2269 std::vector<LLFace*> bump_faces;
2270 std::vector<LLFace*> simple_faces;
2271
2293 std::vector<LLFace*> alpha_faces; 2272 std::vector<LLFace*> alpha_faces;
2294 U32 vertex_count = 0;
2295 U32 index_count = 0;
2296 U32 useage = group->mSpatialPartition->mBufferUsage; 2273 U32 useage = group->mSpatialPartition->mBufferUsage;
2297 2274
2298 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); 2275 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2276 U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2299 max_vertices = llmin(max_vertices, (U32) 65535); 2277 max_vertices = llmin(max_vertices, (U32) 65535);
2300 2278
2301 //get all the faces into a list, putting alpha faces in their own list 2279 U32 cur_total = 0;
2280
2281 //get all the faces into a list
2302 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2282 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2303 { 2283 {
2304 LLDrawable* drawablep = *drawable_iter; 2284 LLDrawable* drawablep = *drawable_iter;
@@ -2324,11 +2304,29 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2324 //sum up face verts and indices 2304 //sum up face verts and indices
2325 drawablep->updateFaceSize(i); 2305 drawablep->updateFaceSize(i);
2326 LLFace* facep = drawablep->getFace(i); 2306 LLFace* facep = drawablep->getFace(i);
2307
2308 if (cur_total > max_total)
2309 {
2310 facep->mVertexBuffer = NULL;
2311 facep->mLastVertexBuffer = NULL;
2312 continue;
2313 }
2314
2315 cur_total += facep->getGeomCount();
2316
2327 if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) 2317 if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA)
2328 { 2318 {
2329 const LLTextureEntry* te = facep->getTextureEntry(); 2319 const LLTextureEntry* te = facep->getTextureEntry();
2330 LLViewerImage* tex = facep->getTexture(); 2320 LLViewerImage* tex = facep->getTexture();
2331 2321
2322 if (facep->isState(LLFace::TEXTURE_ANIM))
2323 {
2324 if (!vobj->mTexAnimMode)
2325 {
2326 facep->clearState(LLFace::TEXTURE_ANIM);
2327 }
2328 }
2329
2332 BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA); 2330 BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA);
2333 U32 type = gPipeline.getPoolTypeFromTE(te, tex); 2331 U32 type = gPipeline.getPoolTypeFromTE(te, tex);
2334 if (type != LLDrawPool::POOL_ALPHA && force_simple) 2332 if (type != LLDrawPool::POOL_ALPHA && force_simple)
@@ -2360,36 +2358,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2360 2358
2361 if (type == LLDrawPool::POOL_ALPHA) 2359 if (type == LLDrawPool::POOL_ALPHA)
2362 { 2360 {
2363 BOOL alpha_opt = LLPipeline::sFastAlpha && gPipeline.canUseWindLightShadersOnObjects() && facep->getVirtualSize() < MIN_ALPHA_SIZE; 2361 if (LLPipeline::sFastAlpha &&
2364 2362 (te->getColor().mV[VW] == 1.0f) &&
2365 const LLColor4& col = facep->getTextureEntry()->getColor(); 2363 facep->getTexture()->getIsAlphaMask())
2366 2364 { //can be treated as alpha mask
2367 if (alpha_opt) 2365 simple_faces.push_back(facep);
2368 { //if we're applying the alpha optimization, only blend faces that have alpha (0.15, 0.5]
2369 //for faces with alpha (0.5, 1.0], render with an alpha mask
2370 //for faces with alpha [0.0, 0.15], don't render
2371 if (col.mV[3] > 0.5f)
2372 {
2373 mFaceList.push_back(facep);
2374 }
2375 else if (col.mV[3] > 0.15f)
2376 {
2377 vertex_count += facep->getGeomCount();
2378 index_count += facep->getIndicesCount();
2379 alpha_faces.push_back(facep);
2380 }
2381 else
2382 { //face has no renderable geometry
2383 facep->mVertexBuffer = NULL;
2384 facep->mLastVertexBuffer = NULL;
2385 //don't alpha wrap drawables that have only tiny tiny alpha faces
2386 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2387 }
2388 } 2366 }
2389 else 2367 else
2390 { 2368 {
2391 vertex_count += facep->getGeomCount();
2392 index_count += facep->getIndicesCount();
2393 alpha_faces.push_back(facep); 2369 alpha_faces.push_back(facep);
2394 } 2370 }
2395 } 2371 }
@@ -2399,124 +2375,302 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2399 { 2375 {
2400 facep->mLastUpdateTime = gFrameTimeSeconds; 2376 facep->mLastUpdateTime = gFrameTimeSeconds;
2401 } 2377 }
2402 mFaceList.push_back(facep); 2378
2379 if (gPipeline.canUseWindLightShadersOnObjects()
2380 && LLPipeline::sRenderBump)
2381 {
2382 if (te->getBumpmap())
2383 { //needs normal + binormal
2384 bump_faces.push_back(facep);
2385 }
2386 else if (te->getShiny() || !te->getFullbright())
2387 { //needs normal
2388 simple_faces.push_back(facep);
2389 }
2390 else
2391 { //doesn't need normal
2392 facep->setState(LLFace::FULLBRIGHT);
2393 fullbright_faces.push_back(facep);
2394 }
2395 }
2396 else
2397 {
2398 if (te->getBumpmap() && LLPipeline::sRenderBump)
2399 { //needs normal + binormal
2400 bump_faces.push_back(facep);
2401 }
2402 else if (te->getShiny() && LLPipeline::sRenderBump ||
2403 !te->getFullbright())
2404 { //needs normal
2405 simple_faces.push_back(facep);
2406 }
2407 else
2408 { //doesn't need normal
2409 facep->setState(LLFace::FULLBRIGHT);
2410 fullbright_faces.push_back(facep);
2411 }
2412 }
2403 } 2413 }
2404 } 2414 }
2405 else 2415 else
2406 { //face has no renderable geometry 2416 { //face has no renderable geometry
2407 facep->mVertexBuffer = NULL; 2417 facep->mVertexBuffer = NULL;
2408 facep->mLastVertexBuffer = NULL; 2418 facep->mLastVertexBuffer = NULL;
2409 //don't alpha wrap drawables that have only tiny tiny alpha faces
2410 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2411 } 2419 }
2412 } 2420 }
2413 } 2421 }
2414 2422
2415 U16 alpha_vertex_count = vertex_count > 65535 ? 65535 : vertex_count;
2416 U32 alpha_index_count = index_count;
2417
2418 group->mBufferUsage = useage; 2423 group->mBufferUsage = useage;
2419 2424
2420 //PROCESS NON-ALPHA FACES 2425 //PROCESS NON-ALPHA FACES
2426 U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2427 U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
2428 U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2429 U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2430
2431 if (LLPipeline::sRenderDeferred)
2421 { 2432 {
2422 //sort faces by things that break batches 2433 bump_mask |= LLVertexBuffer::MAP_BINORMAL;
2423 std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareBatchBreaker()); 2434 }
2424
2425 std::vector<LLFace*>::iterator face_iter = mFaceList.begin();
2426
2427 LLSpatialGroup::buffer_map_t buffer_map;
2428 2435
2429 LLViewerImage* last_tex = NULL; 2436 genDrawInfo(group, simple_mask, simple_faces);
2430 U32 buffer_index = 0; 2437 genDrawInfo(group, bump_mask, bump_faces);
2438 genDrawInfo(group, fullbright_mask, fullbright_faces);
2439 genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
2431 2440
2432 while (face_iter != mFaceList.end()) 2441 if (!LLPipeline::sDelayVBUpdate)
2442 {
2443 //drawables have been rebuilt, clear rebuild status
2444 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2433 { 2445 {
2434 //pull off next face 2446 LLDrawable* drawablep = *drawable_iter;
2435 LLFace* facep = *face_iter; 2447 drawablep->clearState(LLDrawable::REBUILD_ALL);
2436 LLViewerImage* tex = facep->getTexture(); 2448 }
2449 }
2437 2450
2438 if (last_tex == tex) 2451 group->mLastUpdateTime = gFrameTimeSeconds;
2439 { 2452 group->mBuilt = 1.f;
2440 buffer_index++; 2453 group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
2441 } 2454
2442 else 2455 if (LLPipeline::sDelayVBUpdate)
2456 {
2457 group->setState(LLSpatialGroup::MESH_DIRTY);
2458 }
2459
2460 mFaceList.clear();
2461}
2462
2463void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
2464{
2465 if (group->isState(LLSpatialGroup::MESH_DIRTY))
2466 {
2467 S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
2468
2469 group->mBuilt = 1.f;
2470
2471 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2472 {
2473 LLDrawable* drawablep = *drawable_iter;
2474
2475 if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
2443 { 2476 {
2444 last_tex = tex; 2477 continue;
2445 buffer_index = 0;
2446 } 2478 }
2447 2479
2448 U32 index_count = facep->getIndicesCount(); 2480 if (drawablep->isState(LLDrawable::REBUILD_ALL))
2449 U32 geom_count = facep->getGeomCount();
2450
2451 //sum up vertices needed for this texture
2452 std::vector<LLFace*>::iterator i = face_iter;
2453 ++i;
2454
2455 while (i != mFaceList.end() &&
2456 (LLPipeline::sTextureBindTest || (*i)->getTexture() == tex))
2457 { 2481 {
2458 facep = *i; 2482 LLVOVolume* vobj = drawablep->getVOVolume();
2459 2483 vobj->preRebuild();
2460 if (geom_count + facep->getGeomCount() > max_vertices) 2484 LLVolume* volume = vobj->getVolume();
2461 { //cut vertex buffers on geom count too big 2485 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2462 break; 2486 {
2487 LLFace* face = drawablep->getFace(i);
2488 if (face && face->mVertexBuffer.notNull())
2489 {
2490 face->getGeometryVolume(*volume, face->getTEOffset(),
2491 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
2492 }
2463 } 2493 }
2464 2494
2465 ++i; 2495 drawablep->clearState(LLDrawable::REBUILD_ALL);
2466 index_count += facep->getIndicesCount(); 2496 }
2467 geom_count += facep->getGeomCount(); 2497 }
2498
2499 //unmap all the buffers
2500 for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
2501 {
2502 LLSpatialGroup::buffer_texture_map_t& map = i->second;
2503 for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j)
2504 {
2505 LLSpatialGroup::buffer_list_t& list = j->second;
2506 for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k)
2507 {
2508 LLVertexBuffer* buffer = *k;
2509 if (buffer->isLocked())
2510 {
2511 buffer->setBuffer(0);
2512 }
2513 }
2468 } 2514 }
2515 }
2469 2516
2470 //create/delete/resize vertex buffer if needed 2517 // don't forget alpha
2471 LLVertexBuffer* buffer = NULL; 2518 if( group != NULL &&
2472 LLSpatialGroup::buffer_map_t::iterator found_iter = group->mBufferMap.find(tex); 2519 !group->mVertexBuffer.isNull() &&
2473 if (found_iter != group->mBufferMap.end()) 2520 group->mVertexBuffer->isLocked())
2521 {
2522 group->mVertexBuffer->setBuffer(0);
2523 }
2524
2525 //if not all buffers are unmapped
2526 if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
2527 {
2528 llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
2529 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2474 { 2530 {
2475 if (buffer_index < found_iter->second.size()) 2531 LLDrawable* drawablep = *drawable_iter;
2532 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2476 { 2533 {
2477 buffer = found_iter->second[buffer_index]; 2534 LLFace* face = drawablep->getFace(i);
2535 if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked())
2536 {
2537 face->mVertexBuffer->setBuffer(0) ;
2538 }
2478 } 2539 }
2540 }
2541 }
2542
2543 group->clearState(LLSpatialGroup::MESH_DIRTY);
2544 }
2545}
2546
2547void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort)
2548{
2549 //calculate maximum number of vertices to store in a single buffer
2550 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2551 max_vertices = llmin(max_vertices, (U32) 65535);
2552
2553 if (!distance_sort)
2554 {
2555 //sort faces by things that break batches
2556 std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker());
2557 }
2558 else
2559 {
2560 //sort faces by distance
2561 std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
2562 }
2563
2564 std::vector<LLFace*>::iterator face_iter = faces.begin();
2565
2566 LLSpatialGroup::buffer_map_t buffer_map;
2567
2568 LLViewerImage* last_tex = NULL;
2569 S32 buffer_index = 0;
2570
2571 if (distance_sort)
2572 {
2573 buffer_index = -1;
2574 }
2575
2576 while (face_iter != faces.end())
2577 {
2578 //pull off next face
2579 LLFace* facep = *face_iter;
2580 LLViewerImage* tex = facep->getTexture();
2581
2582 if (distance_sort)
2583 {
2584 tex = NULL;
2585 }
2586
2587 if (last_tex == tex)
2588 {
2589 buffer_index++;
2590 }
2591 else
2592 {
2593 last_tex = tex;
2594 buffer_index = 0;
2595 }
2596
2597 U32 index_count = facep->getIndicesCount();
2598 U32 geom_count = facep->getGeomCount();
2599
2600 //sum up vertices needed for this texture
2601 std::vector<LLFace*>::iterator i = face_iter;
2602 ++i;
2603
2604 while (i != faces.end() &&
2605 (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
2606 {
2607 facep = *i;
2608
2609 if (geom_count + facep->getGeomCount() > max_vertices)
2610 { //cut vertex buffers on geom count too big
2611 break;
2479 } 2612 }
2480 2613
2481 if (!buffer) 2614 ++i;
2482 { //create new buffer if needed 2615 index_count += facep->getIndicesCount();
2616 geom_count += facep->getGeomCount();
2617 }
2618
2619 //create/delete/resize vertex buffer if needed
2620 LLVertexBuffer* buffer = NULL;
2621 LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex);
2622
2623 if (found_iter != group->mBufferMap[mask].end())
2624 {
2625 if ((U32) buffer_index < found_iter->second.size())
2626 {
2627 buffer = found_iter->second[buffer_index];
2628 }
2629 }
2630
2631 if (!buffer)
2632 { //create new buffer if needed
2633 buffer = createVertexBuffer(mask,
2634 group->mBufferUsage);
2635 buffer->allocateBuffer(geom_count, index_count, TRUE);
2636 }
2637 else
2638 {
2639 if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage)
2640 {
2483 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, 2641 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2484 group->mBufferUsage); 2642 group->mBufferUsage);
2485 buffer->allocateBuffer(geom_count, index_count, TRUE); 2643 buffer->allocateBuffer(geom_count, index_count, TRUE);
2486 } 2644 }
2487 else 2645 else
2488 { 2646 {
2489 if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage) 2647 buffer->resizeBuffer(geom_count, index_count);
2490 {
2491 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2492 group->mBufferUsage);
2493 buffer->allocateBuffer(geom_count, index_count, TRUE);
2494 }
2495 else
2496 {
2497 buffer->resizeBuffer(geom_count, index_count);
2498 }
2499 } 2648 }
2649 }
2500 2650
2501 buffer_map[tex].push_back(buffer); 2651 buffer_map[mask][tex].push_back(buffer);
2502 2652
2503 //add face geometry 2653 //add face geometry
2504 2654
2505 U32 indices_index = 0; 2655 U32 indices_index = 0;
2506 U16 index_offset = 0; 2656 U16 index_offset = 0;
2507 2657
2508 while (face_iter < i) 2658 while (face_iter < i)
2659 {
2660 facep = *face_iter;
2661 facep->mIndicesIndex = indices_index;
2662 facep->mGeomIndex = index_offset;
2663 facep->mVertexBuffer = buffer;
2509 { 2664 {
2510 facep = *face_iter; 2665 facep->updateRebuildFlags();
2511 LLDrawable* drawablep = facep->getDrawable(); 2666 if (!LLPipeline::sDelayVBUpdate)
2512 LLVOVolume* vobj = drawablep->getVOVolume();
2513 LLVolume* volume = vobj->getVolume();
2514
2515 U32 te_idx = facep->getTEOffset();
2516 facep->mIndicesIndex = indices_index;
2517 facep->mGeomIndex = index_offset;
2518 facep->mVertexBuffer = buffer;
2519 { 2667 {
2668 LLDrawable* drawablep = facep->getDrawable();
2669 LLVOVolume* vobj = drawablep->getVOVolume();
2670 LLVolume* volume = vobj->getVolume();
2671
2672 U32 te_idx = facep->getTEOffset();
2673
2520 if (facep->getGeometryVolume(*volume, te_idx, 2674 if (facep->getGeometryVolume(*volume, te_idx,
2521 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) 2675 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset))
2522 { 2676 {
@@ -2524,168 +2678,133 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2524 facep->getIndicesStart(), facep->getIndicesCount()); 2678 facep->getIndicesStart(), facep->getIndicesCount());
2525 } 2679 }
2526 } 2680 }
2681 }
2527 2682
2528 index_offset += facep->getGeomCount(); 2683 index_offset += facep->getGeomCount();
2529 indices_index += facep->mIndicesCount; 2684 indices_index += facep->mIndicesCount;
2530
2531 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
2532 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
2533 const LLTextureEntry* te = facep->getTextureEntry();
2534 2685
2535 BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; 2686 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
2687 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
2688 const LLTextureEntry* te = facep->getTextureEntry();
2536 2689
2537 if (!is_alpha 2690 BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;
2538 && gPipeline.canUseWindLightShadersOnObjects() 2691
2539 && LLPipeline::sRenderBump 2692 if (is_alpha)
2540 && te->getShiny()) 2693 {
2694 // can we safely treat this as an alpha mask?
2695 if (LLPipeline::sFastAlpha &&
2696 (te->getColor().mV[VW] == 1.0f) &&
2697 facep->getTexture()->getIsAlphaMask())
2541 { 2698 {
2542 if (tex->getPrimaryFormat() == GL_ALPHA) 2699 if (te->getFullbright())
2543 { 2700 {
2544 registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); 2701 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
2545 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2546 }
2547 else if (fullbright)
2548 {
2549 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2550 } 2702 }
2551 else 2703 else
2552 { 2704 {
2553 registerFace(group, facep, LLRenderPass::PASS_SHINY); 2705 registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
2554 } 2706 }
2555 } 2707 }
2556 else 2708 else
2557 { 2709 {
2558 if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) 2710 registerFace(group, facep, LLRenderPass::PASS_ALPHA);
2711 }
2712
2713 if (LLPipeline::sRenderDeferred)
2714 {
2715 registerFace(group, facep, LLRenderPass::PASS_ALPHA_SHADOW);
2716 }
2717 }
2718 else if (gPipeline.canUseVertexShaders()
2719 && LLPipeline::sRenderBump
2720 && te->getShiny())
2721 {
2722 if (tex->getPrimaryFormat() == GL_ALPHA)
2723 {
2724 registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
2725 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2726 }
2727 else if (LLPipeline::sRenderDeferred)
2728 {
2729 if (te->getBumpmap())
2559 { 2730 {
2560 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); 2731 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2561 } 2732 }
2562 else if (fullbright) 2733 else if (te->getFullbright())
2563 { 2734 {
2564 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); 2735 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2565 } 2736 }
2566 else 2737 else
2567 { 2738 {
2739 llassert(mask & LLVertexBuffer::MAP_NORMAL);
2568 registerFace(group, facep, LLRenderPass::PASS_SIMPLE); 2740 registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
2569 } 2741 }
2570
2571 if (!is_alpha && te->getShiny())
2572 {
2573 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2574 }
2575 } 2742 }
2576 2743 else if (fullbright)
2577 if (!is_alpha) 2744 {
2745 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2746 }
2747 else
2578 { 2748 {
2579 facep->setPoolType(LLDrawPool::POOL_SIMPLE); 2749 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2580 2750 }
2581 if (!force_simple && te->getBumpmap()) 2751 }
2752 else
2753 {
2754 if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
2755 {
2756 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2757 }
2758 else if (fullbright)
2759 {
2760 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
2761 }
2762 else
2763 {
2764 if (LLPipeline::sRenderDeferred && te->getBumpmap())
2582 { 2765 {
2583 registerFace(group, facep, LLRenderPass::PASS_BUMP); 2766 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2584 } 2767 }
2768 else
2769 {
2770 llassert(mask & LLVertexBuffer::MAP_NORMAL);
2771 registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
2772 }
2585 } 2773 }
2586 2774
2587 if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) 2775 if (!is_alpha && te->getShiny())
2588 { 2776 {
2589 registerFace(group, facep, LLRenderPass::PASS_GLOW); 2777 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2590 } 2778 }
2591
2592 ++face_iter;
2593 }
2594
2595 buffer->setBuffer(0);
2596 }
2597
2598 group->mBufferMap.clear();
2599 for (LLSpatialGroup::buffer_map_t::iterator i = buffer_map.begin(); i != buffer_map.end(); ++i)
2600 {
2601 group->mBufferMap[i->first] = i->second;
2602 }
2603 }
2604
2605 //PROCESS ALPHA FACES
2606 if (!alpha_faces.empty())
2607 {
2608 //sort alpha faces by distance
2609 std::sort(alpha_faces.begin(), alpha_faces.end(), LLFace::CompareDistanceGreater());
2610
2611 //store alpha faces in root vertex buffer
2612 if (group->mVertexBuffer.isNull() || (LLVertexBuffer::sEnableVBOs && group->mBufferUsage != group->mVertexBuffer->getUsage()))
2613 {
2614 group->mVertexBuffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2615 group->mBufferUsage);
2616 group->mVertexBuffer->allocateBuffer(alpha_vertex_count, alpha_index_count, true);
2617 stop_glerror();
2618 }
2619 else
2620 {
2621 group->mVertexBuffer->resizeBuffer(alpha_vertex_count, alpha_index_count);
2622 stop_glerror();
2623 }
2624
2625 //get vertex buffer striders
2626 LLVertexBuffer* buffer = group->mVertexBuffer;
2627
2628 U32 index_offset = 0;
2629 U32 indices_index = 0;
2630
2631 for (std::vector<LLFace*>::iterator i = alpha_faces.begin(); i != alpha_faces.end(); ++i)
2632 {
2633 LLFace* facep = *i;
2634
2635 if (facep->mGeomCount + index_offset > 65535)
2636 { //cut off alpha nodes at 64k vertices
2637 facep->mVertexBuffer = NULL ;
2638 facep->mLastVertexBuffer = NULL ;
2639 continue ;
2640 } 2779 }
2641 2780
2642 LLDrawable* drawablep = facep->getDrawable(); 2781 if (!is_alpha && !LLPipeline::sRenderDeferred)
2643 LLVOVolume* vobj = drawablep->getVOVolume();
2644 LLVolume* volume = vobj->getVolume();
2645
2646 U32 te_idx = facep->getTEOffset();
2647 facep->mIndicesIndex = indices_index;
2648 facep->mGeomIndex = index_offset;
2649 facep->mVertexBuffer = group->mVertexBuffer;
2650 if (facep->getGeometryVolume(*volume, te_idx,
2651 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(),
2652 index_offset))
2653 { 2782 {
2654 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), 2783 llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
2655 facep->getIndicesStart(), facep->getIndicesCount()); 2784 facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
2785
2786 if (!force_simple && te->getBumpmap())
2787 {
2788 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2789 }
2656 } 2790 }
2657 2791
2658 index_offset += facep->getGeomCount(); 2792 if (LLPipeline::sRenderGlow && te->getGlow() > 0.f)
2659 indices_index += facep->mIndicesCount;
2660
2661 registerFace(group, facep, LLRenderPass::PASS_ALPHA);
2662
2663 if (LLPipeline::sRenderGlow && facep->getTextureEntry()->getGlow() > 0.f)
2664 { 2793 {
2665 registerFace(group, facep, LLRenderPass::PASS_GLOW); 2794 registerFace(group, facep, LLRenderPass::PASS_GLOW);
2666 } 2795 }
2796
2797 ++face_iter;
2667 } 2798 }
2668 2799
2669 buffer->setBuffer(0); 2800 buffer->setBuffer(0);
2670 } 2801 }
2671 else
2672 {
2673 group->mVertexBuffer = NULL;
2674 }
2675 2802
2676 //drawables have been rebuilt, clear rebuild status 2803 group->mBufferMap[mask].clear();
2677 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2804 for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i)
2678 { 2805 {
2679 LLDrawable* drawablep = *drawable_iter; 2806 group->mBufferMap[mask][i->first] = i->second;
2680 drawablep->clearState(LLDrawable::REBUILD_ALL);
2681 } 2807 }
2682
2683 group->mLastUpdateTime = gFrameTimeSeconds;
2684 group->mBuilt = 1.f;
2685 group->clearState(LLSpatialGroup::GEOM_DIRTY |
2686 LLSpatialGroup::ALPHA_DIRTY | LLSpatialGroup::MESH_DIRTY);
2687
2688 mFaceList.clear();
2689} 2808}
2690 2809
2691void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) 2810void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)
@@ -2741,7 +2860,7 @@ LLHUDPartition::LLHUDPartition()
2741 mPartitionType = LLViewerRegion::PARTITION_HUD; 2860 mPartitionType = LLViewerRegion::PARTITION_HUD;
2742 mDrawableType = LLPipeline::RENDER_TYPE_HUD; 2861 mDrawableType = LLPipeline::RENDER_TYPE_HUD;
2743 mSlopRatio = 0.f; 2862 mSlopRatio = 0.f;
2744 mLODPeriod = 16; 2863 mLODPeriod = 1;
2745} 2864}
2746 2865
2747void LLHUDPartition::shift(const LLVector3 &offset) 2866void LLHUDPartition::shift(const LLVector3 &offset)