diff --git a/indra/newview/app_settings/settings_SH.xml b/indra/newview/app_settings/settings_SH.xml
index 75290d85b..74c629334 100644
--- a/indra/newview/app_settings/settings_SH.xml
+++ b/indra/newview/app_settings/settings_SH.xml
@@ -56,5 +56,38 @@
Value
+ SHHighResSnapshotScale
+
+ SHHighResSnapshotForceTile
+
+ SHHighResSnapshotSuperSample
+
diff --git a/indra/newview/llviewerdisplay.cpp b/indra/newview/llviewerdisplay.cpp
index 30e9183f9..1c9da75e4 100644
--- a/indra/newview/llviewerdisplay.cpp
+++ b/indra/newview/llviewerdisplay.cpp
@@ -163,7 +163,11 @@ void display_startup()
glClear(GL_DEPTH_BUFFER_BIT);
}
+#if SHY_MOD //screenshot improvement
+void display_update_camera(bool tiling=false)
+#else //shy_mod
void display_update_camera()
+#endif //ignore
{
llpushcallstacks ;
// TODO: cut draw distance down if customizing avatar?
@@ -172,6 +176,15 @@ void display_update_camera()
// Cut draw distance in half when customizing avatar,
// but on the viewer only.
F32 final_far = gAgent.mDrawDistance;
+#if SHY_MOD //screenshot improvement
+ if(tiling) //Don't animate clouds and water if tiling!
+ {
+ LLViewerCamera::getInstance()->setFar(final_far);
+ gViewerWindow->setup3DRender();
+ LLWorld::getInstance()->setLandFarClip(final_far);
+ return;
+ }
+#endif //shy_mod
if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
{
final_far *= 0.5f;
@@ -216,7 +229,11 @@ void display_stats()
}
// Paint the display!
+#if SHY_MOD // screenshot improvement
+void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, BOOL tiling)
+#else //shy_mod
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
+#endif //ignore
{
LLFastTimer t(LLFastTimer::FTM_RENDER);
@@ -577,7 +594,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
LLGLNamePool::upkeepPools();
stop_glerror();
+#if SHY_MOD //screenshot improvement
+ display_update_camera(tiling);
+#else //shy_mod
display_update_camera();
+#endif //ignore
stop_glerror();
// *TODO: merge these two methods
@@ -707,7 +728,11 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
glClear(GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
}
+#if SHY_MOD // screenshot improvement
+ if (!for_snapshot || tiling)
+#else //shy_mod
if (!for_snapshot)
+#endif //ignore
{
LLAppViewer::instance()->pingMainloopTimeout("Display:Imagery");
gPipeline.generateWaterReflection(*LLViewerCamera::getInstance());
diff --git a/indra/newview/llviewerdisplay.h b/indra/newview/llviewerdisplay.h
index 4d650dec2..5c46a07a9 100644
--- a/indra/newview/llviewerdisplay.h
+++ b/indra/newview/llviewerdisplay.h
@@ -38,7 +38,11 @@ class LLPostProcess;
void display_startup();
void display_cleanup();
+#if SHY_MOD // screenshot improvement
+void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0, BOOL for_snapshot = FALSE, BOOL tiling = FALSE);
+#else //shy_mod
void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0, BOOL for_snapshot = FALSE);
+#endif //ignore
extern BOOL gDisplaySwapBuffers;
extern BOOL gDepthDirty;
diff --git a/indra/newview/llviewermenufile.cpp b/indra/newview/llviewermenufile.cpp
index fd6ec7bf9..733b0411c 100644
--- a/indra/newview/llviewermenufile.cpp
+++ b/indra/newview/llviewermenufile.cpp
@@ -567,8 +567,14 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
if (gSavedSettings.getBOOL("HighResSnapshot"))
{
+#if SHY_MOD // screenshot improvement
+ const F32 mult = gSavedSettings.getF32("SHHighResSnapshotScale");
+ width *= mult;
+ height *= mult;
+#else //shy_mod
width *= 2;
height *= 2;
+#endif //ignore
}
if (gViewerWindow->rawSnapshot(raw,
diff --git a/indra/newview/llviewerwindow.cpp b/indra/newview/llviewerwindow.cpp
index 0d4e8b0be..ee43e2ea5 100644
--- a/indra/newview/llviewerwindow.cpp
+++ b/indra/newview/llviewerwindow.cpp
@@ -4248,6 +4248,20 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
LLRenderTarget target;
F32 scale_factor = 1.0f ;
+
+#if SHY_MOD // screenshot improvement
+ F32 internal_scale = 1.f;
+ static const LLCachedControl force_tile("SHHighResSnapshotForceTile",false);
+ if(force_tile)
+ {
+ static const LLCachedControl super_sample_scale("SHHighResSnapshotSuperSample",1.f);
+ internal_scale = llmax(super_sample_scale.get(),1.f);
+ }
+ // render at specified internal resolution. >1 results in supersampling.
+ image_height *= internal_scale;
+ image_width *= internal_scale;
+#endif //shy_mod
+
if(!keep_window_aspect) //image cropping
{
F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
@@ -4259,6 +4273,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
{
if(image_width > window_width || image_height > window_height) //need to enlarge the scene
{
+#if SHY_MOD // screenshot improvement
+ if(!force_tile)
+#endif //shy_mod
if (gGLManager.mHasFramebufferObject && !show_ui)
{
GLint max_size = 0;
@@ -4295,6 +4312,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
S32 image_buffer_x = llfloor(snapshot_width*scale_factor) ;
S32 image_buffer_y = llfloor(snapshot_height *scale_factor) ;
+#if SHY_MOD // screenshot improvement
+ if(internal_scale > 1.f) //If supersampling... Don't care about max_size.
+#endif //shy_mod
if(image_buffer_x > max_size || image_buffer_y > max_size) //boundary check to avoid memory overflow
{
scale_factor *= llmin((F32)max_size / image_buffer_x, (F32)max_size / image_buffer_y) ;
@@ -4348,11 +4368,32 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
else
{
const U32 subfield = subimage_x+(subimage_y*llceil(scale_factor));
+#if SHY_MOD // screenshot improvement
+ //tiling requires gPipeline.generateWaterReflection to be called in display(). CANNOT be done if using an fbo.
+ display(do_rebuild, scale_factor, subfield, TRUE, !use_fbo && (scale_factor > 1.0f));
+#else //shy_mod
display(do_rebuild, scale_factor, subfield, TRUE);
+#endif
// Required for showing the GUI in snapshots? See DEV-16350 for details. JC
render_ui(scale_factor, subfield);
}
+#if SHY_MOD // screenshot improvement
+ if(scale_factor <= 1.f) //faster. bulk copy opposed to line per line
+ {
+ if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)
+ {
+ glReadPixels(0,0,image_width, image_height,GL_RGB, GL_UNSIGNED_BYTE,raw->getData());
+ }
+ else // SNAPSHOT_TYPE_DEPTH
+ {
+ LLPointer depth_line_buffer = new LLImageRaw(image_width, image_height, sizeof(GL_FLOAT));
+ glReadPixels(0, 0,image_width,image_height, GL_DEPTH_COMPONENT, GL_FLOAT,depth_line_buffer->getData());
+ raw->copy(depth_line_buffer);
+ }
+ continue;
+ }
+#endif //shy_mod
S32 subimage_x_offset = llclamp(buffer_x_offset - (subimage_x * window_width), 0, window_width);
// handle fractional rows
U32 read_width = llmax(0, (window_width - subimage_x_offset) -
@@ -4453,6 +4494,14 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
ret = raw->scale( image_width, image_height, FALSE );
}
+#if SHY_MOD // screenshot improvement
+ if(raw->isBufferInvalid()) //Just checking!
+ return FALSE;
+ if(internal_scale != 1.f) //Scale down our render to the desired dimensions.
+ raw->scale( image_width/internal_scale, image_height/internal_scale );
+ if(raw->isBufferInvalid()) //Just checking!
+ return FALSE;
+#endif //shy_mod
setCursor(UI_CURSOR_ARROW);
diff --git a/indra/newview/pipeline.cpp b/indra/newview/pipeline.cpp
index a2cb74388..78797ab0d 100644
--- a/indra/newview/pipeline.cpp
+++ b/indra/newview/pipeline.cpp
@@ -221,7 +221,11 @@ glh::matrix4f gl_ortho(GLfloat left, GLfloat right, GLfloat bottom, GLfloat top,
return ret;
}
+#if SHY_MOD //screenshot improvement
+void display_update_camera(bool tiling=false);
+#else //shy_mod
void display_update_camera();
+#endif //ignore
//----------------------------------------
S32 LLPipeline::sCompiles = 0;