From 76bf3390eb119a7dfd879bbbc31b4d5e687aac8f Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:56:55 -0700 Subject: DRTVWR-592: (WIP) Detect when terrain materials are loaded, use as fallback when terrain textures do not load --- indra/newview/llvlcomposition.cpp | 135 ++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 42 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 001fab7755..8480c9ce3d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -65,10 +65,10 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mSurfacep = surfacep; // Load Terrain Textures - Original ones - setDetailTextureID(0, TERRAIN_DIRT_DETAIL); - setDetailTextureID(1, TERRAIN_GRASS_DETAIL); - setDetailTextureID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailTextureID(3, TERRAIN_ROCK_DETAIL); + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); // Initialize the texture matrix to defaults. for (S32 i = 0; i < CORNER_COUNT; ++i) @@ -93,7 +93,7 @@ void LLVLComposition::setSurface(LLSurface *surfacep) } -void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) { if(id.isNull()) { @@ -104,6 +104,25 @@ void LLVLComposition::setDetailTextureID(S32 corner, const LLUUID& id) mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); mDetailTextures[corner]->setNoDelete() ; mRawImages[corner] = NULL; + // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. + // *TODO: As the material textures are loaded, prevent deletion + mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); +} + +void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) +{ + if(id.isNull()) + { + mDetailMaterials[corner] = nullptr; + } + else + { + // This is terrain material, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. + mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); + mDetailTextures[corner]->setNoDelete() ; + mRawImages[corner] = NULL; + } } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -149,10 +168,6 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus // simple height) - // Heights map into textures as 0-1 = first, 1-2 = second, etc. - // So we need to compress heights into this range. - const S32 NUM_TEXTURES = 4; - const F32 xyScaleInv = (1.f / xyScale); const F32 zScaleInv = (1.f / zScale); @@ -199,7 +214,7 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component twiddle *= noise_magnitude; - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(NUM_TEXTURES) / height_range; + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; scaled_noisy_height = llmax(0.f, scaled_noisy_height); scaled_noisy_height = llmin(3.f, scaled_noisy_height); @@ -211,6 +226,37 @@ BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, static const U32 BASE_SIZE = 128; +// Boost the texture loading priority +// Return true when ready to use (i.e. texture is sufficiently loaded) +bool boost_texture_until_ready(LLPointer& tex) +{ + if (tex->getDiscardLevel() < 0) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + return false; + } + if ((tex->getDiscardLevel() != 0 && + (tex->getWidth() < BASE_SIZE || + tex->getHeight() < BASE_SIZE))) + { + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority + return false; + } + return true; +} + BOOL LLVLComposition::generateComposition() { @@ -220,35 +266,44 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - for (S32 i = 0; i < 4; i++) + bool textures_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) { - if (mDetailTextures[i]->getDiscardLevel() < 0) - { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); - return FALSE; - } - if ((mDetailTextures[i]->getDiscardLevel() != 0 && - (mDetailTextures[i]->getWidth() < BASE_SIZE || - mDetailTextures[i]->getHeight() < BASE_SIZE))) - { - S32 width = mDetailTextures[i]->getFullWidth(); - S32 height = mDetailTextures[i]->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; - } - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - mDetailTextures[i]->setMinDiscardLevel(ddiscard); - mDetailTextures[i]->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return FALSE; - } + if (!boost_texture_until_ready(mDetailTextures[i])) + { + textures_ready = false; + break; + } } + + if (textures_ready) + { + return TRUE; + } - return TRUE; + bool materials_ready = true; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const LLPointer& mat = mDetailMaterials[i]; + if (!mat.isLoaded() || + (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || + (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || + (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || + (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + { + materials_ready = false; + break; + } + } + + if (materials_ready) + { + return TRUE; + } + else + { + return FALSE; + } } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -469,16 +524,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailTextureID(S32 corner) +LLUUID LLVLComposition::getDetailAssetID(S32 corner) { + llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); return mDetailTextures[corner]->getID(); } -LLViewerFetchedTexture* LLVLComposition::getDetailTexture(S32 corner) -{ - return mDetailTextures[corner]; -} - F32 LLVLComposition::getStartHeight(S32 corner) { return mStartHeight[corner]; -- cgit v1.2.3 From 94e824739b5e8408b52a03e5af8e3fb4e124c616 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:02 -0700 Subject: DRTVWR-592: Render PBR material terrain like legacy, using baseColor texture --- indra/newview/llvlcomposition.cpp | 239 ++++++++++++++++++++++++-------------- 1 file changed, 150 insertions(+), 89 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8480c9ce3d..9ad1a3dd17 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -34,6 +34,8 @@ #include "lltextureview.h" #include "llviewertexture.h" #include "llviewertexturelist.h" +#include "llfetchedgltfmaterial.h" +#include "llgltfmateriallist.h" #include "llviewerregion.h" #include "noise.h" #include "llregionhandle.h" // for from_region_handle @@ -59,8 +61,7 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale), - mParamsReady(FALSE) + LLViewerLayer(width, scale) { mSurfacep = surfacep; @@ -76,9 +77,11 @@ LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); } - mTexScaleX = 16.f; - mTexScaleY = 16.f; - mTexturesLoaded = FALSE; + + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + mMaterialTexturesSet[i] = false; + } } @@ -92,8 +95,19 @@ void LLVLComposition::setSurface(LLSurface *surfacep) mSurfacep = surfacep; } +LLPointer fetch_terrain_texture(const LLUUID& id) +{ + if (id.isNull()) + { + return nullptr; + } + + LLPointer tex = LLViewerTextureManager::getFetchedTexture(id); + tex->setNoDelete(); + return tex; +} -void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { if(id.isNull()) { @@ -101,28 +115,11 @@ void LLVLComposition::setDetailAssetID(S32 corner, const LLUUID& id) } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - // *TODO: Decide if we have textures or materials. Whichever loads first determines the terrain type. - // *TODO: As the material textures are loaded, prevent deletion - mDetailMaterials[corner] = LLGLTFMaterialList::getMaterial(id); -} - -void LLVLComposition::setDetailMaterialID(S32 corner, const LLUUID& id) -{ - if(id.isNull()) - { - mDetailMaterials[corner] = nullptr; - } - else - { - // This is terrain material, but we are not setting it as BOOST_TERRAIN - // since we will be manipulating it later as needed. - mDetailTextures[corner] = LLViewerTextureManager::getFetchedTexture(id); - mDetailTextures[corner]->setNoDelete() ; - mRawImages[corner] = NULL; - } + mDetailTextures[asset] = fetch_terrain_texture(id); + mRawImages[asset] = NULL; + LLPointer& mat = mDetailMaterials[asset]; + mat = gGLTFMaterialList.getMaterial(id); + mMaterialTexturesSet[asset] = false; } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, @@ -228,82 +225,130 @@ static const U32 BASE_SIZE = 128; // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) -bool boost_texture_until_ready(LLPointer& tex) +// static +BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { if (tex->getDiscardLevel() < 0) { - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->addTextureStats(BASE_SIZE*BASE_SIZE); - return false; + if (boost) + { + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->addTextureStats(BASE_SIZE*BASE_SIZE); + } + return FALSE; } if ((tex->getDiscardLevel() != 0 && (tex->getWidth() < BASE_SIZE || tex->getHeight() < BASE_SIZE))) { - S32 width = tex->getFullWidth(); - S32 height = tex->getFullHeight(); - S32 min_dim = llmin(width, height); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + if (boost) { - ddiscard++; - min_dim /= 2; + S32 width = tex->getFullWidth(); + S32 height = tex->getFullHeight(); + S32 min_dim = llmin(width, height); + S32 ddiscard = 0; + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail + tex->setMinDiscardLevel(ddiscard); + tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->setMinDiscardLevel(ddiscard); - tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority - return false; + return FALSE; } - return true; + return TRUE; } -BOOL LLVLComposition::generateComposition() +// Boost the loading priority of every known texture in the material +// Return true when ready to use (i.e. material and all textures within are sufficiently loaded) +// static +BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { + if (!mat->isLoaded()) + { + return FALSE; + } - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } + // Material is loaded, but textures may not be + if (!textures_set) + { + // *NOTE: These can sometimes be set to to nullptr due to + // updateTEMaterialTextures. For the sake of robustness, we emulate + // that fetching behavior by setting textures of null IDs to nullptr. + mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); + mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); + textures_set = true; - bool textures_ready = true; + return FALSE; + } + + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost)) + { + return FALSE; + } + if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost)) + { + return FALSE; + } + + return TRUE; +} + +BOOL LLVLComposition::texturesReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - if (!boost_texture_until_ready(mDetailTextures[i])) + if (!textureReady(mDetailTextures[i], boost)) { - textures_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (textures_ready) - { - return TRUE; - } - - bool materials_ready = true; +BOOL LLVLComposition::materialsReady(BOOL boost) +{ for (S32 i = 0; i < ASSET_COUNT; i++) { - const LLPointer& mat = mDetailMaterials[i]; - if (!mat.isLoaded() || - (mat->mBaseColorTexture && !boost_texture_until_ready(mat->mBaseColorTexture)) || - (mat->mNormalTexture && !boost_texture_until_ready(mat->mNormalTexture)) || - (mat->mMetallicRoughnessTexture && !boost_texture_until_ready(mat->mMetallicRoughnessTexture)) || - (mat->mEmissiveTexture && !boost_texture_until_ready(mat->mEmissiveTexture))) + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - materials_ready = false; - break; + return FALSE; } } + return TRUE; +} - if (materials_ready) +BOOL LLVLComposition::generateComposition() +{ + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } + + if (texturesReady(TRUE)) { return TRUE; } - else + + if (materialsReady(TRUE)) { - return FALSE; + return TRUE; } + + return FALSE; } BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, @@ -323,15 +368,28 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, // // These have already been validated by generateComposition. - U8* st_data[4]; - S32 st_data_size[4]; // for debugging + U8* st_data[ASSET_COUNT]; + S32 st_data_size[ASSET_COUNT]; // for debugging + + const bool use_textures = texturesReady(); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { if (mRawImages[i].isNull()) { // Read back a raw image for this discard level, if it exists - S32 min_dim = llmin(mDetailTextures[i]->getFullWidth(), mDetailTextures[i]->getFullHeight()); + LLViewerFetchedTexture* tex; + if (use_textures) + { + tex = mDetailTextures[i]; + } + else + { + tex = mDetailMaterials[i]->mBaseColorTexture; + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + } + + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) { @@ -339,31 +397,31 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, min_dim /= 2; } - BOOL delete_raw = (mDetailTextures[i]->reloadRawImage(ddiscard) != NULL) ; - if(mDetailTextures[i]->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; + if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. { - if (mDetailTextures[i]->getFetchPriority() <= 0.0f && !mDetailTextures[i]->hasSavedRawImage()) + if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_MAP); - mDetailTextures[i]->forceToRefetchTexture(ddiscard); + tex->setBoostLevel(LLGLTexture::BOOST_MAP); + tex->forceToRefetchTexture(ddiscard); } if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << mDetailTextures[i]->getID() << " Discard: " << ddiscard << LL_ENDL; + LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } - mRawImages[i] = mDetailTextures[i]->getRawImage() ; + mRawImages[i] = tex->getRawImage() ; if(delete_raw) { - mDetailTextures[i]->destroyRawImage() ; + tex->destroyRawImage() ; } - if (mDetailTextures[i]->getWidth(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getHeight(ddiscard) != BASE_SIZE || - mDetailTextures[i]->getComponents() != 3) + if (tex->getWidth(ddiscard) != BASE_SIZE || + tex->getHeight(ddiscard) != BASE_SIZE || + tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); @@ -514,7 +572,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - for (S32 i = 0; i < 4; i++) + for (S32 i = 0; i < ASSET_COUNT; i++) { // Un-boost detatil textures (will get re-boosted if rendering in high detail) mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); @@ -526,7 +584,10 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, LLUUID LLVLComposition::getDetailAssetID(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner] && mDetailTextures[corner]->getID() == mDetailMaterials[corner].getID()); + llassert(mDetailTextures[corner] && mDetailMaterials[corner]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. return mDetailTextures[corner]->getID(); } -- cgit v1.2.3 From 3553fec2084b8be3f3de86cec293c1e363c1388e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:57:10 -0700 Subject: DRTVWR-592: (WIP) Separate code path for terrain rendering and shaders. Just copy/paste for now. Use same draw pool --- indra/newview/llvlcomposition.cpp | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 9ad1a3dd17..5d711f4e5d 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -228,6 +228,8 @@ static const U32 BASE_SIZE = 128; // static BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) { + llassert(tex.notNull()); + if (tex->getDiscardLevel() < 0) { if (boost) @@ -306,6 +308,13 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } +BOOL LLVLComposition::useTextures() +{ + LL_PROFILE_ZONE_SCOPED; + + return texturesReady() || !materialsReady(); +} + BOOL LLVLComposition::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -371,7 +380,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = texturesReady(); + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From 039116abd4166903005b8de6fa5d64f0fdf75422 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:05 -0700 Subject: DRTVWR-592: (WIP) Roughly working draft of PBR terrain --- indra/newview/llvlcomposition.cpp | 1 + 1 file changed, 1 insertion(+) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 5d711f4e5d..815489f753 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -360,6 +360,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } +// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { -- cgit v1.2.3 From 94d8f669acc57d670000498edf22589f7b178af0 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:13 -0700 Subject: DRTVWR-592: Add debug options LocalTerrainAssetN. Fix PBR terrain texture flickering --- indra/newview/llvlcomposition.cpp | 345 ++++++++++++++++++++------------------ 1 file changed, 183 insertions(+), 162 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 815489f753..c4bed85be7 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -42,6 +42,8 @@ #include "llviewercontrol.h" +static const U32 BASE_SIZE = 128; + F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) { @@ -59,40 +61,40 @@ F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F return result; } - -LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : - LLViewerLayer(width, scale) +LLTerrainMaterials::LLTerrainMaterials() { - mSurfacep = surfacep; - - // Load Terrain Textures - Original ones - setDetailAssetID(0, TERRAIN_DIRT_DETAIL); - setDetailAssetID(1, TERRAIN_GRASS_DETAIL); - setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailAssetID(3, TERRAIN_ROCK_DETAIL); - - // Initialize the texture matrix to defaults. - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); - mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); - } - for (S32 i = 0; i < ASSET_COUNT; ++i) { mMaterialTexturesSet[i] = false; } } - -LLVLComposition::~LLVLComposition() +LLTerrainMaterials::~LLTerrainMaterials() { } +BOOL LLTerrainMaterials::generateMaterials() +{ + if (texturesReady(TRUE)) + { + return TRUE; + } -void LLVLComposition::setSurface(LLSurface *surfacep) + if (materialsReady(TRUE)) + { + return TRUE; + } + + return FALSE; +} + +LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { - mSurfacep = surfacep; + llassert(mDetailTextures[asset] && mDetailMaterials[asset]); + // *HACK: Assume both the the material and texture were fetched in the same + // way using the same UUID. However, we may not know at this point which + // one will load. + return mDetailTextures[asset]->getID(); } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -107,126 +109,51 @@ LLPointer fetch_terrain_texture(const LLUUID& id) return tex; } -void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) +void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) { - if(id.isNull()) - { - return; - } // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); - mRawImages[asset] = NULL; LLPointer& mat = mDetailMaterials[asset]; mat = gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, - const F32 width, const F32 height) +BOOL LLTerrainMaterials::useTextures() { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } - - llassert(mSurfacep); - - if (!mSurfacep || !mSurfacep->getRegion()) - { - // We don't always have the region yet here.... - return FALSE; - } - - S32 x_begin, y_begin, x_end, y_end; + LL_PROFILE_ZONE_SCOPED; - x_begin = ll_round( x * mScaleInv ); - y_begin = ll_round( y * mScaleInv ); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); + return texturesReady() || !materialsReady(); +} - if (x_end > mWidth) - { - x_end = mWidth; - } - if (y_end > mWidth) +BOOL LLTerrainMaterials::texturesReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - y_end = mWidth; + if (!textureReady(mDetailTextures[i], boost)) + { + return FALSE; + } } + return TRUE; +} - LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); - - // For perlin noise generation... - const F32 slope_squared = 1.5f*1.5f; - const F32 xyScale = 4.9215f; //0.93284f; - const F32 zScale = 4; //0.92165f; - const F32 z_offset = 0.f; - const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus - // simple height) - - const F32 xyScaleInv = (1.f / xyScale); - const F32 zScaleInv = (1.f / zScale); - - const F32 inv_width = 1.f/mWidth; - - // OK, for now, just have the composition value equal the height at the point. - for (S32 j = y_begin; j < y_end; j++) +BOOL LLTerrainMaterials::materialsReady(BOOL boost) +{ + for (S32 i = 0; i < ASSET_COUNT; i++) { - for (S32 i = x_begin; i < x_end; i++) - { - - F32 vec[3]; - F32 vec1[3]; - F32 twiddle; - - // Bilinearly interpolate the start height and height range of the textures - F32 start_height = bilinear(mStartHeight[SOUTHWEST], - mStartHeight[SOUTHEAST], - mStartHeight[NORTHWEST], - mStartHeight[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - F32 height_range = bilinear(mHeightRange[SOUTHWEST], - mHeightRange[SOUTHEAST], - mHeightRange[NORTHWEST], - mHeightRange[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - - LLVector3 location(i*mScale, j*mScale, 0.f); - - F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; - - // Step 0: Measure the exact height at this texel - vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice - vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; - vec[2] = height*zScaleInv; - // - // Choose material value by adding to the exact height a random value - // - vec1[0] = vec[0]*(0.2222222222f); - vec1[1] = vec[1]*(0.2222222222f); - vec1[2] = vec[2]*(0.2222222222f); - twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions - - twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component - twiddle *= noise_magnitude; - - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; - - scaled_noisy_height = llmax(0.f, scaled_noisy_height); - scaled_noisy_height = llmin(3.f, scaled_noisy_height); - *(mDatap + i + j*mWidth) = scaled_noisy_height; - } - } - return TRUE; + if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) + { + return FALSE; + } + } + return TRUE; } -static const U32 BASE_SIZE = 128; - // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) // static -BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL boost) +BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BOOL boost) { llassert(tex.notNull()); @@ -266,9 +193,9 @@ BOOL LLVLComposition::textureReady(LLPointer& tex, BOOL // Boost the loading priority of every known texture in the material // Return true when ready to use (i.e. material and all textures within are sufficiently loaded) // static -BOOL LLVLComposition::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) +BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) { - if (!mat->isLoaded()) + if (!mat || !mat->isLoaded()) { return FALSE; } @@ -308,37 +235,140 @@ BOOL LLVLComposition::materialReady(LLPointer& mat, bool& return TRUE; } -BOOL LLVLComposition::useTextures() + +LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : + LLTerrainMaterials(), + LLViewerLayer(width, scale) +{ + // Load Terrain Textures - Original ones + setDetailAssetID(0, TERRAIN_DIRT_DETAIL); + setDetailAssetID(1, TERRAIN_GRASS_DETAIL); + setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); + setDetailAssetID(3, TERRAIN_ROCK_DETAIL); + + mSurfacep = surfacep; + + // Initialize the texture matrix to defaults. + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); + mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); + } +} + + +LLVLComposition::~LLVLComposition() { - LL_PROFILE_ZONE_SCOPED; + LLTerrainMaterials::~LLTerrainMaterials(); +} - return texturesReady() || !materialsReady(); + +void LLVLComposition::setSurface(LLSurface *surfacep) +{ + mSurfacep = surfacep; } -BOOL LLVLComposition::texturesReady(BOOL boost) +BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, + const F32 width, const F32 height) { - for (S32 i = 0; i < ASSET_COUNT; i++) + if (!mParamsReady) { - if (!textureReady(mDetailTextures[i], boost)) - { - return FALSE; - } + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; } - return TRUE; -} -BOOL LLVLComposition::materialsReady(BOOL boost) -{ - for (S32 i = 0; i < ASSET_COUNT; i++) + llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) { - if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) - { - return FALSE; - } - } - return TRUE; + // We don't always have the region yet here.... + return FALSE; + } + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round( x * mScaleInv ); + y_begin = ll_round( y * mScaleInv ); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { + x_end = mWidth; + } + if (y_end > mWidth) + { + y_end = mWidth; + } + + LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); + + // For perlin noise generation... + const F32 slope_squared = 1.5f*1.5f; + const F32 xyScale = 4.9215f; //0.93284f; + const F32 zScale = 4; //0.92165f; + const F32 z_offset = 0.f; + const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus + // simple height) + + const F32 xyScaleInv = (1.f / xyScale); + const F32 zScaleInv = (1.f / zScale); + + const F32 inv_width = 1.f/mWidth; + + // OK, for now, just have the composition value equal the height at the point. + for (S32 j = y_begin; j < y_end; j++) + { + for (S32 i = x_begin; i < x_end; i++) + { + + F32 vec[3]; + F32 vec1[3]; + F32 twiddle; + + // Bilinearly interpolate the start height and height range of the textures + F32 start_height = bilinear(mStartHeight[SOUTHWEST], + mStartHeight[SOUTHEAST], + mStartHeight[NORTHWEST], + mStartHeight[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + F32 height_range = bilinear(mHeightRange[SOUTHWEST], + mHeightRange[SOUTHEAST], + mHeightRange[NORTHWEST], + mHeightRange[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + + LLVector3 location(i*mScale, j*mScale, 0.f); + + F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; + + // Step 0: Measure the exact height at this texel + vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice + vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; + vec[2] = height*zScaleInv; + // + // Choose material value by adding to the exact height a random value + // + vec1[0] = vec[0]*(0.2222222222f); + vec1[1] = vec[1]*(0.2222222222f); + vec1[2] = vec[2]*(0.2222222222f); + twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions + + twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component + twiddle *= noise_magnitude; + + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; + + scaled_noisy_height = llmax(0.f, scaled_noisy_height); + scaled_noisy_height = llmin(3.f, scaled_noisy_height); + *(mDatap + i + j*mWidth) = scaled_noisy_height; + } + } + return TRUE; } +LLTerrainMaterials gLocalTerrainMaterials; + BOOL LLVLComposition::generateComposition() { if (!mParamsReady) @@ -347,17 +377,7 @@ BOOL LLVLComposition::generateComposition() return FALSE; } - if (texturesReady(TRUE)) - { - return TRUE; - } - - if (materialsReady(TRUE)) - { - return TRUE; - } - - return FALSE; + return LLTerrainMaterials::generateMaterials(); } // TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. @@ -592,18 +612,19 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, return TRUE; } -LLUUID LLVLComposition::getDetailAssetID(S32 corner) +F32 LLVLComposition::getStartHeight(S32 corner) { - llassert(mDetailTextures[corner] && mDetailMaterials[corner]); - // *HACK: Assume both the the material and texture were fetched in the same - // way using the same UUID. However, we may not know at this point which - // one will load. - return mDetailTextures[corner]->getID(); + return mStartHeight[corner]; } -F32 LLVLComposition::getStartHeight(S32 corner) +void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { - return mStartHeight[corner]; + if (id.isNull()) + { + return; + } + LLTerrainMaterials::setDetailAssetID(asset, id); + mRawImages[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) -- cgit v1.2.3 From 14c3730bf128a6f01825954ee67a06188e134526 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:20 -0700 Subject: DRTVWR-592: Fix unable to undo effect of local terrain debug setting without restarting viewer --- indra/newview/llvlcomposition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c4bed85be7..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -115,7 +115,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); LLPointer& mat = mDetailMaterials[asset]; - mat = gGLTFMaterialList.getMaterial(id); + mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; } -- cgit v1.2.3 From de9184479cfc179ba6e9d6ff388aff7da7f0b4ab Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 09:58:50 -0700 Subject: DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing --- indra/newview/llvlcomposition.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From 2318d657660320b921e1566b54d3833c0401a34c Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 22 May 2023 10:10:14 -0700 Subject: Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing" This reverts commit de9184479cfc179ba6e9d6ff388aff7da7f0b4ab. --- indra/newview/llvlcomposition.cpp | 13 +++---------- 1 file changed, 3 insertions(+), 10 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..8d55c80be8 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,20 +119,13 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() +BOOL LLTerrainMaterials::useTextures() { LL_PROFILE_ZONE_SCOPED; - const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return texturesReady() || !materialsReady(); } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +401,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = useTextures(); for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From 57433341abffba9382e6899b164af40200f5d6d3 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:35:02 -0700 Subject: Revert "Revert "DRTVWR-592: (WIP) Fix tiling only in the PBR case. Begin hooking up code for PBR-specific terrain geometry updates. Unfortunately, this version has a bug which can cause rebuilds to be skipped. Needs more work/testing"" This reverts commit 2318d657660320b921e1566b54d3833c0401a34c. --- indra/newview/llvlcomposition.cpp | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d55c80be8..8cd22e3bdb 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,13 +119,20 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::useTextures() +BOOL LLTerrainMaterials::getMaterialType() +{ + return mMaterialType; +} + +void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; - return texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady() || !materialsReady(); + mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } + BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -401,7 +408,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = useTextures(); + const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From b9ba57fd0004751dfbcbea90264a6e16c5849e5e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:42 -0700 Subject: DRTVWR-592: (WIP) Fix terrain PBR texture repeat seam. Legacy terrain texture repeats currently broken --- indra/newview/llvlcomposition.cpp | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8cd22e3bdb..130d74b286 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -119,7 +119,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) mMaterialTexturesSet[asset] = false; } -BOOL LLTerrainMaterials::getMaterialType() +LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { return mMaterialType; } @@ -132,7 +132,6 @@ void LLTerrainMaterials::updateMaterialType() mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; } - BOOL LLTerrainMaterials::texturesReady(BOOL boost) { for (S32 i = 0; i < ASSET_COUNT; i++) @@ -408,7 +407,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, U8* st_data[ASSET_COUNT]; S32 st_data_size[ASSET_COUNT]; // for debugging - const bool use_textures = getMaterialType() != LLTerrainMaterial::Type::PBR; + const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -423,8 +422,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, else { tex = mDetailMaterials[i]->mBaseColorTexture; - if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } } + // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; -- cgit v1.2.3 From d6aced7abf0c54ec94033534124025c87fb9aeb2 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:38:54 -0700 Subject: DRTVWR-592: Remove WIP separate code path for terrain geometry rebuilds for PBR as that is not needed at the moment --- indra/newview/llvlcomposition.cpp | 11 +++-------- 1 file changed, 3 insertions(+), 8 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 130d74b286..fa19bcae87 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -120,16 +120,11 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) } LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() -{ - return mMaterialType; -} - -void LLTerrainMaterials::updateMaterialType() { LL_PROFILE_ZONE_SCOPED; const BOOL use_textures = texturesReady() || !materialsReady(); - mMaterialType = use_textures ? Type::TEXTURE : Type::PBR; + return use_textures ? Type::TEXTURE : Type::PBR; } BOOL LLTerrainMaterials::texturesReady(BOOL boost) @@ -386,7 +381,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. +// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, const F32 width, const F32 height) { @@ -423,7 +418,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex = mDetailMaterials[i]->mBaseColorTexture; } - // TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) + // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); -- cgit v1.2.3 From ab3b4edac7809008cfed6d1b77e5a4debb22c88e Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 13 Oct 2023 10:39:03 -0700 Subject: DRTVWR-592: Fix broken minimap loading, improve minimap view of PBR materials (still not accurate, but better...) --- indra/newview/llvlcomposition.cpp | 125 +++++++++++++++++++++++++++++++++----- 1 file changed, 109 insertions(+), 16 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index fa19bcae87..f645023217 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -129,26 +129,28 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() BOOL LLTerrainMaterials::texturesReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!textureReady(mDetailTextures[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } BOOL LLTerrainMaterials::materialsReady(BOOL boost) { + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) { - return FALSE; + ready = FALSE; } } - return TRUE; + return ready; } // Boost the texture loading priority @@ -188,6 +190,10 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO } return FALSE; } + if (tex->getComponents() == 0) + { + return FALSE; + } return TRUE; } @@ -381,8 +387,7 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } -// *TODO: Re-evaluate usefulness of this function in the PBR case. There is currently a hack here to treat the material base color like a legacy terrain texture, but I'm not sure if that's useful. -BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, +BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height) { LL_PROFILE_ZONE_SCOPED @@ -390,8 +395,6 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, llassert(x >= 0.f); llassert(y >= 0.f); - LLTimer gen_timer; - /////////////////////////// // // Generate raw data arrays for surface textures @@ -403,6 +406,17 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; + // *TODO: Remove this as it is reduandant computation (first and foremost + // because getMaterialType() does something similar, but also... shouldn't + // the textures/materials already be loaded by now?) + if (use_textures) + { + if (!texturesReady()) { return FALSE; } + } + else + { + if (!materialsReady()) { return FALSE; } + } for (S32 i = 0; i < ASSET_COUNT; i++) { @@ -410,16 +424,37 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { // Read back a raw image for this discard level, if it exists LLViewerFetchedTexture* tex; + LLViewerFetchedTexture* tex_emissive; // Can be null + bool has_base_color_factor; + bool has_emissive_factor; + LLColor3 base_color_factor; + LLColor3 emissive_factor; if (use_textures) { tex = mDetailTextures[i]; + tex_emissive = nullptr; + has_base_color_factor = false; + has_emissive_factor = false; + llassert(tex); } else { tex = mDetailMaterials[i]->mBaseColorTexture; + tex_emissive = mDetailMaterials[i]->mEmissiveTexture; + base_color_factor = LLColor3(mDetailMaterials[i]->mBaseColor); + // *HACK: Treat alpha as black + base_color_factor *= (mDetailMaterials[i]->mBaseColor.mV[VW]); + emissive_factor = mDetailMaterials[i]->mEmissiveColor; + has_base_color_factor = (base_color_factor.mV[VX] != 1.f || + base_color_factor.mV[VY] != 1.f || + base_color_factor.mV[VZ] != 1.f); + has_emissive_factor = (emissive_factor.mV[VX] != 1.f || + emissive_factor.mV[VY] != 1.f || + emissive_factor.mV[VZ] != 1.f); } - // *TODO: Why are terrain textures (not terrain materials) not loading? (that is why there is a getComponents() check here) - if (!tex || tex->getComponents() == 0) { tex = LLViewerFetchedTexture::sWhiteImagep; } + + if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } + // tex_emissive can be null, and then will be ignored S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); S32 ddiscard = 0; @@ -430,8 +465,9 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, } BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; - if(tex->getRawImageLevel() != ddiscard)//raw iamge is not ready, will enter here again later. + if(tex->getRawImageLevel() != ddiscard) { + // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { tex->setBoostLevel(LLGLTexture::BOOST_MAP); @@ -442,21 +478,78 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, { tex->destroyRawImage() ; } - LL_DEBUGS("Terrain") << "cached raw data for terrain detail texture is not ready yet: " << tex->getID() << " Discard: " << ddiscard << LL_ENDL; return FALSE; } + if (tex_emissive) + { + if(tex_emissive->getRawImageLevel() != ddiscard) + { + // Raw image is not ready, will enter here again later. + if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) + { + tex_emissive->setBoostLevel(LLGLTexture::BOOST_MAP); + tex_emissive->forceToRefetchTexture(ddiscard); + } + + if(delete_raw) + { + tex_emissive->destroyRawImage() ; + } + return FALSE; + } + } mRawImages[i] = tex->getRawImage() ; if(delete_raw) { tex->destroyRawImage() ; } - if (tex->getWidth(ddiscard) != BASE_SIZE || + + // *TODO: This isn't quite right for PBR: + // 1) It does not convert the color images from SRGB to linear + // before mixing (which will always require copying the image). + // 2) It mixes emissive and base color before mixing terrain + // materials, but it should be the other way around + // 3) The composite function used to put emissive into base color + // is not an alpha blend. + // Long-term, we should consider a method that is more + // maintainable. Shaders, perhaps? Bake shaders to textures? + LLPointer raw_emissive; + if (tex_emissive) + { + raw_emissive = tex_emissive->getRawImage(); + if (has_emissive_factor || + tex_emissive->getWidth(ddiscard) != BASE_SIZE || + tex_emissive->getHeight(ddiscard) != BASE_SIZE || + tex_emissive->getComponents() != 4) + { + LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); + // Copy RGB, leave alpha alone (set to opaque by default) + newraw_emissive->copy(mRawImages[i]); + if (has_emissive_factor) + { + newraw_emissive->tint(emissive_factor); + } + raw_emissive = newraw_emissive; // deletes old + } + } + if (has_base_color_factor || + raw_emissive || + tex->getWidth(ddiscard) != BASE_SIZE || tex->getHeight(ddiscard) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); newraw->composite(mRawImages[i]); + if (has_base_color_factor) + { + newraw->tint(base_color_factor); + } + // Apply emissive texture + if (raw_emissive) + { + newraw->composite(raw_emissive); + } mRawImages[i] = newraw; // deletes old } } @@ -478,12 +571,12 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (x_end > mWidth) { - LL_WARNS("Terrain") << "x end > width" << LL_ENDL; + llassert(false); x_end = mWidth; } if (y_end > mWidth) { - LL_WARNS("Terrain") << "y end > width" << LL_ENDL; + llassert(false); y_end = mWidth; } @@ -513,7 +606,7 @@ BOOL LLVLComposition::generateTexture(const F32 x, const F32 y, if (tex_comps != st_comps) { - LL_WARNS("Terrain") << "Base texture comps != input texture comps" << LL_ENDL; + llassert(false); return FALSE; } -- cgit v1.2.3 From c583c666d2f463e9de43a571a62b74c3817e5038 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 7 Feb 2024 09:05:25 -0800 Subject: secondlife/viewer#67: (debug) Add temporary setting to force-load PBR terrain --- indra/newview/llvlcomposition.cpp | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index f645023217..7c16ee4f61 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -142,6 +142,27 @@ BOOL LLTerrainMaterials::texturesReady(BOOL boost) BOOL LLTerrainMaterials::materialsReady(BOOL boost) { +#if 1 + static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); + if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce) + { + bool defined = true; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + if (!mDetailMaterials[i]) + { + defined = false; + break; + } + } + if (defined) + { + return TRUE; + } + } +#endif + BOOL ready = TRUE; for (S32 i = 0; i < ASSET_COUNT; i++) { -- cgit v1.2.3 From 9c6e351e05d7e0580700f040af8161da52de7a08 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 8 Feb 2024 13:24:16 -0800 Subject: secondlife/viewer-issues#67: Improve PBR terrain loading robustness --- indra/newview/llvlcomposition.cpp | 128 ++++++++++++++++++++++---------------- 1 file changed, 75 insertions(+), 53 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 7c16ee4f61..c092eb82f3 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -75,12 +75,12 @@ LLTerrainMaterials::~LLTerrainMaterials() BOOL LLTerrainMaterials::generateMaterials() { - if (texturesReady(TRUE)) + if (texturesReady(true, true)) { return TRUE; } - if (materialsReady(TRUE)) + if (materialsReady(true, true)) { return TRUE; } @@ -123,25 +123,41 @@ LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { LL_PROFILE_ZONE_SCOPED; - const BOOL use_textures = texturesReady() || !materialsReady(); + const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false); return use_textures ? Type::TEXTURE : Type::PBR; } -BOOL LLTerrainMaterials::texturesReady(BOOL boost) +bool LLTerrainMaterials::texturesReady(bool boost, bool strict) { - BOOL ready = TRUE; - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (!textureReady(mDetailTextures[i], boost)) + bool ready[ASSET_COUNT]; + // *NOTE: Calls to textureReady may boost textures. Do not early-return. + for (S32 i = 0; i < ASSET_COUNT; i++) + { + ready[i] = textureReady(mDetailTextures[i], boost); + } + + bool one_ready = false; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const bool current_ready = ready[i]; + one_ready = one_ready || current_ready; + if (!current_ready && strict) { - ready = FALSE; + return false; } - } - return ready; + } + return one_ready; } -BOOL LLTerrainMaterials::materialsReady(BOOL boost) +bool LLTerrainMaterials::materialsReady(bool boost, bool strict) { + bool ready[ASSET_COUNT]; + // *NOTE: Calls to materialReady may boost materials/textures. Do not early-return. + for (S32 i = 0; i < ASSET_COUNT; i++) + { + ready[i] = materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost, strict); + } + #if 1 static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); @@ -158,28 +174,31 @@ BOOL LLTerrainMaterials::materialsReady(BOOL boost) } if (defined) { - return TRUE; + return true; } } #endif - BOOL ready = TRUE; - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (!materialReady(mDetailMaterials[i], mMaterialTexturesSet[i], boost)) + bool one_ready = false; + for (S32 i = 0; i < ASSET_COUNT; i++) + { + const bool current_ready = ready[i]; + one_ready = one_ready || current_ready; + if (!current_ready && strict) { - ready = FALSE; + return false; } } - return ready; + return one_ready; } // Boost the texture loading priority // Return true when ready to use (i.e. texture is sufficiently loaded) // static -BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BOOL boost) +bool LLTerrainMaterials::textureReady(LLPointer& tex, bool boost) { - llassert(tex.notNull()); + llassert(tex); + if (!tex) { return false; } if (tex->getDiscardLevel() < 0) { @@ -188,7 +207,7 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail tex->addTextureStats(BASE_SIZE*BASE_SIZE); } - return FALSE; + return false; } if ((tex->getDiscardLevel() != 0 && (tex->getWidth() < BASE_SIZE || @@ -209,23 +228,23 @@ BOOL LLTerrainMaterials::textureReady(LLPointer& tex, BO tex->setMinDiscardLevel(ddiscard); tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } - return FALSE; + return false; } if (tex->getComponents() == 0) { - return FALSE; + return false; } - return TRUE; + return true; } // Boost the loading priority of every known texture in the material -// Return true when ready to use (i.e. material and all textures within are sufficiently loaded) +// Return true when ready to use // static -BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bool& textures_set, BOOL boost) +bool LLTerrainMaterials::materialReady(LLPointer &mat, bool &textures_set, bool boost, bool strict) { if (!mat || !mat->isLoaded()) { - return FALSE; + return false; } // Material is loaded, but textures may not be @@ -234,33 +253,39 @@ BOOL LLTerrainMaterials::materialReady(LLPointer& mat, bo // *NOTE: These can sometimes be set to to nullptr due to // updateTEMaterialTextures. For the sake of robustness, we emulate // that fetching behavior by setting textures of null IDs to nullptr. - mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); - mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); + mat->mBaseColorTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR]); + mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); - mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); - textures_set = true; + mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); + textures_set = true; - return FALSE; + return false; } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].notNull() && !textureReady(mat->mBaseColorTexture, boost)) - { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].notNull() && !textureReady(mat->mNormalTexture, boost)) - { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].notNull() && !textureReady(mat->mMetallicRoughnessTexture, boost)) + // *NOTE: Calls to textureReady may boost textures. Do not early-return. + bool ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT]; + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_BASE_COLOR].isNull() || textureReady(mat->mBaseColorTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL].isNull() || textureReady(mat->mNormalTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS].isNull() || + textureReady(mat->mMetallicRoughnessTexture, boost); + ready[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE] = + mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].isNull() || textureReady(mat->mEmissiveTexture, boost); + + if (strict) { - return FALSE; - } - if (mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE].notNull() && !textureReady(mat->mEmissiveTexture, boost)) - { - return FALSE; + for (U32 i = 0; i < LLGLTFMaterial::GLTF_TEXTURE_INFO_COUNT; ++i) + { + if (!ready[i]) + { + return false; + } + } } - return TRUE; + return true; } @@ -427,16 +452,13 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; - // *TODO: Remove this as it is reduandant computation (first and foremost - // because getMaterialType() does something similar, but also... shouldn't - // the textures/materials already be loaded by now?) if (use_textures) { - if (!texturesReady()) { return FALSE; } + if (!texturesReady(true, true)) { return FALSE; } } else { - if (!materialsReady()) { return FALSE; } + if (!materialsReady(true, true)) { return FALSE; } } for (S32 i = 0; i < ASSET_COUNT; i++) -- cgit v1.2.3 From 2cbf4a15df940d92d38003d302e61fda14e1dc51 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 9 Feb 2024 12:34:02 -0800 Subject: secondlife/viewer#773: Fix RenderTerrainPBREnabled requiring restart and respect simulator feature PBRTerrainEnabled --- indra/newview/llvlcomposition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index c092eb82f3..09b21e4e0a 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -159,7 +159,7 @@ bool LLTerrainMaterials::materialsReady(bool boost, bool strict) } #if 1 - static bool sRenderTerrainPBREnabled = gSavedSettings.get("RenderTerrainPBREnabled"); + static LLCachedControl sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false); static LLCachedControl sRenderTerrainPBRForce(gSavedSettings, "RenderTerrainPBRForce", false); if (sRenderTerrainPBREnabled && sRenderTerrainPBRForce) { -- cgit v1.2.3 From d79498e25991e425510643ecd1303a5675c5fbf6 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 28 Feb 2024 15:02:18 -0800 Subject: secondlife/viewer#712: More intuitive selection of PBR vs texture terrain, and update dropdown to match --- indra/newview/llvlcomposition.cpp | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 09b21e4e0a..9c64381a07 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -91,10 +91,10 @@ BOOL LLTerrainMaterials::generateMaterials() LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { llassert(mDetailTextures[asset] && mDetailMaterials[asset]); - // *HACK: Assume both the the material and texture were fetched in the same - // way using the same UUID. However, we may not know at this point which - // one will load. - return mDetailTextures[asset]->getID(); + // Assume both the the material and texture were fetched in the same way + // using the same UUID. However, we may not know at this point which one + // will load. + return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -133,7 +133,7 @@ bool LLTerrainMaterials::texturesReady(bool boost, bool strict) // *NOTE: Calls to textureReady may boost textures. Do not early-return. for (S32 i = 0; i < ASSET_COUNT; i++) { - ready[i] = textureReady(mDetailTextures[i], boost); + ready[i] = mDetailTextures[i].notNull() && textureReady(mDetailTextures[i], boost); } bool one_ready = false; @@ -250,6 +250,7 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo // Material is loaded, but textures may not be if (!textures_set) { + textures_set = true; // *NOTE: These can sometimes be set to to nullptr due to // updateTEMaterialTextures. For the sake of robustness, we emulate // that fetching behavior by setting textures of null IDs to nullptr. @@ -257,9 +258,6 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo mat->mNormalTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_NORMAL]); mat->mMetallicRoughnessTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_METALLIC_ROUGHNESS]); mat->mEmissiveTexture = fetch_terrain_texture(mat->mTextureId[LLGLTFMaterial::GLTF_TEXTURE_INFO_EMISSIVE]); - textures_set = true; - - return false; } // *NOTE: Calls to textureReady may boost textures. Do not early-return. -- cgit v1.2.3 From 0cb9e7f7e5bd02ded8b9f2bd9cd6c57a70187dcc Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 29 Feb 2024 16:52:35 -0800 Subject: secondlife/viewer#712: Remember previously set textures/materials when possible. Not persistent. --- indra/newview/llvlcomposition.cpp | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 9c64381a07..506ab005c5 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -44,7 +44,6 @@ static const U32 BASE_SIZE = 128; - F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) { // Not sure if this is the right math... @@ -286,16 +285,29 @@ bool LLTerrainMaterials::materialReady(LLPointer &mat, bo return true; } +// static +const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT] +{ + const static LLUUID default_textures[LLVLComposition::ASSET_COUNT] = + { + TERRAIN_DIRT_DETAIL, + TERRAIN_GRASS_DETAIL, + TERRAIN_MOUNTAIN_DETAIL, + TERRAIN_ROCK_DETAIL + }; + return default_textures; +} LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : LLTerrainMaterials(), LLViewerLayer(width, scale) { // Load Terrain Textures - Original ones - setDetailAssetID(0, TERRAIN_DIRT_DETAIL); - setDetailAssetID(1, TERRAIN_GRASS_DETAIL); - setDetailAssetID(2, TERRAIN_MOUNTAIN_DETAIL); - setDetailAssetID(3, TERRAIN_ROCK_DETAIL); + const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + setDetailAssetID(i, default_textures[i]); + } mSurfacep = surfacep; -- cgit v1.2.3 From 96933d05ec8af6e9b5e8cee11c18232027e74ff5 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 20 Mar 2024 17:07:44 -0700 Subject: secondlife/viewer#1027: Fix noise on transparent PBR materials on minimap --- indra/newview/llvlcomposition.cpp | 15 +++++++++++++++ 1 file changed, 15 insertions(+) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 506ab005c5..6b42804a90 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -42,6 +42,8 @@ #include "llviewercontrol.h" +extern LLColor4U MAX_WATER_COLOR; + static const U32 BASE_SIZE = 128; F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) @@ -480,6 +482,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, LLViewerFetchedTexture* tex_emissive; // Can be null bool has_base_color_factor; bool has_emissive_factor; + bool has_alpha; LLColor3 base_color_factor; LLColor3 emissive_factor; if (use_textures) @@ -488,6 +491,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, tex_emissive = nullptr; has_base_color_factor = false; has_emissive_factor = false; + has_alpha = false; llassert(tex); } else @@ -504,6 +508,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, has_emissive_factor = (emissive_factor.mV[VX] != 1.f || emissive_factor.mV[VY] != 1.f || emissive_factor.mV[VZ] != 1.f); + has_alpha = mDetailMaterials[i]->mAlphaMode != LLGLTFMaterial::ALPHA_MODE_OPAQUE; } if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } @@ -588,11 +593,21 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } if (has_base_color_factor || raw_emissive || + has_alpha || tex->getWidth(ddiscard) != BASE_SIZE || tex->getHeight(ddiscard) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); + if (has_alpha) + { + // Approximate the water underneath terrain alpha with solid water color + newraw->clear( + MAX_WATER_COLOR.mV[VX], + MAX_WATER_COLOR.mV[VY], + MAX_WATER_COLOR.mV[VZ], + 255); + } newraw->composite(mRawImages[i]); if (has_base_color_factor) { -- cgit v1.2.3 From 7c92398cf6d0c588a9e3504f107eb1d513877234 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Mon, 25 Mar 2024 15:04:08 -0700 Subject: secondlife/viewer#759: Fix minimap loading for 2k PBR materials, and probably other odd cases --- indra/newview/llvlcomposition.cpp | 130 +++++++++++++++++++++++++++----------- 1 file changed, 93 insertions(+), 37 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 6b42804a90..234b24e440 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -46,21 +46,40 @@ extern LLColor4U MAX_WATER_COLOR; static const U32 BASE_SIZE = 128; -F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) +namespace { - // Not sure if this is the right math... - // Take weighted average of all four points (bilinear interpolation) - F32 result; - - const F32 inv_x_frac = 1.f - x_frac; - const F32 inv_y_frac = 1.f - y_frac; - result = inv_x_frac*inv_y_frac*v00 - + x_frac*inv_y_frac*v10 - + inv_x_frac*y_frac*v01 - + x_frac*y_frac*v11; - - return result; -} + F32 bilinear(const F32 v00, const F32 v01, const F32 v10, const F32 v11, const F32 x_frac, const F32 y_frac) + { + // Not sure if this is the right math... + // Take weighted average of all four points (bilinear interpolation) + F32 result; + + const F32 inv_x_frac = 1.f - x_frac; + const F32 inv_y_frac = 1.f - y_frac; + result = inv_x_frac*inv_y_frac*v00 + + x_frac*inv_y_frac*v10 + + inv_x_frac*y_frac*v01 + + x_frac*y_frac*v11; + + return result; + } + + void unboost_minimap_texture(LLPointer& tex) + { + if (!tex) { return; } + tex->setBoostLevel(LLGLTexture::BOOST_NONE); + tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); + } + + void unboost_minimap_material(LLPointer& mat) + { + if (!mat) { return; } + unboost_minimap_texture(mat->mBaseColorTexture); + unboost_minimap_texture(mat->mNormalTexture); + unboost_minimap_texture(mat->mMetallicRoughnessTexture); + unboost_minimap_texture(mat->mEmissiveTexture); + } +}; LLTerrainMaterials::LLTerrainMaterials() { @@ -514,21 +533,47 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } // tex_emissive can be null, and then will be ignored - S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); - S32 ddiscard = 0; - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; + S32 ddiscard = 0; + { + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + } + + S32 ddiscard_emissive = 0; + if (tex_emissive) + { + S32 min_dim_emissive = llmin(tex_emissive->getFullWidth(), tex_emissive->getFullHeight()); + while (min_dim_emissive > BASE_SIZE && ddiscard_emissive < MAX_DISCARD_LEVEL) + { + ddiscard_emissive++; + min_dim_emissive /= 2; + } } - BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL) ; + // *NOTE: It is probably safe to call destroyRawImage no matter + // what, as LLViewerFetchedTexture::mRawImage is managed by + // LLPointer and not modified with the rare exception of + // icons (see BOOST_ICON). Nevertheless, gate this fix for now, as + // it may have unintended consequences on texture loading. + // We may want to also set the boost level in setDetailAssetID, but + // that is not guaranteed to work if a texture is loaded on an object + // before being loaded as terrain, so we will need this fix + // regardless. + static LLCachedControl sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false); + BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL || sRenderTerrainPBREnabled); + BOOL delete_raw_emissive = (tex_emissive && + (tex_emissive->reloadRawImage(ddiscard_emissive) != NULL || sRenderTerrainPBREnabled)); + if(tex->getRawImageLevel() != ddiscard) { // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - tex->setBoostLevel(LLGLTexture::BOOST_MAP); + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); tex->forceToRefetchTexture(ddiscard); } @@ -540,16 +585,16 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } if (tex_emissive) { - if(tex_emissive->getRawImageLevel() != ddiscard) + if(tex_emissive->getRawImageLevel() != ddiscard_emissive) { // Raw image is not ready, will enter here again later. if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) { - tex_emissive->setBoostLevel(LLGLTexture::BOOST_MAP); - tex_emissive->forceToRefetchTexture(ddiscard); + tex_emissive->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + tex_emissive->forceToRefetchTexture(ddiscard_emissive); } - if(delete_raw) + if(delete_raw_emissive) { tex_emissive->destroyRawImage() ; } @@ -577,8 +622,8 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { raw_emissive = tex_emissive->getRawImage(); if (has_emissive_factor || - tex_emissive->getWidth(ddiscard) != BASE_SIZE || - tex_emissive->getHeight(ddiscard) != BASE_SIZE || + tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE || + tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE || tex_emissive->getComponents() != 4) { LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); @@ -588,14 +633,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { newraw_emissive->tint(emissive_factor); } - raw_emissive = newraw_emissive; // deletes old + raw_emissive = newraw_emissive; } } if (has_base_color_factor || raw_emissive || has_alpha || - tex->getWidth(ddiscard) != BASE_SIZE || - tex->getHeight(ddiscard) != BASE_SIZE || + tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE || + tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || tex->getComponents() != 3) { LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); @@ -618,8 +663,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { newraw->composite(raw_emissive); } + mRawImages[i] = newraw; // deletes old } + + if (delete_raw_emissive) + { + tex_emissive->destroyRawImage(); + } } st_data[i] = mRawImages[i]->getData(); st_data_size[i] = mRawImages[i]->getDataSize(); @@ -765,12 +816,17 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); - for (S32 i = 0; i < ASSET_COUNT; i++) - { - // Un-boost detatil textures (will get re-boosted if rendering in high detail) - mDetailTextures[i]->setBoostLevel(LLGLTexture::BOOST_NONE); - mDetailTextures[i]->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); - } + // Un-boost detail textures (will get re-boosted if rendering in high detail) + for (S32 i = 0; i < ASSET_COUNT; i++) + { + unboost_minimap_texture(mDetailTextures[i]); + } + + // Un-boost textures for each detail material (will get re-boosted if rendering in high detail) + for (S32 i = 0; i < ASSET_COUNT; i++) + { + unboost_minimap_material(mDetailMaterials[i]); + } return TRUE; } -- cgit v1.2.3 From b7b962affd12d8559d3dcf8a70533548df8d6f25 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Wed, 10 Apr 2024 09:59:18 -0700 Subject: viewer#1163: Unboost terrain textures when done to allow deletion --- indra/newview/llvlcomposition.cpp | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 234b24e440..6c0691c6a9 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -69,6 +69,11 @@ namespace if (!tex) { return; } tex->setBoostLevel(LLGLTexture::BOOST_NONE); tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); + + if (tex->getTextureState() == LLGLTexture::NO_DELETE) + { + tex->forceActive(); + } } void unboost_minimap_material(LLPointer& mat) @@ -91,6 +96,11 @@ LLTerrainMaterials::LLTerrainMaterials() LLTerrainMaterials::~LLTerrainMaterials() { + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + unboost_minimap_texture(mDetailTextures[i]); + unboost_minimap_material(mDetailMaterials[i]); + } } BOOL LLTerrainMaterials::generateMaterials() @@ -131,6 +141,12 @@ LLPointer fetch_terrain_texture(const LLUUID& id) void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) { + // *NOTE: If there were multiple terrain swatches using the same asset + // ID, the asset still in use will be temporarily unboosted. + // It will be boosted again during terrain rendering. + unboost_minimap_texture(mDetailTextures[asset]); + unboost_minimap_material(mDetailMaterials[asset]); + // This is terrain texture, but we are not setting it as BOOST_TERRAIN // since we will be manipulating it later as needed. mDetailTextures[asset] = fetch_terrain_texture(id); -- cgit v1.2.3 From 47255bf44d04e5ba7b33d44f8cc738da4be9d53a Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 11 Apr 2024 17:26:02 -0700 Subject: secondlife/viewer#1184: Stop making terrain textures undeletable --- indra/newview/llvlcomposition.cpp | 79 +++++++++++++++++++++++++++------------ 1 file changed, 56 insertions(+), 23 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 6c0691c6a9..6955949571 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -45,6 +45,7 @@ extern LLColor4U MAX_WATER_COLOR; static const U32 BASE_SIZE = 128; +static const F32 TERRAIN_DECODE_PRIORITY = 2048.f * 2048.f; namespace { @@ -64,25 +65,38 @@ namespace return result; } - void unboost_minimap_texture(LLPointer& tex) + void boost_minimap_texture(LLViewerFetchedTexture* tex, F32 virtual_size) + { + llassert(tex); + if (!tex) { return; } + + tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case the raw image is at low detail + tex->addTextureStats(virtual_size); // priority + } + + void boost_minimap_material(LLFetchedGLTFMaterial* mat, F32 virtual_size) + { + if (!mat) { return; } + if (mat->mBaseColorTexture) { boost_minimap_texture(mat->mBaseColorTexture, virtual_size); } + if (mat->mNormalTexture) { boost_minimap_texture(mat->mNormalTexture, virtual_size); } + if (mat->mMetallicRoughnessTexture) { boost_minimap_texture(mat->mMetallicRoughnessTexture, virtual_size); } + if (mat->mEmissiveTexture) { boost_minimap_texture(mat->mEmissiveTexture, virtual_size); } + } + + void unboost_minimap_texture(LLViewerFetchedTexture* tex) { if (!tex) { return; } tex->setBoostLevel(LLGLTexture::BOOST_NONE); tex->setMinDiscardLevel(MAX_DISCARD_LEVEL + 1); - - if (tex->getTextureState() == LLGLTexture::NO_DELETE) - { - tex->forceActive(); - } } - void unboost_minimap_material(LLPointer& mat) + void unboost_minimap_material(LLFetchedGLTFMaterial* mat) { if (!mat) { return; } - unboost_minimap_texture(mat->mBaseColorTexture); - unboost_minimap_texture(mat->mNormalTexture); - unboost_minimap_texture(mat->mMetallicRoughnessTexture); - unboost_minimap_texture(mat->mEmissiveTexture); + if (mat->mBaseColorTexture) { unboost_minimap_texture(mat->mBaseColorTexture); } + if (mat->mNormalTexture) { unboost_minimap_texture(mat->mNormalTexture); } + if (mat->mMetallicRoughnessTexture) { unboost_minimap_texture(mat->mMetallicRoughnessTexture); } + if (mat->mEmissiveTexture) { unboost_minimap_texture(mat->mEmissiveTexture); } } }; @@ -96,11 +110,7 @@ LLTerrainMaterials::LLTerrainMaterials() LLTerrainMaterials::~LLTerrainMaterials() { - for (S32 i = 0; i < ASSET_COUNT; ++i) - { - unboost_minimap_texture(mDetailTextures[i]); - unboost_minimap_material(mDetailMaterials[i]); - } + unboost(); } BOOL LLTerrainMaterials::generateMaterials() @@ -118,6 +128,31 @@ BOOL LLTerrainMaterials::generateMaterials() return FALSE; } +void LLTerrainMaterials::boost() +{ + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + LLPointer& tex = mDetailTextures[i]; + llassert(tex.notNull()); + boost_minimap_texture(tex, TERRAIN_DECODE_PRIORITY); + + LLPointer& mat = mDetailMaterials[i]; + boost_minimap_material(mat, TERRAIN_DECODE_PRIORITY); + } +} + +void LLTerrainMaterials::unboost() +{ + for (S32 i = 0; i < ASSET_COUNT; ++i) + { + LLPointer& tex = mDetailTextures[i]; + unboost_minimap_texture(tex); + + LLPointer& mat = mDetailMaterials[i]; + unboost_minimap_material(mat); + } +} + LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) { llassert(mDetailTextures[asset] && mDetailMaterials[asset]); @@ -135,7 +170,6 @@ LLPointer fetch_terrain_texture(const LLUUID& id) } LLPointer tex = LLViewerTextureManager::getFetchedTexture(id); - tex->setNoDelete(); return tex; } @@ -240,8 +274,7 @@ bool LLTerrainMaterials::textureReady(LLPointer& tex, bo { if (boost) { - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail - tex->addTextureStats(BASE_SIZE*BASE_SIZE); + boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE); } return false; } @@ -251,6 +284,8 @@ bool LLTerrainMaterials::textureReady(LLPointer& tex, bo { if (boost) { + boost_minimap_texture(tex, BASE_SIZE*BASE_SIZE); + S32 width = tex->getFullWidth(); S32 height = tex->getFullHeight(); S32 min_dim = llmin(width, height); @@ -260,9 +295,7 @@ bool LLTerrainMaterials::textureReady(LLPointer& tex, bo ddiscard++; min_dim /= 2; } - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); // in case we are at low detail tex->setMinDiscardLevel(ddiscard); - tex->addTextureStats(BASE_SIZE*BASE_SIZE); // priority } return false; } @@ -589,7 +622,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, // Raw image is not ready, will enter here again later. if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) { - tex->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + boost_minimap_texture(tex, TERRAIN_DECODE_PRIORITY); tex->forceToRefetchTexture(ddiscard); } @@ -606,7 +639,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, // Raw image is not ready, will enter here again later. if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) { - tex_emissive->setBoostLevel(LLGLTexture::BOOST_TERRAIN); + boost_minimap_texture(tex_emissive, TERRAIN_DECODE_PRIORITY); tex_emissive->forceToRefetchTexture(ddiscard_emissive); } -- cgit v1.2.3 From aac18ada713aa34cafe477264ab08d5f1ba4e205 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Fri, 12 Apr 2024 11:27:24 -0700 Subject: secondlife/viewer#1184: Use more robust/memory-friendly setLoadedCallback for minimap gen. Fix some emissive maps. --- indra/newview/llvlcomposition.cpp | 208 +++++++++++++++++++++++--------------- 1 file changed, 127 insertions(+), 81 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 6955949571..b915cce933 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -28,6 +28,8 @@ #include "llvlcomposition.h" +#include + #include "llerror.h" #include "v3math.h" #include "llsurface.h" @@ -513,6 +515,108 @@ BOOL LLVLComposition::generateComposition() return LLTerrainMaterials::generateMaterials(); } +namespace +{ + void prepare_fallback_image(LLImageRaw* raw_image) + { + raw_image->resize(BASE_SIZE, BASE_SIZE, 4); + raw_image->fill(LLColor4U::white); + } + + // Check if the raw image is loaded for this texture at a discard + // level the minimap can use, and if not then try to get it loaded. + bool prepare_raw_image(LLPointer& raw_image, bool emissive, LLViewerFetchedTexture* tex, bool& delete_raw_post) + { + if (!tex) + { + if (!emissive) + { + prepare_fallback_image(raw_image); + } + else + { + llassert(!raw_image); + raw_image = nullptr; + } + return true; + } + if (raw_image) + { + // Callback already initiated + if (raw_image->getDataSize() > 0) + { + // Callback finished + delete_raw_post = true; + return true; + } + else + { + return false; + } + } + + raw_image = new LLImageRaw(); + + S32 ddiscard = 0; + { + S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); + while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) + { + ddiscard++; + min_dim /= 2; + } + } + + struct PendingImage + { + LLImageRaw* mRawImage; + S32 mDesiredDiscard; + LLUUID mTextureId; + PendingImage(LLImageRaw* raw_image, S32 ddiscard, const LLUUID& texture_id) + : mRawImage(raw_image) + , mDesiredDiscard(ddiscard) + , mTextureId(texture_id) + { + mRawImage->ref(); + } + ~PendingImage() + { + mRawImage->unref(); + } + }; + PendingImage* pending_image = new PendingImage(raw_image, ddiscard, tex->getID()); + + loaded_callback_func cb = [](BOOL success, LLViewerFetchedTexture * src_vi, LLImageRaw * src, LLImageRaw * src_aux, S32 discard_level, BOOL is_final, void* userdata) { + PendingImage* pending = (PendingImage*)userdata; + // Owning LLVLComposition still exists + + // Assume mRawImage only used by single LLVLComposition for now + const bool in_use_by_composition = pending->mRawImage->getNumRefs() > 1; + llassert(pending->mRawImage->getNumRefs()); + llassert(pending->mRawImage->getNumRefs() <= 2); + const bool needs_data = !pending->mRawImage->getDataSize(); + if (in_use_by_composition && needs_data) + { + if (success && pending->mDesiredDiscard == discard_level) + { + pending->mRawImage->resize(BASE_SIZE, BASE_SIZE, src->getComponents()); + pending->mRawImage->copyScaled(src); + } + else if (is_final) + { + prepare_fallback_image(pending->mRawImage); + } + } + + if (is_final) { delete userdata; } + }; + tex->setLoadedCallback(cb, ddiscard, true, false, pending_image, nullptr); + tex->forceToSaveRawImage(ddiscard); + + return false; + } +}; + BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, const F32 width, const F32 height) { @@ -580,96 +684,28 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, } if (!tex) { tex = LLViewerFetchedTexture::sWhiteImagep; } - // tex_emissive can be null, and then will be ignored - - S32 ddiscard = 0; - { - S32 min_dim = llmin(tex->getFullWidth(), tex->getFullHeight()); - while (min_dim > BASE_SIZE && ddiscard < MAX_DISCARD_LEVEL) - { - ddiscard++; - min_dim /= 2; - } - } - - S32 ddiscard_emissive = 0; - if (tex_emissive) - { - S32 min_dim_emissive = llmin(tex_emissive->getFullWidth(), tex_emissive->getFullHeight()); - while (min_dim_emissive > BASE_SIZE && ddiscard_emissive < MAX_DISCARD_LEVEL) - { - ddiscard_emissive++; - min_dim_emissive /= 2; - } - } - - // *NOTE: It is probably safe to call destroyRawImage no matter - // what, as LLViewerFetchedTexture::mRawImage is managed by - // LLPointer and not modified with the rare exception of - // icons (see BOOST_ICON). Nevertheless, gate this fix for now, as - // it may have unintended consequences on texture loading. - // We may want to also set the boost level in setDetailAssetID, but - // that is not guaranteed to work if a texture is loaded on an object - // before being loaded as terrain, so we will need this fix - // regardless. - static LLCachedControl sRenderTerrainPBREnabled(gSavedSettings, "RenderTerrainPBREnabled", false); - BOOL delete_raw = (tex->reloadRawImage(ddiscard) != NULL || sRenderTerrainPBREnabled); - BOOL delete_raw_emissive = (tex_emissive && - (tex_emissive->reloadRawImage(ddiscard_emissive) != NULL || sRenderTerrainPBREnabled)); - - if(tex->getRawImageLevel() != ddiscard) - { - // Raw image is not ready, will enter here again later. - if (tex->getFetchPriority() <= 0.0f && !tex->hasSavedRawImage()) - { - boost_minimap_texture(tex, TERRAIN_DECODE_PRIORITY); - tex->forceToRefetchTexture(ddiscard); - } - - if(delete_raw) - { - tex->destroyRawImage() ; - } - return FALSE; - } - if (tex_emissive) - { - if(tex_emissive->getRawImageLevel() != ddiscard_emissive) - { - // Raw image is not ready, will enter here again later. - if (tex_emissive->getFetchPriority() <= 0.0f && !tex_emissive->hasSavedRawImage()) - { - boost_minimap_texture(tex_emissive, TERRAIN_DECODE_PRIORITY); - tex_emissive->forceToRefetchTexture(ddiscard_emissive); - } - if(delete_raw_emissive) - { - tex_emissive->destroyRawImage() ; - } - return FALSE; - } - } + bool delete_raw_post = false; + bool delete_raw_post_emissive = false; + if (!prepare_raw_image(mRawImagesBaseColor[i], false, tex, delete_raw_post)) { return FALSE; } + if (tex_emissive && !prepare_raw_image(mRawImagesEmissive[i], true, tex_emissive, delete_raw_post_emissive)) { return FALSE; } + // tex_emissive can be null, and then will be ignored - mRawImages[i] = tex->getRawImage() ; - if(delete_raw) - { - tex->destroyRawImage() ; - } + // In the simplest case, the minimap image is just the base color. + // This will be replaced if we need to do any tinting/compositing. + mRawImages[i] = mRawImagesBaseColor[i]; // *TODO: This isn't quite right for PBR: // 1) It does not convert the color images from SRGB to linear // before mixing (which will always require copying the image). // 2) It mixes emissive and base color before mixing terrain // materials, but it should be the other way around - // 3) The composite function used to put emissive into base color - // is not an alpha blend. // Long-term, we should consider a method that is more // maintainable. Shaders, perhaps? Bake shaders to textures? LLPointer raw_emissive; if (tex_emissive) { - raw_emissive = tex_emissive->getRawImage(); + raw_emissive = mRawImagesEmissive[i]; if (has_emissive_factor || tex_emissive->getWidth(tex_emissive->getRawImageLevel()) != BASE_SIZE || tex_emissive->getHeight(tex_emissive->getRawImageLevel()) != BASE_SIZE || @@ -677,7 +713,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { LLPointer newraw_emissive = new LLImageRaw(BASE_SIZE, BASE_SIZE, 4); // Copy RGB, leave alpha alone (set to opaque by default) - newraw_emissive->copy(mRawImages[i]); + newraw_emissive->copy(mRawImagesEmissive[i]); if (has_emissive_factor) { newraw_emissive->tint(emissive_factor); @@ -702,7 +738,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, MAX_WATER_COLOR.mV[VZ], 255); } - newraw->composite(mRawImages[i]); + newraw->composite(mRawImagesBaseColor[i]); if (has_base_color_factor) { newraw->tint(base_color_factor); @@ -710,16 +746,24 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, // Apply emissive texture if (raw_emissive) { - newraw->composite(raw_emissive); + newraw->addEmissive(raw_emissive); } mRawImages[i] = newraw; // deletes old } - if (delete_raw_emissive) + if (delete_raw_post) + { + tex->destroyRawImage(); + } + if (delete_raw_post_emissive) { tex_emissive->destroyRawImage(); } + + // Remove intermediary image references + mRawImagesBaseColor[i] = nullptr; + mRawImagesEmissive[i] = nullptr; } st_data[i] = mRawImages[i]->getData(); st_data_size[i] = mRawImages[i]->getDataSize(); @@ -893,6 +937,8 @@ void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) } LLTerrainMaterials::setDetailAssetID(asset, id); mRawImages[asset] = NULL; + mRawImagesBaseColor[asset] = NULL; + mRawImagesEmissive[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) -- cgit v1.2.3 From 19c05046713a2d6b439eee3418baa54a904429f1 Mon Sep 17 00:00:00 2001 From: Cosmic Linden Date: Thu, 25 Apr 2024 17:33:02 -0700 Subject: secondlife/viewer#1184: Fix mac build --- indra/newview/llvlcomposition.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index b915cce933..8d3b5cc8a5 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -608,7 +608,7 @@ namespace } } - if (is_final) { delete userdata; } + if (is_final) { delete pending; } }; tex->setLoadedCallback(cb, ddiscard, true, false, pending_image, nullptr); tex->forceToSaveRawImage(ddiscard); -- cgit v1.2.3 From b06a99f7c76950484972e25d9dbbee8660a6a6c3 Mon Sep 17 00:00:00 2001 From: Andrey Lihatskiy Date: Wed, 15 May 2024 12:47:27 +0300 Subject: Post-merge spaces fix --- indra/newview/llvlcomposition.cpp | 596 +++++++++++++++++++------------------- 1 file changed, 298 insertions(+), 298 deletions(-) (limited to 'indra/newview/llvlcomposition.cpp') diff --git a/indra/newview/llvlcomposition.cpp b/indra/newview/llvlcomposition.cpp index 8d3b5cc8a5..1ffbf20410 100644 --- a/indra/newview/llvlcomposition.cpp +++ b/indra/newview/llvlcomposition.cpp @@ -1,25 +1,25 @@ -/** +/** * @file llvlcomposition.cpp * @brief Viewer-side representation of a composition layer... * * $LicenseInfo:firstyear=2001&license=viewerlgpl$ * Second Life Viewer Source Code * Copyright (C) 2010, 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$ */ @@ -161,7 +161,7 @@ LLUUID LLTerrainMaterials::getDetailAssetID(S32 asset) // Assume both the the material and texture were fetched in the same way // using the same UUID. However, we may not know at this point which one // will load. - return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; + return mDetailTextures[asset] ? mDetailTextures[asset]->getID() : LLUUID::null; } LLPointer fetch_terrain_texture(const LLUUID& id) @@ -183,9 +183,9 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) unboost_minimap_texture(mDetailTextures[asset]); unboost_minimap_material(mDetailMaterials[asset]); - // This is terrain texture, but we are not setting it as BOOST_TERRAIN - // since we will be manipulating it later as needed. - mDetailTextures[asset] = fetch_terrain_texture(id); + // This is terrain texture, but we are not setting it as BOOST_TERRAIN + // since we will be manipulating it later as needed. + mDetailTextures[asset] = fetch_terrain_texture(id); LLPointer& mat = mDetailMaterials[asset]; mat = id.isNull() ? nullptr : gGLTFMaterialList.getMaterial(id); mMaterialTexturesSet[asset] = false; @@ -193,7 +193,7 @@ void LLTerrainMaterials::setDetailAssetID(S32 asset, const LLUUID& id) LLTerrainMaterials::Type LLTerrainMaterials::getMaterialType() { - LL_PROFILE_ZONE_SCOPED; + LL_PROFILE_ZONE_SCOPED; const BOOL use_textures = texturesReady(false, false) || !materialsReady(false, false); return use_textures ? Type::TEXTURE : Type::PBR; @@ -372,23 +372,23 @@ const LLUUID (&LLVLComposition::getDefaultTextures())[ASSET_COUNT] LLVLComposition::LLVLComposition(LLSurface *surfacep, const U32 width, const F32 scale) : LLTerrainMaterials(), - LLViewerLayer(width, scale) + LLViewerLayer(width, scale) { - // Load Terrain Textures - Original ones + // Load Terrain Textures - Original ones const LLUUID (&default_textures)[LLVLComposition::ASSET_COUNT] = LLVLComposition::getDefaultTextures(); for (S32 i = 0; i < ASSET_COUNT; ++i) { setDetailAssetID(i, default_textures[i]); } - mSurfacep = surfacep; + mSurfacep = surfacep; - // Initialize the texture matrix to defaults. - for (S32 i = 0; i < CORNER_COUNT; ++i) - { - mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); - mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); - } + // Initialize the texture matrix to defaults. + for (S32 i = 0; i < CORNER_COUNT; ++i) + { + mStartHeight[i] = gSavedSettings.getF32("TerrainColorStartHeight"); + mHeightRange[i] = gSavedSettings.getF32("TerrainColorHeightRange"); + } } @@ -400,117 +400,117 @@ LLVLComposition::~LLVLComposition() void LLVLComposition::setSurface(LLSurface *surfacep) { - mSurfacep = surfacep; + mSurfacep = surfacep; } BOOL LLVLComposition::generateHeights(const F32 x, const F32 y, - const F32 width, const F32 height) + const F32 width, const F32 height) { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } - - llassert(mSurfacep); - - if (!mSurfacep || !mSurfacep->getRegion()) - { - // We don't always have the region yet here.... - return FALSE; - } - - S32 x_begin, y_begin, x_end, y_end; - - x_begin = ll_round( x * mScaleInv ); - y_begin = ll_round( y * mScaleInv ); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); - - if (x_end > mWidth) - { - x_end = mWidth; - } - if (y_end > mWidth) - { - y_end = mWidth; - } - - LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); - - // For perlin noise generation... - const F32 slope_squared = 1.5f*1.5f; - const F32 xyScale = 4.9215f; //0.93284f; - const F32 zScale = 4; //0.92165f; - const F32 z_offset = 0.f; - const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus - // simple height) - - const F32 xyScaleInv = (1.f / xyScale); - const F32 zScaleInv = (1.f / zScale); - - const F32 inv_width = 1.f/mWidth; - - // OK, for now, just have the composition value equal the height at the point. - for (S32 j = y_begin; j < y_end; j++) - { - for (S32 i = x_begin; i < x_end; i++) - { - - F32 vec[3]; - F32 vec1[3]; - F32 twiddle; - - // Bilinearly interpolate the start height and height range of the textures - F32 start_height = bilinear(mStartHeight[SOUTHWEST], - mStartHeight[SOUTHEAST], - mStartHeight[NORTHWEST], - mStartHeight[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - F32 height_range = bilinear(mHeightRange[SOUTHWEST], - mHeightRange[SOUTHEAST], - mHeightRange[NORTHWEST], - mHeightRange[NORTHEAST], - i*inv_width, j*inv_width); // These will be bilinearly interpolated - - LLVector3 location(i*mScale, j*mScale, 0.f); - - F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; - - // Step 0: Measure the exact height at this texel - vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice - vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; - vec[2] = height*zScaleInv; - // - // Choose material value by adding to the exact height a random value - // - vec1[0] = vec[0]*(0.2222222222f); - vec1[1] = vec[1]*(0.2222222222f); - vec1[2] = vec[2]*(0.2222222222f); - twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions - - twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component - twiddle *= noise_magnitude; - - F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; - - scaled_noisy_height = llmax(0.f, scaled_noisy_height); - scaled_noisy_height = llmin(3.f, scaled_noisy_height); - *(mDatap + i + j*mWidth) = scaled_noisy_height; - } - } - return TRUE; + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } + + llassert(mSurfacep); + + if (!mSurfacep || !mSurfacep->getRegion()) + { + // We don't always have the region yet here.... + return FALSE; + } + + S32 x_begin, y_begin, x_end, y_end; + + x_begin = ll_round( x * mScaleInv ); + y_begin = ll_round( y * mScaleInv ); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { + x_end = mWidth; + } + if (y_end > mWidth) + { + y_end = mWidth; + } + + LLVector3d origin_global = from_region_handle(mSurfacep->getRegion()->getHandle()); + + // For perlin noise generation... + const F32 slope_squared = 1.5f*1.5f; + const F32 xyScale = 4.9215f; //0.93284f; + const F32 zScale = 4; //0.92165f; + const F32 z_offset = 0.f; + const F32 noise_magnitude = 2.f; // Degree to which noise modulates composition layer (versus + // simple height) + + const F32 xyScaleInv = (1.f / xyScale); + const F32 zScaleInv = (1.f / zScale); + + const F32 inv_width = 1.f/mWidth; + + // OK, for now, just have the composition value equal the height at the point. + for (S32 j = y_begin; j < y_end; j++) + { + for (S32 i = x_begin; i < x_end; i++) + { + + F32 vec[3]; + F32 vec1[3]; + F32 twiddle; + + // Bilinearly interpolate the start height and height range of the textures + F32 start_height = bilinear(mStartHeight[SOUTHWEST], + mStartHeight[SOUTHEAST], + mStartHeight[NORTHWEST], + mStartHeight[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + F32 height_range = bilinear(mHeightRange[SOUTHWEST], + mHeightRange[SOUTHEAST], + mHeightRange[NORTHWEST], + mHeightRange[NORTHEAST], + i*inv_width, j*inv_width); // These will be bilinearly interpolated + + LLVector3 location(i*mScale, j*mScale, 0.f); + + F32 height = mSurfacep->resolveHeightRegion(location) + z_offset; + + // Step 0: Measure the exact height at this texel + vec[0] = (F32)(origin_global.mdV[VX]+location.mV[VX])*xyScaleInv; // Adjust to non-integer lattice + vec[1] = (F32)(origin_global.mdV[VY]+location.mV[VY])*xyScaleInv; + vec[2] = height*zScaleInv; + // + // Choose material value by adding to the exact height a random value + // + vec1[0] = vec[0]*(0.2222222222f); + vec1[1] = vec[1]*(0.2222222222f); + vec1[2] = vec[2]*(0.2222222222f); + twiddle = noise2(vec1)*6.5f; // Low freq component for large divisions + + twiddle += turbulence2(vec, 2)*slope_squared; // High frequency component + twiddle *= noise_magnitude; + + F32 scaled_noisy_height = (height + twiddle - start_height) * F32(ASSET_COUNT) / height_range; + + scaled_noisy_height = llmax(0.f, scaled_noisy_height); + scaled_noisy_height = llmin(3.f, scaled_noisy_height); + *(mDatap + i + j*mWidth) = scaled_noisy_height; + } + } + return TRUE; } LLTerrainMaterials gLocalTerrainMaterials; BOOL LLVLComposition::generateComposition() { - if (!mParamsReady) - { - // All the parameters haven't been set yet (we haven't gotten the message from the sim) - return FALSE; - } + if (!mParamsReady) + { + // All the parameters haven't been set yet (we haven't gotten the message from the sim) + return FALSE; + } return LLTerrainMaterials::generateMaterials(); } @@ -618,22 +618,22 @@ namespace }; BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, - const F32 width, const F32 height) + const F32 width, const F32 height) { - LL_PROFILE_ZONE_SCOPED - llassert(mSurfacep); - llassert(x >= 0.f); - llassert(y >= 0.f); + LL_PROFILE_ZONE_SCOPED + llassert(mSurfacep); + llassert(x >= 0.f); + llassert(y >= 0.f); - /////////////////////////// - // - // Generate raw data arrays for surface textures - // - // + /////////////////////////// + // + // Generate raw data arrays for surface textures + // + // - // These have already been validated by generateComposition. - U8* st_data[ASSET_COUNT]; - S32 st_data_size[ASSET_COUNT]; // for debugging + // These have already been validated by generateComposition. + U8* st_data[ASSET_COUNT]; + S32 st_data_size[ASSET_COUNT]; // for debugging const bool use_textures = getMaterialType() != LLTerrainMaterials::Type::PBR; if (use_textures) @@ -645,11 +645,11 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, if (!materialsReady(true, true)) { return FALSE; } } - for (S32 i = 0; i < ASSET_COUNT; i++) - { - if (mRawImages[i].isNull()) - { - // Read back a raw image for this discard level, if it exists + for (S32 i = 0; i < ASSET_COUNT; i++) + { + if (mRawImages[i].isNull()) + { + // Read back a raw image for this discard level, if it exists LLViewerFetchedTexture* tex; LLViewerFetchedTexture* tex_emissive; // Can be null bool has_base_color_factor; @@ -721,14 +721,14 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, raw_emissive = newraw_emissive; } } - if (has_base_color_factor || + if (has_base_color_factor || raw_emissive || has_alpha || tex->getWidth(tex->getRawImageLevel()) != BASE_SIZE || - tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || - tex->getComponents() != 3) - { - LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); + tex->getHeight(tex->getRawImageLevel()) != BASE_SIZE || + tex->getComponents() != 3) + { + LLPointer newraw = new LLImageRaw(BASE_SIZE, BASE_SIZE, 3); if (has_alpha) { // Approximate the water underneath terrain alpha with solid water color @@ -738,7 +738,7 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, MAX_WATER_COLOR.mV[VZ], 255); } - newraw->composite(mRawImagesBaseColor[i]); + newraw->composite(mRawImagesBaseColor[i]); if (has_base_color_factor) { newraw->tint(base_color_factor); @@ -749,8 +749,8 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, newraw->addEmissive(raw_emissive); } - mRawImages[i] = newraw; // deletes old - } + mRawImages[i] = newraw; // deletes old + } if (delete_raw_post) { @@ -764,150 +764,150 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, // Remove intermediary image references mRawImagesBaseColor[i] = nullptr; mRawImagesEmissive[i] = nullptr; - } - st_data[i] = mRawImages[i]->getData(); - st_data_size[i] = mRawImages[i]->getDataSize(); - } - - /////////////////////////////////////// - // - // Generate and clamp x/y bounding box. - // - // - - S32 x_begin, y_begin, x_end, y_end; - x_begin = (S32)(x * mScaleInv); - y_begin = (S32)(y * mScaleInv); - x_end = ll_round( (x + width) * mScaleInv ); - y_end = ll_round( (y + width) * mScaleInv ); - - if (x_end > mWidth) - { + } + st_data[i] = mRawImages[i]->getData(); + st_data_size[i] = mRawImages[i]->getDataSize(); + } + + /////////////////////////////////////// + // + // Generate and clamp x/y bounding box. + // + // + + S32 x_begin, y_begin, x_end, y_end; + x_begin = (S32)(x * mScaleInv); + y_begin = (S32)(y * mScaleInv); + x_end = ll_round( (x + width) * mScaleInv ); + y_end = ll_round( (y + width) * mScaleInv ); + + if (x_end > mWidth) + { llassert(false); - x_end = mWidth; - } - if (y_end > mWidth) - { + x_end = mWidth; + } + if (y_end > mWidth) + { llassert(false); - y_end = mWidth; - } - - - /////////////////////////////////////////// - // - // Generate target texture information, stride ratios. - // - // - - LLViewerTexture *texturep; - U32 tex_width, tex_height, tex_comps; - U32 tex_stride; - F32 tex_x_scalef, tex_y_scalef; - S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; - F32 tex_x_ratiof, tex_y_ratiof; - - texturep = mSurfacep->getSTexture(); - tex_width = texturep->getWidth(); - tex_height = texturep->getHeight(); - tex_comps = texturep->getComponents(); - tex_stride = tex_width * tex_comps; - - U32 st_comps = 3; - U32 st_width = BASE_SIZE; - U32 st_height = BASE_SIZE; - - if (tex_comps != st_comps) - { + y_end = mWidth; + } + + + /////////////////////////////////////////// + // + // Generate target texture information, stride ratios. + // + // + + LLViewerTexture *texturep; + U32 tex_width, tex_height, tex_comps; + U32 tex_stride; + F32 tex_x_scalef, tex_y_scalef; + S32 tex_x_begin, tex_y_begin, tex_x_end, tex_y_end; + F32 tex_x_ratiof, tex_y_ratiof; + + texturep = mSurfacep->getSTexture(); + tex_width = texturep->getWidth(); + tex_height = texturep->getHeight(); + tex_comps = texturep->getComponents(); + tex_stride = tex_width * tex_comps; + + U32 st_comps = 3; + U32 st_width = BASE_SIZE; + U32 st_height = BASE_SIZE; + + if (tex_comps != st_comps) + { llassert(false); - return FALSE; - } - - tex_x_scalef = (F32)tex_width / (F32)mWidth; - tex_y_scalef = (F32)tex_height / (F32)mWidth; - tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); - tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); - tex_x_end = (S32)((F32)x_end * tex_x_scalef); - tex_y_end = (S32)((F32)y_end * tex_y_scalef); - - tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; - tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; - - LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); - U8 *rawp = raw->getData(); - - F32 st_x_stride, st_y_stride; - st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); - st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); - - llassert(st_x_stride > 0.f); - llassert(st_y_stride > 0.f); - //////////////////////////////// - // - // Iterate through the target texture, striding through the - // subtextures and interpolating appropriately. - // - // - - F32 sti, stj; - S32 st_offset; - sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); - stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); - - st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; - for (S32 j = tex_y_begin; j < tex_y_end; j++) - { - U32 offset = j * tex_stride + tex_x_begin * tex_comps; - sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); - for (S32 i = tex_x_begin; i < tex_x_end; i++) - { - S32 tex0, tex1; - F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); - - tex0 = llfloor( composition ); - tex0 = llclamp(tex0, 0, 3); - composition -= tex0; - tex1 = tex0 + 1; - tex1 = llclamp(tex1, 0, 3); - - st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; - for (U32 k = 0; k < tex_comps; k++) - { - // Linearly interpolate based on composition. - if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) - { - // SJB: This shouldn't be happening, but does... Rounding error? - //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL; - //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL; - } - else - { - F32 a = *(st_data[tex0] + st_offset); - F32 b = *(st_data[tex1] + st_offset); - rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); - } - offset++; - st_offset++; - } - - sti += st_x_stride; - if (sti >= st_width) - { - sti -= st_width; - } - } - - stj += st_y_stride; - if (stj >= st_height) - { - stj -= st_height; - } - } - - if (!texturep->hasGLTexture()) - { - texturep->createGLTexture(0, raw); - } - texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); + return FALSE; + } + + tex_x_scalef = (F32)tex_width / (F32)mWidth; + tex_y_scalef = (F32)tex_height / (F32)mWidth; + tex_x_begin = (S32)((F32)x_begin * tex_x_scalef); + tex_y_begin = (S32)((F32)y_begin * tex_y_scalef); + tex_x_end = (S32)((F32)x_end * tex_x_scalef); + tex_y_end = (S32)((F32)y_end * tex_y_scalef); + + tex_x_ratiof = (F32)mWidth*mScale / (F32)tex_width; + tex_y_ratiof = (F32)mWidth*mScale / (F32)tex_height; + + LLPointer raw = new LLImageRaw(tex_width, tex_height, tex_comps); + U8 *rawp = raw->getData(); + + F32 st_x_stride, st_y_stride; + st_x_stride = ((F32)st_width / (F32)mTexScaleX)*((F32)mWidth / (F32)tex_width); + st_y_stride = ((F32)st_height / (F32)mTexScaleY)*((F32)mWidth / (F32)tex_height); + + llassert(st_x_stride > 0.f); + llassert(st_y_stride > 0.f); + //////////////////////////////// + // + // Iterate through the target texture, striding through the + // subtextures and interpolating appropriately. + // + // + + F32 sti, stj; + S32 st_offset; + sti = (tex_x_begin * st_x_stride) - st_width*(llfloor((tex_x_begin * st_x_stride)/st_width)); + stj = (tex_y_begin * st_y_stride) - st_height*(llfloor((tex_y_begin * st_y_stride)/st_height)); + + st_offset = (llfloor(stj * st_width) + llfloor(sti)) * st_comps; + for (S32 j = tex_y_begin; j < tex_y_end; j++) + { + U32 offset = j * tex_stride + tex_x_begin * tex_comps; + sti = (tex_x_begin * st_x_stride) - st_width*((U32)(tex_x_begin * st_x_stride)/st_width); + for (S32 i = tex_x_begin; i < tex_x_end; i++) + { + S32 tex0, tex1; + F32 composition = getValueScaled(i*tex_x_ratiof, j*tex_y_ratiof); + + tex0 = llfloor( composition ); + tex0 = llclamp(tex0, 0, 3); + composition -= tex0; + tex1 = tex0 + 1; + tex1 = llclamp(tex1, 0, 3); + + st_offset = (lltrunc(sti) + lltrunc(stj)*st_width) * st_comps; + for (U32 k = 0; k < tex_comps; k++) + { + // Linearly interpolate based on composition. + if (st_offset >= st_data_size[tex0] || st_offset >= st_data_size[tex1]) + { + // SJB: This shouldn't be happening, but does... Rounding error? + //LL_WARNS() << "offset 0 [" << tex0 << "] =" << st_offset << " >= size=" << st_data_size[tex0] << LL_ENDL; + //LL_WARNS() << "offset 1 [" << tex1 << "] =" << st_offset << " >= size=" << st_data_size[tex1] << LL_ENDL; + } + else + { + F32 a = *(st_data[tex0] + st_offset); + F32 b = *(st_data[tex1] + st_offset); + rawp[ offset ] = (U8)lltrunc( a + composition * (b - a) ); + } + offset++; + st_offset++; + } + + sti += st_x_stride; + if (sti >= st_width) + { + sti -= st_width; + } + } + + stj += st_y_stride; + if (stj >= st_height) + { + stj -= st_height; + } + } + + if (!texturep->hasGLTexture()) + { + texturep->createGLTexture(0, raw); + } + texturep->setSubImage(raw, tex_x_begin, tex_y_begin, tex_x_end - tex_x_begin, tex_y_end - tex_y_begin); // Un-boost detail textures (will get re-boosted if rendering in high detail) for (S32 i = 0; i < ASSET_COUNT; i++) @@ -920,38 +920,38 @@ BOOL LLVLComposition::generateMinimapTileLand(const F32 x, const F32 y, { unboost_minimap_material(mDetailMaterials[i]); } - - return TRUE; + + return TRUE; } F32 LLVLComposition::getStartHeight(S32 corner) { - return mStartHeight[corner]; + return mStartHeight[corner]; } void LLVLComposition::setDetailAssetID(S32 asset, const LLUUID& id) { - if (id.isNull()) - { + if (id.isNull()) + { return; } LLTerrainMaterials::setDetailAssetID(asset, id); - mRawImages[asset] = NULL; - mRawImagesBaseColor[asset] = NULL; - mRawImagesEmissive[asset] = NULL; + mRawImages[asset] = NULL; + mRawImagesBaseColor[asset] = NULL; + mRawImagesEmissive[asset] = NULL; } void LLVLComposition::setStartHeight(S32 corner, const F32 start_height) { - mStartHeight[corner] = start_height; + mStartHeight[corner] = start_height; } F32 LLVLComposition::getHeightRange(S32 corner) { - return mHeightRange[corner]; + return mHeightRange[corner]; } void LLVLComposition::setHeightRange(S32 corner, const F32 range) { - mHeightRange[corner] = range; + mHeightRange[corner] = range; } -- cgit v1.2.3