diff options
Diffstat (limited to 'linden/indra/newview/llvovolume.cpp')
-rw-r--r-- | linden/indra/newview/llvovolume.cpp | 781 |
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) | |||
408 | void LLVOVolume::updateTextures(LLAgent &agent) | 409 | void 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 | ||
1282 | S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) | 1273 | S32 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 | ||
1293 | S32 LLVOVolume::setTEBumpmap(const U8 te, const U8 bumpmap) | 1299 | S32 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 | ||
1321 | S32 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 | |||
1315 | S32 LLVOVolume::setTEShiny(const U8 te, const U8 shiny) | 1332 | S32 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 | ||
1354 | S32 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 | |||
1337 | S32 LLVOVolume::setTEMediaFlags(const U8 te, const U8 media_flags) | 1365 | S32 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 | ||
1392 | void LLVOVolume::updateTEData() | 1420 | void 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 | |||
2463 | void 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 | |||
2547 | void 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 | ||
2691 | void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) | 2810 | void 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 | ||
2747 | void LLHUDPartition::shift(const LLVector3 &offset) | 2866 | void LLHUDPartition::shift(const LLVector3 &offset) |