Merge branch 'DRTVWR-546' of https://bitbucket.org/lindenlab/viewer
commit
ccb078ae08
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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>
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
//
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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!
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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"
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
Loading…
Reference in New Issue