summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--indra/newview/lldrawpoolterrain.cpp29
-rw-r--r--indra/newview/llvlcomposition.cpp239
-rw-r--r--indra/newview/llvlcomposition.h17
3 files changed, 187 insertions, 98 deletions
diff --git a/indra/newview/lldrawpoolterrain.cpp b/indra/newview/lldrawpoolterrain.cpp
index 687ff5f462..9f0f9fd1b2 100644
--- a/indra/newview/lldrawpoolterrain.cpp
+++ b/indra/newview/lldrawpoolterrain.cpp
@@ -256,10 +256,31 @@ void LLDrawPoolTerrain::renderFullShader()
// Hack! Get the region that this draw pool is rendering from!
LLViewerRegion *regionp = mDrawFace[0]->getDrawable()->getVObj()->getRegion();
LLVLComposition *compp = regionp->getComposition();
- LLViewerTexture *detail_texture0p = compp->mDetailTextures[0];
- LLViewerTexture *detail_texture1p = compp->mDetailTextures[1];
- LLViewerTexture *detail_texture2p = compp->mDetailTextures[2];
- LLViewerTexture *detail_texture3p = compp->mDetailTextures[3];
+
+ LLViewerTexture *detail_texture0p;
+ LLViewerTexture *detail_texture1p;
+ LLViewerTexture *detail_texture2p;
+ LLViewerTexture *detail_texture3p;
+ BOOL use_textures = compp->texturesReady() || !compp->materialsReady();
+ if (use_textures)
+ {
+ detail_texture0p = compp->mDetailTextures[0];
+ detail_texture1p = compp->mDetailTextures[1];
+ detail_texture2p = compp->mDetailTextures[2];
+ detail_texture3p = compp->mDetailTextures[3];
+ }
+ else // use materials
+ {
+ detail_texture0p = compp->mDetailMaterials[0]->mBaseColorTexture;
+ detail_texture1p = compp->mDetailMaterials[1]->mBaseColorTexture;
+ detail_texture2p = compp->mDetailMaterials[2]->mBaseColorTexture;
+ detail_texture3p = compp->mDetailMaterials[3]->mBaseColorTexture;
+ LLViewerTexture* blank = LLViewerFetchedTexture::sWhiteImagep;
+ if (!detail_texture0p) { detail_texture0p = blank; }
+ if (!detail_texture1p) { detail_texture1p = blank; }
+ if (!detail_texture2p) { detail_texture2p = blank; }
+ if (!detail_texture3p) { detail_texture3p = blank; }
+ }
LLVector3d region_origin_global = gAgent.getRegion()->getOriginGlobal();
F32 offset_x = (F32)fmod(region_origin_global.mdV[VX], 1.0/(F64)sDetailScale)*sDetailScale;
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<LLViewerFetchedTexture> fetch_terrain_texture(const LLUUID& id)
+{
+ if (id.isNull())
+ {
+ return nullptr;
+ }
+
+ LLPointer<LLViewerFetchedTexture> 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<LLFetchedGLTFMaterial>& 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<LLViewerFetchedTexture>& tex)
+// static
+BOOL LLVLComposition::textureReady(LLPointer<LLViewerFetchedTexture>& 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<LLFetchedGLTFMaterial>& 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<LLFetchedGLTFMaterial>& 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<LLImageRaw> 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();
}
diff --git a/indra/newview/llvlcomposition.h b/indra/newview/llvlcomposition.h
index 3e465efc95..af0cf9323c 100644
--- a/indra/newview/llvlcomposition.h
+++ b/indra/newview/llvlcomposition.h
@@ -30,6 +30,8 @@
#include "llviewerlayer.h"
#include "llpointer.h"
+#include "llimage.h"
+
class LLSurface;
class LLViewerFetchedTexture;
@@ -75,21 +77,26 @@ public:
friend class LLDrawPoolTerrain;
void setParamsReady() { mParamsReady = TRUE; }
BOOL getParamsReady() const { return mParamsReady; }
+ BOOL texturesReady(BOOL boost = FALSE);
+ BOOL materialsReady(BOOL boost = FALSE);
+
protected:
- BOOL mParamsReady;
+ static BOOL textureReady(LLPointer<LLViewerFetchedTexture>& tex, BOOL boost = FALSE);
+ static BOOL materialReady(LLPointer<LLFetchedGLTFMaterial>& mat, bool& textures_set, BOOL boost = FALSE);
+
+ BOOL mParamsReady = FALSE;
LLSurface *mSurfacep;
- BOOL mTexturesLoaded;
- // TODO: Set flag to indicate whether the textures or materials loaded first
LLPointer<LLViewerFetchedTexture> mDetailTextures[ASSET_COUNT];
LLPointer<LLImageRaw> mRawImages[ASSET_COUNT];
LLPointer<LLFetchedGLTFMaterial> mDetailMaterials[ASSET_COUNT];
+ bool mMaterialTexturesSet[ASSET_COUNT];
F32 mStartHeight[CORNER_COUNT];
F32 mHeightRange[CORNER_COUNT];
- F32 mTexScaleX;
- F32 mTexScaleY;
+ F32 mTexScaleX = 16.f;
+ F32 mTexScaleY = 16.f;
};
#endif //LL_LLVLCOMPOSITION_H