1
0
mirror of https://github.com/blawar/GLideN64.git synced 2024-07-02 09:03:37 +00:00

Rewrite PostProcessor: do not modify original buffer, use special frame buffer instead.

Fixed dual heroes: incorrect colors in menu #926
This commit is contained in:
Sergey Lipskiy 2016-04-02 18:56:07 +06:00
parent 82896399fa
commit 427806ac23
3 changed files with 98 additions and 43 deletions

View File

@ -835,15 +835,15 @@ void FrameBufferList::renderBuffer(u32 _address)
dstCoord[0] += 1; // workaround for Adreno's issue with glBindFramebuffer;
#endif // GLESX
PostProcessor::get().doGammaCorrection(pBuffer);
PostProcessor::get().doBlur(pBuffer);
FrameBuffer * pFilteredBuffer = PostProcessor::get().doBlur(PostProcessor::get().doGammaCorrection(pBuffer));
pBuffer->m_postProcessed = pFilteredBuffer->m_postProcessed;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, 0);
//glDrawBuffer( GL_BACK );
float clearColor[4] = { 0.0f, 0.0f, 0.0f, 0.0f };
render.clearColorBuffer(clearColor);
GLenum filter = GL_LINEAR;
if (config.video.multisampling != 0) {
if (config.video.multisampling != 0 && pFilteredBuffer == pBuffer) {
if (X0 > 0 || dstPartHeight > 0 ||
(srcCoord[2] - srcCoord[0]) != (dstCoord[2] - dstCoord[0]) ||
(srcCoord[3] - srcCoord[1]) != (dstCoord[3] - dstCoord[1])) {
@ -855,7 +855,7 @@ void FrameBufferList::renderBuffer(u32 _address)
filter = GL_NEAREST;
}
} else
glBindFramebuffer(GL_READ_FRAMEBUFFER, pBuffer->m_FBO);
glBindFramebuffer(GL_READ_FRAMEBUFFER, pFilteredBuffer->m_FBO);
// glDisable(GL_SCISSOR_TEST) does not affect glBlitFramebuffer, at least on AMD
glScissor(0, 0, ogl.getScreenWidth(), ogl.getScreenHeight() + ogl.getHeightOffset());
@ -902,8 +902,8 @@ void FrameBufferList::renderBuffer(u32 _address)
OGLVideo & ogl = video();
ogl.getRender().updateScissor(pBuffer);
PostProcessor::get().doGammaCorrection(pBuffer);
PostProcessor::get().doBlur(pBuffer);
FrameBuffer * pFilteredBuffer = PostProcessor::get().doBlur(PostProcessor::get().doGammaCorrection(pBuffer));
pBuffer->m_postProcessed = pFilteredBuffer->m_postProcessed;
ogl.getRender().dropRenderState();
gSP.changed = gDP.changed = 0;
@ -913,16 +913,16 @@ void FrameBufferList::renderBuffer(u32 _address)
glDisable( GL_CULL_FACE );
glDisable( GL_POLYGON_OFFSET_FILL );
const u32 width = pBuffer->m_width;
const u32 height = pBuffer->m_height;
const u32 width = pFilteredBuffer->m_width;
const u32 height = pFilteredBuffer->m_height;
pBuffer->m_pTexture->scaleS = ogl.getScaleX() / (float)pBuffer->m_pTexture->realWidth;
pBuffer->m_pTexture->scaleT = ogl.getScaleY() / (float)pBuffer->m_pTexture->realHeight;
pBuffer->m_pTexture->shiftScaleS = 1.0f;
pBuffer->m_pTexture->shiftScaleT = 1.0f;
pBuffer->m_pTexture->offsetS = 0;
pBuffer->m_pTexture->offsetT = (float)height;
textureCache().activateTexture(0, pBuffer->m_pTexture);
pFilteredBuffer->m_pTexture->scaleS = ogl.getScaleX() / (float)pFilteredBuffer->m_pTexture->realWidth;
pFilteredBuffer->m_pTexture->scaleT = ogl.getScaleY() / (float)pFilteredBuffer->m_pTexture->realHeight;
pFilteredBuffer->m_pTexture->shiftScaleS = 1.0f;
pFilteredBuffer->m_pTexture->shiftScaleT = 1.0f;
pFilteredBuffer->m_pTexture->offsetS = 0;
pFilteredBuffer->m_pTexture->offsetT = (float)height;
textureCache().activateTexture(0, pFilteredBuffer->m_pTexture);
gSP.textureTile[0]->fuls = gSP.textureTile[0]->fult = 0.0f;
gSP.textureTile[0]->shifts = gSP.textureTile[0]->shiftt = 0;
currentCombiner()->updateTextureInfo(true);
@ -932,7 +932,7 @@ void FrameBufferList::renderBuffer(u32 _address)
glBindFramebuffer(GL_FRAMEBUFFER, 0);
OGLRender::TexturedRectParams params(0.0f, 0.0f, width, height, 0.0f, 0.0f, width - 1.0f, height - 1.0f, false, false, pBuffer);
OGLRender::TexturedRectParams params(0.0f, 0.0f, width, height, 0.0f, 0.0f, width - 1.0f, height - 1.0f, false, false, pFilteredBuffer);
ogl.getRender().drawTexturedRect(params);
glBindFramebuffer(GL_READ_FRAMEBUFFER, 0);

View File

@ -285,9 +285,8 @@ GLuint _createShaderProgram(const char * _strVertex, const char * _strFragment)
}
static
CachedTexture * _createTexture()
void _initTexture(CachedTexture * pTexture)
{
CachedTexture * pTexture = textureCache().addFrameBufferTexture();
pTexture->format = G_IM_FMT_RGBA;
pTexture->clampS = 1;
pTexture->clampT = 1;
@ -306,25 +305,58 @@ CachedTexture * _createTexture()
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
glBindTexture(GL_TEXTURE_2D, 0);
}
static
CachedTexture * _createTexture()
{
CachedTexture * pTexture = textureCache().addFrameBufferTexture();
_initTexture(pTexture);
return pTexture;
}
static
void _initFBO(GLuint _FBO, CachedTexture * _pTexture)
{
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _FBO);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _pTexture->glName, 0);
assert(checkFBO());
}
static
GLuint _createFBO(CachedTexture * _pTexture)
{
GLuint FBO;
glGenFramebuffers(1, &FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, FBO);
glFramebufferTexture2D(GL_DRAW_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, _pTexture->glName, 0);
assert(checkFBO());
_initFBO(FBO, _pTexture);
return FBO;
}
PostProcessor::PostProcessor()
: m_extractBloomProgram(0)
, m_seperableBlurProgram(0)
, m_glowProgram(0)
, m_bloomProgram(0)
, m_copyProgram(0)
, m_gammaCorrectionProgram(0)
, m_pResultBuffer(nullptr)
, m_FBO_original(0)
, m_FBO_glowMap(0)
, m_FBO_blur(0)
, m_pTextureOriginal(nullptr)
, m_pTextureGlowMap(nullptr)
, m_pTextureBlur(nullptr)
{}
void PostProcessor::_initCommon()
{
m_pTextureOriginal = _createTexture();
m_FBO_original = _createFBO(m_pTextureOriginal);
m_pResultBuffer = new FrameBuffer();
_initTexture(m_pResultBuffer->m_pTexture);
_initFBO(m_pResultBuffer->m_FBO, m_pResultBuffer->m_pTexture);
#ifdef GLES2
m_copyProgram = _createShaderProgram(vertexShader, copyShader);
glUseProgram(m_copyProgram);
@ -424,6 +456,10 @@ void PostProcessor::_destroyCommon()
if (m_pTextureOriginal != nullptr)
textureCache().removeFrameBufferTexture(m_pTextureOriginal);
m_pTextureOriginal = nullptr;
delete m_pResultBuffer;
m_pResultBuffer = nullptr;
}
void PostProcessor::_destroyGammaCorrection()
@ -438,12 +474,15 @@ void PostProcessor::_destroyBlur()
if (m_extractBloomProgram != 0)
glDeleteProgram(m_extractBloomProgram);
m_extractBloomProgram = 0;
if (m_seperableBlurProgram != 0)
glDeleteProgram(m_seperableBlurProgram);
m_seperableBlurProgram = 0;
if (m_glowProgram != 0)
glDeleteProgram(m_glowProgram);
m_glowProgram = 0;
if (m_bloomProgram != 0)
glDeleteProgram(m_bloomProgram);
m_bloomProgram = 0;
@ -451,14 +490,15 @@ void PostProcessor::_destroyBlur()
if (m_FBO_glowMap != 0)
glDeleteFramebuffers(1, &m_FBO_glowMap);
m_FBO_glowMap = 0;
if (m_FBO_blur != 0)
glDeleteFramebuffers(1, &m_FBO_blur);
m_FBO_blur = 0;
m_pTextureOriginal = nullptr;
if (m_pTextureGlowMap != nullptr)
textureCache().removeFrameBufferTexture(m_pTextureGlowMap);
m_pTextureGlowMap = nullptr;
if (m_pTextureBlur != nullptr)
textureCache().removeFrameBufferTexture(m_pTextureBlur);
m_pTextureBlur = nullptr;
@ -510,6 +550,11 @@ void PostProcessor::_preDraw(FrameBuffer * _pBuffer)
OGLVideo & ogl = video();
#ifdef GLES2
m_pResultBuffer->m_width = _pBuffer->m_width;
m_pResultBuffer->m_height = _pBuffer->m_height;
m_pResultBuffer->m_scaleX = _pBuffer->m_scaleX;
m_pResultBuffer->m_scaleY = _pBuffer->m_scaleY;
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_FBO_original);
textureCache().activateTexture(0, _pBuffer->m_pTexture);
glUseProgram(m_copyProgram);
@ -534,13 +579,18 @@ void PostProcessor::_postDraw()
glUseProgram(0);
}
void PostProcessor::doBlur(FrameBuffer * _pBuffer)
FrameBuffer * PostProcessor::doBlur(FrameBuffer * _pBuffer)
{
if (config.bloomFilter.enable == 0)
return;
if (_pBuffer == nullptr)
return nullptr;
if (_pBuffer == nullptr || (_pBuffer->m_postProcessed&PostProcessor::postEffectBlur) == PostProcessor::postEffectBlur)
return;
m_pResultBuffer->m_postProcessed = _pBuffer->m_postProcessed;
if (config.bloomFilter.enable == 0)
return _pBuffer;
if ((_pBuffer->m_postProcessed&PostProcessor::postEffectBlur) == PostProcessor::postEffectBlur)
return m_pResultBuffer;
_pBuffer->m_postProcessed |= PostProcessor::postEffectBlur;
@ -564,33 +614,40 @@ void PostProcessor::doBlur(FrameBuffer * _pBuffer)
glUniform1i(loc, 1);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pResultBuffer->m_FBO);
textureCache().activateTexture(0, m_pTextureOriginal);
textureCache().activateTexture(1, m_pTextureGlowMap);
glUseProgram(m_glowProgram);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
_postDraw();
m_pResultBuffer->m_postProcessed = _pBuffer->m_postProcessed;
return m_pResultBuffer;
}
void PostProcessor::doGammaCorrection(FrameBuffer * _pBuffer)
FrameBuffer * PostProcessor::doGammaCorrection(FrameBuffer * _pBuffer)
{
if (((*REG.VI_STATUS & 8)|config.gammaCorrection.force) == 0)
return;
if (_pBuffer == nullptr)
return nullptr;
if (_pBuffer == nullptr || (_pBuffer->m_postProcessed&PostProcessor::postEffectGammaCorrection) == PostProcessor::postEffectGammaCorrection)
return;
m_pResultBuffer->m_postProcessed = _pBuffer->m_postProcessed;
if (((*REG.VI_STATUS & 8) | config.gammaCorrection.force) == 0)
return _pBuffer;
if ((_pBuffer->m_postProcessed&PostProcessor::postEffectGammaCorrection) == PostProcessor::postEffectGammaCorrection)
return m_pResultBuffer;
_pBuffer->m_postProcessed |= PostProcessor::postEffectGammaCorrection;
_preDraw(_pBuffer);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, _pBuffer->m_FBO);
glBindFramebuffer(GL_DRAW_FRAMEBUFFER, m_pResultBuffer->m_FBO);
textureCache().activateTexture(0, m_pTextureOriginal);
glUseProgram(m_gammaCorrectionProgram);
glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
_postDraw();
m_pResultBuffer->m_postProcessed = _pBuffer->m_postProcessed;
return m_pResultBuffer;
}

View File

@ -10,8 +10,8 @@ public:
void init();
void destroy();
void doBlur(FrameBuffer * _pBuffer);
void doGammaCorrection(FrameBuffer * _pBuffer);
FrameBuffer * doBlur(FrameBuffer * _pBuffer);
FrameBuffer * doGammaCorrection(FrameBuffer * _pBuffer);
static PostProcessor & get();
@ -19,11 +19,7 @@ public:
static const u32 postEffectGammaCorrection = 2U;
private:
PostProcessor() :
m_extractBloomProgram(0), m_seperableBlurProgram(0),
m_glowProgram(0), m_bloomProgram(0), m_copyProgram(0), m_gammaCorrectionProgram(0),
m_FBO_original(0), m_FBO_glowMap(0), m_FBO_blur(0),
m_pTextureOriginal(NULL), m_pTextureGlowMap(NULL), m_pTextureBlur(NULL) {}
PostProcessor();
PostProcessor(const PostProcessor & _other);
void _initCommon();
void _destroyCommon();
@ -42,6 +38,8 @@ private:
GLuint m_gammaCorrectionProgram;
FrameBuffer * m_pResultBuffer;
GLuint m_FBO_original;
GLuint m_FBO_glowMap;
GLuint m_FBO_blur;