master
Ansariel 2022-02-02 10:03:48 +01:00
commit ccb078ae08
17 changed files with 238 additions and 101 deletions

View File

@ -2112,6 +2112,8 @@ set(viewer_APPSETTINGS_FILES
${CMAKE_SOURCE_DIR}/../etc/message.xml
${CMAKE_SOURCE_DIR}/../scripts/messages/message_template.msg
packages-info.txt
featuretable.txt
featuretable_mac.txt
)
if (WINDOWS)

View File

@ -12852,7 +12852,7 @@ Change of this parameter will affect the layout of buttons in notification toast
<key>Value</key>
<real>2.2</real>
</map>
<key>RenderGLCoreProfile</key>
<key>RenderGLContextCoreProfile</key>
<map>
<key>Comment</key>
<string>Don't use a compatibility profile OpenGL context. Requires restart.</string>

View File

@ -70,7 +70,7 @@ RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLCoreProfile 1 1
RenderGLContextCoreProfile 1 1
RenderGLMultiThreaded 1 1
@ -314,12 +314,12 @@ list Intel
RenderAnisotropic 1 0
RenderFSAASamples 1 0
RenderGLMultiThreaded 1 0
RenderGLCoreProfile 1 0
RenderGLContextCoreProfile 1 0
// AMD cards generally perform better when not using VBOs for streaming data
// AMD cards also prefer an OpenGL Compatibility Profile Context
list AMD
RenderUseStreamVBO 1 0
RenderGLCoreProfile 1 0
RenderGLContextCoreProfile 1 0

View File

@ -70,7 +70,7 @@ RenderShadowDetail 1 2
RenderUseStreamVBO 1 1
RenderFSAASamples 1 16
RenderMaxTextureIndex 1 16
RenderGLCoreProfile 1 0
RenderGLContextCoreProfile 1 0
RenderGLMultiThreaded 1 0
//

View File

@ -607,7 +607,7 @@ static void settings_to_globals()
LLSurface::setTextureSize(gSavedSettings.getU32("RegionTextureSize"));
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLCoreProfile");
LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile");
LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport");
// <FS:Ansariel> Vertex Array Objects are required in OpenGL core profile
LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO");

View File

@ -183,6 +183,7 @@ public:
PASS_GLOW,
PASS_GLOW_RIGGED,
PASS_ALPHA,
PASS_ALPHA_RIGGED,
PASS_ALPHA_MASK,
PASS_ALPHA_MASK_RIGGED,
PASS_FULLBRIGHT_ALPHA_MASK, // Diffuse texture used as alpha mask and fullbright

View File

@ -130,23 +130,26 @@ void LLDrawPoolAlpha::renderPostDeferred(S32 pass)
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
deferred_render = TRUE;
// first pass, regular forward alpha rendering
{
emissive_shader = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
prepare_alpha_shader(emissive_shader, true, false);
// prepare shaders
emissive_shader = (LLPipeline::sUnderWaterRender) ? &gObjectEmissiveWaterProgram : &gObjectEmissiveProgram;
prepare_alpha_shader(emissive_shader, true, false);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
prepare_alpha_shader(fullbright_shader, true, false);
fullbright_shader = (LLPipeline::sImpostorRender) ? &gDeferredFullbrightProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredFullbrightWaterProgram : &gDeferredFullbrightProgram;
prepare_alpha_shader(fullbright_shader, true, false);
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
forwardRender();
}
simple_shader = (LLPipeline::sImpostorRender) ? &gDeferredAlphaImpostorProgram :
(LLPipeline::sUnderWaterRender) ? &gDeferredAlphaWaterProgram : &gDeferredAlphaProgram;
prepare_alpha_shader(simple_shader, false, true); //prime simple shader (loads shadow relevant uniforms)
// second pass, render to depth for depth of field effects
// first pass, render rigged objects only and render to depth buffer
forwardRender(true);
// second pass, regular forward alpha rendering
forwardRender();
// final pass, render to depth for depth of field effects
if (!LLPipeline::sImpostorRender && gSavedSettings.getBOOL("RenderDepthOfField"))
{
//update depth buffer sampler
@ -210,10 +213,14 @@ void LLDrawPoolAlpha::render(S32 pass)
prepare_forward_shader(fullbright_shader, minimum_alpha);
prepare_forward_shader(simple_shader, minimum_alpha);
//first pass -- rigged only and drawn to depth buffer
forwardRender(true);
//second pass -- non-rigged, no depth buffer writes
forwardRender();
}
void LLDrawPoolAlpha::forwardRender()
void LLDrawPoolAlpha::forwardRender(bool rigged)
{
gPipeline.enableLightsDynamic();
@ -222,7 +229,8 @@ void LLDrawPoolAlpha::forwardRender()
//enable writing to alpha for emissive effects
gGL.setColorMask(true, true);
bool write_depth = LLDrawPoolWater::sSkipScreenCopy
bool write_depth = rigged
|| LLDrawPoolWater::sSkipScreenCopy
// we want depth written so that rendered alpha will
// contribute to the alpha mask used for impostors
|| LLPipeline::sImpostorRenderAlphaDepthPass;
@ -237,11 +245,17 @@ void LLDrawPoolAlpha::forwardRender()
// If the face is more than 90% transparent, then don't update the Depth buffer for Dof
// We don't want the nearly invisible objects to cause of DoF effects
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2);
renderAlpha(getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, false, rigged);
gGL.setColorMask(true, false);
renderDebugAlpha();
if (!rigged)
{ //render "highlight alpha" on final non-rigged pass
// NOTE -- hacky call here protected by !rigged instead of alongside "forwardRender"
// so renderDebugAlpha is executed while gls_pipeline_alpha and depth GL state
// variables above are still in scope
renderDebugAlpha();
}
}
void LLDrawPoolAlpha::renderDebugAlpha()
@ -293,65 +307,71 @@ void LLDrawPoolAlpha::renderDebugAlpha()
void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask)
{
LL_PROFILE_ZONE_SCOPED;
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
for (int pass = 0; pass < 2; ++pass)
{ //two passes, one rigged and one not
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
{
LLSpatialGroup* group = *i;
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
LLCullResult::sg_iterator begin = pass == 0 ? gPipeline.beginAlphaGroups() : gPipeline.beginRiggedAlphaGroups();
LLCullResult::sg_iterator end = pass == 0 ? gPipeline.endAlphaGroups() : gPipeline.endRiggedAlphaGroups();
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LLDrawInfo& params = **k;
// <FS:Beq> Capture render times
if(params.mFace)
{
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
{
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
}
// </FS:Beq>
if (params.mParticle)
{
continue;
}
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
LLSpatialGroup* group = *i;
if (group->getSpatialPartition()->mRenderByGroup &&
!group->isDead())
{
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA+pass]; // <-- hacky + pass to use PASS_ALPHA_RIGGED on second pass
bool rigged = (params.mAvatar != nullptr);
gHighlightProgram.bind(rigged);
gGL.diffuseColor4f(1, 0, 0, 1);
if (rigged)
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
if (lastAvatar != params.mAvatar ||
lastMeshId != params.mSkinInfo->mHash)
LLDrawInfo& params = **k;
// <FS:Beq> Capture render times
if(params.mFace)
{
if (!uploadMatrixPalette(params))
LLViewerObject* vobj = (LLViewerObject *)params.mFace->getViewerObject();
if(vobj->isAttachment())
{
continue;
trackAttachments( vobj, params.mFace->isState(LLFace::RIGGED), &ratPtr );
}
lastAvatar = params.mAvatar;
lastMeshId = params.mSkinInfo->mHash;
}
}
// </FS:Beq>
LLRenderPass::applyModelMatrix(params);
if (params.mGroup)
{
params.mGroup->rebuildMesh();
}
params.mVertexBuffer->setBufferFast(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
}
if (params.mParticle)
{
continue;
}
bool rigged = (params.mAvatar != nullptr);
gHighlightProgram.bind(rigged);
gGL.diffuseColor4f(1, 0, 0, 1);
if (rigged)
{
if (lastAvatar != params.mAvatar ||
lastMeshId != params.mSkinInfo->mHash)
{
if (!uploadMatrixPalette(params))
{
continue;
}
lastAvatar = params.mAvatar;
lastMeshId = params.mSkinInfo->mHash;
}
}
LLRenderPass::applyModelMatrix(params);
if (params.mGroup)
{
params.mGroup->rebuildMesh();
}
params.mVertexBuffer->setBufferFast(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask);
params.mVertexBuffer->drawRangeFast(params.mDrawMode, params.mStart, params.mEnd, params.mCount, params.mOffset);
}
}
}
}
// make sure static version of highlight shader is bound before returning
gHighlightProgram.bind();
@ -484,6 +504,8 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
LLVOAvatar* lastAvatar = nullptr;
U64 lastMeshId = 0;
mask |= LLVertexBuffer::MAP_WEIGHT4;
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
for (LLDrawInfo* draw : emissives)
{
@ -511,7 +533,7 @@ void LLDrawPoolAlpha::renderRiggedEmissives(U32 mask, std::vector<LLDrawInfo*>&
}
}
void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only)
void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged)
{
LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL;
BOOL initialized_lighting = FALSE;
@ -521,7 +543,21 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only)
U64 lastMeshId = 0;
LLGLSLShader* lastAvatarShader = nullptr;
for (LLCullResult::sg_iterator i = gPipeline.beginAlphaGroups(); i != gPipeline.endAlphaGroups(); ++i)
LLCullResult::sg_iterator begin;
LLCullResult::sg_iterator end;
if (rigged)
{
begin = gPipeline.beginRiggedAlphaGroups();
end = gPipeline.endRiggedAlphaGroups();
}
else
{
begin = gPipeline.beginAlphaGroups();
end = gPipeline.endAlphaGroups();
}
for (LLCullResult::sg_iterator i = begin; i != end; ++i)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("renderAlpha - group");
LLSpatialGroup* group = *i;
@ -553,13 +589,19 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only)
bool disable_cull = is_particle_or_hud_particle;
LLGLDisable cull(disable_cull ? GL_CULL_FACE : 0);
LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[LLRenderPass::PASS_ALPHA];
LLSpatialGroup::drawmap_elem_t& draw_info = rigged ? group->mDrawMap[LLRenderPass::PASS_ALPHA_RIGGED] : group->mDrawMap[LLRenderPass::PASS_ALPHA];
std::unique_ptr<FSPerfStats::RecordAttachmentTime> ratPtr{}; // <FS:Beq/> Render time Stats collection
for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k)
{
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch")
LLDrawInfo& params = **k;
if ((bool)params.mAvatar != rigged)
{
continue;
}
LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch")
U32 have_mask = params.mVertexBuffer->getTypeMask() & mask;
if (have_mask != mask)
{ //FIXME!

View File

@ -55,13 +55,13 @@ public:
/*virtual*/ S32 getNumPasses() { return 1; }
virtual void render(S32 pass = 0);
void forwardRender();
void forwardRender(bool write_depth = false);
/*virtual*/ void prerender();
void renderDebugAlpha();
void renderGroupAlpha(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE);
void renderAlpha(U32 mask, bool depth_only = false);
void renderAlpha(U32 mask, bool depth_only = false, bool rigged = false);
void renderAlphaHighlight(U32 mask);
bool uploadMatrixPalette(const LLDrawInfo& params);

View File

@ -526,9 +526,10 @@ void LLDrawPoolWater::renderWater()
LLColor4 specular(sun_up ? psky->getSunlightColor() : psky->getMoonlightColor());
F32 phase_time = (F32) LLFrameTimer::getElapsedSeconds() * 0.5f;
bool edge = false;
LLGLSLShader *shader = nullptr;
do // twice through, once with normal shader bound & once with edge shader bound
// two passes, first with standard water shader bound, second with edge water shader bound
for( int edge = 0 ; edge < 2; edge++ )
{
// select shader
if (underwater && LLPipeline::sWaterReflections)
@ -681,7 +682,7 @@ void LLDrawPoolWater::renderWater()
gGL.getTexUnit(diffTex)->bind(face->getTexture());
if (edge == (bool) water->getIsEdgePatch())
if ((bool)edge == (bool) water->getIsEdgePatch())
{
face->renderIndexed();
@ -705,9 +706,7 @@ void LLDrawPoolWater::renderWater()
shader->unbind();
gGL.getTexUnit(bumpTex)->unbind(LLTexUnit::TT_TEXTURE);
gGL.getTexUnit(bumpTex2)->unbind(LLTexUnit::TT_TEXTURE);
edge = !edge;
} while (!edge);
}
gGL.getTexUnit(0)->activate();
gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE);

View File

@ -4222,6 +4222,7 @@ LLCullResult::LLCullResult()
{
mVisibleGroupsAllocated = 0;
mAlphaGroupsAllocated = 0;
mRiggedAlphaGroupsAllocated = 0;
mOcclusionGroupsAllocated = 0;
mDrawableGroupsAllocated = 0;
mVisibleListAllocated = 0;
@ -4233,6 +4234,9 @@ LLCullResult::LLCullResult()
mAlphaGroups.clear();
mAlphaGroups.push_back(NULL);
mAlphaGroupsEnd = &mAlphaGroups[0];
mRiggedAlphaGroups.clear();
mRiggedAlphaGroups.push_back(NULL);
mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0];
mOcclusionGroups.clear();
mOcclusionGroups.push_back(NULL);
mOcclusionGroupsEnd = &mOcclusionGroups[0];
@ -4275,6 +4279,9 @@ void LLCullResult::clear()
mAlphaGroupsSize = 0;
mAlphaGroupsEnd = &mAlphaGroups[0];
mRiggedAlphaGroupsSize = 0;
mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[0];
mOcclusionGroupsSize = 0;
mOcclusionGroupsEnd = &mOcclusionGroups[0];
@ -4319,6 +4326,16 @@ LLCullResult::sg_iterator LLCullResult::endAlphaGroups()
return mAlphaGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginRiggedAlphaGroups()
{
return &mRiggedAlphaGroups[0];
}
LLCullResult::sg_iterator LLCullResult::endRiggedAlphaGroups()
{
return mRiggedAlphaGroupsEnd;
}
LLCullResult::sg_iterator LLCullResult::beginOcclusionGroups()
{
return &mOcclusionGroups[0];
@ -4397,6 +4414,20 @@ void LLCullResult::pushAlphaGroup(LLSpatialGroup* group)
mAlphaGroupsEnd = &mAlphaGroups[mAlphaGroupsSize];
}
void LLCullResult::pushRiggedAlphaGroup(LLSpatialGroup* group)
{
if (mRiggedAlphaGroupsSize < mRiggedAlphaGroupsAllocated)
{
mRiggedAlphaGroups[mRiggedAlphaGroupsSize] = group;
}
else
{
pushBack(mRiggedAlphaGroups, mRiggedAlphaGroupsAllocated, group);
}
++mRiggedAlphaGroupsSize;
mRiggedAlphaGroupsEnd = &mRiggedAlphaGroups[mRiggedAlphaGroupsSize];
}
void LLCullResult::pushOcclusionGroup(LLSpatialGroup* group)
{
if (mOcclusionGroupsSize < mOcclusionGroupsAllocated)

View File

@ -481,6 +481,9 @@ public:
sg_iterator beginAlphaGroups();
sg_iterator endAlphaGroups();
sg_iterator beginRiggedAlphaGroups();
sg_iterator endRiggedAlphaGroups();
bool hasOcclusionGroups() { return mOcclusionGroupsSize > 0; }
sg_iterator beginOcclusionGroups();
sg_iterator endOcclusionGroups();
@ -499,6 +502,7 @@ public:
void pushVisibleGroup(LLSpatialGroup* group);
void pushAlphaGroup(LLSpatialGroup* group);
void pushRiggedAlphaGroup(LLSpatialGroup* group);
void pushOcclusionGroup(LLSpatialGroup* group);
void pushDrawableGroup(LLSpatialGroup* group);
void pushDrawable(LLDrawable* drawable);
@ -507,6 +511,7 @@ public:
U32 getVisibleGroupsSize() { return mVisibleGroupsSize; }
U32 getAlphaGroupsSize() { return mAlphaGroupsSize; }
U32 getRiggedAlphaGroupsSize() { return mRiggedAlphaGroupsSize; }
U32 getDrawableGroupsSize() { return mDrawableGroupsSize; }
U32 getVisibleListSize() { return mVisibleListSize; }
U32 getVisibleBridgeSize() { return mVisibleBridgeSize; }
@ -520,6 +525,7 @@ private:
U32 mVisibleGroupsSize;
U32 mAlphaGroupsSize;
U32 mRiggedAlphaGroupsSize;
U32 mOcclusionGroupsSize;
U32 mDrawableGroupsSize;
U32 mVisibleListSize;
@ -527,6 +533,7 @@ private:
U32 mVisibleGroupsAllocated;
U32 mAlphaGroupsAllocated;
U32 mRiggedAlphaGroupsAllocated;
U32 mOcclusionGroupsAllocated;
U32 mDrawableGroupsAllocated;
U32 mVisibleListAllocated;
@ -538,6 +545,8 @@ private:
sg_iterator mVisibleGroupsEnd;
sg_list_t mAlphaGroups;
sg_iterator mAlphaGroupsEnd;
sg_list_t mRiggedAlphaGroups;
sg_iterator mRiggedAlphaGroupsEnd;
sg_list_t mOcclusionGroups;
sg_iterator mOcclusionGroupsEnd;
sg_list_t mDrawableGroups;

View File

@ -348,9 +348,8 @@ static bool handleAnisotropicChanged(const LLSD& newvalue)
static bool handleVSyncChanged(const LLSD& newvalue)
{
#if LL_WINDOWS
gViewerWindow->getWindow()->toggleVSync(newvalue.asBoolean());
#endif
return true;
}

View File

@ -148,6 +148,9 @@ const F32 MIN_HOVER_Z = -2.0f;
const F32 MIN_ATTACHMENT_COMPLEXITY = 0.f;
const F32 DEFAULT_MAX_ATTACHMENT_COMPLEXITY = 1.0e6f;
// Unlike with 'self' avatar, server doesn't inform viewer about
// expected attachments so viewer has to wait to see if anything
// else will arrive
const F32 FIRST_APPEARANCE_CLOUD_MIN_DELAY = 3.f; // seconds
const F32 FIRST_APPEARANCE_CLOUD_MAX_DELAY = 45.f;
@ -779,7 +782,7 @@ LLVOAvatar::LLVOAvatar(const LLUUID& id,
mCurrentGesticulationLevel = 0;
mFirstSeenTimer.reset();
mFirstAppearanceMessageTimer.reset();
mRuthTimer.reset();
mRuthDebugTimer.reset();
mDebugExistenceTimer.reset();
@ -3037,7 +3040,7 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
//override rigged attachments' octree spatial extents with this avatar's bounding box
LLSpatialBridge* bridge = attached_object->mDrawable->getSpatialBridge();
bool rigged = false;
if (bridge)
if (bridge && !bridge->isDead())
{
//transform avatar bounding box into attachment's coordinate frame
LLVector4a extents[2];
@ -3054,13 +3057,21 @@ void LLVOAvatar::idleUpdateMisc(bool detailed_update)
attached_object->mDrawable->makeActive();
attached_object->mDrawable->updateXform(TRUE);
if (!rigged)
if (bridge && !bridge->isDead())
{
if (bridge)
if (!rigged)
{
gPipeline.updateMoveNormalAsync(bridge);
}
else
{
//specialized impl of updateMoveNormalAsync just for rigged attachment SpatialBridge
bridge->setState(LLDrawable::MOVE_UNDAMPED);
bridge->updateMove();
bridge->setState(LLDrawable::EARLY_MOVE);
}
}
attached_object->updateText();
}
}
@ -7248,6 +7259,16 @@ void LLVOAvatar::updateAttachmentOverrides()
#endif
}
void LLVOAvatar::notifyAttachmentMeshLoaded()
{
if (!isFullyLoaded())
{
// We just received mesh or skin info
// Reset timer to wait for more potential meshes or changes
mFullyLoadedTimer.reset();
}
}
//-----------------------------------------------------------------------------
// addAttachmentOverridesForObject
//-----------------------------------------------------------------------------
@ -9096,7 +9117,7 @@ BOOL LLVOAvatar::processFullyLoadedChange(bool loading)
// Note that textures can causes 60s delay on thier own
// so this delay might end up on top of textures' delay
mFirstUseDelaySeconds = llclamp(
mFirstSeenTimer.getElapsedTimeF32(),
mFirstAppearanceMessageTimer.getElapsedTimeF32(),
FIRST_APPEARANCE_CLOUD_MIN_DELAY,
FIRST_APPEARANCE_CLOUD_MAX_DELAY);
@ -9987,6 +10008,9 @@ void LLVOAvatar::onFirstTEMessageReceived()
mMeshTexturesDirty = TRUE;
gPipeline.markGLRebuild(this);
mFirstAppearanceMessageTimer.reset();
mFullyLoadedTimer.reset();
}
}

View File

@ -211,7 +211,7 @@ public:
inline LLJoint* getSkeletonJoint(S32 joint_num) { return mSkeleton[joint_num]; }
inline size_t getSkeletonJointCount() const { return mSkeleton.size(); }
void notifyAttachmentMeshLoaded();
void addAttachmentOverridesForObject(LLViewerObject *vo, std::set<LLUUID>* meshes_seen = NULL, bool recursive = true);
void removeAttachmentOverridesForObject(const LLUUID& mesh_id);
void removeAttachmentOverridesForObject(LLViewerObject *vo);
@ -411,7 +411,7 @@ protected:
private:
BOOL mFirstFullyVisible;
F32 mFirstUseDelaySeconds;
LLFrameTimer mFirstSeenTimer;
LLFrameTimer mFirstAppearanceMessageTimer;
BOOL mFullyLoaded;
BOOL mPreviousFullyLoaded;

View File

@ -1320,13 +1320,17 @@ void LLVOVolume::notifyMeshLoaded()
mSculptChanged = TRUE;
gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_GEOMETRY, TRUE);
if (getAvatar() && !isAnimatedObject())
LLVOAvatar *av = getAvatar();
if (av && !isAnimatedObject())
{
getAvatar()->addAttachmentOverridesForObject(this);
av->addAttachmentOverridesForObject(this);
av->notifyAttachmentMeshLoaded();
}
if (getControlAvatar() && isAnimatedObject())
LLControlAvatar *cav = getControlAvatar();
if (cav && isAnimatedObject())
{
getControlAvatar()->addAttachmentOverridesForObject(this);
cav->addAttachmentOverridesForObject(this);
cav->notifyAttachmentMeshLoaded();
}
updateVisualComplexity();
}
@ -5404,7 +5408,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep,
bool rigged = facep->isState(LLFace::RIGGED);
if (rigged && type != LLRenderPass::PASS_ALPHA)
if (rigged)
{
// hacky, should probably clean up -- if this face is rigged, put it in "type + 1"
// See LLRenderPass PASS_foo enum

View File

@ -4019,6 +4019,16 @@ void LLPipeline::postSort(LLCamera& camera)
sCull->pushAlphaGroup(group);
}
}
LLSpatialGroup::draw_map_t::iterator rigged_alpha = group->mDrawMap.find(LLRenderPass::PASS_ALPHA_RIGGED);
if (rigged_alpha != group->mDrawMap.end())
{ //store rigged alpha groups for LLDrawPoolAlpha prepass (skip distance update, rigged attachments use depth buffer)
if (hasRenderType(LLDrawPool::POOL_ALPHA))
{
sCull->pushRiggedAlphaGroup(group);
}
}
}
}
}
@ -9675,7 +9685,11 @@ void LLPipeline::generateWaterReflection(LLCamera& camera_in)
LLColor3 col = LLEnvironment::instance().getCurrentWater()->getWaterFogColor();
glClearColor(col.mV[0], col.mV[1], col.mV[2], 0.f);
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
// HACK FIX -- pretend underwater camera is the world camera to fix weird visibility artifacts
// during distortion render (doesn't break main render because the camera is the same perspective
// as world camera and occlusion culling is disabled for this pass)
//LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WATER1;
LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD;
mWaterDis.bindTarget();
mWaterDis.getViewport(gGLViewport);
@ -11514,6 +11528,16 @@ LLCullResult::sg_iterator LLPipeline::endAlphaGroups()
return sCull->endAlphaGroups();
}
LLCullResult::sg_iterator LLPipeline::beginRiggedAlphaGroups()
{
return sCull->beginRiggedAlphaGroups();
}
LLCullResult::sg_iterator LLPipeline::endRiggedAlphaGroups()
{
return sCull->endRiggedAlphaGroups();
}
bool LLPipeline::hasRenderType(const U32 type) const
{
// STORM-365 : LLViewerJointAttachment::setAttachmentVisibility() is setting type to 0 to actually mean "do not render"

View File

@ -338,6 +338,8 @@ public:
LLCullResult::drawinfo_iterator endRenderMap(U32 type);
LLCullResult::sg_iterator beginAlphaGroups();
LLCullResult::sg_iterator endAlphaGroups();
LLCullResult::sg_iterator beginRiggedAlphaGroups();
LLCullResult::sg_iterator endRiggedAlphaGroups();
void addTrianglesDrawn(S32 index_count, U32 render_type = LLRender::TRIANGLES);