From c9fbd9e2e820ce4d5e62468f757ee0502fa93af1 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 27 Apr 2022 14:48:25 -0700 Subject: SL-17116 work on implementing MaterialID in ExtraParams of ObjectUpdate and related messages --- indra/llprimitive/CMakeLists.txt | 1 + indra/llprimitive/llmaterial.h | 4 -- indra/llprimitive/llprimitive.cpp | 69 ++++++++++++++++++++++++ indra/llprimitive/llprimitive.h | 20 +++++++ indra/llprimitive/tests/llmessagesystem_stub.cpp | 2 +- indra/llprimitive/tests/llprimitive_test.cpp | 40 ++++++++++++++ 6 files changed, 131 insertions(+), 5 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 7b6d04b096..fff4d8ef0a 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -90,6 +90,7 @@ if (LL_TESTS) INCLUDE(LLAddBuildTest) SET(llprimitive_TEST_SOURCE_FILES llmediaentry.cpp + llprimitive.cpp ) LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}") endif (LL_TESTS) diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index d58b7ee812..1e068c2be3 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -27,8 +27,6 @@ #ifndef LL_LLMATERIAL_H #define LL_LLMATERIAL_H -#include - #include "llmaterialid.h" #include "llsd.h" #include "v4coloru.h" @@ -54,8 +52,6 @@ public: ALPHA_SHADER_COUNT = 4 } eShaderCount; - - static const U8 DEFAULT_SPECULAR_LIGHT_EXPONENT = ((U8)(0.2f * 255)); static const LLColor4U DEFAULT_SPECULAR_LIGHT_COLOR; static const U8 DEFAULT_ENV_INTENSITY = 0; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 67c225d25d..c46e5fb3c5 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -39,6 +39,7 @@ #include "llsdutil_math.h" #include "llprimtexturelist.h" #include "llmaterialid.h" +#include "llsdutil.h" /** * exported constants @@ -1690,6 +1691,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) return (size == 28); case PARAMS_EXTENDED_MESH: return (size == 4); + case PARAMS_RENDER_MATERIAL: + return (size == 16); } return FALSE; @@ -2181,3 +2184,69 @@ bool LLExtendedMeshParams::fromLLSD(LLSD& sd) return false; } + +//============================================================================ + +LLRenderMaterialParams::LLRenderMaterialParams() +{ + mType = PARAMS_RENDER_MATERIAL; +} + +BOOL LLRenderMaterialParams::pack(LLDataPacker &dp) const +{ + return dp.packUUID(mMaterial, "material"); + +// return TRUE; +} + +BOOL LLRenderMaterialParams::unpack(LLDataPacker &dp) +{ + return dp.unpackUUID(mMaterial, "material"); + +// return TRUE; +} + +bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_RENDER_MATERIAL) + { + return false; + } + + const LLRenderMaterialParams ¶m = static_cast(data); + + return param.mMaterial == mMaterial; +} + +void LLRenderMaterialParams::copy(const LLNetworkData& data) +{ + llassert_always(data.mType == PARAMS_RENDER_MATERIAL); + const LLRenderMaterialParams ¶m = static_cast(data); + mMaterial = param.mMaterial; +} + +LLSD LLRenderMaterialParams::asLLSD() const +{ + return llsd::map("material", mMaterial); +} + +bool LLRenderMaterialParams::fromLLSD(LLSD& sd) +{ + if (sd.has("material")) + { + setMaterial(sd["material"]); + return true; + } + + return false; +} + +void LLRenderMaterialParams::setMaterial(const LLUUID & id) +{ + mMaterial = id; +} + +LLUUID LLRenderMaterialParams::getMaterial() const +{ + return mMaterial; +} diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 309b18faa9..e23ddd2916 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -107,6 +107,7 @@ public: PARAMS_RESERVED = 0x50, // Used on server-side PARAMS_MESH = 0x60, PARAMS_EXTENDED_MESH = 0x70, + PARAMS_RENDER_MATERIAL = 0x80, }; public: @@ -320,6 +321,25 @@ public: }; +class LLRenderMaterialParams : public LLNetworkData +{ +private: + LLUUID mMaterial; + +public: + LLRenderMaterialParams(); + BOOL pack(LLDataPacker &dp) const override; + BOOL unpack(LLDataPacker &dp) override; + bool operator==(const LLNetworkData& data) const override; + void copy(const LLNetworkData& data) override; + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setMaterial(const LLUUID & id); + LLUUID getMaterial() const; +}; + // This code is not naming-standards compliant. Leaving it like this for // now to make the connection to code in // BOOL packTEMessage(LLDataPacker &dp) const; diff --git a/indra/llprimitive/tests/llmessagesystem_stub.cpp b/indra/llprimitive/tests/llmessagesystem_stub.cpp index 04e70945c4..9006833054 100644 --- a/indra/llprimitive/tests/llmessagesystem_stub.cpp +++ b/indra/llprimitive/tests/llmessagesystem_stub.cpp @@ -25,7 +25,7 @@ #include "linden_common.h" -char * _PREHASH_TextureEntry; +const char * const _PREHASH_TextureEntry = "TextureEntry"; S32 LLMessageSystem::getSizeFast(char const*, char const*) const { diff --git a/indra/llprimitive/tests/llprimitive_test.cpp b/indra/llprimitive/tests/llprimitive_test.cpp index 0d60c7cd15..0ff0795fdc 100644 --- a/indra/llprimitive/tests/llprimitive_test.cpp +++ b/indra/llprimitive/tests/llprimitive_test.cpp @@ -71,6 +71,46 @@ private: S32 mCurrDetailTest; }; +LLMaterialID::LLMaterialID() {} +LLMaterialID::LLMaterialID(LLMaterialID const &m) = default; +LLMaterialID::~LLMaterialID() {} +void LLMaterialID::set(void const*) { } +U8 const * LLMaterialID::get() const { return mID; } + +LLPrimTextureList::LLPrimTextureList() { } +LLPrimTextureList::~LLPrimTextureList() { } +S32 LLPrimTextureList::setBumpMap(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setOffsetS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setOffsetT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::copyTexture(const U8 index, const LLTextureEntry &te) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setRotation(const U8 index, const F32 r) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setBumpShiny(const U8 index, const U8 bump_shiny) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setFullbright(const U8 index, const U8 t) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setMaterialID(const U8 index, const LLMaterialID& pMaterialID) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setMediaFlags(const U8 index, const U8 media_flags) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setMediaTexGen(const U8 index, const U8 media) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setBumpShinyFullbright(const U8 index, const U8 bump) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setID(const U8 index, const LLUUID& id) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setGlow(const U8 index, const F32 glow) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setAlpha(const U8 index, const F32 alpha) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setColor(const U8 index, const LLColor3& color) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setColor(const U8 index, const LLColor4& color) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setScale(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setScaleS(const U8 index, const F32 s) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setScaleT(const U8 index, const F32 t) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setShiny(const U8 index, const U8 shiny) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setOffset(const U8 index, const F32 s, const F32 t) { return TEM_CHANGE_NONE; } +S32 LLPrimTextureList::setTexGen(const U8 index, const U8 texgen) { return TEM_CHANGE_NONE; } + +LLMaterialPtr LLPrimTextureList::getMaterialParams(const U8 index) { return LLMaterialPtr(); } +void LLPrimTextureList::copy(LLPrimTextureList const & ptl) { mEntryList = ptl.mEntryList; } // do we need to call getTexture()->newCopy()? +void LLPrimTextureList::take(LLPrimTextureList &other_list) { } +void LLPrimTextureList::setSize(S32 new_size) { mEntryList.resize(new_size); } +void LLPrimTextureList::setAllIDs(const LLUUID &id) { } +LLTextureEntry * LLPrimTextureList::getTexture(const U8 index) const { return nullptr; } +S32 LLPrimTextureList::size() const { return mEntryList.size(); } + class PRIMITIVE_TEST_SETUP { public: -- cgit v1.3 From c9ef206e39063c46c1fbab355c1a015e3e8b022e Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 28 Apr 2022 13:08:37 -0700 Subject: Beginning viewer side work for SL-17198 new asset and inventory types for Materials --- indra/llcommon/llassettype.cpp | 1 + indra/llcommon/llassettype.h | 3 ++- indra/llinventory/llinventorytype.cpp | 3 ++- indra/llinventory/llinventorytype.h | 5 ++++- indra/llprimitive/llmaterial.cpp | 11 +++++++++++ indra/llprimitive/llmaterial.h | 2 ++ indra/llui/llui.h | 3 ++- indra/newview/llpanelface.cpp | 4 +++- indra/newview/llpanelface.h | 2 ++ indra/newview/llviewerassettype.cpp | 1 + 10 files changed, 30 insertions(+), 5 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llcommon/llassettype.cpp b/indra/llcommon/llassettype.cpp index e6cc06e8d0..0bb1f1a0fd 100644 --- a/indra/llcommon/llassettype.cpp +++ b/indra/llcommon/llassettype.cpp @@ -96,6 +96,7 @@ LLAssetDictionary::LLAssetDictionary() addEntry(LLAssetType::AT_WIDGET, new AssetEntry("WIDGET", "widget", "widget", false, false, false)); addEntry(LLAssetType::AT_PERSON, new AssetEntry("PERSON", "person", "person", false, false, false)); addEntry(LLAssetType::AT_SETTINGS, new AssetEntry("SETTINGS", "settings", "settings blob", true, true, true)); + addEntry(LLAssetType::AT_MATERIAL, new AssetEntry("MATERIAL", "material", "render material", true, true, true)); addEntry(LLAssetType::AT_UNKNOWN, new AssetEntry("UNKNOWN", "invalid", NULL, false, false, false)); addEntry(LLAssetType::AT_NONE, new AssetEntry("NONE", "-1", NULL, FALSE, FALSE, FALSE)); diff --git a/indra/llcommon/llassettype.h b/indra/llcommon/llassettype.h index 652c548d59..9598f0f707 100644 --- a/indra/llcommon/llassettype.h +++ b/indra/llcommon/llassettype.h @@ -127,8 +127,9 @@ public: AT_RESERVED_6 = 55, AT_SETTINGS = 56, // Collection of settings + AT_MATERIAL = 57, // Render Material - AT_COUNT = 57, + AT_COUNT = 58, // +*********************************************************+ // | TO ADD AN ELEMENT TO THIS ENUM: | diff --git a/indra/llinventory/llinventorytype.cpp b/indra/llinventory/llinventorytype.cpp index 853ed655f5..57d521429c 100644 --- a/indra/llinventory/llinventorytype.cpp +++ b/indra/llinventory/llinventorytype.cpp @@ -153,7 +153,8 @@ DEFAULT_ASSET_FOR_INV_TYPE[LLAssetType::AT_COUNT] = LLInventoryType::IT_NONE, // 53 AT_RESERVED_4 LLInventoryType::IT_NONE, // 54 AT_RESERVED_5 - LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS + LLInventoryType::IT_SETTINGS, // 55 AT_SETTINGS <- why doesnt this match the value in llassettype.h? -brad + LLInventoryType::IT_MATERIAL, // 57 AT_MATERIAL }; // static diff --git a/indra/llinventory/llinventorytype.h b/indra/llinventory/llinventorytype.h index b6e7fb047f..a5543814d8 100644 --- a/indra/llinventory/llinventorytype.h +++ b/indra/llinventory/llinventorytype.h @@ -65,7 +65,8 @@ public: IT_WIDGET = 23, IT_PERSON = 24, IT_SETTINGS = 25, - IT_COUNT = 26, + IT_MATERIAL = 26, + IT_COUNT = 27, IT_UNKNOWN = 255, IT_NONE = -1 @@ -118,6 +119,8 @@ public: ICONNAME_SETTINGS_WATER, ICONNAME_SETTINGS_DAY, + ICONNAME_MATERIAL, + ICONNAME_INVALID, ICONNAME_UNKNOWN, ICONNAME_COUNT, diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a219ac1450..f546ac1645 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -331,6 +331,17 @@ void LLMaterial::setAlphaMaskCutoff(U8 cutoff) mAlphaMaskCutoff = cutoff; } +LLUUID LLMaterial::getMaterialID() const +{ + // TODO - not null + return LLUUID::null; +} + +void LLMaterial::setMaterialID(const LLUUID &material_id) +{ + // TODO - set +} + LLSD LLMaterial::asLLSD() const { LLSD material_data; diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index 1e068c2be3..2f8aafc2cf 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -115,6 +115,8 @@ public: void setDiffuseAlphaMode(U8 alpha_mode); U8 getAlphaMaskCutoff() const; void setAlphaMaskCutoff(U8 cutoff); + LLUUID getMaterialID() const; + void setMaterialID(LLUUID const & material_id); bool isNull() const; static const LLMaterial null; diff --git a/indra/llui/llui.h b/indra/llui/llui.h index 30dbd7248f..86b23c8c93 100644 --- a/indra/llui/llui.h +++ b/indra/llui/llui.h @@ -76,7 +76,8 @@ enum EDragAndDropType DAD_WIDGET = 16, DAD_PERSON = 17, DAD_SETTINGS = 18, - DAD_COUNT = 19, // number of types in this enum + DAD_MATERIAL = 19, + DAD_COUNT = 20, // number of types in this enum }; // Reasons for drags to be denied. diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 094add423f..0b986e9a07 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -123,6 +123,7 @@ F32 LLPanelFace::getCurrentShinyScaleU() { return getChild("shinySca F32 LLPanelFace::getCurrentShinyScaleV() { return getChild("shinyScaleV")->getValue().asReal(); } F32 LLPanelFace::getCurrentShinyOffsetU() { return getChild("shinyOffsetU")->getValue().asReal(); } F32 LLPanelFace::getCurrentShinyOffsetV() { return getChild("shinyOffsetV")->getValue().asReal(); } +LLUUID LLPanelFace::getCurrentMaterialID() { return getChild("materialID")->getValue().asUUID(); } // // Methods @@ -2308,7 +2309,8 @@ void LLPanelFace::onCommitMaterialMaskCutoff(LLUICtrl* ctrl, void* userdata) //static void LLPanelFace::onCommitMaterialID(LLUICtrl* ctrl, void* userdata) { - LLPanelFace* self [[maybe_unused]] = (LLPanelFace*) userdata; + LLPanelFace* self = static_cast(userdata); + LLSelectedTEMaterial::setMaterialID(self, self->getCurrentMaterialID()); } // static diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index f7fa70a144..6ce41a2aa7 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -234,6 +234,7 @@ private: F32 getCurrentShinyScaleV(); F32 getCurrentShinyOffsetU(); F32 getCurrentShinyOffsetV(); + LLUUID getCurrentMaterialID(); // Update visibility of controls to match current UI mode // (e.g. materials vs media editing) @@ -498,6 +499,7 @@ public: DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); + DEF_EDIT_MAT_STATE(LLUUID, const LLUUID&, setMaterialID); }; class LLSelectedTE diff --git a/indra/newview/llviewerassettype.cpp b/indra/newview/llviewerassettype.cpp index 4804ef6ddc..481086f760 100644 --- a/indra/newview/llviewerassettype.cpp +++ b/indra/newview/llviewerassettype.cpp @@ -88,6 +88,7 @@ LLViewerAssetDictionary::LLViewerAssetDictionary() addEntry(LLViewerAssetType::AT_NONE, new ViewerAssetEntry(DAD_NONE)); addEntry(LLViewerAssetType::AT_SETTINGS, new ViewerAssetEntry(DAD_SETTINGS)); + addEntry(LLViewerAssetType::AT_MATERIAL, new ViewerAssetEntry(DAD_MATERIAL)); }; EDragAndDropType LLViewerAssetType::lookupDragAndDropType(EType asset_type) -- cgit v1.3 From 220afbcda0961df86ad08bbd51d96b8c868b2e62 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Jun 2022 18:42:38 -0500 Subject: SL-17285 Add proper reflection probe support to LLVOVolume, LLPrimitive, and LLPanelVolume --- indra/llprimitive/llprimitive.cpp | 95 +++++++++++++ indra/llprimitive/llprimitive.h | 44 ++++++ .../shaders/class3/deferred/reflectionProbeF.glsl | 21 ++- indra/newview/llpanelvolume.cpp | 100 +++++++++++++ indra/newview/llpanelvolume.h | 3 + indra/newview/llreflectionmap.cpp | 51 ++++--- indra/newview/llreflectionmap.h | 10 +- indra/newview/llreflectionmapmanager.cpp | 25 ++-- indra/newview/lltexturefetch.cpp | 1 + indra/newview/llviewerdisplay.cpp | 1 - indra/newview/llviewerobject.cpp | 5 + indra/newview/llviewerwindow.cpp | 3 +- indra/newview/llviewerwindow.h | 4 +- indra/newview/llvovolume.cpp | 157 ++++++++++++++++++--- indra/newview/llvovolume.h | 14 ++ .../newview/skins/default/xui/en/floater_tools.xml | 58 +++++++- 16 files changed, 519 insertions(+), 73 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index c46e5fb3c5..87a78eb447 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -81,6 +81,14 @@ const F32 LIGHT_MIN_CUTOFF = 0.0f; const F32 LIGHT_DEFAULT_CUTOFF = 0.0f; const F32 LIGHT_MAX_CUTOFF = 180.f; +// reflection probes +const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f; +const F32 REFLECTION_PROBE_MAX_AMBIANCE = 1.f; +const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f; +const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f; +const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f; +const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f; + // "Tension" => [0,10], increments of 0.1 const F32 FLEXIBLE_OBJECT_MIN_TENSION = 0.0f; const F32 FLEXIBLE_OBJECT_DEFAULT_TENSION = 1.0f; @@ -1811,6 +1819,93 @@ bool LLLightParams::fromLLSD(LLSD& sd) //============================================================================ +LLReflectionProbeParams::LLReflectionProbeParams() +{ + mType = PARAMS_REFLECTION_PROBE; +} + +BOOL LLReflectionProbeParams::pack(LLDataPacker& dp) const +{ + dp.packF32(mAmbiance, "ambiance"); + dp.packF32(mClipDistance, "clip_distance"); + dp.packU8(mVolumeType, "volume_type"); + return TRUE; +} + +BOOL LLReflectionProbeParams::unpack(LLDataPacker& dp) +{ + F32 ambiance; + F32 clip_distance; + U8 volume_type; + + dp.unpackF32(ambiance, "ambiance"); + setAmbiance(ambiance); + + dp.unpackF32(clip_distance, "clip_distance"); + setClipDistance(clip_distance); + + dp.unpackU8(volume_type, "volume_type"); + setVolumeType((EInfluenceVolumeType)volume_type); + + return TRUE; +} + +bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const +{ + if (data.mType != PARAMS_REFLECTION_PROBE) + { + return false; + } + const LLReflectionProbeParams* param = (const LLReflectionProbeParams*)&data; + if (param->mAmbiance != mAmbiance) + { + return false; + } + if (param->mClipDistance != mClipDistance) + { + return false; + } + if (param->mVolumeType != mVolumeType) + { + return false; + } + return true; +} + +void LLReflectionProbeParams::copy(const LLNetworkData& data) +{ + const LLReflectionProbeParams* param = (LLReflectionProbeParams*)&data; + mType = param->mType; + mAmbiance = param->mAmbiance; + mClipDistance = param->mClipDistance; + mVolumeType = param->mVolumeType; +} + +LLSD LLReflectionProbeParams::asLLSD() const +{ + LLSD sd; + sd["ambiance"] = getAmbiance(); + sd["clip_distance"] = getClipDistance(); + sd["volume_type"] = getVolumeType(); + return sd; +} + +bool LLReflectionProbeParams::fromLLSD(LLSD& sd) +{ + if (!sd.has("ambiance") || + !sd.has("clip_distance") || + !sd.has("volume_type")) + { + return false; + } + + setAmbiance((F32)sd["ambiance"].asReal()); + setClipDistance((F32)sd["clip_distance"].asReal()); + setVolumeType((EInfluenceVolumeType)sd["volume_type"].asInteger()); + + return true; +} +//============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { mSimulateLOD = FLEXIBLE_OBJECT_DEFAULT_NUM_SECTIONS; diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index e23ddd2916..2215133e16 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -108,6 +108,7 @@ public: PARAMS_MESH = 0x60, PARAMS_EXTENDED_MESH = 0x70, PARAMS_RENDER_MATERIAL = 0x80, + PARAMS_REFLECTION_PROBE = 0x90, }; public: @@ -171,6 +172,49 @@ public: F32 getCutoff() const { return mCutoff; } }; +extern const F32 REFLECTION_PROBE_MIN_AMBIANCE; +extern const F32 REFLECTION_PROBE_MAX_AMBIANCE; +extern const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE; +extern const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE; +extern const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE; +extern const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE; + +class LLReflectionProbeParams : public LLNetworkData +{ +public: + enum EInfluenceVolumeType : U8 + { + VOLUME_TYPE_SPHERE = 0, // use a sphere influence volume + VOLUME_TYPE_BOX = 1, // use a box influence volume + DEFAULT_VOLUME_TYPE = VOLUME_TYPE_SPHERE + }; + +protected: + F32 mAmbiance = REFLECTION_PROBE_DEFAULT_AMBIANCE; + F32 mClipDistance = REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE; + EInfluenceVolumeType mVolumeType = DEFAULT_VOLUME_TYPE; + +public: + LLReflectionProbeParams(); + /*virtual*/ BOOL pack(LLDataPacker& dp) const; + /*virtual*/ BOOL unpack(LLDataPacker& dp); + /*virtual*/ bool operator==(const LLNetworkData& data) const; + /*virtual*/ void copy(const LLNetworkData& data); + // LLSD implementations here are provided by Eddy Stryker. + // NOTE: there are currently unused in protocols + LLSD asLLSD() const; + operator LLSD() const { return asLLSD(); } + bool fromLLSD(LLSD& sd); + + void setAmbiance(F32 ambiance) { mAmbiance = llclamp(ambiance, REFLECTION_PROBE_MIN_AMBIANCE, REFLECTION_PROBE_MAX_AMBIANCE); } + void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); } + void setVolumeType(EInfluenceVolumeType type) { mVolumeType = llclamp(type, VOLUME_TYPE_SPHERE, VOLUME_TYPE_BOX); } + + F32 getAmbiance() const { return mAmbiance; } + F32 getClipDistance() const { return mClipDistance; } + EInfluenceVolumeType getVolumeType() const { return mVolumeType; } +}; + //------------------------------------------------- // This structure is also used in the part of the // code that creates new flexible objects. diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 8c1323ba1a..eb9d3f485b 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -1,5 +1,5 @@ /** - * @file class2/deferred/reflectionProbeF.glsl + * @file class3/deferred/reflectionProbeF.glsl * * $LicenseInfo:firstyear=2022&license=viewerlgpl$ * Second Life Viewer Source Code @@ -42,6 +42,8 @@ layout (std140, binding = 1) uniform ReflectionProbes mat4 refBox[REFMAP_COUNT]; // list of bounding spheres for reflection probes sorted by distance to camera (closest first) vec4 refSphere[REFMAP_COUNT]; + // extra parameters (currently only .x used for probe ambiance) + vec4 refParams[REFMAP_COUNT]; // index of cube map in reflectionProbes for a corresponding reflection probe // e.g. cube map channel of refSphere[2] is stored in refIndex[2] // refIndex.x - cubemap channel in reflectionProbes @@ -55,9 +57,6 @@ layout (std140, binding = 1) uniform ReflectionProbes // number of reflection probes present in refSphere int refmapCount; - - // intensity of ambient light from reflection probes - float reflectionAmbiance; }; // Inputs @@ -335,7 +334,7 @@ vec3 tapRefMap(vec3 pos, vec3 dir, float lod, vec3 c, float r2, int i) } } -vec3 sampleProbes(vec3 pos, vec3 dir, float lod) +vec3 sampleProbes(vec3 pos, vec3 dir, float lod, float minweight) { float wsum = 0.0; vec3 col = vec3(0,0,0); @@ -360,7 +359,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod) float atten = 1.0-max(d2-r2, 0.0)/(rr-r2); w *= atten; w *= p; // boost weight based on priority - col += refcol*w; + col += refcol*w*max(minweight, refParams[i].x); wsum += w; } @@ -383,7 +382,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod) float w = 1.0/d2; w *= w; - col += refcol*w; + col += refcol*w*max(minweight, refParams[i].x); wsum += w; } } @@ -399,7 +398,7 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod) vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod) { - vec3 col = sampleProbes(pos, dir, lod); + vec3 col = sampleProbes(pos, dir, lod, 0.f); //desaturate vec3 hcol = col *0.5; @@ -413,7 +412,7 @@ vec3 sampleProbeAmbient(vec3 pos, vec3 dir, float lod) col *= 0.333333; - return col*reflectionAmbiance; + return col; } @@ -445,12 +444,12 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, inout vec3 l if (glossiness > 0.0) { float lod = (1.0-glossiness)*reflection_lods; - glossenv = sampleProbes(pos, normalize(refnormpersp), lod); + glossenv = sampleProbes(pos, normalize(refnormpersp), lod, 1.f); } if (envIntensity > 0.0) { - legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0); + legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, 1.f); } } diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index 89c558e4f8..e7bbe266e5 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -145,6 +145,16 @@ BOOL LLPanelVolume::postBuild() getChild("Light Ambiance")->setValidateBeforeCommit( precommitValidate); } + // REFLECTION PROBE Parameters + { + childSetCommitCallback("Reflection Probe Checkbox Ctrl", onCommitIsReflectionProbe, this); + childSetCommitCallback("Probe Shape Type Combo Ctrl", onCommitProbe, this); + childSetCommitCallback("Probe Ambiance", onCommitProbe, this); + childSetCommitCallback("Probe Near Clip", onCommitProbe, this); + + + } + // PHYSICS Parameters { // PhysicsShapeType combobox @@ -360,6 +370,40 @@ void LLPanelVolume::getState( ) getChildView("Light Ambiance")->setEnabled(false); } + // Reflection Probe + BOOL is_probe = volobjp && volobjp->getIsReflectionProbe(); + getChild("Reflection Probe Checkbox Ctrl")->setValue(is_probe); + getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); + + bool probe_enabled = is_probe && editable && single_volume; + + getChildView("Probe Volume Type Ctrl")->setEnabled(probe_enabled); + getChildView("Probe Ambiance")->setEnabled(probe_enabled); + getChildView("Probe Near Clip")->setEnabled(probe_enabled); + + if (!probe_enabled) + { + getChild("Probe Volume Type Ctrl", true)->clear(); + getChild("Probe Ambiance", true)->clear(); + getChild("Probe Near Clip", true)->clear(); + } + else + { + std::string volume_type; + if (volobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX) + { + volume_type = "Box"; + } + else + { + volume_type = "Sphere"; + } + + getChild("Probe Volume Type Ctrl", true)->setValue(volume_type); + getChild("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance()); + getChild("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip()); + } + // Animated Mesh BOOL is_animated_mesh = single_root_volume && root_volobjp && root_volobjp->isAnimatedObject(); getChild("Animated Mesh Checkbox Ctrl")->setValue(is_animated_mesh); @@ -647,6 +691,10 @@ void LLPanelVolume::clearCtrls() getChildView("Light Radius")->setEnabled(false); getChildView("Light Falloff")->setEnabled(false); + getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(false);; + getChildView("Probe Volume Type Ctrl")->setEnabled(false); + getChildView("Probe Ambiance")->setEnabled(false); + getChildView("Probe Near Clip")->setEnabled(false); getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false); getChildView("Flexible1D Checkbox Ctrl")->setEnabled(false); getChildView("FlexNumSections")->setEnabled(false); @@ -684,6 +732,20 @@ void LLPanelVolume::sendIsLight() LL_INFOS() << "update light sent" << LL_ENDL; } +void LLPanelVolume::sendIsReflectionProbe() +{ + LLViewerObject* objectp = mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume* volobjp = (LLVOVolume*)objectp; + + BOOL value = getChild("Reflection Probe Checkbox Ctrl")->getValue(); + volobjp->setIsReflectionProbe(value); + LL_INFOS() << "update reflection probe sent" << LL_ENDL; +} + void LLPanelVolume::sendIsFlexible() { LLViewerObject* objectp = mObject; @@ -927,6 +989,35 @@ void LLPanelVolume::onCommitLight( LLUICtrl* ctrl, void* userdata ) } +//static +void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*)userdata; + LLViewerObject* objectp = self->mObject; + if (!objectp || (objectp->getPCode() != LL_PCODE_VOLUME)) + { + return; + } + LLVOVolume* volobjp = (LLVOVolume*)objectp; + + + volobjp->setReflectionProbeAmbiance((F32)self->getChild("Probe Ambiance")->getValue().asReal()); + volobjp->setReflectionProbeNearClip((F32)self->getChild("Probe Near Clip")->getValue().asReal()); + + std::string shape_type = self->getChild("Probe Volume Type Ctrl")->getValue().asString(); + LLReflectionProbeParams::EInfluenceVolumeType volume_type = LLReflectionProbeParams::DEFAULT_VOLUME_TYPE; + + if (shape_type == "Sphere") + { + volume_type = LLReflectionProbeParams::VOLUME_TYPE_SPHERE; + } + else if (shape_type == "Box") + { + volume_type = LLReflectionProbeParams::VOLUME_TYPE_BOX; + } + volobjp->setReflectionProbeVolumeType(volume_type); +} + // static void LLPanelVolume::onCommitIsLight( LLUICtrl* ctrl, void* userdata ) { @@ -949,6 +1040,15 @@ void LLPanelVolume::setLightTextureID(const LLUUID &asset_id, const LLUUID &item } //---------------------------------------------------------------------------- +// static +void LLPanelVolume::onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata) +{ + LLPanelVolume* self = (LLPanelVolume*)userdata; + self->sendIsReflectionProbe(); +} + +//---------------------------------------------------------------------------- + // static void LLPanelVolume::onCommitFlexible( LLUICtrl* ctrl, void* userdata ) { diff --git a/indra/newview/llpanelvolume.h b/indra/newview/llpanelvolume.h index 6e49ccb742..16d9ac292d 100644 --- a/indra/newview/llpanelvolume.h +++ b/indra/newview/llpanelvolume.h @@ -56,12 +56,15 @@ public: void refresh(); void sendIsLight(); + void sendIsReflectionProbe(); void sendIsFlexible(); static bool precommitValidate(const LLSD& data); static void onCommitIsLight( LLUICtrl* ctrl, void* userdata); static void onCommitLight( LLUICtrl* ctrl, void* userdata); + static void onCommitIsReflectionProbe(LLUICtrl* ctrl, void* userdata); + static void onCommitProbe(LLUICtrl* ctrl, void* userdata); void onCommitIsFlexible( LLUICtrl* ctrl, void* userdata); static void onCommitFlexible( LLUICtrl* ctrl, void* userdata); void onCommitAnimatedMeshCheckbox(LLUICtrl* ctrl, void* userdata); diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 54a627efd4..f8a2020ccb 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -35,7 +35,6 @@ extern F32SecondsImplicit gFrameTimeSeconds; LLReflectionMap::LLReflectionMap() { - mLastUpdateTime = gFrameTimeSeconds; } void LLReflectionMap::update(U32 resolution, U32 face) @@ -52,7 +51,7 @@ void LLReflectionMap::update(U32 resolution, U32 face) { resolution /= 2; } - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip()); } bool LLReflectionMap::shouldUpdate() @@ -215,6 +214,35 @@ bool LLReflectionMap::intersects(LLReflectionMap* other) return dist < r2; } +extern LLControlGroup gSavedSettings; + +F32 LLReflectionMap::getAmbiance() +{ + static LLCachedControl minimum_ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f); + + F32 ret = 0.f; + if (mViewerObject && mViewerObject->getVolume()) + { + ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeAmbiance(); + } + + return llmax(ret, minimum_ambiance()); +} + +F32 LLReflectionMap::getNearClip() +{ + const F32 MINIMUM_NEAR_CLIP = 0.1f; + + F32 ret = 0.f; + + if (mViewerObject && mViewerObject->getVolume()) + { + ret = ((LLVOVolume*)mViewerObject)->getReflectionProbeNearClip(); + } + + return llmax(ret, MINIMUM_NEAR_CLIP); +} + bool LLReflectionMap::getBox(LLMatrix4& box) { if (mViewerObject) @@ -224,25 +252,8 @@ bool LLReflectionMap::getBox(LLMatrix4& box) { LLVOVolume* vobjp = (LLVOVolume*)mViewerObject; - U8 profile = volume->getProfileType(); - U8 path = volume->getPathType(); - - if (profile == LL_PCODE_PROFILE_SQUARE && - path == LL_PCODE_PATH_LINE) + if (vobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX) { - // nope - /*box = vobjp->getRelativeXform(); - box *= vobjp->mDrawable->getRenderMatrix(); - LLMatrix4 modelview(gGLModelView); - box *= modelview; - box.invert();*/ - - // nope - /*box = LLMatrix4(gGLModelView); - box *= vobjp->mDrawable->getRenderMatrix(); - box *= vobjp->getRelativeXform(); - box.invert();*/ - glh::matrix4f mv(gGLModelView); glh::matrix4f scale; LLVector3 s = vobjp->getScale().scaledVec(LLVector3(0.5f, 0.5f, 0.5f)); diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index 4f0f124118..a358bf5fdf 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -55,9 +55,15 @@ public: // return true if given Reflection Map's influence volume intersect's with this one's bool intersects(LLReflectionMap* other); + // Get the ambiance value to use for this probe + F32 getAmbiance(); + + // Get the near clip plane distance to use for this probe + F32 getNearClip(); + // get the encoded bounding box of this probe's influence volume - // will only return a box if this probe has a volume with a square - // profile and a linear path + // will only return a box if this probe is associated with a VOVolume + // with its reflection probe influence volume to to VOLUME_TYPE_BOX // return false if no bounding box (treat as sphere influence volume) bool getBox(LLMatrix4& box); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 34055653d4..60396b6c60 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -127,18 +127,12 @@ void LLReflectionMapManager::update() camera_pos.load3(LLViewerCamera::instance().getOrigin().mV); // process kill list - for (int i = 0; i < mProbes.size(); ) + for (auto& probe : mKillList) { - auto& iter = std::find(mKillList.begin(), mKillList.end(), mProbes[i]); - if (iter != mKillList.end()) + auto& iter = std::find(mProbes.begin(), mProbes.end(), probe); + if (iter != mProbes.end()) { - deleteProbe(i); - mProbes.erase(mProbes.begin() + i); - mKillList.erase(iter); - } - else - { - ++i; + deleteProbe(iter - mProbes.begin()); } } @@ -275,7 +269,7 @@ LLReflectionMap* LLReflectionMapManager::registerSpatialGroup(LLSpatialGroup* gr { OctreeNode* node = group->getOctreeNode(); F32 size = node->getSize().getF32ptr()[0]; - if (size >= 7.f && size <= 17.f) + if (size >= 15.f && size <= 17.f) { return addProbe(group); } @@ -514,15 +508,15 @@ void LLReflectionMapManager::updateUniforms() LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; // structure for packing uniform buffer object - // see class2/deferred/softenLightF.glsl + // see class3/deferred/reflectionProbeF.glsl struct ReflectionProbeData { LLMatrix4 refBox[LL_REFLECTION_PROBE_COUNT]; // object bounding box as needed LLVector4 refSphere[LL_REFLECTION_PROBE_COUNT]; //origin and radius of refmaps in clip space + LLVector4 refParams[LL_REFLECTION_PROBE_COUNT]; //extra parameters (currently only ambiance) GLint refIndex[LL_REFLECTION_PROBE_COUNT][4]; GLint refNeighbor[4096]; GLint refmapCount; - GLfloat reflectionAmbiance; }; mReflectionMaps.resize(LL_REFLECTION_PROBE_COUNT); @@ -530,9 +524,6 @@ void LLReflectionMapManager::updateUniforms() ReflectionProbeData rpd; - static LLCachedControl ambiance(gSavedSettings, "RenderReflectionProbeAmbiance", 0.f); - rpd.reflectionAmbiance = ambiance; - // load modelview matrix into matrix 4a LLMatrix4a modelview; modelview.loadu(gGLModelView); @@ -573,6 +564,8 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } + rpd.refParams[count].set(refmap->getAmbiance(), 0.f, 0.f, 0.f); + S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { //LL_PROFILE_ZONE_NAMED_CATEGORY_DISPLAY("rmmsu - refNeighbors"); diff --git a/indra/newview/lltexturefetch.cpp b/indra/newview/lltexturefetch.cpp index 0edaf40c66..35e4bb03ac 100644 --- a/indra/newview/lltexturefetch.cpp +++ b/indra/newview/lltexturefetch.cpp @@ -3400,6 +3400,7 @@ void LLTextureFetch::sendRequestListToSimulators() gMessageSystem->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID()); } S32 packet = req->mLastPacket + 1; + LL_INFOS() << req->mID << ": " << req->mImagePriority << LL_ENDL; gMessageSystem->nextBlockFast(_PREHASH_RequestImage); gMessageSystem->addUUIDFast(_PREHASH_Image, req->mID); gMessageSystem->addS8Fast(_PREHASH_DiscardLevel, (S8)req->mDesiredDiscard); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index 1b8e53e667..6d98d9b10e 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -1082,7 +1082,6 @@ void display_cube_face() gPipeline.mBackfaceCull = TRUE; - LLViewerCamera::getInstance()->setNear(MIN_NEAR_PLANE); gViewerWindow->setup3DViewport(); if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 6ecf9dd0c4..732beab448 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -6028,6 +6028,11 @@ LLViewerObject::ExtraParameter* LLViewerObject::createNewParameterEntry(U16 para { new_block = new LLRenderMaterialParams(); break; + } + case LLNetworkData::PARAMS_REFLECTION_PROBE: + { + new_block = new LLReflectionProbeParams(); + break; } default: { diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index a6597e3233..6a60671040 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5270,7 +5270,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ void display_cube_face(); -BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face) +BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip) { // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; @@ -5299,6 +5299,7 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea camera->setView(F_PI_BY_TWO); camera->yaw(0.0); camera->setOrigin(origin); + camera->setNear(near_clip); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index ac7f8b2e39..c9cf7da8c7 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -368,7 +368,9 @@ public: // origin - vantage point to take the snapshot from // cubearray - cubemap array for storing the results // index - cube index in the array to use (cube index, not face-layer) - BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face); + // face - which cube face to update + // near_clip - near clip setting to use + BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip); // special implementation of simpleSnapshot for reflection maps diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 784c0350fc..6aef9ee7c0 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -985,7 +985,12 @@ LLDrawable *LLVOVolume::createDrawable(LLPipeline *pipeline) // Add it to the pipeline mLightSet gPipeline.setLight(mDrawable, TRUE); } - + + if (getIsReflectionProbe()) + { + updateReflectionProbePtr(); + } + updateRadius(); bool force_update = true; // avoid non-alpha mDistance update being optimized away mDrawable->updateDistance(*LLViewerCamera::getInstance(), force_update); @@ -3496,6 +3501,121 @@ F32 LLVOVolume::getLightCutoff() const } } +void LLVOVolume::setIsReflectionProbe(BOOL is_probe) +{ + BOOL was_probe = getIsReflectionProbe(); + if (is_probe != was_probe) + { + if (is_probe) + { + setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE, FALSE, true); + } + } + + updateReflectionProbePtr(); +} + +void LLVOVolume::setReflectionProbeAmbiance(F32 ambiance) +{ + LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getAmbiance() != ambiance) + { + param_block->setAmbiance(ambiance); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + } + } +} + +void LLVOVolume::setReflectionProbeNearClip(F32 near_clip) +{ + LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getClipDistance() != near_clip) + { + param_block->setClipDistance(near_clip); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + } + } +} + +void LLVOVolume::setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type) +{ + LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getVolumeType() != volume_type) + { + param_block->setVolumeType(volume_type); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + } + } +} + + +BOOL LLVOVolume::getIsReflectionProbe() const +{ + // HACK - make this object a Reflection Probe if a certain UUID is detected + static LLCachedControl reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); + LLUUID probe_id(reflection_probe_id); + + for (U8 i = 0; i < getNumTEs(); ++i) + { + if (getTE(i)->getID() == probe_id) + { + return true; + } + } + // END HACK + + return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); +} + +F32 LLVOVolume::getReflectionProbeAmbiance() const +{ + const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + return param_block->getAmbiance(); + } + else + { + return 0.f; + } +} + +F32 LLVOVolume::getReflectionProbeNearClip() const +{ + const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + return param_block->getClipDistance(); + } + else + { + return 0.f; + } +} + +LLReflectionProbeParams::EInfluenceVolumeType LLVOVolume::getReflectionProbeVolumeType() const +{ + const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + return param_block->getVolumeType(); + } + else + { + return LLReflectionProbeParams::DEFAULT_VOLUME_TYPE; + } +} + U32 LLVOVolume::getVolumeInterfaceID() const { if (mVolumeImpl) @@ -4381,6 +4501,23 @@ void LLVOVolume::parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_u gPipeline.setLight(mDrawable, is_light); } } + + updateReflectionProbePtr(); +} + +void LLVOVolume::updateReflectionProbePtr() +{ + if (getIsReflectionProbe()) + { + if (mReflectionProbe.isNull()) + { + mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(this); + } + } + else if (mReflectionProbe.notNull()) + { + mReflectionProbe = nullptr; + } } void LLVOVolume::setSelected(BOOL sel) @@ -5690,24 +5827,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = false; #endif - // HACK - make this object a Reflection Probe if a certain UUID is detected - static LLCachedControl reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); - if (facep->getTextureEntry()->getID() == LLUUID(reflection_probe_id)) - { - if (!vobj->mIsReflectionProbe) - { - vobj->mIsReflectionProbe = true; - vobj->mReflectionProbe = gPipeline.mReflectionMapManager.registerViewerObject(vobj); - } - } - else - { - // not a refleciton probe any more - vobj->mIsReflectionProbe = false; - vobj->mReflectionProbe = nullptr; - } - // END HACK - //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group facep->setVertexBuffer(NULL); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 4cb7a5481c..93a10781c2 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -178,6 +178,9 @@ public: /*virtual*/ void parameterChanged(U16 param_type, bool local_origin); /*virtual*/ void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); + // update mReflectionProbe based on isReflectionProbe() + void updateReflectionProbePtr(); + /*virtual*/ U32 processUpdateMessage(LLMessageSystem *mesgsys, void **user_data, U32 block_num, const EObjectUpdateType update_type, @@ -281,6 +284,17 @@ public: F32 getLightFalloff(const F32 fudge_factor = 1.f) const; F32 getLightCutoff() const; + // Reflection Probes + void setIsReflectionProbe(BOOL is_probe); + void setReflectionProbeAmbiance(F32 ambiance); + void setReflectionProbeNearClip(F32 near_clip); + void setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type); + + BOOL getIsReflectionProbe() const; + F32 getReflectionProbeAmbiance() const; + F32 getReflectionProbeNearClip() const; + LLReflectionProbeParams::EInfluenceVolumeType getReflectionProbeVolumeType() const; + // Flexible Objects U32 getVolumeInterfaceID() const; virtual BOOL isFlexible() const; diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 44bdcd86f9..ae4eb64264 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2353,7 +2353,7 @@ even though the user gets a free copy. layout="topleft" left="10" name="Light Intensity" - top_pad="3" + top_delta="32" width="128" /> - + + + + + + + Date: Fri, 3 Jun 2022 11:36:37 -0500 Subject: SL-17285 Build fix take two. --- indra/llprimitive/llprimitive.cpp | 2 +- .../newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 87a78eb447..6044048d09 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1886,7 +1886,7 @@ LLSD LLReflectionProbeParams::asLLSD() const LLSD sd; sd["ambiance"] = getAmbiance(); sd["clip_distance"] = getClipDistance(); - sd["volume_type"] = getVolumeType(); + sd["volume_type"] = (U8) getVolumeType(); return sd; } diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index edb78f114b..3fd001e7f5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -473,3 +473,4 @@ void applyGlossEnv(inout vec3 color, vec3 glossenv, vec4 spec, vec3 pos, vec3 no reflected_color *= (envIntensity*fresnel)*brighten(spec.rgb); color = mix(color.rgb, reflected_color, envIntensity); } + -- cgit v1.3 From 8c0163bcb48df56112a625550d411741c20c5846 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 13 Apr 2022 12:32:58 -0600 Subject: SL-17214 initial loader class skeleton --- indra/llmath/v4color.h | 12 +- indra/llprimitive/CMakeLists.txt | 2 + indra/llprimitive/lldaeloader.cpp | 26 +-- indra/llprimitive/lldaeloader.h | 2 +- indra/llprimitive/llgltfloader.cpp | 336 ++++++++++++++++++++++++++++++++ indra/llprimitive/llgltfloader.h | 207 ++++++++++++++++++++ indra/llprimitive/llmodelloader.cpp | 13 +- indra/newview/llfilepicker.cpp | 54 +++-- indra/newview/llfilepicker.h | 8 +- indra/newview/llfloatermodelpreview.cpp | 2 +- indra/newview/llmodelpreview.cpp | 50 +++-- indra/newview/llviewermenu.cpp | 5 - indra/newview/llviewermenufile.cpp | 7 - 13 files changed, 640 insertions(+), 84 deletions(-) create mode 100644 indra/llprimitive/llgltfloader.cpp create mode 100644 indra/llprimitive/llgltfloader.h (limited to 'indra/llprimitive') diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index 175edf1471..f2863be531 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -88,7 +88,8 @@ class LLColor4 const LLColor4& set(const LLColor3 &vec); // Sets LLColor4 to LLColor3 vec (no change in alpha) const LLColor4& set(const LLColor3 &vec, F32 a); // Sets LLColor4 to LLColor3 vec, with alpha specified const LLColor4& set(const F32 *vec); // Sets LLColor4 to vec - const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. + const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec + const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. const LLColor4& setAlpha(F32 a); @@ -334,6 +335,15 @@ inline const LLColor4& LLColor4::set(const F32 *vec) return (*this); } +inline const LLColor4& LLColor4::set(const F64 *vec) +{ + mV[VX] = static_cast(vec[VX]); + mV[VY] = static_cast(vec[VY]); + mV[VZ] = static_cast(vec[VZ]); + mV[VW] = static_cast(vec[VW]); + return (*this); +} + // deprecated inline const LLColor4& LLColor4::setVec(F32 x, F32 y, F32 z) { diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index fff4d8ef0a..9d75dab31e 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -28,6 +28,7 @@ include_directories(SYSTEM set(llprimitive_SOURCE_FILES lldaeloader.cpp + llgltfloader.cpp llmaterialid.cpp llmaterial.cpp llmaterialtable.cpp @@ -46,6 +47,7 @@ set(llprimitive_SOURCE_FILES set(llprimitive_HEADER_FILES CMakeLists.txt lldaeloader.h + llgltfloader.h legacy_object_types.h llmaterial.h llmaterialid.h diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index e89690438e..94f8500dab 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2504,19 +2504,19 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& return (status == LLModel::NO_ERRORS); } -//static -LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh) -{ - LLVolumeParams volume_params; - volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); - LLModel* ret = new LLModel(volume_params, 0.f); - createVolumeFacesFromDomMesh(ret, mesh); - if (ret->mLabel.empty()) - { - ret->mLabel = getElementLabel(mesh); - } - return ret; -} +////static +//LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh) +//{ +// LLVolumeParams volume_params; +// volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); +// LLModel* ret = new LLModel(volume_params, 0.f); +// createVolumeFacesFromDomMesh(ret, mesh); +// if (ret->mLabel.empty()) +// { +// ret->mLabel = getElementLabel(mesh); +// } +// return ret; +//} //static diff version supports creating multiple models when material counts spill // over the 8 face server-side limit diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 2b211343e1..9e80980ddf 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -92,7 +92,7 @@ protected: static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg); static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh); - static LLModel* loadModelFromDomMesh(domMesh* mesh); + //static LLModel* loadModelFromDomMesh(domMesh* mesh); // Loads a mesh breaking it into one or more models as necessary // to get around volume face limitations while retaining >8 materials diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp new file mode 100644 index 0000000000..001623ac9e --- /dev/null +++ b/indra/llprimitive/llgltfloader.cpp @@ -0,0 +1,336 @@ +/** + * @file LLGLTFLoader.cpp + * @brief LLGLTFLoader class implementation + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "LLGLTFLoader.h" + +// Import & define single-header gltf import/export lib +#define TINYGLTF_IMPLEMENTATION +#define TINYGLTF_USE_CPP14 // default is C++ 11 + +// tinygltf by default loads image files using STB +#define STB_IMAGE_IMPLEMENTATION +// to use our own image loading: +// 1. replace this definition with TINYGLTF_NO_STB_IMAGE +// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data) + +// tinygltf saves image files using STB +#define STB_IMAGE_WRITE_IMPLEMENTATION +// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data) + +// Additionally, disable inclusion of STB header files entirely with +// TINYGLTF_NO_INCLUDE_STB_IMAGE +// TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE +#include "tinygltf\tiny_gltf.h" + +#include + +#include "llsdserialize.h" +#include "lljoint.h" + +#include "glh/glh_linear.h" +#include "llmatrix4a.h" + +#include +#include + +static const std::string lod_suffix[LLModel::NUM_LODS] = +{ + "_LOD0", + "_LOD1", + "_LOD2", + "", + "_PHYS", +}; + +const U32 LIMIT_MATERIALS_OUTPUT = 12; + +LLGLTFLoader::LLGLTFLoader(std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void * opaque_userdata, + JointTransformMap & jointTransformMap, + JointNameSet & jointsFromNodes, + std::map &jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit) //, + //bool preprocess) + : LLModelLoader( filename, + lod, + load_cb, + joint_lookup_func, + texture_load_func, + state_cb, + opaque_userdata, + jointTransformMap, + jointsFromNodes, + jointAliasMap, + maxJointsPerMesh ), + mGeneratedModelLimit(modelLimit), + //mPreprocessGLTF(preprocess), + mMeshesLoaded(false), + mMaterialsLoaded(false) +{ +} + +LLGLTFLoader::~LLGLTFLoader() {} + +bool LLGLTFLoader::OpenFile(const std::string &filename) +{ + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + // Load a tinygltf model fom a file. Assumes that the input filename has already been + // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. + if (std::string::npos == filename.rfind(".gltf")) + { // file is binary + mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename); + } + else + { // file is ascii + mGltfLoaded = loader.LoadASCIIFromFile(&mGltfModel, &error_msg, &warn_msg, filename); + } + + if (!mGltfLoaded) + { + if (!warn_msg.empty()) + LL_WARNS() << "gltf load warning: " << warn_msg.c_str() << LL_ENDL; + if (!error_msg.empty()) + LL_WARNS() << "gltf load error: " << error_msg.c_str() << LL_ENDL; + return false; + } + + mMeshesLoaded = parseMeshes(); + if (mMeshesLoaded) uploadMeshes(); + + mMaterialsLoaded = parseMaterials(); + if (mMaterialsLoaded) uploadMaterials(); + + return (mMeshesLoaded || mMaterialsLoaded); +} + +bool LLGLTFLoader::parseMeshes() +{ + if (!mGltfLoaded) return false; + + // 2022-04 DJH Volume params from dae example. TODO understand PCODE + LLVolumeParams volume_params; + volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); + + for (tinygltf::Mesh mesh : mGltfModel.meshes) + { + LLModel *pModel = new LLModel(volume_params, 0.f); + + if (populateModelFromMesh(pModel, mesh) && + (LLModel::NO_ERRORS == pModel->getStatus()) && + validate_model(pModel)) + { + mModelList.push_back(pModel); + } + else + { + setLoadState(ERROR_MODEL + pModel->getStatus()); + delete(pModel); + return false; + } + } + return true; +} + +bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh) +{ + pModel->mLabel = mesh.name; + int pos_idx, norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx; + tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a; + + auto prims = mesh.primitives; + for (auto prim : prims) + { + if (prim.indices >= 0) indices_a = mGltfModel.accessors[prim.indices]; + + pos_idx = (prim.attributes.count("POSITION") > 0) ? prim.attributes.at("POSITION") : -1; + if (pos_idx >= 0) + { + positions_a = mGltfModel.accessors[pos_idx]; + if (TINYGLTF_COMPONENT_TYPE_FLOAT != positions_a.componentType) + continue; + auto positions_bv = mGltfModel.bufferViews[positions_a.bufferView]; + auto positions_buf = mGltfModel.buffers[positions_bv.buffer]; + //auto type = positions_vb. + //if (positions_buf.name + } + + norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1; + tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1; + uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1; + uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1; + color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1; + color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1; + + if (prim.mode == TINYGLTF_MODE_TRIANGLES) + { + //auto pos = mesh. TODO resume here DJH 2022-04 + } + } + + //pModel->addFace() + return false; +} + +bool LLGLTFLoader::parseMaterials() +{ + if (!mGltfLoaded) return false; + + // fill local texture data structures + mSamplers.clear(); + for (auto in_sampler : mGltfModel.samplers) + { + gltf_sampler sampler{ 0 }; + sampler.magFilter = in_sampler.magFilter; + sampler.minFilter = in_sampler.minFilter; + sampler.wrapS = in_sampler.wrapS; + sampler.wrapT = in_sampler.wrapT; + sampler.name = in_sampler.name; // unused + mSamplers.push_back(sampler); + } + + mImages.clear(); + for (auto in_image : mGltfModel.images) + { + gltf_image image{ 0 }; + image.numChannels = in_image.component; + image.bytesPerChannel = in_image.bits >> 3; + image.pixelType = in_image.pixel_type; + image.size = in_image.image.size(); + image.height = in_image.height; + image.width = in_image.width; + image.data = in_image.image.data(); + + if (in_image.as_is) + { + LL_WARNS("GLTF_IMPORT") << "Unsupported image encoding" << LL_ENDL; + return false; + } + + if (image.size != image.height * image.width * image.numChannels * image.bytesPerChannel) + { + LL_WARNS("GLTF_IMPORT") << "Image size error" << LL_ENDL; + return false; + } + + mImages.push_back(image); + } + + mTextures.clear(); + for (auto in_tex : mGltfModel.textures) + { + gltf_texture tex{ 0 }; + tex.image_idx = in_tex.source; + tex.sampler_idx = in_tex.sampler; + + if (tex.image_idx >= mImages.size() || tex.sampler_idx >= mSamplers.size()) + { + LL_WARNS("GLTF_IMPORT") << "Texture sampler/image index error" << LL_ENDL; + return false; + } + + mTextures.push_back(tex); + } + + // parse each material + for (tinygltf::Material gltf_material : mGltfModel.materials) + { + gltf_render_material mat{ 0 }; + mat.name = gltf_material.name; + + mat.normalScale = gltf_material.normalTexture.scale; + mat.normalTexIdx = gltf_material.normalTexture.index; + mat.normalTexCoordIdx = gltf_material.normalTexture.texCoord; + + mat.occlusionScale = gltf_material.occlusionTexture.strength; + mat.occlusionTexIdx = gltf_material.occlusionTexture.index; + mat.occlusionTexCoordIdx = gltf_material.occlusionTexture.texCoord; + + mat.emissiveColor.set(gltf_material.emissiveFactor.data()); + mat.emissiveColorTexIdx = gltf_material.emissiveTexture.index; + mat.emissiveColorTexCoordIdx = gltf_material.emissiveTexture.texCoord; + + mat.alphaMode = gltf_material.alphaMode; + mat.alphaMask = gltf_material.alphaCutoff; + + tinygltf::PbrMetallicRoughness& pbr = gltf_material.pbrMetallicRoughness; + mat.hasPBR = true; + + mat.pbr.baseColor.set(pbr.baseColorFactor.data()); + mat.pbr.baseColorTexIdx = pbr.baseColorTexture.index; + mat.pbr.baseColorTexCoordIdx = pbr.baseColorTexture.texCoord; + + mat.pbr.metalness = pbr.metallicFactor; + mat.pbr.roughness = pbr.roughnessFactor; + mat.pbr.metalRoughTexIdx = pbr.metallicRoughnessTexture.index; + mat.pbr.metalRoughTexCoordIdx = pbr.metallicRoughnessTexture.texCoord; + + if (mat.normalTexIdx >= mTextures.size() || + mat.occlusionTexIdx >= mTextures.size() || + mat.emissiveColorTexIdx >= mTextures.size() || + mat.pbr.baseColorTexIdx >= mTextures.size() || + mat.pbr.metalRoughTexIdx >= mTextures.size()) + { + LL_WARNS("GLTF_IMPORT") << "Texture resource index error" << LL_ENDL; + return false; + } + + if (mat.normalTexCoordIdx > 0 || // May have to loosen this condition + mat.occlusionTexCoordIdx > 0 || + mat.emissiveColorTexCoordIdx > 0 || + mat.pbr.baseColorTexCoordIdx > 0 || + mat.pbr.metalRoughTexCoordIdx > 0) + { + LL_WARNS("GLTF_IMPORT") << "Image texcoord index error" << LL_ENDL; + return false; + } + + mMaterials.push_back(mat); + } + + return true; +} + +// TODO: convert raw vertex buffers to UUIDs +void LLGLTFLoader::uploadMeshes() +{ + llassert(0); +} + +// TODO: convert raw index buffers to UUIDs +void LLGLTFLoader::uploadMaterials() +{ + llassert(0); +} + diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h new file mode 100644 index 0000000000..9bffeef4ab --- /dev/null +++ b/indra/llprimitive/llgltfloader.h @@ -0,0 +1,207 @@ +/** + * @file LLGLTFLoader.h + * @brief LLGLTFLoader class definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_LLGLTFLoader_H +#define LL_LLGLTFLoader_H + +#include "tinygltf\tiny_gltf.h" + +#include "llmodelloader.h" + +typedef struct // gltf sampler +{ // Uses GL enums + S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR + S32 magFilter; // GL_NEAREST or GL_LINEAR + S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT + S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT + //S32 wrapR; // seen in some sample files, but not part of glTF 2.0 spec. Ignored. + std::string name; // optional, currently unused + // extensions and extras are sampler optional fields that we don't support - at least initially +} gltf_sampler; + +typedef struct // gltf image +{ // Note that glTF images are defined with row 0 at the top + U8* data; // ptr to decoded image data + U32 size; // in bytes, regardless of channel width + U32 width; + U32 height; + U32 numChannels; // range 1..4 + U32 bytesPerChannel; // converted from gltf "bits", expects only 8, 16 or 32 as input + U32 pixelType; // one of (TINYGLTF_COMPONENT_TYPE)_UNSIGNED_BYTE, _UNSIGNED_SHORT, _UNSIGNED_INT, or _FLOAT +} gltf_image; + +typedef struct // texture +{ + U32 image_idx; + U32 sampler_idx; +} gltf_texture; + + +// TODO: 2022-05 DJH add UUIDs for each texture +typedef struct // gltf_pbrMR_material +{ + // scalar values + LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. + double metalness; + double roughness; + + // textures + U32 baseColorTexIdx; // always sRGB encoded + U32 baseColorTexCoordIdx; + + U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel + U32 metalRoughTexCoordIdx; +} gltf_pbr; + +typedef struct // render material +{ + std::string name; + + // scalar values + double normalScale; // scale applies only to X,Y components of normal + double occlusionScale; // strength multiplier for occlusion + LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent) + std::string alphaMode; // "OPAQUE", "MASK" or "BLEND" + double alphaMask; + + // textures + U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) + U32 normalTexCoordIdx; + + U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded + U32 occlusionTexCoordIdx; + + U32 emissiveColorTexIdx; // always stored as sRGB, in nits (candela / meter^2) + U32 emissiveColorTexCoordIdx; + + // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? + + bool hasPBR; + gltf_pbr pbr; + +} gltf_render_material; + +typedef struct // gltf_mesh +{ + std::string name; + + // TODO DJH 2022-04 + +} gltf_mesh; + +class LLGLTFLoader : public LLModelLoader +{ + public: + typedef std::map material_map; + typedef void gltfElement; // TBD + typedef void GLTF; // TBD + + // typedef std::map > > gltf_model_map; + // gltf_model_map mModelsMap; + + LLGLTFLoader(std::string filename, + S32 lod, + LLModelLoader::load_callback_t load_cb, + LLModelLoader::joint_lookup_func_t joint_lookup_func, + LLModelLoader::texture_load_func_t texture_load_func, + LLModelLoader::state_callback_t state_cb, + void * opaque_userdata, + JointTransformMap & jointTransformMap, + JointNameSet & jointsFromNodes, + std::map &jointAliasMap, + U32 maxJointsPerMesh, + U32 modelLimit); //, + //bool preprocess ); + virtual ~LLGLTFLoader(); + + virtual bool OpenFile(const std::string &filename); + +protected: + tinygltf::Model mGltfModel; + bool mGltfLoaded; + bool mMeshesLoaded; + bool mMaterialsLoaded; + + std::vector mMeshes; + std::vector mMaterials; + + std::vector mTextures; + std::vector mImages; + std::vector mSamplers; + +private: + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels +// bool mPreprocessGLTF; + + bool parseMeshes(); + void uploadMeshes(); + bool parseMaterials(); + void uploadMaterials(); + bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); + + /* + void processElement(gltfElement *element, bool &badElement, GLTF *gltf); + void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); + + material_map getMaterials(LLModel *model, gltfInstance_geometry *instance_geo, GLTF *gltf); + LLImportMaterial profileToMaterial(gltfProfile_COMMON *material, GLTF *gltf); + LLColor4 getGltfColor(gltfElement *element); + + gltfElement *getChildFromElement(gltfElement *pElement, std::string const &name); + + bool isNodeAJoint(gltfNode *pNode); + void processJointNode(gltfNode *pNode, std::map &jointTransforms); + void extractTranslation(gltfTranslate *pTranslate, LLMatrix4 &transform); + void extractTranslationViaElement(gltfElement *pTranslateElement, LLMatrix4 &transform); + void extractTranslationViaSID(gltfElement *pElement, LLMatrix4 &transform); + void buildJointToNodeMappingFromScene(gltfElement *pRoot); + void processJointToNodeMapping(gltfNode *pNode); + void processChildJoints(gltfNode *pParentNode); + + bool verifyCount(int expected, int result); + + // Verify that a controller matches vertex counts + bool verifyController(gltfController *pController); + + static bool addVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh, LLSD &log_msg); + static bool createVolumeFacesFromGltfMesh(LLModel *model, gltfMesh *mesh); + + static LLModel *loadModelFromGltfMesh(gltfMesh *mesh); + + // Loads a mesh breaking it into one or more models as necessary + // to get around volume face limitations while retaining >8 materials + // + bool loadModelsFromGltfMesh(gltfMesh *mesh, std::vector &models_out, U32 submodel_limit); + + static std::string getElementLabel(gltfElement *element); + static size_t getSuffixPosition(std::string label); + static std::string getLodlessLabel(gltfElement *element); + + static std::string preprocessGLTF(std::string filename); + */ + +}; +#endif // LL_LLGLTFLLOADER_H diff --git a/indra/llprimitive/llmodelloader.cpp b/indra/llprimitive/llmodelloader.cpp index 5171621007..554ed54de1 100644 --- a/indra/llprimitive/llmodelloader.cpp +++ b/indra/llprimitive/llmodelloader.cpp @@ -160,7 +160,8 @@ bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::strin std::string::size_type i = model_filename.rfind("."); if (i != std::string::npos) { - slm_filename.replace(i, model_filename.size()-1, ".slm"); + slm_filename.resize(i, '\0'); + slm_filename.append(".slm"); return true; } else @@ -172,7 +173,7 @@ bool LLModelLoader::getSLMFilename(const std::string& model_filename, std::strin bool LLModelLoader::doLoadModel() { //first, look for a .slm file of the same name that was modified later - //than the .dae + //than the specified model file if (mTrySLM) { @@ -182,13 +183,13 @@ bool LLModelLoader::doLoadModel() llstat slm_status; if (LLFile::stat(slm_filename, &slm_status) == 0) { //slm file exists - llstat dae_status; - if (LLFile::stat(mFilename, &dae_status) != 0 || - dae_status.st_mtime < slm_status.st_mtime) + llstat model_file_status; + if (LLFile::stat(mFilename, &model_file_status) != 0 || + model_file_status.st_mtime < slm_status.st_mtime) { if (loadFromSLM(slm_filename)) { //slm successfully loaded, if this fails, fall through and - //try loading from dae + //try loading from model file mLod = -1; //successfully loading from an slm implicitly sets all //LoDs diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 3669fb1eeb..4e2cc34207 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -55,13 +55,11 @@ LLFilePicker LLFilePicker::sInstance; #define IMAGE_FILTER L"Images (*.tga; *.bmp; *.jpg; *.jpeg; *.png)\0*.tga;*.bmp;*.jpg;*.jpeg;*.png\0" #define ANIM_FILTER L"Animations (*.bvh; *.anim)\0*.bvh;*.anim\0" #define COLLADA_FILTER L"Scene (*.dae)\0*.dae\0" -#ifdef _CORY_TESTING -#define GEOMETRY_FILTER L"SL Geometry (*.slg)\0*.slg\0" -#endif +#define GLTF_FILTER L"glTF (*.gltf; *.glb)\0*.gltf;*.glb\0" #define XML_FILTER L"XML files (*.xml)\0*.xml\0" #define SLOBJECT_FILTER L"Objects (*.slobject)\0*.slobject\0" #define RAW_FILTER L"RAW files (*.raw)\0*.raw\0" -#define MODEL_FILTER L"Model files (*.dae)\0*.dae\0" +#define MODEL_FILTER L"Model files (*.dae; *.gltf; *.glb)\0*.dae;*.gltf;*.glb\0" #define SCRIPT_FILTER L"Script files (*.lsl)\0*.lsl\0" #define DICTIONARY_FILTER L"Dictionary files (*.dic; *.xcu)\0*.dic;*.xcu\0" #endif @@ -193,16 +191,14 @@ BOOL LLFilePicker::setupFilter(ELoadFilter filter) mOFN.lpstrFilter = ANIM_FILTER \ L"\0"; break; - case FFLOAD_COLLADA: + case FFLOAD_GLTF: + mOFN.lpstrFilter = GLTF_FILTER \ + L"\0"; + break; + case FFLOAD_COLLADA: mOFN.lpstrFilter = COLLADA_FILTER \ L"\0"; break; -#ifdef _CORY_TESTING - case FFLOAD_GEOMETRY: - mOFN.lpstrFilter = GEOMETRY_FILTER \ - L"\0"; - break; -#endif case FFLOAD_XML: mOFN.lpstrFilter = XML_FILTER \ L"\0"; @@ -480,18 +476,16 @@ BOOL LLFilePicker::getSaveFile(ESaveFilter filter, const std::string& filename, L"XAF Anim File (*.xaf)\0*.xaf\0" \ L"\0"; break; -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: + case FFSAVE_GLTF: if (filename.empty()) { - wcsncpy( mFilesW,L"untitled.slg", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ + wcsncpy( mFilesW,L"untitled.glb", FILENAME_BUFFER_SIZE); /*Flawfinder: ignore*/ } - mOFN.lpstrDefExt = L"slg"; + mOFN.lpstrDefExt = L"glb"; mOFN.lpstrFilter = - L"SLG SL Geometry File (*.slg)\0*.slg\0" \ + L"glTF Asset File (*.gltf *.glb)\0*.gltf;*.glb\0" \ L"\0"; break; -#endif case FFSAVE_XML: if (filename.empty()) { @@ -621,14 +615,13 @@ std::vector* LLFilePicker::navOpenFilterProc(ELoadFilter filter) // allowedv->push_back("bvh"); allowedv->push_back("anim"); break; + case FFLOAD_GLTF: + allowedv->push_back("gltf"); + allowedv->push_back("glb"); + break; case FFLOAD_COLLADA: allowedv->push_back("dae"); break; -#ifdef _CORY_TESTING - case FFLOAD_GEOMETRY: - allowedv->push_back("slg"); - break; -#endif case FFLOAD_XML: allowedv->push_back("xml"); break; @@ -728,13 +721,11 @@ bool LLFilePicker::doNavSaveDialog(ESaveFilter filter, const std::string& filena extension = "xaf"; break; -#ifdef _CORY_TESTING - case FFSAVE_GEOMETRY: + case FFSAVE_GLTF: type = "\?\?\?\?"; creator = "\?\?\?\?"; - extension = "slg"; + extension = "glb"; break; -#endif case FFSAVE_XML: type = "\?\?\?\?"; @@ -1354,10 +1345,13 @@ BOOL LLFilePicker::getOpenFile( ELoadFilter filter, bool blocking ) case FFLOAD_XML: filtername = add_xml_filter_to_gtkchooser(picker); break; - case FFLOAD_COLLADA: - filtername = add_collada_filter_to_gtkchooser(picker); - break; - case FFLOAD_IMAGE: + case FFLOAD_GLTF: + filtername = dead_code_should_blow_up_here(picker); + break; + case FFLOAD_COLLADA: + filtername = add_collada_filter_to_gtkchooser(picker); + break; + case FFLOAD_IMAGE: filtername = add_imageload_filter_to_gtkchooser(picker); break; case FFLOAD_SCRIPT: diff --git a/indra/newview/llfilepicker.h b/indra/newview/llfilepicker.h index 04ba4416d7..a314207da6 100644 --- a/indra/newview/llfilepicker.h +++ b/indra/newview/llfilepicker.h @@ -77,9 +77,7 @@ public: FFLOAD_WAV = 2, FFLOAD_IMAGE = 3, FFLOAD_ANIM = 4, -#ifdef _CORY_TESTING - FFLOAD_GEOMETRY = 5, -#endif + FFLOAD_GLTF = 5, FFLOAD_XML = 6, FFLOAD_SLOBJECT = 7, FFLOAD_RAW = 8, @@ -99,9 +97,7 @@ public: FFSAVE_BMP = 5, FFSAVE_AVI = 6, FFSAVE_ANIM = 7, -#ifdef _CORY_TESTING - FFSAVE_GEOMETRY = 8, -#endif + FFSAVE_GLTF = 8, FFSAVE_XML = 9, FFSAVE_COLLADA = 10, FFSAVE_RAW = 11, diff --git a/indra/newview/llfloatermodelpreview.cpp b/indra/newview/llfloatermodelpreview.cpp index 7279e1ad6d..b77341f806 100644 --- a/indra/newview/llfloatermodelpreview.cpp +++ b/indra/newview/llfloatermodelpreview.cpp @@ -97,7 +97,7 @@ private: }; LLMeshFilePicker::LLMeshFilePicker(LLModelPreview* mp, S32 lod) -: LLFilePickerThread(LLFilePicker::FFLOAD_COLLADA) +: LLFilePickerThread(LLFilePicker::FFLOAD_MODEL) { mMP = mp; mLOD = lod; diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 859d987fc3..e67bd6468e 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -30,6 +30,7 @@ #include "llmodelloader.h" #include "lldaeloader.h" +#include "llgltfloader.h" #include "llfloatermodelpreview.h" #include "llagent.h" @@ -732,20 +733,41 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable std::map joint_alias_map; getJointAliases(joint_alias_map); - mModelLoader = new LLDAELoader( - filename, - lod, - &LLModelPreview::loadedCallback, - &LLModelPreview::lookupJointByName, - &LLModelPreview::loadTextures, - &LLModelPreview::stateChangedCallback, - this, - mJointTransformMap, - mJointsFromNode, - joint_alias_map, - LLSkinningUtil::getMaxJointCount(), - gSavedSettings.getU32("ImporterModelLimit"), - gSavedSettings.getBOOL("ImporterPreprocessDAE")); + // three possible file extensions, .dae .gltf .glb + // check for .dae and if not then assume one of the .gl?? + if (std::string::npos != filename.rfind(".dae")) + { + mModelLoader = new LLDAELoader( + filename, + lod, + &LLModelPreview::loadedCallback, + &LLModelPreview::lookupJointByName, + &LLModelPreview::loadTextures, + &LLModelPreview::stateChangedCallback, + this, + mJointTransformMap, + mJointsFromNode, + joint_alias_map, + LLSkinningUtil::getMaxJointCount(), + gSavedSettings.getU32("ImporterModelLimit"), + gSavedSettings.getBOOL("ImporterPreprocessDAE")); + } + else + { + mModelLoader = new LLGLTFLoader( + filename, + lod, + &LLModelPreview::loadedCallback, + &LLModelPreview::lookupJointByName, + &LLModelPreview::loadTextures, + &LLModelPreview::stateChangedCallback, + this, + mJointTransformMap, + mJointsFromNode, + joint_alias_map, + LLSkinningUtil::getMaxJointCount(), + gSavedSettings.getU32("ImporterModelLimit")); + } if (force_disable_slm) { diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 8732bde35c..9c8a666185 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -267,16 +267,11 @@ void handle_reset_view(); void handle_duplicate_in_place(void*); - void handle_object_owner_self(void*); void handle_object_owner_permissive(void*); void handle_object_lock(void*); void handle_object_asset_ids(void*); void force_take_copy(void*); -#ifdef _CORY_TESTING -void force_export_copy(void*); -void force_import_geometry(void*); -#endif void handle_force_parcel_owner_to_me(void*); void handle_force_parcel_to_content(void*); diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 28ff69eaf5..32fdfe282d 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -277,9 +277,6 @@ void LLMediaFilePicker::notify(const std::vector& filenames) static std::string SOUND_EXTENSIONS = "wav"; static std::string IMAGE_EXTENSIONS = "tga bmp jpg jpeg png"; static std::string ANIM_EXTENSIONS = "bvh anim"; -#ifdef _CORY_TESTING -static std::string GEOMETRY_EXTENSIONS = "slg"; -#endif static std::string XML_EXTENSIONS = "xml"; static std::string SLOBJECT_EXTENSIONS = "slobject"; #endif @@ -301,10 +298,6 @@ std::string build_extensions_string(LLFilePicker::ELoadFilter filter) return SLOBJECT_EXTENSIONS; case LLFilePicker::FFLOAD_MODEL: return MODEL_EXTENSIONS; -#ifdef _CORY_TESTING - case LLFilePicker::FFLOAD_GEOMETRY: - return GEOMETRY_EXTENSIONS; -#endif case LLFilePicker::FFLOAD_XML: return XML_EXTENSIONS; case LLFilePicker::FFLOAD_ALL: -- cgit v1.3 From adaaccd3d74dd05b596693ef7de90aeef20b5f9d Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 17 May 2022 15:54:00 -0600 Subject: SL-17214 additional glTF validation, remove dead code from DAE loader --- indra/llprimitive/CMakeLists.txt | 2 ++ indra/llprimitive/lldaeloader.cpp | 42 ------------------------------------ indra/llprimitive/lldaeloader.h | 3 --- indra/llprimitive/llgltfloader.cpp | 44 ++++++++++++++++++++++---------------- indra/llprimitive/llgltfloader.h | 6 +++++- 5 files changed, 32 insertions(+), 65 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 9d75dab31e..2395841eae 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -10,12 +10,14 @@ include(LLCoreHttp) include(LLXML) include(LLPhysicsExtensions) include(LLCharacter) +include(LLRender) include_directories( ${LLCOMMON_INCLUDE_DIRS} ${LLMATH_INCLUDE_DIRS} ${LLMESSAGE_INCLUDE_DIRS} ${LLXML_INCLUDE_DIRS} + ${LLRENDER_INCLUDE_DIRS} ${LIBS_PREBUILT_DIR}/include/collada ${LIBS_PREBUILT_DIR}/include/collada/1.4 ${LLCHARACTER_INCLUDE_DIRS} diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 94f8500dab..68b29f01da 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2504,20 +2504,6 @@ bool LLDAELoader::addVolumeFacesFromDomMesh(LLModel* pModel,domMesh* mesh, LLSD& return (status == LLModel::NO_ERRORS); } -////static -//LLModel* LLDAELoader::loadModelFromDomMesh(domMesh *mesh) -//{ -// LLVolumeParams volume_params; -// volume_params.setType(LL_PCODE_PROFILE_SQUARE, LL_PCODE_PATH_LINE); -// LLModel* ret = new LLModel(volume_params, 0.f); -// createVolumeFacesFromDomMesh(ret, mesh); -// if (ret->mLabel.empty()) -// { -// ret->mLabel = getElementLabel(mesh); -// } -// return ret; -//} - //static diff version supports creating multiple models when material counts spill // over the 8 face server-side limit // @@ -2608,31 +2594,3 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo return true; } - -bool LLDAELoader::createVolumeFacesFromDomMesh(LLModel* pModel, domMesh* mesh) -{ - if (mesh) - { - pModel->ClearFacesAndMaterials(); - - LLSD placeholder; - addVolumeFacesFromDomMesh(pModel, mesh, placeholder); - - if (pModel->getNumVolumeFaces() > 0) - { - pModel->normalizeVolumeFaces(); - pModel->optimizeVolumeFaces(); - - if (pModel->getNumVolumeFaces() > 0) - { - return true; - } - } - } - else - { - LL_WARNS() << "no mesh found" << LL_ENDL; - } - - return false; -} diff --git a/indra/llprimitive/lldaeloader.h b/indra/llprimitive/lldaeloader.h index 9e80980ddf..52ad908870 100644 --- a/indra/llprimitive/lldaeloader.h +++ b/indra/llprimitive/lldaeloader.h @@ -90,9 +90,6 @@ protected: bool verifyController( domController* pController ); static bool addVolumeFacesFromDomMesh(LLModel* model, domMesh* mesh, LLSD& log_msg); - static bool createVolumeFacesFromDomMesh(LLModel* model, domMesh *mesh); - - //static LLModel* loadModelFromDomMesh(domMesh* mesh); // Loads a mesh breaking it into one or more models as necessary // to get around volume face limitations while retaining >8 materials diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index 001623ac9e..bc9c4760f7 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -211,9 +211,9 @@ bool LLGLTFLoader::parseMaterials() mSamplers.clear(); for (auto in_sampler : mGltfModel.samplers) { - gltf_sampler sampler{ 0 }; - sampler.magFilter = in_sampler.magFilter; - sampler.minFilter = in_sampler.minFilter; + gltf_sampler sampler; + sampler.magFilter = in_sampler.magFilter > 0 ? in_sampler.magFilter : GL_LINEAR; + sampler.minFilter = in_sampler.minFilter > 0 ? in_sampler.minFilter : GL_LINEAR;; sampler.wrapS = in_sampler.wrapS; sampler.wrapT = in_sampler.wrapT; sampler.name = in_sampler.name; // unused @@ -223,10 +223,10 @@ bool LLGLTFLoader::parseMaterials() mImages.clear(); for (auto in_image : mGltfModel.images) { - gltf_image image{ 0 }; + gltf_image image; image.numChannels = in_image.component; - image.bytesPerChannel = in_image.bits >> 3; - image.pixelType = in_image.pixel_type; + image.bytesPerChannel = in_image.bits >> 3; // Convert bits to bytes + image.pixelType = in_image.pixel_type; // Maps exactly, i.e. TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE == GL_UNSIGNED_BYTE, etc image.size = in_image.image.size(); image.height = in_image.height; image.width = in_image.width; @@ -250,7 +250,7 @@ bool LLGLTFLoader::parseMaterials() mTextures.clear(); for (auto in_tex : mGltfModel.textures) { - gltf_texture tex{ 0 }; + gltf_texture tex; tex.image_idx = in_tex.source; tex.sampler_idx = in_tex.sampler; @@ -266,18 +266,21 @@ bool LLGLTFLoader::parseMaterials() // parse each material for (tinygltf::Material gltf_material : mGltfModel.materials) { - gltf_render_material mat{ 0 }; + gltf_render_material mat; mat.name = gltf_material.name; mat.normalScale = gltf_material.normalTexture.scale; + mat.hasNormalTex = gltf_material.normalTexture.index > 0; mat.normalTexIdx = gltf_material.normalTexture.index; mat.normalTexCoordIdx = gltf_material.normalTexture.texCoord; mat.occlusionScale = gltf_material.occlusionTexture.strength; + mat.hasOcclusionTex = gltf_material.occlusionTexture.index > 0; mat.occlusionTexIdx = gltf_material.occlusionTexture.index; mat.occlusionTexCoordIdx = gltf_material.occlusionTexture.texCoord; mat.emissiveColor.set(gltf_material.emissiveFactor.data()); + mat.hasEmissiveTex = gltf_material.emissiveTexture.index > 0; mat.emissiveColorTexIdx = gltf_material.emissiveTexture.index; mat.emissiveColorTexCoordIdx = gltf_material.emissiveTexture.texCoord; @@ -288,29 +291,31 @@ bool LLGLTFLoader::parseMaterials() mat.hasPBR = true; mat.pbr.baseColor.set(pbr.baseColorFactor.data()); + mat.pbr.hasBaseTex = pbr.baseColorTexture.index > 0; mat.pbr.baseColorTexIdx = pbr.baseColorTexture.index; mat.pbr.baseColorTexCoordIdx = pbr.baseColorTexture.texCoord; mat.pbr.metalness = pbr.metallicFactor; mat.pbr.roughness = pbr.roughnessFactor; + mat.pbr.hasMRTex = pbr.metallicRoughnessTexture.index > 0; mat.pbr.metalRoughTexIdx = pbr.metallicRoughnessTexture.index; mat.pbr.metalRoughTexCoordIdx = pbr.metallicRoughnessTexture.texCoord; - if (mat.normalTexIdx >= mTextures.size() || - mat.occlusionTexIdx >= mTextures.size() || - mat.emissiveColorTexIdx >= mTextures.size() || - mat.pbr.baseColorTexIdx >= mTextures.size() || - mat.pbr.metalRoughTexIdx >= mTextures.size()) + if ((mat.hasNormalTex && (mat.normalTexIdx >= mTextures.size())) || + (mat.hasOcclusionTex && (mat.occlusionTexIdx >= mTextures.size())) || + (mat.hasEmissiveTex && (mat.emissiveColorTexIdx >= mTextures.size())) || + (mat.pbr.hasBaseTex && (mat.pbr.baseColorTexIdx >= mTextures.size())) || + (mat.pbr.hasMRTex && (mat.pbr.metalRoughTexIdx >= mTextures.size()))) { LL_WARNS("GLTF_IMPORT") << "Texture resource index error" << LL_ENDL; return false; } - if (mat.normalTexCoordIdx > 0 || // May have to loosen this condition - mat.occlusionTexCoordIdx > 0 || - mat.emissiveColorTexCoordIdx > 0 || - mat.pbr.baseColorTexCoordIdx > 0 || - mat.pbr.metalRoughTexCoordIdx > 0) + if ((mat.hasNormalTex && (mat.normalTexCoordIdx > 2)) || // mesh can have up to 3 sets of UV + (mat.hasOcclusionTex && (mat.occlusionTexCoordIdx > 2)) || + (mat.hasEmissiveTex && (mat.emissiveColorTexCoordIdx > 2)) || + (mat.pbr.hasBaseTex && (mat.pbr.baseColorTexCoordIdx > 2)) || + (mat.pbr.hasMRTex && (mat.pbr.metalRoughTexCoordIdx > 2))) { LL_WARNS("GLTF_IMPORT") << "Image texcoord index error" << LL_ENDL; return false; @@ -331,6 +336,7 @@ void LLGLTFLoader::uploadMeshes() // TODO: convert raw index buffers to UUIDs void LLGLTFLoader::uploadMaterials() { - llassert(0); + //llassert(0); + } diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 9bffeef4ab..08e9836d07 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -27,8 +27,9 @@ #ifndef LL_LLGLTFLoader_H #define LL_LLGLTFLoader_H -#include "tinygltf\tiny_gltf.h" +#include "tinygltf/tiny_gltf.h" +#include "llglheaders.h" #include "llmodelloader.h" typedef struct // gltf sampler @@ -74,6 +75,8 @@ typedef struct // gltf_pbrMR_material U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel U32 metalRoughTexCoordIdx; + + bool hasBaseTex, hasMRTex; } gltf_pbr; typedef struct // render material @@ -100,6 +103,7 @@ typedef struct // render material // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? bool hasPBR; + bool hasNormalTex, hasOcclusionTex, hasEmissiveTex; gltf_pbr pbr; } gltf_render_material; -- cgit v1.3 From c9ebb970ee916ace16e88508dc1a178336a91d52 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Wed, 1 Jun 2022 14:37:20 -0600 Subject: SL-17214 re-work gltf data organization --- indra/llprimitive/llgltfloader.cpp | 138 +++++++++++++++++++++++++++---------- indra/llprimitive/llgltfloader.h | 70 +++++++++---------- 2 files changed, 132 insertions(+), 76 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index bc9c4760f7..3ec11f70c6 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -45,6 +45,9 @@ // TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE #include "tinygltf\tiny_gltf.h" + +// TODO: includes inherited from dae loader. Validate / prune + #include #include "llsdserialize.h" @@ -120,9 +123,9 @@ bool LLGLTFLoader::OpenFile(const std::string &filename) if (!mGltfLoaded) { if (!warn_msg.empty()) - LL_WARNS() << "gltf load warning: " << warn_msg.c_str() << LL_ENDL; + LL_WARNS("GLTF_IMPORT") << "gltf load warning: " << warn_msg.c_str() << LL_ENDL; if (!error_msg.empty()) - LL_WARNS() << "gltf load error: " << error_msg.c_str() << LL_ENDL; + LL_WARNS("GLTF_IMPORT") << "gltf load error: " << error_msg.c_str() << LL_ENDL; return false; } @@ -251,10 +254,11 @@ bool LLGLTFLoader::parseMaterials() for (auto in_tex : mGltfModel.textures) { gltf_texture tex; - tex.image_idx = in_tex.source; - tex.sampler_idx = in_tex.sampler; + tex.imageIdx = in_tex.source; + tex.samplerIdx = in_tex.sampler; + tex.imageUuid.setNull(); - if (tex.image_idx >= mImages.size() || tex.sampler_idx >= mSamplers.size()) + if (tex.imageIdx >= mImages.size() || tex.samplerIdx >= mSamplers.size()) { LL_WARNS("GLTF_IMPORT") << "Texture sampler/image index error" << LL_ENDL; return false; @@ -269,53 +273,53 @@ bool LLGLTFLoader::parseMaterials() gltf_render_material mat; mat.name = gltf_material.name; + tinygltf::PbrMetallicRoughness& pbr = gltf_material.pbrMetallicRoughness; + mat.hasPBR = true; // Always true, for now + + mat.baseColor.set(pbr.baseColorFactor.data()); + mat.hasBaseTex = pbr.baseColorTexture.index >= 0; + mat.baseColorTexIdx = pbr.baseColorTexture.index; + mat.baseColorTexCoords = pbr.baseColorTexture.texCoord; + + mat.metalness = pbr.metallicFactor; + mat.roughness = pbr.roughnessFactor; + mat.hasMRTex = pbr.metallicRoughnessTexture.index >= 0; + mat.metalRoughTexIdx = pbr.metallicRoughnessTexture.index; + mat.metalRoughTexCoords = pbr.metallicRoughnessTexture.texCoord; + mat.normalScale = gltf_material.normalTexture.scale; - mat.hasNormalTex = gltf_material.normalTexture.index > 0; + mat.hasNormalTex = gltf_material.normalTexture.index >= 0; mat.normalTexIdx = gltf_material.normalTexture.index; - mat.normalTexCoordIdx = gltf_material.normalTexture.texCoord; + mat.normalTexCoords = gltf_material.normalTexture.texCoord; mat.occlusionScale = gltf_material.occlusionTexture.strength; - mat.hasOcclusionTex = gltf_material.occlusionTexture.index > 0; + mat.hasOcclusionTex = gltf_material.occlusionTexture.index >= 0; mat.occlusionTexIdx = gltf_material.occlusionTexture.index; - mat.occlusionTexCoordIdx = gltf_material.occlusionTexture.texCoord; + mat.occlusionTexCoords = gltf_material.occlusionTexture.texCoord; mat.emissiveColor.set(gltf_material.emissiveFactor.data()); - mat.hasEmissiveTex = gltf_material.emissiveTexture.index > 0; - mat.emissiveColorTexIdx = gltf_material.emissiveTexture.index; - mat.emissiveColorTexCoordIdx = gltf_material.emissiveTexture.texCoord; + mat.hasEmissiveTex = gltf_material.emissiveTexture.index >= 0; + mat.emissiveTexIdx = gltf_material.emissiveTexture.index; + mat.emissiveTexCoords = gltf_material.emissiveTexture.texCoord; mat.alphaMode = gltf_material.alphaMode; mat.alphaMask = gltf_material.alphaCutoff; - tinygltf::PbrMetallicRoughness& pbr = gltf_material.pbrMetallicRoughness; - mat.hasPBR = true; - - mat.pbr.baseColor.set(pbr.baseColorFactor.data()); - mat.pbr.hasBaseTex = pbr.baseColorTexture.index > 0; - mat.pbr.baseColorTexIdx = pbr.baseColorTexture.index; - mat.pbr.baseColorTexCoordIdx = pbr.baseColorTexture.texCoord; - - mat.pbr.metalness = pbr.metallicFactor; - mat.pbr.roughness = pbr.roughnessFactor; - mat.pbr.hasMRTex = pbr.metallicRoughnessTexture.index > 0; - mat.pbr.metalRoughTexIdx = pbr.metallicRoughnessTexture.index; - mat.pbr.metalRoughTexCoordIdx = pbr.metallicRoughnessTexture.texCoord; - - if ((mat.hasNormalTex && (mat.normalTexIdx >= mTextures.size())) || - (mat.hasOcclusionTex && (mat.occlusionTexIdx >= mTextures.size())) || - (mat.hasEmissiveTex && (mat.emissiveColorTexIdx >= mTextures.size())) || - (mat.pbr.hasBaseTex && (mat.pbr.baseColorTexIdx >= mTextures.size())) || - (mat.pbr.hasMRTex && (mat.pbr.metalRoughTexIdx >= mTextures.size()))) + if ((mat.hasNormalTex && (mat.normalTexIdx >= mTextures.size())) || + (mat.hasOcclusionTex && (mat.occlusionTexIdx >= mTextures.size())) || + (mat.hasEmissiveTex && (mat.emissiveTexIdx >= mTextures.size())) || + (mat.hasBaseTex && (mat.baseColorTexIdx >= mTextures.size())) || + (mat.hasMRTex && (mat.metalRoughTexIdx >= mTextures.size()))) { LL_WARNS("GLTF_IMPORT") << "Texture resource index error" << LL_ENDL; return false; } - if ((mat.hasNormalTex && (mat.normalTexCoordIdx > 2)) || // mesh can have up to 3 sets of UV - (mat.hasOcclusionTex && (mat.occlusionTexCoordIdx > 2)) || - (mat.hasEmissiveTex && (mat.emissiveColorTexCoordIdx > 2)) || - (mat.pbr.hasBaseTex && (mat.pbr.baseColorTexCoordIdx > 2)) || - (mat.pbr.hasMRTex && (mat.pbr.metalRoughTexCoordIdx > 2))) + if ((mat.hasNormalTex && (mat.normalTexCoords > 2)) || // mesh can have up to 3 sets of UV + (mat.hasOcclusionTex && (mat.occlusionTexCoords > 2)) || + (mat.hasEmissiveTex && (mat.emissiveTexCoords > 2)) || + (mat.hasBaseTex && (mat.baseColorTexCoords > 2)) || + (mat.hasMRTex && (mat.metalRoughTexCoords > 2))) { LL_WARNS("GLTF_IMPORT") << "Image texcoord index error" << LL_ENDL; return false; @@ -333,10 +337,68 @@ void LLGLTFLoader::uploadMeshes() llassert(0); } -// TODO: convert raw index buffers to UUIDs +// convert raw image buffers to texture UUIDs & assemble into a render material void LLGLTFLoader::uploadMaterials() { - //llassert(0); + for (gltf_render_material mat : mMaterials) // Initially 1 material per gltf file, but design for multiple + { + if (mat.hasBaseTex) + { + gltf_texture& gtex = mTextures[mat.baseColorTexIdx]; + if (gtex.imageUuid.isNull()) + { + gtex.imageUuid = imageBufferToTextureUUID(gtex); + } + } + + if (mat.hasMRTex) + { + gltf_texture& gtex = mTextures[mat.metalRoughTexIdx]; + if (gtex.imageUuid.isNull()) + { + gtex.imageUuid = imageBufferToTextureUUID(gtex); + } + } + + if (mat.hasNormalTex) + { + gltf_texture& gtex = mTextures[mat.normalTexIdx]; + if (gtex.imageUuid.isNull()) + { + gtex.imageUuid = imageBufferToTextureUUID(gtex); + } + } + if (mat.hasOcclusionTex) + { + gltf_texture& gtex = mTextures[mat.occlusionTexIdx]; + if (gtex.imageUuid.isNull()) + { + gtex.imageUuid = imageBufferToTextureUUID(gtex); + } + } + + if (mat.hasEmissiveTex) + { + gltf_texture& gtex = mTextures[mat.emissiveTexIdx]; + if (gtex.imageUuid.isNull()) + { + gtex.imageUuid = imageBufferToTextureUUID(gtex); + } + } + } } +LLUUID LLGLTFLoader::imageBufferToTextureUUID(const gltf_texture& tex) +{ + //gltf_image& image = mImages[tex.imageIdx]; + //gltf_sampler& sampler = mSamplers[tex.samplerIdx]; + + // fill an LLSD container with image+sampler data + + // upload texture + + // retrieve UUID + + return LLUUID::null; +} diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 08e9836d07..24496f6324 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -32,19 +32,21 @@ #include "llglheaders.h" #include "llmodelloader.h" +// gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD + typedef struct // gltf sampler { // Uses GL enums S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR S32 magFilter; // GL_NEAREST or GL_LINEAR S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT S32 wrapT; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT - //S32 wrapR; // seen in some sample files, but not part of glTF 2.0 spec. Ignored. + //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored. std::string name; // optional, currently unused // extensions and extras are sampler optional fields that we don't support - at least initially } gltf_sampler; typedef struct // gltf image -{ // Note that glTF images are defined with row 0 at the top +{ // Note that glTF images are defined with row 0 at the top (opposite of OpenGL) U8* data; // ptr to decoded image data U32 size; // in bytes, regardless of channel width U32 width; @@ -56,34 +58,19 @@ typedef struct // gltf image typedef struct // texture { - U32 image_idx; - U32 sampler_idx; + U32 imageIdx; + U32 samplerIdx; + LLUUID imageUuid = LLUUID::null; } gltf_texture; - -// TODO: 2022-05 DJH add UUIDs for each texture -typedef struct // gltf_pbrMR_material -{ - // scalar values - LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. - double metalness; - double roughness; - - // textures - U32 baseColorTexIdx; // always sRGB encoded - U32 baseColorTexCoordIdx; - - U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel - U32 metalRoughTexCoordIdx; - - bool hasBaseTex, hasMRTex; -} gltf_pbr; - typedef struct // render material { std::string name; // scalar values + LLColor4 baseColor; // linear encoding. Multiplied with vertex color, if present. + double metalness; + double roughness; double normalScale; // scale applies only to X,Y components of normal double occlusionScale; // strength multiplier for occlusion LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent) @@ -91,20 +78,26 @@ typedef struct // render material double alphaMask; // textures - U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) - U32 normalTexCoordIdx; - - U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded - U32 occlusionTexCoordIdx; - - U32 emissiveColorTexIdx; // always stored as sRGB, in nits (candela / meter^2) - U32 emissiveColorTexCoordIdx; + U32 baseColorTexIdx; // always sRGB encoded + U32 metalRoughTexIdx; // always linear, roughness in G channel, metalness in B channel + U32 normalTexIdx; // linear, valid range R[0-1], G[0-1], B[0.5-1]. Normal = texel * 2 - vec3(1.0) + U32 occlusionTexIdx; // linear, occlusion in R channel, 0 meaning fully occluded, 1 meaning not occluded + U32 emissiveTexIdx; // always stored as sRGB, in nits (candela / meter^2) + + // texture coordinates + U32 baseColorTexCoords; + U32 metalRoughTexCoords; + U32 normalTexCoords; + U32 occlusionTexCoords; + U32 emissiveTexCoords; // TODO: Add traditional (diffuse, normal, specular) UUIDs here, or add this struct to LL_TextureEntry?? bool hasPBR; - bool hasNormalTex, hasOcclusionTex, hasEmissiveTex; - gltf_pbr pbr; + bool hasBaseTex, hasMRTex, hasNormalTex, hasOcclusionTex, hasEmissiveTex; + + // This field is populated after upload + LLUUID material_uuid = LLUUID::null; } gltf_render_material; @@ -112,7 +105,7 @@ typedef struct // gltf_mesh { std::string name; - // TODO DJH 2022-04 + // TODO add mesh import DJH 2022-04 } gltf_mesh; @@ -157,16 +150,17 @@ protected: std::vector mSamplers; private: - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels -// bool mPreprocessGLTF; - bool parseMeshes(); void uploadMeshes(); bool parseMaterials(); void uploadMaterials(); bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); + LLUUID imageBufferToTextureUUID(const gltf_texture& tex); + + U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels + // bool mPreprocessGLTF; - /* + /* Inherited from dae loader - unknown how useful here void processElement(gltfElement *element, bool &badElement, GLTF *gltf); void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); -- cgit v1.3 From 2dc376aa5324448de7d15717d5e24b812d885eea Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Fri, 3 Jun 2022 10:15:56 -0600 Subject: SL-17214 add 3p-tinygltf dependency to autobuild.xml --- autobuild.xml | 60 ++++++++++++++++++++++++++++++++++++++++ indra/cmake/TinyGLTF.cmake | 7 +++++ indra/llprimitive/CMakeLists.txt | 2 ++ 3 files changed, 69 insertions(+) create mode 100644 indra/cmake/TinyGLTF.cmake (limited to 'indra/llprimitive') diff --git a/autobuild.xml b/autobuild.xml index 4c69ff71d4..f80ed200a0 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -3095,6 +3095,66 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 0.132.2 + tinygltf + + canonical_repo + https://bitbucket.org/lindenlab/3p-tinygltf + copyright + // Copyright (c) 2015 - Present Syoyo Fujita, Aurélien Chatelain and many contributors. + description + tinygltf import library + license + MIT + license_file + LICENSES/tinygltf_license.txt + name + tinygltf + platforms + + darwin64 + + archive + + hash + 13ebc64d8ba6276105a3fd516c7224f0 + url + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/100740/887434/tinygltf-v2.5.0-windows64-572388.tar.bz2 + + name + darwin64 + + windows + + archive + + hash + 13ebc64d8ba6276105a3fd516c7224f0 + url + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/100740/887434/tinygltf-v2.5.0-windows64-572388.tar.bz2 + + name + windows + + windows64 + + archive + + hash + 13ebc64d8ba6276105a3fd516c7224f0 + url + https://s3-proxy.lindenlab.com/private-builds-secondlife-com/ct2/100740/887434/tinygltf-v2.5.0-windows64-572388.tar.bz2 + + name + windows64 + + + source + https://bitbucket.org/lindenlab/3p-tinygltf + source_type + git + version + v2.5.0 + tracy canonical_repo diff --git a/indra/cmake/TinyGLTF.cmake b/indra/cmake/TinyGLTF.cmake new file mode 100644 index 0000000000..bb731637a0 --- /dev/null +++ b/indra/cmake/TinyGLTF.cmake @@ -0,0 +1,7 @@ +# -*- cmake -*- +include(Prebuilt) + +use_prebuilt_binary(tinygltf) + +set(TINYGLTF_INCLUDE_DIR ${LIBS_PREBUILT_DIR}/include/tinygltf) + diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 2395841eae..e131b12371 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -11,6 +11,7 @@ include(LLXML) include(LLPhysicsExtensions) include(LLCharacter) include(LLRender) +include(TinyGLTF) include_directories( ${LLCOMMON_INCLUDE_DIRS} @@ -21,6 +22,7 @@ include_directories( ${LIBS_PREBUILT_DIR}/include/collada ${LIBS_PREBUILT_DIR}/include/collada/1.4 ${LLCHARACTER_INCLUDE_DIRS} + ${TINYGLTF_INCLUDE_DIR} ) include_directories(SYSTEM ${LLCOMMON_SYSTEM_INCLUDE_DIRS} -- cgit v1.3 From d3219f57c12ec29025e5c9c68b2cf90d49258672 Mon Sep 17 00:00:00 2001 From: Dave Houlton Date: Tue, 7 Jun 2022 14:42:18 -0600 Subject: SL-17214 remove some dae clutter from gltf header --- indra/llprimitive/llgltfloader.h | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 24496f6324..9ee816e24e 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -75,7 +75,7 @@ typedef struct // render material double occlusionScale; // strength multiplier for occlusion LLColor4 emissiveColor; // emissive mulitiplier, assumed linear encoding (spec 2.0 is silent) std::string alphaMode; // "OPAQUE", "MASK" or "BLEND" - double alphaMask; + double alphaMask; // alpha cut-off // textures U32 baseColorTexIdx; // always sRGB encoded @@ -113,11 +113,6 @@ class LLGLTFLoader : public LLModelLoader { public: typedef std::map material_map; - typedef void gltfElement; // TBD - typedef void GLTF; // TBD - - // typedef std::map > > gltf_model_map; - // gltf_model_map mModelsMap; LLGLTFLoader(std::string filename, S32 lod, @@ -160,7 +155,8 @@ private: U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels // bool mPreprocessGLTF; - /* Inherited from dae loader - unknown how useful here + /* Below inherited from dae loader - unknown if/how useful here + void processElement(gltfElement *element, bool &badElement, GLTF *gltf); void processGltfModel(LLModel *model, GLTF *gltf, gltfElement *pRoot, gltfMesh *mesh, gltfSkin *skin); -- cgit v1.3 From 125b099298652347991c521703109e12bccdd47e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 9 Jun 2022 11:02:21 -0500 Subject: VS2019 build fix --- indra/llprimitive/llgltfloader.h | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 9ee816e24e..91389b5845 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -34,8 +34,10 @@ // gltf_* structs are temporary, used to organize the subset of data that eventually goes into the material LLSD -typedef struct // gltf sampler -{ // Uses GL enums +class gltf_sampler +{ +public: + // Uses GL enums S32 minFilter; // GL_NEAREST, GL_LINEAR, GL_NEAREST_MIPMAP_NEAREST, GL_LINEAR_MIPMAP_NEAREST, GL_NEAREST_MIPMAP_LINEAR or GL_LINEAR_MIPMAP_LINEAR S32 magFilter; // GL_NEAREST or GL_LINEAR S32 wrapS; // GL_CLAMP_TO_EDGE, GL_MIRRORED_REPEAT or GL_REPEAT @@ -43,10 +45,11 @@ typedef struct // gltf sampler //S32 wrapR; // Found in some sample files, but not part of glTF 2.0 spec. Ignored. std::string name; // optional, currently unused // extensions and extras are sampler optional fields that we don't support - at least initially -} gltf_sampler; +}; -typedef struct // gltf image -{ // Note that glTF images are defined with row 0 at the top (opposite of OpenGL) +class gltf_image +{ +public:// Note that glTF images are defined with row 0 at the top (opposite of OpenGL) U8* data; // ptr to decoded image data U32 size; // in bytes, regardless of channel width U32 width; @@ -54,17 +57,19 @@ typedef struct // gltf image U32 numChannels; // range 1..4 U32 bytesPerChannel; // converted from gltf "bits", expects only 8, 16 or 32 as input U32 pixelType; // one of (TINYGLTF_COMPONENT_TYPE)_UNSIGNED_BYTE, _UNSIGNED_SHORT, _UNSIGNED_INT, or _FLOAT -} gltf_image; +}; -typedef struct // texture +class gltf_texture { +public: U32 imageIdx; U32 samplerIdx; LLUUID imageUuid = LLUUID::null; -} gltf_texture; +}; -typedef struct // render material +class gltf_render_material { +public: std::string name; // scalar values @@ -99,15 +104,16 @@ typedef struct // render material // This field is populated after upload LLUUID material_uuid = LLUUID::null; -} gltf_render_material; +}; -typedef struct // gltf_mesh +class gltf_mesh { +public: std::string name; // TODO add mesh import DJH 2022-04 -} gltf_mesh; +}; class LLGLTFLoader : public LLModelLoader { -- cgit v1.3 From 03d85bfb33f53e658256d8bedcf0b4262226cf90 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 9 Jun 2022 19:43:21 -0500 Subject: SL-17573 Add "dynamic" checkbox, also followup on SL-17551 and do "Select Invisible Objects" checkbox instead of "Select Reflection Probes" --- indra/llprimitive/llprimitive.cpp | 103 +++++++++++++-------- indra/llprimitive/llprimitive.h | 15 +-- indra/newview/app_settings/settings.xml | 4 +- indra/newview/llpanelvolume.cpp | 37 ++++---- indra/newview/llreflectionmap.cpp | 14 ++- indra/newview/llreflectionmap.h | 3 + indra/newview/llselectmgr.cpp | 6 +- indra/newview/lltoolselect.cpp | 10 +- indra/newview/llviewermenu.cpp | 8 +- indra/newview/llviewerwindow.cpp | 46 +++++++-- indra/newview/llviewerwindow.h | 2 +- indra/newview/llvovolume.cpp | 36 +++++-- indra/newview/llvovolume.h | 6 +- indra/newview/pipeline.cpp | 9 -- .../newview/skins/default/xui/en/floater_tools.xml | 17 +++- indra/newview/skins/default/xui/en/menu_viewer.xml | 10 +- 16 files changed, 205 insertions(+), 121 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 6044048d09..9e0a079fd9 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1819,92 +1819,117 @@ bool LLLightParams::fromLLSD(LLSD& sd) //============================================================================ +//============================================================================ + LLReflectionProbeParams::LLReflectionProbeParams() { mType = PARAMS_REFLECTION_PROBE; } -BOOL LLReflectionProbeParams::pack(LLDataPacker& dp) const +BOOL LLReflectionProbeParams::pack(LLDataPacker &dp) const { - dp.packF32(mAmbiance, "ambiance"); + dp.packF32(mAmbiance, "ambiance"); dp.packF32(mClipDistance, "clip_distance"); - dp.packU8(mVolumeType, "volume_type"); - return TRUE; + dp.packU8(mFlags, "flags"); + return TRUE; } -BOOL LLReflectionProbeParams::unpack(LLDataPacker& dp) +BOOL LLReflectionProbeParams::unpack(LLDataPacker &dp) { - F32 ambiance; + F32 ambiance; F32 clip_distance; - U8 volume_type; - - dp.unpackF32(ambiance, "ambiance"); - setAmbiance(ambiance); + dp.unpackF32(ambiance, "ambiance"); + setAmbiance(ambiance); + dp.unpackF32(clip_distance, "clip_distance"); - setClipDistance(clip_distance); - - dp.unpackU8(volume_type, "volume_type"); - setVolumeType((EInfluenceVolumeType)volume_type); - - return TRUE; + setClipDistance(clip_distance); + + dp.unpackU8(mFlags, "flags"); + + return TRUE; } bool LLReflectionProbeParams::operator==(const LLNetworkData& data) const { - if (data.mType != PARAMS_REFLECTION_PROBE) - { - return false; - } - const LLReflectionProbeParams* param = (const LLReflectionProbeParams*)&data; - if (param->mAmbiance != mAmbiance) - { - return false; - } + if (data.mType != PARAMS_REFLECTION_PROBE) + { + return false; + } + const LLReflectionProbeParams *param = (const LLReflectionProbeParams*)&data; + if (param->mAmbiance != mAmbiance) + { + return false; + } if (param->mClipDistance != mClipDistance) { return false; } - if (param->mVolumeType != mVolumeType) + if (param->mFlags != mFlags) { return false; } - return true; + return true; } void LLReflectionProbeParams::copy(const LLNetworkData& data) { - const LLReflectionProbeParams* param = (LLReflectionProbeParams*)&data; - mType = param->mType; - mAmbiance = param->mAmbiance; + const LLReflectionProbeParams *param = (LLReflectionProbeParams*)&data; + mType = param->mType; + mAmbiance = param->mAmbiance; mClipDistance = param->mClipDistance; - mVolumeType = param->mVolumeType; + mFlags = param->mFlags; } LLSD LLReflectionProbeParams::asLLSD() const { - LLSD sd; - sd["ambiance"] = getAmbiance(); + LLSD sd; + sd["ambiance"] = getAmbiance(); sd["clip_distance"] = getClipDistance(); - sd["volume_type"] = (U8) getVolumeType(); - return sd; + sd["flags"] = mFlags; + return sd; } bool LLReflectionProbeParams::fromLLSD(LLSD& sd) { if (!sd.has("ambiance") || !sd.has("clip_distance") || - !sd.has("volume_type")) + !sd.has("flags")) { return false; } - setAmbiance((F32)sd["ambiance"].asReal()); + setAmbiance((F32)sd["ambiance"].asReal()); setClipDistance((F32)sd["clip_distance"].asReal()); - setVolumeType((EInfluenceVolumeType)sd["volume_type"].asInteger()); - + mFlags = (U8) sd["flags"].asInteger(); + return true; } + +void LLReflectionProbeParams::setIsBox(bool is_box) +{ + if (is_box) + { + mFlags |= FLAG_BOX_VOLUME; + } + else + { + mFlags &= ~FLAG_BOX_VOLUME; + } +} + +void LLReflectionProbeParams::setIsDynamic(bool is_dynamic) +{ + if (is_dynamic) + { + mFlags |= FLAG_DYNAMIC; + } + else + { + mFlags &= ~FLAG_DYNAMIC; + } +} + //============================================================================ LLFlexibleObjectData::LLFlexibleObjectData() { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 2215133e16..25196fb894 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -182,17 +182,16 @@ extern const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE; class LLReflectionProbeParams : public LLNetworkData { public: - enum EInfluenceVolumeType : U8 + enum EFlags : U8 { - VOLUME_TYPE_SPHERE = 0, // use a sphere influence volume - VOLUME_TYPE_BOX = 1, // use a box influence volume - DEFAULT_VOLUME_TYPE = VOLUME_TYPE_SPHERE + FLAG_BOX_VOLUME = 0x01, // use a box influence volume + FLAG_DYNAMIC = 0x02, // render dynamic objects (avatars) into this Reflection Probe }; protected: F32 mAmbiance = REFLECTION_PROBE_DEFAULT_AMBIANCE; F32 mClipDistance = REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE; - EInfluenceVolumeType mVolumeType = DEFAULT_VOLUME_TYPE; + U8 mFlags = 0; public: LLReflectionProbeParams(); @@ -208,11 +207,13 @@ public: void setAmbiance(F32 ambiance) { mAmbiance = llclamp(ambiance, REFLECTION_PROBE_MIN_AMBIANCE, REFLECTION_PROBE_MAX_AMBIANCE); } void setClipDistance(F32 distance) { mClipDistance = llclamp(distance, REFLECTION_PROBE_MIN_CLIP_DISTANCE, REFLECTION_PROBE_MAX_CLIP_DISTANCE); } - void setVolumeType(EInfluenceVolumeType type) { mVolumeType = llclamp(type, VOLUME_TYPE_SPHERE, VOLUME_TYPE_BOX); } + void setIsBox(bool is_box); + void setIsDynamic(bool is_dynamic); F32 getAmbiance() const { return mAmbiance; } F32 getClipDistance() const { return mClipDistance; } - EInfluenceVolumeType getVolumeType() const { return mVolumeType; } + bool getIsBox() const { return (mFlags & FLAG_BOX_VOLUME) != 0; } + bool getIsDynamic() const { return (mFlags & FLAG_DYNAMIC) != 0; } }; //------------------------------------------------- diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 6df71e1019..327dfe6955 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -11191,10 +11191,10 @@ Value 0 - SelectReflectionProbes + SelectInvisibleObjects Comment - Select reflection probes + Select invisible objects Persist 1 Type diff --git a/indra/newview/llpanelvolume.cpp b/indra/newview/llpanelvolume.cpp index fb2cf484f5..ddce22fa20 100644 --- a/indra/newview/llpanelvolume.cpp +++ b/indra/newview/llpanelvolume.cpp @@ -147,8 +147,9 @@ BOOL LLPanelVolume::postBuild() // REFLECTION PROBE Parameters { - childSetCommitCallback("Reflection Probe Checkbox Ctrl", onCommitIsReflectionProbe, this); - childSetCommitCallback("Probe Volume Type Ctrl", onCommitProbe, this); + childSetCommitCallback("Reflection Probe", onCommitIsReflectionProbe, this); + childSetCommitCallback("Probe Dynamic", onCommitProbe, this); + childSetCommitCallback("Probe Volume Type", onCommitProbe, this); childSetCommitCallback("Probe Ambiance", onCommitProbe, this); childSetCommitCallback("Probe Near Clip", onCommitProbe, this); @@ -372,25 +373,27 @@ void LLPanelVolume::getState( ) // Reflection Probe BOOL is_probe = volobjp && volobjp->isReflectionProbe(); - getChild("Reflection Probe Checkbox Ctrl")->setValue(is_probe); - getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(editable && single_volume && volobjp); + getChild("Reflection Probe")->setValue(is_probe); + getChildView("Reflection Probe")->setEnabled(editable && single_volume && volobjp); bool probe_enabled = is_probe && editable && single_volume; - getChildView("Probe Volume Type Ctrl")->setEnabled(probe_enabled); + getChildView("Probe Dynamic")->setEnabled(probe_enabled); + getChildView("Probe Volume Type")->setEnabled(probe_enabled); getChildView("Probe Ambiance")->setEnabled(probe_enabled); getChildView("Probe Near Clip")->setEnabled(probe_enabled); if (!probe_enabled) { - getChild("Probe Volume Type Ctrl", true)->clear(); + getChild("Probe Volume Type", true)->clear(); getChild("Probe Ambiance", true)->clear(); getChild("Probe Near Clip", true)->clear(); + getChild("Probe Dynamic", true)->clear(); } else { std::string volume_type; - if (volobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX) + if (volobjp->getReflectionProbeIsBox()) { volume_type = "Box"; } @@ -399,9 +402,10 @@ void LLPanelVolume::getState( ) volume_type = "Sphere"; } - getChild("Probe Volume Type Ctrl", true)->setValue(volume_type); + getChild("Probe Volume Type", true)->setValue(volume_type); getChild("Probe Ambiance", true)->setValue(volobjp->getReflectionProbeAmbiance()); getChild("Probe Near Clip", true)->setValue(volobjp->getReflectionProbeNearClip()); + getChild("Probe Dynamic", true)->setValue(volobjp->getReflectionProbeIsDynamic()); } // Animated Mesh @@ -692,7 +696,8 @@ void LLPanelVolume::clearCtrls() getChildView("Light Falloff")->setEnabled(false); getChildView("Reflection Probe Checkbox Ctrl")->setEnabled(false);; - getChildView("Probe Volume Type Ctrl")->setEnabled(false); + getChildView("Probe Volume Type")->setEnabled(false); + getChildView("Probe Dynamic")->setEnabled(false); getChildView("Probe Ambiance")->setEnabled(false); getChildView("Probe Near Clip")->setEnabled(false); getChildView("Animated Mesh Checkbox Ctrl")->setEnabled(false); @@ -1003,19 +1008,11 @@ void LLPanelVolume::onCommitProbe(LLUICtrl* ctrl, void* userdata) volobjp->setReflectionProbeAmbiance((F32)self->getChild("Probe Ambiance")->getValue().asReal()); volobjp->setReflectionProbeNearClip((F32)self->getChild("Probe Near Clip")->getValue().asReal()); + volobjp->setReflectionProbeIsDynamic(self->getChild("Probe Dynamic")->getValue().asBoolean()); - std::string shape_type = self->getChild("Probe Volume Type Ctrl")->getValue().asString(); - LLReflectionProbeParams::EInfluenceVolumeType volume_type = LLReflectionProbeParams::DEFAULT_VOLUME_TYPE; + std::string shape_type = self->getChild("Probe Volume Type")->getValue().asString(); - if (shape_type == "Sphere") - { - volume_type = LLReflectionProbeParams::VOLUME_TYPE_SPHERE; - } - else if (shape_type == "Box") - { - volume_type = LLReflectionProbeParams::VOLUME_TYPE_BOX; - } - volobjp->setReflectionProbeVolumeType(volume_type); + volobjp->setReflectionProbeIsBox(shape_type == "Box"); } // static diff --git a/indra/newview/llreflectionmap.cpp b/indra/newview/llreflectionmap.cpp index 5991d7a170..39e0841fc5 100644 --- a/indra/newview/llreflectionmap.cpp +++ b/indra/newview/llreflectionmap.cpp @@ -51,7 +51,7 @@ void LLReflectionMap::update(U32 resolution, U32 face) { resolution /= 2; } - gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip()); + gViewerWindow->cubeSnapshot(LLVector3(mOrigin), mCubeArray, mCubeIndex, face, getNearClip(), getIsDynamic()); } bool LLReflectionMap::shouldUpdate() @@ -243,6 +243,16 @@ F32 LLReflectionMap::getNearClip() return llmax(ret, MINIMUM_NEAR_CLIP); } +bool LLReflectionMap::getIsDynamic() +{ + if (mViewerObject && mViewerObject->getVolume()) + { + return ((LLVOVolume*)mViewerObject)->getReflectionProbeIsDynamic(); + } + + return false; +} + bool LLReflectionMap::getBox(LLMatrix4& box) { if (mViewerObject) @@ -252,7 +262,7 @@ bool LLReflectionMap::getBox(LLMatrix4& box) { LLVOVolume* vobjp = (LLVOVolume*)mViewerObject; - if (vobjp->getReflectionProbeVolumeType() == LLReflectionProbeParams::VOLUME_TYPE_BOX) + if (vobjp->getReflectionProbeIsBox()) { glh::matrix4f mv(gGLModelView); glh::matrix4f scale; diff --git a/indra/newview/llreflectionmap.h b/indra/newview/llreflectionmap.h index a358bf5fdf..071568e53c 100644 --- a/indra/newview/llreflectionmap.h +++ b/indra/newview/llreflectionmap.h @@ -61,6 +61,9 @@ public: // Get the near clip plane distance to use for this probe F32 getNearClip(); + // Return true if this probe should include avatars in its reflection map + bool getIsDynamic(); + // get the encoded bounding box of this probe's influence volume // will only return a box if this probe is associated with a VOVolume // with its reflection probe influence volume to to VOLUME_TYPE_BOX diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 7b4ba51859..853703b4d5 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1067,8 +1067,7 @@ void LLSelectMgr::highlightObjectOnly(LLViewerObject* objectp) } if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !objectp->permYouOwner()) - || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced())) - || (!gSavedSettings.getBOOL("SelectReflectionProbes") && !objectp->isReflectionProbe())) + || (gSavedSettings.getBOOL("SelectMovableOnly") && (!objectp->permMove() || objectp->isPermanentEnforced()))) { // only select my own objects return; @@ -7128,8 +7127,7 @@ BOOL LLSelectMgr::canSelectObject(LLViewerObject* object, BOOL ignore_select_own if(!ignore_select_owned) { if ((gSavedSettings.getBOOL("SelectOwnedOnly") && !object->permYouOwner()) || - (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced())) || - (!gSavedSettings.getBOOL("SelectReflectionProbes") && object->isReflectionProbe())) + (gSavedSettings.getBOOL("SelectMovableOnly") && (!object->permMove() || object->isPermanentEnforced()))) { // only select my own objects return FALSE; diff --git a/indra/newview/lltoolselect.cpp b/indra/newview/lltoolselect.cpp index 790d9a8ec5..c6f3905ddc 100644 --- a/indra/newview/lltoolselect.cpp +++ b/indra/newview/lltoolselect.cpp @@ -65,7 +65,8 @@ BOOL LLToolSelect::handleMouseDown(S32 x, S32 y, MASK mask) { // do immediate pick query BOOL pick_rigged = false; //gSavedSettings.getBOOL("AnimatedObjectsAllowLeftClick"); - mPick = gViewerWindow->pickImmediate(x, y, TRUE, pick_rigged); + BOOL pick_transparent = gSavedSettings.getBOOL("SelectInvisibleObjects"); + mPick = gViewerWindow->pickImmediate(x, y, pick_transparent, pick_rigged); // Pass mousedown to agent LLTool::handleMouseDown(x, y, mask); @@ -84,15 +85,13 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi } BOOL select_owned = gSavedSettings.getBOOL("SelectOwnedOnly"); BOOL select_movable = gSavedSettings.getBOOL("SelectMovableOnly"); - BOOL select_probe = gSavedSettings.getBOOL("SelectReflectionProbes"); - // *NOTE: These settings must be cleaned up at bottom of function. + // *NOTE: These settings must be cleaned up at bottom of function. if (temp_select || LLSelectMgr::getInstance()->mAllowSelectAvatar) { gSavedSettings.setBOOL("SelectOwnedOnly", FALSE); gSavedSettings.setBOOL("SelectMovableOnly", FALSE); - gSavedSettings.setBOOL("SelectReflectionProbes", FALSE); - LLSelectMgr::getInstance()->setForceSelection(TRUE); + LLSelectMgr::getInstance()->setForceSelection(TRUE); } BOOL extend_select = (pick.mKeyMask == MASK_SHIFT) || (pick.mKeyMask == MASK_CONTROL); @@ -243,7 +242,6 @@ LLObjectSelectionHandle LLToolSelect::handleObjectSelection(const LLPickInfo& pi { gSavedSettings.setBOOL("SelectOwnedOnly", select_owned); gSavedSettings.setBOOL("SelectMovableOnly", select_movable); - gSavedSettings.setBOOL("SelectReflectionProbes", select_probe); LLSelectMgr::getInstance()->setForceSelection(FALSE); } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index b99299528c..b7f94a7e0c 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -7971,13 +7971,13 @@ class LLToolsSelectOnlyMovableObjects : public view_listener_t } }; -class LLToolsSelectReflectionProbes : public view_listener_t +class LLToolsSelectInvisibleObjects : public view_listener_t { bool handleEvent(const LLSD& userdata) { - BOOL cur_val = gSavedSettings.getBOOL("SelectReflectionProbes"); + BOOL cur_val = gSavedSettings.getBOOL("SelectInvisibleObjects"); - gSavedSettings.setBOOL("SelectReflectionProbes", !cur_val); + gSavedSettings.setBOOL("SelectInvisibleObjects", !cur_val); return true; } @@ -9212,7 +9212,7 @@ void initialize_menus() view_listener_t::addMenu(new LLToolsSelectTool(), "Tools.SelectTool"); view_listener_t::addMenu(new LLToolsSelectOnlyMyObjects(), "Tools.SelectOnlyMyObjects"); view_listener_t::addMenu(new LLToolsSelectOnlyMovableObjects(), "Tools.SelectOnlyMovableObjects"); - view_listener_t::addMenu(new LLToolsSelectReflectionProbes(), "Tools.SelectReflectionProbes"); + view_listener_t::addMenu(new LLToolsSelectInvisibleObjects(), "Tools.SelectInvisibleObjects"); view_listener_t::addMenu(new LLToolsSelectBySurrounding(), "Tools.SelectBySurrounding"); view_listener_t::addMenu(new LLToolsShowHiddenSelection(), "Tools.ShowHiddenSelection"); view_listener_t::addMenu(new LLToolsShowSelectionLightRadius(), "Tools.ShowSelectionLightRadius"); diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 6613c8ac01..1230a6d327 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -4196,10 +4196,15 @@ void LLViewerWindow::pickAsync( S32 x, BOOL pick_unselectable) { // "Show Debug Alpha" means no object actually transparent + BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); if (LLDrawPoolAlpha::sShowDebugAlpha) { pick_transparent = TRUE; } + else if (in_build_mode && !gSavedSettings.getBOOL("SelectInvisibleObjects")) + { + pick_transparent = FALSE; + } LLPickInfo pick_info(LLCoordGL(x, y_from_bot), mask, pick_transparent, pick_rigged, FALSE, TRUE, pick_unselectable, callback); schedulePick(pick_info); @@ -4260,7 +4265,7 @@ void LLViewerWindow::returnEmptyPicks() LLPickInfo LLViewerWindow::pickImmediate(S32 x, S32 y_from_bot, BOOL pick_transparent, BOOL pick_rigged, BOOL pick_particle, BOOL pick_unselectable) { BOOL in_build_mode = LLFloaterReg::instanceVisible("build"); - if (in_build_mode || LLDrawPoolAlpha::sShowDebugAlpha) + if ((in_build_mode && gSavedSettings.getBOOL("SelectInvisibleObjects")) || LLDrawPoolAlpha::sShowDebugAlpha) { // build mode allows interaction with all transparent objects // "Show Debug Alpha" means no object actually transparent @@ -5267,7 +5272,7 @@ BOOL LLViewerWindow::simpleSnapshot(LLImageRaw* raw, S32 image_width, S32 image_ void display_cube_face(); -BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip) +BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 cubeIndex, S32 face, F32 near_clip, bool dynamic_render) { // NOTE: implementation derived from LLFloater360Capture::capture360Images() and simpleSnapshot LL_PROFILE_ZONE_SCOPED_CATEGORY_APP; @@ -5300,16 +5305,33 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); + U32 dynamic_render_types[] = { + LLPipeline::RENDER_TYPE_AVATAR, + LLPipeline::RENDER_TYPE_CONTROL_AV, + LLPipeline::RENDER_TYPE_PARTICLES + }; + constexpr U32 dynamic_render_type_count = sizeof(dynamic_render_types) / sizeof(U32); + bool prev_dynamic_render_type[dynamic_render_type_count]; + + + if (!dynamic_render) + { + for (int i = 0; i < dynamic_render_type_count; ++i) + { + prev_dynamic_render_type[i] = gPipeline.hasRenderType(dynamic_render_types[i]); + if (prev_dynamic_render_type[i]) + { + gPipeline.toggleRenderType(dynamic_render_types[i]); + } + } + } + BOOL prev_draw_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI) ? TRUE : FALSE; if (prev_draw_ui != false) { LLPipeline::toggleRenderDebugFeature(LLPipeline::RENDER_DEBUG_FEATURE_UI); } - BOOL prev_draw_particles = gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - if (prev_draw_particles) - { - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); - } + LLPipeline::sShowHUDAttachments = FALSE; LLRect window_rect = getWorldViewRectRaw(); @@ -5365,9 +5387,15 @@ BOOL LLViewerWindow::cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubea } } - if (prev_draw_particles) + if (!dynamic_render) { - gPipeline.toggleRenderType(LLPipeline::RENDER_TYPE_PARTICLES); + for (int i = 0; i < dynamic_render_type_count; ++i) + { + if (prev_dynamic_render_type[i]) + { + gPipeline.toggleRenderType(dynamic_render_types[i]); + } + } } LLPipeline::sShowHUDAttachments = TRUE; diff --git a/indra/newview/llviewerwindow.h b/indra/newview/llviewerwindow.h index 38ec0e1ac8..387a2cb06f 100644 --- a/indra/newview/llviewerwindow.h +++ b/indra/newview/llviewerwindow.h @@ -370,7 +370,7 @@ public: // index - cube index in the array to use (cube index, not face-layer) // face - which cube face to update // near_clip - near clip setting to use - BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip); + BOOL cubeSnapshot(const LLVector3& origin, LLCubeMapArray* cubearray, S32 index, S32 face, F32 near_clip, bool render_avatars); // special implementation of simpleSnapshot for reflection maps diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 8f5d2d1c29..3a619b4fcc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -3545,14 +3545,27 @@ void LLVOVolume::setReflectionProbeNearClip(F32 near_clip) } } -void LLVOVolume::setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type) +void LLVOVolume::setReflectionProbeIsBox(bool is_box) { LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); if (param_block) { - if (param_block->getVolumeType() != volume_type) + if (param_block->getIsBox() != is_box) { - param_block->setVolumeType(volume_type); + param_block->setIsBox(is_box); + parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); + } + } +} + +void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) +{ + LLReflectionProbeParams* param_block = (LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) + { + if (param_block->getIsDynamic() != is_dynamic) + { + param_block->setIsDynamic(is_dynamic); parameterChanged(LLNetworkData::PARAMS_REFLECTION_PROBE, true); } } @@ -3603,17 +3616,26 @@ F32 LLVOVolume::getReflectionProbeNearClip() const } } -LLReflectionProbeParams::EInfluenceVolumeType LLVOVolume::getReflectionProbeVolumeType() const +bool LLVOVolume::getReflectionProbeIsBox() const { const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); if (param_block) { - return param_block->getVolumeType(); + return param_block->getIsBox(); } - else + + return false; +} + +bool LLVOVolume::getReflectionProbeIsDynamic() const +{ + const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); + if (param_block) { - return LLReflectionProbeParams::DEFAULT_VOLUME_TYPE; + return param_block->getIsDynamic(); } + + return false; } U32 LLVOVolume::getVolumeInterfaceID() const diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index ad7a2c5606..1ca6b49c7d 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -289,12 +289,14 @@ public: void setIsReflectionProbe(BOOL is_probe); void setReflectionProbeAmbiance(F32 ambiance); void setReflectionProbeNearClip(F32 near_clip); - void setReflectionProbeVolumeType(LLReflectionProbeParams::EInfluenceVolumeType volume_type); + void setReflectionProbeIsBox(bool is_box); + void setReflectionProbeIsDynamic(bool is_dynamic); BOOL isReflectionProbe() const override; F32 getReflectionProbeAmbiance() const; F32 getReflectionProbeNearClip() const; - LLReflectionProbeParams::EInfluenceVolumeType getReflectionProbeVolumeType() const; + bool getReflectionProbeIsBox() const; + bool getReflectionProbeIsDynamic() const; // Flexible Objects U32 getVolumeInterfaceID() const; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 20a21a685c..28dc3781ba 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6734,15 +6734,6 @@ void LLPipeline::toggleRenderType(U32 type) //static void LLPipeline::toggleRenderTypeControl(U32 type) { - U32 bit = (1< + + label="Select Invisible Objects" + name="Select Invisible Objects"> + control="SelectInvisibleObjects" /> + function="Tools.SelectInvisibleObjects" + parameter="invisible" /> Date: Thu, 23 Jun 2022 16:21:53 -0500 Subject: SL-17653 WIP - Apply GLTF material in Material Editor to selected object when you click "Save" --- indra/llprimitive/llmaterialid.cpp | 7 +++++ indra/llprimitive/llmaterialid.h | 1 + indra/llprimitive/lltextureentry.h | 8 ++++++ indra/newview/llmaterialeditor.cpp | 37 ++++++++++++++++++++++++- indra/newview/llmaterialeditor.h | 3 ++ indra/newview/llspatialpartition.h | 13 +++++++-- indra/newview/llviewerobject.cpp | 56 ++++++++++++++++++++++++++++---------- indra/newview/llviewerobject.h | 14 ++++++++++ indra/newview/llvovolume.cpp | 40 +++++++++++++++++++++++---- 9 files changed, 156 insertions(+), 23 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmaterialid.cpp b/indra/llprimitive/llmaterialid.cpp index f88a607c4f..340a83801c 100644 --- a/indra/llprimitive/llmaterialid.cpp +++ b/indra/llprimitive/llmaterialid.cpp @@ -155,6 +155,13 @@ std::string LLMaterialID::asString() const return materialIDString; } +LLUUID LLMaterialID::asUUID() const +{ + LLUUID ret; + memcpy(ret.mData, mID, MATERIAL_ID_SIZE); + return ret; +} + std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id) { s << material_id.asString(); diff --git a/indra/llprimitive/llmaterialid.h b/indra/llprimitive/llmaterialid.h index ee663f8f99..e6165dfc91 100644 --- a/indra/llprimitive/llmaterialid.h +++ b/indra/llprimitive/llmaterialid.h @@ -61,6 +61,7 @@ public: LLSD asLLSD() const; std::string asString() const; + LLUUID asUUID() const; friend std::ostream& operator<<(std::ostream& s, const LLMaterialID &material_id); diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index dc2e201044..1549b2ce87 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -32,6 +32,7 @@ #include "llsd.h" #include "llmaterialid.h" #include "llmaterial.h" +#include "llgltfmaterial.h" // These bits are used while unpacking TEM messages to tell which aspects of // the texture entry changed. @@ -134,6 +135,10 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); + void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } + LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } + + virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -162,6 +167,8 @@ public: const LLMaterialID& getMaterialID() const { return mMaterialID; }; const LLMaterialPtr getMaterialParams() const { return mMaterial; }; + LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } + // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() // to NOT return NULL. @@ -219,6 +226,7 @@ protected: bool mMaterialUpdatePending; LLMaterialID mMaterialID; LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; // if present, ignore mMaterial // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 05e7ff524a..5a0c23d59b 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -31,6 +31,8 @@ #include "llviewermenufile.h" #include "llappviewer.h" #include "llviewertexture.h" +#include "llselectmgr.h" +#include "llvovolume.h" #include "tinygltf/tiny_gltf.h" @@ -195,6 +197,8 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) void LLMaterialEditor::onClickSave() { + applyToSelection(); + tinygltf::Model model; model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; @@ -450,4 +454,35 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); -} \ No newline at end of file +} + +void LLMaterialEditor::applyToSelection() +{ + LLViewerObject* objectp = LLSelectMgr::instance().getSelection()->getFirstObject(); + if (objectp && objectp->getVolume()) + { + LLGLTFMaterial* mat = new LLGLTFMaterial(); + mat->mAlbedoColor = getAlbedoColor(); + mat->mAlbedoColor.mV[3] = getTransparency(); + mat->mAlbedoId = getAlbedoId(); + + mat->mNormalId = getNormalId(); + + mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mMetallicFactor = getMetalnessFactor(); + mat->mRoughnessFactor = getRoughnessFactor(); + + mat->mEmissiveColor = getEmissiveColor(); + mat->mEmissiveId = getEmissiveId(); + + mat->mDoubleSided = getDoubleSided(); + mat->setAlphaMode(getAlphaMode()); + + LLVOVolume* vobjp = (LLVOVolume*)objectp; + for (int i = 0; i < vobjp->getNumTEs(); ++i) + { + vobjp->getTE(i)->setGLTFMaterial(mat); + vobjp->updateTEMaterialTextures(i); + } + } +} diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index f0c5dca44d..e773ecd169 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -36,6 +36,9 @@ public: // open a file dialog and select a gltf/glb file for import void importMaterial(); + // for live preview, apply current material to currently selected object + void applyToSelection(); + void onClickSave(); // llpanel diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index 07d62be7af..c3e9d8ceb9 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -113,9 +113,14 @@ public: LL_ALIGN_16(LLFace* mFace); //associated face F32 mDistance; U32 mDrawMode; - LLMaterialPtr mMaterial; // If this is null, the following parameters are unused. - LLMaterialID mMaterialID; - U32 mShaderMask; + + // Material points here are likely for debugging only and are immaterial (zing!) + LLMaterialPtr mMaterial; + LLPointer mGLTFMaterial; + + LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info + + U32 mShaderMask; U32 mBlendFuncSrc; U32 mBlendFuncDst; BOOL mHasGlow; @@ -123,6 +128,8 @@ public: const LLMatrix4* mSpecularMapMatrix; LLPointer mNormalMap; const LLMatrix4* mNormalMapMatrix; + LLPointer mEmissiveMap; + LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent F32 mEnvIntensity; F32 mAlphaMaskCutoff; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 857a94d7be..16479e02a2 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -406,6 +406,11 @@ void LLViewerObject::deleteTEImages() delete[] mTESpecularMaps; mTESpecularMaps = NULL; } + + mGLTFAlbedoMaps.clear(); + mGLTFNormalMaps.clear(); + mGLTFMetallicRoughnessMaps.clear(); + mGLTFEmissiveMaps.clear(); } void LLViewerObject::markDead() @@ -4731,6 +4736,11 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTEImages = new_images; mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; + + mGLTFAlbedoMaps.resize(num_tes); + mGLTFNormalMaps.resize(num_tes); + mGLTFMetallicRoughnessMaps.resize(num_tes); + mGLTFEmissiveMaps.resize(num_tes); } else { @@ -4859,23 +4869,28 @@ void LLViewerObject::updateAvatarMeshVisibility(const LLUUID& id, const LLUUID& } } -void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) + +void LLViewerObject::setTE(const U8 te, const LLTextureEntry& texture_entry) { - LLUUID old_image_id; - if (getTE(te)) - { - old_image_id = getTE(te)->getID(); - } - - LLPrimitive::setTE(te, texture_entry); + LLUUID old_image_id; + if (getTE(te)) + { + old_image_id = getTE(te)->getID(); + } - const LLUUID& image_id = getTE(te)->getID(); - LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); - mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + LLPrimitive::setTE(te, texture_entry); - - updateAvatarMeshVisibility(image_id,old_image_id); + const LLUUID& image_id = getTE(te)->getID(); + LLViewerTexture* bakedTexture = getBakedTextureForMagicId(image_id); + mTEImages[te] = bakedTexture ? bakedTexture : LLViewerTextureManager::getFetchedTexture(image_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + + updateAvatarMeshVisibility(image_id, old_image_id); + updateTEMaterialTextures(te); +} + +void LLViewerObject::updateTEMaterialTextures(U8 te) +{ if (getTE(te)->getMaterialParams().notNull()) { const LLUUID& norm_id = getTE(te)->getMaterialParams()->getNormalID(); @@ -4884,6 +4899,20 @@ void LLViewerObject::setTE(const U8 te, const LLTextureEntry &texture_entry) const LLUUID& spec_id = getTE(te)->getMaterialParams()->getSpecularID(); mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } + + auto fetch_texture = [](const LLUUID& id) + { + return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); + }; + + LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); + if (mat != nullptr) + { + mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); + mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId); + mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); + mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); + } } void LLViewerObject::refreshBakeTexture() @@ -5424,7 +5453,6 @@ void LLViewerObject::fitFaceTexture(const U8 face) LL_INFOS() << "fitFaceTexture not implemented" << LL_ENDL; } - LLBBox LLViewerObject::getBoundingBoxAgent() const { LLVector3 position_agent; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1c4cfc6466..5136a7e5ee 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -321,6 +321,7 @@ public: /*virtual*/ void setNumTEs(const U8 num_tes); /*virtual*/ void setTE(const U8 te, const LLTextureEntry &texture_entry); + void updateTEMaterialTextures(U8 te); /*virtual*/ S32 setTETexture(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTENormalMap(const U8 te, const LLUUID &uuid); /*virtual*/ S32 setTESpecularMap(const U8 te, const LLUUID &uuid); @@ -359,6 +360,12 @@ public: LLViewerTexture *getTEImage(const U8 te) const; LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; + + LLViewerTexture* getGLTFAlbedoMap(U8 te) const { return mGLTFAlbedoMaps[te]; } + LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } + LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } + LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } + bool isImageAlphaBlended(const U8 te) const; @@ -675,6 +682,13 @@ public: LLPointer *mTEImages; LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; + + std::vector > mGLTFAlbedoMaps; + std::vector > mGLTFNormalMaps; + std::vector > mGLTFMetallicRoughnessMaps; + std::vector > mGLTFEmissiveMaps; + + // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 3a619b4fcc..302a172858 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5390,10 +5390,26 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerTexture* tex = facep->getTexture(); + U8 index = facep->getTextureIndex(); - LLMaterial* mat = facep->getTextureEntry()->getMaterialParams().get(); - LLMaterialID mat_id = facep->getTextureEntry()->getMaterialID(); + LLMaterial* mat = nullptr; + + LLUUID mat_id; + + LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + if (gltf_mat != nullptr) + { + mat_id = gltf_mat->getHash(); // TODO: cache this hash + } + else + { + mat = facep->getTextureEntry()->getMaterialParams().get(); + if (mat) + { + mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); + } + } bool batchable = false; @@ -5415,7 +5431,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { - if (mat || draw_vec[idx]->mMaterial) + if (mat || gltf_mat || draw_vec[idx]->mMaterial) { //can't batch textures when materials are present (yet) batchable = false; } @@ -5447,7 +5463,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_vec[idx]->mEnd - draw_vec[idx]->mStart + facep->getGeomCount() <= (U32) gGLManager.mGLMaxVertexRange && draw_vec[idx]->mCount + facep->getIndicesCount() <= (U32) gGLManager.mGLMaxIndexRange && #endif - //draw_vec[idx]->mMaterial == mat && draw_vec[idx]->mMaterialID == mat_id && draw_vec[idx]->mFullbright == fullbright && draw_vec[idx]->mBump == bump && @@ -5504,11 +5519,22 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, draw_info->mEnvIntensity = spec; draw_info->mSpecularMap = NULL; draw_info->mMaterial = mat; + draw_info->mGLTFMaterial = gltf_mat; draw_info->mShaderMask = shader_mask; draw_info->mAvatar = facep->mAvatar; draw_info->mSkinInfo = facep->mSkinInfo; - if (mat) + if (gltf_mat) + { + LLViewerObject* vobj = facep->getViewerObject(); + U8 te = facep->getTEOffset(); + + draw_info->mTexture = vobj->getGLTFAlbedoMap(te); + draw_info->mNormalMap = vobj->getGLTFNormalMap(te); + draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); + draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); + } + else if (mat) { draw_info->mMaterialID = mat_id; @@ -5849,6 +5875,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } +#if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); const LLUUID obj_id( vobj->getID() ); @@ -5856,6 +5883,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) #else bool is_pbr = false; #endif +#else + bool is_pbr = facep->getTextureEntry()->getGLTFMaterial() != nullptr; +#endif //ALWAYS null out vertex buffer on rebuild -- if the face lands in a render // batch, it will recover its vertex buffer reference from the spatial group -- cgit v1.3 From 6c678648e0649ca1be62c79af792ffd85ce379a8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 23 Jun 2022 16:40:48 -0500 Subject: SL-17653 Last commit was accidentally partial --- indra/llprimitive/CMakeLists.txt | 1 + indra/llprimitive/llgltfmaterial.h | 89 ++++++++++++++++++++++++++++++++++++++ indra/newview/pipeline.cpp | 5 +++ 3 files changed, 95 insertions(+) create mode 100644 indra/llprimitive/llgltfmaterial.h (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index e131b12371..bb14bb9242 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -52,6 +52,7 @@ set(llprimitive_HEADER_FILES CMakeLists.txt lldaeloader.h llgltfloader.h + llgltfmaterial.h legacy_object_types.h llmaterial.h llmaterialid.h diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h new file mode 100644 index 0000000000..2df4883a3c --- /dev/null +++ b/indra/llprimitive/llgltfmaterial.h @@ -0,0 +1,89 @@ +/** + * @file llgltfmaterial.h + * @brief Material definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llrefcount.h" +#include "v4color.h" +#include "v3color.h" +#include "lluuid.h" +#include "llmd5.h" + +class LLGLTFMaterial : public LLRefCount +{ +public: + + enum AlphaMode + { + ALPHA_MODE_OPAQUE = 0, + ALPHA_MODE_BLEND, + ALPHA_MODE_MASK + }; + + LLUUID mAlbedoId; + LLUUID mNormalId; + LLUUID mMetallicRoughnessId; + LLUUID mEmissiveId; + + LLColor4 mAlbedoColor = LLColor4(1,1,1,1); + LLColor3 mEmissiveColor = LLColor3(0,0,0); + + F32 mMetallicFactor = 0.f; + F32 mRoughnessFactor = 0.f; + bool mDoubleSided = false; + AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; + + // get a UUID based on a hash of this LLGLTFMaterial + LLUUID getHash() const + { + LLMD5 md5; + md5.update((unsigned char*) this, sizeof(this)); + LLUUID id; + md5.raw_digest(id.mData); + return id; + } + + // set mAlphaMode from string. + // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE + void setAlphaMode(const std::string& mode) + { + if (mode == "MASK") + { + mAlphaMode = ALPHA_MODE_MASK; + } + else if (mode == "BLEND") + { + mAlphaMode = ALPHA_MODE_BLEND; + } + else + { + mAlphaMode = ALPHA_MODE_OPAQUE; + } + } +}; + + + diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 030c7b450d..c9f3eb9076 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1647,6 +1647,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima } LLMaterial* mat = te->getMaterialParams().get(); + LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); bool color_alpha = te->getColor().mV[3] < 0.999f; bool alpha = color_alpha; @@ -1680,6 +1681,10 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima { return LLDrawPool::POOL_BUMP; } + else if (gltf_mat && !alpha) + { + return LLDrawPool::POOL_PBR_OPAQUE; + } else if (mat && !alpha) { return LLDrawPool::POOL_MATERIALS; -- cgit v1.3 From 0fe39a1f3f64c336ccbf806e89b62d158d1da110 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Thu, 23 Jun 2022 18:07:10 -0700 Subject: Correcting windows specific filesystem issues and removing unused DAE code in llgltfloader.cpp from SL-17214 --- indra/llprimitive/llgltfloader.cpp | 6 ++---- indra/llprimitive/llgltfloader.h | 1 - 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index 3ec11f70c6..6041c9c273 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -24,7 +24,7 @@ * $/LicenseInfo$ */ -#include "LLGLTFLoader.h" +#include "llgltfloader.h" // Import & define single-header gltf import/export lib #define TINYGLTF_IMPLEMENTATION @@ -43,7 +43,7 @@ // Additionally, disable inclusion of STB header files entirely with // TINYGLTF_NO_INCLUDE_STB_IMAGE // TINYGLTF_NO_INCLUDE_STB_IMAGE_WRITE -#include "tinygltf\tiny_gltf.h" +#include "tinygltf/tiny_gltf.h" // TODO: includes inherited from dae loader. Validate / prune @@ -68,7 +68,6 @@ static const std::string lod_suffix[LLModel::NUM_LODS] = "_PHYS", }; -const U32 LIMIT_MATERIALS_OUTPUT = 12; LLGLTFLoader::LLGLTFLoader(std::string filename, S32 lod, @@ -94,7 +93,6 @@ LLGLTFLoader::LLGLTFLoader(std::string filename, jointsFromNodes, jointAliasMap, maxJointsPerMesh ), - mGeneratedModelLimit(modelLimit), //mPreprocessGLTF(preprocess), mMeshesLoaded(false), mMaterialsLoaded(false) diff --git a/indra/llprimitive/llgltfloader.h b/indra/llprimitive/llgltfloader.h index 91389b5845..b4d6ca1940 100644 --- a/indra/llprimitive/llgltfloader.h +++ b/indra/llprimitive/llgltfloader.h @@ -158,7 +158,6 @@ private: bool populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh); LLUUID imageBufferToTextureUUID(const gltf_texture& tex); - U32 mGeneratedModelLimit; // Attempt to limit amount of generated submodels // bool mPreprocessGLTF; /* Below inherited from dae loader - unknown if/how useful here -- cgit v1.3 From 57805cac68bbc67ecb8a8e76c0ced2ce9b622dd1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 28 Jun 2022 15:15:57 -0500 Subject: SL-17379 More complete integration of material asset type --- indra/llfilesystem/lldiskcache.cpp | 1 + indra/llprimitive/llgltfmaterial.h | 10 + indra/newview/app_settings/settings.xml | 11 + indra/newview/llfloaterbulkpermission.cpp | 1 + indra/newview/llinventorybridge.cpp | 3 +- indra/newview/llmaterialeditor.cpp | 630 ++++++++++++++++++--- indra/newview/llmaterialeditor.h | 50 +- indra/newview/llviewerinventory.cpp | 4 +- indra/newview/llviewermessage.cpp | 6 +- indra/newview/llviewerregion.cpp | 2 + .../newview/skins/default/xui/en/notifications.xml | 25 + 11 files changed, 663 insertions(+), 80 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llfilesystem/lldiskcache.cpp b/indra/llfilesystem/lldiskcache.cpp index ee43a599f7..538446d732 100644 --- a/indra/llfilesystem/lldiskcache.cpp +++ b/indra/llfilesystem/lldiskcache.cpp @@ -209,6 +209,7 @@ const std::string LLDiskCache::assetTypeToString(LLAssetType::EType at) { LLAssetType::AT_PERSON, "PERSON" }, { LLAssetType::AT_MESH, "MESH" }, { LLAssetType::AT_SETTINGS, "SETTINGS" }, + { LLAssetType::AT_MATERIAL, "MATERIAL" }, { LLAssetType::AT_UNKNOWN, "UNKNOWN" } }; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 2df4883a3c..d6f59cd1a3 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -83,6 +83,16 @@ public: mAlphaMode = ALPHA_MODE_OPAQUE; } } + + const char* getAlphaMode() + { + switch (mAlphaMode) + { + case ALPHA_MODE_MASK: return "MASK"; + case ALPHA_MODE_BLEND: return "BLEND"; + default: return "OPAQUE"; + } + } }; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 35a79f12de..1be6124a2a 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -1252,6 +1252,17 @@ Value 1 + BulkChangeIncludeMaterials + + Comment + Bulk permission changes affect materials + Persist + 1 + Type + Boolean + Value + 1 + BulkChangeEveryoneCopy Comment diff --git a/indra/newview/llfloaterbulkpermission.cpp b/indra/newview/llfloaterbulkpermission.cpp index a1a06706bc..a3cc939f85 100644 --- a/indra/newview/llfloaterbulkpermission.cpp +++ b/indra/newview/llfloaterbulkpermission.cpp @@ -306,6 +306,7 @@ void LLFloaterBulkPermission::handleInventory(LLViewerObject* viewer_obj, LLInve ( asstype == LLAssetType::AT_LSL_TEXT && gSavedSettings.getBOOL("BulkChangeIncludeScripts" )) || ( asstype == LLAssetType::AT_SOUND && gSavedSettings.getBOOL("BulkChangeIncludeSounds" )) || ( asstype == LLAssetType::AT_SETTINGS && gSavedSettings.getBOOL("BulkChangeIncludeSettings" )) || + ( asstype == LLAssetType::AT_MATERIAL && gSavedSettings.getBOOL("BulkChangeIncludeMaterials")) || ( asstype == LLAssetType::AT_TEXTURE && gSavedSettings.getBOOL("BulkChangeIncludeTextures" ))) { LLViewerObject* object = gObjectList.findObject(viewer_obj->getID()); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index cd6f631ee1..2bb2c9676b 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -7651,8 +7651,7 @@ public: LLViewerInventoryItem* item = getItem(); if (item) { - // TODO - show UI for material preview? - LL_INFOS() << "inventory action performed on material: " << item->getName() << " " << item->getUUID() << LL_ENDL; + LLFloaterReg::showInstance("material_editor", LLSD(item->getUUID()), TAKE_FOCUS_YES); } LLInvFVBridgeAction::doIt(); } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index f1166fbc0d..ada5bb3882 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -42,8 +42,14 @@ #include "llviewerinventory.h" #include "llviewerregion.h" #include "llvovolume.h" - +#include "roles_constants.h" #include "tinygltf/tiny_gltf.h" +#include "llviewerobjectlist.h" +#include "llfloaterreg.h" +#include "llfilesystem.h" +#include "llsdserialize.h" + +#include ///---------------------------------------------------------------------------- /// Class LLPreviewNotecard @@ -51,9 +57,14 @@ // Default constructor LLMaterialEditor::LLMaterialEditor(const LLSD& key) - : LLFloater(key) + : LLPreview(key) , mHasUnsavedChanges(false) { + const LLInventoryItem* item = getItem(); + if (item) + { + mAssetID = item->getAssetUUID(); + } } BOOL LLMaterialEditor::postBuild() @@ -104,7 +115,7 @@ BOOL LLMaterialEditor::postBuild() // Disable/enable setCanApplyImmediately() based on // working from inventory, upload or editing inworld - return LLFloater::postBuild(); + return LLPreview::postBuild(); } void LLMaterialEditor::onClickCloseBtn(bool app_quitting) @@ -149,7 +160,7 @@ LLColor4 LLMaterialEditor::getAlbedoColor() void LLMaterialEditor::setAlbedoColor(const LLColor4& color) { childSetValue("albedo color", color.getValue()); - childSetValue("transparency", color.mV[3]); + setTransparency(color.mV[3]); } F32 LLMaterialEditor::getTransparency() @@ -157,6 +168,11 @@ F32 LLMaterialEditor::getTransparency() return childGetValue("transparency").asReal(); } +void LLMaterialEditor::setTransparency(F32 transparency) +{ + childSetValue("transparency", transparency); +} + std::string LLMaterialEditor::getAlphaMode() { return childGetValue("alpha mode").asString(); @@ -375,11 +391,51 @@ static U32 write_texture(const LLUUID& id, tinygltf::Model& model) return texture_idx; } + void LLMaterialEditor::onClickSave() { applyToSelection(); + + saveIfNeeded(); +} + +std::string LLMaterialEditor::getGLTFJson(bool prettyprint) +{ tinygltf::Model model; + getGLTFModel(model); + + std::ostringstream str; + + tinygltf::TinyGLTF gltf; + + gltf.WriteGltfSceneToStream(&model, str, prettyprint, false); + + std::string dump = str.str(); + + return dump; +} + +void LLMaterialEditor::getGLBData(std::vector& data) +{ + tinygltf::Model model; + getGLTFModel(model); + + std::ostringstream str; + + tinygltf::TinyGLTF gltf; + + gltf.WriteGltfSceneToStream(&model, str, false, true); + + std::string dump = str.str(); + + data.resize(dump.length()); + + memcpy(&data[0], dump.c_str(), dump.length()); +} + +void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) +{ model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; @@ -392,11 +448,11 @@ void LLMaterialEditor::onClickSave() model.materials[0].alphaMode = getAlphaMode(); LLUUID albedo_id = getAlbedoId(); - + if (albedo_id.notNull()) { U32 texture_idx = write_texture(albedo_id, model); - + pbrMaterial.baseColorTexture.index = texture_idx; } @@ -406,14 +462,14 @@ void LLMaterialEditor::onClickSave() pbrMaterial.metallicFactor = metalness; pbrMaterial.roughnessFactor = roughness; - + LLUUID mr_id = getMetallicRoughnessId(); if (mr_id.notNull()) { U32 texture_idx = write_texture(mr_id, model); pbrMaterial.metallicRoughnessTexture.index = texture_idx; } - + //write emissive LLColor4 emissive_color = getEmissiveColor(); model.materials[0].emissiveFactor.resize(3); @@ -437,54 +493,213 @@ void LLMaterialEditor::onClickSave() //write doublesided model.materials[0].doubleSided = getDoubleSided(); + model.asset.version = "2.0"; +} + +std::string LLMaterialEditor::getEncodedAsset() +{ + LLSD asset; + asset["version"] = "1.0"; + asset["type"] = "GLTF 2.0"; + asset["data"] = getGLTFJson(false); + std::ostringstream str; + LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); - tinygltf::TinyGLTF gltf; - model.asset.version = "2.0"; - gltf.WriteGltfSceneToStream(&model, str, true, false); + return str.str(); +} + +bool LLMaterialEditor::decodeAsset(const std::vector& buffer) +{ + LLSD asset; - std::string dump = str.str(); + std::istrstream str(&buffer[0], buffer.size()); + if (LLSDSerialize::deserialize(asset, str, buffer.size())) + { + if (asset.has("version") && asset["version"] == "1.0") + { + if (asset.has("type") && asset["type"] == "GLTF 2.0") + { + if (asset.has("data") && asset["data"].isString()) + { + std::string data = asset["data"]; + + tinygltf::TinyGLTF gltf; + tinygltf::TinyGLTF loader; + std::string error_msg; + std::string warn_msg; + + tinygltf::Model model_in; + + if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) + { + return setFromGltfModel(model_in, true); + } + else + { + LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; + LL_WARNS() << warn_msg << LL_ENDL; + LL_WARNS() << error_msg << LL_ENDL; + } + } + } + } + } + else + { + LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + } + + return false; +} - LL_INFOS() << mMaterialName << ": " << dump << LL_ENDL; - - // gen a new uuid for this asset - LLTransactionID tid; - tid.generate(); // timestamp-based randomization + uniquification - LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); - std::string res_desc = "Saved Material"; - U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); - LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); - const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? - - create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, - LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, - new LLBoostFuncInventoryCallback([output=dump](LLUUID const & inv_item_id){ - // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() - LLResourceUploadInfo::ptr_t uploadInfo = - std::make_shared( - inv_item_id, - LLAssetType::AT_SETTINGS, // TODO switch to AT_MATERIAL - output, - [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { - LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; - LLSD params = llsd::map("ASSET_ID", new_asset_id); - LLNotificationsUtil::add("MaterialCreated", params); +bool LLMaterialEditor::saveIfNeeded(LLInventoryItem* copyitem, bool sync) +{ + std::string buffer = getEncodedAsset(); + + const LLInventoryItem* item = getItem(); + // save it out to database + if (item) + { + const LLViewerRegion* region = gAgent.getRegion(); + if (!region) + { + LL_WARNS() << "Not connected to a region, cannot save material." << LL_ENDL; + return false; + } + std::string agent_url = region->getCapability("UpdateMaterialAgentInventory"); + std::string task_url = region->getCapability("UpdateMaterialTaskInventory"); + + if (!agent_url.empty() && !task_url.empty()) + { + std::string url; + LLResourceUploadInfo::ptr_t uploadInfo; + + if (mObjectUUID.isNull() && !agent_url.empty()) + { + uploadInfo = std::make_shared(mItemUUID, LLAssetType::AT_MATERIAL, buffer, + [](LLUUID itemId, LLUUID newAssetId, LLUUID newItemId, LLSD) { + LLMaterialEditor::finishInventoryUpload(itemId, newAssetId, newItemId); }); + url = agent_url; + } + else if (!mObjectUUID.isNull() && !task_url.empty()) + { + LLUUID object_uuid(mObjectUUID); + uploadInfo = std::make_shared(mObjectUUID, mItemUUID, LLAssetType::AT_MATERIAL, buffer, + [object_uuid](LLUUID itemId, LLUUID, LLUUID newAssetId, LLSD) { + LLMaterialEditor::finishTaskUpload(itemId, newAssetId, object_uuid); + }); + url = task_url; + } - const LLViewerRegion* region = gAgent.getRegion(); - if (region) + if (!url.empty() && uploadInfo) { - std::string agent_url(region->getCapability("UpdateSettingsAgentInventory")); - if (agent_url.empty()) - { - LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; - } - LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + mAssetStatus = PREVIEW_ASSET_LOADING; + setEnabled(false); + + LLViewerAssetUpload::EnqueueInventoryUpload(url, uploadInfo); } - }) - ); + + } + else // !gAssetStorage + { + LL_WARNS() << "Not connected to an materials capable region." << LL_ENDL; + return false; + } + + if (mCloseAfterSave) + { + closeFloater(); + } + } + else + { //make a new inventory item + // gen a new uuid for this asset + LLTransactionID tid; + tid.generate(); // timestamp-based randomization + uniquification + LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); + std::string res_desc = "Saved Material"; + U32 next_owner_perm = LLPermissions::DEFAULT.getMaskNextOwner(); + LLUUID parent = gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? + + create_inventory_item(gAgent.getID(), gAgent.getSessionID(), parent, tid, mMaterialName, res_desc, + LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, subtype, next_owner_perm, + new LLBoostFuncInventoryCallback([output = buffer](LLUUID const& inv_item_id) { + // from reference in LLSettingsVOBase::createInventoryItem()/updateInventoryItem() + LLResourceUploadInfo::ptr_t uploadInfo = + std::make_shared( + inv_item_id, + LLAssetType::AT_MATERIAL, + output, + [](LLUUID item_id, LLUUID new_asset_id, LLUUID new_item_id, LLSD response) { + LL_INFOS("Material") << "inventory item uploaded. item: " << item_id << " asset: " << new_asset_id << " new_item_id: " << new_item_id << " response: " << response << LL_ENDL; + LLSD params = llsd::map("ASSET_ID", new_asset_id); + LLNotificationsUtil::add("MaterialCreated", params); + }); + + const LLViewerRegion* region = gAgent.getRegion(); + if (region) + { + std::string agent_url(region->getCapability("UpdateMaterialAgentInventory")); + if (agent_url.empty()) + { + LL_ERRS() << "missing required agent inventory cap url" << LL_ENDL; + } + LLViewerAssetUpload::EnqueueInventoryUpload(agent_url, uploadInfo); + } + }) + ); + } + + return true; +} + +void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId) +{ + // Update the UI with the new asset. + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + if (me) + { + if (newItemId.isNull()) + { + me->setAssetId(newAssetId); + me->refreshFromInventory(); + } + else + { + me->refreshFromInventory(newItemId); + } + } } +void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId) +{ + + LLSD floater_key; + floater_key["taskid"] = taskId; + floater_key["itemid"] = itemId; + LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", LLSD(itemId)); + if (me) + { + me->setAssetId(newAssetId); + me->refreshFromInventory(); + } +} + +void LLMaterialEditor::refreshFromInventory(const LLUUID& new_item_id) +{ + if (new_item_id.notNull()) + { + mItemUUID = new_item_id; + setKey(LLSD(new_item_id)); + } + LL_DEBUGS() << "LLPreviewNotecard::refreshFromInventory()" << LL_ENDL; + loadAsset(); +} + + void LLMaterialEditor::onClickSaveAs() { LLSD args; @@ -806,16 +1021,7 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->setEmissiveId(emissive_id); mME->setNormalId(normal_id); - mME->setAlphaMode(material_in.alphaMode); - mME->setAlphaCutoff(material_in.alphaCutoff); - - mME->setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); - mME->setEmissiveColor(get_color(material_in.emissiveFactor)); - - mME->setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); - mME->setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); - - mME->setDoubleSided(material_in.doubleSided); + mME->setFromGltfModel(model_in); std::string new_material = LLTrans::getString("New Material"); mME->setMaterialName(new_material); @@ -826,6 +1032,81 @@ void LLMaterialFilePicker::loadMaterial(const std::string& filename) mME->applyToSelection(); } +bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_textures) +{ + if (model.materials.size() > 0) + { + tinygltf::Material& material_in = model.materials[0]; + + if (set_textures) + { + S32 index; + LLUUID id; + + // get albedo texture + index = material_in.pbrMetallicRoughness.baseColorTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setAlbedoId(id); + } + else + { + setAlbedoId(LLUUID::null); + } + + // get normal map + index = material_in.normalTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setNormalId(id); + } + else + { + setNormalId(LLUUID::null); + } + + // get metallic-roughness texture + index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setMetallicRoughnessId(id); + } + else + { + setMetallicRoughnessId(LLUUID::null); + } + + // get emissive texture + index = material_in.emissiveTexture.index; + if (index >= 0) + { + id.set(model.images[index].uri); + setEmissiveId(id); + } + else + { + setEmissiveId(LLUUID::null); + } + } + + setAlphaMode(material_in.alphaMode); + setAlphaCutoff(material_in.alphaCutoff); + + setAlbedoColor(get_color(material_in.pbrMetallicRoughness.baseColorFactor)); + setEmissiveColor(get_color(material_in.emissiveFactor)); + + setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); + setRoughnessFactor(material_in.pbrMetallicRoughness.roughnessFactor); + + setDoubleSided(material_in.doubleSided); + } + + return true; +} + void LLMaterialEditor::importMaterial() { (new LLMaterialFilePicker(this))->getFile(); @@ -841,22 +1122,7 @@ void LLMaterialEditor::applyToSelection() if (objectp && objectp->getVolume()) { LLGLTFMaterial* mat = new LLGLTFMaterial(); - mat->mAlbedoColor = getAlbedoColor(); - mat->mAlbedoColor.mV[3] = getTransparency(); - mat->mAlbedoId = getAlbedoId(); - - mat->mNormalId = getNormalId(); - - mat->mMetallicRoughnessId = getMetallicRoughnessId(); - mat->mMetallicFactor = getMetalnessFactor(); - mat->mRoughnessFactor = getRoughnessFactor(); - - mat->mEmissiveColor = getEmissiveColor(); - mat->mEmissiveId = getEmissiveId(); - - mat->mDoubleSided = getDoubleSided(); - mat->setAlphaMode(getAlphaMode()); - + getGLTFMaterial(mat); LLVOVolume* vobjp = (LLVOVolume*)objectp; for (int i = 0; i < vobjp->getNumTEs(); ++i) { @@ -867,3 +1133,223 @@ void LLMaterialEditor::applyToSelection() vobjp->markForUpdate(TRUE); } } + +void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) +{ + mat->mAlbedoColor = getAlbedoColor(); + mat->mAlbedoColor.mV[3] = getTransparency(); + mat->mAlbedoId = getAlbedoId(); + + mat->mNormalId = getNormalId(); + + mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mMetallicFactor = getMetalnessFactor(); + mat->mRoughnessFactor = getRoughnessFactor(); + + mat->mEmissiveColor = getEmissiveColor(); + mat->mEmissiveId = getEmissiveId(); + + mat->mDoubleSided = getDoubleSided(); + mat->setAlphaMode(getAlphaMode()); +} + +void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) +{ + setAlbedoColor(mat->mAlbedoColor); + setAlbedoId(mat->mAlbedoId); + setNormalId(mat->mNormalId); + + setMetallicRoughnessId(mat->mMetallicRoughnessId); + setMetalnessFactor(mat->mMetallicFactor); + setRoughnessFactor(mat->mRoughnessFactor); + + setEmissiveColor(mat->mEmissiveColor); + setEmissiveId(mat->mEmissiveId); + + setDoubleSided(mat->mDoubleSided); + setAlphaMode(mat->getAlphaMode()); +} + +void LLMaterialEditor::loadAsset() +{ + // derived from LLPreviewNotecard::loadAsset + + // TODO: see commented out "editor" references and make them do something appropriate to the UI + + // request the asset. + const LLInventoryItem* item = getItem(); + + bool fail = false; + + if (item) + { + LLPermissions perm(item->getPermissions()); + BOOL is_owner = gAgent.allowOperation(PERM_OWNER, perm, GP_OBJECT_MANIPULATE); + BOOL allow_copy = gAgent.allowOperation(PERM_COPY, perm, GP_OBJECT_MANIPULATE); + BOOL allow_modify = canModify(mObjectUUID, item); + BOOL source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); + + if (allow_copy || gAgent.isGodlike()) + { + mAssetID = item->getAssetUUID(); + if (mAssetID.isNull()) + { + mAssetStatus = PREVIEW_ASSET_LOADED; + } + else + { + LLHost source_sim = LLHost(); + LLSD* user_data = new LLSD(); + + if (mObjectUUID.notNull()) + { + LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); + if (objectp && objectp->getRegion()) + { + source_sim = objectp->getRegion()->getHost(); + } + else + { + // The object that we're trying to look at disappeared, bail. + LL_WARNS() << "Can't find object " << mObjectUUID << " associated with notecard." << LL_ENDL; + mAssetID.setNull(); + /*editor->setText(getString("no_object")); + editor->makePristine(); + editor->setEnabled(FALSE);*/ + mAssetStatus = PREVIEW_ASSET_LOADED; + return; + } + user_data->with("taskid", mObjectUUID).with("itemid", mItemUUID); + } + else + { + user_data = new LLSD(mItemUUID); + } + + gAssetStorage->getInvItemAsset(source_sim, + gAgent.getID(), + gAgent.getSessionID(), + item->getPermissions().getOwner(), + mObjectUUID, + item->getUUID(), + item->getAssetUUID(), + item->getType(), + &onLoadComplete, + (void*)user_data, + TRUE); + mAssetStatus = PREVIEW_ASSET_LOADING; + } + } + else + { + mAssetID.setNull(); + /*editor->setText(getString("not_allowed")); + editor->makePristine(); + editor->setEnabled(FALSE);*/ + mAssetStatus = PREVIEW_ASSET_LOADED; + } + + if (!allow_modify) + { + //editor->setEnabled(FALSE); + //getChildView("lock")->setVisible(TRUE); + //getChildView("Edit")->setEnabled(FALSE); + } + + if ((allow_modify || is_owner) && !source_library) + { + //getChildView("Delete")->setEnabled(TRUE); + } + } + else if (mObjectUUID.notNull() && mItemUUID.notNull()) + { + LLViewerObject* objectp = gObjectList.findObject(mObjectUUID); + if (objectp && (objectp->isInventoryPending() || objectp->isInventoryDirty())) + { + // It's a material in object's inventory and we failed to get it because inventory is not up to date. + // Subscribe for callback and retry at inventoryChanged() + registerVOInventoryListener(objectp, NULL); //removes previous listener + + if (objectp->isInventoryDirty()) + { + objectp->requestInventory(); + } + } + else + { + fail = true; + } + } + else + { + fail = true; + } + + if (fail) + { + /*editor->setText(LLStringUtil::null); + editor->makePristine(); + editor->setEnabled(TRUE);*/ + // Don't set asset status here; we may not have set the item id yet + // (e.g. when this gets called initially) + //mAssetStatus = PREVIEW_ASSET_LOADED; + } +} + +// static +void LLMaterialEditor::onLoadComplete(const LLUUID& asset_uuid, + LLAssetType::EType type, + void* user_data, S32 status, LLExtStat ext_status) +{ + LL_INFOS() << "LLMaterialEditor::onLoadComplete()" << LL_ENDL; + LLSD* floater_key = (LLSD*)user_data; + LLMaterialEditor* editor = LLFloaterReg::findTypedInstance("material_editor", *floater_key); + if (editor) + { + if (0 == status) + { + LLFileSystem file(asset_uuid, type, LLFileSystem::READ); + + S32 file_length = file.getSize(); + + std::vector buffer(file_length + 1); + file.read((U8*)&buffer[0], file_length); + + editor->decodeAsset(buffer); + + BOOL modifiable = editor->canModify(editor->mObjectID, editor->getItem()); + editor->setEnabled(modifiable); + editor->mAssetStatus = PREVIEW_ASSET_LOADED; + } + else + { + if (LL_ERR_ASSET_REQUEST_NOT_IN_DATABASE == status || + LL_ERR_FILE_EMPTY == status) + { + LLNotificationsUtil::add("MaterialMissing"); + } + else if (LL_ERR_INSUFFICIENT_PERMISSIONS == status) + { + LLNotificationsUtil::add("MaterialNoPermissions"); + } + else + { + LLNotificationsUtil::add("UnableToLoadMaterial"); + } + + LL_WARNS() << "Problem loading material: " << status << LL_ENDL; + editor->mAssetStatus = PREVIEW_ASSET_ERROR; + } + } + delete floater_key; +} + +void LLMaterialEditor::inventoryChanged(LLViewerObject* object, + LLInventoryObject::object_list_t* inventory, + S32 serial_num, + void* user_data) +{ + removeVOInventoryListener(); + loadAsset(); +} + diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 7f9c6c0b63..4090ed120b 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -26,22 +26,62 @@ #pragma once -#include "llfloater.h" +#include "llpreview.h" +#include "llvoinventorylistener.h" class LLTextureCtrl; -class LLMaterialEditor : public LLFloater +namespace tinygltf +{ + class Model; +} + +class LLGLTFMaterial; + +class LLMaterialEditor : public LLPreview, public LLVOInventoryListener { public: LLMaterialEditor(const LLSD& key); + bool setFromGltfModel(tinygltf::Model& model, bool set_textures = false); + // open a file dialog and select a gltf/glb file for import void importMaterial(); // for live preview, apply current material to currently selected object void applyToSelection(); + void getGLTFMaterial(LLGLTFMaterial* mat); + + void setFromGLTFMaterial(LLGLTFMaterial* mat); + + void loadAsset(); + + static void onLoadComplete(const LLUUID& asset_uuid, LLAssetType::EType type, void* user_data, S32 status, LLExtStat ext_status); + + void inventoryChanged(LLViewerObject* object, LLInventoryObject::object_list_t* inventory, S32 serial_num, void* user_data) override; + void onClickSave(); + + // get a dump of the json representation of the current state of the editor UI in GLTF format + std::string getGLTFJson(bool prettyprint = true); + + void getGLBData(std::vector& data); + + void getGLTFModel(tinygltf::Model& model); + + std::string getEncodedAsset(); + + bool decodeAsset(const std::vector& buffer); + + bool saveIfNeeded(LLInventoryItem* copyitem = nullptr, bool sync = true); + + static void finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, LLUUID newItemId); + + static void finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID taskId); + + void refreshFromInventory(const LLUUID& new_item_id = LLUUID::null); + void onClickSaveAs(); void onSaveAsMsgCallback(const LLSD& notification, const LLSD& response); void onClickCancel(); @@ -60,7 +100,8 @@ public: void setAlbedoColor(const LLColor4& color); F32 getTransparency(); - + void setTransparency(F32 transparency); + std::string getAlphaMode(); void setAlphaMode(const std::string& alpha_mode); @@ -98,6 +139,9 @@ public: void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data); private: + LLUUID mAssetID; + LLUUID mObjectID; + LLTextureCtrl* mAlbedoTextureCtrl; LLTextureCtrl* mMetallicTextureCtrl; LLTextureCtrl* mEmissiveTextureCtrl; diff --git a/indra/newview/llviewerinventory.cpp b/indra/newview/llviewerinventory.cpp index d777cde554..2265379ce4 100644 --- a/indra/newview/llviewerinventory.cpp +++ b/indra/newview/llviewerinventory.cpp @@ -1731,8 +1731,8 @@ void menu_create_inventory_item(LLInventoryPanel* panel, LLFolderBridge *bridge, } else if ("material" == type_name) { - const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_GESTURE); - create_new_item(NEW_GESTURE_NAME, + const LLUUID parent_id = bridge ? bridge->getUUID() : gInventory.findCategoryUUIDForType(LLFolderType::FT_MATERIAL); + create_new_item(NEW_MATERIAL_NAME, parent_id, LLAssetType::AT_MATERIAL, LLInventoryType::IT_MATERIAL, diff --git a/indra/newview/llviewermessage.cpp b/indra/newview/llviewermessage.cpp index a886303563..375f176b60 100644 --- a/indra/newview/llviewermessage.cpp +++ b/indra/newview/llviewermessage.cpp @@ -1414,7 +1414,8 @@ bool check_asset_previewable(const LLAssetType::EType asset_type) (asset_type == LLAssetType::AT_TEXTURE) || (asset_type == LLAssetType::AT_ANIMATION) || (asset_type == LLAssetType::AT_SCRIPT) || - (asset_type == LLAssetType::AT_SOUND); + (asset_type == LLAssetType::AT_SOUND) || + (asset_type == LLAssetType::AT_MATERIAL); } void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_name) @@ -1519,6 +1520,9 @@ void open_inventory_offer(const uuid_vec_t& objects, const std::string& from_nam case LLAssetType::AT_SOUND: LLFloaterReg::showInstance("preview_sound", LLSD(obj_id), take_focus); break; + case LLAssetType::AT_MATERIAL: + LLFloaterReg::showInstance("material editor", LLSD(obj_id), take_focus); + break; default: LL_DEBUGS("Messaging") << "No preview method for previewable asset type : " << LLAssetType::lookupHumanReadable(asset_type) << LL_ENDL; break; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 67ad72e997..6345323ff9 100644 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -3095,6 +3095,8 @@ void LLViewerRegionImpl::buildCapabilityNames(LLSD& capabilityNames) capabilityNames.append("UpdateScriptTask"); capabilityNames.append("UpdateSettingsAgentInventory"); capabilityNames.append("UpdateSettingsTaskInventory"); + capabilityNames.append("UpdateMaterialAgentInventory"); + capabilityNames.append("UpdateMaterialTaskInventory"); capabilityNames.append("UploadBakedTexture"); capabilityNames.append("UserInfo"); capabilityNames.append("ViewerAsset"); diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 0ca3e043e7..ae4b0538d8 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -6762,6 +6762,22 @@ You don't have permission to view this notecard. fail + + Material is missing from database. + fail + + + + You don't have permission to view this material. + fail + + fail + + Unable to load material. + Please try again. + fail + + Date: Wed, 29 Jun 2022 17:59:09 -0500 Subject: SL-17685 Drag and drop material support WIP --- indra/llprimitive/llprimitive.cpp | 109 ++++++++++++++++++++++++++----- indra/llprimitive/llprimitive.h | 24 +++++-- indra/newview/llinventorybridge.cpp | 2 + indra/newview/llpanelgroupnotices.cpp | 1 + indra/newview/llpanelobjectinventory.cpp | 1 + indra/newview/lltooldraganddrop.cpp | 82 ++++++++++++++++++++++- indra/newview/lltooldraganddrop.h | 10 +++ indra/newview/llviewerobject.cpp | 55 ++++++++++++++++ indra/newview/llviewerobject.h | 7 ++ indra/newview/llviewertexteditor.cpp | 1 + indra/newview/llvovolume.cpp | 25 ++----- indra/newview/llvovolume.h | 2 +- 12 files changed, 273 insertions(+), 46 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 9e0a079fd9..6df7111a47 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1700,7 +1700,7 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) case PARAMS_EXTENDED_MESH: return (size == 4); case PARAMS_RENDER_MATERIAL: - return (size == 16); + return (size > 1); } return FALSE; @@ -2312,18 +2312,32 @@ LLRenderMaterialParams::LLRenderMaterialParams() mType = PARAMS_RENDER_MATERIAL; } -BOOL LLRenderMaterialParams::pack(LLDataPacker &dp) const +BOOL LLRenderMaterialParams::pack(LLDataPacker& dp) const { - return dp.packUUID(mMaterial, "material"); + U8 count = (U8)llmin((S32)mEntries.size(), 14); //limited to 255 bytes, no more than 14 material ids -// return TRUE; + dp.packU8(count, "count"); + for (auto& entry : mEntries) + { + dp.packU8(entry.te_idx, "te_idx"); + dp.packUUID(entry.id, "id"); + } + + return TRUE; } -BOOL LLRenderMaterialParams::unpack(LLDataPacker &dp) +BOOL LLRenderMaterialParams::unpack(LLDataPacker& dp) { - return dp.unpackUUID(mMaterial, "material"); + U8 count; + dp.unpackU8(count, "count"); + mEntries.resize(count); + for (auto& entry : mEntries) + { + dp.unpackU8(entry.te_idx, "te_idx"); + dp.unpackUUID(entry.id, "te_id"); + } -// return TRUE; + return TRUE; } bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const @@ -2333,40 +2347,99 @@ bool LLRenderMaterialParams::operator==(const LLNetworkData& data) const return false; } - const LLRenderMaterialParams ¶m = static_cast(data); + const LLRenderMaterialParams& param = static_cast(data); + + if (param.mEntries.size() != mEntries.size()) + { + return false; + } + + for (auto& entry : mEntries) + { + if (param.getMaterial(entry.te_idx) != entry.id) + { + return false; + } + } - return param.mMaterial == mMaterial; + return true; } void LLRenderMaterialParams::copy(const LLNetworkData& data) { llassert_always(data.mType == PARAMS_RENDER_MATERIAL); - const LLRenderMaterialParams ¶m = static_cast(data); - mMaterial = param.mMaterial; + const LLRenderMaterialParams& param = static_cast(data); + mEntries = param.mEntries; } LLSD LLRenderMaterialParams::asLLSD() const { - return llsd::map("material", mMaterial); + LLSD ret; + + for (int i = 0; i < mEntries.size(); ++i) + { + ret[i]["te_idx"] = mEntries[i].te_idx; + ret[i]["id"] = mEntries[i].id; + } + + return ret; } bool LLRenderMaterialParams::fromLLSD(LLSD& sd) { - if (sd.has("material")) + if (sd.isArray()) { - setMaterial(sd["material"]); + mEntries.resize(sd.size()); + for (int i = 0; i < sd.size(); ++i) + { + if (sd[i].has("te_idx") && sd.has("id")) + { + mEntries[i].te_idx = sd[i]["te_idx"].asInteger(); + mEntries[i].id = sd[i]["id"].asUUID(); + } + else + { + return false; + } + } + return true; } return false; } -void LLRenderMaterialParams::setMaterial(const LLUUID & id) +void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id) { - mMaterial = id; + for (int i = 0; i < mEntries.size(); ++i) + { + if (mEntries[i].te_idx == te) + { + if (id.isNull()) + { + mEntries.erase(mEntries.begin() + i); + } + else + { + mEntries[i].id = id; + } + return; + } + } + + mEntries.push_back({ te, id }); } -LLUUID LLRenderMaterialParams::getMaterial() const +LLUUID LLRenderMaterialParams::getMaterial(U8 te) const { - return mMaterial; + for (int i = 0; i < mEntries.size(); ++i) + { + if (mEntries[i].te_idx == te) + { + return mEntries[i].id; + } + } + + return LLUUID::null; } + diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 25196fb894..1c290185b0 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -369,22 +369,30 @@ public: class LLRenderMaterialParams : public LLNetworkData { private: - LLUUID mMaterial; + struct Entry + { + U8 te_idx; + LLUUID id; + }; + std::vector< Entry > mEntries; public: LLRenderMaterialParams(); - BOOL pack(LLDataPacker &dp) const override; - BOOL unpack(LLDataPacker &dp) override; + BOOL pack(LLDataPacker& dp) const override; + BOOL unpack(LLDataPacker& dp) override; bool operator==(const LLNetworkData& data) const override; void copy(const LLNetworkData& data) override; LLSD asLLSD() const; operator LLSD() const { return asLLSD(); } bool fromLLSD(LLSD& sd); - void setMaterial(const LLUUID & id); - LLUUID getMaterial() const; + void setMaterial(U8 te_idx, const LLUUID& id); + LLUUID getMaterial(U8 te_idx) const; + + bool isEmpty() { return mEntries.empty(); } }; + // This code is not naming-standards compliant. Leaving it like this for // now to make the connection to code in // BOOL packTEMessage(LLDataPacker &dp) const; @@ -480,12 +488,12 @@ public: virtual S32 setTEMediaFlags(const U8 te, const U8 flags); virtual S32 setTEGlow(const U8 te, const F32 glow); virtual S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); - virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); + virtual S32 setTEMaterialParams(const U8 index, const LLMaterialPtr pMaterialParams); virtual BOOL setMaterial(const U8 material); // returns TRUE if material changed virtual void setTESelected(const U8 te, bool sel); LLMaterialPtr getTEMaterialParams(const U8 index); - + void copyTEs(const LLPrimitive *primitive); S32 packTEField(U8 *cur_ptr, U8 *data_ptr, U8 data_size, U8 last_face_index, EMsgVariableType type) const; BOOL packTEMessage(LLMessageSystem *mesgsys) const; @@ -563,6 +571,8 @@ public: static LLPCode legacyToPCode(const U8 legacy); static U8 pCodeToLegacy(const LLPCode pcode); static bool getTESTAxes(const U8 face, U32* s_axis, U32* t_axis); + + BOOL hasRenderMaterialParams() const; inline static BOOL isPrimitive(const LLPCode pcode); inline static BOOL isApp(const LLPCode pcode); diff --git a/indra/newview/llinventorybridge.cpp b/indra/newview/llinventorybridge.cpp index 2bb2c9676b..d325831c8f 100644 --- a/indra/newview/llinventorybridge.cpp +++ b/indra/newview/llinventorybridge.cpp @@ -4403,6 +4403,7 @@ BOOL LLFolderBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_GESTURE: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: accept = dragItemIntoFolder(inv_item, drop, tooltip_msg); break; case DAD_LINK: @@ -6032,6 +6033,7 @@ BOOL LLCallingCardBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_GESTURE: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: { LLInventoryItem* inv_item = (LLInventoryItem*)cargo_data; const LLPermissions& perm = inv_item->getPermissions(); diff --git a/indra/newview/llpanelgroupnotices.cpp b/indra/newview/llpanelgroupnotices.cpp index ab32ea3956..82f880c9ee 100644 --- a/indra/newview/llpanelgroupnotices.cpp +++ b/indra/newview/llpanelgroupnotices.cpp @@ -156,6 +156,7 @@ BOOL LLGroupDropTarget::handleDragAndDrop(S32 x, S32 y, MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: { LLViewerInventoryItem* inv_item = (LLViewerInventoryItem*)cargo_data; if(gInventory.getItem(inv_item->getUUID()) diff --git a/indra/newview/llpanelobjectinventory.cpp b/indra/newview/llpanelobjectinventory.cpp index defd7025b8..998cffef4a 100644 --- a/indra/newview/llpanelobjectinventory.cpp +++ b/indra/newview/llpanelobjectinventory.cpp @@ -704,6 +704,7 @@ BOOL LLTaskCategoryBridge::dragOrDrop(MASK mask, BOOL drop, case DAD_CALLINGCARD: case DAD_MESH: case DAD_SETTINGS: + case DAD_MATERIAL: accept = LLToolDragAndDrop::isInventoryDropAcceptable(object, (LLViewerInventoryItem*)cargo_data); if(accept && drop) { diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index 50868d0fa5..a4b34bb5b6 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -256,7 +256,8 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() // |-------------------------------|----------------------------------------------|-----------------------------------------------|---------------------------------------------------|--------------------------------| addEntry(DAD_NONE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_TEXTURE, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dTextureObject, &LLToolDragAndDrop::dad3dNULL)); - addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_MATERIAL, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMaterialObject, &LLToolDragAndDrop::dad3dNULL)); + addEntry(DAD_SOUND, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_CALLINGCARD, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_LANDMARK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_SCRIPT, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dRezScript, &LLToolDragAndDrop::dad3dNULL)); @@ -271,6 +272,7 @@ LLToolDragAndDrop::LLDragAndDropDictionary::LLDragAndDropDictionary() addEntry(DAD_LINK, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_MESH, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dMeshObject, &LLToolDragAndDrop::dad3dNULL)); addEntry(DAD_SETTINGS, new DragAndDropEntry(&LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dNULL, &LLToolDragAndDrop::dad3dGiveInventory, &LLToolDragAndDrop::dad3dUpdateInventory, &LLToolDragAndDrop::dad3dNULL)); + // TODO: animation on self could play it? edit it? // TODO: gesture on self could play it? edit it? }; @@ -1062,6 +1064,66 @@ void LLToolDragAndDrop::dropTextureAllFaces(LLViewerObject* hit_obj, hit_obj->sendTEUpdate(); } + +void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, + S32 hit_face, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (hit_face == -1) return; + if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureOneFace no material item." << LL_ENDL; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); + if (!success) + { + return; + } + + LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; + + hit_obj->setRenderMaterialID(hit_face, asset_id); + + dialog_refresh_all(); + + // send the update to the simulator + hit_obj->sendTEUpdate(); +} + + +void LLToolDragAndDrop::dropMaterialAllFaces(LLViewerObject* hit_obj, + LLInventoryItem* item, + LLToolDragAndDrop::ESource source, + const LLUUID& src_id) +{ + if (!item || item->getInventoryType() != LLInventoryType::IT_MATERIAL) + { + LL_WARNS() << "LLToolDragAndDrop::dropTextureAllFaces no material item." << LL_ENDL; + return; + } + LLUUID asset_id = item->getAssetUUID(); + BOOL success = handleDropTextureProtections(hit_obj, item, source, src_id); + if (!success) + { + return; + } + + S32 num_faces = hit_obj->getNumTEs(); + for (S32 face = 0; face < num_faces; face++) + { + // update viewer side material in anticipation of update from simulator + hit_obj->setRenderMaterialID(face, asset_id); + dialog_refresh_all(); + } + // send the update to the simulator + hit_obj->sendTEUpdate(); +} + + void LLToolDragAndDrop::dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, LLToolDragAndDrop::ESource source, @@ -1628,6 +1690,7 @@ bool LLToolDragAndDrop::handleGiveDragAndDrop(LLUUID dest_agent, LLUUID session_ case DAD_MESH: case DAD_CATEGORY: case DAD_SETTINGS: + case DAD_MATERIAL: { LLInventoryObject* inv_obj = (LLInventoryObject*)cargo_data; if(gInventory.getCategory(inv_obj->getUUID()) || (gInventory.getItem(inv_obj->getUUID()) @@ -1982,6 +2045,17 @@ EAcceptance LLToolDragAndDrop::dad3dApplyToObject( dropTextureOneFace(obj, face, item, mSource, mSourceID); } } + else if (cargo_type == DAD_MATERIAL) + { + if ((mask & MASK_SHIFT)) + { + dropMaterialAllFaces(obj, item, mSource, mSourceID); + } + else + { + dropMaterialOneFace(obj, face, item, mSource, mSourceID); + } + } else if (cargo_type == DAD_MESH) { dropMesh(obj, item, mSource, mSourceID); @@ -2010,6 +2084,12 @@ EAcceptance LLToolDragAndDrop::dad3dTextureObject( return dad3dApplyToObject(obj, face, mask, drop, DAD_TEXTURE); } +EAcceptance LLToolDragAndDrop::dad3dMaterialObject( + LLViewerObject* obj, S32 face, MASK mask, BOOL drop) +{ + return dad3dApplyToObject(obj, face, mask, drop, DAD_MATERIAL); +} + EAcceptance LLToolDragAndDrop::dad3dMeshObject( LLViewerObject* obj, S32 face, MASK mask, BOOL drop) { diff --git a/indra/newview/lltooldraganddrop.h b/indra/newview/lltooldraganddrop.h index 24a712029c..2f6423080e 100644 --- a/indra/newview/lltooldraganddrop.h +++ b/indra/newview/lltooldraganddrop.h @@ -168,6 +168,8 @@ protected: MASK mask, BOOL drop); EAcceptance dad3dTextureObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); + EAcceptance dad3dMaterialObject(LLViewerObject* obj, S32 face, + MASK mask, BOOL drop); EAcceptance dad3dMeshObject(LLViewerObject* obj, S32 face, MASK mask, BOOL drop); // EAcceptance dad3dTextureSelf(LLViewerObject* obj, S32 face, @@ -249,6 +251,14 @@ public: LLInventoryItem* item, ESource source, const LLUUID& src_id); + static void dropMaterialOneFace(LLViewerObject* hit_obj, S32 hit_face, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id); + static void dropMaterialAllFaces(LLViewerObject* hit_obj, + LLInventoryItem* item, + ESource source, + const LLUUID& src_id); static void dropMesh(LLViewerObject* hit_obj, LLInventoryItem* item, ESource source, diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 16479e02a2..232e51896e 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -6991,6 +6991,61 @@ LLVOAvatar* LLViewerObject::getAvatar() const return NULL; } +bool LLViewerObject::hasRenderMaterialParams() const +{ + return getParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL); +} + +void LLViewerObject::setHasRenderMaterialParams(bool has_materials) +{ + bool had_materials = hasRenderMaterialParams(); + + if (had_materials != has_materials) + { + if (has_materials) + { + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, true); + } + else + { + setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, FALSE, true); + } + } +} + +const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const +{ + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + return param_block->getMaterial(te); + } + + return LLUUID::null; +} + +void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) +{ + if (id.notNull()) + { + setHasRenderMaterialParams(true); + } + + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (param_block) + { + param_block->setMaterial(te, id); + + if (param_block->isEmpty()) + { // might be empty if id is null + setHasRenderMaterialParams(false); + } + else + { + parameterChanged(LLNetworkData::PARAMS_RENDER_MATERIAL, true); + } + } +} class ObjectPhysicsProperties : public LLHTTPNode { diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 5136a7e5ee..1392caa855 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -179,6 +179,13 @@ public: const std::string& getAttachmentItemName() const; virtual LLVOAvatar* getAvatar() const; //get the avatar this object is attached to, or NULL if object is not an attachment + + bool hasRenderMaterialParams() const; + void setHasRenderMaterialParams(bool has_params); + + const LLUUID& getRenderMaterialID(U8 te) const; + void setRenderMaterialID(U8 te, const LLUUID& id); + virtual BOOL isHUDAttachment() const { return FALSE; } virtual BOOL isTempAttachment() const; diff --git a/indra/newview/llviewertexteditor.cpp b/indra/newview/llviewertexteditor.cpp index e2de7ac825..7c860936a5 100644 --- a/indra/newview/llviewertexteditor.cpp +++ b/indra/newview/llviewertexteditor.cpp @@ -879,6 +879,7 @@ BOOL LLViewerTextEditor::handleDragAndDrop(S32 x, S32 y, MASK mask, case DAD_ANIMATION: case DAD_GESTURE: case DAD_MESH: + case DAD_MATERIAL: { supported = true; break; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 0706e26fb1..f220547499 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -2162,6 +2162,7 @@ void LLVOVolume::setNumTEs(const U8 num_tes) return ; } + //virtual void LLVOVolume::changeTEImage(S32 index, LLViewerTexture* imagep) { @@ -3501,6 +3502,11 @@ F32 LLVOVolume::getLightCutoff() const } } +BOOL LLVOVolume::isReflectionProbe() const +{ + return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); +} + void LLVOVolume::setIsReflectionProbe(BOOL is_probe) { BOOL was_probe = isReflectionProbe(); @@ -3571,25 +3577,6 @@ void LLVOVolume::setReflectionProbeIsDynamic(bool is_dynamic) } } - -BOOL LLVOVolume::isReflectionProbe() const -{ - // HACK - make this object a Reflection Probe if a certain UUID is detected - static LLCachedControl reflection_probe_id(gSavedSettings, "RenderReflectionProbeTextureHackID", ""); - LLUUID probe_id(reflection_probe_id); - - for (U8 i = 0; i < getNumTEs(); ++i) - { - if (getTE(i)->getID() == probe_id) - { - return true; - } - } - // END HACK - - return getParameterEntryInUse(LLNetworkData::PARAMS_REFLECTION_PROBE); -} - F32 LLVOVolume::getReflectionProbeAmbiance() const { const LLReflectionProbeParams* param_block = (const LLReflectionProbeParams*)getParameterEntry(LLNetworkData::PARAMS_REFLECTION_PROBE); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index f0a4fd427e..79049851b4 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -284,7 +284,7 @@ public: F32 getLightRadius() const; F32 getLightFalloff(const F32 fudge_factor = 1.f) const; F32 getLightCutoff() const; - + // Reflection Probes void setIsReflectionProbe(BOOL is_probe); void setReflectionProbeAmbiance(F32 ambiance); -- cgit v1.3 From 6f6df8ed71702f0ee8d21a2b583818ae360dd093 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 29 Jun 2022 21:42:44 -0500 Subject: SL-17685 Drag and drop material support --- indra/llprimitive/llgltfmaterial.h | 2 ++ indra/llprimitive/llprimitive.cpp | 2 +- indra/llprimitive/llprimitive.h | 2 +- indra/newview/CMakeLists.txt | 2 ++ indra/newview/llmaterialeditor.cpp | 2 +- indra/newview/lltooldraganddrop.cpp | 2 -- indra/newview/llviewerobject.cpp | 29 +++++++++++++++++++++++++++++ indra/newview/llviewerobject.h | 1 + indra/newview/llvovolume.cpp | 2 ++ indra/newview/llvovolume.h | 2 +- 10 files changed, 40 insertions(+), 6 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d6f59cd1a3..a8d5fb8e85 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -53,6 +53,8 @@ public: F32 mMetallicFactor = 0.f; F32 mRoughnessFactor = 0.f; + F32 mAlphaCutoff = 0.f; + bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 6df7111a47..3f0059b759 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2430,7 +2430,7 @@ void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id) mEntries.push_back({ te, id }); } -LLUUID LLRenderMaterialParams::getMaterial(U8 te) const +const LLUUID& LLRenderMaterialParams::getMaterial(U8 te) const { for (int i = 0; i < mEntries.size(); ++i) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index 1c290185b0..d2adfa4a3d 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -387,7 +387,7 @@ public: bool fromLLSD(LLSD& sd); void setMaterial(U8 te_idx, const LLUUID& id); - LLUUID getMaterial(U8 te_idx) const; + const LLUUID& getMaterial(U8 te_idx) const; bool isEmpty() { return mEntries.empty(); } }; diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index d4bd1c8b57..b67bc91277 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -344,6 +344,7 @@ set(viewer_SOURCE_FILES llgesturemgr.cpp llgiveinventory.cpp llglsandbox.cpp + llgltfmateriallist.cpp llgroupactions.cpp llgroupiconctrl.cpp llgrouplist.cpp @@ -986,6 +987,7 @@ set(viewer_HEADER_FILES llgesturelistener.h llgesturemgr.h llgiveinventory.h + llgltfmateriallist.h llgroupactions.h llgroupiconctrl.h llgrouplist.h diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 2455ad2926..9fb9f723cd 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -43,7 +43,6 @@ #include "llviewerregion.h" #include "llvovolume.h" #include "roles_constants.h" -#include "tinygltf/tiny_gltf.h" #include "llviewerobjectlist.h" #include "llfloaterreg.h" #include "llfilesystem.h" @@ -52,6 +51,7 @@ #include "llviewertexturelist.h" #include "llfloaterperms.h" +#include "tinygltf/tiny_gltf.h" #include ///---------------------------------------------------------------------------- diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index a4b34bb5b6..55e8a3b98b 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1083,8 +1083,6 @@ void LLToolDragAndDrop::dropMaterialOneFace(LLViewerObject* hit_obj, { return; } - - LLTextureEntry* tep = hit_obj ? (hit_obj->getTE(hit_face)) : NULL; hit_obj->setRenderMaterialID(hit_face, asset_id); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 232e51896e..753fb014c9 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -107,6 +107,7 @@ #include "llcleanup.h" #include "llcallstack.h" #include "llmeshrepository.h" +#include "llgltfmateriallist.h" #include "llgl.h" //#define DEBUG_UPDATE_TYPE @@ -4906,6 +4907,18 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) }; LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); + LLUUID mat_id = getRenderMaterialID(te); + if (mat == nullptr && mat_id.notNull()) + { + mat = gGLTFMaterialList.getMaterial(mat_id); + getTE(te)->setGLTFMaterial(mat); + } + else if (mat_id.isNull() && mat != nullptr) + { + mat = nullptr; + getTE(te)->setGLTFMaterial(nullptr); + } + if (mat != nullptr) { mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); @@ -4913,6 +4926,14 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); } + else + { + mGLTFAlbedoMaps[te] = nullptr; + mGLTFNormalMaps[te] = nullptr; + mGLTFMetallicRoughnessMaps[te] = nullptr; + mGLTFEmissiveMaps[te] = nullptr; + } + } void LLViewerObject::refreshBakeTexture() @@ -7028,8 +7049,16 @@ void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id) { if (id.notNull()) { + getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); setHasRenderMaterialParams(true); } + else + { + getTE(te)->setGLTFMaterial(nullptr); + } + + faceMappingChanged(); + gPipeline.markTextured(mDrawable); LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); if (param_block) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 1392caa855..109c96dc9c 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -207,6 +207,7 @@ public: // Graphical stuff for objects - maybe broken out into render class later? virtual void updateTextures(); + virtual void faceMappingChanged() {} virtual void boostTexturePriority(BOOL boost_children = TRUE); // When you just want to boost priority of this object virtual LLDrawable* createDrawable(LLPipeline *pipeline); diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 685b24d5d6..4fa9f05c09 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5861,6 +5861,8 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // HACK -- brute force this check every time a drawable gets rebuilt + vobj->updateTEMaterialTextures(i); #if 0 #if LL_RELEASE_WITH_DEBUG_INFO const LLUUID pbr_id( "49c88210-7238-2a6b-70ac-92d4f35963cf" ); diff --git a/indra/newview/llvovolume.h b/indra/newview/llvovolume.h index 79049851b4..db586fd741 100644 --- a/indra/newview/llvovolume.h +++ b/indra/newview/llvovolume.h @@ -172,7 +172,7 @@ public: void markForUpdate(BOOL priority) override; void markForUnload() { LLViewerObject::markForUnload(TRUE); mVolumeChanged = TRUE; } - void faceMappingChanged() { mFaceMappingChanged=TRUE; }; + void faceMappingChanged() override { mFaceMappingChanged=TRUE; } /*virtual*/ void onShift(const LLVector4a &shift_vector) override; // Called when the drawable shifts -- cgit v1.3 From d048795fce3ab83989cb909fde02014f1442cc84 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 5 Aug 2022 16:58:22 -0500 Subject: SL-17870 Nudge PBR material textures so they start downloading. (and add missing validation code for reflection probes network data). --- indra/llprimitive/llprimitive.cpp | 2 ++ indra/newview/llviewerobject.cpp | 9 ++++++++- indra/newview/pipeline.cpp | 1 + 3 files changed, 11 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 3f0059b759..8b470d235c 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -1701,6 +1701,8 @@ BOOL LLNetworkData::isValid(U16 param_type, U32 size) return (size == 4); case PARAMS_RENDER_MATERIAL: return (size > 1); + case PARAMS_REFLECTION_PROBE: + return (size == 9); } return FALSE; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 753fb014c9..bdc47e0c50 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4903,7 +4903,14 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) auto fetch_texture = [](const LLUUID& id) { - return LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); + LLViewerFetchedTexture* img = nullptr; + if (id.notNull()) + { + img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); + img->addTextureStats(64.f * 64.f, TRUE); + } + + return img; }; LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b23c1fe741..017bb808c4 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3766,6 +3766,7 @@ void LLPipeline::touchTextures(LLDrawInfo* info) touchTexture(info->mTexture, info->mVSize); touchTexture(info->mSpecularMap, info->mVSize); touchTexture(info->mNormalMap, info->mVSize); + touchTexture(info->mEmissiveMap, info->mVSize); } void LLPipeline::postSort(LLCamera& camera) -- cgit v1.3 From 7558641610895f1192c0fefa152437524e431eb3 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 8 Aug 2022 15:34:56 -0500 Subject: SL-17937 Fix for broken PBR material batching. --- indra/llprimitive/llgltfmaterial.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a8d5fb8e85..ab381ca55e 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -61,8 +61,10 @@ public: // get a UUID based on a hash of this LLGLTFMaterial LLUUID getHash() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMD5 md5; md5.update((unsigned char*) this, sizeof(this)); + md5.finalize(); LLUUID id; md5.raw_digest(id.mData); return id; -- cgit v1.3 From e49d602bd99f5a3b1257ba1bc7ded133eab1eb1c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 12 Sep 2022 19:48:33 -0500 Subject: SL-18095 Add tangents to mesh assets so we can calculate mikktspace tangents in the mesh's original coordinate frame. --- indra/llmath/llvolume.cpp | 233 ++++++++++++--------- indra/llprimitive/lldaeloader.cpp | 12 +- indra/llprimitive/llmodel.cpp | 41 ++++ indra/llprimitive/llmodel.h | 1 + .../shaders/class1/deferred/pbropaqueF.glsl | 2 + indra/newview/llmodelpreview.cpp | 20 +- 6 files changed, 202 insertions(+), 107 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index fca9471f14..563a325f03 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2431,11 +2431,10 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) LLSD::Binary pos = mdl[i]["Position"]; LLSD::Binary norm = mdl[i]["Normal"]; + LLSD::Binary tangent = mdl[i]["Tangent"]; LLSD::Binary tc = mdl[i]["TexCoord0"]; LLSD::Binary idx = mdl[i]["TriangleList"]; - - //copy out indices S32 num_indices = idx.size() / 2; face.resizeIndices(num_indices); @@ -2534,6 +2533,33 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } + { + if (!tangent.empty()) + { + face.allocateTangents(face.mNumVertices, true); + U16* t = (U16*)&(tangent[0]); + + // store incoming tangents in mMikktSpaceTangents + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to + // maintain compliance with the GLTF spec + LLVector4a* t_out = face.mMikktSpaceTangents; + + for (U32 j = 0; j < num_verts; ++j) + { + t_out->set((F32)t[0], (F32)t[1], (F32)t[2], (F32) t[3]); + t_out->div(65535.f); + t_out->mul(2.f); + t_out->sub(1.f); + + F32* tp = t_out->getF32ptr(); + tp[3] = tp[3] < 0.f ? -1.f : 1.f; + + t_out++; + t += 4; + } + } + } + { if (!tc.empty()) { @@ -5429,124 +5455,135 @@ bool LLVolumeFace::cacheOptimize() llassert(!mOptimized); mOptimized = TRUE; - allocateTangents(mNumVertices, true); + if (!mNormals || !mTexCoords) + { // can't perform this operation without normals and texture coordinates + return false; + } - SMikkTSpaceInterface ms; + if (mMikktSpaceTangents == nullptr) + { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change + allocateTangents(mNumVertices, true); - ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - return face->mNumIndices / 3; - }; + SMikkTSpaceInterface ms; - ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) - { - return 3; - }; + ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + return face->mNumIndices / 3; + }; - ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); - fvPosOut[0] = v[0]; - fvPosOut[1] = v[1]; - fvPosOut[2] = v[2]; - }; - - ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); - fvNormOut[0] = n[0]; - fvNormOut[1] = n[1]; - fvNormOut[2] = n[2]; - }; - - ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; - }; - - ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) - { - MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; + ms.m_getNumVerticesOfFace = [](const SMikkTSpaceContext* pContext, const int iFace) + { + return 3; + }; - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); + ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& vert = face->mPositions[idx]; + F32* v = vert.getF32ptr(); + fvPosOut[0] = v[0]; + fvPosOut[1] = v[1]; + fvPosOut[2] = v[2]; + }; + + ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& norm = face->mNormals[idx]; + F32* n = norm.getF32ptr(); + fvNormOut[0] = n[0]; + fvNormOut[1] = n[1]; + fvNormOut[2] = n[2]; + }; + + ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 idx = face->mIndices[iFace * 3 + iVert]; + auto& tc = face->mTexCoords[idx]; + fvTexcOut[0] = tc.mV[0]; + fvTexcOut[1] = tc.mV[1]; + }; + + ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) + { + MikktData* data = (MikktData*)pContext->m_pUserData; + LLVolumeFace* face = data->face; + S32 i = iFace * 3 + iVert; + S32 idx = face->mIndices[i]; - data->t[i].set(fvTangent); - data->t[i].mV[3] = fSign; - }; + LLVector3 p(face->mPositions[idx].getF32ptr()); + LLVector3 n(face->mNormals[idx].getF32ptr()); + LLVector3 t(fvTangent); - ms.m_setTSpace = nullptr; + // assert that this tangent hasn't already been set + llassert(data->t[i].magVec() < 0.1f); - MikktData data(this); + data->t[i].set(fvTangent); + data->t[i].mV[3] = fSign; + }; - SMikkTSpaceContext ctx = { &ms, &data }; + ms.m_setTSpace = nullptr; - genTangSpaceDefault(&ctx); + MikktData data(this); - //re-weld - meshopt_Stream mos[] = - { - { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, - { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, - { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, - { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } - }; + SMikkTSpaceContext ctx = { &ms, &data }; - std::vector remap; - remap.resize(data.p.size()); + genTangSpaceDefault(&ctx); - U32 stream_count = data.w.empty() ? 4 : 5; + //re-weld + meshopt_Stream mos[] = + { + { &data.p[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.n[0], sizeof(LLVector3), sizeof(LLVector3) }, + { &data.t[0], sizeof(LLVector4), sizeof(LLVector4) }, + { &data.tc[0], sizeof(LLVector2), sizeof(LLVector2) }, + { data.w.empty() ? nullptr : &data.w[0], sizeof(LLVector4), sizeof(LLVector4) } + }; - U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); + std::vector remap; + remap.resize(data.p.size()); - std::vector indices; - indices.resize(mNumIndices); + U32 stream_count = data.w.empty() ? 4 : 5; - //copy results back into volume - resizeVertices(vert_count); + U32 vert_count = meshopt_generateVertexRemapMulti(&remap[0], nullptr, data.p.size(), data.p.size(), mos, stream_count); - if (!data.w.empty()) - { - allocateWeights(vert_count); - } + std::vector indices; + indices.resize(mNumIndices); - allocateTangents(mNumVertices, true); + //copy results back into volume + resizeVertices(vert_count); - for (int i = 0; i < mNumIndices; ++i) - { - U32 src_idx = i; - U32 dst_idx = remap[i]; - mIndices[i] = dst_idx; + if (!data.w.empty()) + { + allocateWeights(vert_count); + } - mPositions[dst_idx].load3(data.p[src_idx].mV); - mNormals[dst_idx].load3(data.n[src_idx].mV); - mTexCoords[dst_idx] = data.tc[src_idx]; - - mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + allocateTangents(mNumVertices, true); - if (mWeights) + for (int i = 0; i < mNumIndices; ++i) { - mWeights[dst_idx].loadua(data.w[src_idx].mV); + U32 src_idx = i; + U32 dst_idx = remap[i]; + mIndices[i] = dst_idx; + + mPositions[dst_idx].load3(data.p[src_idx].mV); + mNormals[dst_idx].load3(data.n[src_idx].mV); + mTexCoords[dst_idx] = data.tc[src_idx]; + + mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + + if (mWeights) + { + mWeights[dst_idx].loadua(data.w[src_idx].mV); + } } } diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 50f4a4306e..9470146ce4 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2551,6 +2551,9 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo LLVolume::face_list_t remainder; do { + // generate tangents and cache optimize before normalizing + ret->preprocessVolumeFaces(); + // Insure we do this once with the whole gang and not per-model // if (!normalized && !mNoNormalize) @@ -2561,10 +2564,11 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); - if (!mNoOptimize) - { - ret->remapVolumeFaces(); - } + // remove unused/redundant vertices after normalizing + //if (!mNoOptimize) + //{ + // ret->remapVolumeFaces(); + //} volume_faces = remainder.size(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 285c5f656b..1ce287d773 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -187,6 +187,15 @@ void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remain } } +// generate mikkt space tangents and cache optimize +void LLModel::preprocessVolumeFaces() +{ + for (auto& face : mVolumeFaces) + { + face.cacheOptimize(); + } +} + // Shrink the model to fit // on a 1x1x1 cube centered at the origin. // The positions and extents @@ -296,6 +305,7 @@ void LLModel::normalizeVolumeFaces() // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; LLVector4a* norm = (LLVector4a*) face.mNormals; + LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents; for (U32 j = 0; j < face.mNumVertices; ++j) { @@ -306,6 +316,14 @@ void LLModel::normalizeVolumeFaces() norm[j].mul(inv_scale); norm[j].normalize3(); } + + if (t) + { + F32 w = t[j].getF32ptr()[3]; + t[j].mul(inv_scale); + t[j].normalize3(); + t[j].getF32ptr()[3] = w; + } } } @@ -726,10 +744,12 @@ LLSD LLModel::writeModel( LLSD::Binary verts(face.mNumVertices*3*2); LLSD::Binary tc(face.mNumVertices*2*2); LLSD::Binary normals(face.mNumVertices*3*2); + LLSD::Binary tangents(face.mNumVertices * 4 * 2); LLSD::Binary indices(face.mNumIndices*2); U32 vert_idx = 0; U32 norm_idx = 0; + U32 tan_idx = 0; U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; @@ -782,6 +802,22 @@ LLSD LLModel::writeModel( normals[norm_idx++] = buff[1]; } } + + if (face.mMikktSpaceTangents) + { //normals + F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); + + for (U32 k = 0; k < 4; ++k) + { //for each component + //convert to 16-bit normalized + U16 val = (U16)((tangent[k] + 1.f) * 0.5f * 65535); + U8* buff = (U8*)&val; + + //write to binary buffer + tangents[tan_idx++] = buff[0]; + tangents[tan_idx++] = buff[1]; + } + } //texcoord if (face.mTexCoords) @@ -819,6 +855,11 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["Normal"] = normals; } + if (face.mMikktSpaceTangents) + { + mdl[model_names[idx]][i]["Tangent"] = tangents; + } + if (face.mTexCoords) { mdl[model_names[idx]][i]["TexCoord0Domain"]["Min"] = min_tc.getValue(); diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index 354ceb26b7..ea97851ce8 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -182,6 +182,7 @@ public: void addFace(const LLVolumeFace& face); void sortVolumeFacesByMaterialName(); + void preprocessVolumeFaces(); void normalizeVolumeFaces(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index ca304f749a..f0f5208f52 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -94,6 +94,8 @@ void main() //col = vec3(0,0,0); //emissive = vary_tangent.xyz*0.5+0.5; //emissive = vec3(sign*0.5+0.5); + //emissive = vNt * 0.5 + 0.5; + //emissive = tnorm*0.5+0.5; // See: C++: addDeferredAttachments(), GLSL: softenLightF frag_data[0] = vec4(col, 0.0); // Diffuse frag_data[1] = vec4(emissive, vertex_color.a); // PBR sRGB Emissive diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index c3fbada9db..2c0f0ae443 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1308,9 +1308,10 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // extra space for normals and text coords S32 tc_bytes_size = ((size_vertices * sizeof(LLVector2)) + 0xF) & ~0xF; - LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* combined_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* combined_normals = combined_positions + size_vertices; - LLVector2* combined_tex_coords = (LLVector2*)(combined_normals + size_vertices); + LLVector4a* combined_tangents = combined_normals + size_vertices; + LLVector2* combined_tex_coords = (LLVector2*)(combined_tangents + size_vertices); // copy indices and vertices into new buffers S32 combined_positions_shift = 0; @@ -1320,6 +1321,9 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { const LLVolumeFace &face = base_model->getVolumeFace(face_idx); + // ensure tangents have been generated or loaded + llassert(face.mMikktSpaceTangents); + // Vertices S32 copy_bytes = face.mNumVertices * sizeof(LLVector4a); LLVector4a::memcpyNonAliased16((F32*)(combined_positions + combined_positions_shift), (F32*)face.mPositions, copy_bytes); @@ -1327,6 +1331,9 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Normals LLVector4a::memcpyNonAliased16((F32*)(combined_normals + combined_positions_shift), (F32*)face.mNormals, copy_bytes); + // Tangents + LLVector4a::memcpyNonAliased16((F32*)(combined_tangents + combined_positions_shift), (F32*)face.mMikktSpaceTangents, copy_bytes); + // Tex coords copy_bytes = face.mNumVertices * sizeof(LLVector2); memcpy((void*)(combined_tex_coords + combined_positions_shift), (void*)face.mTexCoords, copy_bytes); @@ -1428,9 +1435,10 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // IV. Repack back into individual faces - LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 2 * size_vertices + tc_bytes_size); + LLVector4a* buffer_positions = (LLVector4a*)ll_aligned_malloc<64>(sizeof(LLVector4a) * 3 * size_vertices + tc_bytes_size); LLVector4a* buffer_normals = buffer_positions + size_vertices; - LLVector2* buffer_tex_coords = (LLVector2*)(buffer_normals + size_vertices); + LLVector4a* buffer_tangents = buffer_normals + size_vertices; + LLVector2* buffer_tex_coords = (LLVector2*)(buffer_tangents + size_vertices); S32 buffer_idx_size = (size_indices * sizeof(U16) + 0xF) & ~0xF; U16* buffer_indices = (U16*)ll_aligned_malloc_16(buffer_idx_size); S32* old_to_new_positions_map = new S32[size_vertices]; @@ -1511,6 +1519,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe // Copy vertice, normals, tcs buffer_positions[buf_positions_copied] = combined_positions[idx]; buffer_normals[buf_positions_copied] = combined_normals[idx]; + buffer_tangents[buf_positions_copied] = combined_tangents[idx]; buffer_tex_coords[buf_positions_copied] = combined_tex_coords[idx]; old_to_new_positions_map[idx] = buf_positions_copied; @@ -1549,12 +1558,13 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { new_face.resizeIndices(buf_indices_copied); new_face.resizeVertices(buf_positions_copied); - + new_face.allocateTangents(buf_positions_copied, true); S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size); LLVector4a::memcpyNonAliased16((F32*)new_face.mPositions, (F32*)buffer_positions, buf_positions_copied * sizeof(LLVector4a)); LLVector4a::memcpyNonAliased16((F32*)new_face.mNormals, (F32*)buffer_normals, buf_positions_copied * sizeof(LLVector4a)); + LLVector4a::memcpyNonAliased16((F32*)new_face.mMikktSpaceTangents, (F32*)buffer_tangents, buf_positions_copied * sizeof(LLVector4a)); U32 tex_size = (buf_positions_copied * sizeof(LLVector2) + 0xF)&~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mTexCoords, (F32*)buffer_tex_coords, tex_size); -- cgit v1.3 From 82ab5f9765ad76c73d1d7ddd5716b22d6b92bf62 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 15 Sep 2022 17:23:34 -0500 Subject: SL-18156 WIP -- Add NormalizedScale/NormalizedTranslation to mesh assets to recover mesh's original coordinate frame when generating tangents post download. --- indra/llmath/llvolume.cpp | 78 +++++++++++++++++++++++++++------------- indra/llmath/llvolume.h | 6 ++++ indra/llprimitive/llmodel.cpp | 13 ++++++- indra/newview/llmodelpreview.cpp | 9 +++++ 4 files changed, 81 insertions(+), 25 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 563a325f03..ae753fc0f3 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2483,6 +2483,24 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) min_tc.setValue(mdl[i]["TexCoord0Domain"]["Min"]); max_tc.setValue(mdl[i]["TexCoord0Domain"]["Max"]); + //unpack normalized scale/translation + if (mdl[i].has("NormalizedScale")) + { + face.mNormalizedScale.setValue(mdl[i]["NormalizedScale"]); + } + else + { + face.mNormalizedScale.set(1, 1, 1); + } + if (mdl[i].has("NormalizedTranslation")) + { + face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]); + } + else + { + face.mNormalizedTranslation.set(1, 1, 1); + } + LLVector4a pos_range; pos_range.setSub(max_pos, min_pos); LLVector2 tc_range2 = max_tc - min_tc; @@ -2533,6 +2551,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } +#if 0 { if (!tangent.empty()) { @@ -2559,6 +2578,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } } +#endif { if (!tc.empty()) @@ -4888,7 +4908,9 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) } mOptimized = src.mOptimized; - + mNormalizedScale = src.mNormalizedScale; + mNormalizedTranslation = src.mNormalizedTranslation; + //delete return *this; } @@ -5432,12 +5454,19 @@ struct MikktData w.resize(count); } + + LLVector3 inv_scale(1.f / face->mNormalizedScale.mV[0], 1.f / face->mNormalizedScale.mV[1], 1.f / face->mNormalizedScale.mV[2]); + + for (int i = 0; i < face->mNumIndices; ++i) { U32 idx = face->mIndices[i]; p[i].set(face->mPositions[idx].getF32ptr()); + p[i].scaleVec(face->mNormalizedScale); //put mesh in original coordinate frame when reconstructing tangents n[i].set(face->mNormals[idx].getF32ptr()); + n[i].scaleVec(inv_scale); + n[i].normalize(); tc[i].set(face->mTexCoords[idx]); if (face->mWeights) @@ -5481,10 +5510,7 @@ bool LLVolumeFace::cacheOptimize() ms.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& vert = face->mPositions[idx]; - F32* v = vert.getF32ptr(); + F32* v = data->p[iFace * 3 + iVert].mV; fvPosOut[0] = v[0]; fvPosOut[1] = v[1]; fvPosOut[2] = v[2]; @@ -5493,10 +5519,7 @@ bool LLVolumeFace::cacheOptimize() ms.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& norm = face->mNormals[idx]; - F32* n = norm.getF32ptr(); + F32* n = data->n[iFace * 3 + iVert].mV; fvNormOut[0] = n[0]; fvNormOut[1] = n[1]; fvNormOut[2] = n[2]; @@ -5505,27 +5528,16 @@ bool LLVolumeFace::cacheOptimize() ms.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; - S32 idx = face->mIndices[iFace * 3 + iVert]; - auto& tc = face->mTexCoords[idx]; - fvTexcOut[0] = tc.mV[0]; - fvTexcOut[1] = tc.mV[1]; + F32* tc = data->tc[iFace * 3 + iVert].mV; + fvTexcOut[0] = tc[0]; + fvTexcOut[1] = tc[1]; }; ms.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, const int iVert) { MikktData* data = (MikktData*)pContext->m_pUserData; - LLVolumeFace* face = data->face; S32 i = iFace * 3 + iVert; - S32 idx = face->mIndices[i]; - - LLVector3 p(face->mPositions[idx].getF32ptr()); - LLVector3 n(face->mNormals[idx].getF32ptr()); - LLVector3 t(fvTangent); - - // assert that this tangent hasn't already been set - llassert(data->t[i].magVec() < 0.1f); - + data->t[i].set(fvTangent); data->t[i].mV[3] = fSign; }; @@ -5585,6 +5597,24 @@ bool LLVolumeFace::cacheOptimize() mWeights[dst_idx].loadua(data.w[src_idx].mV); } } + + + // put back in normalized coordinate frame + LLVector4a inv_scale(1.f/mNormalizedScale.mV[0], 1.f / mNormalizedScale.mV[1], 1.f / mNormalizedScale.mV[2]); + LLVector4a scale; + scale.load3(mNormalizedScale.mV); + scale.getF32ptr()[3] = 1.f; + + for (int i = 0; i < mNumVertices; ++i) + { + mPositions[i].mul(inv_scale); + mNormals[i].mul(scale); + mNormals[i].normalize3(); + F32 w = mMikktSpaceTangents[i].getF32ptr()[3]; + mMikktSpaceTangents[i].mul(scale); + mMikktSpaceTangents[i].normalize3(); + mMikktSpaceTangents[i].getF32ptr()[3] = w; + } } // cache optimize index buffer diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index f1feaade58..e373d0175d 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -984,6 +984,12 @@ public: //whether or not face has been cache optimized BOOL mOptimized; + // if this is a mesh asset, scale and translation that were applied + // when encoding the source mesh into a unit cube + // used for regenerating tangents + LLVector3 mNormalizedScale = LLVector3(1,1,1); + LLVector3 mNormalizedTranslation; + private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); BOOL createCap(LLVolume* volume, BOOL partial_build = FALSE); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 1ce287d773..ab507edc40 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -337,6 +337,12 @@ void LLModel::normalizeVolumeFaces() mNormalizedScale.set(normalized_scale.getF32ptr()); mNormalizedTranslation.set(trans.getF32ptr()); mNormalizedTranslation *= -1.f; + + for (auto& face : mVolumeFaces) + { + face.mNormalizedScale = mNormalizedScale; + face.mNormalizedTranslation = mNormalizedTranslation; + } } } @@ -749,7 +755,7 @@ LLSD LLModel::writeModel( U32 vert_idx = 0; U32 norm_idx = 0; - U32 tan_idx = 0; + //U32 tan_idx = 0; U32 tc_idx = 0; LLVector2* ftc = (LLVector2*) face.mTexCoords; @@ -803,6 +809,7 @@ LLSD LLModel::writeModel( } } +#if 0 if (face.mMikktSpaceTangents) { //normals F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); @@ -818,6 +825,7 @@ LLSD LLModel::writeModel( tangents[tan_idx++] = buff[1]; } } +#endif //texcoord if (face.mTexCoords) @@ -848,6 +856,9 @@ LLSD LLModel::writeModel( //write out face data mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); + mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); + mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue(); + mdl[model_names[idx]][i]["Position"] = verts; if (face.mNormals) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 2c0f0ae443..4a85d459c5 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1843,6 +1843,15 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d LLModel* target_model = mModel[lod][mdl_idx]; + // carry over normalized transform into simplified model + for (int i = 0; i < base->getNumVolumeFaces(); ++i) + { + LLVolumeFace& src = base->getVolumeFace(i); + LLVolumeFace& dst = target_model->getVolumeFace(i); + dst.mNormalizedScale = src.mNormalizedScale; + dst.mNormalizedTranslation = src.mNormalizedTranslation; + } + S32 model_meshopt_mode = meshopt_mode; // Ideally this should run not per model, -- cgit v1.3 From 8dc59e5ef37836b15d478fb0d04e3043a9f986de Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 16 Sep 2022 16:25:26 -0500 Subject: SL-18128 Clear out much OpenGL cruft and switch to core profile on AMD --- indra/llmath/llvolume.cpp | 15 +- indra/llmath/llvolume.h | 11 +- indra/llprimitive/lldaeloader.cpp | 11 +- indra/llprimitive/llmodel.cpp | 9 - indra/llprimitive/llmodel.h | 1 - indra/llrender/llcubemap.cpp | 6 +- indra/llrender/llgl.cpp | 440 ++------------------- indra/llrender/llgl.h | 63 +-- indra/llrender/llglheaders.h | 277 ------------- indra/llrender/llimagegl.cpp | 110 ++---- indra/llrender/llimagegl.h | 2 +- indra/llrender/llrender.cpp | 50 +-- indra/llrender/llrender.h | 2 - indra/llrender/llrendertarget.cpp | 20 +- indra/llrender/llvertexbuffer.cpp | 200 +++------- indra/newview/app_settings/settings.xml | 12 - indra/newview/featuretable.txt | 7 +- indra/newview/lldrawpoolterrain.cpp | 17 - indra/newview/lldrawpoolwater.cpp | 8 +- indra/newview/lldynamictexture.cpp | 4 +- indra/newview/llface.cpp | 200 +--------- indra/newview/llface.h | 2 - indra/newview/llfeaturemanager.cpp | 38 +- indra/newview/llfloaterpreference.cpp | 11 +- indra/newview/llglsandbox.cpp | 22 +- indra/newview/llscenemonitor.cpp | 8 +- indra/newview/llviewercontrol.cpp | 2 +- indra/newview/llviewermenu.cpp | 40 -- indra/newview/llvieweroctree.cpp | 27 +- indra/newview/llviewershadermgr.cpp | 176 +-------- indra/newview/llviewershadermgr.h | 11 - indra/newview/llviewerwindow.cpp | 33 -- indra/newview/llvosky.cpp | 4 +- indra/newview/llvovolume.cpp | 32 +- indra/newview/pipeline.cpp | 19 +- indra/newview/skins/default/xui/en/menu_viewer.xml | 2 - 36 files changed, 221 insertions(+), 1671 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index ae753fc0f3..559d790d77 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2783,7 +2783,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } - if (!cacheOptimize()) + if (!cacheOptimize(true)) { // Out of memory? LL_WARNS() << "Failed to optimize!" << LL_ENDL; @@ -2824,11 +2824,11 @@ void LLVolume::copyVolumeFaces(const LLVolume* volume) mSculptLevel = 0; } -bool LLVolume::cacheOptimize() +bool LLVolume::cacheOptimize(bool gen_tangents) { for (S32 i = 0; i < mVolumeFaces.size(); ++i) { - if (!mVolumeFaces[i].cacheOptimize()) + if (!mVolumeFaces[i].cacheOptimize(gen_tangents)) { return false; } @@ -5478,18 +5478,13 @@ struct MikktData }; -bool LLVolumeFace::cacheOptimize() +bool LLVolumeFace::cacheOptimize(bool gen_tangents) { //optimize for vertex cache according to Forsyth method: LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; llassert(!mOptimized); mOptimized = TRUE; - if (!mNormals || !mTexCoords) - { // can't perform this operation without normals and texture coordinates - return false; - } - - if (mMikktSpaceTangents == nullptr) + if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords) { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change allocateTangents(mNumVertices, true); diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index e373d0175d..6ea12c6920 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -907,7 +907,7 @@ public: void remap(); void optimize(F32 angle_cutoff = 2.f); - bool cacheOptimize(); + bool cacheOptimize(bool gen_tangents = false); void createOctree(F32 scaler = 0.25f, const LLVector4a& center = LLVector4a(0,0,0), const LLVector4a& size = LLVector4a(0.5f,0.5f,0.5f)); @@ -957,10 +957,6 @@ public: // indexes for mPositions/mNormals/mTexCoords U16* mIndices; - // vertex buffer filled in by LLFace to cache this volume face geometry in vram - // (declared as a LLPointer to LLRefCount to avoid dependency on LLVertexBuffer) - mutable LLPointer mVertexBuffer; - std::vector mEdge; //list of skin weights for rigged volumes @@ -1089,7 +1085,10 @@ public: void copyVolumeFaces(const LLVolume* volume); void copyFacesTo(std::vector &faces) const; void copyFacesFrom(const std::vector &faces); - bool cacheOptimize(); + + // use meshoptimizer to optimize index buffer for vertex shader cache + // gen_tangents - if true, generate MikkTSpace tangents if needed before optimizing index buffer + bool cacheOptimize(bool gen_tangents = false); private: void sculptGenerateMapVertices(U16 sculpt_width, U16 sculpt_height, S8 sculpt_components, const U8* sculpt_data, U8 sculpt_type); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 9470146ce4..dbb34ab60b 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2551,9 +2551,6 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo LLVolume::face_list_t remainder; do { - // generate tangents and cache optimize before normalizing - ret->preprocessVolumeFaces(); - // Insure we do this once with the whole gang and not per-model // if (!normalized && !mNoNormalize) @@ -2565,10 +2562,10 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo ret->trimVolumeFacesToSize(LL_SCULPT_MESH_MAX_FACES, &remainder); // remove unused/redundant vertices after normalizing - //if (!mNoOptimize) - //{ - // ret->remapVolumeFaces(); - //} + if (!mNoOptimize) + { + ret->remapVolumeFaces(); + } volume_faces = remainder.size(); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index ab507edc40..eff47d9d98 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -187,15 +187,6 @@ void LLModel::trimVolumeFacesToSize(U32 new_count, LLVolume::face_list_t* remain } } -// generate mikkt space tangents and cache optimize -void LLModel::preprocessVolumeFaces() -{ - for (auto& face : mVolumeFaces) - { - face.cacheOptimize(); - } -} - // Shrink the model to fit // on a 1x1x1 cube centered at the origin. // The positions and extents diff --git a/indra/llprimitive/llmodel.h b/indra/llprimitive/llmodel.h index ea97851ce8..354ceb26b7 100644 --- a/indra/llprimitive/llmodel.h +++ b/indra/llprimitive/llmodel.h @@ -182,7 +182,6 @@ public: void addFace(const LLVolumeFace& face); void sortVolumeFacesByMaterialName(); - void preprocessVolumeFaces(); void normalizeVolumeFaces(); void trimVolumeFacesToSize(U32 new_count = LL_SCULPT_MESH_MAX_FACES, LLVolume::face_list_t* remainder = NULL); void remapVolumeFaces(); diff --git a/indra/llrender/llcubemap.cpp b/indra/llrender/llcubemap.cpp index e41765622f..254288a86e 100644 --- a/indra/llrender/llcubemap.cpp +++ b/indra/llrender/llcubemap.cpp @@ -67,7 +67,7 @@ void LLCubeMap::initGL() { llassert(gGLManager.mInited); - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { // Not initialized, do stuff. if (mImages[0].isNull()) @@ -252,7 +252,7 @@ void LLCubeMap::enable(S32 stage) void LLCubeMap::enableTexture(S32 stage) { mTextureStage = stage; - if (gGLManager.mHasCubeMap && stage >= 0 && LLCubeMap::sUseCubeMaps) + if (stage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(stage)->enable(LLTexUnit::TT_CUBE_MAP); } @@ -265,7 +265,7 @@ void LLCubeMap::disable(void) void LLCubeMap::disableTexture(void) { - if (gGLManager.mHasCubeMap && mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) + if (mTextureStage >= 0 && LLCubeMap::sUseCubeMaps) { gGL.getTexUnit(mTextureStage)->disable(); if (mTextureStage == 0) diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 5253ed3d51..71303b0517 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -86,15 +86,15 @@ void APIENTRY gl_debug_callback(GLenum source, const GLchar* message, GLvoid* userParam) { - /*if (severity != GL_DEBUG_SEVERITY_HIGH_ARB // && - severity != GL_DEBUG_SEVERITY_MEDIUM_ARB && - severity != GL_DEBUG_SEVERITY_LOW_ARB + /*if (severity != GL_DEBUG_SEVERITY_HIGH // && + severity != GL_DEBUG_SEVERITY_MEDIUM && + severity != GL_DEBUG_SEVERITY_LOW ) { //suppress out-of-spec messages sent by nvidia driver (mostly vertexbuffer hints) return; }*/ - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_WARNS() << "----- GL ERROR --------" << LL_ENDL; } @@ -107,7 +107,15 @@ void APIENTRY gl_debug_callback(GLenum source, LL_WARNS() << "Severity: " << std::hex << severity << LL_ENDL; LL_WARNS() << "Message: " << message << LL_ENDL; LL_WARNS() << "-----------------------" << LL_ENDL; - if (severity == GL_DEBUG_SEVERITY_HIGH_ARB) + + GLint vao = 0; + glGetIntegerv(GL_VERTEX_ARRAY_BINDING, &vao); + GLint vbo = 0; + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &vbo); + GLint ibo = 0; + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &ibo); + + if (severity == GL_DEBUG_SEVERITY_HIGH) { LL_ERRS() << "Halting on GL Error" << LL_ENDL; } @@ -931,44 +939,12 @@ LLGLManager gGLManager; LLGLManager::LLGLManager() : mInited(FALSE), mIsDisabled(FALSE), - - mHasMultitexture(FALSE), - mHasATIMemInfo(FALSE), - mHasAMDAssociations(FALSE), - mHasNVXMemInfo(FALSE), - mNumTextureUnits(1), - mHasMipMapGeneration(FALSE), - mHasCompressedTextures(FALSE), - mHasFramebufferObject(FALSE), mMaxSamples(0), - mHasBlendFuncSeparate(FALSE), - mHasSync(FALSE), - mHasVertexBufferObject(FALSE), - mHasVertexArrayObject(FALSE), - mHasMapBufferRange(FALSE), - mHasFlushBufferRange(FALSE), - mHasPBuffer(FALSE), - mNumTextureImageUnits(0), - mHasOcclusionQuery(FALSE), - mHasTimerQuery(FALSE), - mHasOcclusionQuery2(FALSE), - mHasPointParameters(FALSE), - mHasDrawBuffers(FALSE), - mHasTextureRectangle(FALSE), - mHasTextureMultisample(FALSE), - mHasTransformFeedback(FALSE), - mHasUniformBufferObject(FALSE), + mNumTextureImageUnits(1), mMaxSampleMaskWords(0), mMaxColorTextureSamples(0), mMaxDepthTextureSamples(0), mMaxIntegerSamples(0), - - mHasAnisotropic(FALSE), - mHasARBEnvCombine(FALSE), - mHasCubeMap(FALSE), - mHasCubeMapArray(FALSE), - mHasDebugOutput(FALSE), - mIsAMD(FALSE), mIsNVIDIA(FALSE), mIsIntel(FALSE), @@ -976,9 +952,6 @@ LLGLManager::LLGLManager() : mIsMobileGF(FALSE), #endif mHasRequirements(TRUE), - - mHasSeparateSpecularColor(FALSE), - mDriverVersionMajor(1), mDriverVersionMinor(0), mDriverVersionRelease(0), @@ -996,7 +969,6 @@ LLGLManager::LLGLManager() : //--------------------------------------------------------------------- void LLGLManager::initWGL() { - mHasPBuffer = FALSE; #if LL_WINDOWS && !LL_MESA_HEADLESS if (!glh_init_extensions("WGL_ARB_pixel_format")) { @@ -1035,10 +1007,6 @@ void LLGLManager::initWGL() { LL_WARNS("RenderInit") << "No ARB WGL render texture extensions" << LL_ENDL; } - - mHasPBuffer = ExtensionExists("WGL_ARB_pbuffer", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_render_texture", gGLHExts.mSysExts) && - ExtensionExists("WGL_ARB_pixel_format", gGLHExts.mSysExts); #endif } @@ -1052,7 +1020,7 @@ bool LLGLManager::initGL() stop_glerror(); -#if LL_WINDOWS +#if 0 && LL_WINDOWS if (!glGetStringi) { glGetStringi = (PFNGLGETSTRINGIPROC) GLH_EXT_GET_PROC_ADDRESS("glGetStringi"); @@ -1199,23 +1167,6 @@ bool LLGLManager::initGL() } #endif - if (mHasATIMemInfo && mVRAM == 0) - { //ask the gl how much vram is free at startup and attempt to use no more than half of that - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - mVRAM = meminfo[0] / 1024; - LL_WARNS("RenderInit") << "VRAM Detected (ATIMemInfo):" << mVRAM << LL_ENDL; - } - - if (mHasNVXMemInfo && mVRAM == 0) - { - S32 dedicated_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_DEDICATED_VIDMEM_NVX, &dedicated_memory); - mVRAM = dedicated_memory/1024; - LL_WARNS("RenderInit") << "VRAM Detected (NVXMemInfo):" << mVRAM << LL_ENDL; - } - #if LL_WINDOWS if (mVRAM < 256) { @@ -1243,62 +1194,22 @@ bool LLGLManager::initGL() stop_glerror(); - GLint num_tex_image_units; - glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS_ARB, &num_tex_image_units); - mNumTextureImageUnits = llmin(num_tex_image_units, 32); - - if (mHasMultitexture) + glGetIntegerv(GL_MAX_TEXTURE_IMAGE_UNITS, &mNumTextureImageUnits); + stop_glerror(); + glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); + stop_glerror(); + glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); + stop_glerror(); + if (mGLVersion >= 4.59f) { - if (LLRender::sGLCoreProfile) - { - mNumTextureUnits = llmin(mNumTextureImageUnits, MAX_GL_TEXTURE_UNITS); - } - else - { - GLint num_tex_units; - glGetIntegerv(GL_MAX_TEXTURE_UNITS_ARB, &num_tex_units); - mNumTextureUnits = llmin(num_tex_units, (GLint)MAX_GL_TEXTURE_UNITS); - if (mIsIntel) - { - mNumTextureUnits = llmin(mNumTextureUnits, 2); - } - } + glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY, &mMaxAnisotropy); } - else - { - mHasRequirements = FALSE; - - // We don't support cards that don't support the GL_ARB_multitexture extension - LL_WARNS("RenderInit") << "GL Drivers do not support GL_ARB_multitexture" << LL_ENDL; - return false; - } - - stop_glerror(); - - if (mHasTextureMultisample) - { - glGetIntegerv(GL_MAX_COLOR_TEXTURE_SAMPLES, &mMaxColorTextureSamples); - glGetIntegerv(GL_MAX_DEPTH_TEXTURE_SAMPLES, &mMaxDepthTextureSamples); - glGetIntegerv(GL_MAX_INTEGER_SAMPLES, &mMaxIntegerSamples); - glGetIntegerv(GL_MAX_SAMPLE_MASK_WORDS, &mMaxSampleMaskWords); - } - - stop_glerror(); - - //HACK always disable texture multisample, use FXAA instead - mHasTextureMultisample = FALSE; -#if LL_WINDOWS - if (mIsIntel && mGLVersion <= 3.f) - { //never try to use framebuffer objects on older intel drivers (crashy) - mHasFramebufferObject = FALSE; - } -#endif - - if (mHasFramebufferObject) - { - glGetIntegerv(GL_MAX_SAMPLES, &mMaxSamples); - } - stop_glerror(); initGLStates(); @@ -1406,62 +1317,22 @@ void LLGLManager::asLLSD(LLSD& info) info["vram"] = mVRAM; - // Extensions used by everyone - info["has_multitexture"] = mHasMultitexture; - info["has_ati_mem_info"] = mHasATIMemInfo; - info["has_nvx_mem_info"] = mHasNVXMemInfo; - info["num_texture_units"] = mNumTextureUnits; - info["has_mip_map_generation"] = mHasMipMapGeneration; - info["has_compressed_textures"] = mHasCompressedTextures; - info["has_framebuffer_object"] = mHasFramebufferObject; + // OpenGL limits info["max_samples"] = mMaxSamples; - info["has_blend_func_separate"] = mHasBlendFuncSeparate || LLRender::sGLCoreProfile; - - // ARB Extensions - info["has_vertex_buffer_object"] = mHasVertexBufferObject; - info["has_vertex_array_object"] = mHasVertexArrayObject; - info["has_sync"] = mHasSync; - info["has_map_buffer_range"] = mHasMapBufferRange; - info["has_flush_buffer_range"] = mHasFlushBufferRange; - info["has_pbuffer"] = mHasPBuffer; - info["has_shader_objects"] = std::string("Assumed TRUE"); // was mHasShaderObjects; - info["has_vertex_shader"] = std::string("Assumed TRUE"); // was mHasVertexShader; - info["has_fragment_shader"] = std::string("Assumed TRUE"); // was mHasFragmentShader; info["num_texture_image_units"] = mNumTextureImageUnits; - info["has_occlusion_query"] = mHasOcclusionQuery; - info["has_timer_query"] = mHasTimerQuery; - info["has_occlusion_query2"] = mHasOcclusionQuery2; - info["has_point_parameters"] = mHasPointParameters; - info["has_draw_buffers"] = mHasDrawBuffers; - info["has_depth_clamp"] = mHasDepthClamp; - info["has_texture_rectangle"] = mHasTextureRectangle; - info["has_texture_multisample"] = mHasTextureMultisample; - info["has_transform_feedback"] = mHasTransformFeedback; info["max_sample_mask_words"] = mMaxSampleMaskWords; info["max_color_texture_samples"] = mMaxColorTextureSamples; info["max_depth_texture_samples"] = mMaxDepthTextureSamples; info["max_integer_samples"] = mMaxIntegerSamples; + info["max_vertex_range"] = mGLMaxVertexRange; + info["max_index_range"] = mGLMaxIndexRange; + info["max_texture_size"] = mGLMaxTextureSize; - // Other extensions. - info["has_anisotropic"] = mHasAnisotropic; - info["has_arb_env_combine"] = mHasARBEnvCombine; - info["has_cube_map"] = mHasCubeMap; - info["has_debug_output"] = mHasDebugOutput; - info["has_srgb_texture"] = mHassRGBTexture; - info["has_srgb_framebuffer"] = mHassRGBFramebuffer; - info["has_texture_srgb_decode"] = mHasTexturesRGBDecode; - - // Vendor-specific extensions + // Which vendor info["is_ati"] = mIsAMD; // note, do not rename is_ati to is_amd without coordinating with DW info["is_nvidia"] = mIsNVIDIA; info["is_intel"] = mIsIntel; - // Other fields - info["has_requirements"] = mHasRequirements; - info["has_separate_specular_color"] = mHasSeparateSpecularColor; - info["max_vertex_range"] = mGLMaxVertexRange; - info["max_index_range"] = mGLMaxIndexRange; - info["max_texture_size"] = mGLMaxTextureSize; info["gl_renderer"] = mGLRenderer; } @@ -1480,60 +1351,6 @@ void LLGLManager::shutdownGL() void LLGLManager::initExtensions() { -#if LL_MESA_HEADLESS -# ifdef GL_ARB_multitexture - mHasMultitexture = TRUE; -# else - mHasMultitexture = FALSE; -# endif // GL_ARB_multitexture -# ifdef GL_ARB_texture_env_combine - mHasARBEnvCombine = TRUE; -# else - mHasARBEnvCombine = FALSE; -# endif // GL_ARB_texture_env_combine -# ifdef GL_ARB_texture_compression - mHasCompressedTextures = TRUE; -# else - mHasCompressedTextures = FALSE; -# endif // GL_ARB_texture_compression -# ifdef GL_ARB_vertex_buffer_object - mHasVertexBufferObject = TRUE; -# else - mHasVertexBufferObject = FALSE; -# endif // GL_ARB_vertex_buffer_object -# ifdef GL_EXT_framebuffer_object - mHasFramebufferObject = TRUE; -# else - mHasFramebufferObject = FALSE; -# endif // GL_EXT_framebuffer_object -# ifdef GL_ARB_draw_buffers - mHasDrawBuffers = TRUE; -#else - mHasDrawBuffers = FALSE; -# endif // GL_ARB_draw_buffers -# if defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) - mHasDepthClamp = TRUE; -#else - mHasDepthClamp = FALSE; -#endif // defined(GL_NV_depth_clamp) || defined(GL_ARB_depth_clamp) -# if GL_EXT_blend_func_separate - mHasBlendFuncSeparate = TRUE; -#else - mHasBlendFuncSeparate = FALSE; -# endif // GL_EXT_blend_func_separate - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - mHasTextureRectangle = FALSE; -#else // LL_MESA_HEADLESS //important, gGLHExts.mSysExts is uninitialized until after glh_init_extensions is called - - mHasMultitexture = TRUE; - mHasCubeMap = TRUE; - mHasCompressedTextures = TRUE; - #if LL_DARWIN GLint num_extensions = 0; std::string all_extensions{""}; @@ -1550,173 +1367,12 @@ void LLGLManager::initExtensions() } #endif - mHasSeparateSpecularColor = ExtensionExists("GL_EXT_separate_specular_color", gGLHExts.mSysExts); - mHasAnisotropic = ExtensionExists("GL_EXT_texture_filter_anisotropic", gGLHExts.mSysExts); - - // In core profile - mHasARBEnvCombine = TRUE; //ExtensionExists("GL_ARB_texture_env_combine", gGLHExts.mSysExts); - mHasTimerQuery = FALSE; //FIXME //ExtensionExists("GL_ARB_timer_query", gGLHExts.mSysExts); - mHasOcclusionQuery = TRUE; //ExtensionExists("GL_ARB_occlusion_query", gGLHExts.mSysExts); - mHasOcclusionQuery2 = TRUE; // ExtensionExists("GL_ARB_occlusion_query2", gGLHExts.mSysExts); - mHasVertexBufferObject = TRUE; //ExtensionExists("GL_ARB_vertex_buffer_object", gGLHExts.mSysExts); - mHasVertexArrayObject = TRUE; //ExtensionExists("GL_ARB_vertex_array_object", gGLHExts.mSysExts); - mHasMapBufferRange = TRUE; ExtensionExists("GL_ARB_map_buffer_range", gGLHExts.mSysExts); - mHasFlushBufferRange = ExtensionExists("GL_APPLE_flush_buffer_range", gGLHExts.mSysExts); // Apple has mHasMapBufferRange now - mHasSync = TRUE; //ExtensionExists("GL_ARB_sync", gGLHExts.mSysExts); - mHasFramebufferObject = TRUE; //ExtensionExists("GL_ARB_framebuffer_object", gGLHExts.mSysExts); - mHassRGBFramebuffer = TRUE; //ExtensionExists("GL_ARB_framebuffer_sRGB", gGLHExts.mSysExts); - mHasDrawBuffers = TRUE; //ExtensionExists("GL_ARB_draw_buffers", gGLHExts.mSysExts); - mHasTextureRectangle = TRUE; //ExtensionExists("GL_ARB_texture_rectangle", gGLHExts.mSysExts); - mHasTextureMultisample = TRUE; //ExtensionExists("GL_ARB_texture_multisample", gGLHExts.mSysExts); - mHasUniformBufferObject = TRUE; //ExtensionExists("GL_ARB_uniform_buffer_object", gGLHExts.mSysExts); - mHasCubeMapArray = TRUE; //ExtensionExists("GL_ARB_texture_cube_map_array", gGLHExts.mSysExts); - mHasPointParameters = TRUE; //ExtensionExists("GL_ARB_point_parameters", gGLHExts.mSysExts); - - mHasATIMemInfo = ExtensionExists("GL_ATI_meminfo", gGLHExts.mSysExts); //Basic AMD method, also see mHasAMDAssociations - mHasNVXMemInfo = ExtensionExists("GL_NVX_gpu_memory_info", gGLHExts.mSysExts); - // NOTE: Using extensions breaks reflections when Shadows are set to projector. See: SL-16727 - //mHasDepthClamp = ExtensionExists("GL_ARB_depth_clamp", gGLHExts.mSysExts) || ExtensionExists("GL_NV_depth_clamp", gGLHExts.mSysExts); - mHasDepthClamp = FALSE; - // mask out FBO support when packed_depth_stencil isn't there 'cause we need it for LLRenderTarget -Brad - -#ifdef GL_EXT_texture_sRGB - mHassRGBTexture = ExtensionExists("GL_EXT_texture_sRGB", gGLHExts.mSysExts); -#endif - - -#ifdef GL_EXT_texture_sRGB_decode - mHasTexturesRGBDecode = ExtensionExists("GL_EXT_texture_sRGB_decode", gGLHExts.mSysExts); -#else - mHasTexturesRGBDecode = ExtensionExists("GL_ARB_texture_sRGB_decode", gGLHExts.mSysExts); -#endif - - mHasMipMapGeneration = mHasFramebufferObject || mGLVersion >= 1.4f; + // OpenGL 4.x capabilities + mHasCubeMapArray = mGLVersion >= 3.99f; + mHasTransformFeedback = mGLVersion >= 3.99f; + mHasDebugOutput = mGLVersion >= 4.29f; - mHasBlendFuncSeparate = ExtensionExists("GL_EXT_blend_func_separate", gGLHExts.mSysExts); - mHasDebugOutput = mGLVersion >= 4.3f ? TRUE : FALSE; - mHasTransformFeedback = mGLVersion >= 4.f ? TRUE : FALSE; -#endif - -#if LL_LINUX - LL_INFOS() << "initExtensions() checking shell variables to adjust features..." << LL_ENDL; - // Our extension support for the Linux Client is very young with some - // potential driver gotchas, so offer a semi-secret way to turn it off. - if (getenv("LL_GL_NOEXT")) - { - //mHasMultitexture = FALSE; // NEEDED! - mHasDepthClamp = FALSE; - mHasARBEnvCombine = FALSE; - mHasCompressedTextures = FALSE; - mHasVertexBufferObject = FALSE; - mHasFramebufferObject = FALSE; - mHasDrawBuffers = FALSE; - mHasBlendFuncSeparate = FALSE; - mHasMipMapGeneration = FALSE; - mHasSeparateSpecularColor = FALSE; - mHasAnisotropic = FALSE; - mHasCubeMap = FALSE; - mHasOcclusionQuery = FALSE; - mHasPointParameters = FALSE; - LL_WARNS("RenderInit") << "GL extension support DISABLED via LL_GL_NOEXT" << LL_ENDL; - } - else if (getenv("LL_GL_BASICEXT")) /* Flawfinder: ignore */ - { - // This switch attempts to turn off all support for exotic - // extensions which I believe correspond to fatal driver - // bug reports. This should be the default until we get a - // proper blacklist/whitelist on Linux. - mHasMipMapGeneration = FALSE; - mHasAnisotropic = FALSE; - //mHasCubeMap = FALSE; // apparently fatal on Intel 915 & similar - //mHasOcclusionQuery = FALSE; // source of many ATI system hangs - mHasBlendFuncSeparate = FALSE; - LL_WARNS("RenderInit") << "GL extension support forced to SIMPLE level via LL_GL_BASICEXT" << LL_ENDL; - } - if (getenv("LL_GL_BLACKLIST")) /* Flawfinder: ignore */ - { - // This lets advanced troubleshooters disable specific - // GL extensions to isolate problems with their hardware. - // SL-28126 - const char *const blacklist = getenv("LL_GL_BLACKLIST"); /* Flawfinder: ignore */ - LL_WARNS("RenderInit") << "GL extension support partially disabled via LL_GL_BLACKLIST: " << blacklist << LL_ENDL; - if (strchr(blacklist,'a')) mHasARBEnvCombine = FALSE; - if (strchr(blacklist,'b')) mHasCompressedTextures = FALSE; - if (strchr(blacklist,'c')) mHasVertexBufferObject = FALSE; - if (strchr(blacklist,'d')) mHasMipMapGeneration = FALSE;//S -// if (strchr(blacklist,'f')) mHasNVVertexArrayRange = FALSE;//S -// if (strchr(blacklist,'g')) mHasNVFence = FALSE;//S - if (strchr(blacklist,'h')) mHasSeparateSpecularColor = FALSE; - if (strchr(blacklist,'i')) mHasAnisotropic = FALSE;//S - if (strchr(blacklist,'j')) mHasCubeMap = FALSE;//S -// if (strchr(blacklist,'k')) mHasATIVAO = FALSE;//S - if (strchr(blacklist,'l')) mHasOcclusionQuery = FALSE; - if (strchr(blacklist,'p')) mHasPointParameters = FALSE;//S - if (strchr(blacklist,'q')) mHasFramebufferObject = FALSE;//S - if (strchr(blacklist,'r')) mHasDrawBuffers = FALSE;//S - if (strchr(blacklist,'s')) mHasTextureRectangle = FALSE; - if (strchr(blacklist,'t')) mHasBlendFuncSeparate = FALSE;//S - if (strchr(blacklist,'u')) mHasDepthClamp = FALSE; - - } -#endif // LL_LINUX - - if (!mHasMultitexture) - { - LL_INFOS("RenderInit") << "Couldn't initialize multitexturing" << LL_ENDL; - } - if (!mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Couldn't initialize mipmap generation" << LL_ENDL; - } - if (!mHasARBEnvCombine) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_env_combine" << LL_ENDL; - } - if (!mHasSeparateSpecularColor) - { - LL_INFOS("RenderInit") << "Couldn't initialize separate specular color" << LL_ENDL; - } - if (!mHasAnisotropic) - { - LL_INFOS("RenderInit") << "Couldn't initialize anisotropic filtering" << LL_ENDL; - } - if (!mHasCompressedTextures) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_compression" << LL_ENDL; - } - if (!mHasOcclusionQuery) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query" << LL_ENDL; - } - if (!mHasOcclusionQuery2) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_occlusion_query2" << LL_ENDL; - } - if (!mHasPointParameters) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_point_parameters" << LL_ENDL; - } - if (!mHasBlendFuncSeparate && !LLRender::sGLCoreProfile) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_EXT_blend_func_separate" << LL_ENDL; - } - if (!mHasDrawBuffers) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_draw_buffers" << LL_ENDL; - } - if (!mHasCubeMapArray) - { - LL_INFOS("RenderInit") << "Couldn't initialize GL_ARB_texture_cube_map_array" << LL_ENDL; - } - - // Disable certain things due to known bugs - if (mIsIntel && mHasMipMapGeneration) - { - LL_INFOS("RenderInit") << "Disabling mip-map generation for Intel GPUs" << LL_ENDL; - mHasMipMapGeneration = FALSE; - } - - // Misc + // Misc glGetIntegerv(GL_MAX_ELEMENTS_VERTICES, (GLint*) &mGLMaxVertexRange); glGetIntegerv(GL_MAX_ELEMENTS_INDICES, (GLint*) &mGLMaxIndexRange); glGetIntegerv(GL_MAX_TEXTURE_SIZE, (GLint*) &mGLMaxTextureSize); @@ -2795,7 +2451,7 @@ void LLGLState::checkTextureChannels(const std::string& msg) glh::matrix4f identity; identity.identity(); - for (GLint i = 1; i < gGLManager.mNumTextureUnits; i++) + for (GLint i = 1; i < gGLManager.mNumTextureImageUnits; i++) { gGL.getTexUnit(i)->activate(); @@ -2833,12 +2489,6 @@ void LLGLState::checkTextureChannels(const std::string& msg) for (S32 j = (i == 0 ? 1 : 0); j < 9; j++) { - if (j == 8 && !gGLManager.mHasTextureRectangle || - j == 9 && !gGLManager.mHasTextureMultisample) - { - continue; - } - if (glIsEnabled(value[j])) { error = TRUE; @@ -3329,36 +2979,29 @@ LLGLSquashToFarClip::~LLGLSquashToFarClip() LLGLSyncFence::LLGLSyncFence() { -#ifdef GL_ARB_sync mSync = 0; -#endif } LLGLSyncFence::~LLGLSyncFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } -#endif } void LLGLSyncFence::placeFence() { -#ifdef GL_ARB_sync if (mSync) { glDeleteSync(mSync); } mSync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); -#endif } bool LLGLSyncFence::isCompleted() { bool ret = true; -#ifdef GL_ARB_sync if (mSync) { GLenum status = glClientWaitSync(mSync, 0, 1); @@ -3367,13 +3010,11 @@ bool LLGLSyncFence::isCompleted() ret = false; } } -#endif return ret; } void LLGLSyncFence::wait() { -#ifdef GL_ARB_sync if (mSync) { while (glClientWaitSync(mSync, 0, FENCE_WAIT_TIME_NANOSECONDS) == GL_TIMEOUT_EXPIRED) @@ -3382,7 +3023,6 @@ void LLGLSyncFence::wait() waits++; } } -#endif } LLGLSPipelineSkyBox::LLGLSPipelineSkyBox() diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index 3c40f85654..e3c07604aa 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -76,52 +76,27 @@ public: BOOL mInited; BOOL mIsDisabled; - // Extensions used by everyone - BOOL mHasMultitexture; - BOOL mHasATIMemInfo; - BOOL mHasAMDAssociations; - BOOL mHasNVXMemInfo; - S32 mNumTextureUnits; - BOOL mHasMipMapGeneration; - BOOL mHasCompressedTextures; - BOOL mHasFramebufferObject; + // OpenGL limits S32 mMaxSamples; - BOOL mHasBlendFuncSeparate; - - // ARB Extensions - BOOL mHasVertexBufferObject; - BOOL mHasVertexArrayObject; - BOOL mHasSync; - BOOL mHasMapBufferRange; - BOOL mHasFlushBufferRange; - BOOL mHasPBuffer; - S32 mNumTextureImageUnits; - BOOL mHasOcclusionQuery; - BOOL mHasTimerQuery; - BOOL mHasOcclusionQuery2; - BOOL mHasPointParameters; - BOOL mHasDrawBuffers; - BOOL mHasDepthClamp; - BOOL mHasTextureRectangle; - BOOL mHasTextureMultisample; - BOOL mHasTransformFeedback; - BOOL mHasUniformBufferObject; + S32 mNumTextureImageUnits; S32 mMaxSampleMaskWords; S32 mMaxColorTextureSamples; S32 mMaxDepthTextureSamples; S32 mMaxIntegerSamples; - - // Other extensions. - BOOL mHasAnisotropic; - BOOL mHasARBEnvCombine; - BOOL mHasCubeMap; - BOOL mHasCubeMapArray; - BOOL mHasDebugOutput; - BOOL mHassRGBTexture; - BOOL mHassRGBFramebuffer; - BOOL mHasTexturesRGBDecode; - + S32 mGLMaxVertexRange; + S32 mGLMaxIndexRange; + S32 mGLMaxTextureSize; + F32 mMaxAnisotropy = 0.f; + + // GL 4.x capabilities + bool mHasCubeMapArray = false; + bool mHasDebugOutput = false; + bool mHasTransformFeedback = false; + bool mHasAnisotropic = false; + // Vendor-specific extensions + bool mHasAMDAssociations = false; + BOOL mIsAMD; BOOL mIsNVIDIA; BOOL mIsIntel; @@ -134,9 +109,6 @@ public: // Whether this version of GL is good enough for SL to use BOOL mHasRequirements; - // Misc extensions - BOOL mHasSeparateSpecularColor; - S32 mDriverVersionMajor; S32 mDriverVersionMinor; S32 mDriverVersionRelease; @@ -147,9 +119,6 @@ public: std::string mGLVersionString; S32 mVRAM; // VRAM in MB - S32 mGLMaxVertexRange; - S32 mGLMaxIndexRange; - S32 mGLMaxTextureSize; void getPixelFormat(); // Get the best pixel format @@ -415,9 +384,7 @@ public: class LLGLSyncFence : public LLGLFence { public: -#ifdef GL_ARB_sync GLsync mSync; -#endif LLGLSyncFence(); virtual ~LLGLSyncFence(); diff --git a/indra/llrender/llglheaders.h b/indra/llrender/llglheaders.h index f2b51fbafb..0aacf3bf0e 100644 --- a/indra/llrender/llglheaders.h +++ b/indra/llrender/llglheaders.h @@ -41,277 +41,6 @@ # include "GL/glh_extensions.h" # undef __APPLE__ -#elif LL_LINUX -//---------------------------------------------------------------------------- -// LL_LINUX - -//---------------------------------------------------------------------------- -// Linux, MESA headers, but not necessarily assuming MESA runtime. -// quotes so we get libraries/.../GL/ version -#include "GL/gl.h" -#include "GL/glext.h" -#include "GL/glu.h" - - -#if LL_LINUX && !LL_MESA_HEADLESS -// The __APPLE__ kludge is to make glh_extensions.h not symbol-clash horribly -# define __APPLE__ -# include "GL/glh_extensions.h" -# undef __APPLE__ - -/* Although SDL very likely ends up calling glXGetProcAddress() itself, - if we use SDL_GL_GetProcAddress() then we get bogus addresses back on - some systems. Weird. */ -/*# include "SDL/SDL.h" - # define GLH_EXT_GET_PROC_ADDRESS(p) SDL_GL_GetProcAddress(p) */ -#define GLX_GLXEXT_PROTOTYPES 1 -# include "GL/glx.h" -# include "GL/glxext.h" -// Use glXGetProcAddressARB instead of glXGetProcAddress - the ARB symbol -// is considered 'legacy' but works on more machines. -# define GLH_EXT_GET_PROC_ADDRESS(p) glXGetProcAddress((const GLubyte*)(p)) -#endif // LL_LINUX && !LL_MESA_HEADLESS - -#if LL_LINUX && defined(WINGDIAPI) -// WINGDIAPI gets set if we are using the linux nvidia gl.h header which needs -// the functions below setting up. -# define LL_LINUX_NV_GL_HEADERS 1 -#else -# define LL_LINUX_NV_GL_HEADERS 0 -#endif // LL_LINUX && defined(WINGDIAPI) - - -#if LL_LINUX_NV_GL_HEADERS -// Missing functions when using nvidia headers: -extern PFNGLACTIVETEXTUREPROC glActiveTexture; -extern PFNGLCLIENTACTIVETEXTUREPROC glClientActiveTexture; -extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -#endif // LL_LINUX_NV_GL_HEADERS - -// GL_ARB_vertex_array_object -extern PFNGLBINDVERTEXARRAYPROC glBindVertexArray; -extern PFNGLDELETEVERTEXARRAYSPROC glDeleteVertexArrays; -extern PFNGLGENVERTEXARRAYSPROC glGenVertexArrays; -extern PFNGLISVERTEXARRAYPROC glIsVertexArray; - -// GL_ARB_vertex_buffer_object -extern PFNGLBINDBUFFERPROC glBindBuffer; -extern PFNGLDELETEBUFFERSPROC glDeleteBuffers; -extern PFNGLGENBUFFERSPROC glGenBuffers; -extern PFNGLISBUFFERPROC glIsBuffer; -extern PFNGLBUFFERDATAPROC glBufferData; -extern PFNGLBUFFERSUBDATAPROC glBufferSubData; -extern PFNGLGETBUFFERSUBDATAPROC glGetBufferSubData; -extern PFNGLMAPBUFFERPROC glMapBuffer; -extern PFNGLUNMAPBUFFERPROC glUnmapBuffer; -extern PFNGLGETBUFFERPARAMETERIVPROC glGetBufferParameteriv; -extern PFNGLGETBUFFERPOINTERVPROC glGetBufferPointerv; - -// GL_ARB_sync -extern PFNGLFENCESYNCPROC glFenceSync; -extern PFNGLISSYNCPROC glIsSync; -extern PFNGLDELETESYNCPROC glDeleteSync; -extern PFNGLCLIENTWAITSYNCPROC glClientWaitSync; -extern PFNGLWAITSYNCPROC glWaitSync; -extern PFNGLGETINTEGER64VPROC glGetInteger64v; -extern PFNGLGETSYNCIVPROC glGetSynciv; - -// GL_APPLE_flush_buffer_range -extern PFNGLBUFFERPARAMETERIAPPLEPROC glBufferParameteriAPPLE; -extern PFNGLFLUSHMAPPEDBUFFERRANGEAPPLEPROC glFlushMappedBufferRangeAPPLE; - -// GL_ARB_map_buffer_range -extern PFNGLMAPBUFFERRANGEPROC glMapBufferRange; -extern PFNGLFLUSHMAPPEDBUFFERRANGEPROC glFlushMappedBufferRange; - -// GL_ATI_vertex_array_object -extern PFNGLNEWOBJECTBUFFERATIPROC glNewObjectBufferATI; -extern PFNGLISOBJECTBUFFERATIPROC glIsObjectBufferATI; -extern PFNGLUPDATEOBJECTBUFFERATIPROC glUpdateObjectBufferATI; -extern PFNGLGETOBJECTBUFFERFVATIPROC glGetObjectBufferfvATI; -extern PFNGLGETOBJECTBUFFERIVATIPROC glGetObjectBufferivATI; -extern PFNGLFREEOBJECTBUFFERATIPROC glFreeObjectBufferATI; -extern PFNGLARRAYOBJECTATIPROC glArrayObjectATI; -extern PFNGLVERTEXATTRIBARRAYOBJECTATIPROC glVertexAttribArrayObjectATI; -extern PFNGLGETARRAYOBJECTFVATIPROC glGetArrayObjectfvATI; -extern PFNGLGETARRAYOBJECTIVATIPROC glGetArrayObjectivATI; -extern PFNGLVARIANTARRAYOBJECTATIPROC glVariantObjectArrayATI; -extern PFNGLGETVARIANTARRAYOBJECTFVATIPROC glGetVariantArrayObjectfvATI; -extern PFNGLGETVARIANTARRAYOBJECTIVATIPROC glGetVariantArrayObjectivATI; - -// GL_ARB_occlusion_query -extern PFNGLGENQUERIESPROC glGenQueries; -extern PFNGLDELETEQUERIESPROC glDeleteQueries; -extern PFNGLISQUERYPROC glIsQuery; -extern PFNGLBEGINQUERYPROC glBeginQuery; -extern PFNGLENDQUERYPROC glEndQuery; -extern PFNGLGETQUERYIVPROC glGetQueryiv; -extern PFNGLGETQUERYOBJECTIVPROC glGetQueryObjectiv; -extern PFNGLGETQUERYOBJECTUIVPROC glGetQueryObjectuiv; - -// GL_ARB_timer_query -extern PFNGLQUERYCOUNTERPROC glQueryCounter; -extern PFNGLGETQUERYOBJECTI64VPROC glGetQueryObjecti64v; -extern PFNGLGETQUERYOBJECTUI64VPROC glGetQueryObjectui64v; - -// GL_ARB_point_parameters -extern PFNGLPOINTPARAMETERFPROC glPointParameterf; -extern PFNGLPOINTPARAMETERFVPROC glPointParameterfv; - -// GL_ARB_shader_objects -extern PFNGLDELETEOBJECTPROC glDeleteObject; -extern PFNGLGETHANDLEPROC glGetHandle; -extern PFNGLDETACHOBJECTPROC glDetachObject; -extern PFNGLCREATESHADEROBJECTPROC glCreateShaderObject; -extern PFNGLSHADERSOURCEPROC glShaderSource; -extern PFNGLCOMPILESHADERPROC glCompileShader; -extern PFNGLCREATEPROGRAMOBJECTPROC glCreateProgramObject; -extern PFNGLATTACHOBJECTPROC glAttachObject; -extern PFNGLLINKPROGRAMPROC glLinkProgram; -extern PFNGLUSEPROGRAMOBJECTPROC glUseProgramObject; -extern PFNGLVALIDATEPROGRAMPROC glValidateProgram; -extern PFNGLUNIFORM1FPROC glUniform1f; -extern PFNGLUNIFORM2FPROC glUniform2f; -extern PFNGLUNIFORM3FPROC glUniform3f; -extern PFNGLUNIFORM4FPROC glUniform4f; -extern PFNGLUNIFORM1IPROC glUniform1i; -extern PFNGLUNIFORM2IPROC glUniform2i; -extern PFNGLUNIFORM3IPROC glUniform3i; -extern PFNGLUNIFORM4IPROC glUniform4i; -extern PFNGLUNIFORM1FVPROC glUniform1fv; -extern PFNGLUNIFORM2FVPROC glUniform2fv; -extern PFNGLUNIFORM3FVPROC glUniform3fv; -extern PFNGLUNIFORM4FVPROC glUniform4fv; -extern PFNGLUNIFORM1IVPROC glUniform1iv; -extern PFNGLUNIFORM2IVPROC glUniform2iv; -extern PFNGLUNIFORM3IVPROC glUniform3iv; -extern PFNGLUNIFORM4IVPROC glUniform4iv; -extern PFNGLUNIFORMMATRIX2FVPROC glUniformMatrix2fv; -extern PFNGLUNIFORMMATRIX3FVPROC glUniformMatrix3fv; -extern PFNGLUNIFORMMATRIX3X4FVPROC glUniformMatrix3x4fv; -extern PFNGLUNIFORMMATRIX4FVPROC glUniformMatrix4fv; -extern PFNGLGETOBJECTPARAMETERFVPROC glGetObjectParameterfv; -extern PFNGLGETOBJECTPARAMETERIVPROC glGetObjectParameteriv; -extern PFNGLGETINFOLOGPROC glGetInfoLog; -extern PFNGLGETATTACHEDOBJECTSPROC glGetAttachedObjects; -extern PFNGLGETUNIFORMLOCATIONPROC glGetUniformLocation; -extern PFNGLGETACTIVEUNIFORMPROC glGetActiveUniform; -extern PFNGLGETUNIFORMFVPROC glGetUniformfv; -extern PFNGLGETUNIFORMIVPROC glGetUniformiv; -extern PFNGLGETSHADERSOURCEPROC glGetShaderSource; - -// GL_ARB_vertex_shader -extern PFNGLVERTEXATTRIB1DPROC glVertexAttrib1d; -extern PFNGLVERTEXATTRIB1DVPROC glVertexAttrib1dv; -extern PFNGLVERTEXATTRIB1FPROC glVertexAttrib1f; -extern PFNGLVERTEXATTRIB1FVPROC glVertexAttrib1fv; -extern PFNGLVERTEXATTRIB1SPROC glVertexAttrib1s; -extern PFNGLVERTEXATTRIB1SVPROC glVertexAttrib1sv; -extern PFNGLVERTEXATTRIB2DPROC glVertexAttrib2d; -extern PFNGLVERTEXATTRIB2DVPROC glVertexAttrib2dv; -extern PFNGLVERTEXATTRIB2FPROC glVertexAttrib2f; -extern PFNGLVERTEXATTRIB2FVPROC glVertexAttrib2fv; -extern PFNGLVERTEXATTRIB2SPROC glVertexAttrib2s; -extern PFNGLVERTEXATTRIB2SVPROC glVertexAttrib2sv; -extern PFNGLVERTEXATTRIB3DPROC glVertexAttrib3d; -extern PFNGLVERTEXATTRIB3DVPROC glVertexAttrib3dv; -extern PFNGLVERTEXATTRIB3FPROC glVertexAttrib3f; -extern PFNGLVERTEXATTRIB3FVPROC glVertexAttrib3fv; -extern PFNGLVERTEXATTRIB3SPROC glVertexAttrib3s; -extern PFNGLVERTEXATTRIB3SVPROC glVertexAttrib3sv; -extern PFNGLVERTEXATTRIB4NBVPROC glVertexAttrib4nbv; -extern PFNGLVERTEXATTRIB4NIVPROC glVertexAttrib4niv; -extern PFNGLVERTEXATTRIB4NSVPROC glVertexAttrib4nsv; -extern PFNGLVERTEXATTRIB4NUBPROC glVertexAttrib4nub; -extern PFNGLVERTEXATTRIB4NUBVPROC glVertexAttrib4nubv; -extern PFNGLVERTEXATTRIB4NUIVPROC glVertexAttrib4nuiv; -extern PFNGLVERTEXATTRIB4NUSVPROC glVertexAttrib4nusv; -extern PFNGLVERTEXATTRIB4BVPROC glVertexAttrib4bv; -extern PFNGLVERTEXATTRIB4DPROC glVertexAttrib4d; -extern PFNGLVERTEXATTRIB4DVPROC glVertexAttrib4dv; -extern PFNGLVERTEXATTRIB4FPROC glVertexAttrib4f; -extern PFNGLVERTEXATTRIB4FVPROC glVertexAttrib4fv; -extern PFNGLVERTEXATTRIB4IVPROC glVertexAttrib4iv; -extern PFNGLVERTEXATTRIB4SPROC glVertexAttrib4s; -extern PFNGLVERTEXATTRIB4SVPROC glVertexAttrib4sv; -extern PFNGLVERTEXATTRIB4UBVPROC glVertexAttrib4ubv; -extern PFNGLVERTEXATTRIB4UIVPROC glVertexAttrib4uiv; -extern PFNGLVERTEXATTRIB4USVPROC glVertexAttrib4usv; -extern PFNGLVERTEXATTRIBPOINTERPROC glVertexAttribPointer; -extern PFNGLVERTEXATTRIBIPOINTERPROC glVertexAttribIPointer; -extern PFNGLENABLEVERTEXATTRIBARRAYPROC glEnableVertexAttribArray; -extern PFNGLDISABLEVERTEXATTRIBARRAYPROC glDisableVertexAttribArray; -extern PFNGLPROGRAMSTRINGPROC glProgramString; -extern PFNGLBINDPROGRAMPROC glBindProgram; -extern PFNGLDELETEPROGRAMSPROC glDeletePrograms; -extern PFNGLGENPROGRAMSPROC glGenPrograms; -extern PFNGLPROGRAMENVPARAMETER4DPROC glProgramEnvParameter4d; -extern PFNGLPROGRAMENVPARAMETER4DVPROC glProgramEnvParameter4dv; -extern PFNGLPROGRAMENVPARAMETER4FPROC glProgramEnvParameter4f; -extern PFNGLPROGRAMENVPARAMETER4FVPROC glProgramEnvParameter4fv; -extern PFNGLPROGRAMLOCALPARAMETER4DPROC glProgramLocalParameter4d; -extern PFNGLPROGRAMLOCALPARAMETER4DVPROC glProgramLocalParameter4dv; -extern PFNGLPROGRAMLOCALPARAMETER4FPROC glProgramLocalParameter4f; -extern PFNGLPROGRAMLOCALPARAMETER4FVPROC glProgramLocalParameter4fv; -extern PFNGLGETPROGRAMENVPARAMETERDVPROC glGetProgramEnvParameterdv; -extern PFNGLGETPROGRAMENVPARAMETERFVPROC glGetProgramEnvParameterfv; -extern PFNGLGETPROGRAMLOCALPARAMETERDVPROC glGetProgramLocalParameterdv; -extern PFNGLGETPROGRAMLOCALPARAMETERFVPROC glGetProgramLocalParameterfv; -extern PFNGLGETPROGRAMIVPROC glGetProgramiv; -extern PFNGLGETPROGRAMSTRINGPROC glGetProgramString; -extern PFNGLGETVERTEXATTRIBDVPROC glGetVertexAttribdv; -extern PFNGLGETVERTEXATTRIBFVPROC glGetVertexAttribfv; -extern PFNGLGETVERTEXATTRIBIVPROC glGetVertexAttribiv; -extern PFNGLGETVERTEXATTRIBPOINTERVPROC glGetVertexAttribPointerv; -extern PFNGLISPROGRAMPROC glIsProgram; -extern PFNGLBINDATTRIBLOCATIONPROC glBindAttribLocation; -extern PFNGLGETACTIVEATTRIBPROC glGetActiveAttrib; -extern PFNGLGETATTRIBLOCATIONPROC glGetAttribLocation; - -extern PFNGLCOMPRESSEDTEXIMAGE2DPROC glCompressedTexImage2D; -extern PFNGLGETCOMPRESSEDTEXIMAGEPROC glGetCompressedTexImage; - -//GL_EXT_blend_func_separate -extern PFNGLBLENDFUNCSEPARATEEXTPROC glBlendFuncSeparateEXT; - -//GL_ARB_framebuffer_object -extern PFNGLISRENDERBUFFERPROC glIsRenderbuffer; -extern PFNGLBINDRENDERBUFFERPROC glBindRenderbuffer; -extern PFNGLDELETERENDERBUFFERSPROC glDeleteRenderbuffers; -extern PFNGLGENRENDERBUFFERSPROC glGenRenderbuffers; -extern PFNGLRENDERBUFFERSTORAGEPROC glRenderbufferStorage; -extern PFNGLGETRENDERBUFFERPARAMETERIVPROC glGetRenderbufferParameteriv; -extern PFNGLISFRAMEBUFFERPROC glIsFramebuffer; -extern PFNGLBINDFRAMEBUFFERPROC glBindFramebuffer; -extern PFNGLDELETEFRAMEBUFFERSPROC glDeleteFramebuffers; -extern PFNGLGENFRAMEBUFFERSPROC glGenFramebuffers; -extern PFNGLCHECKFRAMEBUFFERSTATUSPROC glCheckFramebufferStatus; -extern PFNGLFRAMEBUFFERTEXTURE1DPROC glFramebufferTexture1D; -extern PFNGLFRAMEBUFFERTEXTURE2DPROC glFramebufferTexture2D; -extern PFNGLFRAMEBUFFERTEXTURE3DPROC glFramebufferTexture3D; -extern PFNGLFRAMEBUFFERRENDERBUFFERPROC glFramebufferRenderbuffer; -extern PFNGLGETFRAMEBUFFERATTACHMENTPARAMETERIVPROC glGetFramebufferAttachmentParameteriv; -extern PFNGLGENERATEMIPMAPPROC glGenerateMipmap; -extern PFNGLBLITFRAMEBUFFERPROC glBlitFramebuffer; -extern PFNGLRENDERBUFFERSTORAGEMULTISAMPLEPROC glRenderbufferStorageMultisample; -extern PFNGLFRAMEBUFFERTEXTURELAYERPROC glFramebufferTextureLayer; - -//GL_ARB_draw_buffers -extern PFNGLDRAWBUFFERSPROC glDrawBuffers; - -//GL_ARB_texture_multisample -extern PFNGLTEXIMAGE2DMULTISAMPLEPROC glTexImage2DMultisample; -extern PFNGLTEXIMAGE3DMULTISAMPLEPROC glTexImage3DMultisample; -extern PFNGLGETMULTISAMPLEFVPROC glGetMultisamplefv; -extern PFNGLSAMPLEMASKIPROC glSampleMaski; - -//transform feedback (4.0 core) -extern PFNGLBEGINTRANSFORMFEEDBACKPROC glBeginTransformFeedback; -extern PFNGLENDTRANSFORMFEEDBACKPROC glEndTransformFeedback; -extern PFNGLTRANSFORMFEEDBACKVARYINGSPROC glTransformFeedbackVaryings; -extern PFNGLBINDBUFFERRANGEPROC glBindBufferRange; -extern PFNGLBINDBUFFERBASEPROC glBindBufferBase; - #elif LL_WINDOWS //---------------------------------------------------------------------------- // LL_WINDOWS @@ -345,12 +74,6 @@ extern PFNWGLGETSWAPINTERVALEXTPROC wglGetSwapIntervalEXT; // WGL_ARB_create_context extern PFNWGLCREATECONTEXTATTRIBSARBPROC wglCreateContextAttribsARB; -// GL_VERSION_1_2 -//extern PFNGLDRAWRANGEELEMENTSPROC glDrawRangeElements; -//extern PFNGLTEXIMAGE3DPROC glTexImage3D; -//extern PFNGLTEXSUBIMAGE3DPROC glTexSubImage3D; -//extern PFNGLCOPYTEXSUBIMAGE3DPROC glCopyTexSubImage3D; - // GL_VERSION_1_3 extern PFNGLACTIVETEXTUREPROC glActiveTexture; extern PFNGLSAMPLECOVERAGEPROC glSampleCoverage; diff --git a/indra/llrender/llimagegl.cpp b/indra/llrender/llimagegl.cpp index d8e312106c..6eb7da302f 100644 --- a/indra/llrender/llimagegl.cpp +++ b/indra/llrender/llimagegl.cpp @@ -352,7 +352,7 @@ void LLImageGL::updateStats(F32 current_time) //static void LLImageGL::destroyGL(BOOL save_state) { - for (S32 stage = 0; stage < gGLManager.mNumTextureUnits; stage++) + for (S32 stage = 0; stage < gGLManager.mNumTextureImageUnits; stage++) { gGL.getTexUnit(stage)->unbind(LLTexUnit::TT_TEXTURE); } @@ -520,7 +520,6 @@ void LLImageGL::init(BOOL usemipmaps) mPickMaskHeight = 0; mUseMipMaps = usemipmaps; mHasExplicitFormat = FALSE; - mAutoGenMips = FALSE; mIsMask = FALSE; mNeedsAlphaAndPickMask = TRUE ; @@ -1069,30 +1068,12 @@ BOOL LLImageGL::preAddToAtlas(S32 discard_level, const LLImageRaw* raw_image) mFormatType = GL_UNSIGNED_BYTE; break; case 3: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else -#endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else -#endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1525,30 +1506,12 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const LLImageRaw* imageraw, S mFormatType = GL_UNSIGNED_BYTE; break; case 3: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8; - } - else - #endif - { - mFormatInternal = GL_RGB8; - } + mFormatInternal = GL_RGB8; mFormatPrimary = GL_RGB; mFormatType = GL_UNSIGNED_BYTE; break; case 4: - #if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - mFormatInternal = GL_SRGB8_ALPHA8; - } - else - #endif - { - mFormatInternal = GL_RGBA8; - } + mFormatInternal = GL_RGBA8; mFormatPrimary = GL_RGBA; mFormatType = GL_UNSIGNED_BYTE; break; @@ -1637,7 +1600,7 @@ BOOL LLImageGL::createGLTexture(S32 discard_level, const U8* data_in, BOOL data_ if (mUseMipMaps) { - mAutoGenMips = gGLManager.mHasMipMapGeneration; + mAutoGenMips = true; } mCurrentDiscardLevel = discard_level; @@ -1694,44 +1657,37 @@ void LLImageGL::syncToMainThread(LLGLuint new_tex_name) { LL_PROFILE_ZONE_NAMED("cglt - sync"); - if (gGLManager.mHasSync) + if (gGLManager.mIsNVIDIA) { - if (gGLManager.mIsNVIDIA) - { - // wait for texture upload to finish before notifying main thread - // upload is complete - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - glDeleteSync(sync); - } - else - { - // post a sync to the main thread (will execute before tex name swap lambda below) - // glFlush calls here are partly superstitious and partly backed by observation - // on AMD hardware - glFlush(); - auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); - glFlush(); - LL::WorkQueue::postMaybe( - mMainQueue, - [=]() - { - LL_PROFILE_ZONE_NAMED("cglt - wait sync"); - { - LL_PROFILE_ZONE_NAMED("glWaitSync"); - glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); - } - { - LL_PROFILE_ZONE_NAMED("glDeleteSync"); - glDeleteSync(sync); - } - }); - } + // wait for texture upload to finish before notifying main thread + // upload is complete + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + glClientWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + glDeleteSync(sync); } else { - glFinish(); + // post a sync to the main thread (will execute before tex name swap lambda below) + // glFlush calls here are partly superstitious and partly backed by observation + // on AMD hardware + glFlush(); + auto sync = glFenceSync(GL_SYNC_GPU_COMMANDS_COMPLETE, 0); + glFlush(); + LL::WorkQueue::postMaybe( + mMainQueue, + [=]() + { + LL_PROFILE_ZONE_NAMED("cglt - wait sync"); + { + LL_PROFILE_ZONE_NAMED("glWaitSync"); + glWaitSync(sync, 0, GL_TIMEOUT_IGNORED); + } + { + LL_PROFILE_ZONE_NAMED("glDeleteSync"); + glDeleteSync(sync); + } + }); } } diff --git a/indra/llrender/llimagegl.h b/indra/llrender/llimagegl.h index b4618fd35c..bbd024abd9 100644 --- a/indra/llrender/llimagegl.h +++ b/indra/llrender/llimagegl.h @@ -219,7 +219,7 @@ private: U16 mPickMaskHeight; S8 mUseMipMaps; BOOL mHasExplicitFormat; // If false (default), GL format is f(mComponents) - S8 mAutoGenMips; + bool mAutoGenMips = false; BOOL mIsMask; BOOL mNeedsAlphaAndPickMask; diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index 554721399a..6e659641fe 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -335,7 +335,7 @@ bool LLTexUnit::bind(LLCubeMap* cubeMap) if (mCurrTexture != cubeMap->mImages[0]->getTexName()) { - if (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (LLCubeMap::sUseCubeMaps) { activate(); enable(LLTexUnit::TT_CUBE_MAP); @@ -516,22 +516,15 @@ void LLTexUnit::setTextureFilteringOption(LLTexUnit::eTextureFilterOptions optio } } - if (gGLManager.mHasAnisotropic) + if (gGLManager.mGLVersion >= 4.59f) { if (LLImageGL::sGlobalUseAnisotropic && option == TFO_ANISOTROPIC) { - if (gGL.mMaxAnisotropy < 1.f) - { - glGetFloatv(GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &gGL.mMaxAnisotropy); - - LL_INFOS() << "gGL.mMaxAnisotropy: " << gGL.mMaxAnisotropy << LL_ENDL ; - gGL.mMaxAnisotropy = llmax(1.f, gGL.mMaxAnisotropy) ; - } - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, gGL.mMaxAnisotropy); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, gGLManager.mMaxAnisotropy); } else { - glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY_EXT, 1.f); + glTexParameterf(sGLTextureType[mCurrTexType], GL_TEXTURE_MAX_ANISOTROPY, 1.f); } } } @@ -650,29 +643,6 @@ void LLTexUnit::debugTextureUnit(void) void LLTexUnit::setTextureColorSpace(eTextureColorSpace space) { mTexColorSpace = space; - -#if USE_SRGB_DECODE - if (gGLManager.mHasTexturesRGBDecode) - { - if (space == TCS_SRGB) - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_DECODE_EXT); - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } - - if (gDebugGL) - { - assert_glerror(); - } - } - else - { - glTexParameteri(sGLTextureType[mCurrTexType], GL_TEXTURE_SRGB_DECODE_EXT, GL_SKIP_DECODE_EXT); - } -#endif } LLLightState::LLLightState(S32 index) @@ -846,8 +816,7 @@ LLRender::LLRender() mCount(0), mQuadCycle(0), mMode(LLRender::TRIANGLES), - mCurrTextureUnitIndex(0), - mMaxAnisotropy(0.f) + mCurrTextureUnitIndex(0) { mTexUnits.reserve(LL_NUM_TEXTURE_LAYERS); for (U32 i = 0; i < LL_NUM_TEXTURE_LAYERS; i++) @@ -912,11 +881,9 @@ void LLRender::init() if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) { //bind a dummy vertex array object so we're core profile compliant -#ifdef GL_ARB_vertex_array_object U32 ret; glGenVertexArrays(1, &ret); glBindVertexArray(ret); -#endif } @@ -1492,12 +1459,7 @@ void LLRender::blendFunc(eBlendFactor color_sfactor, eBlendFactor color_dfactor, llassert(color_dfactor < BF_UNDEF); llassert(alpha_sfactor < BF_UNDEF); llassert(alpha_dfactor < BF_UNDEF); - if (!LLRender::sGLCoreProfile && !gGLManager.mHasBlendFuncSeparate) - { - LL_WARNS_ONCE("render") << "no glBlendFuncSeparateEXT(), using color-only blend func" << LL_ENDL; - blendFunc(color_sfactor, color_dfactor); - return; - } + if (mCurrBlendColorSFactor != color_sfactor || mCurrBlendColorDFactor != color_dfactor || mCurrBlendAlphaSFactor != alpha_sfactor || mCurrBlendAlphaDFactor != alpha_dfactor) { diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index b1fb60cf92..3e4a1fe933 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -493,8 +493,6 @@ private: eBlendFactor mCurrBlendAlphaSFactor; eBlendFactor mCurrBlendAlphaDFactor; - F32 mMaxAnisotropy; - std::vector mUIOffset; std::vector mUIScale; diff --git a/indra/llrender/llrendertarget.cpp b/indra/llrender/llrendertarget.cpp index fa23654978..015312e570 100644 --- a/indra/llrender/llrendertarget.cpp +++ b/indra/llrender/llrendertarget.cpp @@ -134,7 +134,7 @@ bool LLRenderTarget::allocate(U32 resx, U32 resy, U32 color_fmt, bool depth, boo mUsage = usage; mUseDepth = depth; - if ((sUseFBO || use_fbo) && gGLManager.mHasFramebufferObject) + if ((sUseFBO || use_fbo)) { if (depth) { @@ -234,11 +234,9 @@ bool LLRenderTarget::addColorAttachment(U32 color_fmt) llassert( offset < 4 ); return false; } - if( offset > 0 && (mFBO == 0 || !gGLManager.mHasDrawBuffers) ) + if( offset > 0 && (mFBO == 0) ) { - LL_WARNS() << "FBO not used or no drawbuffers available; mFBO=" << (U32)mFBO << " gGLManager.mHasDrawBuffers=" << (U32)gGLManager.mHasDrawBuffers << LL_ENDL; llassert( mFBO != 0 ); - llassert( gGLManager.mHasDrawBuffers ); return false; } @@ -484,14 +482,12 @@ void LLRenderTarget::bindTarget() sCurFBO = mFBO; stop_glerror(); - if (gGLManager.mHasDrawBuffers) - { //setup multiple render targets - GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, - GL_COLOR_ATTACHMENT1, - GL_COLOR_ATTACHMENT2, - GL_COLOR_ATTACHMENT3}; - glDrawBuffers(mTex.size(), drawbuffers); - } + //setup multiple render targets + GLenum drawbuffers[] = {GL_COLOR_ATTACHMENT0, + GL_COLOR_ATTACHMENT1, + GL_COLOR_ATTACHMENT2, + GL_COLOR_ATTACHMENT3}; + glDrawBuffers(mTex.size(), drawbuffers); if (mTex.empty()) { //no color buffer to draw to diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index a40ea2eb1e..d05f916d95 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -744,7 +744,7 @@ void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const //static void LLVertexBuffer::initClass(bool use_vbo, bool no_vbo_mapping) { - sEnableVBOs = use_vbo && gGLManager.mHasVertexBufferObject; + sEnableVBOs = use_vbo; sDisableVBOMapping = sEnableVBOs && no_vbo_mapping; } @@ -753,9 +753,7 @@ void LLVertexBuffer::unbind() { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; @@ -923,9 +921,7 @@ LLVertexBuffer::~LLVertexBuffer() if (mGLArray) { -#if GL_ARB_vertex_array_object releaseVAOName(mGLArray); -#endif } sCount--; @@ -956,10 +952,7 @@ void LLVertexBuffer::placeFence() const { /*if (!mFence && useVBOs()) { - if (gGLManager.mHasSync) - { - mFence = new LLGLSyncFence(); - } + mFence = new LLGLSyncFence(); } if (mFence) @@ -1234,11 +1227,9 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) //actually allocate space for the vertex buffer if using VBO mapping flush(); //unmap - if (gGLManager.mHasVertexArrayObject && useVBOs() && sUseVAO) + if (useVBOs() && sUseVAO) { -#if GL_ARB_vertex_array_object mGLArray = getVAOName(); -#endif setupVertexArray(); } } @@ -1254,9 +1245,7 @@ void LLVertexBuffer::setupVertexArray() } LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; static const U32 attrib_size[] = @@ -1443,7 +1432,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1492,58 +1481,34 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) + if (map_range) { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = mOffsets[type] + sTypeSize[type]*index; - S32 length = (sTypeSize[type]*count+0xF) & ~0xF; - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else + S32 offset = mOffsets[type] + sTypeSize[type]*index; + S32 length = (sTypeSize[type]*count+0xF) & ~0xF; + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); + } + else + { + if (gDebugGL) { -#ifdef GL_ARB_map_buffer_range + GLint size = 0; + glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - if (gDebugGL) + if (size < mSize) { - GLint size = 0; - glGetBufferParameteriv(GL_ARRAY_BUFFER, GL_BUFFER_SIZE, &size); - - if (size < mSize) - { - LL_ERRS() << "Invalid buffer size." << LL_ENDL; - } + LL_ERRS() << "Invalid buffer size." << LL_ENDL; } - - src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif - } - } - else if (gGLManager.mHasFlushBufferRange) - { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); } - } - else - { - map_range = false; - src = (U8*) glMapBuffer(GL_ARRAY_BUFFER, GL_WRITE_ONLY); + + src = (U8*) glMapBufferRange(GL_ARRAY_BUFFER, 0, mSize, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - llassert(src != NULL); + llassert(src != NULL); mMappedData = LL_NEXT_ALIGNED_ADDRESS(src); mAlignedOffset = mMappedData - src; @@ -1569,7 +1534,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran //-------------------- GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL; @@ -1590,7 +1555,7 @@ U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_ran map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedData; } @@ -1616,7 +1581,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (useVBOs()) { - if (!mMappable || gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappable) { if (count == -1) { @@ -1657,7 +1622,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if (gDebugGL && useVBOs()) { GLint elem = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &elem); if (elem != mGLIndices) { @@ -1673,48 +1638,24 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) { U8* src = NULL; waitFence(); - if (gGLManager.mHasMapBufferRange) + if (map_range) { - if (map_range) - { -#ifdef GL_ARB_map_buffer_range - S32 offset = sizeof(U16)*index; - S32 length = sizeof(U16)*count; - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT | - GL_MAP_INVALIDATE_RANGE_BIT); -#endif - } - else - { -#ifdef GL_ARB_map_buffer_range - src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, - GL_MAP_WRITE_BIT | - GL_MAP_FLUSH_EXPLICIT_BIT); -#endif - } - } - else if (gGLManager.mHasFlushBufferRange) - { - if (map_range) - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } - else - { - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); - } + S32 offset = sizeof(U16)*index; + S32 length = sizeof(U16)*count; + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT | + GL_MAP_INVALIDATE_RANGE_BIT); } else { - map_range = false; - src = (U8*) glMapBuffer(GL_ELEMENT_ARRAY_BUFFER, GL_WRITE_ONLY); + src = (U8*) glMapBufferRange(GL_ELEMENT_ARRAY_BUFFER, 0, sizeof(U16)*mNumIndices, + GL_MAP_WRITE_BIT | + GL_MAP_FLUSH_EXPLICIT_BIT); } - + llassert(src != NULL); - mMappedIndexData = src; //LL_NEXT_ALIGNED_ADDRESS(src); mAlignedIndexOffset = mMappedIndexData - src; stop_glerror(); @@ -1729,7 +1670,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) if(mMappable) { GLint buff; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL; @@ -1748,7 +1689,7 @@ U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) map_range = false; } - if (map_range && gGLManager.mHasMapBufferRange && mMappable) + if (map_range && mMappable) { return mMappedIndexData; } @@ -1812,25 +1753,20 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedVertexRegions.empty()) { - if (!mMappedVertexRegions.empty()) + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush vertex"); - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; - S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; - S32 length = sTypeSize[region.mType]*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); - } - } - - mMappedVertexRegions.clear(); + const MappedRegion& region = mMappedVertexRegions[i]; + S32 offset = region.mIndex >= 0 ? mOffsets[region.mType]+sTypeSize[region.mType]*region.mIndex : 0; + S32 length = sTypeSize[region.mType]*region.mCount; + glFlushMappedBufferRange(GL_ARRAY_BUFFER, offset, length); } + + mMappedVertexRegions.clear(); } + stop_glerror(); glUnmapBuffer(GL_ARRAY_BUFFER); stop_glerror(); @@ -1884,25 +1820,19 @@ void LLVertexBuffer::unmapBuffer() } else { - if (gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange) + if (!mMappedIndexRegions.empty()) { - if (!mMappedIndexRegions.empty()) + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) { - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); - const MappedRegion& region = mMappedIndexRegions[i]; - S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; - S32 length = sizeof(U16)*region.mCount; - if (gGLManager.mHasMapBufferRange) - { - glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); - } - stop_glerror(); - } - - mMappedIndexRegions.clear(); + LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - flush index"); + const MappedRegion& region = mMappedIndexRegions[i]; + S32 offset = region.mIndex >= 0 ? sizeof(U16)*region.mIndex : 0; + S32 length = sizeof(U16)*region.mCount; + glFlushMappedBufferRange(GL_ELEMENT_ARRAY_BUFFER, offset, length); + stop_glerror(); } + + mMappedIndexRegions.clear(); } glUnmapBuffer(GL_ELEMENT_ARRAY_BUFFER); @@ -2034,9 +1964,7 @@ bool LLVertexBuffer::bindGLArray() { { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; -#if GL_ARB_vertex_array_object glBindVertexArray(mGLArray); -#endif sGLRenderArray = mGLArray; } @@ -2228,7 +2156,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (gDebugGL && !mGLArray) { GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLBuffer) { if (gDebugSession) @@ -2243,7 +2171,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) if (mGLIndices) { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &buff); + glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); if ((GLuint)buff != mGLIndices) { if (gDebugSession) @@ -2264,9 +2192,7 @@ void LLVertexBuffer::setBuffer(U32 data_mask) { if (sGLRenderArray) { -#if GL_ARB_vertex_array_object glBindVertexArray(0); -#endif sGLRenderArray = 0; sGLRenderIndices = 0; sIBOActive = false; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 9508c1dc2d..100bcf7ab9 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10784,18 +10784,6 @@ Value 0 - RenderUseTransformFeedback - - Comment - [EXPERIMENTAL] Use transform feedback shaders for LoD updates - Persist - 1 - Type - Boolean - Value - 0 - - RenderVBOMappingDisable Comment diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 6b4ab1be17..abc379a44f 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 36 +version 37 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -287,14 +287,9 @@ list Intel RenderAnisotropic 1 0 RenderFSAASamples 1 0 RenderGLMultiThreaded 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 // HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 list AMD -RenderUseStreamVBO 1 0 -RenderGLContextCoreProfile 1 0 RenderReflectionProbeCount 1 16 diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index be33e1b30a..55c8d84838 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -165,19 +165,6 @@ void LLDrawPoolTerrain::render(S32 pass) LLOverrideFaceColor override(this, 1.f, 1.f, 1.f, 1.f); - if (!gGLManager.mHasMultitexture) - { - // No multitexture, render simple land. - renderSimple(); // Render without multitexture - return; - } - // Render simplified land if video card can't do sufficient multitexturing - if (!gGLManager.mHasARBEnvCombine || (gGLManager.mNumTextureUnits < 2)) - { - renderSimple(); // Render without multitexture - return; - } - LLGLSPipeline gls; if (mShaderLevel > 1 && sShader->mShaderLevel > 0) @@ -194,10 +181,6 @@ void LLDrawPoolTerrain::render(S32 pass) { renderSimple(); } - else if (gGLManager.mNumTextureUnits < 4) - { - renderFull2TU(); - } else { renderFull4TU(); diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index a84f62036e..576024ead3 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -104,7 +104,7 @@ void LLDrawPoolWater::restoreGL() void LLDrawPoolWater::prerender() { - mShaderLevel = (gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; + mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; } S32 LLDrawPoolWater::getNumPasses() @@ -188,12 +188,6 @@ void LLDrawPoolWater::render(S32 pass) stop_glerror(); - if (!gGLManager.mHasMultitexture) - { - // Ack! No multitexture! Bail! - return; - } - LLFace* refl_face = voskyp->getReflFace(); gPipeline.disableLights(); diff --git a/indra/newview/lldynamictexture.cpp b/indra/newview/lldynamictexture.cpp index 63e7887d81..361a7666fa 100644 --- a/indra/newview/lldynamictexture.cpp +++ b/indra/newview/lldynamictexture.cpp @@ -125,7 +125,7 @@ void LLViewerDynamicTexture::preRender(BOOL clear_depth) llassert(mFullHeight <= static_cast(gPipeline.mPhysicsDisplay.getHeight())); } - if (gGLManager.mHasFramebufferObject && gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) + if (gPipeline.mPhysicsDisplay.isComplete() && !gGLManager.mIsAMD) { //using offscreen render target, just use the bottom left corner mOrigin.set(0, 0); } @@ -212,7 +212,7 @@ BOOL LLViewerDynamicTexture::updateAllInstances() return TRUE; } - bool use_fbo = gGLManager.mHasFramebufferObject && gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; + bool use_fbo = gPipeline.mBake.isComplete() && !gGLManager.mIsAMD; if (use_fbo) { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 3f69815e38..5562f1d057 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1211,55 +1211,6 @@ bool LLFace::canRenderAsMask() return false; } - -//static -void LLFace::cacheFaceInVRAM(const LLVolumeFace& vf) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE; - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL; - - if (vf.mWeights) - { - mask |= LLVertexBuffer::MAP_WEIGHT4; - } - - LLVertexBuffer* buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); - vf.mVertexBuffer = buff; - - buff->allocateBuffer(vf.mNumVertices, 0, true); - - LLStrider f_vert; - LLStrider f_tangent; - LLStrider f_norm; - LLStrider f_tc; - - buff->getTangentStrider(f_tangent); - buff->getVertexStrider(f_vert); - buff->getNormalStrider(f_norm); - buff->getTexCoord0Strider(f_tc); - - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - *f_vert++ = vf.mPositions[i]; - *f_tangent++ = vf.mTangents[i]; - *f_tc++ = vf.mTexCoords[i]; - (*f_norm++).set(vf.mNormals[i].getF32ptr()); - } - - if (vf.mWeights) - { - LLStrider f_wght; - buff->getWeight4Strider(f_wght); - for (U32 i = 0; i < vf.mNumVertices; ++i) - { - (*f_wght++).set(vf.mWeights[i].getF32ptr()); - } - } - - buff->flush(); -} - //helper function for pushing primitives for transform shaders and cleaning up //uninitialized data on the tail, plus tracking number of expected primitives void push_for_transform(LLVertexBuffer* buff, U32 source_count, U32 dest_count) @@ -1304,7 +1255,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, //don't use map range (generates many redundant unmap calls) - bool map_range = false; //gGLManager.mHasMapBufferRange || gGLManager.mHasFlushBufferRange; + bool map_range = false; if (mVertexBuffer.notNull()) { @@ -1535,155 +1486,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - -#ifdef GL_TRANSFORM_FEEDBACK_BUFFER - if (use_transform_feedback && - mVertexBuffer->getUsage() == GL_DYNAMIC_COPY && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - mVertexBuffer->useVBOs() && //target buffer is in VRAM - !rebuild_weights && //TODO: add support for weights - !volume.isUnique()) //source volume is NOT flexi - { //use transform feedback to pack vertex buffer - - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - transform feedback"); - LLGLEnable discard(GL_RASTERIZER_DISCARD); - LLVertexBuffer* buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - - if (vf.mVertexBuffer.isNull() || buff->getNumVerts() != vf.mNumVertices) - { - mVObjp->getVolume()->genTangents(f); - LLFace::cacheFaceInVRAM(vf); - buff = (LLVertexBuffer*) vf.mVertexBuffer.get(); - } - - LLGLSLShader* cur_shader = LLGLSLShader::sCurBoundShaderPtr; - - gGL.pushMatrix(); - gGL.loadMatrix((GLfloat*) mat_vert_in.mMatrix); - - if (rebuild_pos) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf position"); - gTransformPositionProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_VERTEX, mGeomIndex, mGeomCount); - - U8 index = mTextureIndex < FACE_DO_NOT_BATCH_TEXTURES ? mTextureIndex : 0; - - S32 val = 0; - U8* vp = (U8*) &val; - vp[0] = index; - vp[1] = 0; - vp[2] = 0; - vp[3] = 0; - - gTransformPositionProgram.uniform1i(sTextureIndexIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - - push_for_transform(buff, vf.mNumVertices, mGeomCount); - - glEndTransformFeedback(); - } - - if (rebuild_color) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf color"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_COLOR, mGeomIndex, mGeomCount); - - S32 val = *((S32*) color.mV); - - gTransformColorProgram.uniform1i(sColorIn, val); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_emissive) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf emissive"); - gTransformColorProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_EMISSIVE, mGeomIndex, mGeomCount); - - U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); - - S32 glow32 = glow | - (glow << 8) | - (glow << 16) | - (glow << 24); - - gTransformColorProgram.uniform1i(sColorIn, glow32); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_normal) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf normal"); - gTransformNormalProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_NORMAL, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_NORMAL); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tangent) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tangent"); - gTransformTangentProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TANGENT, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TANGENT); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - - if (rebuild_tcoord) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tf tcoord"); - gTransformTexCoordProgram.bind(); - - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD0, mGeomIndex, mGeomCount); - - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - - bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); - - if (do_bump) - { - mVertexBuffer->bindForFeedback(0, LLVertexBuffer::TYPE_TEXCOORD1, mGeomIndex, mGeomCount); - glBeginTransformFeedback(GL_POINTS); - buff->setBuffer(LLVertexBuffer::MAP_TEXCOORD0); - push_for_transform(buff, vf.mNumVertices, mGeomCount); - glEndTransformFeedback(); - } - } - - glBindBuffer(GL_TRANSFORM_FEEDBACK_BUFFER, 0); - gGL.popMatrix(); - - if (cur_shader) - { - cur_shader->bind(); - } - } - else -#endif { //if it's not fullbright and has no normals, bake sunlight based on face normal //bool bake_sunlight = !getTextureEntry()->getFullbright() && diff --git a/indra/newview/llface.h b/indra/newview/llface.h index aa00c9d052..4778a8110b 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -81,8 +81,6 @@ public: PARTICLE = 0x0080, }; - static void cacheFaceInVRAM(const LLVolumeFace& vf); - public: LLFace(LLDrawable* drawablep, LLViewerObject* objp) { diff --git a/indra/newview/llfeaturemanager.cpp b/indra/newview/llfeaturemanager.cpp index 826d4892ef..2c770f6ab8 100644 --- a/indra/newview/llfeaturemanager.cpp +++ b/indra/newview/llfeaturemanager.cpp @@ -431,41 +431,9 @@ bool LLFeatureManager::loadGPUClass() LL_WARNS("RenderInit") << "Unable to get an accurate benchmark; defaulting to class 3" << LL_ENDL; mGPUClass = GPU_CLASS_3; #else - if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } - else if (gGLManager.mGLVersion < 3.3f) - { - mGPUClass = GPU_CLASS_2; - } - else if (gGLManager.mGLVersion < 4.f) - { - mGPUClass = GPU_CLASS_3; - } - else - { - mGPUClass = GPU_CLASS_4; - } - if (gGLManager.mIsIntel && mGPUClass > GPU_CLASS_1) - { - // Intels are generally weaker then other GPUs despite having advanced features - mGPUClass = (EGPUClass)(mGPUClass - 1); - } + mGPUClass = GPU_CLASS_2; #endif } - else if (gGLManager.mGLVersion <= 2.f) - { - mGPUClass = GPU_CLASS_0; - } - else if (gGLManager.mGLVersion <= 3.f) - { - mGPUClass = GPU_CLASS_1; - } else if (gbps <= 5.f) { mGPUClass = GPU_CLASS_0; @@ -679,10 +647,6 @@ void LLFeatureManager::applyBaseMasks() { maskFeatures("TexUnit8orLess"); } - if (gGLManager.mHasMapBufferRange) - { - maskFeatures("MapBufferRange"); - } if (gGLManager.mVRAM > 512) { maskFeatures("VRAMGT512"); diff --git a/indra/newview/llfloaterpreference.cpp b/indra/newview/llfloaterpreference.cpp index 68928e9c8f..7b01e9050b 100644 --- a/indra/newview/llfloaterpreference.cpp +++ b/indra/newview/llfloaterpreference.cpp @@ -1198,7 +1198,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() LLTextBox* reflections_text = getChild("ReflectionsText"); // Reflections - BOOL reflections = gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps; + BOOL reflections = LLCubeMap::sUseCubeMaps; ctrl_reflections->setEnabled(reflections); reflections_text->setEnabled(reflections); @@ -1227,14 +1227,7 @@ void LLFloaterPreferenceGraphicsAdvanced::refreshEnabledState() // Hardware settings - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - getChildView("vbo")->setEnabled(FALSE); - } - - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures") || - !gGLManager.mHasVertexBufferObject) + if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderCompressTextures")) { getChildView("texture compression")->setEnabled(FALSE); } diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index d75f3eef6f..38ec24cae8 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -987,9 +987,8 @@ private: //----------------------------------------------------------------------------- F32 gpu_benchmark() { - if (!gGLManager.mHasTimerQuery) + if (gGLManager.mGLVersion < 3.3f) { // don't bother benchmarking venerable drivers which don't support accurate timing anyway - // and are likely to be correctly identified by the GPU table already. return -1.f; } @@ -1115,16 +1114,6 @@ F32 gpu_benchmark() // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); -#ifdef GL_ARB_vertex_array_object - U32 glarray = 0; - - if (LLRender::sGLCoreProfile) - { - glGenVertexArrays(1, &glarray); - glBindVertexArray(glarray); - } -#endif - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); glFinish(); @@ -1157,15 +1146,6 @@ F32 gpu_benchmark() } } -#ifdef GL_ARB_vertex_array_object - if (LLRender::sGLCoreProfile) - { - glBindVertexArray(0); - glDeleteVertexArrays(1, &glarray); - } -#endif - - std::sort(results.begin(), results.end()); F32 gbps = results[results.size()/2]; diff --git a/indra/newview/llscenemonitor.cpp b/indra/newview/llscenemonitor.cpp index 6a2f53aa42..49d5aa3e14 100644 --- a/indra/newview/llscenemonitor.cpp +++ b/indra/newview/llscenemonitor.cpp @@ -445,14 +445,14 @@ void LLSceneMonitor::calcDiffAggregate() if(mDiffState == EXECUTE_DIFF) { - glBeginQuery(GL_SAMPLES_PASSED_ARB, mQueryObject); + glBeginQuery(GL_SAMPLES_PASSED, mQueryObject); } gl_draw_scaled_target(0, 0, S32(mDiff->getWidth() * mDiffPixelRatio), S32(mDiff->getHeight() * mDiffPixelRatio), mDiff); if(mDiffState == EXECUTE_DIFF) { - glEndQuery(GL_SAMPLES_PASSED_ARB); + glEndQuery(GL_SAMPLES_PASSED); mDiffState = WAIT_ON_RESULT; } @@ -483,11 +483,11 @@ void LLSceneMonitor::fetchQueryResult() mDiffState = WAITING_FOR_NEXT_DIFF; GLuint available = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_AVAILABLE, &available); if(available) { GLuint count = 0; - glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT_ARB, &count); + glGetQueryObjectuiv(mQueryObject, GL_QUERY_RESULT, &count); mDiffResult = sqrtf(count * 0.5f / (mDiff->getWidth() * mDiff->getHeight() * mDiffPixelRatio * mDiffPixelRatio)); //0.5 -> (front face + back face) diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 9682945208..2413d7705a 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -381,7 +381,7 @@ static bool handleJoystickChanged(const LLSD& newvalue) static bool handleUseOcclusionChanged(const LLSD& newvalue) { - LLPipeline::sUseOcclusion = (newvalue.asBoolean() && gGLManager.mHasOcclusionQuery + LLPipeline::sUseOcclusion = (newvalue.asBoolean() && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") && !gUseWireframe) ? 2 : 0; return true; } diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index dd82d43ab2..f10cb329a9 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2309,44 +2309,6 @@ class LLAdvancedCheckViewAdminOptions : public view_listener_t } }; -///////////////////////////////////// -// Enable Object Object Occlusion /// -///////////////////////////////////// -class LLAdvancedEnableObjectObjectOcclusion: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - - bool new_value = gGLManager.mHasOcclusionQuery; // && LLFeatureManager::getInstance()->isFeatureAvailable(userdata.asString()); - return new_value; -} -}; - -///////////////////////////////////// -// Enable Framebuffer Objects /// -///////////////////////////////////// -class LLAdvancedEnableRenderFBO: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject; - return new_value; - } -}; - -///////////////////////////////////// -// Enable Deferred Rendering /// -///////////////////////////////////// -class LLAdvancedEnableRenderDeferred: public view_listener_t -{ - bool handleEvent(const LLSD& userdata) - { - bool new_value = gGLManager.mHasFramebufferObject && LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WINDLIGHT) > 1 && - LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR) > 0; - return new_value; - } -}; - ////////////////// // ADMIN STATUS // ////////////////// @@ -9367,8 +9329,6 @@ void initialize_menus() view_listener_t::addMenu(new LLAdvancedToggleWireframe(), "Advanced.ToggleWireframe"); view_listener_t::addMenu(new LLAdvancedCheckWireframe(), "Advanced.CheckWireframe"); // Develop > Render - view_listener_t::addMenu(new LLAdvancedEnableObjectObjectOcclusion(), "Advanced.EnableObjectObjectOcclusion"); - view_listener_t::addMenu(new LLAdvancedToggleRandomizeFramerate(), "Advanced.ToggleRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedCheckRandomizeFramerate(), "Advanced.CheckRandomizeFramerate"); view_listener_t::addMenu(new LLAdvancedTogglePeriodicSlowFrame(), "Advanced.TogglePeriodicSlowFrame"); diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index c785c80cea..a75eb518f3 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -917,15 +917,12 @@ void LLOcclusionCullingGroup::handleChildAddition(const OctreeNode* parent, Octr void LLOcclusionCullingGroup::releaseOcclusionQueryObjectNames() { - if (gGLManager.mHasOcclusionQuery) + for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) { - for (U32 i = 0; i < LLViewerCamera::NUM_CAMERAS; ++i) + if (mOcclusionQuery[i]) { - if (mOcclusionQuery[i]) - { - releaseOcclusionQueryObjectName(mOcclusionQuery[i]); - mOcclusionQuery[i] = 0; - } + releaseOcclusionQueryObjectName(mOcclusionQuery[i]); + mOcclusionQuery[i] = 0; } } } @@ -1129,7 +1126,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint available; { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query available"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE_ARB, &available); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_AVAILABLE, &available); } if (available) @@ -1137,7 +1134,7 @@ void LLOcclusionCullingGroup::checkOcclusion() GLuint query_result; // Will be # samples drawn, or a boolean depending on mHasOcclusionQuery2 (both are type GLuint) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("co - query result"); - glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT_ARB, &query_result); + glGetQueryObjectuiv(mOcclusionQuery[LLViewerCamera::sCurCameraID], GL_QUERY_RESULT, &query_result); } #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.erase(mOcclusionQuery[LLViewerCamera::sCurCameraID]); @@ -1197,7 +1194,6 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh OCCLUSION_FUDGE_Z = 1.; } - // Don't cull hole/edge water, unless we have the GL_ARB_depth_clamp extension if (earlyFail(camera, bounds)) { LL_PROFILE_ZONE_NAMED_CATEGORY_OCTREE("doOcclusion - early fail"); @@ -1221,17 +1217,12 @@ void LLOcclusionCullingGroup::doOcclusion(LLCamera* camera, const LLVector4a* sh // Depth clamp all water to avoid it being culled as a result of being // behind the far clip plane, and in the case of edge water to avoid // it being culled while still visible. - bool const use_depth_clamp = gGLManager.mHasDepthClamp && - (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || + bool const use_depth_clamp = (mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_WATER || mSpatialPartition->mDrawableType == LLPipeline::RENDER_TYPE_VOIDWATER); - LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); + LLGLEnable clamp(use_depth_clamp ? GL_DEPTH_CLAMP : 0); -#if !LL_DARWIN - U32 mode = gGLManager.mHasOcclusionQuery2 ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED_ARB; -#else - U32 mode = GL_SAMPLES_PASSED_ARB; -#endif + U32 mode = gGLManager.mGLVersion >= 3.3f ? GL_ANY_SAMPLES_PASSED : GL_SAMPLES_PASSED; #if LL_TRACK_PENDING_OCCLUSION_QUERIES sPendingQueries.insert(mOcclusionQuery[LLViewerCamera::sCurCameraID]); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 2ebe0f826f..296a383ed0 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -70,13 +70,6 @@ bool LLViewerShaderMgr::sSkipReload = false; LLVector4 gShinyOrigin; -//transform shaders -LLGLSLShader gTransformPositionProgram; -LLGLSLShader gTransformTexCoordProgram; -LLGLSLShader gTransformNormalProgram; -LLGLSLShader gTransformColorProgram; -LLGLSLShader gTransformTangentProgram; - //utility shaders LLGLSLShader gOcclusionProgram; LLGLSLShader gSkinnedOcclusionProgram; @@ -469,7 +462,7 @@ void LLViewerShaderMgr::setShaders() initAttribsAndUniforms(); gPipeline.releaseGLBuffers(); - LLPipeline::sWaterReflections = gGLManager.mHasCubeMap && LLPipeline::sRenderTransparentWater; + LLPipeline::sWaterReflections = LLPipeline::sRenderTransparentWater; LLPipeline::sRenderGlow = gSavedSettings.getBOOL("RenderGlow"); LLPipeline::updateRenderDeferred(); @@ -513,13 +506,6 @@ void LLViewerShaderMgr::setShaders() S32 wl_class = 1; S32 water_class = 2; S32 deferred_class = 0; - S32 transform_class = gGLManager.mHasTransformFeedback ? 1 : 0; - - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - if (!use_transform_feedback) - { - transform_class = 0; - } if (useRenderDeferred) { @@ -572,7 +558,6 @@ void LLViewerShaderMgr::setShaders() mShaderLevel[SHADER_EFFECT] = effect_class; mShaderLevel[SHADER_WINDLIGHT] = wl_class; mShaderLevel[SHADER_DEFERRED] = deferred_class; - mShaderLevel[SHADER_TRANSFORM] = transform_class; std::string shader_name = loadBasicShaders(); if (shader_name.empty()) @@ -657,20 +642,6 @@ void LLViewerShaderMgr::setShaders() } } - if (loaded) - { - loaded = loadTransformShaders(); - if (loaded) - { - LL_INFOS() << "Loaded transform shaders." << LL_ENDL; - } - else - { - LL_WARNS() << "Failed to load transform shaders." << LL_ENDL; - llassert(loaded); - } - } - if (loaded) { // Load max avatar shaders to set the max level @@ -816,12 +787,6 @@ void LLViewerShaderMgr::unloadShaders() gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - mShaderLevel[SHADER_LIGHTING] = 0; mShaderLevel[SHADER_OBJECT] = 0; mShaderLevel[SHADER_AVATAR] = 0; @@ -830,7 +795,6 @@ void LLViewerShaderMgr::unloadShaders() mShaderLevel[SHADER_INTERFACE] = 0; mShaderLevel[SHADER_EFFECT] = 0; mShaderLevel[SHADER_WINDLIGHT] = 0; - mShaderLevel[SHADER_TRANSFORM] = 0; gPipeline.mShadersLoaded = false; } @@ -1643,8 +1607,8 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() shader->mFeatures.hasReflectionProbes = mShaderLevel[SHADER_DEFERRED]; shader->mShaderFiles.clear(); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER_ARB)); - shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER_ARB)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaV.glsl", GL_VERTEX_SHADER)); + shader->mShaderFiles.push_back(make_pair("deferred/pbralphaF.glsl", GL_FRAGMENT_SHADER)); shader->clearPermutations(); @@ -2437,10 +2401,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowV.glsl", GL_VERTEX_SHADER)); gDeferredShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now gDeferredShadowProgram.mRiggedVariant = &gDeferredSkinnedShadowProgram; success = gDeferredShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2456,10 +2417,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredSkinnedShadowProgram.addPermutation("DEPTH_CLAMP", "1"); // disable depth clamp for now success = gDeferredSkinnedShadowProgram.createShader(NULL, NULL); llassert(success); } @@ -2472,10 +2430,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowCubeProgram.mShaderFiles.clear(); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowCubeV.glsl", GL_VERTEX_SHADER)); gDeferredShadowCubeProgram.mShaderFiles.push_back(make_pair("deferred/shadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); - } + // gDeferredShadowCubeProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowCubeProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredShadowCubeProgram.createShader(NULL, NULL); llassert(success); @@ -2491,10 +2446,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowFullbrightAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowFullbrightAlphaMaskProgram; @@ -2512,10 +2464,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.clearPermutations(); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } + gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.addPermutation("IS_FULLBRIGHT", "1"); gDeferredSkinnedShadowFullbrightAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowFullbrightAlphaMaskProgram.createShader(NULL, NULL); @@ -2530,10 +2479,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskV.glsl", GL_VERTEX_SHADER)); gDeferredShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gDeferredShadowAlphaMaskProgram.mRiggedVariant = &gDeferredSkinnedShadowAlphaMaskProgram; success = gDeferredShadowAlphaMaskProgram.createShader(NULL, NULL); @@ -2548,10 +2493,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.clear(); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskSkinnedV.glsl", GL_VERTEX_SHADER)); gDeferredSkinnedShadowAlphaMaskProgram.mShaderFiles.push_back(make_pair("deferred/shadowAlphaMaskF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredSkinnedShadowAlphaMaskProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredSkinnedShadowAlphaMaskProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredSkinnedShadowAlphaMaskProgram.createShader(NULL, NULL); llassert(success); @@ -2565,10 +2506,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarShadowProgram.mShaderFiles.clear(); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarShadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAvatarShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAvatarShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2581,7 +2518,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2594,7 +2530,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.clear(); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAvatarAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/avatarAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAvatarAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAvatarAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAvatarAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2608,10 +2543,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentShadowProgram.mShaderFiles.clear(); gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentShadowF.glsl", GL_FRAGMENT_SHADER)); - if (gGLManager.mHasDepthClamp) - { - gDeferredAttachmentShadowProgram.addPermutation("DEPTH_CLAMP", "1"); - } gDeferredAttachmentShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2624,7 +2555,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentAlphaShadowProgram.mShaderFiles.clear(); gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentAlphaShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAttachmentAlphaShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaShadowProgram.createShader(NULL, NULL); llassert(success); @@ -2637,7 +2567,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.clear(); gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaShadowV.glsl", GL_VERTEX_SHADER)); gDeferredAttachmentAlphaMaskShadowProgram.mShaderFiles.push_back(make_pair("deferred/attachmentAlphaMaskShadowF.glsl", GL_FRAGMENT_SHADER)); - gDeferredAttachmentAlphaMaskShadowProgram.addPermutation("DEPTH_CLAMP", gGLManager.mHasDepthClamp ? "1" : "0"); gDeferredAttachmentAlphaMaskShadowProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredAttachmentAlphaMaskShadowProgram.createShader(NULL, NULL); llassert(success); @@ -3976,95 +3905,6 @@ BOOL LLViewerShaderMgr::loadShadersWindLight() return success; } -BOOL LLViewerShaderMgr::loadTransformShaders() -{ - BOOL success = TRUE; - - if (mShaderLevel[SHADER_TRANSFORM] < 1) - { - gTransformPositionProgram.unload(); - gTransformTexCoordProgram.unload(); - gTransformNormalProgram.unload(); - gTransformColorProgram.unload(); - gTransformTangentProgram.unload(); - return TRUE; - } - - if (success) - { - gTransformPositionProgram.mName = "Position Transform Shader"; - gTransformPositionProgram.mShaderFiles.clear(); - gTransformPositionProgram.mShaderFiles.push_back(make_pair("transform/positionV.glsl", GL_VERTEX_SHADER)); - gTransformPositionProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "position_out", - "texture_index_out", - }; - - success = gTransformPositionProgram.createShader(NULL, NULL, 2, varyings); - } - - if (success) - { - gTransformTexCoordProgram.mName = "TexCoord Transform Shader"; - gTransformTexCoordProgram.mShaderFiles.clear(); - gTransformTexCoordProgram.mShaderFiles.push_back(make_pair("transform/texcoordV.glsl", GL_VERTEX_SHADER)); - gTransformTexCoordProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "texcoord_out", - }; - - success = gTransformTexCoordProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformNormalProgram.mName = "Normal Transform Shader"; - gTransformNormalProgram.mShaderFiles.clear(); - gTransformNormalProgram.mShaderFiles.push_back(make_pair("transform/normalV.glsl", GL_VERTEX_SHADER)); - gTransformNormalProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "normal_out", - }; - - success = gTransformNormalProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformColorProgram.mName = "Color Transform Shader"; - gTransformColorProgram.mShaderFiles.clear(); - gTransformColorProgram.mShaderFiles.push_back(make_pair("transform/colorV.glsl", GL_VERTEX_SHADER)); - gTransformColorProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "color_out", - }; - - success = gTransformColorProgram.createShader(NULL, NULL, 1, varyings); - } - - if (success) - { - gTransformTangentProgram.mName = "Binormal Transform Shader"; - gTransformTangentProgram.mShaderFiles.clear(); - gTransformTangentProgram.mShaderFiles.push_back(make_pair("transform/binormalV.glsl", GL_VERTEX_SHADER)); - gTransformTangentProgram.mShaderLevel = mShaderLevel[SHADER_TRANSFORM]; - - const char* varyings[] = { - "tangent_out", - }; - - success = gTransformTangentProgram.createShader(NULL, NULL, 1, varyings); - } - - - return success; -} - std::string LLViewerShaderMgr::getShaderDirPrefix(void) { return gDirUtilp->getExpandedFilename(LL_PATH_APP_SETTINGS, "shaders/class"); diff --git a/indra/newview/llviewershadermgr.h b/indra/newview/llviewershadermgr.h index 19d8e87d66..464efd6e3f 100644 --- a/indra/newview/llviewershadermgr.h +++ b/indra/newview/llviewershadermgr.h @@ -62,7 +62,6 @@ public: BOOL loadShadersWater(); BOOL loadShadersInterface(); BOOL loadShadersWindLight(); - BOOL loadTransformShaders(); std::vector mShaderLevel; S32 mMaxAvatarShaderLevel; @@ -78,7 +77,6 @@ public: SHADER_WINDLIGHT, SHADER_WATER, SHADER_DEFERRED, - SHADER_TRANSFORM, SHADER_COUNT }; @@ -150,15 +148,6 @@ inline bool operator != (LLViewerShaderMgr::shader_iter const & a, LLViewerShade extern LLVector4 gShinyOrigin; -//transform shaders -extern LLGLSLShader gTransformPositionProgram; -extern LLGLSLShader gTransformTexCoordProgram; -extern LLGLSLShader gTransformNormalProgram; -extern LLGLSLShader gTransformColorProgram; -extern LLGLSLShader gTransformTangentProgram; - - - //utility shaders extern LLGLSLShader gOcclusionProgram; extern LLGLSLShader gOcclusionCubeProgram; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e9815a7872..5474098d16 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -597,29 +597,6 @@ public: { LLTrace::Recording& last_frame_recording = LLTrace::get_frame_recording().getLastRecording(); - if (gGLManager.mHasATIMemInfo) - { - S32 meminfo[4]; - glGetIntegerv(GL_TEXTURE_FREE_MEMORY_ATI, meminfo); - - addText(xpos, ypos, llformat("%.2f MB Texture Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - - if (gGLManager.mHasVertexBufferObject) - { - glGetIntegerv(GL_VBO_FREE_MEMORY_ATI, meminfo); - addText(xpos, ypos, llformat("%.2f MB VBO Memory Free", meminfo[0]/1024.f)); - ypos += y_inc; - } - } - else if (gGLManager.mHasNVXMemInfo) - { - S32 free_memory; - glGetIntegerv(GL_GPU_MEMORY_INFO_CURRENT_AVAILABLE_VIDMEM_NVX, &free_memory); - addText(xpos, ypos, llformat("%.2f MB Video Memory Free", free_memory/1024.f)); - ypos += y_inc; - } - //show streaming cost/triangle count of known prims in current region OR selection { F32 cost = 0.f; @@ -1979,11 +1956,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) LL_DEBUGS("Window") << "Loading feature tables." << LL_ENDL; // Initialize OpenGL Renderer - if (!LLFeatureManager::getInstance()->isFeatureAvailable("RenderVBOEnable") || - !gGLManager.mHasVertexBufferObject) - { - gSavedSettings.setBOOL("RenderVBOEnable", FALSE); - } LLVertexBuffer::initClass(gSavedSettings.getBOOL("RenderVBOEnable"), gSavedSettings.getBOOL("RenderVBOMappingDisable")); LL_INFOS("RenderInit") << "LLVertexBuffer initialization done." << LL_ENDL ; gGL.init() ; @@ -1997,11 +1969,6 @@ LLViewerWindow::LLViewerWindow(const Params& p) gSavedSettings.setBOOL("ProbeHardwareOnStartup", FALSE); } - if (!gGLManager.mHasDepthClamp) - { - LL_INFOS("RenderInit") << "Missing feature GL_ARB_depth_clamp. Void water might disappear in rare cases." << LL_ENDL; - } - // If we crashed while initializng GL stuff last time, disable certain features if (gSavedSettings.getBOOL("RenderInitError")) { diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index b7a5a0667b..9f43fb9b82 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -531,7 +531,7 @@ void LLVOSky::initCubeMap() images.push_back(mShinyTex[side].getImageRaw()); } - if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (!mCubeMap && gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { mCubeMap = new LLCubeMap(false); } @@ -576,7 +576,7 @@ void LLVOSky::restoreGL() updateDirections(psky); - if (gSavedSettings.getBOOL("RenderWater") && gGLManager.mHasCubeMap && LLCubeMap::sUseCubeMaps) + if (gSavedSettings.getBOOL("RenderWater") && LLCubeMap::sUseCubeMaps) { initCubeMap(); } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 61589640fe..ad1711d3fb 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -1121,27 +1121,7 @@ BOOL LLVOVolume::setVolume(const LLVolumeParams ¶ms_in, const S32 detail, bo } } - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - bool cache_in_vram = use_transform_feedback && gTransformPositionProgram.mProgramObject && - (!mVolumeImpl || !mVolumeImpl->isVolumeUnique()); - - if (cache_in_vram) - { //this volume might be used as source data for a transform object, put it in vram - LLVolume* volume = getVolume(); - for (S32 i = 0; i < volume->getNumFaces(); ++i) - { - const LLVolumeFace& face = volume->getVolumeFace(i); - if (face.mVertexBuffer.notNull()) - { //already cached - break; - } - volume->genTangents(i); - LLFace::cacheFaceInVRAM(face); - } - } - - return TRUE; + return TRUE; } else if (NO_LOD == lod) { @@ -6417,16 +6397,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace U32 geometryBytes = 0; U32 buffer_usage = group->mBufferUsage; - static LLCachedControl use_transform_feedback(gSavedSettings, "RenderUseTransformFeedback", false); - - if (use_transform_feedback && - gTransformPositionProgram.mProgramObject && //transform shaders are loaded - buffer_usage == GL_DYNAMIC_DRAW && //target buffer is in VRAM - !(mask & LLVertexBuffer::MAP_WEIGHT4)) //TODO: add support for weights - { - buffer_usage = GL_DYNAMIC_COPY; - } - #if LL_DARWIN // HACK from Leslie: // Disable VBO usage for alpha on Mac OS X because it kills the framerate diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 858cc90d04..f8ab68e57d 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -892,16 +892,7 @@ bool LLPipeline::allocateScreenBuffer(U32 resX, U32 resY, U32 samples) if (!mRT->occlusionDepth.allocate(resX/occlusion_divisor, resY/occlusion_divisor, 0, TRUE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (!addDeferredAttachments(mRT->deferredScreen)) return false; - GLuint screenFormat = GL_RGBA16; - if (gGLManager.mIsAMD) - { - screenFormat = GL_RGBA12; - } - - if (gGLManager.mGLVersion < 4.f && gGLManager.mIsNVIDIA) - { - screenFormat = GL_RGBA16F_ARB; - } + GLuint screenFormat = GL_RGBA; if (!mRT->screen.allocate(resX, resY, screenFormat, FALSE, FALSE, LLTexUnit::TT_RECT_TEXTURE, FALSE, samples)) return false; if (samples > 0) @@ -1065,8 +1056,7 @@ void LLPipeline::refreshCachedSettings() LLPipeline::sUseOcclusion = (!gUseWireframe && LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gSavedSettings.getBOOL("UseOcclusion") - && gGLManager.mHasOcclusionQuery) ? 2 : 0; + && gSavedSettings.getBOOL("UseOcclusion")) ? 2 : 0; WindLightUseAtmosShaders = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("WindLightUseAtmosShaders"); RenderDeferred = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderDeferred"); @@ -2355,8 +2345,7 @@ static LLTrace::BlockTimerStatHandle FTM_CULL("Object Culling"); void LLPipeline::updateCull(LLCamera& camera, LLCullResult& result, LLPlane* planep) { static LLCachedControl use_occlusion(gSavedSettings,"UseOcclusion"); - static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion") - && gGLManager.mHasOcclusionQuery; + static bool can_use_occlusion = LLFeatureManager::getInstance()->isFeatureAvailable("UseOcclusion"); LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_CULL); @@ -9759,7 +9748,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LLGLEnable cull(GL_CULL_FACE); //enable depth clamping if available - LLGLEnable depth_clamp(gGLManager.mHasDepthClamp ? GL_DEPTH_CLAMP : 0); + //LLGLEnable depth_clamp(GL_DEPTH_CLAMP); if (use_shader) { diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index eb4f9f16fa..825d1202a6 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -3099,8 +3099,6 @@ function="World.EnvPreset" - -- cgit v1.3 From 8f1d22686551f4d6783d03cd3685085ed7fcb96c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 23 Sep 2022 11:19:56 -0500 Subject: SL-18134 Rename Albedo to Base Color to be more consistent with GLTF spec --- indra/llprimitive/llgltfmaterial.h | 4 +- indra/newview/llface.cpp | 2 +- indra/newview/lllocalgltfmaterials.cpp | 12 +- indra/newview/lllocalgltfmaterials.h | 2 +- indra/newview/llmaterialeditor.cpp | 152 ++++++++++----------- indra/newview/llmaterialeditor.h | 24 ++-- indra/newview/llpanelface.cpp | 20 +-- indra/newview/lltinygltfhelper.cpp | 16 +-- indra/newview/lltinygltfhelper.h | 4 +- indra/newview/llviewerobject.cpp | 8 +- indra/newview/llviewerobject.h | 4 +- indra/newview/llvovolume.cpp | 4 +- .../default/xui/en/floater_material_editor.xml | 14 +- .../skins/default/xui/en/panel_tools_texture.xml | 4 +- 14 files changed, 135 insertions(+), 135 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index ab381ca55e..36636c3b4e 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -43,12 +43,12 @@ public: ALPHA_MODE_MASK }; - LLUUID mAlbedoId; + LLUUID mBaseColorId; LLUUID mNormalId; LLUUID mMetallicRoughnessId; LLUUID mEmissiveId; - LLColor4 mAlbedoColor = LLColor4(1,1,1,1); + LLColor4 mBaseColor = LLColor4(1,1,1,1); LLColor3 mEmissiveColor = LLColor3(0,0,0); F32 mMetallicFactor = 0.f; diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5562f1d057..5de8bda787 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1336,7 +1336,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (tep->getGLTFMaterial()) { - color = tep->getGLTFMaterial()->mAlbedoColor; + color = tep->getGLTFMaterial()->mBaseColor; } if (rebuild_color) diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 5373400e9d..524693e7ea 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -259,8 +259,8 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat) std::string folder = gDirUtilp->getDirName(filename_lc); tinygltf::Material material_in = model_in.materials[0]; - // get albedo texture - LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); + // get base color texture + LLPointer base_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index); // get normal map LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index); // get metallic-roughness texture @@ -276,12 +276,12 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat) // todo: pass it into local bitmaps? LLTinyGLTFHelper::initFetchedTextures(material_in, - albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mAlbedoFetched, mNormalFetched, mMRFetched, mEmissiveFetched); + base_img, normal_img, mr_img, emissive_img, occlusion_img, + mBaseColorFetched, mNormalFetched, mMRFetched, mEmissiveFetched); - if (mAlbedoFetched) + if (mBaseColorFetched) { - mat->mAlbedoId = mAlbedoFetched->getID(); + mat->mBaseColorId= mBaseColorFetched->getID(); } if (mNormalFetched) { diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 1bca06ba2a..de775615a8 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -79,7 +79,7 @@ private: /* members */ S32 mUpdateRetries; // material needs to maintain textures - LLPointer mAlbedoFetched; + LLPointer mBaseColorFetched; LLPointer mNormalFetched; LLPointer mMRFetched; LLPointer mEmissiveFetched; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 4efbf19572..12d21cf284 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -60,7 +60,7 @@ #include -const std::string MATERIAL_ALBEDO_DEFAULT_NAME = "Albedo"; +const std::string MATERIAL_BASE_COLOR_DEFAULT_NAME = "Base Color"; const std::string MATERIAL_NORMAL_DEFAULT_NAME = "Normal"; const std::string MATERIAL_METALLIC_DEFAULT_NAME = "Metallic Roughness"; const std::string MATERIAL_EMISSIVE_DEFAULT_NAME = "Emissive"; @@ -101,12 +101,12 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) BOOL LLMaterialEditor::postBuild() { - mAlbedoTextureCtrl = getChild("albedo_texture"); + mBaseColorTextureCtrl = getChild("base_color_texture"); mMetallicTextureCtrl = getChild("metallic_roughness_texture"); mEmissiveTextureCtrl = getChild("emissive_texture"); mNormalTextureCtrl = getChild("normal_texture"); - mAlbedoTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitAlbedoTexture, this, _1, _2)); + mBaseColorTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitBaseColorTexture, this, _1, _2)); mMetallicTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitMetallicTexture, this, _1, _2)); mEmissiveTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitEmissiveTexture, this, _1, _2)); mNormalTextureCtrl->setCommitCallback(boost::bind(&LLMaterialEditor::onCommitNormalTexture, this, _1, _2)); @@ -116,7 +116,7 @@ BOOL LLMaterialEditor::postBuild() childSetAction("cancel", boost::bind(&LLMaterialEditor::onClickCancel, this)); S32 upload_cost = LLAgentBenefitsMgr::current().getTextureUploadCost(); - getChild("albedo_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); + getChild("base_color_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("metallic_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("emissive_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); getChild("normal_upload_fee")->setTextArg("[FEE]", llformat("%d", upload_cost)); @@ -130,8 +130,8 @@ BOOL LLMaterialEditor::postBuild() childSetCommitCallback("double sided", changes_callback, NULL); - // Albedo - childSetCommitCallback("albedo color", changes_callback, NULL); + // BaseColor + childSetCommitCallback("base color", changes_callback, NULL); childSetCommitCallback("transparency", changes_callback, NULL); childSetCommitCallback("alpha mode", changes_callback, NULL); childSetCommitCallback("alpha cutoff", changes_callback, NULL); @@ -177,18 +177,18 @@ void LLMaterialEditor::onClose(bool app_quitting) LLPreview::onClose(app_quitting); } -LLUUID LLMaterialEditor::getAlbedoId() +LLUUID LLMaterialEditor::getBaseColorId() { - return mAlbedoTextureCtrl->getValue().asUUID(); + return mBaseColorTextureCtrl->getValue().asUUID(); } -void LLMaterialEditor::setAlbedoId(const LLUUID& id) +void LLMaterialEditor::setBaseColorId(const LLUUID& id) { - mAlbedoTextureCtrl->setValue(id); - mAlbedoTextureCtrl->setDefaultImageAssetID(id); + mBaseColorTextureCtrl->setValue(id); + mBaseColorTextureCtrl->setDefaultImageAssetID(id); } -void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) +void LLMaterialEditor::setBaseColorUploadId(const LLUUID& id) { // Might be better to use local textures and // assign a fee in case of a local texture @@ -196,23 +196,23 @@ void LLMaterialEditor::setAlbedoUploadId(const LLUUID& id) { // todo: this does not account for posibility of texture // being from inventory, need to check that - childSetValue("albedo_upload_fee", getString("upload_fee_string")); + childSetValue("base_color_upload_fee", getString("upload_fee_string")); // Only set if we will need to upload this texture - mAlbedoTextureUploadId = id; + mBaseColorTextureUploadId = id; } setHasUnsavedChanges(true); } -LLColor4 LLMaterialEditor::getAlbedoColor() +LLColor4 LLMaterialEditor::getBaseColor() { - LLColor4 ret = linearColor4(LLColor4(childGetValue("albedo color"))); + LLColor4 ret = linearColor4(LLColor4(childGetValue("base color"))); ret.mV[3] = getTransparency(); return ret; } -void LLMaterialEditor::setAlbedoColor(const LLColor4& color) +void LLMaterialEditor::setBaseColor(const LLColor4& color) { - childSetValue("albedo color", srgbColor4(color).getValue()); + childSetValue("base color", srgbColor4(color).getValue()); setTransparency(color.mV[3]); } @@ -370,7 +370,7 @@ void LLMaterialEditor::setHasUnsavedChanges(bool value) } S32 upload_texture_count = 0; - if (mAlbedoTextureUploadId.notNull() && mAlbedoTextureUploadId == getAlbedoId()) + if (mBaseColorTextureUploadId.notNull() && mBaseColorTextureUploadId == getBaseColorId()) { upload_texture_count++; } @@ -401,23 +401,23 @@ void LLMaterialEditor::setCanSave(BOOL value) childSetEnabled("save", value); } -void LLMaterialEditor::onCommitAlbedoTexture(LLUICtrl * ctrl, const LLSD & data) +void LLMaterialEditor::onCommitBaseColorTexture(LLUICtrl * ctrl, const LLSD & data) { // might be better to use arrays, to have a single callback // and not to repeat the same thing for each tecture control - LLUUID new_val = mAlbedoTextureCtrl->getValue().asUUID(); - if (new_val == mAlbedoTextureUploadId && mAlbedoTextureUploadId.notNull()) + LLUUID new_val = mBaseColorTextureCtrl->getValue().asUUID(); + if (new_val == mBaseColorTextureUploadId && mBaseColorTextureUploadId.notNull()) { - childSetValue("albedo_upload_fee", getString("upload_fee_string")); + childSetValue("base_color_upload_fee", getString("upload_fee_string")); } else { // Texture picker has 'apply now' with 'cancel' support. - // Keep mAlbedoJ2C and mAlbedoFetched, it's our storage in + // Keep mBaseColorJ2C and mBaseColorFetched, it's our storage in // case user decides to cancel changes. - // Without mAlbedoFetched, viewer will eventually cleanup + // Without mBaseColorFetched, viewer will eventually cleanup // the texture that is not in use - childSetValue("albedo_upload_fee", getString("no_upload_fee_string")); + childSetValue("base_color_upload_fee", getString("no_upload_fee_string")); } setHasUnsavedChanges(true); applyToSelection(); @@ -547,19 +547,19 @@ void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) model.materials.resize(1); tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; - // write albedo - LLColor4 albedo_color = getAlbedoColor(); - albedo_color.mV[3] = getTransparency(); - write_color(albedo_color, pbrMaterial.baseColorFactor); + // write base color + LLColor4 base_color = getBaseColor(); + base_color.mV[3] = getTransparency(); + write_color(base_color, pbrMaterial.baseColorFactor); model.materials[0].alphaCutoff = getAlphaCutoff(); model.materials[0].alphaMode = getAlphaMode(); - LLUUID albedo_id = getAlbedoId(); + LLUUID base_color_id = getBaseColorId(); - if (albedo_id.notNull()) + if (base_color_id.notNull()) { - U32 texture_idx = write_texture(albedo_id, model); + U32 texture_idx = write_texture(base_color_id, model); pbrMaterial.baseColorTexture.index = texture_idx; } @@ -677,9 +677,9 @@ const std::string LLMaterialEditor::buildMaterialDescription() // control UUI for NULL is a valid metric for if it was loaded // or not but I suspect this code will change a lot so may need // to revisit - if (!mAlbedoTextureCtrl->getValue().asUUID().isNull()) + if (!mBaseColorTextureCtrl->getValue().asUUID().isNull()) { - desc << mAlbedoName; + desc << mBaseColorName; desc << ", "; } if (!mMetallicTextureCtrl->getValue().asUUID().isNull()) @@ -1050,22 +1050,22 @@ void LLMaterialFilePicker::notify(const std::vector& filenames) } static void pack_textures( - LLPointer& albedo_img, + LLPointer& base_color_img, LLPointer& normal_img, LLPointer& mr_img, LLPointer& emissive_img, LLPointer& occlusion_img, - LLPointer& albedo_j2c, + LLPointer& base_color_j2c, LLPointer& normal_j2c, LLPointer& mr_j2c, LLPointer& emissive_j2c) { // NOTE : remove log spam and lossless vs lossy comparisons when the logs are no longer useful - if (albedo_img) + if (base_color_img) { - albedo_j2c = LLViewerTextureList::convertToUploadFile(albedo_img); - LL_INFOS() << "Albedo: " << albedo_j2c->getDataSize() << LL_ENDL; + base_color_j2c = LLViewerTextureList::convertToUploadFile(base_color_img); + LL_INFOS() << "BaseColor: " << base_color_j2c->getDataSize() << LL_ENDL; } if (normal_img) @@ -1146,8 +1146,8 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) model_out.asset.version = "2.0"; model_out.materials.resize(1); - // get albedo texture - LLPointer albedo_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mAlbedoName); + // get base color texture + LLPointer base_color_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.pbrMetallicRoughness.baseColorTexture.index, mBaseColorName); // get normal map LLPointer normal_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.normalTexture.index, mNormalName); // get metallic-roughness texture @@ -1162,20 +1162,20 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) occlusion_img = LLTinyGLTFHelper::getTexture(folder, model_in, material_in.occlusionTexture.index, tmp); } - LLTinyGLTFHelper::initFetchedTextures(material_in, albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mAlbedoFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); - pack_textures(albedo_img, normal_img, mr_img, emissive_img, occlusion_img, - mAlbedoJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); + LLTinyGLTFHelper::initFetchedTextures(material_in, base_color_img, normal_img, mr_img, emissive_img, occlusion_img, + mBaseColorFetched, mNormalFetched, mMetallicRoughnessFetched, mEmissiveFetched); + pack_textures(base_color_img, normal_img, mr_img, emissive_img, occlusion_img, + mBaseColorJ2C, mNormalJ2C, mMetallicRoughnessJ2C, mEmissiveJ2C); - LLUUID albedo_id; - if (mAlbedoFetched.notNull()) + LLUUID base_color_id; + if (mBaseColorFetched.notNull()) { - mAlbedoFetched->forceToSaveRawImage(0, F32_MAX); - albedo_id = mAlbedoFetched->getID(); + mBaseColorFetched->forceToSaveRawImage(0, F32_MAX); + base_color_id = mBaseColorFetched->getID(); - if (mAlbedoName.empty()) + if (mBaseColorName.empty()) { - mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; + mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; } } @@ -1215,8 +1215,8 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename) } } - setAlbedoId(albedo_id); - setAlbedoUploadId(albedo_id); + setBaseColorId(base_color_id); + setBaseColorUploadId(base_color_id); setMetallicRoughnessId(mr_id); setMetallicRoughnessUploadId(mr_id); setEmissiveId(emissive_id); @@ -1245,16 +1245,16 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture S32 index; LLUUID id; - // get albedo texture + // get base color texture index = material_in.pbrMetallicRoughness.baseColorTexture.index; if (index >= 0) { id.set(model.images[index].uri); - setAlbedoId(id); + setBaseColorId(id); } else { - setAlbedoId(LLUUID::null); + setBaseColorId(LLUUID::null); } // get normal map @@ -1297,7 +1297,7 @@ bool LLMaterialEditor::setFromGltfModel(tinygltf::Model& model, bool set_texture setAlphaMode(material_in.alphaMode); setAlphaCutoff(material_in.alphaCutoff); - setAlbedoColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor)); + setBaseColor(LLTinyGLTFHelper::getColor(material_in.pbrMetallicRoughness.baseColorFactor)); setEmissiveColor(LLTinyGLTFHelper::getColor(material_in.emissiveFactor)); setMetalnessFactor(material_in.pbrMetallicRoughness.metallicFactor); @@ -1331,7 +1331,7 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c stripped_uri = stripped_uri.substr(0, max_texture_name_length - 1); } - // We intend to append the type of texture (albedo, emissive etc.) to the + // We intend to append the type of texture (base color, emissive etc.) to the // name of the texture but sometimes the creator already did that. To try // to avoid repeats (not perfect), we look for the texture type in the name // and if we find it, do not append the type, later on. One way this fails @@ -1357,7 +1357,7 @@ const std::string LLMaterialEditor::getImageNameFromUri(std::string image_uri, c // so we can include everything if (stripped_uri.length() > 0) { - // example "DamagedHelmet: base layer (Albedo)" + // example "DamagedHelmet: base layer" return STRINGIZE( mMaterialNameShort << ": " << @@ -1476,17 +1476,17 @@ void LLMaterialEditor::setFromGltfMetaData(const std::string& filename, tinygltf { const tinygltf::Material& first_material = model.materials[0]; - mAlbedoName = MATERIAL_ALBEDO_DEFAULT_NAME; - // note: unlike the other textures, albedo doesn't have its own entry + mBaseColorName = MATERIAL_BASE_COLOR_DEFAULT_NAME; + // note: unlike the other textures, base color doesn't have its own entry // in the tinyGLTF Material struct. Rather, it is taken from a // sub-texture in the pbrMetallicRoughness member int index = first_material.pbrMetallicRoughness.baseColorTexture.index; if (index > -1 && index < model.images.size()) { // sanitize the name we decide to use for each texture - std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_ALBEDO_DEFAULT_NAME); + std::string texture_name = getImageNameFromUri(model.images[index].uri, MATERIAL_BASE_COLOR_DEFAULT_NAME); LLInventoryObject::correctInventoryName(texture_name); - mAlbedoName = texture_name; + mBaseColorName = texture_name; } mEmissiveName = MATERIAL_EMISSIVE_DEFAULT_NAME; @@ -1559,9 +1559,9 @@ void LLMaterialEditor::applyToSelection() void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) { - mat->mAlbedoColor = getAlbedoColor(); - mat->mAlbedoColor.mV[3] = getTransparency(); - mat->mAlbedoId = getAlbedoId(); + mat->mBaseColor = getBaseColor(); + mat->mBaseColor.mV[3] = getTransparency(); + mat->mBaseColorId = getBaseColorId(); mat->mNormalId = getNormalId(); @@ -1579,8 +1579,8 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) { - setAlbedoColor(mat->mAlbedoColor); - setAlbedoId(mat->mAlbedoId); + setBaseColor(mat->mBaseColor); + setBaseColorId(mat->mBaseColorId); setNormalId(mat->mNormalId); setMetallicRoughnessId(mat->mMetallicRoughnessId); @@ -1801,23 +1801,23 @@ S32 LLMaterialEditor::saveTextures() { S32 work_count = 0; LLSD key = getKey(); // must be locally declared for lambda's capture to work - if (mAlbedoTextureUploadId == getAlbedoId() && mAlbedoTextureUploadId.notNull()) + if (mBaseColorTextureUploadId == getBaseColorId() && mBaseColorTextureUploadId.notNull()) { mUploadingTexturesCount++; work_count++; - saveTexture(mAlbedoJ2C, mAlbedoName, mAlbedoTextureUploadId, [key](LLUUID newAssetId, LLSD response) + saveTexture(mBaseColorJ2C, mBaseColorName, mBaseColorTextureUploadId, [key](LLUUID newAssetId, LLSD response) { LLMaterialEditor* me = LLFloaterReg::findTypedInstance("material_editor", key); if (me) { if (response["success"].asBoolean()) { - me->setAlbedoId(newAssetId); + me->setBaseColorId(newAssetId); } else { // To make sure that we won't retry (some failures can cb immediately) - me->setAlbedoId(LLUUID::null); + me->setBaseColorId(LLUUID::null); } me->mUploadingTexturesCount--; @@ -1902,17 +1902,17 @@ S32 LLMaterialEditor::saveTextures() } // discard upload buffers once textures have been saved - mAlbedoJ2C = nullptr; + mBaseColorJ2C = nullptr; mNormalJ2C = nullptr; mEmissiveJ2C = nullptr; mMetallicRoughnessJ2C = nullptr; - mAlbedoFetched = nullptr; + mBaseColorFetched = nullptr; mNormalFetched = nullptr; mMetallicRoughnessFetched = nullptr; mEmissiveFetched = nullptr; - mAlbedoTextureUploadId.setNull(); + mBaseColorTextureUploadId.setNull(); mNormalTextureUploadId.setNull(); mMetallicTextureUploadId.setNull(); mEmissiveTextureUploadId.setNull(); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index cc72193a0e..0d741614b8 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -108,14 +108,14 @@ public: void onClose(bool app_quitting) override; - LLUUID getAlbedoId(); - void setAlbedoId(const LLUUID& id); - void setAlbedoUploadId(const LLUUID& id); + LLUUID getBaseColorId(); + void setBaseColorId(const LLUUID& id); + void setBaseColorUploadId(const LLUUID& id); - LLColor4 getAlbedoColor(); + LLColor4 getBaseColor(); - // sets both albedo color and transparency - void setAlbedoColor(const LLColor4& color); + // sets both base color and transparency + void setBaseColor(const LLColor4& color); F32 getTransparency(); void setTransparency(F32 transparency); @@ -156,7 +156,7 @@ public: void setCanSaveAs(BOOL value); void setCanSave(BOOL value); - void onCommitAlbedoTexture(LLUICtrl* ctrl, const LLSD& data); + void onCommitBaseColorTexture(LLUICtrl* ctrl, const LLSD& data); void onCommitMetallicTexture(LLUICtrl* ctrl, const LLSD& data); void onCommitEmissiveTexture(LLUICtrl* ctrl, const LLSD& data); void onCommitNormalTexture(LLUICtrl* ctrl, const LLSD& data); @@ -169,32 +169,32 @@ private: LLUUID mAssetID; LLUUID mObjectID; - LLTextureCtrl* mAlbedoTextureCtrl; + LLTextureCtrl* mBaseColorTextureCtrl; LLTextureCtrl* mMetallicTextureCtrl; LLTextureCtrl* mEmissiveTextureCtrl; LLTextureCtrl* mNormalTextureCtrl; // 'Default' texture, unless it's null or from inventory is the one with the fee - LLUUID mAlbedoTextureUploadId; + LLUUID mBaseColorTextureUploadId; LLUUID mMetallicTextureUploadId; LLUUID mEmissiveTextureUploadId; LLUUID mNormalTextureUploadId; // last known name of each texture - std::string mAlbedoName; + std::string mBaseColorName; std::string mNormalName; std::string mMetallicRoughnessName; std::string mEmissiveName; // keep pointers to fetched textures or viewer will remove them // if user temporary selects something else with 'apply now' - LLPointer mAlbedoFetched; + LLPointer mBaseColorFetched; LLPointer mNormalFetched; LLPointer mMetallicRoughnessFetched; LLPointer mEmissiveFetched; // J2C versions of packed buffers for uploading - LLPointer mAlbedoJ2C; + LLPointer mBaseColorJ2C; LLPointer mNormalJ2C; LLPointer mMetallicRoughnessJ2C; LLPointer mEmissiveJ2C; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f7eff39da7..a4a91baad8 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -105,7 +105,7 @@ const S32 MATTYPE_SPECULAR = 2; // Specular map const S32 ALPHAMODE_MASK = 2; // Alpha masking mode const S32 BUMPY_TEXTURE = 18; // use supplied normal map const S32 SHINY_TEXTURE = 4; // use supplied specular map -const S32 PBRTYPE_ALBEDO = 0; // PBR Albedo +const S32 PBRTYPE_BASE_COLOR = 0; // PBR Base Color const S32 PBRTYPE_NORMAL = 1; // PBR Normal const S32 PBRTYPE_METALLIC = 2; // PBR Metallic @@ -344,7 +344,7 @@ BOOL LLPanelFace::postBuild() if (radio_pbr_type) { radio_pbr_type->setCommitCallback(LLPanelFace::onCommitPbrType, this); - radio_pbr_type->selectNthItem(PBRTYPE_ALBEDO); + radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR); } mCtrlGlow = getChild("glow"); @@ -897,9 +897,9 @@ void LLPanelFace::updateUI(bool force_set_values /*false*/) radio_mat_type->setEnabled(editable); LLRadioGroup* radio_pbr_type = getChild("radio_pbr_type"); - if (radio_pbr_type->getSelectedIndex() < PBRTYPE_ALBEDO) + if (radio_pbr_type->getSelectedIndex() < PBRTYPE_BASE_COLOR) { - radio_pbr_type->selectNthItem(PBRTYPE_ALBEDO); + radio_pbr_type->selectNthItem(PBRTYPE_BASE_COLOR); } radio_pbr_type->setEnabled(editable); @@ -2570,7 +2570,7 @@ void LLPanelFace::updateVisibility() bool show_texture = (show_media || (show_material && (material_type == MATTYPE_DIFFUSE) && mComboMatMedia->getEnabled())); bool show_bumpiness = show_material && (material_type == MATTYPE_NORMAL) && mComboMatMedia->getEnabled(); bool show_shininess = show_material && (material_type == MATTYPE_SPECULAR) && mComboMatMedia->getEnabled(); - bool show_pbr_albedo = show_pbr && (pbr_type == PBRTYPE_ALBEDO) && mComboMatMedia->getEnabled(); + bool show_pbr_base_color = show_pbr && (pbr_type == PBRTYPE_BASE_COLOR) && mComboMatMedia->getEnabled(); bool show_pbr_normal = show_pbr && (pbr_type == PBRTYPE_NORMAL) && mComboMatMedia->getEnabled(); bool show_pbr_metallic = show_pbr && (pbr_type == PBRTYPE_METALLIC) && mComboMatMedia->getEnabled(); @@ -2594,11 +2594,11 @@ void LLPanelFace::updateVisibility() updateAlphaControls(); } // texture scale and position controls are shared between bpr and non-pbr textures - getChildView("TexScaleU")->setVisible(show_texture || show_pbr_albedo); - getChildView("TexScaleV")->setVisible(show_texture || show_pbr_albedo); - getChildView("TexRot")->setVisible(show_texture || show_pbr_albedo); - getChildView("TexOffsetU")->setVisible(show_texture || show_pbr_albedo); - getChildView("TexOffsetV")->setVisible(show_texture || show_pbr_albedo); + getChildView("TexScaleU")->setVisible(show_texture || show_pbr_base_color); + getChildView("TexScaleV")->setVisible(show_texture || show_pbr_base_color); + getChildView("TexRot")->setVisible(show_texture || show_pbr_base_color); + getChildView("TexOffsetU")->setVisible(show_texture || show_pbr_base_color); + getChildView("TexOffsetV")->setVisible(show_texture || show_pbr_base_color); // Specular map controls getChildView("shinytexture control")->setVisible(show_shininess); diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index 935f8e7794..3125cacbd5 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -62,19 +62,19 @@ void copy_red_channel(LLPointer& src_img, LLPointer& dst } void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material, - LLPointer& albedo_img, + LLPointer& base_color_img, LLPointer& normal_img, LLPointer& mr_img, LLPointer& emissive_img, LLPointer& occlusion_img, - LLPointer& albedo_tex, + LLPointer& base_color_tex, LLPointer& normal_tex, LLPointer& mr_tex, LLPointer& emissive_tex) { - if (albedo_img) + if (base_color_img) { - albedo_tex = LLViewerTextureManager::getFetchedTexture(albedo_img, FTType::FTT_LOCAL_FILE, true); + base_color_tex = LLViewerTextureManager::getFetchedTexture(base_color_img, FTType::FTT_LOCAL_FILE, true); } if (normal_img) @@ -128,15 +128,15 @@ void LLTinyGLTFHelper::setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model) auto& material_in = model.materials[0]; - // get albedo texture + // get base color texture index = material_in.pbrMetallicRoughness.baseColorTexture.index; if (index >= 0) { - mat->mAlbedoId.set(model.images[index].uri); + mat->mBaseColorId.set(model.images[index].uri); } else { - mat->mAlbedoId.setNull(); + mat->mBaseColorId.setNull(); } // get normal map @@ -175,7 +175,7 @@ void LLTinyGLTFHelper::setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model) mat->setAlphaMode(material_in.alphaMode); mat->mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); - mat->mAlbedoColor = getColor(material_in.pbrMetallicRoughness.baseColorFactor); + mat->mBaseColor= getColor(material_in.pbrMetallicRoughness.baseColorFactor); mat->mEmissiveColor = getColor(material_in.emissiveFactor); mat->mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index a25fdac41d..89e09b189e 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -42,12 +42,12 @@ namespace LLTinyGLTFHelper LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index); void initFetchedTextures(tinygltf::Material& material, - LLPointer& albedo_img, + LLPointer& base_color_img, LLPointer& normal_img, LLPointer& mr_img, LLPointer& emissive_img, LLPointer& occlusion_img, - LLPointer& albedo_tex, + LLPointer& base_color_tex, LLPointer& normal_tex, LLPointer& mr_tex, LLPointer& emissive_tex); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index f9c8f396a2..4e866658a6 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -415,7 +415,7 @@ void LLViewerObject::deleteTEImages() mTESpecularMaps = NULL; } - mGLTFAlbedoMaps.clear(); + mGLTFBaseColorMaps.clear(); mGLTFNormalMaps.clear(); mGLTFMetallicRoughnessMaps.clear(); mGLTFEmissiveMaps.clear(); @@ -4753,7 +4753,7 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; - mGLTFAlbedoMaps.resize(num_tes); + mGLTFBaseColorMaps.resize(num_tes); mGLTFNormalMaps.resize(num_tes); mGLTFMetallicRoughnessMaps.resize(num_tes); mGLTFEmissiveMaps.resize(num_tes); @@ -4943,14 +4943,14 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) if (mat != nullptr) { - mGLTFAlbedoMaps[te] = fetch_texture(mat->mAlbedoId); + mGLTFBaseColorMaps[te] = fetch_texture(mat->mBaseColorId); mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId); mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId); mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId); } else { - mGLTFAlbedoMaps[te] = nullptr; + mGLTFBaseColorMaps[te] = nullptr; mGLTFNormalMaps[te] = nullptr; mGLTFMetallicRoughnessMaps[te] = nullptr; mGLTFEmissiveMaps[te] = nullptr; diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 32f03c7869..1bb67fa80f 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -371,7 +371,7 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; - LLViewerTexture* getGLTFAlbedoMap(U8 te) const { return mGLTFAlbedoMaps[te]; } + LLViewerTexture* getGLTFBaseColorMap(U8 te) const { return mGLTFBaseColorMaps[te]; } LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } @@ -693,7 +693,7 @@ public: LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; - std::vector > mGLTFAlbedoMaps; + std::vector > mGLTFBaseColorMaps; std::vector > mGLTFNormalMaps; std::vector > mGLTFMetallicRoughnessMaps; std::vector > mGLTFEmissiveMaps; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index ad1711d3fb..d18997b780 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5520,13 +5520,13 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLViewerObject* vobj = facep->getViewerObject(); U8 te = facep->getTEOffset(); - draw_info->mTexture = vobj->getGLTFAlbedoMap(te); + draw_info->mTexture = vobj->getGLTFBaseColorMap(te); draw_info->mNormalMap = vobj->getGLTFNormalMap(te); draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); if (draw_info->mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) { - draw_info->mAlphaMaskCutoff = gltf_mat->mAlphaCutoff * gltf_mat->mAlbedoColor.mV[3]; + draw_info->mAlphaMaskCutoff = gltf_mat->mAlphaCutoff * gltf_mat->mBaseColor.mV[3]; } else { diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index eda28c5a4b..67cbb253d9 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -50,7 +50,7 @@ layout="topleft" left="1" mouse_opaque="false" - name="albedo_texture_pnl" + name="base_color_texture_pnl" top_pad="5" > - Albedo: + width="128"> + Base Color: No upload fee @@ -111,7 +111,7 @@ layout="topleft" left_delta="0" top_pad="5" - name="albedo color" + name="base color" width="40" /> Date: Fri, 23 Sep 2022 12:53:24 -0500 Subject: SL-18156 Cleanup of MikktSpace integration, apply MikktSpace tangents to all meshes. --- indra/llmath/llvolume.cpp | 77 ++++++++++++--------------------- indra/llmath/llvolume.h | 6 +-- indra/llprimitive/lldaeloader.cpp | 2 +- indra/llprimitive/llmodel.cpp | 16 +++---- indra/newview/app_settings/settings.xml | 11 ----- indra/newview/llface.cpp | 16 ++----- indra/newview/llmodelpreview.cpp | 3 +- 7 files changed, 43 insertions(+), 88 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llvolume.cpp b/indra/llmath/llvolume.cpp index 454969b912..21df7f2b2d 100644 --- a/indra/llmath/llvolume.cpp +++ b/indra/llmath/llvolume.cpp @@ -2102,14 +2102,11 @@ void LLVolume::regen() createVolumeFaces(); } -void LLVolume::genTangents(S32 face, bool mikktspace) +void LLVolume::genTangents(S32 face) { // generate legacy tangents for the specified face - // if mikktspace is true, only generate tangents if mikktspace tangents are not present (handles the case for non-mesh prims) - if (!mikktspace || mVolumeFaces[face].mMikktSpaceTangents == nullptr) - { - mVolumeFaces[face].createTangents(); - } + llassert(!isMeshAssetLoaded() || mVolumeFaces[face].mTangents != nullptr); // if this is a complete mesh asset, we should already have tangents + mVolumeFaces[face].createTangents(); } LLVolume::~LLVolume() @@ -2492,15 +2489,7 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) { face.mNormalizedScale.set(1, 1, 1); } - if (mdl[i].has("NormalizedTranslation")) - { - face.mNormalizedTranslation.setValue(mdl[i]["NormalizedTranslation"]); - } - else - { - face.mNormalizedTranslation.set(1, 1, 1); - } - + LLVector4a pos_range; pos_range.setSub(max_pos, min_pos); LLVector2 tc_range2 = max_tc - min_tc; @@ -2551,17 +2540,16 @@ bool LLVolume::unpackVolumeFaces(std::istream& is, S32 size) } } -#if 0 +#if 0 // keep this code for now in case we decide to add support for on-the-wire tangents { if (!tangent.empty()) { - face.allocateTangents(face.mNumVertices, true); + face.allocateTangents(face.mNumVertices); U16* t = (U16*)&(tangent[0]); - // store incoming tangents in mMikktSpaceTangents - // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the CLTF shaders to + // NOTE: tangents coming from the asset may not be mikkt space, but they should always be used by the GLTF shaders to // maintain compliance with the GLTF spec - LLVector4a* t_out = face.mMikktSpaceTangents; + LLVector4a* t_out = face.mTangents; for (U32 j = 0; j < num_verts; ++j) { @@ -4111,7 +4099,7 @@ S32 LLVolume::lineSegmentIntersect(const LLVector4a& start, const LLVector4a& en { if (tangent_out != NULL) // if the caller wants tangents, we may need to generate them { - genTangents(i); + genTangents(i); } if (isUnique()) @@ -4854,15 +4842,15 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mTangents = NULL; } - if (src.mMikktSpaceTangents) + if (src.mTangents) { - allocateTangents(src.mNumVertices, true); - LLVector4a::memcpyNonAliased16((F32*)mMikktSpaceTangents, (F32*)src.mMikktSpaceTangents, vert_size); + allocateTangents(src.mNumVertices); + LLVector4a::memcpyNonAliased16((F32*)mTangents, (F32*)src.mTangents, vert_size); } else { - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; + ll_aligned_free_16(mTangents); + mTangents = nullptr; } if (src.mWeights) @@ -4909,8 +4897,7 @@ LLVolumeFace& LLVolumeFace::operator=(const LLVolumeFace& src) mOptimized = src.mOptimized; mNormalizedScale = src.mNormalizedScale; - mNormalizedTranslation = src.mNormalizedTranslation; - + //delete return *this; } @@ -4937,8 +4924,6 @@ void LLVolumeFace::freeData() mIndices = NULL; ll_aligned_free_16(mTangents); mTangents = NULL; - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; ll_aligned_free_16(mWeights); mWeights = NULL; @@ -5060,9 +5045,6 @@ void LLVolumeFace::remap() ll_aligned_free_16(mTangents); mTangents = NULL; - ll_aligned_free_16(mMikktSpaceTangents); - mMikktSpaceTangents = nullptr; - // Assign new values mIndices = remap_indices; mPositions = remap_positions; @@ -5484,10 +5466,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) llassert(!mOptimized); mOptimized = TRUE; - if (mMikktSpaceTangents == nullptr && gen_tangents && mNormals && mTexCoords) - { // make sure to generate mikkt space tangents for cache optimizing since the index buffer may change - allocateTangents(mNumVertices, true); - + if (gen_tangents && mNormals && mTexCoords) + { // generate mikkt space tangents before cache optimizing since the index buffer may change + // a bit of a hack to do this here, but this function gets called exactly once for the lifetime of a mesh + // and is executed on a background thread SMikkTSpaceInterface ms; ms.m_getNumFaces = [](const SMikkTSpaceContext* pContext) @@ -5573,7 +5555,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) allocateWeights(vert_count); } - allocateTangents(mNumVertices, true); + allocateTangents(mNumVertices); for (int i = 0; i < mNumIndices; ++i) { @@ -5585,7 +5567,7 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) mNormals[dst_idx].load3(data.n[src_idx].mV); mTexCoords[dst_idx] = data.tc[src_idx]; - mMikktSpaceTangents[dst_idx].loadua(data.t[src_idx].mV); + mTangents[dst_idx].loadua(data.t[src_idx].mV); if (mWeights) { @@ -5605,10 +5587,10 @@ bool LLVolumeFace::cacheOptimize(bool gen_tangents) mPositions[i].mul(inv_scale); mNormals[i].mul(scale); mNormals[i].normalize3(); - F32 w = mMikktSpaceTangents[i].getF32ptr()[3]; - mMikktSpaceTangents[i].mul(scale); - mMikktSpaceTangents[i].normalize3(); - mMikktSpaceTangents[i].getF32ptr()[3] = w; + F32 w = mTangents[i].getF32ptr()[3]; + mTangents[i].mul(scale); + mTangents[i].normalize3(); + mTangents[i].getF32ptr()[3] = w; } } @@ -5703,7 +5685,6 @@ void LLVolumeFace::swapData(LLVolumeFace& rhs) llswap(rhs.mPositions, mPositions); llswap(rhs.mNormals, mNormals); llswap(rhs.mTangents, mTangents); - llswap(rhs.mMikktSpaceTangents, mMikktSpaceTangents); llswap(rhs.mTexCoords, mTexCoords); llswap(rhs.mIndices,mIndices); llswap(rhs.mNumVertices, mNumVertices); @@ -6415,7 +6396,6 @@ void LLVolumeFace::createTangents() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - if (!mTangents) { allocateTangents(mNumVertices); @@ -6539,11 +6519,10 @@ void LLVolumeFace::pushVertex(const LLVector4a& pos, const LLVector4a& norm, con mNumVertices++; } -void LLVolumeFace::allocateTangents(S32 num_verts, bool mikktspace) +void LLVolumeFace::allocateTangents(S32 num_verts) { - auto& buff = mikktspace ? mMikktSpaceTangents : mTangents; - ll_aligned_free_16(buff); - buff = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); + ll_aligned_free_16(mTangents); + mTangents = (LLVector4a*) ll_aligned_malloc_16(sizeof(LLVector4a)*num_verts); } void LLVolumeFace::allocateWeights(S32 num_verts) diff --git a/indra/llmath/llvolume.h b/indra/llmath/llvolume.h index 6ea12c6920..3aa7034357 100644 --- a/indra/llmath/llvolume.h +++ b/indra/llmath/llvolume.h @@ -873,7 +873,7 @@ public: void createTangents(); void resizeVertices(S32 num_verts); - void allocateTangents(S32 num_verts, bool mikktspace = false); + void allocateTangents(S32 num_verts); void allocateWeights(S32 num_verts); void allocateJointIndices(S32 num_verts); void resizeIndices(S32 num_indices); @@ -947,7 +947,6 @@ public: LLVector4a* mPositions; // Contains vertices, nortmals and texcoords LLVector4a* mNormals; // pointer into mPositions LLVector4a* mTangents; - LLVector4a* mMikktSpaceTangents = nullptr; // for GLTF rendering, use mikkt space tangents LLVector2* mTexCoords; // pointer into mPositions // mIndices contains mNumIndices amount of elements. @@ -984,7 +983,6 @@ public: // when encoding the source mesh into a unit cube // used for regenerating tangents LLVector3 mNormalizedScale = LLVector3(1,1,1); - LLVector3 mNormalizedTranslation; private: BOOL createUnCutCubeCap(LLVolume* volume, BOOL partial_build = FALSE); @@ -1031,7 +1029,7 @@ public: void setDirty() { mPathp->setDirty(); mProfilep->setDirty(); } void regen(); - void genTangents(S32 face, bool mikktspace = false); + void genTangents(S32 face); BOOL isConvex() const; BOOL isCap(S32 face); diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index dbb34ab60b..73b97cec08 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2581,7 +2581,7 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod]; next->getVolumeFaces() = remainder; next->mNormalizedScale = ret->mNormalizedScale; - next->mNormalizedTranslation = ret->mNormalizedTranslation; + if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) { next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end()); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index a6492f43d4..33d52d89bd 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -53,7 +53,6 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) : LLVolume(params, detail), mNormalizedScale(1,1,1), - mNormalizedTranslation(0,0,0), mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) @@ -296,7 +295,7 @@ void LLModel::normalizeVolumeFaces() // the positions to fit within the unit cube. LLVector4a* pos = (LLVector4a*) face.mPositions; LLVector4a* norm = (LLVector4a*) face.mNormals; - LLVector4a* t = (LLVector4a*)face.mMikktSpaceTangents; + LLVector4a* t = (LLVector4a*)face.mTangents; for (U32 j = 0; j < face.mNumVertices; ++j) { @@ -329,10 +328,10 @@ void LLModel::normalizeVolumeFaces() mNormalizedTranslation.set(trans.getF32ptr()); mNormalizedTranslation *= -1.f; + // remember normalized scale so original dimensions can be recovered for mesh processing (i.e. tangent generation) for (auto& face : mVolumeFaces) { face.mNormalizedScale = mNormalizedScale; - face.mNormalizedTranslation = mNormalizedTranslation; } } } @@ -800,10 +799,10 @@ LLSD LLModel::writeModel( } } -#if 0 - if (face.mMikktSpaceTangents) +#if 0 // keep this code for now in case we want to support transporting tangents with mesh assets + if (face.mTangents) { //normals - F32* tangent = face.mMikktSpaceTangents[j].getF32ptr(); + F32* tangent = face.mTangents[j].getF32ptr(); for (U32 k = 0; k < 4; ++k) { //for each component @@ -848,7 +847,6 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["PositionDomain"]["Min"] = min_pos.getValue(); mdl[model_names[idx]][i]["PositionDomain"]["Max"] = max_pos.getValue(); mdl[model_names[idx]][i]["NormalizedScale"] = face.mNormalizedScale.getValue(); - mdl[model_names[idx]][i]["NormalizedTranslation"] = face.mNormalizedTranslation.getValue(); mdl[model_names[idx]][i]["Position"] = verts; @@ -857,10 +855,12 @@ LLSD LLModel::writeModel( mdl[model_names[idx]][i]["Normal"] = normals; } - if (face.mMikktSpaceTangents) +#if 0 // keep this code for now in case we decide to transport tangents with mesh assets + if (face.mTangents) { mdl[model_names[idx]][i]["Tangent"] = tangents; } +#endif if (face.mTexCoords) { diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 01271ddc28..f183f49039 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10558,17 +10558,6 @@ Value 0 - RenderUseMikktSpace - - Comment - Use Mikkt Space tangents on GLTF materials. - Persist - 1 - Type - Boolean - Value - 1 - RenderUseTriStrips Comment diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 5de8bda787..b24bc69791 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1968,24 +1968,14 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); F32* tangents = (F32*) tangent.get(); - LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial(); - static LLCachedControl use_mikktspace(gSavedSettings, "RenderUseMikktSpace"); - bool mikktspace = use_mikktspace && gltf_mat != nullptr; - - mVObjp->getVolume()->genTangents(f, mikktspace); + mVObjp->getVolume()->genTangents(f); LLVector4Logical mask; mask.clear(); mask.setElement<3>(); - LLVector4a* tbuff = mikktspace ? vf.mMikktSpaceTangents : vf.mTangents; - if (tbuff == nullptr) - { // non-mesh prims will not have mikktspace tangents - tbuff = vf.mTangents; - } - - LLVector4a* src = tbuff; - LLVector4a* end = tbuff+num_vertices; + LLVector4a* src = vf.mTangents; + LLVector4a* end = vf.mTangents +num_vertices; while (src < end) { diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 076ebd80c2..aa3446a308 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -1549,7 +1549,7 @@ F32 LLModelPreview::genMeshOptimizerPerModel(LLModel *base_model, LLModel *targe { new_face.resizeIndices(buf_indices_copied); new_face.resizeVertices(buf_positions_copied); - new_face.allocateTangents(buf_positions_copied, true); + new_face.allocateTangents(buf_positions_copied); S32 idx_size = (buf_indices_copied * sizeof(U16) + 0xF) & ~0xF; LLVector4a::memcpyNonAliased16((F32*)new_face.mIndices, (F32*)buffer_indices, idx_size); @@ -1839,7 +1839,6 @@ void LLModelPreview::genMeshOptimizerLODs(S32 which_lod, S32 meshopt_mode, U32 d LLVolumeFace& src = base->getVolumeFace(i); LLVolumeFace& dst = target_model->getVolumeFace(i); dst.mNormalizedScale = src.mNormalizedScale; - dst.mNormalizedTranslation = src.mNormalizedTranslation; } S32 model_meshopt_mode = meshopt_mode; -- cgit v1.3 From f6762c3de57434730a2cbf6d0241bf1db5c9346c Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 14 Oct 2022 17:35:48 -0500 Subject: SL-18105 Add to/from json capability to LLGLTFMaterial --- indra/llmath/v3color.h | 32 ++++++ indra/llmath/v4color.h | 29 +++++ indra/llprimitive/CMakeLists.txt | 1 + indra/llprimitive/llgltfmaterial.cpp | 199 +++++++++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 34 +++++- indra/newview/llgltfmateriallist.cpp | 13 +-- indra/newview/lllocalgltfmaterials.cpp | 2 +- indra/newview/lltinygltfhelper.cpp | 65 ----------- indra/newview/lltinygltfhelper.h | 1 - 9 files changed, 293 insertions(+), 83 deletions(-) create mode 100644 indra/llprimitive/llgltfmaterial.cpp (limited to 'indra/llprimitive') diff --git a/indra/llmath/v3color.h b/indra/llmath/v3color.h index 0b3b4ea3e1..d925f56e97 100644 --- a/indra/llmath/v3color.h +++ b/indra/llmath/v3color.h @@ -88,6 +88,16 @@ public: const LLColor3& set(F32 x, F32 y, F32 z); // Sets LLColor3 to (x, y, z) const LLColor3& set(const LLColor3 &vec); // Sets LLColor3 to vec const LLColor3& set(const F32 *vec); // Sets LLColor3 to vec + + // set from a vector of unknown type and size + // may leave some data unmodified + template + const LLColor3& set(const std::vector& v); + + // write to a vector of unknown type and size + // maye leave some data unmodified + template + void write(std::vector& v) const; F32 magVec() const; // deprecated F32 magVecSquared() const; // deprecated @@ -504,4 +514,26 @@ inline const LLVector3 linearColor3v(const T& a) { return LLVector3(linearColor3p(a.mV).mV); } +template +const LLColor3& LLColor3::set(const std::vector& v) +{ + for (S32 i = 0; i < llmin((S32)v.size(), 3); ++i) + { + mV[i] = v[i]; + } + + return *this; +} + +// write to a vector of unknown type and size +// maye leave some data unmodified +template +void LLColor3::write(std::vector& v) const +{ + for (int i = 0; i < llmin((S32)v.size(), 3); ++i) + { + v[i] = mV[i]; + } +} + #endif diff --git a/indra/llmath/v4color.h b/indra/llmath/v4color.h index f2863be531..daa61594fb 100644 --- a/indra/llmath/v4color.h +++ b/indra/llmath/v4color.h @@ -91,6 +91,15 @@ class LLColor4 const LLColor4& set(const F64 *vec); // Sets LLColor4 to (double)vec const LLColor4& set(const LLColor4U& color4u); // Sets LLColor4 to color4u, rescaled. + // set from a vector of unknown type and size + // may leave some data unmodified + template + const LLColor4& set(const std::vector& v); + + // write to a vector of unknown type and size + // maye leave some data unmodified + template + void write(std::vector& v) const; const LLColor4& setAlpha(F32 a); @@ -690,5 +699,25 @@ inline const LLColor4 linearColor4(const LLColor4 &a) return linearColor; } +template +const LLColor4& LLColor4::set(const std::vector& v) +{ + for (S32 i = 0; i < llmin((S32)v.size(), 4); ++i) + { + mV[i] = v[i]; + } + + return *this; +} + +template +void LLColor4::write(std::vector& v) const +{ + for (int i = 0; i < llmin((S32)v.size(), 4); ++i) + { + v[i] = mV[i]; + } +} + #endif diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index bb14bb9242..328b22f900 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -33,6 +33,7 @@ include_directories(SYSTEM set(llprimitive_SOURCE_FILES lldaeloader.cpp llgltfloader.cpp + llgltfmaterial.cpp llmaterialid.cpp llmaterial.cpp llmaterialtable.cpp diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp new file mode 100644 index 0000000000..369a1786a3 --- /dev/null +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -0,0 +1,199 @@ +/** + * @file llgltfmaterial.cpp + * @brief Material definition + * + * $LicenseInfo:firstyear=2022&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2022, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgltfmaterial.h" + +#include "tiny_gltf.h" + +bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) +{ + tinygltf::TinyGLTF gltf; + + tinygltf::Model model_in; + + if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), "")) + { + setFromModel(model_in, 0); + + //DEBUG generate json and print + LL_INFOS() << asJSON(true) << LL_ENDL; + + return true; + } + + return false; +} + +std::string LLGLTFMaterial::asJSON(bool prettyprint) const +{ + tinygltf::TinyGLTF gltf; + tinygltf::Model model_out; + + std::ostringstream str; + + writeToModel(model_out, 0); + + gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); + + return str.str(); +} + +void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) +{ + if (model.materials.size() <= mat_index) + { + return; + } + + const tinygltf::Material& material_in = model.materials[mat_index]; + + // get base color texture + S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; + if (tex_index >= 0) + { + mBaseColorId.set(model.images[tex_index].uri); + } + else + { + mBaseColorId.setNull(); + } + + // get normal map + tex_index = material_in.normalTexture.index; + if (tex_index >= 0) + { + mNormalId.set(model.images[tex_index].uri); + } + else + { + mNormalId.setNull(); + } + + // get metallic-roughness texture + tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; + if (tex_index >= 0) + { + mMetallicRoughnessId.set(model.images[tex_index].uri); + } + else + { + mMetallicRoughnessId.setNull(); + } + + // get emissive texture + tex_index = material_in.emissiveTexture.index; + if (tex_index >= 0) + { + mEmissiveId.set(model.images[tex_index].uri); + } + else + { + mEmissiveId.setNull(); + } + + setAlphaMode(material_in.alphaMode); + mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); + + mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor); + mEmissiveColor.set(material_in.emissiveFactor); + + mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); + mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); + + mDoubleSided = material_in.doubleSided; +} + +void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const +{ + if (model.materials.size() < mat_index+1) + { + model.materials.resize(mat_index + 1); + } + + tinygltf::Material& material_out = model.materials[mat_index]; + + // set base color texture + if (mBaseColorId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.baseColorTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mBaseColorId.asString(); + } + + // set normal texture + if (mNormalId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.normalTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mNormalId.asString(); + } + + // set metallic-roughness texture + if (mMetallicRoughnessId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mMetallicRoughnessId.asString(); + } + + // set emissive texture + if (mEmissiveId.notNull()) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.emissiveTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mEmissiveId.asString(); + } + + material_out.alphaMode = getAlphaMode(); + material_out.alphaCutoff = mAlphaCutoff; + + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); + mEmissiveColor.write(material_out.emissiveFactor); + + material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; + material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; + + material_out.doubleSided = mDoubleSided; +} + diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 36636c3b4e..8efcc9d753 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -32,6 +32,13 @@ #include "lluuid.h" #include "llmd5.h" +#include + +namespace tinygltf +{ + class Model; +} + class LLGLTFMaterial : public LLRefCount { public: @@ -48,8 +55,8 @@ public: LLUUID mMetallicRoughnessId; LLUUID mEmissiveId; - LLColor4 mBaseColor = LLColor4(1,1,1,1); - LLColor3 mEmissiveColor = LLColor3(0,0,0); + LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); + LLColor3 mEmissiveColor = LLColor3(0, 0, 0); F32 mMetallicFactor = 0.f; F32 mRoughnessFactor = 0.f; @@ -63,7 +70,7 @@ public: { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; LLMD5 md5; - md5.update((unsigned char*) this, sizeof(this)); + md5.update((unsigned char*)this, sizeof(this)); md5.finalize(); LLUUID id; md5.raw_digest(id.mData); @@ -88,7 +95,7 @@ public: } } - const char* getAlphaMode() + const char* getAlphaMode() const { switch (mAlphaMode) { @@ -97,7 +104,24 @@ public: default: return "OPAQUE"; } } -}; + // set the contents of this LLGLTFMaterial from the given json + // returns true if successful + // json - the json text to load from + // warn_msg - warning message from TinyGLTF if any + // error_msg - error_msg from TinyGLTF if any + bool fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg); + // get the contents of this LLGLTFMaterial as a json string + std::string asJSON(bool prettyprint = false) const; + + // initialize from given tinygltf::Model + // model - the model to reference + // mat_index - index of material in model's material array + void setFromModel(const tinygltf::Model& model, S32 mat_index); + + // write to given tinygltf::Model + void writeToModel(tinygltf::Model& model, S32 mat_index) const; + +}; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 5cbf853179..a5d2be2d4e 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -83,18 +83,9 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { std::string data = asset["data"]; - tinygltf::TinyGLTF gltf; - tinygltf::TinyGLTF loader; - std::string error_msg; - std::string warn_msg; + std::string warn_msg, error_msg; - tinygltf::Model model_in; - - if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) - { - LLTinyGLTFHelper::setFromModel(mat, model_in, 0); - } - else + if (!mat->fromJSON(data, warn_msg, error_msg)) { LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; LL_WARNS() << warn_msg << LL_ENDL; diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 1f16549a47..fe2b7ac816 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -270,7 +270,7 @@ bool LLLocalGLTFMaterial::loadMaterial(LLPointer mat, S32 index) } // sets everything, but textures will have inaccurate ids - LLTinyGLTFHelper::setFromModel(mat, model_in, index); + mat->setFromModel(model_in, index); std::string folder = gDirUtilp->getDirName(filename_lc); tinygltf::Material material_in = model_in.materials[index]; diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index c3dc10c2a0..c80e87652a 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -122,71 +122,6 @@ void LLTinyGLTFHelper::initFetchedTextures(tinygltf::Material& material, } } -void LLTinyGLTFHelper::setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 mat_index) -{ - if (model.materials.size() <= mat_index) - { - return; - } - - tinygltf::Material& material_in = model.materials[mat_index]; - - // get base color texture - S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; - if (tex_index >= 0) - { - mat->mBaseColorId.set(model.images[tex_index].uri); - } - else - { - mat->mBaseColorId.setNull(); - } - - // get normal map - tex_index = material_in.normalTexture.index; - if (tex_index >= 0) - { - mat->mNormalId.set(model.images[tex_index].uri); - } - else - { - mat->mNormalId.setNull(); - } - - // get metallic-roughness texture - tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; - if (tex_index >= 0) - { - mat->mMetallicRoughnessId.set(model.images[tex_index].uri); - } - else - { - mat->mMetallicRoughnessId.setNull(); - } - - // get emissive texture - tex_index = material_in.emissiveTexture.index; - if (tex_index >= 0) - { - mat->mEmissiveId.set(model.images[tex_index].uri); - } - else - { - mat->mEmissiveId.setNull(); - } - - mat->setAlphaMode(material_in.alphaMode); - mat->mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); - - mat->mBaseColor= getColor(material_in.pbrMetallicRoughness.baseColorFactor); - mat->mEmissiveColor = getColor(material_in.emissiveFactor); - - mat->mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); - mat->mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); - - mat->mDoubleSided = material_in.doubleSided; -} - LLColor4 LLTinyGLTFHelper::getColor(const std::vector& in) { LLColor4 out; diff --git a/indra/newview/lltinygltfhelper.h b/indra/newview/lltinygltfhelper.h index afe4517417..9c2e5afc17 100644 --- a/indra/newview/lltinygltfhelper.h +++ b/indra/newview/lltinygltfhelper.h @@ -35,7 +35,6 @@ class LLViewerFetchedTexture; namespace LLTinyGLTFHelper { - void setFromModel(LLGLTFMaterial* mat, tinygltf::Model& model, S32 index); LLColor4 getColor(const std::vector& in); const tinygltf::Image* getImageFromTextureIndex(const tinygltf::Model& model, S32 texture_index); LLImageRaw* getTexture(const std::string& folder, const tinygltf::Model& model, S32 texture_index, std::string& name); -- cgit v1.3 From 44687a78625d6ed21a82356b07e9927f8d45f629 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Mon, 17 Oct 2022 15:47:15 -0700 Subject: WIP for SL-17697 live editing now computes diffs of changed material properties in tinygltf schema json --- indra/llprimitive/llgltfmaterial.cpp | 94 ++++++++++++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 2 + 2 files changed, 96 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 369a1786a3..951b768678 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -197,3 +197,97 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.doubleSided = mDoubleSided; } +void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const +{ + if (model.materials.size() < mat_index+1) + { + model.materials.resize(mat_index + 1); + } + + tinygltf::Material& material_out = model.materials[mat_index]; + + // TODO - fix handling of resetting to null/default values + + // set base color texture + if (mBaseColorId.notNull() && mBaseColorId != base_material->mBaseColorId) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.baseColorTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mBaseColorId.asString(); + } + + // set normal texture + if (mNormalId.notNull() && mNormalId != base_material->mNormalId) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.normalTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mNormalId.asString(); + } + + // set metallic-roughness texture + if (mMetallicRoughnessId.notNull() && mMetallicRoughnessId != base_material->mMetallicRoughnessId) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mMetallicRoughnessId.asString(); + } + + // set emissive texture + if (mEmissiveId.notNull() && mEmissiveId != base_material->mEmissiveId) + { + U32 idx = model.images.size(); + model.images.resize(idx + 1); + model.textures.resize(idx + 1); + + material_out.emissiveTexture.index = idx; + model.textures[idx].source = idx; + model.images[idx].uri = mEmissiveId.asString(); + } + + if(mAlphaMode != base_material->mAlphaMode) + { + material_out.alphaMode = getAlphaMode(); + } + + if(mAlphaCutoff != base_material->mAlphaCutoff) + { + material_out.alphaCutoff = mAlphaCutoff; + } + + if(mBaseColor != base_material->mBaseColor) + { + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); + } + + if(mEmissiveColor != base_material->mEmissiveColor) + { + mEmissiveColor.write(material_out.emissiveFactor); + } + + if(mMetallicFactor != base_material->mMetallicFactor) + { + material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; + } + + if(mRoughnessFactor != base_material->mRoughnessFactor) + { + material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; + } + + if(mDoubleSided != base_material->mDoubleSided) + { + material_out.doubleSided = mDoubleSided; + } +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 8efcc9d753..e8d1d67f1b 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -123,5 +123,7 @@ public: // write to given tinygltf::Model void writeToModel(tinygltf::Model& model, S32 mat_index) const; + // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model + void writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const; }; -- cgit v1.3 From d0c2c862efe2ce684b48092465cc753b3ab64da9 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 19 Oct 2022 09:18:24 -0700 Subject: SL-18105 viewer side for handling Material Override LargeGenericMessage LLGLTFMaterialList now decodes gltf json overrides from the server and stores them in LLTextureEntry::mGLTFMaterialOverrides --- indra/llprimitive/lltextureentry.h | 8 ++++++ indra/newview/llgltfmateriallist.cpp | 55 +++++++++++++++++++++++++++--------- 2 files changed, 50 insertions(+), 13 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 1549b2ce87..24875f0d21 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -200,6 +200,10 @@ public: // Media flags enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; + // GLTF override + LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } + void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } + public: F32 mScaleS; // S, T offset F32 mScaleT; // S, T offset @@ -228,6 +232,10 @@ protected: LLMaterialPtr mMaterial; LLPointer mGLTFMaterial; // if present, ignore mMaterial + // GLTF material parameter overrides -- the viewer will use this data to override material parameters + // set by the asset + LLPointer mGLTFMaterialOverrides; + // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 0fd5f37b51..9c04ef4c38 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -35,36 +35,65 @@ #include "lltinygltfhelper.h" #include "llviewercontrol.h" #include "llviewergenericmessage.h" +#include "llviewerobjectlist.h" #include "tinygltf/tiny_gltf.h" #include +#include "json/reader.h" +#include "json/value.h" + namespace { class LLGLTFOverrideDispatchHandler : public LLDispatchHandler { + LOG_CLASS(LLGLTFOverrideDispatchHandler); public: LLGLTFOverrideDispatchHandler() = default; ~LLGLTFOverrideDispatchHandler() override = default; bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override { - for (std::string const & s : strings) { - LL_DEBUGS() << "received override: " << s << LL_ENDL; - -#if 0 - // for now messages are coming in llsd - LLSD override_data; - std::istringstream input(s); - LLSDSerialize::deserialize(override_data, input, s.length()); - LL_DEBUGS() << "deserialized override: " << override_data << LL_ENDL; -#else + // iterate over pairs of parameters + int i; + for (i = 0; i+1 < strings.size(); i += 2) + { + std::string params_json = strings[i]; + std::string override_json = strings[i+1]; + + LL_DEBUGS() << "received override: " << params_json << " | " << override_json << LL_ENDL; + + Json::Value params; + Json::Reader reader; + bool success = reader.parse(params_json, params); + if (!success) + { + LL_WARNS() << "failed to parse override parameters. errors: " << reader.getFormatedErrorMessages() << LL_ENDL; + break; + } + + LLViewerObject * obj = gObjectList.findObject(LLUUID(params["object_id"].asString())); + S32 side = params["side"].asInt(); + std::string warn_msg, error_msg; - LLGLTFMaterial override_data; - override_data.fromJSON(s, warn_msg, error_msg); -#endif + LLPointer override_data = new LLGLTFMaterial(); + success = override_data->fromJSON(override_json, warn_msg, error_msg); +// if (!success) +// { +// LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; +// break; +// } + + if(obj) + { + obj->getTE(side)->setGLTFMaterialOverride(override_data); + } + + LL_DEBUGS() << "successfully parsed override: " << override_data->asJSON() << LL_ENDL; } + LL_WARNS_IF(i != strings.size()) << "parse error or unhandled mismatched odd number of parameters for material override" << LL_ENDL; + return true; } }; -- cgit v1.3 From de4c018499ddaebbe466fb5a8938554a2d4a3b19 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 19 Oct 2022 14:41:17 -0500 Subject: SL-18105 Hook up render pipe directly to LLTextureEntry::mGLTFMaterial and add LLViewerFetchedTextures to LLFetchedGLTFMaterial. Lower reflection probe resolution to 128x128 per side. --- indra/llprimitive/llgltfmaterial.cpp | 187 +++++++++++++++++++-- indra/llprimitive/llgltfmaterial.h | 71 ++++++-- indra/llprimitive/lltextureentry.h | 22 ++- indra/newview/app_settings/logcontrol.xml | 1 + .../shaders/class1/interface/irradianceGenF.glsl | 2 +- .../shaders/class1/interface/radianceGenF.glsl | 4 +- .../shaders/class3/deferred/reflectionProbeF.glsl | 2 +- indra/newview/featuretable.txt | 4 +- indra/newview/lldrawpoolalpha.cpp | 40 +---- indra/newview/lldrawpoolpbropaque.cpp | 55 +----- indra/newview/llfetchedgltfmaterial.cpp | 61 +++++++ indra/newview/llfetchedgltfmaterial.h | 14 +- indra/newview/llreflectionmapmanager.h | 2 +- indra/newview/llspatialpartition.h | 8 +- indra/newview/llviewerobject.cpp | 57 +++---- indra/newview/llviewerobject.h | 13 -- indra/newview/llvovolume.cpp | 18 +- indra/newview/pipeline.cpp | 23 ++- 18 files changed, 378 insertions(+), 206 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 951b768678..19081cd76f 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -28,12 +28,44 @@ #include "llgltfmaterial.h" -#include "tiny_gltf.h" +#include "tinygltf/tiny_gltf.h" + +LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) +{ + *this = rhs; +} + +LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) +{ + //have to do a manual operator= because of LLRefCount + mBaseColorId = rhs.mBaseColorId; + mNormalId = rhs.mNormalId; + mMetallicRoughnessId = rhs.mMetallicRoughnessId; + mEmissiveId = rhs.mEmissiveId; + + mBaseColor = rhs.mBaseColor; + mEmissiveColor = rhs.mEmissiveColor; + + mMetallicFactor = rhs.mMetallicFactor; + mRoughnessFactor = rhs.mRoughnessFactor; + mAlphaCutoff = rhs.mAlphaCutoff; + + mDoubleSided = rhs.mDoubleSided; + mAlphaMode = rhs.mAlphaMode; + + for (S32 i = 0; i < 3; ++i) + { + mTextureTransform[i] = rhs.mTextureTransform[i]; + } + + return *this; +} bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) { +#if 1 tinygltf::TinyGLTF gltf; - + tinygltf::Model model_in; if (gltf.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, json.c_str(), json.length(), "")) @@ -45,12 +77,13 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st return true; } - +#endif return false; } std::string LLGLTFMaterial::asJSON(bool prettyprint) const { +#if 1 tinygltf::TinyGLTF gltf; tinygltf::Model model_out; @@ -61,6 +94,9 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); return str.str(); +#else + return ""; +#endif } void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) @@ -130,7 +166,7 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const { - if (model.materials.size() < mat_index+1) + if (model.materials.size() < mat_index + 1) { model.materials.resize(mat_index + 1); } @@ -143,7 +179,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const U32 idx = model.images.size(); model.images.resize(idx + 1); model.textures.resize(idx + 1); - + material_out.pbrMetallicRoughness.baseColorTexture.index = idx; model.textures[idx].source = idx; model.images[idx].uri = mBaseColorId.asString(); @@ -160,7 +196,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const model.textures[idx].source = idx; model.images[idx].uri = mNormalId.asString(); } - + // set metallic-roughness texture if (mMetallicRoughnessId.notNull()) { @@ -187,7 +223,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; - + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); mEmissiveColor.write(material_out.emissiveFactor); @@ -195,11 +231,130 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; material_out.doubleSided = mDoubleSided; + + model.asset.version = "2.0"; +} + + +void LLGLTFMaterial::setBaseColorId(const LLUUID& id) +{ + mBaseColorId = id; +} + +void LLGLTFMaterial::setNormalId(const LLUUID& id) +{ + mNormalId = id; +} + +void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id) +{ + mMetallicRoughnessId = id; +} + +void LLGLTFMaterial::setEmissiveId(const LLUUID& id) +{ + mEmissiveId = id; +} + +void LLGLTFMaterial::setBaseColorFactor(const LLColor3& baseColor, F32 transparency) +{ + mBaseColor.set(baseColor, transparency); + mBaseColor.clamp(); +} + +void LLGLTFMaterial::setAlphaCutoff(F32 cutoff) +{ + mAlphaCutoff = llclamp(cutoff, 0.f, 1.f); +} + +void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor) +{ + mEmissiveColor = emissiveColor; + mEmissiveColor.clamp(); +} + +void LLGLTFMaterial::setMetallicFactor(F32 metallic) +{ + mMetallicFactor = llclamp(metallic, 0.f, 1.f); +} + +void LLGLTFMaterial::setRoughnessFactor(F32 roughness) +{ + mRoughnessFactor = llclamp(roughness, 0.f, 1.f); +} + +void LLGLTFMaterial::setAlphaMode(S32 mode) +{ + mAlphaMode = (AlphaMode)llclamp(mode, (S32)ALPHA_MODE_OPAQUE, (S32)ALPHA_MODE_MASK); +} + +void LLGLTFMaterial::setDoubleSided(bool double_sided) +{ + // sure, no clamping will ever be needed for a bool, but include the + // setter for consistency with the clamping API + mDoubleSided = double_sided; +} + +// Default value accessors + +LLUUID LLGLTFMaterial::getDefaultBaseColorId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultNormalId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultEmissiveId() +{ + return LLUUID::null; +} + +LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId() +{ + return LLUUID::null; +} + +F32 LLGLTFMaterial::getDefaultAlphaCutoff() +{ + return 0.f; +} + +S32 LLGLTFMaterial::getDefaultAlphaMode() +{ + return (S32)ALPHA_MODE_OPAQUE; +} + +F32 LLGLTFMaterial::getDefaultMetallicFactor() +{ + return 0.f; +} + +F32 LLGLTFMaterial::getDefaultRoughnessFactor() +{ + return 0.f; +} + +LLColor4 LLGLTFMaterial::getDefaultBaseColor() +{ + return LLColor4::white; +} + +LLColor3 LLGLTFMaterial::getDefaultEmissiveColor() +{ + return LLColor3::black; +} + +bool LLGLTFMaterial::getDefaultDoubleSided() +{ + return false; } -void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const +void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const { - if (model.materials.size() < mat_index+1) + if (model.materials.size() < mat_index + 1) { model.materials.resize(mat_index + 1); } @@ -256,37 +411,37 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model & model, S32 mat_inde model.images[idx].uri = mEmissiveId.asString(); } - if(mAlphaMode != base_material->mAlphaMode) + if (mAlphaMode != base_material->mAlphaMode) { material_out.alphaMode = getAlphaMode(); } - if(mAlphaCutoff != base_material->mAlphaCutoff) + if (mAlphaCutoff != base_material->mAlphaCutoff) { material_out.alphaCutoff = mAlphaCutoff; } - if(mBaseColor != base_material->mBaseColor) + if (mBaseColor != base_material->mBaseColor) { mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); } - if(mEmissiveColor != base_material->mEmissiveColor) + if (mEmissiveColor != base_material->mEmissiveColor) { mEmissiveColor.write(material_out.emissiveFactor); } - if(mMetallicFactor != base_material->mMetallicFactor) + if (mMetallicFactor != base_material->mMetallicFactor) { material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; } - if(mRoughnessFactor != base_material->mRoughnessFactor) + if (mRoughnessFactor != base_material->mRoughnessFactor) { material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; } - if(mDoubleSided != base_material->mDoubleSided) + if (mDoubleSided != base_material->mDoubleSided) { material_out.doubleSided = mDoubleSided; } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index e8d1d67f1b..9c82f08805 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -27,8 +27,10 @@ #pragma once #include "llrefcount.h" +#include "llmemory.h" #include "v4color.h" #include "v3color.h" +#include "v2math.h" #include "lluuid.h" #include "llmd5.h" @@ -43,6 +45,13 @@ class LLGLTFMaterial : public LLRefCount { public: + struct TextureTransform + { + LLVector2 mOffset = { 0.f, 0.f }; + LLVector2 mScale = { 1.f, 1.f }; + F32 mRotation = 0.f; + }; + enum AlphaMode { ALPHA_MODE_OPAQUE = 0, @@ -50,6 +59,11 @@ public: ALPHA_MODE_MASK }; + LLGLTFMaterial() {} + LLGLTFMaterial(const LLGLTFMaterial& rhs); + + LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs); + LLUUID mBaseColorId; LLUUID mNormalId; LLUUID mMetallicRoughnessId; @@ -65,17 +79,41 @@ public: bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; - // get a UUID based on a hash of this LLGLTFMaterial - LLUUID getHash() const + enum TextureTransformIdx : U32 { - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLMD5 md5; - md5.update((unsigned char*)this, sizeof(this)); - md5.finalize(); - LLUUID id; - md5.raw_digest(id.mData); - return id; - } + TEXTURE_TRANSFORM_DIFFUSE_EMISSIVE, + TEXTURE_TRANSFORM_NORMAL, + TEXTURE_TRANSFORM_METALLIC_ROUGHNESS + }; + TextureTransform mTextureTransform[3]; + + //setters for various members (will clamp to acceptable ranges) + + void setBaseColorId(const LLUUID& id); + void setNormalId(const LLUUID& id); + void setMetallicRoughnessId(const LLUUID& id); + void setEmissiveId(const LLUUID& id); + + void setBaseColorFactor(const LLColor3& baseColor, F32 transparency); + void setAlphaCutoff(F32 cutoff); + void setEmissiveColorFactor(const LLColor3& emissiveColor); + void setMetallicFactor(F32 metallic); + void setRoughnessFactor(F32 roughness); + void setAlphaMode(S32 mode); + void setDoubleSided(bool double_sided); + + // Default value accessors + static LLUUID getDefaultBaseColorId(); + static LLUUID getDefaultNormalId(); + static LLUUID getDefaultEmissiveId(); + static LLUUID getDefaultMetallicRoughnessId(); + static F32 getDefaultAlphaCutoff(); + static S32 getDefaultAlphaMode(); + static F32 getDefaultMetallicFactor(); + static F32 getDefaultRoughnessFactor(); + static LLColor4 getDefaultBaseColor(); + static LLColor3 getDefaultEmissiveColor(); + static bool getDefaultDoubleSided(); // set mAlphaMode from string. // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE @@ -123,7 +161,18 @@ public: // write to given tinygltf::Model void writeToModel(tinygltf::Model& model, S32 mat_index) const; + // get a UUID based on a hash of this LLGLTFMaterial + LLUUID getHash() const + { + LLMD5 md5; + md5.update((unsigned char*)this, sizeof(this)); + md5.finalize(); + LLUUID id; + md5.raw_digest(id.mData); + return id; + } + // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model - void writeOverridesToModel(tinygltf::Model & model, S32 mat_index, LLGLTFMaterial const * base_material) const; + void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const; }; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 24875f0d21..bb74d258fd 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -135,10 +135,6 @@ public: S32 setMaterialID(const LLMaterialID& pMaterialID); S32 setMaterialParams(const LLMaterialPtr pMaterialParams); - void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } - LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } - - virtual const LLUUID &getID() const { return mID; } const LLColor4 &getColor() const { return mColor; } const F32 getAlpha() const { return mColor.mV[VALPHA]; } @@ -200,10 +196,18 @@ public: // Media flags enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; + // GLTF asset + void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } + LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } + // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } + // GLTF render + LLGLTFMaterial* getGLTFRenderMaterial() { return mGLTFRenderMaterial; } + void setGLTFRenderMaterial(LLGLTFMaterial* mat) { mGLTFRenderMaterial = mat; } + public: F32 mScaleS; // S, T offset F32 mScaleT; // S, T offset @@ -230,12 +234,18 @@ protected: bool mMaterialUpdatePending; LLMaterialID mMaterialID; LLMaterialPtr mMaterial; - LLPointer mGLTFMaterial; // if present, ignore mMaterial + + // Reference to GLTF material asset state + // On the viewer, this should be the same LLGLTFMaterial instance that exists in LLGLTFMaterialList + LLPointer mGLTFMaterial; // GLTF material parameter overrides -- the viewer will use this data to override material parameters - // set by the asset + // set by the asset and store the results in mRenderGLTFMaterial LLPointer mGLTFMaterialOverrides; + // GLTF material to use for rendering -- will always be an LLFetchedGLTFMaterial + LLPointer mGLTFRenderMaterial; + // Note the media data is not sent via the same message structure as the rest of the TE LLMediaEntry* mMediaEntry; // The media data for the face diff --git a/indra/newview/app_settings/logcontrol.xml b/indra/newview/app_settings/logcontrol.xml index 482012cdd6..2a26cb9a43 100644 --- a/indra/newview/app_settings/logcontrol.xml +++ b/indra/newview/app_settings/logcontrol.xml @@ -73,6 +73,7 @@ Avatar Voice --> + Capabilities diff --git a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl index b633813819..feaf562686 100644 --- a/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/irradianceGenF.glsl @@ -196,7 +196,7 @@ vec4 filterColor(vec3 N) // apply the bias to the lod lod += u_lodBias; - lod = clamp(lod, 0, 7); + lod = clamp(lod, 0, 6); // sample lambertian at a lower resolution to avoid fireflies vec4 lambertian = textureLod(reflectionProbes, vec4(H, sourceIdx), lod); diff --git a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl index f4879b52de..32f157e9d2 100644 --- a/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class1/interface/radianceGenF.glsl @@ -127,7 +127,7 @@ vec4 prefilterEnvMap(vec3 R) float envMapDim = 256.0; int numSamples = 4; - float numMips = 7.0; + float numMips = 6.0; float roughness = mipLevel/numMips; @@ -151,7 +151,7 @@ vec4 prefilterEnvMap(vec3 R) // Solid angle of 1 pixel across all cube faces float omegaP = 4.0 * PI / (6.0 * envMapDim * envMapDim); // Biased (+1.0) mip level for better result - float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f); + float mip = roughness == 0.0 ? 0.0 : clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, numMips); //float mip = clamp(0.5 * log2(omegaS / omegaP) + 1.0, 0.0f, 7.f); color += textureLod(reflectionProbes, vec4(L,sourceIdx), mip) * dotNL; totalWeight += dotNL; diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 211e1f5d8d..ca436033f1 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -507,7 +507,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, vec3 pos, vec3 norm, float glossiness, bool errorCorrect) { // TODO - don't hard code lods - float reflection_lods = 7; + float reflection_lods = 6; preProbeSample(pos); vec3 refnormpersp = reflect(pos.xyz, norm.xyz); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index 2cb48e51d0..efd498183d 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -286,9 +286,9 @@ RenderFSAASamples 1 0 RenderGLMultiThreaded 1 0 RenderGLContextCoreProfile 1 0 -// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 16 +// HACK: Current AMD drivers have bugged cubemap arrays, limit number of reflection probes to 32 list AMD -RenderReflectionProbeCount 1 16 +RenderReflectionProbeCount 1 32 list GL3 RenderFSAASamples 0 0 diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 01b2647eaa..41e52846b3 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -675,45 +675,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) gPipeline.bindDeferredShader(*target_shader); } - if (params.mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(params.mTexture); // diffuse - } - else - { - gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); - } - - if (params.mNormalMap) - { - target_shader->bindTexture(LLShaderMgr::BUMP_MAP, params.mNormalMap); - } - else - { - target_shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - } - - if (params.mSpecularMap) - { - target_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, params.mSpecularMap); // PBR linear packed Occlusion, Roughness, Metal. - } - else - { - target_shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - if (params.mEmissiveMap) - { - target_shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, params.mEmissiveMap); // PBR sRGB Emissive - } - else - { - target_shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - target_shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, params.mGLTFMaterial->mRoughnessFactor); - target_shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, params.mGLTFMaterial->mMetallicFactor); - target_shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, params.mGLTFMaterial->mEmissiveColor.mV); + params.mGLTFMaterial->bind(target_shader); } else { diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 71f648a714..2f710e570b 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -95,57 +95,10 @@ void LLDrawPoolPBROpaque::renderDeferred(S32 pass) for (LLCullResult::drawinfo_iterator i = begin; i != end; ++i) { LLDrawInfo* pparams = *i; - LLGLTFMaterial *mat = pparams->mGLTFMaterial; - - // glTF 2.0 Specification 3.9.4. Alpha Coverage - // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK - F32 min_alpha = -1.0; - if (mat->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) - { - min_alpha = mat->mAlphaCutoff; - } - shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); - - if (pparams->mTexture.notNull()) - { - gGL.getTexUnit(0)->bindFast(pparams->mTexture); // diffuse - } - else - { - gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); - } - - if (pparams->mNormalMap) - { - shader->bindTexture(LLShaderMgr::BUMP_MAP, pparams->mNormalMap); - } - else - { - shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); - } - - if (pparams->mSpecularMap) - { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, pparams->mSpecularMap); // PBR linear packed Occlusion, Roughness, Metal. - } - else - { - shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - if (pparams->mEmissiveMap) - { - shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, pparams->mEmissiveMap); // PBR sRGB Emissive - } - else - { - shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); - } - - shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, pparams->mGLTFMaterial->mRoughnessFactor); - shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, pparams->mGLTFMaterial->mMetallicFactor); - shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, pparams->mGLTFMaterial->mEmissiveColor.mV); - + auto& mat = pparams->mGLTFMaterial; + + mat->bind(shader); + LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0); bool tex_setup = false; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index a06dd276cd..2d3015635c 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -27,6 +27,10 @@ #include "llfetchedgltfmaterial.h" +#include "llviewertexturelist.h" +#include "llavatarappearancedefines.h" +#include "llshadermgr.h" + LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() : LLGLTFMaterial() , mExpectedFlusTime(0.f) @@ -38,5 +42,62 @@ LLFetchedGLTFMaterial::LLFetchedGLTFMaterial() LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() { + +} + +void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader) +{ + // glTF 2.0 Specification 3.9.4. Alpha Coverage + // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK + F32 min_alpha = -1.0; + + if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) + { + min_alpha = mAlphaCutoff; + } + shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); + + if (mBaseColorTexture.notNull()) + { + gGL.getTexUnit(0)->bindFast(mBaseColorTexture); + } + else + { + gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); + } + + + if (mNormalTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture); + } + else + { + shader->bindTexture(LLShaderMgr::BUMP_MAP, LLViewerFetchedTexture::sFlatNormalImagep); + } + + if (mMetallicRoughnessTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, mMetallicRoughnessTexture); // PBR linear packed Occlusion, Roughness, Metal. + } + else + { + shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + if (mEmissiveTexture.notNull()) + { + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, mEmissiveTexture); // PBR sRGB Emissive + } + else + { + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, LLViewerFetchedTexture::sWhiteImagep); + } + + // NOTE: base color factor is baked into vertex stream + + shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor); + shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); + shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 4cbe6651c4..3b2801bf77 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -28,14 +28,26 @@ #include "llgltfmaterial.h" #include "llpointer.h" +#include "llviewertexture.h" -class LLFetchedGLTFMaterial : public LLGLTFMaterial +class LLGLSLShader; + +class LLFetchedGLTFMaterial: public LLGLTFMaterial { friend class LLGLTFMaterialList; // for lifetime management public: LLFetchedGLTFMaterial(); virtual ~LLFetchedGLTFMaterial(); + // bind this material for rendering + void bind(LLGLSLShader* shader); + + // Textures used for fetching/rendering + LLPointer mBaseColorTexture; + LLPointer mNormalTexture; + LLPointer mMetallicRoughnessTexture; + LLPointer mEmissiveTexture; + protected: //Lifetime management F64 mExpectedFlusTime; // since epoch in seconds diff --git a/indra/newview/llreflectionmapmanager.h b/indra/newview/llreflectionmapmanager.h index 14b762998a..e0a2c00db3 100644 --- a/indra/newview/llreflectionmapmanager.h +++ b/indra/newview/llreflectionmapmanager.h @@ -38,7 +38,7 @@ class LLViewerObject; #define LL_MAX_REFLECTION_PROBE_COUNT 256 // reflection probe resolution -#define LL_REFLECTION_PROBE_RESOLUTION 256 +#define LL_REFLECTION_PROBE_RESOLUTION 128 #define LL_IRRADIANCE_MAP_RESOLUTION 64 // reflection probe mininum scale diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index c3e9d8ceb9..0d16b818f1 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -41,6 +41,7 @@ #include "llviewercamera.h" #include "llvector4a.h" #include "llvoavatar.h" +#include "llfetchedgltfmaterial.h" #include #include @@ -114,9 +115,11 @@ public: F32 mDistance; U32 mDrawMode; - // Material points here are likely for debugging only and are immaterial (zing!) + // Material pointer here is likely for debugging only and are immaterial (zing!) LLMaterialPtr mMaterial; - LLPointer mGLTFMaterial; + + // PBR material parameters + LLPointer mGLTFMaterial; LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info @@ -128,7 +131,6 @@ public: const LLMatrix4* mSpecularMapMatrix; LLPointer mNormalMap; const LLMatrix4* mNormalMapMatrix; - LLPointer mEmissiveMap; LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent F32 mEnvIntensity; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index a256b770b1..ccc1259c25 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -414,11 +414,6 @@ void LLViewerObject::deleteTEImages() delete[] mTESpecularMaps; mTESpecularMaps = NULL; } - - mGLTFBaseColorMaps.clear(); - mGLTFNormalMaps.clear(); - mGLTFMetallicRoughnessMaps.clear(); - mGLTFEmissiveMaps.clear(); } void LLViewerObject::markDead() @@ -4766,11 +4761,6 @@ void LLViewerObject::setNumTEs(const U8 num_tes) mTEImages = new_images; mTENormalMaps = new_normmaps; mTESpecularMaps = new_specmaps; - - mGLTFBaseColorMaps.resize(num_tes); - mGLTFNormalMaps.resize(num_tes); - mGLTFMetallicRoughnessMaps.resize(num_tes); - mGLTFEmissiveMaps.resize(num_tes); } else { @@ -4930,14 +4920,28 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } - auto fetch_texture = [](const LLUUID& id, LLViewerObject *obj) + LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFMaterial(); + LLUUID mat_id = getRenderMaterialID(te); + if (mat == nullptr && mat_id.notNull()) + { + mat = (LLFetchedGLTFMaterial*) gGLTFMaterialList.getMaterial(mat_id); + getTE(te)->setGLTFMaterial(mat); + } + else if (mat_id.isNull() && mat != nullptr) + { + mat = nullptr; + getTE(te)->setGLTFMaterial(nullptr); + } + + auto fetch_texture = [this](const LLUUID& id) { LLViewerFetchedTexture* img = nullptr; if (id.notNull()) { if (LLAvatarAppearanceDefines::LLAvatarAppearanceDictionary::isBakedImageId(id)) { - LLViewerTexture* viewerTexture = obj->getBakedTextureForMagicId(id); + // TODO -- fall back to LLTextureEntry::mGLTFRenderMaterial when overriding with baked texture + LLViewerTexture* viewerTexture = getBakedTextureForMagicId(id); img = viewerTexture ? dynamic_cast(viewerTexture) : nullptr; } else @@ -4950,34 +4954,13 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) return img; }; - LLGLTFMaterial* mat = getTE(te)->getGLTFMaterial(); - LLUUID mat_id = getRenderMaterialID(te); - if (mat == nullptr && mat_id.notNull()) - { - mat = gGLTFMaterialList.getMaterial(mat_id); - getTE(te)->setGLTFMaterial(mat); - } - else if (mat_id.isNull() && mat != nullptr) - { - mat = nullptr; - getTE(te)->setGLTFMaterial(nullptr); - } - if (mat != nullptr) { - mGLTFBaseColorMaps[te] = fetch_texture(mat->mBaseColorId, this); - mGLTFNormalMaps[te] = fetch_texture(mat->mNormalId, this); - mGLTFMetallicRoughnessMaps[te] = fetch_texture(mat->mMetallicRoughnessId, this); - mGLTFEmissiveMaps[te] = fetch_texture(mat->mEmissiveId, this); + mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId); + mat->mNormalTexture = fetch_texture(mat->mNormalId); + mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId); + mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId); } - else - { - mGLTFBaseColorMaps[te] = nullptr; - mGLTFNormalMaps[te] = nullptr; - mGLTFMetallicRoughnessMaps[te] = nullptr; - mGLTFEmissiveMaps[te] = nullptr; - } - } void LLViewerObject::refreshBakeTexture() diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 9d80f095c9..5d72f7f3c3 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -371,12 +371,6 @@ public: LLViewerTexture *getTENormalMap(const U8 te) const; LLViewerTexture *getTESpecularMap(const U8 te) const; - LLViewerTexture* getGLTFBaseColorMap(U8 te) const { return mGLTFBaseColorMaps[te]; } - LLViewerTexture* getGLTFNormalMap(U8 te) const { return mGLTFNormalMaps[te]; } - LLViewerTexture* getGLTFEmissiveMap(U8 te) const { return mGLTFEmissiveMaps[te]; } - LLViewerTexture* getGLTFMetallicRoughnessMap(U8 te) const { return mGLTFMetallicRoughnessMaps[te]; } - - bool isImageAlphaBlended(const U8 te) const; void fitFaceTexture(const U8 face); @@ -693,13 +687,6 @@ public: LLPointer *mTENormalMaps; LLPointer *mTESpecularMaps; - std::vector > mGLTFBaseColorMaps; - std::vector > mGLTFNormalMaps; - std::vector > mGLTFMetallicRoughnessMaps; - std::vector > mGLTFEmissiveMaps; - - - // true if user can select this object by clicking under any circumstances (even if pick_unselectable is true) // can likely be factored out BOOL mbCanSelect; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 2a06331b63..c1c80d5adc 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5390,7 +5390,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLUUID mat_id; - LLGLTFMaterial* gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFMaterial(); if (gltf_mat != nullptr) { mat_id = gltf_mat->getHash(); // TODO: cache this hash @@ -5519,21 +5519,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (gltf_mat) { - LLViewerObject* vobj = facep->getViewerObject(); - U8 te = facep->getTEOffset(); - - draw_info->mTexture = vobj->getGLTFBaseColorMap(te); - draw_info->mNormalMap = vobj->getGLTFNormalMap(te); - draw_info->mSpecularMap = vobj->getGLTFMetallicRoughnessMap(te); - draw_info->mEmissiveMap = vobj->getGLTFEmissiveMap(te); - if (draw_info->mGLTFMaterial->mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) - { - draw_info->mAlphaMaskCutoff = gltf_mat->mAlphaCutoff * gltf_mat->mBaseColor.mV[3]; - } - else - { - draw_info->mAlphaMaskCutoff = 1.f; - } + // nothing to do, render pools will reference the GLTF material } else if (mat) { diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 0c27296440..cb54cec165 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -3723,15 +3723,26 @@ void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) void LLPipeline::touchTextures(LLDrawInfo* info) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - for (int i = 0; i < info->mTextureList.size(); ++i) + + auto& mat = info->mGLTFMaterial; + if (mat.notNull()) { - touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); + touchTexture(mat->mBaseColorTexture, info->mVSize); + touchTexture(mat->mNormalTexture, info->mVSize); + touchTexture(mat->mMetallicRoughnessTexture, info->mVSize); + touchTexture(mat->mEmissiveTexture, info->mVSize); } + else + { + for (int i = 0; i < info->mTextureList.size(); ++i) + { + touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); + } - touchTexture(info->mTexture, info->mVSize); - touchTexture(info->mSpecularMap, info->mVSize); - touchTexture(info->mNormalMap, info->mVSize); - touchTexture(info->mEmissiveMap, info->mVSize); + touchTexture(info->mTexture, info->mVSize); + touchTexture(info->mSpecularMap, info->mVSize); + touchTexture(info->mNormalMap, info->mVSize); + } } void LLPipeline::postSort(LLCamera& camera) -- cgit v1.3 From 8741c05cc10d3f39f272bb4739e7313309539d07 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 19 Oct 2022 17:23:54 -0500 Subject: SL-18105 Hook up TE override material to render pipe by way of render material. --- indra/llprimitive/llgltfmaterial.cpp | 25 +++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 3 +++ indra/llprimitive/lltextureentry.cpp | 19 +++++++++++++++++++ indra/llprimitive/lltextureentry.h | 13 ++++++------- indra/newview/llface.cpp | 6 +++--- indra/newview/llgltfmateriallist.cpp | 6 +++++- indra/newview/llviewerobject.cpp | 32 +++++++++++++++++++++++++++++++- indra/newview/llviewerobject.h | 1 + indra/newview/llvovolume.cpp | 10 +++++----- indra/newview/pipeline.cpp | 2 +- 10 files changed, 99 insertions(+), 18 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 19081cd76f..b9ef2de61a 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -446,3 +446,28 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index material_out.doubleSided = mDoubleSided; } } + +void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +{ + if (override_mat.mBaseColorId != getDefaultBaseColorId()) + { + mBaseColorId = override_mat.mBaseColorId; + } + + if (override_mat.mNormalId != getDefaultNormalId()) + { + mNormalId = override_mat.mNormalId; + } + + if (override_mat.mMetallicRoughnessId != getDefaultMetallicRoughnessId()) + { + mMetallicRoughnessId = override_mat.mMetallicRoughnessId; + } + + if (override_mat.mEmissiveId != getDefaultEmissiveId()) + { + mEmissiveId = override_mat.mEmissiveId; + } + + //TODO -- implement non texture parameters +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 9c82f08805..32695d92f4 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -174,5 +174,8 @@ public: // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const; + + void applyOverride(const LLGLTFMaterial& override_mat); + }; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 284dfc15f4..e185404ada 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -491,6 +491,25 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) return TEM_CHANGE_NONE; } +void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) +{ + mGLTFMaterial = material; + if (mGLTFMaterial == nullptr) + { + setGLTFRenderMaterial(nullptr); + } +} + +S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat) +{ + if (mGLTFRenderMaterial != mat) + { + mGLTFRenderMaterial = mat; + return TEM_CHANGE_TEXTURE; + } + return TEM_CHANGE_NONE; +} + S32 LLTextureEntry::setMediaFlags(U8 media_flags) { media_flags &= TEM_MEDIA_MASK; diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index bb74d258fd..2c932a10df 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -163,8 +163,6 @@ public: const LLMaterialID& getMaterialID() const { return mMaterialID; }; const LLMaterialPtr getMaterialParams() const { return mMaterial; }; - LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } - // *NOTE: it is possible for hasMedia() to return true, but getMediaData() to return NULL. // CONVERSELY, it is also possible for hasMedia() to return false, but getMediaData() // to NOT return NULL. @@ -197,16 +195,17 @@ public: enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; // GLTF asset - void setGLTFMaterial(LLGLTFMaterial* material) { mGLTFMaterial = material; } - LLGLTFMaterial* getGLTFMaterial() { return mGLTFMaterial; } + void setGLTFMaterial(LLGLTFMaterial* material); + LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } - // GLTF render - LLGLTFMaterial* getGLTFRenderMaterial() { return mGLTFRenderMaterial; } - void setGLTFRenderMaterial(LLGLTFMaterial* mat) { mGLTFRenderMaterial = mat; } + // GLTF render material + // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter + LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial : getGLTFMaterial(); } + S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); public: F32 mScaleS; // S, T offset diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 4ae8335ca7..23b56aa579 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1334,9 +1334,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLColor4U color = tep->getColor(); - if (tep->getGLTFMaterial()) + if (tep->getGLTFRenderMaterial()) { - color = tep->getGLTFMaterial()->mBaseColor; + color = tep->getGLTFRenderMaterial()->mBaseColor; } if (rebuild_color) @@ -1599,7 +1599,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, scalea.load3(scale.mV); LLMaterial* mat = tep->getMaterialParams().get(); - LLGLTFMaterial* gltf_mat = tep->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 9c04ef4c38..86f4faa9d0 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -36,6 +36,7 @@ #include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "llviewerobjectlist.h" +#include "pipeline.h" #include "tinygltf/tiny_gltf.h" #include @@ -86,7 +87,10 @@ namespace if(obj) { - obj->getTE(side)->setGLTFMaterialOverride(override_data); + if (obj->setTEGLTFMaterialOverride(side, override_data)) + { + gPipeline.markTextured(obj->mDrawable); + } } LL_DEBUGS() << "successfully parsed override: " << override_data->asJSON() << LL_ENDL; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ccc1259c25..4923771a31 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4920,7 +4920,7 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) mTESpecularMaps[te] = LLViewerTextureManager::getFetchedTexture(spec_id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_ALM, LLViewerTexture::LOD_TEXTURE); } - LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFMaterial(); + LLFetchedGLTFMaterial* mat = (LLFetchedGLTFMaterial*) getTE(te)->getGLTFRenderMaterial(); LLUUID mat_id = getRenderMaterialID(te); if (mat == nullptr && mat_id.notNull()) { @@ -5319,6 +5319,36 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri return retval; } +S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat) +{ + S32 retval = TEM_CHANGE_NONE; + + LLTextureEntry* tep = getTE(te); + if (!tep) + { + LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + return retval; + } + + LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial(); + + tep->setGLTFMaterialOverride(override_mat); + + if (override_mat && src_mat) + { + LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); + render_mat->applyOverride(*override_mat); + tep->setGLTFRenderMaterial(render_mat); + retval = TEM_CHANGE_TEXTURE; + } + else if (tep->setGLTFRenderMaterial(nullptr)) + { + retval = TEM_CHANGE_TEXTURE; + } + + return retval; +} + void LLViewerObject::refreshMaterials() { setChanged(TEXTURE); diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 5d72f7f3c3..bd70532ab7 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -356,6 +356,7 @@ public: /*virtual*/ S32 setTEGlow(const U8 te, const F32 glow); /*virtual*/ S32 setTEMaterialID(const U8 te, const LLMaterialID& pMaterialID); /*virtual*/ S32 setTEMaterialParams(const U8 te, const LLMaterialPtr pMaterialParams); + S32 setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* mat); // Used by Materials update functions to properly kick off rebuilds // of VBs etc when materials updates require changes. diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index c1c80d5adc..127abde19e 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5223,7 +5223,7 @@ bool can_batch_texture(LLFace* facep) return false; } - if (facep->getTextureEntry()->getGLTFMaterial() != nullptr) + if (facep->getTextureEntry()->getGLTFRenderMaterial() != nullptr) { // PBR materials break indexed texture batching return false; } @@ -5390,7 +5390,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, LLUUID mat_id; - auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFMaterial(); + auto* gltf_mat = (LLFetchedGLTFMaterial*) facep->getTextureEntry()->getGLTFRenderMaterial(); if (gltf_mat != nullptr) { mat_id = gltf_mat->getHash(); // TODO: cache this hash @@ -5873,7 +5873,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) bool is_pbr = false; #endif #else - LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFMaterial(); + LLGLTFMaterial *gltf_mat = facep->getTextureEntry()->getGLTFRenderMaterial(); bool is_pbr = gltf_mat != nullptr; #endif @@ -6011,7 +6011,7 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) if (gPipeline.canUseWindLightShadersOnObjects() && LLPipeline::sRenderBump) { - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); if (LLPipeline::sRenderDeferred && (gltf_mat != nullptr || (te->getMaterialParams().notNull() && !te->getMaterialID().isNull()))) @@ -6716,7 +6716,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace BOOL is_alpha = (facep->getPoolType() == LLDrawPool::POOL_ALPHA) ? TRUE : FALSE; - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); LLMaterial* mat = nullptr; bool can_be_shiny = false; diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cb54cec165..b6d9e5fd36 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -1617,7 +1617,7 @@ U32 LLPipeline::getPoolTypeFromTE(const LLTextureEntry* te, LLViewerTexture* ima } LLMaterial* mat = te->getMaterialParams().get(); - LLGLTFMaterial* gltf_mat = te->getGLTFMaterial(); + LLGLTFMaterial* gltf_mat = te->getGLTFRenderMaterial(); bool color_alpha = te->getColor().mV[3] < 0.999f; bool alpha = color_alpha; -- cgit v1.3 From 8ead80e6e5bdbbc7271b45dd29997548c38c7a53 Mon Sep 17 00:00:00 2001 From: Brad Kittenbrink Date: Wed, 19 Oct 2022 15:32:18 -0700 Subject: Xcode compat fix for SL-18105 material overrides --- indra/llprimitive/lltextureentry.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 2c932a10df..8dc3434a01 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -204,7 +204,7 @@ public: // GLTF render material // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter - LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial : getGLTFMaterial(); } + LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial.get() : getGLTFMaterial(); } S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); public: -- cgit v1.3 From 7231e0b3dd5bff9c87349d52b6927cec354527cd Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 20 Oct 2022 10:20:18 -0700 Subject: SL-18411: Copy over LLGLTFMaterial changes (most notably various getters/setters and texture transform stub) --- indra/llprimitive/llgltfmaterial.cpp | 43 ++++++++++++++++++++++++++++------- indra/llprimitive/llgltfmaterial.h | 44 +++++++++++++++++++++++------------- 2 files changed, 63 insertions(+), 24 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index b9ef2de61a..8f08a8b2cf 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -37,7 +37,7 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) { - //have to do a manual operator= because of LLRefCount + //have to do a manual operator= because of LLRefCount mBaseColorId = rhs.mBaseColorId; mNormalId = rhs.mNormalId; mMetallicRoughnessId = rhs.mMetallicRoughnessId; @@ -53,10 +53,7 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mDoubleSided = rhs.mDoubleSided; mAlphaMode = rhs.mAlphaMode; - for (S32 i = 0; i < 3; ++i) - { - mTextureTransform[i] = rhs.mTextureTransform[i]; - } + mTextureTransform = rhs.mTextureTransform; return *this; } @@ -285,16 +282,31 @@ void LLGLTFMaterial::setRoughnessFactor(F32 roughness) void LLGLTFMaterial::setAlphaMode(S32 mode) { - mAlphaMode = (AlphaMode)llclamp(mode, (S32)ALPHA_MODE_OPAQUE, (S32)ALPHA_MODE_MASK); + mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK); } void LLGLTFMaterial::setDoubleSided(bool double_sided) { - // sure, no clamping will ever be needed for a bool, but include the + // sure, no clamping will ever be needed for a bool, but include the // setter for consistency with the clamping API mDoubleSided = double_sided; } +void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset) +{ + mTextureTransform[texture_info].mOffset = offset; +} + +void LLGLTFMaterial::setTextureScale(TextureInfo texture_info, const LLVector2& scale) +{ + mTextureTransform[texture_info].mScale = scale; +} + +void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation) +{ + mTextureTransform[texture_info].mRotation = rotation; +} + // Default value accessors LLUUID LLGLTFMaterial::getDefaultBaseColorId() @@ -324,7 +336,7 @@ F32 LLGLTFMaterial::getDefaultAlphaCutoff() S32 LLGLTFMaterial::getDefaultAlphaMode() { - return (S32)ALPHA_MODE_OPAQUE; + return (S32) ALPHA_MODE_OPAQUE; } F32 LLGLTFMaterial::getDefaultMetallicFactor() @@ -352,6 +364,21 @@ bool LLGLTFMaterial::getDefaultDoubleSided() return false; } +LLVector2 LLGLTFMaterial::getDefaultTextureOffset() +{ + return LLVector2(0.f, 0.f); +} + +LLVector2 LLGLTFMaterial::getDefaultTextureScale() +{ + return LLVector2(1.f, 1.f); +} + +F32 LLGLTFMaterial::getDefaultTextureRotation() +{ + return 0.f; +} + void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const { if (model.materials.size() < mat_index + 1) diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 32695d92f4..ea7e402805 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -79,13 +79,30 @@ public: bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; - enum TextureTransformIdx : U32 + // get a UUID based on a hash of this LLGLTFMaterial + LLUUID getHash() const + { + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + LLMD5 md5; + md5.update((unsigned char*)this, sizeof(this)); + md5.finalize(); + LLUUID id; + md5.raw_digest(id.mData); + // *TODO: Hash the overrides + return id; + } + + enum TextureInfo : U32 { - TEXTURE_TRANSFORM_DIFFUSE_EMISSIVE, - TEXTURE_TRANSFORM_NORMAL, - TEXTURE_TRANSFORM_METALLIC_ROUGHNESS + GLTF_TEXTURE_INFO_BASE_COLOR, + GLTF_TEXTURE_INFO_NORMAL, + GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, + GLTF_TEXTURE_INFO_EMISSIVE, + + GLTF_TEXTURE_INFO_COUNT }; - TextureTransform mTextureTransform[3]; + + std::array mTextureTransform; //setters for various members (will clamp to acceptable ranges) @@ -101,6 +118,9 @@ public: void setRoughnessFactor(F32 roughness); void setAlphaMode(S32 mode); void setDoubleSided(bool double_sided); + void setTextureOffset(TextureInfo texture_info, const LLVector2& offset); + void setTextureScale(TextureInfo texture_info, const LLVector2& scale); + void setTextureRotation(TextureInfo texture_info, float rotation); // Default value accessors static LLUUID getDefaultBaseColorId(); @@ -114,6 +134,9 @@ public: static LLColor4 getDefaultBaseColor(); static LLColor3 getDefaultEmissiveColor(); static bool getDefaultDoubleSided(); + static LLVector2 getDefaultTextureOffset(); + static LLVector2 getDefaultTextureScale(); + static F32 getDefaultTextureRotation(); // set mAlphaMode from string. // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE @@ -161,17 +184,6 @@ public: // write to given tinygltf::Model void writeToModel(tinygltf::Model& model, S32 mat_index) const; - // get a UUID based on a hash of this LLGLTFMaterial - LLUUID getHash() const - { - LLMD5 md5; - md5.update((unsigned char*)this, sizeof(this)); - md5.finalize(); - LLUUID id; - md5.raw_digest(id.mData); - return id; - } - // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const; -- cgit v1.3 From fd751f4e99557f4d1ef9cbdc4ab7b7a765b563d1 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 20 Oct 2022 17:45:03 -0500 Subject: SL-18105 Add remaining parameters to applyOverride --- indra/llprimitive/llgltfmaterial.cpp | 59 +++++++++++++++++++++++++++++++++++- 1 file changed, 58 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 8f08a8b2cf..7b6612b90a 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -476,6 +476,8 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { + // TODO: potentially reimplement this with a more general purpose JSON merge + if (override_mat.mBaseColorId != getDefaultBaseColorId()) { mBaseColorId = override_mat.mBaseColorId; @@ -496,5 +498,60 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) mEmissiveId = override_mat.mEmissiveId; } - //TODO -- implement non texture parameters + if (override_mat.mBaseColor != getDefaultBaseColor()) + { + mBaseColor = override_mat.mBaseColor; + } + + if (override_mat.mEmissiveColor != getDefaultEmissiveColor()) + { + mEmissiveColor = override_mat.mEmissiveColor; + } + + if (override_mat.mMetallicFactor != getDefaultMetallicFactor()) + { + mMetallicFactor = override_mat.mMetallicFactor; + } + + if (override_mat.mRoughnessFactor != getDefaultRoughnessFactor()) + { + mRoughnessFactor = override_mat.mRoughnessFactor; + } + + if (override_mat.mAlphaMode != getDefaultAlphaMode()) + { + mAlphaMode = override_mat.mAlphaMode; + } + if (override_mat.mAlphaCutoff != getDefaultAlphaCutoff()) + { + mAlphaCutoff = override_mat.mAlphaCutoff; + } + + if (override_mat.mDoubleSided != getDefaultDoubleSided()) + { + mDoubleSided = override_mat.mDoubleSided; + } + + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset()) + { + mTextureTransform[i].mOffset = override_mat.mTextureTransform[i].mOffset; + } + + if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) + { + mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; + } + + if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) + { + mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; + } + + if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation()) + { + mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation; + } + } } -- cgit v1.3 From 88659e9fe793a02fb4edcbf8ef07307c25119604 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Sat, 22 Oct 2022 15:25:03 -0500 Subject: SL-18105 When saving an object's material to inventory, save the version that as overrides applied. --- indra/llprimitive/lltextureentry.cpp | 51 +++++++++++++++++++++++++----------- indra/newview/llgltfmateriallist.cpp | 1 + indra/newview/llmaterialeditor.cpp | 14 +++++++++- indra/newview/llmaterialeditor.h | 3 ++- indra/newview/llpanelface.cpp | 2 +- indra/newview/llviewermenu.cpp | 6 ++--- indra/newview/llviewerobject.cpp | 3 +++ 7 files changed, 58 insertions(+), 22 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index e185404ada..68de480d87 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -80,22 +80,7 @@ LLTextureEntry::LLTextureEntry(const LLTextureEntry &rhs) , mSelected(false) , mMaterialUpdatePending(false) { - mID = rhs.mID; - mScaleS = rhs.mScaleS; - mScaleT = rhs.mScaleT; - mOffsetS = rhs.mOffsetS; - mOffsetT = rhs.mOffsetT; - mRotation = rhs.mRotation; - mColor = rhs.mColor; - mBump = rhs.mBump; - mMediaFlags = rhs.mMediaFlags; - mGlow = rhs.mGlow; - mMaterialID = rhs.mMaterialID; - mMaterial = rhs.mMaterial; - if (rhs.mMediaEntry != NULL) { - // Make a copy - mMediaEntry = new LLMediaEntry(*rhs.mMediaEntry); - } + *this = rhs; } LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) @@ -124,6 +109,17 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) else { mMediaEntry = NULL; } + + mMaterialID = rhs.mMaterialID; + + if (rhs.mGLTFMaterialOverrides.notNull()) + { + mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides); + } + else + { + mGLTFMaterialOverrides = nullptr; + } } return *this; @@ -218,6 +214,11 @@ void LLTextureEntry::asLLSD(LLSD& sd) const sd[TEXTURE_MEDIA_DATA_KEY] = mediaData; } sd["glow"] = mGlow; + + if (mGLTFMaterialOverrides.notNull()) + { + sd["gltf_override"] = mGLTFMaterialOverrides->asJSON(); + } } bool LLTextureEntry::fromLLSD(const LLSD& sd) @@ -282,6 +283,24 @@ bool LLTextureEntry::fromLLSD(const LLSD& sd) setGlow((F32)sd[w].asReal() ); } + w = "gltf_override"; + if (sd.has(w)) + { + if (mGLTFMaterialOverrides.isNull()) + { + mGLTFMaterialOverrides = new LLGLTFMaterial(); + } + + std::string warn_msg, error_msg; + if (!mGLTFMaterialOverrides->fromJSON(sd[w].asString(), warn_msg, error_msg)) + { + LL_WARNS() << llformat("Failed to parse GLTF json: %s -- %s", warn_msg.c_str(), error_msg.c_str()) << LL_ENDL; + LL_WARNS() << sd[w].asString() << LL_ENDL; + + mGLTFMaterialOverrides = nullptr; + } + } + return true; fail: return false; diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 88923ba734..4861c2a33b 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -74,6 +74,7 @@ namespace } LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID()); + llassert(obj); // should never get an override for an object we don't know about S32 side = message["side"].asInteger(); std::string gltf_json = message["gltf_json"].asString(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 038f4df863..8086bcf402 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1401,7 +1401,7 @@ void LLMaterialEditor::loadMaterialFromFile(const std::string& filename, S32 ind } } -void LLMaterialEditor::loadLiveMaterialEditor() +void LLMaterialEditor::loadLive() { LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); if (me->setFromSelection()) @@ -1416,6 +1416,18 @@ void LLMaterialEditor::loadLiveMaterialEditor() } } +void LLMaterialEditor::loadObjectSave() +{ + LLMaterialEditor* me = (LLMaterialEditor*)LLFloaterReg::getInstance("material_editor", LLSD(LIVE_MATERIAL_EDITOR_KEY)); + if (me->setFromSelection()) + { + me->mIsOverride = false; + me->childSetVisible("save", false); + me->openFloater(); + me->setFocus(TRUE); + } +} + void LLMaterialEditor::loadFromGLTFMaterial(LLUUID &asset_id) { if (asset_id.isNull()) diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 9cd8bcd88b..23cb32aacf 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -103,7 +103,8 @@ public: // will promt to select specific one static void loadMaterialFromFile(const std::string& filename, S32 index = -1); - static void loadLiveMaterialEditor(); + static void loadLive(); + static void loadObjectSave(); static void loadFromGLTFMaterial(LLUUID &asset_id); diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index f8e786fc97..c6e0bc5153 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4588,7 +4588,7 @@ void LLPanelFace::onPbrStartEditing() LL_DEBUGS() << "loading material live editor with asset " << material_id << LL_ENDL; - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } bool LLPanelFace::isIdenticalPlanarTexgen() diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 47b355e554..18d215f9f4 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -2970,7 +2970,7 @@ void load_life_gltf_material(bool copy) } else { - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } LLViewerJoystick::getInstance()->moveObjects(true); @@ -2980,12 +2980,12 @@ void load_life_gltf_material(bool copy) void handle_object_edit_gltf_material() { handle_object_edit(); - LLMaterialEditor::loadLiveMaterialEditor(); + LLMaterialEditor::loadLive(); } void handle_object_save_gltf_material() { - load_life_gltf_material(true); + LLMaterialEditor::loadObjectSave(); } void handle_attachment_edit(const LLUUID& inv_item_id) diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index eaf0287dae..603dcc4fa7 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5333,6 +5333,9 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma tep->setGLTFMaterialOverride(override_mat); + // if override mat exists, we must also have a source mat + llassert(override_mat ? src_mat : true); + if (override_mat && src_mat) { LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); -- cgit v1.3 From 5c86ec6a6130bef9348d6155c6a7404914c20418 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 24 Oct 2022 16:26:42 -0500 Subject: SL-18105 Add mechanism for applying overrides that were received before associated ViewerObject was ready to receive them. --- indra/llprimitive/lltextureentry.cpp | 11 ++++++++ indra/llprimitive/lltextureentry.h | 4 +-- indra/newview/llgltfmateriallist.cpp | 49 ++++++++++++++++++++++++++++++++---- indra/newview/llgltfmateriallist.h | 10 ++++++++ indra/newview/llviewerobject.cpp | 5 ++-- indra/newview/llvovolume.cpp | 4 +++ 6 files changed, 74 insertions(+), 9 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 68de480d87..d810c6ed25 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -519,6 +519,17 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) } } +LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const +{ + if (mGLTFRenderMaterial.notNull()) + { + return mGLTFRenderMaterial; + } + + llassert(getGLTFMaterialOverride() == nullptr); + return getGLTFMaterial(); +} + S32 LLTextureEntry::setGLTFRenderMaterial(LLGLTFMaterial* mat) { if (mGLTFRenderMaterial != mat) diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 8dc3434a01..e37bc9a3b6 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -199,12 +199,12 @@ public: LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } // GLTF override - LLGLTFMaterial* getGLTFMaterialOverride() { return mGLTFMaterialOverrides; } + LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } // GLTF render material // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter - LLGLTFMaterial* getGLTFRenderMaterial() const { return mGLTFRenderMaterial.notNull() ? mGLTFRenderMaterial.get() : getGLTFMaterial(); } + LLGLTFMaterial* getGLTFRenderMaterial() const; S32 setGLTFRenderMaterial(LLGLTFMaterial* mat); public: diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 4861c2a33b..cd60d34d2f 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -43,6 +43,8 @@ #include "json/reader.h" #include "json/value.h" +LLGLTFMaterialList gGLTFMaterialList; + namespace { class LLGLTFMaterialOverrideDispatchHandler : public LLDispatchHandler @@ -72,24 +74,27 @@ namespace LL_WARNS() << "LLGLTFMaterialOverrideDispatchHandler: Attempted to read parameter data into LLSD but failed:" << llsdRaw << LL_ENDL; } } + + LLUUID object_id = message["object_id"].asUUID(); - LLViewerObject * obj = gObjectList.findObject(message["object_id"].asUUID()); - llassert(obj); // should never get an override for an object we don't know about + LLViewerObject * obj = gObjectList.findObject(object_id); S32 side = message["side"].asInteger(); std::string gltf_json = message["gltf_json"].asString(); std::string warn_msg, error_msg; LLPointer override_data = new LLGLTFMaterial(); bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg); + if (!success) { LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; } else { - if (obj) + if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) { - obj->setTEGLTFMaterialOverride(side, override_data); + // object not ready to receive override data, queue for later + gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); } } @@ -99,7 +104,41 @@ namespace LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message; } -LLGLTFMaterialList gGLTFMaterialList; +void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data) +{ + override_list_t& overrides = mQueuedOverrides[id]; + + if (overrides.size() < side + 1) + { + overrides.resize(side + 1); + } + + overrides[side] = override_data; +} + +void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) +{ + const LLUUID& id = obj->getID(); + auto& iter = mQueuedOverrides.find(id); + + if (iter != mQueuedOverrides.end()) + { + override_list_t& overrides = iter->second; + for (int i = 0; i < overrides.size(); ++i) + { + if (overrides[i].notNull()) + { + if (!obj->getTE(i)->getGLTFMaterial()) + { // object doesn't have its base GLTF material yet, don't apply override (yet) + return; + } + obj->setTEGLTFMaterialOverride(i, overrides[i]); + } + } + + mQueuedOverrides.erase(iter); + } +} LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index 4b905e32c9..ee32dc8825 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -48,10 +48,20 @@ public: void flushMaterials(); static void registerCallbacks(); + + // save an override update for later (for example, if an override arrived for an unknown object) + void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data); + + void applyQueuedOverrides(LLViewerObject* obj); + private: typedef std::unordered_map > uuid_mat_map_t; uuid_mat_map_t mList; + typedef std::vector > override_list_t; + typedef std::unordered_map queued_override_map_t; + queued_override_map_t mQueuedOverrides; + LLUUID mLastUpdateKey; }; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 603dcc4fa7..ac519970b7 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -247,6 +247,7 @@ LLViewerObject *LLViewerObject::createObject(const LLUUID &id, const LLPCode pco LL_WARNS() << "Unknown object pcode " << (S32)pcode << LL_ENDL; res = NULL; break; } + return res; } @@ -5324,8 +5325,8 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma LLTextureEntry* tep = getTE(te); if (!tep) - { - LL_WARNS() << "No texture entry for te " << (S32)te << ", object " << mID << LL_ENDL; + { // this could happen if the object is not fully formed yet + // returning TEM_CHANGE_NONE here signals to LLGLTFMaterialList to queue the override for later return retval; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index cb58c173d9..aea4353bc8 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -88,6 +88,7 @@ #include "llcallstack.h" #include "llsculptidsize.h" #include "llavatarappearancedefines.h" +#include "llgltfmateriallist.h" const F32 FORCE_SIMPLE_RENDER_AREA = 512.f; const F32 FORCE_CULL_AREA = 8.f; @@ -5823,6 +5824,9 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } + // apply any pending material overrides + gGLTFMaterialList.applyQueuedOverrides(vobj); + std::string vobj_name = llformat("Vol%p", vobj); bool is_mesh = vobj->isMesh(); -- cgit v1.3 From 8f47657d646c06dbba8d44497c0f81fd00730cc8 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 26 Oct 2022 16:08:28 -0500 Subject: SL-18443 Allow nulling out of override data and implement new override message protocol. --- indra/llprimitive/lltextureentry.cpp | 14 ++++- indra/llprimitive/lltextureentry.h | 2 +- indra/newview/llgltfmateriallist.cpp | 116 ++++++++++++++++++++++++++++++----- indra/newview/llgltfmateriallist.h | 7 +++ indra/newview/llmaterialeditor.cpp | 29 +-------- indra/newview/llmaterialeditor.h | 2 - indra/newview/llselectmgr.cpp | 38 +----------- indra/newview/llviewerobject.cpp | 14 +++++ 8 files changed, 138 insertions(+), 84 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index d810c6ed25..7640dd70bd 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -512,13 +512,25 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) { - mGLTFMaterial = material; + // assert on precondtion: + // whether or not mGLTFMaterial is null, any existing override should have been nulled out + // before calling setGLTFMaterial + // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID + llassert(getGLTFMaterialOverride() == nullptr); + + mGLTFMaterial = material; if (mGLTFMaterial == nullptr) { setGLTFRenderMaterial(nullptr); } } +void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat) +{ + llassert(mat == nullptr || getGLTFMaterial() != nullptr); // if override is not null, base material must not be null + mGLTFMaterialOverrides = mat; +} + LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const { if (mGLTFRenderMaterial.notNull()) diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index e37bc9a3b6..d94e14bd73 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -200,7 +200,7 @@ public: // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } - void setGLTFMaterialOverride(LLGLTFMaterial* mat) { mGLTFMaterialOverrides = mat; } + void setGLTFMaterialOverride(LLGLTFMaterial* mat); // GLTF render material // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index cd60d34d2f..3b4e9406bb 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -36,13 +36,15 @@ #include "llviewercontrol.h" #include "llviewergenericmessage.h" #include "llviewerobjectlist.h" - +#include "llcorehttputil.h" #include "tinygltf/tiny_gltf.h" #include #include "json/reader.h" #include "json/value.h" +#include + LLGLTFMaterialList gGLTFMaterialList; namespace @@ -77,27 +79,80 @@ namespace LLUUID object_id = message["object_id"].asUUID(); - LLViewerObject * obj = gObjectList.findObject(object_id); - S32 side = message["side"].asInteger(); - std::string gltf_json = message["gltf_json"].asString(); - - std::string warn_msg, error_msg; - LLPointer override_data = new LLGLTFMaterial(); - bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg); + LLViewerObject * obj = gObjectList.findObject(object_id); // NOTE: null object here does NOT mean nothing to do, parse message and queue results for later + bool clear_all = true; - if (!success) + if (message.has("sides") && message.has("gltf_json")) { - LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; + LLSD& sides = message["sides"]; + LLSD& gltf_json = message["gltf_json"]; + + if (sides.isArray() && gltf_json.isArray() && + sides.size() != 0 && + sides.size() == gltf_json.size()) + { + clear_all = false; + + // message should be interpreted thusly: + /// sides is a list of face indices + // gltf_json is a list of corresponding json + // any side not represented in "sides" has no override + + // parse json + std::unordered_set side_set; + + for (int i = 0; i < sides.size(); ++i) + { + LLPointer override_data = new LLGLTFMaterial(); + + std::string gltf_json = message["gltf_json"][i].asString(); + + std::string warn_msg, error_msg; + + bool success = override_data->fromJSON(gltf_json, warn_msg, error_msg); + + if (!success) + { + LL_WARNS() << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; + } + else + { + S32 side = sides[i].asInteger(); + // flag this side to not be nulled out later + side_set.insert(sides); + + if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) + { + // object not ready to receive override data, queue for later + gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); + } + } + } + + if (obj && side_set.size() != obj->getNumTEs()) + { // object exists and at least one texture entry needs to have its override data nulled out + for (int i = 0; i < obj->getNumTEs(); ++i) + { + if (side_set.find(i) == side_set.end()) + { + obj->setTEGLTFMaterialOverride(i, nullptr); + } + } + } + } + else + { + LL_WARNS() << "Malformed GLTF override message data: " << message << LL_ENDL; + } } - else - { - if (!obj || !obj->setTEGLTFMaterialOverride(side, override_data)) + + if (clear_all && obj) + { // override list was empty or an error occurred, null out all overrides for this object + for (int i = 0; i < obj->getNumTEs(); ++i) { - // object not ready to receive override data, queue for later - gGLTFMaterialList.queueOverrideUpdate(object_id, side, override_data); + obj->setTEGLTFMaterialOverride(i, nullptr); } } - return true; } }; @@ -296,3 +351,32 @@ void LLGLTFMaterialList::registerCallbacks() { gGenericDispatcher.addHandler("GLTFMaterialOverride", &handle_gltf_override_message); } + +// static +void LLGLTFMaterialList::modifyMaterialCoro(std::string cap_url, LLSD overrides) +{ + LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); + LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t + httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); + LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); + LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); + LLCore::HttpHeaders::ptr_t httpHeaders; + + httpOpts->setFollowRedirects(true); + + LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; + + LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); + + LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; + LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); + + if (!status) + { + LL_WARNS() << "Failed to modify material." << LL_ENDL; + } + else if (!result["success"].asBoolean()) + { + LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; + } +} diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index ee32dc8825..f770f6ecc8 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -49,6 +49,13 @@ public: static void registerCallbacks(); + // apply given override data via given cap url + // cap_url -- should be gAgent.getRegionCapability("ModifyMaterialParams") + // overrides -- LLSD map in the format + // "object_id": LLUUID - object to be modified + // "side": integer - index of face to be modified + // "gltf_json" : string - GLTF compliant json of override data (optional, if omitted any existing override data will be cleared) + static void modifyMaterialCoro(std::string cap_url, LLSD overrides); // save an override update for later (for example, if an override arrived for an unknown object) void queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 06705a277b..5ae16db1f6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1994,7 +1994,7 @@ public: "side", te, "gltf_json", overrides_json ); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLMaterialEditor::modifyMaterialCoro, mEditor, mCapUrl, overrides)); + LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, mCapUrl, overrides)); } return true; } @@ -2452,30 +2452,3 @@ void LLMaterialEditor::loadDefaults() setFromGltfModel(model_in, 0, true); } -void LLMaterialEditor::modifyMaterialCoro(std::string cap_url, LLSD overrides) -{ - LLCore::HttpRequest::policy_t httpPolicy(LLCore::HttpRequest::DEFAULT_POLICY_ID); - LLCoreHttpUtil::HttpCoroutineAdapter::ptr_t - httpAdapter(new LLCoreHttpUtil::HttpCoroutineAdapter("modifyMaterialCoro", httpPolicy)); - LLCore::HttpRequest::ptr_t httpRequest(new LLCore::HttpRequest); - LLCore::HttpOptions::ptr_t httpOpts(new LLCore::HttpOptions); - LLCore::HttpHeaders::ptr_t httpHeaders; - - httpOpts->setFollowRedirects(true); - - LL_DEBUGS() << "Applying override via ModifyMaterialParams cap: " << overrides << LL_ENDL; - - LLSD result = httpAdapter->postAndSuspend(httpRequest, cap_url, overrides, httpOpts, httpHeaders); - - LLSD httpResults = result[LLCoreHttpUtil::HttpCoroutineAdapter::HTTP_RESULTS]; - LLCore::HttpStatus status = LLCoreHttpUtil::HttpCoroutineAdapter::getStatusFromLLSD(httpResults); - - if (!status) - { - LL_WARNS() << "Failed to modify material." << LL_ENDL; - } - else if (!result["success"].asBoolean()) - { - LL_WARNS() << "Failed to modify material: " << result["message"] << LL_ENDL; - } -} diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 60907b18ba..53f19d877b 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -219,8 +219,6 @@ public: // initialize the UI from a default GLTF material void loadDefaults(); - void modifyMaterialCoro(std::string cap_url, LLSD overrides); - private: void setFromGLTFMaterial(LLGLTFMaterial* mat); bool setFromSelection(); diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 2475900d0e..ac508c4e8a 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1950,48 +1950,14 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) if (te != -1) { - LLTextureEntry* tep = objectp->getTE(te); - if (asset_id.notNull()) - { - tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } - else - { - tep->setGLTFMaterial(nullptr); - } - - objectp->faceMappingChanged(); - gPipeline.markTextured(objectp->mDrawable); - - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (param_block) - { - param_block->setMaterial(te, asset_id); - } + objectp->setRenderMaterialID(te, asset_id); } else // Shouldn't happen? { S32 num_faces = objectp->getNumTEs(); for (S32 face = 0; face < num_faces; face++) { - LLTextureEntry* tep = objectp->getTE(face); - if (asset_id.notNull()) - { - tep->setGLTFMaterial(gGLTFMaterialList.getMaterial(asset_id)); - } - else - { - tep->setGLTFMaterial(nullptr); - } - - objectp->faceMappingChanged(); - gPipeline.markTextured(objectp->mDrawable); - - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)objectp->getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (param_block) - { - param_block->setMaterial(face, asset_id); - } + objectp->setRenderMaterialID(te, asset_id); } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index ac519970b7..7dbe0652b1 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7115,6 +7115,20 @@ const LLUUID& LLViewerObject::getRenderMaterialID(U8 te) const void LLViewerObject::setRenderMaterialID(U8 te, const LLUUID& id, bool update_server) { + if (update_server) + { + // clear out any existing override data and render material + getTE(te)->setGLTFMaterialOverride(nullptr); + getTE(te)->setGLTFRenderMaterial(nullptr); + + LLCoros::instance().launch("modifyMaterialCoro", + std::bind(&LLGLTFMaterialList::modifyMaterialCoro, + gAgent.getRegionCapability("ModifyMaterialParams"), + llsd::map( + "object_id", getID(), + "side", te))); + } + if (id.notNull()) { getTE(te)->setGLTFMaterial(gGLTFMaterialList.getMaterial(id)); -- cgit v1.3 From 0e02f25604ac8518b23fcb0b466866013c90dc91 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 26 Oct 2022 23:51:13 -0500 Subject: SL-18472 Fix for assert when increasing number of texture entries on existing primitive with overrides applied. --- indra/llprimitive/lltextureentry.cpp | 2 ++ indra/newview/llviewerobject.cpp | 37 ++++++++++++++++++++++++++++++++---- 2 files changed, 35 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 2803afde60..611f146a84 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -112,6 +112,8 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mMaterialID = rhs.mMaterialID; + mGLTFMaterial = rhs.mGLTFMaterial; + if (rhs.mGLTFMaterialOverrides.notNull()) { mGLTFMaterialOverrides = new LLGLTFMaterial(*rhs.mGLTFMaterialOverrides); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cbdf3964e5..aebeeb21ac 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4767,9 +4767,38 @@ void LLViewerObject::setNumTEs(const U8 num_tes) { deleteTEImages(); } + + S32 original_tes = getNumTEs(); + LLPrimitive::setNumTEs(num_tes); setChanged(TEXTURE); + // touch up GLTF materials + if (original_tes > 0) + { + for (int i = original_tes; i < getNumTEs(); ++i) + { + LLTextureEntry* src = getTE(original_tes - 1); + LLTextureEntry* tep = getTE(i); + setRenderMaterialID(i, getRenderMaterialID(original_tes - 1), false); + + if (tep) + { + LLGLTFMaterial* base_material = src->getGLTFMaterial(); + LLGLTFMaterial* override_material = src->getGLTFMaterialOverride(); + if (base_material && override_material) + { + tep->setGLTFMaterialOverride(new LLGLTFMaterial(*override_material)); + + LLGLTFMaterial* render_material = new LLFetchedGLTFMaterial(); + *render_material = *base_material; + render_material->applyOverride(*override_material); + tep->setGLTFRenderMaterial(render_material); + } + } + } + } + if (mDrawable.notNull()) { gPipeline.markTextured(mDrawable); @@ -7129,12 +7158,12 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat for (S32 te = start_idx; te < end_idx; ++te) { + // clear out any existing override data and render material + getTE(te)->setGLTFMaterialOverride(nullptr); + getTE(te)->setGLTFRenderMaterial(nullptr); + if (update_server) { - // clear out any existing override data and render material - getTE(te)->setGLTFMaterialOverride(nullptr); - getTE(te)->setGLTFRenderMaterial(nullptr); - LLCoros::instance().launch("modifyMaterialCoro", std::bind(&LLGLTFMaterialList::modifyMaterialCoro, gAgent.getRegionCapability("ModifyMaterialParams"), -- cgit v1.3 From 5364da4d8eae518b0a53fdbbf675c6bff1797fed Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 27 Oct 2022 12:22:00 -0700 Subject: SL-18411: GLTF material transform serialization, plus fix improper indexing not matching GLTF spec --- indra/llprimitive/llgltfmaterial.cpp | 266 +++++++++++++++++++---------------- indra/llprimitive/llgltfmaterial.h | 8 ++ 2 files changed, 152 insertions(+), 122 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 7b6612b90a..6164234d6c 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -30,6 +30,11 @@ #include "tinygltf/tiny_gltf.h" +const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; +const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; +const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; +const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; + LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; @@ -82,6 +87,7 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const { #if 1 tinygltf::TinyGLTF gltf; + tinygltf::Model model_out; std::ostringstream str; @@ -105,118 +111,131 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) const tinygltf::Material& material_in = model.materials[mat_index]; - // get base color texture - S32 tex_index = material_in.pbrMetallicRoughness.baseColorTexture.index; - if (tex_index >= 0) - { - mBaseColorId.set(model.images[tex_index].uri); - } - else + // Apply base color texture + setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId); + // Apply normal map + setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId); + // Apply metallic-roughness texture + setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId); + // Apply emissive texture + setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId); + + setAlphaMode(material_in.alphaMode); + mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); + + mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor); + mEmissiveColor.set(material_in.emissiveFactor); + + mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); + mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); + + mDoubleSided = material_in.doubleSided; +} + +LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value) +{ + const auto it = object.find(key); + if (it == object.end()) { - mBaseColorId.setNull(); + return default_value; } - - // get normal map - tex_index = material_in.normalTexture.index; - if (tex_index >= 0) + const tinygltf::Value& vec2_json = std::get<1>(*it); + if (!vec2_json.IsArray() || vec2_json.ArrayLen() < LENGTHOFVECTOR2) { - mNormalId.set(model.images[tex_index].uri); + return default_value; } - else + LLVector2 value; + for (U32 i = 0; i < LENGTHOFVECTOR2; ++i) { - mNormalId.setNull(); + const tinygltf::Value& real_json = vec2_json.Get(i); + if (!real_json.IsReal()) + { + return default_value; + } + value.mV[i] = (F32)real_json.Get(); } + return value; +} - // get metallic-roughness texture - tex_index = material_in.pbrMetallicRoughness.metallicRoughnessTexture.index; - if (tex_index >= 0) +F32 float_from_json(const tinygltf::Value::Object& object, const char* key, const F32 default_value) +{ + const auto it = object.find(key); + if (it == object.end()) { - mMetallicRoughnessId.set(model.images[tex_index].uri); + return default_value; } - else + const tinygltf::Value& real_json = std::get<1>(*it); + if (!real_json.IsReal()) { - mMetallicRoughnessId.setNull(); + return default_value; } + return (F32)real_json.GetNumberAsDouble(); +} - // get emissive texture - tex_index = material_in.emissiveTexture.index; - if (tex_index >= 0) +template +std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info) +{ + const S32 texture_idx = texture_info.index; + if (texture_idx < 0 || texture_idx >= model.textures.size()) { - mEmissiveId.set(model.images[tex_index].uri); + return ""; } - else + const tinygltf::Texture& texture = model.textures[texture_idx]; + + // Ignore texture.sampler for now + + const S32 image_idx = texture.source; + if (image_idx < 0 || image_idx >= model.images.size()) { - mEmissiveId.setNull(); + return ""; } + const tinygltf::Image& image = model.images[image_idx]; - setAlphaMode(material_in.alphaMode); - mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); - - mBaseColor.set(material_in.pbrMetallicRoughness.baseColorFactor); - mEmissiveColor.set(material_in.emissiveFactor); + return image.uri; +} - mMetallicFactor = llclamp((F32)material_in.pbrMetallicRoughness.metallicFactor, 0.f, 1.f); - mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); +// *NOTE: Use template here as workaround for the different similar texture info classes +template +void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out) +{ + const std::string uri = gltf_get_texture_image(model, texture_info); + texture_id_out.set(uri); - mDoubleSided = material_in.doubleSided; + const tinygltf::Value::Object& extensions_object = texture_info.extensions; + const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM); + if (transform_it != extensions_object.end()) + { + const tinygltf::Value& transform_json = std::get<1>(*transform_it); + if (transform_json.IsObject()) + { + const tinygltf::Value::Object& transform_object = transform_json.Get(); + TextureTransform& transform = mTextureTransform[texture_info_id]; + transform.mOffset = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset()); + transform.mScale = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale()); + transform.mRotation = float_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation()); + } + } } void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const { - if (model.materials.size() < mat_index + 1) + if (model.materials.size() < mat_index+1) { model.materials.resize(mat_index + 1); } tinygltf::Material& material_out = model.materials[mat_index]; - // set base color texture - if (mBaseColorId.notNull()) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.pbrMetallicRoughness.baseColorTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mBaseColorId.asString(); - } + constexpr bool is_override = false; + // set base color texture + writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId, is_override, LLUUID()); // set normal texture - if (mNormalId.notNull()) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.normalTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mNormalId.asString(); - } - + writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId, is_override, LLUUID()); // set metallic-roughness texture - if (mMetallicRoughnessId.notNull()) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mMetallicRoughnessId.asString(); - } - + writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId, is_override, LLUUID()); // set emissive texture - if (mEmissiveId.notNull()) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.emissiveTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mEmissiveId.asString(); - } + writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId, is_override, LLUUID()); material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; @@ -232,6 +251,46 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const model.asset.version = "2.0"; } +template +void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const std::string& uri) +{ + const S32 image_idx = model.images.size(); + model.images.emplace_back(); + model.images[image_idx].uri = uri; + + // The texture, not to be confused with the texture info + const S32 texture_idx = model.textures.size(); + model.textures.emplace_back(); + tinygltf::Texture& texture = model.textures[texture_idx]; + texture.source = image_idx; + + texture_info.index = texture_idx; +} + +template +void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id, bool is_override, const LLUUID& base_texture_id) const +{ + if (texture_id.isNull() || (is_override && texture_id == base_texture_id)) + { + return; + } + + gltf_allocate_texture_image(model, texture_info, texture_id.asString()); + + tinygltf::Value::Object transform_map; + const TextureTransform& transform = mTextureTransform[texture_info_id]; + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mOffset.mV[VX]), + tinygltf::Value(transform.mOffset.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mScale.mV[VX]), + tinygltf::Value(transform.mScale.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation); + texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); +} + void LLGLTFMaterial::setBaseColorId(const LLUUID& id) { @@ -390,53 +449,16 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index // TODO - fix handling of resetting to null/default values - // set base color texture - if (mBaseColorId.notNull() && mBaseColorId != base_material->mBaseColorId) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.pbrMetallicRoughness.baseColorTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mBaseColorId.asString(); - } + constexpr bool is_override = true; + // set base color texture + writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId, is_override, base_material->mBaseColorId); // set normal texture - if (mNormalId.notNull() && mNormalId != base_material->mNormalId) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.normalTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mNormalId.asString(); - } - + writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId, is_override, base_material->mNormalId); // set metallic-roughness texture - if (mMetallicRoughnessId.notNull() && mMetallicRoughnessId != base_material->mMetallicRoughnessId) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.pbrMetallicRoughness.metallicRoughnessTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mMetallicRoughnessId.asString(); - } - + writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId, is_override, base_material->mMetallicRoughnessId); // set emissive texture - if (mEmissiveId.notNull() && mEmissiveId != base_material->mEmissiveId) - { - U32 idx = model.images.size(); - model.images.resize(idx + 1); - model.textures.resize(idx + 1); - - material_out.emissiveTexture.index = idx; - model.textures[idx].source = idx; - model.images[idx].uri = mEmissiveId.asString(); - } + writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId, is_override, base_material->mEmissiveId); if (mAlphaMode != base_material->mAlphaMode) { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index ea7e402805..b0afb11bb5 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -118,6 +118,7 @@ public: void setRoughnessFactor(F32 roughness); void setAlphaMode(S32 mode); void setDoubleSided(bool double_sided); + void setTextureOffset(TextureInfo texture_info, const LLVector2& offset); void setTextureScale(TextureInfo texture_info, const LLVector2& scale); void setTextureRotation(TextureInfo texture_info, float rotation); @@ -189,5 +190,12 @@ public: void applyOverride(const LLGLTFMaterial& override_mat); +private: + + template + void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out); + + template + void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id, bool is_override, const LLUUID& base_texture_id) const; }; -- cgit v1.3 From b1f529082ba0d785bafe1aa49298eb2f9eca1d3f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 31 Oct 2022 20:42:47 +0200 Subject: SL-18446 Fix emissive tint --- indra/llprimitive/llgltfmaterial.cpp | 2 ++ 1 file changed, 2 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6164234d6c..9743bad7a7 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -241,6 +241,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.alphaCutoff = mAlphaCutoff; mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); + material_out.emissiveFactor.resize(3); // 0 size by default mEmissiveColor.write(material_out.emissiveFactor); material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; @@ -477,6 +478,7 @@ void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index if (mEmissiveColor != base_material->mEmissiveColor) { + material_out.emissiveFactor.resize(3); // 0 size by default mEmissiveColor.write(material_out.emissiveFactor); } -- cgit v1.3 From 75e743be2f60916e6bf78da24814551bd6415116 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Mon, 31 Oct 2022 15:58:20 -0500 Subject: SL-18442 Port of Caladbolg's fix for emissive overrides not taking. Remove unused function. --- indra/llprimitive/llgltfmaterial.cpp | 67 ++++-------------------------------- indra/llprimitive/llgltfmaterial.h | 3 -- 2 files changed, 7 insertions(+), 63 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 9743bad7a7..f771337c92 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -241,8 +241,14 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.alphaCutoff = mAlphaCutoff; mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); + material_out.emissiveFactor.resize(3); // 0 size by default - mEmissiveColor.write(material_out.emissiveFactor); + + if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor()) + { + material_out.emissiveFactor.resize(3); + mEmissiveColor.write(material_out.emissiveFactor); + } material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; @@ -439,65 +445,6 @@ F32 LLGLTFMaterial::getDefaultTextureRotation() return 0.f; } -void LLGLTFMaterial::writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const -{ - if (model.materials.size() < mat_index + 1) - { - model.materials.resize(mat_index + 1); - } - - tinygltf::Material& material_out = model.materials[mat_index]; - - // TODO - fix handling of resetting to null/default values - - constexpr bool is_override = true; - - // set base color texture - writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId, is_override, base_material->mBaseColorId); - // set normal texture - writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId, is_override, base_material->mNormalId); - // set metallic-roughness texture - writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId, is_override, base_material->mMetallicRoughnessId); - // set emissive texture - writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId, is_override, base_material->mEmissiveId); - - if (mAlphaMode != base_material->mAlphaMode) - { - material_out.alphaMode = getAlphaMode(); - } - - if (mAlphaCutoff != base_material->mAlphaCutoff) - { - material_out.alphaCutoff = mAlphaCutoff; - } - - if (mBaseColor != base_material->mBaseColor) - { - mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); - } - - if (mEmissiveColor != base_material->mEmissiveColor) - { - material_out.emissiveFactor.resize(3); // 0 size by default - mEmissiveColor.write(material_out.emissiveFactor); - } - - if (mMetallicFactor != base_material->mMetallicFactor) - { - material_out.pbrMetallicRoughness.metallicFactor = mMetallicFactor; - } - - if (mRoughnessFactor != base_material->mRoughnessFactor) - { - material_out.pbrMetallicRoughness.roughnessFactor = mRoughnessFactor; - } - - if (mDoubleSided != base_material->mDoubleSided) - { - material_out.doubleSided = mDoubleSided; - } -} - void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { // TODO: potentially reimplement this with a more general purpose JSON merge diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index b0afb11bb5..d94ce6e281 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -185,9 +185,6 @@ public: // write to given tinygltf::Model void writeToModel(tinygltf::Model& model, S32 mat_index) const; - // calculate the fields in this material that differ from a base material and write them out to a given tinygltf::Model - void writeOverridesToModel(tinygltf::Model& model, S32 mat_index, LLGLTFMaterial const* base_material) const; - void applyOverride(const LLGLTFMaterial& override_mat); private: -- cgit v1.3 From 9f21fba6d9a28cd1b324a115a0a2f86613a134e7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 1 Nov 2022 08:31:01 -0500 Subject: SL-18513 Put profile markers around GLTF code. --- indra/llprimitive/llgltfmaterial.cpp | 17 ++++----- indra/llprimitive/lltextureentry.cpp | 2 + indra/newview/llgltfmateriallist.cpp | 73 ++++++++++++++++++++++-------------- indra/newview/llviewerobject.cpp | 1 + 4 files changed, 55 insertions(+), 38 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index f771337c92..cd629dbbd8 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -42,6 +42,7 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) { + LL_PROFILE_ZONE_SCOPED; //have to do a manual operator= because of LLRefCount mBaseColorId = rhs.mBaseColorId; mNormalId = rhs.mNormalId; @@ -65,7 +66,7 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) { -#if 1 + LL_PROFILE_ZONE_SCOPED; tinygltf::TinyGLTF gltf; tinygltf::Model model_in; @@ -74,18 +75,14 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st { setFromModel(model_in, 0); - //DEBUG generate json and print - LL_INFOS() << asJSON(true) << LL_ENDL; - return true; } -#endif return false; } std::string LLGLTFMaterial::asJSON(bool prettyprint) const { -#if 1 + LL_PROFILE_ZONE_SCOPED; tinygltf::TinyGLTF gltf; tinygltf::Model model_out; @@ -97,13 +94,11 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); return str.str(); -#else - return ""; -#endif } void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) { + LL_PROFILE_ZONE_SCOPED; if (model.materials.size() <= mat_index) { return; @@ -198,6 +193,7 @@ std::string gltf_get_texture_image(const tinygltf::Model& model, const T& textur template void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out) { + LL_PROFILE_ZONE_SCOPED; const std::string uri = gltf_get_texture_image(model, texture_info); texture_id_out.set(uri); @@ -219,6 +215,7 @@ void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& textu void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const { + LL_PROFILE_ZONE_SCOPED; if (model.materials.size() < mat_index+1) { model.materials.resize(mat_index + 1); @@ -277,6 +274,7 @@ void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const template void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id, bool is_override, const LLUUID& base_texture_id) const { + LL_PROFILE_ZONE_SCOPED; if (texture_id.isNull() || (is_override && texture_id == base_texture_id)) { return; @@ -447,6 +445,7 @@ F32 LLGLTFMaterial::getDefaultTextureRotation() void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { + LL_PROFILE_ZONE_SCOPED; // TODO: potentially reimplement this with a more general purpose JSON merge if (override_mat.mBaseColorId != getDefaultBaseColorId()) diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 611f146a84..a0d5793dcc 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -198,6 +198,7 @@ LLSD LLTextureEntry::asLLSD() const void LLTextureEntry::asLLSD(LLSD& sd) const { + LL_PROFILE_ZONE_SCOPED; sd["imageid"] = mID; sd["colors"] = ll_sd_from_color4(mColor); sd["scales"] = mScaleS; @@ -225,6 +226,7 @@ void LLTextureEntry::asLLSD(LLSD& sd) const bool LLTextureEntry::fromLLSD(const LLSD& sd) { + LL_PROFILE_ZONE_SCOPED; const char *w, *x; w = "imageid"; if (sd.has(w)) diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index d91a448bc8..a4033f0d4d 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -61,6 +61,7 @@ namespace bool operator()(const LLDispatcher* dispatcher, const std::string& key, const LLUUID& invoice, const sparam_t& strings) override { + LL_PROFILE_ZONE_SCOPED; // receive override data from simulator via LargeGenericMessage // message should have: // object_id - UUID of LLViewerObject @@ -196,6 +197,7 @@ void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFM void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) { + LL_PROFILE_ZONE_SCOPED; const LLUUID& id = obj->getID(); auto iter = mQueuedOverrides.find(id); @@ -225,9 +227,11 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) { + LL_PROFILE_ZONE_SCOPED; uuid_mat_map_t::iterator iter = mList.find(id); if (iter == mList.end()) { + LL_PROFILE_ZONE_NAMED("gltf fetch") LLFetchedGLTFMaterial* mat = new LLFetchedGLTFMaterial(); mList[id] = mat; @@ -242,55 +246,66 @@ LLGLTFMaterial* LLGLTFMaterialList::getMaterial(const LLUUID& id) gAssetStorage->getAssetData(id, LLAssetType::AT_MATERIAL, [=](const LLUUID& id, LLAssetType::EType asset_type, void* user_data, S32 status, LLExtStat ext_status) { + LL_PROFILE_ZONE_SCOPED("gltf asset callback"); if (status) { LL_WARNS() << "Error getting material asset data: " << LLAssetStorage::getErrorString(status) << " (" << status << ")" << LL_ENDL; } - LLFileSystem file(id, asset_type, LLFileSystem::READ); - auto size = file.getSize(); - if (!size) + std::vector buffer; + { - LL_DEBUGS() << "Zero size material." << LL_ENDL; - mat->mFetching = false; - mat->unref(); - return; - } + LL_PROFILE_ZONE_SCOPED("gltf read asset"); + LLFileSystem file(id, asset_type, LLFileSystem::READ); + auto size = file.getSize(); + if (!size) + { + LL_DEBUGS() << "Zero size material." << LL_ENDL; + mat->mFetching = false; + mat->unref(); + return; + } - std::vector buffer; - buffer.resize(size); - file.read((U8*)&buffer[0], buffer.size()); - LLSD asset; - // read file into buffer - std::istrstream str(&buffer[0], buffer.size()); + buffer.resize(size); + file.read((U8*)&buffer[0], buffer.size()); + } - if (LLSDSerialize::deserialize(asset, str, buffer.size())) { - if (asset.has("version") && asset["version"] == "1.0") + LL_PROFILE_ZONE_SCOPED("gltf deserialize asset"); + + LLSD asset; + + // read file into buffer + std::istrstream str(&buffer[0], buffer.size()); + + if (LLSDSerialize::deserialize(asset, str, buffer.size())) { - if (asset.has("type") && asset["type"].asString() == "GLTF 2.0") + if (asset.has("version") && asset["version"] == "1.0") { - if (asset.has("data") && asset["data"].isString()) + if (asset.has("type") && asset["type"].asString() == "GLTF 2.0") { - std::string data = asset["data"]; + if (asset.has("data") && asset["data"].isString()) + { + std::string data = asset["data"]; - std::string warn_msg, error_msg; + std::string warn_msg, error_msg; - if (!mat->fromJSON(data, warn_msg, error_msg)) - { - LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; - LL_WARNS() << warn_msg << LL_ENDL; - LL_WARNS() << error_msg << LL_ENDL; + if (!mat->fromJSON(data, warn_msg, error_msg)) + { + LL_WARNS() << "Failed to decode material asset: " << LL_ENDL; + LL_WARNS() << warn_msg << LL_ENDL; + LL_WARNS() << error_msg << LL_ENDL; + } } } } } - } - else - { - LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + else + { + LL_WARNS() << "Failed to deserialize material LLSD" << LL_ENDL; + } } mat->mFetching = false; diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 43525a3173..a649387795 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5350,6 +5350,7 @@ S32 LLViewerObject::setTEMaterialParams(const U8 te, const LLMaterialPtr pMateri S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_mat) { + LL_PROFILE_ZONE_SCOPED; S32 retval = TEM_CHANGE_NONE; LLTextureEntry* tep = getTE(te); -- cgit v1.3 From a4ad75e93c20f140d9503c119201128b0f9e4d0e Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Tue, 1 Nov 2022 15:17:22 -0500 Subject: SL-18520 WIP - Use off-by-epsilon and special UUID identifier hacks to allow overriding to default values. --- indra/llprimitive/llgltfmaterial.cpp | 176 ++++++++++++++++++++++++++--------- indra/llprimitive/llgltfmaterial.h | 69 ++++++-------- indra/newview/llmaterialeditor.cpp | 50 +++++----- 3 files changed, 182 insertions(+), 113 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index cd629dbbd8..4b1f89f99f 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -28,6 +28,7 @@ #include "llgltfmaterial.h" +// NOTE -- this should be the one and only place tiny_gltf.h is included #include "tinygltf/tiny_gltf.h" const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; @@ -35,6 +36,9 @@ const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; +// special UUID that indicates a null UUID in override data +static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); + LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; @@ -296,64 +300,144 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); } +// static +void LLGLTFMaterial::hackOverrideUUID(LLUUID& id) +{ + if (id == LLUUID::null) + { + id = GLTF_OVERRIDE_NULL_UUID; + } +} -void LLGLTFMaterial::setBaseColorId(const LLUUID& id) +void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override) { mBaseColorId = id; + if (for_override) + { + hackOverrideUUID(mBaseColorId); + } } -void LLGLTFMaterial::setNormalId(const LLUUID& id) +void LLGLTFMaterial::setNormalId(const LLUUID& id, bool for_override) { mNormalId = id; + if (for_override) + { + hackOverrideUUID(mNormalId); + } } -void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id) +void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id, bool for_override) { mMetallicRoughnessId = id; + if (for_override) + { + hackOverrideUUID(mMetallicRoughnessId); + } } -void LLGLTFMaterial::setEmissiveId(const LLUUID& id) +void LLGLTFMaterial::setEmissiveId(const LLUUID& id, bool for_override) { mEmissiveId = id; + if (for_override) + { + hackOverrideUUID(mEmissiveId); + } } -void LLGLTFMaterial::setBaseColorFactor(const LLColor3& baseColor, F32 transparency) +void LLGLTFMaterial::setBaseColorFactor(const LLColor4& baseColor, bool for_override) { - mBaseColor.set(baseColor, transparency); + mBaseColor.set(baseColor); mBaseColor.clamp(); + + if (for_override) + { // hack -- nudge off of default value + if (mBaseColor == getDefaultBaseColor()) + { + mBaseColor.mV[3] -= FLT_EPSILON; + } + } } -void LLGLTFMaterial::setAlphaCutoff(F32 cutoff) +void LLGLTFMaterial::setAlphaCutoff(F32 cutoff, bool for_override) { mAlphaCutoff = llclamp(cutoff, 0.f, 1.f); + if (for_override) + { // hack -- nudge off of default value + if (mAlphaCutoff == getDefaultAlphaCutoff()) + { + mAlphaCutoff -= FLT_EPSILON; + } + } } -void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor) +void LLGLTFMaterial::setEmissiveColorFactor(const LLColor3& emissiveColor, bool for_override) { mEmissiveColor = emissiveColor; mEmissiveColor.clamp(); + + if (for_override) + { // hack -- nudge off of default value + if (mEmissiveColor == getDefaultEmissiveColor()) + { + mEmissiveColor.mV[0] += FLT_EPSILON; + } + } +} + +void LLGLTFMaterial::setMetallicFactor(F32 metallic, bool for_override) +{ + mMetallicFactor = llclamp(metallic, 0.f, for_override ? 1.f - FLT_EPSILON : 1.f); } -void LLGLTFMaterial::setMetallicFactor(F32 metallic) +void LLGLTFMaterial::setRoughnessFactor(F32 roughness, bool for_override) { - mMetallicFactor = llclamp(metallic, 0.f, 1.f); + mRoughnessFactor = llclamp(roughness, 0.f, for_override ? 1.f - FLT_EPSILON : 1.f); } -void LLGLTFMaterial::setRoughnessFactor(F32 roughness) +void LLGLTFMaterial::setAlphaMode(const std::string& mode, bool for_override) { - mRoughnessFactor = llclamp(roughness, 0.f, 1.f); + S32 m = getDefaultAlphaMode(); + if (mode == "MASK") + { + m = ALPHA_MODE_MASK; + } + else if (mode == "BLEND") + { + m = ALPHA_MODE_BLEND; + } + + setAlphaMode(m, for_override); +} + +const char* LLGLTFMaterial::getAlphaMode() const +{ + switch (mAlphaMode) + { + case ALPHA_MODE_MASK: return "MASK"; + case ALPHA_MODE_BLEND: return "BLEND"; + default: return "OPAQUE"; + } } -void LLGLTFMaterial::setAlphaMode(S32 mode) +void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override) { mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK); + if (for_override) + { + // TODO: what do? + } } -void LLGLTFMaterial::setDoubleSided(bool double_sided) +void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override) { // sure, no clamping will ever be needed for a bool, but include the // setter for consistency with the clamping API mDoubleSided = double_sided; + if (for_override) + { + // TODO: what do? + } } void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset) @@ -371,102 +455,102 @@ void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation mTextureTransform[texture_info].mRotation = rotation; } -// Default value accessors +// Default value accessors (NOTE: these MUST match the GLTF specification) + +// Make a static default material for accessors +const LLGLTFMaterial LLGLTFMaterial::sDefault; LLUUID LLGLTFMaterial::getDefaultBaseColorId() { - return LLUUID::null; + return sDefault.mBaseColorId; } LLUUID LLGLTFMaterial::getDefaultNormalId() { - return LLUUID::null; + return sDefault.mNormalId; } LLUUID LLGLTFMaterial::getDefaultEmissiveId() { - return LLUUID::null; + return sDefault.mEmissiveId; } LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId() { - return LLUUID::null; + return sDefault.mMetallicRoughnessId; } F32 LLGLTFMaterial::getDefaultAlphaCutoff() { - return 0.f; + return sDefault.mAlphaCutoff; } S32 LLGLTFMaterial::getDefaultAlphaMode() { - return (S32) ALPHA_MODE_OPAQUE; + return (S32) sDefault.mAlphaMode; } F32 LLGLTFMaterial::getDefaultMetallicFactor() { - return 0.f; + return sDefault.mMetallicFactor; } F32 LLGLTFMaterial::getDefaultRoughnessFactor() { - return 0.f; + return sDefault.mRoughnessFactor; } LLColor4 LLGLTFMaterial::getDefaultBaseColor() { - return LLColor4::white; + return sDefault.mBaseColor; } LLColor3 LLGLTFMaterial::getDefaultEmissiveColor() { - return LLColor3::black; + return sDefault.mEmissiveColor; } bool LLGLTFMaterial::getDefaultDoubleSided() { - return false; + return sDefault.mDoubleSided; } LLVector2 LLGLTFMaterial::getDefaultTextureOffset() { - return LLVector2(0.f, 0.f); + return sDefault.mTextureTransform[0].mOffset; } LLVector2 LLGLTFMaterial::getDefaultTextureScale() { - return LLVector2(1.f, 1.f); + return sDefault.mTextureTransform[0].mScale; } F32 LLGLTFMaterial::getDefaultTextureRotation() { - return 0.f; + return sDefault.mTextureTransform[0].mRotation; } -void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +// static +void LLGLTFMaterial::applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id) { - LL_PROFILE_ZONE_SCOPED; - // TODO: potentially reimplement this with a more general purpose JSON merge - - if (override_mat.mBaseColorId != getDefaultBaseColorId()) + if (override_id != GLTF_OVERRIDE_NULL_UUID) { - mBaseColorId = override_mat.mBaseColorId; + dst_id = override_id; } - - if (override_mat.mNormalId != getDefaultNormalId()) + else { - mNormalId = override_mat.mNormalId; + dst_id = LLUUID::null; } +} - if (override_mat.mMetallicRoughnessId != getDefaultMetallicRoughnessId()) - { - mMetallicRoughnessId = override_mat.mMetallicRoughnessId; - } +void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +{ + LL_PROFILE_ZONE_SCOPED; - if (override_mat.mEmissiveId != getDefaultEmissiveId()) - { - mEmissiveId = override_mat.mEmissiveId; - } + applyOverrideUUID(mBaseColorId, override_mat.mBaseColorId); + applyOverrideUUID(mNormalId, override_mat.mNormalId); + applyOverrideUUID(mMetallicRoughnessId, override_mat.mMetallicRoughnessId); + applyOverrideUUID(mEmissiveId, override_mat.mEmissiveId); if (override_mat.mBaseColor != getDefaultBaseColor()) { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d94ce6e281..a385539cc5 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -45,6 +45,9 @@ class LLGLTFMaterial : public LLRefCount { public: + // default material for reference + static const LLGLTFMaterial sDefault; + struct TextureTransform { LLVector2 mOffset = { 0.f, 0.f }; @@ -69,12 +72,13 @@ public: LLUUID mMetallicRoughnessId; LLUUID mEmissiveId; + // NOTE : initialize values to defaults according to the GLTF spec LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); LLColor3 mEmissiveColor = LLColor3(0, 0, 0); - F32 mMetallicFactor = 0.f; - F32 mRoughnessFactor = 0.f; - F32 mAlphaCutoff = 0.f; + F32 mMetallicFactor = 1.f; + F32 mRoughnessFactor = 1.f; + F32 mAlphaCutoff = 0.5f; bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; @@ -105,19 +109,22 @@ public: std::array mTextureTransform; //setters for various members (will clamp to acceptable ranges) + // for_override - set to true if this value is being set as part of an override (important for handling override to default value) + + void setBaseColorId(const LLUUID& id, bool for_override = false); + void setNormalId(const LLUUID& id, bool for_override = false); + void setMetallicRoughnessId(const LLUUID& id, bool for_override = false); + void setEmissiveId(const LLUUID& id, bool for_override = false); - void setBaseColorId(const LLUUID& id); - void setNormalId(const LLUUID& id); - void setMetallicRoughnessId(const LLUUID& id); - void setEmissiveId(const LLUUID& id); + void setBaseColorFactor(const LLColor4& baseColor, bool for_override = false); + void setAlphaCutoff(F32 cutoff, bool for_override = false); + void setEmissiveColorFactor(const LLColor3& emissiveColor, bool for_override = false); + void setMetallicFactor(F32 metallic, bool for_override = false); + void setRoughnessFactor(F32 roughness, bool for_override = false); + void setAlphaMode(S32 mode, bool for_override = false); + void setDoubleSided(bool double_sided, bool for_override = false); - void setBaseColorFactor(const LLColor3& baseColor, F32 transparency); - void setAlphaCutoff(F32 cutoff); - void setEmissiveColorFactor(const LLColor3& emissiveColor); - void setMetallicFactor(F32 metallic); - void setRoughnessFactor(F32 roughness); - void setAlphaMode(S32 mode); - void setDoubleSided(bool double_sided); + //NOTE: texture offsets only exist in overrides, so "for_override" is not needed void setTextureOffset(TextureInfo texture_info, const LLVector2& offset); void setTextureScale(TextureInfo texture_info, const LLVector2& scale); @@ -139,34 +146,16 @@ public: static LLVector2 getDefaultTextureScale(); static F32 getDefaultTextureRotation(); + + static void hackOverrideUUID(LLUUID& id); + static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id); + // set mAlphaMode from string. // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE - void setAlphaMode(const std::string& mode) - { - if (mode == "MASK") - { - mAlphaMode = ALPHA_MODE_MASK; - } - else if (mode == "BLEND") - { - mAlphaMode = ALPHA_MODE_BLEND; - } - else - { - mAlphaMode = ALPHA_MODE_OPAQUE; - } - } - - const char* getAlphaMode() const - { - switch (mAlphaMode) - { - case ALPHA_MODE_MASK: return "MASK"; - case ALPHA_MODE_BLEND: return "BLEND"; - default: return "OPAQUE"; - } - } - + void setAlphaMode(const std::string& mode, bool for_override = false); + + const char* getAlphaMode() const; + // set the contents of this LLGLTFMaterial from the given json // returns true if successful // json - the json text to load from diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index c99e7307ed..0ae8dcbcf7 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -70,21 +70,20 @@ static const std::string LIVE_MATERIAL_EDITOR_KEY = "Live Editor"; // Dirty flags static const U32 MATERIAL_BASE_COLOR_DIRTY = 0x1 << 0; -static const U32 MATERIAL_BASE_TRANSPARENCY_DIRTY = 0x1 << 1; -static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 2; +static const U32 MATERIAL_BASE_COLOR_TEX_DIRTY = 0x1 << 1; -static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 3; +static const U32 MATERIAL_NORMAL_TEX_DIRTY = 0x1 << 2; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 4; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 5; -static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 6; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY = 0x1 << 3; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY = 0x1 << 4; +static const U32 MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY = 0x1 << 5; -static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 7; -static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 8; +static const U32 MATERIAL_EMISIVE_COLOR_DIRTY = 0x1 << 6; +static const U32 MATERIAL_EMISIVE_TEX_DIRTY = 0x1 << 7; -static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 9; -static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 10; -static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 11; +static const U32 MATERIAL_DOUBLE_SIDED_DIRTY = 0x1 << 8; +static const U32 MATERIAL_ALPHA_MODE_DIRTY = 0x1 << 9; +static const U32 MATERIAL_ALPHA_CUTOFF_DIRTY = 0x1 << 10; LLUUID LLMaterialEditor::mOverrideObjectId; S32 LLMaterialEditor::mOverrideObjectTE = -1; @@ -384,7 +383,7 @@ BOOL LLMaterialEditor::postBuild() // BaseColor childSetCommitCallback("base color", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); - childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_TRANSPARENCY_DIRTY); + childSetCommitCallback("transparency", changes_callback, (void*)&MATERIAL_BASE_COLOR_DIRTY); childSetCommitCallback("alpha mode", changes_callback, (void*)&MATERIAL_ALPHA_MODE_DIRTY); childSetCommitCallback("alpha cutoff", changes_callback, (void*)&MATERIAL_ALPHA_CUTOFF_DIRTY); @@ -2263,55 +2262,52 @@ public: // Override object's values with values from editor where appropriate if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_DIRTY) { - material->mBaseColor = mEditor->getBaseColor(); - } - if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_TRANSPARENCY_DIRTY) - { - material->mBaseColor.mV[3] = mEditor->getTransparency(); + LLColor4 baseColor = mEditor->getBaseColor(); + material->setBaseColorFactor(mEditor->getBaseColor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_BASE_COLOR_TEX_DIRTY) { - material->mBaseColorId = mEditor->getBaseColorId(); + material->setBaseColorId(mEditor->getBaseColorId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_NORMAL_TEX_DIRTY) { - material->mNormalId = mEditor->getNormalId(); + material->setNormalId(mEditor->getNormalId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { - material->mMetallicRoughnessId = mEditor->getMetallicRoughnessId(); + material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) { - material->mMetallicFactor = mEditor->getMetalnessFactor(); + material->setMetallicFactor(mEditor->getMetalnessFactor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_METALLIC_ROUGHTNESS_ROUGHNESS_DIRTY) { - material->mRoughnessFactor = mEditor->getRoughnessFactor(); + material->setRoughnessFactor(mEditor->getRoughnessFactor(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_COLOR_DIRTY) { - material->mEmissiveColor = mEditor->getEmissiveColor(); + material->setEmissiveColorFactor(LLColor3(mEditor->getEmissiveColor()), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_EMISIVE_TEX_DIRTY) { - material->mEmissiveId = mEditor->getEmissiveId(); + material->setEmissiveId(mEditor->getEmissiveId(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_DOUBLE_SIDED_DIRTY) { - material->mDoubleSided = mEditor->getDoubleSided(); + material->setDoubleSided(mEditor->getDoubleSided(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_MODE_DIRTY) { - material->setAlphaMode(mEditor->getAlphaMode()); + material->setAlphaMode(mEditor->getAlphaMode(), true); } if (mEditor->getUnsavedChangesFlags() & MATERIAL_ALPHA_CUTOFF_DIRTY) { - material->mAlphaCutoff = mEditor->getAlphaCutoff(); + material->setAlphaCutoff(mEditor->getAlphaCutoff(), true); } std::string overrides_json = material->asJSON(); -- cgit v1.3 From c3f94ab9a1da2c0c5304ff624b54fad6a43506ae Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 2 Nov 2022 12:14:56 -0500 Subject: SL-18520 Use GLTF material.extras to pass flags for enabling overriding alpha mode and double sided to default --- indra/llprimitive/llgltfmaterial.cpp | 73 ++++++++++++++++++++++++------------ indra/llprimitive/llgltfmaterial.h | 8 ++-- indra/newview/llmaterialeditor.cpp | 8 +++- 3 files changed, 59 insertions(+), 30 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 4b1f89f99f..172cbdb7ce 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -65,6 +65,9 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mTextureTransform = rhs.mTextureTransform; + mOverrideDoubleSided = rhs.mOverrideDoubleSided; + mOverrideAlphaMode = rhs.mOverrideDoubleSided; + return *this; } @@ -129,6 +132,22 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) mRoughnessFactor = llclamp((F32)material_in.pbrMetallicRoughness.roughnessFactor, 0.f, 1.f); mDoubleSided = material_in.doubleSided; + + if (material_in.extras.IsObject()) + { + tinygltf::Value::Object extras = material_in.extras.Get(); + auto& alpha_mode = extras.find("override_alpha_mode"); + if (alpha_mode != extras.end()) + { + mOverrideAlphaMode = alpha_mode->second.Get(); + } + + auto& double_sided = extras.find("override_double_sided"); + if (double_sided != extras.end()) + { + mOverrideDoubleSided = double_sided->second.Get(); + } + } } LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value) @@ -256,6 +275,27 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.doubleSided = mDoubleSided; + + // generate "extras" string + tinygltf::Value::Object extras; + bool write_extras = false; + if (mOverrideAlphaMode && mAlphaMode == getDefaultAlphaMode()) + { + extras["override_alpha_mode"] = tinygltf::Value(mOverrideAlphaMode); + write_extras = true; + } + + if (mOverrideDoubleSided && mDoubleSided == getDefaultDoubleSided()) + { + extras["override_double_sided"] = tinygltf::Value(mOverrideDoubleSided); + write_extras = true; + } + + if (write_extras) + { + material_out.extras = tinygltf::Value(extras); + } + model.asset.version = "2.0"; } @@ -425,7 +465,7 @@ void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override) mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK); if (for_override) { - // TODO: what do? + mOverrideAlphaMode = true; } } @@ -436,7 +476,7 @@ void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override) mDoubleSided = double_sided; if (for_override) { - // TODO: what do? + mOverrideDoubleSided = true; } } @@ -460,26 +500,6 @@ void LLGLTFMaterial::setTextureRotation(TextureInfo texture_info, float rotation // Make a static default material for accessors const LLGLTFMaterial LLGLTFMaterial::sDefault; -LLUUID LLGLTFMaterial::getDefaultBaseColorId() -{ - return sDefault.mBaseColorId; -} - -LLUUID LLGLTFMaterial::getDefaultNormalId() -{ - return sDefault.mNormalId; -} - -LLUUID LLGLTFMaterial::getDefaultEmissiveId() -{ - return sDefault.mEmissiveId; -} - -LLUUID LLGLTFMaterial::getDefaultMetallicRoughnessId() -{ - return sDefault.mMetallicRoughnessId; -} - F32 LLGLTFMaterial::getDefaultAlphaCutoff() { return sDefault.mAlphaCutoff; @@ -535,7 +555,10 @@ void LLGLTFMaterial::applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id { if (override_id != GLTF_OVERRIDE_NULL_UUID) { - dst_id = override_id; + if (override_id != LLUUID::null) + { + dst_id = override_id; + } } else { @@ -572,7 +595,7 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) mRoughnessFactor = override_mat.mRoughnessFactor; } - if (override_mat.mAlphaMode != getDefaultAlphaMode()) + if (override_mat.mAlphaMode != getDefaultAlphaMode() || override_mat.mOverrideAlphaMode) { mAlphaMode = override_mat.mAlphaMode; } @@ -581,7 +604,7 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) mAlphaCutoff = override_mat.mAlphaCutoff; } - if (override_mat.mDoubleSided != getDefaultDoubleSided()) + if (override_mat.mDoubleSided != getDefaultDoubleSided() || override_mat.mOverrideDoubleSided) { mDoubleSided = override_mat.mDoubleSided; } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a385539cc5..9489837de7 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -83,6 +83,10 @@ public: bool mDoubleSided = false; AlphaMode mAlphaMode = ALPHA_MODE_OPAQUE; + // override specific flags for state that can't use off-by-epsilon or UUID hack + bool mOverrideDoubleSided = false; + bool mOverrideAlphaMode = false; + // get a UUID based on a hash of this LLGLTFMaterial LLUUID getHash() const { @@ -131,10 +135,6 @@ public: void setTextureRotation(TextureInfo texture_info, float rotation); // Default value accessors - static LLUUID getDefaultBaseColorId(); - static LLUUID getDefaultNormalId(); - static LLUUID getDefaultEmissiveId(); - static LLUUID getDefaultMetallicRoughnessId(); static F32 getDefaultAlphaCutoff(); static S32 getDefaultAlphaMode(); static F32 getDefaultMetallicFactor(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 0ae8dcbcf7..004d61a2ec 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2312,7 +2312,13 @@ public: std::string overrides_json = material->asJSON(); - +#if 1 + // debug + std::string err, warn; + LLGLTFMaterial debug; + debug.fromJSON(overrides_json, warn, err); +#endif + LLSD overrides = llsd::map( "object_id", objectp->getID(), "side", te, -- cgit v1.3 From 9e7b725c15ea0bfea5246eb81dd7a100b7ac5b6b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 31 Oct 2022 09:42:27 -0700 Subject: SL-18485: Render GLTF materials with extension KHR_texture_transform with approprate texture transforms --- indra/llprimitive/llgltfmaterial.cpp | 22 ++++++ indra/llprimitive/llgltfmaterial.h | 3 + indra/llrender/llshadermgr.cpp | 10 ++- indra/llrender/llshadermgr.h | 4 + indra/llrender/llvertexbuffer.cpp | 92 ++++++++++++++++++++++ indra/llrender/llvertexbuffer.h | 24 ++++-- .../shaders/class1/deferred/pbralphaV.glsl | 44 ++++++----- .../shaders/class1/deferred/pbropaqueF.glsl | 30 ++++--- .../shaders/class1/deferred/pbropaqueV.glsl | 38 +++++---- .../shaders/class2/deferred/pbralphaF.glsl | 41 +++++----- indra/newview/llface.cpp | 6 ++ indra/newview/llfetchedgltfmaterial.cpp | 9 +++ 12 files changed, 243 insertions(+), 80 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 172cbdb7ce..649d4dbe8f 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -39,6 +39,28 @@ const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; // special UUID that indicates a null UUID in override data static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); +// https://github.com/KhronosGroup/glTF/tree/main/extensions/3.0/Khronos/KHR_texture_transform +LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() +{ + LLMatrix3 scale; + scale.mMatrix[0][0] = mScale[0]; + scale.mMatrix[1][1] = mScale[1]; + + LLMatrix3 rotation; + const F32 cos_r = cos(mRotation); + const F32 sin_r = sin(mRotation); + rotation.mMatrix[0][0] = cos_r; + rotation.mMatrix[0][1] = sin_r; + rotation.mMatrix[1][0] = -sin_r; + rotation.mMatrix[1][1] = cos_r; + + LLMatrix3 offset; + offset.mMatrix[2][0] = mOffset[0]; + offset.mMatrix[2][1] = mOffset[1]; + + return offset * rotation * scale; +} + LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 9489837de7..60116fd423 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -28,6 +28,7 @@ #include "llrefcount.h" #include "llmemory.h" +#include "m3math.h" #include "v4color.h" #include "v3color.h" #include "v2math.h" @@ -53,6 +54,8 @@ public: LLVector2 mOffset = { 0.f, 0.f }; LLVector2 mScale = { 1.f, 1.f }; F32 mRotation = 0.f; + + LLMatrix3 asMatrix(); }; enum AlphaMode diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 7f7829c18e..e8cf7ec758 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1163,6 +1163,10 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedAttribs.push_back("weight4"); mReservedAttribs.push_back("clothing"); mReservedAttribs.push_back("texture_index"); + mReservedAttribs.push_back("basecolor_texcoord"); // GLTF + mReservedAttribs.push_back("normal_texcoord"); // GLTF + mReservedAttribs.push_back("metallic_roughness_texcoord"); // GLTF + mReservedAttribs.push_back("emissive_texcoord"); // GLTF //matrix state mReservedUniforms.push_back("modelview_matrix"); @@ -1177,7 +1181,11 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("texture_matrix3"); mReservedUniforms.push_back("object_plane_s"); mReservedUniforms.push_back("object_plane_t"); - llassert(mReservedUniforms.size() == LLShaderMgr::OBJECT_PLANE_T+1); + mReservedUniforms.push_back("texture_basecolor_matrix"); // GLTF + mReservedUniforms.push_back("texture_normal_matrix"); // GLTF + mReservedUniforms.push_back("texture_metallic_roughness_matrix"); // GLTF + mReservedUniforms.push_back("texture_emissive_matrix"); // GLTF + llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_MATRIX+1); mReservedUniforms.push_back("viewport"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index 6d2138f405..e1fb60eccf 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -51,6 +51,10 @@ public: TEXTURE_MATRIX3, // "texture_matrix3" OBJECT_PLANE_S, // "object_plane_s" OBJECT_PLANE_T, // "object_plane_t" + TEXTURE_BASECOLOR_MATRIX, // "texture_basecolor_matrix" (GLTF) + TEXTURE_NORMAL_MATRIX, // "texture_normal_matrix" (GLTF) + TEXTURE_METALLIC_ROUGHNESS_MATRIX, // "texture_metallic_roughness_matrix" (GLTF) + TEXTURE_EMISSIVE_MATRIX, // "texture_emissive_matrix" (GLTF) VIEWPORT, // "viewport" LIGHT_POSITION, // "light_position" LIGHT_DIRECTION, // "light_direction" diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index f51000b9a6..b33708cae6 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -358,6 +358,10 @@ const S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = sizeof(LLVector4), // TYPE_WEIGHT4, sizeof(LLVector4), // TYPE_CLOTHWEIGHT, sizeof(LLVector4), // TYPE_TEXTURE_INDEX (actually exists as position.w), no extra data, but stride is 16 bytes + sizeof(LLVector2), // TYPE_BASECOLOR_TEXCOORD, + sizeof(LLVector2), // TYPE_NORMAL_TEXCOORD, + sizeof(LLVector2), // TYPE_METALLIC_ROUGHNESS_TEXCOORD, + sizeof(LLVector2), // TYPE_EMISSIVE_TEXCOORD, }; static const std::string vb_type_name[] = @@ -375,6 +379,10 @@ static const std::string vb_type_name[] = "TYPE_WEIGHT4", "TYPE_CLOTHWEIGHT", "TYPE_TEXTURE_INDEX", + "TYPE_BASECOLOR_TEXCOORD", + "TYPE_NORMAL_TEXCOORD", + "TYPE_METALLIC_ROUGHNESS_TEXCOORD", + "TYPE_EMISSIVE_TEXCOORD", "TYPE_MAX", "TYPE_INDEX", }; @@ -1270,6 +1278,10 @@ void LLVertexBuffer::setupVertexArray() 4, //TYPE_WEIGHT4, 4, //TYPE_CLOTHWEIGHT, 1, //TYPE_TEXTURE_INDEX + 2, // TYPE_BASECOLOR_TEXCOORD, + 2, // TYPE_NORMAL_TEXCOORD, + 2, // TYPE_METALLIC_ROUGHNESS_TEXCOORD, + 2, // TYPE_EMISSIVE_TEXCOORD, }; static const U32 attrib_type[] = @@ -1287,6 +1299,10 @@ void LLVertexBuffer::setupVertexArray() GL_FLOAT, //TYPE_WEIGHT4, GL_FLOAT, //TYPE_CLOTHWEIGHT, GL_UNSIGNED_INT, //TYPE_TEXTURE_INDEX + GL_FLOAT, // TYPE_BASECOLOR_TEXCOORD, + GL_FLOAT, // TYPE_NORMAL_TEXCOORD, + GL_FLOAT, // TYPE_METALLIC_ROUGHNESS_TEXCOORD, + GL_FLOAT, // TYPE_EMISSIVE_TEXCOORD, }; static const bool attrib_integer[] = @@ -1304,6 +1320,10 @@ void LLVertexBuffer::setupVertexArray() false, //TYPE_WEIGHT4, false, //TYPE_CLOTHWEIGHT, true, //TYPE_TEXTURE_INDEX + false, // TYPE_BASECOLOR_TEXCOORD, + false, // TYPE_NORMAL_TEXCOORD, + false, // TYPE_METALLIC_ROUGHNESS_TEXCOORD, + false, // TYPE_EMISSIVE_TEXCOORD, }; static const U32 attrib_normalized[] = @@ -1321,6 +1341,10 @@ void LLVertexBuffer::setupVertexArray() GL_FALSE, //TYPE_WEIGHT4, GL_FALSE, //TYPE_CLOTHWEIGHT, GL_FALSE, //TYPE_TEXTURE_INDEX + GL_FALSE, // TYPE_BASECOLOR_TEXCOORD, + GL_FALSE, // TYPE_NORMAL_TEXCOORD, + GL_FALSE, // TYPE_METALLIC_ROUGHNESS_TEXCOORD, + GL_FALSE, // TYPE_EMISSIVE_TEXCOORD, }; bindGLBuffer(true); @@ -1961,6 +1985,26 @@ bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 in return VertexBufferStrider::get(*this, strider, index, count, map_range); } +bool LLVertexBuffer::getBasecolorTexcoordStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} + +bool LLVertexBuffer::getNormalTexcoordStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} + +bool LLVertexBuffer::getMetallicRoughnessTexcoordStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} + +bool LLVertexBuffer::getEmissiveTexcoordStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +{ + return VertexBufferStrider::get(*this, strider, index, count, map_range); +} + //---------------------------------------------------------------------------- bool LLVertexBuffer::bindGLArray() @@ -2379,6 +2423,30 @@ void LLVertexBuffer::setupVertexBuffer(U32 data_mask) void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } + if (data_mask & MAP_BASECOLOR_TEXCOORD) + { + S32 loc = TYPE_BASECOLOR_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_BASECOLOR_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BASECOLOR_TEXCOORD], ptr); + } + if (data_mask & MAP_NORMAL_TEXCOORD) + { + S32 loc = TYPE_NORMAL_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL_TEXCOORD], ptr); + } + if (data_mask & MAP_METALLIC_ROUGHNESS_TEXCOORD) + { + S32 loc = TYPE_METALLIC_ROUGHNESS_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_METALLIC_ROUGHNESS_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_METALLIC_ROUGHNESS_TEXCOORD], ptr); + } + if (data_mask & MAP_EMISSIVE_TEXCOORD) + { + S32 loc = TYPE_EMISSIVE_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE_TEXCOORD], ptr); + } llglassertok(); } @@ -2472,6 +2540,30 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } + if (data_mask & MAP_BASECOLOR_TEXCOORD) + { + S32 loc = TYPE_BASECOLOR_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_BASECOLOR_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_BASECOLOR_TEXCOORD], ptr); + } + if (data_mask & MAP_NORMAL_TEXCOORD) + { + S32 loc = TYPE_NORMAL_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_NORMAL_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL_TEXCOORD], ptr); + } + if (data_mask & MAP_METALLIC_ROUGHNESS_TEXCOORD) + { + S32 loc = TYPE_METALLIC_ROUGHNESS_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_METALLIC_ROUGHNESS_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_METALLIC_ROUGHNESS_TEXCOORD], ptr); + } + if (data_mask & MAP_EMISSIVE_TEXCOORD) + { + S32 loc = TYPE_EMISSIVE_TEXCOORD; + void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE_TEXCOORD]); + glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE_TEXCOORD], ptr); + } } LLVertexBuffer::MappedRegion::MappedRegion(S32 type, S32 index, S32 count) diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 233d7785f8..b54e99ca27 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -160,11 +160,12 @@ public: //WARNING -- when updating these enums you MUST // 1 - update LLVertexBuffer::sTypeSize - // 2 - add a strider accessor - // 3 - modify LLVertexBuffer::setupVertexBuffer - // 4 - modify LLVertexBuffer::setupClientArray - // 5 - modify LLViewerShaderMgr::mReservedAttribs - // 6 - update LLVertexBuffer::setupVertexArray + // 2 - update LLVertexBuffer::vb_type_name + // 3 - add a strider accessor + // 4 - modify LLVertexBuffer::setupVertexBuffer + // 5 - modify LLVertexBuffer::setupVertexBufferFast + // 6 - modify LLViewerShaderMgr::mReservedAttribs + // 7 - update LLVertexBuffer::setupVertexArray // clang-format off enum { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms() @@ -181,6 +182,10 @@ public: TYPE_WEIGHT4, // "weight4" TYPE_CLOTHWEIGHT, // "clothing" TYPE_TEXTURE_INDEX, // "texture_index" + TYPE_BASECOLOR_TEXCOORD, // "basecolor_texcoord" (GLTF) + TYPE_NORMAL_TEXCOORD, // "normal_texcoord" (GLTF) + TYPE_METALLIC_ROUGHNESS_TEXCOORD, // "metallic_roughness_texcoord" (GLTF) + TYPE_EMISSIVE_TEXCOORD, // "emissive_texcoord" (GLTF) TYPE_MAX, // TYPE_MAX is the size/boundary marker for attributes that go in the vertex buffer TYPE_INDEX, // TYPE_INDEX is beyond _MAX because it lives in a separate (index) buffer }; @@ -195,12 +200,15 @@ public: MAP_TEXCOORD3 = (1<& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getWeight4Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool getClothWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getBasecolorTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getNormalTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getMetallicRoughnessTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getEmissiveTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); bool useVBOs() const; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index d0d76fd0cb..19bca098e8 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -44,29 +44,32 @@ uniform mat4 modelview_projection_matrix; VARYING vec3 vary_position; #endif -uniform mat4 texture_matrix0; +uniform mat3 texture_basecolor_matrix; +uniform mat3 texture_normal_matrix; +uniform mat3 texture_metallic_roughness_matrix; +uniform mat3 texture_emissive_matrix; #ifdef HAS_SUN_SHADOW -VARYING vec3 vary_fragcoord; +out vec3 vary_fragcoord; uniform float near_clip; #endif -ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 tangent; -ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec2 texcoord1; -ATTRIBUTE vec2 texcoord2; - - -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec3 vary_normal; -VARYING vec3 vary_tangent; +in vec3 position; +in vec4 diffuse_color; +in vec3 normal; +in vec4 tangent; +in vec2 texcoord0; + +out vec2 basecolor_texcoord; +out vec2 normal_texcoord; +out vec2 metallic_roughness_texcoord; +out vec2 emissive_texcoord; + +out vec4 vertex_color; + +out vec3 vary_tangent; flat out float vary_sign; +out vec3 vary_normal; void main() @@ -89,9 +92,10 @@ void main() vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); #endif - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; - vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; + basecolor_texcoord = (texture_basecolor_matrix * vec3(texcoord0,1)).xy; + normal_texcoord = (texture_normal_matrix * vec3(texcoord0,1)).xy; + metallic_roughness_texcoord = (texture_metallic_roughness_matrix * vec3(texcoord0,1)).xy; + emissive_texcoord = (texture_emissive_matrix * vec3(texcoord0,1)).xy; #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index 7376e9eb47..39419e9d78 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -36,15 +36,16 @@ uniform sampler2D specularMap; // Packed: Occlusion, Metal, Roughness out vec4 frag_data[4]; -VARYING vec3 vary_position; -VARYING vec4 vertex_color; -VARYING vec3 vary_normal; -VARYING vec3 vary_tangent; +in vec3 vary_position; +in vec4 vertex_color; +in vec3 vary_normal; +in vec3 vary_tangent; flat in float vary_sign; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; +in vec2 basecolor_texcoord; +in vec2 normal_texcoord; +in vec2 metallic_roughness_texcoord; +in vec2 emissive_texcoord; uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() @@ -56,19 +57,16 @@ uniform mat3 normal_matrix; void main() { -// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; -// else - vec4 albedo = texture2D(diffuseMap, vary_texcoord0.xy).rgba; - if (albedo.a < minimum_alpha) + vec4 basecolor = texture2D(diffuseMap, basecolor_texcoord.xy).rgba; + if (basecolor.a < minimum_alpha) { discard; } - vec3 col = vertex_color.rgb * srgb_to_linear(albedo.rgb); + vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb); // from mikktspace.com - vec3 vNt = texture2D(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; + vec3 vNt = texture2D(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -81,13 +79,13 @@ void main() // occlusion 1.0 // roughness 0.0 // metal 0.0 - vec3 spec = texture2D(specularMap, vary_texcoord2.xy).rgb; + vec3 spec = texture2D(specularMap, metallic_roughness_texcoord.xy).rgb; spec.g *= roughnessFactor; spec.b *= metallicFactor; vec3 emissive = emissiveColor; - emissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); + emissive *= srgb_to_linear(texture2D(emissiveMap, emissive_texcoord.xy).rgb); tnorm *= gl_FrontFacing ? 1.0 : -1.0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 5573c02a60..25bf19b4ec 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -37,25 +37,27 @@ uniform mat3 normal_matrix; uniform mat4 modelview_projection_matrix; #endif -uniform mat4 texture_matrix0; +uniform mat3 texture_basecolor_matrix; +uniform mat3 texture_normal_matrix; +uniform mat3 texture_metallic_roughness_matrix; +uniform mat3 texture_emissive_matrix; -ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec3 normal; -ATTRIBUTE vec4 tangent; -ATTRIBUTE vec2 texcoord0; -ATTRIBUTE vec2 texcoord1; -ATTRIBUTE vec2 texcoord2; +in vec3 position; +in vec4 diffuse_color; +in vec3 normal; +in vec4 tangent; +in vec2 texcoord0; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; +out vec2 basecolor_texcoord; +out vec2 normal_texcoord; +out vec2 metallic_roughness_texcoord; +out vec2 emissive_texcoord; -VARYING vec4 vertex_color; +out vec4 vertex_color; -VARYING vec3 vary_tangent; +out vec3 vary_tangent; flat out float vary_sign; -VARYING vec3 vary_normal; +out vec3 vary_normal; void main() { @@ -73,9 +75,11 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; - vary_texcoord1 = (texture_matrix0 * vec4(texcoord1,0,1)).xy; - vary_texcoord2 = (texture_matrix0 * vec4(texcoord2,0,1)).xy; + basecolor_texcoord = (texture_basecolor_matrix * vec3(texcoord0,1)).xy; + normal_texcoord = (texture_normal_matrix * vec3(texcoord0,1)).xy; + metallic_roughness_texcoord = (texture_metallic_roughness_matrix * vec3(texcoord0,1)).xy; + emissive_texcoord = (texture_emissive_matrix * vec3(texcoord0,1)).xy; + #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; vec3 t = (mat*vec4(tangent.xyz+position.xyz,1.0)).xyz-pos.xyz; diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index b39f834e41..6500c4bb1f 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -45,17 +45,21 @@ uniform vec3 moon_dir; out vec4 frag_color; #ifdef HAS_SUN_SHADOW - VARYING vec3 vary_fragcoord; + in vec3 vary_fragcoord; uniform vec2 screen_res; #endif -VARYING vec3 vary_position; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; -VARYING vec2 vary_texcoord1; -VARYING vec2 vary_texcoord2; -VARYING vec3 vary_normal; -VARYING vec3 vary_tangent; +in vec3 vary_position; + +in vec2 basecolor_texcoord; +in vec2 normal_texcoord; +in vec2 metallic_roughness_texcoord; +in vec2 emissive_texcoord; + +in vec4 vertex_color; + +in vec3 vary_normal; +in vec3 vary_tangent; flat in float vary_sign; @@ -155,21 +159,18 @@ void main() waterClip(pos); -// IF .mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; -// vec3 col = vertex_color.rgb * diffuseLookup(vary_texcoord0.xy).rgb; -// else - vec4 albedo = texture(diffuseMap, vary_texcoord0.xy).rgba; - albedo.rgb = srgb_to_linear(albedo.rgb); + vec4 basecolor = texture(diffuseMap, basecolor_texcoord.xy).rgba; + basecolor.rgb = srgb_to_linear(basecolor.rgb); #ifdef HAS_ALPHA_MASK - if (albedo.a < minimum_alpha) + if (basecolor.a < minimum_alpha) { discard; } #endif - vec3 baseColor = vertex_color.rgb * albedo.rgb; + vec3 col = vertex_color.rgb * basecolor.rgb; - vec3 vNt = texture(bumpMap, vary_texcoord1.xy).xyz*2.0-1.0; + vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; float sign = vary_sign; vec3 vN = vary_normal; vec3 vT = vary_tangent.xyz; @@ -192,7 +193,7 @@ void main() scol = sampleDirectionalShadow(pos.xyz, norm.xyz, frag); #endif - vec3 orm = texture(specularMap, vary_texcoord2.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space + vec3 orm = texture(specularMap, metallic_roughness_texcoord.xy).rgb; //orm is packed into "emissiveRect" to keep the data in linear color space float perceptualRoughness = orm.g * roughnessFactor; float metallic = orm.b * metallicFactor; @@ -201,7 +202,7 @@ void main() // emissiveColor is the emissive color factor from GLTF and is already in linear space vec3 colorEmissive = emissiveColor; // emissiveMap here is a vanilla RGB texture encoded as sRGB, manually convert to linear - colorEmissive *= srgb_to_linear(texture2D(emissiveMap, vary_texcoord0.xy).rgb); + colorEmissive *= srgb_to_linear(texture2D(emissiveMap, emissive_texcoord.xy).rgb); // PBR IBL float gloss = 1.0 - perceptualRoughness; @@ -214,7 +215,7 @@ void main() vec3 diffuseColor; vec3 specularColor; - calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor); + calcDiffuseSpecular(col.rgb, metallic, diffuseColor, specularColor); vec3 v = -normalize(pos.xyz); color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten); @@ -235,5 +236,5 @@ void main() color.rgb += light.rgb; - frag_color = vec4(color.rgb,albedo.a * vertex_color.a); + frag_color = vec4(color.rgb,basecolor.a * vertex_color.a); } diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 23b56aa579..528675072b 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -1601,6 +1601,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, LLMaterial* mat = tep->getMaterialParams().get(); LLGLTFMaterial* gltf_mat = tep->getGLTFRenderMaterial(); + if (gltf_mat) + { + // Transforms will be applied later + do_xform = false; + } + bool do_bump = bump_code && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1); if ((mat || gltf_mat) && !do_bump) diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 22be8a03dd..a873d062bd 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -101,6 +101,15 @@ void LLFetchedGLTFMaterial::bind(LLGLSLShader* shader) shader->uniform1f(LLShaderMgr::ROUGHNESS_FACTOR, mRoughnessFactor); shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); + + const LLMatrix3 base_color_matrix = mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].asMatrix(); + shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_BASECOLOR_MATRIX, 1, false, (F32*)base_color_matrix.mMatrix); + const LLMatrix3 normal_matrix = mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].asMatrix(); + shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_NORMAL_MATRIX, 1, false, (F32*)normal_matrix.mMatrix); + const LLMatrix3 metallic_roughness_matrix = mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].asMatrix(); + shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_MATRIX, 1, false, (F32*)metallic_roughness_matrix.mMatrix); + const LLMatrix3 emissive_matrix = mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].asMatrix(); + shader->uniformMatrix3fv(LLShaderMgr::TEXTURE_EMISSIVE_MATRIX, 1, false, (F32*)emissive_matrix.mMatrix); } } -- cgit v1.3 From 3e7e146be689233b21e31c091298dcfa2cb1adfc Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 2 Nov 2022 14:58:24 -0500 Subject: SL-18520 Fix for mac build. --- indra/llprimitive/llgltfmaterial.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 172cbdb7ce..c76f547570 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -136,13 +136,13 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) if (material_in.extras.IsObject()) { tinygltf::Value::Object extras = material_in.extras.Get(); - auto& alpha_mode = extras.find("override_alpha_mode"); + const auto& alpha_mode = extras.find("override_alpha_mode"); if (alpha_mode != extras.end()) { mOverrideAlphaMode = alpha_mode->second.Get(); } - auto& double_sided = extras.find("override_double_sided"); + const auto& double_sided = extras.find("override_double_sided"); if (double_sided != extras.end()) { mOverrideDoubleSided = double_sided->second.Get(); -- cgit v1.3 From cba87c62cc3c31d48c680bf92aa7ae2b9555ba69 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 8 Nov 2022 10:53:24 -0800 Subject: SL-18523: When editing an object's material override, use the object's material override as a base, rather than its render material --- indra/llprimitive/llgltfmaterial.cpp | 26 ++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 3 +++ indra/newview/llmaterialeditor.cpp | 15 +++++++++++---- 3 files changed, 40 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6d23cb8039..ee1931a27b 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -61,6 +61,29 @@ LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() return offset * rotation * scale; } +LLGLTFMaterial::LLGLTFMaterial(bool for_override) +: LLGLTFMaterial() +{ + if (for_override) + { + setBaseColorId(mBaseColorId, for_override); + setNormalId(mNormalId, for_override); + setMetallicRoughnessId(mMetallicRoughnessId, for_override); + setEmissiveId(mEmissiveId, for_override); + + setBaseColorFactor(mBaseColor, for_override); + setAlphaCutoff(mAlphaCutoff, for_override); + setEmissiveColorFactor(mEmissiveColor, for_override); + setMetallicFactor(mMetallicFactor, for_override); + setRoughnessFactor(mRoughnessFactor, for_override); + setAlphaMode(mAlphaMode, for_override); + setDoubleSided(mDoubleSided, for_override); + + // *NOTE: Texture offsets only exist in overrides, so there is no need + // to hack in the override value here. + } +} + LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; @@ -588,6 +611,9 @@ void LLGLTFMaterial::applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id } } +// Make a static default material override for editing materials +const LLGLTFMaterial LLGLTFMaterial::sOverrideDefault{true}; + void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { LL_PROFILE_ZONE_SCOPED; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 60116fd423..2476818b27 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -48,6 +48,8 @@ public: // default material for reference static const LLGLTFMaterial sDefault; + // default material override for reference + static const LLGLTFMaterial sOverrideDefault; struct TextureTransform { @@ -66,6 +68,7 @@ public: }; LLGLTFMaterial() {} + LLGLTFMaterial(bool for_override); LLGLTFMaterial(const LLGLTFMaterial& rhs); LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index a0cb4e1c8f..70b165460a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2385,19 +2385,26 @@ public: // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only LLTextureEntry* tep = objectp->getTE(te); - LLPointer material = tep->getGLTFRenderMaterial(); - if (material.isNull()) + if (tep->getGLTFMaterial().isNull()) { // overrides are not supposed to work or apply if // there is no base material to work from return false; } - + LLPointer material = tep->getGLTFMaterialOverride(); // make a copy to not invalidate existing // material for multiple objects - material = new LLGLTFMaterial(*material); + if (material.isNull()) + { + // Start with a material override which does not make any changes + material = new LLGLTFMaterial(LLGLTFMaterial::sOverrideDefault); + } + else + { + material = new LLGLTFMaterial(*material); + } U32 changed_flags = mEditor->getUnsavedChangesFlags(); U32 reverted_flags = mEditor->getRevertedChangesFlags(); -- cgit v1.3 From 4aaa48419594c993c6c1b0bd2f5585c6492b6a31 Mon Sep 17 00:00:00 2001 From: Sabrina Shanman Date: Wed, 9 Nov 2022 00:16:41 +0000 Subject: Revert "SL-18523: When editing an object's material override, use the object's material override as a base, rather than its render material (pull request #1190)" --- indra/llprimitive/llgltfmaterial.cpp | 26 -------------------------- indra/llprimitive/llgltfmaterial.h | 3 --- indra/newview/llmaterialeditor.cpp | 15 ++++----------- 3 files changed, 4 insertions(+), 40 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index ee1931a27b..6d23cb8039 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -61,29 +61,6 @@ LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() return offset * rotation * scale; } -LLGLTFMaterial::LLGLTFMaterial(bool for_override) -: LLGLTFMaterial() -{ - if (for_override) - { - setBaseColorId(mBaseColorId, for_override); - setNormalId(mNormalId, for_override); - setMetallicRoughnessId(mMetallicRoughnessId, for_override); - setEmissiveId(mEmissiveId, for_override); - - setBaseColorFactor(mBaseColor, for_override); - setAlphaCutoff(mAlphaCutoff, for_override); - setEmissiveColorFactor(mEmissiveColor, for_override); - setMetallicFactor(mMetallicFactor, for_override); - setRoughnessFactor(mRoughnessFactor, for_override); - setAlphaMode(mAlphaMode, for_override); - setDoubleSided(mDoubleSided, for_override); - - // *NOTE: Texture offsets only exist in overrides, so there is no need - // to hack in the override value here. - } -} - LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; @@ -611,9 +588,6 @@ void LLGLTFMaterial::applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id } } -// Make a static default material override for editing materials -const LLGLTFMaterial LLGLTFMaterial::sOverrideDefault{true}; - void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { LL_PROFILE_ZONE_SCOPED; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 2476818b27..60116fd423 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -48,8 +48,6 @@ public: // default material for reference static const LLGLTFMaterial sDefault; - // default material override for reference - static const LLGLTFMaterial sOverrideDefault; struct TextureTransform { @@ -68,7 +66,6 @@ public: }; LLGLTFMaterial() {} - LLGLTFMaterial(bool for_override); LLGLTFMaterial(const LLGLTFMaterial& rhs); LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 70b165460a..a0cb4e1c8f 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -2385,26 +2385,19 @@ public: // Selection can cover multiple objects, and live editor is // supposed to overwrite changed values only LLTextureEntry* tep = objectp->getTE(te); + LLPointer material = tep->getGLTFRenderMaterial(); - if (tep->getGLTFMaterial().isNull()) + if (material.isNull()) { // overrides are not supposed to work or apply if // there is no base material to work from return false; } - LLPointer material = tep->getGLTFMaterialOverride(); + // make a copy to not invalidate existing // material for multiple objects - if (material.isNull()) - { - // Start with a material override which does not make any changes - material = new LLGLTFMaterial(LLGLTFMaterial::sOverrideDefault); - } - else - { - material = new LLGLTFMaterial(*material); - } + material = new LLGLTFMaterial(*material); U32 changed_flags = mEditor->getUnsavedChangesFlags(); U32 reverted_flags = mEditor->getRevertedChangesFlags(); -- cgit v1.3 From fe2a07a80f4f0ae913078cca11a5242c24e550ed Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Fri, 11 Nov 2022 14:34:57 -0600 Subject: SL-18616 Fix for dropping mOverrideAlphaMode on copy --- indra/llprimitive/llgltfmaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6d23cb8039..6fbcf50482 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -88,7 +88,7 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mTextureTransform = rhs.mTextureTransform; mOverrideDoubleSided = rhs.mOverrideDoubleSided; - mOverrideAlphaMode = rhs.mOverrideDoubleSided; + mOverrideAlphaMode = rhs.mOverrideAlphaMode; return *this; } -- cgit v1.3 From e4dd9c1e648e38c15a1fa792ffeb5754ae936709 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 14 Nov 2022 14:40:24 -0800 Subject: SL-18634: Fix GLTF material texture transform not serializing when texture ID is null --- indra/llprimitive/llgltfmaterial.cpp | 21 ++++++++++++--------- indra/llprimitive/llgltfmaterial.h | 8 +++++--- 2 files changed, 17 insertions(+), 12 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6fbcf50482..e8e4b62934 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -61,6 +61,11 @@ LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() return offset * rotation * scale; } +bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const +{ + return mOffset == other.mOffset && mScale == other.mScale && mRotation == other.mRotation; +} + LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) { *this = rhs; @@ -268,16 +273,14 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const tinygltf::Material& material_out = model.materials[mat_index]; - constexpr bool is_override = false; - // set base color texture - writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId, is_override, LLUUID()); + writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId); // set normal texture - writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId, is_override, LLUUID()); + writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId); // set metallic-roughness texture - writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId, is_override, LLUUID()); + writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId); // set emissive texture - writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId, is_override, LLUUID()); + writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId); material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; @@ -338,10 +341,11 @@ void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const } template -void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id, bool is_override, const LLUUID& base_texture_id) const +void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const { LL_PROFILE_ZONE_SCOPED; - if (texture_id.isNull() || (is_override && texture_id == base_texture_id)) + const TextureTransform& transform = mTextureTransform[texture_info_id]; + if (texture_id.isNull() && transform == sDefault.mTextureTransform[0]) { return; } @@ -349,7 +353,6 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex gltf_allocate_texture_image(model, texture_info, texture_id.asString()); tinygltf::Value::Object transform_map; - const TextureTransform& transform = mTextureTransform[texture_info_id]; transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ tinygltf::Value(transform.mOffset.mV[VX]), tinygltf::Value(transform.mOffset.mV[VY]) diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 60116fd423..aa49a58f0c 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -56,6 +56,8 @@ public: F32 mRotation = 0.f; LLMatrix3 asMatrix(); + + bool operator==(const TextureTransform& other) const; }; enum AlphaMode @@ -149,14 +151,14 @@ public: static LLVector2 getDefaultTextureScale(); static F32 getDefaultTextureRotation(); - + static void hackOverrideUUID(LLUUID& id); static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id); // set mAlphaMode from string. // Anything otherthan "MASK" or "BLEND" sets mAlphaMode to ALPHA_MODE_OPAQUE void setAlphaMode(const std::string& mode, bool for_override = false); - + const char* getAlphaMode() const; // set the contents of this LLGLTFMaterial from the given json @@ -185,6 +187,6 @@ private: void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out); template - void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id, bool is_override, const LLUUID& base_texture_id) const; + void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const; }; -- cgit v1.3 From 366efa4384e6effa6640c9f125756c58c07fcabe Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 4 Jan 2023 18:00:06 +0200 Subject: SL-18741 Add gltf to bulk uploads on mac And cleaned up dupplicate mScale code --- indra/llprimitive/llgltfmaterial.cpp | 5 ----- indra/newview/llfilepicker.cpp | 2 ++ 2 files changed, 2 insertions(+), 5 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index e8e4b62934..c98fd7d1ee 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -646,11 +646,6 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; } - if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) - { - mTextureTransform[i].mScale = override_mat.mTextureTransform[i].mScale; - } - if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation()) { mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation; diff --git a/indra/newview/llfilepicker.cpp b/indra/newview/llfilepicker.cpp index 1ec25ccaa1..39bac89864 100644 --- a/indra/newview/llfilepicker.cpp +++ b/indra/newview/llfilepicker.cpp @@ -608,6 +608,8 @@ std::vector* LLFilePicker::navOpenFilterProc(ELoadFilter filter) // allowedv->push_back("dic"); allowedv->push_back("xcu"); allowedv->push_back("gif"); + allowedv->push_back("gltf"); + allowedv->push_back("glb"); case FFLOAD_IMAGE: allowedv->push_back("jpg"); allowedv->push_back("jpeg"); -- cgit v1.3 From 4fa77b6f728b6be3d2e7fc74dda97b835476f797 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 12 Dec 2022 14:12:03 -0800 Subject: SL-18820: Update LLGLTFMaterial: Add setBaseMaterial() and equality comparison --- indra/llprimitive/llgltfmaterial.cpp | 33 +++++++++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 7 ++++++- 2 files changed, 39 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index c98fd7d1ee..5442af33d0 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -98,6 +98,29 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) return *this; } +bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const +{ + return mBaseColorId == rhs.mBaseColorId && + mNormalId == rhs.mNormalId && + mMetallicRoughnessId == rhs.mMetallicRoughnessId && + mEmissiveId == rhs.mEmissiveId && + + mBaseColor == rhs.mBaseColor && + mEmissiveColor == rhs.mEmissiveColor && + + mMetallicFactor == rhs.mMetallicFactor && + mRoughnessFactor == rhs.mRoughnessFactor && + mAlphaCutoff == rhs.mAlphaCutoff && + + mDoubleSided == rhs.mDoubleSided && + mAlphaMode == rhs.mAlphaMode && + + mTextureTransform == rhs.mTextureTransform && + + mOverrideDoubleSided == rhs.mOverrideDoubleSided && + mOverrideAlphaMode == rhs.mOverrideAlphaMode; +} + bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, std::string& error_msg) { LL_PROFILE_ZONE_SCOPED; @@ -365,6 +388,16 @@ void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, Tex texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); } +bool LLGLTFMaterial::setBaseMaterial() +{ + const LLGLTFMaterial old_override = *this; + *this = sDefault; + // Preserve the texture transforms + mTextureTransform = old_override.mTextureTransform; + return *this != old_override; +} + + // static void LLGLTFMaterial::hackOverrideUUID(LLUUID& id) { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index aa49a58f0c..7bfcd3bf66 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -71,6 +71,8 @@ public: LLGLTFMaterial(const LLGLTFMaterial& rhs); LLGLTFMaterial& operator=(const LLGLTFMaterial& rhs); + bool operator==(const LLGLTFMaterial& rhs) const; + bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); } LLUUID mBaseColorId; LLUUID mNormalId; @@ -101,7 +103,6 @@ public: md5.finalize(); LLUUID id; md5.raw_digest(id.mData); - // *TODO: Hash the overrides return id; } @@ -181,6 +182,10 @@ public: void applyOverride(const LLGLTFMaterial& override_mat); + // For material overrides only. Clears most properties to + // default/fallthrough, but preserves the transforms. + bool setBaseMaterial(); + private: template -- cgit v1.3 From 693925ef23ef41e3927a9654a7f423d0e24ce19a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 13 Dec 2022 10:41:21 -0800 Subject: SL-18820: Fix applying material clearing transform overrides. Loosen some asserts to allow non-default transform overrides. --- indra/llprimitive/llgltfmaterial.cpp | 16 +++++++++++++-- indra/llprimitive/llgltfmaterial.h | 4 ++++ indra/llprimitive/lltextureentry.cpp | 29 ++++++++++++++++++++++---- indra/llprimitive/lltextureentry.h | 6 +++++- indra/newview/llgltfmateriallist.cpp | 29 +++++++++++++++++++++++--- indra/newview/llgltfmateriallist.h | 7 ++++--- indra/newview/llpanelface.cpp | 4 ++-- indra/newview/llselectmgr.cpp | 21 ++++++------------- indra/newview/llviewerobject.cpp | 40 ++++++++++++++++++++++++------------ indra/newview/llviewerobject.h | 2 +- 10 files changed, 114 insertions(+), 44 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 5442af33d0..a8dad89292 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -392,11 +392,23 @@ bool LLGLTFMaterial::setBaseMaterial() { const LLGLTFMaterial old_override = *this; *this = sDefault; - // Preserve the texture transforms - mTextureTransform = old_override.mTextureTransform; + setBaseMaterial(old_override); return *this != old_override; } +bool LLGLTFMaterial::isClearedForBaseMaterial() +{ + LLGLTFMaterial cleared_override = sDefault; + cleared_override.setBaseMaterial(*this); + return *this == cleared_override; +} + +// For material overrides only. Copies transforms from the old override. +void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat) +{ + mTextureTransform = old_override_mat.mTextureTransform; +} + // static void LLGLTFMaterial::hackOverrideUUID(LLUUID& id) diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 7bfcd3bf66..dec7b696f8 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -185,6 +185,8 @@ public: // For material overrides only. Clears most properties to // default/fallthrough, but preserves the transforms. bool setBaseMaterial(); + // True if setBaseMaterial() was just called + bool isClearedForBaseMaterial(); private: @@ -193,5 +195,7 @@ private: template void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const; + + void setBaseMaterial(const LLGLTFMaterial& old_override_mat); }; diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index a0d5793dcc..49f67918f8 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -514,15 +514,15 @@ S32 LLTextureEntry::setBumpShiny(U8 bump_shiny) return TEM_CHANGE_NONE; } -void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material) +void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin) { if (material != getGLTFMaterial()) { // assert on precondtion: - // whether or not mGLTFMaterial is null, any existing override should have been nulled out + // whether or not mGLTFMaterial is null, any existing override should have been cleared // before calling setGLTFMaterial // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID - llassert(getGLTFMaterialOverride() == nullptr); + llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); mGLTFMaterial = material; if (mGLTFMaterial == nullptr) @@ -538,6 +538,27 @@ void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat) mGLTFMaterialOverrides = mat; } +S32 LLTextureEntry::setBaseMaterial() +{ + S32 changed = TEM_CHANGE_NONE; + + if (mGLTFMaterialOverrides) + { + if (mGLTFMaterialOverrides->setBaseMaterial()) + { + changed = TEM_CHANGE_TEXTURE; + } + + if (LLGLTFMaterial::sDefault == *mGLTFMaterialOverrides) + { + mGLTFMaterialOverrides = nullptr; + changed = TEM_CHANGE_TEXTURE; + } + } + + return changed; +} + LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const { if (mGLTFRenderMaterial.notNull()) @@ -545,7 +566,7 @@ LLGLTFMaterial* LLTextureEntry::getGLTFRenderMaterial() const return mGLTFRenderMaterial; } - llassert(getGLTFMaterialOverride() == nullptr); + llassert(getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); return getGLTFMaterial(); } diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index d94e14bd73..9a81181f3a 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -195,12 +195,16 @@ public: enum { MF_NONE = 0x0, MF_HAS_MEDIA = 0x1 }; // GLTF asset - void setGLTFMaterial(LLGLTFMaterial* material); + void setGLTFMaterial(LLGLTFMaterial* material, bool local_origin = true); LLGLTFMaterial* getGLTFMaterial() const { return mGLTFMaterial; } // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } void setGLTFMaterialOverride(LLGLTFMaterial* mat); + // Clear most overrides so the render material better matches the material + // ID (preserve transforms). If the overrides become passthrough, set the + // overrides to nullptr. + S32 setBaseMaterial(); // GLTF render material // nuanced behavior here -- if there is no render material, fall back to getGLTFMaterial, but ONLY for the getter, not the setter diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index d04a674e91..9539ffc700 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -404,9 +404,19 @@ void LLGLTFMaterialList::queueModify(const LLUUID& id, S32 side, const LLGLTFMat } } -void LLGLTFMaterialList::queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id) +void LLGLTFMaterialList::queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id) { - sApplyQueue.push_back({ object_id, side, asset_id}); + const LLGLTFMaterial* material_override = obj->getTE(side)->getGLTFMaterialOverride(); + if (material_override) + { + LLGLTFMaterial* cleared_override = new LLGLTFMaterial(*material_override); + cleared_override->setBaseMaterial(); + sApplyQueue.push_back({ obj->getID(), side, asset_id, cleared_override }); + } + else + { + sApplyQueue.push_back({ obj->getID(), side, asset_id, nullptr }); + } } void LLGLTFMaterialList::queueUpdate(const LLSD& data) @@ -436,6 +446,11 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool)) { data[i]["gltf_json"] = e.override_data.asJSON(); } + else + { + // Clear all overrides + data[i]["gltf_json"] = ""; + } llassert(is_valid_update(data[i])); ++i; @@ -447,7 +462,15 @@ void LLGLTFMaterialList::flushUpdates(void(*done_callback)(bool)) data[i]["object_id"] = e.object_id; data[i]["side"] = e.side; data[i]["asset_id"] = e.asset_id; - data[i]["gltf_json"] = ""; // null out any existing overrides when applying a material asset + if (e.override_data) + { + data[i]["gltf_json"] = e.override_data->asJSON(); + } + else + { + // Clear all overrides + data[i]["gltf_json"] = ""; + } llassert(is_valid_update(data[i])); ++i; diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index abbb755599..70540e5e01 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -59,7 +59,7 @@ public: // side - TexureEntry index to modify, or -1 for all sides // mat - material to apply as override, or nullptr to remove existing overrides and revert to asset // - // NOTE: do not use to revert to asset when applying a new asset id, use queueApplyMaterialAsset below + // NOTE: do not use to revert to asset when applying a new asset id, use queueApply below static void queueModify(const LLUUID& id, S32 side, const LLGLTFMaterial* mat); // Queue an application of a material asset we want to send to the simulator. Call "flushUpdates" to flush pending updates. @@ -67,8 +67,8 @@ public: // side - TextureEntry index to apply material to, or -1 for all sides // asset_id - ID of material asset to apply, or LLUUID::null to disassociate current material asset // - // NOTE: implicitly removes any override data if present - static void queueApply(const LLUUID& object_id, S32 side, const LLUUID& asset_id); + // NOTE: Implicitly clears most override data if present + static void queueApply(const LLViewerObject* obj, S32 side, const LLUUID& asset_id); // flush pending material updates to the simulator // Automatically called once per frame, but may be called explicitly @@ -136,6 +136,7 @@ protected: LLUUID object_id; S32 side = -1; LLUUID asset_id; + LLPointer override_data; }; typedef std::list apply_queue_t; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 0b18bdc6e6..cf02f3c4e4 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -4527,8 +4527,8 @@ void LLPanelFace::onPasteTexture(LLViewerObject* objectp, S32 te) tep->setGLTFRenderMaterial(nullptr); tep->setGLTFMaterialOverride(nullptr); - // blank out any override data on the server - LLGLTFMaterialList::queueApply(objectp->getID(), te, LLUUID::null); + // blank out most override data on the server + LLGLTFMaterialList::queueApply(objectp, te, LLUUID::null); } // Texture map diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 4a69eba4d3..cb1e46068e 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1806,11 +1806,9 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) } // apply texture for the selected faces + // blank out most override data on the server //add(LLStatViewer::EDIT_TEXTURE, 1); - object->setRenderMaterialID(te, asset_id, false /*will be sent later*/); - - // blank out any override data on the server - LLGLTFMaterialList::queueApply(object->getID(), te, asset_id); + object->setRenderMaterialID(te, asset_id); } } } @@ -1949,10 +1947,8 @@ void LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) objectp->setParameterEntryInUse(LLNetworkData::PARAMS_RENDER_MATERIAL, TRUE, false /*prevent an update*/); } - objectp->setRenderMaterialID(te, asset_id, false /*prevent an update to prevent a race condition*/); - - // blank out any override data on the server - LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id); + // Blank out most override data on the object and send to server + objectp->setRenderMaterialID(te, asset_id); return true; } @@ -2223,17 +2219,12 @@ void LLSelectMgr::selectionRevertGLTFMaterials() && asset_id.notNull()) { // Restore overrides - LLSD overrides; - overrides["object_id"] = objectp->getID(); - overrides["side"] = te; - - overrides["gltf_json"] = nodep->mSavedGLTFOverrideMaterials[te]->asJSON(); - LLGLTFMaterialList::queueUpdate(overrides); + LLGLTFMaterialList::queueModify(objectp->getID(), te, nodep->mSavedGLTFOverrideMaterials[te]); } else { //blank override out - LLGLTFMaterialList::queueApply(objectp->getID(), te, asset_id); + LLGLTFMaterialList::queueApply(objectp, te, asset_id); } } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index dd7f679846..2bd0de4d6c 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -7163,11 +7163,11 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat { // implementation is delicate - // if update is bound for server, should always null out GLTFRenderMaterial and GLTFMaterialOverride even if ids haven't changed + // if update is bound for server, should always null out GLTFRenderMaterial and clear GLTFMaterialOverride even if ids haven't changed // (the case where ids haven't changed indicates the user has reapplied the original material, in which case overrides should be dropped) - // otherwise, should only null out where ids have changed + // otherwise, should only null out the render material where ids or overrides have changed // (the case where ids have changed but overrides are still present is from unsynchronized updates from the simulator) - + S32 start_idx = 0; S32 end_idx = getNumTEs(); @@ -7180,6 +7180,13 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat start_idx = llmax(start_idx, 0); end_idx = llmin(end_idx, (S32) getNumTEs()); + LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); + if (!param_block && id.notNull()) + { // block doesn't exist, but it will need to + param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data; + } + + // update local state for (S32 te = start_idx; te < end_idx; ++te) { @@ -7192,17 +7199,27 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat new_material = gGLTFMaterialList.getMaterial(id); } - bool material_changed = tep->getGLTFMaterial() != new_material; + bool material_changed = !param_block || id != param_block->getMaterial(te); + + if (update_server) + { + // Clear most overrides so the render material better matches the material + // ID (preserve transforms). If overrides become passthrough, set the overrides + // to nullptr. + if (tep->setBaseMaterial()) + { + material_changed = true; + } + } if (update_server || material_changed) { tep->setGLTFRenderMaterial(nullptr); - tep->setGLTFMaterialOverride(nullptr); } if (new_material != tep->getGLTFMaterial()) { - tep->setGLTFMaterial(new_material); + tep->setGLTFMaterial(new_material, !update_server); } } @@ -7215,17 +7232,14 @@ void LLViewerObject::setRenderMaterialID(S32 te_in, const LLUUID& id, bool updat // update via ModifyMaterialParams cap (server will echo back changes) for (S32 te = start_idx; te < end_idx; ++te) { - LLGLTFMaterialList::queueApply(getID(), te, id); + // This sends a cleared version of this object's current material + // override, but the override should already be cleared due to + // calling setBaseMaterial above. + LLGLTFMaterialList::queueApply(this, te, id); } } // predictively update LLRenderMaterialParams (don't wait for server) - LLRenderMaterialParams* param_block = (LLRenderMaterialParams*)getParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL); - if (!param_block && id.notNull()) - { // block doesn't exist, but it will need to - param_block = (LLRenderMaterialParams*)createNewParameterEntry(LLNetworkData::PARAMS_RENDER_MATERIAL)->data; - } - if (param_block) { // update existing parameter block for (S32 te = start_idx; te < end_idx; ++te) diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 8c4afdcba4..71d7a7ebbb 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -188,7 +188,7 @@ public: // set the RenderMaterialID for the given TextureEntry // te - TextureEntry index to set, or -1 for all TEs // id - asset id of material asset - // update_server - if true, will send updates to server + // update_server - if true, will send updates to server and clear most overrides void setRenderMaterialID(S32 te, const LLUUID& id, bool update_server = true); void setRenderMaterialIDs(const LLUUID& id); -- cgit v1.3 From 7bd9d21e19b923096ba2b5ea3cbc8be3e13d7aa0 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Thu, 19 Jan 2023 09:13:45 -0600 Subject: Optimizations, decruft, and intel compatibility pass (#53) SL-18869, SL-18772 Overhaul VBO management, restore occlusion culling, intel compatibility pass, etc --- indra/llprimitive/llmaterial.cpp | 13 + indra/llprimitive/llmaterial.h | 1 + indra/llrender/llgl.cpp | 217 +-- indra/llrender/llgl.h | 9 +- indra/llrender/llglslshader.cpp | 21 + indra/llrender/llrender.cpp | 37 +- indra/llrender/llrender.h | 46 +- indra/llrender/llrendernavprim.cpp | 2 +- indra/llrender/llshadermgr.cpp | 29 +- indra/llrender/llvertexbuffer.cpp | 1442 ++++++-------------- indra/llrender/llvertexbuffer.h | 205 ++- indra/llwindow/llwindowwin32.cpp | 36 +- indra/newview/app_settings/settings.xml | 2 +- .../shaders/class3/deferred/reflectionProbeF.glsl | 7 +- indra/newview/featuretable.txt | 4 +- indra/newview/featuretable_mac.txt | 4 +- indra/newview/llappviewer.cpp | 1 - indra/newview/lldrawable.cpp | 11 +- indra/newview/lldrawpool.cpp | 48 +- indra/newview/lldrawpool.h | 19 +- indra/newview/lldrawpoolalpha.cpp | 59 +- indra/newview/lldrawpoolavatar.cpp | 19 - indra/newview/lldrawpoolavatar.h | 6 - indra/newview/lldrawpoolbump.cpp | 55 +- indra/newview/lldrawpoolbump.h | 8 +- indra/newview/lldrawpoolmaterials.cpp | 6 +- indra/newview/lldrawpoolpbropaque.cpp | 6 +- indra/newview/lldrawpoolsimple.cpp | 97 +- indra/newview/lldrawpoolterrain.cpp | 5 +- indra/newview/lldrawpoolterrain.h | 14 +- indra/newview/lldrawpooltree.cpp | 6 +- indra/newview/lldrawpoolwater.cpp | 393 +----- indra/newview/lldrawpoolwater.h | 10 - indra/newview/llface.cpp | 215 +-- indra/newview/llface.h | 9 +- indra/newview/llflexibleobject.cpp | 1 + indra/newview/llfloaterimagepreview.cpp | 6 +- indra/newview/llglsandbox.cpp | 8 +- indra/newview/llhudobject.cpp | 2 +- indra/newview/llhudtext.cpp | 2 - indra/newview/llmodelpreview.cpp | 28 +- indra/newview/llreflectionmapmanager.cpp | 10 +- indra/newview/llspatialpartition.cpp | 218 ++- indra/newview/llspatialpartition.h | 133 +- indra/newview/llsprite.cpp | 7 +- indra/newview/llstartup.cpp | 2 - indra/newview/llviewerdisplay.cpp | 37 +- indra/newview/llviewerjointmesh.cpp | 19 +- indra/newview/llviewerobject.cpp | 15 +- indra/newview/llviewerobject.h | 13 +- indra/newview/llvieweroctree.cpp | 8 +- indra/newview/llviewershadermgr.cpp | 29 +- indra/newview/llviewertexture.cpp | 2 +- indra/newview/llviewertexturelist.cpp | 41 + indra/newview/llviewerwindow.cpp | 20 +- indra/newview/llvoavatar.cpp | 17 +- indra/newview/llvograss.cpp | 17 +- indra/newview/llvoground.cpp | 6 +- indra/newview/llvopartgroup.cpp | 196 ++- indra/newview/llvopartgroup.h | 9 +- indra/newview/llvosky.cpp | 18 +- indra/newview/llvosurfacepatch.cpp | 29 +- indra/newview/llvotree.cpp | 22 +- indra/newview/llvovolume.cpp | 269 ++-- indra/newview/llvowater.cpp | 21 +- indra/newview/llvowlsky.cpp | 28 +- indra/newview/pipeline.cpp | 618 ++------- indra/newview/pipeline.h | 20 +- 68 files changed, 1362 insertions(+), 3571 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index f546ac1645..0ab97a0df3 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llmaterial.h" +#include "llmd5.h" /** * Materials cap parameters @@ -475,4 +476,16 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode) return ret; } +LLUUID LLMaterial::getHash() const +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + LLMD5 md5; + // HACK - hash the bytes of this LLMaterial, but trim off the S32 in LLRefCount + md5.update((unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); + md5.finalize(); + LLUUID id; + md5.raw_digest(id.mData); + // *TODO: Hash the overrides + return id; +} diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index 2f8aafc2cf..d715671ae1 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -125,6 +125,7 @@ public: bool operator != (const LLMaterial& rhs) const; U32 getShaderMask(U32 alpha_mode = DIFFUSE_ALPHA_MODE_DEFAULT); + LLUUID getHash() const; protected: LLUUID mNormalID; diff --git a/indra/llrender/llgl.cpp b/indra/llrender/llgl.cpp index 67bd9e277e..9dfe5ef9ff 100644 --- a/indra/llrender/llgl.cpp +++ b/indra/llrender/llgl.cpp @@ -2395,234 +2395,39 @@ void LLGLState::dumpStates() } } -void LLGLState::checkStates(const std::string& msg) +void LLGLState::checkStates(GLboolean writeAlpha) { if (!gDebugGL) { return; } - stop_glerror(); - GLint src; GLint dst; glGetIntegerv(GL_BLEND_SRC, &src); glGetIntegerv(GL_BLEND_DST, &dst); - - stop_glerror(); - - BOOL error = FALSE; - - /*if (src != GL_SRC_ALPHA || dst != GL_ONE_MINUS_SRC_ALPHA) - { - if (gDebugSession) - { - gFailLog << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << std::endl; - error = TRUE; - } - else - { - LL_GL_ERRS << "Blend function corrupted: " << std::hex << src << " " << std::hex << dst << " " << msg << std::dec << LL_ENDL; - } - }*/ + llassert_always(src == GL_SRC_ALPHA); + llassert_always(dst == GL_ONE_MINUS_SRC_ALPHA); + + GLboolean colorMask[4]; + glGetBooleanv(GL_COLOR_WRITEMASK, colorMask); + llassert_always(colorMask[0]); + llassert_always(colorMask[1]); + llassert_always(colorMask[2]); + llassert_always(colorMask[3] == writeAlpha); for (boost::unordered_map::iterator iter = sStateMap.begin(); iter != sStateMap.end(); ++iter) { LLGLenum state = iter->first; LLGLboolean cur_state = iter->second; - stop_glerror(); LLGLboolean gl_state = glIsEnabled(state); - stop_glerror(); if(cur_state != gl_state) { dumpStates(); - if (gDebugSession) - { - gFailLog << llformat("LLGLState error. State: 0x%04x",state) << std::endl; - error = TRUE; - } - else - { - LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL; - } - } - } - - if (error) - { - ll_fail("LLGLState::checkStates failed."); - } - stop_glerror(); -} - -void LLGLState::checkTextureChannels(const std::string& msg) -{ -#if 0 - if (!gDebugGL) - { - return; - } - stop_glerror(); - - GLint activeTexture; - glGetIntegerv(GL_ACTIVE_TEXTURE, &activeTexture); - stop_glerror(); - - BOOL error = FALSE; - - if (activeTexture == GL_TEXTURE0) - { - GLint tex_env_mode = 0; - - glGetTexEnviv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, &tex_env_mode); - stop_glerror(); - - if (tex_env_mode != GL_MODULATE) - { - error = TRUE; - LL_WARNS("RenderState") << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << LL_ENDL; - if (gDebugSession) - { - gFailLog << "GL_TEXTURE_ENV_MODE invalid: " << std::hex << tex_env_mode << std::dec << std::endl; - } + LL_GL_ERRS << llformat("LLGLState error. State: 0x%04x",state) << LL_ENDL; } } - - static const char* label[] = - { - "GL_TEXTURE_2D", - "GL_TEXTURE_COORD_ARRAY", - "GL_TEXTURE_1D", - "GL_TEXTURE_CUBE_MAP", - "GL_TEXTURE_GEN_S", - "GL_TEXTURE_GEN_T", - "GL_TEXTURE_GEN_Q", - "GL_TEXTURE_GEN_R", - "GL_TEXTURE_RECTANGLE", - "GL_TEXTURE_2D_MULTISAMPLE" - }; - - static GLint value[] = - { - GL_TEXTURE_2D, - GL_TEXTURE_COORD_ARRAY, - GL_TEXTURE_1D, - GL_TEXTURE_CUBE_MAP, - GL_TEXTURE_GEN_S, - GL_TEXTURE_GEN_T, - GL_TEXTURE_GEN_Q, - GL_TEXTURE_GEN_R, - GL_TEXTURE_RECTANGLE, - GL_TEXTURE_2D_MULTISAMPLE - }; - - GLint stackDepth = 0; - - glh::matrix4f mat; - glh::matrix4f identity; - identity.identity(); - - for (GLint i = 1; i < gGLManager.mNumTextureImageUnits; i++) - { - gGL.getTexUnit(i)->activate(); - - if (i < gGLManager.mNumTextureUnits) - { - glClientActiveTexture(GL_TEXTURE0+i); - stop_glerror(); - glGetIntegerv(GL_TEXTURE_STACK_DEPTH, &stackDepth); - stop_glerror(); - - if (stackDepth != 1) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix stack corrupted." << LL_ENDL; - - if (gDebugSession) - { - gFailLog << "Texture matrix stack corrupted." << std::endl; - } - } - - glGetFloatv(GL_TEXTURE_MATRIX, (GLfloat*) mat.m); - stop_glerror(); - - if (mat != identity) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix in channel " << i << " corrupt." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "Texture matrix in channel " << i << " corrupt." << std::endl; - } - } - - for (S32 j = (i == 0 ? 1 : 0); - j < 9; j++) - { - if (glIsEnabled(value[j])) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture channel " << i << " still has " << label[j] << " enabled." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "Texture channel " << i << " still has " << label[j] << " enabled." << std::endl; - } - } - stop_glerror(); - } - - glGetFloatv(GL_TEXTURE_MATRIX, mat.m); - stop_glerror(); - - if (mat != identity) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture matrix " << i << " is not identity." << LL_ENDL; - if (gDebugSession) - { - gFailLog << "Texture matrix " << i << " is not identity." << std::endl; - } - } - } - - { - GLint tex = 0; - stop_glerror(); - glGetIntegerv(GL_TEXTURE_BINDING_2D, &tex); - stop_glerror(); - - if (tex != 0) - { - error = TRUE; - LL_WARNS("RenderState") << "Texture channel " << i << " still has texture " << tex << " bound." << LL_ENDL; - - if (gDebugSession) - { - gFailLog << "Texture channel " << i << " still has texture " << tex << " bound." << std::endl; - } - } - } - } - - stop_glerror(); - gGL.getTexUnit(0)->activate(); - glClientActiveTexture(GL_TEXTURE0); - stop_glerror(); - - if (error) - { - if (gDebugSession) - { - ll_fail("LLGLState::checkTextureChannels failed."); - } - else - { - LL_GL_ERRS << "GL texture state corruption detected. " << msg << LL_ENDL; - } - } -#endif } /////////////////////////////////////////////////////////////////////// diff --git a/indra/llrender/llgl.h b/indra/llrender/llgl.h index e3c07604aa..eb0650d998 100644 --- a/indra/llrender/llgl.h +++ b/indra/llrender/llgl.h @@ -231,9 +231,12 @@ public: static void resetTextureStates(); static void dumpStates(); - static void checkStates(const std::string& msg = ""); - static void checkTextureChannels(const std::string& msg = ""); - + + // make sure GL blend function, GL states, and GL color mask match + // what we expect + // writeAlpha - whether or not writing to alpha channel is expected + static void checkStates(GLboolean writeAlpha = GL_TRUE); + protected: static boost::unordered_map sStateMap; diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index c5f4efd2c0..982b2a847a 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -154,15 +154,33 @@ void LLGLSLShader::finishProfile(bool emit_report) std::sort(sorted.begin(), sorted.end(), LLGLSLShaderCompareTimeElapsed()); + bool unbound = false; for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) { (*iter)->dumpStats(); + if ((*iter)->mBinds == 0) + { + unbound = true; + } } LL_INFOS() << "-----------------------------------" << LL_ENDL; LL_INFOS() << "Total rendering time: " << llformat("%.4f ms", sTotalTimeElapsed / 1000000.f) << LL_ENDL; LL_INFOS() << "Total samples drawn: " << llformat("%.4f million", sTotalSamplesDrawn / 1000000.f) << LL_ENDL; LL_INFOS() << "Total triangles drawn: " << llformat("%.3f million", sTotalTrianglesDrawn / 1000000.f) << LL_ENDL; + LL_INFOS() << "-----------------------------------" << LL_ENDL; + + if (unbound) + { + LL_INFOS() << "The following shaders were unused: " << LL_ENDL; + for (std::vector::iterator iter = sorted.begin(); iter != sorted.end(); ++iter) + { + if ((*iter)->mBinds == 0) + { + LL_INFOS() << (*iter)->mName << LL_ENDL; + } + } + } } } @@ -985,6 +1003,8 @@ void LLGLSLShader::bind() { LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; + llassert(mProgramObject != 0); + gGL.flush(); if (sCurBoundShader != mProgramObject) // Don't re-bind current shader @@ -998,6 +1018,7 @@ void LLGLSLShader::bind() sCurBoundShader = mProgramObject; sCurBoundShaderPtr = this; placeProfileQuery(); + LLVertexBuffer::setupClientArrays(mAttributeMask); } if (mUniformsDirty) diff --git a/indra/llrender/llrender.cpp b/indra/llrender/llrender.cpp index bba6a46e43..a8db69a9a4 100644 --- a/indra/llrender/llrender.cpp +++ b/indra/llrender/llrender.cpp @@ -164,13 +164,10 @@ void LLTexUnit::enable(eTextureType type) if ( (mCurrTexType != type || gGL.mDirty) && (type != TT_NONE) ) { - stop_glerror(); activate(); - stop_glerror(); if (mCurrTexType != TT_NONE && !gGL.mDirty) { disable(); // Force a disable of a previous texture type if it's enabled. - stop_glerror(); } mCurrTexType = type; @@ -184,11 +181,7 @@ void LLTexUnit::disable(void) if (mCurrTexType != TT_NONE) { - activate(); unbind(mCurrTexType); - gGL.flush(); - setTextureColorSpace(TCS_LINEAR); - mCurrTexType = TT_NONE; } } @@ -196,7 +189,7 @@ void LLTexUnit::disable(void) void LLTexUnit::bindFast(LLTexture* texture) { LLImageGL* gl_tex = texture->getGLTexture(); - + texture->setActive(); glActiveTexture(GL_TEXTURE0 + mIndex); gGL.mCurrTextureUnitIndex = mIndex; mCurrTexture = gl_tex->getTexName(); @@ -889,12 +882,11 @@ void LLRender::init(bool needs_vertex_buffer) // necessary for reflection maps glEnable(GL_TEXTURE_CUBE_MAP_SEAMLESS); - if (sGLCoreProfile && !LLVertexBuffer::sUseVAO) - { //bind a dummy vertex array object so we're core profile compliant - U32 ret; - glGenVertexArrays(1, &ret); - glBindVertexArray(ret); - } + { //bind a dummy vertex array object so we're core profile compliant + U32 ret; + glGenVertexArrays(1, &ret); + glBindVertexArray(ret); + } if (needs_vertex_buffer) { @@ -906,8 +898,8 @@ void LLRender::initVertexBuffer() { llassert_always(mBuffer.isNull()); stop_glerror(); - mBuffer = new LLVertexBuffer(immediate_mask, 0); - mBuffer->allocateBuffer(4096, 0, TRUE); + mBuffer = new LLVertexBuffer(immediate_mask); + mBuffer->allocateBuffer(4096, 0); mBuffer->getVertexStrider(mVerticesp); mBuffer->getTexCoord0Strider(mTexcoordsp); mBuffer->getColorStrider(mColorsp); @@ -1604,6 +1596,7 @@ void LLRender::flush() if (mCount > 0) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; + llassert(LLGLSLShader::sCurBoundShaderPtr != nullptr); if (!mUIOffset.empty()) { sUICalls++; @@ -1691,8 +1684,11 @@ void LLRender::flush() else { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vb cache miss"); - vb = new LLVertexBuffer(attribute_mask, GL_STATIC_DRAW); - vb->allocateBuffer(count, 0, true); + vb = new LLVertexBuffer(attribute_mask); + vb->allocateBuffer(count, 0); + + vb->setBuffer(); + vb->setPositionData((LLVector4a*) mVerticesp.get()); if (attribute_mask & LLVertexBuffer::MAP_TEXCOORD0) @@ -1733,7 +1729,7 @@ void LLRender::flush() } } - vb->setBuffer(attribute_mask); + vb->setBuffer(); if (mMode == LLRender::QUADS && sGLCoreProfile) { @@ -2034,8 +2030,7 @@ void LLRender::texCoord2fv(const GLfloat* tc) void LLRender::color4ub(const GLubyte& r, const GLubyte& g, const GLubyte& b, const GLubyte& a) { - if (!LLGLSLShader::sCurBoundShaderPtr || - LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR) + if (!LLGLSLShader::sCurBoundShaderPtr || LLGLSLShader::sCurBoundShaderPtr->mAttributeMask & LLVertexBuffer::MAP_COLOR) { mColorsp[mCount] = LLColor4U(r,g,b,a); } diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 9fabeb1d7a..cbd3de5736 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -277,7 +277,7 @@ class LLRender friend class LLTexUnit; public: - enum eTexIndex + enum eTexIndex : U8 { DIFFUSE_MAP = 0, ALTERNATE_DIFFUSE_MAP = 1, @@ -286,14 +286,15 @@ public: NUM_TEXTURE_CHANNELS = 3, }; - enum eVolumeTexIndex + enum eVolumeTexIndex : U8 { LIGHT_TEX = 0, SCULPT_TEX, NUM_VOLUME_TEXTURE_CHANNELS, }; - typedef enum { + enum eGeomModes : U8 + { TRIANGLES = 0, TRIANGLE_STRIP, TRIANGLE_FAN, @@ -303,9 +304,9 @@ public: QUADS, LINE_LOOP, NUM_MODES - } eGeomModes; + }; - typedef enum + enum eCompareFunc : U8 { CF_NEVER = 0, CF_ALWAYS, @@ -316,9 +317,9 @@ public: CF_GREATER_EQUAL, CF_GREATER, CF_DEFAULT - } eCompareFunc; + }; - typedef enum + enum eBlendType : U8 { BT_ALPHA = 0, BT_ADD, @@ -327,25 +328,26 @@ public: BT_MULT_ALPHA, BT_MULT_X2, BT_REPLACE - } eBlendType; + }; - typedef enum + // WARNING: this MUST match the LL_PART_BF enum in LLPartData, so set values explicitly in case someone + // decides to add more or reorder them + enum eBlendFactor : U8 { BF_ONE = 0, - BF_ZERO, - BF_DEST_COLOR, - BF_SOURCE_COLOR, - BF_ONE_MINUS_DEST_COLOR, - BF_ONE_MINUS_SOURCE_COLOR, - BF_DEST_ALPHA, - BF_SOURCE_ALPHA, - BF_ONE_MINUS_DEST_ALPHA, - BF_ONE_MINUS_SOURCE_ALPHA, - + BF_ZERO = 1, + BF_DEST_COLOR = 2, + BF_SOURCE_COLOR = 3, + BF_ONE_MINUS_DEST_COLOR = 4, + BF_ONE_MINUS_SOURCE_COLOR = 5, + BF_DEST_ALPHA = 6, + BF_SOURCE_ALPHA = 7, + BF_ONE_MINUS_DEST_ALPHA = 8, + BF_ONE_MINUS_SOURCE_ALPHA = 9, BF_UNDEF - } eBlendFactor; + }; - typedef enum + enum eMatrixMode : U8 { MM_MODELVIEW = 0, MM_PROJECTION, @@ -355,7 +357,7 @@ public: MM_TEXTURE3, NUM_MATRIX_MODES, MM_TEXTURE - } eMatrixMode; + }; LLRender(); ~LLRender(); diff --git a/indra/llrender/llrendernavprim.cpp b/indra/llrender/llrendernavprim.cpp index ca72964832..d610a44bc6 100644 --- a/indra/llrender/llrendernavprim.cpp +++ b/indra/llrender/llrendernavprim.cpp @@ -53,7 +53,7 @@ void LLRenderNavPrim::renderLLTri( const LLVector3& a, const LLVector3& b, const //============================================================================= void LLRenderNavPrim::renderNavMeshVB( U32 mode, LLVertexBuffer* pVBO, int vertCnt ) { - pVBO->setBuffer( LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_NORMAL ); + pVBO->setBuffer(); pVBO->drawArrays( mode, 0, vertCnt ); } //============================================================================= diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index b189e5452c..ee8ac359c7 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -590,6 +590,7 @@ static std::string get_shader_log(GLuint ret) static std::string get_program_log(GLuint ret) { + LL_PROFILE_ZONE_SCOPED_CATEGORY_SHADER; std::string res; //get log length @@ -1113,16 +1114,24 @@ GLuint LLShaderMgr::loadShaderFile(const std::string& filename, S32 & shader_lev BOOL LLShaderMgr::linkProgramObject(GLuint obj, BOOL suppress_errors) { //check for errors - glLinkProgram(obj); - GLint success = GL_TRUE; - glGetProgramiv(obj, GL_LINK_STATUS, &success); - if (!suppress_errors && success == GL_FALSE) - { - //an error occured, print log - LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL; - dumpObjectLog(obj, TRUE, "linker"); - return success; - } + { + LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER("glLinkProgram"); + glLinkProgram(obj); + } + + GLint success = GL_TRUE; + + { + LL_PROFILE_ZONE_NAMED_CATEGORY_SHADER("glsl check link status"); + glGetProgramiv(obj, GL_LINK_STATUS, &success); + if (!suppress_errors && success == GL_FALSE) + { + //an error occured, print log + LL_SHADER_LOADING_WARNS() << "GLSL Linker Error:" << LL_ENDL; + dumpObjectLog(obj, TRUE, "linker"); + return success; + } + } std::string log = get_program_log(obj); LLStringUtil::toLower(log); diff --git a/indra/llrender/llvertexbuffer.cpp b/indra/llrender/llvertexbuffer.cpp index bc33591ed7..f1d71ec94d 100644 --- a/indra/llrender/llvertexbuffer.cpp +++ b/indra/llrender/llvertexbuffer.cpp @@ -70,25 +70,6 @@ struct CompareMappedRegion } }; - -const U32 LL_VBO_BLOCK_SIZE = 2048; -const U32 LL_VBO_POOL_MAX_SEED_SIZE = 256*1024; - -U32 vbo_block_size(U32 size) -{ //what block size will fit size? - U32 mod = size % LL_VBO_BLOCK_SIZE; - return mod == 0 ? size : size + (LL_VBO_BLOCK_SIZE-mod); -} - -U32 vbo_block_index(U32 size) -{ - U32 blocks = vbo_block_size(size)/LL_VBO_BLOCK_SIZE; // block count reqd - llassert(blocks > 0); - return blocks - 1; // Adj index, i.e. single-block allocations are at index 0, etc -} - -const U32 LL_VBO_POOL_SEED_COUNT = vbo_block_index(LL_VBO_POOL_MAX_SEED_SIZE) + 1; - #define ENABLE_GL_WORK_QUEUE 0 #if ENABLE_GL_WORK_QUEUE @@ -294,6 +275,8 @@ static GLuint gen_buffer() return sNamePool[--sIndex]; } +#define ANALYZE_VBO_POOL 0 + class LLVBOPool { public: @@ -316,13 +299,42 @@ public: Pool mVBOPool; Pool mIBOPool; - U32 mMissCount = 0; + U32 mTouchCount = 0; + +#if ANALYZE_VBO_POOL + U64 mDistributed = 0; + U64 mAllocated = 0; + U64 mReserved = 0; + U32 mMisses = 0; + U32 mHits = 0; +#endif + + // increase the size to some common value (e.g. a power of two) to increase hit rate + void adjustSize(U32& size) + { + // size = nhpo2(size); // (193/303)/580 MB (distributed/allocated)/reserved in VBO Pool. Overhead: 66 percent. Hit rate: 77 percent + + //(245/276)/385 MB (distributed/allocated)/reserved in VBO Pool. Overhead: 57 percent. Hit rate: 69 percent + //(187/209)/397 MB (distributed/allocated)/reserved in VBO Pool. Overhead: 112 percent. Hit rate: 76 percent + U32 block_size = llmax(nhpo2(size) / 8, (U32) 16); + size += block_size - (size % block_size); + } void allocate(GLenum type, U32 size, GLuint& name, U8*& data) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - - size = nhpo2(size); + llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); + llassert(name == 0); // non zero name indicates a gl name that wasn't freed + llassert(data == nullptr); // non null data indicates a buffer that wasn't freed + llassert(size >= 2); // any buffer size smaller than a single index is nonsensical + +#if ANALYZE_VBO_POOL + mDistributed += size; + adjustSize(size); + mAllocated += size; +#else + adjustSize(size); +#endif auto& pool = type == GL_ELEMENT_ARRAY_BUFFER ? mIBOPool : mVBOPool; @@ -332,13 +344,9 @@ public: LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("vbo pool miss"); LL_PROFILE_GPU_ZONE("vbo alloc"); - ++mMissCount; - if (mMissCount > 1024) - { //clean cache on every 1024 misses - mMissCount = 0; - clean(); - } - +#if ANALYZE_VBO_POOL + mMisses++; +#endif name = gen_buffer(); glBindBuffer(type, name); glBufferData(type, size, nullptr, GL_DYNAMIC_DRAW); @@ -355,22 +363,47 @@ public: } else { +#if ANALYZE_VBO_POOL + mHits++; + llassert(mReserved >= size); // assert if accounting gets messed up + mReserved -= size; +#endif + std::list& entries = iter->second; Entry& entry = entries.back(); name = entry.mGLName; data = entry.mData; - + entries.pop_back(); if (entries.empty()) { pool.erase(iter); } } + + clean(); } void free(GLenum type, U32 size, GLuint name, U8* data) { - size = nhpo2(size); + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + llassert(type == GL_ARRAY_BUFFER || type == GL_ELEMENT_ARRAY_BUFFER); + llassert(size >= 2); + llassert(name != 0); + llassert(data != nullptr); + + clean(); + +#if ANALYZE_VBO_POOL + llassert(mDistributed >= size); + mDistributed -= size; + adjustSize(size); + llassert(mAllocated >= size); + mAllocated -= size; + mReserved += size; +#else + adjustSize(size); +#endif auto& pool = type == GL_ELEMENT_ARRAY_BUFFER ? mIBOPool : mVBOPool; @@ -386,10 +419,19 @@ public: { iter->second.push_front({ data, name, std::chrono::steady_clock::now() }); } + } + // clean periodically (clean gets called for every alloc/free) void clean() { + mTouchCount++; + if (mTouchCount < 1024) // clean every 1k touches + { + return; + } + mTouchCount = 0; + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; std::unordered_map>* pools[] = { &mVBOPool, &mIBOPool }; @@ -410,7 +452,12 @@ public: auto& entry = entries.back(); ll_aligned_free_16(entry.mData); glDeleteBuffers(1, &entry.mGLName); +#if ANALYZE_VBO_POOL + llassert(mReserved >= iter->first); + mReserved -= iter->first; +#endif entries.pop_back(); + } if (entries.empty()) @@ -423,6 +470,16 @@ public: } } } + +#if ANALYZE_VBO_POOL + LL_INFOS() << llformat("(%d/%d)/%d MB (distributed/allocated)/total in VBO Pool. Overhead: %d percent. Hit rate: %d percent", + mDistributed / 1000000, + mAllocated / 1000000, + (mAllocated + mReserved) / 1000000, // total bytes + ((mAllocated+mReserved-mDistributed)*100)/llmax(mDistributed, (U64) 1), // overhead percent + (mHits*100)/llmax(mMisses+mHits, (U32)1)) // hit rate percent + << LL_ENDL; +#endif } void clear() @@ -445,6 +502,10 @@ public: } } +#if ANALYZE_VBO_POOL + mReserved = 0; +#endif + mIBOPool.clear(); mVBOPool.clear(); } @@ -457,35 +518,14 @@ static LLVBOPool* sVBOPool = nullptr; //============================================================================ // //static -std::list LLVertexBuffer::sAvailableVAOName; -U32 LLVertexBuffer::sCurVAOName = 1; - -U32 LLVertexBuffer::sAllocatedIndexBytes = 0; -U32 LLVertexBuffer::sIndexCount = 0; - -U32 LLVertexBuffer::sBindCount = 0; -U32 LLVertexBuffer::sSetCount = 0; -S32 LLVertexBuffer::sCount = 0; -S32 LLVertexBuffer::sGLCount = 0; -S32 LLVertexBuffer::sMappedCount = 0; -bool LLVertexBuffer::sDisableVBOMapping = false; -bool LLVertexBuffer::sEnableVBOs = true; U32 LLVertexBuffer::sGLRenderBuffer = 0; -U32 LLVertexBuffer::sGLRenderArray = 0; U32 LLVertexBuffer::sGLRenderIndices = 0; U32 LLVertexBuffer::sLastMask = 0; -bool LLVertexBuffer::sVBOActive = false; -bool LLVertexBuffer::sIBOActive = false; -U32 LLVertexBuffer::sAllocatedBytes = 0; U32 LLVertexBuffer::sVertexCount = 0; -bool LLVertexBuffer::sMapped = false; -bool LLVertexBuffer::sUseStreamDraw = true; -bool LLVertexBuffer::sUseVAO = false; -bool LLVertexBuffer::sPreferStreamDraw = false; //NOTE: each component must be AT LEAST 4 bytes in size to avoid a performance penalty on AMD hardware -const S32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = +const U32 LLVertexBuffer::sTypeSize[LLVertexBuffer::TYPE_MAX] = { sizeof(LLVector4), // TYPE_VERTEX, sizeof(LLVector4), // TYPE_NORMAL, @@ -534,62 +574,34 @@ const U32 LLVertexBuffer::sGLMode[LLRender::NUM_MODES] = }; //static -U32 LLVertexBuffer::getVAOName() -{ - U32 ret = 0; - - if (!sAvailableVAOName.empty()) - { - ret = sAvailableVAOName.front(); - sAvailableVAOName.pop_front(); - } - else - { -#ifdef GL_ARB_vertex_array_object - glGenVertexArrays(1, &ret); -#endif - } - - return ret; -} - -//static -void LLVertexBuffer::releaseVAOName(U32 name) +void LLVertexBuffer::setupClientArrays(U32 data_mask) { - sAvailableVAOName.push_back(name); -} + if (sLastMask != data_mask) + { + for (U32 i = 0; i < TYPE_MAX; ++i) + { + S32 loc = i; + U32 mask = 1 << i; -//static -void LLVertexBuffer::setupClientArrays(U32 data_mask) -{ - if (sLastMask != data_mask) - { + if (sLastMask & (1 << i)) + { //was enabled + if (!(data_mask & mask)) + { //needs to be disabled + glDisableVertexAttribArray(loc); + } + } + else + { //was disabled + if (data_mask & mask) + { //needs to be enabled + glEnableVertexAttribArray(loc); + } + } + } + } - for (U32 i = 0; i < TYPE_MAX; ++i) - { - S32 loc = i; - - U32 mask = 1 << i; - - if (sLastMask & (1 << i)) - { //was enabled - if (!(data_mask & mask)) - { //needs to be disabled - glDisableVertexAttribArray(loc); - } - } - else - { //was disabled - if (data_mask & mask) - { //needs to be enabled - glEnableVertexAttribArray(loc); - } - } - } - - sLastMask = data_mask; - } + sLastMask = data_mask; } //static @@ -606,7 +618,7 @@ void LLVertexBuffer::drawArrays(U32 mode, const std::vector& pos) } //static -void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp) +void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); @@ -644,8 +656,13 @@ void LLVertexBuffer::drawElements(U32 mode, const LLVector4a* pos, const LLVecto gGL.flush(); } -void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const +bool LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_offset) const { + if (!gDebugGL) + { + return true; + } + llassert(start < (U32)mNumVerts); llassert(end < (U32)mNumVerts); @@ -663,9 +680,8 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL; } - if (gDebugGL && !useVBOs()) { - U16* idx = ((U16*) getIndicesPointer())+indices_offset; + U16* idx = (U16*) mMappedIndexData+indices_offset; for (U32 i = 0; i < count; ++i) { llassert(idx[i] >= start); @@ -681,22 +697,20 @@ void LLVertexBuffer::validateRange(U32 start, U32 end, U32 count, U32 indices_of if (shader && shader->mFeatures.mIndexedTextureChannels > 1) { - LLStrider v; - //hack to get non-const reference - LLVertexBuffer* vb = (LLVertexBuffer*) this; - vb->getVertexStrider(v); - + LLVector4a* v = (LLVector4a*) mMappedData; + for (U32 i = start; i < end; i++) { - S32 idx = (S32) (v[i][3]+0.25f); - llassert(idx >= 0); - if (idx < 0 || idx >= shader->mFeatures.mIndexedTextureChannels) + U32 idx = (U32) (v[i][3]+0.25f); + if (idx >= shader->mFeatures.mIndexedTextureChannels) { LL_ERRS() << "Bad texture index found in vertex data stream." << LL_ENDL; } } } } + + return true; } #ifdef LL_PROFILER_ENABLE_RENDER_DOC @@ -707,124 +721,35 @@ void LLVertexBuffer::setLabel(const char* label) { void LLVertexBuffer::drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const { - validateRange(start, end, count, indices_offset); - gGL.syncMatrices(); - - llassert(mNumVerts >= 0); - llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - - if (mGLIndices != sGLRenderIndices) - { - LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; - } - - if (mGLBuffer != sGLRenderBuffer) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } - - if (gDebugGL && useVBOs()) - { - GLint elem = 0; - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING_ARB, &elem); - - if (elem != mGLIndices) - { - LL_ERRS() << "Wrong index buffer bound!" << LL_ENDL; - } - } - - if (mode >= LLRender::NUM_MODES) - { - LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL; - return; - } - - U16* idx = ((U16*) getIndicesPointer())+indices_offset; - - glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, - idx); -} - -void LLVertexBuffer::drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const -{ + llassert(validateRange(start, end, count, indices_offset)); + llassert(mGLBuffer == sGLRenderBuffer); + llassert(mGLIndices == sGLRenderIndices); gGL.syncMatrices(); - U16* idx = ((U16*)getIndicesPointer()) + indices_offset; - - glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, - idx); + glDrawRangeElements(sGLMode[mode], start, end, count, GL_UNSIGNED_SHORT, + (GLvoid*) (indices_offset * sizeof(U16))); } void LLVertexBuffer::draw(U32 mode, U32 count, U32 indices_offset) const { - llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); - gGL.syncMatrices(); - - llassert(mNumIndices >= 0); - if (indices_offset >= (U32) mNumIndices || - indices_offset + count > (U32) mNumIndices) - { - LL_ERRS() << "Bad index buffer draw range: [" << indices_offset << ", " << indices_offset+count << "]" << LL_ENDL; - } - - - if (mGLIndices != sGLRenderIndices) - { - LL_ERRS() << "Wrong index buffer bound." << LL_ENDL; - } - - if (mGLBuffer != sGLRenderBuffer) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } - - if (mode >= LLRender::NUM_MODES) - { - LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL; - return; - } - - glDrawElements(sGLMode[mode], count, GL_UNSIGNED_SHORT, - ((U16*) getIndicesPointer()) + indices_offset); + drawRange(mode, 0, mNumVerts, count, indices_offset); } void LLVertexBuffer::drawArrays(U32 mode, U32 first, U32 count) const { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - llassert(LLGLSLShader::sCurBoundShaderPtr != NULL); + llassert(first + count <= mNumVerts); + llassert(mGLBuffer == sGLRenderBuffer); + llassert(mGLIndices == sGLRenderIndices); + gGL.syncMatrices(); - -#ifndef LL_RELEASE_FOR_DOWNLOAD - llassert(mNumVerts >= 0); - if (first >= (U32) mNumVerts || - first + count > (U32) mNumVerts) - { - LL_ERRS() << "Bad vertex buffer draw range: [" << first << ", " << first+count << "]" << LL_ENDL; - } - - if (mGLBuffer != sGLRenderBuffer || useVBOs() != sVBOActive) - { - LL_ERRS() << "Wrong vertex buffer bound." << LL_ENDL; - } - - if (mode >= LLRender::NUM_MODES) - { - LL_ERRS() << "Invalid draw mode: " << mode << LL_ENDL; - return; - } -#endif - glDrawArrays(sGLMode[mode], first, count); } //static void LLVertexBuffer::initClass(LLWindow* window) { - sEnableVBOs = true; - sDisableVBOMapping = true; - + llassert(sVBOPool == nullptr); sVBOPool = new LLVBOPool(); #if ENABLE_GL_WORK_QUEUE @@ -841,29 +766,11 @@ void LLVertexBuffer::initClass(LLWindow* window) //static void LLVertexBuffer::unbind() { - if (sGLRenderArray) - { - glBindVertexArray(0); - sGLRenderArray = 0; - sGLRenderIndices = 0; - sIBOActive = false; - } - - if (sVBOActive) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - sVBOActive = false; - } - if (sIBOActive) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - sIBOActive = false; - } + glBindBuffer(GL_ARRAY_BUFFER, 0); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); sGLRenderBuffer = 0; sGLRenderIndices = 0; - - setupClientArrays(0); } //static @@ -886,67 +793,26 @@ void LLVertexBuffer::cleanupClass() delete sQueue; sQueue = nullptr; #endif - - //llassert(0 == sAllocatedBytes); - //llassert(0 == sAllocatedIndexBytes); } //---------------------------------------------------------------------------- -S32 LLVertexBuffer::determineUsage(S32 usage) -{ - S32 ret_usage = usage; - - if (!sEnableVBOs) - { - ret_usage = 0; - } - - if (ret_usage == GL_STREAM_DRAW && !sUseStreamDraw) - { - ret_usage = 0; - } - - // dynamic draw or nothing - ret_usage = GL_DYNAMIC_DRAW; - - return ret_usage; -} - -LLVertexBuffer::LLVertexBuffer(U32 typemask, S32 usage) +LLVertexBuffer::LLVertexBuffer(U32 typemask) : LLRefCount(), - - mNumVerts(0), - mNumIndices(0), - mSize(0), - mIndicesSize(0), - mTypeMask(typemask), - mUsage(LLVertexBuffer::determineUsage(usage)), - mGLBuffer(0), - mGLIndices(0), - mMappedData(NULL), - mMappedIndexData(NULL), - mMappedDataUsingVBOs(false), - mMappedIndexDataUsingVBOs(false), - mVertexLocked(false), - mIndexLocked(false), - mFinal(false), - mEmpty(true) + mTypeMask(typemask) { //zero out offsets for (U32 i = 0; i < TYPE_MAX; i++) { mOffsets[i] = 0; } - - sCount++; } //static -S32 LLVertexBuffer::calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices) +U32 LLVertexBuffer::calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices) { - S32 offset = 0; - for (S32 i=0; iallocate(GL_ARRAY_BUFFER, size, mGLBuffer, mMappedData); - } - - sGLCount++; -} - -void LLVertexBuffer::genIndices(U32 size) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - - mIndicesSize = size; + llassert(mSize == 0); + llassert(mGLBuffer == 0); + llassert(mMappedData == nullptr); - if (sVBOPool) - { - sVBOPool->allocate(GL_ELEMENT_ARRAY_BUFFER, size, mGLIndices, mMappedIndexData); + mSize = size; + sVBOPool->allocate(GL_ARRAY_BUFFER, mSize, mGLBuffer, mMappedData); } - sGLCount++; } -void LLVertexBuffer::releaseBuffer() +void LLVertexBuffer::genIndices(U32 size) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + llassert(sVBOPool); if (sVBOPool) { - sVBOPool->free(GL_ARRAY_BUFFER, mSize, mGLBuffer, mMappedData); - } - - mGLBuffer = 0; - mMappedData = nullptr; - - sGLCount--; -} - -void LLVertexBuffer::releaseIndices() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - - if (sVBOPool) - { - sVBOPool->free(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mGLIndices, mMappedIndexData); + llassert(mIndicesSize == 0); + llassert(mGLIndices == 0); + llassert(mMappedIndexData == nullptr); + mIndicesSize = size; + sVBOPool->allocate(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mGLIndices, mMappedIndexData); } - - mMappedIndexData = nullptr; - - sGLCount--; } bool LLVertexBuffer::createGLBuffer(U32 size) @@ -1080,23 +911,8 @@ bool LLVertexBuffer::createGLBuffer(U32 size) bool success = true; - mEmpty = true; - - mMappedDataUsingVBOs = useVBOs(); + genBuffer(size); - if (mMappedDataUsingVBOs) - { - genBuffer(size); - } - else - { - static int gl_buffer_idx = 0; - mGLBuffer = ++gl_buffer_idx; - - mMappedData = (U8*)ll_aligned_malloc_16(size); - mSize = size; - } - if (!mMappedData) { success = false; @@ -1118,27 +934,8 @@ bool LLVertexBuffer::createGLIndices(U32 size) bool success = true; - mEmpty = true; - - //pad by 16 bytes for aligned copies - size += 16; - - mMappedIndexDataUsingVBOs = useVBOs(); - - if (mMappedIndexDataUsingVBOs) - { - //pad by another 16 bytes for VBO pointer adjustment - size += 16; - genIndices(size); - } - else - { - mMappedIndexData = (U8*)ll_aligned_malloc_16(size); - static int gl_buffer_idx = 0; - mGLIndices = ++gl_buffer_idx; - mIndicesSize = size; - } - + genIndices(size); + if (!mMappedIndexData) { success = false; @@ -1150,43 +947,37 @@ void LLVertexBuffer::destroyGLBuffer() { if (mGLBuffer || mMappedData) { - if (mMappedDataUsingVBOs) - { - releaseBuffer(); - } - else - { - ll_aligned_free_16((void*)mMappedData); - mMappedData = NULL; - mEmpty = true; - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + //llassert(sVBOPool); + if (sVBOPool) + { + sVBOPool->free(GL_ARRAY_BUFFER, mSize, mGLBuffer, mMappedData); + } + + mSize = 0; + mGLBuffer = 0; + mMappedData = nullptr; } - - mGLBuffer = 0; - //unbind(); } void LLVertexBuffer::destroyGLIndices() { if (mGLIndices || mMappedIndexData) { - if (mMappedIndexDataUsingVBOs) - { - releaseIndices(); - } - else - { - ll_aligned_free_16((void*)mMappedIndexData); - mMappedIndexData = NULL; - mEmpty = true; - } - } + LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; + //llassert(sVBOPool); + if (sVBOPool) + { + sVBOPool->free(GL_ELEMENT_ARRAY_BUFFER, mIndicesSize, mGLIndices, mMappedIndexData); + } - mGLIndices = 0; - //unbind(); + mIndicesSize = 0; + mGLIndices = 0; + mMappedIndexData = nullptr; + } } -bool LLVertexBuffer::updateNumVerts(S32 nverts) +bool LLVertexBuffer::updateNumVerts(U32 nverts) { llassert(nverts >= 0); @@ -1200,19 +991,17 @@ bool LLVertexBuffer::updateNumVerts(S32 nverts) U32 needed_size = calcOffsets(mTypeMask, mOffsets, nverts); - if (needed_size > mSize || needed_size <= mSize/2) - { - success &= createGLBuffer(needed_size); - } + if (needed_size != mSize) + { + success &= createGLBuffer(needed_size); + } - sVertexCount -= mNumVerts; + llassert(mSize == needed_size); mNumVerts = nverts; - sVertexCount += mNumVerts; - return success; } -bool LLVertexBuffer::updateNumIndices(S32 nindices) +bool LLVertexBuffer::updateNumIndices(U32 nindices) { llassert(nindices >= 0); @@ -1220,22 +1009,18 @@ bool LLVertexBuffer::updateNumIndices(S32 nindices) U32 needed_size = sizeof(U16) * nindices; - if (needed_size > mIndicesSize || needed_size <= mIndicesSize/2) + if (needed_size != mIndicesSize) { success &= createGLIndices(needed_size); } - sIndexCount -= mNumIndices; + llassert(mIndicesSize == needed_size); mNumIndices = nindices; - sIndexCount += mNumIndices; - return success; } -bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) +bool LLVertexBuffer::allocateBuffer(U32 nverts, U32 nindices) { - stop_glerror(); - if (nverts < 0 || nindices < 0 || nverts > 65536) { @@ -1247,44 +1032,14 @@ bool LLVertexBuffer::allocateBuffer(S32 nverts, S32 nindices, bool create) success &= updateNumVerts(nverts); success &= updateNumIndices(nindices); - if (create && (nverts || nindices)) - { - //actually allocate space for the vertex buffer if using VBO mapping - flush(); //unmap - } - return success; } -bool LLVertexBuffer::resizeBuffer(S32 newnverts, S32 newnindices) -{ - llassert(newnverts >= 0); - llassert(newnindices >= 0); - - bool success = true; - - success &= updateNumVerts(newnverts); - success &= updateNumIndices(newnindices); - - if (useVBOs()) - { - flush(); //unmap - } - - return success; -} - -bool LLVertexBuffer::useVBOs() const -{ - //it's generally ineffective to use VBO for things that are streaming on apple - return (mUsage != 0); -} - //---------------------------------------------------------------------------- // if no gap between region and given range exists, expand region to cover given range and return true // otherwise return false -bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end) +bool expand_region(LLVertexBuffer::MappedRegion& region, U32 start, U32 end) { if (end < region.mStart || @@ -1301,152 +1056,79 @@ bool expand_region(LLVertexBuffer::MappedRegion& region, S32 start, S32 end) // Map for data access -U8* LLVertexBuffer::mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range) +U8* LLVertexBuffer::mapVertexBuffer(LLVertexBuffer::AttributeType type, U32 index, S32 count) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - if (mFinal) - { - LL_ERRS() << "LLVertexBuffer::mapVeretxBuffer() called on a finalized buffer." << LL_ENDL; - } - if (!useVBOs() && !mMappedData && !mMappedIndexData) - { - LL_ERRS() << "LLVertexBuffer::mapVertexBuffer() called on unallocated buffer." << LL_ENDL; - } + + if (count == -1) + { + count = mNumVerts - index; + } + U32 start = mOffsets[type] + sTypeSize[type] * index; + U32 end = start + sTypeSize[type] * count-1; - if (useVBOs()) - { - if (count == -1) + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) + { + MappedRegion& region = mMappedVertexRegions[i]; + if (expand_region(region, start, end)) { - count = mNumVerts - index; + flagged = true; + break; } - - S32 start = mOffsets[type] + sTypeSize[type] * index; - S32 end = start + sTypeSize[type] * count; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - MappedRegion& region = mMappedVertexRegions[i]; - if (expand_region(region, start, end)) - { - flagged = true; - break; - } - } - - if (!flagged) - { - //didn't expand an existing region, make a new one - mMappedVertexRegions.push_back({ start, end }); - } - - if (mVertexLocked && map_range) - { - LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL; - } - - if (!mVertexLocked) - { - mVertexLocked = true; - sMappedCount++; - stop_glerror(); - - map_range = false; - - if (!mMappedData) - { - log_glerror(); - - //check the availability of memory - LLMemory::logMemoryInfo(true); - - LL_ERRS() << "memory allocation for vertex data failed." << LL_ENDL; - - } - } } - else + + if (!flagged) { - map_range = false; + //didn't expand an existing region, make a new one + mMappedVertexRegions.push_back({ start, end }); } return mMappedData+mOffsets[type]+sTypeSize[type]*index; } -U8* LLVertexBuffer::mapIndexBuffer(S32 index, S32 count, bool map_range) +U8* LLVertexBuffer::mapIndexBuffer(U32 index, S32 count) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - if (mFinal) - { - LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on a finalized buffer." << LL_ENDL; - } - if (!useVBOs() && !mMappedData && !mMappedIndexData) + + if (count == -1) { - LL_ERRS() << "LLVertexBuffer::mapIndexBuffer() called on unallocated buffer." << LL_ENDL; + count = mNumIndices-index; } - if (useVBOs()) - { - if (count == -1) - { - count = mNumIndices-index; - } - - S32 start = sizeof(U16) * index; - S32 end = start + sizeof(U16) * count; - - bool flagged = false; - // flag region as mapped - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) - { - MappedRegion& region = mMappedIndexRegions[i]; - if (expand_region(region, start, end)) - { - flagged = true; - break; - } - } + U32 start = sizeof(U16) * index; + U32 end = start + sizeof(U16) * count-1; - if (!flagged) + bool flagged = false; + // flag region as mapped + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + MappedRegion& region = mMappedIndexRegions[i]; + if (expand_region(region, start, end)) { - //didn't expand an existing region, make a new one - mMappedIndexRegions.push_back({ start, end }); + flagged = true; + break; } + } - if (mIndexLocked && map_range) - { - LL_ERRS() << "Attempted to map a specific range of a buffer that was already mapped." << LL_ENDL; - } - - if (!mIndexLocked) - { - mIndexLocked = true; - sMappedCount++; - stop_glerror(); - - map_range = false; - } - - if (!mMappedIndexData) - { - log_glerror(); - LLMemory::logMemoryInfo(true); - - LL_ERRS() << "memory allocation for Index data failed. " << LL_ENDL; - } - } - else - { - map_range = false; - } + if (!flagged) + { + //didn't expand an existing region, make a new one + mMappedIndexRegions.push_back({ start, end }); + } return mMappedIndexData + sizeof(U16)*index; } -static void flush_vbo(GLenum target, S32 start, S32 end, void* data) +// flush the given byte range +// target -- "targret" parameter for glBufferSubData +// start -- first byte to copy +// end -- last byte to copy (NOT last byte + 1) +// data -- mMappedData or mMappedIndexData +static void flush_vbo(GLenum target, U32 start, U32 end, void* data) { if (end != 0) { @@ -1455,122 +1137,109 @@ static void flush_vbo(GLenum target, S32 start, S32 end, void* data) LL_PROFILE_ZONE_NUM(end); LL_PROFILE_ZONE_NUM(end-start); - constexpr S32 block_size = 65536; + constexpr U32 block_size = 8192; - for (S32 i = start; i < end; i += block_size) + for (U32 i = start; i <= end; i += block_size) { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("glBufferSubData block"); - LL_PROFILE_GPU_ZONE("glBufferSubData"); - S32 tend = llmin(i + block_size, end); - glBufferSubData(target, i, tend - i, (U8*) data + (i-start)); + //LL_PROFILE_GPU_ZONE("glBufferSubData"); + U32 tend = llmin(i + block_size, end); + glBufferSubData(target, i, tend - i+1, (U8*) data + (i-start)); } } } void LLVertexBuffer::unmapBuffer() { - if (!useVBOs()) - { - return; //nothing to unmap - } + struct SortMappedRegion + { + bool operator()(const MappedRegion& lhs, const MappedRegion& rhs) + { + return lhs.mStart < rhs.mStart; + } + }; - bool updated_all = false; - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - if (mMappedData && mVertexLocked) + if (!mMappedVertexRegions.empty()) { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - vertex"); - bindGLBuffer(true); - updated_all = mIndexLocked; //both vertex and index buffers done updating - - if (!mMappedVertexRegions.empty()) - { - S32 start = 0; - S32 end = 0; - - for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) - { - const MappedRegion& region = mMappedVertexRegions[i]; - if (region.mStart == end + 1) - { - end = region.mEnd; - } - else - { - flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start); - start = region.mStart; - end = region.mEnd; - } - } + if (sGLRenderBuffer != mGLBuffer) + { + glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); + sGLRenderBuffer = mGLBuffer; + } + + U32 start = 0; + U32 end = 0; - flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start); + std::sort(mMappedVertexRegions.begin(), mMappedVertexRegions.end(), SortMappedRegion()); - mMappedVertexRegions.clear(); - } - else + for (U32 i = 0; i < mMappedVertexRegions.size(); ++i) { - llassert(false); // this shouldn't happen -- a buffer must always be explicitly mapped + const MappedRegion& region = mMappedVertexRegions[i]; + if (region.mStart == end + 1) + { + end = region.mEnd; + } + else + { + flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start); + start = region.mStart; + end = region.mEnd; + } } - - mVertexLocked = false; - sMappedCount--; + + flush_vbo(GL_ARRAY_BUFFER, start, end, (U8*)mMappedData + start); + + mMappedVertexRegions.clear(); } - if (mMappedIndexData && mIndexLocked) + if (!mMappedIndexRegions.empty()) { LL_PROFILE_ZONE_NAMED_CATEGORY_VERTEX("unmapBuffer - index"); - bindGLIndices(); - - if (!mMappedIndexRegions.empty()) - { - S32 start = 0; - S32 end = 0; - for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + if (mGLIndices != sGLRenderIndices) + { + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; + } + U32 start = 0; + U32 end = 0; + + std::sort(mMappedIndexRegions.begin(), mMappedIndexRegions.end(), SortMappedRegion()); + + for (U32 i = 0; i < mMappedIndexRegions.size(); ++i) + { + const MappedRegion& region = mMappedIndexRegions[i]; + if (region.mStart == end + 1) { - const MappedRegion& region = mMappedIndexRegions[i]; - if (region.mStart == end + 1) - { - end = region.mEnd; - } - else - { - flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start); - start = region.mStart; - end = region.mEnd; - } + end = region.mEnd; } + else + { + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start); + start = region.mStart; + end = region.mEnd; + } + } - flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start); - - mMappedIndexRegions.clear(); - } - else - { - llassert(false); // this shouldn't happen -- a buffer must always be explicitly mapped - } - - mIndexLocked = false; - sMappedCount--; - } + flush_vbo(GL_ELEMENT_ARRAY_BUFFER, start, end, (U8*)mMappedIndexData + start); - if(updated_all) - { - mEmpty = false; + mMappedIndexRegions.clear(); } } //---------------------------------------------------------------------------- -template struct VertexBufferStrider +template struct VertexBufferStrider { typedef LLStrider strider_t; static bool get(LLVertexBuffer& vbo, strider_t& strider, - S32 index, S32 count, bool map_range) + S32 index, S32 count) { if (type == LLVertexBuffer::TYPE_INDEX) { - U8* ptr = vbo.mapIndexBuffer(index, count, map_range); + U8* ptr = vbo.mapIndexBuffer(index, count); if (ptr == NULL) { @@ -1584,9 +1253,9 @@ template struct VertexBufferStrider } else if (vbo.hasDataType(type)) { - S32 stride = LLVertexBuffer::sTypeSize[type]; + U32 stride = LLVertexBuffer::sTypeSize[type]; - U8* ptr = vbo.mapVertexBuffer(type, index, count, map_range); + U8* ptr = vbo.mapVertexBuffer(type, index, count); if (ptr == NULL) { @@ -1606,500 +1275,157 @@ template struct VertexBufferStrider } }; -bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getVertexStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getVertexStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getVertexStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getIndexStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getIndexStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getTexCoord0Strider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTexCoord0Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getTexCoord1Strider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTexCoord1Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getTexCoord2Strider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTexCoord2Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getNormalStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getNormalStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getTangentStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getTangentStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getTangentStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getColorStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getColorStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getEmissiveStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getWeightStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getWeightStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getWeight4Strider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getWeight4Strider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } -bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, S32 index, S32 count, bool map_range) +bool LLVertexBuffer::getClothWeightStrider(LLStrider& strider, U32 index, S32 count) { - return VertexBufferStrider::get(*this, strider, index, count, map_range); + return VertexBufferStrider::get(*this, strider, index, count); } //---------------------------------------------------------------------------- -bool LLVertexBuffer::bindGLBuffer(bool force_bind) + +// Set for rendering +void LLVertexBuffer::setBuffer() { - bool ret = false; + // no data may be pending + llassert(mMappedVertexRegions.empty()); + llassert(mMappedIndexRegions.empty()); - if (useVBOs() && (force_bind || (mGLBuffer && (mGLBuffer != sGLRenderBuffer || !sVBOActive)))) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); - sGLRenderBuffer = mGLBuffer; - sBindCount++; - sVBOActive = true; - ret = true; - } + // a shader must be bound + llassert(LLGLSLShader::sCurBoundShaderPtr); - return ret; -} + U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; -bool LLVertexBuffer::bindGLBufferFast() -{ - if (mGLBuffer != sGLRenderBuffer || !sVBOActive) + // this Vertex Buffer must provide all necessary attributes for currently bound shader + llassert(((~data_mask & mTypeMask) > 0) || (mTypeMask == data_mask)); + + if (sGLRenderBuffer != mGLBuffer) { glBindBuffer(GL_ARRAY_BUFFER, mGLBuffer); sGLRenderBuffer = mGLBuffer; - sBindCount++; - sVBOActive = true; - return true; - } - - return false; -} - -bool LLVertexBuffer::bindGLIndices(bool force_bind) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_VERTEX; - - bool ret = false; - if (useVBOs() && (force_bind || (mGLIndices && (mGLIndices != sGLRenderIndices || !sIBOActive)))) - { - /*if (sMapped) - { - LL_ERRS() << "VBO bound while another VBO mapped!" << LL_ENDL; - }*/ - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; - stop_glerror(); - sBindCount++; - sIBOActive = true; - ret = true; - } - - return ret; -} - -bool LLVertexBuffer::bindGLIndicesFast() -{ - if (mGLIndices != sGLRenderIndices || !sIBOActive) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); - sGLRenderIndices = mGLIndices; - sBindCount++; - sIBOActive = true; - - return true; + setupVertexBuffer(); } - - return false; -} - -void LLVertexBuffer::flush(bool discard) -{ - if (useVBOs()) - { - unmapBuffer(); - } -} - -// bind for transform feedback (quick 'n dirty) -void LLVertexBuffer::bindForFeedback(U32 channel, U32 type, U32 index, U32 count) -{ -#ifdef GL_TRANSFORM_FEEDBACK_BUFFER - U32 offset = mOffsets[type] + sTypeSize[type]*index; - U32 size= (sTypeSize[type]*count); - glBindBufferRange(GL_TRANSFORM_FEEDBACK_BUFFER, channel, mGLBuffer, offset, size); -#endif -} - -// Set for rendering -void LLVertexBuffer::setBuffer(U32 data_mask) -{ - flush(); - - //set up pointers if the data mask is different ... - bool setup = (sLastMask != data_mask); - - if (gDebugGL && data_mask != 0) - { //make sure data requirements are fulfilled - LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; - if (shader) - { - U32 required_mask = 0; - for (U32 i = 0; i < LLVertexBuffer::TYPE_TEXTURE_INDEX; ++i) - { - if (shader->getAttribLocation(i) > -1) - { - U32 required = 1 << i; - if ((data_mask & required) == 0) - { - LL_WARNS() << "Missing attribute: " << LLShaderMgr::instance()->mReservedAttribs[i] << LL_ENDL; - } - - required_mask |= required; - } - } - - if ((data_mask & required_mask) != required_mask) - { - - U32 unsatisfied_mask = (required_mask & ~data_mask); - - for (U32 i = 0; i < TYPE_MAX; i++) - { - U32 unsatisfied_flag = unsatisfied_mask & (1 << i); - switch (unsatisfied_flag) - { - case 0: break; - case MAP_VERTEX: LL_INFOS() << "Missing vert pos" << LL_ENDL; break; - case MAP_NORMAL: LL_INFOS() << "Missing normals" << LL_ENDL; break; - case MAP_TEXCOORD0: LL_INFOS() << "Missing TC 0" << LL_ENDL; break; - case MAP_TEXCOORD1: LL_INFOS() << "Missing TC 1" << LL_ENDL; break; - case MAP_TEXCOORD2: LL_INFOS() << "Missing TC 2" << LL_ENDL; break; - case MAP_TEXCOORD3: LL_INFOS() << "Missing TC 3" << LL_ENDL; break; - case MAP_COLOR: LL_INFOS() << "Missing vert color" << LL_ENDL; break; - case MAP_EMISSIVE: LL_INFOS() << "Missing emissive" << LL_ENDL; break; - case MAP_TANGENT: LL_INFOS() << "Missing tangent" << LL_ENDL; break; - case MAP_WEIGHT: LL_INFOS() << "Missing weight" << LL_ENDL; break; - case MAP_WEIGHT4: LL_INFOS() << "Missing weightx4" << LL_ENDL; break; - case MAP_CLOTHWEIGHT: LL_INFOS() << "Missing clothweight" << LL_ENDL; break; - case MAP_TEXTURE_INDEX: LL_INFOS() << "Missing tex index" << LL_ENDL; break; - default: LL_INFOS() << "Missing who effin knows: " << unsatisfied_flag << LL_ENDL; - } - } - - // TYPE_INDEX is beyond TYPE_MAX, so check for it individually - if (unsatisfied_mask & (1 << TYPE_INDEX)) - { - LL_INFOS() << "Missing indices" << LL_ENDL; - } - - LL_ERRS() << "Shader consumption mismatches data provision." << LL_ENDL; - } - } - } - - if (useVBOs()) - { - const bool bindBuffer = bindGLBuffer(); - const bool bindIndices = bindGLIndices(); - - setup = setup || bindBuffer || bindIndices; - - if (gDebugGL) - { - GLint buff; - glGetIntegerv(GL_ARRAY_BUFFER_BINDING, &buff); - if ((GLuint)buff != mGLBuffer) - { - if (gDebugSession) - { - gFailLog << "Invalid GL vertex buffer bound: " << buff << std::endl; - } - else - { - LL_ERRS() << "Invalid GL vertex buffer bound: " << buff << LL_ENDL; - } - } - - if (mGLIndices) - { - glGetIntegerv(GL_ELEMENT_ARRAY_BUFFER_BINDING, &buff); - if ((GLuint)buff != mGLIndices) - { - if (gDebugSession) - { - gFailLog << "Invalid GL index buffer bound: " << buff << std::endl; - } - else - { - LL_ERRS() << "Invalid GL index buffer bound: " << buff << LL_ENDL; - } - } - } - } - - - } - else - { - if (sGLRenderArray) - { - glBindVertexArray(0); - sGLRenderArray = 0; - sGLRenderIndices = 0; - sIBOActive = false; - } - - if (mGLBuffer) - { - if (sVBOActive) - { - glBindBuffer(GL_ARRAY_BUFFER, 0); - sBindCount++; - sVBOActive = false; - setup = true; // ... or a VBO is deactivated - } - if (sGLRenderBuffer != mGLBuffer) - { - sGLRenderBuffer = mGLBuffer; - setup = true; // ... or a client memory pointer changed - } - } - if (mGLIndices) - { - if (sIBOActive) - { - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - sBindCount++; - sIBOActive = false; - } - - sGLRenderIndices = mGLIndices; - } - } - - setupClientArrays(data_mask); - - if (mGLBuffer) - { - if (data_mask && setup) - { - setupVertexBuffer(data_mask); // subclass specific setup (virtual function) - sSetCount++; - } - } -} - -void LLVertexBuffer::setBufferFast(U32 data_mask) -{ - if (useVBOs()) + else if (sLastMask != data_mask) { - //set up pointers if the data mask is different ... - bool setup = (sLastMask != data_mask); - - const bool bindBuffer = bindGLBufferFast(); - const bool bindIndices = bindGLIndicesFast(); - - setup = setup || bindBuffer || bindIndices; - - setupClientArrays(data_mask); - - if (data_mask && setup) - { - setupVertexBufferFast(data_mask); - sSetCount++; - } + setupVertexBuffer(); + sLastMask = data_mask; } - else + + if (mGLIndices != sGLRenderIndices) { - //fallback to slow path when not using VBOs - setBuffer(data_mask); + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, mGLIndices); + sGLRenderIndices = mGLIndices; } } // virtual (default) -void LLVertexBuffer::setupVertexBuffer(U32 data_mask) -{ - stop_glerror(); - U8* base = useVBOs() ? nullptr: mMappedData; - - if (gDebugGL && ((data_mask & mTypeMask) != data_mask)) - { - for (U32 i = 0; i < LLVertexBuffer::TYPE_MAX; ++i) - { - U32 mask = 1 << i; - if (mask & data_mask && !(mask & mTypeMask)) - { //bit set in data_mask, but not set in mTypeMask - LL_WARNS() << "Missing required component " << vb_type_name[i] << LL_ENDL; - } - } - LL_ERRS() << "LLVertexBuffer::setupVertexBuffer missing required components for supplied data mask." << LL_ENDL; - } - - if (data_mask & MAP_NORMAL) - { - S32 loc = TYPE_NORMAL; - void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); - glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); - } - if (data_mask & MAP_TEXCOORD3) - { - S32 loc = TYPE_TEXCOORD3; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); - } - if (data_mask & MAP_TEXCOORD2) - { - S32 loc = TYPE_TEXCOORD2; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); - } - if (data_mask & MAP_TEXCOORD1) - { - S32 loc = TYPE_TEXCOORD1; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); - } - if (data_mask & MAP_TANGENT) - { - S32 loc = TYPE_TANGENT; - void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); - glVertexAttribPointer(loc, 4,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); - } - if (data_mask & MAP_TEXCOORD0) - { - S32 loc = TYPE_TEXCOORD0; - void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); - glVertexAttribPointer(loc,2,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); - } - if (data_mask & MAP_COLOR) - { - S32 loc = TYPE_COLOR; - //bind emissive instead of color pointer if emissive is present - void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); - } - if (data_mask & MAP_EMISSIVE) - { - S32 loc = TYPE_EMISSIVE; - void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - - if (!(data_mask & MAP_COLOR)) - { //map emissive to color channel when color is not also being bound to avoid unnecessary shader swaps - loc = TYPE_COLOR; - glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); - } - } - if (data_mask & MAP_WEIGHT) - { - S32 loc = TYPE_WEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); - glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); - } - if (data_mask & MAP_WEIGHT4) - { - S32 loc = TYPE_WEIGHT4; - void* ptr = (void*)(base+mOffsets[TYPE_WEIGHT4]); - glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); - } - if (data_mask & MAP_CLOTHWEIGHT) - { - S32 loc = TYPE_CLOTHWEIGHT; - void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); - glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); - } - if (data_mask & MAP_TEXTURE_INDEX && - (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30)) //indexed texture rendering requires GLSL 1.30 or later - { - S32 loc = TYPE_TEXTURE_INDEX; - void *ptr = (void*) (base + mOffsets[TYPE_VERTEX] + 12); - glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); - } - if (data_mask & MAP_VERTEX) - { - S32 loc = TYPE_VERTEX; - void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); - glVertexAttribPointer(loc, 3,GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); - } - - llglassertok(); - } - -void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) +void LLVertexBuffer::setupVertexBuffer() { U8* base = nullptr; + U32 data_mask = LLGLSLShader::sCurBoundShaderPtr->mAttributeMask; + if (data_mask & MAP_NORMAL) { - S32 loc = TYPE_NORMAL; + AttributeType loc = TYPE_NORMAL; void* ptr = (void*)(base + mOffsets[TYPE_NORMAL]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_NORMAL], ptr); } if (data_mask & MAP_TEXCOORD3) { - S32 loc = TYPE_TEXCOORD3; + AttributeType loc = TYPE_TEXCOORD3; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD3]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD3], ptr); } if (data_mask & MAP_TEXCOORD2) { - S32 loc = TYPE_TEXCOORD2; + AttributeType loc = TYPE_TEXCOORD2; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD2]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD2], ptr); } if (data_mask & MAP_TEXCOORD1) { - S32 loc = TYPE_TEXCOORD1; + AttributeType loc = TYPE_TEXCOORD1; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD1]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD1], ptr); } if (data_mask & MAP_TANGENT) { - S32 loc = TYPE_TANGENT; + AttributeType loc = TYPE_TANGENT; void* ptr = (void*)(base + mOffsets[TYPE_TANGENT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TANGENT], ptr); } if (data_mask & MAP_TEXCOORD0) { - S32 loc = TYPE_TEXCOORD0; + AttributeType loc = TYPE_TEXCOORD0; void* ptr = (void*)(base + mOffsets[TYPE_TEXCOORD0]); glVertexAttribPointer(loc, 2, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_TEXCOORD0], ptr); } if (data_mask & MAP_COLOR) { - S32 loc = TYPE_COLOR; + AttributeType loc = TYPE_COLOR; //bind emissive instead of color pointer if emissive is present void* ptr = (data_mask & MAP_EMISSIVE) ? (void*)(base + mOffsets[TYPE_EMISSIVE]) : (void*)(base + mOffsets[TYPE_COLOR]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_COLOR], ptr); } if (data_mask & MAP_EMISSIVE) { - S32 loc = TYPE_EMISSIVE; + AttributeType loc = TYPE_EMISSIVE; void* ptr = (void*)(base + mOffsets[TYPE_EMISSIVE]); glVertexAttribPointer(loc, 4, GL_UNSIGNED_BYTE, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_EMISSIVE], ptr); @@ -2111,31 +1437,31 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) } if (data_mask & MAP_WEIGHT) { - S32 loc = TYPE_WEIGHT; + AttributeType loc = TYPE_WEIGHT; void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT]); glVertexAttribPointer(loc, 1, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT], ptr); } if (data_mask & MAP_WEIGHT4) { - S32 loc = TYPE_WEIGHT4; + AttributeType loc = TYPE_WEIGHT4; void* ptr = (void*)(base + mOffsets[TYPE_WEIGHT4]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_WEIGHT4], ptr); } if (data_mask & MAP_CLOTHWEIGHT) { - S32 loc = TYPE_CLOTHWEIGHT; + AttributeType loc = TYPE_CLOTHWEIGHT; void* ptr = (void*)(base + mOffsets[TYPE_CLOTHWEIGHT]); glVertexAttribPointer(loc, 4, GL_FLOAT, GL_TRUE, LLVertexBuffer::sTypeSize[TYPE_CLOTHWEIGHT], ptr); } if (data_mask & MAP_TEXTURE_INDEX) { - S32 loc = TYPE_TEXTURE_INDEX; + AttributeType loc = TYPE_TEXTURE_INDEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX] + 12); glVertexAttribIPointer(loc, 1, GL_UNSIGNED_INT, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } if (data_mask & MAP_VERTEX) { - S32 loc = TYPE_VERTEX; + AttributeType loc = TYPE_VERTEX; void* ptr = (void*)(base + mOffsets[TYPE_VERTEX]); glVertexAttribPointer(loc, 3, GL_FLOAT, GL_FALSE, LLVertexBuffer::sTypeSize[TYPE_VERTEX], ptr); } @@ -2143,20 +1469,20 @@ void LLVertexBuffer::setupVertexBufferFast(U32 data_mask) void LLVertexBuffer::setPositionData(const LLVector4a* data) { - bindGLBuffer(); - flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts(), (U8*) data); + llassert(sGLRenderBuffer == mGLBuffer); + flush_vbo(GL_ARRAY_BUFFER, 0, sizeof(LLVector4a) * getNumVerts()-1, (U8*) data); } void LLVertexBuffer::setTexCoordData(const LLVector2* data) { - bindGLBuffer(); - flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts(), (U8*)data); + llassert(sGLRenderBuffer == mGLBuffer); + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_TEXCOORD0], mOffsets[TYPE_TEXCOORD0] + sTypeSize[TYPE_TEXCOORD0] * getNumVerts() - 1, (U8*)data); } void LLVertexBuffer::setColorData(const LLColor4U* data) { - bindGLBuffer(); - flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts(), (U8*) data); + llassert(sGLRenderBuffer == mGLBuffer); + flush_vbo(GL_ARRAY_BUFFER, mOffsets[TYPE_COLOR], mOffsets[TYPE_COLOR] + sTypeSize[TYPE_COLOR] * getNumVerts() - 1, (U8*) data); } diff --git a/indra/llrender/llvertexbuffer.h b/indra/llrender/llvertexbuffer.h index 926d37b052..571856f013 100644 --- a/indra/llrender/llvertexbuffer.h +++ b/indra/llrender/llvertexbuffer.h @@ -53,17 +53,16 @@ //============================================================================ // base class class LLPrivateMemoryPool; -class LLVertexBuffer : public LLRefCount +class LLVertexBuffer final : public LLRefCount { public: struct MappedRegion { - S32 mStart; - S32 mEnd; + U32 mStart; + U32 mEnd; }; LLVertexBuffer(const LLVertexBuffer& rhs) - : mUsage(rhs.mUsage) { *this = rhs; } @@ -74,42 +73,31 @@ public: return *this; } - static std::list sAvailableVAOName; - static U32 sCurVAOName; - - static bool sUseStreamDraw; - static bool sUseVAO; - static bool sPreferStreamDraw; - - static U32 getVAOName(); - static void releaseVAOName(U32 name); - static void initClass(LLWindow* window); static void cleanupClass(); static void setupClientArrays(U32 data_mask); static void drawArrays(U32 mode, const std::vector& pos); - static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, S32 num_indices, const U16* indicesp); + static void drawElements(U32 mode, const LLVector4a* pos, const LLVector2* tc, U32 num_indices, const U16* indicesp); static void unbind(); //unbind any bound vertex buffer //get the size of a vertex with the given typemask - static S32 calcVertexSize(const U32& typemask); + static U32 calcVertexSize(const U32& typemask); //get the size of a buffer with the given typemask and vertex count //fill offsets with the offset of each vertex component array into the buffer // indexed by the following enum - static S32 calcOffsets(const U32& typemask, S32* offsets, S32 num_vertices); + static U32 calcOffsets(const U32& typemask, U32* offsets, U32 num_vertices); //WARNING -- when updating these enums you MUST // 1 - update LLVertexBuffer::sTypeSize // 2 - update LLVertexBuffer::vb_type_name // 3 - add a strider accessor // 4 - modify LLVertexBuffer::setupVertexBuffer - // 5 - modify LLVertexBuffer::setupVertexBufferFast // 6 - modify LLViewerShaderMgr::mReservedAttribs // clang-format off - enum { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms() + enum AttributeType { // Shader attribute name, set in LLShaderMgr::initAttribsAndUniforms() TYPE_VERTEX = 0, // "position" TYPE_NORMAL, // "normal" TYPE_TEXCOORD0, // "texcoord0" @@ -147,45 +135,37 @@ public: protected: friend class LLRender; - virtual ~LLVertexBuffer(); // use unref() + ~LLVertexBuffer(); // use unref() - virtual void setupVertexBuffer(U32 data_mask); - void setupVertexBufferFast(U32 data_mask); + void setupVertexBuffer(); void genBuffer(U32 size); void genIndices(U32 size); - bool bindGLBuffer(bool force_bind = false); - bool bindGLBufferFast(); - bool bindGLIndices(bool force_bind = false); - bool bindGLIndicesFast(); - void releaseBuffer(); - void releaseIndices(); bool createGLBuffer(U32 size); bool createGLIndices(U32 size); void destroyGLBuffer(); void destroyGLIndices(); - bool updateNumVerts(S32 nverts); - bool updateNumIndices(S32 nindices); - void unmapBuffer(); - + bool updateNumVerts(U32 nverts); + bool updateNumIndices(U32 nindices); + public: - LLVertexBuffer(U32 typemask, S32 usage); + LLVertexBuffer(U32 typemask); - // map for data access - U8* mapVertexBuffer(S32 type, S32 index, S32 count, bool map_range); - U8* mapIndexBuffer(S32 index, S32 count, bool map_range); + // allocate buffer + bool allocateBuffer(U32 nverts, U32 nindices); - void bindForFeedback(U32 channel, U32 type, U32 index, U32 count); + // map for data access (see also getFooStrider below) + U8* mapVertexBuffer(AttributeType type, U32 index, S32 count = -1); + U8* mapIndexBuffer(U32 index, S32 count = -1); + void unmapBuffer(); // set for rendering - virtual void setBuffer(U32 data_mask); // calls setupVertexBuffer() if data_mask is not 0 - void setBufferFast(U32 data_mask); // calls setupVertexBufferFast(), assumes data_mask is not 0 among other assumptions - - void flush(bool discard = false); //flush pending data to GL memory, if discard is true, discard previous VBO - // allocate buffer - bool allocateBuffer(S32 nverts, S32 nindices, bool create); - virtual bool resizeBuffer(S32 newnverts, S32 newnindices); - + // assumes (and will assert on) the following: + // - this buffer has no pending unampBuffer call + // - a shader is currently bound + // - This buffer has sufficient attributes within it to satisfy the needs of the currently bound shader + void setBuffer(); + // Only call each getVertexPointer, etc, once before calling unmapBuffer() // call unmapBuffer() after calls to getXXXStrider() before any cals to setBuffer() // example: @@ -193,57 +173,49 @@ public: // vb->getNormalStrider(norms); // setVertsNorms(verts, norms); // vb->unmapBuffer(); - bool getVertexStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getVertexStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getIndexStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTexCoord0Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTexCoord1Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTexCoord2Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getNormalStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getTangentStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getColorStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getEmissiveStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getWeight4Strider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getClothWeightStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getBasecolorTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getNormalTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getMetallicRoughnessTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); - bool getEmissiveTexcoordStrider(LLStrider& strider, S32 index=0, S32 count = -1, bool map_range = false); + bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getVertexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getIndexStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord0Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord1Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTexCoord2Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getNormalStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getTangentStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getColorStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getEmissiveStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getWeight4Strider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getClothWeightStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getBasecolorTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getNormalTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getMetallicRoughnessTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); + bool getEmissiveTexcoordStrider(LLStrider& strider, U32 index=0, S32 count = -1); void setPositionData(const LLVector4a* data); void setTexCoordData(const LLVector2* data); void setColorData(const LLColor4U* data); - bool useVBOs() const; - bool isEmpty() const { return mEmpty; } - bool isLocked() const { return mVertexLocked || mIndexLocked; } - S32 getNumVerts() const { return mNumVerts; } - S32 getNumIndices() const { return mNumIndices; } + U32 getNumVerts() const { return mNumVerts; } + U32 getNumIndices() const { return mNumIndices; } - U8* getIndicesPointer() const { return useVBOs() ? nullptr : mMappedIndexData; } - U8* getVerticesPointer() const { return useVBOs() ? nullptr : mMappedData; } U32 getTypeMask() const { return mTypeMask; } - bool hasDataType(S32 type) const { return ((1 << type) & getTypeMask()); } - S32 getSize() const; - S32 getIndicesSize() const { return mIndicesSize; } + bool hasDataType(AttributeType type) const { return ((1 << type) & getTypeMask()); } + U32 getSize() const { return mSize; } + U32 getIndicesSize() const { return mIndicesSize; } U8* getMappedData() const { return mMappedData; } U8* getMappedIndices() const { return mMappedIndexData; } - S32 getOffset(S32 type) const { return mOffsets[type]; } - S32 getUsage() const { return mUsage; } - bool isWriteable() const { return (mUsage == GL_STREAM_DRAW) ? true : false; } - + U32 getOffset(AttributeType type) const { return mOffsets[type]; } + + // these functions assume (and assert on) the current VBO being bound + // Detailed error checking can be enabled by setting gDebugGL to true void draw(U32 mode, U32 count, U32 indices_offset) const; void drawArrays(U32 mode, U32 offset, U32 count) const; - void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; - - //implementation for inner loops that does no safety checking - void drawRangeFast(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; + void drawRange(U32 mode, U32 start, U32 end, U32 count, U32 indices_offset) const; //for debugging, validate data in given range is valid - void validateRange(U32 start, U32 end, U32 count, U32 offset) const; + bool validateRange(U32 start, U32 end, U32 count, U32 offset) const; #ifdef LL_PROFILER_ENABLE_RENDER_DOC void setLabel(const char* label); @@ -251,62 +223,45 @@ public: protected: - U32 mGLBuffer; // GL VBO handle - U32 mGLIndices; // GL IBO handle + U32 mGLBuffer = 0; // GL VBO handle + U32 mGLIndices = 0; // GL IBO handle + U32 mNumVerts = 0; // Number of vertices allocated + U32 mNumIndices = 0; // Number of indices allocated + U32 mOffsets[TYPE_MAX]; // byte offsets into mMappedData of each attribute - U32 mTypeMask; + U8* mMappedData = nullptr; // pointer to currently mapped data (NULL if unmapped) + U8* mMappedIndexData = nullptr; // pointer to currently mapped indices (NULL if unmapped) - S32 mNumVerts; // Number of vertices allocated - S32 mNumIndices; // Number of indices allocated - - S32 mSize; - S32 mIndicesSize; - - const S32 mUsage; // GL usage - - U8* mMappedData; // pointer to currently mapped data (NULL if unmapped) - U8* mMappedIndexData; // pointer to currently mapped indices (NULL if unmapped) - - U32 mMappedDataUsingVBOs : 1; - U32 mMappedIndexDataUsingVBOs : 1; - U32 mVertexLocked : 1; // if true, vertex buffer is being or has been written to in client memory - U32 mIndexLocked : 1; // if true, index buffer is being or has been written to in client memory - U32 mFinal : 1; // if true, buffer can not be mapped again - U32 mEmpty : 1; // if true, client buffer is empty (or NULL). Old values have been discarded. + U32 mTypeMask = 0; // bitmask of present vertex attributes - S32 mOffsets[TYPE_MAX]; - - std::vector mMappedVertexRegions; - std::vector mMappedIndexRegions; + U32 mSize = 0; // size in bytes of mMappedData + U32 mIndicesSize = 0; // size in bytes of mMappedIndexData - static S32 determineUsage(S32 usage); + std::vector mMappedVertexRegions; // list of mMappedData byte ranges that must be sent to GL + std::vector mMappedIndexRegions; // list of mMappedIndexData byte ranges that must be sent to GL private: - static LLPrivateMemoryPool* sPrivatePoolp; + // DEPRECATED + // These function signatures are deprecated, but for some reason + // there are classes in an external package that depend on LLVertexBuffer + + // TODO: move these classes into viewer repository + friend class LLNavShapeVBOManager; + friend class LLNavMeshVBOManager; + + LLVertexBuffer(U32 typemask, U32 usage) + : LLVertexBuffer(typemask) + {} + + bool allocateBuffer(S32 nverts, S32 nindices, BOOL create) { return allocateBuffer(nverts, nindices); } public: - static S32 sCount; - static S32 sGLCount; - static S32 sMappedCount; - static bool sMapped; - typedef std::list buffer_list_t; - - static bool sDisableVBOMapping; //disable glMapBufferARB - static bool sEnableVBOs; - static const S32 sTypeSize[TYPE_MAX]; + static const U32 sTypeSize[TYPE_MAX]; static const U32 sGLMode[LLRender::NUM_MODES]; static U32 sGLRenderBuffer; - static U32 sGLRenderArray; static U32 sGLRenderIndices; - static bool sVBOActive; - static bool sIBOActive; static U32 sLastMask; - static U32 sAllocatedBytes; - static U32 sAllocatedIndexBytes; static U32 sVertexCount; - static U32 sIndexCount; - static U32 sBindCount; - static U32 sSetCount; }; #ifdef LL_PROFILER_ENABLE_RENDER_DOC diff --git a/indra/llwindow/llwindowwin32.cpp b/indra/llwindow/llwindowwin32.cpp index 7787e2eb26..a195964bb1 100644 --- a/indra/llwindow/llwindowwin32.cpp +++ b/indra/llwindow/llwindowwin32.cpp @@ -1051,16 +1051,19 @@ BOOL LLWindowWin32::maximize() BOOL success = FALSE; if (!mWindowHandle) return success; - WINDOWPLACEMENT placement; - placement.length = sizeof(WINDOWPLACEMENT); - - success = GetWindowPlacement(mWindowHandle, &placement); - if (!success) return success; + mWindowThread->post([=] + { + WINDOWPLACEMENT placement; + placement.length = sizeof(WINDOWPLACEMENT); - placement.showCmd = SW_MAXIMIZE; + if (GetWindowPlacement(mWindowHandle, &placement)) + { + placement.showCmd = SW_MAXIMIZE; + SetWindowPlacement(mWindowHandle, &placement); + } + }); - success = SetWindowPlacement(mWindowHandle, &placement); - return success; + return TRUE; } BOOL LLWindowWin32::getFullscreen() @@ -1408,14 +1411,6 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO return FALSE; } - if (pfd.cAlphaBits < 8) - { - OSMessageBox(mCallbacks->translateString("MBAlpha"), - mCallbacks->translateString("MBError"), OSMB_OK); - close(); - return FALSE; - } - if (!SetPixelFormat(mhDC, pixel_format, &pfd)) { OSMessageBox(mCallbacks->translateString("MBPixelFmtSetErr"), @@ -1474,7 +1469,7 @@ BOOL LLWindowWin32::switchContext(BOOL fullscreen, const LLCoordScreen& size, BO attrib_list[cur_attrib++] = 24; attrib_list[cur_attrib++] = WGL_ALPHA_BITS_ARB; - attrib_list[cur_attrib++] = 8; + attrib_list[cur_attrib++] = 0; U32 end_attrib = 0; if (mFSAASamples > 0) @@ -1705,13 +1700,6 @@ const S32 max_format = (S32)num_formats - 1; return FALSE; } - if (pfd.cAlphaBits < 8) - { - OSMessageBox(mCallbacks->translateString("MBAlpha"), mCallbacks->translateString("MBError"), OSMB_OK); - close(); - return FALSE; - } - mhRC = 0; if (wglCreateContextAttribsARB) { //attempt to create a specific versioned context diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index ac449e45ef..ec4125c2bf 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -8745,7 +8745,7 @@ Vector3 Value - 0.01 + 0.25 0.0 0.0 diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index ea41ac5f2d..0cb966296a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -505,7 +505,7 @@ vec3 tapIrradianceMap(vec3 pos, vec3 dir, out float w, vec3 c, int i) v -= c; v = env_mat * v; { - return texture(irradianceProbes, vec4(v.xyz, refIndex[i].x)).rgb * refParams[i].x; + return textureLod(irradianceProbes, vec4(v.xyz, refIndex[i].x), 0).rgb * refParams[i].x; } } @@ -676,14 +676,15 @@ void sampleReflectionProbesLegacy(inout vec3 ambenv, inout vec3 glossenv, inout vec3 refnormpersp = reflect(pos.xyz, norm.xyz); + ambenv = sampleProbeAmbient(pos, norm); - + if (glossiness > 0.0) { float lod = (1.0-glossiness)*reflection_lods; glossenv = sampleProbes(pos, normalize(refnormpersp), lod, false); } - + if (envIntensity > 0.0) { legacyenv = sampleProbes(pos, normalize(refnormpersp), 0.0, false); diff --git a/indra/newview/featuretable.txt b/indra/newview/featuretable.txt index f8a5086130..90de369424 100644 --- a/indra/newview/featuretable.txt +++ b/indra/newview/featuretable.txt @@ -1,4 +1,4 @@ -version 43 +version 44 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -55,7 +55,7 @@ RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 -UseOcclusion 1 0 +UseOcclusion 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 diff --git a/indra/newview/featuretable_mac.txt b/indra/newview/featuretable_mac.txt index 0f84ade82a..45e3827f60 100644 --- a/indra/newview/featuretable_mac.txt +++ b/indra/newview/featuretable_mac.txt @@ -1,4 +1,4 @@ -version 42 +version 43 // The version number above should be incremented IF AND ONLY IF some // change has been made that is sufficiently important to justify // resetting the graphics preferences of all users to the recommended @@ -53,7 +53,7 @@ RenderVBOEnable 1 1 RenderVBOMappingDisable 1 1 RenderVolumeLODFactor 1 2.0 UseStartScreen 1 1 -UseOcclusion 1 0 +UseOcclusion 1 1 WindLightUseAtmosShaders 1 1 WLSkyDetail 1 128 Disregard128DefaultDrawDistance 1 1 diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index d4d8b985ce..dd4363d2a4 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -535,7 +535,6 @@ static void settings_to_globals() LLRender::sGLCoreProfile = gSavedSettings.getBOOL("RenderGLContextCoreProfile"); #endif LLRender::sNsightDebugSupport = gSavedSettings.getBOOL("RenderNsightDebugSupport"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); LLImageGL::sGlobalUseAnisotropic = gSavedSettings.getBOOL("RenderAnisotropic"); LLImageGL::sCompressTextures = gSavedSettings.getBOOL("RenderCompressTextures"); LLVOVolume::sLODFactor = llclamp(gSavedSettings.getF32("RenderVolumeLODFactor"), 0.01f, MAX_LOD_FACTOR); diff --git a/indra/newview/lldrawable.cpp b/indra/newview/lldrawable.cpp index 74625423fe..7d869562ca 100644 --- a/indra/newview/lldrawable.cpp +++ b/indra/newview/lldrawable.cpp @@ -702,7 +702,8 @@ F32 LLDrawable::updateXform(BOOL undamped) ((dist_vec_squared(old_pos, target_pos) > 0.f) || (1.f - dot(old_rot, target_rot)) > 0.f)) { //fix for BUG-840, MAINT-2275, MAINT-1742, MAINT-2247 - gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); + mVObjp->shrinkWrap(); + gPipeline.markRebuild(this, LLDrawable::REBUILD_POSITION, TRUE); } else if (!getVOVolume() && !isAvatar()) { @@ -1252,10 +1253,10 @@ LLSpatialPartition* LLDrawable::getSpatialPartition() LLSpatialBridge::LLSpatialBridge(LLDrawable* root, BOOL render_by_group, U32 data_mask, LLViewerRegion* regionp) : LLDrawable(root->getVObj(), true), - LLSpatialPartition(data_mask, render_by_group, GL_STREAM_DRAW, regionp) + LLSpatialPartition(data_mask, render_by_group, regionp) { - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE - + LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWABLE; + mOcclusionEnabled = false; mBridge = this; mDrawable = root; root->setSpatialBridge(this); @@ -1758,7 +1759,7 @@ LLDrawable* LLDrawable::getRoot() } LLBridgePartition::LLBridgePartition(LLViewerRegion* regionp) -: LLSpatialPartition(0, FALSE, 0, regionp) +: LLSpatialPartition(0, false, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 2abbe2f2f8..a5990492b1 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -385,7 +385,7 @@ LLRenderPass::~LLRenderPass() } -void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) +void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, bool texture) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; @@ -395,19 +395,18 @@ void LLRenderPass::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL t LLDrawInfo *pparams = *k; if (pparams) { - pushBatch(*pparams, mask, texture); + pushBatch(*pparams, texture); } } } -void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) +void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; - mask |= LLVertexBuffer::MAP_WEIGHT4; - + for (LLSpatialGroup::drawmap_elem_t::iterator k = draw_info.begin(); k != draw_info.end(); ++k) { LLDrawInfo* pparams = *k; @@ -420,7 +419,7 @@ void LLRenderPass::renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, lastMeshId = pparams->mSkinInfo->mHash; } - pushBatch(*pparams, mask, texture); + pushBatch(*pparams, texture); } } } @@ -446,7 +445,7 @@ void teardown_texture_matrix(LLDrawInfo& params) } } -void LLRenderPass::pushGLTFBatches(U32 type, U32 mask) +void LLRenderPass::pushGLTFBatches(U32 type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); @@ -467,19 +466,19 @@ void LLRenderPass::pushGLTFBatches(U32 type, U32 mask) applyModelMatrix(params); - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); teardown_texture_matrix(params); } } -void LLRenderPass::pushRiggedGLTFBatches(U32 type, U32 mask) +void LLRenderPass::pushRiggedGLTFBatches(U32 type) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; - mask |= LLVertexBuffer::MAP_WEIGHT4; + auto* begin = gPipeline.beginRenderMap(type); auto* end = gPipeline.endRenderMap(type); for (LLCullResult::drawinfo_iterator i = begin; i != end; ) @@ -505,14 +504,14 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type, U32 mask) lastMeshId = params.mSkinInfo->mHash; } - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); teardown_texture_matrix(params); } } -void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); @@ -522,16 +521,15 @@ void LLRenderPass::pushBatches(U32 type, U32 mask, BOOL texture, BOOL batch_text LLDrawInfo* pparams = *i; LLCullResult::increment_iterator(i, end); - pushBatch(*pparams, mask, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures); } } -void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOAvatar* lastAvatar = nullptr; U64 lastMeshId = 0; - mask |= LLVertexBuffer::MAP_WEIGHT4; auto* begin = gPipeline.beginRenderMap(type); auto* end = gPipeline.endRenderMap(type); for (LLCullResult::drawinfo_iterator i = begin; i != end; ) @@ -546,11 +544,11 @@ void LLRenderPass::pushRiggedBatches(U32 type, U32 mask, BOOL texture, BOOL batc lastMeshId = pparams->mSkinInfo->mHash; } - pushBatch(*pparams, mask, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures); } } -void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); @@ -560,11 +558,11 @@ void LLRenderPass::pushMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_ LLDrawInfo* pparams = *i; LLCullResult::increment_iterator(i, end); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); - pushBatch(*pparams, mask, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures); } } -void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL batch_textures) +void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOAvatar* lastAvatar = nullptr; @@ -593,7 +591,7 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture, BOOL lastMeshId = pparams->mSkinInfo->mHash; } - pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures); } } @@ -612,7 +610,7 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) } } -void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; if (!params.mCount) @@ -662,8 +660,8 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL ba // params.mGroup->rebuildMesh(); //} - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 9a4b09b973..7050723116 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -333,7 +333,6 @@ public: return "PASS_GLTF_PBR"; case PASS_GLTF_PBR_RIGGED: return "PASS_GLTF_PBR_RIGGED"; - default: return "Unknown pass"; } @@ -350,17 +349,17 @@ public: void resetDrawOrders() { } static void applyModelMatrix(const LLDrawInfo& params); - virtual void pushBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); - virtual void pushRiggedBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); - void pushGLTFBatches(U32 type, U32 mask); - void pushRiggedGLTFBatches(U32 type, U32 mask); - virtual void pushMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); - virtual void pushRiggedMaskBatches(U32 type, U32 mask, BOOL texture = TRUE, BOOL batch_textures = FALSE); - virtual void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE); + virtual void pushBatches(U32 type, bool texture = true, bool batch_textures = false); + virtual void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false); + void pushGLTFBatches(U32 type); + void pushRiggedGLTFBatches(U32 type); + virtual void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false); + virtual void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false); + virtual void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); static bool uploadMatrixPalette(LLDrawInfo& params); static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo); - virtual void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); - virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE); + virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true); + virtual void renderRiggedGroup(LLSpatialGroup* group, U32 type, bool texture = true); }; class LLFacePool : public LLDrawPool diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 07381acd25..ed952689fa 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -379,11 +379,6 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) { LLDrawInfo& params = **k; - if (params.mParticle) - { - continue; - } - bool rigged = (params.mAvatar != nullptr); gHighlightProgram.bind(rigged); gGL.diffuseColor4f(1, 0, 0, 1); @@ -403,12 +398,8 @@ void LLDrawPoolAlpha::renderAlphaHighlight(U32 mask) } LLRenderPass::applyModelMatrix(params); - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } - params.mVertexBuffer->setBufferFast(rigged ? mask | LLVertexBuffer::MAP_WEIGHT4 : mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); } } } @@ -435,9 +426,9 @@ inline bool IsEmissive(LLDrawInfo& params) inline void Draw(LLDrawInfo* draw, U32 mask) { - draw->mVertexBuffer->setBufferFast(mask); + draw->mVertexBuffer->setBuffer(); LLRenderPass::applyModelMatrix(*draw); - draw->mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); + draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } bool LLDrawPoolAlpha::TexSetup(LLDrawInfo* draw, bool use_material) @@ -530,8 +521,8 @@ void LLDrawPoolAlpha::RestoreTexSetup(bool tex_setup) void LLDrawPoolAlpha::drawEmissive(U32 mask, LLDrawInfo* draw) { LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::EMISSIVE_BRIGHTNESS, 1.f); - draw->mVertexBuffer->setBufferFast((mask & ~LLVertexBuffer::MAP_COLOR) | LLVertexBuffer::MAP_EMISSIVE); - draw->mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); + draw->mVertexBuffer->setBuffer(); + draw->mVertexBuffer->drawRange(LLRender::TRIANGLES, draw->mStart, draw->mEnd, draw->mCount, draw->mOffset); } @@ -665,30 +656,6 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("ra - push batch"); - U32 have_mask = params.mVertexBuffer->getTypeMask() & mask; - if (have_mask != mask) - { //FIXME! - LL_WARNS_ONCE() << "Missing required components, expected mask: " << mask - << " present: " << have_mask - << ". Skipping render batch." << LL_ENDL; - continue; - } - - if(depth_only) - { - // when updating depth buffer, discard faces that are more than 90% transparent - LLFace* face = params.mFace; - if(face) - { - const LLTextureEntry* tep = face->getTextureEntry(); - if(tep) - { // don't render faces that are more than 90% transparent - if(tep->getColor().mV[3] < MINIMUM_IMPOSTOR_ALPHA) - continue; - } - } - } - LLRenderPass::applyModelMatrix(params); LLMaterial* mat = NULL; @@ -835,18 +802,8 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) reset_minimum_alpha = true; } - U32 drawMask = mask; - if (params.mFullbright) - { - drawMask &= ~(LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); - } - if (params.mAvatar != nullptr) - { - drawMask |= LLVertexBuffer::MAP_WEIGHT4; - } - - params.mVertexBuffer->setBufferFast(drawMask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (reset_minimum_alpha) { diff --git a/indra/newview/lldrawpoolavatar.cpp b/indra/newview/lldrawpoolavatar.cpp index 67c3000410..8a3ab20ab4 100644 --- a/indra/newview/lldrawpoolavatar.cpp +++ b/indra/newview/lldrawpoolavatar.cpp @@ -53,8 +53,6 @@ #include "llviewercontrol.h" // for gSavedSettings #include "llviewertexturelist.h" -static U32 sDataMask = LLDrawPoolAvatar::VERTEX_DATA_MASK; -static U32 sBufferUsage = GL_STREAM_DRAW; static U32 sShaderLevel = 0; LLGLSLShader* LLDrawPoolAvatar::sVertexProgram = NULL; @@ -143,15 +141,6 @@ void LLDrawPoolAvatar::prerender() mShaderLevel = LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_AVATAR); sShaderLevel = mShaderLevel; - - if (sShaderLevel > 0) - { - sBufferUsage = GL_DYNAMIC_DRAW; - } - else - { - sBufferUsage = GL_STREAM_DRAW; - } } LLMatrix4& LLDrawPoolAvatar::getModelView() @@ -932,11 +921,3 @@ LLColor3 LLDrawPoolAvatar::getDebugColor() const } -LLVertexBufferAvatar::LLVertexBufferAvatar() -: LLVertexBuffer(sDataMask, - GL_STREAM_DRAW) //avatars are always stream draw due to morph targets -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_AVATAR -} - - diff --git a/indra/newview/lldrawpoolavatar.h b/indra/newview/lldrawpoolavatar.h index 21add39b21..ff78c6c60a 100644 --- a/indra/newview/lldrawpoolavatar.h +++ b/indra/newview/lldrawpoolavatar.h @@ -129,12 +129,6 @@ typedef enum static LLGLSLShader* sVertexProgram; }; -class LLVertexBufferAvatar : public LLVertexBuffer -{ -public: - LLVertexBufferAvatar(); -}; - extern S32 AVATAR_OFFSET_POS; extern S32 AVATAR_OFFSET_NORMAL; extern S32 AVATAR_OFFSET_TEX0; diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 4379fdc603..9c871514f7 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -353,22 +353,22 @@ void LLDrawPoolBump::renderShiny() { if (mRigged) { - LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_SHINY_RIGGED, true, true); } else { - LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + LLRenderPass::pushBatches(LLRenderPass::PASS_SHINY, true, true); } } else { if (mRigged) { - gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, sVertexMask, TRUE); + gPipeline.renderRiggedGroups(this, LLRenderPass::PASS_SHINY_RIGGED, true); } else { - gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, sVertexMask, TRUE); + gPipeline.renderGroups(this, LLRenderPass::PASS_SHINY, true); } } } @@ -508,22 +508,22 @@ void LLDrawPoolBump::renderFullbrightShiny() { if (mRigged) { - LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, true, true); } else { - LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, true, true); } } else { if (mRigged) { - LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED, sVertexMask); + LLRenderPass::pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY_RIGGED); } else { - LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY, sVertexMask); + LLRenderPass::pushBatches(LLRenderPass::PASS_FULLBRIGHT_SHINY); } } } @@ -549,7 +549,7 @@ void LLDrawPoolBump::endFullbrightShiny() mShiny = FALSE; } -void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture = TRUE) +void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, bool texture = true) { LLSpatialGroup::drawmap_elem_t& draw_info = group->mDrawMap[type]; @@ -559,11 +559,7 @@ void LLDrawPoolBump::renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL applyModelMatrix(params); - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } - params.mVertexBuffer->setBuffer(mask); + params.mVertexBuffer->setBuffer(); params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); } } @@ -574,7 +570,7 @@ BOOL LLDrawPoolBump::bindBumpMap(LLDrawInfo& params, S32 channel) { U8 bump_code = params.mBump; - return bindBumpMap(bump_code, params.mTexture, params.mVSize, channel); + return bindBumpMap(bump_code, params.mTexture, channel); } //static @@ -584,14 +580,14 @@ BOOL LLDrawPoolBump::bindBumpMap(LLFace* face, S32 channel) if (te) { U8 bump_code = te->getBumpmap(); - return bindBumpMap(bump_code, face->getTexture(), face->getVirtualSize(), channel); + return bindBumpMap(bump_code, face->getTexture(), channel); } return FALSE; } //static -BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsize, S32 channel) +BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, S32 channel) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //Note: texture atlas does not support bump texture now. @@ -617,7 +613,7 @@ BOOL LLDrawPoolBump::bindBumpMap(U8 bump_code, LLViewerTexture* texture, F32 vsi if( bump_code < LLStandardBumpmap::sStandardBumpmapCount ) { bump = gStandardBumpmapList[bump_code].mImage; - gBumpImageList.addTextureStats(bump_code, tex->getID(), vsize); + gBumpImageList.addTextureStats(bump_code, tex->getID(), tex->getMaxVirtualSize()); } break; } @@ -674,7 +670,7 @@ void LLDrawPoolBump::renderBump(U32 pass) /// Get rid of z-fighting with non-bump pass. LLGLEnable polyOffset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.0f, -1.0f); - renderBump(pass, sVertexMask); + pushBumpBatches(pass); } //static @@ -719,8 +715,6 @@ void LLDrawPoolBump::renderDeferred(S32 pass) LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_COLOR; - LLVOAvatar* avatar = nullptr; U64 skin = 0; @@ -741,11 +735,11 @@ void LLDrawPoolBump::renderDeferred(S32 pass) avatar = params.mAvatar; skin = params.mSkinInfo->mHash; } - pushBatch(params, mask | LLVertexBuffer::MAP_WEIGHT4, TRUE, FALSE); + pushBatch(params, true, false); } else { - pushBatch(params, mask, TRUE, FALSE); + pushBatch(params, true, false); } } @@ -1342,7 +1336,7 @@ void LLBumpImageList::onSourceLoaded( BOOL success, LLViewerTexture *src_vi, LLI } } -void LLDrawPoolBump::renderBump(U32 type, U32 mask) +void LLDrawPoolBump::pushBumpBatches(U32 type) { LLVOAvatar* avatar = nullptr; U64 skin = 0; @@ -1350,7 +1344,6 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) if (mRigged) { // nudge type enum and include skinweights for rigged pass type += 1; - mask |= LLVertexBuffer::MAP_WEIGHT4; } LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); @@ -1377,12 +1370,12 @@ void LLDrawPoolBump::renderBump(U32 type, U32 mask) } } } - pushBatch(params, mask, FALSE); + pushBatch(params, false); } } } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; applyModelMatrix(params); @@ -1435,12 +1428,8 @@ void LLDrawPoolBump::pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL } } - if (params.mGroup) - { - params.mGroup->rebuildMesh(); - } - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index cf463f4458..4400308451 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -55,10 +55,10 @@ public: virtual void render(S32 pass = 0) override; virtual S32 getNumPasses() override; /*virtual*/ void prerender() override; - void pushBatch(LLDrawInfo& params, U32 mask, BOOL texture, BOOL batch_textures = FALSE) override; + void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false) override; - void renderBump(U32 type, U32 mask); - void renderGroup(LLSpatialGroup* group, U32 type, U32 mask, BOOL texture) override; + void pushBumpBatches(U32 type); + void renderGroup(LLSpatialGroup* group, U32 type, bool texture) override; S32 numBumpPasses(); @@ -87,7 +87,7 @@ public: static BOOL bindBumpMap(LLFace* face, S32 channel = -2); private: - static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, F32 vsize, S32 channel); + static BOOL bindBumpMap(U8 bump_code, LLViewerTexture* tex, S32 channel); bool mRigged = false; // if true, doing a rigged pass }; diff --git a/indra/newview/lldrawpoolmaterials.cpp b/indra/newview/lldrawpoolmaterials.cpp index 858fb871d3..735f32ddbb 100644 --- a/indra/newview/lldrawpoolmaterials.cpp +++ b/indra/newview/lldrawpoolmaterials.cpp @@ -156,8 +156,6 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) type += 1; } - U32 mask = mShader->mAttributeMask; - LLCullResult::drawinfo_iterator begin = gPipeline.beginRenderMap(type); LLCullResult::drawinfo_iterator end = gPipeline.endRenderMap(type); @@ -304,8 +302,8 @@ void LLDrawPoolMaterials::renderDeferred(S32 pass) params.mGroup->rebuildMesh(); }*/ - params.mVertexBuffer->setBufferFast(mask); - params.mVertexBuffer->drawRangeFast(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); + params.mVertexBuffer->setBuffer(); + params.mVertexBuffer->drawRange(LLRender::TRIANGLES, params.mStart, params.mEnd, params.mCount, params.mOffset); if (tex_setup) { diff --git a/indra/newview/lldrawpoolpbropaque.cpp b/indra/newview/lldrawpoolpbropaque.cpp index 0e44a9be28..9dd1bc0ba2 100644 --- a/indra/newview/lldrawpoolpbropaque.cpp +++ b/indra/newview/lldrawpoolpbropaque.cpp @@ -43,13 +43,11 @@ void LLDrawPoolGLTFPBR::renderDeferred(S32 pass) for (U32 type : types) { gDeferredPBROpaqueProgram.bind(); - pushGLTFBatches(type, getVertexDataMask()); + pushGLTFBatches(type); gDeferredPBROpaqueProgram.bind(true); - pushRiggedGLTFBatches(type+1, getVertexDataMask()); + pushRiggedGLTFBatches(type+1); } - - LLGLSLShader::sCurBoundShaderPtr->unbind(); } diff --git a/indra/newview/lldrawpoolsimple.cpp b/indra/newview/lldrawpoolsimple.cpp index 57aa1c73f0..3a659e0efc 100644 --- a/indra/newview/lldrawpoolsimple.cpp +++ b/indra/newview/lldrawpoolsimple.cpp @@ -99,12 +99,12 @@ void LLDrawPoolGlow::render(LLGLSLShader* shader) //first pass -- static objects setup_glow_shader(shader); - pushBatches(LLRenderPass::PASS_GLOW, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_GLOW, true, true); // second pass -- rigged objects shader = shader->mRiggedVariant; setup_glow_shader(shader); - pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_GLOW_RIGGED, true, true); gGL.setColorMask(true, false); gGL.setSceneBlendType(LLRender::BT_ALPHA); @@ -161,21 +161,19 @@ void LLDrawPoolSimple::render(S32 pass) gPipeline.enableLightsDynamic(); - U32 mask = getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX; - // first pass -- static objects { setup_simple_shader(shader); - pushBatches(LLRenderPass::PASS_SIMPLE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SIMPLE, true, true); if (LLPipeline::sRenderDeferred) { //if deferred rendering is enabled, bump faces aren't registered as simple //render bump faces here as simple so bump faces will appear under water - pushBatches(LLRenderPass::PASS_BUMP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_MATERIAL, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_SPECMAP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMMAP, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMSPEC, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_BUMP, true, true); + pushBatches(LLRenderPass::PASS_MATERIAL, true, true); + pushBatches(LLRenderPass::PASS_SPECMAP, true, true); + pushBatches(LLRenderPass::PASS_NORMMAP, true, true); + pushBatches(LLRenderPass::PASS_NORMSPEC, true, true); } } @@ -183,16 +181,16 @@ void LLDrawPoolSimple::render(S32 pass) { shader = shader->mRiggedVariant; setup_simple_shader(shader); - pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, true, true); if (LLPipeline::sRenderDeferred) { //if deferred rendering is enabled, bump faces aren't registered as simple //render bump faces here as simple so bump faces will appear under water - pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_BUMP_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_RIGGED, true, true); } } } @@ -228,19 +226,19 @@ void LLDrawPoolAlphaMask::render(S32 pass) // render static setup_simple_shader(shader); - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, true, true); + pushMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, true, true); + pushMaskBatches(LLRenderPass::PASS_SPECMAP_MASK, true, true); + pushMaskBatches(LLRenderPass::PASS_NORMMAP_MASK, true, true); + pushMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK, true, true); // render rigged setup_simple_shader(shader->mRiggedVariant); - pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); - pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, true, true); + pushRiggedMaskBatches(LLRenderPass::PASS_MATERIAL_ALPHA_MASK_RIGGED, true, true); + pushRiggedMaskBatches(LLRenderPass::PASS_SPECMAP_MASK_RIGGED, true, true); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMMAP_MASK_RIGGED, true, true); + pushRiggedMaskBatches(LLRenderPass::PASS_NORMSPEC_MASK_RIGGED, true, true); } LLDrawPoolFullbrightAlphaMask::LLDrawPoolFullbrightAlphaMask() : @@ -269,11 +267,11 @@ void LLDrawPoolFullbrightAlphaMask::render(S32 pass) // render static setup_fullbright_shader(shader); - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true); // render rigged setup_fullbright_shader(shader->mRiggedVariant); - pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, true, true); } //=============================== @@ -293,11 +291,11 @@ void LLDrawPoolSimple::renderDeferred(S32 pass) //render static setup_simple_shader(&gDeferredDiffuseProgram); - pushBatches(LLRenderPass::PASS_SIMPLE, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_SIMPLE, true, true); //render rigged setup_simple_shader(gDeferredDiffuseProgram.mRiggedVariant); - pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_SIMPLE_RIGGED, true, true); } static LLTrace::BlockTimerStatHandle FTM_RENDER_ALPHA_MASK_DEFERRED("Deferred Alpha Mask"); @@ -310,11 +308,11 @@ void LLDrawPoolAlphaMask::renderDeferred(S32 pass) //render static setup_simple_shader(shader); - pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_ALPHA_MASK, true, true); //render rigged setup_simple_shader(shader->mRiggedVariant); - pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, getVertexDataMask() | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_ALPHA_MASK_RIGGED, true, true); } // grass drawpool @@ -453,15 +451,14 @@ void LLDrawPoolFullbright::renderPostDeferred(S32 pass) } gGL.setSceneBlendType(LLRender::BT_ALPHA); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; // render static setup_fullbright_shader(shader); - pushBatches(LLRenderPass::PASS_FULLBRIGHT, fullbright_mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, true, true); // render rigged setup_fullbright_shader(shader->mRiggedVariant); - pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, fullbright_mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, true, true); } void LLDrawPoolFullbright::render(S32 pass) @@ -480,24 +477,21 @@ void LLDrawPoolFullbright::render(S32 pass) shader = &gObjectFullbrightProgram; } - - U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - // render static setup_fullbright_shader(shader); - pushBatches(LLRenderPass::PASS_FULLBRIGHT, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, mask, TRUE, TRUE); - pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, mask, TRUE, TRUE); + pushBatches(LLRenderPass::PASS_FULLBRIGHT, true, true); + pushBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE, true, true); + pushBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE, true, true); + pushBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE, true, true); + pushBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE, true, true); // render rigged setup_fullbright_shader(shader->mRiggedVariant); - pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, mask, TRUE, TRUE); - pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, mask, TRUE, TRUE); + pushRiggedBatches(LLRenderPass::PASS_FULLBRIGHT_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_MATERIAL_ALPHA_EMISSIVE_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_SPECMAP_EMISSIVE_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_NORMMAP_EMISSIVE_RIGGED, true, true); + pushRiggedBatches(LLRenderPass::PASS_NORMSPEC_EMISSIVE_RIGGED, true, true); } S32 LLDrawPoolFullbright::getNumPasses() @@ -531,14 +525,13 @@ void LLDrawPoolFullbrightAlphaMask::renderPostDeferred(S32 pass) } LLGLDisable blend(GL_BLEND); - U32 fullbright_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_COLOR | LLVertexBuffer::MAP_TEXTURE_INDEX; - + // render static setup_fullbright_shader(shader); - pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, fullbright_mask, TRUE, TRUE); + pushMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true); // render rigged setup_fullbright_shader(shader->mRiggedVariant); - pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, fullbright_mask, TRUE, TRUE); + pushRiggedMaskBatches(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK_RIGGED, true, true); } diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp index 55c8d84838..64178f0a59 100644 --- a/indra/newview/lldrawpoolterrain.cpp +++ b/indra/newview/lldrawpoolterrain.cpp @@ -148,7 +148,7 @@ void LLDrawPoolTerrain::boostTerrainDetailTextures() for (S32 i = 0; i < 4; i++) { compp->mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); - gPipeline.touchTexture(compp->mDetailTextures[i], 1024.f * 1024.f); + compp->mDetailTextures[i]->addTextureStats(1024.f * 1024.f); } } @@ -821,8 +821,7 @@ void LLDrawPoolTerrain::renderOwnership() iter != mDrawFace.end(); iter++) { LLFace *facep = *iter; - facep->renderIndexed(LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0); + facep->renderIndexed(); } gGL.matrixMode(LLRender::MM_TEXTURE); diff --git a/indra/newview/lldrawpoolterrain.h b/indra/newview/lldrawpoolterrain.h index 5b4558020d..e00e0c4720 100644 --- a/indra/newview/lldrawpoolterrain.h +++ b/indra/newview/lldrawpoolterrain.h @@ -33,14 +33,12 @@ class LLDrawPoolTerrain : public LLFacePool { LLPointer mTexturep; public: - enum - { - VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_TEXCOORD1 | - LLVertexBuffer::MAP_TEXCOORD2 | - LLVertexBuffer::MAP_TEXCOORD3 + enum + { + VERTEX_DATA_MASK = LLVertexBuffer::MAP_VERTEX | + LLVertexBuffer::MAP_NORMAL | + LLVertexBuffer::MAP_TEXCOORD0 | + LLVertexBuffer::MAP_TEXCOORD1 }; virtual U32 getVertexDataMask(); diff --git a/indra/newview/lldrawpooltree.cpp b/indra/newview/lldrawpooltree.cpp index facfb235c9..61a8e20b54 100644 --- a/indra/newview/lldrawpooltree.cpp +++ b/indra/newview/lldrawpooltree.cpp @@ -93,7 +93,7 @@ void LLDrawPoolTree::render(S32 pass) LLGLState test(GL_ALPHA_TEST, 0); gGL.getTexUnit(sDiffTex)->bindFast(mTexturep); - gPipeline.touchTexture(mTexturep, 1024.f * 1024.f); // <=== keep Linden tree textures at full res + mTexturep->addTextureStats(1024.f * 1024.f); // <=== keep Linden tree textures at full res for (std::vector::iterator iter = mDrawFace.begin(); iter != mDrawFace.end(); iter++) @@ -117,8 +117,8 @@ void LLDrawPoolTree::render(S32 pass) gPipeline.mMatrixOpCount++; } - buff->setBufferFast(LLDrawPoolTree::VERTEX_DATA_MASK); - buff->drawRangeFast(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); + buff->setBuffer(); + buff->drawRange(LLRender::TRIANGLES, 0, buff->getNumVerts()-1, buff->getNumIndices(), 0); } } } diff --git a/indra/newview/lldrawpoolwater.cpp b/indra/newview/lldrawpoolwater.cpp index c2fe52683b..1808fb5987 100644 --- a/indra/newview/lldrawpoolwater.cpp +++ b/indra/newview/lldrawpoolwater.cpp @@ -92,36 +92,19 @@ void LLDrawPoolWater::setNormalMaps(const LLUUID& normalMapId, const LLUUID& nex mWaterNormp[1]->addTextureStats(1024.f*1024.f); } -//static -void LLDrawPoolWater::restoreGL() -{ - /*LLSettingsWater::ptr_t pwater = LLEnvironment::instance().getCurrentWater(); - if (pwater) - { - setTransparentTextures(pwater->getTransparentTextureID(), pwater->getNextTransparentTextureID()); - setOpaqueTexture(pwater->GetDefaultOpaqueTextureAssetId()); - setNormalMaps(pwater->getNormalMapID(), pwater->getNextNormalMapID()); - }*/ -} - void LLDrawPoolWater::prerender() { mShaderLevel = LLCubeMap::sUseCubeMaps ? LLViewerShaderMgr::instance()->getShaderLevel(LLViewerShaderMgr::SHADER_WATER) : 0; } -S32 LLDrawPoolWater::getNumPasses() -{ - if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) - { - return 1; - } - - return 0; -} - S32 LLDrawPoolWater::getNumPostDeferredPasses() { - return 1; + if (LLViewerCamera::getInstance()->getOrigin().mV[2] < 1024.f) + { + return 1; + } + + return 0; } void LLDrawPoolWater::beginPostDeferredPass(S32 pass) @@ -134,13 +117,6 @@ void LLDrawPoolWater::beginPostDeferredPass(S32 pass) LLRenderTarget& src = gPipeline.mRT->screen; LLRenderTarget& dst = gPipeline.mWaterDis; -#if 0 - dst.copyContents(src, - 0, 0, src.getWidth(), src.getHeight(), - 0, 0, dst.getWidth(), dst.getHeight(), - GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, - GL_NEAREST); -#else dst.bindTarget(); gCopyDepthProgram.bind(); @@ -150,369 +126,14 @@ void LLDrawPoolWater::beginPostDeferredPass(S32 pass) gGL.getTexUnit(diff_map)->bind(&src); gGL.getTexUnit(depth_map)->bind(&src, true); - gPipeline.mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + gPipeline.mScreenTriangleVB->setBuffer(); gPipeline.mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); dst.flush(); -#endif } } void LLDrawPoolWater::renderPostDeferred(S32 pass) -{ - renderWater(); -} - - -S32 LLDrawPoolWater::getNumDeferredPasses() -{ - return 0; -} - -//=============================== -//DEFERRED IMPLEMENTATION -//=============================== -void LLDrawPoolWater::renderDeferred(S32 pass) -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); - - if (!LLPipeline::sRenderTransparentWater) - { - // Will render opaque water without use of ALM - render(pass); - return; - } - - deferred_render = TRUE; - renderWater(); - deferred_render = FALSE; -#endif -} - -//========================================= - -void LLDrawPoolWater::render(S32 pass) -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; //LL_RECORD_BLOCK_TIME(FTM_RENDER_WATER); - if (mDrawFace.empty() || LLDrawable::getCurrentFrame() <= 1) - { - return; - } - - //do a quick 'n dirty depth sort - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace* facep = *iter; - facep->mDistance = -facep->mCenterLocal.mV[2]; - } - - std::sort(mDrawFace.begin(), mDrawFace.end(), LLFace::CompareDistanceGreater()); - - // See if we are rendering water as opaque or not - if (!LLPipeline::sRenderTransparentWater) - { - // render water for low end hardware - renderOpaqueLegacyWater(); - return; - } - - LLGLEnable blend(GL_BLEND); - - if ((mShaderLevel > 0) && !sSkipScreenCopy) - { - renderWater(); - return; - } - - LLVOSky *voskyp = gSky.mVOSkyp; - - stop_glerror(); - - LLFace* refl_face = voskyp->getReflFace(); - - gPipeline.disableLights(); - - LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - - LLGLDisable cullFace(GL_CULL_FACE); - - // Set up second pass first - gGL.getTexUnit(1)->activate(); - gGL.getTexUnit(1)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->bind(mWaterImagep[0]) ; - - gGL.getTexUnit(2)->activate(); - gGL.getTexUnit(2)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(2)->bind(mWaterImagep[1]) ; - - LLVector3 camera_up = LLViewerCamera::getInstance()->getUpAxis(); - F32 up_dot = camera_up * LLVector3::z_axis; - - LLColor4 water_color; - if (LLViewerCamera::getInstance()->cameraUnderWater()) - { - water_color.setVec(1.f, 1.f, 1.f, 0.4f); - } - else - { - water_color.setVec(1.f, 1.f, 1.f, 0.5f*(1.f + up_dot)); - } - - gGL.diffuseColor4fv(water_color.mV); - - // Automatically generate texture coords for detail map - glEnable(GL_TEXTURE_GEN_S); //texture unit 1 - glEnable(GL_TEXTURE_GEN_T); //texture unit 1 - glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - - // Slowly move over time. - F32 offset = fmod(gFrameTimeSeconds*2.f, 100.f); - F32 tp0[4] = {16.f/256.f, 0.0f, 0.0f, offset*0.01f}; - F32 tp1[4] = {0.0f, 16.f/256.f, 0.0f, offset*0.01f}; - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); - - gGL.getTexUnit(0)->activate(); - - glClearStencil(1); - glClear(GL_STENCIL_BUFFER_BIT); - //LLGLEnable gls_stencil(GL_STENCIL_TEST); - glStencilOp(GL_KEEP, GL_REPLACE, GL_KEEP); - glStencilFunc(GL_ALWAYS, 0, 0xFFFFFFFF); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - if (voskyp->isReflFace(face)) - { - continue; - } - gGL.getTexUnit(0)->bind(face->getTexture()); - face->renderIndexed(); - } - - // Now, disable texture coord generation on texture state 1 - gGL.getTexUnit(1)->activate(); - gGL.getTexUnit(1)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(1)->disable(); - - glDisable(GL_TEXTURE_GEN_S); //texture unit 1 - glDisable(GL_TEXTURE_GEN_T); //texture unit 1 - - gGL.getTexUnit(2)->activate(); - gGL.getTexUnit(2)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(2)->disable(); - - glDisable(GL_TEXTURE_GEN_S); //texture unit 1 - glDisable(GL_TEXTURE_GEN_T); //texture unit 1 - - // Disable texture coordinate and color arrays - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - - stop_glerror(); - - if (gSky.mVOSkyp->getCubeMap() && !LLPipeline::sReflectionProbesEnabled) - { - gSky.mVOSkyp->getCubeMap()->enable(0); - gSky.mVOSkyp->getCubeMap()->bind(); - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - LLMatrix4 camera_mat = LLViewerCamera::getInstance()->getModelview(); - LLMatrix4 camera_rot(camera_mat.getMat3()); - camera_rot.invert(); - - gGL.loadMatrix((F32 *)camera_rot.mMatrix); - - gGL.matrixMode(LLRender::MM_MODELVIEW); - LLOverrideFaceColor overrid(this, 1.f, 1.f, 1.f, 0.5f*up_dot); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - if (voskyp->isReflFace(face)) - { - //refl_face = face; - continue; - } - - if (face->getGeomCount() > 0) - { - face->renderIndexed(); - } - } - - gSky.mVOSkyp->getCubeMap()->disable(); - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - } - - glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP); - - if (refl_face) - { - glStencilFunc(GL_NOTEQUAL, 0, 0xFFFFFFFF); - renderReflection(refl_face); - } -#endif -} - -// for low end hardware -void LLDrawPoolWater::renderOpaqueLegacyWater() -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLVOSky *voskyp = gSky.mVOSkyp; - - if (voskyp == NULL) - { - return; - } - - LLGLSLShader* shader = NULL; - if (LLPipeline::sUnderWaterRender) - { - shader = &gObjectSimpleNonIndexedTexGenWaterProgram; - } - else - { - shader = &gObjectSimpleNonIndexedTexGenProgram; - } - - shader->bind(); - - stop_glerror(); - - // Depth sorting and write to depth buffer - // since this is opaque, we should see nothing - // behind the water. No blending because - // of no transparency. And no face culling so - // that the underside of the water is also opaque. - LLGLDepthTest gls_depth(GL_TRUE, GL_TRUE); - LLGLDisable no_cull(GL_CULL_FACE); - LLGLDisable no_blend(GL_BLEND); - - gPipeline.disableLights(); - - // Activate the texture binding and bind one - // texture since all images will have the same texture - gGL.getTexUnit(0)->activate(); - gGL.getTexUnit(0)->enable(LLTexUnit::TT_TEXTURE); - gGL.getTexUnit(0)->bind(mOpaqueWaterImagep); - - // Automatically generate texture coords for water texture - if (!shader) - { - glEnable(GL_TEXTURE_GEN_S); //texture unit 0 - glEnable(GL_TEXTURE_GEN_T); //texture unit 0 - glTexGenf(GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - glTexGenf(GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR); - } - - // Use the fact that we know all water faces are the same size - // to save some computation - - // Slowly move texture coordinates over time so the watter appears - // to be moving. - F32 movement_period_secs = 50.f; - - F32 offset = fmod(gFrameTimeSeconds, movement_period_secs); - - if (movement_period_secs != 0) - { - offset /= movement_period_secs; - } - else - { - offset = 0; - } - - F32 tp0[4] = { 16.f / 256.f, 0.0f, 0.0f, offset }; - F32 tp1[4] = { 0.0f, 16.f / 256.f, 0.0f, offset }; - - if (!shader) - { - glTexGenfv(GL_S, GL_OBJECT_PLANE, tp0); - glTexGenfv(GL_T, GL_OBJECT_PLANE, tp1); - } - else - { - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_S, 1, tp0); - shader->uniform4fv(LLShaderMgr::OBJECT_PLANE_T, 1, tp1); - } - - gGL.diffuseColor3f(1.f, 1.f, 1.f); - - for (std::vector::iterator iter = mDrawFace.begin(); - iter != mDrawFace.end(); iter++) - { - LLFace *face = *iter; - if (voskyp->isReflFace(face)) - { - continue; - } - - face->renderIndexed(); - } - - stop_glerror(); - - if (!shader) - { - // Reset the settings back to expected values - glDisable(GL_TEXTURE_GEN_S); //texture unit 0 - glDisable(GL_TEXTURE_GEN_T); //texture unit 0 - } - - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); -#endif -} - - -void LLDrawPoolWater::renderReflection(LLFace* face) -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; - LLVOSky *voskyp = gSky.mVOSkyp; - - if (!voskyp) - { - return; - } - - if (!face->getGeomCount()) - { - return; - } - - S8 dr = voskyp->getDrawRefl(); - if (dr < 0) - { - return; - } - - LLGLSNoFog noFog; - - gGL.getTexUnit(0)->bind((dr == 0) ? voskyp->getSunTex() : voskyp->getMoonTex()); - - LLOverrideFaceColor override(this, LLColor4(face->getFaceColor().mV)); - face->renderIndexed(); -#endif -} - -void LLDrawPoolWater::renderWater() { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; if (!deferred_render) diff --git a/indra/newview/lldrawpoolwater.h b/indra/newview/lldrawpoolwater.h index 418430d68a..3158b0a59b 100644 --- a/indra/newview/lldrawpoolwater.h +++ b/indra/newview/lldrawpoolwater.h @@ -61,25 +61,15 @@ public: LLDrawPoolWater(); /*virtual*/ ~LLDrawPoolWater(); - static void restoreGL(); - - S32 getNumPostDeferredPasses() override; void beginPostDeferredPass(S32 pass) override; void renderPostDeferred(S32 pass) override; - S32 getNumDeferredPasses() override; - void renderDeferred(S32 pass = 0) override; - S32 getNumPasses() override; - void render(S32 pass = 0) override; void prerender() override; LLViewerTexture *getDebugTexture() override; LLColor3 getDebugColor() const; // For AGP debug display - void renderReflection(LLFace* face); - void renderWater(); - void setTransparentTextures(const LLUUID& transparentTextureId, const LLUUID& nextTransparentTextureId); void setOpaqueTexture(const LLUUID& opaqueTextureId); void setNormalMaps(const LLUUID& normalMapId, const LLUUID& nextNormalMapId); diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 878022a2c8..345fb81ada 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -192,7 +192,6 @@ void LLFace::destroy() if (isState(LLFace::PARTICLE)) { - LLVOPartGroup::freeVBSlot(getGeomIndex()/4); clearState(LLFace::PARTICLE); } @@ -539,6 +538,7 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) if (mDrawablep->isState(LLDrawable::RIGGED)) { +#if 0 // TODO -- there is no way this won't destroy our GL machine as implemented, rewrite it to not rely on software skinning LLVOVolume* volume = mDrawablep->getVOVolume(); if (volume) { @@ -562,12 +562,13 @@ void LLFace::renderSelected(LLViewerTexture *imagep, const LLColor4& color) glDisableClientState(GL_TEXTURE_COORD_ARRAY); } } +#endif } else { // cheaters sometimes prosper... // - mVertexBuffer->setBuffer(mVertexBuffer->getTypeMask()); + mVertexBuffer->setBuffer(); mVertexBuffer->draw(LLRender::TRIANGLES, mIndicesCount, mIndicesIndex); } @@ -654,54 +655,8 @@ void LLFace::renderOneWireframe(const LLColor4 &color, F32 fogCfx, bool wirefram } } -/* removed in lieu of raycast uv detection -void LLFace::renderSelectedUV() -{ - LLViewerTexture* red_blue_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test1.j2c", TRUE, LLGLTexture::BOOST_UI); - LLViewerTexture* green_imagep = LLViewerTextureManager::getFetchedTextureFromFile("uv_test2.tga", TRUE, LLGLTexture::BOOST_UI); - - LLGLSUVSelect object_select; - - // use red/blue gradient to get coarse UV coordinates - renderSelected(red_blue_imagep, LLColor4::white); - - static F32 bias = 0.f; - static F32 factor = -10.f; - glPolygonOffset(factor, bias); - - // add green dither pattern on top of red/blue gradient - gGL.blendFunc(LLRender::BF_ONE, LLRender::BF_ONE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.pushMatrix(); - // make green pattern repeat once per texel in red/blue texture - gGL.scalef(256.f, 256.f, 1.f); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - renderSelected(green_imagep, LLColor4::white); - - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.popMatrix(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - gGL.blendFunc(LLRender::BF_SOURCE_ALPHA, LLRender::BF_ONE_MINUS_SOURCE_ALPHA); -} -*/ - void LLFace::setDrawInfo(LLDrawInfo* draw_info) { - if (draw_info) - { - if (draw_info->mFace) - { - draw_info->mFace->setDrawInfo(NULL); - } - draw_info->mFace = this; - } - - if (mDrawInfo) - { - mDrawInfo->mFace = NULL; - } - mDrawInfo = draw_info; } @@ -1225,10 +1180,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, updateRebuildFlags(); } - - //don't use map range (generates many redundant unmap calls) - bool map_range = false; - if (mVertexBuffer.notNull()) { if (num_indices + (S32) mIndicesIndex > mVertexBuffer->getNumIndices()) @@ -1355,7 +1306,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, if (full_rebuild) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - indices"); - mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount, map_range); + mVertexBuffer->getIndexStrider(indicesp, mIndicesIndex, mIndicesCount); volatile __m128i* dst = (__m128i*) indicesp.get(); __m128i* src = (__m128i*) vf.mIndices; @@ -1378,11 +1329,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, *idx++ = vf.mIndices[i]+index_offset; } } - - if (map_range) - { - mVertexBuffer->flush(); - } } F32 r = 0, os = 0, ot = 0, ms = 0, mt = 0, cos_ang = 0, sin_ang = 0; @@ -1694,11 +1640,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } } - - if (map_range) - { - mVertexBuffer->flush(); - } } else { //bump mapped or has material, just do the whole expensive loop @@ -1718,12 +1659,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, switch (ch) { case 0: - mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTexCoord0Strider(dst, mGeomIndex, mGeomCount); break; case 1: if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD1)) { - mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTexCoord1Strider(dst, mGeomIndex, mGeomCount); if (mat && !tex_anim) { r = mat->getNormalRotation(); @@ -1743,7 +1684,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, case 2: if (mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_TEXCOORD2)) { - mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTexCoord2Strider(dst, mGeomIndex, mGeomCount); if (mat && !tex_anim) { r = mat->getSpecularRotation(); @@ -1802,14 +1743,9 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, } } - if (map_range) - { - mVertexBuffer->flush(); - } - if ((!mat && !gltf_mat) && do_bump) { - mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTexCoord1Strider(tex_coords1, mGeomIndex, mGeomCount); mVObjp->getVolume()->genTangents(f); @@ -1844,11 +1780,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, *tex_coords1++ = tc; } - - if (map_range) - { - mVertexBuffer->flush(); - } } } } @@ -1864,7 +1795,7 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, llassert(num_vertices > 0); - mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getVertexStrider(vert, mGeomIndex, mGeomCount); F32* dst = (F32*) vert.get(); @@ -1910,18 +1841,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, res0.store4a((F32*) dst); dst += 4; } - - if (map_range) - { - mVertexBuffer->flush(); - } } if (rebuild_normal) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - normal"); - mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getNormalStrider(norm, mGeomIndex, mGeomCount); F32* normals = (F32*) norm.get(); LLVector4a* src = vf.mNormals; LLVector4a* end = src+num_vertices; @@ -1933,17 +1859,12 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, normal.store4a(normals); normals += 4; } - - if (map_range) - { - mVertexBuffer->flush(); - } } if (rebuild_tangent) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - tangent"); - mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getTangentStrider(tangent, mGeomIndex, mGeomCount); F32* tangents = (F32*) tangent.get(); mVObjp->getVolume()->genTangents(f); @@ -1965,29 +1886,20 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, src++; tangents += 4; } - - if (map_range) - { - mVertexBuffer->flush(); - } } if (rebuild_weights && vf.mWeights) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - weight"); - mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getWeight4Strider(wght, mGeomIndex, mGeomCount); F32* weights = (F32*) wght.get(); LLVector4a::memcpyNonAliased16(weights, (F32*) vf.mWeights, num_vertices*4*sizeof(F32)); - if (map_range) - { - mVertexBuffer->flush(); - } } if (rebuild_color && mVertexBuffer->hasDataType(LLVertexBuffer::TYPE_COLOR) ) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - color"); - mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getColorStrider(colors, mGeomIndex, mGeomCount); LLVector4a src; @@ -2008,18 +1920,13 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, src.store4a(dst); dst += 4; } - - if (map_range) - { - mVertexBuffer->flush(); - } } if (rebuild_emissive) { LL_PROFILE_ZONE_NAMED_CATEGORY_FACE("getGeometryVolume - emissive"); LLStrider emissive; - mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount, map_range); + mVertexBuffer->getEmissiveStrider(emissive, mGeomIndex, mGeomCount); U8 glow = (U8) llclamp((S32) (getTextureEntry()->getGlow()*255), 0, 255); @@ -2047,11 +1954,6 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, src.store4a(dst); dst += 4; } - - if (map_range) - { - mVertexBuffer->flush(); - } } } @@ -2074,6 +1976,15 @@ BOOL LLFace::getGeometryVolume(const LLVolume& volume, return TRUE; } +void LLFace::renderIndexed() +{ + if (mVertexBuffer.notNull()) + { + mVertexBuffer->setBuffer(); + mVertexBuffer->drawRange(LLRender::TRIANGLES, getGeomIndex(), getGeomIndex() + getGeomCount()-1, getIndicesCount(), getIndicesStart()); + } +} + //check if the face has a media BOOL LLFace::hasMedia() const { @@ -2405,92 +2316,12 @@ void LLFace::setViewerObject(LLViewerObject* objp) mVObjp = objp; } -const LLColor4& LLFace::getRenderColor() const -{ - if (isState(USE_FACE_COLOR)) - { - return mFaceColor; // Face Color - } - else - { - const LLTextureEntry* tep = getTextureEntry(); - return (tep ? tep->getColor() : LLColor4::white); - } -} - -void LLFace::renderSetColor() const -{ - if (!LLFacePool::LLOverrideFaceColor::sOverrideFaceColor) - { - const LLColor4* color = &(getRenderColor()); - - gGL.diffuseColor4fv(color->mV); - } -} - -S32 LLFace::pushVertices(const U16* index_array) const -{ - if (mIndicesCount) - { - mVertexBuffer->drawRange(LLRender::TRIANGLES, mGeomIndex, mGeomIndex+mGeomCount-1, mIndicesCount, mIndicesIndex); - gPipeline.addTrianglesDrawn(mIndicesCount); - } - - return mIndicesCount; -} const LLMatrix4& LLFace::getRenderMatrix() const { return mDrawablep->getRenderMatrix(); } -S32 LLFace::renderElements(const U16 *index_array) const -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - S32 ret = 0; - - if (isState(GLOBAL)) - { - ret = pushVertices(index_array); - } - else - { - gGL.pushMatrix(); - gGL.multMatrix((float*)getRenderMatrix().mMatrix); - ret = pushVertices(index_array); - gGL.popMatrix(); - } - - return ret; -} - -S32 LLFace::renderIndexed() -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - if(mDrawablep == NULL || mDrawPoolp == NULL) - { - return 0; - } - - return renderIndexed(mDrawPoolp->getVertexDataMask()); -} - -S32 LLFace::renderIndexed(U32 mask) -{ - LL_PROFILE_ZONE_SCOPED_CATEGORY_FACE - - if (mVertexBuffer.isNull()) - { - return 0; - } - - mVertexBuffer->setBuffer(mask); - U16* index_array = (U16*) mVertexBuffer->getIndicesPointer(); - return renderElements(index_array); -} - //============================================================================ // From llface.inl diff --git a/indra/newview/llface.h b/indra/newview/llface.h index 0cb986b8ed..ee8316018b 100644 --- a/indra/newview/llface.h +++ b/indra/newview/llface.h @@ -125,12 +125,6 @@ public: S32 getIndexInTex(U32 ch) const {llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); return mIndexInTex[ch];} void setIndexInTex(U32 ch, S32 index) { llassert(ch < LLRender::NUM_TEXTURE_CHANNELS); mIndexInTex[ch] = index ;} - - void renderSetColor() const; - S32 renderElements(const U16 *index_array) const; - S32 renderIndexed (); - S32 renderIndexed (U32 mask); - S32 pushVertices(const U16* index_array) const; void setWorldMatrix(const LLMatrix4& mat); const LLTextureEntry* getTextureEntry() const { return mVObjp->getTE(mTEOffset); } @@ -151,11 +145,12 @@ public: void setDrawable(LLDrawable *drawable); void setTEOffset(const S32 te_offset); + void renderIndexed(); void setFaceColor(const LLColor4& color); // override material color void unsetFaceColor(); // switch back to material color const LLColor4& getFaceColor() const { return mFaceColor; } - const LLColor4& getRenderColor() const; + //for volumes void updateRebuildFlags(); diff --git a/indra/newview/llflexibleobject.cpp b/indra/newview/llflexibleobject.cpp index d5115df35f..500e3cc41b 100644 --- a/indra/newview/llflexibleobject.cpp +++ b/indra/newview/llflexibleobject.cpp @@ -399,6 +399,7 @@ void LLVolumeImplFlexible::doIdleUpdate() updateRenderRes(); + mVO->shrinkWrap(); gPipeline.markRebuild(drawablep, LLDrawable::REBUILD_POSITION, FALSE); } } diff --git a/indra/newview/llfloaterimagepreview.cpp b/indra/newview/llfloaterimagepreview.cpp index 89ba687d25..b2be6a925e 100644 --- a/indra/newview/llfloaterimagepreview.cpp +++ b/indra/newview/llfloaterimagepreview.cpp @@ -797,8 +797,8 @@ void LLImagePreviewSculpted::setPreviewTarget(LLImageRaw* imagep, F32 distance) U32 num_indices = vf.mNumIndices; U32 num_vertices = vf.mNumVertices; - mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0, 0); - if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices, TRUE)) + mVertexBuffer = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + if (!mVertexBuffer->allocateBuffer(num_vertices, num_indices)) { LL_WARNS() << "Failed to allocate Vertex Buffer for image preview to" << num_vertices << " vertices and " @@ -906,7 +906,7 @@ BOOL LLImagePreviewSculpted::render() const F32 BRIGHTNESS = 0.9f; gGL.diffuseColor3f(BRIGHTNESS, BRIGHTNESS, BRIGHTNESS); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0); + mVertexBuffer->setBuffer(); mVertexBuffer->draw(LLRender::TRIANGLES, num_indices, 0); gGL.popMatrix(); diff --git a/indra/newview/llglsandbox.cpp b/indra/newview/llglsandbox.cpp index 78dba81d9a..fe7c1c8f2c 100644 --- a/indra/newview/llglsandbox.cpp +++ b/indra/newview/llglsandbox.cpp @@ -1083,9 +1083,9 @@ F32 gpu_benchmark() delete [] pixels; //make a dummy triangle to draw with - LLPointer buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STREAM_DRAW); + LLPointer buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX); - if (!buff->allocateBuffer(3, 0, true)) + if (!buff->allocateBuffer(3, 0)) { LL_WARNS("Benchmark") << "Failed to allocate buffer during benchmark." << LL_ENDL; // abandon the benchmark test @@ -1109,12 +1109,12 @@ F32 gpu_benchmark() v[1].set(-1, -3, 0); v[2].set(3, 1, 0); - buff->flush(); + buff->unmapBuffer(); // ensure matched pair of bind() and unbind() calls ShaderBinder binder(gBenchmarkProgram); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + buff->setBuffer(); glFinish(); F32 time_passed = 0; // seconds diff --git a/indra/newview/llhudobject.cpp b/indra/newview/llhudobject.cpp index fe6793ce73..292045f25d 100644 --- a/indra/newview/llhudobject.cpp +++ b/indra/newview/llhudobject.cpp @@ -269,9 +269,9 @@ void LLHUDObject::renderAll() { LLGLSUIDefault gls_ui; + gUIProgram.bind(); gGL.color4f(1, 1, 1, 1); - gUIProgram.bind(); LLGLDepthTest depth(GL_FALSE, GL_FALSE); LLHUDObject *hud_objp; diff --git a/indra/newview/llhudtext.cpp b/indra/newview/llhudtext.cpp index 5544f33aea..22dca07096 100644 --- a/indra/newview/llhudtext.cpp +++ b/indra/newview/llhudtext.cpp @@ -573,7 +573,6 @@ void LLHUDText::markDead() void LLHUDText::renderAllHUD() { LLGLState::checkStates(); - LLGLState::checkTextureChannels(); { LLGLEnable color_mat(GL_COLOR_MATERIAL); @@ -590,7 +589,6 @@ void LLHUDText::renderAllHUD() LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); } void LLHUDText::shiftAll(const LLVector3& offset) diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 914528c7ce..df1a29d039 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -2788,9 +2788,9 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) mask |= LLVertexBuffer::MAP_WEIGHT4; } - vb = new LLVertexBuffer(mask, 0); + vb = new LLVertexBuffer(mask); - if (!vb->allocateBuffer(num_vertices, num_indices, TRUE)) + if (!vb->allocateBuffer(num_vertices, num_indices)) { // We are likely to crash due this failure, if this happens, find a way to gracefully stop preview std::ostringstream out; @@ -2861,7 +2861,7 @@ void LLModelPreview::genBuffers(S32 lod, bool include_skin_weights) *(index_strider++) = vf.mIndices[i]; } - vb->flush(); + vb->unmapBuffer(); mVertexBuffer[lod][mdl].push_back(vb); @@ -3055,11 +3055,11 @@ void LLModelPreview::addEmptyFace(LLModel* pTarget) { U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - LLPointer buff = new LLVertexBuffer(type_mask, 0); + LLPointer buff = new LLVertexBuffer(type_mask); - buff->allocateBuffer(1, 3, true); + buff->allocateBuffer(1, 3); memset((U8*)buff->getMappedData(), 0, buff->getSize()); - memset((U8*)buff->getIndicesPointer(), 0, buff->getIndicesSize()); + memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize()); buff->validateRange(0, buff->getNumVerts() - 1, buff->getNumIndices(), 0); @@ -3316,8 +3316,6 @@ BOOL LLModelPreview::render() gGL.pushMatrix(); gGL.color4fv(PREVIEW_EDGE_COL.mV); - const U32 type_mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_TEXCOORD0; - LLGLEnable normalize(GL_NORMALIZE); if (!mBaseModel.empty() && mVertexBuffer[5].empty()) @@ -3380,7 +3378,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[mPreviewLOD][model][i]; - buffer->setBuffer(type_mask & buffer->getTypeMask()); + buffer->setBuffer(); if (textures) { @@ -3417,7 +3415,7 @@ BOOL LLModelPreview::render() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); } - buffer->flush(); + buffer->unmapBuffer(); } gGL.popMatrix(); } @@ -3531,7 +3529,7 @@ BOOL LLModelPreview::render() gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); gGL.diffuseColor4fv(PREVIEW_PSYH_FILL_COL.mV); - buffer->setBuffer(type_mask & buffer->getTypeMask()); + buffer->setBuffer(); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts() - 1, buffer->getNumIndices(), 0); gGL.diffuseColor4fv(PREVIEW_PSYH_EDGE_COL.mV); @@ -3542,7 +3540,7 @@ BOOL LLModelPreview::render() glPolygonMode(GL_FRONT_AND_BACK, GL_FILL); glLineWidth(1.f); - buffer->flush(); + buffer->unmapBuffer(); } } } @@ -3592,7 +3590,7 @@ BOOL LLModelPreview::render() { LLVertexBuffer* buffer = mVertexBuffer[LLModel::LOD_PHYSICS][model][v]; - buffer->setBuffer(type_mask & buffer->getTypeMask()); + buffer->setBuffer(); LLStrider pos_strider; buffer->getVertexStrider(pos_strider, 0); @@ -3614,7 +3612,7 @@ BOOL LLModelPreview::render() } } - buffer->flush(); + buffer->unmapBuffer(); } } } @@ -3745,7 +3743,7 @@ BOOL LLModelPreview::render() const std::string& binding = instance.mModel->mMaterialList[i]; const LLImportMaterial& material = instance.mMaterial[binding]; - buffer->setBuffer(type_mask & buffer->getTypeMask()); + buffer->setBuffer(); gGL.diffuseColor4fv(material.mDiffuseColor.mV); gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index d9d6341617..b87406cb6e 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -513,7 +513,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) { //generate radiance map gRadianceGenProgram.bind(); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + mVertexBuffer->setBuffer(); S32 channel = gRadianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); @@ -563,7 +563,7 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) mTexture->bind(channel); gIrradianceGenProgram.uniform1i(sSourceIdx, targetIdx); - mVertexBuffer->setBuffer(LLVertexBuffer::MAP_VERTEX); + mVertexBuffer->setBuffer(); int start_mip = 0; // find the mip target to start with based on irradiance map resolution for (start_mip = 0; start_mip < mMipChain.size(); ++start_mip) @@ -900,8 +900,8 @@ void LLReflectionMapManager::initReflectionMaps() if (mVertexBuffer.isNull()) { U32 mask = LLVertexBuffer::MAP_VERTEX; - LLPointer buff = new LLVertexBuffer(mask, GL_STATIC_DRAW); - buff->allocateBuffer(4, 0, TRUE); + LLPointer buff = new LLVertexBuffer(mask); + buff->allocateBuffer(4, 0); LLStrider v; @@ -912,7 +912,7 @@ void LLReflectionMapManager::initReflectionMaps() v[2] = LLVector3(-1, 1, -1); v[3] = LLVector3(1, 1, -1); - buff->flush(); + buff->unmapBuffer(); mVertexBuffer = buff; } diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index 7653913c2b..2f199cc8e7 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -59,12 +59,12 @@ extern bool gShiftFrame; static U32 sZombieGroups = 0; U32 LLSpatialGroup::sNodeCount = 0; -BOOL LLSpatialGroup::sNoDelete = FALSE; +bool LLSpatialGroup::sNoDelete = false; static F32 sLastMaxTexPriority = 1.f; static F32 sCurMaxTexPriority = 1.f; -BOOL LLSpatialPartition::sTeleportRequested = FALSE; +bool LLSpatialPartition::sTeleportRequested = false; //static counter for frame to switch LOD on @@ -309,14 +309,13 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) if (vertex_count > 0 && index_count > 0) { //create vertex buffer containing volume geometry for this node { - group->mBuilt = 1.f; - if (group->mVertexBuffer.isNull() || - !group->mVertexBuffer->isWriteable() || - (group->mBufferUsage != group->mVertexBuffer->getUsage() && LLVertexBuffer::sEnableVBOs)) + if (group->mVertexBuffer.isNull() || + group->mVertexBuffer->getNumVerts() != vertex_count || + group->mVertexBuffer->getNumVerts() != index_count) { - group->mVertexBuffer = createVertexBuffer(mVertexDataMask, group->mBufferUsage); - if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count, true)) + group->mVertexBuffer = new LLVertexBuffer(mVertexDataMask); + if (!group->mVertexBuffer->allocateBuffer(vertex_count, index_count)) { LL_WARNS() << "Failed to allocate Vertex Buffer on rebuild to " << vertex_count << " vertices and " @@ -325,18 +324,6 @@ void LLSpatialPartition::rebuildGeom(LLSpatialGroup* group) group->mBufferMap.clear(); } } - else - { - if (!group->mVertexBuffer->resizeBuffer(vertex_count, index_count)) - { - // Is likely to cause a crash. If this gets triggered find a way to avoid it (don't forget to reset face) - LL_WARNS() << "Failed to resize Vertex Buffer on rebuild to " - << vertex_count << " vertices and " - << index_count << " indices" << LL_ENDL; - group->mVertexBuffer = NULL; - group->mBufferMap.clear(); - } - } } if (group->mVertexBuffer) @@ -538,7 +525,6 @@ LLSpatialGroup::LLSpatialGroup(OctreeNode* node, LLSpatialPartition* part) : LLO mSurfaceArea(0.f), mBuilt(0.f), mVertexBuffer(NULL), - mBufferUsage(part->mBufferUsage), mDistance(0.f), mDepth(0.f), mLastUpdateDistance(-1.f), @@ -567,6 +553,7 @@ void LLSpatialGroup::updateDistance(LLCamera &camera) if (LLViewerCamera::sCurCameraID != LLViewerCamera::CAMERA_WORLD) { LL_WARNS() << "Attempted to update distance for camera other than world camera!" << LL_ENDL; + llassert(false); return; } @@ -838,13 +825,12 @@ void LLSpatialGroup::destroyGL(bool keep_occlusion) //============================================== -LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 buffer_usage, LLViewerRegion* regionp) +LLSpatialPartition::LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp) : mRenderByGroup(render_by_group), mBridge(NULL) { mRegionp = regionp; mPartitionType = LLViewerRegion::PARTITION_NONE; mVertexDataMask = data_mask; - mBufferUsage = buffer_usage; mDepthMask = FALSE; mSlopRatio = 0.25f; mInfiniteFarClip = FALSE; @@ -1437,15 +1423,15 @@ S32 LLSpatialPartition::cull(LLCamera &camera, bool do_occlusion) return 0; } -void pushVerts(LLDrawInfo* params, U32 mask) +void pushVerts(LLDrawInfo* params) { LLRenderPass::applyModelMatrix(*params); - params->mVertexBuffer->setBuffer(mask); - params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES, + params->mVertexBuffer->setBuffer(); + params->mVertexBuffer->drawRange(LLRender::TRIANGLES, params->mStart, params->mEnd, params->mCount, params->mOffset); } -void pushVerts(LLSpatialGroup* group, U32 mask) +void pushVerts(LLSpatialGroup* group) { LLDrawInfo* params = NULL; @@ -1454,36 +1440,25 @@ void pushVerts(LLSpatialGroup* group, U32 mask) for (LLSpatialGroup::drawmap_elem_t::iterator j = i->second.begin(); j != i->second.end(); ++j) { params = *j; - pushVerts(params, mask); + pushVerts(params); } } } -void pushVerts(LLFace* face, U32 mask) +void pushVerts(LLFace* face) { if (face) { llassert(face->verify()); - - LLVertexBuffer* buffer = face->getVertexBuffer(); - - if (buffer && (face->getGeomCount() >= 3)) - { - buffer->setBuffer(mask); - U16 start = face->getGeomStart(); - U16 end = start + face->getGeomCount()-1; - U32 count = face->getIndicesCount(); - U16 offset = face->getIndicesStart(); - buffer->drawRange(LLRender::TRIANGLES, start, end, count, offset); - } + face->renderIndexed(); } } -void pushVerts(LLDrawable* drawable, U32 mask) +void pushVerts(LLDrawable* drawable) { for (S32 i = 0; i < drawable->getNumFaces(); ++i) { - pushVerts(drawable->getFace(i), mask); + pushVerts(drawable->getFace(i)); } } @@ -1497,16 +1472,16 @@ void pushVerts(LLVolume* volume) } } -void pushBufferVerts(LLVertexBuffer* buffer, U32 mask) +void pushBufferVerts(LLVertexBuffer* buffer) { if (buffer) { - buffer->setBuffer(mask); + buffer->setBuffer(); buffer->drawRange(LLRender::TRIANGLES, 0, buffer->getNumVerts()-1, buffer->getNumIndices(), 0); } } -void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true) +void pushBufferVerts(LLSpatialGroup* group, bool push_alpha = true) { if (group->getSpatialPartition()->mRenderByGroup) { @@ -1517,7 +1492,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true) if (push_alpha) { - pushBufferVerts(group->mVertexBuffer, mask); + pushBufferVerts(group->mVertexBuffer); } for (LLSpatialGroup::buffer_map_t::iterator i = group->mBufferMap.begin(); i != group->mBufferMap.end(); ++i) @@ -1526,7 +1501,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true) { for (LLSpatialGroup::buffer_list_t::iterator k = j->second.begin(); k != j->second.end(); ++k) { - pushBufferVerts(*k, mask); + pushBufferVerts(*k); } } } @@ -1539,7 +1514,7 @@ void pushBufferVerts(LLSpatialGroup* group, U32 mask, bool push_alpha = true) }*/ } -void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) +void pushVertsColorCoded(LLSpatialGroup* group) { LLDrawInfo* params = NULL; @@ -1564,8 +1539,8 @@ void pushVertsColorCoded(LLSpatialGroup* group, U32 mask) params = *j; LLRenderPass::applyModelMatrix(*params); gGL.diffuseColor4f(colors[col].mV[0], colors[col].mV[1], colors[col].mV[2], 0.5f); - params->mVertexBuffer->setBuffer(mask); - params->mVertexBuffer->drawRange(params->mParticle ? LLRender::POINTS : LLRender::TRIANGLES, + params->mVertexBuffer->setBuffer(); + params->mVertexBuffer->drawRange(LLRender::TRIANGLES, params->mStart, params->mEnd, params->mCount, params->mOffset); col = (col+1)%col_count; } @@ -1637,17 +1612,8 @@ void renderOctree(LLSpatialGroup* group) if (group->mBuilt > 0.f) { group->mBuilt -= 2.f * gFrameIntervalSeconds.value(); - if (group->mBufferUsage == GL_STATIC_DRAW) - { - col.setVec(1.0f, 0, 0, group->mBuilt*0.5f); - } - else - { - col.setVec(0.1f,0.1f,1,0.1f); - //col.setVec(1.0f, 1.0f, 0, sinf(group->mBuilt*3.14159f)*0.5f); - } - - if (group->mBufferUsage != GL_STATIC_DRAW) + col.setVec(0.1f,0.1f,1,0.1f); + { LLGLDepthTest gl_depth(FALSE, FALSE); glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -1708,20 +1674,36 @@ void renderOctree(LLSpatialGroup* group) LLFace* face = drawable->getFace(j); if (face && face->getVertexBuffer()) { - if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) - { - gGL.diffuseColor4f(0, 1, 0, group->mBuilt); - } - else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f) - { - gGL.diffuseColor4f(1, 0, 0, group->mBuilt); - } - else - { - continue; - } + LLVOVolume* vol = drawable->getVOVolume(); - face->getVertexBuffer()->setBuffer(LLVertexBuffer::MAP_VERTEX | (rigged ? LLVertexBuffer::MAP_WEIGHT4 : 0)); + if (gFrameTimeSeconds - face->mLastUpdateTime < 0.5f) + { + if (vol && vol->isShrinkWrapped()) + { + gGL.diffuseColor4f(0, 1, 1, group->mBuilt); + } + else + { + gGL.diffuseColor4f(0, 1, 0, group->mBuilt); + } + } + else if (gFrameTimeSeconds - face->mLastMoveTime < 0.5f) + { + if (vol && vol->isShrinkWrapped()) + { + gGL.diffuseColor4f(1, 1, 0, group->mBuilt); + } + else + { + gGL.diffuseColor4f(1, 0, 0, group->mBuilt); + } + } + else + { + continue; + } + + face->getVertexBuffer()->setBuffer(); //drawBox((face->mExtents[0] + face->mExtents[1])*0.5f, // (face->mExtents[1]-face->mExtents[0])*0.5f); face->getVertexBuffer()->draw(LLRender::TRIANGLES, face->getIndicesCount(), face->getIndicesStart()); @@ -1743,18 +1725,6 @@ void renderOctree(LLSpatialGroup* group) gGL.diffuseColor4f(1,1,1,1); } } - else - { - if (group->mBufferUsage == GL_STATIC_DRAW && !group->isEmpty() - && group->getSpatialPartition()->mRenderByGroup) - { - col.setVec(0.8f, 0.4f, 0.1f, 0.1f); - } - else - { - col.setVec(0.1f, 0.1f, 1.f, 0.1f); - } - } gGL.diffuseColor4fv(col.mV); LLVector4a fudge; @@ -1907,7 +1877,7 @@ void renderXRay(LLSpatialGroup* group, LLCamera* camera) if (render_objects) { - pushBufferVerts(group, LLVertexBuffer::MAP_VERTEX, false); + pushBufferVerts(group, false); bool selected = false; @@ -1989,7 +1959,7 @@ void renderUpdateType(LLDrawable* drawablep) { for (S32 i = 0; i < num_faces; ++i) { - pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + pushVerts(drawablep->getFace(i)); } } } @@ -2080,7 +2050,7 @@ void renderComplexityDisplay(LLDrawable* drawablep) { for (S32 i = 0; i < num_faces; ++i) { - pushVerts(drawablep->getFace(i), LLVertexBuffer::MAP_VERTEX); + pushVerts(drawablep->getFace(i)); } } LLViewerObject::const_child_list_t children = voVol->getChildren(); @@ -2094,7 +2064,7 @@ void renderComplexityDisplay(LLDrawable* drawablep) { for (S32 i = 0; i < num_faces; ++i) { - pushVerts(child->mDrawable->getFace(i), LLVertexBuffer::MAP_VERTEX); + pushVerts(child->mDrawable->getFace(i)); } } } @@ -2736,7 +2706,7 @@ void renderPhysicsShapes(LLSpatialGroup* group, bool wireframe) { glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); - buff->setBuffer(LLVertexBuffer::MAP_VERTEX); + buff->setBuffer(); gGL.diffuseColor4f(0.2f, 0.5f, 0.3f, 0.5f); buff->draw(LLRender::TRIANGLES, buff->getNumIndices(), 0); @@ -2842,7 +2812,7 @@ void renderTextureAnim(LLDrawInfo* params) LLGLEnable blend(GL_BLEND); gGL.diffuseColor4f(1,1,0,0.5f); - pushVerts(params, LLVertexBuffer::MAP_VERTEX); + pushVerts(params); } void renderBatchSize(LLDrawInfo* params) @@ -2850,7 +2820,6 @@ void renderBatchSize(LLDrawInfo* params) LLGLEnable offset(GL_POLYGON_OFFSET_FILL); glPolygonOffset(-1.f, 1.f); LLGLSLShader* old_shader = LLGLSLShader::sCurBoundShaderPtr; - U32 mask = LLVertexBuffer::MAP_VERTEX; bool bind = false; if (params->mAvatar) { @@ -2859,11 +2828,11 @@ void renderBatchSize(LLDrawInfo* params) bind = true; old_shader->mRiggedVariant->bind(); LLRenderPass::uploadMatrixPalette(*params); - mask |= LLVertexBuffer::MAP_WEIGHT4; } - gGL.diffuseColor4ubv((GLubyte*)&(params->mDebugColor)); - pushVerts(params, mask); + + gGL.diffuseColor4ubv(params->getDebugColor().mV); + pushVerts(params); if (bind) { @@ -2919,7 +2888,7 @@ void renderTexelDensity(LLDrawable* drawable) if (buffer && (facep->getGeomCount() >= 3)) { - buffer->setBuffer(LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0); + buffer->setBuffer(); U16 start = facep->getGeomStart(); U16 end = start + facep->getGeomCount()-1; U32 count = facep->getIndicesCount(); @@ -2994,7 +2963,7 @@ void renderLights(LLDrawable* drawablep) LLFace * face = drawablep->getFace(i); if (face) { - pushVerts(face, LLVertexBuffer::MAP_VERTEX); + pushVerts(face); } } @@ -3967,58 +3936,46 @@ LLDrawable* LLSpatialGroup::lineSegmentIntersect(const LLVector4a& start, const LLDrawInfo::LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, LLViewerTexture* texture, LLVertexBuffer* buffer, - bool selected, - BOOL fullbright, U8 bump, BOOL particle, F32 part_size) + bool fullbright, U8 bump) : mVertexBuffer(buffer), mTexture(texture), - mTextureMatrix(NULL), - mModelMatrix(NULL), mStart(start), mEnd(end), mCount(count), mOffset(offset), mFullbright(fullbright), mBump(bump), - mParticle(particle), - mPartSize(part_size), - mVSize(0.f), - mGroup(NULL), - mFace(NULL), - mDistance(0.f), - mMaterial(NULL), - mShaderMask(0), - mSpecColor(1.0f, 1.0f, 1.0f, 0.5f), mBlendFuncSrc(LLRender::BF_SOURCE_ALPHA), mBlendFuncDst(LLRender::BF_ONE_MINUS_SOURCE_ALPHA), - mHasGlow(FALSE), + mHasGlow(false), mEnvIntensity(0.0f), - mAlphaMaskCutoff(0.5f), - mDiffuseAlphaMode(0) + mAlphaMaskCutoff(0.5f) { mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); - - mDebugColor = (rand() << 16) + rand(); - ((U8*)&mDebugColor)[3] = 200; } LLDrawInfo::~LLDrawInfo() { - /*if (LLSpatialGroup::sNoDelete) - { - LL_ERRS() << "LLDrawInfo deleted illegally!" << LL_ENDL; - }*/ - - if (mFace) - { - mFace->setDrawInfo(NULL); - } - if (gDebugGL) { gPipeline.checkReferences(this); } } +LLColor4U LLDrawInfo::getDebugColor() const +{ + LLColor4U color; + + LLCRC hash; + hash.update((U8*)this + sizeof(S32), sizeof(LLDrawInfo) - sizeof(S32)); + + *((U32*) color.mV) = hash.getCRC(); + + color.mV[3] = 200; + + return color; +} + void LLDrawInfo::validate() { mVertexBuffer->validateRange(mStart, mEnd, mCount, mOffset); @@ -4029,11 +3986,6 @@ U64 LLDrawInfo::getSkinHash() return mSkinInfo ? mSkinInfo->mHash : 0; } -LLVertexBuffer* LLGeometryManager::createVertexBuffer(U32 type_mask, U32 usage) -{ - return new LLVertexBuffer(type_mask, usage); -} - LLCullResult::LLCullResult() { mVisibleGroupsAllocated = 0; diff --git a/indra/newview/llspatialpartition.h b/indra/newview/llspatialpartition.h index b765bd1632..bc0eabfa0e 100644 --- a/indra/newview/llspatialpartition.h +++ b/indra/newview/llspatialpartition.h @@ -56,9 +56,15 @@ class LLSpatialGroup; class LLViewerRegion; class LLReflectionMap; -void pushVerts(LLFace* face, U32 mask); +void pushVerts(LLFace* face); -class LLDrawInfo : public LLRefCount +/* + Class that represents a single Draw Call + + Make every effort to keep size minimal. + Member ordering is important for cache coherency +*/ +class LLDrawInfo final : public LLRefCount { LL_ALIGN_NEW; protected: @@ -75,11 +81,13 @@ public: LL_ERRS() << "Illegal operation!" << LL_ENDL; return *this; } + + // return a hash of this LLDrawInfo as a debug color + LLColor4U getDebugColor() const; LLDrawInfo(U16 start, U16 end, U32 count, U32 offset, - LLViewerTexture* image, LLVertexBuffer* buffer, - bool selected, - BOOL fullbright = FALSE, U8 bump = 0, BOOL particle = FALSE, F32 part_size = 0); + LLViewerTexture* image, LLVertexBuffer* buffer, + bool fullbright = false, U8 bump = 0); void validate(); @@ -88,54 +96,46 @@ public: U64 getSkinHash(); LLPointer mVertexBuffer; + U16 mStart = 0; + U16 mEnd = 0; + U32 mCount = 0; + U32 mOffset = 0; + LLPointer mTexture; - std::vector > mTextureList; + LLPointer mSpecularMap; + LLPointer mNormalMap; - // virtual size of mTexture and mTextureList textures - // used to update the decode priority of textures in this DrawInfo - std::vector mTextureListVSize; - - const LLMatrix4* mTextureMatrix; - const LLMatrix4* mModelMatrix; - U16 mStart; - U16 mEnd; - U32 mCount; - U32 mOffset; - BOOL mFullbright; - U8 mBump; - U8 mShiny; - U8 mTextureTimer = 1; - BOOL mParticle; - F32 mPartSize; - F32 mVSize; - LLSpatialGroup* mGroup; - LL_ALIGN_16(LLFace* mFace); //associated face - F32 mDistance; - S32 mDebugColor; + const LLMatrix4* mSpecularMapMatrix = nullptr; + const LLMatrix4* mNormalMapMatrix = nullptr; + const LLMatrix4* mTextureMatrix = nullptr; + const LLMatrix4* mModelMatrix = nullptr; + + LLPointer mAvatar = nullptr; + LLMeshSkinInfo* mSkinInfo = nullptr; // Material pointer here is likely for debugging only and are immaterial (zing!) - LLMaterialPtr mMaterial; - + LLPointer mMaterial; + // PBR material parameters LLPointer mGLTFMaterial; - + + LLVector4 mSpecColor = LLVector4(1.f, 1.f, 1.f, 0.5f); // XYZ = Specular RGB, W = Specular Exponent + + std::vector > mTextureList; + LLUUID mMaterialID; // id of LLGLTFMaterial or LLMaterial applied to this draw info - U32 mShaderMask; - U32 mBlendFuncSrc; - U32 mBlendFuncDst; - BOOL mHasGlow; - LLPointer mSpecularMap; - const LLMatrix4* mSpecularMapMatrix; - LLPointer mNormalMap; - const LLMatrix4* mNormalMapMatrix; - - LLVector4 mSpecColor; // XYZ = Specular RGB, W = Specular Exponent - F32 mEnvIntensity; - F32 mAlphaMaskCutoff; - U8 mDiffuseAlphaMode; - LLPointer mAvatar = nullptr; - LLMeshSkinInfo* mSkinInfo = nullptr; + U32 mShaderMask = 0; + F32 mEnvIntensity = 0.f; + F32 mAlphaMaskCutoff = 0.5f; + + LLRender::eBlendFactor mBlendFuncSrc = LLRender::BF_SOURCE_ALPHA; + LLRender::eBlendFactor mBlendFuncDst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + U8 mDiffuseAlphaMode = 0; + U8 mBump = 0; + U8 mShiny = 0; + bool mFullbright = false; + bool mHasGlow = false; struct CompareTexture { @@ -196,19 +196,9 @@ public: && (lhs.isNull() || (rhs.notNull() && lhs->mBump > rhs->mBump)); } }; - - struct CompareDistanceGreater - { - bool operator()(const LLPointer& lhs, const LLPointer& rhs) - { - // sort by mBump value, sort NULL down to the end - return lhs.get() != rhs.get() - && (lhs.isNull() || (rhs.notNull() && lhs->mDistance > rhs->mDistance)); - } - }; }; -LL_ALIGN_PREFIX(64) +LL_ALIGN_PREFIX(16) class LLSpatialGroup : public LLOcclusionCullingGroup { friend class LLSpatialPartition; @@ -227,7 +217,7 @@ public: } static U32 sNodeCount; - static BOOL sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE + static bool sNoDelete; //deletion of spatial groups and draw info not allowed if TRUE typedef std::vector > sg_vector_t; typedef std::vector > bridge_list_t; @@ -343,25 +333,21 @@ public: LL_ALIGN_16(LLVector4a mViewAngle); LL_ALIGN_16(LLVector4a mLastUpdateViewAngle); - F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() - protected: virtual ~LLSpatialGroup(); public: + LLPointer mVertexBuffer; + draw_map_t mDrawMap; + bridge_list_t mBridgeList; buffer_map_t mBufferMap; //used by volume buffers to attempt to reuse vertex buffers + F32 mObjectBoxSize; //cached mObjectBounds[1].getLength3() U32 mGeometryBytes; //used by volumes to track how many bytes of geometry data are in this node F32 mSurfaceArea; //used by volumes to track estimated surface area of geometry in this node - F32 mBuilt; - LLPointer mVertexBuffer; - - U32 mBufferUsage; - draw_map_t mDrawMap; - F32 mDistance; F32 mDepth; F32 mLastUpdateDistance; @@ -375,8 +361,7 @@ public: U32 mRenderOrder = 0; // Reflection Probe associated with this node (if any) LLPointer mReflectionProbe = nullptr; - -} LL_ALIGN_POSTFIX(64); +} LL_ALIGN_POSTFIX(16); class LLGeometryManager { @@ -387,14 +372,12 @@ public: virtual void rebuildMesh(LLSpatialGroup* group) = 0; virtual void getGeometry(LLSpatialGroup* group) = 0; virtual void addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count); - - virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; class LLSpatialPartition: public LLViewerOctreePartition, public LLGeometryManager { public: - LLSpatialPartition(U32 data_mask, BOOL render_by_group, U32 mBufferUsage, LLViewerRegion* regionp); + LLSpatialPartition(U32 data_mask, BOOL render_by_group, LLViewerRegion* regionp); virtual ~LLSpatialPartition(); LLSpatialGroup *put(LLDrawable *drawablep, BOOL was_visible = FALSE); @@ -445,14 +428,13 @@ public: // use a pointer instead of making "isBridge" and "asBridge" virtual so it's safe // to call asBridge() from the destructor - BOOL mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane - U32 mBufferUsage; - const BOOL mRenderByGroup; + bool mInfiniteFarClip; // if TRUE, frustum culling ignores far clip plane + const bool mRenderByGroup; U32 mVertexDataMask; F32 mSlopRatio; //percentage distance must change before drawables receive LOD update (default is 0.25); - BOOL mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering + bool mDepthMask; //if TRUE, objects in this partition will be written to depth during alpha rendering - static BOOL sTeleportRequested; //started to issue a teleport request + static bool sTeleportRequested; //started to issue a teleport request }; // class for creating bridges between spatial partitions @@ -631,7 +613,6 @@ class LLTerrainPartition : public LLSpatialPartition public: LLTerrainPartition(LLViewerRegion* regionp); virtual void getGeometry(LLSpatialGroup* group); - virtual LLVertexBuffer* createVertexBuffer(U32 type_mask, U32 usage); }; //spatial partition for trees diff --git a/indra/newview/llsprite.cpp b/indra/newview/llsprite.cpp index 0cdad86a76..b641afc1ef 100644 --- a/indra/newview/llsprite.cpp +++ b/indra/newview/llsprite.cpp @@ -189,9 +189,8 @@ void LLSprite::updateFace(LLFace &face) if (!face.getVertexBuffer()) { LLVertexBuffer* buff = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0, - GL_STREAM_DRAW); - buff->allocateBuffer(4, 12, TRUE); + LLVertexBuffer::MAP_TEXCOORD0 ); + buff->allocateBuffer(4, 12); face.setGeomIndex(0); face.setIndicesIndex(0); face.setVertexBuffer(buff); @@ -243,7 +242,7 @@ void LLSprite::updateFace(LLFace &face) *indicesp++ = 3 + index_offset; } - face.getVertexBuffer()->flush(); + face.getVertexBuffer()->unmapBuffer(); face.mCenterAgent = mPosition; } diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 76b7347b21..0019038c76 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -1559,12 +1559,10 @@ bool idle_startup() LL_DEBUGS("AppInit") << "Initializing sky..." << LL_ENDL; // Initialize all of the viewer object classes for the first time (doing things like texture fetches. LLGLState::checkStates(); - LLGLState::checkTextureChannels(); gSky.init(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); display_startup(); diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp index d1a89a5846..5af03477d6 100644 --- a/indra/newview/llviewerdisplay.cpp +++ b/indra/newview/llviewerdisplay.cpp @@ -148,7 +148,6 @@ void display_startup() static S32 frame_count = 0; LLGLState::checkStates(); - LLGLState::checkTextureChannels(); if (frame_count++ > 1) // make sure we have rendered a frame first { @@ -160,7 +159,6 @@ void display_startup() } LLGLState::checkStates(); - LLGLState::checkTextureChannels(); glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT); LLGLSUIDefault gls_ui; @@ -168,7 +166,6 @@ void display_startup() if (gViewerWindow) gViewerWindow->setup2DRender(); - gGL.color4f(1,1,1,1); if (gViewerWindow) gViewerWindow->draw(); gGL.flush(); @@ -176,7 +173,6 @@ void display_startup() LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); if (gViewerWindow && gViewerWindow->getWindow()) gViewerWindow->getWindow()->swapBuffers(); @@ -282,7 +278,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); stop_glerror(); @@ -324,7 +319,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLAppViewer::instance()->pingMainloopTimeout("Display:CheckStates"); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); ////////////////////////////////////////////////////////// // @@ -681,7 +675,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gDepthDirty = FALSE; LLGLState::checkStates(); - LLGLState::checkTextureChannels(); static LLCullResult result; LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; @@ -690,7 +683,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) stop_glerror(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); LLAppViewer::instance()->pingMainloopTimeout("Display:Swap"); @@ -706,7 +698,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) glClearColor(0,0,0,0); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); if (!for_snapshot) { @@ -719,7 +710,6 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); glh::matrix4f proj = get_current_projection(); glh::matrix4f mod = get_current_modelview(); @@ -736,10 +726,8 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) gViewerWindow->setup3DViewport(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - } - glClear(GL_DEPTH_BUFFER_BIT); // | GL_STENCIL_BUFFER_BIT); + glClear(GL_DEPTH_BUFFER_BIT); } ////////////////////////////////////// @@ -925,19 +913,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot) } gOcclusionProgram.unbind(); - } - - gGL.setColorMask(true, false); - if (LLPipeline::sRenderDeferred) - { - gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true); } - else - { - gPipeline.renderGeom(*LLViewerCamera::getInstance(), TRUE); - } + gGL.setColorMask(true, true); + gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance(), true); //store this frame's modelview matrix for use //when rendering next frame's occlusion queries @@ -1099,14 +1079,10 @@ void display_cube_face() } gPipeline.mRT->deferredScreen.clear(); - gGL.setColorMask(true, false); - LLViewerCamera::sCurCameraID = LLViewerCamera::CAMERA_WORLD; gPipeline.renderGeomDeferred(*LLViewerCamera::getInstance()); - gGL.setColorMask(true, true); - gPipeline.mRT->deferredScreen.flush(); gPipeline.renderDeferredLighting(); @@ -1340,9 +1316,12 @@ void render_ui(F32 zoom_factor, int subfield) } { + LLGLState::checkStates(); + // Render our post process prior to the HUD, UI, etc. gPipeline.renderPostProcess(); + LLGLState::checkStates(); // draw hud and 3D ui elements into screen render target so they'll be able to use // the depth buffer (avoids extra copy of depth buffer per frame) gPipeline.screenTarget()->bindTarget(); @@ -1354,6 +1333,7 @@ void render_ui(F32 zoom_factor, int subfield) // 3. Use transient zones LL_PROFILE_ZONE_NAMED_CATEGORY_UI("HUD"); //LL_RECORD_BLOCK_TIME(FTM_RENDER_HUD); render_hud_elements(); + LLGLState::checkStates(); render_hud_attachments(); LLGLState::checkStates(); @@ -1364,8 +1344,6 @@ void render_ui(F32 zoom_factor, int subfield) gPipeline.disableLights(); } - gGL.color4f(1,1,1,1); - bool render_ui = gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI); if (render_ui) { @@ -1507,6 +1485,7 @@ void render_ui_3d() stop_glerror(); gUIProgram.bind(); + gGL.color4f(1, 1, 1, 1); // Coordinate axes if (gSavedSettings.getBOOL("ShowAxes")) diff --git a/indra/newview/llviewerjointmesh.cpp b/indra/newview/llviewerjointmesh.cpp index f3b0e82b3a..be2a1da968 100644 --- a/indra/newview/llviewerjointmesh.cpp +++ b/indra/newview/llviewerjointmesh.cpp @@ -1,4 +1,4 @@ -/** + /** * @file llviewerjointmesh.cpp * @brief Implementation of LLViewerJointMesh class * @@ -62,10 +62,6 @@ extern PFNGLWEIGHTFVARBPROC glWeightfvARB; extern PFNGLVERTEXBLENDARBPROC glVertexBlendARB; #endif -static const U32 sRenderMask = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_NORMAL | - LLVertexBuffer::MAP_TEXCOORD0; - //----------------------------------------------------------------------------- //----------------------------------------------------------------------------- // LLViewerJointMesh @@ -287,8 +283,6 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) gGL.getTexUnit(diffuse_channel)->bind(LLViewerTextureManager::getFetchedTexture(IMG_DEFAULT)); } - U32 mask = sRenderMask; - U32 start = mMesh->mFaceVertexOffset; U32 end = start + mMesh->mFaceVertexCount - 1; U32 count = mMesh->mFaceIndexCount; @@ -304,14 +298,9 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) { uploadJointMatrices(); } - mask = mask | LLVertexBuffer::MAP_WEIGHT; - if (mFace->getPool()->getShaderLevel() > 1) - { - mask = mask | LLVertexBuffer::MAP_CLOTHWEIGHT; - } } - buff->setBuffer(mask); + buff->setBuffer(); buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); } else @@ -319,7 +308,7 @@ U32 LLViewerJointMesh::drawShape( F32 pixelArea, BOOL first_pass, BOOL is_dummy) gGL.pushMatrix(); LLMatrix4 jointToWorld = getWorldMatrix(); gGL.multMatrix((GLfloat*)jointToWorld.mMatrix); - buff->setBuffer(mask); + buff->setBuffer(); buff->drawRange(LLRender::TRIANGLES, start, end, count, offset); gGL.popMatrix(); } @@ -506,7 +495,7 @@ void LLViewerJointMesh::updateGeometry(LLFace *mFace, LLPolyMesh *mMesh) } } - buffer->flush(); + buffer->unmapBuffer(); } void LLViewerJointMesh::updateJointGeometry() diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 2bd0de4d6c..f416080f9e 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5477,6 +5477,7 @@ S32 LLViewerObject::setTERotation(const U8 te, const F32 r) if (mDrawable.notNull() && retval) { gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_TCOORD); + shrinkWrap(); } return retval; } @@ -6865,7 +6866,7 @@ F32 LLAlphaObject::getPartSize(S32 idx) return 0.f; } -void LLAlphaObject::getBlendFunc(S32 face, U32& src, U32& dst) +void LLAlphaObject::getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst) { } @@ -7278,6 +7279,18 @@ void LLViewerObject::setRenderMaterialIDs(const LLRenderMaterialParams* material } } +void LLViewerObject::shrinkWrap() +{ + if (!mShouldShrinkWrap) + { + mShouldShrinkWrap = true; + if (mDrawable) + { // we weren't shrink wrapped before but we are now, update the spatial partition + gPipeline.markPartitionMove(mDrawable); + } + } +} + class ObjectPhysicsProperties : public LLHTTPNode { public: diff --git a/indra/newview/llviewerobject.h b/indra/newview/llviewerobject.h index 71d7a7ebbb..fae29c3bc2 100644 --- a/indra/newview/llviewerobject.h +++ b/indra/newview/llviewerobject.h @@ -602,6 +602,14 @@ public: virtual void parameterChanged(U16 param_type, bool local_origin); virtual void parameterChanged(U16 param_type, LLNetworkData* data, BOOL in_use, bool local_origin); + bool isShrinkWrapped() const { return mShouldShrinkWrap; } + + // Used to improve performance. If an object is likely to rebuild its vertex buffer often + // as a side effect of some update (color update, scale, etc), setting this to true + // will cause it to be pushed deeper into the octree and isolate it from other nodes + // so that nearby objects won't attempt to share a vertex buffer with this object. + void shrinkWrap(); + friend class LLViewerObjectList; friend class LLViewerMediaList; @@ -866,6 +874,9 @@ protected: F32 mPhysicsCost; F32 mLinksetPhysicsCost; + // If true, "shrink wrap" this volume in its spatial partition. See "shrinkWrap" + bool mShouldShrinkWrap = false; + bool mCostStale; mutable bool mPhysicsShapeUnknown; @@ -978,7 +989,7 @@ public: LLStrider& emissivep, LLStrider& indicesp) = 0; - virtual void getBlendFunc(S32 face, U32& src, U32& dst); + virtual void getBlendFunc(S32 face, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst); F32 mDepth; }; diff --git a/indra/newview/llvieweroctree.cpp b/indra/newview/llvieweroctree.cpp index 1f16161780..7d6c18ae67 100644 --- a/indra/newview/llvieweroctree.cpp +++ b/indra/newview/llvieweroctree.cpp @@ -103,11 +103,11 @@ U8* get_box_fan_indices_ptr(LLCamera* camera, const LLVector4a& center) } //create a vertex buffer for efficiently rendering cubes -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) +LLVertexBuffer* ll_create_cube_vb(U32 type_mask) { - LLVertexBuffer* ret = new LLVertexBuffer(type_mask, usage); + LLVertexBuffer* ret = new LLVertexBuffer(type_mask); - ret->allocateBuffer(8, 64, true); + ret->allocateBuffer(8, 64); LLStrider pos; LLStrider idx; @@ -129,7 +129,7 @@ LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage) idx[i] = sOcclusionIndices[i]; } - ret->flush(); + ret->unmapBuffer(); return ret; } diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5d79c8e6b2..ebc6df22ac 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -192,7 +192,6 @@ LLGLSLShader gDeferredUnderWaterProgram; LLGLSLShader gDeferredDiffuseProgram; LLGLSLShader gDeferredDiffuseAlphaMaskProgram; LLGLSLShader gDeferredSkinnedDiffuseAlphaMaskProgram; -LLGLSLShader gDeferredNonIndexedDiffuseProgram; LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskProgram; LLGLSLShader gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram; LLGLSLShader gDeferredSkinnedDiffuseProgram; @@ -435,6 +434,7 @@ S32 LLViewerShaderMgr::getShaderLevel(S32 type) void LLViewerShaderMgr::setShaders() { + LL_PROFILE_ZONE_SCOPED; //setShaders might be called redundantly by gSavedSettings, so return on reentrance static bool reentrance = false; @@ -792,7 +792,6 @@ void LLViewerShaderMgr::unloadShaders() gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); - gDeferredNonIndexedDiffuseProgram.unload(); gDeferredSkinnedDiffuseProgram.unload(); gDeferredSkinnedBumpProgram.unload(); @@ -969,6 +968,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() BOOL LLViewerShaderMgr::loadShadersEnvironment() { + LL_PROFILE_ZONE_SCOPED; #if 1 // DEPRECATED -- forward rendering is deprecated BOOL success = TRUE; @@ -1039,6 +1039,7 @@ BOOL LLViewerShaderMgr::loadShadersEnvironment() BOOL LLViewerShaderMgr::loadShadersWater() { + LL_PROFILE_ZONE_SCOPED; #if 1 // DEPRECATED -- forward rendering is deprecated BOOL success = TRUE; BOOL terrainWaterSuccess = TRUE; @@ -1179,6 +1180,7 @@ BOOL LLViewerShaderMgr::loadShadersWater() BOOL LLViewerShaderMgr::loadShadersEffects() { + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; if (mShaderLevel[SHADER_EFFECT] == 0) @@ -1224,6 +1226,7 @@ BOOL LLViewerShaderMgr::loadShadersEffects() BOOL LLViewerShaderMgr::loadShadersDeferred() { + LL_PROFILE_ZONE_SCOPED; bool use_sun_shadow = mShaderLevel[SHADER_DEFERRED] > 1 && gSavedSettings.getS32("RenderShadowDetail") > 0; @@ -1237,14 +1240,13 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredTreeShadowProgram.unload(); gDeferredSkinnedTreeShadowProgram.unload(); gDeferredDiffuseProgram.unload(); + gDeferredSkinnedDiffuseProgram.unload(); gDeferredDiffuseAlphaMaskProgram.unload(); gDeferredSkinnedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskProgram.unload(); gDeferredNonIndexedDiffuseAlphaMaskNoColorProgram.unload(); - gDeferredNonIndexedDiffuseProgram.unload(); - gDeferredSkinnedDiffuseProgram.unload(); - gDeferredSkinnedBumpProgram.unload(); gDeferredBumpProgram.unload(); + gDeferredSkinnedBumpProgram.unload(); gDeferredImpostorProgram.unload(); gDeferredTerrainProgram.unload(); gDeferredTerrainWaterProgram.unload(); @@ -1410,19 +1412,6 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() llassert(success); } - if (success) - { - gDeferredNonIndexedDiffuseProgram.mName = "Non Indexed Deferred Diffuse Shader"; - gDeferredNonIndexedDiffuseProgram.mShaderFiles.clear(); - gDeferredNonIndexedDiffuseProgram.mFeatures.encodesNormal = true; - gDeferredNonIndexedDiffuseProgram.mFeatures.hasSrgb = true; - gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseV.glsl", GL_VERTEX_SHADER)); - gDeferredNonIndexedDiffuseProgram.mShaderFiles.push_back(make_pair("deferred/diffuseF.glsl", GL_FRAGMENT_SHADER)); - gDeferredNonIndexedDiffuseProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; - success = gDeferredNonIndexedDiffuseProgram.createShader(NULL, NULL); - llassert(success); - } - if (success) { gDeferredBumpProgram.mName = "Deferred Bump Shader"; @@ -2961,6 +2950,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() BOOL LLViewerShaderMgr::loadShadersObject() { + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; if (success) @@ -3487,6 +3477,7 @@ BOOL LLViewerShaderMgr::loadShadersObject() BOOL LLViewerShaderMgr::loadShadersAvatar() { + LL_PROFILE_ZONE_SCOPED; #if 1 // DEPRECATED -- forward rendering is deprecated BOOL success = TRUE; @@ -3585,6 +3576,7 @@ BOOL LLViewerShaderMgr::loadShadersAvatar() BOOL LLViewerShaderMgr::loadShadersInterface() { + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; if (success) @@ -3964,6 +3956,7 @@ BOOL LLViewerShaderMgr::loadShadersInterface() BOOL LLViewerShaderMgr::loadShadersWindLight() { + LL_PROFILE_ZONE_SCOPED; BOOL success = TRUE; #if 1 // DEPRECATED -- forward rendering is deprecated if (mShaderLevel[SHADER_WINDLIGHT] < 2) diff --git a/indra/newview/llviewertexture.cpp b/indra/newview/llviewertexture.cpp index c295bc76c0..721498572f 100644 --- a/indra/newview/llviewertexture.cpp +++ b/indra/newview/llviewertexture.cpp @@ -1018,7 +1018,7 @@ LLViewerFetchedTexture* LLViewerFetchedTexture::getSmokeImage() sSmokeImagep = LLViewerTextureManager::getFetchedTexture(IMG_SMOKE); } - gPipeline.touchTexture(sSmokeImagep, 1024.f * 1024.f); + sSmokeImagep->addTextureStats(1024.f * 1024.f); return sSmokeImagep; } diff --git a/indra/newview/llviewertexturelist.cpp b/indra/newview/llviewertexturelist.cpp index 1b9154a158..312bc31faa 100644 --- a/indra/newview/llviewertexturelist.cpp +++ b/indra/newview/llviewertexturelist.cpp @@ -861,6 +861,14 @@ void LLViewerTextureList::clearFetchingRequests() } } +static void touch_texture(LLViewerFetchedTexture* tex, F32 vsize) +{ + if (tex) + { + tex->addTextureStats(vsize); + } +} + void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imagep) { if (imagep->isInDebug() || imagep->isUnremovable()) @@ -869,6 +877,39 @@ void LLViewerTextureList::updateImageDecodePriority(LLViewerFetchedTexture* imag return; //is in debug, ignore. } + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE + { + for (U32 i = 0; i < LLRender::NUM_TEXTURE_CHANNELS; ++i) + { + for (U32 fi = 0; fi < imagep->getNumFaces(i); ++fi) + { + const LLFace* face = (*(imagep->getFaceList(i)))[fi]; + + if (face && face->getViewerObject() && face->getTextureEntry()) + { + F32 vsize = face->getVirtualSize(); + + // if a GLTF material is present, ignore that face + // as far as this texture stats go, but update the GLTF material + // stats + const LLTextureEntry* te = face->getTextureEntry(); + LLFetchedGLTFMaterial* mat = te ? (LLFetchedGLTFMaterial*)te->getGLTFRenderMaterial() : nullptr; + if (mat) + { + touch_texture(mat->mBaseColorTexture, vsize); + touch_texture(mat->mNormalTexture, vsize); + touch_texture(mat->mMetallicRoughnessTexture, vsize); + touch_texture(mat->mEmissiveTexture, vsize); + } + else + { + imagep->addTextureStats(vsize); + } + } + } + } + } + F32 lazy_flush_timeout = 30.f; // stop decoding F32 max_inactive_time = 20.f; // actually delete S32 min_refs = 3; // 1 for mImageList, 1 for mUUIDMap, 1 for local reference diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index 5848cbfd9d..bccb2a5e77 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -658,18 +658,6 @@ public: } - addText(xpos, ypos, llformat("%d Vertex Buffers", LLVertexBuffer::sGLCount)); - ypos += y_inc; - - addText(xpos, ypos, llformat("%d Mapped Buffers", LLVertexBuffer::sMappedCount)); - ypos += y_inc; - - addText(xpos, ypos, llformat("%d Vertex Buffer Binds", LLVertexBuffer::sBindCount)); - ypos += y_inc; - - addText(xpos, ypos, llformat("%d Vertex Buffer Sets", LLVertexBuffer::sSetCount)); - ypos += y_inc; - addText(xpos, ypos, llformat("%d Texture Binds", LLImageGL::sBindCount)); ypos += y_inc; @@ -744,9 +732,7 @@ public: ypos += y_inc; } - LLVertexBuffer::sBindCount = LLImageGL::sBindCount = - LLVertexBuffer::sSetCount = LLImageGL::sUniqueCount = - gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; + gPipeline.mNumVisibleNodes = LLPipeline::sVisibleLightCount = 0; } if (gSavedSettings.getBOOL("DebugShowAvatarRenderInfo")) { @@ -2641,10 +2627,10 @@ void LLViewerWindow::setMenuBackgroundColor(bool god_mode, bool dev_grid) void LLViewerWindow::drawDebugText() { + gUIProgram.bind(); gGL.color4f(1,1,1,1); gGL.pushMatrix(); gGL.pushUIMatrix(); - gUIProgram.bind(); { // scale view by UI global scale factor and aspect ratio correction factor gGL.scaleUI(mDisplayScale.mV[VX], mDisplayScale.mV[VY], 1.f); @@ -2701,6 +2687,7 @@ void LLViewerWindow::draw() // No translation needed, this view is glued to 0,0 gUIProgram.bind(); + gGL.color4f(1, 1, 1, 1); gGL.pushMatrix(); LLUI::pushMatrix(); @@ -5688,7 +5675,6 @@ void LLViewerWindow::restoreGL(const std::string& progress_message) gSky.restoreGL(); gPipeline.restoreGL(); - LLDrawPoolWater::restoreGL(); LLManipTranslate::restoreGL(); gBumpImageList.restoreGL(); diff --git a/indra/newview/llvoavatar.cpp b/indra/newview/llvoavatar.cpp index ee12019da2..05fac036fb 100644 --- a/indra/newview/llvoavatar.cpp +++ b/indra/newview/llvoavatar.cpp @@ -2348,15 +2348,15 @@ void LLVOAvatar::updateMeshData() LLVertexBuffer* buff = facep->getVertexBuffer(); if(!facep->getVertexBuffer()) { - buff = new LLVertexBufferAvatar(); - if (!buff->allocateBuffer(num_vertices, num_indices, TRUE)) + buff = new LLVertexBuffer(LLDrawPoolAvatar::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(num_vertices, num_indices)) { LL_WARNS() << "Failed to allocate Vertex Buffer for Mesh to " << num_vertices << " vertices and " << num_indices << " indices" << LL_ENDL; // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) facep->setSize(1, 3); - buff->allocateBuffer(1, 3, true); + buff->allocateBuffer(1, 3); memset((U8*) buff->getMappedData(), 0, buff->getSize()); memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); } @@ -2371,12 +2371,13 @@ void LLVOAvatar::updateMeshData() } else { - if (!buff->resizeBuffer(num_vertices, num_indices)) - { + buff = new LLVertexBuffer(buff->getTypeMask()); + if (!buff->allocateBuffer(num_vertices, num_indices)) + { LL_WARNS() << "Failed to allocate vertex buffer for Mesh, Substituting" << LL_ENDL; // Attempt to create a dummy triangle (one vertex, 3 indices, all 0) facep->setSize(1, 3); - buff->resizeBuffer(1, 3); + buff->allocateBuffer(1, 3); memset((U8*) buff->getMappedData(), 0, buff->getSize()); memset((U8*) buff->getMappedIndices(), 0, buff->getIndicesSize()); } @@ -2413,7 +2414,7 @@ void LLVOAvatar::updateMeshData() } stop_glerror(); - buff->flush(); + buff->unmapBuffer(); if(!f_num) { @@ -5039,7 +5040,7 @@ U32 LLVOAvatar::renderSkinned() LLVertexBuffer* vb = face->getVertexBuffer(); if (vb) { - vb->flush(); + vb->unmapBuffer(); } } } diff --git a/indra/newview/llvograss.cpp b/indra/newview/llvograss.cpp index b4b2db5d51..56faab92c5 100644 --- a/indra/newview/llvograss.cpp +++ b/indra/newview/llvograss.cpp @@ -594,7 +594,7 @@ U32 LLVOGrass::getPartitionType() const } LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_GRASS; mPartitionType = LLViewerRegion::PARTITION_GRASS; @@ -602,13 +602,10 @@ LLGrassPartition::LLGrassPartition(LLViewerRegion* regionp) mDepthMask = TRUE; mSlopRatio = 0.1f; mRenderPass = LLRenderPass::PASS_GRASS; - mBufferUsage = GL_DYNAMIC_DRAW; } void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) { - group->mBufferUsage = mBufferUsage; - mFaceList.clear(); LLViewerCamera* camera = LLViewerCamera::getInstance(); @@ -624,11 +621,6 @@ void LLGrassPartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count LLAlphaObject* obj = (LLAlphaObject*) drawablep->getVObj().get(); obj->mDepth = 0.f; - if (drawablep->isAnimating()) - { - group->mBufferUsage = GL_STREAM_DRAW; - } - U32 count = 0; for (S32 j = 0; j < drawablep->getNumFaces(); ++j) { @@ -707,8 +699,7 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) S32 idx = draw_vec.size()-1; - BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); - F32 vsize = facep->getVirtualSize(); + bool fullbright = facep->isState(LLFace::FULLBRIGHT); if (idx >= 0 && draw_vec[idx]->mEnd == facep->getGeomIndex()-1 && draw_vec[idx]->mTexture == facep->getTexture() && @@ -719,7 +710,6 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); - draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } else { @@ -731,14 +721,13 @@ void LLGrassPartition::getGeometry(LLSpatialGroup* group) //facep->getTexture(), buffer, object->isSelected(), fullbright); - info->mVSize = vsize; draw_vec.push_back(info); //for alpha sorting facep->setDrawInfo(info); } } - buffer->flush(); + buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/llvoground.cpp b/indra/newview/llvoground.cpp index 28bd5a3c97..c2f7d4fef6 100644 --- a/indra/newview/llvoground.cpp +++ b/indra/newview/llvoground.cpp @@ -93,8 +93,8 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) if (!face->getVertexBuffer()) { face->setSize(5, 12); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK, GL_STREAM_DRAW); - if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolGround::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount())) { LL_WARNS() << "Failed to allocate Vertex Buffer for VOGround to " << face->getGeomCount() << " vertices and " @@ -160,7 +160,7 @@ BOOL LLVOGround::updateGeometry(LLDrawable *drawable) *(texCoordsp++) = LLVector2(0.f, 1.f); *(texCoordsp++) = LLVector2(0.5f, 0.5f); - face->getVertexBuffer()->flush(); + face->getVertexBuffer()->unmapBuffer(); LLPipeline::sCompiles++; return TRUE; } diff --git a/indra/newview/llvopartgroup.cpp b/indra/newview/llvopartgroup.cpp index a5c65d6ed4..ac302ef421 100644 --- a/indra/newview/llvopartgroup.cpp +++ b/indra/newview/llvopartgroup.cpp @@ -46,18 +46,8 @@ extern U64MicrosecondsImplicit gFrameTime; -LLPointer LLVOPartGroup::sVB = NULL; -S32 LLVOPartGroup::sVBSlotFree[]; -S32* LLVOPartGroup::sVBSlotCursor = NULL; - void LLVOPartGroup::initClass() { - for (S32 i = 0; i < LL_MAX_PARTICLE_COUNT; ++i) - { - sVBSlotFree[i] = i; - } - - sVBSlotCursor = sVBSlotFree; } //static @@ -65,9 +55,10 @@ void LLVOPartGroup::restoreGL() { //TODO: optimize out binormal mask here. Specular and normal coords as well. - sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2, GL_STREAM_DRAW); +#if 0 + sVB = new LLVertexBuffer(VERTEX_DATA_MASK | LLVertexBuffer::MAP_TANGENT | LLVertexBuffer::MAP_TEXCOORD1 | LLVertexBuffer::MAP_TEXCOORD2); U32 count = LL_MAX_PARTICLE_COUNT; - if (!sVB->allocateBuffer(count*4, count*6, true)) + if (!sVB->allocateBuffer(count*4, count*6)) { LL_WARNS() << "Failed to allocate Vertex Buffer to " << count*4 << " vertices and " @@ -117,27 +108,14 @@ void LLVOPartGroup::restoreGL() *texcoordsp++ = LLVector2(1.f, 0.f); } - sVB->flush(); + sVB->unmapBuffer(); +#endif } //static void LLVOPartGroup::destroyGL() { - sVB = NULL; -} - -//static -S32 LLVOPartGroup::findAvailableVBSlot() -{ - if (sVBSlotCursor >= sVBSlotFree + LL_MAX_PARTICLE_COUNT) - { //no more available slots - return -1; - } - - S32 ret = *sVBSlotCursor; - sVBSlotCursor++; - return ret; } bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) @@ -155,20 +133,6 @@ bool ll_is_part_idx_allocated(S32 idx, S32* start, S32* end) return false; } -//static -void LLVOPartGroup::freeVBSlot(S32 idx) -{ - llassert(idx < LL_MAX_PARTICLE_COUNT && idx >= 0); - //llassert(sVBSlotCursor > sVBSlotFree); - //llassert(ll_is_part_idx_allocated(idx, sVBSlotCursor, sVBSlotFree+LL_MAX_PARTICLE_COUNT)); - - if (sVBSlotCursor > sVBSlotFree) - { - sVBSlotCursor--; - *sVBSlotCursor = idx; - } -} - LLVOPartGroup::LLVOPartGroup(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLAlphaObject(id, pcode, regionp), mViewerPartGroupp(NULL) @@ -291,13 +255,13 @@ F32 LLVOPartGroup::getPartSize(S32 idx) return 0.f; } -void LLVOPartGroup::getBlendFunc(S32 idx, U32& src, U32& dst) +void LLVOPartGroup::getBlendFunc(S32 idx, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst) { if (idx < (S32) mViewerPartGroupp->mParticles.size()) { LLViewerPart* part = mViewerPartGroupp->mParticles[idx]; - src = part->mBlendFuncSource; - dst = part->mBlendFuncDest; + src = (LLRender::eBlendFactor) part->mBlendFuncSource; + dst = (LLRender::eBlendFactor) part->mBlendFuncDest; } } @@ -738,7 +702,7 @@ U32 LLVOPartGroup::getPartitionType() const } LLParticlePartition::LLParticlePartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, GL_STREAM_DRAW, regionp) +: LLSpatialPartition(LLDrawPoolAlpha::VERTEX_DATA_MASK | LLVertexBuffer::MAP_TEXTURE_INDEX, TRUE, regionp) { mRenderPass = LLRenderPass::PASS_ALPHA; mDrawableType = LLPipeline::RENDER_TYPE_PARTICLES; @@ -758,32 +722,68 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; LL_PROFILE_GPU_ZONE("particle vbo"); - if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) - { - return; - } + if (group->isDead() || !group->hasState(LLSpatialGroup::GEOM_DIRTY)) + { + return; + } - if (group->changeLOD()) - { - group->mLastUpdateDistance = group->mDistance; - group->mLastUpdateViewAngle = group->mViewAngle; - } - - group->clearDrawMap(); - - //get geometry count - U32 index_count = 0; - U32 vertex_count = 0; + if (group->changeLOD()) + { + group->mLastUpdateDistance = group->mDistance; + group->mLastUpdateViewAngle = group->mViewAngle; + } - addGeometryCount(group, vertex_count, index_count); - + group->clearDrawMap(); + + //get geometry count + U32 index_count = 0; + U32 vertex_count = 0; + + addGeometryCount(group, vertex_count, index_count); - if (vertex_count > 0 && index_count > 0 && LLVOPartGroup::sVB) - { - group->mBuilt = 1.f; - //use one vertex buffer for all groups - group->mVertexBuffer = LLVOPartGroup::sVB; - getGeometry(group); + + if (vertex_count > 0 && index_count > 0) + { + group->mBuilt = 1.f; + if (group->mVertexBuffer.isNull() || + group->mVertexBuffer->getNumVerts() < vertex_count || group->mVertexBuffer->getNumIndices() < index_count) + { + group->mVertexBuffer = new LLVertexBuffer(LLVOPartGroup::VERTEX_DATA_MASK); + group->mVertexBuffer->allocateBuffer(vertex_count, index_count); + + // initialize index and texture coordinates only when buffer is reallocated + U16* indicesp = (U16*)group->mVertexBuffer->mapIndexBuffer(0, index_count); + + U16 geom_idx = 0; + for (U32 i = 0; i < index_count; i += 6) + { + *indicesp++ = geom_idx + 0; + *indicesp++ = geom_idx + 1; + *indicesp++ = geom_idx + 2; + + *indicesp++ = geom_idx + 1; + *indicesp++ = geom_idx + 3; + *indicesp++ = geom_idx + 2; + + geom_idx += 4; + } + + LLStrider texcoordsp; + + group->mVertexBuffer->getTexCoord0Strider(texcoordsp); + + for (U32 i = 0; i < vertex_count; i += 4) + { + *texcoordsp++ = LLVector2(0.f, 1.f); + *texcoordsp++ = LLVector2(0.f, 0.f); + *texcoordsp++ = LLVector2(1.f, 1.f); + *texcoordsp++ = LLVector2(1.f, 0.f); + } + + } + + + getGeometry(group); } else { @@ -797,8 +797,6 @@ void LLParticlePartition::rebuildGeom(LLSpatialGroup* group) void LLParticlePartition::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) { - group->mBufferUsage = mBufferUsage; - mFaceList.clear(); LLViewerCamera* camera = LLViewerCamera::getInstance(); @@ -851,10 +849,8 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLVertexBuffer* buffer = group->mVertexBuffer; - LLStrider indicesp; LLStrider verticesp; LLStrider normalsp; - LLStrider texcoordsp; LLStrider colorsp; LLStrider emissivep; @@ -863,7 +859,9 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) buffer->getColorStrider(colorsp); buffer->getEmissiveStrider(emissivep); - + S32 geom_idx = 0; + S32 indices_idx = 0; + LLSpatialGroup::drawmap_elem_t& draw_vec = group->mDrawMap[mRenderPass]; for (std::vector::iterator i = mFaceList.begin(); i != mFaceList.end(); ++i) @@ -871,56 +869,44 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) LLFace* facep = *i; LLAlphaObject* object = (LLAlphaObject*) facep->getViewerObject(); - if (!facep->isState(LLFace::PARTICLE)) - { //set the indices of this face - S32 idx = LLVOPartGroup::findAvailableVBSlot(); - if (idx >= 0) - { - facep->setGeomIndex(idx*4); - facep->setIndicesIndex(idx*6); - facep->setVertexBuffer(LLVOPartGroup::sVB); - facep->setPoolType(LLDrawPool::POOL_ALPHA); - facep->setState(LLFace::PARTICLE); - } - else - { - continue; //out of space in particle buffer - } - } - - S32 geom_idx = (S32) facep->getGeomIndex(); + facep->setGeomIndex(geom_idx); + facep->setIndicesIndex(indices_idx); - LLStrider cur_idx = indicesp + facep->getIndicesStart(); LLStrider cur_vert = verticesp + geom_idx; LLStrider cur_norm = normalsp + geom_idx; - LLStrider cur_tc = texcoordsp + geom_idx; LLStrider cur_col = colorsp + geom_idx; LLStrider cur_glow = emissivep + geom_idx; + // not actually used + LLStrider cur_tc; + LLStrider cur_idx; + + + geom_idx += 4; + indices_idx += 6; + LLColor4U* start_glow = cur_glow.get(); object->getGeometry(facep->getTEOffset(), cur_vert, cur_norm, cur_tc, cur_col, cur_glow, cur_idx); - BOOL has_glow = FALSE; + bool has_glow = FALSE; if (cur_glow.get() != start_glow) { - has_glow = TRUE; + has_glow = true; } llassert(facep->getGeomCount() == 4); llassert(facep->getIndicesCount() == 6); - - + S32 idx = draw_vec.size()-1; - BOOL fullbright = facep->isState(LLFace::FULLBRIGHT); - F32 vsize = facep->getVirtualSize(); + bool fullbright = facep->isState(LLFace::FULLBRIGHT); bool batched = false; - U32 bf_src = LLRender::BF_SOURCE_ALPHA; - U32 bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; + LLRender::eBlendFactor bf_src = LLRender::BF_SOURCE_ALPHA; + LLRender::eBlendFactor bf_dst = LLRender::BF_ONE_MINUS_SOURCE_ALPHA; object->getBlendFunc(facep->getTEOffset(), bf_src, bf_dst); @@ -940,7 +926,6 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) batched = true; info->mCount += facep->getIndicesCount(); info->mEnd += facep->getGeomCount(); - info->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } else if (draw_vec[idx]->mStart == facep->getGeomIndex()+facep->getGeomCount()+1) { @@ -948,12 +933,10 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) info->mCount += facep->getIndicesCount(); info->mStart -= facep->getGeomCount(); info->mOffset = facep->getIndicesStart(); - info->mVSize = llmax(draw_vec[idx]->mVSize, vsize); } } } - if (!batched) { U32 start = facep->getGeomIndex(); @@ -961,19 +944,18 @@ void LLParticlePartition::getGeometry(LLSpatialGroup* group) U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); LLDrawInfo* info = new LLDrawInfo(start,end,count,offset,facep->getTexture(), - buffer, object->isSelected(), fullbright); + buffer, fullbright); - info->mVSize = vsize; info->mBlendFuncDst = bf_dst; info->mBlendFuncSrc = bf_src; info->mHasGlow = has_glow; - info->mParticle = TRUE; draw_vec.push_back(info); //for alpha sorting facep->setDrawInfo(info); } } + buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/llvopartgroup.h b/indra/newview/llvopartgroup.h index a45d381dfa..4d471134d4 100644 --- a/indra/newview/llvopartgroup.h +++ b/indra/newview/llvopartgroup.h @@ -40,16 +40,9 @@ class LLVOPartGroup : public LLAlphaObject { public: - //vertex buffer for holding all particles - static LLPointer sVB; - static S32 sVBSlotFree[LL_MAX_PARTICLE_COUNT]; - static S32 *sVBSlotCursor; - static void initClass(); static void restoreGL(); static void destroyGL(); - static S32 findAvailableVBSlot(); - static void freeVBSlot(S32 idx); enum { @@ -99,7 +92,7 @@ public: void updateFaceSize(S32 idx) { } F32 getPartSize(S32 idx); - void getBlendFunc(S32 idx, U32& src, U32& dst); + void getBlendFunc(S32 idx, LLRender::eBlendFactor& src, LLRender::eBlendFactor& dst); LLUUID getPartOwner(S32 idx); LLUUID getPartSource(S32 idx); diff --git a/indra/newview/llvosky.cpp b/indra/newview/llvosky.cpp index d5979b2280..59fcacf914 100644 --- a/indra/newview/llvosky.cpp +++ b/indra/newview/llvosky.cpp @@ -1010,8 +1010,8 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) face->setSize(4, 6); face->setGeomIndex(0); face->setIndicesIndex(0); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW); - buff->allocateBuffer(4, 6, TRUE); + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK); + buff->allocateBuffer(4, 6); face->setVertexBuffer(buff); index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -1046,7 +1046,7 @@ BOOL LLVOSky::updateGeometry(LLDrawable *drawable) *indicesp++ = index_offset + 3; *indicesp++ = index_offset + 2; - buff->flush(); + buff->unmapBuffer(); } } @@ -1139,8 +1139,8 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const if (!facep->getVertexBuffer()) { facep->setSize(4, 6); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK, GL_STREAM_DRAW); - if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount(), TRUE)) + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolSky::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(facep->getGeomCount(), facep->getIndicesCount())) { LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " << facep->getGeomCount() << " vertices and " @@ -1179,7 +1179,7 @@ bool LLVOSky::updateHeavenlyBodyGeometry(LLDrawable *drawable, F32 scale, const *indicesp++ = index_offset + 2; *indicesp++ = index_offset + 3; - facep->getVertexBuffer()->flush(); + facep->getVertexBuffer()->unmapBuffer(); return TRUE; } @@ -1379,8 +1379,8 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, if (!face->getVertexBuffer() || quads*4 != face->getGeomCount()) { face->setSize(quads * 4, quads * 6); - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_STREAM_DRAW); - if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount())) { LL_WARNS() << "Failed to allocate Vertex Buffer for vosky to " << face->getGeomCount() << " vertices and " @@ -1523,7 +1523,7 @@ void LLVOSky::updateReflectionGeometry(LLDrawable *drawable, F32 H, } } - face->getVertexBuffer()->flush(); + face->getVertexBuffer()->unmapBuffer(); } } diff --git a/indra/newview/llvosurfacepatch.cpp b/indra/newview/llvosurfacepatch.cpp index 69ae3cf23b..067272ec44 100644 --- a/indra/newview/llvosurfacepatch.cpp +++ b/indra/newview/llvosurfacepatch.cpp @@ -45,26 +45,6 @@ F32 LLVOSurfacePatch::sLODFactor = 1.f; -//============================================================================ - -class LLVertexBufferTerrain : public LLVertexBuffer -{ -public: - LLVertexBufferTerrain() : - LLVertexBuffer(MAP_VERTEX | MAP_NORMAL | MAP_TEXCOORD0 | MAP_TEXCOORD1 | MAP_COLOR, GL_DYNAMIC_DRAW) - { - //texture coordinates 2 and 3 exist, but use the same data as texture coordinate 1 - }; - - // virtual - void setupVertexBuffer(U32 data_mask) - { - LLVertexBuffer::setupVertexBuffer(data_mask & ~(MAP_TEXCOORD2 | MAP_TEXCOORD3)); - } -}; - -//============================================================================ - LLVOSurfacePatch::LLVOSurfacePatch(const LLUUID &id, const LLPCode pcode, LLViewerRegion *regionp) : LLStaticViewerObject(id, pcode, regionp), mDirtiedPatch(FALSE), @@ -1001,7 +981,7 @@ U32 LLVOSurfacePatch::getPartitionType() const } LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, GL_DYNAMIC_DRAW, regionp) +: LLSpatialPartition(LLDrawPoolTerrain::VERTEX_DATA_MASK, FALSE, regionp) { mOcclusionEnabled = FALSE; mInfiniteFarClip = TRUE; @@ -1009,11 +989,6 @@ LLTerrainPartition::LLTerrainPartition(LLViewerRegion* regionp) mPartitionType = LLViewerRegion::PARTITION_TERRAIN; } -LLVertexBuffer* LLTerrainPartition::createVertexBuffer(U32 type_mask, U32 usage) -{ - return new LLVertexBufferTerrain(); -} - void LLTerrainPartition::getGeometry(LLSpatialGroup* group) { LL_PROFILE_ZONE_SCOPED; @@ -1051,7 +1026,7 @@ void LLTerrainPartition::getGeometry(LLSpatialGroup* group) index_offset += facep->getGeomCount(); } - buffer->flush(); + buffer->unmapBuffer(); mFaceList.clear(); } diff --git a/indra/newview/llvotree.cpp b/indra/newview/llvotree.cpp index b6f8d162ba..0da77e4f8b 100644 --- a/indra/newview/llvotree.cpp +++ b/indra/newview/llvotree.cpp @@ -538,8 +538,8 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) max_vertices += sLODVertexCount[lod]; } - mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, 0); - if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices, TRUE)) + mReferenceBuffer = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + if (!mReferenceBuffer->allocateBuffer(max_vertices, max_indices)) { LL_WARNS() << "Failed to allocate Vertex Buffer on update to " << max_vertices << " vertices and " @@ -862,7 +862,7 @@ BOOL LLVOTree::updateGeometry(LLDrawable *drawable) slices /= 2; } - mReferenceBuffer->flush(); + mReferenceBuffer->unmapBuffer(); llassert(vertex_count == max_vertices); llassert(index_count == max_indices); } @@ -921,19 +921,19 @@ void LLVOTree::updateMesh() LLFace* facep = mDrawable->getFace(0); if (!facep) return; - LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK, GL_STATIC_DRAW); - if (!buff->allocateBuffer(vert_count, index_count, TRUE)) + LLVertexBuffer* buff = new LLVertexBuffer(LLDrawPoolTree::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(vert_count, index_count)) { LL_WARNS() << "Failed to allocate Vertex Buffer on mesh update to " << vert_count << " vertices and " << index_count << " indices" << LL_ENDL; - buff->allocateBuffer(1, 3, true); + buff->allocateBuffer(1, 3); memset((U8*)buff->getMappedData(), 0, buff->getSize()); memset((U8*)buff->getMappedIndices(), 0, buff->getIndicesSize()); facep->setSize(1, 3); facep->setVertexBuffer(buff); - mReferenceBuffer->flush(); - buff->flush(); + mReferenceBuffer->unmapBuffer(); + buff->unmapBuffer(); return; } @@ -954,8 +954,8 @@ void LLVOTree::updateMesh() genBranchPipeline(vertices, normals, tex_coords, colors, indices, idx_offset, scale_mat, mTrunkLOD, stop_depth, mDepth, mTrunkDepth, 1.0, mTwist, droop, mBranches, alpha); - mReferenceBuffer->flush(); - buff->flush(); + mReferenceBuffer->unmapBuffer(); + buff->unmapBuffer(); } void LLVOTree::appendMesh(LLStrider& vertices, @@ -1226,7 +1226,7 @@ U32 LLVOTree::getPartitionType() const } LLTreePartition::LLTreePartition(LLViewerRegion* regionp) -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp) +: LLSpatialPartition(0, FALSE, regionp) { mDrawableType = LLPipeline::RENDER_TYPE_TREE; mPartitionType = LLViewerRegion::PARTITION_TREE; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 53158ee66f..02d1654878 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -95,7 +95,6 @@ const F32 FORCE_CULL_AREA = 8.f; U32 JOINT_COUNT_REQUIRED_FOR_FULLRIG = 1; BOOL gAnimateTextures = TRUE; -//extern BOOL gHideSelectedObjects; F32 LLVOVolume::sLODFactor = 1.f; F32 LLVOVolume::sLODSlopDistanceFactor = 0.5f; //Changing this to zero, effectively disables the LOD transition slop @@ -526,6 +525,10 @@ U32 LLVOVolume::processUpdateMessage(LLMessageSystem *mesgsys, if (result & teDirtyBits) { updateTEData(); + if (mDrawable) + { //on the fly TE updates break batches, isolate in octree + shrinkWrap(); + } } if (result & TEM_CHANGE_MEDIA) { @@ -585,6 +588,7 @@ void LLVOVolume::animateTextures() { if (!mDead) { + shrinkWrap(); F32 off_s = 0.f, off_t = 0.f, scale_s = 1.f, scale_t = 1.f, rot = 0.f; S32 result = mTextureAnimp->animateTextures(off_s, off_t, scale_s, scale_t, rot); @@ -976,6 +980,11 @@ void LLVOVolume::setScale(const LLVector3 &scale, BOOL damped) //since drawable transforms do not include scale, changing volume scale //requires an immediate rebuild of volume verts. gPipeline.markRebuild(mDrawable, LLDrawable::REBUILD_POSITION, TRUE); + + if (mDrawable) + { + shrinkWrap(); + } } } @@ -2197,7 +2206,12 @@ S32 LLVOVolume::setTETexture(const U8 te, const LLUUID &uuid) S32 res = LLViewerObject::setTETexture(te, uuid); if (res) { - gPipeline.markTextured(mDrawable); + if (mDrawable) + { + // dynamic texture changes break batches, isolate in octree + shrinkWrap(); + gPipeline.markTextured(mDrawable); + } mFaceMappingChanged = TRUE; } return res; @@ -2232,6 +2246,7 @@ S32 LLVOVolume::setTEColor(const U8 te, const LLColor4& color) // These should only happen on updates which are not the initial update. mColorChanged = TRUE; mDrawable->setState(LLDrawable::REBUILD_COLOR); + shrinkWrap(); dirtyMesh(); } } @@ -2321,7 +2336,11 @@ S32 LLVOVolume::setTEGlow(const U8 te, const F32 glow) S32 res = LLViewerObject::setTEGlow(te, glow); if (res) { - gPipeline.markTextured(mDrawable); + if (mDrawable) + { + gPipeline.markTextured(mDrawable); + shrinkWrap(); + } mFaceMappingChanged = TRUE; } return res; @@ -4359,83 +4378,61 @@ void LLVOVolume::updateSpatialExtents(LLVector4a& newMin, LLVector4a& newMax) F32 LLVOVolume::getBinRadius() { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - F32 radius; - - F32 scale = 1.f; - - static LLCachedControl octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3); - static LLCachedControl octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4); - static LLCachedControl octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f)); - static LLCachedControl octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f)); + F32 radius; - S32 size_factor = llmax((S32)octree_size_factor, 1); - S32 attachment_size_factor = llmax((S32)octree_attachment_size_factor, 1); - LLVector3 distance_factor = octree_distance_factor; - LLVector3 alpha_distance_factor = octree_alpha_distance_factor; + static LLCachedControl octree_size_factor(gSavedSettings, "OctreeStaticObjectSizeFactor", 3); + static LLCachedControl octree_attachment_size_factor(gSavedSettings, "OctreeAttachmentSizeFactor", 4); + static LLCachedControl octree_distance_factor(gSavedSettings, "OctreeDistanceFactor", LLVector3(0.01f, 0.f, 0.f)); + static LLCachedControl octree_alpha_distance_factor(gSavedSettings, "OctreeAlphaDistanceFactor", LLVector3(0.1f, 0.f, 0.f)); - const LLVector4a* ext = mDrawable->getSpatialExtents(); - - BOOL shrink_wrap = mDrawable->isAnimating(); - BOOL alpha_wrap = FALSE; + S32 size_factor = llmax((S32)octree_size_factor, 1); + LLVector3 alpha_distance_factor = octree_alpha_distance_factor; - if (!isHUDAttachment()) - { - for (S32 i = 0; i < mDrawable->getNumFaces(); i++) - { - LLFace* face = mDrawable->getFace(i); - if (!face) continue; - if (face->isInAlphaPool() && - !face->canRenderAsMask()) - { - alpha_wrap = TRUE; - break; - } - } - } - else - { - shrink_wrap = FALSE; - } + //const LLVector4a* ext = mDrawable->getSpatialExtents(); - if (alpha_wrap) - { - LLVector3 bounds = getScale(); - radius = llmin(bounds.mV[1], bounds.mV[2]); - radius = llmin(radius, bounds.mV[0]); - radius *= 0.5f; - radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1]; - radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0]; - } - else if (shrink_wrap) - { - LLVector4a rad; - rad.setSub(ext[1], ext[0]); - - radius = rad.getLength3().getF32()*0.5f; - } - else if (mDrawable->isStatic()) - { - F32 szf = size_factor; + bool shrink_wrap = mShouldShrinkWrap || mDrawable->isAnimating(); + bool alpha_wrap = FALSE; - radius = llmax(mDrawable->getRadius(), szf); - - radius = powf(radius, 1.f+szf/radius); + if (!isHUDAttachment() && mDrawable->mDistanceWRTCamera < alpha_distance_factor[2]) + { + for (S32 i = 0; i < mDrawable->getNumFaces(); i++) + { + LLFace* face = mDrawable->getFace(i); + if (!face) continue; + if (face->isInAlphaPool() && + !face->canRenderAsMask()) + { + alpha_wrap = TRUE; + break; + } + } + } + else + { + shrink_wrap = FALSE; + } - radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; - radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; - } - else if (mDrawable->getVObj()->isAttachment()) - { - radius = llmax((S32) mDrawable->getRadius(),1)*attachment_size_factor; - } - else - { - radius = mDrawable->getRadius(); - radius *= 1.f + mDrawable->mDistanceWRTCamera * distance_factor[1]; - radius += mDrawable->mDistanceWRTCamera * distance_factor[0]; - } + if (alpha_wrap) + { + LLVector3 bounds = getScale(); + radius = llmin(bounds.mV[1], bounds.mV[2]); + radius = llmin(radius, bounds.mV[0]); + radius *= 0.5f; + //radius *= 1.f+mDrawable->mDistanceWRTCamera*alpha_distance_factor[1]; + //radius += mDrawable->mDistanceWRTCamera*alpha_distance_factor[0]; + } + else if (shrink_wrap) + { + radius = mDrawable->getRadius() * 0.25f; + } + else + { + F32 szf = size_factor; + radius = llmax(mDrawable->getRadius(), szf); + //radius = llmax(radius, mDrawable->mDistanceWRTCamera * distance_factor[0]); + } - return llclamp(radius*scale, 0.5f, 256.f); + return llclamp(radius, 0.5f, 256.f); } const LLVector3 LLVOVolume::getPivotPositionAgent() const @@ -4478,6 +4475,11 @@ void LLVOVolume::markForUpdate(BOOL priority) } } + if (mDrawable) + { + shrinkWrap(); + } + LLViewerObject::markForUpdate(priority); mVolumeChanged = TRUE; } @@ -4990,7 +4992,7 @@ U32 LLVOVolume::getPartitionType() const } LLVolumePartition::LLVolumePartition(LLViewerRegion* regionp) -: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, GL_DYNAMIC_DRAW, regionp), +: LLSpatialPartition(LLVOVolume::VERTEX_DATA_MASK, TRUE, regionp), LLVolumeGeometryManager() { mLODPeriod = 32; @@ -4998,7 +5000,6 @@ LLVolumeGeometryManager() mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_VOLUME; mSlopRatio = 0.25f; - mBufferUsage = GL_DYNAMIC_DRAW; } LLVolumeBridge::LLVolumeBridge(LLDrawable* drawablep, LLViewerRegion* regionp) @@ -5010,8 +5011,6 @@ LLVolumeGeometryManager() mDrawableType = LLPipeline::RENDER_TYPE_VOLUME; mPartitionType = LLViewerRegion::PARTITION_BRIDGE; - mBufferUsage = GL_DYNAMIC_DRAW; - mSlopRatio = 0.25f; } @@ -5164,7 +5163,7 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, S32 idx = draw_vec.size()-1; - BOOL fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || + bool fullbright = (type == LLRenderPass::PASS_FULLBRIGHT) || (type == LLRenderPass::PASS_INVISIBLE) || (type == LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK) || (type == LLRenderPass::PASS_ALPHA && facep->isState(LLFace::FULLBRIGHT)) || @@ -5227,7 +5226,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, mat = facep->getTextureEntry()->getMaterialParams().get(); if (mat) { - mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); + //mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); + mat_id = facep->getTextureEntry()->getMaterialParams()->getHash(); } } @@ -5247,8 +5247,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, } } - F32 vsize = facep->getVirtualSize(); //TODO -- adjust by texture scale? - if (index < FACE_DO_NOT_BATCH_TEXTURES && idx >= 0) { if (mat || gltf_mat || draw_vec[idx]->mMaterial) @@ -5261,12 +5259,10 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { batchable = true; draw_vec[idx]->mTextureList[index] = tex; - draw_vec[idx]->mTextureListVSize[index] = vsize; } else if (draw_vec[idx]->mTextureList[index] == tex) { //this face's texture index can be used with this batch batchable = true; - draw_vec[idx]->mTextureListVSize[index] = llmax(vsize, draw_vec[idx]->mTextureListVSize[index]); } } else @@ -5295,14 +5291,11 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { draw_vec[idx]->mCount += facep->getIndicesCount(); draw_vec[idx]->mEnd += facep->getGeomCount(); - draw_vec[idx]->mVSize = llmax(draw_vec[idx]->mVSize, vsize); if (index < FACE_DO_NOT_BATCH_TEXTURES && index >= draw_vec[idx]->mTextureList.size()) { draw_vec[idx]->mTextureList.resize(index+1); draw_vec[idx]->mTextureList[index] = tex; - draw_vec[idx]->mTextureListVSize.resize(index + 1); - draw_vec[idx]->mTextureListVSize[index] = vsize; } draw_vec[idx]->validate(); } @@ -5312,10 +5305,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, U32 end = start + facep->getGeomCount()-1; U32 offset = facep->getIndicesStart(); U32 count = facep->getIndicesCount(); - LLPointer draw_info = new LLDrawInfo(start,end,count,offset, tex, - facep->getVertexBuffer(), selected, fullbright, bump); - draw_info->mGroup = group; - draw_info->mVSize = vsize; + LLPointer draw_info = new LLDrawInfo(start,end,count,offset, tex, + facep->getVertexBuffer(), fullbright, bump); draw_vec.push_back(draw_info); draw_info->mTextureMatrix = tex_mat; draw_info->mModelMatrix = model_mat; @@ -5388,8 +5379,6 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, { //initialize texture list for texture batching draw_info->mTextureList.resize(index+1); draw_info->mTextureList[index] = tex; - draw_info->mTextureListVSize.resize(index + 1); - draw_info->mTextureListVSize[index] = vsize; } draw_info->validate(); } @@ -5551,8 +5540,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) U32 spec_count[2] = { 0 }; U32 normspec_count[2] = { 0 }; - U32 useage = group->getSpatialPartition()->mBufferUsage; - static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); static LLCachedControl max_node_size(gSavedSettings, "RenderMaxNodeSize", 65536); U32 max_vertices = (max_vbo_size * 1024)/LLVertexBuffer::calcVertexSize(group->getSpatialPartition()->mVertexDataMask); @@ -5584,11 +5571,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) continue; } - if (drawablep->isAnimating()) - { //fall back to stream draw for animating verts - useage = GL_STREAM_DRAW; - } - LLVOVolume* vobj = drawablep->getVOVolume(); if (!vobj) @@ -5928,8 +5910,6 @@ void LLVolumeGeometryManager::rebuildGeom(LLSpatialGroup* group) } } - group->mBufferUsage = useage; - //PROCESS NON-ALPHA FACES U32 simple_mask = LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_NORMAL | LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_COLOR; U32 alpha_mask = simple_mask | 0x80000000; //hack to give alpha verts their own VBO @@ -6022,8 +6002,6 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) group->mBuilt = 1.f; - S32 num_mapped_vertex_buffer = LLVertexBuffer::sMappedCount ; - const U32 MAX_BUFFER_COUNT = 4096; LLVertexBuffer* locked_buffer[MAX_BUFFER_COUNT]; @@ -6074,11 +6052,7 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) gPipeline.markRebuild(group, TRUE); } - - if (buff->isLocked() && buffer_count < MAX_BUFFER_COUNT) - { - locked_buffer[buffer_count++] = buff; - } + buff->unmapBuffer(); } } } @@ -6096,44 +6070,17 @@ void LLVolumeGeometryManager::rebuildMesh(LLSpatialGroup* group) LL_PROFILE_ZONE_NAMED("rebuildMesh - flush"); for (LLVertexBuffer** iter = locked_buffer, ** end_iter = locked_buffer+buffer_count; iter != end_iter; ++iter) { - (*iter)->flush(); + (*iter)->unmapBuffer(); } // don't forget alpha if(group != NULL && - !group->mVertexBuffer.isNull() && - group->mVertexBuffer->isLocked()) + !group->mVertexBuffer.isNull()) { - group->mVertexBuffer->flush(); - } - } - - //if not all buffers are unmapped - if(num_mapped_vertex_buffer != LLVertexBuffer::sMappedCount) - { - LL_WARNS() << "Not all mapped vertex buffers are unmapped!" << LL_ENDL ; - for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) - { - LLDrawable* drawablep = (LLDrawable*)(*drawable_iter)->getDrawable(); - if(!drawablep) - { - continue; - } - for (S32 i = 0; i < drawablep->getNumFaces(); ++i) - { - LLFace* face = drawablep->getFace(i); - if (face) - { - LLVertexBuffer* buff = face->getVertexBuffer(); - if (buff && buff->isLocked()) - { - buff->flush(); - } - } - } + group->mVertexBuffer->unmapBuffer(); } } - + group->clearState(LLSpatialGroup::MESH_DIRTY | LLSpatialGroup::NEW_DRAWINFO); } } @@ -6200,18 +6147,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; U32 geometryBytes = 0; - U32 buffer_usage = group->mBufferUsage; - -#if LL_DARWIN - // HACK from Leslie: - // Disable VBO usage for alpha on Mac OS X because it kills the framerate - // due to implicit calls to glTexSubImage that are beyond our control. - // (this works because the only calls here that sort by distance are alpha) - if (distance_sort) - { - buffer_usage = 0x0; - } -#endif //calculate maximum number of vertices to store in a single buffer static LLCachedControl max_vbo_size(gSavedSettings, "RenderMaxVBOSize", 512); @@ -6428,19 +6363,13 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace } } - - if (flexi && buffer_usage && buffer_usage != GL_STREAM_DRAW) - { - buffer_usage = GL_STREAM_DRAW; - } - //create vertex buffer LLPointer buffer; { LL_PROFILE_ZONE_NAMED("genDrawInfo - allocate"); - buffer = createVertexBuffer(mask, buffer_usage); - if(!buffer->allocateBuffer(geom_count, index_count, TRUE)) + buffer = new LLVertexBuffer(mask); + if(!buffer->allocateBuffer(geom_count, index_count)) { LL_WARNS() << "Failed to allocate group Vertex Buffer to " << geom_count << " vertices and " @@ -6830,7 +6759,7 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace if (buffer) { - buffer->flush(); + buffer->unmapBuffer(); } } @@ -6845,9 +6774,6 @@ U32 LLVolumeGeometryManager::genDrawInfo(LLSpatialGroup* group, U32 mask, LLFace void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& vertex_count, U32& index_count) { - //initialize to default usage for this partition - U32 usage = group->getSpatialPartition()->mBufferUsage; - //for each drawable for (LLSpatialGroup::element_iter drawable_iter = group->getDataBegin(); drawable_iter != group->getDataEnd(); ++drawable_iter) { @@ -6857,23 +6783,13 @@ void LLVolumeGeometryManager::addGeometryCount(LLSpatialGroup* group, U32& verte { continue; } - - if (drawablep->isAnimating()) - { //fall back to stream draw for animating verts - usage = GL_STREAM_DRAW; - } } - - group->mBufferUsage = usage; } void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_count, U32 &index_count) { LL_PROFILE_ZONE_SCOPED_CATEGORY_VOLUME; - //initialize to default usage for this partition - U32 usage = group->getSpatialPartition()->mBufferUsage; - //clear off any old faces mFaceList.clear(); @@ -6887,11 +6803,6 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun continue; } - if (drawablep->isAnimating()) - { //fall back to stream draw for animating verts - usage = GL_STREAM_DRAW; - } - //for each face for (S32 i = 0; i < drawablep->getNumFaces(); i++) { @@ -6916,8 +6827,6 @@ void LLGeometryManager::addGeometryCount(LLSpatialGroup* group, U32 &vertex_coun } } } - - group->mBufferUsage = usage; } LLHUDPartition::LLHUDPartition(LLViewerRegion* regionp) : LLBridgePartition(regionp) diff --git a/indra/newview/llvowater.cpp b/indra/newview/llvowater.cpp index 6f30092326..2356e72aab 100644 --- a/indra/newview/llvowater.cpp +++ b/indra/newview/llvowater.cpp @@ -150,10 +150,14 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) indices_per_quad * num_quads); LLVertexBuffer* buff = face->getVertexBuffer(); - if (!buff || !buff->isWriteable()) + if (!buff || + buff->getNumIndices() != face->getIndicesCount() || + buff->getNumVerts() != face->getGeomCount() || + face->getIndicesStart() != 0 || + face->getGeomIndex() != 0) { - buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); - if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount(), TRUE)) + buff = new LLVertexBuffer(LLDrawPoolWater::VERTEX_DATA_MASK); + if (!buff->allocateBuffer(face->getGeomCount(), face->getIndicesCount())) { LL_WARNS() << "Failed to allocate Vertex Buffer on water update to " << face->getGeomCount() << " vertices and " @@ -163,13 +167,6 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) face->setGeomIndex(0); face->setVertexBuffer(buff); } - else - { - if (!buff->resizeBuffer(face->getGeomCount(), face->getIndicesCount())) - { - LL_WARNS() << "Failed to resize Vertex Buffer" << LL_ENDL; - } - } index_offset = face->getGeometry(verticesp,normalsp,texCoordsp, indicesp); @@ -230,7 +227,7 @@ BOOL LLVOWater::updateGeometry(LLDrawable *drawable) } } - buff->flush(); + buff->unmapBuffer(); mDrawable->movePartition(); LLPipeline::sCompiles++; @@ -295,7 +292,7 @@ U32 LLVOVoidWater::getPartitionType() const } LLWaterPartition::LLWaterPartition(LLViewerRegion* regionp) -: LLSpatialPartition(0, FALSE, GL_DYNAMIC_DRAW, regionp) +: LLSpatialPartition(0, FALSE, regionp) { mInfiniteFarClip = TRUE; mDrawableType = LLPipeline::RENDER_TYPE_WATER; diff --git a/indra/newview/llvowlsky.cpp b/indra/newview/llvowlsky.cpp index 524fd4c49e..86e4853280 100644 --- a/indra/newview/llvowlsky.cpp +++ b/indra/newview/llvowlsky.cpp @@ -151,9 +151,9 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) if (mFsSkyVerts.isNull()) { - mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW); + mFsSkyVerts = new LLVertexBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK); - if (!mFsSkyVerts->allocateBuffer(4, 6, TRUE)) + if (!mFsSkyVerts->allocateBuffer(4, 6)) { LL_WARNS() << "Failed to allocate Vertex Buffer on full screen sky update" << LL_ENDL; } @@ -184,7 +184,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) *indices++ = 3; *indices++ = 2; - mFsSkyVerts->flush(); + mFsSkyVerts->unmapBuffer(); } { @@ -216,7 +216,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) for (U32 i = 0; i < strips_segments ;++i) { - LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK, GL_STATIC_DRAW); + LLVertexBuffer * segment = new LLVertexBuffer(LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK); mStripsVerts[i] = segment; U32 num_stacks_this_seg = stacks_per_seg; @@ -237,7 +237,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) const U32 num_indices_this_seg = 1+num_stacks_this_seg*(2+2*verts_per_stack); llassert(num_indices_this_seg * sizeof(U16) <= max_buffer_bytes); - bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg, TRUE); + bool allocated = segment->allocateBuffer(num_verts_this_seg, num_indices_this_seg); #if RELEASE_SHOW_WARNS if( !allocated ) { @@ -267,7 +267,7 @@ BOOL LLVOWLSky::updateGeometry(LLDrawable * drawable) buildStripsBuffer(begin_stack, end_stack, vertices, texCoords, indices, dome_radius, verts_per_stack, total_stacks); // and unlock the buffer - segment->flush(); + segment->unmapBuffer(); } #if RELEASE_SHOW_DEBUG @@ -288,7 +288,7 @@ void LLVOWLSky::drawStars(void) // render the stars as a sphere centered at viewer camera if (mStarsVerts.notNull()) { - mStarsVerts->setBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); + mStarsVerts->setBuffer(); mStarsVerts->drawArrays(LLRender::TRIANGLES, 0, getStarsNumVerts()*4); } } @@ -302,7 +302,7 @@ void LLVOWLSky::drawFsSky(void) LLGLDisable disable_blend(GL_BLEND); - mFsSkyVerts->setBuffer(LLDrawPoolWLSky::ADV_ATMO_SKY_VERTEX_DATA_MASK); + mFsSkyVerts->setBuffer(); mFsSkyVerts->drawRange(LLRender::TRIANGLES, 0, mFsSkyVerts->getNumVerts() - 1, mFsSkyVerts->getNumIndices(), 0); gPipeline.addTrianglesDrawn(mFsSkyVerts->getNumIndices()); LLVertexBuffer::unbind(); @@ -317,15 +317,13 @@ void LLVOWLSky::drawDome(void) LLGLDepthTest gls_depth(GL_TRUE, GL_FALSE); - const U32 data_mask = LLDrawPoolWLSky::SKY_VERTEX_DATA_MASK; - std::vector< LLPointer >::const_iterator strips_vbo_iter, end_strips; end_strips = mStripsVerts.end(); for(strips_vbo_iter = mStripsVerts.begin(); strips_vbo_iter != end_strips; ++strips_vbo_iter) { LLVertexBuffer * strips_segment = strips_vbo_iter->get(); - strips_segment->setBuffer(data_mask); + strips_segment->setBuffer(); strips_segment->drawRange( LLRender::TRIANGLE_STRIP, @@ -518,10 +516,10 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) LLStrider colorsp; LLStrider texcoordsp; - if (mStarsVerts.isNull() || !mStarsVerts->isWriteable()) + if (mStarsVerts.isNull()) { - mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK, GL_DYNAMIC_DRAW); - if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0, TRUE)) + mStarsVerts = new LLVertexBuffer(LLDrawPoolWLSky::STAR_VERTEX_DATA_MASK); + if (!mStarsVerts->allocateBuffer(getStarsNumVerts()*6, 0)) { LL_WARNS() << "Failed to allocate Vertex Buffer for Sky to " << getStarsNumVerts() * 6 << " vertices" << LL_ENDL; } @@ -578,6 +576,6 @@ BOOL LLVOWLSky::updateStarGeometry(LLDrawable *drawable) *(colorsp++) = LLColor4U(mStarColors[vtx]); } - mStarsVerts->flush(); + mStarsVerts->unmapBuffer(); return TRUE; } diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index cedbe4d117..beaa3cdb69 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -285,7 +285,7 @@ static LLStaticHashedString sKernScale("kern_scale"); void drawBox(const LLVector4a& c, const LLVector4a& r); void drawBoxOutline(const LLVector3& pos, const LLVector3& size); U32 nhpo2(U32 v); -LLVertexBuffer* ll_create_cube_vb(U32 type_mask, U32 usage); +LLVertexBuffer* ll_create_cube_vb(U32 type_mask); void display_update_camera(); //---------------------------------------- @@ -416,9 +416,6 @@ void LLPipeline::init() gOctreeMinSize = gSavedSettings.getF32("OctreeMinimumNodeSize"); sDynamicLOD = gSavedSettings.getBOOL("RenderDynamicLOD"); sRenderBump = TRUE; // DEPRECATED -- gSavedSettings.getBOOL("RenderObjectBump"); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); - LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); sRenderAttachedLights = gSavedSettings.getBOOL("RenderAttachedLights"); sRenderAttachedParticles = gSavedSettings.getBOOL("RenderAttachedParticles"); @@ -498,15 +495,15 @@ void LLPipeline::init() if (mCubeVB.isNull()) { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); } - mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); - mDeferredVB->allocateBuffer(8, 0, true); + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK); + mDeferredVB->allocateBuffer(8, 0); { - mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); - mScreenTriangleVB->allocateBuffer(3, 0, true); + mScreenTriangleVB = new LLVertexBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->allocateBuffer(3, 0); LLStrider vert; mScreenTriangleVB->getVertexStrider(vert); @@ -514,7 +511,7 @@ void LLPipeline::init() vert[1].set(-1, -3, 0); vert[2].set(3, 1, 0); - mScreenTriangleVB->flush(); + mScreenTriangleVB->unmapBuffer(); } setLightingDetail(-1); @@ -706,11 +703,6 @@ void LLPipeline::destroyGL() releaseGLBuffers(); - if (LLVertexBuffer::sEnableVBOs) - { - LLVertexBuffer::sEnableVBOs = FALSE; - } - if (mMeshDirtyQueryObject) { glDeleteQueries(1, &mMeshDirtyQueryObject); @@ -2505,14 +2497,6 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d dest.bindTarget(); dest.clear(GL_DEPTH_BUFFER_BIT); - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - LLStrider tc0; - - vert[0].set(-1,1,0); - vert[1].set(-1,-3,0); - vert[2].set(3,1,0); - if (source.getUsage() == LLTexUnit::TT_TEXTURE) { shader = &gDownsampleDepthRectProgram; @@ -2532,8 +2516,8 @@ void LLPipeline::downsampleDepthBuffer(LLRenderTarget& source, LLRenderTarget& d { LLGLDepthTest depth(GL_TRUE, GL_TRUE, GL_ALWAYS); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } dest.flush(); @@ -2552,6 +2536,8 @@ void LLPipeline::doOcclusion(LLCamera& camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; LL_PROFILE_GPU_ZONE("doOcclusion"); + llassert(!gCubeSnapshot); + if (LLPipeline::sUseOcclusion > 1 && !LLSpatialPartition::sTeleportRequested && (sCull->hasOcclusionGroups() || LLVOCachePartition::sNeedsOcclusionCheck)) { @@ -2572,25 +2558,13 @@ void LLPipeline::doOcclusion(LLCamera& camera) LLGLDisable cull(GL_CULL_FACE); - - bool bind_shader = (LLGLSLShader::sCurBoundShader == 0); - if (bind_shader) - { - if (LLPipeline::sShadowRender) - { - gDeferredShadowCubeProgram.bind(); - } - else - { - gOcclusionCubeProgram.bind(); - } - } + gOcclusionCubeProgram.bind(); if (mCubeVB.isNull()) { //cube VB will be used for issuing occlusion queries - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); } - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mCubeVB->setBuffer(); for (LLCullResult::sg_iterator iter = sCull->beginOcclusionGroups(); iter != sCull->endOcclusionGroups(); ++iter) { @@ -2610,19 +2584,7 @@ void LLPipeline::doOcclusion(LLCamera& camera) } } - if (bind_shader) - { - if (LLPipeline::sShadowRender) - { - gDeferredShadowCubeProgram.unbind(); - } - else - { - gOcclusionCubeProgram.unbind(); - } - } - - gGL.setColorMask(true, false); + gGL.setColorMask(true, true); } } @@ -3661,50 +3623,6 @@ void renderSoundHighlights(LLDrawable *drawablep) } } -void LLPipeline::touchTexture(LLViewerTexture* tex, F32 vsize) -{ - if (tex) - { - tex->setActive(); - tex->addTextureStats(vsize); - } -} - -void LLPipeline::touchTextures(LLDrawInfo* info) -{ - if (--info->mTextureTimer == 0) - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - // reset texture timer in a noisy fashion to avoid clumping of updates - const U32 MIN_WAIT_TIME = 8; - const U32 MAX_WAIT_TIME = 16; - - info->mTextureTimer = ll_rand() % (MAX_WAIT_TIME - MIN_WAIT_TIME) + MIN_WAIT_TIME; - - auto& mat = info->mGLTFMaterial; - if (mat.notNull()) - { - touchTexture(mat->mBaseColorTexture, info->mVSize); - touchTexture(mat->mNormalTexture, info->mVSize); - touchTexture(mat->mMetallicRoughnessTexture, info->mVSize); - touchTexture(mat->mEmissiveTexture, info->mVSize); - } - else - { - info->mTextureTimer += (U8) info->mTextureList.size(); - - for (int i = 0; i < info->mTextureList.size(); ++i) - { - touchTexture(info->mTextureList[i], info->mTextureListVSize[i]); - } - - touchTexture(info->mTexture, info->mVSize); - touchTexture(info->mSpecularMap, info->mVSize); - touchTexture(info->mNormalMap, info->mVSize); - } - } -} - void LLPipeline::postSort(LLCamera &camera) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; @@ -3757,28 +3675,6 @@ void LLPipeline::postSort(LLCamera &camera) continue; } - // DEBUG -- force a texture virtual size update every frame - /*if (group->getSpatialPartition()->mDrawableType == LLPipeline::RENDER_TYPE_VOLUME) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_TEXTURE("plps - update vsize"); - auto& entries = group->getData(); - for (auto& entry : entries) - { - if (entry) - { - auto* data = entry->getDrawable(); - if (data) - { - LLVOVolume* volume = ((LLDrawable*)data)->getVOVolume(); - if (volume) - { - volume->updateTextureVirtualSize(true); - } - } - } - } - }*/ - for (LLSpatialGroup::drawmap_elem_t::iterator k = src_vec.begin(); k != src_vec.end(); ++k) { LLDrawInfo *info = *k; @@ -3786,7 +3682,6 @@ void LLPipeline::postSort(LLCamera &camera) sCull->pushDrawInfo(j->first, info); if (!sShadowRender && !sReflectionRender && !gCubeSnapshot) { - touchTextures(info); addTrianglesDrawn(info->mCount); } } @@ -3830,17 +3725,6 @@ void LLPipeline::postSort(LLCamera &camera) } } - // flush particle VB - if (LLVOPartGroup::sVB) - { - LL_PROFILE_GPU_ZONE("flush particle vb"); - LLVOPartGroup::sVB->flush(); - } - else - { - LL_WARNS_ONCE() << "Missing particle buffer" << LL_ENDL; - } - /*bool use_transform_feedback = gTransformPositionProgram.mProgramObject && !mMeshDirtyGroup.empty(); if (use_transform_feedback) @@ -3989,9 +3873,8 @@ void render_hud_elements() //glStencilMask(0xFFFFFFFF); //glStencilOp(GL_KEEP, GL_KEEP, GL_REPLACE); - gGL.color4f(1,1,1,1); - gUIProgram.bind(); + gGL.color4f(1, 1, 1, 1); LLGLDepthTest depth(GL_TRUE, GL_FALSE); if (!LLPipeline::sReflectionRender && gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) @@ -4151,261 +4034,6 @@ void LLPipeline::renderHighlights() //debug use U32 LLPipeline::sCurRenderPoolType = 0 ; -void LLPipeline::renderGeom(LLCamera& camera, bool forceVBOUpdate) -{ -#if 0 - LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; //LL_RECORD_BLOCK_TIME(FTM_RENDER_GEOMETRY); - LL_PROFILE_GPU_ZONE("renderGeom"); - assertInitialized(); - - F32 saved_modelview[16]; - F32 saved_projection[16]; - - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) - { - saved_modelview[i] = gGLModelView[i]; - saved_projection[i] = gGLProjection[i]; - } - } - - /////////////////////////////////////////// - // - // Sync and verify GL state - // - // - - stop_glerror(); - - LLVertexBuffer::unbind(); - - // Do verification of GL state - LLGLState::checkStates(); - LLGLState::checkTextureChannels(); - if (mRenderDebugMask & RENDER_DEBUG_VERIFY) - { - if (!verify()) - { - LL_ERRS() << "Pipeline verification failed!" << LL_ENDL; - } - } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:ForceVBO"); - - // Initialize lots of GL state to "safe" values - gGL.getTexUnit(0)->unbind(LLTexUnit::TT_TEXTURE); - gGL.matrixMode(LLRender::MM_TEXTURE); - gGL.loadIdentity(); - gGL.matrixMode(LLRender::MM_MODELVIEW); - - LLGLSPipeline gls_pipeline; - LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0); - - LLGLState gls_color_material(GL_COLOR_MATERIAL, mLightingDetail < 2); - - // Toggle backface culling for debugging - LLGLEnable cull_face(mBackfaceCull ? GL_CULL_FACE : 0); - // Set fog - bool use_fog = hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_FOG); - LLGLEnable fog_enable(use_fog && - !gPipeline.canUseWindLightShadersOnObjects() ? GL_FOG : 0); - gSky.updateFog(camera.getFar()); - if (!use_fog) - { - sUnderWaterRender = false; - } - - gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sDefaultImagep); - LLViewerFetchedTexture::sDefaultImagep->setAddressMode(LLTexUnit::TAM_WRAP); - - - ////////////////////////////////////////////// - // - // Actually render all of the geometry - // - // - stop_glerror(); - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPools"); - - for (pool_set_t::iterator iter = mPools.begin(); iter != mPools.end(); ++iter) - { - LLDrawPool *poolp = *iter; - if (hasRenderType(poolp->getType())) - { - poolp->prerender(); - } - } - - { - bool occlude = sUseOcclusion > 1; -#if 1 // DEPRECATED -- requires forward rendering - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pools"); //LL_RECORD_BLOCK_TIME(FTM_POOLS); - - // HACK: don't calculate local lights if we're rendering the HUD! - // Removing this check will cause bad flickering when there are - // HUD elements being rendered AND the user is in flycam mode -nyx - if (!gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - calcNearbyLights(camera); - setupHWLights(NULL); - } - - U32 cur_type = 0; - - pool_set_t::iterator iter1 = mPools.begin(); - while ( iter1 != mPools.end() ) - { - LLDrawPool *poolp = *iter1; - - cur_type = poolp->getType(); - - //debug use - sCurRenderPoolType = cur_type ; - - if (occlude && cur_type >= LLDrawPool::POOL_GRASS) - { - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); - doOcclusion(camera); - } - - - pool_set_t::iterator iter2 = iter1; - if (hasRenderType(poolp->getType()) && poolp->getNumPasses() > 0) - { - LL_PROFILE_ZONE_NAMED_CATEGORY_DRAWPOOL("pool render"); //LL_RECORD_BLOCK_TIME(FTM_POOLRENDER); - - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - for( S32 i = 0; i < poolp->getNumPasses(); i++ ) - { - LLVertexBuffer::unbind(); - poolp->beginRenderPass(i); - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - - if ( !p->getSkipRenderFlag() ) { p->render(i); } - } - poolp->endRenderPass(i); - LLVertexBuffer::unbind(); - if (gDebugGL) - { - std::string msg = llformat("pass %d", i); - LLGLState::checkStates(msg); - //LLGLState::checkTextureChannels(msg); - //LLGLState::checkClientArrays(msg); - } - } - } - else - { - // Skip all pools of this type - for (iter2 = iter1; iter2 != mPools.end(); iter2++) - { - LLDrawPool *p = *iter2; - if (p->getType() != cur_type) - { - break; - } - } - } - iter1 = iter2; - stop_glerror(); - - } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDrawPoolsEnd"); - - LLVertexBuffer::unbind(); -#endif - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - - if (occlude) - { // catch uncommon condition where pools at drawpool grass and later are disabled - occlude = false; - gGLLastMatrix = NULL; - gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); - doOcclusion(camera); - } - } - - LLVertexBuffer::unbind(); - LLGLState::checkStates(); - - if (!LLPipeline::sImpostorRender) - { - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderHighlights"); - - if (!sReflectionRender) - { - renderHighlights(); - } - - // Contains a list of the faces of objects that are physical or - // have touch-handlers. - mHighlightFaces.clear(); - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderDebug"); - - renderDebug(); - - LLVertexBuffer::unbind(); - - if (!LLPipeline::sReflectionRender && !LLPipeline::sRenderDeferred) - { - if (gPipeline.hasRenderDebugFeatureMask(LLPipeline::RENDER_DEBUG_FEATURE_UI)) - { - // Render debugging beacons. - gObjectList.renderObjectBeacons(); - gObjectList.resetObjectBeacons(); - gSky.addSunMoonBeacons(); - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } - } - else - { - // Make sure particle effects disappear - LLHUDObject::renderAllForTimer(); - } - - LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomEnd"); - - //HACK: preserve/restore matrices around HUD render - if (gPipeline.hasRenderType(LLPipeline::RENDER_TYPE_HUD)) - { - for (U32 i = 0; i < 16; i++) - { - gGLModelView[i] = saved_modelview[i]; - gGLProjection[i] = saved_projection[i]; - } - } - } - - LLVertexBuffer::unbind(); - - LLGLState::checkStates(); -// LLGLState::checkTextureChannels(); -// LLGLState::checkClientArrays(); -#endif -} - void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) { LLAppViewer::instance()->pingMainloopTimeout("Pipeline:RenderGeomDeferred"); @@ -4438,7 +4066,6 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); if (LLViewerShaderMgr::instance()->mShaderLevel[LLViewerShaderMgr::SHADER_DEFERRED] > 1) { @@ -4464,9 +4091,7 @@ void LLPipeline::renderGeomDeferred(LLCamera& camera, bool do_occlusion) occlude = false; gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); - LLGLSLShader::bindNoShader(); doOcclusion(camera); - gGL.setColorMask(true, false); } pool_set_t::iterator iter2 = iter1; @@ -4586,7 +4211,7 @@ void LLPipeline::renderGeomPostDeferred(LLCamera& camera) if (gDebugGL || gDebugPipeline) { - LLGLState::checkStates(); + LLGLState::checkStates(GL_FALSE); } } } @@ -4667,8 +4292,6 @@ void LLPipeline::renderGeomShadow(LLCamera& camera) } poolp->endShadowPass(i); LLVertexBuffer::unbind(); - - LLGLState::checkStates(); } } else @@ -5049,8 +4672,6 @@ void LLPipeline::renderDebug() } } - gGL.color4f(1,1,1,1); - gGLLastMatrix = NULL; gGL.loadMatrix(gGLModelView); gGL.setColorMask(true, false); @@ -5059,6 +4680,7 @@ void LLPipeline::renderDebug() if (!hud_only && !mDebugBlips.empty()) { //render debug blips gUIProgram.bind(); + gGL.color4f(1, 1, 1, 1); gGL.getTexUnit(0)->bind(LLViewerFetchedTexture::sWhiteImagep, true); @@ -5154,7 +4776,7 @@ void LLPipeline::renderDebug() LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("probe debug display"); bindDeferredShader(gReflectionProbeDisplayProgram, NULL); - mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); // Provide our projection matrix. set_camera_projection_matrix(gReflectionProbeDisplayProgram); @@ -7259,45 +6881,35 @@ void LLPipeline::doResetVertexBuffers(bool forced) LLVOPartGroup::destroyGL(); gGL.resetVertexBuffer(); - if (LLVertexBuffer::sGLCount != 0) - { - LL_WARNS() << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << LL_ENDL; - } - LLVertexBuffer::unbind(); updateRenderBump(); updateRenderDeferred(); - LLVertexBuffer::sUseStreamDraw = gSavedSettings.getBOOL("RenderUseStreamVBO"); - LLVertexBuffer::sUseVAO = gSavedSettings.getBOOL("RenderUseVAO"); - LLVertexBuffer::sPreferStreamDraw = gSavedSettings.getBOOL("RenderPreferStreamDraw"); - LLVertexBuffer::sEnableVBOs = gSavedSettings.getBOOL("RenderVBOEnable"); - LLVertexBuffer::sDisableVBOMapping = LLVertexBuffer::sEnableVBOs && gSavedSettings.getBOOL("RenderVBOMappingDisable") ; sBakeSunlight = gSavedSettings.getBOOL("RenderBakeSunlight"); sNoAlpha = gSavedSettings.getBOOL("RenderNoAlpha"); LLPipeline::sTextureBindTest = gSavedSettings.getBOOL("RenderDebugTextureBind"); gGL.initVertexBuffer(); - mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK, 0); - mDeferredVB->allocateBuffer(8, 0, true); + mDeferredVB = new LLVertexBuffer(DEFERRED_VB_MASK); + mDeferredVB->allocateBuffer(8, 0); LLVOPartGroup::restoreGL(); } -void LLPipeline::renderObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) +void LLPipeline::renderObjects(U32 type, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; if (rigged) { - mSimplePool->pushRiggedBatches(type + 1, mask, texture, batch_texture); + mSimplePool->pushRiggedBatches(type + 1, texture, batch_texture); } else { - mSimplePool->pushBatches(type, mask, texture, batch_texture); + mSimplePool->pushBatches(type, texture, batch_texture); } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; @@ -7326,8 +6938,8 @@ void LLPipeline::renderShadowSimple(U32 type) { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("push shadow simple"); mSimplePool->applyModelMatrix(params); - vb->setBufferFast(LLVertexBuffer::MAP_VERTEX); - vb->drawRangeFast(LLRender::TRIANGLES, 0, vb->getNumVerts()-1, vb->getNumIndices(), 0); + vb->setBuffer(); + vb->drawRange(LLRender::TRIANGLES, 0, vb->getNumVerts()-1, vb->getNumIndices(), 0); last_vb = vb; } } @@ -7335,7 +6947,7 @@ void LLPipeline::renderShadowSimple(U32 type) gGLLastMatrix = NULL; } -void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, bool rigged) +void LLPipeline::renderAlphaObjects(bool texture, bool batch_texture, bool rigged) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; assertInitialized(); @@ -7363,12 +6975,12 @@ void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, lastMeshId = pparams->mSkinInfo->mHash; } - mSimplePool->pushBatch(*pparams, mask | LLVertexBuffer::MAP_WEIGHT4, texture, batch_texture); + mSimplePool->pushBatch(*pparams, texture, batch_texture); } } else if (pparams->mAvatar == nullptr) { - mSimplePool->pushBatch(*pparams, mask, texture, batch_texture); + mSimplePool->pushBatch(*pparams, texture, batch_texture); } } @@ -7376,35 +6988,35 @@ void LLPipeline::renderAlphaObjects(U32 mask, bool texture, bool batch_texture, gGLLastMatrix = NULL; } -void LLPipeline::renderMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) +void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; if (rigged) { - mAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); + mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); } else { - mAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; } -void LLPipeline::renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture, bool batch_texture, bool rigged) +void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batch_texture, bool rigged) { assertInitialized(); gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; if (rigged) { - mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, mask, texture, batch_texture); + mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); } else { - mFullbrightAlphaMaskPool->pushMaskBatches(type, mask, texture, batch_texture); + mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; @@ -7476,7 +7088,6 @@ void LLPipeline::renderPostProcess() { LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); assertInitialized(); @@ -7486,7 +7097,6 @@ void LLPipeline::renderPostProcess() LL_RECORD_BLOCK_TIME(FTM_RENDER_BLOOM); LL_PROFILE_GPU_ZONE("renderPostProcess"); - gGL.color4f(1, 1, 1, 1); LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); LLGLDisable cull(GL_CULL_FACE); @@ -7605,6 +7215,7 @@ void LLPipeline::renderPostProcess() } gGlowProgram.unbind(); + gGL.setSceneBlendType(LLRender::BT_ALPHA); } else // !sRenderGlow, skip the glow ping-pong and just clear the result target { @@ -7920,7 +7531,6 @@ void LLPipeline::renderFinalize() { LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); assertInitialized(); @@ -7952,7 +7562,7 @@ void LLPipeline::renderFinalize() LL_PROFILE_GPU_ZONE("screen space reflections"); bindDeferredShader(gPostScreenSpaceReflectionProgram, NULL); - mScreenTriangleVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); set_camera_projection_matrix(gPostScreenSpaceReflectionProgram); @@ -7993,7 +7603,7 @@ void LLPipeline::renderFinalize() // Apply gamma correction to the frame here. gDeferredPostGammaCorrectProgram.bind(); - // mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + S32 channel = 0; channel = gDeferredPostGammaCorrectProgram.enableTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget()->getUsage()); if (channel > -1) @@ -8134,7 +7744,7 @@ void LLPipeline::renderFinalize() { U32 mask = LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0 | LLVertexBuffer::MAP_TEXCOORD1; LLPointer buff = new LLVertexBuffer(mask, 0); - buff->allocateBuffer(3, 0, TRUE); + buff->allocateBuffer(3, 0); LLStrider v; LLStrider uv1; @@ -8167,7 +7777,7 @@ void LLPipeline::renderFinalize() LLGLEnable multisample(RenderFSAASamples > 0 ? GL_MULTISAMPLE : 0); - buff->setBuffer(mask); + buff->setBuffer(); buff->drawArrays(LLRender::TRIANGLE_STRIP, 0, 3); gGlowCombineProgram.unbind(); @@ -8190,7 +7800,6 @@ void LLPipeline::renderFinalize() LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); // flush calls made to "addTrianglesDrawn" so far to stats machinery recordTrianglesDrawn(); @@ -8301,7 +7910,6 @@ void LLPipeline::bindDeferredShaderFast(LLGLSLShader& shader) void LLPipeline::bindDeferredShader(LLGLSLShader& shader, LLRenderTarget* light_target) { LL_PROFILE_ZONE_SCOPED_CATEGORY_PIPELINE; - LL_PROFILE_GPU_ZONE("bindDeferredShader"); LLRenderTarget* deferred_target = &mRT->deferredScreen; //LLRenderTarget* deferred_depth_target = &mRT->deferredDepth; LLRenderTarget* deferred_light_target = &mRT->deferredLight; @@ -8602,13 +8210,6 @@ void LLPipeline::renderDeferredLighting() glh::matrix4f mat = copy_matrix(gGLModelView); - LLStrider vert; - mDeferredVB->getVertexStrider(vert); - - vert[0].set(-1, 1, 0); - vert[1].set(-1, -3, 0); - vert[2].set(3, 1, 0); - setupHWLights(NULL); // to set mSun/MoonDir; glh::vec4f tc(mSunDir.mV); @@ -8626,7 +8227,7 @@ void LLPipeline::renderDeferredLighting() { // paint shadow/SSAO light map (direct lighting lightmap) LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - sun shadow"); bindDeferredShader(gDeferredSunProgram, deferred_light_target); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); glClearColor(1, 1, 1, 1); deferred_light_target->clear(GL_COLOR_BUFFER_BIT); glClearColor(0, 0, 0, 0); @@ -8658,9 +8259,7 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } unbindDeferredShader(gDeferredSunProgram); @@ -8690,7 +8289,7 @@ void LLPipeline::renderDeferredLighting() glClearColor(0, 0, 0, 0); bindDeferredShader(gDeferredBlurLightProgram); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); LLVector3 go = RenderShadowGaussian; const U32 kern_length = 4; F32 blur_size = RenderShadowBlurSize; @@ -8719,9 +8318,7 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } screen_target->flush(); @@ -8729,7 +8326,7 @@ void LLPipeline::renderDeferredLighting() bindDeferredShader(gDeferredBlurLightProgram, screen_target); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); deferred_light_target->bindTarget(); gDeferredBlurLightProgram.uniform2f(sDelta, 0.f, 1.f); @@ -8737,9 +8334,7 @@ void LLPipeline::renderDeferredLighting() { LLGLDisable blend(GL_BLEND); LLGLDepthTest depth(GL_TRUE, GL_FALSE, GL_ALWAYS); - stop_glerror(); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); - stop_glerror(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } deferred_light_target->flush(); unbindDeferredShader(gDeferredBlurLightProgram); @@ -8781,9 +8376,8 @@ void LLPipeline::renderDeferredLighting() // full screen blit - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } @@ -8836,10 +8430,10 @@ void LLPipeline::renderDeferredLighting() if (mCubeVB.isNull()) { - mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX, GL_STATIC_DRAW); + mCubeVB = ll_create_cube_vb(LLVertexBuffer::MAP_VERTEX); } - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mCubeVB->setBuffer(); LLGLDepthTest depth(GL_TRUE, GL_FALSE); // mNearbyLights already includes distance calculation and excludes muted avatars. @@ -8942,7 +8536,7 @@ void LLPipeline::renderDeferredLighting() LLGLDepthTest depth(GL_TRUE, GL_FALSE); bindDeferredShader(gDeferredSpotLightProgram); - mCubeVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mCubeVB->setBuffer(); gDeferredSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -8976,12 +8570,6 @@ void LLPipeline::renderDeferredLighting() unbindDeferredShader(gDeferredSpotLightProgram); } - // reset mDeferredVB to fullscreen triangle - mDeferredVB->getVertexStrider(vert); - vert[0].set(-1, 1, 0); - vert[1].set(-1, -3, 0); - vert[2].set(3, 1, 0); - { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("renderDeferredLighting - fullscreen lights"); LLGLDepthTest depth(GL_FALSE); @@ -9014,8 +8602,8 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiLightProgram[idx].uniform1f(LLShaderMgr::MULTI_LIGHT_FAR_Z, far_z); far_z = 0.f; count = 0; - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->setBuffer(); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); unbindDeferredShader(gDeferredMultiLightProgram[idx]); } } @@ -9024,7 +8612,7 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiSpotLightProgram.enableTexture(LLShaderMgr::DEFERRED_PROJECTION); - mDeferredVB->setBuffer(LLVertexBuffer::MAP_VERTEX); + mScreenTriangleVB->setBuffer(); for (LLDrawable::drawable_list_t::iterator iter = fullscreen_spot_lights.begin(); iter != fullscreen_spot_lights.end(); ++iter) { @@ -9049,7 +8637,7 @@ void LLPipeline::renderDeferredLighting() gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::DIFFUSE_COLOR, 1, col.mV); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_FALLOFF, light_falloff_final); - mDeferredVB->drawArrays(LLRender::TRIANGLES, 0, 3); + mScreenTriangleVB->drawArrays(LLRender::TRIANGLES, 0, 3); } gDeferredMultiSpotLightProgram.disableTexture(LLShaderMgr::DEFERRED_PROJECTION); @@ -9098,6 +8686,8 @@ void LLPipeline::renderDeferredLighting() } screen_target->flush(); + + gGL.setColorMask(true, true); } void LLPipeline::setupSpotLight(LLGLSLShader& shader, LLDrawable* drawablep) @@ -9534,7 +9124,7 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { if (rigged) { - renderObjects(type, LLVertexBuffer::MAP_VERTEX, FALSE, FALSE, rigged); + renderObjects(type, false, false, rigged); } else { @@ -9571,11 +9161,6 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha"); LL_PROFILE_GPU_ZONE("shadow alpha"); - U32 mask = LLVertexBuffer::MAP_VERTEX | - LLVertexBuffer::MAP_TEXCOORD0 | - LLVertexBuffer::MAP_COLOR | - LLVertexBuffer::MAP_TEXTURE_INDEX; - for (int i = 0; i < 2; ++i) { bool rigged = i == 1; @@ -9586,37 +9171,44 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha masked"); - renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, mask, TRUE, TRUE, rigged); + LL_PROFILE_GPU_ZONE("shadow alpha masked"); + renderMaskedObjects(LLRenderPass::PASS_ALPHA_MASK, true, true, rigged); } { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha blend"); + LL_PROFILE_GPU_ZONE("shadow alpha blend"); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); - renderAlphaObjects(mask, TRUE, TRUE, rigged); + renderAlphaObjects(true, true, rigged); } { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow fullbright alpha masked"); + LL_PROFILE_GPU_ZONE("shadow alpha masked"); gDeferredShadowFullbrightAlphaMaskProgram.bind(rigged); LLGLSLShader::sCurBoundShaderPtr->uniform1f(LLShaderMgr::DEFERRED_SHADOW_TARGET_WIDTH, (float)target_width); LLGLSLShader::sCurBoundShaderPtr->uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); - renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, mask, TRUE, TRUE, rigged); + renderFullbrightMaskedObjects(LLRenderPass::PASS_FULLBRIGHT_ALPHA_MASK, true, true, rigged); } { LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha grass"); + LL_PROFILE_GPU_ZONE("shadow alpha grass"); gDeferredTreeShadowProgram.bind(rigged); if (i == 0) { LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(0.598f); - renderObjects(LLRenderPass::PASS_GRASS, LLVertexBuffer::MAP_VERTEX | LLVertexBuffer::MAP_TEXCOORD0, TRUE); + renderObjects(LLRenderPass::PASS_GRASS, true); } - U32 no_idx_mask = mask & ~LLVertexBuffer::MAP_TEXTURE_INDEX; - renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, no_idx_mask, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, no_idx_mask, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, no_idx_mask, true, false, rigged); - renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, no_idx_mask, true, false, rigged); + { + LL_PROFILE_ZONE_NAMED_CATEGORY_PIPELINE("shadow alpha material"); + LL_PROFILE_GPU_ZONE("shadow alpha material"); + renderMaskedObjects(LLRenderPass::PASS_NORMSPEC_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_MATERIAL_ALPHA_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_SPECMAP_MASK, true, false, rigged); + renderMaskedObjects(LLRenderPass::PASS_NORMMAP_MASK, true, false, rigged); + } } } @@ -9634,11 +9226,11 @@ void LLPipeline::renderShadow(glh::matrix4f& view, glh::matrix4f& proj, LLCamera if (rigged) { - mAlphaMaskPool->pushRiggedGLTFBatches(type + 1, mask); + mAlphaMaskPool->pushRiggedGLTFBatches(type + 1); } else { - mAlphaMaskPool->pushGLTFBatches(type, mask); + mAlphaMaskPool->pushGLTFBatches(type); } gGL.loadMatrix(gGLModelView); @@ -9891,7 +9483,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) bool skip_avatar_update = false; if (!isAgentAvatarValid() || gAgentCamera.getCameraAnimating() || gAgentCamera.getCameraMode() != CAMERA_MODE_MOUSELOOK || !LLVOAvatar::sVisibleInFirstPerson) { - skip_avatar_update = true; } @@ -10005,12 +9596,6 @@ void LLPipeline::generateSunShadow(LLCamera& camera) clip = RenderShadowOrthoClipPlanes; mSunOrthoClipPlanes = LLVector4(clip, clip.mV[2]*clip.mV[2]/clip.mV[1]); - //if (gCubeSnapshot) - { //always do a single 64m shadow in reflection maps - mSunClipPlanes.set(64.f, 128.f, 256.f); - mSunOrthoClipPlanes.set(64.f, 128.f, 256.f); - } - //currently used for amount to extrude frusta corners for constructing shadow frusta //LLVector3 n = RenderShadowNearDist; //F32 nearDist[] = { n.mV[0], n.mV[1], n.mV[2], n.mV[2] }; @@ -10515,7 +10100,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { static LLCullResult result[4]; - renderShadow(view[j], proj[j], shadow_cam, result[j], TRUE, FALSE, target_width); + renderShadow(view[j], proj[j], shadow_cam, result[j], true, true, target_width); } mRT->shadow[j].flush(); @@ -10670,7 +10255,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) RenderSpotLight = drawable; - renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], FALSE, FALSE, target_width); + renderShadow(view[i + 4], proj[i + 4], shadow_cam, result[i], false, true, target_width); RenderSpotLight = nullptr; @@ -10698,7 +10283,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) gGL.loadMatrix(proj[1].m); gGL.matrixMode(LLRender::MM_MODELVIEW); } - gGL.setColorMask(true, false); + gGL.setColorMask(true, true); for (U32 i = 0; i < 16; i++) { @@ -10714,7 +10299,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) } } -void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) +void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, bool texture) { for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { @@ -10724,12 +10309,12 @@ void LLPipeline::renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool textu gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && group->mDrawMap.find(type) != group->mDrawMap.end()) { - pass->renderGroup(group,type,mask,texture); + pass->renderGroup(group,type,texture); } } } -void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture) +void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture) { for (LLCullResult::sg_iterator i = sCull->beginVisibleGroups(); i != sCull->endVisibleGroups(); ++i) { @@ -10739,7 +10324,7 @@ void LLPipeline::renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool gPipeline.hasRenderType(group->getSpatialPartition()->mDrawableType) && group->mDrawMap.find(type) != group->mDrawMap.end()) { - pass->renderRiggedGroup(group, type, mask, texture); + pass->renderRiggedGroup(group, type, texture); } } } @@ -10751,7 +10336,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) LL_RECORD_BLOCK_TIME(FTM_GENERATE_IMPOSTOR); LL_PROFILE_GPU_ZONE("generateImpostor"); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); static LLCullResult result; result.clear(); @@ -10977,17 +10561,10 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) if (preview_avatar) { // previews don't care about imposters - if (LLPipeline::sRenderDeferred) - { - renderGeomDeferred(camera); - renderGeomPostDeferred(camera); - } - else - { - renderGeom(camera); - } + renderGeomDeferred(camera); + renderGeomPostDeferred(camera); } - else if (LLPipeline::sRenderDeferred) + else { avatar->mImpostor.clear(); renderGeomDeferred(camera); @@ -11009,28 +10586,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) sImpostorRenderAlphaDepthPass = false; } - else - { - LLGLEnable scissor(GL_SCISSOR_TEST); - glScissor(0, 0, resX, resY); - avatar->mImpostor.clear(); - renderGeom(camera); - - // Shameless hack time: render it all again, - // this time writing the depth - // values we need to generate the alpha mask below - // while preserving the alpha-sorted color rendering - // from the previous pass - // - sImpostorRenderAlphaDepthPass = true; - - // depth-only here... - // - gGL.setColorMask(false,false); - renderGeom(camera); - - sImpostorRenderAlphaDepthPass = false; - } LLDrawPoolAvatar::sMinimumAlpha = old_alpha; @@ -11121,7 +10676,6 @@ void LLPipeline::generateImpostor(LLVOAvatar* avatar, bool preview_avatar) LLVertexBuffer::unbind(); LLGLState::checkStates(); - LLGLState::checkTextureChannels(); } bool LLPipeline::hasRenderBatches(const U32 type) const diff --git a/indra/newview/pipeline.h b/indra/newview/pipeline.h index d3793da347..689dc385ae 100644 --- a/indra/newview/pipeline.h +++ b/indra/newview/pipeline.h @@ -266,21 +266,17 @@ public: void stateSort(LLDrawable* drawablep, LLCamera& camera); void postSort(LLCamera& camera); - //update stats for textures in given DrawInfo - void touchTextures(LLDrawInfo* info); - void touchTexture(LLViewerTexture* tex, F32 vsize); - void forAllVisibleDrawables(void (*func)(LLDrawable*)); - void renderObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); void renderShadowSimple(U32 type); - void renderAlphaObjects(U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); - void renderMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); - void renderFullbrightMaskedObjects(U32 type, U32 mask, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderAlphaObjects(bool texture = true, bool batch_texture = false, bool rigged = false); + void renderMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); + void renderFullbrightMaskedObjects(U32 type, bool texture = true, bool batch_texture = false, bool rigged = false); - void renderGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); - void renderRiggedGroups(LLRenderPass* pass, U32 type, U32 mask, bool texture); + void renderGroups(LLRenderPass* pass, U32 type, bool texture); + void renderRiggedGroups(LLRenderPass* pass, U32 type, bool texture); void grabReferences(LLCullResult& result); void clearReferences(); @@ -290,9 +286,7 @@ public: void checkReferences(LLDrawable* drawable); void checkReferences(LLDrawInfo* draw_info); void checkReferences(LLSpatialGroup* group); - - - void renderGeom(LLCamera& camera, bool forceVBOUpdate = false); + void renderGeomDeferred(LLCamera& camera, bool do_occlusion = false); void renderGeomPostDeferred(LLCamera& camera); void renderGeomShadow(LLCamera& camera); -- cgit v1.3 From 473ade269628d1fb6cbc7b96a91e1c0aec1b8e59 Mon Sep 17 00:00:00 2001 From: Henri Beauchamp Date: Tue, 31 Jan 2023 17:42:51 +0100 Subject: SL-19110 Fast hashing classes for use in place of the slow LLMD5, where speed matters. (#64) This commit adds the HBXX64 and HBXX128 classes for use as a drop-in replacement for the slow LLMD5 hashing class, where speed matters and backward compatibility (with standard hashing algorithms) and/or cryptographic hashing qualities are not required. It also replaces LLMD5 with HBXX* in a few existing hot (well, ok, just "warm" for some) paths meeting the above requirements, while paving the way for future use cases, such as in the DRTVWR-559 and sibling branches where the slow LLMD5 is used (e.g. to hash materials and vertex buffer cache entries), and could be use such a (way) faster algorithm with very significant benefits and no negative impact. Here is the comment I added in indra/llcommon/hbxx.h: // HBXXH* classes are to be used where speed matters and cryptographic quality // is not required (no "one-way" guarantee, though they are likely not worst in // this respect than MD5 which got busted and is now considered too weak). The // xxHash code they are built upon is vectorized and about 50 times faster than // MD5. A 64 bits hash class is also provided for when 128 bits of entropy are // not needed. The hashes collision rate is similar to MD5's. // See https://github.com/Cyan4973/xxHash#readme for details. --- autobuild.xml | 30 ++ indra/cmake/CMakeLists.txt | 1 + indra/cmake/LLCommon.cmake | 1 + indra/cmake/xxHash.cmake | 8 + indra/llcommon/CMakeLists.txt | 2 + indra/llcommon/hbxxh.cpp | 377 +++++++++++++++++++++ indra/llcommon/hbxxh.h | 259 ++++++++++++++ indra/llcommon/lluuid.cpp | 28 +- indra/llprimitive/llmodel.cpp | 19 +- .../newview/skins/default/xui/da/floater_about.xml | 1 + .../newview/skins/default/xui/de/floater_about.xml | 1 + .../newview/skins/default/xui/en/floater_about.xml | 1 + .../newview/skins/default/xui/es/floater_about.xml | 1 + .../newview/skins/default/xui/fr/floater_about.xml | 1 + .../newview/skins/default/xui/it/floater_about.xml | 1 + .../newview/skins/default/xui/ja/floater_about.xml | 1 + .../newview/skins/default/xui/pt/floater_about.xml | 1 + .../newview/skins/default/xui/ru/floater_about.xml | 1 + .../newview/skins/default/xui/tr/floater_about.xml | 1 + .../newview/skins/default/xui/zh/floater_about.xml | 1 + 20 files changed, 704 insertions(+), 32 deletions(-) create mode 100644 indra/cmake/xxHash.cmake create mode 100644 indra/llcommon/hbxxh.cpp create mode 100644 indra/llcommon/hbxxh.h (limited to 'indra/llprimitive') diff --git a/autobuild.xml b/autobuild.xml index f749b20b5e..67c9b84af2 100644 --- a/autobuild.xml +++ b/autobuild.xml @@ -2928,6 +2928,36 @@ Copyright (c) 2012, 2014, 2015, 2016 nghttp2 contributors version 0.54.1.555529 + xxhash + + copyright + Copyright 2012-2020 Yann Collet + description + xxHash Extremely fast hash algorithm + license + bsd + license_file + LICENSES/xxhash.txt + name + xxhash + platforms + + common + + archive + + hash + f54f21dda4ce25b112f0cc7b4ce38bba + url + http://sldev.free.fr/libraries/xxhash-0.8.1-20230124.tar.bz2 + + name + common + + + version + 0.8.1 + zlib-ng canonical_repo diff --git a/indra/cmake/CMakeLists.txt b/indra/cmake/CMakeLists.txt index 4d70089737..fb3c7216c7 100644 --- a/indra/cmake/CMakeLists.txt +++ b/indra/cmake/CMakeLists.txt @@ -91,6 +91,7 @@ set(cmake_SOURCE_FILES VisualLeakDetector.cmake LibVLCPlugin.cmake XmlRpcEpi.cmake + xxHash.cmake ZLIBNG.cmake ) diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 53871791fd..528b43c3fc 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -4,6 +4,7 @@ include(APR) include(Boost) include(EXPAT) include(Tracy) +include(xxHash) include(ZLIBNG) set(LLCOMMON_INCLUDE_DIRS diff --git a/indra/cmake/xxHash.cmake b/indra/cmake/xxHash.cmake new file mode 100644 index 0000000000..a7c1cba62c --- /dev/null +++ b/indra/cmake/xxHash.cmake @@ -0,0 +1,8 @@ +# -*- cmake -*- +if (XXHASH_CMAKE_INCLUDED) + return() +endif (XXHASH_CMAKE_INCLUDED) +set (XXHASH_CMAKE_INCLUDED TRUE) + +include(Prebuilt) +use_prebuilt_binary(xxhash) diff --git a/indra/llcommon/CMakeLists.txt b/indra/llcommon/CMakeLists.txt index 991c3f70a1..fab7550c9a 100644 --- a/indra/llcommon/CMakeLists.txt +++ b/indra/llcommon/CMakeLists.txt @@ -119,6 +119,7 @@ set(llcommon_SOURCE_FILES lluriparser.cpp lluuid.cpp llworkerthread.cpp + hbxxh.cpp u64.cpp threadpool.cpp workqueue.cpp @@ -257,6 +258,7 @@ set(llcommon_HEADER_FILES llwin32headers.h llwin32headerslean.h llworkerthread.h + hbxxh.h lockstatic.h stdtypes.h stringize.h diff --git a/indra/llcommon/hbxxh.cpp b/indra/llcommon/hbxxh.cpp new file mode 100644 index 0000000000..e94581d415 --- /dev/null +++ b/indra/llcommon/hbxxh.cpp @@ -0,0 +1,377 @@ +/** + * @file hbxxh.cpp + * @brief High performances vectorized hashing based on xxHash. + * + * $LicenseInfo:firstyear=2023&license=viewergpl$ + * Second Life Viewer Source Code + * Copyright (c) 2023, Henri Beauchamp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +// This define ensures that xxHash will be compiled within this module, with +// vectorized (*) and inlined functions (with no exported API symbol); our +// xxhash "pre-built library" package actually only contains the xxhash.h +// header (no library needed at link time). +// (*) SSE2 is normally used for x86(_64) builds, unless you enabled AVX2 +// in your build, in which case the latter would be used instead. For ARM64 +// builds, this would also automatically enable NEON vectorization. +#define XXH_INLINE_ALL +#include "xxhash.h" + +#include "hbxxh.h" + +// How many bytes to grab at a time when hashing files or streams +constexpr size_t BLOCK_LEN = 4096; + +/////////////////////////////////////////////////////////////////////////////// +// HBXXH64 class +/////////////////////////////////////////////////////////////////////////////// + +//static +U64 HBXXH64::digest(const void* buffer, size_t len) +{ + return XXH3_64bits(buffer, len); +} + +//static +U64 HBXXH64::digest(const char* str) +{ + return XXH3_64bits((const void*)str, strlen(str)); +} + +//static +U64 HBXXH64::digest(const std::string& str) +{ + return XXH3_64bits((const void*)str.c_str(), str.size()); +} + +// Must be called by all constructors. +void HBXXH64::init() +{ + mDigest = 0; + mState = (void*)XXH3_createState(); + if (!mState || XXH3_64bits_reset((XXH3_state_t*)mState) != XXH_OK) + { + LL_WARNS() << "Failed to initialize state !" << LL_ENDL; + } +} + +HBXXH64::~HBXXH64() +{ + if (mState) + { + XXH3_freeState((XXH3_state_t*)mState); + } +} + +void HBXXH64::update(const void* buffer, size_t len) +{ + if (mState) + { + XXH3_64bits_update((XXH3_state_t*)mState, buffer, len); + } + else + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + } +} + +void HBXXH64::update(const std::string& str) +{ + if (mState) + { + XXH3_64bits_update((XXH3_state_t*)mState, (const void*)str.c_str(), + str.length()); + } + else + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + } +} + +void HBXXH64::update(std::istream& stream) +{ + if (!mState) + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + return; + } + + char buffer[BLOCK_LEN]; + size_t len; + while (stream.good()) + { + stream.read(buffer, BLOCK_LEN); + len = stream.gcount(); + XXH3_64bits_update((XXH3_state_t*)mState, (const void*)buffer, len); + } +} + +void HBXXH64::update(FILE* file) +{ + if (!mState) + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + return; + } + + char buffer[BLOCK_LEN]; + size_t len; + while ((len = fread((void*)buffer, 1, BLOCK_LEN, file))) + { + XXH3_64bits_update((XXH3_state_t*)mState, (const void*)buffer, len); + } + fclose(file); +} + +void HBXXH64::finalize() +{ + if (!mState) + { + LL_WARNS() << "Already finalized !" << LL_ENDL; + return; + } + mDigest = XXH3_64bits_digest((XXH3_state_t*)mState); + XXH3_freeState((XXH3_state_t*)mState); + mState = NULL; +} + +U64 HBXXH64::digest() const +{ + return mState ? XXH3_64bits_digest((XXH3_state_t*)mState) : mDigest; +} + +std::ostream& operator<<(std::ostream& stream, HBXXH64 context) +{ + stream << context.digest(); + return stream; +} + +/////////////////////////////////////////////////////////////////////////////// +// HBXXH128 class +/////////////////////////////////////////////////////////////////////////////// + +//static +LLUUID HBXXH128::digest(const void* buffer, size_t len) +{ + XXH128_hash_t hash = XXH3_128bits(buffer, len); + LLUUID id; + U64* data = (U64*)id.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; + return id; +} + +//static +LLUUID HBXXH128::digest(const char* str) +{ + XXH128_hash_t hash = XXH3_128bits((const void*)str, strlen(str)); + LLUUID id; + U64* data = (U64*)id.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; + return id; +} + +//static +LLUUID HBXXH128::digest(const std::string& str) +{ + XXH128_hash_t hash = XXH3_128bits((const void*)str.c_str(), str.size()); + LLUUID id; + U64* data = (U64*)id.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; + return id; +} + +//static +void HBXXH128::digest(LLUUID& result, const void* buffer, size_t len) +{ + XXH128_hash_t hash = XXH3_128bits(buffer, len); + U64* data = (U64*)result.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; +} + +//static +void HBXXH128::digest(LLUUID& result, const char* str) +{ + XXH128_hash_t hash = XXH3_128bits((const void*)str, strlen(str)); + U64* data = (U64*)result.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; +} + +//static +void HBXXH128::digest(LLUUID& result, const std::string& str) +{ + XXH128_hash_t hash = XXH3_128bits((const void*)str.c_str(), str.size()); + U64* data = (U64*)result.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; +} + +// Must be called by all constructors. +void HBXXH128::init() +{ + mState = (void*)XXH3_createState(); + if (!mState || XXH3_128bits_reset((XXH3_state_t*)mState) != XXH_OK) + { + LL_WARNS() << "Failed to initialize state !" << LL_ENDL; + } +} + +HBXXH128::~HBXXH128() +{ + if (mState) + { + XXH3_freeState((XXH3_state_t*)mState); + } +} + +void HBXXH128::update(const void* buffer, size_t len) +{ + if (mState) + { + XXH3_128bits_update((XXH3_state_t*)mState, buffer, len); + } + else + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + } +} + +void HBXXH128::update(const std::string& str) +{ + if (mState) + { + XXH3_128bits_update((XXH3_state_t*)mState, (const void*)str.c_str(), + str.length()); + } + else + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + } +} + +void HBXXH128::update(std::istream& stream) +{ + if (!mState) + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + return; + } + + char buffer[BLOCK_LEN]; + size_t len; + while (stream.good()) + { + stream.read(buffer, BLOCK_LEN); + len = stream.gcount(); + XXH3_128bits_update((XXH3_state_t*)mState, (const void*)buffer, len); + } +} + +void HBXXH128::update(FILE* file) +{ + if (!mState) + { + LL_WARNS() << "Cannot update a finalized digest !" << LL_ENDL; + return; + } + + char buffer[BLOCK_LEN]; + size_t len; + while ((len = fread((void*)buffer, 1, BLOCK_LEN, file))) + { + XXH3_128bits_update((XXH3_state_t*)mState, (const void*)buffer, len); + } + fclose(file); +} + +void HBXXH128::finalize() +{ + if (!mState) + { + LL_WARNS() << "Already finalized !" << LL_ENDL; + return; + } + XXH128_hash_t hash = XXH3_128bits_digest((XXH3_state_t*)mState); + U64* data = (U64*)mDigest.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; + XXH3_freeState((XXH3_state_t*)mState); + mState = NULL; +} + +const LLUUID& HBXXH128::digest() const +{ + if (mState) + { + XXH128_hash_t hash = XXH3_128bits_digest((XXH3_state_t*)mState); + // We cheat the const-ness of the method here, but this is OK, since + // mDigest is private and cannot be accessed indirectly by other + // methods than digest() ones, that do check for mState to decide + // wether mDigest's current value may be provided as is or not. This + // cheat saves us a temporary LLLUID copy. + U64* data = (U64*)mDigest.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; + } + return mDigest; +} + +void HBXXH128::digest(LLUUID& result) const +{ + if (!mState) + { + result = mDigest; + return; + } + XXH128_hash_t hash = XXH3_128bits_digest((XXH3_state_t*)mState); + U64* data = (U64*)result.mData; + // Note: we do not check endianness here and we just store in the same + // order as XXH128_hash_t, that is low word "first". + data[0] = hash.low64; + data[1] = hash.high64; +} + +std::ostream& operator<<(std::ostream& stream, HBXXH128 context) +{ + stream << context.digest(); + return stream; +} diff --git a/indra/llcommon/hbxxh.h b/indra/llcommon/hbxxh.h new file mode 100644 index 0000000000..8a5f977648 --- /dev/null +++ b/indra/llcommon/hbxxh.h @@ -0,0 +1,259 @@ +/** + * @file hbxxh.h + * @brief High performances vectorized hashing based on xxHash. + * + * $LicenseInfo:firstyear=2023&license=viewergpl$ + * Second Life Viewer Source Code + * Copyright (c) 2023, Henri Beauchamp. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#ifndef LL_HBXXH_H +#define LL_HBXXH_H + +#include "lluuid.h" + +// HBXXH* classes are to be used where speed matters and cryptographic quality +// is not required (no "one-way" guarantee, though they are likely not worst in +// this respect than MD5 which got busted and is now considered too weak). The +// xxHash code they are built upon is vectorized and about 50 times faster than +// MD5. A 64 bits hash class is also provided for when 128 bits of entropy are +// not needed. The hashes collision rate is similar to MD5's. +// See https://github.com/Cyan4973/xxHash#readme for details. + +// 64 bits hashing class + +class HBXXH64 +{ + friend std::ostream& operator<<(std::ostream&, HBXXH64); + +protected: + LOG_CLASS(HBXXH64); + +public: + inline HBXXH64() { init(); } + + // Constructors for special circumstances; they all digest the first passed + // parameter. Set 'do_finalize' to false if you do not want to finalize the + // context, which is useful/needed when you want to update() it afterwards. + // Ideally, the compiler should be smart enough to get our clue and + // optimize out the const bool test during inlining... + + inline HBXXH64(const void* buffer, size_t len, + const bool do_finalize = true) + { + init(); + update(buffer, len); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH64(const std::string& str, const bool do_finalize = true) + { + init(); + update(str); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH64(std::istream& s, const bool do_finalize = true) + { + init(); + update(s); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH64(FILE* file, const bool do_finalize = true) + { + init(); + update(file); + if (do_finalize) + { + finalize(); + } + } + + ~HBXXH64(); + + void update(const void* buffer, size_t len); + void update(const std::string& str); + void update(std::istream& s); + void update(FILE* file); + + // Note that unlike what happens with LLMD5, you do not need to finalize() + // HBXXH64 before using digest(), and you may keep updating() it even after + // you got a first digest() (the next digest would of course change after + // any update). It is still useful to use finalize() when you do not want + // to store a final digest() result in a separate U64; after this method + // has been called, digest() simply returns mDigest value. + void finalize(); + + U64 digest() const; + + // Fast static methods. Use them when hashing just one contiguous block of + // data. + static U64 digest(const void* buffer, size_t len); + static U64 digest(const char* str); // str must be NUL-terminated + static U64 digest(const std::string& str); + +private: + void init(); + +private: + // We use a void pointer to avoid including xxhash.h here for XXH3_state_t + // (which cannot either be trivially forward-declared, due to complex API + // related pre-processor macros in xxhash.h). + void* mState; + U64 mDigest; +}; + +inline bool operator==(const HBXXH64& a, const HBXXH64& b) +{ + return a.digest() == b.digest(); +} + +inline bool operator!=(const HBXXH64& a, const HBXXH64& b) +{ + return a.digest() != b.digest(); +} + +// 128 bits hashing class + +class HBXXH128 +{ + friend std::ostream& operator<<(std::ostream&, HBXXH128); + +protected: + LOG_CLASS(HBXXH128); + +public: + inline HBXXH128() { init(); } + + // Constructors for special circumstances; they all digest the first passed + // parameter. Set 'do_finalize' to false if you do not want to finalize the + // context, which is useful/needed when you want to update() it afterwards. + // Ideally, the compiler should be smart enough to get our clue and + // optimize out the const bool test during inlining... + + inline HBXXH128(const void* buffer, size_t len, + const bool do_finalize = true) + { + init(); + update(buffer, len); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH128(const std::string& str, const bool do_finalize = true) + { + init(); + update(str); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH128(std::istream& s, const bool do_finalize = true) + { + init(); + update(s); + if (do_finalize) + { + finalize(); + } + } + + inline HBXXH128(FILE* file, const bool do_finalize = true) + { + init(); + update(file); + if (do_finalize) + { + finalize(); + } + } + + ~HBXXH128(); + + void update(const void* buffer, size_t len); + void update(const std::string& str); + void update(std::istream& s); + void update(FILE* file); + + // Note that unlike what happens with LLMD5, you do not need to finalize() + // HBXXH128 before using digest(), and you may keep updating() it even + // after you got a first digest() (the next digest would of course change + // after any update). It is still useful to use finalize() when you do not + // want to store a final digest() result in a separate LLUUID; after this + // method has been called, digest() simply returns a reference on mDigest. + void finalize(); + + // We use an LLUUID for the digest, since this is a 128 bits wide native + // type available in the viewer code, making it easy to manipulate. It also + // allows to use HBXXH128 efficiently in LLUUID generate() and combine() + // methods. + const LLUUID& digest() const; + + // Here, we avoid an LLUUID copy whenever we already got one to store the + // result *and* we did not yet call finalize(). + void digest(LLUUID& result) const; + + // Fast static methods. Use them when hashing just one contiguous block of + // data. + static LLUUID digest(const void* buffer, size_t len); + static LLUUID digest(const char* str); // str must be NUL-terminated + static LLUUID digest(const std::string& str); + // Same as above, but saves you from an LLUUID copy when you already got + // one for storage use. + static void digest(LLUUID& result, const void* buffer, size_t len); + static void digest(LLUUID& result, const char* str); // str NUL-terminated + static void digest(LLUUID& result, const std::string& str); + +private: + void init(); + +private: + // We use a void pointer to avoid including xxhash.h here for XXH3_state_t + // (which cannot either be trivially forward-declared, due to complex API + // related pre-processor macros in xxhash.h). + void* mState; + LLUUID mDigest; +}; + +inline bool operator==(const HBXXH128& a, const HBXXH128& b) +{ + return a.digest() == b.digest(); +} + +inline bool operator!=(const HBXXH128& a, const HBXXH128& b) +{ + return a.digest() != b.digest(); +} + +#endif // LL_HBXXH_H diff --git a/indra/llcommon/lluuid.cpp b/indra/llcommon/lluuid.cpp index acce8366ea..8ff6c45760 100644 --- a/indra/llcommon/lluuid.cpp +++ b/indra/llcommon/lluuid.cpp @@ -40,11 +40,11 @@ #include "lluuid.h" #include "llerror.h" #include "llrand.h" -#include "llmd5.h" #include "llstring.h" #include "lltimer.h" #include "llthread.h" #include "llmutex.h" +#include "hbxxh.h" const LLUUID LLUUID::null; const LLTransactionID LLTransactionID::tnull; @@ -402,11 +402,9 @@ LLUUID LLUUID::operator^(const LLUUID& rhs) const void LLUUID::combine(const LLUUID& other, LLUUID& result) const { - LLMD5 md5_uuid; - md5_uuid.update((unsigned char*)mData, 16); - md5_uuid.update((unsigned char*)other.mData, 16); - md5_uuid.finalize(); - md5_uuid.raw_digest(result.mData); + HBXXH128 hash((const void*)mData, 16, false); // false = do not finalize + hash.update((const void*)other.mData, 16); + hash.digest(result); } LLUUID LLUUID::combine(const LLUUID &other) const @@ -857,17 +855,12 @@ void LLUUID::generate() tmp >>= 8; mData[8] = (unsigned char) tmp; - LLMD5 md5_uuid; - - md5_uuid.update(mData,16); - md5_uuid.finalize(); - md5_uuid.raw_digest(mData); + HBXXH128::digest(*this, (const void*)mData, 16); } void LLUUID::generate(const std::string& hash_string) { - LLMD5 md5_uuid((U8*)hash_string.c_str()); - md5_uuid.raw_digest(mData); + HBXXH128::digest(*this, hash_string); } U32 LLUUID::getRandomSeed() @@ -885,13 +878,8 @@ U32 LLUUID::getRandomSeed() seed[7]=(unsigned char)(pid); getSystemTime((uuid_time_t *)(&seed[8])); - LLMD5 md5_seed; - - md5_seed.update(seed,16); - md5_seed.finalize(); - md5_seed.raw_digest(seed); - - return(*(U32 *)seed); + U64 seed64 = HBXXH64((const void*)seed, 16).digest(); + return U32(seed64) ^ U32(seed64 >> 32); } BOOL LLUUID::parseUUID(const std::string& buf, LLUUID* value) diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index 206142fdd5..52fb8e3802 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -31,7 +31,7 @@ #include "llconvexdecomposition.h" #include "llsdserialize.h" #include "llvector4a.h" -#include "llmd5.h" +#include "hbxxh.h" #ifdef LL_USESYSTEMLIBS # include @@ -1564,7 +1564,7 @@ LLSD LLMeshSkinInfo::asLLSD(bool include_joints, bool lock_scale_if_joint_positi void LLMeshSkinInfo::updateHash() { // get hash of data relevant to render batches - LLMD5 hash; + HBXXH64 hash; //mJointNames for (auto& name : mJointNames) @@ -1573,24 +1573,19 @@ void LLMeshSkinInfo::updateHash() } //mJointNums - hash.update((U8*)&(mJointNums[0]), sizeof(S32) * mJointNums.size()); + hash.update((const void*)mJointNums.data(), sizeof(S32) * mJointNums.size()); //mInvBindMatrix F32* src = mInvBindMatrix[0].getF32ptr(); - for (int i = 0; i < mInvBindMatrix.size() * 16; ++i) + for (size_t i = 0, count = mInvBindMatrix.size() * 16; i < count; ++i) { S32 t = llround(src[i] * 10000.f); - hash.update((U8*)&t, sizeof(S32)); + hash.update((const void*)&t, sizeof(S32)); } - //hash.update((U8*)&(mInvBindMatrix[0]), sizeof(LLMatrix4a) * mInvBindMatrix.size()); + //hash.update((const void*)mInvBindMatrix.data(), sizeof(LLMatrix4a) * mInvBindMatrix.size()); - hash.finalize(); - - U64 digest[2]; - hash.raw_digest((U8*) digest); - - mHash = digest[0]; + mHash = hash.digest(); } U32 LLMeshSkinInfo::sizeBytes() const diff --git a/indra/newview/skins/default/xui/da/floater_about.xml b/indra/newview/skins/default/xui/da/floater_about.xml index b322e67bb7..7bcae69779 100644 --- a/indra/newview/skins/default/xui/da/floater_about.xml +++ b/indra/newview/skins/default/xui/da/floater_about.xml @@ -70,6 +70,7 @@ PCRE Copyright (c) 1997-2008 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2002 Jean-loup Gailly and Mark Adler. google-perftools Copyright (c) 2005, Google Inc. diff --git a/indra/newview/skins/default/xui/de/floater_about.xml b/indra/newview/skins/default/xui/de/floater_about.xml index b2708f7141..10ccf0d5da 100644 --- a/indra/newview/skins/default/xui/de/floater_about.xml +++ b/indra/newview/skins/default/xui/de/floater_about.xml @@ -29,6 +29,7 @@ mit Open-Source-Beiträgen von: SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga. SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com). xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly und Mark Adler. Second Life Viewer verwendet Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (und Lizenzgeber). Alle Rechte vorbehalten. Details siehe www.havok.com. diff --git a/indra/newview/skins/default/xui/en/floater_about.xml b/indra/newview/skins/default/xui/en/floater_about.xml index eb07425dfe..1ad7811d85 100644 --- a/indra/newview/skins/default/xui/en/floater_about.xml +++ b/indra/newview/skins/default/xui/en/floater_about.xml @@ -112,6 +112,7 @@ Dummy Name replaced at run time SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. Second Life Viewer uses Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (and its Licensors). All Rights Reserved. See www.havok.com for details. diff --git a/indra/newview/skins/default/xui/es/floater_about.xml b/indra/newview/skins/default/xui/es/floater_about.xml index f59f534908..e14ba32f69 100644 --- a/indra/newview/skins/default/xui/es/floater_about.xml +++ b/indra/newview/skins/default/xui/es/floater_about.xml @@ -29,6 +29,7 @@ con contribuciones de código abierto de: SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly y Mark Adler. El visor de Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (y sus licenciadores). Reservados todos los derechos. Vea los detalles en www.havok.com. diff --git a/indra/newview/skins/default/xui/fr/floater_about.xml b/indra/newview/skins/default/xui/fr/floater_about.xml index df6b61e293..09da1fb5fd 100644 --- a/indra/newview/skins/default/xui/fr/floater_about.xml +++ b/indra/newview/skins/default/xui/fr/floater_about.xml @@ -29,6 +29,7 @@ avec les contributions Open Source de : SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-Loup Gailly et Mark Adler. Le client Second Life utilise Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (et ses concédants de licence). Tous droits réservés. Pour plus de détails, consultez le site Web www.havok.com. diff --git a/indra/newview/skins/default/xui/it/floater_about.xml b/indra/newview/skins/default/xui/it/floater_about.xml index edb334e13e..7e195d3ca9 100644 --- a/indra/newview/skins/default/xui/it/floater_about.xml +++ b/indra/newview/skins/default/xui/it/floater_about.xml @@ -29,6 +29,7 @@ con contributi open source da: SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly e Mark Adler. Il Viewer Second Life utilizza Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e licenziatari). Tutti i diritti riservati. Per informazioni dettagliate, vedere www.havok.com. diff --git a/indra/newview/skins/default/xui/ja/floater_about.xml b/indra/newview/skins/default/xui/ja/floater_about.xml index 6a39d057e2..22a65003d3 100644 --- a/indra/newview/skins/default/xui/ja/floater_about.xml +++ b/indra/newview/skins/default/xui/ja/floater_about.xml @@ -29,6 +29,7 @@ PCRE Copyright (c) 1997-2012 University of Cambridge SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. +xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. Second Life ビューワでは Havok (TM) Physics が使用されています。(c)Copyright 1999-2010 Havok.com Inc. (and its Licensors).無断複写・複製・転載を禁じます。詳細については www.havok.com をご参照ください。 diff --git a/indra/newview/skins/default/xui/pt/floater_about.xml b/indra/newview/skins/default/xui/pt/floater_about.xml index 3c0ca332ac..aaed728f84 100644 --- a/indra/newview/skins/default/xui/pt/floater_about.xml +++ b/indra/newview/skins/default/xui/pt/floater_about.xml @@ -29,6 +29,7 @@ com contribuições de código aberto de: SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. O Visualizador do Second Life usa Havok (TM) Physics. (c)Copyright 1999-2010 Havok.com Inc. (e seus Licenciantes). Todos os direitos reservados. Consulte www.havok.com para obter detalhes. diff --git a/indra/newview/skins/default/xui/ru/floater_about.xml b/indra/newview/skins/default/xui/ru/floater_about.xml index 44216e0430..a65a979ccd 100644 --- a/indra/newview/skins/default/xui/ru/floater_about.xml +++ b/indra/newview/skins/default/xui/ru/floater_about.xml @@ -29,6 +29,7 @@ SDL (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib (C) 1995-2012 Jean-loup Gailly и Mark Adler. В клиенте Second Life используется технология Havok (TM) Physics. (C) 1999-2010 Havok.com Inc. (и лицензиары компании). Все права защищены. Подробнее см. веб-сайт www.havok.com. diff --git a/indra/newview/skins/default/xui/tr/floater_about.xml b/indra/newview/skins/default/xui/tr/floater_about.xml index faa504a996..40ca3707c3 100644 --- a/indra/newview/skins/default/xui/tr/floater_about.xml +++ b/indra/newview/skins/default/xui/tr/floater_about.xml @@ -29,6 +29,7 @@ açık kaynak kod katkısında bulunanlar şunlardır: SDL Telif Hakkı (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Telif Hakkı (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Telif Hakkı (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Telif Hakkı (C) 1995-2012 Jean-loup Gailly ve Mark Adler. Second Life Görüntüleyicisi Havok (TM) Fizik motorunu kullanmaktadır. (c)Telif Hakkı 1999-2010 Havok.com Inc. (ve Lisans Verenleri). Tüm Hakları Saklıdır. Ayrıntılı bilgi için bkz. www.havok.com diff --git a/indra/newview/skins/default/xui/zh/floater_about.xml b/indra/newview/skins/default/xui/zh/floater_about.xml index d7d2a52750..a56ae753d1 100644 --- a/indra/newview/skins/default/xui/zh/floater_about.xml +++ b/indra/newview/skins/default/xui/zh/floater_about.xml @@ -29,6 +29,7 @@ SDL Copyright (C) 1997, 1998, 1999, 2000, 2001, 2002 Sam Lantinga SSLeay Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com) xmlrpc-epi Copyright (C) 2000 Epinions, Inc. + xxHash Copyright (C) 2012-2020 Yann Collet. zlib Copyright (C) 1995-2012 Jean-loup Gailly and Mark Adler. 第二人生 Viewer 採用 Havok (TM) 物理引擎。 (c)Copyright 1999-2010 Havok.com Inc.(及其放照人)。 保留一切權利。 詳情見 www.havok.com。 -- cgit v1.3 From dc1dd7a274e1ce49eb68ca525eba7f2e39032fa8 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Thu, 2 Feb 2023 12:25:03 -0800 Subject: Fix some unused variable warnings in DRTVWR-559 --- indra/llprimitive/llgltfloader.cpp | 5 ++++- indra/newview/llmaterialeditor.cpp | 4 +--- 2 files changed, 5 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index 6041c9c273..fd304f7bc9 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -167,7 +167,7 @@ bool LLGLTFLoader::parseMeshes() bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh &mesh) { pModel->mLabel = mesh.name; - int pos_idx, norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx; + int pos_idx; tinygltf::Accessor indices_a, positions_a, normals_a, uv0_a, color0_a; auto prims = mesh.primitives; @@ -187,12 +187,15 @@ bool LLGLTFLoader::populateModelFromMesh(LLModel* pModel, const tinygltf::Mesh & //if (positions_buf.name } +#if 0 + int norm_idx, tan_idx, uv0_idx, uv1_idx, color0_idx, color1_idx; norm_idx = (prim.attributes.count("NORMAL") > 0) ? prim.attributes.at("NORMAL") : -1; tan_idx = (prim.attributes.count("TANGENT") > 0) ? prim.attributes.at("TANGENT") : -1; uv0_idx = (prim.attributes.count("TEXCOORDS_0") > 0) ? prim.attributes.at("TEXCOORDS_0") : -1; uv1_idx = (prim.attributes.count("TEXCOORDS_1") > 0) ? prim.attributes.at("TEXCOORDS_1") : -1; color0_idx = (prim.attributes.count("COLOR_0") > 0) ? prim.attributes.at("COLOR_0") : -1; color1_idx = (prim.attributes.count("COLOR_1") > 0) ? prim.attributes.at("COLOR_1") : -1; +#endif if (prim.mode == TINYGLTF_MODE_TRIANGLES) { diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5628327ebe..14ebfa451a 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -770,7 +770,7 @@ void LLMaterialEditor::markChangesUnsaved(U32 dirty_flag) const LLInventoryItem* item = getItem(); if (item) { - LLPermissions perm(item->getPermissions()); + //LLPermissions perm(item->getPermissions()); bool allow_modify = canModify(mObjectUUID, item); bool source_library = mObjectUUID.isNull() && gInventory.isObjectDescendentOf(mItemUUID, gInventory.getLibraryRootFolderID()); bool source_notecard = mNotecardInventoryID.notNull(); @@ -1339,7 +1339,6 @@ bool LLMaterialEditor::updateInventoryItem(const std::string &buffer, const LLUU } else if (!task_id.isNull() && !task_url.empty()) { - LLUUID object_uuid(task_id); uploadInfo = std::make_shared(task_id, item_id, LLAssetType::AT_MATERIAL, buffer, [](LLUUID itemId, LLUUID task_id, LLUUID newAssetId, LLSD) { @@ -1390,7 +1389,6 @@ void LLMaterialEditor::createInventoryItem(const std::string &buffer, const std: // gen a new uuid for this asset LLTransactionID tid; tid.generate(); // timestamp-based randomization + uniquification - LLAssetID new_asset_id = tid.makeAssetID(gAgent.getSecureSessionID()); U32 next_owner_perm = LLFloaterPerms::getNextOwnerPerms("Materials"); LLUUID parent = gInventory.findUserDefinedCategoryUUIDForType(LLFolderType::FT_MATERIAL); const U8 subtype = NO_INV_SUBTYPE; // TODO maybe use AT_SETTINGS and LLSettingsType::ST_MATERIAL ? -- cgit v1.3 From 93b1da52f56293663d9bfe5272a83a77185f4cff Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Feb 2023 14:35:09 -0600 Subject: SL-18908 Make media texture override base color and emissive texture on PBR materials when present. --- indra/llprimitive/llgltfmaterial.h | 12 +++++------- indra/llprimitive/llmaterial.cpp | 8 ++------ indra/newview/lldrawpool.cpp | 4 ++-- indra/newview/lldrawpoolalpha.cpp | 2 +- indra/newview/llface.cpp | 2 +- indra/newview/llfetchedgltfmaterial.cpp | 14 +++++++++----- indra/newview/llfetchedgltfmaterial.h | 3 ++- indra/newview/llvovolume.cpp | 5 ++++- 8 files changed, 26 insertions(+), 24 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index dec7b696f8..2bd2d34b53 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -33,7 +33,7 @@ #include "v3color.h" #include "v2math.h" #include "lluuid.h" -#include "llmd5.h" +#include "hbxxh.h" #include @@ -98,12 +98,10 @@ public: LLUUID getHash() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLMD5 md5; - md5.update((unsigned char*)this, sizeof(this)); - md5.finalize(); - LLUUID id; - md5.raw_digest(id.mData); - return id; + // HACK - hash the bytes of this object but don't include the ref count + LLUUID hash; + HBXXH128::digest(hash, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); + return hash; } enum TextureInfo : U32 diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index 0ab97a0df3..a694a666c6 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -27,7 +27,7 @@ #include "linden_common.h" #include "llmaterial.h" -#include "llmd5.h" +#include "hbxxh.h" /** * Materials cap parameters @@ -479,13 +479,9 @@ U32 LLMaterial::getShaderMask(U32 alpha_mode) LLUUID LLMaterial::getHash() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - LLMD5 md5; // HACK - hash the bytes of this LLMaterial, but trim off the S32 in LLRefCount - md5.update((unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); - md5.finalize(); LLUUID id; - md5.raw_digest(id.mData); - // *TODO: Hash the overrides + HBXXH128::digest(id, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); return id; } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index a5990492b1..e35e889a69 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -458,7 +458,7 @@ void LLRenderPass::pushGLTFBatches(U32 type) auto& mat = params.mGLTFMaterial; - mat->bind(); + mat->bind(params.mTexture); LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0); @@ -489,7 +489,7 @@ void LLRenderPass::pushRiggedGLTFBatches(U32 type) auto& mat = params.mGLTFMaterial; - mat->bind(); + mat->bind(params.mTexture); LLGLDisable cull_face(mat->mDoubleSided ? GL_CULL_FACE : 0); diff --git a/indra/newview/lldrawpoolalpha.cpp b/indra/newview/lldrawpoolalpha.cpp index 4c8d32fad2..d3d5235770 100644 --- a/indra/newview/lldrawpoolalpha.cpp +++ b/indra/newview/lldrawpoolalpha.cpp @@ -679,7 +679,7 @@ void LLDrawPoolAlpha::renderAlpha(U32 mask, bool depth_only, bool rigged) gPipeline.bindDeferredShaderFast(*target_shader); } - params.mGLTFMaterial->bind(); + params.mGLTFMaterial->bind(params.mTexture); } else { diff --git a/indra/newview/llface.cpp b/indra/newview/llface.cpp index 811f475705..45e7709409 100644 --- a/indra/newview/llface.cpp +++ b/indra/newview/llface.cpp @@ -362,7 +362,7 @@ void LLFace::switchTexture(U32 ch, LLViewerTexture* new_texture) if (ch == LLRender::DIFFUSE_MAP) { - getViewerObject()->changeTEImage(mTEOffset, new_texture) ; + getViewerObject()->changeTEImage(mTEOffset, new_texture) ; } setTexture(ch, new_texture) ; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 047f1a4965..003b373e50 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -46,7 +46,7 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() } -void LLFetchedGLTFMaterial::bind() +void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) { // glTF 2.0 Specification 3.9.4. Alpha Coverage // mAlphaCutoff is only valid for LLGLTFMaterial::ALPHA_MODE_MASK @@ -54,15 +54,19 @@ void LLFetchedGLTFMaterial::bind() LLGLSLShader* shader = LLGLSLShader::sCurBoundShaderPtr; + // override emissive and base color textures with media tex if present + LLViewerTexture* baseColorTex = media_tex ? media_tex : mBaseColorTexture; + LLViewerTexture* emissiveTex = media_tex ? media_tex : mEmissiveTexture; + if (mAlphaMode == LLGLTFMaterial::ALPHA_MODE_MASK) { min_alpha = mAlphaCutoff; } shader->uniform1f(LLShaderMgr::MINIMUM_ALPHA, min_alpha); - if (mBaseColorTexture.notNull()) + if (baseColorTex != nullptr) { - gGL.getTexUnit(0)->bindFast(mBaseColorTexture); + gGL.getTexUnit(0)->bindFast(baseColorTex); } else { @@ -89,9 +93,9 @@ void LLFetchedGLTFMaterial::bind() shader->bindTexture(LLShaderMgr::SPECULAR_MAP, LLViewerFetchedTexture::sWhiteImagep); } - if (mEmissiveTexture.notNull()) + if (emissiveTex != nullptr) { - shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, mEmissiveTexture); // PBR sRGB Emissive + shader->bindTexture(LLShaderMgr::EMISSIVE_MAP, emissiveTex); // PBR sRGB Emissive } else { diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index f784f19c4f..96f7fbea8e 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -43,7 +43,8 @@ public: void onMaterialComplete(std::function material_complete); // bind this material for rendering - void bind(); + // media_tex - optional media texture that may override the base color texture + void bind(LLViewerTexture* media_tex = nullptr); // Textures used for fetching/rendering LLPointer mBaseColorTexture; diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index 02d1654878..c9fbe680c7 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5220,13 +5220,16 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (gltf_mat != nullptr) { mat_id = gltf_mat->getHash(); // TODO: cache this hash + if (!facep->hasMedia()) + { // no media texture, face texture will be unused + tex = nullptr; + } } else { mat = facep->getTextureEntry()->getMaterialParams().get(); if (mat) { - //mat_id = facep->getTextureEntry()->getMaterialID().asUUID(); mat_id = facep->getTextureEntry()->getMaterialParams()->getHash(); } } -- cgit v1.3 From d6841c07983a46ff805ed23a7318efbf9cca3b24 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 9 Feb 2023 15:04:46 -0800 Subject: SL-19080: Update GLTF Material asset upload to v1.1, with stricter GLTF compliance and removal of unsupported features --- indra/llprimitive/CMakeLists.txt | 2 + indra/llprimitive/llgltfmaterial.cpp | 151 +++++++------- indra/llprimitive/llgltfmaterial.h | 53 +++-- indra/llprimitive/tests/llgltfmaterial_test.cpp | 255 ++++++++++++++++++++++++ indra/newview/llgltfmateriallist.cpp | 4 +- indra/newview/llmaterialeditor.cpp | 209 +++++-------------- indra/newview/llmaterialeditor.h | 9 +- indra/newview/lltinygltfhelper.cpp | 16 +- indra/newview/llviewermenufile.cpp | 8 +- indra/newview/llviewerobject.cpp | 8 +- 10 files changed, 441 insertions(+), 274 deletions(-) create mode 100644 indra/llprimitive/tests/llgltfmaterial_test.cpp (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 328b22f900..dd25c19713 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -99,6 +99,8 @@ if (LL_TESTS) SET(llprimitive_TEST_SOURCE_FILES llmediaentry.cpp llprimitive.cpp + llgltfmaterial.cpp ) + LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}") endif (LL_TESTS) diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index a8dad89292..2e920aa44e 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -31,6 +31,10 @@ // NOTE -- this should be the one and only place tiny_gltf.h is included #include "tinygltf/tiny_gltf.h" +const char* LLGLTFMaterial::ASSET_VERSION = "1.1"; +const char* LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0"; +const std::array LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" }; + const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; @@ -73,16 +77,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) { - LL_PROFILE_ZONE_SCOPED; - //have to do a manual operator= because of LLRefCount - mBaseColorId = rhs.mBaseColorId; - mNormalId = rhs.mNormalId; - mMetallicRoughnessId = rhs.mMetallicRoughnessId; - mEmissiveId = rhs.mEmissiveId; + //have to do a manual operator= because of LLRefCount + mTextureId = rhs.mTextureId; + + mTextureTransform = rhs.mTextureTransform; mBaseColor = rhs.mBaseColor; mEmissiveColor = rhs.mEmissiveColor; - + mMetallicFactor = rhs.mMetallicFactor; mRoughnessFactor = rhs.mRoughnessFactor; mAlphaCutoff = rhs.mAlphaCutoff; @@ -90,8 +92,6 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mDoubleSided = rhs.mDoubleSided; mAlphaMode = rhs.mAlphaMode; - mTextureTransform = rhs.mTextureTransform; - mOverrideDoubleSided = rhs.mOverrideDoubleSided; mOverrideAlphaMode = rhs.mOverrideAlphaMode; @@ -100,10 +100,9 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const { - return mBaseColorId == rhs.mBaseColorId && - mNormalId == rhs.mNormalId && - mMetallicRoughnessId == rhs.mMetallicRoughnessId && - mEmissiveId == rhs.mEmissiveId && + return mTextureId == rhs.mTextureId && + + mTextureTransform == rhs.mTextureTransform && mBaseColor == rhs.mBaseColor && mEmissiveColor == rhs.mEmissiveColor && @@ -115,8 +114,6 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const mDoubleSided == rhs.mDoubleSided && mAlphaMode == rhs.mAlphaMode && - mTextureTransform == rhs.mTextureTransform && - mOverrideDoubleSided == rhs.mOverrideDoubleSided && mOverrideAlphaMode == rhs.mOverrideAlphaMode; } @@ -148,6 +145,8 @@ std::string LLGLTFMaterial::asJSON(bool prettyprint) const writeToModel(model_out, 0); + // To ensure consistency in asset upload, this should be the only reference + // to WriteGltfSceneToStream in the viewer. gltf.WriteGltfSceneToStream(&model_out, str, prettyprint, false); return str.str(); @@ -164,13 +163,13 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) const tinygltf::Material& material_in = model.materials[mat_index]; // Apply base color texture - setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId); + setFromTexture(model, material_in.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR); // Apply normal map - setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId); + setFromTexture(model, material_in.normalTexture, GLTF_TEXTURE_INFO_NORMAL); // Apply metallic-roughness texture - setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId); + setFromTexture(model, material_in.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS); // Apply emissive texture - setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId); + setFromTexture(model, material_in.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE); setAlphaMode(material_in.alphaMode); mAlphaCutoff = llclamp((F32)material_in.alphaCutoff, 0.f, 1.f); @@ -264,11 +263,11 @@ std::string gltf_get_texture_image(const tinygltf::Model& model, const T& textur // *NOTE: Use template here as workaround for the different similar texture info classes template -void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out) +void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id) { LL_PROFILE_ZONE_SCOPED; const std::string uri = gltf_get_texture_image(model, texture_info); - texture_id_out.set(uri); + mTextureId[texture_info_id].set(uri); const tinygltf::Value::Object& extensions_object = texture_info.extensions; const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM); @@ -297,21 +296,24 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const tinygltf::Material& material_out = model.materials[mat_index]; // set base color texture - writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR, mBaseColorId); + writeToTexture(model, material_out.pbrMetallicRoughness.baseColorTexture, GLTF_TEXTURE_INFO_BASE_COLOR); // set normal texture - writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL, mNormalId); + writeToTexture(model, material_out.normalTexture, GLTF_TEXTURE_INFO_NORMAL); // set metallic-roughness texture - writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, mMetallicRoughnessId); + writeToTexture(model, material_out.pbrMetallicRoughness.metallicRoughnessTexture, GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS); // set emissive texture - writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE, mEmissiveId); + writeToTexture(model, material_out.emissiveTexture, GLTF_TEXTURE_INFO_EMISSIVE); + // set occlusion texture + // *NOTE: This is required for ORM materials for GLTF compliance. + // See: https://registry.khronos.org/glTF/specs/2.0/glTF-2.0.html#_material_occlusiontexture + writeToTexture(model, material_out.occlusionTexture, GLTF_TEXTURE_INFO_OCCLUSION); + material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; - + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); - material_out.emissiveFactor.resize(3); // 0 size by default - if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor()) { material_out.emissiveFactor.resize(3); @@ -323,7 +325,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.doubleSided = mDoubleSided; - // generate "extras" string tinygltf::Value::Object extras; bool write_extras = false; @@ -364,28 +365,43 @@ void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const } template -void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const +void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const { LL_PROFILE_ZONE_SCOPED; + const LLUUID& texture_id = mTextureId[texture_info_id]; const TextureTransform& transform = mTextureTransform[texture_info_id]; - if (texture_id.isNull() && transform == sDefault.mTextureTransform[0]) + const bool is_blank_transform = transform == sDefault.mTextureTransform[0]; + // Check if this material matches all the fallback values, and if so, then + // skip including it to reduce material size + if (!force_write && texture_id.isNull() && is_blank_transform) { return; } + // tinygltf will discard this texture info if there is no valid texture, + // causing potential loss of information for overrides, so ensure one is + // defined. -Cosmic,2023-01-30 gltf_allocate_texture_image(model, texture_info, texture_id.asString()); - tinygltf::Value::Object transform_map; - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ - tinygltf::Value(transform.mOffset.mV[VX]), - tinygltf::Value(transform.mOffset.mV[VY]) - })); - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({ - tinygltf::Value(transform.mScale.mV[VX]), - tinygltf::Value(transform.mScale.mV[VY]) - })); - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation); - texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); + if (!is_blank_transform) + { + tinygltf::Value::Object transform_map; + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mOffset.mV[VX]), + tinygltf::Value(transform.mOffset.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mScale.mV[VX]), + tinygltf::Value(transform.mScale.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation); + texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); + } +} + +void LLGLTFMaterial::sanitizeAssetMaterial() +{ + mTextureTransform = sDefault.mTextureTransform; } bool LLGLTFMaterial::setBaseMaterial() @@ -419,40 +435,33 @@ void LLGLTFMaterial::hackOverrideUUID(LLUUID& id) } } -void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override) +void LLGLTFMaterial::setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override) { - mBaseColorId = id; + mTextureId[texture_info] = id; if (for_override) { - hackOverrideUUID(mBaseColorId); + hackOverrideUUID(mTextureId[texture_info]); } } +void LLGLTFMaterial::setBaseColorId(const LLUUID& id, bool for_override) +{ + setTextureId(GLTF_TEXTURE_INFO_BASE_COLOR, id, for_override); +} + void LLGLTFMaterial::setNormalId(const LLUUID& id, bool for_override) { - mNormalId = id; - if (for_override) - { - hackOverrideUUID(mNormalId); - } + setTextureId(GLTF_TEXTURE_INFO_NORMAL, id, for_override); } -void LLGLTFMaterial::setMetallicRoughnessId(const LLUUID& id, bool for_override) +void LLGLTFMaterial::setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override) { - mMetallicRoughnessId = id; - if (for_override) - { - hackOverrideUUID(mMetallicRoughnessId); - } + setTextureId(GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, id, for_override); } void LLGLTFMaterial::setEmissiveId(const LLUUID& id, bool for_override) { - mEmissiveId = id; - if (for_override) - { - hackOverrideUUID(mEmissiveId); - } + setTextureId(GLTF_TEXTURE_INFO_EMISSIVE, id, for_override); } void LLGLTFMaterial::setBaseColorFactor(const LLColor4& baseColor, bool for_override) @@ -533,10 +542,7 @@ const char* LLGLTFMaterial::getAlphaMode() const void LLGLTFMaterial::setAlphaMode(S32 mode, bool for_override) { mAlphaMode = (AlphaMode) llclamp(mode, (S32) ALPHA_MODE_OPAQUE, (S32) ALPHA_MODE_MASK); - if (for_override) - { - mOverrideAlphaMode = true; - } + mOverrideAlphaMode = for_override && mAlphaMode == getDefaultAlphaMode(); } void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override) @@ -544,10 +550,7 @@ void LLGLTFMaterial::setDoubleSided(bool double_sided, bool for_override) // sure, no clamping will ever be needed for a bool, but include the // setter for consistency with the clamping API mDoubleSided = double_sided; - if (for_override) - { - mOverrideDoubleSided = true; - } + mOverrideDoubleSided = for_override && mDoubleSided == getDefaultDoubleSided(); } void LLGLTFMaterial::setTextureOffset(TextureInfo texture_info, const LLVector2& offset) @@ -640,10 +643,12 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) { LL_PROFILE_ZONE_SCOPED; - applyOverrideUUID(mBaseColorId, override_mat.mBaseColorId); - applyOverrideUUID(mNormalId, override_mat.mNormalId); - applyOverrideUUID(mMetallicRoughnessId, override_mat.mMetallicRoughnessId); - applyOverrideUUID(mEmissiveId, override_mat.mEmissiveId); + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLUUID& texture_id = mTextureId[i]; + const LLUUID& override_texture_id = override_mat.mTextureId[i]; + applyOverrideUUID(texture_id, override_texture_id); + } if (override_mat.mBaseColor != getDefaultBaseColor()) { diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index dec7b696f8..fd26e7563c 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -49,6 +49,11 @@ public: // default material for reference static const LLGLTFMaterial sDefault; + static const char* ASSET_VERSION; + static const char* ASSET_TYPE; + static const std::array ACCEPTED_ASSET_VERSIONS; + static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); } + struct TextureTransform { LLVector2 mOffset = { 0.f, 0.f }; @@ -74,10 +79,25 @@ public: bool operator==(const LLGLTFMaterial& rhs) const; bool operator!=(const LLGLTFMaterial& rhs) const { return !(*this == rhs); } - LLUUID mBaseColorId; - LLUUID mNormalId; - LLUUID mMetallicRoughnessId; - LLUUID mEmissiveId; + enum TextureInfo : U32 + { + GLTF_TEXTURE_INFO_BASE_COLOR, + GLTF_TEXTURE_INFO_NORMAL, + GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, + // *NOTE: GLTF_TEXTURE_INFO_OCCLUSION is currently ignored, in favor of + // the values specified with GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS. + // Currently, only ORM materials are supported (materials which define + // occlusion, roughness, and metallic in the same texture). + // -Cosmic,2023-01-26 + GLTF_TEXTURE_INFO_OCCLUSION = GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, + GLTF_TEXTURE_INFO_EMISSIVE, + + GLTF_TEXTURE_INFO_COUNT + }; + + std::array mTextureId; + + std::array mTextureTransform; // NOTE : initialize values to defaults according to the GLTF spec LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); @@ -106,24 +126,14 @@ public: return id; } - enum TextureInfo : U32 - { - GLTF_TEXTURE_INFO_BASE_COLOR, - GLTF_TEXTURE_INFO_NORMAL, - GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, - GLTF_TEXTURE_INFO_EMISSIVE, - - GLTF_TEXTURE_INFO_COUNT - }; - - std::array mTextureTransform; - //setters for various members (will clamp to acceptable ranges) // for_override - set to true if this value is being set as part of an override (important for handling override to default value) + void setTextureId(TextureInfo texture_info, const LLUUID& id, bool for_override = false); + void setBaseColorId(const LLUUID& id, bool for_override = false); void setNormalId(const LLUUID& id, bool for_override = false); - void setMetallicRoughnessId(const LLUUID& id, bool for_override = false); + void setOcclusionRoughnessMetallicId(const LLUUID& id, bool for_override = false); void setEmissiveId(const LLUUID& id, bool for_override = false); void setBaseColorFactor(const LLColor4& baseColor, bool for_override = false); @@ -182,6 +192,10 @@ public: void applyOverride(const LLGLTFMaterial& override_mat); + // For base materials only (i.e. assets). Clears transforms to + // default since they're not supported in assets yet. + void sanitizeAssetMaterial(); + // For material overrides only. Clears most properties to // default/fallthrough, but preserves the transforms. bool setBaseMaterial(); @@ -189,12 +203,11 @@ public: bool isClearedForBaseMaterial(); private: - template - void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id, LLUUID& texture_id_out); + void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id); template - void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, const LLUUID& texture_id) const; + void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; void setBaseMaterial(const LLGLTFMaterial& old_override_mat); }; diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp new file mode 100644 index 0000000000..4f58f4e567 --- /dev/null +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -0,0 +1,255 @@ +/** + * @file llgltfmaterial_test.cpp + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "linden_common.h" +#include "lltut.h" + +#include "../llgltfmaterial.h" +#include "lluuid.cpp" + +// Import & define single-header gltf import/export lib +#define TINYGLTF_IMPLEMENTATION +#define TINYGLTF_USE_CPP14 // default is C++ 11 + +// tinygltf by default loads image files using STB +#define STB_IMAGE_IMPLEMENTATION +// to use our own image loading: +// 1. replace this definition with TINYGLTF_NO_STB_IMAGE +// 2. provide image loader callback with TinyGLTF::SetImageLoader(LoadimageDataFunction LoadImageData, void *user_data) + +// tinygltf saves image files using STB +#define STB_IMAGE_WRITE_IMPLEMENTATION +// similarly, can override with TINYGLTF_NO_STB_IMAGE_WRITE and TinyGLTF::SetImageWriter(fxn, data) + +// Disable reading external images to prevent warnings and speed up the tests. +// We don't need this for the tests, but still need the filesystem +// implementation to be defined in order for llprimitive to link correctly. +#define TINYGLTF_NO_EXTERNAL_IMAGE 1 + +#include "tinygltf/tiny_gltf.h" + +namespace tut +{ + struct llgltfmaterial + { + }; + typedef test_group llgltfmaterial_t; + typedef llgltfmaterial_t::object llgltfmaterial_object_t; + tut::llgltfmaterial_t tut_llgltfmaterial("llgltfmaterial"); + + // A positive 32-bit float with a long string representation + constexpr F32 test_fraction = 1.09045365e-32; + // A larger positive 32-bit float for values that get zeroed if below a threshold + constexpr F32 test_fraction_big = 0.109045; + + void apply_test_material_texture_ids(LLGLTFMaterial& material) + { + material.setBaseColorId(LLUUID::generateNewID()); + material.setNormalId(LLUUID::generateNewID()); + material.setOcclusionRoughnessMetallicId(LLUUID::generateNewID()); + material.setEmissiveId(LLUUID::generateNewID()); + } + + void apply_test_material_texture_transforms(LLGLTFMaterial& material) + { + LLGLTFMaterial::TextureTransform test_transform; + test_transform.mOffset.mV[VX] = test_fraction; + test_transform.mOffset.mV[VY] = test_fraction; + test_transform.mScale.mV[VX] = test_fraction; + test_transform.mScale.mV[VY] = test_fraction; + test_transform.mRotation = test_fraction; + for (LLGLTFMaterial::TextureInfo i = LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; i = LLGLTFMaterial::TextureInfo((U32)i + 1)) + { + material.setTextureOffset(i, test_transform.mOffset); + material.setTextureScale(i, test_transform.mScale); + material.setTextureRotation(i, test_transform.mRotation); + } + } + + void apply_test_material_factors(LLGLTFMaterial& material) + { + material.setBaseColorFactor(LLColor4(test_fraction_big, test_fraction_big, test_fraction_big, test_fraction_big)); + material.setEmissiveColorFactor(LLColor3(test_fraction_big, test_fraction_big, test_fraction_big)); + material.setMetallicFactor(test_fraction); + material.setRoughnessFactor(test_fraction); + } + + LLGLTFMaterial create_test_material() + { + LLGLTFMaterial material; + + apply_test_material_texture_ids(material); + + apply_test_material_texture_transforms(material); + + apply_test_material_factors(material); + + material.setAlphaCutoff(test_fraction); + // Because this is the default value, it should append to the extras field to mark it as an override + material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE); + // Because this is the default value, it should append to the extras field to mark it as an override + material.setDoubleSided(false); + + return material; + } + + void ensure_gltf_material_serialize(const std::string& ensure_suffix, const LLGLTFMaterial& material_in) + { + const std::string json_in = material_in.asJSON(); + LLGLTFMaterial material_out; + std::string warn_msg; + std::string error_msg; + bool serialize_success = material_out.fromJSON(json_in, warn_msg, error_msg); + ensure_equals("LLGLTFMaterial serialization has no warnings: " + ensure_suffix, "", warn_msg); + ensure_equals("LLGLTFMaterial serialization has no errors: " + ensure_suffix, "", error_msg); + ensure("LLGLTFMaterial serializes successfully: " + ensure_suffix, serialize_success); + ensure("LLGLTFMaterial is preserved when deserialized: " + ensure_suffix, material_in == material_out); + const std::string json_out = material_out.asJSON(); + ensure_equals("LLGLTFMaterial is preserved when serialized: " + ensure_suffix, json_in, json_out); + } + + void ensure_gltf_material_trimmed(const std::string& material_json, const std::string& must_not_contain) + { + ensure("LLGLTFMaterial serialization trims property '" + must_not_contain + "'", material_json.find(must_not_contain) == std::string::npos); + } + + // Test that GLTF material fields have not changed since these tests were written + template<> template<> + void llgltfmaterial_object_t::test<1>() + { + if (sizeof(void*) > 4) // Don't bother running this test for 32-bit systems + { + // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) + ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216); + } + ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4); + } + + // Test that occlusion and metallicRoughness are the same (They are different for asset validation. See lluploadmaterial.cpp) + template<> template<> + void llgltfmaterial_object_t::test<2>() + { + ensure_equals("LLGLTFMaterial occlusion does not differ from metallic roughness", LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS, LLGLTFMaterial::GLTF_TEXTURE_INFO_OCCLUSION); + } + + // Ensure double sided and alpha mode overrides serialize as expected + template<> template<> + void llgltfmaterial_object_t::test<3>() + { + const bool doubleSideds[] { false, true }; + const LLGLTFMaterial::AlphaMode alphaModes[] { LLGLTFMaterial::ALPHA_MODE_OPAQUE, LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK }; + const bool forOverrides[] { false, true }; + + for (bool doubleSided : doubleSideds) + { + for (bool forOverride : forOverrides) + { + LLGLTFMaterial material; + material.setDoubleSided(doubleSided, forOverride); + const bool overrideBit = (doubleSided == false) && forOverride; + ensure_equals("LLGLTFMaterial: double sided = " + std::to_string(doubleSided) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideDoubleSided, overrideBit); + ensure_gltf_material_serialize("double sided = " + std::to_string(doubleSided), material); + } + } + + for (LLGLTFMaterial::AlphaMode alphaMode : alphaModes) + { + for (bool forOverride : forOverrides) + { + LLGLTFMaterial material; + material.setAlphaMode(alphaMode, forOverride); + const bool overrideBit = (alphaMode == LLGLTFMaterial::ALPHA_MODE_OPAQUE) && forOverride; + ensure_equals("LLGLTFMaterial: alpha mode = " + std::to_string(alphaMode) + " override bit when forOverride = " + std::to_string(forOverride), material.mOverrideAlphaMode, overrideBit); + ensure_gltf_material_serialize("alpha mode = " + std::to_string(alphaMode), material); + } + } + } + + // Test that a GLTF material's transform components serialize as expected + template<> template<> + void llgltfmaterial_object_t::test<4>() + { + LLGLTFMaterial material; + LLGLTFMaterial::TextureTransform& transform = material.mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]; + transform.mOffset[VX] = 1.f; + transform.mOffset[VY] = 2.f; + transform.mScale[VX] = 0.05f; + transform.mScale[VY] = 100.f; + transform.mRotation = 1.571f; + ensure_gltf_material_serialize("material with transform", material); + } + + // Test that a GLTF material avoids serializing a material unnecessarily + template<> template<> + void llgltfmaterial_object_t::test<5>() + { + { + const LLGLTFMaterial material; + const std::string material_json = material.asJSON(); + ensure_gltf_material_trimmed(material_json, "pbrMetallicRoughness"); + ensure_gltf_material_trimmed(material_json, "normalTexture"); + ensure_gltf_material_trimmed(material_json, "emissiveTexture"); + ensure_gltf_material_trimmed(material_json, "occlusionTexture"); + } + + { + LLGLTFMaterial metallic_factor_material; + metallic_factor_material.setMetallicFactor(0.5); + const std::string metallic_factor_material_json = metallic_factor_material.asJSON(); + ensure_gltf_material_trimmed(metallic_factor_material_json, "baseColorTexture"); + ensure_gltf_material_trimmed(metallic_factor_material_json, "metallicRoughnessTexture"); + } + } + + // Test that a GLTF material preserves values on serialization + template<> template<> + void llgltfmaterial_object_t::test<6>() + { + { + const LLGLTFMaterial full_material = create_test_material(); + ensure_gltf_material_serialize("full material", full_material); + } + + { + LLGLTFMaterial texture_ids_only_material; + apply_test_material_texture_ids(texture_ids_only_material); + ensure_gltf_material_serialize("material with texture IDs only", texture_ids_only_material); + } + + { + LLGLTFMaterial texture_transforms_only_material; + apply_test_material_texture_ids(texture_transforms_only_material); + ensure_gltf_material_serialize("material with texture transforms only", texture_transforms_only_material); + } + + { + LLGLTFMaterial factors_only_material; + apply_test_material_factors(factors_only_material); + ensure_gltf_material_serialize("material with scaling/tint factors only", factors_only_material); + } + } +} diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index bc094ac838..4051521ad4 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -564,9 +564,9 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp if (LLSDSerialize::deserialize(asset, str, buffer.size())) { - if (asset.has("version") && asset["version"] == "1.0") + if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString())) { - if (asset.has("type") && asset["type"].asString() == "GLTF 2.0") + if (asset.has("type") && asset["type"].asString() == LLGLTFMaterial::ASSET_TYPE) { if (asset.has("data") && asset["data"].isString()) { diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 5628327ebe..173f5620c6 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -277,10 +277,10 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) llassert(mat.notNull()); // by this point shouldn't be null if (mat.notNull()) { - tex_color_id = mat->mBaseColorId; - tex_metal_id = mat->mMetallicRoughnessId; - tex_emissive_id = mat->mEmissiveId; - tex_normal_id = mat->mNormalId; + tex_color_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]; + tex_metal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]; + tex_emissive_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]; + tex_normal_id = mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]; } if (mFirst) { @@ -949,7 +949,7 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { - nodep->mSavedGLTFOverrideMaterials[te]->setMetallicRoughnessId(mCtrl->getValue().asUUID(), true); + nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true); break; } case MATERIAL_EMISIVE_TEX_DIRTY: @@ -991,30 +991,6 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ LLSelectMgr::getInstance()->getSelection()->applyToNodes(&func); } -static void write_color(const LLColor4& color, std::vector& c) -{ - for (int i = 0; i < c.size(); ++i) // NOTE -- use c.size because some gltf colors are 3-component - { - c[i] = color.mV[i]; - } -} - -static U32 write_texture(const LLUUID& id, tinygltf::Model& model) -{ - tinygltf::Image image; - image.uri = id.asString(); - model.images.push_back(image); - U32 image_idx = model.images.size() - 1; - - tinygltf::Texture texture; - texture.source = image_idx; - model.textures.push_back(texture); - U32 texture_idx = model.textures.size() - 1; - - return texture_idx; -} - - void LLMaterialEditor::onClickSave() { if (!capabilitiesAvailable()) @@ -1034,109 +1010,14 @@ void LLMaterialEditor::onClickSave() saveIfNeeded(); } - -std::string LLMaterialEditor::getGLTFJson(bool prettyprint) -{ - tinygltf::Model model; - getGLTFModel(model); - - std::ostringstream str; - - tinygltf::TinyGLTF gltf; - - gltf.WriteGltfSceneToStream(&model, str, prettyprint, false); - - std::string dump = str.str(); - - return dump; -} - -void LLMaterialEditor::getGLBData(std::vector& data) -{ - tinygltf::Model model; - getGLTFModel(model); - - std::ostringstream str; - - tinygltf::TinyGLTF gltf; - - gltf.WriteGltfSceneToStream(&model, str, false, true); - - std::string dump = str.str(); - - data.resize(dump.length()); - - memcpy(&data[0], dump.c_str(), dump.length()); -} - -void LLMaterialEditor::getGLTFModel(tinygltf::Model& model) -{ - model.materials.resize(1); - tinygltf::PbrMetallicRoughness& pbrMaterial = model.materials[0].pbrMetallicRoughness; - - // write base color - LLColor4 base_color = getBaseColor(); - base_color.mV[3] = getTransparency(); - write_color(base_color, pbrMaterial.baseColorFactor); - - model.materials[0].alphaCutoff = getAlphaCutoff(); - model.materials[0].alphaMode = getAlphaMode(); - - LLUUID base_color_id = getBaseColorId(); - - if (base_color_id.notNull()) - { - U32 texture_idx = write_texture(base_color_id, model); - - pbrMaterial.baseColorTexture.index = texture_idx; - } - - // write metallic/roughness - F32 metalness = getMetalnessFactor(); - F32 roughness = getRoughnessFactor(); - - pbrMaterial.metallicFactor = metalness; - pbrMaterial.roughnessFactor = roughness; - - LLUUID mr_id = getMetallicRoughnessId(); - if (mr_id.notNull()) - { - U32 texture_idx = write_texture(mr_id, model); - pbrMaterial.metallicRoughnessTexture.index = texture_idx; - } - - //write emissive - LLColor4 emissive_color = getEmissiveColor(); - model.materials[0].emissiveFactor.resize(3); - write_color(emissive_color, model.materials[0].emissiveFactor); - - LLUUID emissive_id = getEmissiveId(); - if (emissive_id.notNull()) - { - U32 idx = write_texture(emissive_id, model); - model.materials[0].emissiveTexture.index = idx; - } - - //write normal - LLUUID normal_id = getNormalId(); - if (normal_id.notNull()) - { - U32 idx = write_texture(normal_id, model); - model.materials[0].normalTexture.index = idx; - } - - //write doublesided - model.materials[0].doubleSided = getDoubleSided(); - - model.asset.version = "2.0"; -} - std::string LLMaterialEditor::getEncodedAsset() { LLSD asset; - asset["version"] = "1.0"; - asset["type"] = "GLTF 2.0"; - asset["data"] = getGLTFJson(false); + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + LLGLTFMaterial mat; + getGLTFMaterial(&mat); + asset["data"] = mat.asJSON(); std::ostringstream str; LLSDSerialize::serialize(asset, str, LLSDSerialize::LLSD_BINARY); @@ -1151,9 +1032,9 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) std::istrstream str(&buffer[0], buffer.size()); if (LLSDSerialize::deserialize(asset, str, buffer.size())) { - if (asset.has("version") && asset["version"] == "1.0") + if (asset.has("version") && LLGLTFMaterial::isAcceptedVersion(asset["version"].asString())) { - if (asset.has("type") && asset["type"] == "GLTF 2.0") + if (asset.has("type") && asset["type"] == LLGLTFMaterial::ASSET_TYPE) { if (asset.has("data") && asset["data"].isString()) { @@ -1169,6 +1050,12 @@ bool LLMaterialEditor::decodeAsset(const std::vector& buffer) if (loader.LoadASCIIFromString(&model_in, &error_msg, &warn_msg, data.c_str(), data.length(), "")) { // assets are only supposed to have one item + // *NOTE: This duplicates some functionality from + // LLGLTFMaterial::fromJSON, but currently does the job + // better for the material editor use case. + // However, LLGLTFMaterial::asJSON should always be + // used when uploading materials, to ensure the + // asset is valid. return setFromGltfModel(model_in, 0, true); } else @@ -1977,7 +1864,9 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con { // don't use override material here, it has 'hacked ids' // and values, use end result, apply it on top of local. - me->setBaseColor(render_material->mBaseColor); + const LLColor4& base_color = render_material->mBaseColor; + me->setBaseColor(LLColor3(base_color)); + me->setTransparency(base_color[VW]); me->setMetalnessFactor(render_material->mMetallicFactor); me->setRoughnessFactor(render_material->mRoughnessFactor); me->setEmissiveColor(render_material->mEmissiveColor); @@ -1988,24 +1877,24 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con // most things like colors we can apply without verifying // but texture ids are going to be different from both, base and override // so only apply override id if there is actually a difference - if (local_material->mBaseColorId != render_material->mBaseColorId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) { - me->setBaseColorId(render_material->mBaseColorId); + me->setBaseColorId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); me->childSetValue("base_color_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mNormalId != render_material->mNormalId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) { - me->setNormalId(render_material->mNormalId); + me->setNormalId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); me->childSetValue("normal_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mMetallicRoughnessId != render_material->mMetallicRoughnessId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) { - me->setMetallicRoughnessId(render_material->mMetallicRoughnessId); + me->setMetallicRoughnessId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); me->childSetValue("metallic_upload_fee", me->getString("no_upload_fee_string")); } - if (local_material->mEmissiveId != render_material->mEmissiveId) + if (local_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] != render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) { - me->setEmissiveId(render_material->mEmissiveId); + me->setEmissiveId(render_material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); me->childSetValue("emissive_upload_fee", me->getString("no_upload_fee_string")); } @@ -2019,7 +1908,11 @@ void LLMaterialEditor::saveMaterialAs(const LLGLTFMaterial* render_material, con LLSD payload; if (render_material) { - payload["data"] = render_material->asJSON(); + // Make a copy of the render material with unsupported transforms removed + LLGLTFMaterial asset_material = *render_material; + asset_material.sanitizeAssetMaterial(); + // Serialize the sanitized render material + payload["data"] = asset_material.asJSON(); } else { @@ -2042,8 +1935,9 @@ void LLMaterialEditor::onSaveObjectsMaterialAsMsgCallback(const LLSD& notificati if (0 == option) { LLSD asset; - asset["version"] = "1.0"; - asset["type"] = "GLTF 2.0"; + asset["version"] = LLGLTFMaterial::ASSET_VERSION; + asset["type"] = LLGLTFMaterial::ASSET_TYPE; + // This is the string serialized from LLGLTFMaterial::asJSON asset["data"] = notification["payload"]["data"]; std::ostringstream str; @@ -2586,7 +2480,7 @@ public: } else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull()) { - material->setBaseColorId(revert_mat->mBaseColorId, false); + material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false); } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) @@ -2595,16 +2489,16 @@ public: } else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull()) { - material->setNormalId(revert_mat->mNormalId, false); + material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { - material->setMetallicRoughnessId(mEditor->getMetallicRoughnessId(), true); + material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true); } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull()) { - material->setMetallicRoughnessId(revert_mat->mMetallicRoughnessId, false); + material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false); } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2640,7 +2534,7 @@ public: } else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull()) { - material->setEmissiveId(revert_mat->mEmissiveId, false); + material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false); } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -2753,20 +2647,23 @@ void LLMaterialEditor::applyToSelection() } } +// Get a dump of the json representation of the current state of the editor UI +// in GLTF format, excluding transforms as they are not supported in material +// assets. (See also LLGLTFMaterial::sanitizeAssetMaterial()) void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) { mat->mBaseColor = getBaseColor(); mat->mBaseColor.mV[3] = getTransparency(); - mat->mBaseColorId = getBaseColorId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = getBaseColorId(); - mat->mNormalId = getNormalId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = getNormalId(); - mat->mMetallicRoughnessId = getMetallicRoughnessId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = getMetallicRoughnessId(); mat->mMetallicFactor = getMetalnessFactor(); mat->mRoughnessFactor = getRoughnessFactor(); mat->mEmissiveColor = getEmissiveColor(); - mat->mEmissiveId = getEmissiveId(); + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = getEmissiveId(); mat->mDoubleSided = getDoubleSided(); mat->setAlphaMode(getAlphaMode()); @@ -2776,15 +2673,15 @@ void LLMaterialEditor::getGLTFMaterial(LLGLTFMaterial* mat) void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) { setBaseColor(mat->mBaseColor); - setBaseColorId(mat->mBaseColorId); - setNormalId(mat->mNormalId); + setBaseColorId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + setNormalId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); - setMetallicRoughnessId(mat->mMetallicRoughnessId); + setMetallicRoughnessId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); setMetalnessFactor(mat->mMetallicFactor); setRoughnessFactor(mat->mRoughnessFactor); setEmissiveColor(mat->mEmissiveColor); - setEmissiveId(mat->mEmissiveId); + setEmissiveId(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 74c776031e..0401190773 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -84,8 +84,7 @@ protected: }; class LLMaterialEditor : public LLPreview, public LLVOInventoryListener -{ -public: +{ public: LLMaterialEditor(const LLSD& key); bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false); @@ -98,6 +97,7 @@ public: // for live preview, apply current material to currently selected object void applyToSelection(); + // get a dump of the json representation of the current state of the editor UI as a material object void getGLTFMaterial(LLGLTFMaterial* mat); void loadAsset() override; @@ -131,11 +131,6 @@ public: void onClickSave(); - // get a dump of the json representation of the current state of the editor UI in GLTF format - std::string getGLTFJson(bool prettyprint = true); - - void getGLBData(std::vector& data); - void getGLTFModel(tinygltf::Model& model); std::string getEncodedAsset(); diff --git a/indra/newview/lltinygltfhelper.cpp b/indra/newview/lltinygltfhelper.cpp index 611911014a..1a8e868d11 100644 --- a/indra/newview/lltinygltfhelper.cpp +++ b/indra/newview/lltinygltfhelper.cpp @@ -309,48 +309,48 @@ bool LLTinyGLTFHelper::getMaterialFromFile( if (base_color_tex) { base_color_tex->addTextureStats(64.f * 64.f, TRUE); - material->mBaseColorId = base_color_tex->getID(); + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = base_color_tex->getID(); material->mBaseColorTexture = base_color_tex; } else { - material->mBaseColorId = LLUUID::null; + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = LLUUID::null; material->mBaseColorTexture = nullptr; } if (normal_tex) { normal_tex->addTextureStats(64.f * 64.f, TRUE); - material->mNormalId = normal_tex->getID(); + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = normal_tex->getID(); material->mNormalTexture = normal_tex; } else { - material->mNormalId = LLUUID::null; + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = LLUUID::null; material->mNormalTexture = nullptr; } if (mr_tex) { mr_tex->addTextureStats(64.f * 64.f, TRUE); - material->mMetallicRoughnessId = mr_tex->getID(); + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = mr_tex->getID(); material->mMetallicRoughnessTexture = mr_tex; } else { - material->mMetallicRoughnessId = LLUUID::null; + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = LLUUID::null; material->mMetallicRoughnessTexture = nullptr; } if (emissive_tex) { emissive_tex->addTextureStats(64.f * 64.f, TRUE); - material->mEmissiveId = emissive_tex->getID(); + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = emissive_tex->getID(); material->mEmissiveTexture = emissive_tex; } else { - material->mEmissiveId = LLUUID::null; + material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = LLUUID::null; material->mEmissiveTexture = nullptr; } diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp index 84b0010545..9743f00ab8 100644 --- a/indra/newview/llviewermenufile.cpp +++ b/indra/newview/llviewermenufile.cpp @@ -543,19 +543,19 @@ bool get_bulk_upload_expected_cost(const std::vector& filenames, S3 // Todo: make it account for possibility of same texture in different // materials and even in scope of same material S32 texture_count = 0; - if (material->mBaseColorId.notNull()) + if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull()) { texture_count++; } - if (material->mMetallicRoughnessId.notNull()) + if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull()) { texture_count++; } - if (material->mNormalId.notNull()) + if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull()) { texture_count++; } - if (material->mEmissiveId.notNull()) + if (material->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull()) { texture_count++; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 5a365c79ea..88d5d50845 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -4993,10 +4993,10 @@ void LLViewerObject::updateTEMaterialTextures(U8 te) if (mat != nullptr) { - mat->mBaseColorTexture = fetch_texture(mat->mBaseColorId); - mat->mNormalTexture = fetch_texture(mat->mNormalId); - mat->mMetallicRoughnessTexture = fetch_texture(mat->mMetallicRoughnessId); - mat->mEmissiveTexture= fetch_texture(mat->mEmissiveId); + mat->mBaseColorTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mMetallicRoughnessTexture = fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); + mat->mEmissiveTexture= fetch_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); } } -- cgit v1.3 From a56385345f3fb261b8c2c375960f1328c296ebf2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 9 Feb 2023 16:13:57 -0800 Subject: SL-19080: Address clang-provided errors --- indra/llprimitive/llgltfmaterial.cpp | 2 +- indra/llprimitive/llgltfmaterial.h | 2 +- indra/llprimitive/tests/llgltfmaterial_test.cpp | 2 -- 3 files changed, 2 insertions(+), 4 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 2e920aa44e..291e2c2bf5 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -33,7 +33,7 @@ const char* LLGLTFMaterial::ASSET_VERSION = "1.1"; const char* LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0"; -const std::array LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" }; +const std::array LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" }; const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index fd26e7563c..89c7f75c44 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -51,7 +51,7 @@ public: static const char* ASSET_VERSION; static const char* ASSET_TYPE; - static const std::array ACCEPTED_ASSET_VERSIONS; + static const std::array ACCEPTED_ASSET_VERSIONS; static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); } struct TextureTransform diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 4f58f4e567..5ef88c8119 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -23,8 +23,6 @@ * $/LicenseInfo$ */ -#pragma once - #include "linden_common.h" #include "lltut.h" -- cgit v1.3 From d2a2541de598f8d85dba28e88f0b44ccdcdd6ba6 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 10 Feb 2023 17:07:05 -0800 Subject: SL-19080: Restrict LLGLTFMaterial fields test to a single compiler target, as results can vary between compilers --- indra/llprimitive/tests/llgltfmaterial_test.cpp | 3 +++ 1 file changed, 3 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 5ef88c8119..859cf99e3a 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -142,7 +142,10 @@ namespace tut if (sizeof(void*) > 4) // Don't bother running this test for 32-bit systems { // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) + // This test result will vary between compilers, so only test a single platform +#if LL_WINDOWS ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216); +#endif } ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4); } -- cgit v1.3 From b66c95e487303f9e566b2cbc85fc26676a48ce66 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 10 Feb 2023 16:08:23 -0800 Subject: SL-19121: Add some override tests --- indra/llprimitive/tests/llgltfmaterial_test.cpp | 87 +++++++++++++++++++++++++ 1 file changed, 87 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 859cf99e3a..97aa544c60 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -253,4 +253,91 @@ namespace tut ensure_gltf_material_serialize("material with scaling/tint factors only", factors_only_material); } } + + // Test that sDefault is a no-op override + template<> template<> + void llgltfmaterial_object_t::test<7>() + { + const LLGLTFMaterial material_asset = create_test_material(); + LLGLTFMaterial render_material = material_asset; + render_material.applyOverride(LLGLTFMaterial::sDefault); + ensure("LLGLTFMaterial: sDefault is a no-op override", material_asset == render_material); + } + + // Test application of transform overrides + template<> template<> + void llgltfmaterial_object_t::test<8>() + { + LLGLTFMaterial override_material; + apply_test_material_texture_transforms(override_material); + LLGLTFMaterial render_material; + render_material.applyOverride(override_material); + ensure("LLGLTFMaterial: transform overrides", render_material == override_material); + } + + // Test application of flag-based overrides + template<> template<> + void llgltfmaterial_object_t::test<9>() + { + { + LLGLTFMaterial override_material; + override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, true); + override_material.setDoubleSided(true, true); + + LLGLTFMaterial render_material; + + render_material.applyOverride(override_material); + + ensure("LLGLTFMaterial: extra overrides with non-default values applied over default", render_material == override_material); + } + { + LLGLTFMaterial override_material; + override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true); + override_material.setDoubleSided(false, true); + + LLGLTFMaterial render_material; + override_material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_BLEND, false); + override_material.setDoubleSided(true, false); + + render_material.applyOverride(override_material); + // Not interested in these flags for equality comparison + override_material.mOverrideDoubleSided = false; + override_material.mOverrideAlphaMode = false; + + ensure("LLGLTFMaterial: extra overrides with default values applied over non-default", render_material == override_material); + } + } + + // Test application of texture overrides + template<> template<> + void llgltfmaterial_object_t::test<10>() + { + const U32 texture_count = 2; + const LLUUID override_textures[texture_count] = { LLUUID::null, LLUUID::generateNewID() }; + const LLUUID asset_textures[texture_count] = { LLUUID::generateNewID(), LLUUID::null }; + for (U32 i = 0; i < texture_count; ++i) + { + LLGLTFMaterial override_material; + const LLUUID& override_texture = override_textures[i]; + for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1)) + { + override_material.setTextureId(j, override_texture, true); + } + + LLGLTFMaterial render_material; + const LLUUID& asset_texture = asset_textures[i]; + for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1)) + { + render_material.setTextureId(j, asset_texture, false); + } + + render_material.applyOverride(override_material); + + for (LLGLTFMaterial::TextureInfo j = LLGLTFMaterial::TextureInfo(0); j < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; j = LLGLTFMaterial::TextureInfo(U32(j) + 1)) + { + const LLUUID& render_texture = render_material.mTextureId[j]; + ensure_equals("LLGLTFMaterial: Override texture ID " + override_texture.asString() + " replaces underlying texture ID " + asset_texture.asString(), render_texture, override_texture); + } + } + } } -- cgit v1.3 From df440f3f33a277f927035d051bc98341227bbea5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 14 Feb 2023 15:33:52 -0800 Subject: SL-19121: Address review comments from SL-19080 phase 2 --- indra/llprimitive/llgltfmaterial.cpp | 12 ++++++------ indra/llprimitive/llgltfmaterial.h | 4 ++-- indra/llprimitive/tests/llgltfmaterial_test.cpp | 11 +++++------ 3 files changed, 13 insertions(+), 14 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 291e2c2bf5..4d7b10982a 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -31,14 +31,14 @@ // NOTE -- this should be the one and only place tiny_gltf.h is included #include "tinygltf/tiny_gltf.h" -const char* LLGLTFMaterial::ASSET_VERSION = "1.1"; -const char* LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0"; +const char* const LLGLTFMaterial::ASSET_VERSION = "1.1"; +const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0"; const std::array LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" }; -const char* GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; -const char* GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; -const char* GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; -const char* GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; +const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; +const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; +const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; +const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; // special UUID that indicates a null UUID in override data static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a3e0c0d9ca..cae7284421 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -49,8 +49,8 @@ public: // default material for reference static const LLGLTFMaterial sDefault; - static const char* ASSET_VERSION; - static const char* ASSET_TYPE; + static const char* const ASSET_VERSION; + static const char* const ASSET_TYPE; static const std::array ACCEPTED_ASSET_VERSIONS; static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); } diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index 97aa544c60..b3f56788f7 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -139,14 +139,13 @@ namespace tut template<> template<> void llgltfmaterial_object_t::test<1>() { - if (sizeof(void*) > 4) // Don't bother running this test for 32-bit systems - { - // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) - // This test result will vary between compilers, so only test a single platform +#if ADDRESS_SIZE != 32 #if LL_WINDOWS - ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216); + // If any fields are added/changed, these tests should be updated (consider also updating ASSET_VERSION in LLGLTFMaterial) + // This test result will vary between compilers, so only test a single platform + ensure_equals("fields supported for GLTF (sizeof check)", sizeof(LLGLTFMaterial), 216); +#endif #endif - } ensure_equals("LLGLTFMaterial texture info count", (U32)LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT, 4); } -- cgit v1.3 From d1531eb2cec851e663e1bdde2e2858a939a6cb81 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Tue, 14 Feb 2023 15:44:02 -0800 Subject: SL-19121: Add additional test at request of review --- indra/llprimitive/tests/llgltfmaterial_test.cpp | 27 +++++++++++++++++++++++++ 1 file changed, 27 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/tests/llgltfmaterial_test.cpp b/indra/llprimitive/tests/llgltfmaterial_test.cpp index b3f56788f7..88b6fae3a7 100644 --- a/indra/llprimitive/tests/llgltfmaterial_test.cpp +++ b/indra/llprimitive/tests/llgltfmaterial_test.cpp @@ -339,4 +339,31 @@ namespace tut } } } + + // Test non-persistence of default value flags in overrides + template<> template<> + void llgltfmaterial_object_t::test<11>() + { + const S32 non_default_alpha_modes[] = { LLGLTFMaterial::ALPHA_MODE_BLEND, LLGLTFMaterial::ALPHA_MODE_MASK }; + for (S32 non_default_alpha_mode : non_default_alpha_modes) + { + LLGLTFMaterial material; + // Set default alpha mode + material.setAlphaMode(LLGLTFMaterial::ALPHA_MODE_OPAQUE, true); + ensure_equals("LLGLTFMaterial: alpha mode override flag set", material.mOverrideAlphaMode, true); + // Set non-default alpha mode + material.setAlphaMode(non_default_alpha_mode, true); + ensure_equals("LLGLTFMaterial: alpha mode override flag unset", material.mOverrideAlphaMode, false); + } + + { + // Set default double sided + LLGLTFMaterial material; + material.setDoubleSided(false, true); + ensure_equals("LLGLTFMaterial: double sided override flag set", material.mOverrideDoubleSided, true); + // Set non-default double sided + material.setDoubleSided(true, true); + ensure_equals("LLGLTFMaterial: double sided override flag unset", material.mOverrideDoubleSided, false); + } + } } -- cgit v1.3 From 6494eed242b1cf64160e379c6d40df333deae23a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 23 Feb 2023 10:58:39 -0800 Subject: SL-19228: Fix GLTF texture transform rotation and add UV debug (PBR only). See textureUtilV.glsl for UV coordinate comments --- indra/llprimitive/llgltfmaterial.cpp | 4 +- indra/llrender/llshadermgr.cpp | 5 ++ indra/newview/app_settings/settings.xml | 12 +++++ .../shaders/class1/deferred/pbralphaV.glsl | 29 +++++++++--- .../shaders/class1/deferred/pbrglowV.glsl | 6 ++- .../shaders/class1/deferred/pbropaqueF.glsl | 14 ++++++ .../shaders/class1/deferred/pbropaqueV.glsl | 30 +++++++++--- .../shaders/class1/deferred/textureUtilV.glsl | 55 ++++++++++++++++++++++ .../shaders/class2/deferred/pbralphaF.glsl | 14 ++++++ indra/newview/llviewercontrol.cpp | 1 + indra/newview/llviewershadermgr.cpp | 18 +++++++ indra/newview/skins/default/xui/en/menu_viewer.xml | 10 ++++ 12 files changed, 181 insertions(+), 17 deletions(-) create mode 100644 indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 4d7b10982a..d0ecf611ff 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -54,8 +54,8 @@ LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() const F32 cos_r = cos(mRotation); const F32 sin_r = sin(mRotation); rotation.mMatrix[0][0] = cos_r; - rotation.mMatrix[0][1] = sin_r; - rotation.mMatrix[1][0] = -sin_r; + rotation.mMatrix[0][1] = -sin_r; + rotation.mMatrix[1][0] = sin_r; rotation.mMatrix[1][1] = cos_r; LLMatrix3 offset; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 6cada320fa..13074032e0 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -177,6 +177,11 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) return FALSE; } } + + if (!shader->attachVertexObject("deferred/textureUtilV.glsl")) + { + return FALSE; + } /////////////////////////////////////// // Attach Fragment Shader Features Next diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 304932dd1a..ed6269df65 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -9727,6 +9727,18 @@ 1 + RenderDebugTexcoord + + Comment + Enables a colored debug overlay on meshes to show UV coordinates. Not all meshes support this setting. + Persist + 0 + Type + Boolean + Value + 0 + + RenderDeferredBlurLight Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index da27be6e7f..ee44ad874c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -64,6 +64,9 @@ out vec2 basecolor_texcoord; out vec2 normal_texcoord; out vec2 metallic_roughness_texcoord; out vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +out vec2 original_texcoord; +#endif out vec4 vertex_color; @@ -71,6 +74,8 @@ out vec3 vary_tangent; flat out float vary_sign; out vec3 vary_normal; +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform); + void main() { @@ -90,10 +95,13 @@ void main() vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); #endif - basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy; - normal_texcoord = (texture_matrix0 * vec4(texture_normal_matrix * vec3(texcoord0,1), 1)).xy; - metallic_roughness_texcoord = (texture_matrix0 * vec4(texture_metallic_roughness_matrix * vec3(texcoord0,1), 1)).xy; - emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy; + basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); + normal_texcoord = texture_transform(texcoord0, texture_normal_matrix, texture_matrix0); + metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_matrix, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_matrix, texture_matrix0); +#if DEBUG_TEXCOORD + original_texcoord = texcoord0; +#endif #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; @@ -135,9 +143,15 @@ in vec2 texcoord0; out vec2 basecolor_texcoord; out vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +out vec2 original_texcoord; +#endif out vec4 vertex_color; +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform); + + void main() { //transform vertex @@ -145,8 +159,11 @@ void main() gl_Position = vert; vary_position = vert.xyz; - basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy; - emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy; + basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_matrix, texture_matrix0); +#if DEBUG_TEXCOORD + original_texcoord = texcoord0; +#endif vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl index 75b24336c5..bcad1c1ceb 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl @@ -47,6 +47,8 @@ out vec2 emissive_texcoord; out vec4 vertex_emissive; +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform); + void main() { #ifdef HAS_SKIN @@ -62,8 +64,8 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy; - emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy; + basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_matrix, texture_matrix0); vertex_emissive = emissive; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl index c4c5a7872b..fd2aa6eb54 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueF.glsl @@ -51,6 +51,9 @@ in vec2 basecolor_texcoord; in vec2 normal_texcoord; in vec2 metallic_roughness_texcoord; in vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +in vec2 original_texcoord; +#endif uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() @@ -69,6 +72,10 @@ void main() } vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb); +#if DEBUG_TEXCOORD + vec3 texcoord_color = vec3(mod(original_texcoord, 1.0), 0); + col = texcoord_color; +#endif // from mikktspace.com vec3 vNt = texture2D(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; @@ -123,6 +130,9 @@ in vec4 vertex_color; in vec2 basecolor_texcoord; in vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +in vec2 original_texcoord; +#endif uniform float minimum_alpha; // PBR alphaMode: MASK, See: mAlphaCutoff, setAlphaCutoff() @@ -138,6 +148,10 @@ void main() } vec3 col = vertex_color.rgb * srgb_to_linear(basecolor.rgb); +#if DEBUG_TEXCOORD + vec3 texcoord_color = vec3(mod(original_texcoord, 1.0), 0); + col = texcoord_color; +#endif vec3 emissive = emissiveColor; emissive *= srgb_to_linear(texture2D(emissiveMap, emissive_texcoord.xy).rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 8320640e42..aeb6b85e12 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -53,6 +53,9 @@ out vec2 basecolor_texcoord; out vec2 normal_texcoord; out vec2 metallic_roughness_texcoord; out vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +out vec2 original_texcoord; +#endif out vec4 vertex_color; @@ -60,6 +63,8 @@ out vec3 vary_tangent; flat out float vary_sign; out vec3 vary_normal; +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform); + void main() { #ifdef HAS_SKIN @@ -75,11 +80,14 @@ void main() //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - - basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy; - normal_texcoord = (texture_matrix0 * vec4(texture_normal_matrix * vec3(texcoord0,1), 1)).xy; - metallic_roughness_texcoord = (texture_matrix0 * vec4(texture_metallic_roughness_matrix * vec3(texcoord0,1), 1)).xy; - emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy; + + basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); + normal_texcoord = texture_transform(texcoord0, texture_normal_matrix, texture_matrix0); + metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_matrix, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_matrix, texture_matrix0); +#if DEBUG_TEXCOORD + original_texcoord = texcoord0; +#endif #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; @@ -115,16 +123,24 @@ in vec2 texcoord0; out vec2 basecolor_texcoord; out vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +out vec2 original_texcoord; +#endif out vec4 vertex_color; +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform); + void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - basecolor_texcoord = (texture_matrix0 * vec4(texture_basecolor_matrix * vec3(texcoord0,1), 1)).xy; - emissive_texcoord = (texture_matrix0 * vec4(texture_emissive_matrix * vec3(texcoord0,1), 1)).xy; + basecolor_texcoord = texture_transform(texcoord0, texture_basecolor_matrix, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_matrix, texture_matrix0); +#if DEBUG_TEXCOORD + original_texcoord = texcoord0; +#endif vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl new file mode 100644 index 0000000000..b146c665f9 --- /dev/null +++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl @@ -0,0 +1,55 @@ +/** + * @file class1/deferred/textureUtilV.glsl + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +// vertex_texcoord - The UV texture coordinates sampled from the vertex at +// runtime. Per SL convention, this is in a right-handed UV coordinate +// system. Collada models also have right-handed UVs. +// khr_gltf_transform - The texture transform matrix as defined in the +// KHR_texture_transform GLTF extension spec. It assumes a left-handed UV +// coordinate system. GLTF models also have left-handed UVs. +// sl_animation_transform - The texture transform matrix for texture +// animations, available through LSL script functions such as +// LlSetTextureAnim. It assumes a right-handed UV coordinate system. +// texcoord - The final texcoord to use for image sampling +vec2 texture_transform(vec2 vertex_texcoord, mat3 khr_gltf_transform, mat4 sl_animation_transform) +{ + vec2 texcoord = vertex_texcoord; + + // Convert to left-handed coordinate system. The offset of 1 is necessary + // for rotations to be applied correctly. + // In the future, we could bake this coordinate conversion into the uniform + // that khr_gltf_transform comes from, since it's applied immediately + // before. + texcoord.y = 1.0 - texcoord.y; + texcoord = (khr_gltf_transform * vec3(texcoord, 1.0)).xy; + // Convert back to right-handed coordinate system + texcoord.y = 1.0 - texcoord.y; + texcoord = (sl_animation_transform * vec4(texcoord, 0, 1)).xy; + + // To make things more confusing, all SL image assets are upside-down + // We may need an additional sign flip here when we implement a Vulkan backend + + return texcoord; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 35ccc65a8e..47d6c5e195 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -57,6 +57,9 @@ in vec2 basecolor_texcoord; in vec2 normal_texcoord; in vec2 metallic_roughness_texcoord; in vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +in vec2 original_texcoord; +#endif in vec4 vertex_color; @@ -173,6 +176,10 @@ void main() #endif vec3 col = vertex_color.rgb * basecolor.rgb; +#if DEBUG_TEXCOORD + vec3 texcoord_color = vec3(mod(original_texcoord, 1.0), 0); + col = texcoord_color; +#endif vec3 vNt = texture(bumpMap, normal_texcoord.xy).xyz*2.0-1.0; float sign = vary_sign; @@ -265,6 +272,9 @@ in vec3 vary_position; in vec2 basecolor_texcoord; in vec2 emissive_texcoord; +#if DEBUG_TEXCOORD +in vec2 original_texcoord; +#endif in vec4 vertex_color; @@ -292,6 +302,10 @@ void main() #endif color = vertex_color.rgb * basecolor.rgb; +#if DEBUG_TEXCOORD + vec3 texcoord_color = vec3(mod(original_texcoord, 1.0), 0); + color = texcoord_color; +#endif // emissiveColor is the emissive color factor from GLTF and is already in linear space vec3 colorEmissive = emissiveColor; diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 341f94241a..6426512d5f 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -682,6 +682,7 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); + setting_setup_signal_listener(gSavedSettings, "RenderDebugTexcoord", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); setting_setup_signal_listener(gSavedSettings, "ChatPersistTime", handleChatPersistTimeChanged); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 5d3da55499..b866cedaaa 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -653,6 +653,7 @@ std::string LLViewerShaderMgr::loadBasicShaders() shaders.push_back( make_pair( "environment/srgbF.glsl", 1 ) ); shaders.push_back( make_pair( "avatar/avatarSkinV.glsl", 1 ) ); shaders.push_back( make_pair( "avatar/objectSkinV.glsl", 1 ) ); + shaders.push_back( make_pair( "deferred/textureUtilV.glsl", 1 ) ); if (gGLManager.mGLSLVersionMajor >= 2 || gGLManager.mGLSLVersionMinor >= 30) { shaders.push_back( make_pair( "objects/indexedTextureV.glsl", 1 ) ); @@ -1319,6 +1320,11 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueV.glsl", GL_VERTEX_SHADER)); gDeferredPBROpaqueProgram.mShaderFiles.push_back(make_pair("deferred/pbropaqueF.glsl", GL_FRAGMENT_SHADER)); gDeferredPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; + gDeferredPBROpaqueProgram.clearPermutations(); + if (gSavedSettings.getBOOL("RenderDebugTexcoord")) + { + gDeferredPBROpaqueProgram.addPermutation("DEBUG_TEXCOORD", "1"); + } success = make_rigged_variant(gDeferredPBROpaqueProgram, gDeferredSkinnedPBROpaqueProgram); if (success) @@ -1355,6 +1361,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gHUDPBROpaqueProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; gHUDPBROpaqueProgram.clearPermutations(); gHUDPBROpaqueProgram.addPermutation("IS_HUD", "1"); + if (gSavedSettings.getBOOL("RenderDebugTexcoord")) + { + gHUDPBROpaqueProgram.addPermutation("DEBUG_TEXCOORD", "1"); + } success = gHUDPBROpaqueProgram.createShader(NULL, NULL); @@ -1398,6 +1408,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() { shader->addPermutation("HAS_SUN_SHADOW", "1"); } + if (gSavedSettings.getBOOL("RenderDebugTexcoord")) + { + shader->addPermutation("DEBUG_TEXCOORD", "1"); + } shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = make_rigged_variant(*shader, gDeferredSkinnedPBRAlphaProgram); @@ -1430,6 +1444,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() shader->clearPermutations(); shader->addPermutation("IS_HUD", "1"); + if (gSavedSettings.getBOOL("RenderDebugTexcoord")) + { + shader->addPermutation("DEBUG_TEXCOORD", "1"); + } shader->mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = shader->createShader(NULL, NULL); diff --git a/indra/newview/skins/default/xui/en/menu_viewer.xml b/indra/newview/skins/default/xui/en/menu_viewer.xml index b8515cb096..04dde696d5 100644 --- a/indra/newview/skins/default/xui/en/menu_viewer.xml +++ b/indra/newview/skins/default/xui/en/menu_viewer.xml @@ -2843,6 +2843,16 @@ function="World.EnvPreset" function="Advanced.ToggleInfoDisplay" parameter="texture anim" /> + + + + -- cgit v1.3 From b27c41578b4bb54ee87fbb8d05f29d9d9a9e2768 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 27 Feb 2023 15:57:45 -0800 Subject: SL-19279: LLGLSLShader::bindXXX is not free. Pack the uniforms --- indra/llprimitive/llgltfmaterial.cpp | 30 +++++--------- indra/llprimitive/llgltfmaterial.h | 3 +- indra/llrender/llshadermgr.cpp | 20 +++------ indra/llrender/llshadermgr.h | 16 ++------ .../shaders/class1/deferred/pbralphaV.glsl | 40 +++++++----------- .../shaders/class1/deferred/pbrglowV.glsl | 14 +++---- .../shaders/class1/deferred/pbropaqueV.glsl | 48 ++++++++-------------- .../shaders/class1/deferred/textureUtilV.glsl | 4 +- indra/newview/llfetchedgltfmaterial.cpp | 24 +++++------ 9 files changed, 70 insertions(+), 129 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index d0ecf611ff..62b693919c 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -43,26 +43,16 @@ const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; // special UUID that indicates a null UUID in override data static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); -// https://github.com/KhronosGroup/glTF/tree/main/extensions/3.0/Khronos/KHR_texture_transform -LLMatrix3 LLGLTFMaterial::TextureTransform::asMatrix() -{ - LLMatrix3 scale; - scale.mMatrix[0][0] = mScale[0]; - scale.mMatrix[1][1] = mScale[1]; - - LLMatrix3 rotation; - const F32 cos_r = cos(mRotation); - const F32 sin_r = sin(mRotation); - rotation.mMatrix[0][0] = cos_r; - rotation.mMatrix[0][1] = -sin_r; - rotation.mMatrix[1][0] = sin_r; - rotation.mMatrix[1][1] = cos_r; - - LLMatrix3 offset; - offset.mMatrix[2][0] = mOffset[0]; - offset.mMatrix[2][1] = mOffset[1]; - - return offset * rotation * scale; +void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) +{ + packed[0] = mScale.mV[VX]; + packed[1] = mScale.mV[VY]; + packed[2] = mRotation; + // packed[3] = unused + packed[4] = mOffset.mV[VX]; + packed[5] = mOffset.mV[VY]; + // packed[6] = unused + // packed[7] = unused } bool LLGLTFMaterial::TextureTransform::operator==(const TextureTransform& other) const diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index cae7284421..e701b62fdc 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -28,7 +28,6 @@ #include "llrefcount.h" #include "llmemory.h" -#include "m3math.h" #include "v4color.h" #include "v3color.h" #include "v2math.h" @@ -60,7 +59,7 @@ public: LLVector2 mScale = { 1.f, 1.f }; F32 mRotation = 0.f; - LLMatrix3 asMatrix(); + void getPacked(F32 (&packed)[8]); bool operator==(const TextureTransform& other) const; }; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index c355115e8c..6fb319fd5b 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -1074,20 +1074,12 @@ void LLShaderMgr::initAttribsAndUniforms() mReservedUniforms.push_back("object_plane_s"); mReservedUniforms.push_back("object_plane_t"); - mReservedUniforms.push_back("texture_base_color_scale"); // (GLTF) - mReservedUniforms.push_back("texture_base_color_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_base_color_offset"); // (GLTF) - mReservedUniforms.push_back("texture_normal_scale"); // (GLTF) - mReservedUniforms.push_back("texture_normal_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_normal_offset"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_scale"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_metallic_roughness_offset"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_scale"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_rotation"); // (GLTF) - mReservedUniforms.push_back("texture_emissive_offset"); // (GLTF) - - llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_OFFSET+1); + mReservedUniforms.push_back("texture_base_color_transform"); // (GLTF) + mReservedUniforms.push_back("texture_normal_transform"); // (GLTF) + mReservedUniforms.push_back("texture_metallic_roughness_transform"); // (GLTF) + mReservedUniforms.push_back("texture_emissive_transform"); // (GLTF) + + llassert(mReservedUniforms.size() == LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM+1); mReservedUniforms.push_back("viewport"); diff --git a/indra/llrender/llshadermgr.h b/indra/llrender/llshadermgr.h index f7439a65af..93ea49d16a 100644 --- a/indra/llrender/llshadermgr.h +++ b/indra/llrender/llshadermgr.h @@ -53,18 +53,10 @@ public: OBJECT_PLANE_S, // "object_plane_s" OBJECT_PLANE_T, // "object_plane_t" - TEXTURE_BASE_COLOR_SCALE, // "texture_base_color_scale" (GLTF) - TEXTURE_BASE_COLOR_ROTATION, // "texture_base_color_rotation" (GLTF) - TEXTURE_BASE_COLOR_OFFSET, // "texture_base_color_offset" (GLTF) - TEXTURE_NORMAL_SCALE, // "texture_normal_scale" (GLTF) - TEXTURE_NORMAL_ROTATION, // "texture_normal_rotation" (GLTF) - TEXTURE_NORMAL_OFFSET, // "texture_normal_offset" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_SCALE, // "texture_metallic_roughness_scale" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_ROTATION,// "texture_metallic_roughness_rotation" (GLTF) - TEXTURE_METALLIC_ROUGHNESS_OFFSET, // "texture_metallic_roughness_offset" (GLTF) - TEXTURE_EMISSIVE_SCALE, // "texture_emissive_scale" (GLTF) - TEXTURE_EMISSIVE_ROTATION, // "texture_emissive_rotation" (GLTF) - TEXTURE_EMISSIVE_OFFSET, // "texture_emissive_offset" (GLTF) + TEXTURE_BASE_COLOR_TRANSFORM, // "texture_base_color_transform" (GLTF) + TEXTURE_NORMAL_TRANSFORM, // "texture_normal_transform" (GLTF) + TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, // "texture_metallic_roughness_transform" (GLTF) + TEXTURE_EMISSIVE_TRANSFORM, // "texture_emissive_transform" (GLTF) VIEWPORT, // "viewport" LIGHT_POSITION, // "light_position" diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl index a9e114dddc..e9515a9187 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbralphaV.glsl @@ -44,18 +44,10 @@ uniform mat4 modelview_matrix; out vec3 vary_position; -uniform vec2 texture_base_color_scale; -uniform float texture_base_color_rotation; -uniform vec2 texture_base_color_offset; -uniform vec2 texture_normal_scale; -uniform float texture_normal_rotation; -uniform vec2 texture_normal_offset; -uniform vec2 texture_metallic_roughness_scale; -uniform float texture_metallic_roughness_rotation; -uniform vec2 texture_metallic_roughness_offset; -uniform vec2 texture_emissive_scale; -uniform float texture_emissive_rotation; -uniform vec2 texture_emissive_offset; +uniform vec4[2] texture_base_color_transform; +uniform vec4[2] texture_normal_transform; +uniform vec4[2] texture_metallic_roughness_transform; +uniform vec4[2] texture_emissive_transform; out vec3 vary_fragcoord; @@ -78,7 +70,7 @@ out vec3 vary_tangent; flat out float vary_sign; out vec3 vary_normal; -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform); +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() @@ -97,10 +89,10 @@ void main() vary_fragcoord.xyz = vert.xyz + vec3(0,0,near_clip); - base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0); - normal_texcoord = texture_transform(texcoord0, texture_normal_scale, texture_normal_rotation, texture_normal_offset, texture_matrix0); - metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_scale, texture_metallic_roughness_rotation, texture_metallic_roughness_offset, texture_matrix0); - emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0); + base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0); + metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; @@ -133,12 +125,8 @@ uniform mat4 modelview_matrix; out vec3 vary_position; -uniform vec2 texture_base_color_scale; -uniform float texture_base_color_rotation; -uniform vec2 texture_base_color_offset; -uniform vec2 texture_emissive_scale; -uniform float texture_emissive_rotation; -uniform vec2 texture_emissive_offset; +uniform vec4[2] texture_base_color_transform; +uniform vec4[2] texture_emissive_transform; in vec3 position; in vec4 diffuse_color; @@ -149,7 +137,7 @@ out vec2 emissive_texcoord; out vec4 vertex_color; -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform); +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() @@ -159,8 +147,8 @@ void main() gl_Position = vert; vary_position = vert.xyz; - base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0); - emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0); + base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl index b73d08cf0d..82a50a115c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbrglowV.glsl @@ -34,12 +34,8 @@ uniform mat4 modelview_projection_matrix; uniform mat4 texture_matrix0; -uniform vec2 texture_base_color_scale; -uniform float texture_base_color_rotation; -uniform vec2 texture_base_color_offset; -uniform vec2 texture_emissive_scale; -uniform float texture_emissive_rotation; -uniform vec2 texture_emissive_offset; +uniform vec4[2] texture_base_color_transform; +uniform vec4[2] texture_emissive_transform; in vec3 position; in vec4 emissive; @@ -51,7 +47,7 @@ out vec2 emissive_texcoord; out vec4 vertex_emissive; -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform); +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() { @@ -68,8 +64,8 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0); - emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0); + base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); vertex_emissive = emissive; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl index 6f50aefdab..e2c23ac8f0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/pbropaqueV.glsl @@ -38,18 +38,10 @@ uniform mat4 modelview_projection_matrix; #endif uniform mat4 texture_matrix0; -uniform vec2 texture_base_color_scale; -uniform float texture_base_color_rotation; -uniform vec2 texture_base_color_offset; -uniform vec2 texture_normal_scale; -uniform float texture_normal_rotation; -uniform vec2 texture_normal_offset; -uniform vec2 texture_metallic_roughness_scale; -uniform float texture_metallic_roughness_rotation; -uniform vec2 texture_metallic_roughness_offset; -uniform vec2 texture_emissive_scale; -uniform float texture_emissive_rotation; -uniform vec2 texture_emissive_offset; +uniform vec4[2] texture_base_color_transform; +uniform vec4[2] texture_normal_transform; +uniform vec4[2] texture_metallic_roughness_transform; +uniform vec4[2] texture_emissive_transform; in vec3 position; in vec4 diffuse_color; @@ -68,7 +60,7 @@ out vec3 vary_tangent; flat out float vary_sign; out vec3 vary_normal; -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform); +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() { @@ -86,10 +78,10 @@ void main() gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); #endif - base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0); - normal_texcoord = texture_transform(texcoord0, texture_normal_scale, texture_normal_rotation, texture_normal_offset, texture_matrix0); - metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_scale, texture_metallic_roughness_rotation, texture_metallic_roughness_offset, texture_matrix0); - emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0); + base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + normal_texcoord = texture_transform(texcoord0, texture_normal_transform, texture_matrix0); + metallic_roughness_texcoord = texture_transform(texcoord0, texture_metallic_roughness_transform, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); #ifdef HAS_SKIN vec3 n = (mat*vec4(normal.xyz+position.xyz,1.0)).xyz-pos.xyz; @@ -114,18 +106,10 @@ uniform mat4 modelview_projection_matrix; uniform mat4 texture_matrix0; -uniform vec2 texture_base_color_scale; -uniform float texture_base_color_rotation; -uniform vec2 texture_base_color_offset; -uniform vec2 texture_normal_scale; -uniform float texture_normal_rotation; -uniform vec2 texture_normal_offset; -uniform vec2 texture_metallic_roughness_scale; -uniform float texture_metallic_roughness_rotation; -uniform vec2 texture_metallic_roughness_offset; -uniform vec2 texture_emissive_scale; -uniform float texture_emissive_rotation; -uniform vec2 texture_emissive_offset; +uniform vec4[2] texture_base_color_transform; +uniform vec4[2] texture_normal_transform; +uniform vec4[2] texture_metallic_roughness_transform; +uniform vec4[2] texture_emissive_transform; in vec3 position; in vec4 diffuse_color; @@ -136,15 +120,15 @@ out vec2 emissive_texcoord; out vec4 vertex_color; -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform); +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); void main() { //transform vertex gl_Position = modelview_projection_matrix * vec4(position.xyz, 1.0); - base_color_texcoord = texture_transform(texcoord0, texture_base_color_scale, texture_base_color_rotation, texture_base_color_offset, texture_matrix0); - emissive_texcoord = texture_transform(texcoord0, texture_emissive_scale, texture_emissive_rotation, texture_emissive_offset, texture_matrix0); + base_color_texcoord = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); + emissive_texcoord = texture_transform(texcoord0, texture_emissive_transform, texture_matrix0); vertex_color = diffuse_color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl index 39cc07d2d1..71f7ec52c4 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/textureUtilV.glsl @@ -58,7 +58,7 @@ vec2 khr_texture_transform(vec2 texcoord, vec2 scale, float rotation, vec2 offse // animations, available through LSL script functions such as // LlSetTextureAnim. It assumes a right-handed UV coordinate system. // texcoord - The final texcoord to use for image sampling -vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf_rotation, vec2 khr_gltf_offset, mat4 sl_animation_transform) +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform) { vec2 texcoord = vertex_texcoord; @@ -67,7 +67,7 @@ vec2 texture_transform(vec2 vertex_texcoord, vec2 khr_gltf_scale, float khr_gltf // Convert to left-handed coordinate system. The offset of 1 is necessary // for rotations to be applied correctly. texcoord.y = 1.0 - texcoord.y; - texcoord = khr_texture_transform(texcoord, khr_gltf_scale, khr_gltf_rotation, khr_gltf_offset); + texcoord = khr_texture_transform(texcoord, khr_gltf_transform[0].xy, khr_gltf_transform[0].z, khr_gltf_transform[1].xy); // Convert back to right-handed coordinate system texcoord.y = 1.0 - texcoord.y; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 2f2c58aa3a..80074cc655 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -110,21 +110,21 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); - shader->uniform2fv(LLShaderMgr::TEXTURE_BASE_COLOR_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mScale.mV); - shader->uniform1f(LLShaderMgr::TEXTURE_BASE_COLOR_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mRotation); - shader->uniform2fv(LLShaderMgr::TEXTURE_BASE_COLOR_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].mOffset.mV); + F32 base_color_packed[8]; + mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed); + shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed); - shader->uniform2fv(LLShaderMgr::TEXTURE_NORMAL_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mScale.mV); - shader->uniform1f(LLShaderMgr::TEXTURE_NORMAL_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mRotation); - shader->uniform2fv(LLShaderMgr::TEXTURE_NORMAL_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].mOffset.mV); + F32 normal_packed[8]; + mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed); + shader->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, (F32*)normal_packed); - shader->uniform2fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mScale.mV); - shader->uniform1f(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mRotation); - shader->uniform2fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].mOffset.mV); + F32 metallic_roughness_packed[8]; + mTextureTransform[GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].getPacked(metallic_roughness_packed); + shader->uniform4fv(LLShaderMgr::TEXTURE_METALLIC_ROUGHNESS_TRANSFORM, 2, (F32*)metallic_roughness_packed); - shader->uniform2fv(LLShaderMgr::TEXTURE_EMISSIVE_SCALE, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mScale.mV); - shader->uniform1f(LLShaderMgr::TEXTURE_EMISSIVE_ROTATION, mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mRotation); - shader->uniform2fv(LLShaderMgr::TEXTURE_EMISSIVE_OFFSET, 1, (F32*)mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].mOffset.mV); + F32 emissive_packed[8]; + mTextureTransform[GLTF_TEXTURE_INFO_EMISSIVE].getPacked(emissive_packed); + shader->uniform4fv(LLShaderMgr::TEXTURE_EMISSIVE_TRANSFORM, 2, (F32*)emissive_packed); } } -- cgit v1.3 From bc7856098f70371dd392c74689df267cce819aa7 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Thu, 2 Mar 2023 16:36:03 -0600 Subject: SL-19281 Unify handling of haze and gamma between fullbright and not and move haze back to sRGB color space to stay consistent with sky colors. Also fix broken "roughness" stuck at 0.2. --- indra/llprimitive/llgltfmaterial.h | 3 +- indra/llrender/llcubemaparray.cpp | 2 +- .../shaders/class1/deferred/deferredUtil.glsl | 9 ++-- .../shaders/class1/deferred/fullbrightF.glsl | 3 ++ .../class1/deferred/postDeferredGammaCorrect.glsl | 49 +++++++------------ .../shaders/class1/environment/waterFogF.glsl | 7 ++- .../shaders/class2/deferred/alphaF.glsl | 11 ++++- .../shaders/class2/deferred/pbralphaF.glsl | 11 ++++- .../shaders/class2/deferred/reflectionProbeF.glsl | 1 - .../shaders/class2/windlight/atmosphericsF.glsl | 4 +- .../class2/windlight/atmosphericsFuncs.glsl | 15 +++--- .../shaders/class2/windlight/gammaF.glsl | 29 ++++------- .../shaders/class2/windlight/transportF.glsl | 18 ++++--- .../shaders/class3/deferred/materialF.glsl | 13 +++-- .../shaders/class3/deferred/reflectionProbeF.glsl | 24 ++++------ .../shaders/class3/deferred/softenLightF.glsl | 56 ++++++++++++++++++---- .../shaders/class3/environment/waterF.glsl | 17 +++++-- indra/newview/llreflectionmapmanager.cpp | 4 +- indra/newview/llsettingsvo.cpp | 4 +- indra/newview/llviewershadermgr.cpp | 6 ++- indra/newview/pipeline.cpp | 2 + 21 files changed, 168 insertions(+), 120 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index e701b62fdc..b453b91e67 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -98,7 +98,8 @@ public: std::array mTextureTransform; - // NOTE : initialize values to defaults according to the GLTF spec + // NOTE: initialize values to defaults according to the GLTF spec + // NOTE: these values should be in linear color space LLColor4 mBaseColor = LLColor4(1, 1, 1, 1); LLColor3 mEmissiveColor = LLColor3(0, 0, 0); diff --git a/indra/llrender/llcubemaparray.cpp b/indra/llrender/llcubemaparray.cpp index 52118172c0..ac48a633c7 100644 --- a/indra/llrender/llcubemaparray.cpp +++ b/indra/llrender/llcubemaparray.cpp @@ -122,7 +122,7 @@ void LLCubeMapArray::allocate(U32 resolution, U32 components, U32 count, BOOL us bind(0); - U32 format = components == 4 ? GL_RGBA12 : GL_RGB10; + U32 format = components == 4 ? GL_RGBA12 : GL_RGB16F; U32 mip = 0; diff --git a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl index 6ab966ae01..0b4a59c866 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/deferredUtil.glsl @@ -396,7 +396,7 @@ vec3 pbrIbl(vec3 diffuseColor, specContrib = specular * ao; - return (diffuse + specular*0.5) * ao; //reduce by half to place in appropriate color space for atmospherics + return (diffuse + specular) * ao; } vec3 pbrIbl(vec3 diffuseColor, @@ -562,16 +562,13 @@ vec3 pbrBaseLight(vec3 diffuseColor, vec3 specularColor, float metallic, vec3 v, float NdotV = clamp(abs(dot(norm, v)), 0.001, 1.0); vec3 ibl_spec; - color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, 0.2, ibl_spec); + color += pbrIbl(diffuseColor, specularColor, radiance, irradiance, ao, NdotV, perceptualRoughness, ibl_spec); color += pbrPunctual(diffuseColor, specularColor, perceptualRoughness, metallic, norm, v, normalize(light_dir), specContrib) * sunlit * 2.75 * scol; specContrib *= sunlit * 2.75 * scol; specContrib += ibl_spec; - color += colorEmissive*0.5; - - color = atmosFragLightingLinear(color, additive, atten); - color = scaleSoftClipFragLinear(color); + color += colorEmissive; //divide by two to correct for magical multiply by two in atmosFragLighting return color; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index afe504743d..c406c669f2 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -88,8 +88,11 @@ void main() #endif #ifndef IS_HUD + color.rgb = fullbrightAtmosTransport(color.rgb); + color.rgb = fullbrightScaleSoftClip(color.rgb); color.rgb = srgb_to_linear(color.rgb); #endif + frag_color.rgb = color.rgb; frag_color.a = color.a; } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index cc77712347..383fcaa9a7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -44,9 +44,6 @@ vec3 linear_to_srgb(vec3 cl); //=============================================================== // tone mapping taken from Khronos sample implementation //=============================================================== -const float GAMMA = 2.2; -const float INV_GAMMA = 1.0 / GAMMA; - // sRGB => XYZ => D65_2_D60 => AP1 => RRT_SAT const mat3 ACESInputMat = mat3 @@ -65,29 +62,6 @@ const mat3 ACESOutputMat = mat3 -0.07367, -0.00605, 1.07602 ); - -// linear to sRGB approximation -// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html -vec3 linearTosRGB(vec3 color) -{ - return pow(color, vec3(INV_GAMMA)); -} - - -// sRGB to linear approximation -// see http://chilliant.blogspot.com/2012/08/srgb-approximations-for-hlsl.html -vec3 sRGBToLinear(vec3 srgbIn) -{ - return vec3(pow(srgbIn.xyz, vec3(GAMMA))); -} - - -vec4 sRGBToLinear(vec4 srgbIn) -{ - return vec4(sRGBToLinear(srgbIn.xyz), srgbIn.w); -} - - // ACES tone map (faster approximation) // see: https://knarkowicz.wordpress.com/2016/01/06/aces-filmic-tone-mapping-curve/ vec3 toneMapACES_Narkowicz(vec3 color) @@ -128,13 +102,13 @@ vec3 toneMapACES_Hill(vec3 color) } uniform float exposure; +uniform float gamma; vec3 toneMap(vec3 color) { color *= exposure; #ifdef TONEMAP_ACES_NARKOWICZ - color *= 0.8; color = toneMapACES_Narkowicz(color); #endif @@ -146,11 +120,12 @@ vec3 toneMap(vec3 color) // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621 // this factor is based on the exposure correction of Krzysztof Narkowicz in his // implemetation of ACES tone mapping - color *= 0.85/0.6; + color *= 1.0/0.6; + //color /= 0.6; color = toneMapACES_Hill(color); #endif - return linearTosRGB(color); + return linear_to_srgb(color); } //=============================================================== @@ -193,16 +168,26 @@ float noise(vec2 x) { //============================= + +vec3 legacyGamma(vec3 color) +{ + color = 1. - clamp(color, vec3(0.), vec3(1.)); + color = 1. - pow(color, vec3(gamma)); // s/b inverted already CPU-side + + return color; +} + void main() { //this is the one of the rare spots where diffuseRect contains linear color values (not sRGB) vec4 diff = texture2D(diffuseRect, vary_fragcoord); diff.rgb = toneMap(diff.rgb); - vec2 tc = vary_fragcoord.xy*screen_res; - + diff.rgb = legacyGamma(diff.rgb); + + vec2 tc = vary_fragcoord.xy*screen_res*4.0; vec3 seed = (diff.rgb+vec3(1.0))*vec3(tc.xy, tc.x+tc.y); vec3 nz = vec3(noise(seed.rg), noise(seed.gb), noise(seed.rb)); - diff.rgb += nz*0.008; + diff.rgb += nz*0.003; //diff.rgb = nz; frag_color = diff; } diff --git a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl index 16651dcdbc..e3a201c724 100644 --- a/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/waterFogF.glsl @@ -33,6 +33,7 @@ uniform float waterFogKS; vec3 getPositionEye(); vec3 srgb_to_linear(vec3 col); +vec3 linear_to_srgb(vec3 col); vec4 applyWaterFogView(vec3 pos, vec4 color) { @@ -68,6 +69,7 @@ vec4 applyWaterFogView(vec3 pos, vec4 color) float D = pow(0.98, l*kd); color.rgb = color.rgb * D + kc.rgb * L; + color.a = kc.a + color.a; return color; } @@ -120,7 +122,10 @@ vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit) return color; } - return applyWaterFogViewLinearNoClip(pos, color, sunlit); + color.rgb = linear_to_srgb(color.rgb); + color = applyWaterFogView(pos, color); + color.rgb = srgb_to_linear(color.rgb); + return color; } vec4 applyWaterFogViewLinear(vec3 pos, vec4 color) diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index e2694e060e..ef35bf3fd7 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -250,6 +250,9 @@ void main() calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = srgb_to_linear(sunlit); + vec3 amblit_linear = amblit; + vec3 irradiance; vec3 glossenv; vec3 legacyenv; @@ -266,7 +269,7 @@ void main() color.a = final_alpha; - vec3 sun_contrib = min(final_da, shadow) * sunlit; + vec3 sun_contrib = min(final_da, shadow) * sunlit_linear; color.rgb = max(amblit, irradiance); @@ -274,8 +277,10 @@ void main() color.rgb *= diffuse_linear.rgb; + color.rgb = linear_to_srgb(color.rgb); color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); color.rgb = scaleSoftClipFragLinear(color.rgb); + color.rgb = srgb_to_linear(color.rgb); vec4 light = vec4(0,0,0,0); @@ -294,8 +299,9 @@ void main() color.rgb += light.rgb; #endif // !defined(LOCAL_LIGHT_KILL) + #ifdef WATER_FOG - color = applyWaterFogViewLinear(pos.xyz, color, sunlit); + color = applyWaterFogViewLinear(pos.xyz, color, sunlit_linear); #endif // WATER_FOG #endif // #else // FOR_IMPOSTOR @@ -303,6 +309,7 @@ void main() #ifdef IS_HUD color.rgb = linear_to_srgb(color.rgb); #endif + frag_color = color; } diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index 2a093827cb..fb76db99a0 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -82,6 +82,8 @@ vec3 srgb_to_linear(vec3 c); vec3 linear_to_srgb(vec3 c); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); +vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten); +vec3 scaleSoftClipFragLinear(vec3 color); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); @@ -196,6 +198,8 @@ void main() vec3 atten; calcAtmosphericVarsLinear(pos.xyz, norm, light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = srgb_to_linear(sunlit); + vec2 frag = vary_fragcoord.xy/vary_fragcoord.z*0.5+0.5; #ifdef HAS_SUN_SHADOW @@ -229,9 +233,14 @@ void main() vec3 v = -normalize(pos.xyz); vec3 spec; - color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec); + color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec); glare += max(max(spec.r, spec.g), spec.b); + color.rgb = linear_to_srgb(color.rgb); + color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); + color.rgb = scaleSoftClipFragLinear(color.rgb); + color.rgb = srgb_to_linear(color.rgb); + vec3 light = vec3(0); // Punctual lights diff --git a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl index 5fa53c374b..080f622155 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/reflectionProbeF.glsl @@ -47,7 +47,6 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness) { sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness); - glossenv *= 8.0; } vec4 sampleReflectionProbesDebug(vec3 pos) diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 6668a00841..1d02498209 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -33,8 +33,8 @@ vec3 linear_to_srgb(vec3 col); vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { light *= atten.r; - light += additive; - return light * 2.0; + light += additive * 2.0; + return light; } vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten) diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index f9f625ecdb..768f422060 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -137,8 +137,8 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou additive = (blue_horizon.rgb * blue_weight.rgb) * (cs + tmpAmbient.rgb) + (haze_horizon * haze_weight.rgb) * (cs * haze_glow + tmpAmbient.rgb); // brightness of surface both sunlight and ambient - sunlit = sunlight.rgb; - amblit = tmpAmbient.rgb; + sunlit = sunlight.rgb * 0.7; + amblit = tmpAmbient.rgb * 0.25; additive *= vec3(1.0 - combined_haze); } @@ -150,21 +150,22 @@ vec3 srgb_to_linear(vec3 col); float ambientLighting(vec3 norm, vec3 light_dir) { float ambient = min(abs(dot(norm.xyz, light_dir.xyz)), 1.0); - ambient *= 0.56; + ambient *= 0.5; ambient *= ambient; ambient = (1.0 - ambient); return ambient; } -// return colors in linear space +// return lit amblit in linear space, leave sunlit and additive in sRGB space void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten) { calcAtmosphericVars(inPositionEye, light_dir, 1.0, sunlit, amblit, additive, atten, false); - sunlit = srgb_to_linear(sunlit); - additive = srgb_to_linear(additive); - amblit = ambient_linear; + + sunlit *= 2.0; + amblit *= 2.0; amblit *= ambientLighting(norm, light_dir); + amblit = srgb_to_linear(amblit); } diff --git a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl index 9a9b179e6a..027bfb866f 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/gammaF.glsl @@ -22,43 +22,34 @@ * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA * $/LicenseInfo$ */ -uniform float gamma; -vec3 getAtmosAttenuation(); -vec3 getAdditiveColor(); + // DEPRECATED -vec3 srgb_to_linear(vec3 col); -vec3 linear_to_srgb(vec3 col); +//soft clip effect has been moved to postDeferredGammaCorrect legacyGamma, this file is effectively dead +// but these functions need to be removed from all existing shaders before removing this file -vec3 scaleSoftClipFragLinear(vec3 light) -{ // identical to non-linear version and that's probably close enough - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side +vec3 scaleSoftClipFrag(vec3 light) +{ return light; } -vec3 scaleSoftClipFrag(vec3 light) -{ - //soft clip effect: - light = 1. - clamp(light, vec3(0.), vec3(1.)); - light = 1. - pow(light, vec3(gamma)); // s/b inverted already CPU-side +vec3 scaleSoftClipFragLinear(vec3 light) +{ // identical to non-linear version and that's probably close enough return light; } vec3 scaleSoftClip(vec3 light) { - return scaleSoftClipFrag(light); + return light; } vec3 fullbrightScaleSoftClipFrag(vec3 light, vec3 add, vec3 atten) { - //return mix(scaleSoftClipFrag(light.rgb), add, atten); - return scaleSoftClipFrag(light.rgb); + return light; } vec3 fullbrightScaleSoftClip(vec3 light) { - return fullbrightScaleSoftClipFrag(light, getAdditiveColor(), getAtmosAttenuation()); + return light; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index c509d865ba..6aa719d200 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -48,23 +48,27 @@ vec3 atmosTransport(vec3 light) vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten) { // same as non-linear version, probably fine - float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; - return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); + //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; + //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); + return atmosTransportFrag(light, additive, atten); } vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten) { - float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; - return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); + //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; + //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); + return atmosTransportFrag(light, additive, atten); } vec3 fullbrightAtmosTransport(vec3 light) { - return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); + //return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); + return atmosTransport(light); } vec3 fullbrightShinyAtmosTransport(vec3 light) { - float brightness = dot(light.rgb, vec3(0.33333)); - return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); + //float brightness = dot(light.rgb, vec3(0.33333)); + //return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); + return atmosTransport(light); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 49529860be..add1cb2a37 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -334,16 +334,19 @@ void main() vec3 atten; calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = srgb_to_linear(sunlit); + vec3 amblit_linear = amblit; + vec3 ambenv; vec3 glossenv; vec3 legacyenv; sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, pos.xy*0.5+0.5, pos.xyz, norm.xyz, glossiness, env); // use sky settings ambient or irradiance map sample, whichever is brighter - color = max(amblit, ambenv); + color = max(amblit_linear, ambenv); float da = clamp(dot(norm.xyz, light_dir.xyz), 0.0, 1.0); - vec3 sun_contrib = min(da, shadow) * sunlit; + vec3 sun_contrib = min(da, shadow) * sunlit_linear; color.rgb += sun_contrib; color *= diffcol.rgb; @@ -354,7 +357,7 @@ void main() if (glossiness > 0.0) // specular reflection { float sa = dot(normalize(refnormpersp), light_dir.xyz); - vec3 dumbshiny = sunlit * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r); + vec3 dumbshiny = sunlit_linear * shadow * (texture2D(lightFunc, vec2(sa, glossiness)).r); // add the two types of shiny together vec3 spec_contrib = dumbshiny * spec.rgb; @@ -379,8 +382,10 @@ void main() glare += cur_glare; } - color.rgb = mix(atmosFragLightingLinear(color.rgb, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), emissive); + color.rgb = linear_to_srgb(color.rgb); + color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); color.rgb = scaleSoftClipFragLinear(color.rgb); + color.rgb = srgb_to_linear(color.rgb); vec3 npos = normalize(-pos.xyz); vec3 light = vec3(0, 0, 0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl index 23c6f4d5ae..c6d649086a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/reflectionProbeF.glsl @@ -458,28 +458,24 @@ float sphereWeight(vec3 pos, vec3 dir, vec3 origin, float r, float min_da, int i // dir - pixel normal // w - weight of sample (distance and angular attenuation) // dw - weight of sample (distance only) -// vi - return value of intersection point with influence volume -// wi - return value of approximate world space position of sampled pixel -// lod - which mip to bias towards (lower is higher res, sharper reflections) +// lod - which mip to sample (lower is higher res, sharper reflections) // c - center of probe // r2 - radius of probe squared // i - index of probe -vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, out vec3 vi, out vec3 wi, float lod, vec3 c, int i) +vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, float lod, vec3 c, int i) { - //lod = max(lod, 1); // parallax adjustment - vec3 v; if (refIndex[i].w < 0) - { + { // box probe float d = 0; v = boxIntersect(pos, dir, i, d); w = max(d, 0.001); } else - { + { // sphere probe float r = refSphere[i].w; float rr = r * r; @@ -491,16 +487,12 @@ vec3 tapRefMap(vec3 pos, vec3 dir, out float w, out float dw, out vec3 vi, out v w = sphereWeight(pos, dir, refSphere[i].xyz, r, 0.25, i, dw); } - vi = v; - v -= c; vec3 d = normalize(v); v = env_mat * v; - vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod); - - wi = d * ret.a * 256.0+c; + vec4 ret = textureLod(reflectionProbes, vec4(v.xyz, refIndex[i].x), lod) * refParams[i].y; return ret.rgb; } @@ -568,12 +560,11 @@ vec3 sampleProbes(vec3 pos, vec3 dir, float lod) float w = 0; float dw = 0; - vec3 vi, wi; vec3 refcol; { - refcol = tapRefMap(pos, dir, w, dw, vi, wi, lod, refSphere[i].xyz, i); + refcol = tapRefMap(pos, dir, w, dw, lod, refSphere[i].xyz, i); col[p] += refcol.rgb*w; wsum[p] += w; @@ -665,7 +656,7 @@ void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness) { // TODO - don't hard code lods - float reflection_lods = max_probe_lod; + float reflection_lods = max_probe_lod-1; preProbeSample(pos); vec3 refnormpersp = reflect(pos.xyz, norm.xyz); @@ -690,6 +681,7 @@ void sampleReflectionProbesWater(inout vec3 ambenv, inout vec3 glossenv, vec2 tc, vec3 pos, vec3 norm, float glossiness) { sampleReflectionProbes(ambenv, glossenv, tc, pos, norm, glossiness); + glossenv *= 0.25; } void debugTapRefMap(vec3 pos, vec3 dir, float depth, int i, inout vec4 col) diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 8d48e6f596..dfd1d47b3e 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -85,6 +85,8 @@ float getDepth(vec2 pos_screen); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); +uniform vec4 waterPlane; + #ifdef WATER_FOG vec4 applyWaterFogViewLinear(vec3 pos, vec4 color); #endif @@ -153,6 +155,24 @@ void main() calcAtmosphericVarsLinear(pos.xyz, norm.xyz, light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = srgb_to_linear(sunlit); + vec3 amblit_linear = amblit; + + bool do_atmospherics = false; + +#ifndef WATER_FOG + // when above water, mask off atmospherics below water + if (dot(pos.xyz, waterPlane.xyz) + waterPlane.w > 0.0) + { + do_atmospherics = true; + } +#else + do_atmospherics = true; +#endif + + vec3 irradiance = vec3(0); + vec3 radiance = vec3(0); + if (GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_PBR)) { vec3 orm = texture2D(specularRect, tc).rgb; @@ -161,23 +181,32 @@ void main() float ao = orm.r * ambocc; vec3 colorEmissive = texture2D(emissiveRect, tc).rgb; - // PBR IBL float gloss = 1.0 - perceptualRoughness; - vec3 irradiance = vec3(0); - vec3 radiance = vec3(0); + sampleReflectionProbes(irradiance, radiance, tc, pos.xyz, norm.xyz, gloss); // Take maximium of legacy ambient vs irradiance sample as irradiance // NOTE: ao is applied in pbrIbl (see pbrBaseLight), do not apply here - irradiance = max(amblit,irradiance); + irradiance = max(amblit_linear,irradiance); vec3 diffuseColor; vec3 specularColor; calcDiffuseSpecular(baseColor.rgb, metallic, diffuseColor, specularColor); vec3 v = -normalize(pos.xyz); - color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + color = vec3(1,0,1); + color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten); + + + if (do_atmospherics) + { + color = linear_to_srgb(color); + color = atmosFragLightingLinear(color, additive, atten); + color = srgb_to_linear(color); + } + + } else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { @@ -199,12 +228,12 @@ void main() sampleReflectionProbesLegacy(irradiance, glossenv, legacyenv, tc, pos.xyz, norm.xyz, spec.a, envIntensity); // use sky settings ambient or irradiance map sample, whichever is brighter - irradiance = max(amblit, irradiance); + irradiance = max(amblit_linear, irradiance); // apply lambertian IBL only (see pbrIbl) color.rgb = irradiance * ambocc; - vec3 sun_contrib = min(da, scol) * sunlit; + vec3 sun_contrib = min(da, scol) * sunlit_linear; color.rgb += sun_contrib; color.rgb *= baseColor.rgb; @@ -230,9 +259,16 @@ void main() applyLegacyEnv(color, legacyenv, spec, pos.xyz, norm.xyz, envIntensity); } - color = mix(atmosFragLightingLinear(color, additive, atten), fullbrightAtmosTransportFragLinear(color, additive, atten), baseColor.a); - color = scaleSoftClipFragLinear(color); - } + + if (do_atmospherics) + { + color = linear_to_srgb(color); + color = atmosFragLightingLinear(color, additive, atten); + color = srgb_to_linear(color); + } + } + + #ifdef WATER_FOG vec4 fogged = applyWaterFogViewLinear(pos.xyz, vec4(color, bloom)); diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index a87682affb..991079e77a 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -114,6 +114,7 @@ vec3 BlendNormal(vec3 bump1, vec3 bump2) } vec3 srgb_to_linear(vec3 col); +vec3 linear_to_srgb(vec3 col); vec3 vN, vT, vB; @@ -200,6 +201,8 @@ void main() calcAtmosphericVarsLinear(pos.xyz, wavef, vary_light_dir, sunlit, amblit, additive, atten); + vec3 sunlit_linear = srgb_to_linear(sunlit); + #ifdef TRANSPARENT_WATER vec4 fb = texture2D(screenTex, distort2); float depth = texture2D(screenDepth, distort2).r; @@ -216,9 +219,10 @@ void main() fb = applyWaterFogViewLinear(refPos, fb, sunlit); #else - vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit); + vec4 fb = applyWaterFogViewLinear(viewVec*2048.0, vec4(1.0), sunlit_linear); #endif + fb.rgb *= 0.75; float metallic = 0.0; float perceptualRoughness = 0.05; float gloss = 1.0 - perceptualRoughness; @@ -247,10 +251,7 @@ void main() vec3 punctual = pbrPunctual(vec3(0), specularColor, 0.1, metallic, normalize(wavef+up*max(dist, 32.0)/32.0*(1.0-vdu)), v, normalize(light_dir)); - vec3 color = punctual * sunlit * 2.75 * scol; - - color = atmosFragLightingLinear(color, additive, atten); - color = scaleSoftClipFragLinear(color); + vec3 color = punctual * sunlit_linear * 2.75 * scol; vec3 ibl = pbrIbl(vec3(0), vec3(1), radiance, vec3(0), ao, NdotV, 0.0); @@ -274,6 +275,12 @@ void main() color = mix(color, fb.rgb, f); + color.rgb = linear_to_srgb(color.rgb); + color = atmosFragLightingLinear(color, additive, atten); + color = scaleSoftClipFragLinear(color); + color.rgb = srgb_to_linear(color.rgb); + + float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); frag_color = vec4(color, spec); //*sunAngle2); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 9962d0c10c..61d8756490 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -814,7 +814,7 @@ void LLReflectionMapManager::updateUniforms() F32 minimum_ambiance = psky->getTotalReflectionProbeAmbiance(cloud_shadow_scale); F32 ambscale = gCubeSnapshot && !isRadiancePass() ? 0.f : 1.f; - + F32 radscale = gCubeSnapshot && !isRadiancePass() ? 0.5f : 1.f; for (auto* refmap : mReflectionMaps) { @@ -852,7 +852,7 @@ void LLReflectionMapManager::updateUniforms() rpd.refIndex[count][3] = -rpd.refIndex[count][3]; } - rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, 0.f, 0.f, 0.f); + rpd.refParams[count].set(llmax(minimum_ambiance, refmap->getAmbiance())*ambscale, radscale, 0.f, 0.f); S32 ni = nc; // neighbor ("index") - index into refNeighbor to write indices for current reflection probe's neighbors { diff --git a/indra/newview/llsettingsvo.cpp b/indra/newview/llsettingsvo.cpp index 1752b2494f..ac5bde7b9b 100644 --- a/indra/newview/llsettingsvo.cpp +++ b/indra/newview/llsettingsvo.cpp @@ -716,15 +716,15 @@ void LLSettingsVOSky::applySpecial(void *ptarget, bool force) LLColor3 ambient(getTotalAmbient()); - shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV)); - if (radiance_pass) { // during an irradiance map update, disable ambient lighting (direct lighting only) and desaturate sky color (avoid tinting the world blue) shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, LLVector3::zero.mV); + shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3::zero.mV); } else { shader->uniform3fv(LLShaderMgr::AMBIENT_LINEAR, linearColor3v(getAmbientColor() / 3.f)); // note magic number 3.f comes from SLIDER_SCALE_SUN_AMBIENT + shader->uniform3fv(LLShaderMgr::AMBIENT, LLVector3(ambient.mV)); } shader->uniform3fv(LLShaderMgr::BLUE_HORIZON_LINEAR, linearColor3v(getBlueHorizon() / 2.f)); // note magic number of 2.f comes from SLIDER_SCALE_BLUE_HORIZON_DENSITY diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index f4f20ee7a6..31c71aac2a 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -235,7 +235,6 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderLevel(SHADER_COUNT, 0), mMaxAvatarShaderLevel(0) { - /// Make sure WL Sky is the first program //ONLY shaders that need WL Param management should be added here mShaderList.push_back(&gAvatarProgram); mShaderList.push_back(&gWaterProgram); @@ -291,6 +290,7 @@ LLViewerShaderMgr::LLViewerShaderMgr() : mShaderList.push_back(&gDeferredPBRAlphaProgram); mShaderList.push_back(&gHUDPBRAlphaProgram); mShaderList.push_back(&gDeferredSkinnedPBRAlphaProgram); + mShaderList.push_back(&gDeferredPostGammaCorrectProgram); // for gamma } @@ -2524,6 +2524,10 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() else if (tonemapper == 2) { gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_HILL_EXPOSURE_BOOST", "1"); + } + else + { + gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_LINEAR", "1"); } gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index b5b5d9ef7f..fffccc72ea 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -8119,6 +8119,8 @@ void LLPipeline::renderDeferredLighting() soften_shader.uniform1i(LLShaderMgr::SUN_UP_FACTOR, environment.getIsSunUp() ? 1 : 0); soften_shader.uniform3fv(LLShaderMgr::LIGHTNORM, 1, environment.getClampedLightNorm().mV); + soften_shader.uniform4fv(LLShaderMgr::WATER_WATERPLANE, 1, LLDrawPoolAlpha::sWaterPlane.mV); + { LLGLDepthTest depth(GL_FALSE); LLGLDisable blend(GL_BLEND); -- cgit v1.3 From 33e44b2059831594f91a84d07b316e8eee94bd4f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 10 Mar 2023 00:56:57 +0200 Subject: SL-19353 Mesh importer throws an error when the file extension is upper case --- indra/llprimitive/llgltfloader.cpp | 4 +++- indra/newview/llmodelpreview.cpp | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfloader.cpp b/indra/llprimitive/llgltfloader.cpp index fd304f7bc9..7394f99794 100644 --- a/indra/llprimitive/llgltfloader.cpp +++ b/indra/llprimitive/llgltfloader.cpp @@ -106,10 +106,12 @@ bool LLGLTFLoader::OpenFile(const std::string &filename) tinygltf::TinyGLTF loader; std::string error_msg; std::string warn_msg; + std::string filename_lc(filename); + LLStringUtil::toLower(filename_lc); // Load a tinygltf model fom a file. Assumes that the input filename has already been // been sanitized to one of (.gltf , .glb) extensions, so does a simple find to distinguish. - if (std::string::npos == filename.rfind(".gltf")) + if (std::string::npos == filename_lc.rfind(".gltf")) { // file is binary mGltfLoaded = loader.LoadBinaryFromFile(&mGltfModel, &error_msg, &warn_msg, filename); } diff --git a/indra/newview/llmodelpreview.cpp b/indra/newview/llmodelpreview.cpp index 56a48cb74d..7ae48eef8c 100644 --- a/indra/newview/llmodelpreview.cpp +++ b/indra/newview/llmodelpreview.cpp @@ -750,7 +750,9 @@ void LLModelPreview::loadModel(std::string filename, S32 lod, bool force_disable // three possible file extensions, .dae .gltf .glb // check for .dae and if not then assume one of the .gl?? - if (std::string::npos != filename.rfind(".dae")) + std::string filename_lc(filename); + LLStringUtil::toLower(filename_lc); + if (std::string::npos != filename_lc.rfind(".dae")) { mModelLoader = new LLDAELoader( filename, -- cgit v1.3 From e23b3972a00370aff25d582ce33dc0db6d795213 Mon Sep 17 00:00:00 2001 From: Dave Parks Date: Wed, 22 Mar 2023 18:25:47 -0500 Subject: DRTVWR-559 Fix for bad hashing of materials breaking render batches and who knows what else. --- indra/llprimitive/llgltfmaterial.cpp | 10 ++++++++++ indra/llprimitive/llgltfmaterial.h | 9 +-------- indra/llprimitive/llmaterial.cpp | 2 +- indra/newview/llvovolume.cpp | 3 ++- 4 files changed, 14 insertions(+), 10 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 62b693919c..f3aa5b0648 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -692,3 +692,13 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) } } } + +LLUUID LLGLTFMaterial::getHash() const +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; + // HACK - hash the bytes of this object but don't include the ref count + LLUUID hash; + HBXXH128::digest(hash, (unsigned char*)this + sizeof(LLRefCount), sizeof(*this) - sizeof(LLRefCount)); + return hash; +} + diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index b453b91e67..a53b68a50f 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -115,14 +115,7 @@ public: bool mOverrideAlphaMode = false; // get a UUID based on a hash of this LLGLTFMaterial - LLUUID getHash() const - { - LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; - // HACK - hash the bytes of this object but don't include the ref count - LLUUID hash; - HBXXH128::digest(hash, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); - return hash; - } + LLUUID getHash() const; //setters for various members (will clamp to acceptable ranges) // for_override - set to true if this value is being set as part of an override (important for handling override to default value) diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index a694a666c6..37525e4a3d 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -481,7 +481,7 @@ LLUUID LLMaterial::getHash() const LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; // HACK - hash the bytes of this LLMaterial, but trim off the S32 in LLRefCount LLUUID id; - HBXXH128::digest(id, (unsigned char*)this + sizeof(S32), sizeof(this) - sizeof(S32)); + HBXXH128::digest(id, (unsigned char*)this + sizeof(LLRefCount), sizeof(*this) - sizeof(LLRefCount)); return id; } diff --git a/indra/newview/llvovolume.cpp b/indra/newview/llvovolume.cpp index e1335acc17..237f9e34a0 100644 --- a/indra/newview/llvovolume.cpp +++ b/indra/newview/llvovolume.cpp @@ -5416,7 +5416,8 @@ void LLVolumeGeometryManager::registerFace(LLSpatialGroup* group, LLFace* facep, if (gltf_mat) { - // nothing to do, render pools will reference the GLTF material + // just remember the material ID, render pools will reference the GLTF material + draw_info->mMaterialID = mat_id; } else if (mat) { -- cgit v1.3 From d423263d54fc72cf857f3e147ac3860ca16c652f Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 23 Mar 2023 01:18:07 +0200 Subject: SL-19169 Local material updates aren't applied with non-default transforms --- indra/llprimitive/llgltfmaterial.h | 7 +++++ indra/llprimitive/lltextureentry.cpp | 27 +++++++++++++++++++ indra/newview/llfetchedgltfmaterial.cpp | 12 +++++++++ indra/newview/llfetchedgltfmaterial.h | 2 ++ indra/newview/lllocalgltfmaterials.cpp | 31 ++++++++++++++++++++++ indra/newview/lllocalgltfmaterials.h | 5 ++++ indra/newview/llviewerobject.cpp | 9 +++---- .../default/xui/en/floater_material_editor.xml | 1 - 8 files changed, 88 insertions(+), 6 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a53b68a50f..bdabd657e1 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -41,6 +41,8 @@ namespace tinygltf class Model; } +class LLTextureEntry; + class LLGLTFMaterial : public LLRefCount { public: @@ -193,6 +195,11 @@ public: // True if setBaseMaterial() was just called bool isClearedForBaseMaterial(); + // For local materials, they have to keep track of where + // they are assigned to for full updates + virtual void addTextureEntry(LLTextureEntry* te) {}; + virtual void removeTextureEntry(LLTextureEntry* te) {}; + private: template void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id); diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 49f67918f8..a665db378b 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -112,7 +112,15 @@ LLTextureEntry &LLTextureEntry::operator=(const LLTextureEntry &rhs) mMaterialID = rhs.mMaterialID; + if (mGLTFMaterial) + { + mGLTFMaterial->removeTextureEntry(this); + } mGLTFMaterial = rhs.mGLTFMaterial; + if (mGLTFMaterial) + { + mGLTFMaterial->addTextureEntry(this); + } if (rhs.mGLTFMaterialOverrides.notNull()) { @@ -155,6 +163,12 @@ LLTextureEntry::~LLTextureEntry() delete mMediaEntry; mMediaEntry = NULL; } + + if (mGLTFMaterial) + { + mGLTFMaterial->removeTextureEntry(this); + mGLTFMaterial = NULL; + } } bool LLTextureEntry::operator!=(const LLTextureEntry &rhs) const @@ -524,7 +538,20 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); + if (mGLTFMaterial) + { + // Local materials have to keep track + // due to update mechanics + mGLTFMaterial->removeTextureEntry(this); + } + mGLTFMaterial = material; + + if (mGLTFMaterial) + { + mGLTFMaterial->addTextureEntry(this); + } + if (mGLTFMaterial == nullptr) { setGLTFRenderMaterial(nullptr); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 80074cc655..2e71b4fa87 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -46,6 +46,18 @@ LLFetchedGLTFMaterial::~LLFetchedGLTFMaterial() } +LLFetchedGLTFMaterial& LLFetchedGLTFMaterial::operator=(const LLFetchedGLTFMaterial& rhs) +{ + LLGLTFMaterial::operator =(rhs); + + mBaseColorTexture = rhs.mBaseColorTexture; + mNormalTexture = rhs.mNormalTexture; + mMetallicRoughnessTexture = rhs.mMetallicRoughnessTexture; + mEmissiveTexture = rhs.mEmissiveTexture; + + return *this; +} + void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) { // glTF 2.0 Specification 3.9.4. Alpha Coverage diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 0b51770493..1668657281 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -39,6 +39,8 @@ public: LLFetchedGLTFMaterial(); virtual ~LLFetchedGLTFMaterial(); + LLFetchedGLTFMaterial& operator=(const LLFetchedGLTFMaterial& rhs); + // If this material is loaded, fire the given function void onMaterialComplete(std::function material_complete); diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index 996b168262..d464ea0571 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -45,6 +45,7 @@ #include "llmaterialmgr.h" #include "llnotificationsutil.h" #include "llscrolllistctrl.h" +#include "lltextureentry.h" #include "lltinygltfhelper.h" #include "llviewertexture.h" @@ -118,6 +119,15 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const return mMaterialIndex; } +void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.insert(te); +} +void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.erase(te); +} + /* update functions */ bool LLLocalGLTFMaterial::updateSelf() { @@ -154,6 +164,27 @@ bool LLLocalGLTFMaterial::updateSelf() gGLTFMaterialList.addMaterial(mWorldID, this); mUpdateRetries = LL_LOCAL_UPDATE_RETRIES; + + for (LLTextureEntry* entry : mTextureEntires) + { + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + if (override_mat) + { + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) + { + *render_mat = *this; + render_mat->applyOverride(*override_mat); + } + } + } + updated = true; } diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 6919b9b4b2..1442b83a40 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -34,6 +34,7 @@ class LLScrollListCtrl; class LLGLTFMaterial; class LLViewerObject; +class LLTextureEntry; class LLLocalGLTFMaterial : public LLFetchedGLTFMaterial { @@ -48,6 +49,9 @@ public: /* accessors */ LLUUID getWorldID() const; S32 getIndexInFile() const; + void addTextureEntry(LLTextureEntry* te) override; + void removeTextureEntry(LLTextureEntry* te) override; + public: bool updateSelf(); @@ -77,6 +81,7 @@ private: /* members */ ELinkStatus mLinkStatus; S32 mUpdateRetries; S32 mMaterialIndex; // Single file can have more than one + std::set mTextureEntires; }; class LLLocalGLTFMaterialTimer : public LLEventTimer diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index cb1694821d..a3a825c199 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5368,8 +5368,10 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma LLFetchedGLTFMaterial* src_mat = (LLFetchedGLTFMaterial*) tep->getGLTFMaterial(); + // if override mat exists, we must also have a source mat if (!src_mat) - { // we can get into this state if an override has arrived before the viewer has + { + // we can get into this state if an override has arrived before the viewer has // received or handled an update, return TEM_CHANGE_NONE to signal to LLGLTFMaterialList that it // should queue the update for later return retval; @@ -5383,10 +5385,7 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma tep->setGLTFMaterialOverride(override_mat); - // if override mat exists, we must also have a source mat - llassert(override_mat ? bool(src_mat) : true); - - if (override_mat && src_mat) + if (override_mat) { LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); render_mat->applyOverride(*override_mat); diff --git a/indra/newview/skins/default/xui/en/floater_material_editor.xml b/indra/newview/skins/default/xui/en/floater_material_editor.xml index 1c58ea6977..a6a401f43e 100644 --- a/indra/newview/skins/default/xui/en/floater_material_editor.xml +++ b/indra/newview/skins/default/xui/en/floater_material_editor.xml @@ -29,7 +29,6 @@ color="DkGray2" opaque="true" tab_stop="true" - border="false" reserve_scroll_corner="false"> Date: Wed, 29 Mar 2023 17:05:40 -0700 Subject: CMake and tests fixups after merge with main for DRTVWR-559 --- indra/cmake/LLCommon.cmake | 1 - indra/cmake/LLMath.cmake | 1 - indra/cmake/LLRender.cmake | 22 ---------------------- indra/cmake/Tracy.cmake | 7 ++----- indra/llprimitive/CMakeLists.txt | 7 +++---- indra/newview/CMakeLists.txt | 6 +++--- indra/newview/llgltfmateriallist.cpp | 2 -- .../newview/tests/llviewercontrollistener_test.cpp | 5 ++--- indra/newview/tests/llvocache_test.cpp | 9 +++++---- 9 files changed, 15 insertions(+), 45 deletions(-) delete mode 100644 indra/cmake/LLRender.cmake (limited to 'indra/llprimitive') diff --git a/indra/cmake/LLCommon.cmake b/indra/cmake/LLCommon.cmake index 03f1fe39cb..869d5805f2 100644 --- a/indra/cmake/LLCommon.cmake +++ b/indra/cmake/LLCommon.cmake @@ -9,4 +9,3 @@ include(ZLIBNG) include(JsonCpp) include(XmlRpcEpi) - ${TRACY_LIBRARY} diff --git a/indra/cmake/LLMath.cmake b/indra/cmake/LLMath.cmake index 688e62e24b..e841d2ac78 100644 --- a/indra/cmake/LLMath.cmake +++ b/indra/cmake/LLMath.cmake @@ -2,5 +2,4 @@ include(Variables) include(Mikktspace) -include(MESHOPTIMIZER) diff --git a/indra/cmake/LLRender.cmake b/indra/cmake/LLRender.cmake deleted file mode 100644 index 2d9d3725ad..0000000000 --- a/indra/cmake/LLRender.cmake +++ /dev/null @@ -1,22 +0,0 @@ -# -*- cmake -*- - -include(Variables) -include(FreeType) -include(GLH) -include(GLEXT) - -set(LLRENDER_INCLUDE_DIRS - ${LIBS_OPEN_DIR}/llrender - ${GLH_INCLUDE_DIR} - ${GLEXT_INCLUDE_DIR} - ) - -if (BUILD_HEADLESS) - set(LLRENDER_HEADLESS_LIBRARIES - llrenderheadless - ) -endif (BUILD_HEADLESS) -set(LLRENDER_LIBRARIES - llrender - ) - diff --git a/indra/cmake/Tracy.cmake b/indra/cmake/Tracy.cmake index cf9c866f8e..0bf3bd85ff 100644 --- a/indra/cmake/Tracy.cmake +++ b/indra/cmake/Tracy.cmake @@ -11,11 +11,8 @@ if (USE_TRACY) use_prebuilt_binary(tracy) target_include_directories( ll::tracy SYSTEM INTERFACE ${LIBS_PREBUILT_DIR}/include/tracy) - set(TRACY_LIBRARY "TracyClient") - set(TRACY_LIBRARY "TracyClient") -# See: indra/llcommon/llprofiler.h - target_compile_definitions(ll::tracy INTERFACE LL_PROFILER_CONFIGURATION=3 ) - set(TRACY_LIBRARY "TracyClient") + # See: indra/llcommon/llprofiler.h + add_compile_definitions(LL_PROFILER_CONFIGURATION=3) endif (USE_TRACY) diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index f8f55759ae..76d261ab3e 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -7,11 +7,8 @@ include(LLCommon) include(LLCoreHttp) include(LLPhysicsExtensions) include(LLPrimitive) -include(LLRender) include(GLH) include(TinyGLTF) - ${LLRENDER_INCLUDE_DIRS} - ${TINYGLTF_INCLUDE_DIR} set(llprimitive_SOURCE_FILES lldaeloader.cpp @@ -68,6 +65,7 @@ target_link_libraries(llprimitive llcorehttp llxml llcharacter + llrender llphysicsextensions_impl ll::colladadom ll::pcre @@ -82,6 +80,7 @@ if (LL_TESTS) llprimitive.cpp llgltfmaterial.cpp ) - + + set_property(SOURCE llprimitive.cpp PROPERTY LL_TEST_ADDITIONAL_LIBRARIES llmessage) LL_ADD_PROJECT_UNIT_TESTS(llprimitive "${llprimitive_TEST_SOURCE_FILES}") endif (LL_TESTS) diff --git a/indra/newview/CMakeLists.txt b/indra/newview/CMakeLists.txt index 12d452011d..b197182009 100644 --- a/indra/newview/CMakeLists.txt +++ b/indra/newview/CMakeLists.txt @@ -2229,8 +2229,8 @@ if (LL_TESTS) set_source_files_properties( llvocache.cpp PROPERTIES - LL_TEST_ADDITIONAL_SOURCE_FILES - ../llmessage/lldatapacker.cpp + LL_TEST_ADDITIONAL_SOURCE_FILES ../llmessage/lldatapacker.cpp + LL_TEST_ADDITIONAL_PROJECTS "llprimitive" ) set(test_libs @@ -2251,7 +2251,6 @@ if (LL_TESTS) LL_TEST_ADDITIONAL_LIBRARIES "${test_libs}" ) - set_source_files_properties( llworldmap.cpp llworldmipmap.cpp @@ -2271,6 +2270,7 @@ if (LL_TESTS) PROPERTIES LL_TEST_ADDITIONAL_SOURCE_FILES llversioninfo.cpp ) + set_property( SOURCE ${viewer_TEST_SOURCE_FILES} PROPERTY diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 9c78e48cab..57a67f52f6 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -554,8 +554,6 @@ void LLGLTFMaterialList::onAssetLoadComplete(const LLUUID& id, LLAssetType::ETyp LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); - typedef std::pair return_data_t; - main_queue->postTo( general_queue, [id, asset_type, asset_data]() // Work done on general queue diff --git a/indra/newview/tests/llviewercontrollistener_test.cpp b/indra/newview/tests/llviewercontrollistener_test.cpp index 6d100ef984..8aed2a8043 100644 --- a/indra/newview/tests/llviewercontrollistener_test.cpp +++ b/indra/newview/tests/llviewercontrollistener_test.cpp @@ -10,9 +10,9 @@ */ // Precompiled header -#include "llviewerprecompiledheaders.h" +#include "../llviewerprecompiledheaders.h" // associated header -#include "llviewercontrollistener.h" +#include "../llviewercontrollistener.h" // STL headers // std headers // external library headers @@ -21,7 +21,6 @@ #include "../test/catch_and_store_what_in.h" // catch_what() #include "commoncontrol.h" #include "llcontrol.h" // LLControlGroup -#include "llviewercontrollistener.h" /***************************************************************************** * TUT diff --git a/indra/newview/tests/llvocache_test.cpp b/indra/newview/tests/llvocache_test.cpp index ea6abe254e..c27730eb58 100644 --- a/indra/newview/tests/llvocache_test.cpp +++ b/indra/newview/tests/llvocache_test.cpp @@ -28,15 +28,16 @@ #include "../llviewerprecompiledheaders.h" #include "../test/lltut.h" -#include "llvocache.h" +#include "../llvocache.h" #include "lldir.h" -#include "llhudobject.h" +#include "../llhudobject.h" #include "llregionhandle.h" #include "llsdutil.h" #include "llsdserialize.h" -#include "llviewerobjectlist.h" -#include "llviewerregion.h" + +#include "../llviewerobjectlist.h" +#include "../llviewerregion.h" #include "lldir_stub.cpp" #include "llvieweroctree_stub.cpp" -- cgit v1.3 From 7c831d115b55b96129806353a51a01dcf2bcebba Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 3 Apr 2023 17:22:40 -0500 Subject: SL-18458 Make LLVOCache the one source of truth on most recently received overrides. (#147) --- indra/llprimitive/lltextureentry.cpp | 11 ++++++-- indra/llprimitive/lltextureentry.h | 2 +- indra/newview/llappviewer.cpp | 2 +- indra/newview/llfetchedgltfmaterial.cpp | 2 +- indra/newview/llgltfmateriallist.cpp | 45 +++++++++++++++---------------- indra/newview/llspatialpartition.cpp | 5 ++-- indra/newview/llviewerobject.cpp | 23 +++++++++------- indra/newview/llviewerregion.cpp | 35 ++++++++++++++---------- indra/newview/llviewerregion.h | 2 ++ indra/newview/llvocache.cpp | 47 ++++++++++++++++++++++++--------- indra/newview/llvocache.h | 8 +++--- 11 files changed, 112 insertions(+), 70 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index a665db378b..17b1f4cf5c 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -559,10 +559,17 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin } } -void LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat) +S32 LLTextureEntry::setGLTFMaterialOverride(LLGLTFMaterial* mat) { llassert(mat == nullptr || getGLTFMaterial() != nullptr); // if override is not null, base material must not be null - mGLTFMaterialOverrides = mat; + if (mat == mGLTFMaterialOverrides) + { + return TEM_CHANGE_NONE; + } + + mGLTFMaterialOverrides = mat; + + return TEM_CHANGE_TEXTURE; } S32 LLTextureEntry::setBaseMaterial() diff --git a/indra/llprimitive/lltextureentry.h b/indra/llprimitive/lltextureentry.h index 9a81181f3a..f5f2c0172d 100644 --- a/indra/llprimitive/lltextureentry.h +++ b/indra/llprimitive/lltextureentry.h @@ -200,7 +200,7 @@ public: // GLTF override LLGLTFMaterial* getGLTFMaterialOverride() const { return mGLTFMaterialOverrides; } - void setGLTFMaterialOverride(LLGLTFMaterial* mat); + S32 setGLTFMaterialOverride(LLGLTFMaterial* mat); // Clear most overrides so the render material better matches the material // ID (preserve transforms). If the overrides become passthrough, set the // overrides to nullptr. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 12ed123805..b17c78abac 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4281,7 +4281,7 @@ U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 15; + const U32 INDRA_OBJECT_CACHE_VERSION = 16; return INDRA_OBJECT_CACHE_VERSION; } diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 2e71b4fa87..4efe1ad189 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -89,7 +89,7 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) if (!LLPipeline::sShadowRender) { - if (mNormalTexture.notNull()) + if (mNormalTexture.notNull() && mNormalTexture->getDiscardLevel() <= 4) { shader->bindTexture(LLShaderMgr::BUMP_MAP, mNormalTexture); } diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 57a67f52f6..08ce43434f 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -192,14 +192,7 @@ public: { LL_DEBUGS("GLTF") << "material overrides cache" << LL_ENDL; - // default to main region if message doesn't specify - LLViewerRegion * region = gAgent.getRegion();; - - if (object_override.mHasRegionHandle) - { - // TODO start requiring this once server sends this for all messages - region = LLWorld::instance().getRegionFromHandle(object_override.mRegionHandle); - } + LLViewerRegion * region = LLWorld::instance().getRegionFromHandle(object_override.mRegionHandle); if (region) { @@ -248,8 +241,8 @@ public: { results.reserve(object_override.mSides.size()); // parse json - std::map::const_iterator iter = object_override.mSides.begin(); - std::map::const_iterator end = object_override.mSides.end(); + std::unordered_map::const_iterator iter = object_override.mSides.begin(); + std::unordered_map::const_iterator end = object_override.mSides.end(); while (iter != end) { LLPointer override_data = new LLGLTFMaterial(); @@ -278,7 +271,6 @@ public: }, [object_override, this](std::vector results) // Callback to main thread { - LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId); if (results.size() > 0 ) @@ -292,23 +284,16 @@ public: // flag this side to not be nulled out later side_set.insert(results[i].mSide); - if (!obj || !obj->setTEGLTFMaterialOverride(results[i].mSide, results[i].mMaterial)) + if (obj) { - // object not ready to receive override data, queue for later - gGLTFMaterialList.queueOverrideUpdate(object_override.mObjectId, results[i].mSide, results[i].mMaterial); - } - else if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected()) - { - doSelectionCallbacks(object_override.mObjectId, results[i].mSide); + obj->setTEGLTFMaterialOverride(results[i].mSide, results[i].mMaterial); } } - else + + // unblock material editor + if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected()) { - // unblock material editor - if (obj && obj->getTE(results[i].mSide) && obj->getTE(results[i].mSide)->isSelected()) - { - doSelectionCallbacks(object_override.mObjectId, results[i].mSide); - } + doSelectionCallbacks(object_override.mObjectId, results[i].mSide); } } @@ -353,6 +338,7 @@ namespace void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data) { +#if 0 override_list_t& overrides = mQueuedOverrides[id]; if (overrides.size() < side + 1) @@ -361,6 +347,7 @@ void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFM } overrides[side] = override_data; +#endif } void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) @@ -368,6 +355,8 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) LL_PROFILE_ZONE_SCOPED; llassert(obj); + +#if 0 const LLUUID& id = obj->getID(); auto iter = mQueuedOverrides.find(id); @@ -410,6 +399,14 @@ void LLGLTFMaterialList::applyQueuedOverrides(LLViewerObject* obj) mQueuedOverrides.erase(iter); } +#else + // the override cache is the authoritarian source of the most recent override data + LLViewerRegion* regionp = obj->getRegion(); + if (regionp) + { + regionp->applyCacheMiscExtras(obj); + } +#endif } void LLGLTFMaterialList::queueModify(const LLViewerObject* obj, S32 side, const LLGLTFMaterial* mat) diff --git a/indra/newview/llspatialpartition.cpp b/indra/newview/llspatialpartition.cpp index fc9b3093e8..4d99ee1386 100644 --- a/indra/newview/llspatialpartition.cpp +++ b/indra/newview/llspatialpartition.cpp @@ -1375,7 +1375,7 @@ S32 LLSpatialPartition::cull(LLCamera &camera, std::vector* result selecter.traverse(mOctree); return 0; - } +} extern BOOL gCubeSnapshot; @@ -1540,6 +1540,7 @@ void pushVertsColorCoded(LLSpatialGroup* group) // - a linked rigged drawable face has the wrong draw order index bool check_rigged_group(LLDrawable* drawable) { +#if 0 if (drawable->isState(LLDrawable::RIGGED)) { LLSpatialGroup* group = drawable->getSpatialGroup(); @@ -1587,7 +1588,7 @@ bool check_rigged_group(LLDrawable* drawable) } } } - +#endif return true; } diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 1c53bddb62..e641ac4215 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5399,19 +5399,22 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma return retval; } - tep->setGLTFMaterialOverride(override_mat); + retval = tep->setGLTFMaterialOverride(override_mat); - if (override_mat) + if (retval) { - LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); - render_mat->applyOverride(*override_mat); - tep->setGLTFRenderMaterial(render_mat); - retval = TEM_CHANGE_TEXTURE; + if (override_mat) + { + LLFetchedGLTFMaterial* render_mat = new LLFetchedGLTFMaterial(*src_mat); + render_mat->applyOverride(*override_mat); + tep->setGLTFRenderMaterial(render_mat); + retval = TEM_CHANGE_TEXTURE; - } - else if (tep->setGLTFRenderMaterial(nullptr)) - { - retval = TEM_CHANGE_TEXTURE; + } + else if (tep->setGLTFRenderMaterial(nullptr)) + { + retval = TEM_CHANGE_TEXTURE; + } } return retval; diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 192a96a408..b159cc2750 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -2651,20 +2651,8 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data) { - LLUUID object_id = override_data.mObjectId; - LLViewerObject * obj = gObjectList.findObject(object_id); - if (obj != nullptr) - { - llassert(obj->getRegion() == this); - - U32 local_id = obj->getLocalID(); - - mImpl->mGLTFOverridesJson[local_id] = override_data; - } - else - { - LL_WARNS("GLTF") << "got material override for unknown object_id, cannot cache it" << LL_ENDL; - } + U32 object_id = override_data.mLocalId; + mImpl->mGLTFOverridesJson[object_id] = override_data; } LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) @@ -3560,3 +3548,22 @@ void LLViewerRegion::loadCacheMiscExtras(U32 local_id) LLGLTFMaterialList::loadCacheOverrides(iter->second); } } + +void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj) +{ + LL_PROFILE_ZONE_SCOPED_CATEGORY_DISPLAY; + llassert(obj); + + U32 local_id = obj->getLocalID(); + auto iter = mImpl->mGLTFOverridesJson.find(local_id); + if (iter != mImpl->mGLTFOverridesJson.end()) + { + llassert(iter->second.mGLTFMaterial.size() == iter->second.mSides.size()); + + for (auto& side : iter->second.mGLTFMaterial) + { + obj->setTEGLTFMaterialOverride(side.first, side.second); + } + } +} + diff --git a/indra/newview/llviewerregion.h b/indra/newview/llviewerregion.h index b132a3a5f3..fe0fdfb930 100644 --- a/indra/newview/llviewerregion.h +++ b/indra/newview/llviewerregion.h @@ -426,6 +426,8 @@ private: public: void loadCacheMiscExtras(U32 local_id); + void applyCacheMiscExtras(LLViewerObject* obj); + struct CompareDistance { bool operator()(const LLViewerRegion* const& lhs, const LLViewerRegion* const& rhs) diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index 0fbcf9c624..7081ecaa4b 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -57,9 +57,14 @@ BOOL check_write(LLAPRFile* apr_file, void* src, S32 n_bytes) bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) { - if (!data.has("object_id")) + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; + + llassert(data.has("local_id")); + llassert(data.has("object_id")); + llassert(data.has("region_handle_x") && data.has("region_handle_y")); + + if (!data.has("local_id")) { - mObjectId.setNull(); return false; } @@ -69,13 +74,13 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) U32 region_handle_y = data["region_handle_y"].asInteger(); U32 region_handle_x = data["region_handle_x"].asInteger(); mRegionHandle = to_region_handle(region_handle_x, region_handle_y); - mHasRegionHandle = true; } else { - mHasRegionHandle = false; + return false; } + mLocalId = data["local_id"].asInteger(); mObjectId = data["object_id"]; // message should be interpreted thusly: @@ -94,7 +99,26 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) for (int i = 0; i < sides.size(); ++i) { S32 side_idx = sides[i].asInteger(); - mSides[side_idx] = gltf_json[i].asString(); + std::string gltf_json_str = gltf_json[i].asString(); + mSides[side_idx] = gltf_json_str; + LLGLTFMaterial* override_mat = new LLGLTFMaterial(); + std::string error, warn; + if (override_mat->fromJSON(gltf_json_str, warn, error)) + { + mGLTFMaterial[i] = override_mat; + } + else + { + LL_WARNS() << "Invalid GLTF string: \n" << gltf_json_str << LL_ENDL; + if (!error.empty()) + { + LL_WARNS() << "Error: " << error << LL_ENDL; + } + if (!warn.empty()) + { + LL_WARNS() << "Warning: " << warn << LL_ENDL; + } + } } } else @@ -107,16 +131,15 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) LLSD LLGLTFOverrideCacheEntry::toLLSD() const { + LL_PROFILE_ZONE_SCOPED_CATEGORY_NETWORK; LLSD data; - if (mHasRegionHandle) - { - U32 region_handle_x, region_handle_y; - from_region_handle(mRegionHandle, ®ion_handle_x, ®ion_handle_y); - data["region_handle_y"] = LLSD::Integer(region_handle_y); - data["region_handle_x"] = LLSD::Integer(region_handle_x); - } + U32 region_handle_x, region_handle_y; + from_region_handle(mRegionHandle, ®ion_handle_x, ®ion_handle_y); + data["region_handle_y"] = LLSD::Integer(region_handle_y); + data["region_handle_x"] = LLSD::Integer(region_handle_x); data["object_id"] = mObjectId; + data["local_id"] = (LLSD::Integer) mLocalId; for (auto const & side : mSides) { diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index dcc8d37c5c..ec0df31828 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -32,6 +32,7 @@ #include "lldir.h" #include "llvieweroctree.h" #include "llapr.h" +#include "llgltfmaterial.h" #include @@ -46,9 +47,10 @@ public: LLSD toLLSD() const; LLUUID mObjectId; - std::map mSides; //json per side - U64 mRegionHandle; - bool mHasRegionHandle; + U32 mLocalId = 0; + std::unordered_map mSides; //json per side + std::unordered_map > mGLTFMaterial; //GLTF material per side + U64 mRegionHandle = 0; }; class LLVOCacheEntry -- cgit v1.3 From 698966f8e7ddcc0b123a83d7c4e381778f8cd8ab Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 4 Apr 2023 12:29:12 -0500 Subject: SL-19538 Remove hacky ambiance scale and take the mittens off probe a… (#151) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * SL-19538 Remove hacky ambiance scale and take the mittens off probe ambiance values. Fix for sky brightening being done in sRGB space. --- indra/llprimitive/llprimitive.cpp | 2 +- indra/llrender/llshadermgr.cpp | 2 +- indra/newview/app_settings/settings.xml | 11 --------- .../shaders/class1/deferred/fullbrightF.glsl | 4 ++-- .../app_settings/shaders/class1/deferred/skyV.glsl | 2 +- .../shaders/class2/deferred/alphaF.glsl | 2 -- .../shaders/class2/deferred/pbralphaF.glsl | 6 +---- .../shaders/class2/interface/irradianceGenF.glsl | 3 --- .../shaders/class2/windlight/atmosphericsF.glsl | 6 ++++- .../class2/windlight/atmosphericsFuncs.glsl | 4 +--- .../shaders/class2/windlight/transportF.glsl | 22 ++++-------------- .../shaders/class3/deferred/fullbrightShinyF.glsl | 5 +---- .../shaders/class3/deferred/materialF.glsl | 4 ---- .../shaders/class3/deferred/softenLightF.glsl | 4 +--- .../shaders/class3/environment/waterF.glsl | 4 ---- indra/newview/llreflectionmapmanager.cpp | 4 ---- indra/newview/llviewershadermgr.cpp | 2 +- indra/newview/pipeline.cpp | 26 ++++------------------ .../default/xui/en/floater_adjust_environment.xml | 2 +- .../newview/skins/default/xui/en/floater_tools.xml | 2 +- .../default/xui/en/panel_settings_sky_atmos.xml | 2 +- 21 files changed, 26 insertions(+), 93 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 8b470d235c..5dfce4ae16 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -83,7 +83,7 @@ const F32 LIGHT_MAX_CUTOFF = 180.f; // reflection probes const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f; -const F32 REFLECTION_PROBE_MAX_AMBIANCE = 1.f; +const F32 REFLECTION_PROBE_MAX_AMBIANCE = 100.f; const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f; const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f; const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f; diff --git a/indra/llrender/llshadermgr.cpp b/indra/llrender/llshadermgr.cpp index 016cbe6e75..e1679c7f52 100644 --- a/indra/llrender/llshadermgr.cpp +++ b/indra/llrender/llshadermgr.cpp @@ -276,7 +276,7 @@ BOOL LLShaderMgr::attachShaderFeatures(LLGLSLShader * shader) } } - if (features->hasAtmospherics || features->isDeferred) + if (features->hasAtmospherics || features->isDeferred || features->hasTransport) { if (!shader->attachFragmentObject("windlight/atmosphericsFuncs.glsl")) { return FALSE; diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 5ffd610fba..4490e3eec2 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10347,17 +10347,6 @@ Value 128 - RenderReflectionProbeAmbianceScale - - Comment - Scaler to apply to reflection probes to over-brighten sky contributions to indirect light - Persist - 1 - Type - F32 - Value - 8 - RenderTonemapper Comment diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index 3a15fd1111..03df9fd4a1 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -44,7 +44,6 @@ vec4 applyWaterFogView(vec3 pos, vec4 color); vec3 srgb_to_linear(vec3 cs); vec3 linear_to_srgb(vec3 cl); vec3 fullbrightAtmosTransport(vec3 light); -vec3 fullbrightScaleSoftClip(vec3 light); #ifdef HAS_ALPHA_MASK uniform float minimum_alpha; @@ -88,8 +87,9 @@ void main() #endif #ifndef IS_HUD - color.rgb = fullbrightAtmosTransport(color.rgb); color.rgb = srgb_to_linear(color.rgb); + color.rgb = fullbrightAtmosTransport(color.rgb); + #endif frag_color.rgb = color.rgb; diff --git a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl index 0090155e5c..62d134188c 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/skyV.glsl @@ -91,7 +91,7 @@ void main() vary_LightNormPosDot = rel_pos_lightnorm_dot; // Initialize temp variables - vec3 sunlight = (sun_up_factor == 1) ? sunlight_color*2.0 : moonlight_color; + vec3 sunlight = (sun_up_factor == 1) ? sunlight_color : moonlight_color; // Sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index e7322c14fb..70be9a9029 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -276,9 +276,7 @@ void main() color.rgb *= diffuse_linear.rgb; - color.rgb = linear_to_srgb(color.rgb); color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); - color.rgb = srgb_to_linear(color.rgb); vec4 light = vec4(0,0,0,0); diff --git a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl index fb76db99a0..b76443f0f0 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/pbralphaF.glsl @@ -83,7 +83,6 @@ vec3 linear_to_srgb(vec3 c); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); vec3 atmosFragLightingLinear(vec3 color, vec3 additive, vec3 atten); -vec3 scaleSoftClipFragLinear(vec3 color); void calcHalfVectors(vec3 lv, vec3 n, vec3 v, out vec3 h, out vec3 l, out float nh, out float nl, out float nv, out float vh, out float lightDist); float calcLegacyDistanceAttenuation(float distance, float falloff); @@ -236,11 +235,8 @@ void main() color = pbrBaseLight(diffuseColor, specularColor, metallic, v, norm.xyz, perceptualRoughness, light_dir, sunlit_linear, scol, radiance, irradiance, colorEmissive, ao, additive, atten, spec); glare += max(max(spec.r, spec.g), spec.b); - color.rgb = linear_to_srgb(color.rgb); color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); - color.rgb = scaleSoftClipFragLinear(color.rgb); - color.rgb = srgb_to_linear(color.rgb); - + vec3 light = vec3(0); // Punctual lights diff --git a/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl index baf68e11f4..d21af946e0 100644 --- a/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl +++ b/indra/newview/app_settings/shaders/class2/interface/irradianceGenF.glsl @@ -32,7 +32,6 @@ uniform samplerCubeArray reflectionProbes; uniform int sourceIdx; uniform float max_probe_lod; -uniform float ambiance_scale; in vec3 vary_dir; @@ -200,8 +199,6 @@ vec4 filterColor(vec3 N) color /= float(u_sampleCount); - color.rgb *= ambiance_scale; - return color; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 1d02498209..22e93496d2 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -30,10 +30,14 @@ vec3 scaleSoftClipFrag(vec3 light); vec3 srgb_to_linear(vec3 col); vec3 linear_to_srgb(vec3 col); +uniform int sun_up_factor; + vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { light *= atten.r; - light += additive * 2.0; + additive = srgb_to_linear(additive*2.0); + additive *= sun_up_factor + 1.0; + light += additive; return light; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index c2527db218..12a99edc34 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -63,9 +63,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou vec3 rel_pos_norm = normalize(rel_pos); float rel_pos_len = length(rel_pos); - float scale = sun_up_factor + 1; vec3 sunlight = (sun_up_factor == 1) ? sunlight_color: moonlight_color; - sunlight *= scale; // sunlight attenuation effect (hue and brightness) due to atmosphere // this is used later for sunlight modulation at various altitudes @@ -143,7 +141,7 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou // fudge sunlit and amblit to get consistent lighting compared to legacy // midday before PBR was a thing - sunlit = sunlight.rgb / scale; + sunlit = sunlight.rgb; amblit = tmpAmbient.rgb * 0.25; additive *= vec3(1.0 - combined_haze); diff --git a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl index 6aa719d200..8221ba9516 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/transportF.glsl @@ -30,14 +30,13 @@ vec3 getAdditiveColor(); vec3 getAtmosAttenuation(); -vec3 srgb_to_linear(vec3 col); -vec3 linear_to_srgb(vec3 col); +vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten); + +// the below implementations are deprecated but remain here as adapters for shaders that haven't been refactored yet vec3 atmosTransportFrag(vec3 light, vec3 additive, vec3 atten) { - light *= atten.r; - light += additive * 2.0; - return light; + return atmosFragLighting(light, additive, atten); } vec3 atmosTransport(vec3 light) @@ -45,30 +44,17 @@ vec3 atmosTransport(vec3 light) return atmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); } -vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten) -{ - // same as non-linear version, probably fine - //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; - //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); - return atmosTransportFrag(light, additive, atten); -} - vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten) { - //float brightness = dot(light.rgb * 0.5, vec3(0.3333)) + 0.1; - //return mix(atmosTransportFrag(light.rgb, additive, atten), light.rgb + additive, brightness * brightness); return atmosTransportFrag(light, additive, atten); } vec3 fullbrightAtmosTransport(vec3 light) { - //return fullbrightAtmosTransportFrag(light, getAdditiveColor(), getAtmosAttenuation()); return atmosTransport(light); } vec3 fullbrightShinyAtmosTransport(vec3 light) { - //float brightness = dot(light.rgb, vec3(0.33333)); - //return mix(atmosTransport(light.rgb), (light.rgb + getAdditiveColor().rgb) * (2.0 - brightness), brightness * brightness); return atmosTransport(light); } diff --git a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl index b90de7609b..f6bed16c84 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/fullbrightShinyF.glsl @@ -43,9 +43,7 @@ VARYING vec3 vary_position; uniform samplerCube environmentMap; -vec3 fullbrightShinyAtmosTransport(vec3 light); vec3 fullbrightAtmosTransportFrag(vec3 light, vec3 additive, vec3 atten); -vec3 fullbrightScaleSoftClip(vec3 light); void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, out vec3 sunlit, out vec3 amblit, out vec3 additive, out vec3 atten, bool use_ao); @@ -88,9 +86,8 @@ void main() sampleReflectionProbesLegacy(ambenv, glossenv, legacyenv, vec2(0), pos.xyz, norm.xyz, spec.a, env_intensity); applyLegacyEnv(color.rgb, legacyenv, spec, pos, norm, env_intensity); - color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten); - color.rgb = fullbrightScaleSoftClip(color.rgb); color.rgb = srgb_to_linear(color.rgb); + color.rgb = fullbrightAtmosTransportFrag(color.rgb, additive, atten); #endif color.a = 1.0; diff --git a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl index 6e41df34a4..02ab4494f6 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/materialF.glsl @@ -44,7 +44,6 @@ vec4 applyWaterFogView(vec3 pos, vec4 color); vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten); vec3 scaleSoftClipFragLinear(vec3 l); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); -vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten); vec3 srgb_to_linear(vec3 cs); vec3 linear_to_srgb(vec3 cs); @@ -386,10 +385,7 @@ void main() glare += cur_glare; } - color.rgb = linear_to_srgb(color.rgb); color.rgb = atmosFragLightingLinear(color.rgb, additive, atten); - color.rgb = scaleSoftClipFragLinear(color.rgb); - color.rgb = srgb_to_linear(color.rgb); vec3 npos = normalize(-pos.xyz); vec3 light = vec3(0, 0, 0); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index 0e3ebd1534..7953360054 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -71,7 +71,6 @@ vec4 getPositionWithDepth(vec2 pos_screen, float depth); void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, out vec3 sunlit, out vec3 amblit, out vec3 atten, out vec3 additive); vec3 atmosFragLightingLinear(vec3 l, vec3 additive, vec3 atten); vec3 scaleSoftClipFragLinear(vec3 l); -vec3 fullbrightAtmosTransportFragLinear(vec3 light, vec3 additive, vec3 atten); // reflection probe interface void sampleReflectionProbes(inout vec3 ambenv, inout vec3 glossenv, @@ -212,6 +211,7 @@ void main() { //should only be true of WL sky, just port over base color value color = srgb_to_linear(texture2D(emissiveRect, tc).rgb); + color *= sun_up_factor + 1.0; } else { @@ -262,9 +262,7 @@ void main() if (do_atmospherics) { - color = linear_to_srgb(color); color = atmosFragLightingLinear(color, additive, atten); - color = srgb_to_linear(color); } } diff --git a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl index 9da86759c9..ec0439fa97 100644 --- a/indra/newview/app_settings/shaders/class3/environment/waterF.glsl +++ b/indra/newview/app_settings/shaders/class3/environment/waterF.glsl @@ -282,11 +282,7 @@ void main() color = mix(color, fb.rgb, f); - color.rgb = linear_to_srgb(color.rgb); color = atmosFragLightingLinear(color, additive, atten); - color = scaleSoftClipFragLinear(color); - color.rgb = srgb_to_linear(color.rgb); - float spec = min(max(max(punctual.r, punctual.g), punctual.b), 0.05); diff --git a/indra/newview/llreflectionmapmanager.cpp b/indra/newview/llreflectionmapmanager.cpp index 09ac7e57a4..bccd76415f 100644 --- a/indra/newview/llreflectionmapmanager.cpp +++ b/indra/newview/llreflectionmapmanager.cpp @@ -651,10 +651,6 @@ void LLReflectionMapManager::updateProbeFace(LLReflectionMap* probe, U32 face) S32 channel = gIrradianceGenProgram.enableTexture(LLShaderMgr::REFLECTION_PROBES, LLTexUnit::TT_CUBE_MAP_ARRAY); mTexture->bind(channel); - static LLCachedControl ambiance_scale(gSavedSettings, "RenderReflectionProbeAmbianceScale", 8.f); - static LLStaticHashedString ambiance_scale_str("ambiance_scale"); - - gIrradianceGenProgram.uniform1f(ambiance_scale_str, ambiance_scale); gIrradianceGenProgram.uniform1i(sSourceIdx, sourceIdx); gIrradianceGenProgram.uniform1f(LLShaderMgr::REFLECTION_PROBE_MAX_LOD, mMaxProbeLOD); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index b50cb49b7e..8b402e210d 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -1920,7 +1920,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredFullbrightProgram.mFeatures.calculatesAtmospherics = true; gDeferredFullbrightProgram.mFeatures.hasGamma = true; gDeferredFullbrightProgram.mFeatures.hasTransport = true; - gDeferredFullbrightProgram.mFeatures.hasSrgb = true; + gDeferredFullbrightProgram.mFeatures.hasSrgb = true; gDeferredFullbrightProgram.mFeatures.mIndexedTextureChannels = LLGLSLShader::sIndexedTextureChannels; gDeferredFullbrightProgram.mShaderFiles.clear(); gDeferredFullbrightProgram.mShaderFiles.push_back(make_pair("deferred/fullbrightV.glsl", GL_VERTEX_SHADER)); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index dfe365b737..11deff5bff 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -5637,15 +5637,6 @@ void LLPipeline::setupHWLights() // Ambient LLColor4 ambient = psky->getTotalAmbient(); - static LLCachedControl ambiance_scale(gSavedSettings, "RenderReflectionProbeAmbianceScale", 8.f); - - F32 light_scale = 1.f; - - if (gCubeSnapshot && !mReflectionMapManager.isRadiancePass()) - { //darken local lights based on brightening of sky lighting - light_scale = 1.f / ambiance_scale; - } - gGL.setAmbientLightColor(ambient); bool sun_up = environment.getIsSunUp(); @@ -5739,7 +5730,7 @@ void LLPipeline::setupHWLights() } //send linear light color to shader - LLColor4 light_color = light->getLightLinearColor()*light_scale; + LLColor4 light_color = light->getLightLinearColor(); light_color.mV[3] = 0.0f; F32 fade = iter->fade; @@ -7885,15 +7876,6 @@ void LLPipeline::renderDeferredLighting() llassert(!sRenderingHUDs); - static LLCachedControl ambiance_scale(gSavedSettings, "RenderReflectionProbeAmbianceScale", 8.f); - - F32 light_scale = 1.f; - - if (gCubeSnapshot && !mReflectionMapManager.isRadiancePass()) - { //darken local lights based on brightening of sky lighting - light_scale = 1.f / ambiance_scale; - } - LLRenderTarget *screen_target = &mRT->screen; LLRenderTarget* deferred_light_target = &mRT->deferredLight; @@ -8129,7 +8111,7 @@ void LLPipeline::renderDeferredLighting() F32 s = volume->getLightRadius() * 1.5f; // send light color to shader in linear space - LLColor3 col = volume->getLightLinearColor()*light_scale; + LLColor3 col = volume->getLightLinearColor(); if (col.magVecSquared() < 0.001f) { @@ -8223,7 +8205,7 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredSpotLightProgram, drawablep); // send light color to shader in linear space - LLColor3 col = volume->getLightLinearColor() * light_scale; + LLColor3 col = volume->getLightLinearColor(); gDeferredSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, c); gDeferredSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, s); @@ -8298,7 +8280,7 @@ void LLPipeline::renderDeferredLighting() setupSpotLight(gDeferredMultiSpotLightProgram, drawablep); // send light color to shader in linear space - LLColor3 col = volume->getLightLinearColor() * light_scale; + LLColor3 col = volume->getLightLinearColor(); gDeferredMultiSpotLightProgram.uniform3fv(LLShaderMgr::LIGHT_CENTER, 1, tc.v); gDeferredMultiSpotLightProgram.uniform1f(LLShaderMgr::LIGHT_SIZE, light_size_final); diff --git a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml index 39fe573c98..f6bfb3574d 100644 --- a/indra/newview/skins/default/xui/en/floater_adjust_environment.xml +++ b/indra/newview/skins/default/xui/en/floater_adjust_environment.xml @@ -266,7 +266,7 @@ layout="topleft" left_delta="5" min_val="0" - max_val="1" + max_val="10" name="probe_ambiance" top_pad="5" width="185" diff --git a/indra/newview/skins/default/xui/en/floater_tools.xml b/indra/newview/skins/default/xui/en/floater_tools.xml index 1faf9c3152..5e999ed245 100644 --- a/indra/newview/skins/default/xui/en/floater_tools.xml +++ b/indra/newview/skins/default/xui/en/floater_tools.xml @@ -2574,7 +2574,7 @@ even though the user gets a free copy. label="Ambiance" label_width="55" left="10" - max_val="1" + max_val="100" min_val="0" mouse_opaque="true" name="Probe Ambiance" diff --git a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml index 094be36b01..a80b1a9166 100644 --- a/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml +++ b/indra/newview/skins/default/xui/en/panel_settings_sky_atmos.xml @@ -333,7 +333,7 @@ layout="topleft" left_delta="5" min_val="0" - max_val="1" + max_val="10" name="probe_ambiance" top_delta="20" width="219" -- cgit v1.3 From 2b2154f0217758b27b544d066024d922ba234d51 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 11 Apr 2023 15:09:58 -0500 Subject: SL-19564 Rebalance exposure and sky. Hack legacy diffuse map saturation and brightness to allow ACES Hill all the time. --- indra/llprimitive/lltextureentry.cpp | 2 +- indra/llrender/llglslshader.cpp | 3 +- indra/newview/app_settings/settings.xml | 19 +++--------- .../shaders/class1/deferred/exposureF.glsl | 7 +++-- .../shaders/class1/deferred/fullbrightF.glsl | 2 ++ .../shaders/class1/deferred/luminanceF.glsl | 2 +- .../class1/deferred/postDeferredGammaCorrect.glsl | 22 +++++-------- .../shaders/class1/environment/srgbF.glsl | 29 ++++++++++++++++- .../shaders/class2/deferred/alphaF.glsl | 2 ++ .../shaders/class2/windlight/atmosphericsF.glsl | 4 +-- .../class2/windlight/atmosphericsFuncs.glsl | 8 ++--- .../shaders/class3/deferred/multiPointLightF.glsl | 2 ++ .../shaders/class3/deferred/multiSpotLightF.glsl | 3 +- .../shaders/class3/deferred/pointLightF.glsl | 3 +- .../shaders/class3/deferred/softenLightF.glsl | 13 ++++++-- .../shaders/class3/deferred/spotLightF.glsl | 2 ++ indra/newview/llenvironment.cpp | 3 +- indra/newview/llenvironment.h | 1 + indra/newview/llsculptidsize.cpp | 2 +- indra/newview/lltoolcomp.cpp | 2 +- indra/newview/llviewercontrol.cpp | 1 - indra/newview/llviewermedia.cpp | 8 +++++ indra/newview/llviewermenu.cpp | 10 ++++++ indra/newview/llviewershadermgr.cpp | 15 +-------- indra/newview/pipeline.cpp | 12 +++++--- .../en/floater_preferences_graphics_advanced.xml | 36 ---------------------- indra/newview/skins/default/xui/en/menu_viewer.xml | 32 ++++++++++++------- 27 files changed, 128 insertions(+), 117 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lltextureentry.cpp b/indra/llprimitive/lltextureentry.cpp index 17b1f4cf5c..71caff1686 100644 --- a/indra/llprimitive/lltextureentry.cpp +++ b/indra/llprimitive/lltextureentry.cpp @@ -536,7 +536,7 @@ void LLTextureEntry::setGLTFMaterial(LLGLTFMaterial* material, bool local_origin // whether or not mGLTFMaterial is null, any existing override should have been cleared // before calling setGLTFMaterial // NOTE: if you're hitting this assert, try to make sure calling code is using LLViewerObject::setRenderMaterialID - llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); + //llassert(!local_origin || getGLTFMaterialOverride() == nullptr || getGLTFMaterialOverride()->isClearedForBaseMaterial()); if (mGLTFMaterial) { diff --git a/indra/llrender/llglslshader.cpp b/indra/llrender/llglslshader.cpp index 61a17e5f52..d27528296f 100644 --- a/indra/llrender/llglslshader.cpp +++ b/indra/llrender/llglslshader.cpp @@ -1099,7 +1099,8 @@ S32 LLGLSLShader::bindTexture(S32 uniform, LLRenderTarget* texture, bool depth, if (uniform > -1) { - gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0)); + bool has_mips = mode == LLTexUnit::TFO_TRILINEAR || mode == LLTexUnit::TFO_ANISOTROPIC; + gGL.getTexUnit(uniform)->bindManual(texture->getUsage(), texture->getTexture(0), has_mips); gGL.getTexUnit(uniform)->setTextureFilteringOption(mode); diff --git a/indra/newview/app_settings/settings.xml b/indra/newview/app_settings/settings.xml index 7d15214ccb..3d8cbc9527 100644 --- a/indra/newview/app_settings/settings.xml +++ b/indra/newview/app_settings/settings.xml @@ -10358,17 +10358,6 @@ Value 128 - RenderTonemapper - - Comment - Which tone mapping function to use (0 - Linear, 1 - ACES Narkowicz, 2 - ACES Hill) - Persist - 1 - Type - U32 - Value - 2 - RenderExposure Comment @@ -10456,7 +10445,7 @@ Type F32 Value - 3.0 + 1.25 RenderReflectionProbeMaxLocalLightAmbiance @@ -10478,7 +10467,7 @@ Type F32 Value - 0.125 + 0.6 RenderDynamicExposureMax @@ -10489,7 +10478,7 @@ Type F32 Value - 1.3 + 1.5 RenderDynamicExposureCoefficient @@ -10500,7 +10489,7 @@ Type F32 Value - 0.175 + 0.3 RenderShaderLODThreshold diff --git a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl index 7ed8e4c8ce..81f1e9aed0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/exposureF.glsl @@ -48,8 +48,11 @@ void main() vec2 tc = vec2(0.5,0.5); float L = textureLod(emissiveRect, tc, 8).r; - - float s = clamp(dynamic_exposure_params.x/L, dynamic_exposure_params.y, dynamic_exposure_params.z); + float max_L = dynamic_exposure_params.x; + L = clamp(L, 0.0, max_L); + L /= max_L; + L = pow(L, 2.0); + float s = mix(dynamic_exposure_params.z, dynamic_exposure_params.y, L); float prev = texture(exposureMap, vec2(0.5,0.5)).r; diff --git a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl index b5eae3a1d5..11532135dd 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/fullbrightF.glsl @@ -42,6 +42,7 @@ vec4 applyWaterFogView(vec3 pos, vec4 color); #endif vec3 srgb_to_linear(vec3 cs); +vec3 legacy_adjust(vec3 c); vec3 linear_to_srgb(vec3 cl); vec3 fullbrightAtmosTransport(vec3 light); @@ -87,6 +88,7 @@ void main() #endif #ifndef IS_HUD + color.rgb = legacy_adjust(color.rgb); color.rgb = srgb_to_linear(color.rgb); color.rgb = fullbrightAtmosTransport(color.rgb); diff --git a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl index e63e666778..e0eb91480e 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/luminanceF.glsl @@ -44,9 +44,9 @@ float lum(vec3 col) void main() { vec2 tc = vary_fragcoord*0.6+0.2; + tc.y -= 0.1; vec3 c = texture(diffuseRect, tc).rgb + texture(emissiveRect, tc).rgb; float L = lum(c); - frag_color = vec4(L); } diff --git a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl index ae6bdbba95..de766d6bc7 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/postDeferredGammaCorrect.glsl @@ -105,29 +105,21 @@ vec3 toneMapACES_Hill(vec3 color) uniform float exposure; uniform float gamma; +vec3 legacy_adjust_post(vec3 c); + vec3 toneMap(vec3 color, float gs) { float exp_scale = texture(exposureMap, vec2(0.5,0.5)).r; color *= exposure * exp_scale * gs; -#ifdef TONEMAP_ACES_NARKOWICZ - color = toneMapACES_Narkowicz(color); -#endif - -#ifdef TONEMAP_ACES_HILL color = toneMapACES_Hill(color); -#endif -#ifdef TONEMAP_ACES_HILL_EXPOSURE_BOOST - // boost exposure as discussed in https://github.com/mrdoob/three.js/pull/19621 - // this factor is based on the exposure correction of Krzysztof Narkowicz in his - // implemetation of ACES tone mapping - color *= 1.0/0.6; - color = toneMapACES_Hill(color); -#endif + color = linear_to_srgb(color); - return linear_to_srgb(color); + color = legacy_adjust_post(color); + + return color; } //=============================================================== @@ -181,7 +173,7 @@ vec3 legacyGamma(vec3 color) float legacyGammaApprox() { - //TODO -- figure out how to plumb this in as a uniform + //TODO -- figure out how to plumb this in as a uniform float c = 0.5; float gc = 1.0-pow(c, gamma); diff --git a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl index 4a8b892c3a..a3b48e0898 100644 --- a/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl +++ b/indra/newview/app_settings/shaders/class1/environment/srgbF.glsl @@ -72,7 +72,7 @@ vec3 rgb2hsv(vec3 c) vec4 q = mix(vec4(p.xyw, c.r), vec4(c.r, p.yzx), step(p.x, c.r)); float d = q.x - min(q.w, q.y); - float e = 1.0e-10; + float e = 1.0e-3; return vec3(abs(q.z + (q.w - q.y) / (6.0 * d + e)), d / (q.x + e), q.x); } @@ -82,3 +82,30 @@ vec3 hsv2rgb(vec3 c) vec3 p = abs(fract(c.xxx + K.xyz) * 6.0 - K.www); return c.z * mix(K.xxx, clamp(p - K.xxx, 0.0, 1.0), c.y); } + +vec3 legacy_adjust_no_brighten(vec3 c) +{ + vec3 desat = rgb2hsv(c.rgb); + desat.g *= 0.75; + desat.rgb = hsv2rgb(desat); + return desat; +} + +vec3 legacy_adjust(vec3 c) +{ +#if 1 + vec3 desat = rgb2hsv(c.rgb); + desat.g *= 1.0-(1.0-desat.b)*0.5; + //desat.g = max(desat.g-0.1*c.b-0.1, 0.0); + desat.b += (1.0-desat.b)*0.1f; + desat.rgb = hsv2rgb(desat); + return desat; +#else + return c; +#endif +} + +vec3 legacy_adjust_post(vec3 c) +{ + return c; +} diff --git a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl index 53552870ae..f4d6eff69e 100644 --- a/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl +++ b/indra/newview/app_settings/shaders/class2/deferred/alphaF.glsl @@ -77,6 +77,7 @@ vec4 applyWaterFogViewLinear(vec3 pos, vec4 color, vec3 sunlit); vec3 srgb_to_linear(vec3 c); vec3 linear_to_srgb(vec3 c); +vec3 legacy_adjust(vec3 c); vec2 encode_normal (vec3 n); vec3 atmosFragLightingLinear(vec3 light, vec3 additive, vec3 atten); @@ -239,6 +240,7 @@ void main() } diffuse_srgb.rgb *= vertex_color.rgb; + diffuse_srgb.rgb = legacy_adjust(diffuse_srgb.rgb); diffuse_linear.rgb = srgb_to_linear(diffuse_srgb.rgb); #endif // USE_VERTEX_COLOR diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl index 49ff49fdd8..e314555ef9 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsF.glsl @@ -36,9 +36,9 @@ vec3 atmosFragLighting(vec3 light, vec3 additive, vec3 atten) { light *= atten.r; additive = srgb_to_linear(additive*2.0); - // magic 3.0 here is to match the default RenderSkyHDRScale -- this parameter needs to be plumbed into sky settings or something + // magic 1.25 here is to match the default RenderSkyHDRScale -- this parameter needs to be plumbed into sky settings or something // so it's available to all shaders that call atmosFragLighting instead of just softenLightF.glsl - additive *= sun_up_factor*3.0 + 1.0; + additive *= sun_up_factor*1.25 + 1.0; light += additive; return light; } diff --git a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl index 14ce33f81f..22db9dce03 100644 --- a/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl +++ b/indra/newview/app_settings/shaders/class2/windlight/atmosphericsFuncs.glsl @@ -139,10 +139,8 @@ void calcAtmosphericVars(vec3 inPositionEye, vec3 light_dir, float ambFactor, ou // brightness of surface both sunlight and ambient - // fudge sunlit and amblit to get consistent lighting compared to legacy - // midday before PBR was a thing - sunlit = sunlight.rgb * (1.0+sun_up_factor*0.2); - amblit = tmpAmbient.rgb * 0.25; + sunlit = sunlight.rgb; + amblit = vec3(1,0,1); //should no longer be used, filled in by calcAtmosphericVarsLinear additive *= vec3(1.0 - combined_haze); } @@ -172,7 +170,7 @@ void calcAtmosphericVarsLinear(vec3 inPositionEye, vec3 norm, vec3 light_dir, ou sunlit *= 2.0; // squash ambient to approximate whatever weirdness legacy atmospherics were doing - amblit = ambient_color * 0.5 * (1.0+sun_up_factor*0.3); + amblit = ambient_color; // * (1.0+sun_up_factor*0.3); amblit *= ambientLighting(norm, light_dir); amblit = srgb_to_linear(amblit); diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl index 23ba95949a..5a2924afe5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiPointLightF.glsl @@ -58,6 +58,7 @@ vec4 getNormalEnvIntensityFlags(vec2 screenpos, out vec3 n, out float envIntensi vec2 getScreenXY(vec4 clip); vec2 getScreenCoord(vec4 clip); vec3 srgb_to_linear(vec3 c); +vec3 legacy_adjust(vec3 c); // Util vec3 hue_to_rgb(float hue); @@ -131,6 +132,7 @@ void main() } else { + diffuse.rgb = legacy_adjust(diffuse.rgb); diffuse = srgb_to_linear(diffuse); spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl index 30b7895157..33e5b2346c 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/multiSpotLightF.glsl @@ -83,6 +83,7 @@ vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n); vec2 getScreenXY(vec4 clip); vec2 getScreenCoord(vec4 clip); vec3 srgb_to_linear(vec3 cs); +vec3 legacy_adjust(vec3 c); vec4 texture2DLodSpecular(vec2 tc, float lod); vec4 getPosition(vec2 pos_screen); @@ -182,7 +183,7 @@ void main() } else { - + diffuse = legacy_adjust(diffuse); diffuse = srgb_to_linear(diffuse); spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl index 30b96ce8dc..471e5e7fd3 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/pointLightF.glsl @@ -63,6 +63,7 @@ vec4 getPosition(vec2 pos_screen); vec2 getScreenXY(vec4 clip); vec2 getScreenCoord(vec4 clip); vec3 srgb_to_linear(vec3 c); +vec3 legacy_adjust(vec3 c); float getDepth(vec2 tc); vec3 pbrPunctual(vec3 diffuseColor, vec3 specularColor, @@ -121,7 +122,7 @@ void main() { discard; } - + diffuse = legacy_adjust(diffuse); diffuse = srgb_to_linear(diffuse); spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl index e1206cc844..8f5bd6141a 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/softenLightF.glsl @@ -83,9 +83,12 @@ float getDepth(vec2 pos_screen); vec3 linear_to_srgb(vec3 c); vec3 srgb_to_linear(vec3 c); +vec3 legacy_adjust(vec3 c); uniform vec4 waterPlane; +uniform int cube_snapshot; + #ifdef WATER_FOG vec4 applyWaterFogViewLinear(vec3 pos, vec4 color); #endif @@ -207,12 +210,18 @@ void main() else if (!GET_GBUFFER_FLAG(GBUFFER_FLAG_HAS_ATMOS)) { //should only be true of WL sky, just port over base color value - color = srgb_to_linear(texture2D(emissiveRect, tc).rgb); - color *= sun_up_factor * sky_hdr_scale + 1.0; + color = texture2D(emissiveRect, tc).rgb; + color = srgb_to_linear(color); + if (sun_up_factor > 0) + { + color *= sky_hdr_scale + 1.0; + } } else { // legacy shaders are still writng sRGB to gbuffer + baseColor.rgb = legacy_adjust(baseColor.rgb); + baseColor.rgb = srgb_to_linear(baseColor.rgb); spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl index 33ea2129cf..3d06bb27a5 100644 --- a/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl +++ b/indra/newview/app_settings/shaders/class3/deferred/spotLightF.glsl @@ -91,6 +91,7 @@ vec3 getProjectedLightSpecularColor(vec3 pos, vec3 n); vec2 getScreenXY(vec4 clip_point); vec2 getScreenCoord(vec4 clip_point); vec3 srgb_to_linear(vec3 c); +vec3 legacy_adjust(vec3 c); vec4 texture2DLodSpecular(vec2 tc, float lod); vec4 getPosition(vec2 pos_screen); @@ -189,6 +190,7 @@ void main() } else { + diffuse = legacy_adjust(diffuse); diffuse = srgb_to_linear(diffuse); spec.rgb = srgb_to_linear(spec.rgb); diff --git a/indra/newview/llenvironment.cpp b/indra/newview/llenvironment.cpp index 6557c2b351..9fe8b00071 100644 --- a/indra/newview/llenvironment.cpp +++ b/indra/newview/llenvironment.cpp @@ -812,7 +812,8 @@ const F64Seconds LLEnvironment::TRANSITION_SLOW(10.0f); const F64Seconds LLEnvironment::TRANSITION_ALTITUDE(5.0f); const LLUUID LLEnvironment::KNOWN_SKY_SUNRISE("01e41537-ff51-2f1f-8ef7-17e4df760bfb"); -const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("7819e136-b6af-2e32-9c85-0b94121bb359"); +const LLUUID LLEnvironment::KNOWN_SKY_MIDDAY("d0401f82-56b9-f3ef-c6aa-13b589f7fdad"); +const LLUUID LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY("6c83e853-e7f8-cad7-8ee6-5f31c453721c"); const LLUUID LLEnvironment::KNOWN_SKY_SUNSET("084e26cd-a900-28e8-08d0-64a9de5c15e2"); const LLUUID LLEnvironment::KNOWN_SKY_MIDNIGHT("8a01b97a-cb20-c1ea-ac63-f7ea84ad0090"); diff --git a/indra/newview/llenvironment.h b/indra/newview/llenvironment.h index 64fd170e43..4383f54f25 100644 --- a/indra/newview/llenvironment.h +++ b/indra/newview/llenvironment.h @@ -61,6 +61,7 @@ public: static const LLUUID KNOWN_SKY_SUNRISE; static const LLUUID KNOWN_SKY_MIDDAY; + static const LLUUID KNOWN_SKY_LEGACY_MIDDAY; static const LLUUID KNOWN_SKY_SUNSET; static const LLUUID KNOWN_SKY_MIDNIGHT; diff --git a/indra/newview/llsculptidsize.cpp b/indra/newview/llsculptidsize.cpp index 9edd78bff0..3d5102902d 100644 --- a/indra/newview/llsculptidsize.cpp +++ b/indra/newview/llsculptidsize.cpp @@ -65,7 +65,7 @@ void LLSculptIDSize::inc(const LLDrawable *pdrawable, int sz) pair_iter_iter_BY_SCULPT_ID_t itLU = mSizeInfo.get().equal_range(sculptId); if (itLU.first == itLU.second) { //register - llassert(mSizeInfo.get().end() == mSizeInfo.get().find(pdrawable)); + //llassert(mSizeInfo.get().end() == mSizeInfo.get().find(pdrawable)); mSizeInfo.get().insert(Info(pdrawable, sz, boost::make_shared(sz), sculptId)); total_size = sz; } diff --git a/indra/newview/lltoolcomp.cpp b/indra/newview/lltoolcomp.cpp index 6d54a3770c..b8357b3454 100644 --- a/indra/newview/lltoolcomp.cpp +++ b/indra/newview/lltoolcomp.cpp @@ -268,7 +268,7 @@ BOOL LLToolCompTranslate::handleHover(S32 x, S32 y, MASK mask) BOOL LLToolCompTranslate::handleMouseDown(S32 x, S32 y, MASK mask) { mMouseDown = TRUE; - gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ TRUE, LLFloaterReg::instanceVisible("build")); + gViewerWindow->pickAsync(x, y, mask, pickCallback, /*BOOL pick_transparent*/ FALSE, LLFloaterReg::instanceVisible("build")); return TRUE; } diff --git a/indra/newview/llviewercontrol.cpp b/indra/newview/llviewercontrol.cpp index 59b566efb6..8973d1c099 100644 --- a/indra/newview/llviewercontrol.cpp +++ b/indra/newview/llviewercontrol.cpp @@ -656,7 +656,6 @@ void settings_setup_listeners() setting_setup_signal_listener(gSavedSettings, "RenderReflectionsEnabled", handleReflectionProbeDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderScreenSpaceReflections", handleReflectionProbeDetailChanged); setting_setup_signal_listener(gSavedSettings, "RenderShadowDetail", handleSetShaderChanged); - setting_setup_signal_listener(gSavedSettings, "RenderTonemapper", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderDeferredSSAO", handleSetShaderChanged); setting_setup_signal_listener(gSavedSettings, "RenderPerformanceTest", handleRenderPerfTestChanged); setting_setup_signal_listener(gSavedSettings, "ChatFontSize", handleChatFontSizeChanged); diff --git a/indra/newview/llviewermedia.cpp b/indra/newview/llviewermedia.cpp index c8e279c991..d0dd02426e 100644 --- a/indra/newview/llviewermedia.cpp +++ b/indra/newview/llviewermedia.cpp @@ -79,6 +79,8 @@ #include // for SkinFolder listener #include +extern BOOL gCubeSnapshot; + // *TODO: Consider enabling mipmaps (they have been disabled for a long time). Likely has a significant performance impact for tiled/high texture repeat media. Mip generation in a shader may also be an option if necessary. constexpr BOOL USE_MIPMAPS = FALSE; @@ -264,6 +266,7 @@ viewer_media_t LLViewerMedia::newMediaImpl( viewer_media_t LLViewerMedia::updateMediaImpl(LLMediaEntry* media_entry, const std::string& previous_url, bool update_from_self) { + llassert(!gCubeSnapshot); // Try to find media with the same media ID viewer_media_t media_impl = getMediaImplFromTextureID(media_entry->getMediaID()); @@ -626,6 +629,8 @@ void LLViewerMedia::updateMedia(void *dummy_arg) { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_UPDATE); + llassert(!gCubeSnapshot); + // Enable/disable the plugin read thread LLPluginProcessParent::setUseReadThread(gSavedSettings.getBOOL("PluginUseReadThread")); @@ -3003,6 +3008,7 @@ void LLViewerMediaImpl::updateImagesMediaStreams() LLViewerMediaTexture* LLViewerMediaImpl::updateMediaImage() { LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; + llassert(!gCubeSnapshot); if (!mMediaSource) { return nullptr; // not ready for updating @@ -3558,6 +3564,8 @@ void LLViewerMediaImpl::calculateInterest() LL_PROFILE_ZONE_SCOPED_CATEGORY_MEDIA; //LL_RECORD_BLOCK_TIME(FTM_MEDIA_CALCULATE_INTEREST); LLViewerMediaTexture* texture = LLViewerTextureManager::findMediaTexture( mTextureId ); + llassert(!gCubeSnapshot); + if(texture != NULL) { mInterest = texture->getMaxVirtualSize(); diff --git a/indra/newview/llviewermenu.cpp b/indra/newview/llviewermenu.cpp index 89538b3bd5..e8b9a22c60 100644 --- a/indra/newview/llviewermenu.cpp +++ b/indra/newview/llviewermenu.cpp @@ -8898,6 +8898,12 @@ class LLWorldEnvSettings : public view_listener_t LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); defocusEnvFloaters(); } + else if (event_name == "legacy noon") + { + LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY, LLEnvironment::TRANSITION_INSTANT); + LLEnvironment::instance().setSelectedEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::TRANSITION_INSTANT); + defocusEnvFloaters(); + } else if (event_name == "sunset") { LLEnvironment::instance().setEnvironment(LLEnvironment::ENV_LOCAL, LLEnvironment::KNOWN_SKY_SUNSET, LLEnvironment::TRANSITION_INSTANT); @@ -8966,6 +8972,10 @@ class LLWorldEnableEnvSettings : public view_listener_t { result = (skyid == LLEnvironment::KNOWN_SKY_MIDDAY); } + else if (event_name == "legacy noon") + { + result = (skyid == LLEnvironment::KNOWN_SKY_LEGACY_MIDDAY); + } else if (event_name == "sunset") { result = (skyid == LLEnvironment::KNOWN_SKY_SUNSET); diff --git a/indra/newview/llviewershadermgr.cpp b/indra/newview/llviewershadermgr.cpp index 4c34c6f6e5..1fd536ceac 100644 --- a/indra/newview/llviewershadermgr.cpp +++ b/indra/newview/llviewershadermgr.cpp @@ -2555,20 +2555,7 @@ BOOL LLViewerShaderMgr::loadShadersDeferred() gDeferredPostGammaCorrectProgram.mFeatures.isDeferred = true; gDeferredPostGammaCorrectProgram.mShaderFiles.clear(); gDeferredPostGammaCorrectProgram.clearPermutations(); - U32 tonemapper = gSavedSettings.getU32("RenderTonemapper"); - if (tonemapper == 1) - { - gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_NARKOWICZ", "1"); - } - else if (tonemapper == 2) - { - gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_ACES_HILL_EXPOSURE_BOOST", "1"); - } - else - { - gDeferredPostGammaCorrectProgram.addPermutation("TONEMAP_LINEAR", "1"); - } - gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); + gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredNoTCV.glsl", GL_VERTEX_SHADER)); gDeferredPostGammaCorrectProgram.mShaderFiles.push_back(make_pair("deferred/postDeferredGammaCorrect.glsl", GL_FRAGMENT_SHADER)); gDeferredPostGammaCorrectProgram.mShaderLevel = mShaderLevel[SHADER_DEFERRED]; success = gDeferredPostGammaCorrectProgram.createShader(NULL, NULL); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index e4ffa5b6b0..4266c16f94 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -7336,13 +7336,13 @@ void LLPipeline::renderFinalize() mLastExposure.bindTexture(0, channel); } + static LLStaticHashedString dt("dt"); + static LLStaticHashedString noiseVec("noiseVec"); + static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); static LLCachedControl dynamic_exposure_coefficient(gSavedSettings, "RenderDynamicExposureCoefficient", 0.175f); static LLCachedControl dynamic_exposure_min(gSavedSettings, "RenderDynamicExposureMin", 0.125f); static LLCachedControl dynamic_exposure_max(gSavedSettings, "RenderDynamicExposureMax", 1.3f); - static LLStaticHashedString dt("dt"); - static LLStaticHashedString noiseVec("noiseVec"); - static LLStaticHashedString dynamic_exposure_params("dynamic_exposure_params"); gExposureProgram.uniform1f(dt, gFrameIntervalSeconds); gExposureProgram.uniform2f(noiseVec, ll_frand() * 2.0 - 1.0, ll_frand() * 2.0 - 1.0); gExposureProgram.uniform3f(dynamic_exposure_params, dynamic_exposure_coefficient, dynamic_exposure_min, dynamic_exposure_max); @@ -7370,7 +7370,7 @@ void LLPipeline::renderFinalize() gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::DEFERRED_DIFFUSE, screenTarget(), false, LLTexUnit::TFO_POINT); - gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); + gDeferredPostGammaCorrectProgram.bindTexture(LLShaderMgr::EXPOSURE_MAP, &mExposureMap); gDeferredPostGammaCorrectProgram.uniform2f(LLShaderMgr::DEFERRED_SCREEN_RES, screenTarget()->getWidth(), screenTarget()->getHeight()); @@ -9466,6 +9466,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) set_current_projection(saved_proj); LLVector3 eye = camera.getOrigin(); + llassert(eye.isFinite()); //camera used for shadow cull/render LLCamera shadow_cam; @@ -9745,6 +9746,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) { //get perspective projection view[j] = view[j].inverse(); + //llassert(origin.isFinite()); glh::vec3f origin_agent(origin.mV); @@ -9752,7 +9754,7 @@ void LLPipeline::generateSunShadow(LLCamera& camera) view[j].mult_matrix_vec(origin_agent); eye = LLVector3(origin_agent.v); - + //llassert(eye.isFinite()); if (!hasRenderDebugMask(LLPipeline::RENDER_DEBUG_SHADOW_FRUSTA) && !gCubeSnapshot) { mShadowFrustOrigin[j] = eye; diff --git a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml index 17875e9c19..16b965843d 100644 --- a/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml +++ b/indra/newview/skins/default/xui/en/floater_preferences_graphics_advanced.xml @@ -712,42 +712,6 @@ value="2"/> - - - Tonemapper: - - - - - - - - - - - + + + + + + + + Date: Fri, 21 Apr 2023 13:26:24 -0700 Subject: SL-19606: Fix missing GLTF texture transforms in PBR alpha mask/alpha blend shadows --- indra/llprimitive/llgltfmaterial.cpp | 2 +- indra/llprimitive/llgltfmaterial.h | 2 +- .../shaders/class1/deferred/shadowAlphaMaskF.glsl | 8 +++--- .../shaders/class1/deferred/shadowAlphaMaskV.glsl | 25 +++++++++--------- indra/newview/lldrawpool.cpp | 30 +++++++++++++++------- indra/newview/lldrawpool.h | 12 +++++---- indra/newview/lldrawpoolbump.cpp | 4 ++- indra/newview/lldrawpoolbump.h | 2 +- indra/newview/llfetchedgltfmaterial.cpp | 8 +++--- indra/newview/pipeline.cpp | 12 ++++----- 10 files changed, 61 insertions(+), 44 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index f3aa5b0648..c16803d39d 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -43,7 +43,7 @@ const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; // special UUID that indicates a null UUID in override data static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); -void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) +void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const { packed[0] = mScale.mV[VX]; packed[1] = mScale.mV[VY]; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index bdabd657e1..0bd65fadef 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -61,7 +61,7 @@ public: LLVector2 mScale = { 1.f, 1.f }; F32 mRotation = 0.f; - void getPacked(F32 (&packed)[8]); + void getPacked(F32 (&packed)[8]) const; bool operator==(const TextureTransform& other) const; }; diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl index 68e9addc1b..eb2ba68415 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskF.glsl @@ -33,10 +33,10 @@ out vec4 frag_color; uniform sampler2D diffuseMap; -VARYING vec4 post_pos; -VARYING float target_pos_x; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +in vec4 post_pos; +in float target_pos_x; +in vec4 vertex_color; +in vec2 vary_texcoord0; uniform float minimum_alpha; void main() diff --git a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl index 2249a7f239..72a07fa3d0 100644 --- a/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl +++ b/indra/newview/app_settings/shaders/class1/deferred/shadowAlphaMaskV.glsl @@ -27,26 +27,27 @@ uniform mat4 texture_matrix0; #if defined(HAS_SKIN) uniform mat4 modelview_matrix; uniform mat4 projection_matrix; +mat4 getObjectSkinnedTransform(); #else uniform mat4 modelview_projection_matrix; #endif + +uniform vec4[2] texture_base_color_transform; +vec2 texture_transform(vec2 vertex_texcoord, vec4[2] khr_gltf_transform, mat4 sl_animation_transform); + uniform float shadow_target_width; -ATTRIBUTE vec3 position; -ATTRIBUTE vec4 diffuse_color; -ATTRIBUTE vec2 texcoord0; +in vec3 position; +in vec4 diffuse_color; +in vec2 texcoord0; -VARYING vec4 post_pos; -VARYING float target_pos_x; -VARYING vec4 vertex_color; -VARYING vec2 vary_texcoord0; +out vec4 post_pos; +out float target_pos_x; +out vec4 vertex_color; +out vec2 vary_texcoord0; void passTextureIndex(); -#if defined(HAS_SKIN) -mat4 getObjectSkinnedTransform(); -#endif - void main() { //transform vertex @@ -69,6 +70,6 @@ void main() passTextureIndex(); - vary_texcoord0 = (texture_matrix0 * vec4(texcoord0,0,1)).xy; + vary_texcoord0 = texture_transform(texcoord0, texture_base_color_transform, texture_matrix0); vertex_color = diffuse_color; } diff --git a/indra/newview/lldrawpool.cpp b/indra/newview/lldrawpool.cpp index 2eb277fc4e..3de0e8a7c4 100644 --- a/indra/newview/lldrawpool.cpp +++ b/indra/newview/lldrawpool.cpp @@ -504,7 +504,7 @@ void LLRenderPass::pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvat pushGLTFBatch(params); } -void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures) +void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); @@ -514,11 +514,12 @@ void LLRenderPass::pushBatches(U32 type, bool texture, bool batch_textures) LLDrawInfo* pparams = *i; LLCullResult::increment_iterator(i, end); - pushBatch(*pparams, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures, reset_gltf); + reset_gltf = false; } } -void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures) +void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOAvatar* lastAvatar = nullptr; @@ -537,11 +538,12 @@ void LLRenderPass::pushRiggedBatches(U32 type, bool texture, bool batch_textures lastMeshId = pparams->mSkinInfo->mHash; } - pushBatch(*pparams, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures, reset_gltf); + reset_gltf = false; } } -void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures) +void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; auto* begin = gPipeline.beginRenderMap(type); @@ -551,11 +553,12 @@ void LLRenderPass::pushMaskBatches(U32 type, bool texture, bool batch_textures) LLDrawInfo* pparams = *i; LLCullResult::increment_iterator(i, end); LLGLSLShader::sCurBoundShaderPtr->setMinimumAlpha(pparams->mAlphaMaskCutoff); - pushBatch(*pparams, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures, reset_gltf); + reset_gltf = false; } } -void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures) +void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; LLVOAvatar* lastAvatar = nullptr; @@ -584,7 +587,8 @@ void LLRenderPass::pushRiggedMaskBatches(U32 type, bool texture, bool batch_text lastMeshId = pparams->mSkinInfo->mHash; } - pushBatch(*pparams, texture, batch_textures); + pushBatch(*pparams, texture, batch_textures, reset_gltf); + reset_gltf = false; } } @@ -603,7 +607,14 @@ void LLRenderPass::applyModelMatrix(const LLDrawInfo& params) } } -void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures) +void LLRenderPass::resetGLTFTextureTransform() +{ + F32 ignore_gltf_transform[8]; + LLGLTFMaterial::sDefault.mTextureTransform[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(ignore_gltf_transform); + LLGLSLShader::sCurBoundShaderPtr->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)ignore_gltf_transform); +} + +void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; if (!params.mCount) @@ -612,6 +623,7 @@ void LLRenderPass::pushBatch(LLDrawInfo& params, bool texture, bool batch_textur } applyModelMatrix(params); + if (reset_gltf) { resetGLTFTextureTransform(); } bool tex_setup = false; diff --git a/indra/newview/lldrawpool.h b/indra/newview/lldrawpool.h index 09c95a1705..8704f2e340 100644 --- a/indra/newview/lldrawpool.h +++ b/indra/newview/lldrawpool.h @@ -349,15 +349,17 @@ public: void resetDrawOrders() { } static void applyModelMatrix(const LLDrawInfo& params); - virtual void pushBatches(U32 type, bool texture = true, bool batch_textures = false); - virtual void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false); + static void resetGLTFTextureTransform(); + virtual void pushBatches(U32 type, bool texture = true, bool batch_textures = false, bool reset_gltf = false); + virtual void pushRiggedBatches(U32 type, bool texture = true, bool batch_textures = false, bool reset_gltf = false); void pushGLTFBatches(U32 type); void pushGLTFBatch(LLDrawInfo& params); void pushRiggedGLTFBatches(U32 type); void pushRiggedGLTFBatch(LLDrawInfo& params, LLVOAvatar*& lastAvatar, U64& lastMeshId); - virtual void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false); - virtual void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false); - virtual void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false); + virtual void pushMaskBatches(U32 type, bool texture = true, bool batch_textures = false, bool reset_gltf = false); + virtual void pushRiggedMaskBatches(U32 type, bool texture = true, bool batch_textures = false, bool reset_gltf = false); + // reset_gltf: batch is interleaved with GLTF batches that share the same shader + virtual void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false, bool reset_gltf = false); static bool uploadMatrixPalette(LLDrawInfo& params); static bool uploadMatrixPalette(LLVOAvatar* avatar, LLMeshSkinInfo* skinInfo); virtual void renderGroup(LLSpatialGroup* group, U32 type, bool texture = true); diff --git a/indra/newview/lldrawpoolbump.cpp b/indra/newview/lldrawpoolbump.cpp index 45c74776e1..35265b6df0 100644 --- a/indra/newview/lldrawpoolbump.cpp +++ b/indra/newview/lldrawpoolbump.cpp @@ -1218,13 +1218,15 @@ void LLDrawPoolBump::pushBumpBatches(U32 type) } } -void LLDrawPoolBump::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures) +void LLDrawPoolBump::pushBatch(LLDrawInfo& params, bool texture, bool batch_textures, bool reset_gltf) { LL_PROFILE_ZONE_SCOPED_CATEGORY_DRAWPOOL; applyModelMatrix(params); bool tex_setup = false; + if (reset_gltf) { LLRenderPass::resetGLTFTextureTransform(); } + if (batch_textures && params.mTextureList.size() > 1) { for (U32 i = 0; i < params.mTextureList.size(); ++i) diff --git a/indra/newview/lldrawpoolbump.h b/indra/newview/lldrawpoolbump.h index 840af0c99d..41c4879ded 100644 --- a/indra/newview/lldrawpoolbump.h +++ b/indra/newview/lldrawpoolbump.h @@ -53,7 +53,7 @@ public: LLDrawPoolBump(); /*virtual*/ void prerender() override; - void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false) override; + void pushBatch(LLDrawInfo& params, bool texture, bool batch_textures = false, bool reset_gltf = false) override; void pushBumpBatches(U32 type); void renderGroup(LLSpatialGroup* group, U32 type, bool texture) override; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 1f7d672062..1fb3577dd7 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -90,6 +90,10 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) gGL.getTexUnit(0)->bindFast(LLViewerFetchedTexture::sWhiteImagep); } + F32 base_color_packed[8]; + mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed); + shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed); + if (!LLPipeline::sShadowRender) { if (mNormalTexture.notNull() && mNormalTexture->getDiscardLevel() <= 4) @@ -125,10 +129,6 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) shader->uniform1f(LLShaderMgr::METALLIC_FACTOR, mMetallicFactor); shader->uniform3fv(LLShaderMgr::EMISSIVE_COLOR, 1, mEmissiveColor.mV); - F32 base_color_packed[8]; - mTextureTransform[GLTF_TEXTURE_INFO_BASE_COLOR].getPacked(base_color_packed); - shader->uniform4fv(LLShaderMgr::TEXTURE_BASE_COLOR_TRANSFORM, 2, (F32*)base_color_packed); - F32 normal_packed[8]; mTextureTransform[GLTF_TEXTURE_INFO_NORMAL].getPacked(normal_packed); shader->uniform4fv(LLShaderMgr::TEXTURE_NORMAL_TRANSFORM, 2, (F32*)normal_packed); diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp index 60d19bf1d6..ee011bf37c 100644 --- a/indra/newview/pipeline.cpp +++ b/indra/newview/pipeline.cpp @@ -6794,7 +6794,7 @@ void LLPipeline::renderAlphaObjects(bool rigged) lastMeshId = pparams->mSkinInfo->mHash; } - mSimplePool->pushBatch(*pparams, true, true); + mSimplePool->pushBatch(*pparams, true, true, true); } } else @@ -6805,7 +6805,7 @@ void LLPipeline::renderAlphaObjects(bool rigged) } else { - mSimplePool->pushBatch(*pparams, true, true); + mSimplePool->pushBatch(*pparams, true, true, true); } } } @@ -6822,11 +6822,11 @@ void LLPipeline::renderMaskedObjects(U32 type, bool texture, bool batch_texture, gGLLastMatrix = NULL; if (rigged) { - mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); + mAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture, true); } else { - mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); + mAlphaMaskPool->pushMaskBatches(type, texture, batch_texture, true); } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; @@ -6840,11 +6840,11 @@ void LLPipeline::renderFullbrightMaskedObjects(U32 type, bool texture, bool batc gGLLastMatrix = NULL; if (rigged) { - mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture); + mFullbrightAlphaMaskPool->pushRiggedMaskBatches(type+1, texture, batch_texture, true); } else { - mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture); + mFullbrightAlphaMaskPool->pushMaskBatches(type, texture, batch_texture, true); } gGL.loadMatrix(gGLModelView); gGLLastMatrix = NULL; -- cgit v1.3 From 6a812fa1ba9170ba34706d303913cc5aa5f187ac Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 3 May 2023 13:23:05 -0700 Subject: Improved fix for SL-19675 crash. How about just don't refer to data when you don't need it --- indra/llprimitive/llgltfmaterial.h | 1 + indra/newview/llgltfmateriallist.cpp | 18 +++++++++--------- 2 files changed, 10 insertions(+), 9 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 0bd65fadef..ad7784f6d1 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -167,6 +167,7 @@ public: // set the contents of this LLGLTFMaterial from the given json // returns true if successful + // if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned // json - the json text to load from // warn_msg - warning message from TinyGLTF if any // error_msg - error_msg from TinyGLTF if any diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 7d677626ce..1e49ea2eba 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -227,16 +227,16 @@ public: // fromJson() is performance heavy offload to a thread. main_queue->postTo( general_queue, - [object_override]() // Work done on general queue + [sides=object_override.mSides]() // Work done on general queue { std::vector results; - if (!object_override.mSides.empty()) + if (!sides.empty()) { - results.reserve(object_override.mSides.size()); + results.reserve(sides.size()); // parse json - std::unordered_map::const_iterator iter = object_override.mSides.begin(); - std::unordered_map::const_iterator end = object_override.mSides.end(); + std::unordered_map::const_iterator iter = sides.begin(); + std::unordered_map::const_iterator end = sides.end(); while (iter != end) { std::string warn_msg, error_msg; @@ -259,9 +259,9 @@ public: } return results; }, - [object_override, this](std::vector results) // Callback to main thread + [object_id=object_override.mObjectId, this](std::vector results) // Callback to main thread { - LLViewerObject * obj = gObjectList.findObject(object_override.mObjectId); + LLViewerObject * obj = gObjectList.findObject(object_id); if (results.size() > 0 ) { @@ -287,7 +287,7 @@ public: // unblock material editor if (obj && obj->getTE(side) && obj->getTE(side)->isSelected()) { - doSelectionCallbacks(object_override.mObjectId, side); + doSelectionCallbacks(object_id, side); } } @@ -300,7 +300,7 @@ public: obj->setTEGLTFMaterialOverride(i, nullptr); if (obj->getTE(i) && obj->getTE(i)->isSelected()) { - doSelectionCallbacks(object_override.mObjectId, i); + doSelectionCallbacks(object_id, i); } } } -- cgit v1.3 From e7e565dc6e7e0c666132ffffa4798b2cfc00d6a4 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 21 Jul 2023 13:01:11 -0700 Subject: SL-20024: Put material in object inventory when material is no-modify or no-transfer --- indra/llprimitive/llmaterial.cpp | 11 ----------- indra/llprimitive/llmaterial.h | 2 -- indra/newview/llpanelface.cpp | 7 +------ indra/newview/llpanelface.h | 1 - indra/newview/llselectmgr.cpp | 36 ++++++++++++++++++++++++++---------- indra/newview/llselectmgr.h | 14 ++++++++++++-- indra/newview/lltooldraganddrop.cpp | 20 ++++++++++++++++++++ 7 files changed, 59 insertions(+), 32 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmaterial.cpp b/indra/llprimitive/llmaterial.cpp index f6cb3c8b70..0d146de949 100644 --- a/indra/llprimitive/llmaterial.cpp +++ b/indra/llprimitive/llmaterial.cpp @@ -332,17 +332,6 @@ void LLMaterial::setAlphaMaskCutoff(U8 cutoff) mAlphaMaskCutoff = cutoff; } -LLUUID LLMaterial::getMaterialID() const -{ - // TODO - not null - return LLUUID::null; -} - -void LLMaterial::setMaterialID(const LLUUID &material_id) -{ - // TODO - set -} - LLSD LLMaterial::asLLSD() const { LLSD material_data; diff --git a/indra/llprimitive/llmaterial.h b/indra/llprimitive/llmaterial.h index b46d85c2d1..81f41ddc51 100644 --- a/indra/llprimitive/llmaterial.h +++ b/indra/llprimitive/llmaterial.h @@ -115,8 +115,6 @@ public: void setDiffuseAlphaMode(U8 alpha_mode); U8 getAlphaMaskCutoff() const; void setAlphaMaskCutoff(U8 cutoff); - LLUUID getMaterialID() const; - void setMaterialID(LLUUID const & material_id); bool isNull() const; static const LLMaterial null; diff --git a/indra/newview/llpanelface.cpp b/indra/newview/llpanelface.cpp index 837217387f..b633ccc5d5 100644 --- a/indra/newview/llpanelface.cpp +++ b/indra/newview/llpanelface.cpp @@ -3093,12 +3093,7 @@ void LLPanelFace::onSelectPbr(const LLSD& data) { id = pbr_ctrl->getImageAssetID(); } - if (LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) - { - LLSelectedTEMaterial::setMaterialID(this, id); - } - else - { + if (!LLSelectMgr::getInstance()->selectionSetGLTFMaterial(id)) refresh(); } } diff --git a/indra/newview/llpanelface.h b/indra/newview/llpanelface.h index f6a813f9e5..e2d9f65e58 100644 --- a/indra/newview/llpanelface.h +++ b/indra/newview/llpanelface.h @@ -583,7 +583,6 @@ public: DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setNormalID); DEF_EDIT_MAT_STATE(LLUUID,const LLUUID&,setSpecularID); DEF_EDIT_MAT_STATE(LLColor4U, const LLColor4U&,setSpecularLightColor); - DEF_EDIT_MAT_STATE(LLUUID, const LLUUID&, setMaterialID); }; class LLSelectedTE diff --git a/indra/newview/llselectmgr.cpp b/indra/newview/llselectmgr.cpp index 5c1a339570..6692d124d8 100644 --- a/indra/newview/llselectmgr.cpp +++ b/indra/newview/llselectmgr.cpp @@ -1773,15 +1773,17 @@ void LLObjectSelection::applyNoCopyTextureToTEs(LLViewerInventoryItem* item) } } -void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) +bool LLObjectSelection::applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item) { if (!item) { - return; + return false; } LLUUID asset_id = item->getAssetUUID(); + bool material_copied_all_faces = true; + for (iterator iter = begin(); iter != end(); ++iter) { LLSelectNode* node = *iter; @@ -1797,12 +1799,17 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) { if (node->isTESelected(te)) { - //(no-copy) materials must be moved to the object's inventory only once + //(no-copy), (no-modify), and (no-transfer) materials must be moved to the object's inventory only once // without making any copies if (!material_copied && asset_id.notNull()) { - LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); - material_copied = true; + material_copied = (bool)LLToolDragAndDrop::handleDropMaterialProtections(object, item, LLToolDragAndDrop::SOURCE_AGENT, LLUUID::null); + } + if (!material_copied) + { + // Applying the material is not possible for this object given the current inventory + material_copied_all_faces = false; + break; } // apply texture for the selected faces @@ -1814,6 +1821,8 @@ void LLObjectSelection::applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item) } LLGLTFMaterialList::flushUpdates(); + + return material_copied_all_faces; } @@ -1924,6 +1933,8 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) { LLViewerInventoryItem* mItem; LLUUID mMatId; + bool material_copied_any_face = false; + bool material_copied_all_faces = true; f(LLViewerInventoryItem* item, const LLUUID& id) : mItem(item), mMatId(id) {} bool apply(LLViewerObject* objectp, S32 te) { @@ -1950,14 +1961,19 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) } }; - if (item && !item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID())) + bool success = true; + if (item && + (!item->getPermissions().allowOperationBy(PERM_COPY, gAgent.getID()) || + !item->getPermissions().allowOperationBy(PERM_TRANSFER, gAgent.getID()) || + !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID()) + )) { - getSelection()->applyNoCopyPbrMaterialToTEs(item); + success = success && getSelection()->applyRestrictedPbrMaterialToTEs(item); } else { f setfunc(item, mat_id); - getSelection()->applyToTEs(&setfunc); + success = success && getSelection()->applyToTEs(&setfunc); } struct g : public LLSelectedObjectFunctor @@ -1986,11 +2002,11 @@ bool LLSelectMgr::selectionSetGLTFMaterial(const LLUUID& mat_id) return true; } } sendfunc(item); - getSelection()->applyToObjects(&sendfunc); + success = success && getSelection()->applyToObjects(&sendfunc); LLGLTFMaterialList::flushUpdates(); - return true; + return success; } //----------------------------------------------------------------------------- diff --git a/indra/newview/llselectmgr.h b/indra/newview/llselectmgr.h index 327134a487..f89209b437 100644 --- a/indra/newview/llselectmgr.h +++ b/indra/newview/llselectmgr.h @@ -378,7 +378,17 @@ public: * Then this only texture is used for all selected faces. */ void applyNoCopyTextureToTEs(LLViewerInventoryItem* item); - void applyNoCopyPbrMaterialToTEs(LLViewerInventoryItem* item); + /* + * Multi-purpose function for applying PBR materials to the + * selected object or faces, any combination of copy/mod/transfer + * permission restrictions. This method moves the restricted + * material to the object's inventory and doesn't make a copy of the + * material for each face. Then this only material is used for + * all selected faces. + * Returns false if applying the material failed on one or more selected + * faces. + */ + bool applyRestrictedPbrMaterialToTEs(LLViewerInventoryItem* item); ESelectType getSelectType() const { return mSelectType; } @@ -635,7 +645,7 @@ public: void selectionSetRestitution(F32 restitution); void selectionSetMaterial(U8 material); bool selectionSetImage(const LLUUID& imageid); // could be item or asset id - bool selectionSetGLTFMaterial(const LLUUID& mat_id); // could be item or asset id + bool selectionSetGLTFMaterial(const LLUUID& mat_id); // material id only void selectionSetColor(const LLColor4 &color); void selectionSetColorOnly(const LLColor4 &color); // Set only the RGB channels void selectionSetAlphaOnly(const F32 alpha); // Set only the alpha channel diff --git a/indra/newview/lltooldraganddrop.cpp b/indra/newview/lltooldraganddrop.cpp index dd5f607b04..23a6634154 100644 --- a/indra/newview/lltooldraganddrop.cpp +++ b/indra/newview/lltooldraganddrop.cpp @@ -1042,6 +1042,26 @@ BOOL LLToolDragAndDrop::handleDropMaterialProtections(LLViewerObject* hit_obj, // we should return false here. This will requre a separate listener // since without listener, we have no way to receive update } + else if (LLAssetType::AT_MATERIAL == new_item->getType() && + !item->getPermissions().allowOperationBy(PERM_MODIFY, gAgent.getID())) + { + // Check that we can add the material as inventory to the object + if (willObjectAcceptInventory(hit_obj,item) < ACCEPT_YES_COPY_SINGLE ) + { + return FALSE; + } + // *FIX: may want to make sure agent can paint hit_obj. + + // Add the material item to the target object's inventory. + hit_obj->updateMaterialInventory(new_item, TASK_INVENTORY_ITEM_KEY, true); + + // Force the object to update and refetch its inventory so it has this material. + hit_obj->dirtyInventory(); + hit_obj->requestInventory(); + // TODO: Check to see if adding the item was successful; if not, then + // we should return false here. This will requre a separate listener + // since without listener, we have no way to receive update + } return TRUE; } -- cgit v1.3 From 455bbcf742691b709353aa3c3e35a76d0ff38ee4 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 29 Aug 2023 16:42:55 -0500 Subject: SL-20229 Add GenericStreamingMessage and use it to receive GLTF material overrides --- indra/llmessage/CMakeLists.txt | 2 + indra/llmessage/llgenericstreamingmessage.cpp | 72 +++++++++++ indra/llmessage/llgenericstreamingmessage.h | 50 ++++++++ indra/llmessage/message_prehash.cpp | 1 + indra/llmessage/message_prehash.h | 1 + indra/llprimitive/llgltfmaterial.cpp | 172 ++++++++++++++++++++++++++ indra/llprimitive/llgltfmaterial.h | 9 ++ indra/newview/llappviewer.cpp | 2 +- indra/newview/llgltfmateriallist.cpp | 75 +++++++++-- indra/newview/llgltfmateriallist.h | 3 + indra/newview/llstartup.cpp | 1 + indra/newview/llviewergenericmessage.cpp | 18 ++- indra/newview/llviewergenericmessage.h | 1 + indra/newview/llviewerregion.cpp | 16 +-- indra/newview/llvocache.cpp | 34 ++--- indra/newview/llvocache.h | 2 +- scripts/messages/message_template.msg | 19 +++ scripts/messages/message_template.msg.sha1 | 2 +- 18 files changed, 430 insertions(+), 50 deletions(-) create mode 100644 indra/llmessage/llgenericstreamingmessage.cpp create mode 100644 indra/llmessage/llgenericstreamingmessage.h (limited to 'indra/llprimitive') diff --git a/indra/llmessage/CMakeLists.txt b/indra/llmessage/CMakeLists.txt index 4786956e85..e44309476b 100644 --- a/indra/llmessage/CMakeLists.txt +++ b/indra/llmessage/CMakeLists.txt @@ -30,6 +30,7 @@ set(llmessage_SOURCE_FILES lldispatcher.cpp llexperiencecache.cpp llfiltersd2xmlrpc.cpp + llgenericstreamingmessage.cpp llhost.cpp llhttpnode.cpp llhttpsdhandler.cpp @@ -114,6 +115,7 @@ set(llmessage_HEADER_FILES llextendedstatus.h llfiltersd2xmlrpc.h llfollowcamparams.h + llgenericstreamingmessage.h llhost.h llhttpnode.h llhttpnodeadapter.h diff --git a/indra/llmessage/llgenericstreamingmessage.cpp b/indra/llmessage/llgenericstreamingmessage.cpp new file mode 100644 index 0000000000..8627675c54 --- /dev/null +++ b/indra/llmessage/llgenericstreamingmessage.cpp @@ -0,0 +1,72 @@ +/** + * @file llgenericstreamingmessage.cpp + * @brief Generic Streaming Message helpers. Shared between viewer and simulator. + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#include "linden_common.h" + +#include "llgenericstreamingmessage.h" + +#include "message.h" + +void LLGenericStreamingMessage::send(LLMessageSystem* msg) +{ +#if 0 // viewer cannot send GenericStreamingMessage + msg->newMessageFast(_PREHASH_GenericStreamingMessage); + + if (mData.size() < 1024 * 7) + { // disable warning about big messages unless we're sending a REALLY big message + msg->tempDisableWarnAboutBigMessage(); + } + else + { + LL_WARNS("Messaging") << "Attempted to send too large GenericStreamingMessage, dropping." << LL_ENDL; + return; + } + + msg->nextBlockFast(_PREHASH_MethodData); + msg->addU16Fast(_PREHASH_Method, mMethod); + msg->nextBlockFast(_PREHASH_DataBlock); + msg->addStringFast(_PREHASH_Data, mData.c_str()); +#endif +} + +void LLGenericStreamingMessage::unpack(LLMessageSystem* msg) +{ + U16* m = (U16*)&mMethod; // squirrely pass enum as U16 by reference + msg->getU16Fast(_PREHASH_MethodData, _PREHASH_Method, *m); + + constexpr int MAX_SIZE = 7 * 1024; + + char buffer[MAX_SIZE]; + + // NOTE: don't use getStringFast to avoid 1200 byte truncation + U32 size = msg->getSizeFast(_PREHASH_DataBlock, _PREHASH_Data); + msg->getBinaryDataFast(_PREHASH_DataBlock, _PREHASH_Data, buffer, size, 0, MAX_SIZE); + + mData.assign(buffer, size); +} + + + diff --git a/indra/llmessage/llgenericstreamingmessage.h b/indra/llmessage/llgenericstreamingmessage.h new file mode 100644 index 0000000000..9ac9719ea1 --- /dev/null +++ b/indra/llmessage/llgenericstreamingmessage.h @@ -0,0 +1,50 @@ +/** + * @file llgenericstreamingmessage.h + * @brief Generic Streaming Message helpers. Shared between viewer and simulator. + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include +#include "stdtypes.h" + +class LLMessageSystem; + +class LLGenericStreamingMessage +{ +public: + enum Method : U16 + { + METHOD_GLTF_MATERIAL_OVERRIDE = 0x4175, + METHOD_UNKNOWN = 0xFFFF, + }; + + void send(LLMessageSystem* msg); + void unpack(LLMessageSystem* msg); + + Method mMethod = METHOD_UNKNOWN; + std::string mData; +}; + + diff --git a/indra/llmessage/message_prehash.cpp b/indra/llmessage/message_prehash.cpp index 57ea954054..4dccacb889 100644 --- a/indra/llmessage/message_prehash.cpp +++ b/indra/llmessage/message_prehash.cpp @@ -1367,6 +1367,7 @@ char const* const _PREHASH_MuteType = LLMessageStringTable::getInstance()->getSt char const* const _PREHASH_IMViaEMail = LLMessageStringTable::getInstance()->getString("IMViaEMail"); char const* const _PREHASH_RentPrice = LLMessageStringTable::getInstance()->getString("RentPrice"); char const* const _PREHASH_GenericMessage = LLMessageStringTable::getInstance()->getString("GenericMessage"); +char const* const _PREHASH_GenericStreamingMessage = LLMessageStringTable::getInstance()->getString("GenericStreamingMessage"); char const* const _PREHASH_ChildAgentAlive = LLMessageStringTable::getInstance()->getString("ChildAgentAlive"); char const* const _PREHASH_AssetType = LLMessageStringTable::getInstance()->getString("AssetType"); char const* const _PREHASH_SpawnPointBlock = LLMessageStringTable::getInstance()->getString("SpawnPointBlock"); diff --git a/indra/llmessage/message_prehash.h b/indra/llmessage/message_prehash.h index 572dadd408..a393bbabb2 100644 --- a/indra/llmessage/message_prehash.h +++ b/indra/llmessage/message_prehash.h @@ -1368,6 +1368,7 @@ extern char const* const _PREHASH_MuteType; extern char const* const _PREHASH_IMViaEMail; extern char const* const _PREHASH_RentPrice; extern char const* const _PREHASH_GenericMessage; +extern char const* const _PREHASH_GenericStreamingMessage; extern char const* const _PREHASH_ChildAgentAlive; extern char const* const _PREHASH_AssetType; extern char const* const _PREHASH_SpawnPointBlock; diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index c16803d39d..8475e7231a 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -27,6 +27,7 @@ #include "linden_common.h" #include "llgltfmaterial.h" +#include "llsdserialize.h" // NOTE -- this should be the one and only place tiny_gltf.h is included #include "tinygltf/tiny_gltf.h" @@ -693,6 +694,177 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) } } +void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) +{ + LL_PROFILE_ZONE_SCOPED; + llassert(data.isUndefined()); + + // make every effort to shave bytes here + + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + LLUUID& texture_id = mTextureId[i]; + const LLUUID& override_texture_id = override_mat.mTextureId[i]; + if (override_texture_id.notNull() && override_texture_id != texture_id) + { + data["tex"][i] = LLSD::UUID(override_texture_id); + } + + } + + if (override_mat.mBaseColor != getDefaultBaseColor()) + { + data["bc"] = override_mat.mBaseColor.getValue(); + } + + if (override_mat.mEmissiveColor != getDefaultEmissiveColor()) + { + data["ec"] = override_mat.mEmissiveColor.getValue(); + } + + if (override_mat.mMetallicFactor != getDefaultMetallicFactor()) + { + data["mf"] = override_mat.mMetallicFactor; + } + + if (override_mat.mRoughnessFactor != getDefaultRoughnessFactor()) + { + data["rf"] = override_mat.mRoughnessFactor; + } + + if (override_mat.mAlphaMode != getDefaultAlphaMode() || override_mat.mOverrideAlphaMode) + { + data["am"] = override_mat.mAlphaMode; + } + + if (override_mat.mAlphaCutoff != getDefaultAlphaCutoff()) + { + data["ac"] = override_mat.mAlphaCutoff; + } + + if (override_mat.mDoubleSided != getDefaultDoubleSided() || override_mat.mOverrideDoubleSided) + { + data["ds"] = override_mat.mDoubleSided; + } + + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (override_mat.mTextureTransform[i].mOffset != getDefaultTextureOffset()) + { + data["ti"][i]["o"] = override_mat.mTextureTransform[i].mOffset.getValue(); + } + + if (override_mat.mTextureTransform[i].mScale != getDefaultTextureScale()) + { + data["ti"][i]["s"] = override_mat.mTextureTransform[i].mScale.getValue(); + } + + if (override_mat.mTextureTransform[i].mRotation != getDefaultTextureRotation()) + { + data["ti"][i]["r"] = override_mat.mTextureTransform[i].mRotation; + } + } + +#if 0 + { + std::ostringstream ostr; + LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_NOTATION); + std::string param_str(ostr.str()); + LL_INFOS() << param_str << LL_ENDL; + LL_INFOS() << "Notation size: " << param_str.size() << LL_ENDL; + } + + { + std::ostringstream ostr; + LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_BINARY); + std::string param_str(ostr.str()); + LL_INFOS() << "Binary size: " << param_str.size() << LL_ENDL; + } +#endif +} + + +void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) +{ + const LLSD& tex = data["tex"]; + + if (tex.isArray()) + { + for (int i = 0; i < tex.size(); ++i) + { + mTextureId[i] = tex[i].asUUID(); + } + } + + const LLSD& bc = data["bc"]; + if (bc.isDefined()) + { + mBaseColor.setValue(bc); + } + + const LLSD& ec = data["ec"]; + if (ec.isDefined()) + { + mEmissiveColor.setValue(ec); + } + + const LLSD& mf = data["mf"]; + if (mf.isReal()) + { + mMetallicFactor = mf.asReal(); + } + + const LLSD& rf = data["rf"]; + if (rf.isReal()) + { + mRoughnessFactor = rf.asReal(); + } + + const LLSD& am = data["am"]; + if (am.isInteger()) + { + mAlphaMode = (AlphaMode) am.asInteger(); + } + + const LLSD& ac = data["ac"]; + if (ac.isReal()) + { + mAlphaCutoff = ac.asReal(); + } + + const LLSD& ds = data["ds"]; + if (data.isBoolean()) + { + mDoubleSided = ds.asBoolean(); + mOverrideDoubleSided = true; + } + + const LLSD& ti = data["ti"]; + if (ti.isArray()) + { + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + const LLSD& o = ti[i]["o"]; + if (o.isDefined()) + { + mTextureTransform[i].mOffset.setValue(o); + } + + const LLSD& s = ti[i]["s"]; + if (s.isDefined()) + { + mTextureTransform[i].mScale.setValue(s); + } + + const LLSD& r = ti[i]["r"]; + if (r.isReal()) + { + mTextureTransform[i].mRotation = r.asReal(); + } + } + } +} + LLUUID LLGLTFMaterial::getHash() const { LL_PROFILE_ZONE_SCOPED_CATEGORY_TEXTURE; diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index ad7784f6d1..ca27507707 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -176,6 +176,7 @@ public: // get the contents of this LLGLTFMaterial as a json string std::string asJSON(bool prettyprint = false) const; + // initialize from given tinygltf::Model // model - the model to reference // mat_index - index of material in model's material array @@ -185,6 +186,14 @@ public: void writeToModel(tinygltf::Model& model, S32 mat_index) const; void applyOverride(const LLGLTFMaterial& override_mat); + + // apply the given LLSD override data + void applyOverrideLLSD(const LLSD& data); + + // Get the given override on this LLGLTFMaterial as LLSD + // override_mat -- the override source data + // data -- output LLSD object (should be passed in empty) + void getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data); // For base materials only (i.e. assets). Clears transforms to // default since they're not supported in assets yet. diff --git a/indra/newview/llappviewer.cpp b/indra/newview/llappviewer.cpp index 343778fe03..a6e938e54c 100644 --- a/indra/newview/llappviewer.cpp +++ b/indra/newview/llappviewer.cpp @@ -4138,7 +4138,7 @@ U32 LLAppViewer::getObjectCacheVersion() { // Viewer object cache version, change if object update // format changes. JC - const U32 INDRA_OBJECT_CACHE_VERSION = 16; + const U32 INDRA_OBJECT_CACHE_VERSION = 17; return INDRA_OBJECT_CACHE_VERSION; } diff --git a/indra/newview/llgltfmateriallist.cpp b/indra/newview/llgltfmateriallist.cpp index 99a052f719..a204315a2a 100644 --- a/indra/newview/llgltfmateriallist.cpp +++ b/indra/newview/llgltfmateriallist.cpp @@ -160,9 +160,9 @@ public: // sides - array of S32 indices of texture entries // gltf_json - array of corresponding Strings of GLTF json for override data - LLSD message; bool success = true; +#if 0 //deprecated for(const std::string& llsdRaw : strings) { std::istringstream llsdData(llsdRaw); @@ -198,6 +198,7 @@ public: applyData(object_override); } +#endif return success; } @@ -213,6 +214,7 @@ public: { // Parse the data +#if 0 // DEPRECATED LL::WorkQueue::ptr_t main_queue = LL::WorkQueue::getInstance("mainloop"); LL::WorkQueue::ptr_t general_queue = LL::WorkQueue::getInstance("General"); @@ -235,24 +237,17 @@ public: results.reserve(sides.size()); // parse json - std::unordered_map::const_iterator iter = sides.begin(); - std::unordered_map::const_iterator end = sides.end(); + std::unordered_map::const_iterator iter = sides.begin(); + std::unordered_map::const_iterator end = sides.end(); while (iter != end) { - std::string warn_msg, error_msg; - ReturnData result; - bool success = result.mMaterial.fromJSON(iter->second, warn_msg, error_msg); - - result.mSuccess = success; + result.mMaterial.applyOverrideLLSD(iter->second); + + result.mSuccess = true; result.mSide = iter->first; - if (!success) - { - LL_WARNS("GLTF") << "failed to parse GLTF override data. errors: " << error_msg << " | warnings: " << warn_msg << LL_ENDL; - } - results.push_back(result); iter++; } @@ -318,6 +313,7 @@ public: } }); } +#endif } private: @@ -330,6 +326,59 @@ namespace LLGLTFMaterialOverrideDispatchHandler handle_gltf_override_message; } +void LLGLTFMaterialList::applyOverrideMessage(LLMessageSystem* msg, const std::string& data_in) +{ + std::istringstream str(data_in); + + LLSD data; + + LLSDSerialize::fromNotation(data, str, data_in.length()); + + const LLHost& host = msg->getSender(); + + LLViewerRegion* region = LLWorld::instance().getRegion(host); + + if (region) + { + U32 local_id = data.get("id").asInteger(); + LLUUID id; + gObjectList.getUUIDFromLocal(id, local_id, host.getAddress(), host.getPort()); + LLViewerObject* obj = gObjectList.findObject(id); + + if (obj) + { + const LLSD& tes = data["te"]; + const LLSD& od = data["od"]; + + if (tes.isArray()) + { + LLGLTFOverrideCacheEntry cache; + cache.mLocalId = local_id; + cache.mObjectId = id; + cache.mRegionHandle = region->getHandle(); + + for (int i = 0; i < tes.size(); ++i) + { + S32 te = tes[i].asInteger(); + LLGLTFMaterial* mat = new LLGLTFMaterial(); // setTEGLTFMaterialOverride will take ownership + mat->applyOverrideLLSD(od[i]); + obj->setTEGLTFMaterialOverride(te, mat); + + cache.mSides[te] = od[i]; + cache.mGLTFMaterial[te] = mat; + + if (obj->getTE(te) && obj->getTE(te)->isSelected()) + { + handle_gltf_override_message.doSelectionCallbacks(id, te); + } + } + + region->cacheFullUpdateGLTFOverride(cache); + } + } + } +} + void LLGLTFMaterialList::queueOverrideUpdate(const LLUUID& id, S32 side, LLGLTFMaterial* override_data) { #if 0 diff --git a/indra/newview/llgltfmateriallist.h b/indra/newview/llgltfmateriallist.h index ce8781baba..7317214019 100644 --- a/indra/newview/llgltfmateriallist.h +++ b/indra/newview/llgltfmateriallist.h @@ -101,6 +101,9 @@ public: static void loadCacheOverrides(const LLGLTFOverrideCacheEntry& override); + // Apply an override update with the given data + void applyOverrideMessage(LLMessageSystem* msg, const std::string& data); + private: friend class LLGLTFMaterialOverrideDispatchHandler; // save an override update that we got from the simulator for later (for example, if an override arrived for an unknown object) diff --git a/indra/newview/llstartup.cpp b/indra/newview/llstartup.cpp index 8ffab761f4..eccfd40fe6 100644 --- a/indra/newview/llstartup.cpp +++ b/indra/newview/llstartup.cpp @@ -2709,6 +2709,7 @@ void register_viewer_callbacks(LLMessageSystem* msg) msg->setHandlerFunc("InitiateDownload", process_initiate_download); msg->setHandlerFunc("LandStatReply", LLFloaterTopObjects::handle_land_reply); msg->setHandlerFunc("GenericMessage", process_generic_message); + msg->setHandlerFunc("GenericStreamingMessage", process_generic_streaming_message); msg->setHandlerFunc("LargeGenericMessage", process_large_generic_message); msg->setHandlerFuncFast(_PREHASH_FeatureDisabled, process_feature_disabled_message); diff --git a/indra/newview/llviewergenericmessage.cpp b/indra/newview/llviewergenericmessage.cpp index d3de9d72bf..7ea792c404 100644 --- a/indra/newview/llviewergenericmessage.cpp +++ b/indra/newview/llviewergenericmessage.cpp @@ -32,9 +32,10 @@ #include "lldispatcher.h" #include "lluuid.h" #include "message.h" +#include "llgenericstreamingmessage.h" #include "llagent.h" - +#include "llgltfmateriallist.h" LLDispatcher gGenericDispatcher; @@ -92,6 +93,21 @@ void process_generic_message(LLMessageSystem* msg, void**) } } +void process_generic_streaming_message(LLMessageSystem* msg, void**) +{ + LLGenericStreamingMessage data; + data.unpack(msg); + switch (data.mMethod) + { + case LLGenericStreamingMessage::METHOD_GLTF_MATERIAL_OVERRIDE: + gGLTFMaterialList.applyOverrideMessage(msg, data.mData); + break; + default: + LL_WARNS() << "GenericStreamingMessage received unknown method: " << data.mMethod << LL_ENDL; + break; + } +} + void process_large_generic_message(LLMessageSystem* msg, void**) { LLUUID agent_id; diff --git a/indra/newview/llviewergenericmessage.h b/indra/newview/llviewergenericmessage.h index 170f38a485..96a73a3d5f 100644 --- a/indra/newview/llviewergenericmessage.h +++ b/indra/newview/llviewergenericmessage.h @@ -38,6 +38,7 @@ void send_generic_message(const std::string& method, const LLUUID& invoice = LLUUID::null); void process_generic_message(LLMessageSystem* msg, void**); +void process_generic_streaming_message(LLMessageSystem* msg, void**); void process_large_generic_message(LLMessageSystem* msg, void**); diff --git a/indra/newview/llviewerregion.cpp b/indra/newview/llviewerregion.cpp index 6b92b16ef4..ead1e8c073 100755 --- a/indra/newview/llviewerregion.cpp +++ b/indra/newview/llviewerregion.cpp @@ -215,7 +215,7 @@ public: LLVOCacheEntry::vocache_entry_set_t mVisibleEntries; //must-be-created visible entries wait for objects creation. LLVOCacheEntry::vocache_entry_priority_list_t mWaitingList; //transient list storing sorted visible entries waiting for object creation. std::set mNonCacheableCreatedList; //list of local ids of all non-cacheable objects - LLVOCacheEntry::vocache_gltf_overrides_map_t mGLTFOverridesJson; // for materials + LLVOCacheEntry::vocache_gltf_overrides_map_t mGLTFOverridesLLSD; // for materials // time? // LRU info? @@ -787,7 +787,7 @@ void LLViewerRegion::loadObjectCache() { LLVOCache & vocache = LLVOCache::instance(); vocache.readFromCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap); - vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesJson); + vocache.readGenericExtrasFromCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD); if (mImpl->mCacheMap.empty()) { @@ -817,7 +817,7 @@ void LLViewerRegion::saveObjectCache() LLVOCache & instance = LLVOCache::instance(); instance.writeToCache(mHandle, mImpl->mCacheID, mImpl->mCacheMap, mCacheDirty, removal_enabled); - instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesJson, mCacheDirty, removal_enabled); + instance.writeGenericExtrasToCache(mHandle, mImpl->mCacheID, mImpl->mGLTFOverridesLLSD, mCacheDirty, removal_enabled); mCacheDirty = FALSE; } @@ -2656,7 +2656,7 @@ LLViewerRegion::eCacheUpdateResult LLViewerRegion::cacheFullUpdate(LLViewerObjec void LLViewerRegion::cacheFullUpdateGLTFOverride(const LLGLTFOverrideCacheEntry &override_data) { U32 local_id = override_data.mLocalId; - mImpl->mGLTFOverridesJson[local_id] = override_data; + mImpl->mGLTFOverridesLLSD[local_id] = override_data; } LLVOCacheEntry* LLViewerRegion::getCacheEntryForOctree(U32 local_id) @@ -3546,8 +3546,8 @@ std::string LLViewerRegion::getSimHostName() void LLViewerRegion::loadCacheMiscExtras(U32 local_id) { - auto iter = mImpl->mGLTFOverridesJson.find(local_id); - if (iter != mImpl->mGLTFOverridesJson.end()) + auto iter = mImpl->mGLTFOverridesLLSD.find(local_id); + if (iter != mImpl->mGLTFOverridesLLSD.end()) { LLGLTFMaterialList::loadCacheOverrides(iter->second); } @@ -3559,8 +3559,8 @@ void LLViewerRegion::applyCacheMiscExtras(LLViewerObject* obj) llassert(obj); U32 local_id = obj->getLocalID(); - auto iter = mImpl->mGLTFOverridesJson.find(local_id); - if (iter != mImpl->mGLTFOverridesJson.end()) + auto iter = mImpl->mGLTFOverridesLLSD.find(local_id); + if (iter != mImpl->mGLTFOverridesLLSD.end()) { llassert(iter->second.mGLTFMaterial.size() == iter->second.mSides.size()); diff --git a/indra/newview/llvocache.cpp b/indra/newview/llvocache.cpp index a92057d010..dd5b9f9fd5 100644 --- a/indra/newview/llvocache.cpp +++ b/indra/newview/llvocache.cpp @@ -85,40 +85,24 @@ bool LLGLTFOverrideCacheEntry::fromLLSD(const LLSD& data) // message should be interpreted thusly: /// sides is a list of face indices - // gltf_json is a list of corresponding json + // gltf_llsd is a list of corresponding GLTF override LLSD // any side not represented in "sides" has no override - if (data.has("sides") && data.has("gltf_json")) + if (data.has("sides") && data.has("gltf_llsd")) { LLSD const& sides = data.get("sides"); - LLSD const& gltf_json = data.get("gltf_json"); + LLSD const& gltf_llsd = data.get("gltf_llsd"); - if (sides.isArray() && gltf_json.isArray() && + if (sides.isArray() && gltf_llsd.isArray() && sides.size() != 0 && - sides.size() == gltf_json.size()) + sides.size() == gltf_llsd.size()) { for (int i = 0; i < sides.size(); ++i) { S32 side_idx = sides[i].asInteger(); - std::string gltf_json_str = gltf_json[i].asString(); - mSides[side_idx] = gltf_json_str; + mSides[side_idx] = gltf_llsd[i]; LLGLTFMaterial* override_mat = new LLGLTFMaterial(); - std::string error, warn; - if (override_mat->fromJSON(gltf_json_str, warn, error)) - { - mGLTFMaterial[side_idx] = override_mat; - } - else - { - LL_WARNS() << "Invalid GLTF string: \n" << gltf_json_str << LL_ENDL; - if (!error.empty()) - { - LL_WARNS() << "Error: " << error << LL_ENDL; - } - if (!warn.empty()) - { - LL_WARNS() << "Warning: " << warn << LL_ENDL; - } - } + override_mat->applyOverrideLLSD(gltf_llsd[i]); + mGLTFMaterial[side_idx] = override_mat; } } else @@ -157,7 +141,7 @@ LLSD LLGLTFOverrideCacheEntry::toLLSD() const // check that mSides and mGLTFMaterial have exactly the same keys present llassert(mGLTFMaterial.count(side.first) == 1); data["sides"].append(LLSD::Integer(side.first)); - data["gltf_json"].append(side.second); + data["gltf_llsd"].append(side.second); } return data; diff --git a/indra/newview/llvocache.h b/indra/newview/llvocache.h index ec0df31828..8525edd121 100644 --- a/indra/newview/llvocache.h +++ b/indra/newview/llvocache.h @@ -48,7 +48,7 @@ public: LLUUID mObjectId; U32 mLocalId = 0; - std::unordered_map mSides; //json per side + std::unordered_map mSides; //override LLSD per side std::unordered_map > mGLTFMaterial; //GLTF material per side U64 mRegionHandle = 0; }; diff --git a/scripts/messages/message_template.msg b/scripts/messages/message_template.msg index a3ddc6d336..c019a76793 100755 --- a/scripts/messages/message_template.msg +++ b/scripts/messages/message_template.msg @@ -5790,6 +5790,25 @@ version 2.0 } } +// GenericStreamingMessage +// Optimized generic message for streaming arbitrary data to viewer +// Avoid payloads over 7KB (8KB ceiling) +// Method -- magic number indicating method to use to decode payload: +// 0x4175 - GLTF material override data +// Payload -- data to be decoded +{ + GenericStreamingMessage High 31 Trusted Unencoded + { + MethodData Single + { Method U16 } + } + + { + DataBlock Single + { Data Variable 2 } + } +} + // LargeGenericMessage // Similar to the above messages, but can handle larger payloads and serialized // LLSD. Uses HTTP transport diff --git a/scripts/messages/message_template.msg.sha1 b/scripts/messages/message_template.msg.sha1 index 4712a03e8d..ddde49680e 100755 --- a/scripts/messages/message_template.msg.sha1 +++ b/scripts/messages/message_template.msg.sha1 @@ -1 +1 @@ -dddb11f7e45f1779ff536819f36a20e63d572ba8 \ No newline at end of file +992450072b9c04c2157247be5cf5341b96d6f167 \ No newline at end of file -- cgit v1.3 From 813acc39feec14b0c78fd9f704b358331ff87896 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Fri, 22 Sep 2023 14:23:07 -0500 Subject: SL-20325 Fix for double sided not working. --- indra/llprimitive/llgltfmaterial.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 8475e7231a..19b7413934 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -833,7 +833,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) } const LLSD& ds = data["ds"]; - if (data.isBoolean()) + if (ds.isBoolean()) { mDoubleSided = ds.asBoolean(); mOverrideDoubleSided = true; -- cgit v1.3 From d22ea319a51707bdcc0a8cb946143208d8c3f553 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 9 Oct 2023 16:05:58 -0700 Subject: SL-20225: LLGLTFMaterial code sync --- indra/llprimitive/CMakeLists.txt | 1 + indra/llprimitive/llgltfmaterial.cpp | 161 +++++---------------------- indra/llprimitive/llgltfmaterial.h | 38 +++++-- indra/llprimitive/llgltfmaterial_templates.h | 142 +++++++++++++++++++++++ 4 files changed, 197 insertions(+), 145 deletions(-) create mode 100644 indra/llprimitive/llgltfmaterial_templates.h (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/CMakeLists.txt b/indra/llprimitive/CMakeLists.txt index 76d261ab3e..2bd1edaacc 100644 --- a/indra/llprimitive/CMakeLists.txt +++ b/indra/llprimitive/CMakeLists.txt @@ -34,6 +34,7 @@ set(llprimitive_HEADER_FILES lldaeloader.h llgltfloader.h llgltfmaterial.h + llgltfmaterial_templates.h legacy_object_types.h llmaterial.h llmaterialid.h diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 19b7413934..f42c11ee21 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -24,25 +24,28 @@ * $/LicenseInfo$ */ + #include "linden_common.h" #include "llgltfmaterial.h" + #include "llsdserialize.h" // NOTE -- this should be the one and only place tiny_gltf.h is included #include "tinygltf/tiny_gltf.h" +#include "llgltfmaterial_templates.h" const char* const LLGLTFMaterial::ASSET_VERSION = "1.1"; const char* const LLGLTFMaterial::ASSET_TYPE = "GLTF 2.0"; const std::array LLGLTFMaterial::ACCEPTED_ASSET_VERSIONS = { "1.0", "1.1" }; -const char* const GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; -const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; -const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; -const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; +const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM = "KHR_texture_transform"; +const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_SCALE = "scale"; +const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_OFFSET = "offset"; +const char* const LLGLTFMaterial::GLTF_FILE_EXTENSION_TRANSFORM_ROTATION = "rotation"; // special UUID that indicates a null UUID in override data -static const LLUUID GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); +const LLUUID LLGLTFMaterial::GLTF_OVERRIDE_NULL_UUID = LLUUID("ffffffff-ffff-ffff-ffff-ffffffffffff"); void LLGLTFMaterial::TextureTransform::getPacked(F32 (&packed)[8]) const { @@ -68,14 +71,14 @@ LLGLTFMaterial::LLGLTFMaterial(const LLGLTFMaterial& rhs) LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) { - //have to do a manual operator= because of LLRefCount + //have to do a manual operator= because of LLRefCount mTextureId = rhs.mTextureId; mTextureTransform = rhs.mTextureTransform; mBaseColor = rhs.mBaseColor; mEmissiveColor = rhs.mEmissiveColor; - + mMetallicFactor = rhs.mMetallicFactor; mRoughnessFactor = rhs.mRoughnessFactor; mAlphaCutoff = rhs.mAlphaCutoff; @@ -97,7 +100,7 @@ bool LLGLTFMaterial::operator==(const LLGLTFMaterial& rhs) const mBaseColor == rhs.mBaseColor && mEmissiveColor == rhs.mEmissiveColor && - + mMetallicFactor == rhs.mMetallicFactor && mRoughnessFactor == rhs.mRoughnessFactor && mAlphaCutoff == rhs.mAlphaCutoff && @@ -122,6 +125,7 @@ bool LLGLTFMaterial::fromJSON(const std::string& json, std::string& warn_msg, st return true; } + return false; } @@ -190,7 +194,8 @@ void LLGLTFMaterial::setFromModel(const tinygltf::Model& model, S32 mat_index) } } -LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value) +// static +LLVector2 LLGLTFMaterial::vec2FromJson(const tinygltf::Value::Object& object, const char* key, const LLVector2& default_value) { const auto it = object.find(key); if (it == object.end()) @@ -215,7 +220,8 @@ LLVector2 vec2_from_json(const tinygltf::Value::Object& object, const char* key, return value; } -F32 float_from_json(const tinygltf::Value::Object& object, const char* key, const F32 default_value) +// static +F32 LLGLTFMaterial::floatFromJson(const tinygltf::Value::Object& object, const char* key, const F32 default_value) { const auto it = object.find(key); if (it == object.end()) @@ -230,52 +236,6 @@ F32 float_from_json(const tinygltf::Value::Object& object, const char* key, cons return (F32)real_json.GetNumberAsDouble(); } -template -std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info) -{ - const S32 texture_idx = texture_info.index; - if (texture_idx < 0 || texture_idx >= model.textures.size()) - { - return ""; - } - const tinygltf::Texture& texture = model.textures[texture_idx]; - - // Ignore texture.sampler for now - - const S32 image_idx = texture.source; - if (image_idx < 0 || image_idx >= model.images.size()) - { - return ""; - } - const tinygltf::Image& image = model.images[image_idx]; - - return image.uri; -} - -// *NOTE: Use template here as workaround for the different similar texture info classes -template -void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id) -{ - LL_PROFILE_ZONE_SCOPED; - const std::string uri = gltf_get_texture_image(model, texture_info); - mTextureId[texture_info_id].set(uri); - - const tinygltf::Value::Object& extensions_object = texture_info.extensions; - const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM); - if (transform_it != extensions_object.end()) - { - const tinygltf::Value& transform_json = std::get<1>(*transform_it); - if (transform_json.IsObject()) - { - const tinygltf::Value::Object& transform_object = transform_json.Get(); - TextureTransform& transform = mTextureTransform[texture_info_id]; - transform.mOffset = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset()); - transform.mScale = vec2_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale()); - transform.mRotation = float_from_json(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation()); - } - } -} - void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const { LL_PROFILE_ZONE_SCOPED; @@ -302,7 +262,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const material_out.alphaMode = getAlphaMode(); material_out.alphaCutoff = mAlphaCutoff; - + mBaseColor.write(material_out.pbrMetallicRoughness.baseColorFactor); if (mEmissiveColor != LLGLTFMaterial::getDefaultEmissiveColor()) @@ -320,7 +280,7 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const tinygltf::Value::Object extras; bool write_extras = false; if (mOverrideAlphaMode && mAlphaMode == getDefaultAlphaMode()) - { + { extras["override_alpha_mode"] = tinygltf::Value(mOverrideAlphaMode); write_extras = true; } @@ -339,57 +299,6 @@ void LLGLTFMaterial::writeToModel(tinygltf::Model& model, S32 mat_index) const model.asset.version = "2.0"; } -template -void gltf_allocate_texture_image(tinygltf::Model& model, T& texture_info, const std::string& uri) -{ - const S32 image_idx = model.images.size(); - model.images.emplace_back(); - model.images[image_idx].uri = uri; - - // The texture, not to be confused with the texture info - const S32 texture_idx = model.textures.size(); - model.textures.emplace_back(); - tinygltf::Texture& texture = model.textures[texture_idx]; - texture.source = image_idx; - - texture_info.index = texture_idx; -} - -template -void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const -{ - LL_PROFILE_ZONE_SCOPED; - const LLUUID& texture_id = mTextureId[texture_info_id]; - const TextureTransform& transform = mTextureTransform[texture_info_id]; - const bool is_blank_transform = transform == sDefault.mTextureTransform[0]; - // Check if this material matches all the fallback values, and if so, then - // skip including it to reduce material size - if (!force_write && texture_id.isNull() && is_blank_transform) - { - return; - } - - // tinygltf will discard this texture info if there is no valid texture, - // causing potential loss of information for overrides, so ensure one is - // defined. -Cosmic,2023-01-30 - gltf_allocate_texture_image(model, texture_info, texture_id.asString()); - - if (!is_blank_transform) - { - tinygltf::Value::Object transform_map; - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ - tinygltf::Value(transform.mOffset.mV[VX]), - tinygltf::Value(transform.mOffset.mV[VY]) - })); - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({ - tinygltf::Value(transform.mScale.mV[VX]), - tinygltf::Value(transform.mScale.mV[VY]) - })); - transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation); - texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); - } -} - void LLGLTFMaterial::sanitizeAssetMaterial() { mTextureTransform = sDefault.mTextureTransform; @@ -403,19 +312,19 @@ bool LLGLTFMaterial::setBaseMaterial() return *this != old_override; } -bool LLGLTFMaterial::isClearedForBaseMaterial() -{ - LLGLTFMaterial cleared_override = sDefault; - cleared_override.setBaseMaterial(*this); - return *this == cleared_override; -} - // For material overrides only. Copies transforms from the old override. void LLGLTFMaterial::setBaseMaterial(const LLGLTFMaterial& old_override_mat) { mTextureTransform = old_override_mat.mTextureTransform; } +bool LLGLTFMaterial::isClearedForBaseMaterial() const +{ + LLGLTFMaterial cleared_override = sDefault; + cleared_override.setBaseMaterial(*this); + return *this == cleared_override; +} + // static void LLGLTFMaterial::hackOverrideUUID(LLUUID& id) @@ -516,7 +425,7 @@ void LLGLTFMaterial::setAlphaMode(const std::string& mode, bool for_override) { m = ALPHA_MODE_BLEND; } - + setAlphaMode(m, for_override); } @@ -709,7 +618,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d { data["tex"][i] = LLSD::UUID(override_texture_id); } - } if (override_mat.mBaseColor != getDefaultBaseColor()) @@ -764,23 +672,6 @@ void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& d data["ti"][i]["r"] = override_mat.mTextureTransform[i].mRotation; } } - -#if 0 - { - std::ostringstream ostr; - LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_NOTATION); - std::string param_str(ostr.str()); - LL_INFOS() << param_str << LL_ENDL; - LL_INFOS() << "Notation size: " << param_str.size() << LL_ENDL; - } - - { - std::ostringstream ostr; - LLSDSerialize::serialize(data, ostr, LLSDSerialize::LLSD_BINARY); - std::string param_str(ostr.str()); - LL_INFOS() << "Binary size: " << param_str.size() << LL_ENDL; - } -#endif } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index ca27507707..a078a530a4 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -35,10 +35,13 @@ #include "hbxxh.h" #include +#include namespace tinygltf { class Model; + struct TextureInfo; + class Value; } class LLTextureEntry; @@ -52,6 +55,9 @@ public: static const char* const ASSET_VERSION; static const char* const ASSET_TYPE; + // Max allowed size of a GLTF material asset or override, when serialized + // as a minified JSON string + static constexpr size_t MAX_ASSET_LENGTH = 2048; static const std::array ACCEPTED_ASSET_VERSIONS; static bool isAcceptedVersion(const std::string& version) { return std::find(ACCEPTED_ASSET_VERSIONS.cbegin(), ACCEPTED_ASSET_VERSIONS.cend(), version) != ACCEPTED_ASSET_VERSIONS.cend(); } @@ -64,6 +70,7 @@ public: void getPacked(F32 (&packed)[8]) const; bool operator==(const TextureTransform& other) const; + bool operator!=(const TextureTransform& other) const { return !(*this == other); } }; enum AlphaMode @@ -96,8 +103,13 @@ public: GLTF_TEXTURE_INFO_COUNT }; - std::array mTextureId; + static const char* const GLTF_FILE_EXTENSION_TRANSFORM; + static const char* const GLTF_FILE_EXTENSION_TRANSFORM_SCALE; + static const char* const GLTF_FILE_EXTENSION_TRANSFORM_OFFSET; + static const char* const GLTF_FILE_EXTENSION_TRANSFORM_ROTATION; + static const LLUUID GLTF_OVERRIDE_NULL_UUID; + std::array mTextureId; std::array mTextureTransform; // NOTE: initialize values to defaults according to the GLTF spec @@ -137,7 +149,7 @@ public: void setAlphaMode(S32 mode, bool for_override = false); void setDoubleSided(bool double_sided, bool for_override = false); - //NOTE: texture offsets only exist in overrides, so "for_override" is not needed + // *NOTE: texture offsets only exist in overrides, so "for_override" is not needed void setTextureOffset(TextureInfo texture_info, const LLVector2& offset); void setTextureScale(TextureInfo texture_info, const LLVector2& scale); @@ -155,7 +167,6 @@ public: static LLVector2 getDefaultTextureScale(); static F32 getDefaultTextureRotation(); - static void hackOverrideUUID(LLUUID& id); static void applyOverrideUUID(LLUUID& dst_id, const LLUUID& override_id); @@ -164,7 +175,7 @@ public: void setAlphaMode(const std::string& mode, bool for_override = false); const char* getAlphaMode() const; - + // set the contents of this LLGLTFMaterial from the given json // returns true if successful // if unsuccessful, the contents of this LLGLTFMaterial should be left unchanged and false is returned @@ -176,7 +187,6 @@ public: // get the contents of this LLGLTFMaterial as a json string std::string asJSON(bool prettyprint = false) const; - // initialize from given tinygltf::Model // model - the model to reference // mat_index - index of material in model's material array @@ -202,21 +212,29 @@ public: // For material overrides only. Clears most properties to // default/fallthrough, but preserves the transforms. bool setBaseMaterial(); + void setBaseMaterial(const LLGLTFMaterial& old_override_mat); // True if setBaseMaterial() was just called - bool isClearedForBaseMaterial(); + bool isClearedForBaseMaterial() const; // For local materials, they have to keep track of where // they are assigned to for full updates virtual void addTextureEntry(LLTextureEntry* te) {}; virtual void removeTextureEntry(LLTextureEntry* te) {}; -private: +protected: + static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); + static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); + + template + static void allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri); + template void setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id); + template + static void setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform); template void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; - - void setBaseMaterial(const LLGLTFMaterial& old_override_mat); + template + static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false); }; - diff --git a/indra/llprimitive/llgltfmaterial_templates.h b/indra/llprimitive/llgltfmaterial_templates.h new file mode 100644 index 0000000000..f607dfe967 --- /dev/null +++ b/indra/llprimitive/llgltfmaterial_templates.h @@ -0,0 +1,142 @@ +/** + * @file llgltfmaterial_templates.h + * @brief Material template definition + * + * $LicenseInfo:firstyear=2023&license=viewerlgpl$ + * Second Life Viewer Source Code + * Copyright (C) 2023, Linden Research, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; + * version 2.1 of the License only. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * + * Linden Research, Inc., 945 Battery Street, San Francisco, CA 94111 USA + * $/LicenseInfo$ + */ + +#pragma once + +#include "llgltfmaterial.h" + +// Use templates here as workaround for the different similar texture info classes in tinygltf +// Includer must first include tiny_gltf.h with the desired flags + +template +std::string gltf_get_texture_image(const tinygltf::Model& model, const T& texture_info) +{ + const S32 texture_idx = texture_info.index; + if (texture_idx < 0 || texture_idx >= model.textures.size()) + { + return ""; + } + const tinygltf::Texture& texture = model.textures[texture_idx]; + + // Ignore texture.sampler for now + + const S32 image_idx = texture.source; + if (image_idx < 0 || image_idx >= model.images.size()) + { + return ""; + } + const tinygltf::Image& image = model.images[image_idx]; + + return image.uri; +} + +template +void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, TextureInfo texture_info_id) +{ + setFromTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id]); + const std::string uri = gltf_get_texture_image(model, texture_info); +} + +// static +template +void LLGLTFMaterial::setFromTexture(const tinygltf::Model& model, const T& texture_info, LLUUID& texture_id, TextureTransform& transform) +{ + LL_PROFILE_ZONE_SCOPED; + const std::string uri = gltf_get_texture_image(model, texture_info); + texture_id.set(uri); + + const tinygltf::Value::Object& extensions_object = texture_info.extensions; + const auto transform_it = extensions_object.find(GLTF_FILE_EXTENSION_TRANSFORM); + if (transform_it != extensions_object.end()) + { + const tinygltf::Value& transform_json = std::get<1>(*transform_it); + if (transform_json.IsObject()) + { + const tinygltf::Value::Object& transform_object = transform_json.Get(); + transform.mOffset = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_OFFSET, getDefaultTextureOffset()); + transform.mScale = vec2FromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_SCALE, getDefaultTextureScale()); + transform.mRotation = floatFromJson(transform_object, GLTF_FILE_EXTENSION_TRANSFORM_ROTATION, getDefaultTextureRotation()); + } + } +} + +// static +template +void LLGLTFMaterial::allocateTextureImage(tinygltf::Model& model, T& texture_info, const std::string& uri) +{ + const S32 image_idx = model.images.size(); + model.images.emplace_back(); + model.images[image_idx].uri = uri; + + // The texture, not to be confused with the texture info + const S32 texture_idx = model.textures.size(); + model.textures.emplace_back(); + tinygltf::Texture& texture = model.textures[texture_idx]; + texture.source = image_idx; + + texture_info.index = texture_idx; +} + +// static +template +void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write) const +{ + writeToTexture(model, texture_info, mTextureId[texture_info_id], mTextureTransform[texture_info_id], force_write); +} + +// static +template +void LLGLTFMaterial::writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write) +{ + LL_PROFILE_ZONE_SCOPED; + const bool is_blank_transform = transform == sDefault.mTextureTransform[0]; + // Check if this material matches all the fallback values, and if so, then + // skip including it to reduce material size + if (!force_write && texture_id.isNull() && is_blank_transform) + { + return; + } + + // tinygltf will discard this texture info if there is no valid texture, + // causing potential loss of information for overrides, so ensure one is + // defined. -Cosmic,2023-01-30 + allocateTextureImage(model, texture_info, texture_id.asString()); + + if (!is_blank_transform) + { + tinygltf::Value::Object transform_map; + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_OFFSET] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mOffset.mV[VX]), + tinygltf::Value(transform.mOffset.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_SCALE] = tinygltf::Value(tinygltf::Value::Array({ + tinygltf::Value(transform.mScale.mV[VX]), + tinygltf::Value(transform.mScale.mV[VY]) + })); + transform_map[GLTF_FILE_EXTENSION_TRANSFORM_ROTATION] = tinygltf::Value(transform.mRotation); + texture_info.extensions[GLTF_FILE_EXTENSION_TRANSFORM] = tinygltf::Value(transform_map); + } +} -- cgit v1.3 From 07a830a4cef1ccc600f8c4dc5e4fcdba83df839b Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 12 Oct 2023 13:02:23 -0700 Subject: SL-20062: Fix near clip on reflection probes being clamped to at or below 10 --- indra/llmath/llcamera.h | 2 +- indra/llprimitive/llprimitive.cpp | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) (limited to 'indra/llprimitive') diff --git a/indra/llmath/llcamera.h b/indra/llmath/llcamera.h index 27eaa614c9..c4d04f5d02 100644 --- a/indra/llmath/llcamera.h +++ b/indra/llmath/llcamera.h @@ -39,7 +39,7 @@ const F32 DEFAULT_NEAR_PLANE = 0.25f; const F32 DEFAULT_FAR_PLANE = 64.f; // far reaches across two horizontal, not diagonal, regions const F32 MAX_ASPECT_RATIO = 50.0f; -const F32 MAX_NEAR_PLANE = 10.f; +const F32 MAX_NEAR_PLANE = 1023.9f; // Clamp the near plane just before the skybox ends const F32 MAX_FAR_PLANE = 100000.0f; //1000000.0f; // Max allowed. Not good Z precision though. const F32 MAX_FAR_CLIP = 512.0f; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 5dfce4ae16..350d84ae6c 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -85,6 +85,8 @@ const F32 LIGHT_MAX_CUTOFF = 180.f; const F32 REFLECTION_PROBE_MIN_AMBIANCE = 0.f; const F32 REFLECTION_PROBE_MAX_AMBIANCE = 100.f; const F32 REFLECTION_PROBE_DEFAULT_AMBIANCE = 0.f; +// *NOTE: Clip distances are clamped in LLCamera::setNear. The max clip +// distance is currently limited by the skybox const F32 REFLECTION_PROBE_MIN_CLIP_DISTANCE = 0.f; const F32 REFLECTION_PROBE_MAX_CLIP_DISTANCE = 1024.f; const F32 REFLECTION_PROBE_DEFAULT_CLIP_DISTANCE = 0.f; -- cgit v1.3 From 26163e2154647e99567b1ce01b89ed208eb11bb8 Mon Sep 17 00:00:00 2001 From: Brad Linden Date: Wed, 25 Oct 2023 16:27:38 -0700 Subject: Fix DRTVWR-559 std::array usage in llrender and llprimitive after merge --- indra/llprimitive/llgltfmaterial.h | 1 + indra/llrender/llrender.h | 2 ++ 2 files changed, 3 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index a078a530a4..822a0aab22 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -34,6 +34,7 @@ #include "lluuid.h" #include "hbxxh.h" +#include #include #include diff --git a/indra/llrender/llrender.h b/indra/llrender/llrender.h index 98141d71f5..fd922affba 100644 --- a/indra/llrender/llrender.h +++ b/indra/llrender/llrender.h @@ -44,6 +44,8 @@ #include "llmatrix4a.h" #include "glh/glh_linear.h" +#include + class LLVertexBuffer; class LLCubeMap; class LLImageGL; -- cgit v1.3 From dc63dfc0dd6554f5f45b1d80bd4cb9258eefee95 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Wed, 25 Oct 2023 23:38:12 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #1 Update editor in which texture changed to local --- indra/llprimitive/llgltfmaterial.h | 6 +++ indra/newview/llfloaterchangeitemthumbnail.cpp | 2 +- indra/newview/lllocalbitmaps.cpp | 48 ++++++++++++----- indra/newview/lllocalbitmaps.h | 28 ++++++---- indra/newview/llmaterialeditor.cpp | 75 ++++++++++++++++++++++++++ indra/newview/llmaterialeditor.h | 2 + indra/newview/llpanelprofile.cpp | 4 +- indra/newview/lltexturectrl.cpp | 27 ++++++---- indra/newview/lltexturectrl.h | 12 ++++- 9 files changed, 168 insertions(+), 36 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 822a0aab22..548e2c52f4 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -222,6 +222,10 @@ public: virtual void addTextureEntry(LLTextureEntry* te) {}; virtual void removeTextureEntry(LLTextureEntry* te) {}; + // For local textures so that editor will know to track changes + void setHasLocalTextures(bool val) { mHasLocalTextures = val; } + bool hasLocalTextures() { return mHasLocalTextures; } + protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); static F32 floatFromJson(const std::map& object, const char* key, const F32 default_value); @@ -238,4 +242,6 @@ protected: void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; template static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false); + + bool mHasLocalTextures; }; diff --git a/indra/newview/llfloaterchangeitemthumbnail.cpp b/indra/newview/llfloaterchangeitemthumbnail.cpp index f54240f6f4..0301627c15 100644 --- a/indra/newview/llfloaterchangeitemthumbnail.cpp +++ b/indra/newview/llfloaterchangeitemthumbnail.cpp @@ -760,7 +760,7 @@ void LLFloaterChangeItemThumbnail::showTexturePicker(const LLUUID &thumbnail_id) { //texture_floaterp->setTextureSelectedCallback(); //texture_floaterp->setOnUpdateImageStatsCallback(); - texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&) + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource, const LLUUID&, const LLUUID&, const LLUUID&) { if (op == LLTextureCtrl::TEXTURE_SELECT) { diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 257208470e..6f1e4c9419 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -142,27 +142,27 @@ LLLocalBitmap::~LLLocalBitmap() } /* accessors */ -std::string LLLocalBitmap::getFilename() +std::string LLLocalBitmap::getFilename() const { return mFilename; } -std::string LLLocalBitmap::getShortName() +std::string LLLocalBitmap::getShortName() const { return mShortName; } -LLUUID LLLocalBitmap::getTrackingID() +LLUUID LLLocalBitmap::getTrackingID() const { return mTrackingID; } -LLUUID LLLocalBitmap::getWorldID() +LLUUID LLLocalBitmap::getWorldID() const { return mWorldID; } -bool LLLocalBitmap::getValid() +bool LLLocalBitmap::getValid() const { return mValid; } @@ -273,6 +273,11 @@ bool LLLocalBitmap::updateSelf(EUpdateType optional_firstupdate) return updated; } +boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextureCallback& cb) +{ + return mChangedSignal.connect(cb); +} + bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) { bool decode_successful = false; @@ -340,7 +345,7 @@ bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) return decode_successful; } -void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) +void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id) { // checking for misuse. if (old_id == new_id) @@ -350,6 +355,8 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) return; } + mChangedSignal(old_id, new_id); + // processing updates per channel; makes the process scalable. // the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc. updateUserPrims(old_id, new_id, LLRender::DIFFUSE_MAP); @@ -381,6 +388,9 @@ void LLLocalBitmap::replaceIDs(LLUUID old_id, LLUUID new_id) updateUserLayers(old_id, new_id, LLWearableType::WT_UNIVERSAL); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); + + // Go over any local material + } // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects @@ -1020,11 +1030,11 @@ void LLLocalBitmapMgr::delUnit(LLUUID tracking_id) } } -LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) +LLUUID LLLocalBitmapMgr::getWorldID(const LLUUID &tracking_id) const { LLUUID world_id = LLUUID::null; - for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) { LLLocalBitmap* unit = *iter; if (unit->getTrackingID() == tracking_id) @@ -1036,9 +1046,9 @@ LLUUID LLLocalBitmapMgr::getWorldID(LLUUID tracking_id) return world_id; } -bool LLLocalBitmapMgr::isLocal(const LLUUID world_id) +bool LLLocalBitmapMgr::isLocal(const LLUUID &world_id) const { - for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) { LLLocalBitmap* unit = *iter; if (unit->getWorldID() == world_id) @@ -1049,11 +1059,11 @@ bool LLLocalBitmapMgr::isLocal(const LLUUID world_id) return false; } -std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) +std::string LLLocalBitmapMgr::getFilename(const LLUUID &tracking_id) const { std::string filename = ""; - for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + for (local_list_citer iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) { LLLocalBitmap* unit = *iter; if (unit->getTrackingID() == tracking_id) @@ -1065,6 +1075,20 @@ std::string LLLocalBitmapMgr::getFilename(LLUUID tracking_id) return filename; } +boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback &cb) +{ + for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + { + LLLocalBitmap* unit = *iter; + if (unit->getTrackingID() == tracking_id) + { + unit->setChangedCallback(cb); + } + } + + return boost::signals2::connection(); +} + void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl) { if (ctrl) diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index bb026ed3aa..f36fd6d320 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -44,11 +44,11 @@ class LLLocalBitmap ~LLLocalBitmap(); public: /* accessors */ - std::string getFilename(); - std::string getShortName(); - LLUUID getTrackingID(); - LLUUID getWorldID(); - bool getValid(); + std::string getFilename() const; + std::string getShortName() const; + LLUUID getTrackingID() const; + LLUUID getWorldID() const; + bool getValid() const; public: /* self update public section */ enum EUpdateType @@ -59,9 +59,14 @@ class LLLocalBitmap bool updateSelf(EUpdateType = UT_REGUPDATE); + typedef boost::signals2::signal LLLocalTextureChangedSignal; + typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback; + boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb); + private: /* self update private section */ bool decodeBitmap(LLPointer raw); - void replaceIDs(LLUUID old_id, LLUUID new_id); + void replaceIDs(const LLUUID &old_id, LLUUID new_id); std::vector prepUpdateObjects(LLUUID old_id, U32 channel); void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel); void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel); @@ -93,6 +98,7 @@ class LLLocalBitmap EExtension mExtension; ELinkStatus mLinkStatus; S32 mUpdateRetries; + LLLocalTextureChangedSignal mChangedSignal; }; @@ -120,10 +126,11 @@ public: void delUnit(LLUUID tracking_id); bool checkTextureDimensions(std::string filename); - LLUUID getWorldID(LLUUID tracking_id); - bool isLocal(LLUUID world_id); - std::string getFilename(LLUUID tracking_id); - + LLUUID getWorldID(const LLUUID &tracking_id) const; + bool isLocal(const LLUUID& world_id) const; + std::string getFilename(const LLUUID &tracking_id) const; + boost::signals2::connection setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback& cb); + void feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); void setNeedsRebake(); @@ -134,6 +141,7 @@ private: LLLocalBitmapTimer mTimer; bool mNeedsRebake; typedef std::list::iterator local_list_iter; + typedef std::list::const_iterator local_list_citer; }; #endif diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7a65231a2d..63d86cda61 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -532,6 +532,11 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } + for (boost::signals2::connection& cn : mTextureChangesUpdates) + { + cn.disconnect(); + } + LLPreview::onClose(app_quitting); } @@ -861,6 +866,47 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } +void LLMaterialEditor::replaceTexture(const LLUUID& old_id, const LLUUID& new_id) +{ + // todo: might be a good idea to set mBaseColorTextureUploadId here + // and when texturectrl picks a local texture + if (getBaseColorId() == old_id) + { + mBaseColorTextureCtrl->setValue(new_id); + } + if (mBaseColorTextureCtrl->getDefaultImageAssetID() == old_id) + { + mBaseColorTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getMetallicRoughnessId() == old_id) + { + mMetallicTextureCtrl->setValue(new_id); + } + if (mMetallicTextureCtrl->getDefaultImageAssetID() == old_id) + { + mMetallicTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getEmissiveId() == old_id) + { + mEmissiveTextureCtrl->setValue(new_id); + } + if (mEmissiveTextureCtrl->getDefaultImageAssetID() == old_id) + { + mEmissiveTextureCtrl->setDefaultImageAssetID(new_id); + } + + if (getNormalId() == old_id) + { + mNormalTextureCtrl->setValue(new_id); + } + if (mNormalTextureCtrl->getDefaultImageAssetID() == old_id) + { + mNormalTextureCtrl->setDefaultImageAssetID(new_id); + } +} + void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { if (!mIsOverride) @@ -911,6 +957,20 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + // Theoretically LLSD should be smart enough to not need this, but for extra safety + LLSD key = llsd_clone(getKey()); + // Subscribe material editor to local texture updates + mTextureChangesUpdates.push_back( + LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), + [this](const LLUUID &old_id, const LLUUID& new_id) + { + replaceTexture(old_id, new_id); + })); + } } markChangesUnsaved(dirty_flag); @@ -923,6 +983,17 @@ void LLMaterialEditor::onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ applyToSelection(); } +void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) +{ + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + mat->setHasLocalTextures(true); + // Todo: subscrive material for an update + // tex_ctrl->getLocalTrackingID(); + } +} + void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag) { mUnsavedChanges |= dirty_flag; @@ -958,21 +1029,25 @@ void LLMaterialEditor::onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_ case MATERIAL_BASE_COLOR_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setBaseColorId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setOcclusionRoughnessMetallicId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_EMISIVE_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setEmissiveId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } case MATERIAL_NORMAL_TEX_DIRTY: { nodep->mSavedGLTFOverrideMaterials[te]->setNormalId(mCtrl->getValue().asUUID(), true); + update_local_texture(mCtrl, nodep->mSavedGLTFOverrideMaterials[te].get()); break; } // Colors diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 1c40fcc348..4af68adce2 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -219,6 +219,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void setCanSave(bool value); void setEnableEditing(bool can_modify); + void replaceTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); @@ -306,5 +307,6 @@ private: static bool mOverrideInProgress; static bool mSelectionNeedsUpdate; boost::signals2::connection mSelectionUpdateSlot; + std::list mTextureChangesUpdates; }; diff --git a/indra/newview/llpanelprofile.cpp b/indra/newview/llpanelprofile.cpp index 1a4546875d..c2c9139c19 100644 --- a/indra/newview/llpanelprofile.cpp +++ b/indra/newview/llpanelprofile.cpp @@ -1959,7 +1959,7 @@ void LLPanelProfileSecondLife::onShowTexturePicker() mFloaterTexturePickerHandle = texture_floaterp->getHandle(); - texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&) + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&) { if (op == LLTextureCtrl::TEXTURE_SELECT) { @@ -2285,7 +2285,7 @@ void LLPanelProfileFirstLife::onChangePhoto() mFloaterTexturePickerHandle = texture_floaterp->getHandle(); - texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&) + texture_floaterp->setOnFloaterCommitCallback([this](LLTextureCtrl::ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID&, const LLUUID&) { if (op == LLTextureCtrl::TEXTURE_SELECT) { diff --git a/indra/newview/lltexturectrl.cpp b/indra/newview/lltexturectrl.cpp index 10667b02d9..3988bceb4e 100644 --- a/indra/newview/lltexturectrl.cpp +++ b/indra/newview/lltexturectrl.cpp @@ -846,6 +846,7 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) } LLUUID asset_id = mImageAssetID; LLUUID inventory_id; + LLUUID tracking_id; LLPickerSource mode = (LLPickerSource)mModeSelector->getValue().asInteger(); switch (mode) @@ -886,16 +887,16 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) if (!mLocalScrollCtrl->getAllSelected().empty()) { LLSD data = mLocalScrollCtrl->getFirstSelected()->getValue(); - LLUUID temp_id = data["id"]; + tracking_id = data["id"]; S32 asset_type = data["type"].asInteger(); if (LLAssetType::AT_MATERIAL == asset_type) { - asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(temp_id); + asset_id = LLLocalGLTFMaterialMgr::getInstance()->getWorldID(tracking_id); } else { - asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(temp_id); + asset_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); } } else @@ -912,13 +913,13 @@ void LLFloaterTexturePicker::commitCallback(LLTextureCtrl::ETexturePickOp op) break; } - mOnFloaterCommitCallback(op, mode, asset_id, inventory_id); + mOnFloaterCommitCallback(op, mode, asset_id, inventory_id, tracking_id); } void LLFloaterTexturePicker::commitCancel() { if (!mNoCopyTextureSelected && mOnFloaterCommitCallback && mCanApply) { - mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null); + mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, mOriginalImageAssetID, LLUUID::null, LLUUID::null); } } @@ -972,7 +973,7 @@ void LLFloaterTexturePicker::onBtnCancel(void* userdata) self->setImageID( self->mOriginalImageAssetID ); if (self->mOnFloaterCommitCallback) { - self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null); + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CANCEL, PICKER_UNKNOWN, self->mOriginalImageAssetID, LLUUID::null, LLUUID::null); } self->mViewModel->resetDirty(); self->closeFloater(); @@ -1177,7 +1178,7 @@ void LLFloaterTexturePicker::onLocalScrollCommit(LLUICtrl* ctrl, void* userdata) { if (self->mOnFloaterCommitCallback) { - self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null); + self->mOnFloaterCommitCallback(LLTextureCtrl::TEXTURE_CHANGE, PICKER_LOCAL, inworld_id, LLUUID::null, tracking_id); } } } @@ -1804,7 +1805,7 @@ void LLTextureCtrl::showPicker(BOOL take_focus) } if (texture_floaterp) { - texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4)); + texture_floaterp->setOnFloaterCommitCallback(boost::bind(&LLTextureCtrl::onFloaterCommit, this, _1, _2, _3, _4, _5)); } if (texture_floaterp) { @@ -1928,7 +1929,7 @@ void LLTextureCtrl::onFloaterClose() mFloaterHandle.markDead(); } -void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id) +void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& asset_id, const LLUUID& inv_id, const LLUUID& tracking_id) { LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); @@ -1951,16 +1952,23 @@ void LLTextureCtrl::onFloaterCommit(ETexturePickOp op, LLPickerSource source, co case PICKER_INVENTORY: mImageItemID = inv_id; mImageAssetID = asset_id; + mLocalTrackingID.setNull(); break; case PICKER_BAKE: + mImageItemID = LLUUID::null; + mImageAssetID = asset_id; + mLocalTrackingID.setNull(); + break; case PICKER_LOCAL: mImageItemID = LLUUID::null; mImageAssetID = asset_id; + mLocalTrackingID = tracking_id; break; case PICKER_UNKNOWN: default: mImageItemID = floaterp->findItemID(asset_id, FALSE); mImageAssetID = asset_id; + mLocalTrackingID.setNull(); break; } @@ -2018,6 +2026,7 @@ void LLTextureCtrl::setImageAssetID( const LLUUID& asset_id ) { mImageItemID.setNull(); mImageAssetID = asset_id; + mLocalTrackingID.setNull(); LLFloaterTexturePicker* floaterp = (LLFloaterTexturePicker*)mFloaterHandle.get(); if( floaterp && getEnabled() ) { diff --git a/indra/newview/lltexturectrl.h b/indra/newview/lltexturectrl.h index 180c4fa4b8..c47df5accb 100644 --- a/indra/newview/lltexturectrl.h +++ b/indra/newview/lltexturectrl.h @@ -200,7 +200,11 @@ public: void closeDependentFloater(); void onFloaterClose(); - void onFloaterCommit(ETexturePickOp op, LLPickerSource source, const LLUUID& local_id, const LLUUID& inv_id); + void onFloaterCommit(ETexturePickOp op, + LLPickerSource source, + const LLUUID& local_id, + const LLUUID& inv_id, + const LLUUID& tracking_id); // This call is returned when a drag is detected. Your callback // should return TRUE if the drag is acceptable. @@ -230,6 +234,9 @@ public: void setInventoryPickType(EPickInventoryType type); EPickInventoryType getInventoryPickType() { return mInventoryPickType; }; + bool isImageLocal() { return mLocalTrackingID.notNull(); } + LLUUID getLocalTrackingID() { return mLocalTrackingID; } + private: BOOL allowDrop(LLInventoryItem* item, EDragAndDropType cargo_type, std::string& tooltip_msg); BOOL doDrop(LLInventoryItem* item); @@ -247,6 +254,7 @@ private: LLUUID mImageAssetID; LLUUID mDefaultImageAssetID; LLUUID mBlankImageAssetID; + LLUUID mLocalTrackingID; LLUIImagePtr mFallbackImage; std::string mDefaultImageName; LLHandle mFloaterHandle; @@ -272,7 +280,7 @@ private: ////////////////////////////////////////////////////////////////////////////////////////// // LLFloaterTexturePicker -typedef boost::function floater_commit_callback; +typedef boost::function floater_commit_callback; typedef boost::function floater_close_callback; typedef boost::function set_image_asset_id_callback; typedef boost::function texture)> set_on_update_image_stats_callback; -- cgit v1.3 From 596a63051ebabfec51e48be02bbec33ab962d915 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 27 Oct 2023 23:41:13 +0300 Subject: SL-20523 Local textures not updating on PBR Materials #2 --- indra/llprimitive/llgltfmaterial.cpp | 46 ++++++++++++ indra/llprimitive/llgltfmaterial.h | 12 ++-- indra/newview/llfetchedgltfmaterial.cpp | 49 +++++++++++++ indra/newview/llfetchedgltfmaterial.h | 3 + indra/newview/lllocalbitmaps.cpp | 55 ++++++++++++++- indra/newview/lllocalbitmaps.h | 12 +++- indra/newview/llmaterialeditor.cpp | 121 +++++++++++++++++++++++++++----- indra/newview/llmaterialeditor.h | 13 +++- 8 files changed, 283 insertions(+), 28 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index f42c11ee21..6afd83904f 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -89,6 +89,11 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mOverrideDoubleSided = rhs.mOverrideDoubleSided; mOverrideAlphaMode = rhs.mOverrideAlphaMode; + mLocalTextureIds = rhs.mLocalTextureIds; + mLocalTextureTrackingIds = rhs.mLocalTextureTrackingIds; + + updateTextureTracking(); + return *this; } @@ -765,3 +770,44 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } +void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +{ + mLocalTextureTrackingIds.insert(tracking_id); + mLocalTextureIds.insert(tex_id); +} + +void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +{ + mLocalTextureTrackingIds.erase(tracking_id); + mLocalTextureIds.erase(tex_id); +} + +bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +{ + bool res = false; + + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (mTextureId[i] == old_id) + { + mTextureId[i] = new_id; + res = true; + } + } + + mLocalTextureIds.erase(old_id); + if (res) + { + mLocalTextureIds.insert(new_id); + } + + return res; +} + +void LLGLTFMaterial::updateTextureTracking() +{ + if (mLocalTextureTrackingIds.size() > 0) + { + LL_WARNS() << "copied a material with local textures, but tracking not implemented" << LL_ENDL; + } +} diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 548e2c52f4..d45ada1561 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -223,8 +223,14 @@ public: virtual void removeTextureEntry(LLTextureEntry* te) {}; // For local textures so that editor will know to track changes - void setHasLocalTextures(bool val) { mHasLocalTextures = val; } - bool hasLocalTextures() { return mHasLocalTextures; } + void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); + void removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id); + bool hasLocalTextures() { return !mLocalTextureIds.empty(); } + virtual bool replaceLocalTexture(const LLUUID &old_id, const LLUUID& new_id); + virtual void updateTextureTracking(); + + uuid_set_t mLocalTextureIds; + uuid_set_t mLocalTextureTrackingIds; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); @@ -242,6 +248,4 @@ protected: void writeToTexture(tinygltf::Model& model, T& texture_info, TextureInfo texture_info_id, bool force_write = false) const; template static void writeToTexture(tinygltf::Model& model, T& texture_info, const LLUUID& texture_id, const TextureTransform& transform, bool force_write = false); - - bool mHasLocalTextures; }; diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index fc9d42bfb6..71a961ce49 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -144,6 +144,55 @@ void LLFetchedGLTFMaterial::bind(LLViewerTexture* media_tex) } +LLViewerFetchedTexture* fetch_texture(const LLUUID& id) +{ + LLViewerFetchedTexture* img = nullptr; + if (id.notNull()) + { + img = LLViewerTextureManager::getFetchedTexture(id, FTT_DEFAULT, TRUE, LLGLTexture::BOOST_NONE, LLViewerTexture::LOD_TEXTURE); + img->addTextureStats(64.f * 64.f, TRUE); + } + return img; +}; + +bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +{ + bool res = false; + if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] == old_id) + { + mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = new_id; + mBaseColorTexture = fetch_texture(new_id); + res = true; + } + if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] == old_id) + { + mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = new_id; + mNormalTexture = fetch_texture(new_id); + res = true; + } + if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] == old_id) + { + mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = new_id; + mMetallicRoughnessTexture = fetch_texture(new_id); + res = true; + } + if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] == old_id) + { + mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = new_id; + mEmissiveTexture = fetch_texture(new_id); + res = true; + } + return res; +} + +void LLFetchedGLTFMaterial::updateTextureTracking() +{ + for (const LLUUID& id : mLocalTextureTrackingIds) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(id, this); + } +} + void LLFetchedGLTFMaterial::materialBegin() { llassert(!mFetching); diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 1668657281..02426bf088 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,6 +50,9 @@ public: bool isFetching() const { return mFetching; } + virtual bool replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) override; + virtual void updateTextureTracking() override; + // Textures used for fetching/rendering LLPointer mBaseColorTexture; LLPointer mNormalTexture; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 6f1e4c9419..88de575f91 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -46,6 +46,7 @@ #include /* misc headers */ +#include "llgltfmaterial.h" #include "llscrolllistctrl.h" #include "lllocaltextureobject.h" #include "llviewertexturelist.h" @@ -131,6 +132,14 @@ LLLocalBitmap::~LLLocalBitmap() LLLocalBitmapMgr::getInstance()->doRebake(); } + for (LLPointer &mat : mGLTFMaterialWithLocalTextures) + { + mat->removeLocalTextureTracking(getTrackingID(), getWorldID()); + } + + mChangedSignal(getTrackingID(), getWorldID(), LLUUID()); + mChangedSignal.disconnect_all_slots(); + // delete self from gimagelist LLViewerFetchedTexture* image = gTextureList.findImage(mWorldID, TEX_LIST_STANDARD); gTextureList.deleteImage(image); @@ -278,6 +287,17 @@ boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextu return mChangedSignal.connect(cb); } +void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) +{ + if (mat + // dupplicate prevention + && mat->mLocalTextureTrackingIds.find(getTrackingID()) == mat->mLocalTextureTrackingIds.end()) + { + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); + } +} + bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) { bool decode_successful = false; @@ -355,7 +375,7 @@ void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id) return; } - mChangedSignal(old_id, new_id); + mChangedSignal(getTrackingID(), old_id, new_id); // processing updates per channel; makes the process scalable. // the only actual difference is in SetTE* call i.e. SetTETexture, SetTENormal, etc. @@ -389,8 +409,7 @@ void LLLocalBitmap::replaceIDs(const LLUUID& old_id, LLUUID new_id) updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERPANTS); updateUserLayers(old_id, new_id, LLWearableType::WT_UNDERSHIRT); - // Go over any local material - + updateGLTFMaterials(old_id, new_id); } // this function sorts the faces from a getFaceList[getNumFaces] into a list of objects @@ -588,6 +607,24 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp } } +void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) +{ + // Might be a better idea to hold this in LLGLTFMaterialList + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) + { + if ((*it)->replaceLocalTexture(old_id, new_id)) + { + ++it; + } + else + { + // matching id not found, no longer in use + (*it)->removeLocalTextureTracking(getTrackingID(), new_id); + it = mGLTFMaterialWithLocalTextures.erase(it); + } + } +} + LLAvatarAppearanceDefines::ETextureIndex LLLocalBitmap::getTexIndex( LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind) { @@ -1089,6 +1126,18 @@ boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID return boost::signals2::connection(); } +void LLLocalBitmapMgr::associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat) +{ + for (local_list_iter iter = mBitmapList.begin(); iter != mBitmapList.end(); iter++) + { + LLLocalBitmap* unit = *iter; + if (unit->getTrackingID() == tracking_id) + { + unit->addGLTFMaterial(mat); + } + } +} + void LLLocalBitmapMgr::feedScrollList(LLScrollListCtrl* ctrl) { if (ctrl) diff --git a/indra/newview/lllocalbitmaps.h b/indra/newview/lllocalbitmaps.h index f36fd6d320..1fdf9dccbf 100644 --- a/indra/newview/lllocalbitmaps.h +++ b/indra/newview/lllocalbitmaps.h @@ -36,6 +36,7 @@ class LLScrollListCtrl; class LLImageRaw; class LLViewerObject; +class LLGLTFMaterial; class LLLocalBitmap { @@ -59,10 +60,12 @@ class LLLocalBitmap bool updateSelf(EUpdateType = UT_REGUPDATE); - typedef boost::signals2::signal LLLocalTextureChangedSignal; typedef LLLocalTextureChangedSignal::slot_type LLLocalTextureCallback; boost::signals2::connection setChangedCallback(const LLLocalTextureCallback& cb); + void addGLTFMaterial(LLGLTFMaterial* mat); private: /* self update private section */ bool decodeBitmap(LLPointer raw); @@ -71,6 +74,7 @@ class LLLocalBitmap void updateUserPrims(LLUUID old_id, LLUUID new_id, U32 channel); void updateUserVolumes(LLUUID old_id, LLUUID new_id, U32 channel); void updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableType::EType type); + void updateGLTFMaterials(LLUUID old_id, LLUUID new_id); LLAvatarAppearanceDefines::ETextureIndex getTexIndex(LLWearableType::EType type, LLAvatarAppearanceDefines::EBakedTextureIndex baked_texind); private: /* private enums */ @@ -100,6 +104,11 @@ class LLLocalBitmap S32 mUpdateRetries; LLLocalTextureChangedSignal mChangedSignal; + // Store a list of accosiated materials + // Might be a better idea to hold this in LLGLTFMaterialList + typedef std::vector > mat_list_t; + mat_list_t mGLTFMaterialWithLocalTextures; + }; class LLLocalBitmapTimer : public LLEventTimer @@ -130,6 +139,7 @@ public: bool isLocal(const LLUUID& world_id) const; std::string getFilename(const LLUUID &tracking_id) const; boost::signals2::connection setOnChangedCallback(const LLUUID tracking_id, const LLLocalBitmap::LLLocalTextureCallback& cb); + void associateGLTFMaterial(const LLUUID tracking_id, LLGLTFMaterial* mat); void feedScrollList(LLScrollListCtrl* ctrl); void doUpdates(); diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 63d86cda61..b8e34b7409 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -363,6 +363,15 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) } } +LLMaterialEditor::~LLMaterialEditor() +{ + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); +} + void LLMaterialEditor::setObjectID(const LLUUID& object_id) { LLPreview::setObjectID(object_id); @@ -532,11 +541,6 @@ void LLMaterialEditor::onClose(bool app_quitting) mSelectionUpdateSlot.disconnect(); } - for (boost::signals2::connection& cn : mTextureChangesUpdates) - { - cn.disconnect(); - } - LLPreview::onClose(app_quitting); } @@ -866,7 +870,27 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) mNormalTextureCtrl->setEnabled(can_modify); } -void LLMaterialEditor::replaceTexture(const LLUUID& old_id, const LLUUID& new_id) +void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) +{ + LocalTextureConnection info; + info.mTrackingId = tracking_id; + info.mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, + [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) + { + if (new_id.isNull()) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + mTextureChangesUpdates.erase(dirty_flag); + } + else + { + replaceLocalTexture(old_id, new_id); + } + }); + mTextureChangesUpdates[dirty_flag] = info; +} + +void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here // and when texturectrl picks a local texture @@ -958,18 +982,17 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + // unsubcribe potential old callabck + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); + if (found != mTextureChangesUpdates.end()) + { + found->second.mConnection.disconnect(); + } + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - // Theoretically LLSD should be smart enough to not need this, but for extra safety - LLSD key = llsd_clone(getKey()); - // Subscribe material editor to local texture updates - mTextureChangesUpdates.push_back( - LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tex_ctrl->getLocalTrackingID(), - [this](const LLUUID &old_id, const LLUUID& new_id) - { - replaceTexture(old_id, new_id); - })); + subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); } } @@ -988,9 +1011,8 @@ void update_local_texture(LLUICtrl* ctrl, LLGLTFMaterial* mat) LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; if (tex_ctrl->isImageLocal()) { - mat->setHasLocalTextures(true); - // Todo: subscrive material for an update - // tex_ctrl->getLocalTrackingID(); + // subscrive material to updates of local textures + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tex_ctrl->getLocalTrackingID(), mat); } } @@ -1465,6 +1487,20 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L { me->refreshFromInventory(itemId); } + + if (me && !me->mTextureChangesUpdates.empty()) + { + const LLInventoryItem* item = me->getItem(); + if (item) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } + } } } @@ -1479,6 +1515,16 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID me->setAssetId(newAssetId); me->refreshFromInventory(); me->setEnabled(true); + + if (me && !me->mTextureChangesUpdates.empty()) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } } } @@ -1512,6 +1558,17 @@ void LLMaterialEditor::finishSaveAs( { me->loadAsset(); me->setEnabled(true); + + // Local texure support + if (!me->mTextureChangesUpdates.empty()) + { + // local materials were assigned, force load material and init tracking + LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); + for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); + } + } } } else if(has_unsaved_changes) @@ -2975,6 +3032,34 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setDoubleSided(mat->mDoubleSided); setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); + + + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); + + for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + { + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + } + } } bool LLMaterialEditor::setFromSelection() diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index 4af68adce2..fd8b259a1a 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -87,6 +87,7 @@ protected: class LLMaterialEditor : public LLPreview, public LLVOInventoryListener { public: LLMaterialEditor(const LLSD& key); + ~LLMaterialEditor(); bool setFromGltfModel(const tinygltf::Model& model, S32 index, bool set_textures = false); @@ -219,7 +220,8 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener void setCanSave(bool value); void setEnableEditing(bool can_modify); - void replaceTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support + void subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id); + void replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id); // Local texture support void onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); void onCancelCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); void onSelectCtrl(LLUICtrl* ctrl, const LLSD& data, S32 dirty_flag); @@ -307,6 +309,13 @@ private: static bool mOverrideInProgress; static bool mSelectionNeedsUpdate; boost::signals2::connection mSelectionUpdateSlot; - std::list mTextureChangesUpdates; + + struct LocalTextureConnection + { + LLUUID mTrackingId; + boost::signals2::connection mConnection; + }; + typedef std::map mat_connection_map_t; + mat_connection_map_t mTextureChangesUpdates; }; -- cgit v1.3 From 3a5b678eba5d86acccb1a1f233f862d292258fac Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Mon, 30 Oct 2023 23:56:33 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #3 --- indra/llprimitive/llgltfmaterial.cpp | 9 ++++++ indra/llprimitive/llgltfmaterial.h | 5 ++-- indra/newview/lllocalbitmaps.cpp | 26 +++++++++++++++- indra/newview/llmaterialeditor.cpp | 58 +++++++++++++++++++----------------- 4 files changed, 68 insertions(+), 30 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 6afd83904f..e590b14656 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -770,6 +770,15 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } +void LLGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.insert(te); +} +void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.erase(te); +} + void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { mLocalTextureTrackingIds.insert(tracking_id); diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index d45ada1561..2a9ef3ffe0 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -219,8 +219,8 @@ public: // For local materials, they have to keep track of where // they are assigned to for full updates - virtual void addTextureEntry(LLTextureEntry* te) {}; - virtual void removeTextureEntry(LLTextureEntry* te) {}; + virtual void addTextureEntry(LLTextureEntry* te); + virtual void removeTextureEntry(LLTextureEntry* te); // For local textures so that editor will know to track changes void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); @@ -231,6 +231,7 @@ public: uuid_set_t mLocalTextureIds; uuid_set_t mLocalTextureTrackingIds; + std::set mTextureEntires; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 88de575f91..6775685a6a 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -614,6 +614,30 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) { if ((*it)->replaceLocalTexture(old_id, new_id)) { + for (LLTextureEntry* entry : (*it)->mTextureEntires) + { + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + if (override_mat) + { + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) + { + llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); + LLFetchedGLTFMaterial *fetched_mat = dynamic_cast((*it).get()); + if (fetched_mat) + { + *render_mat = *fetched_mat; + } + render_mat->applyOverride(*override_mat); + } + } + } ++it; } else @@ -1119,7 +1143,7 @@ boost::signals2::connection LLLocalBitmapMgr::setOnChangedCallback(const LLUUID LLLocalBitmap* unit = *iter; if (unit->getTrackingID() == tracking_id) { - unit->setChangedCallback(cb); + return unit->setChangedCallback(cb); } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index b8e34b7409..836ea5c869 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -365,11 +365,6 @@ LLMaterialEditor::LLMaterialEditor(const LLSD& key) LLMaterialEditor::~LLMaterialEditor() { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); } void LLMaterialEditor::setObjectID(const LLUUID& object_id) @@ -540,6 +535,11 @@ void LLMaterialEditor::onClose(bool app_quitting) { mSelectionUpdateSlot.disconnect(); } + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + { + cn.second.mConnection.disconnect(); + } + mTextureChangesUpdates.clear(); LLPreview::onClose(app_quitting); } @@ -872,22 +872,24 @@ void LLMaterialEditor::setEnableEditing(bool can_modify) void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tracking_id) { - LocalTextureConnection info; - info.mTrackingId = tracking_id; - info.mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, - [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) - { - if (new_id.isNull()) - { - mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); - mTextureChangesUpdates.erase(dirty_flag); - } - else - { - replaceLocalTexture(old_id, new_id); - } - }); - mTextureChangesUpdates[dirty_flag] = info; + if (mTextureChangesUpdates[dirty_flag].mTrackingId != tracking_id) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + mTextureChangesUpdates[dirty_flag].mTrackingId = tracking_id; + mTextureChangesUpdates[dirty_flag].mConnection = LLLocalBitmapMgr::getInstance()->setOnChangedCallback(tracking_id, + [this, dirty_flag](const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) + { + if (new_id.isNull()) + { + mTextureChangesUpdates[dirty_flag].mConnection.disconnect(); + //mTextureChangesUpdates.erase(dirty_flag); + } + else + { + replaceLocalTexture(old_id, new_id); + } + }); + } } void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) @@ -981,19 +983,21 @@ void LLMaterialEditor::onCommitTexture(LLUICtrl* ctrl, const LLSD& data, S32 dir // the texture that is not in use childSetValue(upload_fee_ctrl_name, getString("no_upload_fee_string")); } + } + LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; + if (tex_ctrl->isImageLocal()) + { + subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); + } + else + { // unsubcribe potential old callabck mat_connection_map_t::iterator found = mTextureChangesUpdates.find(dirty_flag); if (found != mTextureChangesUpdates.end()) { found->second.mConnection.disconnect(); } - - LLTextureCtrl* tex_ctrl = (LLTextureCtrl*)ctrl; - if (tex_ctrl->isImageLocal()) - { - subscribeToLocalTexture(dirty_flag, tex_ctrl->getLocalTrackingID()); - } } markChangesUnsaved(dirty_flag); -- cgit v1.3 From 52c60ab3fdb8617471eccd9df52cc126e0243e76 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 00:33:39 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #4 --- indra/llprimitive/llgltfmaterial.cpp | 27 ++++---- indra/llprimitive/llgltfmaterial.h | 12 ++-- indra/newview/llfetchedgltfmaterial.cpp | 23 ++++++- indra/newview/llfetchedgltfmaterial.h | 3 +- indra/newview/lllocalbitmaps.cpp | 23 ++++--- indra/newview/llmaterialeditor.cpp | 115 ++++++++++++++++++++++++++++---- indra/newview/llmaterialeditor.h | 1 + indra/newview/llviewerobject.cpp | 8 +++ 8 files changed, 167 insertions(+), 45 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index e590b14656..3945be3254 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -89,8 +89,7 @@ LLGLTFMaterial& LLGLTFMaterial::operator=(const LLGLTFMaterial& rhs) mOverrideDoubleSided = rhs.mOverrideDoubleSided; mOverrideAlphaMode = rhs.mOverrideAlphaMode; - mLocalTextureIds = rhs.mLocalTextureIds; - mLocalTextureTrackingIds = rhs.mLocalTextureTrackingIds; + mTrackingIdToLocalTexture = rhs.mTrackingIdToLocalTexture; updateTextureTracking(); @@ -606,6 +605,8 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) mTextureTransform[i].mRotation = override_mat.mTextureTransform[i].mRotation; } } + + mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin()); } void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) @@ -781,17 +782,15 @@ void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { - mLocalTextureTrackingIds.insert(tracking_id); - mLocalTextureIds.insert(tex_id); + mTrackingIdToLocalTexture[tracking_id] = tex_id; } -void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) +void LLGLTFMaterial::removeLocalTextureTracking(const LLUUID& tracking_id) { - mLocalTextureTrackingIds.erase(tracking_id); - mLocalTextureIds.erase(tex_id); + mTrackingIdToLocalTexture.erase(tracking_id); } -bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) { bool res = false; @@ -804,10 +803,13 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new } } - mLocalTextureIds.erase(old_id); if (res) { - mLocalTextureIds.insert(new_id); + mTrackingIdToLocalTexture[tracking_id] = new_id; + } + else + { + mTrackingIdToLocalTexture.erase(tracking_id); } return res; @@ -815,8 +817,5 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new void LLGLTFMaterial::updateTextureTracking() { - if (mLocalTextureTrackingIds.size() > 0) - { - LL_WARNS() << "copied a material with local textures, but tracking not implemented" << LL_ENDL; - } + // setTEGLTFMaterialOverride is responsible for tracking } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 2a9ef3ffe0..7b38663307 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -196,7 +196,7 @@ public: // write to given tinygltf::Model void writeToModel(tinygltf::Model& model, S32 mat_index) const; - void applyOverride(const LLGLTFMaterial& override_mat); + virtual void applyOverride(const LLGLTFMaterial& override_mat); // apply the given LLSD override data void applyOverrideLLSD(const LLSD& data); @@ -224,13 +224,13 @@ public: // For local textures so that editor will know to track changes void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); - void removeLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id); - bool hasLocalTextures() { return !mLocalTextureIds.empty(); } - virtual bool replaceLocalTexture(const LLUUID &old_id, const LLUUID& new_id); + void removeLocalTextureTracking(const LLUUID& tracking_id); + bool hasLocalTextures() { return !mTrackingIdToLocalTexture.empty(); } + virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); virtual void updateTextureTracking(); - uuid_set_t mLocalTextureIds; - uuid_set_t mLocalTextureTrackingIds; + typedef std::map local_tex_map_t; + local_tex_map_t mTrackingIdToLocalTexture; std::set mTextureEntires; protected: diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index 71a961ce49..c61b25f0a2 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -155,7 +155,14 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id) return img; }; -bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) +void LLFetchedGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) +{ + LLGLTFMaterial::applyOverride(override_mat); + + updateTextureTracking(); +} + +bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) { bool res = false; if (mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] == old_id) @@ -182,14 +189,24 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& old_id, const LLUU mEmissiveTexture = fetch_texture(new_id); res = true; } + + if (res) + { + mTrackingIdToLocalTexture[tracking_id] = new_id; + } + else + { + mTrackingIdToLocalTexture.erase(tracking_id); + } + return res; } void LLFetchedGLTFMaterial::updateTextureTracking() { - for (const LLUUID& id : mLocalTextureTrackingIds) + for (local_tex_map_t::value_type val : mTrackingIdToLocalTexture) { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(id, this); + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this); } } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index 02426bf088..d778966c22 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,7 +50,8 @@ public: bool isFetching() const { return mFetching; } - virtual bool replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) override; + void applyOverride(const LLGLTFMaterial& override_mat) override; + virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override; virtual void updateTextureTracking() override; // Textures used for fetching/rendering diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 6775685a6a..cd5b2e262b 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -134,7 +134,7 @@ LLLocalBitmap::~LLLocalBitmap() for (LLPointer &mat : mGLTFMaterialWithLocalTextures) { - mat->removeLocalTextureTracking(getTrackingID(), getWorldID()); + mat->removeLocalTextureTracking(getTrackingID()); } mChangedSignal(getTrackingID(), getWorldID(), LLUUID()); @@ -289,12 +289,17 @@ boost::signals2::connection LLLocalBitmap::setChangedCallback(const LLLocalTextu void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) { - if (mat - // dupplicate prevention - && mat->mLocalTextureTrackingIds.find(getTrackingID()) == mat->mLocalTextureTrackingIds.end()) + if (!mat) { - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); - mGLTFMaterialWithLocalTextures.push_back(mat); + return; + } + for (mat_list_t::value_type ptr : mGLTFMaterialWithLocalTextures) + { + if (ptr.get() != mat) + { + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); + } } } @@ -612,7 +617,7 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Might be a better idea to hold this in LLGLTFMaterialList for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) { - if ((*it)->replaceLocalTexture(old_id, new_id)) + if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { for (LLTextureEntry* entry : (*it)->mTextureEntires) { @@ -642,8 +647,8 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) } else { - // matching id not found, no longer in use - (*it)->removeLocalTextureTracking(getTrackingID(), new_id); + // Matching id not found, no longer in use + // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 836ea5c869..1b606b0311 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -892,6 +892,16 @@ void LLMaterialEditor::subscribeToLocalTexture(S32 dirty_flag, const LLUUID& tra } } +LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) +{ + mat_connection_map_t::iterator found = mTextureChangesUpdates.find(flag); + if (found != mTextureChangesUpdates.end()) + { + return found->second.mTrackingId; + } + return LLUUID(); +} + void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here @@ -2827,28 +2837,58 @@ public: if (changed_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) { material->setBaseColorId(mEditor->getBaseColorId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_BASE_COLOR_TEX_DIRTY) && revert_mat.notNull()) { material->setBaseColorId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_BASE_COLOR_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_NORMAL_TEX_DIRTY) { material->setNormalId(mEditor->getNormalId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_NORMAL_TEX_DIRTY) && revert_mat.notNull()) { material->setNormalId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_NORMAL_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) { material->setOcclusionRoughnessMetallicId(mEditor->getMetallicRoughnessId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY) && revert_mat.notNull()) { material->setOcclusionRoughnessMetallicId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_METALLIC_ROUGHTNESS_METALNESS_DIRTY) @@ -2881,10 +2921,20 @@ public: if (changed_flags & MATERIAL_EMISIVE_TEX_DIRTY) { material->setEmissiveId(mEditor->getEmissiveId(), true); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } else if ((reverted_flags & MATERIAL_EMISIVE_TEX_DIRTY) && revert_mat.notNull()) { material->setEmissiveId(revert_mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE], false); + LLUUID tracking_id = mEditor->getLocalTextureTrackingIdFromFlag(MATERIAL_EMISIVE_TEX_DIRTY); + if (tracking_id.notNull()) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(tracking_id, material); + } } if (changed_flags & MATERIAL_DOUBLE_SIDED_DIRTY) @@ -3044,24 +3094,65 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } mTextureChangesUpdates.clear(); - for (const LLUUID& tracking_id : mat->mLocalTextureTrackingIds) + if (mat->hasLocalTextures()) { - LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(tracking_id); - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) - { - subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, tracking_id); - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, tracking_id); + cn.second.mConnection.disconnect(); } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + mTextureChangesUpdates.clear(); + + for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) { - subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, tracking_id); + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); + if (val.second != world_id) + { + LL_WARNS() << "world id mismatch" << LL_ENDL; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + subscribeToLocalTexture(MATERIAL_BASE_COLOR_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + subscribeToLocalTexture(MATERIAL_METALLIC_ROUGHTNESS_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + subscribeToLocalTexture(MATERIAL_EMISIVE_TEX_DIRTY, val.first); + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, val.first); + } } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + } + else + { + for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) { - subscribeToLocalTexture(MATERIAL_NORMAL_TEX_DIRTY, tracking_id); + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + continue; + } + cn.second.mConnection.disconnect(); } } } diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index fd8b259a1a..e6939098e0 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -231,6 +231,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener U32 getUnsavedChangesFlags() { return mUnsavedChanges; } U32 getRevertedChangesFlags() { return mRevertedChanges; } + LLUUID getLocalTextureTrackingIdFromFlag(U32 flag); static bool capabilitiesAvailable(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 3b5b986725..8228775596 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5482,6 +5482,14 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma } } + if (retval == TEM_CHANGE_TEXTURE) + { + for (LLGLTFMaterial::local_tex_map_t::value_type val : override_mat->mTrackingIdToLocalTexture) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); + } + } + return retval; } -- cgit v1.3 From 0d8893822d8975194313e940914afc8945754a21 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 2 Nov 2023 23:49:55 +0200 Subject: SL-20523 Local textures not updating on PBR Materials #5 --- indra/llprimitive/llgltfmaterial.cpp | 12 +-- indra/llprimitive/llgltfmaterial.h | 6 +- indra/newview/llfetchedgltfmaterial.cpp | 19 +++-- indra/newview/llfetchedgltfmaterial.h | 5 +- indra/newview/lllocalbitmaps.cpp | 69 +++++++++++------ indra/newview/lllocalgltfmaterials.cpp | 9 --- indra/newview/lllocalgltfmaterials.h | 4 - indra/newview/llmaterialeditor.cpp | 130 +++++++++++++++++++++----------- indra/newview/llmaterialeditor.h | 1 + indra/newview/llviewerobject.cpp | 13 ++-- 10 files changed, 158 insertions(+), 110 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 3945be3254..390110b0ec 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -607,6 +607,8 @@ void LLGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) } mTrackingIdToLocalTexture.insert(override_mat.mTrackingIdToLocalTexture.begin(), override_mat.mTrackingIdToLocalTexture.begin()); + + updateTextureTracking(); } void LLGLTFMaterial::getOverrideLLSD(const LLGLTFMaterial& override_mat, LLSD& data) @@ -771,15 +773,6 @@ LLUUID LLGLTFMaterial::getHash() const return hash; } -void LLGLTFMaterial::addTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.insert(te); -} -void LLGLTFMaterial::removeTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.erase(te); -} - void LLGLTFMaterial::addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID& tex_id) { mTrackingIdToLocalTexture[tracking_id] = tex_id; @@ -818,4 +811,5 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID void LLGLTFMaterial::updateTextureTracking() { // setTEGLTFMaterialOverride is responsible for tracking + // for material overrides editor will set it } diff --git a/indra/llprimitive/llgltfmaterial.h b/indra/llprimitive/llgltfmaterial.h index 7b38663307..02f62fb08c 100644 --- a/indra/llprimitive/llgltfmaterial.h +++ b/indra/llprimitive/llgltfmaterial.h @@ -219,8 +219,8 @@ public: // For local materials, they have to keep track of where // they are assigned to for full updates - virtual void addTextureEntry(LLTextureEntry* te); - virtual void removeTextureEntry(LLTextureEntry* te); + virtual void addTextureEntry(LLTextureEntry* te) {}; + virtual void removeTextureEntry(LLTextureEntry* te) {}; // For local textures so that editor will know to track changes void addLocalTextureTracking(const LLUUID& tracking_id, const LLUUID &tex_id); @@ -229,9 +229,9 @@ public: virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID &old_id, const LLUUID& new_id); virtual void updateTextureTracking(); + // These fields are local to viewer and are a part of local bitmap support typedef std::map local_tex_map_t; local_tex_map_t mTrackingIdToLocalTexture; - std::set mTextureEntires; protected: static LLVector2 vec2FromJson(const std::map& object, const char* key, const LLVector2& default_value); diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index c61b25f0a2..a47b52fddc 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -155,13 +155,6 @@ LLViewerFetchedTexture* fetch_texture(const LLUUID& id) return img; }; -void LLFetchedGLTFMaterial::applyOverride(const LLGLTFMaterial& override_mat) -{ - LLGLTFMaterial::applyOverride(override_mat); - - updateTextureTracking(); -} - bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) { bool res = false; @@ -202,9 +195,19 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const return res; } +void LLFetchedGLTFMaterial::addTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.insert(te); +} + +void LLFetchedGLTFMaterial::removeTextureEntry(LLTextureEntry* te) +{ + mTextureEntires.erase(te); +} + void LLFetchedGLTFMaterial::updateTextureTracking() { - for (local_tex_map_t::value_type val : mTrackingIdToLocalTexture) + for (local_tex_map_t::value_type &val : mTrackingIdToLocalTexture) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, this); } diff --git a/indra/newview/llfetchedgltfmaterial.h b/indra/newview/llfetchedgltfmaterial.h index d778966c22..2559aa46cc 100644 --- a/indra/newview/llfetchedgltfmaterial.h +++ b/indra/newview/llfetchedgltfmaterial.h @@ -50,7 +50,8 @@ public: bool isFetching() const { return mFetching; } - void applyOverride(const LLGLTFMaterial& override_mat) override; + void addTextureEntry(LLTextureEntry* te) override; + void removeTextureEntry(LLTextureEntry* te) override; virtual bool replaceLocalTexture(const LLUUID& tracking_id, const LLUUID& old_id, const LLUUID& new_id) override; virtual void updateTextureTracking() override; @@ -60,6 +61,8 @@ public: LLPointer mMetallicRoughnessTexture; LLPointer mEmissiveTexture; + std::set mTextureEntires; + protected: // Lifetime management diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index cd5b2e262b..4121df4bac 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -293,14 +293,28 @@ void LLLocalBitmap::addGLTFMaterial(LLGLTFMaterial* mat) { return; } - for (mat_list_t::value_type ptr : mGLTFMaterialWithLocalTextures) + + mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) { - if (ptr.get() != mat) + if (it->get() == mat) + { + return; + } + + if ((*it)->getNumRefs() == 1) + { + it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); + } + else { - mat->addLocalTextureTracking(getTrackingID(), getWorldID()); - mGLTFMaterialWithLocalTextures.push_back(mat); + it++; } } + + mat->addLocalTextureTracking(getTrackingID(), getWorldID()); + mGLTFMaterialWithLocalTextures.push_back(mat); } bool LLLocalBitmap::decodeBitmap(LLPointer rawimg) @@ -615,31 +629,41 @@ void LLLocalBitmap::updateUserLayers(LLUUID old_id, LLUUID new_id, LLWearableTyp void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) { // Might be a better idea to hold this in LLGLTFMaterialList - for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != mGLTFMaterialWithLocalTextures.end();) + mat_list_t::iterator end = mGLTFMaterialWithLocalTextures.end(); + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) { - if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) + if ((*it)->getNumRefs() == 1) + { + // render and override materials are often recreated, + // clean up any remains + it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); + } + else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { - for (LLTextureEntry* entry : (*it)->mTextureEntires) + LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get()); + if (fetched_mat) { - // Normally a change in applied material id is supposed to - // drop overrides thus reset material, but local materials - // currently reuse their existing asset id, and purpose is - // to preview how material will work in-world, overrides - // included, so do an override to render update instead. - LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); - if (override_mat) + for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); - if (render_mat) + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + if (override_mat) { - llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); - LLFetchedGLTFMaterial *fetched_mat = dynamic_cast((*it).get()); - if (fetched_mat) + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) { - *render_mat = *fetched_mat; + llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); + { + *render_mat = *fetched_mat; + } + render_mat->applyOverride(*override_mat); } - render_mat->applyOverride(*override_mat); } } } @@ -650,6 +674,7 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) // Matching id not found, no longer in use // material would clean itself, remove from the list it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); } } } diff --git a/indra/newview/lllocalgltfmaterials.cpp b/indra/newview/lllocalgltfmaterials.cpp index b7fdead3f9..61e0163798 100644 --- a/indra/newview/lllocalgltfmaterials.cpp +++ b/indra/newview/lllocalgltfmaterials.cpp @@ -119,15 +119,6 @@ S32 LLLocalGLTFMaterial::getIndexInFile() const return mMaterialIndex; } -void LLLocalGLTFMaterial::addTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.insert(te); -} -void LLLocalGLTFMaterial::removeTextureEntry(LLTextureEntry* te) -{ - mTextureEntires.erase(te); -} - /* update functions */ bool LLLocalGLTFMaterial::updateSelf() { diff --git a/indra/newview/lllocalgltfmaterials.h b/indra/newview/lllocalgltfmaterials.h index 1442b83a40..13b7577e96 100644 --- a/indra/newview/lllocalgltfmaterials.h +++ b/indra/newview/lllocalgltfmaterials.h @@ -49,9 +49,6 @@ public: /* accessors */ LLUUID getWorldID() const; S32 getIndexInFile() const; - void addTextureEntry(LLTextureEntry* te) override; - void removeTextureEntry(LLTextureEntry* te) override; - public: bool updateSelf(); @@ -81,7 +78,6 @@ private: /* members */ ELinkStatus mLinkStatus; S32 mUpdateRetries; S32 mMaterialIndex; // Single file can have more than one - std::set mTextureEntires; }; class LLLocalGLTFMaterialTimer : public LLEventTimer diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 1b606b0311..7d1ac32282 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -343,6 +343,39 @@ bool LLSelectedTEGetMatData::apply(LLViewerObject* objectp, S32 te_index) return false; } +class LLSelectedTEUpdateOverrides: public LLSelectedNodeFunctor +{ +public: + LLSelectedTEUpdateOverrides(LLMaterialEditor* me) : mEditor(me) {} + + virtual bool apply(LLSelectNode* nodep); + + LLMaterialEditor* mEditor; +}; + +bool LLSelectedTEUpdateOverrides::apply(LLSelectNode* nodep) +{ + LLViewerObject* objectp = nodep->getObject(); + if (!objectp) + { + return false; + } + S32 num_tes = llmin((S32)objectp->getNumTEs(), (S32)objectp->getNumFaces()); // avatars have TEs but no faces + for (S32 te_index = 0; te_index < num_tes; ++te_index) + { + + LLTextureEntry* tep = objectp->getTE(te_index); + LLGLTFMaterial* override_mat = tep->getGLTFMaterialOverride(); + if (mEditor->updateMaterialLocalSubscription(override_mat)) + { + LLGLTFMaterial* render_mat = tep->getGLTFRenderMaterial(); + mEditor->updateMaterialLocalSubscription(render_mat); + } + } + + return true; +} + ///---------------------------------------------------------------------------- /// Class LLMaterialEditor ///---------------------------------------------------------------------------- @@ -535,7 +568,7 @@ void LLMaterialEditor::onClose(bool app_quitting) { mSelectionUpdateSlot.disconnect(); } - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) + for (mat_connection_map_t::value_type &cn : mTextureChangesUpdates) { cn.second.mConnection.disconnect(); } @@ -902,6 +935,45 @@ LLUUID LLMaterialEditor::getLocalTextureTrackingIdFromFlag(U32 flag) return LLUUID(); } +bool LLMaterialEditor::updateMaterialLocalSubscription(LLGLTFMaterial* mat) +{ + if (!mat) + { + return false; + } + + bool res = false; + for (mat_connection_map_t::value_type& cn : mTextureChangesUpdates) + { + LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); + res = true; + continue; + } + } + return res; +} + void LLMaterialEditor::replaceLocalTexture(const LLUUID& old_id, const LLUUID& new_id) { // todo: might be a good idea to set mBaseColorTextureUploadId here @@ -1509,7 +1581,7 @@ void LLMaterialEditor::finishInventoryUpload(LLUUID itemId, LLUUID newAssetId, L { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1534,7 +1606,7 @@ void LLMaterialEditor::finishTaskUpload(LLUUID itemId, LLUUID newAssetId, LLUUID { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(newAssetId); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -1578,7 +1650,7 @@ void LLMaterialEditor::finishSaveAs( { // local materials were assigned, force load material and init tracking LLGLTFMaterial* mat = gGLTFMaterialList.getMaterial(item->getAssetUUID()); - for (mat_connection_map_t::value_type val : me->mTextureChangesUpdates) + for (mat_connection_map_t::value_type &val : me->mTextureChangesUpdates) { LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.second.mTrackingId, mat); } @@ -3087,22 +3159,9 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) setAlphaMode(mat->getAlphaMode()); setAlphaCutoff(mat->mAlphaCutoff); - - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - if (mat->hasLocalTextures()) { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - cn.second.mConnection.disconnect(); - } - mTextureChangesUpdates.clear(); - - for (LLGLTFMaterial::local_tex_map_t::value_type val : mat->mTrackingIdToLocalTexture) + for (LLGLTFMaterial::local_tex_map_t::value_type &val : mat->mTrackingIdToLocalTexture) { LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(val.first); if (val.second != world_id) @@ -3127,34 +3186,6 @@ void LLMaterialEditor::setFromGLTFMaterial(LLGLTFMaterial* mat) } } } - else - { - for (mat_connection_map_t::value_type cn : mTextureChangesUpdates) - { - LLUUID world_id = LLLocalBitmapMgr::getInstance()->getWorldID(cn.second.mTrackingId); - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - if (world_id == mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(cn.second.mTrackingId, mat); - continue; - } - cn.second.mConnection.disconnect(); - } - } } bool LLMaterialEditor::setFromSelection() @@ -3173,6 +3204,8 @@ bool LLMaterialEditor::setFromSelection() const LLViewerInventoryItem* item = selected_object->getInventoryItemByAsset(func.mMaterialId); const bool allow_modify = !item || canModify(selected_object, item); setEnableEditing(allow_modify); + + // todo: apply local texture data to all materials in selection } else { @@ -3195,6 +3228,11 @@ bool LLMaterialEditor::setFromSelection() // Memorize selection data for filtering further updates mOverrideObjectId = func.mObjectId; mOverrideObjectTE = func.mObjectTE; + + // Ovverdired might have been updated, + // refresh state of local textures in overrides + LLSelectedTEUpdateOverrides local_tex_func(this); + selected_objects->applyToNodes(&local_tex_func); } return func.mMaterial.notNull(); diff --git a/indra/newview/llmaterialeditor.h b/indra/newview/llmaterialeditor.h index e6939098e0..95a4c4572d 100644 --- a/indra/newview/llmaterialeditor.h +++ b/indra/newview/llmaterialeditor.h @@ -232,6 +232,7 @@ class LLMaterialEditor : public LLPreview, public LLVOInventoryListener U32 getUnsavedChangesFlags() { return mUnsavedChanges; } U32 getRevertedChangesFlags() { return mRevertedChanges; } LLUUID getLocalTextureTrackingIdFromFlag(U32 flag); + bool updateMaterialLocalSubscription(LLGLTFMaterial* mat); static bool capabilitiesAvailable(); diff --git a/indra/newview/llviewerobject.cpp b/indra/newview/llviewerobject.cpp index 8228775596..2bcd0858d3 100644 --- a/indra/newview/llviewerobject.cpp +++ b/indra/newview/llviewerobject.cpp @@ -5475,6 +5475,11 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma tep->setGLTFRenderMaterial(render_mat); retval = TEM_CHANGE_TEXTURE; + for (LLGLTFMaterial::local_tex_map_t::value_type &val : override_mat->mTrackingIdToLocalTexture) + { + LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); + } + } else if (tep->setGLTFRenderMaterial(nullptr)) { @@ -5482,14 +5487,6 @@ S32 LLViewerObject::setTEGLTFMaterialOverride(U8 te, LLGLTFMaterial* override_ma } } - if (retval == TEM_CHANGE_TEXTURE) - { - for (LLGLTFMaterial::local_tex_map_t::value_type val : override_mat->mTrackingIdToLocalTexture) - { - LLLocalBitmapMgr::getInstance()->associateGLTFMaterial(val.first, override_mat); - } - } - return retval; } -- cgit v1.3 From cc089d88ad5ab9088a5036e1d6f301d87cb3b127 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Fri, 3 Nov 2023 21:07:46 +0200 Subject: SL-20523 Ensure override gets updated before render material --- indra/llprimitive/llgltfmaterial.cpp | 4 +++ indra/newview/llfetchedgltfmaterial.cpp | 8 +++++ indra/newview/lllocalbitmaps.cpp | 60 +++++++++++++++++++-------------- indra/newview/llmaterialeditor.cpp | 4 +++ 4 files changed, 50 insertions(+), 26 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index 390110b0ec..d2c911a189 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -794,6 +794,10 @@ bool LLGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const LLUUID mTextureId[i] = new_id; res = true; } + else if (mTextureId[i] == new_id) + { + res = true; + } } if (res) diff --git a/indra/newview/llfetchedgltfmaterial.cpp b/indra/newview/llfetchedgltfmaterial.cpp index a47b52fddc..1a47293523 100644 --- a/indra/newview/llfetchedgltfmaterial.cpp +++ b/indra/newview/llfetchedgltfmaterial.cpp @@ -183,6 +183,14 @@ bool LLFetchedGLTFMaterial::replaceLocalTexture(const LLUUID& tracking_id, const res = true; } + for (int i = 0; i < GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (mTextureId[i] == new_id) + { + res = true; + } + } + if (res) { mTrackingIdToLocalTexture[tracking_id] = new_id; diff --git a/indra/newview/lllocalbitmaps.cpp b/indra/newview/lllocalbitmaps.cpp index 4121df4bac..5a5fb7474c 100644 --- a/indra/newview/lllocalbitmaps.cpp +++ b/indra/newview/lllocalbitmaps.cpp @@ -641,41 +641,49 @@ void LLLocalBitmap::updateGLTFMaterials(LLUUID old_id, LLUUID new_id) } else if ((*it)->replaceLocalTexture(mTrackingID, old_id, new_id)) { - LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get()); - if (fetched_mat) + it++; + } + else + { + // Matching id not found, no longer in use + // material would clean itself, remove from the list + it = mGLTFMaterialWithLocalTextures.erase(it); + end = mGLTFMaterialWithLocalTextures.end(); + } + } + + // Render material consists of base and override materials, make sure replaceLocalTexture + // gets called for base and override before applyOverride + end = mGLTFMaterialWithLocalTextures.end(); + for (mat_list_t::iterator it = mGLTFMaterialWithLocalTextures.begin(); it != end;) + { + LLFetchedGLTFMaterial* fetched_mat = dynamic_cast((*it).get()); + if (fetched_mat) + { + for (LLTextureEntry* entry : fetched_mat->mTextureEntires) { - for (LLTextureEntry* entry : fetched_mat->mTextureEntires) + // Normally a change in applied material id is supposed to + // drop overrides thus reset material, but local materials + // currently reuse their existing asset id, and purpose is + // to preview how material will work in-world, overrides + // included, so do an override to render update instead. + LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); + if (override_mat) { - // Normally a change in applied material id is supposed to - // drop overrides thus reset material, but local materials - // currently reuse their existing asset id, and purpose is - // to preview how material will work in-world, overrides - // included, so do an override to render update instead. - LLGLTFMaterial* override_mat = entry->getGLTFMaterialOverride(); - if (override_mat) + // do not create a new material, reuse existing pointer + LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); + if (render_mat) { - // do not create a new material, reuse existing pointer - LLFetchedGLTFMaterial* render_mat = (LLFetchedGLTFMaterial*)entry->getGLTFRenderMaterial(); - if (render_mat) + llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); { - llassert(dynamic_cast(entry->getGLTFRenderMaterial()) != nullptr); - { - *render_mat = *fetched_mat; - } - render_mat->applyOverride(*override_mat); + *render_mat = *fetched_mat; } + render_mat->applyOverride(*override_mat); } } } - ++it; - } - else - { - // Matching id not found, no longer in use - // material would clean itself, remove from the list - it = mGLTFMaterialWithLocalTextures.erase(it); - end = mGLTFMaterialWithLocalTextures.end(); } + ++it; } } diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 7d1ac32282..11a528314e 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -3231,6 +3231,10 @@ bool LLMaterialEditor::setFromSelection() // Ovverdired might have been updated, // refresh state of local textures in overrides + // + // Todo: this probably shouldn't be here, but in localbitmap, + // subscried to all material overrides if we want copied + // objects to get properly updated as well LLSelectedTEUpdateOverrides local_tex_func(this); selected_objects->applyToNodes(&local_tex_func); } -- cgit v1.3 From e7b71cd8a10898320cf3e0aebc05bfdec3d2ffa3 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Wed, 8 Nov 2023 11:50:46 -0600 Subject: SL-20582 Fix for overriding to alpha mode blend not working. Incidental decruft of dead code (thanks, Rye!) --- indra/llprimitive/llgltfmaterial.cpp | 1 + indra/llprimitive/llprimitive.cpp | 36 ------------------------------------ indra/llprimitive/llprimitive.h | 5 +---- 3 files changed, 2 insertions(+), 40 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index f42c11ee21..c1f2a04154 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -715,6 +715,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) if (am.isInteger()) { mAlphaMode = (AlphaMode) am.asInteger(); + mOverrideAlphaMode = true; } const LLSD& ac = data["ac"]; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 350d84ae6c..904747af2d 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2376,42 +2376,6 @@ void LLRenderMaterialParams::copy(const LLNetworkData& data) mEntries = param.mEntries; } -LLSD LLRenderMaterialParams::asLLSD() const -{ - LLSD ret; - - for (int i = 0; i < mEntries.size(); ++i) - { - ret[i]["te_idx"] = mEntries[i].te_idx; - ret[i]["id"] = mEntries[i].id; - } - - return ret; -} - -bool LLRenderMaterialParams::fromLLSD(LLSD& sd) -{ - if (sd.isArray()) - { - mEntries.resize(sd.size()); - for (int i = 0; i < sd.size(); ++i) - { - if (sd[i].has("te_idx") && sd.has("id")) - { - mEntries[i].te_idx = sd[i]["te_idx"].asInteger(); - mEntries[i].id = sd[i]["id"].asUUID(); - } - else - { - return false; - } - } - - return true; - } - - return false; -} void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index d2adfa4a3d..0b7dbd703a 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -382,10 +382,7 @@ public: BOOL unpack(LLDataPacker& dp) override; bool operator==(const LLNetworkData& data) const override; void copy(const LLNetworkData& data) override; - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - + void setMaterial(U8 te_idx, const LLUUID& id); const LLUUID& getMaterial(U8 te_idx) const; -- cgit v1.3 From 843866d193a0fb5ea882408c8862335ab9c5539b Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Mon, 13 Nov 2023 13:12:48 -0600 Subject: Drtvwr 596 11/8/2023 (#501) * SL-20570 Fix for lossy (and square) normal maps when importing GLTF materials. * SL-20582 Fix for overriding to alpha mode blend not working. Incidental decruft of dead code (thanks, Rye!) --- indra/llprimitive/llgltfmaterial.cpp | 1 + indra/llprimitive/llprimitive.cpp | 36 ------------------------------------ indra/llprimitive/llprimitive.h | 5 +---- indra/newview/llmaterialeditor.cpp | 14 +++----------- 4 files changed, 5 insertions(+), 51 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index d2c911a189..ae165f7fa4 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -723,6 +723,7 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) if (am.isInteger()) { mAlphaMode = (AlphaMode) am.asInteger(); + mOverrideAlphaMode = true; } const LLSD& ac = data["ac"]; diff --git a/indra/llprimitive/llprimitive.cpp b/indra/llprimitive/llprimitive.cpp index 350d84ae6c..904747af2d 100644 --- a/indra/llprimitive/llprimitive.cpp +++ b/indra/llprimitive/llprimitive.cpp @@ -2376,42 +2376,6 @@ void LLRenderMaterialParams::copy(const LLNetworkData& data) mEntries = param.mEntries; } -LLSD LLRenderMaterialParams::asLLSD() const -{ - LLSD ret; - - for (int i = 0; i < mEntries.size(); ++i) - { - ret[i]["te_idx"] = mEntries[i].te_idx; - ret[i]["id"] = mEntries[i].id; - } - - return ret; -} - -bool LLRenderMaterialParams::fromLLSD(LLSD& sd) -{ - if (sd.isArray()) - { - mEntries.resize(sd.size()); - for (int i = 0; i < sd.size(); ++i) - { - if (sd[i].has("te_idx") && sd.has("id")) - { - mEntries[i].te_idx = sd[i]["te_idx"].asInteger(); - mEntries[i].id = sd[i]["id"].asUUID(); - } - else - { - return false; - } - } - - return true; - } - - return false; -} void LLRenderMaterialParams::setMaterial(U8 te, const LLUUID& id) { diff --git a/indra/llprimitive/llprimitive.h b/indra/llprimitive/llprimitive.h index d2adfa4a3d..0b7dbd703a 100644 --- a/indra/llprimitive/llprimitive.h +++ b/indra/llprimitive/llprimitive.h @@ -382,10 +382,7 @@ public: BOOL unpack(LLDataPacker& dp) override; bool operator==(const LLNetworkData& data) const override; void copy(const LLNetworkData& data) override; - LLSD asLLSD() const; - operator LLSD() const { return asLLSD(); } - bool fromLLSD(LLSD& sd); - + void setMaterial(U8 te_idx, const LLUUID& id); const LLUUID& getMaterial(U8 te_idx) const; diff --git a/indra/newview/llmaterialeditor.cpp b/indra/newview/llmaterialeditor.cpp index 11a528314e..a5437f7a88 100644 --- a/indra/newview/llmaterialeditor.cpp +++ b/indra/newview/llmaterialeditor.cpp @@ -1840,17 +1840,9 @@ static void pack_textures( if (normal_img) { - normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img); - - LLPointer test; - test = LLViewerTextureList::convertToUploadFile(normal_img, 1024, true); - - S32 lossy_bytes = normal_j2c->getDataSize(); - S32 lossless_bytes = test->getDataSize(); - - LL_DEBUGS("MaterialEditor") << llformat("Lossless vs Lossy: (%d/%d) = %.2f", lossless_bytes, lossy_bytes, (F32)lossless_bytes / lossy_bytes) << LL_ENDL; - - normal_j2c = test; + // create a losslessly compressed version of the normal map + normal_j2c = LLViewerTextureList::convertToUploadFile(normal_img, 1024, false, true); + LL_DEBUGS("MaterialEditor") << "Normal: " << normal_j2c->getDataSize() << LL_ENDL; } if (mr_img) -- cgit v1.3 From 0edb7cad6bdeaf02cbd89d1f2dd38c47d6078c03 Mon Sep 17 00:00:00 2001 From: RunitaiLinden Date: Tue, 14 Nov 2023 13:33:11 -0600 Subject: SL-20340 Fix for off-by-epsilon hack falling off when serializing overrides as LLSD. (#513) --- indra/llprimitive/llgltfmaterial.cpp | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llgltfmaterial.cpp b/indra/llprimitive/llgltfmaterial.cpp index c1f2a04154..9945c230a2 100644 --- a/indra/llprimitive/llgltfmaterial.cpp +++ b/indra/llprimitive/llgltfmaterial.cpp @@ -691,24 +691,44 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) if (bc.isDefined()) { mBaseColor.setValue(bc); + if (mBaseColor == getDefaultBaseColor()) + { + // HACK -- nudge by epsilon if we receive a default value (indicates override to default) + mBaseColor.mV[3] -= FLT_EPSILON; + } } const LLSD& ec = data["ec"]; if (ec.isDefined()) { mEmissiveColor.setValue(ec); + if (mEmissiveColor == getDefaultEmissiveColor()) + { + // HACK -- nudge by epsilon if we receive a default value (indicates override to default) + mEmissiveColor.mV[0] += FLT_EPSILON; + } } const LLSD& mf = data["mf"]; if (mf.isReal()) { mMetallicFactor = mf.asReal(); + if (mMetallicFactor == getDefaultMetallicFactor()) + { + // HACK -- nudge by epsilon if we receive a default value (indicates override to default) + mMetallicFactor -= FLT_EPSILON; + } } const LLSD& rf = data["rf"]; if (rf.isReal()) { mRoughnessFactor = rf.asReal(); + if (mRoughnessFactor == getDefaultRoughnessFactor()) + { + // HACK -- nudge by epsilon if we receive a default value (indicates override to default) + mRoughnessFactor -= FLT_EPSILON; + } } const LLSD& am = data["am"]; @@ -722,6 +742,11 @@ void LLGLTFMaterial::applyOverrideLLSD(const LLSD& data) if (ac.isReal()) { mAlphaCutoff = ac.asReal(); + if (mAlphaCutoff == getDefaultAlphaCutoff()) + { + // HACK -- nudge by epsilon if we receive a default value (indicates override to default) + mAlphaCutoff -= FLT_EPSILON; + } } const LLSD& ds = data["ds"]; -- cgit v1.3 From f35127faa03b438b5348c56c9e04b7b1a2c698ea Mon Sep 17 00:00:00 2001 From: Rye Mutt Date: Mon, 20 Nov 2023 10:18:27 -0500 Subject: Fix failure to save the normalized translation data during collada upload --- indra/llprimitive/lldaeloader.cpp | 3 ++- indra/llprimitive/llmodel.cpp | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/lldaeloader.cpp b/indra/llprimitive/lldaeloader.cpp index 46e1cb4922..2e4b013b77 100644 --- a/indra/llprimitive/lldaeloader.cpp +++ b/indra/llprimitive/lldaeloader.cpp @@ -2584,7 +2584,8 @@ bool LLDAELoader::loadModelsFromDomMesh(domMesh* mesh, std::vector& mo next->mLabel = model_name + (char)((int)'a' + next->mSubmodelID) + lod_suffix[mLod]; next->getVolumeFaces() = remainder; next->mNormalizedScale = ret->mNormalizedScale; - + next->mNormalizedTranslation = ret->mNormalizedTranslation; + if ( ret->mMaterialList.size() > LL_SCULPT_MESH_MAX_FACES) { next->mMaterialList.assign(ret->mMaterialList.begin() + LL_SCULPT_MESH_MAX_FACES, ret->mMaterialList.end()); diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index ee493968de..99a5697a84 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -52,7 +52,8 @@ const int MODEL_NAMES_LENGTH = sizeof(model_names) / sizeof(std::string); LLModel::LLModel(LLVolumeParams& params, F32 detail) : LLVolume(params, detail), - mNormalizedScale(1,1,1), + mNormalizedScale(1,1,1), + mNormalizedTranslation(0, 0, 0), mPelvisOffset( 0.0f ), mStatus(NO_ERRORS), mSubmodelID(0) -- cgit v1.3 From c81c15b74137e1471c6c1d95c421d3d69fe99fd4 Mon Sep 17 00:00:00 2001 From: Andrey Kleshchev Date: Thu, 23 Nov 2023 21:22:02 +0200 Subject: SL-18875 Crash at LLModel::writeModel Looks like a crash iterating over weight_list& weights = model[idx]->getJointInfluences(pos); --- indra/llprimitive/llmodel.cpp | 22 ++++++++++++++++------ 1 file changed, 16 insertions(+), 6 deletions(-) (limited to 'indra/llprimitive') diff --git a/indra/llprimitive/llmodel.cpp b/indra/llprimitive/llmodel.cpp index fbd97b3de7..153b9a1d23 100644 --- a/indra/llprimitive/llmodel.cpp +++ b/indra/llprimitive/llmodel.cpp @@ -997,7 +997,12 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) weight_map::iterator iterPos = mSkinWeights.begin(); weight_map::iterator iterEnd = mSkinWeights.end(); - llassert(!mSkinWeights.empty()); + if (mSkinWeights.empty()) + { + // function calls iter->second on all return paths + // everything that calls this function should precheck that there is data. + LL_ERRS() << "called getJointInfluences with empty weights list" << LL_ENDL; + } for ( ; iterPos!=iterEnd; ++iterPos ) { @@ -1024,11 +1029,16 @@ LLModel::weight_list& LLModel::getJointInfluences(const LLVector3& pos) const F32 epsilon = 1e-5f; weight_map::iterator iter_up = mSkinWeights.lower_bound(pos); weight_map::iterator iter_down = iter_up; - if (iter_up != mSkinWeights.end()) - { - iter_down = ++iter_up; - } - weight_map::iterator best = iter_up; + weight_map::iterator best = iter_up; + if (iter_up != mSkinWeights.end()) + { + iter_down = ++iter_up; + } + else + { + // Assumes that there is at least one element + --best; + } F32 min_dist = (iter->first - pos).magVec(); -- cgit v1.3