Reworked LLPostProcess and implemented FBO support (much faster if multiple post shaders are enabled, or need a lot of passes).

Tweaked LLRenderTarget to support depth textures if FBO support is lacking.
Prefer LLRenderTarget::getFBO() over LLRenderTarget::sUseFBO when determining how to handle a specific LLRenderTarget object. (Decoupling to simplify logic without having to track a global)
This commit is contained in:
Shyotl
2012-07-29 04:28:11 -05:00
parent 701230b49c
commit 1d1947c51a
17 changed files with 660 additions and 473 deletions

View File

@@ -0,0 +1,23 @@
/**
* @file colorFilterF.glsl
*
* Copyright (c) 2007-$CurrentYear$, Linden Research, Inc.
* $License$
*/
#extension GL_ARB_texture_rectangle : enable
#ifdef DEFINE_GL_FRAGCOLOR
out vec4 gl_FragColor;
#endif
uniform sampler2DRect tex0;
uniform int layerCount;
VARYING vec2 vary_texcoord0;
void main(void)
{
vec3 color = pow(floor(pow(vec3(texture2D(tex0, vary_texcoord0.st)),vec3(.6)) * layerCount)/layerCount,vec3(1.66666));
gl_FragColor = vec4(color, 1.0);
}

View File

@@ -174,6 +174,8 @@
<boolean>0</boolean>
<key>enable_gauss_blur</key>
<boolean>0</boolean>
<key>enable_posterize</key>
<boolean>0</boolean>
<key>gauss_blur_passes</key>
<integer>2</integer>
<key>extract_high</key>
@@ -186,6 +188,8 @@
<real>0.40000000000000002</real>
<key>saturation</key>
<real>1</real>
</map>
<key>posterize_layers</key>
<real>10</real>
</map>
</map>
</llsd>

View File

@@ -57,7 +57,6 @@
#include "lldaycyclemanager.h"
#include "llwlparamset.h"
#include "llwlparammanager.h"
#include "llpostprocess.h"
#include "llfloaterwindlight.h"

View File

@@ -115,17 +115,7 @@ LLFloaterPostProcess* LLFloaterPostProcess::instance()
void LLFloaterPostProcess::onControlChanged(LLUICtrl* ctrl, void* userData)
{
char const *VariableName = (char const *)userData;
char buf[256];
S32 elem=0;
if(sscanf(VariableName,"%255[^[][%d]", buf, &elem) == 2)
{
LLPostProcess::getInstance()->tweaks[(const char*)buf][elem] = ctrl->getValue();
}
else
{
LLPostProcess::getInstance()->tweaks[VariableName] = ctrl->getValue();
}
LLPostProcess::getInstance()->setSelectedEffectValue((char const *)userData,ctrl->getValue());
}
void LLFloaterPostProcess::onLoadEffect(void* userData)
@@ -145,7 +135,7 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
std::string effectName(editBox->getValue().asString());
if (LLPostProcess::getInstance()->mAllEffects.has(effectName))
if (LLPostProcess::getInstance()->getAllEffectInfo().has(effectName))
{
LLSD payload;
payload["effect_name"] = effectName;
@@ -153,7 +143,7 @@ void LLFloaterPostProcess::onSaveEffect(void* userData)
}
else
{
LLPostProcess::getInstance()->saveEffect(effectName);
LLPostProcess::getInstance()->saveEffectAs(effectName);
sPostProcess->syncMenu();
}
}
@@ -175,7 +165,7 @@ bool LLFloaterPostProcess::saveAlertCallback(const LLSD& notification, const LLS
// if they choose save, do it. Otherwise, don't do anything
if (option == 0)
{
LLPostProcess::getInstance()->saveEffect(notification["payload"]["effect_name"].asString());
LLPostProcess::getInstance()->saveEffectAs(notification["payload"]["effect_name"].asString());
sPostProcess->syncMenu();
}
@@ -209,17 +199,17 @@ void LLFloaterPostProcess::syncMenu()
comboBox->removeall();
LLSD::map_const_iterator currEffect;
for(currEffect = LLPostProcess::getInstance()->mAllEffects.beginMap();
currEffect != LLPostProcess::getInstance()->mAllEffects.endMap();
for(currEffect = LLPostProcess::getInstance()->getAllEffectInfo().beginMap();
currEffect != LLPostProcess::getInstance()->getAllEffectInfo().endMap();
++currEffect)
{
comboBox->add(currEffect->first);
}
// set the current effect as selected.
comboBox->selectByValue(LLPostProcess::getInstance()->getSelectedEffect());
comboBox->selectByValue(LLPostProcess::getInstance()->getSelectedEffectName());
LLSD &tweaks = LLPostProcess::getInstance()->tweaks;
const LLSD &tweaks = LLPostProcess::getInstance()->getSelectedEffectInfo();
//Iterate down all uniforms handled by post-process shaders. Update any linked ui elements.
for (LLSD::map_const_iterator it = tweaks.beginMap(); it != tweaks.endMap(); ++it)
{

View File

@@ -62,7 +62,6 @@
#include "llwaterparamset.h"
#include "llwaterparammanager.h"
#include "llpostprocess.h"
#undef max

View File

@@ -62,7 +62,6 @@
#include "llwlparamset.h"
#include "llwlparammanager.h"
#include "llpostprocess.h"
#undef max

View File

@@ -200,7 +200,6 @@
#include "llnamelistctrl.h"
#include "llnamebox.h"
#include "llnameeditor.h"
#include "llpostprocess.h"
#include "llwlparammanager.h"
#include "llwaterparammanager.h"
#include "llagentlanguage.h"

View File

@@ -1009,7 +1009,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo
if (LLPipeline::sRenderDeferred && !LLPipeline::sUnderWaterRender)
{
gPipeline.mDeferredScreen.flush();
if(LLRenderTarget::sUseFBO)
if(gPipeline.mDeferredScreen.getFBO())
{
LLRenderTarget::copyContentsToFramebuffer(gPipeline.mDeferredScreen, 0, 0, gPipeline.mDeferredScreen.getWidth(),
gPipeline.mDeferredScreen.getHeight(), 0, 0,
@@ -1021,7 +1021,7 @@ void display(BOOL rebuild, F32 zoom_factor, int subfield, BOOL for_snapshot, boo
else
{
gPipeline.mScreen.flush();
if(LLRenderTarget::sUseFBO)
if(gPipeline.mScreen.getFBO())
{
LLRenderTarget::copyContentsToFramebuffer(gPipeline.mScreen, 0, 0, gPipeline.mScreen.getWidth(),
gPipeline.mScreen.getHeight(), 0, 0,
@@ -1283,14 +1283,12 @@ void render_ui(F32 zoom_factor, int subfield, bool tiling)
if (to_texture)
{
gPipeline.renderBloom(gSnapshot, zoom_factor, subfield, tiling);
gPipeline.mScreen.flush(); //blit, etc.
}
/// We copy the frame buffer straight into a texture here,
/// and then display it again with compositor effects.
/// Using render to texture would be faster/better, but I don't have a
/// grasp of their full display stack just yet.
if(gPipeline.canUseVertexShaders())
LLPostProcess::getInstance()->apply(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
{
LLPostProcess::getInstance()->renderEffects(gViewerWindow->getWindowDisplayWidth(), gViewerWindow->getWindowDisplayHeight());
}
render_hud_elements();
render_hud_attachments();

View File

@@ -170,6 +170,7 @@ LLGLSLShader gGlowExtractProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in
LLGLSLShader gPostColorFilterProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList
LLGLSLShader gPostNightVisionProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList
LLGLSLShader gPostGaussianBlurProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList
LLGLSLShader gPostPosterizeProgram(LLViewerShaderMgr::SHADER_EFFECT); //Not in mShaderList
// Deferred rendering shaders
LLGLSLShader gDeferredImpostorProgram(LLViewerShaderMgr::SHADER_DEFERRED);
@@ -958,6 +959,23 @@ BOOL LLViewerShaderMgr::loadShadersEffects()
gPostGaussianBlurProgram.uniform1i("tex0", 0);
}
}
{
vector<string> shaderUniforms;
shaderUniforms.reserve(1);
shaderUniforms.push_back("layerCount");
gPostPosterizeProgram.mName = "Posterize Shader (Post)";
gPostPosterizeProgram.mShaderFiles.clear();
gPostPosterizeProgram.mShaderFiles.push_back(make_pair("effects/PosterizeF.glsl", GL_FRAGMENT_SHADER_ARB));
gPostPosterizeProgram.mShaderFiles.push_back(make_pair("interface/onetexturenocolorV.glsl", GL_VERTEX_SHADER_ARB));
gPostPosterizeProgram.mShaderLevel = mVertexShaderLevel[SHADER_EFFECT];
if(gPostPosterizeProgram.createShader(NULL, &shaderUniforms))
{
gPostPosterizeProgram.bind();
gPostPosterizeProgram.uniform1i("tex0", 0);
}
}
#endif
return success;

View File

@@ -4839,7 +4839,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
if(LLPostProcess::instanceExists())
{
LLPostProcess::getInstance()->invalidate();
LLPostProcess::getInstance()->destroyGL();
}
gTextureList.destroyGL(save_state);

View File

@@ -54,6 +54,7 @@
#include "llglheaders.h"
#include "llrender.h"
#include "llwindow.h"
#include "llpostprocess.h"
// newview includes
#include "llagent.h"
@@ -863,6 +864,9 @@ void LLPipeline::releaseGLBuffers()
gBumpImageList.destroyGL();
LLVOAvatar::resetImpostors();
if(LLPostProcess::instanceExists())
LLPostProcess::getInstance()->destroyGL();
}
void LLPipeline::releaseLUTBuffers()
@@ -6111,12 +6115,14 @@ void LLPipeline::doResetVertexBuffers()
LLVOPartGroup::destroyGL();
if(LLPostProcess::instanceExists())
LLPostProcess::getInstance()->destroyGL();
LLVertexBuffer::cleanupClass();
//delete all name pool caches
LLGLNamePool::cleanupPools();
if (LLVertexBuffer::sGLCount > 0)
{
llwarns << "VBO wipe failed -- " << LLVertexBuffer::sGLCount << " buffers remaining." << llendl;
@@ -6923,7 +6929,7 @@ void LLPipeline::renderBloom(BOOL for_snapshot, F32 zoom_factor, int subfield, b
}
if (LLRenderTarget::sUseFBO)
if (mScreen.getFBO())
{ //copy depth buffer from mScreen to framebuffer
LLRenderTarget::copyContentsToFramebuffer(mScreen, 0, 0, mScreen.getWidth(), mScreen.getHeight(),
0, 0, mScreen.getWidth(), mScreen.getHeight(), GL_DEPTH_BUFFER_BIT, GL_NEAREST);

View File

@@ -146,6 +146,25 @@
left="14" max_val="1" min_val="0" mouse_opaque="true"
name="noise_strength" show_text="true" value="1.0" width="200" />
</panel>
<panel border="true" bottom="-180" follows="left|top|right|bottom" height="400"
label="Posterize" left="1" mouse_opaque="false"
name="PosterizePanel" width="398">
<check_box bottom="-20" follows="left|top"
font="SansSerifSmall" height="16" initial_value="false" label="Enable"
left="14" mouse_opaque="true" name="enable_posterize" width="200" />
<text type="string" length="1" bg_visible="false" border_drop_shadow_visible="false" border_visible="false"
bottom_delta="-21" drop_shadow_visible="true" follows="left|top|right"
font="SansSerif" h_pad="0" halign="left" height="16"
left="10" mouse_opaque="true" name="PosterLayersText" v_pad="0"
width="355">
Layer Count
</text>
<slider bottom_delta="-30" can_edit_text="true"
decimal_digits="3" follows="left"
height="18" increment="1" initial_val="10" label="" left="14"
max_val="20" min_val="1" mouse_opaque="true"
name="posterize_layers" show_text="true" value="10" width="200" />
</panel>
<!--<panel border="true" bottom="-180" follows="left|top|right|bottom" height="400"
label="Bloom" left="1" mouse_opaque="true"
name="BloomPanel" width="398">