aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/linden/indra/newview/llvovolume.cpp
diff options
context:
space:
mode:
authorJacek Antonelli2009-04-30 13:04:20 -0500
committerJacek Antonelli2009-04-30 13:07:16 -0500
commitca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch)
tree8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llvovolume.cpp
parentSecond Life viewer sources 1.22.11 (diff)
downloadmeta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.zip
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.gz
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.bz2
meta-impy-ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e.tar.xz
Second Life viewer sources 1.23.0-RC
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r--linden/indra/newview/llvovolume.cpp737
1 files changed, 410 insertions, 327 deletions
diff --git a/linden/indra/newview/llvovolume.cpp b/linden/indra/newview/llvovolume.cpp
index ad44356..8f11661 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 ||
@@ -1282,10 +1272,12 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color)
1282S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) 1272S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color)
1283{ 1273{
1284 S32 res = LLViewerObject::setTEColor(te, color); 1274 S32 res = LLViewerObject::setTEColor(te, color);
1285 if (res) 1275 if (res && mDrawable.notNull())
1286 { 1276 {
1287 gPipeline.markTextured(mDrawable); 1277 //gPipeline.markTextured(mDrawable);
1288 mFaceMappingChanged = TRUE; 1278 mDrawable->setState(LLDrawable::REBUILD_COLOR);
1279 dirtyMesh();
1280 //mFaceMappingChanged = TRUE;
1289 } 1281 }
1290 return res; 1282 return res;
1291} 1283}
@@ -1391,11 +1383,11 @@ S32 LLVOVolume::setTEScaleT(const U8 te, const F32 t)
1391 1383
1392void LLVOVolume::updateTEData() 1384void LLVOVolume::updateTEData()
1393{ 1385{
1394 if (mDrawable.notNull()) 1386 /*if (mDrawable.notNull())
1395 { 1387 {
1396 mFaceMappingChanged = TRUE; 1388 mFaceMappingChanged = TRUE;
1397 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE); 1389 gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_MATERIAL, TRUE);
1398 } 1390 }*/
1399} 1391}
1400 1392
1401//---------------------------------------------------------------------------- 1393//----------------------------------------------------------------------------
@@ -1823,7 +1815,9 @@ F32 LLVOVolume::getBinRadius()
1823 { 1815 {
1824 LLFace* face = mDrawable->getFace(i); 1816 LLFace* face = mDrawable->getFace(i);
1825 if (face->getPoolType() == LLDrawPool::POOL_ALPHA && 1817 if (face->getPoolType() == LLDrawPool::POOL_ALPHA &&
1826 (!LLPipeline::sFastAlpha || face->getVirtualSize() > MIN_ALPHA_SIZE)) 1818 (!LLPipeline::sFastAlpha ||
1819 face->getFaceColor().mV[3] != 1.f ||
1820 !face->getTexture()->getIsAlphaMask()))
1827 { 1821 {
1828 alpha_wrap = TRUE; 1822 alpha_wrap = TRUE;
1829 break; 1823 break;
@@ -1848,14 +1842,20 @@ F32 LLVOVolume::getBinRadius()
1848 } 1842 }
1849 else if (mDrawable->isStatic()) 1843 else if (mDrawable->isStatic())
1850 { 1844 {
1851 if (mDrawable->getRadius() < 2.0f) 1845 /*if (mDrawable->getRadius() < 2.0f)
1852 { 1846 {
1853 radius = 16.f; 1847 radius = 16.f;
1854 } 1848 }
1855 else 1849 else
1856 { 1850 {
1857 radius = llmax(mDrawable->getRadius(), 32.f); 1851 radius = llmax(mDrawable->getRadius(), 32.f);
1858 } 1852 }*/
1853
1854 radius = (((S32) mDrawable->getRadius())/2+1)*8;
1855 }
1856 else if (mDrawable->getVObj()->isAttachment())
1857 {
1858 radius = (((S32) (mDrawable->getRadius()*4)+1))*2;
1859 } 1859 }
1860 else 1860 else
1861 { 1861 {
@@ -2127,6 +2127,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2127 glow = (U8) (facep->getTextureEntry()->getGlow() * 255); 2127 glow = (U8) (facep->getTextureEntry()->getGlow() * 255);
2128 } 2128 }
2129 2129
2130 if (facep->mVertexBuffer.isNull())
2131 {
2132 llerrs << "WTF?" << llendl;
2133 }
2134
2130 if (idx >= 0 && 2135 if (idx >= 0 &&
2131 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer && 2136 draw_vec[idx]->mVertexBuffer == facep->mVertexBuffer &&
2132 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && 2137 draw_vec[idx]->mEnd == facep->getGeomIndex()-1 &&
@@ -2145,6 +2150,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2145 draw_vec[idx]->mEnd += facep->getGeomCount(); 2150 draw_vec[idx]->mEnd += facep->getGeomCount();
2146 draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize()); 2151 draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, facep->getVirtualSize());
2147 validate_draw_info(*draw_vec[idx]); 2152 validate_draw_info(*draw_vec[idx]);
2153 update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[0]);
2154 update_min_max(draw_vec[idx]->mExtents[0], draw_vec[idx]->mExtents[1], facep->mExtents[1]);
2148 } 2155 }
2149 else 2156 else
2150 { 2157 {
@@ -2160,6 +2167,12 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
2160 draw_info->mTextureMatrix = tex_mat; 2167 draw_info->mTextureMatrix = tex_mat;
2161 draw_info->mModelMatrix = model_mat; 2168 draw_info->mModelMatrix = model_mat;
2162 draw_info->mGlowColor.setVec(0,0,0,glow); 2169 draw_info->mGlowColor.setVec(0,0,0,glow);
2170 if (type == LLRenderPass::PASS_ALPHA)
2171 { //for alpha sorting
2172 facep->setDrawInfo(draw_info);
2173 }
2174 draw_info->mExtents[0] = facep->mExtents[0];
2175 draw_info->mExtents[1] = facep->mExtents[1];
2163 validate_draw_info(*draw_info); 2176 validate_draw_info(*draw_info);
2164 } 2177 }
2165} 2178}
@@ -2183,89 +2196,15 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2183 2196
2184 group->mLastUpdateViewAngle = group->mViewAngle; 2197 group->mLastUpdateViewAngle = group->mViewAngle;
2185 2198
2186 if (!group->isState(LLSpatialGroup::GEOM_DIRTY | 2199 if (!group->isState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY))
2187 LLSpatialGroup::ALPHA_DIRTY))
2188 { 2200 {
2189 if (group->isState(LLSpatialGroup::MESH_DIRTY)) 2201 if (group->isState(LLSpatialGroup::MESH_DIRTY) && !LLPipeline::sDelayVBUpdate)
2190 { 2202 {
2191 S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
2192
2193 group->mBuilt = 1.f;
2194 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO); 2203 LLFastTimer ftm(LLFastTimer::FTM_REBUILD_VBO);
2195
2196 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB); 2204 LLFastTimer ftm2(LLFastTimer::FTM_REBUILD_VOLUME_VB);
2197 2205
2198 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2206 rebuildMesh(group);
2199 {
2200 LLDrawable* drawablep = *drawable_iter;
2201
2202 if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
2203 {
2204 continue;
2205 }
2206
2207 if (drawablep->isState(LLDrawable::REBUILD_ALL))
2208 {
2209 LLVOVolume* vobj = drawablep->getVOVolume();
2210 vobj->preRebuild();
2211 LLVolume* volume = vobj->getVolume();
2212 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2213 {
2214 LLFace* face = drawablep->getFace(i);
2215 if (face && face->mVertexBuffer.notNull())
2216 {
2217 face->getGeometryVolume(*volume, face->getTEOffset(),
2218 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
2219 }
2220 }
2221
2222 drawablep->clearState(LLDrawable::REBUILD_ALL);
2223 }
2224 }
2225
2226 //unmap all the buffers
2227 for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
2228 {
2229 LLSpatialGroup::buffer_list_t& list = i->second;
2230 for (LLSpatialGroup::buffer_list_t::iterator j = list.begin(); j != list.end(); ++j)
2231 {
2232 LLVertexBuffer* buffer = *j;
2233 if (buffer->isLocked())
2234 {
2235 buffer->setBuffer(0);
2236 }
2237 }
2238 }
2239
2240 // don't forget alpha
2241 if( group != NULL &&
2242 !group->mVertexBuffer.isNull() &&
2243 group->mVertexBuffer->isLocked())
2244 {
2245 group->mVertexBuffer->setBuffer(0);
2246 }
2247
2248 //if not all buffers are unmapped
2249 if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
2250 {
2251 llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
2252 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2253 {
2254 LLDrawable* drawablep = *drawable_iter;
2255 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2256 {
2257 LLFace* face = drawablep->getFace(i);
2258 if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked())
2259 {
2260 face->mVertexBuffer->setBuffer(0) ;
2261 }
2262 }
2263 }
2264 }
2265
2266 group->clearState(LLSpatialGroup::MESH_DIRTY);
2267 } 2207 }
2268
2269 return; 2208 return;
2270 } 2209 }
2271 2210
@@ -2278,15 +2217,20 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2278 2217
2279 mFaceList.clear(); 2218 mFaceList.clear();
2280 2219
2220 std::vector<LLFace*> fullbright_faces;
2221 std::vector<LLFace*> bump_faces;
2222 std::vector<LLFace*> simple_faces;
2223
2281 std::vector<LLFace*> alpha_faces; 2224 std::vector<LLFace*> alpha_faces;
2282 U32 vertex_count = 0;
2283 U32 index_count = 0;
2284 U32 useage = group->mSpatialPartition->mBufferUsage; 2225 U32 useage = group->mSpatialPartition->mBufferUsage;
2285 2226
2286 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask); 2227 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2228 U32 max_total = (gSavedSettings.getS32("RenderMaxNodeSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2287 max_vertices = llmin(max_vertices, (U32) 65535); 2229 max_vertices = llmin(max_vertices, (U32) 65535);
2288 2230
2289 //get all the faces into a list, putting alpha faces in their own list 2231 U32 cur_total = 0;
2232
2233 //get all the faces into a list
2290 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2234 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2291 { 2235 {
2292 LLDrawable* drawablep = *drawable_iter; 2236 LLDrawable* drawablep = *drawable_iter;
@@ -2312,11 +2256,29 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2312 //sum up face verts and indices 2256 //sum up face verts and indices
2313 drawablep->updateFaceSize(i); 2257 drawablep->updateFaceSize(i);
2314 LLFace* facep = drawablep->getFace(i); 2258 LLFace* facep = drawablep->getFace(i);
2259
2260 if (cur_total > max_total)
2261 {
2262 facep->mVertexBuffer = NULL;
2263 facep->mLastVertexBuffer = NULL;
2264 continue;
2265 }
2266
2267 cur_total += facep->getGeomCount();
2268
2315 if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA) 2269 if (facep->hasGeometry() && facep->mPixelArea > FORCE_CULL_AREA)
2316 { 2270 {
2317 const LLTextureEntry* te = facep->getTextureEntry(); 2271 const LLTextureEntry* te = facep->getTextureEntry();
2318 LLViewerImage* tex = facep->getTexture(); 2272 LLViewerImage* tex = facep->getTexture();
2319 2273
2274 if (facep->isState(LLFace::TEXTURE_ANIM))
2275 {
2276 if (!vobj->mTexAnimMode)
2277 {
2278 facep->clearState(LLFace::TEXTURE_ANIM);
2279 }
2280 }
2281
2320 BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA); 2282 BOOL force_simple = (facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA);
2321 U32 type = gPipeline.getPoolTypeFromTE(te, tex); 2283 U32 type = gPipeline.getPoolTypeFromTE(te, tex);
2322 if (type != LLDrawPool::POOL_ALPHA && force_simple) 2284 if (type != LLDrawPool::POOL_ALPHA && force_simple)
@@ -2348,36 +2310,14 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2348 2310
2349 if (type == LLDrawPool::POOL_ALPHA) 2311 if (type == LLDrawPool::POOL_ALPHA)
2350 { 2312 {
2351 BOOL alpha_opt = LLPipeline::sFastAlpha && gPipeline.canUseWindLightShadersOnObjects() && facep->getVirtualSize() < MIN_ALPHA_SIZE; 2313 if (LLPipeline::sFastAlpha &&
2352 2314 (te->getColor().mV[VW] == 1.0f) &&
2353 const LLColor4& col = facep->getTextureEntry()->getColor(); 2315 facep->getTexture()->getIsAlphaMask())
2354 2316 { //can be treated as alpha mask
2355 if (alpha_opt) 2317 simple_faces.push_back(facep);
2356 { //if we're applying the alpha optimization, only blend faces that have alpha (0.15, 0.5]
2357 //for faces with alpha (0.5, 1.0], render with an alpha mask
2358 //for faces with alpha [0.0, 0.15], don't render
2359 if (col.mV[3] > 0.5f)
2360 {
2361 mFaceList.push_back(facep);
2362 }
2363 else if (col.mV[3] > 0.15f)
2364 {
2365 vertex_count += facep->getGeomCount();
2366 index_count += facep->getIndicesCount();
2367 alpha_faces.push_back(facep);
2368 }
2369 else
2370 { //face has no renderable geometry
2371 facep->mVertexBuffer = NULL;
2372 facep->mLastVertexBuffer = NULL;
2373 //don't alpha wrap drawables that have only tiny tiny alpha faces
2374 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2375 }
2376 } 2318 }
2377 else 2319 else
2378 { 2320 {
2379 vertex_count += facep->getGeomCount();
2380 index_count += facep->getIndicesCount();
2381 alpha_faces.push_back(facep); 2321 alpha_faces.push_back(facep);
2382 } 2322 }
2383 } 2323 }
@@ -2387,124 +2327,302 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2387 { 2327 {
2388 facep->mLastUpdateTime = gFrameTimeSeconds; 2328 facep->mLastUpdateTime = gFrameTimeSeconds;
2389 } 2329 }
2390 mFaceList.push_back(facep); 2330
2331 if (gPipeline.canUseWindLightShadersOnObjects()
2332 && LLPipeline::sRenderBump)
2333 {
2334 if (te->getBumpmap())
2335 { //needs normal + binormal
2336 bump_faces.push_back(facep);
2337 }
2338 else if (te->getShiny() || !te->getFullbright())
2339 { //needs normal
2340 simple_faces.push_back(facep);
2341 }
2342 else
2343 { //doesn't need normal
2344 facep->setState(LLFace::FULLBRIGHT);
2345 fullbright_faces.push_back(facep);
2346 }
2347 }
2348 else
2349 {
2350 if (te->getBumpmap() && LLPipeline::sRenderBump)
2351 { //needs normal + binormal
2352 bump_faces.push_back(facep);
2353 }
2354 else if (te->getShiny() && LLPipeline::sRenderBump ||
2355 !te->getFullbright())
2356 { //needs normal
2357 simple_faces.push_back(facep);
2358 }
2359 else
2360 { //doesn't need normal
2361 facep->setState(LLFace::FULLBRIGHT);
2362 fullbright_faces.push_back(facep);
2363 }
2364 }
2391 } 2365 }
2392 } 2366 }
2393 else 2367 else
2394 { //face has no renderable geometry 2368 { //face has no renderable geometry
2395 facep->mVertexBuffer = NULL; 2369 facep->mVertexBuffer = NULL;
2396 facep->mLastVertexBuffer = NULL; 2370 facep->mLastVertexBuffer = NULL;
2397 //don't alpha wrap drawables that have only tiny tiny alpha faces
2398 facep->setPoolType(LLDrawPool::POOL_SIMPLE);
2399 } 2371 }
2400 } 2372 }
2401 } 2373 }
2402 2374
2403 U16 alpha_vertex_count = vertex_count > 65535 ? 65535 : vertex_count;
2404 U32 alpha_index_count = index_count;
2405
2406 group->mBufferUsage = useage; 2375 group->mBufferUsage = useage;
2407 2376
2408 //PROCESS NON-ALPHA FACES 2377 //PROCESS NON-ALPHA FACES
2378 U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2379 U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO
2380 U32 bump_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2381 U32 fullbright_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR;
2382
2383 if (LLPipeline::sRenderDeferred)
2409 { 2384 {
2410 //sort faces by things that break batches 2385 bump_mask |= LLVertexBuffer::MAP_BINORMAL;
2411 std::sort(mFaceList.begin(), mFaceList.end(), LLFace::CompareBatchBreaker()); 2386 }
2412
2413 std::vector<LLFace*>::iterator face_iter = mFaceList.begin();
2414
2415 LLSpatialGroup::buffer_map_t buffer_map;
2416 2387
2417 LLViewerImage* last_tex = NULL; 2388 genDrawInfo(group, simple_mask, simple_faces);
2418 U32 buffer_index = 0; 2389 genDrawInfo(group, bump_mask, bump_faces);
2390 genDrawInfo(group, fullbright_mask, fullbright_faces);
2391 genDrawInfo(group, alpha_mask, alpha_faces, TRUE);
2419 2392
2420 while (face_iter != mFaceList.end()) 2393 if (!LLPipeline::sDelayVBUpdate)
2394 {
2395 //drawables have been rebuilt, clear rebuild status
2396 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2421 { 2397 {
2422 //pull off next face 2398 LLDrawable* drawablep = *drawable_iter;
2423 LLFace* facep = *face_iter; 2399 drawablep->clearState(LLDrawable::REBUILD_ALL);
2424 LLViewerImage* tex = facep->getTexture(); 2400 }
2401 }
2425 2402
2426 if (last_tex == tex) 2403 group->mLastUpdateTime = gFrameTimeSeconds;
2427 { 2404 group->mBuilt = 1.f;
2428 buffer_index++; 2405 group->clearState(LLSpatialGroup::GEOM_DIRTY | LLSpatialGroup::ALPHA_DIRTY);
2429 } 2406
2430 else 2407 if (LLPipeline::sDelayVBUpdate)
2408 {
2409 group->setState(LLSpatialGroup::MESH_DIRTY);
2410 }
2411
2412 mFaceList.clear();
2413}
2414
2415void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group)
2416{
2417 if (group->isState(LLSpatialGroup::MESH_DIRTY))
2418 {
2419 S32 num_mapped_veretx_buffer = LLVertexBuffer::sMappedCount ;
2420
2421 group->mBuilt = 1.f;
2422
2423 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2424 {
2425 LLDrawable* drawablep = *drawable_iter;
2426
2427 if (drawablep->isDead() || drawablep->isState(LLDrawable::FORCE_INVISIBLE) )
2431 { 2428 {
2432 last_tex = tex; 2429 continue;
2433 buffer_index = 0;
2434 } 2430 }
2435 2431
2436 U32 index_count = facep->getIndicesCount(); 2432 if (drawablep->isState(LLDrawable::REBUILD_ALL))
2437 U32 geom_count = facep->getGeomCount();
2438
2439 //sum up vertices needed for this texture
2440 std::vector<LLFace*>::iterator i = face_iter;
2441 ++i;
2442
2443 while (i != mFaceList.end() &&
2444 (LLPipeline::sTextureBindTest || (*i)->getTexture() == tex))
2445 { 2433 {
2446 facep = *i; 2434 LLVOVolume* vobj = drawablep->getVOVolume();
2447 2435 vobj->preRebuild();
2448 if (geom_count + facep->getGeomCount() > max_vertices) 2436 LLVolume* volume = vobj->getVolume();
2449 { //cut vertex buffers on geom count too big 2437 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2450 break; 2438 {
2439 LLFace* face = drawablep->getFace(i);
2440 if (face && face->mVertexBuffer.notNull())
2441 {
2442 face->getGeometryVolume(*volume, face->getTEOffset(),
2443 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), face->getGeomIndex());
2444 }
2451 } 2445 }
2452 2446
2453 ++i; 2447 drawablep->clearState(LLDrawable::REBUILD_ALL);
2454 index_count += facep->getIndicesCount(); 2448 }
2455 geom_count += facep->getGeomCount(); 2449 }
2450
2451 //unmap all the buffers
2452 for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i)
2453 {
2454 LLSpatialGroup::buffer_texture_map_t& map = i->second;
2455 for (LLSpatialGroup::buffer_texture_map_t::iterator j = map.begin(); j != map.end(); ++j)
2456 {
2457 LLSpatialGroup::buffer_list_t& list = j->second;
2458 for (LLSpatialGroup::buffer_list_t::iterator k = list.begin(); k != list.end(); ++k)
2459 {
2460 LLVertexBuffer* buffer = *k;
2461 if (buffer->isLocked())
2462 {
2463 buffer->setBuffer(0);
2464 }
2465 }
2456 } 2466 }
2467 }
2457 2468
2458 //create/delete/resize vertex buffer if needed 2469 // don't forget alpha
2459 LLVertexBuffer* buffer = NULL; 2470 if( group != NULL &&
2460 LLSpatialGroup::buffer_map_t::iterator found_iter = group->mBufferMap.find(tex); 2471 !group->mVertexBuffer.isNull() &&
2461 if (found_iter != group->mBufferMap.end()) 2472 group->mVertexBuffer->isLocked())
2473 {
2474 group->mVertexBuffer->setBuffer(0);
2475 }
2476
2477 //if not all buffers are unmapped
2478 if(num_mapped_veretx_buffer != LLVertexBuffer::sMappedCount)
2479 {
2480 llwarns << "Not all mapped vertex buffers are unmapped!" << llendl ;
2481 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter)
2462 { 2482 {
2463 if (buffer_index < found_iter->second.size()) 2483 LLDrawable* drawablep = *drawable_iter;
2484 for (S32 i = 0; i < drawablep->getNumFaces(); ++i)
2464 { 2485 {
2465 buffer = found_iter->second[buffer_index]; 2486 LLFace* face = drawablep->getFace(i);
2487 if (face && face->mVertexBuffer.notNull() && face->mVertexBuffer->isLocked())
2488 {
2489 face->mVertexBuffer->setBuffer(0) ;
2490 }
2466 } 2491 }
2492 }
2493 }
2494
2495 group->clearState(LLSpatialGroup::MESH_DIRTY);
2496 }
2497}
2498
2499void LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, std::vector<LLFace*>& faces, BOOL distance_sort)
2500{
2501 //calculate maximum number of vertices to store in a single buffer
2502 U32 max_vertices = (gSavedSettings.getS32("RenderMaxVBOSize")*1024)/LLVertexBuffer::calcStride(group->mSpatialPartition->mVertexDataMask);
2503 max_vertices = llmin(max_vertices, (U32) 65535);
2504
2505 if (!distance_sort)
2506 {
2507 //sort faces by things that break batches
2508 std::sort(faces.begin(), faces.end(), LLFace::CompareBatchBreaker());
2509 }
2510 else
2511 {
2512 //sort faces by distance
2513 std::sort(faces.begin(), faces.end(), LLFace::CompareDistanceGreater());
2514 }
2515
2516 std::vector<LLFace*>::iterator face_iter = faces.begin();
2517
2518 LLSpatialGroup::buffer_map_t buffer_map;
2519
2520 LLViewerImage* last_tex = NULL;
2521 S32 buffer_index = 0;
2522
2523 if (distance_sort)
2524 {
2525 buffer_index = -1;
2526 }
2527
2528 while (face_iter != faces.end())
2529 {
2530 //pull off next face
2531 LLFace* facep = *face_iter;
2532 LLViewerImage* tex = facep->getTexture();
2533
2534 if (distance_sort)
2535 {
2536 tex = NULL;
2537 }
2538
2539 if (last_tex == tex)
2540 {
2541 buffer_index++;
2542 }
2543 else
2544 {
2545 last_tex = tex;
2546 buffer_index = 0;
2547 }
2548
2549 U32 index_count = facep->getIndicesCount();
2550 U32 geom_count = facep->getGeomCount();
2551
2552 //sum up vertices needed for this texture
2553 std::vector<LLFace*>::iterator i = face_iter;
2554 ++i;
2555
2556 while (i != faces.end() &&
2557 (LLPipeline::sTextureBindTest || (distance_sort || (*i)->getTexture() == tex)))
2558 {
2559 facep = *i;
2560
2561 if (geom_count + facep->getGeomCount() > max_vertices)
2562 { //cut vertex buffers on geom count too big
2563 break;
2564 }
2565
2566 ++i;
2567 index_count += facep->getIndicesCount();
2568 geom_count += facep->getGeomCount();
2569 }
2570
2571 //create/delete/resize vertex buffer if needed
2572 LLVertexBuffer* buffer = NULL;
2573 LLSpatialGroup::buffer_texture_map_t::iterator found_iter = group->mBufferMap[mask].find(tex);
2574
2575 if (found_iter != group->mBufferMap[mask].end())
2576 {
2577 if ((U32) buffer_index < found_iter->second.size())
2578 {
2579 buffer = found_iter->second[buffer_index];
2467 } 2580 }
2468 2581 }
2469 if (!buffer) 2582
2470 { //create new buffer if needed 2583 if (!buffer)
2584 { //create new buffer if needed
2585 buffer = createVertexBuffer(mask,
2586 group->mBufferUsage);
2587 buffer->allocateBuffer(geom_count, index_count, TRUE);
2588 }
2589 else
2590 {
2591 if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage)
2592 {
2471 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask, 2593 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2472 group->mBufferUsage); 2594 group->mBufferUsage);
2473 buffer->allocateBuffer(geom_count, index_count, TRUE); 2595 buffer->allocateBuffer(geom_count, index_count, TRUE);
2474 } 2596 }
2475 else 2597 else
2476 { 2598 {
2477 if (LLVertexBuffer::sEnableVBOs && buffer->getUsage() != group->mBufferUsage) 2599 buffer->resizeBuffer(geom_count, index_count);
2478 {
2479 buffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2480 group->mBufferUsage);
2481 buffer->allocateBuffer(geom_count, index_count, TRUE);
2482 }
2483 else
2484 {
2485 buffer->resizeBuffer(geom_count, index_count);
2486 }
2487 } 2600 }
2601 }
2488 2602
2489 buffer_map[tex].push_back(buffer); 2603 buffer_map[mask][tex].push_back(buffer);
2490 2604
2491 //add face geometry 2605 //add face geometry
2492 2606
2493 U32 indices_index = 0; 2607 U32 indices_index = 0;
2494 U16 index_offset = 0; 2608 U16 index_offset = 0;
2495 2609
2496 while (face_iter < i) 2610 while (face_iter < i)
2611 {
2612 facep = *face_iter;
2613 facep->mIndicesIndex = indices_index;
2614 facep->mGeomIndex = index_offset;
2615 facep->mVertexBuffer = buffer;
2497 { 2616 {
2498 facep = *face_iter; 2617 facep->updateRebuildFlags();
2499 LLDrawable* drawablep = facep->getDrawable(); 2618 if (!LLPipeline::sDelayVBUpdate)
2500 LLVOVolume* vobj = drawablep->getVOVolume();
2501 LLVolume* volume = vobj->getVolume();
2502
2503 U32 te_idx = facep->getTEOffset();
2504 facep->mIndicesIndex = indices_index;
2505 facep->mGeomIndex = index_offset;
2506 facep->mVertexBuffer = buffer;
2507 { 2619 {
2620 LLDrawable* drawablep = facep->getDrawable();
2621 LLVOVolume* vobj = drawablep->getVOVolume();
2622 LLVolume* volume = vobj->getVolume();
2623
2624 U32 te_idx = facep->getTEOffset();
2625
2508 if (facep->getGeometryVolume(*volume, te_idx, 2626 if (facep->getGeometryVolume(*volume, te_idx,
2509 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset)) 2627 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(), index_offset))
2510 { 2628 {
@@ -2512,168 +2630,133 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group)
2512 facep->getIndicesStart(), facep->getIndicesCount()); 2630 facep->getIndicesStart(), facep->getIndicesCount());
2513 } 2631 }
2514 } 2632 }
2633 }
2515 2634
2516 index_offset += facep->getGeomCount(); 2635 index_offset += facep->getGeomCount();
2517 indices_index += facep->mIndicesCount; 2636 indices_index += facep->mIndicesCount;
2518
2519 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
2520 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
2521 const LLTextureEntry* te = facep->getTextureEntry();
2522 2637
2523 BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE; 2638 BOOL force_simple = facep->mPixelArea < FORCE_SIMPLE_RENDER_AREA;
2639 BOOL fullbright = facep->isState(LLFace::FULLBRIGHT);
2640 const LLTextureEntry* te = facep->getTextureEntry();
2524 2641
2525 if (!is_alpha 2642 BOOL is_alpha = facep->getPoolType() == LLDrawPool::POOL_ALPHA ? TRUE : FALSE;
2526 && gPipeline.canUseWindLightShadersOnObjects() 2643
2527 && LLPipeline::sRenderBump 2644 if (is_alpha)
2528 && te->getShiny()) 2645 {
2646 // can we safely treat this as an alpha mask?
2647 if (LLPipeline::sFastAlpha &&
2648 (te->getColor().mV[VW] == 1.0f) &&
2649 facep->getTexture()->getIsAlphaMask())
2529 { 2650 {
2530 if (tex->getPrimaryFormat() == GL_ALPHA) 2651 if (te->getFullbright())
2531 { 2652 {
2532 registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY); 2653 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK);
2533 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2534 }
2535 else if (fullbright)
2536 {
2537 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2538 } 2654 }
2539 else 2655 else
2540 { 2656 {
2541 registerFace(group, facep, LLRenderPass::PASS_SHINY); 2657 registerFace(group, facep, LLRenderPass::PASS_ALPHA_MASK);
2542 } 2658 }
2543 } 2659 }
2544 else 2660 else
2545 { 2661 {
2546 if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA) 2662 registerFace(group, facep, LLRenderPass::PASS_ALPHA);
2663 }
2664
2665 if (LLPipeline::sRenderDeferred)
2666 {
2667 registerFace(group, facep, LLRenderPass::PASS_ALPHA_SHADOW);
2668 }
2669 }
2670 else if (gPipeline.canUseVertexShaders()
2671 && LLPipeline::sRenderBump
2672 && te->getShiny())
2673 {
2674 if (tex->getPrimaryFormat() == GL_ALPHA)
2675 {
2676 registerFace(group, facep, LLRenderPass::PASS_INVISI_SHINY);
2677 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2678 }
2679 else if (LLPipeline::sRenderDeferred)
2680 {
2681 if (te->getBumpmap())
2547 { 2682 {
2548 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE); 2683 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2549 } 2684 }
2550 else if (fullbright) 2685 else if (te->getFullbright())
2551 { 2686 {
2552 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT); 2687 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2553 } 2688 }
2554 else 2689 else
2555 { 2690 {
2691 llassert(mask & LLVertexBuffer::MAP_NORMAL);
2556 registerFace(group, facep, LLRenderPass::PASS_SIMPLE); 2692 registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
2557 } 2693 }
2558
2559 if (!is_alpha && te->getShiny())
2560 {
2561 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2562 }
2563 } 2694 }
2564 2695 else if (fullbright)
2565 if (!is_alpha) 2696 {
2697 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT_SHINY);
2698 }
2699 else
2566 { 2700 {
2567 facep->setPoolType(LLDrawPool::POOL_SIMPLE); 2701 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2568 2702 }
2569 if (!force_simple && te->getBumpmap()) 2703 }
2704 else
2705 {
2706 if (!is_alpha && tex->getPrimaryFormat() == GL_ALPHA)
2707 {
2708 registerFace(group, facep, LLRenderPass::PASS_INVISIBLE);
2709 }
2710 else if (fullbright)
2711 {
2712 registerFace(group, facep, LLRenderPass::PASS_FULLBRIGHT);
2713 }
2714 else
2715 {
2716 if (LLPipeline::sRenderDeferred && te->getBumpmap())
2570 { 2717 {
2571 registerFace(group, facep, LLRenderPass::PASS_BUMP); 2718 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2572 } 2719 }
2720 else
2721 {
2722 llassert(mask & LLVertexBuffer::MAP_NORMAL);
2723 registerFace(group, facep, LLRenderPass::PASS_SIMPLE);
2724 }
2573 } 2725 }
2574 2726
2575 if (LLPipeline::sRenderGlow && te->getGlow() > 0.f) 2727 if (!is_alpha && te->getShiny())
2576 { 2728 {
2577 registerFace(group, facep, LLRenderPass::PASS_GLOW); 2729 registerFace(group, facep, LLRenderPass::PASS_SHINY);
2578 } 2730 }
2579
2580 ++face_iter;
2581 } 2731 }
2582 2732
2583 buffer->setBuffer(0); 2733 if (!is_alpha && !LLPipeline::sRenderDeferred)
2584 }
2585
2586 group->mBufferMap.clear();
2587 for (LLSpatialGroup::buffer_map_t::iterator i = buffer_map.begin(); i != buffer_map.end(); ++i)
2588 {
2589 group->mBufferMap[i->first] = i->second;
2590 }
2591 }
2592
2593 //PROCESS ALPHA FACES
2594 if (!alpha_faces.empty())
2595 {
2596 //sort alpha faces by distance
2597 std::sort(alpha_faces.begin(), alpha_faces.end(), LLFace::CompareDistanceGreater());
2598
2599 //store alpha faces in root vertex buffer
2600 if (group->mVertexBuffer.isNull() || (LLVertexBuffer::sEnableVBOs && group->mBufferUsage != group->mVertexBuffer->getUsage()))
2601 {
2602 group->mVertexBuffer = createVertexBuffer(group->mSpatialPartition->mVertexDataMask,
2603 group->mBufferUsage);
2604 group->mVertexBuffer->allocateBuffer(alpha_vertex_count, alpha_index_count, true);
2605 stop_glerror();
2606 }
2607 else
2608 {
2609 group->mVertexBuffer->resizeBuffer(alpha_vertex_count, alpha_index_count);
2610 stop_glerror();
2611 }
2612
2613 //get vertex buffer striders
2614 LLVertexBuffer* buffer = group->mVertexBuffer;
2615
2616 U32 index_offset = 0;
2617 U32 indices_index = 0;
2618
2619 for (std::vector<LLFace*>::iterator i = alpha_faces.begin(); i != alpha_faces.end(); ++i)
2620 {
2621 LLFace* facep = *i;
2622
2623 if (facep->mGeomCount + index_offset > 65535)
2624 { //cut off alpha nodes at 64k vertices
2625 facep->mVertexBuffer = NULL ;
2626 facep->mLastVertexBuffer = NULL ;
2627 continue ;
2628 }
2629
2630 LLDrawable* drawablep = facep->getDrawable();
2631 LLVOVolume* vobj = drawablep->getVOVolume();
2632 LLVolume* volume = vobj->getVolume();
2633
2634 U32 te_idx = facep->getTEOffset();
2635 facep->mIndicesIndex = indices_index;
2636 facep->mGeomIndex = index_offset;
2637 facep->mVertexBuffer = group->mVertexBuffer;
2638 if (facep->getGeometryVolume(*volume, te_idx,
2639 vobj->getRelativeXform(), vobj->getRelativeXformInvTrans(),
2640 index_offset))
2641 { 2734 {
2642 buffer->markDirty(facep->getGeomIndex(), facep->getGeomCount(), 2735 llassert((mask & LLVertexBuffer::MAP_NORMAL) || fullbright);
2643 facep->getIndicesStart(), facep->getIndicesCount()); 2736 facep->setPoolType((fullbright) ? LLDrawPool::POOL_FULLBRIGHT : LLDrawPool::POOL_SIMPLE);
2737
2738 if (!force_simple && te->getBumpmap())
2739 {
2740 registerFace(group, facep, LLRenderPass::PASS_BUMP);
2741 }
2644 } 2742 }
2645 2743
2646 index_offset += facep->getGeomCount(); 2744 if (LLPipeline::sRenderGlow && te->getGlow() > 0.f)
2647 indices_index += facep->mIndicesCount;
2648
2649 registerFace(group, facep, LLRenderPass::PASS_ALPHA);
2650
2651 if (LLPipeline::sRenderGlow && facep->getTextureEntry()->getGlow() > 0.f)
2652 { 2745 {
2653 registerFace(group, facep, LLRenderPass::PASS_GLOW); 2746 registerFace(group, facep, LLRenderPass::PASS_GLOW);
2654 } 2747 }
2748
2749 ++face_iter;
2655 } 2750 }
2656 2751
2657 buffer->setBuffer(0); 2752 buffer->setBuffer(0);
2658 } 2753 }
2659 else
2660 {
2661 group->mVertexBuffer = NULL;
2662 }
2663 2754
2664 //drawables have been rebuilt, clear rebuild status 2755 group->mBufferMap[mask].clear();
2665 for (LLSpatialGroup::element_iter drawable_iter = group->getData().begin(); drawable_iter != group->getData().end(); ++drawable_iter) 2756 for (LLSpatialGroup::buffer_texture_map_t::iterator i = buffer_map[mask].begin(); i != buffer_map[mask].end(); ++i)
2666 { 2757 {
2667 LLDrawable* drawablep = *drawable_iter; 2758 group->mBufferMap[mask][i->first] = i->second;
2668 drawablep->clearState(LLDrawable::REBUILD_ALL);
2669 } 2759 }
2670
2671 group->mLastUpdateTime = gFrameTimeSeconds;
2672 group->mBuilt = 1.f;
2673 group->clearState(LLSpatialGroup::GEOM_DIRTY |
2674 LLSpatialGroup::ALPHA_DIRTY | LLSpatialGroup::MESH_DIRTY);
2675
2676 mFaceList.clear();
2677} 2760}
2678 2761
2679void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) 2762void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count)