diff options
author | Jacek Antonelli | 2009-04-30 13:04:20 -0500 |
---|---|---|
committer | Jacek Antonelli | 2009-04-30 13:07:16 -0500 |
commit | ca8149ca6d157eb4b5fc8ba0e5ba3a6e56f72e7e (patch) | |
tree | 8348301d0ac44a524f1819b777686bf086907d76 /linden/indra/newview/llvovolume.cpp | |
parent | Second Life viewer sources 1.22.11 (diff) | |
download | meta-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.cpp | 737 |
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) | |||
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 || |
@@ -1282,10 +1272,12 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor3& color) | |||
1282 | S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) | 1272 | S32 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 | ||
1392 | void LLVOVolume::updateTEData() | 1384 | void 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 | |||
2415 | void 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 | |||
2499 | void 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 | ||
2679 | void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) | 2762 | void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) |