diff options
| author | Cosmic Linden <cosmic@lindenlab.com> | 2024-03-19 16:03:57 -0700 | 
|---|---|---|
| committer | Cosmic Linden <cosmic@lindenlab.com> | 2024-03-19 16:03:57 -0700 | 
| commit | 7792e62d3c9e3f8b2a27e7e9cbbc8db2c584b682 (patch) | |
| tree | a083ed8e310e193e09f1008724c138e8f85d219d | |
| parent | 2a325fdebadd32a230f10b372b25ec5474e50f63 (diff) | |
secondlife/viewer-issues#82: Don't allow transparent texture terrain
| -rw-r--r-- | indra/llimage/llimage.cpp | 22 | ||||
| -rw-r--r-- | indra/llimage/llimage.h | 2 | ||||
| -rw-r--r-- | indra/newview/llfloaterregioninfo.cpp | 29 | ||||
| -rw-r--r-- | indra/newview/skins/default/xui/en/notifications.xml | 26 | 
4 files changed, 78 insertions, 1 deletions
| diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp index acfc254b65..16609b60be 100644 --- a/indra/llimage/llimage.cpp +++ b/indra/llimage/llimage.cpp @@ -990,6 +990,28 @@ void LLImageRaw::verticalFlip()  } +bool LLImageRaw::checkHasTransparentPixels() +{ +    if (getComponents() != 4) +    { +        return false; +    } + +    U8* data = getData(); +    U32 pixels = getWidth() * getHeight(); + +    // check alpha channel for all 255 +    for (U32 i = 0; i < pixels; ++i) +    { +        if (data[i * 4 + 3] != 255) +        { +            return true; +        } +    } + +    return false; +} +  bool LLImageRaw::optimizeAwayAlpha()  {      if (getComponents() == 4) diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h index fc8d62cc96..93b58b2356 100644 --- a/indra/llimage/llimage.h +++ b/indra/llimage/llimage.h @@ -210,6 +210,8 @@ public:  	void verticalFlip(); +    // Returns true if the image is not fully opaque +    bool checkHasTransparentPixels();      // if the alpha channel is all 100% opaque, delete it      // returns true if alpha channel was deleted      bool optimizeAwayAlpha(); diff --git a/indra/newview/llfloaterregioninfo.cpp b/indra/newview/llfloaterregioninfo.cpp index 8c4b6fc857..706f7cf943 100644 --- a/indra/newview/llfloaterregioninfo.cpp +++ b/indra/newview/llfloaterregioninfo.cpp @@ -1330,7 +1330,7 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()  		if (!texture_ctrl) continue;  		LLUUID image_asset_id = texture_ctrl->getImageAssetID(); -		LLViewerTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id); +		LLViewerFetchedTexture* img = LLViewerTextureManager::getFetchedTexture(image_asset_id);  		S32 components = img->getComponents();  		// Must ask for highest resolution version's width. JC  		S32 width = img->getFullWidth(); @@ -1348,6 +1348,33 @@ BOOL LLPanelRegionTerrainInfo::validateTextureSizes()  			return FALSE;  		} +        if (components == 4) +        { +            if (!img->hasSavedRawImage()) +            { +                // Raw image isn't loaded yet +                // Assume it's invalid due to presence of alpha channel +                LLSD args; +                args["TEXTURE_NUM"] = i+1; +                args["TEXTURE_BIT_DEPTH"] = llformat("%d",components * 8); +                LLNotificationsUtil::add("InvalidTerrainAlphaNotFullyLoaded", args); +                return FALSE; +            } +            // Slower path: Calculate alpha from raw image pixels (not needed +            // for GLTF materials, which use alphaMode to determine +            // transparency) +            // Raw image is pretty much guaranteed to be saved due to the texture swatches +            LLImageRaw* raw = img->getSavedRawImage(); +            if (raw->checkHasTransparentPixels()) +            { +                LLSD args; +                args["TEXTURE_NUM"] = i+1; +                LLNotificationsUtil::add("InvalidTerrainAlpha", args); +                return FALSE; +            } +            LL_WARNS() << "Terrain texture image in slot " << i << " with ID " << image_asset_id << " has alpha channel, but pixels are opaque. Is alpha being optimized away in the texture uploader?" << LL_ENDL; +        } +  		if (width > max_terrain_texture_size || height > max_terrain_texture_size)  		{ diff --git a/indra/newview/skins/default/xui/en/notifications.xml b/indra/newview/skins/default/xui/en/notifications.xml index 1a6cadf43e..c1e6e7b9f0 100644 --- a/indra/newview/skins/default/xui/en/notifications.xml +++ b/indra/newview/skins/default/xui/en/notifications.xml @@ -4010,6 +4010,32 @@ Replace texture [TEXTURE_NUM] with an RGB [MAX_SIZE]x[MAX_SIZE] or smaller image    <notification     icon="alertmodal.tga" +   name="InvalidTerrainAlphaNotFullyLoaded" +   type="alertmodal"> +Couldn't set region textures: +Terrain texture [TEXTURE_NUM] is not fully loaded, but is assumed to contain transparency due to a bit depth of [TEXTURE_BIT_DEPTH]. Transparency is not currently supported for terrain textures. + +If texture [TEXTURE_NUM] is opaque, wait for the texture to fully load and then click "Apply" again. + +Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false. +  <tag>fail</tag> +  </notification> + +  <notification +   icon="alertmodal.tga" +   name="InvalidTerrainAlpha" +   type="alertmodal"> +Couldn't set region textures: +Terrain texture [TEXTURE_NUM] contains transparency. Transparency is not currently supported for terrain textures. + +Replace texture [TEXTURE_NUM] with an opaque RGB image, then click "Apply" again. + +Alpha is only supported for terrain materials (PBR Metallic Roughness), when alphaMode="MASK" and doubleSided=false. +  <tag>fail</tag> +  </notification> + +  <notification +   icon="alertmodal.tga"     name="InvalidTerrainSize"     type="alertmodal">  Couldn't set region textures: | 
