Sorted out high-res snapshot issues.
LL has since removed high-res snapshots using render targets. I find this change to be favorable, as rendertargets were very finicky to get working with anti-aliasing. Also, deferred rendering uses many rendertargets that depend on screen resolution. Changing resolution every screenshot is.. not very awesome. There is some deviation from LL's viewer. I've kept the old tiled glow pass enabled for non-deferred, as it fixes issues with tile edges truncating glow propogation. However, this does no work with deferred yet. I need to pin down why. I assume using binding one of the RenderTargets is required for deferred. Additionally, the usage of a RenderTarget for snapshots is what prevented me from fully enabling my supersampling settings. Now that that hurdle is gone, I consider including this new setting by default to be safe enough. And a note: Do not remove the 'tiling' variable when merging with v2 changes, as singu's glow pass is 'special'. There are other fixes absent from LL's viewer that require knowing if the render is tiled or not. (water reflections/cloud freezing)
This commit is contained in:
@@ -105,6 +105,7 @@ BOOL gForceRenderLandFence = FALSE;
|
||||
BOOL gDisplaySwapBuffers = FALSE;
|
||||
BOOL gDepthDirty = FALSE;
|
||||
BOOL gResizeScreenTexture = FALSE;
|
||||
BOOL gWindowResized = FALSE;
|
||||
BOOL gSnapshot = FALSE;
|
||||
|
||||
U32 gRecentFrameCount = 0; // number of 'recent' frames
|
||||
@@ -114,7 +115,7 @@ LLFrameTimer gRecentMemoryTime;
|
||||
// Rendering stuff
|
||||
void pre_show_depth_buffer();
|
||||
void post_show_depth_buffer();
|
||||
void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
|
||||
void render_ui(F32 zoom_factor = 1.f, int subfield = 0, bool tiling = false);
|
||||
void render_hud_attachments();
|
||||
void render_ui_3d();
|
||||
void render_ui_2d();
|
||||
@@ -167,11 +168,7 @@ 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?
|
||||
@@ -180,7 +177,6 @@ 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);
|
||||
@@ -188,7 +184,6 @@ void display_update_camera()
|
||||
LLWorld::getInstance()->setLandFarClip(final_far);
|
||||
return;
|
||||
}
|
||||
#endif //shy_mod
|
||||
if (CAMERA_MODE_CUSTOMIZE_AVATAR == gAgent.getCameraMode())
|
||||
{
|
||||
final_far *= 0.5f;
|
||||
@@ -233,18 +228,26 @@ 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
|
||||
void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, bool tiling)
|
||||
{
|
||||
LLFastTimer t(LLFastTimer::FTM_RENDER);
|
||||
|
||||
if (LLPipeline::sRenderDeferred)
|
||||
if (gWindowResized)
|
||||
{ //skip render on frames where window has been resized
|
||||
gGL.flush();
|
||||
glClear(GL_COLOR_BUFFER_BIT);
|
||||
gViewerWindow->mWindow->swapBuffers();
|
||||
gPipeline.resizeScreenTexture();
|
||||
gResizeScreenTexture = FALSE;
|
||||
gWindowResized = FALSE;
|
||||
return;
|
||||
}
|
||||
|
||||
//Nope
|
||||
/*if (LLPipeline::sRenderDeferred)
|
||||
{ //hack to make sky show up in deferred snapshots
|
||||
for_snapshot = FALSE;
|
||||
}
|
||||
}*/
|
||||
|
||||
if (LLPipeline::sRenderFrameTest)
|
||||
{
|
||||
@@ -603,11 +606,7 @@ 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
|
||||
@@ -680,7 +679,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
LLGLState::checkTextureChannels();
|
||||
LLGLState::checkClientArrays();
|
||||
|
||||
BOOL to_texture = gPipeline.canUseVertexShaders() && (LLPipeline::sRenderDeferred || (LLPipeline::sRenderGlow && !gSnapshot));
|
||||
BOOL to_texture = gPipeline.canUseVertexShaders() && LLPipeline::sRenderGlow;
|
||||
|
||||
LLAppViewer::instance()->pingMainloopTimeout("Display:Swap");
|
||||
|
||||
@@ -703,7 +702,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
LLGLState::checkTextureChannels();
|
||||
LLGLState::checkClientArrays();
|
||||
|
||||
if (!for_snapshot)
|
||||
if (!for_snapshot || LLPipeline::sRenderDeferred)
|
||||
{
|
||||
if (gFrameCount > 1)
|
||||
{ //for some reason, ATI 4800 series will error out if you
|
||||
@@ -739,11 +738,7 @@ 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());
|
||||
@@ -878,7 +873,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
glClearColor(0,0,0,0);
|
||||
gPipeline.mDeferredScreen.clear();
|
||||
}
|
||||
else
|
||||
else if(!tiling)
|
||||
{
|
||||
gPipeline.mScreen.bindTarget();
|
||||
gPipeline.mScreen.clear();
|
||||
@@ -922,7 +917,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot)
|
||||
{
|
||||
gPipeline.mDeferredScreen.flush();
|
||||
}
|
||||
else
|
||||
else if(!tiling)
|
||||
{
|
||||
gPipeline.mScreen.flush();
|
||||
}
|
||||
@@ -1136,7 +1131,7 @@ BOOL setup_hud_matrices(const LLRect& screen_region)
|
||||
}
|
||||
|
||||
|
||||
void render_ui(F32 zoom_factor, int subfield)
|
||||
void render_ui(F32 zoom_factor, int subfield, bool tiling)
|
||||
{
|
||||
LLGLState::checkStates();
|
||||
|
||||
@@ -1151,7 +1146,7 @@ void render_ui(F32 zoom_factor, int subfield)
|
||||
|
||||
if (to_texture)
|
||||
{
|
||||
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield);
|
||||
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield, tiling);
|
||||
gPipeline.mScreen.flush(); //blit, etc.
|
||||
}
|
||||
/// We copy the frame buffer straight into a texture here,
|
||||
|
||||
@@ -38,11 +38,7 @@ 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
|
||||
void display(BOOL rebuild = TRUE, F32 zoom_factor = 1.f, int subfield = 0, BOOL for_snapshot = FALSE, bool tiling = false);
|
||||
|
||||
extern BOOL gDisplaySwapBuffers;
|
||||
extern BOOL gDepthDirty;
|
||||
@@ -50,6 +46,7 @@ extern BOOL gTeleportDisplay;
|
||||
extern LLFrameTimer gTeleportDisplayTimer;
|
||||
extern BOOL gForceRenderLandFence;
|
||||
extern BOOL gResizeScreenTexture;
|
||||
extern BOOL gWindowResized;
|
||||
extern F32 gSavedDrawDistance;
|
||||
|
||||
#endif // LL_LLVIEWERDISPLAY_H
|
||||
|
||||
@@ -571,7 +571,7 @@ class LLFileTakeSnapshotToDisk : public view_listener_t
|
||||
|
||||
if (gSavedSettings.getBOOL("HighResSnapshot"))
|
||||
{
|
||||
#if SHY_MOD // screenshot improvement
|
||||
#if 1//SHY_MOD // screenshot improvement
|
||||
const F32 mult = gSavedSettings.getF32("SHHighResSnapshotScale");
|
||||
width *= mult;
|
||||
height *= mult;
|
||||
|
||||
@@ -200,7 +200,7 @@
|
||||
//
|
||||
// Globals
|
||||
//
|
||||
void render_ui(F32 zoom_factor = 1.f, int subfield = 0);
|
||||
void render_ui(F32 zoom_factor = 1.f, int subfield = 0, bool tiling = false);
|
||||
LLBottomPanel* gBottomPanel = NULL;
|
||||
|
||||
extern BOOL gDebugClicks;
|
||||
@@ -2130,6 +2130,7 @@ void LLViewerWindow::reshape(S32 width, S32 height)
|
||||
return;
|
||||
}
|
||||
|
||||
gWindowResized = TRUE;
|
||||
glViewport(0, 0, width, height );
|
||||
|
||||
if (height > 0)
|
||||
@@ -4278,21 +4279,27 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
||||
// Copy screen to a buffer
|
||||
// crop sides or top and bottom, if taking a snapshot of different aspect ratio
|
||||
// from window
|
||||
S32 snapshot_width = mWindowRect.getWidth();
|
||||
S32 snapshot_height = mWindowRect.getHeight();
|
||||
// SNAPSHOT
|
||||
S32 window_width = mWindowRect.getWidth();
|
||||
S32 window_height = mWindowRect.getHeight();
|
||||
LLRect window_rect = mWindowRect;
|
||||
BOOL use_fbo = FALSE;
|
||||
|
||||
LLRenderTarget target;
|
||||
S32 snapshot_width = window_rect.getWidth();
|
||||
S32 snapshot_height = window_rect.getHeight();
|
||||
// SNAPSHOT
|
||||
S32 window_width = snapshot_width;
|
||||
S32 window_height = snapshot_height;
|
||||
|
||||
|
||||
F32 scale_factor = 1.0f ;
|
||||
|
||||
bool is_tiling = false;
|
||||
|
||||
#if SHY_MOD // screenshot improvement
|
||||
//fbo method no longer supported. Good riddance
|
||||
/*LLRenderTarget target;
|
||||
bool use_fbo = false;
|
||||
static const LLCachedControl<bool> force_tile("SHHighResSnapshotForceTile",false);*/
|
||||
|
||||
#if 1//SHY_MOD // screenshot improvement
|
||||
F32 internal_scale = 1.f;
|
||||
static const LLCachedControl<bool> force_tile("SHHighResSnapshotForceTile",false);
|
||||
if(force_tile)
|
||||
//if(force_tile)
|
||||
{
|
||||
static const LLCachedControl<F32> super_sample_scale("SHHighResSnapshotSuperSample",1.f);
|
||||
internal_scale = llmax(super_sample_scale.get(),1.f);
|
||||
@@ -4313,10 +4320,8 @@ 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)
|
||||
//Unsupported
|
||||
/*if (!force_tile && gGLManager.mHasFramebufferObject && !show_ui)
|
||||
{
|
||||
GLint max_size = 0;
|
||||
glGetIntegerv(GL_MAX_RENDERBUFFER_SIZE_EXT, &max_size);
|
||||
@@ -4336,12 +4341,13 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
||||
}
|
||||
}
|
||||
|
||||
if(!use_fbo) //no re-projection, so tiling the scene
|
||||
if(!use_fbo) //no re-projection, so tiling the scene*/
|
||||
{
|
||||
F32 ratio = llmin( (F32)window_width / image_width , (F32)window_height / image_height) ;
|
||||
snapshot_width = (S32)(ratio * image_width) ;
|
||||
snapshot_height = (S32)(ratio * image_height) ;
|
||||
scale_factor = llmax(1.0f, 1.0f / ratio) ;
|
||||
is_tiling = true;
|
||||
}
|
||||
}
|
||||
//else: keep the current scene scale, re-scale it if necessary after reading out.
|
||||
@@ -4351,9 +4357,9 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
||||
S32 buffer_y_offset = llfloor(((window_height - snapshot_height) * scale_factor) / 2.f);
|
||||
|
||||
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.
|
||||
S32 image_buffer_y = llfloor(snapshot_height*scale_factor) ;
|
||||
#if 1//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
|
||||
{
|
||||
@@ -4418,20 +4424,16 @@ 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
|
||||
display(do_rebuild, scale_factor, subfield, TRUE, is_tiling);
|
||||
// Required for showing the GUI in snapshots? See DEV-16350 for details. JC
|
||||
render_ui(scale_factor, subfield);
|
||||
render_ui(scale_factor, subfield, is_tiling);
|
||||
}
|
||||
|
||||
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) -
|
||||
llmax(0, (window_width * (subimage_x + 1)) - (buffer_x_offset + raw->getWidth())));
|
||||
|
||||
for(U32 out_y = 0; out_y < read_height ; out_y++)
|
||||
{
|
||||
S32 output_buffer_offset = (
|
||||
@@ -4451,7 +4453,8 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
||||
if (type == SNAPSHOT_TYPE_OBJECT_ID || type == SNAPSHOT_TYPE_COLOR)
|
||||
{
|
||||
glReadPixels(
|
||||
subimage_x_offset, out_y + subimage_y_offset,
|
||||
subimage_x_offset,
|
||||
out_y + subimage_y_offset,
|
||||
read_width, 1,
|
||||
GL_RGB, GL_UNSIGNED_BYTE,
|
||||
raw->getData() + output_buffer_offset
|
||||
@@ -4487,12 +4490,12 @@ BOOL LLViewerWindow::rawSnapshot(LLImageRaw *raw, S32 image_width, S32 image_hei
|
||||
output_buffer_offset_y += subimage_y_offset;
|
||||
}
|
||||
|
||||
if (use_fbo)
|
||||
/*if (use_fbo)
|
||||
{
|
||||
mWindowRect = window_rect;
|
||||
target.flush();
|
||||
glBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
|
||||
}
|
||||
}*/
|
||||
gDisplaySwapBuffers = FALSE;
|
||||
gDepthDirty = TRUE;
|
||||
|
||||
@@ -4528,7 +4531,7 @@ 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 1//SHY_MOD // screenshot improvement
|
||||
if(raw->isBufferInvalid()) //Just checking!
|
||||
return FALSE;
|
||||
if(internal_scale != 1.f) //Scale down our render to the desired dimensions.
|
||||
@@ -4793,6 +4796,7 @@ void LLViewerWindow::restoreGL(const std::string& progress_message)
|
||||
LLVOAvatar::restoreGL();
|
||||
|
||||
gResizeScreenTexture = TRUE;
|
||||
gWindowResized = TRUE;
|
||||
|
||||
if (gFloaterCustomize && gFloaterCustomize->getVisible())
|
||||
{
|
||||
|
||||
@@ -224,11 +224,7 @@ 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;
|
||||
@@ -5300,7 +5296,7 @@ void LLPipeline::bindScreenToTexture()
|
||||
|
||||
}
|
||||
|
||||
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
|
||||
void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, bool tiling)
|
||||
{
|
||||
if (!(gPipeline.canUseVertexShaders() &&
|
||||
sRenderGlow))
|
||||
@@ -5352,7 +5348,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
|
||||
gGL.setColorMask(true, true);
|
||||
glClearColor(0,0,0,0);
|
||||
|
||||
if (for_snapshot)
|
||||
if (tiling && !LLPipeline::sRenderDeferred) //Need to coax this into working with deferred now that tiling is back.
|
||||
{
|
||||
gGL.getTexUnit(0)->bind(&mGlow[1]);
|
||||
{
|
||||
@@ -5374,7 +5370,6 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
|
||||
|
||||
LLGLEnable blend(GL_BLEND);
|
||||
gGL.setSceneBlendType(LLRender::BT_ADD);
|
||||
|
||||
|
||||
gGL.begin(LLRender::TRIANGLE_STRIP);
|
||||
gGL.color4f(1,1,1,1);
|
||||
@@ -5462,10 +5457,10 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield)
|
||||
const U32 glow_res = llmax(1,
|
||||
llmin(1024, 1 << glowResPow));
|
||||
|
||||
static const LLCachedControl<S32> glow_iters("RenderGlowIterations",2);//*2;
|
||||
static const LLCachedControl<S32> glow_iters("RenderGlowIterations",2);
|
||||
S32 kernel = glow_iters*2;
|
||||
static const LLCachedControl<F32> glow_width("RenderGlowWidth",1.3f);// / glow_res;
|
||||
F32 delta = glow_width/glow_res;
|
||||
static const LLCachedControl<F32> glow_width("RenderGlowWidth",1.3f);
|
||||
F32 delta = glow_width*zoom_factor/glow_res;
|
||||
// Use half the glow width if we have the res set to less than 9 so that it looks
|
||||
// almost the same in either case.
|
||||
if (glowResPow < 9)
|
||||
|
||||
@@ -99,7 +99,7 @@ public:
|
||||
void setDisableVBOMapping(BOOL no_vbo_mapping);
|
||||
void generateImpostor(LLVOAvatar* avatar);
|
||||
void bindScreenToTexture();
|
||||
void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0);
|
||||
void renderBloom(BOOL for_snapshot, F32 zoom_factor = 1.f, int subfield = 0, bool tiling = false);
|
||||
|
||||
void init();
|
||||
void cleanup();
|
||||
|
||||
Reference in New Issue
Block a user