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:
Shyotl
2011-04-21 23:36:41 -05:00
parent 673a338bf5
commit 98c2b7e11f
6 changed files with 66 additions and 75 deletions

View File

@@ -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,

View File

@@ -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

View File

@@ -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;

View File

@@ -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())
{

View File

@@ -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)

View File

@@ -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();