From 2193c913818ee4013ad3104127d6544e6dece8d0 Mon Sep 17 00:00:00 2001 From: Rye Mutt <rye@alchemyviewer.org> Date: Sat, 7 May 2022 00:58:04 -0400 Subject: [PATCH] Add 24bit depth snapshot from FS --- indra/llmath/llquantize.h | 13 +++++++- indra/newview/llfloatersnapshot.cpp | 2 ++ indra/newview/llsnapshotmodel.h | 3 +- indra/newview/llviewerwindow.cpp | 32 ++++++++++++++++++- .../skins/default/xui/en/floater_snapshot.xml | 4 +++ 5 files changed, 51 insertions(+), 3 deletions(-) diff --git a/indra/llmath/llquantize.h b/indra/llmath/llquantize.h index 10c950abbb0..f685309e658 100644 --- a/indra/llmath/llquantize.h +++ b/indra/llmath/llquantize.h @@ -43,6 +43,7 @@ LL_ALIGN_16( const F32 F_OOU8MAX_4A[4] ) = { OOU8MAX, OOU8MAX, OOU8MAX, OOU8MAX const U8 FIRSTVALIDCHAR = 54; const U8 MAXSTRINGVAL = U8MAX - FIRSTVALIDCHAR; //we don't allow newline or null +const U32 U24MAX = 16777215; inline U16 F32_to_U16_ROUND(F32 val, F32 lower, F32 upper) { @@ -107,6 +108,16 @@ inline U8 F32_to_U8(F32 val, F32 lower, F32 upper) return (U8)(llfloor(val*U8MAX)); } +inline U32 F32_to_U32(F32 val, F32 lower, F32 upper) +{ + val = llclamp(val, lower, upper); + // make sure that the value is positive and normalized to <0, 1> + val -= lower; + val /= (upper - lower); + + return (U32)(ll_round(val*U24MAX)); +} + inline F32 U8_to_F32(U8 ival, F32 lower, F32 upper) { F32 val = ival*OOU8MAX; @@ -130,7 +141,7 @@ inline U8 F32_TO_STRING(F32 val, F32 lower, F32 upper) val -= lower; //[0, upper-lower] val /= (upper - lower); //[0,1] val = val * MAXSTRINGVAL; //[0, MAXSTRINGVAL] - val = floor(val + 0.5f); //[0, MAXSTRINGVAL] + val = floorf(val + 0.5f); //[0, MAXSTRINGVAL] U8 stringVal = (U8)(val) + FIRSTVALIDCHAR; //[FIRSTVALIDCHAR, MAXSTRINGVAL + FIRSTVALIDCHAR] return stringVal; diff --git a/indra/newview/llfloatersnapshot.cpp b/indra/newview/llfloatersnapshot.cpp index 5f77a55092b..448e081a1cd 100644 --- a/indra/newview/llfloatersnapshot.cpp +++ b/indra/newview/llfloatersnapshot.cpp @@ -140,6 +140,8 @@ LLSnapshotModel::ESnapshotLayerType LLFloaterSnapshot::Impl::getLayerType(LLFloa type = LLSnapshotModel::SNAPSHOT_TYPE_COLOR; else if (id == "depth") type = LLSnapshotModel::SNAPSHOT_TYPE_DEPTH; + else if (id == "depth24") + type = LLSnapshotModel::SNAPSHOT_TYPE_DEPTH24; return type; } diff --git a/indra/newview/llsnapshotmodel.h b/indra/newview/llsnapshotmodel.h index fd251349ba5..77a151060cc 100644 --- a/indra/newview/llsnapshotmodel.h +++ b/indra/newview/llsnapshotmodel.h @@ -49,7 +49,8 @@ class LLSnapshotModel typedef enum { SNAPSHOT_TYPE_COLOR, - SNAPSHOT_TYPE_DEPTH + SNAPSHOT_TYPE_DEPTH, + SNAPSHOT_TYPE_DEPTH24 } ESnapshotLayerType; }; diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp index e1dd9fd3740..ae4c3405009 100644 --- a/indra/newview/llviewerwindow.cpp +++ b/indra/newview/llviewerwindow.cpp @@ -5141,7 +5141,7 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei if ((image_width <= gGLManager.mGLMaxTextureSize && image_height <= gGLManager.mGLMaxTextureSize) && (image_width > window_width || image_height > window_height) && LLPipeline::sRenderDeferred && !show_ui) { - U32 color_fmt = type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH ? GL_DEPTH_COMPONENT : GL_RGBA; + U32 color_fmt = (type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH || type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH24) ? GL_DEPTH_COMPONENT : GL_RGBA; if (scratch_space.allocate(image_width, image_height, color_fmt, true, true)) { original_width = gPipeline.mDeferredScreen.getWidth(); @@ -5287,6 +5287,36 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei raw->getData() + output_buffer_offset ); } + else if (type == LLSnapshotModel::SNAPSHOT_TYPE_DEPTH24) + { + LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GLfloat)); // need to store floating point values + glReadPixels( + subimage_x_offset, out_y + subimage_y_offset, + read_width, 1, + GL_DEPTH_COMPONENT, GL_FLOAT, + depth_line_buffer->getData()// current output pixel is beginning of buffer... + ); + + for (S32 i = 0; i < (S32)read_width; i++) + { + F32 depth_float = *(F32*)(depth_line_buffer->getData() + (i * sizeof(F32))); + + F32 linear_depth_float = 1.f / (depth_conversion_factor_1 - (depth_float * depth_conversion_factor_2)); + U32 RGB24 = F32_to_U32(linear_depth_float, viewerCamera.getNear(), viewerCamera.getFar()); + //A max value of 16777215 for RGB24 evaluates to black when it shold be white. The clamp assures that the divisions do not somehow become >=256. + U8 depth_byteR = (U8)(llclamp(llfloor(RGB24 / 65536.f), 0, 255)); + U8 depth_byteG = (U8)(llclamp(llfloor((RGB24 - depth_byteR * 65536) / 256.f), 0, 255)); + U8 depth_byteB = (U8)(llclamp((RGB24 - depth_byteR * 65536 - depth_byteG * 256), 0u, 255u)); + // write converted scanline out to result image + *(raw->getData() + output_buffer_offset + (i * raw->getComponents())) = depth_byteR; + *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + 1) = depth_byteG; + *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + 2) = depth_byteB; + for (S32 j = 3; j < raw->getComponents(); j++) + { + *(raw->getData() + output_buffer_offset + (i * raw->getComponents()) + j) = depth_byteR; + } + } + } else // LLSnapshotModel::SNAPSHOT_TYPE_DEPTH { LLPointer<LLImageRaw> depth_line_buffer = new LLImageRaw(read_width, 1, sizeof(GLfloat)); // need to store floating point values diff --git a/indra/newview/skins/default/xui/en/floater_snapshot.xml b/indra/newview/skins/default/xui/en/floater_snapshot.xml index f441e3cbd7e..bccf0426bfb 100644 --- a/indra/newview/skins/default/xui/en/floater_snapshot.xml +++ b/indra/newview/skins/default/xui/en/floater_snapshot.xml @@ -160,6 +160,10 @@ label="Depth" name="Depth" value="depth" /> + <combo_box.item + label="Depth (24 bit)" + name="Depth24" + value="depth24" /> </combo_box> <check_box label="Interface" -- GitLab