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:
@@ -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);
|
||||
}
|
||||
@@ -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>
|
||||
@@ -57,7 +57,6 @@
|
||||
#include "lldaycyclemanager.h"
|
||||
#include "llwlparamset.h"
|
||||
#include "llwlparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
#include "llfloaterwindlight.h"
|
||||
|
||||
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
#include "llwaterparamset.h"
|
||||
#include "llwaterparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
|
||||
#undef max
|
||||
|
||||
|
||||
@@ -62,7 +62,6 @@
|
||||
|
||||
#include "llwlparamset.h"
|
||||
#include "llwlparammanager.h"
|
||||
#include "llpostprocess.h"
|
||||
|
||||
#undef max
|
||||
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -4839,7 +4839,7 @@ void LLViewerWindow::stopGL(BOOL save_state)
|
||||
|
||||
if(LLPostProcess::instanceExists())
|
||||
{
|
||||
LLPostProcess::getInstance()->invalidate();
|
||||
LLPostProcess::getInstance()->destroyGL();
|
||||
}
|
||||
|
||||
gTextureList.destroyGL(save_state);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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">
|
||||
|
||||
Reference in New Issue
Block a user