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 + + Comment + High-resolution snapshot scale. + Persist + 1 + Type + F32 + Value + 2.0 + + SHHighResSnapshotForceTile + + Comment + Force tiling of snapshots (enables AA and supersampling) + Persist + 1 + Type + Boolean + Value + 0 + + SHHighResSnapshotSuperSample + + Comment + Set the supersampling scale in tiled screenshots. + Persist + 1 + Type + F32 + Value + 1.0 + 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;