From 3e80fa3dbc943de9b784fedc202ba38cf238f46d Mon Sep 17 00:00:00 2001 From: David Parks Date: Mon, 2 Nov 2009 19:55:37 +0000 Subject: Sync up with render-pipeline-7 ignore-dead-branch --- indra/newview/pipeline.cpp | 241 ++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 214 insertions(+), 27 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b50e71bf48..7cf5cf75ad 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -342,6 +342,8 @@ LLPipeline::LLPipeline() : mGlowPool(NULL), mBumpPool(NULL), mWLSkyPool(NULL), + mMeshMutex(NULL), + mMeshThreadCount(0), mLightMask(0), mLightMovingMask(0), mLightingDetail(0) @@ -399,6 +401,7 @@ void LLPipeline::init() stop_glerror(); + mMeshMutex = new LLMutex(NULL); for (U32 i = 0; i < 2; ++i) { mSpotLightFade[i] = 1.f; @@ -473,6 +476,9 @@ void LLPipeline::cleanup() //delete mWLSkyPool; mWLSkyPool = NULL; + delete mMeshMutex; + mMeshMutex = NULL; + releaseGLBuffers(); mBloomImagep = NULL; @@ -1783,6 +1789,8 @@ void LLPipeline::rebuildPriorityGroups() assertInitialized(); + notifyLoadedMeshes(); + // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) @@ -1793,6 +1801,7 @@ void LLPipeline::rebuildPriorityGroups() } mGroupQ1.clear(); + } void LLPipeline::rebuildGroups() @@ -3419,27 +3428,14 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); - renderHighlights(); - mHighlightFaces.clear(); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - LLHUDObject::renderAll(); - gObjectList.resetObjectBeacons(); - } - if (occlude) { occlude = FALSE; gGLLastMatrix = NULL; glLoadMatrixd(gGLModelView); doOcclusion(camera); + gGLLastMatrix = NULL; + glLoadMatrixd(gGLModelView); } } @@ -5836,6 +5832,12 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield) gGL.getTexUnit(0)->activate(); gGL.getTexUnit(0)->setTextureBlendType(LLTexUnit::TB_MULT); + + if (LLRenderTarget::sUseFBO) + { //copy depth buffer from mScreen to framebuffer + LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(), + 0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST); + } } @@ -6912,6 +6914,24 @@ void LLPipeline::renderDeferredLighting() mRenderTypeMask = render_mask; } + { + //render highlights, etc. + renderHighlights(); + mHighlightFaces.clear(); + + renderDebug(); + + LLVertexBuffer::unbind(); + + if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + // Render debugging beacons. + gObjectList.renderObjectBeacons(); + LLHUDObject::renderAll(); + gObjectList.resetObjectBeacons(); + } + } + mScreen.flush(); } @@ -7241,18 +7261,12 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in) LLGLDisable cull(GL_CULL_FACE); updateCull(camera, ref_result, 1); stateSort(camera, ref_result); - gGL.setColorMask(true, true); - mWaterRef.clear(); - gGL.setColorMask(true, false); - - } - else - { - gGL.setColorMask(true, true); - mWaterRef.clear(); - gGL.setColorMask(true, false); - } - + } + + gGL.setColorMask(true, true); + mWaterRef.clear(); + gGL.setColorMask(true, false); + ref_mask = mRenderTypeMask; mRenderTypeMask = mask; } @@ -7907,6 +7921,7 @@ void LLPipeline::generateHighlight(LLCamera& camera) mHighlight.flush(); gGL.setColorMask(true, false); + gViewerWindow->setup3DViewport(); } } @@ -8886,3 +8901,175 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() } +void LLPipeline::loadMesh(LLVOVolume* volume, LLUUID mesh_id) +{ + + { + LLMutexLock lock(mMeshMutex); + //add volume to list of loading meshes + mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id); + if (iter != mLoadingMeshes.end()) + { //request pending for this mesh, append volume id to list + iter->second.insert(volume->getID()); + return; + } + + //first request for this mesh + mLoadingMeshes[mesh_id].insert(volume->getID()); + } + + if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH)) + { //already have asset, load desired LOD in background + mPendingMeshes.push_back(new LLMeshThread(mesh_id, volume->getVolume())); + } + else + { //fetch asset and load when done + gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH, + getMeshAssetCallback, volume->getVolume(), TRUE); + } + +} + +//static +void LLPipeline::getMeshAssetCallback(LLVFS *vfs, + const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + gPipeline.mPendingMeshes.push_back(new LLMeshThread(asset_uuid, (LLVolume*) user_data)); +} + + +LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target) +: LLThread("mesh_loading_thread") +{ + mMeshID = mesh_id; + mVolume = NULL; + mDetail = target->getDetail(); + mTargetVolume = target; +} + +LLPipeline::LLMeshThread::~LLMeshThread() +{ + +} + +void LLPipeline::LLMeshThread::run() +{ + if (!gAssetStorage || LLApp::instance()->isQuitting()) + { + return; + } + + char* buffer = NULL; + S32 size = 0; + + LLVFS* vfs = gAssetStorage->mVFS; + + { + LLVFile file(vfs, mMeshID, LLAssetType::AT_MESH, LLVFile::READ); + file.waitForLock(VFSLOCK_READ); + size = file.getSize(); + + if (size == 0) + { + gPipeline.meshLoaded(this); + return; + } + + buffer = new char[size]; + file.read((U8*)&buffer[0], size); + } + + { + std::string buffer_string(buffer, size); + std::istringstream buffer_stream(buffer_string); + + { + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + mVolume = new LLVolume(volume_params, mDetail); + mVolume->createVolumeFacesFromStream(buffer_stream); + } + } + delete[] buffer; + + gPipeline.meshLoaded(this); +} + +void LLPipeline::meshLoaded(LLPipeline::LLMeshThread* mesh_thread) +{ + LLMutexLock lock(mMeshMutex); + mLoadedMeshes.push_back(mesh_thread); +} + +void LLPipeline::notifyLoadedMeshes() +{ //called from main thread + + U32 max_thread_count = llmax(gSavedSettings.getU32("MeshThreadCount"), (U32) 1); + while (mMeshThreadCount < max_thread_count && !mPendingMeshes.empty()) + { + LLMeshThread* mesh_thread = mPendingMeshes.front(); + mesh_thread->start(); + ++mMeshThreadCount; + mPendingMeshes.pop_front(); + } + + LLMutexLock lock(mMeshMutex); + std::list stopping_threads; + + for (std::list::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter) + { //for each mesh done loading + LLMeshThread* mesh = *iter; + + if (!mesh->isStopped()) + { //don't process a LLMeshThread until it's stopped + stopping_threads.push_back(mesh); + continue; + } + + //get list of objects waiting to be notified this mesh is loaded + mesh_load_map::iterator obj_iter = mLoadingMeshes.find(mesh->mMeshID); + + if (mesh->mVolume && obj_iter != mLoadingMeshes.end()) + { + //make sure target volume is still valid + BOOL valid = FALSE; + + for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); + + if (vobj) + { + if (vobj->getVolume() == mesh->mTargetVolume) + { + valid = TRUE; + } + } + } + + + if (valid) + { + mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); + for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) + { + LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); + if (vobj) + { + vobj->notifyMeshLoaded(); + } + } + } + + mLoadingMeshes.erase(mesh->mMeshID); + } + + delete mesh; + --mMeshThreadCount; + } + + mLoadedMeshes = stopping_threads; +} + -- cgit v1.2.3 From 88292104d9a2332e6169f2add8f0b590bb22dbff Mon Sep 17 00:00:00 2001 From: David Parks Date: Wed, 4 Nov 2009 14:19:05 +0000 Subject: Fix for crash when loading some meshes. Added button to auto-fill LODs. --- indra/newview/pipeline.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 7cf5cf75ad..4fc94c08bc 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8988,6 +8988,7 @@ void LLPipeline::LLMeshThread::run() { LLVolumeParams volume_params; volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + volume_params.setSculptID(mMeshID, LL_SCULPT_TYPE_MESH); mVolume = new LLVolume(volume_params, mDetail); mVolume->createVolumeFacesFromStream(buffer_stream); } -- cgit v1.2.3 From 1c495c56c1011f4514d96b75cbcfb5a8256de78f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 5 Nov 2009 17:12:18 -0600 Subject: Fix for crash on teleport to mesh enabled region. Fix for flashing meshes on LOD switch. --- indra/newview/pipeline.cpp | 47 ++++++++++++++++++++++++++++++++++++++++------ 1 file changed, 41 insertions(+), 6 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 1a1d29ac32..4ac95fa939 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8902,33 +8902,68 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() } -void LLPipeline::loadMesh(LLVOVolume* volume, LLUUID mesh_id) +void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) { - { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id); if (iter != mLoadingMeshes.end()) { //request pending for this mesh, append volume id to list - iter->second.insert(volume->getID()); + iter->second.insert(vobj->getID()); return; } //first request for this mesh - mLoadingMeshes[mesh_id].insert(volume->getID()); + mLoadingMeshes[mesh_id].insert(vobj->getID()); } if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH)) { //already have asset, load desired LOD in background - mPendingMeshes.push_back(new LLMeshThread(mesh_id, volume->getVolume())); + mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume())); } else { //fetch asset and load when done gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH, - getMeshAssetCallback, volume->getVolume(), TRUE); + getMeshAssetCallback, vobj->getVolume(), TRUE); } + //do a quick search to see if we can't display something while we wait for this mesh to load + LLVolume* volume = vobj->getVolume(); + + if (volume) + { + LLVolumeParams params = volume->getParams(); + + LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params); + + if (group) + { + //first see what the next lowest LOD available might be + for (S32 i = detail-1; i >= 0; --i) + { + LLVolume* lod = group->refLOD(i); + if (lod && lod->getNumVolumeFaces() > 0) + { + volume->copyVolumeFaces(lod); + group->derefLOD(lod); + return; + } + } + + //no lower LOD is a available, is a higher lod available? + for (S32 i = detail+1; i < 4; ++i) + { + LLVolume* lod = group->refLOD(i); + if (lod && lod->getNumVolumeFaces() > 0) + { + volume->copyVolumeFaces(lod); + group->derefLOD(lod); + return; + } + } + } + } } //static -- cgit v1.2.3 From 10069e0e13e3214ba9320fdce915440b2e12f938 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 5 Nov 2009 19:58:10 -0600 Subject: Fix for prims all being 0 lod. Fix for dangling prim references. --- indra/newview/pipeline.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 4ac95fa939..3554ceb7f0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8949,6 +8949,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); return; } + group->derefLOD(lod); } //no lower LOD is a available, is a higher lod available? @@ -8961,6 +8962,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); return; } + group->derefLOD(lod); } } } -- cgit v1.2.3 From 4e420a36c67e611cd7d85652b43d9cd65315e563 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 7 Nov 2009 08:22:39 -0600 Subject: Fix for missing LOD spam. --- indra/newview/pipeline.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3554ceb7f0..f13bb73acf 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8949,6 +8949,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); return; } + group->derefLOD(lod); } @@ -8962,6 +8963,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); return; } + group->derefLOD(lod); } } -- cgit v1.2.3 From 81bfdcbfae4f203e60f00794966383b01475995b Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 18 Nov 2009 18:10:48 -0600 Subject: Tetrahedron displays in place of unloaded mesh. Still has some LOD issues. --- indra/newview/pipeline.cpp | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index c262e94ff4..3410ad6559 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8976,6 +8976,9 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); } } + + //nothing found, so make a tetrahedron + volume->makeTetrahedron(); } } @@ -9102,7 +9105,11 @@ void LLPipeline::notifyLoadedMeshes() if (valid) { - mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); + if (mesh->mVolume->getNumVolumeFaces() > 0) + { + mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); + } + for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); -- cgit v1.2.3 From 62233f22469cdc66042fc7bbbbd367dbb7212fde Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 24 Nov 2009 07:38:04 -0600 Subject: Fix for copying of tetrahedrons in place of mesh LODs. Fix for bad tetrahedron bounding box. Bad fix for simultaneous loading of multiple LODs. --- indra/newview/pipeline.cpp | 50 ++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 3410ad6559..0ee619244b 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8913,23 +8913,29 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) { + + if (detail < 0 || detail > 4) + { + return; + } + { LLMutexLock lock(mMeshMutex); //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes.find(mesh_id); - if (iter != mLoadingMeshes.end()) + mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); + if (iter != mLoadingMeshes[detail].end()) { //request pending for this mesh, append volume id to list iter->second.insert(vobj->getID()); return; } //first request for this mesh - mLoadingMeshes[mesh_id].insert(vobj->getID()); + mLoadingMeshes[detail][mesh_id].insert(vobj->getID()); } if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH)) { //already have asset, load desired LOD in background - mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume())); + mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume(), detail)); } else { //fetch asset and load when done @@ -8952,7 +8958,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) for (S32 i = detail-1; i >= 0; --i) { LLVolume* lod = group->refLOD(i); - if (lod && lod->getNumVolumeFaces() > 0) + if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) { volume->copyVolumeFaces(lod); group->derefLOD(lod); @@ -8966,7 +8972,7 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) for (S32 i = detail+1; i < 4; ++i) { LLVolume* lod = group->refLOD(i); - if (lod && lod->getNumVolumeFaces() > 0) + if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) { volume->copyVolumeFaces(lod); group->derefLOD(lod); @@ -8976,6 +8982,10 @@ void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) group->derefLOD(lod); } } + else + { + llerrs << "WTF?" << llendl; + } //nothing found, so make a tetrahedron volume->makeTetrahedron(); @@ -8992,12 +9002,22 @@ void LLPipeline::getMeshAssetCallback(LLVFS *vfs, } -LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target) +LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail) : LLThread("mesh_loading_thread") { mMeshID = mesh_id; mVolume = NULL; mDetail = target->getDetail(); + + if (detail == -1) + { + mDetailIndex = LLVolumeLODGroup::getVolumeDetailFromScale(target->getDetail()); + } + else + { + mDetailIndex = detail; + } + mTargetVolume = target; } @@ -9073,6 +9093,10 @@ void LLPipeline::notifyLoadedMeshes() for (std::list::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter) { //for each mesh done loading + + + + LLMeshThread* mesh = *iter; if (!mesh->isStopped()) @@ -9081,10 +9105,12 @@ void LLPipeline::notifyLoadedMeshes() continue; } + S32 detail = mesh->mDetailIndex; + //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes.find(mesh->mMeshID); + mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh->mMeshID); - if (mesh->mVolume && obj_iter != mLoadingMeshes.end()) + if (mesh->mVolume && obj_iter != mLoadingMeshes[detail].end()) { //make sure target volume is still valid BOOL valid = FALSE; @@ -9109,6 +9135,10 @@ void LLPipeline::notifyLoadedMeshes() { mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); } + else + { + llwarns << "Mesh loading returned empty volume." << llendl; + } for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { @@ -9120,7 +9150,7 @@ void LLPipeline::notifyLoadedMeshes() } } - mLoadingMeshes.erase(mesh->mMeshID); + mLoadingMeshes[detail].erase(mesh->mMeshID); } delete mesh; -- cgit v1.2.3 From 6d66910c6e2fbb25bf8b5c7b90e795f350342104 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 25 Nov 2009 11:35:41 -0600 Subject: Fix for spam on invalid mesh asset. Fix for index buffer overflow spam and crash in llvertexbuffer. --- indra/newview/pipeline.cpp | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0ee619244b..af3a35615c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1807,8 +1807,6 @@ void LLPipeline::rebuildPriorityGroups() assertInitialized(); - notifyLoadedMeshes(); - // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) @@ -1888,6 +1886,8 @@ void LLPipeline::updateGeom(F32 max_dtime) // for now, only LLVOVolume does this to throttle LOD changes LLVOVolume::preUpdateGeom(); + notifyLoadedMeshes(); + // Iterate through all drawables on the priority build queue, for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); iter != mBuildQ1.end();) @@ -8913,7 +8913,6 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) { - if (detail < 0 || detail > 4) { return; @@ -9093,10 +9092,6 @@ void LLPipeline::notifyLoadedMeshes() for (std::list::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter) { //for each mesh done loading - - - - LLMeshThread* mesh = *iter; if (!mesh->isStopped()) @@ -9131,14 +9126,13 @@ void LLPipeline::notifyLoadedMeshes() if (valid) { - if (mesh->mVolume->getNumVolumeFaces() > 0) - { - mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); - } - else + if (mesh->mVolume->getNumVolumeFaces() <= 0) { llwarns << "Mesh loading returned empty volume." << llendl; + mesh->mVolume->makeTetrahedron(); } + + mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) { -- cgit v1.2.3 From 695969c77066de5032bdc9caefecf9b32b076b2f Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 11 Dec 2009 14:47:11 -0600 Subject: HTTP Mesh fetch FTW.. still busted --- indra/newview/pipeline.cpp | 255 +-------------------------------------------- 1 file changed, 4 insertions(+), 251 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 610804c5eb..b37645d2de 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -70,6 +70,7 @@ #include "llgldbg.h" #include "llhudmanager.h" #include "lllightconstants.h" +#include "llmeshrepository.h" #include "llresmgr.h" #include "llselectmgr.h" #include "llsky.h" @@ -103,6 +104,7 @@ #include "llspatialpartition.h" #include "llmutelist.h" #include "lltoolpie.h" +#include "llcurl.h" #ifdef _DEBUG @@ -342,8 +344,6 @@ LLPipeline::LLPipeline() : mGlowPool(NULL), mBumpPool(NULL), mWLSkyPool(NULL), - mMeshMutex(NULL), - mMeshThreadCount(0), mLightMask(0), mLightMovingMask(0), mLightingDetail(0), @@ -403,7 +403,6 @@ void LLPipeline::init() stop_glerror(); - mMeshMutex = new LLMutex(NULL); for (U32 i = 0; i < 2; ++i) { mSpotLightFade[i] = 1.f; @@ -478,9 +477,6 @@ void LLPipeline::cleanup() //delete mWLSkyPool; mWLSkyPool = NULL; - delete mMeshMutex; - mMeshMutex = NULL; - releaseGLBuffers(); mBloomImagep = NULL; @@ -1802,6 +1798,8 @@ void LLPipeline::rebuildPriorityGroups() assertInitialized(); + gMeshRepo.notifyLoadedMeshes(); + // Iterate through all drawables on the priority build queue, for (LLSpatialGroup::sg_list_t::iterator iter = mGroupQ1.begin(); iter != mGroupQ1.end(); ++iter) @@ -1881,8 +1879,6 @@ void LLPipeline::updateGeom(F32 max_dtime) // for now, only LLVOVolume does this to throttle LOD changes LLVOVolume::preUpdateGeom(); - notifyLoadedMeshes(); - // Iterate through all drawables on the priority build queue, for (LLDrawable::drawable_list_t::iterator iter = mBuildQ1.begin(); iter != mBuildQ1.end();) @@ -8912,246 +8908,3 @@ LLCullResult::sg_list_t::iterator LLPipeline::endAlphaGroups() } -void LLPipeline::loadMesh(LLVOVolume* vobj, LLUUID mesh_id, S32 detail) -{ - if (detail < 0 || detail > 4) - { - return; - } - - { - LLMutexLock lock(mMeshMutex); - //add volume to list of loading meshes - mesh_load_map::iterator iter = mLoadingMeshes[detail].find(mesh_id); - if (iter != mLoadingMeshes[detail].end()) - { //request pending for this mesh, append volume id to list - iter->second.insert(vobj->getID()); - return; - } - - //first request for this mesh - mLoadingMeshes[detail][mesh_id].insert(vobj->getID()); - } - - if (gAssetStorage->hasLocalAsset(mesh_id, LLAssetType::AT_MESH)) - { //already have asset, load desired LOD in background - mPendingMeshes.push_back(new LLMeshThread(mesh_id, vobj->getVolume(), detail)); - } - else - { //fetch asset and load when done - gAssetStorage->getAssetData(mesh_id, LLAssetType::AT_MESH, - getMeshAssetCallback, vobj->getVolume(), TRUE); - } - - //do a quick search to see if we can't display something while we wait for this mesh to load - LLVolume* volume = vobj->getVolume(); - - if (volume) - { - LLVolumeParams params = volume->getParams(); - - LLVolumeLODGroup* group = LLPrimitive::getVolumeManager()->getGroup(params); - - if (group) - { - //first see what the next lowest LOD available might be - for (S32 i = detail-1; i >= 0; --i) - { - LLVolume* lod = group->refLOD(i); - if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) - { - volume->copyVolumeFaces(lod); - group->derefLOD(lod); - return; - } - - group->derefLOD(lod); - } - - //no lower LOD is a available, is a higher lod available? - for (S32 i = detail+1; i < 4; ++i) - { - LLVolume* lod = group->refLOD(i); - if (lod && !lod->isTetrahedron() && lod->getNumVolumeFaces() > 0) - { - volume->copyVolumeFaces(lod); - group->derefLOD(lod); - return; - } - - group->derefLOD(lod); - } - } - else - { - llerrs << "WTF?" << llendl; - } - - //nothing found, so make a tetrahedron - volume->makeTetrahedron(); - } -} - -//static -void LLPipeline::getMeshAssetCallback(LLVFS *vfs, - const LLUUID& asset_uuid, - LLAssetType::EType type, - void* user_data, S32 status, LLExtStat ext_status) -{ - gPipeline.mPendingMeshes.push_back(new LLMeshThread(asset_uuid, (LLVolume*) user_data)); -} - - -LLPipeline::LLMeshThread::LLMeshThread(LLUUID mesh_id, LLVolume* target, S32 detail) -: LLThread("mesh_loading_thread") -{ - mMeshID = mesh_id; - mVolume = NULL; - mDetail = target->getDetail(); - - if (detail == -1) - { - mDetailIndex = LLVolumeLODGroup::getVolumeDetailFromScale(target->getDetail()); - } - else - { - mDetailIndex = detail; - } - - mTargetVolume = target; -} - -LLPipeline::LLMeshThread::~LLMeshThread() -{ - -} - -void LLPipeline::LLMeshThread::run() -{ - if (!gAssetStorage || LLApp::instance()->isQuitting()) - { - return; - } - - char* buffer = NULL; - S32 size = 0; - - LLVFS* vfs = gAssetStorage->mVFS; - - { - LLVFile file(vfs, mMeshID, LLAssetType::AT_MESH, LLVFile::READ); - file.waitForLock(VFSLOCK_READ); - size = file.getSize(); - - if (size == 0) - { - gPipeline.meshLoaded(this); - return; - } - - buffer = new char[size]; - file.read((U8*)&buffer[0], size); - } - - { - std::string buffer_string(buffer, size); - std::istringstream buffer_stream(buffer_string); - - { - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - volume_params.setSculptID(mMeshID, LL_SCULPT_TYPE_MESH); - mVolume = new LLVolume(volume_params, mDetail); - mVolume->createVolumeFacesFromStream(buffer_stream); - } - } - delete[] buffer; - - gPipeline.meshLoaded(this); -} - -void LLPipeline::meshLoaded(LLPipeline::LLMeshThread* mesh_thread) -{ - LLMutexLock lock(mMeshMutex); - mLoadedMeshes.push_back(mesh_thread); -} - -void LLPipeline::notifyLoadedMeshes() -{ //called from main thread - - U32 max_thread_count = llmax(gSavedSettings.getU32("MeshThreadCount"), (U32) 1); - while (mMeshThreadCount < max_thread_count && !mPendingMeshes.empty()) - { - LLMeshThread* mesh_thread = mPendingMeshes.front(); - mesh_thread->start(); - ++mMeshThreadCount; - mPendingMeshes.pop_front(); - } - - LLMutexLock lock(mMeshMutex); - std::list stopping_threads; - - for (std::list::iterator iter = mLoadedMeshes.begin(); iter != mLoadedMeshes.end(); ++iter) - { //for each mesh done loading - LLMeshThread* mesh = *iter; - - if (!mesh->isStopped()) - { //don't process a LLMeshThread until it's stopped - stopping_threads.push_back(mesh); - continue; - } - - S32 detail = mesh->mDetailIndex; - - //get list of objects waiting to be notified this mesh is loaded - mesh_load_map::iterator obj_iter = mLoadingMeshes[detail].find(mesh->mMeshID); - - if (mesh->mVolume && obj_iter != mLoadingMeshes[detail].end()) - { - //make sure target volume is still valid - BOOL valid = FALSE; - - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) - { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); - - if (vobj) - { - if (vobj->getVolume() == mesh->mTargetVolume) - { - valid = TRUE; - } - } - } - - - if (valid) - { - if (mesh->mVolume->getNumVolumeFaces() <= 0) - { - llwarns << "Mesh loading returned empty volume." << llendl; - mesh->mVolume->makeTetrahedron(); - } - - mesh->mTargetVolume->copyVolumeFaces(mesh->mVolume); - - for (std::set::iterator vobj_iter = obj_iter->second.begin(); vobj_iter != obj_iter->second.end(); ++vobj_iter) - { - LLVOVolume* vobj = (LLVOVolume*) gObjectList.findObject(*vobj_iter); - if (vobj) - { - vobj->notifyMeshLoaded(); - } - } - } - - mLoadingMeshes[detail].erase(mesh->mMeshID); - } - - delete mesh; - --mMeshThreadCount; - } - - mLoadedMeshes = stopping_threads; -} - -- cgit v1.2.3 From c6aaf115ade4b335df9ca479992b08e028ffd910 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 16 Dec 2009 09:26:53 -0600 Subject: Quick 'n dirty prioritization scheme for mesh loading. Sprinkling of fast timers in areas that are likely to stall. --- indra/newview/pipeline.cpp | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b37645d2de..cac266a683 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1143,9 +1143,15 @@ void LLPipeline::allocDrawable(LLViewerObject *vobj) } +static LLFastTimer::DeclareTimer FTM_UNLINK("Unlink"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_MOVE_LIST("Movelist"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_SPATIAL_PARTITION("Spatial Partition"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_LIGHT_SET("Light Set"); +static LLFastTimer::DeclareTimer FTM_REMOVE_FROM_HIGHLIGHT_SET("Highlight Set"); + void LLPipeline::unlinkDrawable(LLDrawable *drawable) { - LLFastTimer t(FTM_PIPELINE); + LLFastTimer t(FTM_UNLINK); assertInitialized(); @@ -1154,6 +1160,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) // Based on flags, remove the drawable from the queues that it's on. if (drawablep->isState(LLDrawable::ON_MOVE_LIST)) { + LLFastTimer t(FTM_REMOVE_FROM_MOVE_LIST); LLDrawable::drawable_vector_t::iterator iter = std::find(mMovedList.begin(), mMovedList.end(), drawablep); if (iter != mMovedList.end()) { @@ -1163,6 +1170,7 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) if (drawablep->getSpatialGroup()) { + LLFastTimer t(FTM_REMOVE_FROM_SPATIAL_PARTITION); if (!drawablep->getSpatialGroup()->mSpatialPartition->remove(drawablep, drawablep->getSpatialGroup())) { #ifdef LL_RELEASE_FOR_DOWNLOAD @@ -1173,18 +1181,23 @@ void LLPipeline::unlinkDrawable(LLDrawable *drawable) } } - mLights.erase(drawablep); - for (light_set_t::iterator iter = mNearbyLights.begin(); - iter != mNearbyLights.end(); iter++) { - if (iter->drawable == drawablep) + LLFastTimer t(FTM_REMOVE_FROM_LIGHT_SET); + mLights.erase(drawablep); + + for (light_set_t::iterator iter = mNearbyLights.begin(); + iter != mNearbyLights.end(); iter++) { - mNearbyLights.erase(iter); - break; + if (iter->drawable == drawablep) + { + mNearbyLights.erase(iter); + break; + } } } { + LLFastTimer t(FTM_REMOVE_FROM_HIGHLIGHT_SET); HighlightItem item(drawablep); mHighlightSet.erase(item); -- cgit v1.2.3 From c3b37faba3cba425d749345a978ddec16bbd1338 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 28 Jan 2010 16:20:06 -0800 Subject: first dribble of directional lights for shaderless path. --- indra/newview/pipeline.cpp | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d66662ed49..bced8a8e07 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4596,8 +4596,22 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); glLightf (gllight, GL_LINEAR_ATTENUATION, atten); glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); - glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + if (light->getLightTexture()) // directional (spot-)light + { + LLVector3 spotparams = light->getSpotLightParams(); + LLQuaternion quat = light->getRenderRotation(); + LLVector3 at_axis(0,0,-1); // todo: verify against deferred + at_axis *= quat; + llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; + glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); + glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); // fixme - focus + glLightf (gllight, GL_SPOT_CUTOFF, 22.0f); // fixme - fov + } + else // omnidirectional (point) light + { + glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); + glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + } cur_light++; if (cur_light >= 8) { @@ -4613,7 +4627,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); } - if (gAgent.getAvatarObject() && gAgent.getAvatarObject()->mSpecialRenderMode == 3) { -- cgit v1.2.3 From cf3df7968ef654ba7cafeafd463e7107b80ca07f Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 28 Jan 2010 18:21:33 -0800 Subject: woo, dumb GL lights now match up to our dumb shader model pretty well. next: shader model needs to grok point vs directional, shader model needs to resurrect ambient which I seem to have broken --- indra/newview/pipeline.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index bced8a8e07..71f9ce7eb2 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4284,7 +4284,7 @@ void LLPipeline::setupAvatarLights(BOOL for_edit) glLightf (GL_LIGHT1, GL_LINEAR_ATTENUATION, 0.0f); glLightf (GL_LIGHT1, GL_QUADRATIC_ATTENUATION, 0.0f); glLightf (GL_LIGHT1, GL_SPOT_EXPONENT, 0.0f); - glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); + glLightf (GL_LIGHT1, GL_SPOT_CUTOFF, 180.0f); } else if (gAvatarBacklight) // Always true (unless overridden in a devs .ini) { @@ -4600,12 +4600,12 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) { LLVector3 spotparams = light->getSpotLightParams(); LLQuaternion quat = light->getRenderRotation(); - LLVector3 at_axis(0,0,-1); // todo: verify against deferred + LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction at_axis *= quat; llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); - glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); // fixme - focus - glLightf (gllight, GL_SPOT_CUTOFF, 22.0f); // fixme - fov + glLightf (gllight, GL_SPOT_EXPONENT, 1.0f); // 1.0 = good old dot product + glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere } else // omnidirectional (point) light { -- cgit v1.2.3 From f773b6ef9669bab6765678f8b07831144dd44a5e Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 28 Jan 2010 18:50:10 -0800 Subject: cheaply resurrect the difference between spotlight and omnidirectional, as far as the shader is concerned. not complete. --- indra/newview/pipeline.cpp | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 71f9ce7eb2..6cd8b94405 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4592,7 +4592,6 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightfv(gllight, GL_POSITION, light_pos_gl.mV); glLightfv(gllight, GL_DIFFUSE, light_color.mV); glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); glLightf (gllight, GL_LINEAR_ATTENUATION, atten); glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); @@ -4606,11 +4605,16 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); glLightf (gllight, GL_SPOT_EXPONENT, 1.0f); // 1.0 = good old dot product glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere + glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); } else // omnidirectional (point) light { glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); + + // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight + const float specular = {0.f, 0.f, 0.f, 1.f}, + glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); } cur_light++; if (cur_light >= 8) -- cgit v1.2.3 From bc0a9fd5fe0675d7327ee182ff4ac20c39e76305 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 28 Jan 2010 21:48:22 -0800 Subject: getting closer to point/spot interchangability --- indra/newview/pipeline.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6cd8b94405..e12412c58c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4613,8 +4613,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight - const float specular = {0.f, 0.f, 0.f, 1.f}, - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); + const float specular[] = {0.f, 0.f, 0.f, 1.f}; + glLightfv(gllight, GL_SPECULAR, specular); } cur_light++; if (cur_light >= 8) -- cgit v1.2.3 From fcaca49a9496154419a8f44c17cba16b028d3518 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Thu, 28 Jan 2010 23:58:50 -0800 Subject: cheap no-branch goodness for rendering both spotlights and pointlights with the same shader code. kill already-nerfed quadratic attenuation which it seems we won't be supporting any decade soon. --- indra/newview/pipeline.cpp | 42 +++++++++++++++--------------------------- 1 file changed, 15 insertions(+), 27 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e12412c58c..2ad0bad11f 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4572,40 +4572,30 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos_gl(light_pos, 1.0f); F32 light_radius = llmax(light->getLightRadius(), 0.001f); - F32 atten, quad; -#if 0 //1.9.1 - if (pool->getVertexShaderLevel() > 0) - { - atten = light_radius; - quad = llmax(light->getLightFalloff(), 0.0001f); - } - else -#endif - { - F32 x = (3.f * (1.f + light->getLightFalloff())); - atten = x / (light_radius); // % of brightness at radius - quad = 0.0f; - } + F32 x = (3.f * (1.f + light->getLightFalloff())); + float linatten = x / (light_radius); // % of brightness at radius + mHWLightColors[cur_light] = light_color; S32 gllight = GL_LIGHT0+cur_light; glLightfv(gllight, GL_POSITION, light_pos_gl.mV); glLightfv(gllight, GL_DIFFUSE, light_color.mV); glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, atten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); + glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); + glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); if (light->getLightTexture()) // directional (spot-)light { LLVector3 spotparams = light->getSpotLightParams(); LLQuaternion quat = light->getRenderRotation(); LLVector3 at_axis(0,0,-1); // this matches deferred rendering's object light direction at_axis *= quat; - llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; + //llinfos << "SPOT!!!!!!! fov: " << spotparams.mV[0] << " focus: " << spotparams.mV[1] << " dir: " << at_axis << llendl; glLightfv(gllight, GL_SPOT_DIRECTION, at_axis.mV); - glLightf (gllight, GL_SPOT_EXPONENT, 1.0f); // 1.0 = good old dot product + glLightf (gllight, GL_SPOT_EXPONENT, 2.0f); // 2.0 = good old dot product ^ 2 glLightf (gllight, GL_SPOT_CUTOFF, 90.0f); // hemisphere - glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); + const float specular[] = {0.f, 0.f, 0.f, 0.f}; + glLightfv(gllight, GL_SPECULAR, specular); } else // omnidirectional (point) light { @@ -4615,6 +4605,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) // we use specular.w = 1.0 as a cheap hack for the shaders to know that this is omnidirectional rather than a spotlight const float specular[] = {0.f, 0.f, 0.f, 1.f}; glLightfv(gllight, GL_SPECULAR, specular); + //llinfos << "boring light" << llendl; } cur_light++; if (cur_light >= 8) @@ -4641,13 +4632,10 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) LLVector4 light_pos_gl(light_pos, 1.0f); F32 light_radius = 16.f; - F32 atten, quad; - { - F32 x = 3.f; - atten = x / (light_radius); // % of brightness at radius - quad = 0.0f; - } + F32 x = 3.f; + float linatten = x / (light_radius); // % of brightness at radius + mHWLightColors[2] = light_color; S32 gllight = GL_LIGHT2; glLightfv(gllight, GL_POSITION, light_pos_gl.mV); @@ -4655,8 +4643,8 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightfv(gllight, GL_AMBIENT, LLColor4::black.mV); glLightfv(gllight, GL_SPECULAR, LLColor4::black.mV); glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); - glLightf (gllight, GL_LINEAR_ATTENUATION, atten); - glLightf (gllight, GL_QUADRATIC_ATTENUATION, quad); + glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); + glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); glLightf (gllight, GL_SPOT_EXPONENT, 0.0f); glLightf (gllight, GL_SPOT_CUTOFF, 180.0f); } -- cgit v1.2.3 From e8899c4f4c2ae95f108b9bbf543e401debc9c588 Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Mon, 1 Feb 2010 17:29:08 +0000 Subject: start to abstract-out the 'is a spotlight' question so one day we can perhaps make the UI hurt less. --- indra/newview/pipeline.cpp | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 2ad0bad11f..cb0baf77f1 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4584,7 +4584,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) glLightf (gllight, GL_CONSTANT_ATTENUATION, 0.0f); glLightf (gllight, GL_LINEAR_ATTENUATION, linatten); glLightf (gllight, GL_QUADRATIC_ATTENUATION, 0.0f); - if (light->getLightTexture()) // directional (spot-)light + if (light->isLightSpotlight()) // directional (spot-)light { LLVector3 spotparams = light->getSpotLightParams(); LLQuaternion quat = light->getRenderRotation(); @@ -6693,7 +6693,7 @@ void LLPipeline::renderDeferredLighting() { //draw box if camera is outside box if (render_local) { - if (volume->getLightTexture()) + if (volume->isLightSpotlight()) { drawablep->getVOVolume()->updateSpotLightPriority(); spot_lights.push_back(drawablep); @@ -6710,7 +6710,7 @@ void LLPipeline::renderDeferredLighting() } else if (render_fullscreen) { - if (volume->getLightTexture()) + if (volume->isLightSpotlight()) { drawablep->getVOVolume()->updateSpotLightPriority(); fullscreen_spot_lights.push_back(drawablep); -- cgit v1.2.3 From 3dc32880ae0f2f0f5499a7f271df666759fc220a Mon Sep 17 00:00:00 2001 From: Tofu Linden Date: Mon, 1 Feb 2010 17:50:55 +0000 Subject: const fix. --- indra/newview/pipeline.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cb0baf77f1..b25c7c9212 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4573,7 +4573,7 @@ void LLPipeline::setupHWLights(LLDrawPool* pool) F32 light_radius = llmax(light->getLightRadius(), 0.001f); - F32 x = (3.f * (1.f + light->getLightFalloff())); + F32 x = (3.f * (1.f + light->getLightFalloff())); // why this magic? probably trying to match a historic behavior. float linatten = x / (light_radius); // % of brightness at radius mHWLightColors[cur_light] = light_color; -- cgit v1.2.3 From 095a5e84408b47ef3c5610e111aefe51d77633ca Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 6 Feb 2010 17:33:12 -0600 Subject: Draw prims using triangle strips instead of triangle lists. --- indra/newview/pipeline.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) (limited to 'indra/newview/pipeline.cpp') diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index d5f87b73fe..91da9e39e0 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -270,6 +270,7 @@ BOOL LLPipeline::sDelayVBUpdate = TRUE; BOOL LLPipeline::sFastAlpha = TRUE; BOOL LLPipeline::sDisableShaders = FALSE; BOOL LLPipeline::sRenderBump = TRUE; +BOOL LLPipeline::sUseTriStrips = TRUE; BOOL LLPipeline::sUseFarClip = TRUE; BOOL LLPipeline::sShadowRender = FALSE; BOOL LLPipeline::sWaterReflections = FALSE; @@ -358,6 +359,7 @@ void LLPipeline::init() sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -3495,9 +3497,19 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) } -void LLPipeline::addTrianglesDrawn(S32 count) +void LLPipeline::addTrianglesDrawn(S32 index_count, U32 render_type) { assertInitialized(); + S32 count = 0; + if (render_type == LLRender::TRIANGLE_STRIP) + { + count = index_count-2; + } + else + { + count = index_count/3; + } + mTrianglesDrawn += count; mBatchCount++; mMaxBatchSize = llmax(mMaxBatchSize, count); @@ -5349,6 +5361,7 @@ void LLPipeline::resetVertexBuffers(LLDrawable* drawable) void LLPipeline::resetVertexBuffers() { sRenderBump = gSavedSettings.getBOOL("RenderObjectBump"); + sUseTriStrips = gSavedSettings.getBOOL("RenderUseTriStrips"); for (LLWorld::region_list_t::const_iterator iter = LLWorld::getInstance()->getRegionList().begin(); iter != LLWorld::getInstance()->getRegionList().end(); ++iter) -- cgit v1.2.3