summaryrefslogtreecommitdiff
path: root/indra/llimage
diff options
context:
space:
mode:
authorCosmic Linden <cosmic@lindenlab.com>2024-04-12 11:27:24 -0700
committerCosmic Linden <cosmic@lindenlab.com>2024-04-25 16:48:07 -0700
commitaac18ada713aa34cafe477264ab08d5f1ba4e205 (patch)
tree97128896389c46d7741e319bb43615198a32a231 /indra/llimage
parent47255bf44d04e5ba7b33d44f8cc738da4be9d53a (diff)
secondlife/viewer#1184: Use more robust/memory-friendly setLoadedCallback for minimap gen. Fix some emissive maps.
Diffstat (limited to 'indra/llimage')
-rw-r--r--indra/llimage/llimage.cpp69
-rw-r--r--indra/llimage/llimage.h6
2 files changed, 75 insertions, 0 deletions
diff --git a/indra/llimage/llimage.cpp b/indra/llimage/llimage.cpp
index 16609b60be..8d35fd140e 100644
--- a/indra/llimage/llimage.cpp
+++ b/indra/llimage/llimage.cpp
@@ -1874,6 +1874,75 @@ void LLImageRaw::compositeRowScaled4onto3( U8* in, U8* out, S32 in_pixel_len, S3
}
}
+
+void LLImageRaw::addEmissive(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ if (!validateSrcAndDst(__FUNCTION__, src, dst))
+ {
+ return;
+ }
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert(3 == dst->getComponents());
+
+ if( 3 == dst->getComponents() )
+ {
+ if( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) )
+ {
+ addEmissiveUnscaled(src);
+ }
+ else
+ {
+ addEmissiveScaled(src);
+ }
+ }
+}
+
+void LLImageRaw::addEmissiveUnscaled(LLImageRaw* src)
+{
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert((3 == src->getComponents()) || (4 == src->getComponents()));
+ llassert((3 == dst->getComponents()) || (4 == dst->getComponents()));
+ llassert( (src->getWidth() == dst->getWidth()) && (src->getHeight() == dst->getHeight()) );
+
+ U8* const src_data = src->getData();
+ U8* const dst_data = dst->getData();
+ for(S32 y = 0; y < dst->getHeight(); ++y)
+ {
+ const S32 src_row_offset = src->getComponents() * src->getWidth() * y;
+ const S32 dst_row_offset = dst->getComponents() * dst->getWidth() * y;
+ for (S32 x = 0; x < dst->getWidth(); ++x)
+ {
+ const S32 src_offset = src_row_offset + (x * src->getComponents());
+ const S32 dst_offset = dst_row_offset + (x * dst->getComponents());
+ U8* const src_pixel = src_data + src_offset;
+ U8* const dst_pixel = dst_data + dst_offset;
+ dst_pixel[0] = llmin(255, dst_pixel[0] + src_pixel[0]);
+ dst_pixel[1] = llmin(255, dst_pixel[1] + src_pixel[1]);
+ dst_pixel[2] = llmin(255, dst_pixel[2] + src_pixel[2]);
+ }
+ }
+}
+
+void LLImageRaw::addEmissiveScaled(LLImageRaw* src)
+{
+ LL_INFOS() << __FUNCTION__ << LL_ENDL;
+
+ LLImageRaw* dst = this; // Just for clarity.
+
+ llassert( (4 == src->getComponents()) && (3 == dst->getComponents()) );
+
+ LLImageRaw temp(dst->getWidth(), dst->getHeight(), dst->getComponents());
+ llassert_always(temp.getDataSize() > 0);
+ temp.copyScaled(src);
+
+ dst->addEmissiveUnscaled(&temp);
+}
+
+
bool LLImageRaw::validateSrcAndDst(std::string func, LLImageRaw* src, LLImageRaw* dst)
{
if (!src || !dst || src->isBufferInvalid() || dst->isBufferInvalid())
diff --git a/indra/llimage/llimage.h b/indra/llimage/llimage.h
index 93b58b2356..c49184e338 100644
--- a/indra/llimage/llimage.h
+++ b/indra/llimage/llimage.h
@@ -276,6 +276,12 @@ public:
// Src and dst are same size. Src has 4 components. Dst has 3 components.
void compositeUnscaled4onto3( LLImageRaw* src );
+ // Emissive operations used by minimap
+ // Roughly emulates GLTF emissive texture, but is not GLTF-compliant
+ // *TODO: Remove in favor of shader
+ void addEmissive(LLImageRaw* src);
+ void addEmissiveScaled(LLImageRaw* src);
+ void addEmissiveUnscaled(LLImageRaw* src);
protected:
// Create an image from a local file (generally used in tools)
//bool createFromFile(const std::string& filename, bool j2c_lowest_mip_only = false);