diff --git a/autobuild.xml b/autobuild.xml index ae084fe9d0..4b77e62b66 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3030,11 +3030,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 43c5f93517794aeade550e4266b959d1f0cfcb7f + f77b90faf4505af9aef5d5356af7442be87ccc39 hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-darwin64-17630578914.tar.zst + https://github.com/RyeMutt/3p-webrtc-build/releases/download/m137.1/webrtc-m137.1.18519550447-darwin64-18519550447.tar.zst name darwin64 @@ -3044,11 +3044,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - efc5b176d878cfc16b8f82445d82ddb96815b6ab + cd14e4b8320f9f3ece86388f7394dfee11255b0f hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-linux64-17630578914.tar.zst + https://github.com/RyeMutt/3p-webrtc-build/releases/download/m137.1/webrtc-m137.1.18519550447-linux64-18519550447.tar.zst name linux64 @@ -3058,11 +3058,11 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors archive hash - 1e36f100de32c7c71325497a672fb1659b3f206d + 952e58eed658d81e54f6137a5fa554e40119fc5d hash_algorithm sha1 url - https://github.com/secondlife/3p-webrtc-build/releases/download/m137.7151.04.20-universal/webrtc-m137.7151.04.20-universal.17630578914-windows64-17630578914.tar.zst + https://github.com/RyeMutt/3p-webrtc-build/releases/download/m137.1/webrtc-m137.1.18519550447-windows64-18519550447.tar.zst name windows64 diff --git a/indra/cmake/Linking.cmake b/indra/cmake/Linking.cmake index 900a64e2dd..4dd60c55ea 100644 --- a/indra/cmake/Linking.cmake +++ b/indra/cmake/Linking.cmake @@ -43,6 +43,7 @@ if(NOT DARWIN) link_directories(${AUTOBUILD_INSTALL_DIR}/lib/release) endif(NOT DARWIN) + add_library( ll::oslibraries INTERFACE IMPORTED ) if (LINUX) diff --git a/indra/llrender/llgltexture.cpp b/indra/llrender/llgltexture.cpp index 87e7400a24..1143f54d1e 100644 --- a/indra/llrender/llgltexture.cpp +++ b/indra/llrender/llgltexture.cpp @@ -63,6 +63,10 @@ LLGLTexture::~LLGLTexture() void LLGLTexture::init() { mBoostLevel = LLGLTexture::BOOST_NONE; + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + // Added a previous boost level to allow for restoring boost after BOOST_SELECTED is applied + mPrevBoostLevel = LLGLTexture::BOOST_NONE; + // [FIRE-36016] mFullWidth = 0; mFullHeight = 0; @@ -107,6 +111,20 @@ void LLGLTexture::setBoostLevel(S32 level) } } +// [FIRE-36016] - Re-added Store/Restore boost levels of selected objects +// Changes the current boost level back to the previous value +void LLGLTexture::restoreBoostLevel() +{ + mBoostLevel = mPrevBoostLevel; +} + +// Stores the current boost level in the previous boost +void LLGLTexture::storeBoostLevel() +{ + mPrevBoostLevel = mBoostLevel; +} +// [FIRE-36016] + void LLGLTexture::forceActive() { mTextureState = ACTIVE ; diff --git a/indra/llrender/llgltexture.h b/indra/llrender/llgltexture.h index 48132fa956..bc06784917 100644 --- a/indra/llrender/llgltexture.h +++ b/indra/llrender/llgltexture.h @@ -101,6 +101,10 @@ public: void setBoostLevel(S32 level); S32 getBoostLevel() { return mBoostLevel; } + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + void restoreBoostLevel(); // Now restores the mBoostLevel with the mPrevBoostLevel + void storeBoostLevel(); // Stores the current mBoostLevel in mPrevBoostLevel + // [FIRE-36016] S32 getFullWidth() const { return mFullWidth; } S32 getFullHeight() const { return mFullHeight; } @@ -183,6 +187,9 @@ public: protected: S32 mBoostLevel; // enum describing priority level + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + S32 mPrevBoostLevel; // enum describing priority level (Previous Value for BOOST_SELECTION restore) + // [FIRE-36016] U32 mFullWidth; U32 mFullHeight; bool mUseMipMaps; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 0c8c7d3012..d76bf3f29a 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1546,9 +1546,6 @@ void LLShaderMgr::initAttribsAndUniforms() // reserved uniforms for snapshot frame mReservedUniforms.push_back("border_color"); mReservedUniforms.push_back("border_thickness"); - mReservedUniforms.push_back("guide_color"); - mReservedUniforms.push_back("guide_thickness"); - mReservedUniforms.push_back("guide_style"); mReservedUniforms.push_back("frame_rect"); // @@ -1565,4 +1562,3 @@ void LLShaderMgr::initAttribsAndUniforms() dupe_check.insert(mReservedUniforms[i]); } } - diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index f7e9649cba..5cbc6f40c1 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -357,9 +357,6 @@ public: // Uniforms for snapshot frame SNAPSHOT_BORDER_COLOR, // "border_color" SNAPSHOT_BORDER_THICKNESS, // "border_thickness" - SNAPSHOT_GUIDE_COLOR, // "guide_color" - SNAPSHOT_GUIDE_THICKNESS, // "guide_thickness" - SNAPSHOT_GUIDE_STYLE, // "guide_style" SNAPSHOT_FRAME_RECT, // "frame_rect" // END_RESERVED_UNIFORMS diff --git a/indra/llui/llfloater.cpp b/indra/llui/llfloater.cpp index 548ee2037d..2c07eb2410 100644 --- a/indra/llui/llfloater.cpp +++ b/indra/llui/llfloater.cpp @@ -2464,7 +2464,7 @@ void LLFloater::drawConeToOwner(F32 &context_cone_opacity, LLRect local_rect = getLocalRect(); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - LLGLEnable(GL_CULL_FACE); + LLGLEnable cull_face(GL_CULL_FACE); gGL.begin(LLRender::TRIANGLE_STRIP); { gGL.color4f(0.f, 0.f, 0.f, contex_cone_in_alpha * context_cone_opacity); diff --git a/indra/llwebrtc/llwebrtc.cpp b/indra/llwebrtc/llwebrtc.cpp index 828896f620..d5182b16e7 100644 --- a/indra/llwebrtc/llwebrtc.cpp +++ b/indra/llwebrtc/llwebrtc.cpp @@ -1495,6 +1495,10 @@ void freePeerConnection(LLWebRTCPeerConnectionInterface* peer_connection) void init(LLWebRTCLogCallback* logCallback) { + if (gWebRTCImpl) + { + return; + } gWebRTCImpl = new LLWebRTCImpl(logCallback); gWebRTCImpl->init(); } diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 41e05c58f8..a79ccd7ad3 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -26650,6 +26650,28 @@ Change of this parameter will affect the layout of buttons in notification toast Value 1.0 + FSSnapshotGuideVisibility + + Comment + The blend factor used to color the snapshot framing guides + Persist + 1 + Type + F32 + Value + 0.5 + + FSSnapshotGuideStyle + + Comment + The framing guide layout to display inside the snapshot frame + Persist + 1 + Type + String + Value + rule_of_thirds + FSManipRotateJointUseNaturalDirection Comment diff --git a/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl b/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl index aed4eecc60..1a56d52018 100644 --- a/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl +++ b/indra/newview/app_settings/shaders/class1/post/snapshotFrameF.glsl @@ -5,9 +5,6 @@ uniform vec2 screen_res; uniform vec4 frame_rect; // x, y, width, height (normalized 0->1) uniform vec3 border_color; uniform float border_thickness; // in pixels -uniform vec3 guide_color; -uniform float guide_thickness; // in pixels -uniform float guide_style; // 0: no guide, 1: rule of thirds, 2: golden spiral in vec2 vary_fragcoord; @@ -57,20 +54,6 @@ void main() diff.rgb = mix(diff.rgb, border_color, 0.5); } - // Draw guide based on guide_style - if (guide_style == 1) - { - // Draw rule of thirds guide - float third_x = (frame_rect_px.z - frame_rect_px.x) / 3.0; - float third_y = (frame_rect_px.w - frame_rect_px.y) / 3.0; - if ((tc.x > frame_rect_px.x + third_x - guide_thickness && tc.x < frame_rect_px.x + third_x + guide_thickness) || - (tc.x > frame_rect_px.x + 2.0 * third_x - guide_thickness && tc.x < frame_rect_px.x + 2.0 * third_x + guide_thickness) || - (tc.y > frame_rect_px.y + third_y - guide_thickness && tc.y < frame_rect_px.y + third_y + guide_thickness) || - (tc.y > frame_rect_px.y + 2.0 * third_y - guide_thickness && tc.y < frame_rect_px.y + 2.0 * third_y + guide_thickness)) - { - diff.rgb = mix(diff.rgb, guide_color, 0.05); - } - } } frag_color = diff; -} \ No newline at end of file +} diff --git a/indra/newview/fsmaniprotatejoint.cpp b/indra/newview/fsmaniprotatejoint.cpp index 6b5c936c71..1cdd3d47b4 100644 --- a/indra/newview/fsmaniprotatejoint.cpp +++ b/indra/newview/fsmaniprotatejoint.cpp @@ -603,7 +603,7 @@ void FSManipRotateJoint::renderCenterCircle(const F32 radius, const LLColor4& no LLGLDepthTest gls_depth(GL_FALSE); constexpr int segments = 64; - glLineWidth(6.0f); // Set the desired line thickness + gGL.setLineWidth(6.0f); // Set the desired line thickness // Compute a scale factor that already factors in the radius. float scale = radius; @@ -637,7 +637,7 @@ void FSManipRotateJoint::renderCenterCircle(const F32 radius, const LLColor4& no } gGL.end(); - glLineWidth(1.0f); // Reset the line width. + gGL.setLineWidth(1.0f); // Reset the line width. } gGL.popMatrix(); } diff --git a/indra/newview/fsradarmenu.cpp b/indra/newview/fsradarmenu.cpp index d0daacc492..599cb2acc7 100644 --- a/indra/newview/fsradarmenu.cpp +++ b/indra/newview/fsradarmenu.cpp @@ -37,6 +37,7 @@ #include "llagent.h" #include "llavataractions.h" #include "llcallingcard.h" // for LLAvatarTracker +#include "lllogchat.h" #include "llnetmap.h" #include "llviewermenu.h" // for gMenuHolder #include "rlvactions.h" @@ -83,6 +84,7 @@ LLContextMenu* FSRadarMenu::createMenu() registrar.add("Avatar.Derender", boost::bind(&LLAvatarActions::derender, id, false)); registrar.add("Avatar.DerenderPermanent", boost::bind(&LLAvatarActions::derender, id, true)); registrar.add("Avatar.AddToContactSet", boost::bind(&FSRadarMenu::addToContactSet, this)); + registrar.add("Avatar.Calllog", boost::bind(&LLAvatarActions::viewChatHistory, id)); registrar.add("Nearby.People.TeleportToAvatar", boost::bind(&FSRadarMenu::teleportToAvatar, this)); registrar.add("Nearby.People.TrackAvatar", boost::bind(&FSRadarMenu::onTrackAvatarMenuItemClick, this)); registrar.add("Nearby.People.SetRenderMode", boost::bind(&FSRadarMenu::onSetRenderMode, this, _2)); @@ -234,6 +236,10 @@ bool FSRadarMenu::enableContextMenuItem(const LLSD& userdata) const LLUUID& id = mUUIDs.front(); return RlvActions::canPayAvatar(id); } + else if (item == std::string("can_callog")) + { + return LLLogChat::isTranscriptExist(mUUIDs.front()); + } return false; } diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index 1de859aa80..6ba8ece706 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -445,10 +445,7 @@ bool LLTaskInvFVBridge::removeItem() return true; } - LLSD payload; - payload["task_id"] = mPanel->getTaskUUID(); - payload["inventory_ids"].append(mUUID); - LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); + LLNotificationsUtil::add("CantModifyContentInNoModTask"); return false; } } @@ -471,13 +468,7 @@ void LLTaskInvFVBridge::removeBatch(std::vector& batch) if (!object->permModify()) { - LLSD payload; - payload["task_id"] = mPanel->getTaskUUID(); - for (LLFolderViewModelItem* item : batch) - { - payload["inventory_ids"].append(((LLTaskInvFVBridge*)item)->getUUID()); - } - LLNotificationsUtil::add("RemoveItemWarn", LLSD(), payload, boost::bind(&remove_task_inventory_callback, _1, _2, mPanel)); + LLNotificationsUtil::add("CantModifyContentInNoModTask"); } else { diff --git a/indra/newview/llviewerfloaterreg.cpp b/indra/newview/llviewerfloaterreg.cpp index 2c32e9b971..e4a7c1398c 100644 --- a/indra/newview/llviewerfloaterreg.cpp +++ b/indra/newview/llviewerfloaterreg.cpp @@ -605,6 +605,7 @@ void LLViewerFloaterReg::registerFloaters() LLFloaterReg::add("stop_queue", "floater_script_queue.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("snapshot", "floater_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("simple_snapshot", "floater_simple_snapshot.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); + LLFloaterReg::add("snapshot_guide_settings", "floater_snapshot_guide_settings.xml", (LLFloaterBuildFunc)&LLFloaterReg::build);// photo guide settings // Search floater is deferred to login now so we can tell what grid we're in. //LLFloaterReg::add("search", "floater_search.xml", (LLFloaterBuildFunc)&LLFloaterReg::build); LLFloaterReg::add("profile", "floater_profile.xml",(LLFloaterBuildFunc)&LLFloaterReg::build); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 396dd43130..81a9138939 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4336,6 +4336,14 @@ void LLViewerObject::boostTexturePriority(bool boost_children /* = true */) S32 tex_count = getNumTEs(); for (i = 0; i < tex_count; i++) { + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + // This fixes textures becoming blury (Esepecially with Bias > 1.0f) after an object is selected and unselected. + // If this is changing the boost level for the TEImage for the first time, store the boost level before modifying it. + if (getTEImage(i)->getBoostLevel() != LLGLTexture::BOOST_SELECTED) + { + getTEImage(i)->storeBoostLevel(); + } + // [FIRE-36016] getTEImage(i)->setBoostLevel(LLGLTexture::BOOST_SELECTED); } @@ -4345,7 +4353,21 @@ void LLViewerObject::boostTexturePriority(bool boost_children /* = true */) if (sculpt_params) { LLUUID sculpt_id = sculpt_params->getSculptTexture(); - LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + //LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE)->setBoostLevel(LLGLTexture::BOOST_SELECTED); + // This fixes textures becoming blury (Esepecially with Bias > 1.0f) after an object is selected and unselected. + // If this is changing the boost level for the sculpted for the first time, store the boost level before modifying it. + LLViewerFetchedTexture* sculptedTexture = LLViewerTextureManager::getFetchedTexture(sculpt_id, FTT_DEFAULT, true, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + if (sculptedTexture) + { + // If the texture is already boost selected, don't store the boost level again. Otherwise, it will overwrite the saved boost level with itself. + if (sculptedTexture->getBoostLevel() != LLGLTexture::BOOST_SELECTED) + { + sculptedTexture->storeBoostLevel(); + } + sculptedTexture->setBoostLevel(LLGLTexture::BOOST_SELECTED); + } + // [FIRE-36016] } } diff --git a/indra/newview/llviewerparceloverlay.cpp b/indra/newview/llviewerparceloverlay.cpp index 8a7075a2a9..f19d6b5aa4 100644 --- a/indra/newview/llviewerparceloverlay.cpp +++ b/indra/newview/llviewerparceloverlay.cpp @@ -825,7 +825,7 @@ void LLViewerParcelOverlay::renderPropertyLinesOnMinimap(F32 scale_pixels_per_me const S32 GRIDS_PER_EDGE = mParcelGridsPerEdge; gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - glLineWidth(1.0f); + gGL.setLineWidth(1.0f); gGL.color4fv(parcel_outline_color); for (S32 i = 0; i <= GRIDS_PER_EDGE; i++) { diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index 5036acbdaa..cce3b4b637 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -3191,7 +3191,12 @@ void LLViewerLODTexture::processTextureStats() // unset it immediately after we consume it if (getBoostLevel() == BOOST_SELECTED) { - setBoostLevel(BOOST_NONE); + // [FIRE-36016] - Re-added Store/Restore boost levels of selected objects + //setBoostLevel(BOOST_NONE); + // Restore the boost level instead of just setting to BOOST_NONE + // Can cause Sculpts and other boosted objects to lose boost and become subject to discard levels with Bias over 1.0f + restoreBoostLevel(); + // > [FIRE-36016] } } diff --git a/indra/newview/llvoicewebrtc.cpp b/indra/newview/llvoicewebrtc.cpp index 8ef59f1047..e5f5db3a3c 100644 --- a/indra/newview/llvoicewebrtc.cpp +++ b/indra/newview/llvoicewebrtc.cpp @@ -273,6 +273,11 @@ void LLWebRTCVoiceClient::cleanupSingleton() void LLWebRTCVoiceClient::init(LLPumpIO* pump) { // constructor will set up LLVoiceClient::getInstance() + initWebRTC(); +} + +void LLWebRTCVoiceClient::initWebRTC() +{ llwebrtc::init(this); mWebRTCDeviceInterface = llwebrtc::getDeviceInterface(); @@ -292,6 +297,7 @@ void LLWebRTCVoiceClient::terminate() mVoiceEnabled = false; llwebrtc::terminate(); + mWebRTCDeviceInterface = nullptr; sShuttingDown = true; } @@ -1813,6 +1819,15 @@ void LLWebRTCVoiceClient::onChangeDetailed(const LLMute& mute) } } +void LLWebRTCVoiceClient::userAuthorized(const std::string& user_id, const LLUUID& agentID) +{ + if (sShuttingDown) + { + sShuttingDown = false; // was terminated, restart + initWebRTC(); + } +} + void LLWebRTCVoiceClient::predSetUserMute(const LLWebRTCVoiceClient::sessionStatePtr_t &session, const LLUUID &id, bool mute) { session->setUserMute(id, mute); diff --git a/indra/newview/llvoicewebrtc.h b/indra/newview/llvoicewebrtc.h index 722d81fdc2..2ce575852a 100644 --- a/indra/newview/llvoicewebrtc.h +++ b/indra/newview/llvoicewebrtc.h @@ -204,7 +204,7 @@ public: //@} // authorize the user - void userAuthorized(const std::string &user_id, const LLUUID &agentID) override {}; + void userAuthorized(const std::string &user_id, const LLUUID &agentID) override; void OnConnectionEstablished(const std::string& channelID, const LLUUID& regionID); @@ -443,6 +443,8 @@ public: boost::signals2::connection mAvatarNameCacheConnection; private: + // init or restart the WebRTC device interface. + void initWebRTC(); // Coroutine support methods //--- diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 6dbe59033d..d9791f58b3 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -4546,17 +4546,365 @@ void LLPipeline::recordTrianglesDrawn() add(LLStatViewer::TRIANGLES_DRAWN, LLUnits::Triangles::fromValue(count)); } +// Rework Snapshot Guide Rendering +void LLPipeline::renderSnapshotGuidesOverlay() +{ + if (!mSnapshotGuideState.active || !mSnapshotGuideState.show_guides) + { + mSnapshotGuideState.active = false; + return; + } + + if (!gViewerWindow || !gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + mSnapshotGuideState.active = false; + return; + } + + LLRect view_rect = gViewerWindow->getWorldViewRectRaw(); + const F32 width = (F32)view_rect.getWidth(); + const F32 height = (F32)view_rect.getHeight(); + if (width <= 0.f || height <= 0.f) + { + mSnapshotGuideState.active = false; + return; + } + + const F32 left_norm = llmin(mSnapshotGuideState.left, mSnapshotGuideState.right); + const F32 right_norm = llmax(mSnapshotGuideState.left, mSnapshotGuideState.right); + const F32 bottom_norm = llmin(mSnapshotGuideState.bottom, mSnapshotGuideState.top); + const F32 top_norm = llmax(mSnapshotGuideState.bottom, mSnapshotGuideState.top); + + const F32 left_px = left_norm * width; + const F32 right_px = right_norm * width; + const F32 bottom_px = bottom_norm * height; + const F32 top_px = top_norm * height; + + const F32 frame_width = right_px - left_px; + const F32 frame_height = top_px - bottom_px; + if (frame_width <= 0.f || frame_height <= 0.f) + { + mSnapshotGuideState.active = false; + return; + } + + const F32 alpha = llclamp(mSnapshotGuideState.visibility, 0.f, 1.f); + if (alpha <= 0.f) + { + mSnapshotGuideState.active = false; + return; + } + + LLGLDisable depth(GL_DEPTH_TEST); + LLGLDisable cull(GL_CULL_FACE); + LLGLDisable stencil(GL_STENCIL_TEST); + LLGLEnable blend(GL_BLEND); + gGL.setSceneBlendType(LLRender::BT_ALPHA); + + LLGLSLShader* ui_shader = &gUIProgram; + ui_shader->bind(); + + if (!LLViewerFetchedTexture::sWhiteImagep.isNull()) + { + gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep); + } + else + { + gGL.getTexUnit(0)->bindManual(LLTexUnit::TT_TEXTURE, LLTexUnit::sWhiteTexture); + } + + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGL.ortho(0.f, width, 0.f, height, -1.f, 1.f); + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.pushMatrix(); + gGL.loadIdentity(); + gGLLastMatrix = nullptr; + + const LLColor4 line_color(mSnapshotGuideState.color, alpha); + gGL.color4fv(line_color.mV); + + const F32 thickness = llmax(mSnapshotGuideState.thickness, 0.f); + const F32 half_thickness = thickness * 0.5f; + auto draw_filled_rect = [&](F32 l, F32 b, F32 r, F32 t) + { + const S32 left_i = ll_round(l); + const S32 right_i = ll_round(r); + const S32 top_i = ll_round(t); + const S32 bottom_i = ll_round(b); + gl_rect_2d(left_i, top_i, right_i, bottom_i, line_color, true); + }; + + auto draw_vertical_norm = [&](F32 norm) + { + const F32 x = left_px + frame_width * norm; + draw_filled_rect(x - half_thickness, bottom_px, x + half_thickness, top_px); + }; + + auto draw_horizontal_norm = [&](F32 norm) + { + const F32 y = bottom_px + frame_height * norm; + draw_filled_rect(left_px, y - half_thickness, right_px, y + half_thickness); + }; + + switch (mSnapshotGuideState.style) + { + case SnapshotGuideState::Style::RuleOfThirds: + { + constexpr std::array offsets = { 1.f / 3.f, 2.f / 3.f }; + for (F32 offset : offsets) + { + draw_vertical_norm(offset); + draw_horizontal_norm(offset); + } + break; + } + case SnapshotGuideState::Style::GoldenRatio: + { + constexpr F32 phi = 1.61803398875f; + const SnapshotGuideState::GoldenOrientation orientation = mSnapshotGuideState.golden_orientation; + + const F32 scale = llmin(frame_width / phi, frame_height); + if (scale <= 0.f) + { + break; + } + + const F32 golden_width = phi * scale; + const F32 golden_height = scale; + const F32 pad_x = frame_width - golden_width; + const F32 pad_y = frame_height - golden_height; + + F32 anchor_x = left_px; + F32 anchor_y = bottom_px; + switch (orientation) + { + case SnapshotGuideState::GoldenOrientation::TopLeft: + anchor_y += pad_y; + break; + case SnapshotGuideState::GoldenOrientation::TopRight: + anchor_x += pad_x; + anchor_y += pad_y; + break; + case SnapshotGuideState::GoldenOrientation::BottomRight: + anchor_x += pad_x; + break; + case SnapshotGuideState::GoldenOrientation::BottomLeft: + default: + break; + } + + auto map_point = [&](F32 local_x, F32 local_y) -> LLVector2 + { + F32 x = local_x; + F32 y = local_y; + + if (orientation == SnapshotGuideState::GoldenOrientation::TopLeft || + orientation == SnapshotGuideState::GoldenOrientation::BottomLeft) + { + x = golden_width - local_x; + } + + if (orientation == SnapshotGuideState::GoldenOrientation::BottomLeft || + orientation == SnapshotGuideState::GoldenOrientation::BottomRight) + { + y = golden_height - local_y; + } + + return LLVector2(anchor_x + x, anchor_y + y); + }; + + std::vector> line_segments; + line_segments.reserve(24); + + auto add_line = [&](F32 x0, F32 y0, F32 x1, F32 y1) + { + line_segments.emplace_back(map_point(x0, y0), map_point(x1, y1)); + }; + + // Outline of the fitted golden rectangle. + add_line(0.f, 0.f, golden_width, 0.f); + add_line(0.f, golden_height, golden_width, golden_height); + add_line(0.f, 0.f, 0.f, golden_height); + add_line(golden_width, 0.f, golden_width, golden_height); + + // Generate subdivision lines while we walk the squares. + F32 x0 = 0.f; + F32 y0 = 0.f; + F32 x1 = golden_width; + F32 y1 = golden_height; + + for (U32 step = 0; step < 12; ++step) + { + const F32 width = x1 - x0; + const F32 height = y1 - y0; + if (width <= 1.f || height <= 1.f) + { + break; + } + + switch (step % 4) + { + case 0: + x0 += height; + add_line(x0, y0, x0, y1); + break; + case 1: + y0 += width; + add_line(x0, y0, x1, y0); + break; + case 2: + x1 -= height; + add_line(x1, y0, x1, y1); + break; + default: + y1 -= width; + add_line(x0, y1, x1, y1); + break; + } + } + + auto draw_golden_spiral = [&](U32 max_depth) + { + gGL.begin(LLRender::LINE_STRIP); + + F32 spiral_x0 = 0.f; + F32 spiral_y0 = 0.f; + F32 spiral_x1 = golden_width; + F32 spiral_y1 = golden_height; + + for (U32 step = 0; step < max_depth; ++step) + { + const F32 width = spiral_x1 - spiral_x0; + const F32 height = spiral_y1 - spiral_y0; + if (width <= 1.f || height <= 1.f) + { + break; + } + + F32 size = 0.f; + F32 cx = 0.f; + F32 cy = 0.f; + F32 start_angle = 0.f; + F32 end_angle = 0.f; + + switch (step % 4) + { + case 0: // left square + size = height; + cx = spiral_x0 + size; + cy = spiral_y0 + size; + start_angle = F_PI; + end_angle = 1.5f * F_PI; + spiral_x0 += size; + break; + case 1: // bottom square + size = width; + cx = spiral_x0; + cy = spiral_y0 + size; + start_angle = 1.5f * F_PI; + end_angle = 2.f * F_PI; + spiral_y0 += size; + break; + case 2: // right square + size = height; + cx = spiral_x1 - size; + cy = spiral_y0; + start_angle = 0.f; + end_angle = F_PI_BY_TWO; + spiral_x1 -= size; + break; + case 3: // top square + default: + size = width; + cx = spiral_x0 + size; + cy = spiral_y1 - size; + start_angle = F_PI_BY_TWO; + end_angle = F_PI; + spiral_y1 -= size; + break; + } + + if (size <= 0.f) + { + break; + } + + const S32 segments = llclamp((S32)(size / 4.f), 12, 64); + for (S32 i = 0; i <= segments; ++i) + { + const F32 t = start_angle + (end_angle - start_angle) * (F32)i / (F32)segments; + const F32 local_x = cx + cosf(t) * size; + const F32 local_y = cy + sinf(t) * size; + LLVector2 mapped = map_point(local_x, local_y); + gGL.vertex2f(mapped.mV[0], mapped.mV[1]); + } + } + + gGL.end(); + }; + + gGL.flush(); + const F32 line_width = llmax(thickness, 1.f); + gGL.setLineWidth(line_width); + draw_golden_spiral(12); + gGL.setLineWidth(1.f); + + if (!line_segments.empty()) + { + gGL.flush(); + gGL.setLineWidth(line_width); + gGL.begin(LLRender::LINES); + for (const auto& segment : line_segments) + { + gGL.vertex2f(segment.first.mV[VX], segment.first.mV[VY]); + gGL.vertex2f(segment.second.mV[VX], segment.second.mV[VY]); + } + gGL.end(); + gGL.setLineWidth(1.f); + } + break; + } + case SnapshotGuideState::Style::Diagonal: + { + const F32 line_width = llmax(thickness, 1.f); + gGL.flush(); + gGL.setLineWidth(line_width); + gGL.begin(LLRender::LINES); + gGL.vertex2f(left_px, bottom_px); + gGL.vertex2f(right_px, top_px); + gGL.vertex2f(left_px, top_px); + gGL.vertex2f(right_px, bottom_px); + gGL.end(); + gGL.setLineWidth(1.f); + break; + } + } + + gGL.matrixMode(LLRender::MM_MODELVIEW); + gGL.popMatrix(); + gGL.matrixMode(LLRender::MM_PROJECTION); + gGL.popMatrix(); + gGLLastMatrix = nullptr; + + ui_shader->unbind(); + + mSnapshotGuideState.active = false; +} +// + // FIRE-32023 Focus Point Rendering void LLPipeline::renderFocusPoint() { - static LLCachedControl render_focus_point_crosshair(gSavedSettings, "FSFocusPointRender", false); - if ( sDoFEnabled && render_focus_point_crosshair && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + if (sDoFEnabled && render_focus_point_crosshair && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) { gDebugProgram.bind(); LLVector3 focus_point = sLastFocusPoint; F32 size = 0.02f; - LLGLDepthTest gls_depth(GL_FALSE); + LLGLDepthTest gls_depth(GL_FALSE); gGL.pushMatrix(); gGL.translatef(focus_point.mV[VX], focus_point.mV[VY], focus_point.mV[VZ]); @@ -4571,23 +4919,24 @@ void LLPipeline::renderFocusPoint() } gGL.vertex3f(-size, 0.0f, 0.0f); gGL.vertex3f(size, 0.0f, 0.0f); - + // Y-axis (Green) gGL.vertex3f(0.0f, -size, 0.0f); gGL.vertex3f(0.0f, size, 0.0f); - + // Z-axis (Blue) gGL.vertex3f(0.0f, 0.0f, -size); gGL.vertex3f(0.0f, 0.0f, size); gGL.end(); - + gGL.popMatrix(); gGL.flush(); gDebugProgram.unbind(); - } + } } // + void LLPipeline::renderPhysicsDisplay() { if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) @@ -4598,9 +4947,9 @@ void LLPipeline::renderPhysicsDisplay() gGL.flush(); gDebugProgram.bind(); - LLGLEnable(GL_POLYGON_OFFSET_LINE); + LLGLEnable ploygon_offset_line(GL_POLYGON_OFFSET_LINE); glPolygonOffset(3.f, 3.f); - glLineWidth(3.f); + gGL.setLineWidth(3.f); LLGLEnable blend(GL_BLEND); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -4642,7 +4991,7 @@ void LLPipeline::renderPhysicsDisplay() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); } } - glLineWidth(1.f); + gGL.setLineWidth(1.f); gDebugProgram.unbind(); } @@ -8125,6 +8474,9 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst) static LLCachedControl show_frame(gSavedSettings, "FSSnapshotShowCaptureFrame", false); static LLCachedControl show_guides(gSavedSettings, "FSSnapshotShowGuides", false); + mSnapshotGuideState.active = false; + mSnapshotGuideState.show_guides = false; + float left = 0.f; float top = 0.f; float right = 1.f; @@ -8135,12 +8487,41 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst) static LLCachedControl guide_color(gSavedSettings, "FSSnapshotFrameGuideColor", LLColor3(1.f, 1.f, 0.f)); static LLCachedControl border_thickness(gSavedSettings, "FSSnapshotFrameBorderWidth", 2.0f); static LLCachedControl guide_thickness(gSavedSettings, "FSSnapshotFrameGuideWidth", 2.0f); + static LLCachedControl guide_visibility(gSavedSettings, "FSSnapshotGuideVisibility", 0.5f); + static LLCachedControl guide_style_setting(gSavedSettings, "FSSnapshotGuideStyle", std::string("rule_of_thirds")); - F32 guide_style = 1.f; // 0:off, 1:rule_of_thirds, others maybe in the future - if (!show_guides) + SnapshotGuideState::Style guide_style = SnapshotGuideState::Style::RuleOfThirds; + SnapshotGuideState::GoldenOrientation golden_orientation = SnapshotGuideState::GoldenOrientation::TopLeft; + const std::string style_value = guide_style_setting(); + if (style_value == "golden_ratio" || style_value == "golden_ratio_top_left") { - guide_style = 0.f; + guide_style = SnapshotGuideState::Style::GoldenRatio; + golden_orientation = SnapshotGuideState::GoldenOrientation::TopLeft; } + else if (style_value == "golden_ratio_top_right") + { + guide_style = SnapshotGuideState::Style::GoldenRatio; + golden_orientation = SnapshotGuideState::GoldenOrientation::TopRight; + } + else if (style_value == "golden_ratio_bottom_left") + { + guide_style = SnapshotGuideState::Style::GoldenRatio; + golden_orientation = SnapshotGuideState::GoldenOrientation::BottomLeft; + } + else if (style_value == "golden_ratio_bottom_right") + { + guide_style = SnapshotGuideState::Style::GoldenRatio; + golden_orientation = SnapshotGuideState::GoldenOrientation::BottomRight; + } + else if (style_value == "diagonal") + { + guide_style = SnapshotGuideState::Style::Diagonal; + } + else + { + guide_style = SnapshotGuideState::Style::RuleOfThirds; + } + const F32 guide_visibility_value = show_guides ? (F32)guide_visibility : 0.f; const bool simple_snapshot_visible = LLFloaterReg::instanceVisible("simple_snapshot"); const bool flickr_snapshot_visible = LLFloaterReg::instanceVisible("flickr"); const bool primfeed_snapshot_visible = LLFloaterReg::instanceVisible("primfeed"); // Primfeed integration @@ -8254,17 +8635,7 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst) LLShaderMgr::SNAPSHOT_BORDER_THICKNESS, (GLfloat)border_thickness); - shader->uniform3fv( - LLShaderMgr::SNAPSHOT_GUIDE_COLOR, - 1, - guide_color().mV); - - shader->uniform1f( - LLShaderMgr::SNAPSHOT_GUIDE_THICKNESS, - (GLfloat)guide_thickness); - shader->uniform1f( - LLShaderMgr::SNAPSHOT_GUIDE_STYLE, - (GLfloat)guide_style); + // Guides are rendered in a later UI pass; no additional uniforms required here. mScreenTriangleVB->setBuffer(); mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); @@ -8273,6 +8644,22 @@ bool LLPipeline::renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst) shader->disableTexture(LLShaderMgr::DEFERRED_DIFFUSE, src->getUsage()); shader->unbind(); dst->flush(); + + if (show_frame && show_guides && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) + { + mSnapshotGuideState.active = true; + mSnapshotGuideState.show_guides = true; + mSnapshotGuideState.left = left; + mSnapshotGuideState.right = right; + mSnapshotGuideState.bottom = bottom; + mSnapshotGuideState.top = top; + mSnapshotGuideState.color = guide_color(); + mSnapshotGuideState.thickness = guide_thickness(); + mSnapshotGuideState.visibility = llclamp(guide_visibility_value, 0.f, 1.f); + mSnapshotGuideState.style = guide_style; + mSnapshotGuideState.golden_orientation = golden_orientation; + } + return true; } // @@ -8663,7 +9050,8 @@ void LLPipeline::renderFinalize() gDeferredPostNoDoFNoiseProgram.unbind(); gGL.setSceneBlendType(LLRender::BT_ALPHA); - + + renderSnapshotGuidesOverlay(); // Render snapshot guides as part of UI renderFocusPoint(); // FIRE-32023 render focus point if (hasRenderDebugMask(LLPipeline::RENDER_DEBUG_PHYSICS_SHAPES)) diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index 4100b75134..cb905e42a1 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -354,6 +354,7 @@ public: void renderHighlights(); bool renderVignette(LLRenderTarget* src, LLRenderTarget* dst); bool renderSnapshotFrame(LLRenderTarget* src, LLRenderTarget* dst); // Add snapshot frame rendering + void renderSnapshotGuidesOverlay(); // Add snapshot composition guide rendering void renderDebug(); void renderPhysicsDisplay(); @@ -1024,6 +1025,39 @@ protected: U32 mLightMask; U32 mLightMovingMask; + // Add snapshot guides as part of UI rendering to avoid issues in compositor + struct SnapshotGuideState + { + enum class Style : U8 + { + RuleOfThirds, + GoldenRatio, + Diagonal + }; + + enum class GoldenOrientation : U8 + { + TopLeft, + TopRight, + BottomLeft, + BottomRight + }; + + bool active = false; + bool show_guides = false; + F32 left = 0.f; + F32 right = 1.f; + F32 bottom = 0.f; + F32 top = 1.f; + LLColor3 color = LLColor3(1.f, 1.f, 1.f); + F32 thickness = 0.f; + F32 visibility = 0.f; + Style style = Style::RuleOfThirds; + GoldenOrientation golden_orientation = GoldenOrientation::TopLeft; + }; + + SnapshotGuideState mSnapshotGuideState; + // static bool sRenderPhysicalBeacons; static bool sRenderMOAPBeacons; static bool sRenderScriptedTouchBeacons; diff --git a/indra/newview/skins/default/xui/az/menu_fs_radar.xml b/indra/newview/skins/default/xui/az/menu_fs_radar.xml index ba4fc83ce4..79a95c3de1 100644 --- a/indra/newview/skins/default/xui/az/menu_fs_radar.xml +++ b/indra/newview/skins/default/xui/az/menu_fs_radar.xml @@ -25,6 +25,7 @@ + diff --git a/indra/newview/skins/default/xui/de/floater_snapshot.xml b/indra/newview/skins/default/xui/de/floater_snapshot.xml index 76e7d93710..922a50e3c4 100644 --- a/indra/newview/skins/default/xui/de/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/de/floater_snapshot.xml @@ -60,7 +60,8 @@ - + + + + + Guide Color and Appearance + + + + + + Guide Style + + + + + + + + + + + diff --git a/indra/newview/skins/default/xui/en/menu_fs_radar.xml b/indra/newview/skins/default/xui/en/menu_fs_radar.xml index 08ce090e85..15a7d7e143 100644 --- a/indra/newview/skins/default/xui/en/menu_fs_radar.xml +++ b/indra/newview/skins/default/xui/en/menu_fs_radar.xml @@ -187,6 +187,16 @@ + + + + diff --git a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml index f305fc5e37..ae9d55f2f7 100644 --- a/indra/newview/skins/default/xui/en/panel_flickr_photo.xml +++ b/indra/newview/skins/default/xui/en/panel_flickr_photo.xml @@ -136,24 +136,49 @@ width="251"> Refreshing... - - + + + + + Refreshing... - - - + + + + + + - - \ No newline at end of file + left="10"> + + + + + + diff --git a/indra/newview/skins/default/xui/es/menu_fs_radar.xml b/indra/newview/skins/default/xui/es/menu_fs_radar.xml index a809ed70ed..d2631081c6 100644 --- a/indra/newview/skins/default/xui/es/menu_fs_radar.xml +++ b/indra/newview/skins/default/xui/es/menu_fs_radar.xml @@ -15,6 +15,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/menu_fs_radar.xml b/indra/newview/skins/default/xui/fr/menu_fs_radar.xml index 08b7b124da..9667ecf86c 100644 --- a/indra/newview/skins/default/xui/fr/menu_fs_radar.xml +++ b/indra/newview/skins/default/xui/fr/menu_fs_radar.xml @@ -25,6 +25,7 @@ + diff --git a/indra/newview/skins/default/xui/fr/panel_flickr_photo.xml b/indra/newview/skins/default/xui/fr/panel_flickr_photo.xml index 5f035b3334..07fc5cc54d 100644 --- a/indra/newview/skins/default/xui/fr/panel_flickr_photo.xml +++ b/indra/newview/skins/default/xui/fr/panel_flickr_photo.xml @@ -7,8 +7,10 @@ Actualisation... - - + + + +