diff --git a/code/renderergl2/tr_backend.c b/code/renderergl2/tr_backend.c index 5c160ab45..0cffa4ee2 100644 --- a/code/renderergl2/tr_backend.c +++ b/code/renderergl2/tr_backend.c @@ -342,7 +342,7 @@ void RB_BeginDrawingView (void) { { FBO_t *fbo = backEnd.viewParms.targetFbo; - if (fbo == NULL && (!r_postProcess->integer || !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL))) + if (fbo == NULL) fbo = tr.renderFbo; if (tr.renderCubeFbo && fbo == tr.renderCubeFbo) @@ -708,7 +708,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte * if (glRefConfig.framebufferObject) { - FBO_Bind(r_postProcess->integer ? NULL : tr.renderFbo); + FBO_Bind(tr.renderFbo); } RB_SetGL2D(); @@ -793,7 +793,7 @@ const void *RB_StretchPic ( const void *data ) { cmd = (const stretchPicCommand_t *)data; if (glRefConfig.framebufferObject) - FBO_Bind(r_postProcess->integer ? NULL : tr.renderFbo); + FBO_Bind(tr.renderFbo); RB_SetGL2D(); @@ -1202,15 +1202,12 @@ const void *RB_DrawBuffer( const void *data ) { // clear screen for debugging if ( r_clear->integer ) { - qglClearColor( 1, 0, 0.5, 1 ); - qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - if (glRefConfig.framebufferObject && tr.renderFbo) { FBO_Bind(tr.renderFbo); - - qglClearColor( 1, 0, 0.5, 1 ); - qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); } + + qglClearColor( 1, 0, 0.5, 1 ); + qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); } return (const void *)(cmd + 1); @@ -1381,18 +1378,15 @@ const void *RB_SwapBuffers( const void *data ) { if (glRefConfig.framebufferObject) { - if (!r_postProcess->integer) + if (tr.msaaResolveFbo && r_hdr->integer) { - if (tr.msaaResolveFbo && r_hdr->integer) - { - // Resolving an RGB16F MSAA FBO to the screen messes with the brightness, so resolve to an RGB16F FBO first - FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); - FBO_FastBlit(tr.msaaResolveFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - else if (tr.renderFbo) - { - FBO_FastBlit(tr.renderFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); - } + // Resolving an RGB16F MSAA FBO to the screen messes with the brightness, so resolve to an RGB16F FBO first + FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + FBO_FastBlit(tr.msaaResolveFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); + } + else if (tr.renderFbo) + { + FBO_FastBlit(tr.renderFbo, NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } } @@ -1454,7 +1448,7 @@ RB_PostProcess const void *RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; - FBO_t *srcFbo; + FBO_t *srcFbo, *dstFbo; ivec4_t srcBox, dstBox; qboolean autoExposure; @@ -1475,6 +1469,8 @@ const void *RB_PostProcess(const void *data) } srcFbo = tr.renderFbo; + dstFbo = tr.renderFbo; + if (tr.msaaResolveFbo) { // Resolve the MSAA before anything else @@ -1508,13 +1504,13 @@ const void *RB_PostProcess(const void *data) if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; - RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); + + // Use an intermediate FBO because it can't blit to the same FBO directly + // and can't read from an MSAA dstFbo later. + RB_ToneMap(srcFbo, srcBox, tr.screenScratchFbo, srcBox, autoExposure); + FBO_FastBlit(tr.screenScratchFbo, srcBox, srcFbo, srcBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); } - else if (r_cameraExposure->value == 0.0f) - { - FBO_FastBlit(srcFbo, srcBox, NULL, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); - } - else + else if (r_cameraExposure->value != 0.0f) { vec4_t color; @@ -1523,17 +1519,20 @@ const void *RB_PostProcess(const void *data) color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[3] = 1.0f; - FBO_Blit(srcFbo, srcBox, NULL, NULL, dstBox, NULL, color, 0); + FBO_BlitFromTexture(tr.whiteImage, NULL, NULL, srcFbo, srcBox, NULL, color, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } } if (r_drawSunRays->integer) - RB_SunRays(NULL, srcBox, NULL, dstBox); + RB_SunRays(srcFbo, srcBox, srcFbo, srcBox); if (1) - RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor); + RB_BokehBlur(srcFbo, srcBox, srcFbo, srcBox, backEnd.refdef.blurFactor); else - RB_GaussianBlur(backEnd.refdef.blurFactor); + RB_GaussianBlur(srcFbo, srcFbo, backEnd.refdef.blurFactor); + + if (srcFbo != dstFbo) + FBO_FastBlit(srcFbo, srcBox, dstFbo, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); #if 0 if (0) @@ -1549,7 +1548,7 @@ const void *RB_PostProcess(const void *data) if (scale < 0.01f) scale = 5.0f; - FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); + FBO_FastBlit(dstFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); iQtrBox[0] = backEnd.viewParms.viewportX * tr.quarterImage[0]->width / (float)glConfig.vidWidth; iQtrBox[1] = backEnd.viewParms.viewportY * tr.quarterImage[0]->height / (float)glConfig.vidHeight; @@ -1595,7 +1594,7 @@ const void *RB_PostProcess(const void *data) SetViewportAndScissor(); - FBO_FastBlit(tr.quarterFbo[1], NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); + FBO_FastBlit(tr.quarterFbo[1], NULL, dstFbo, NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); FBO_Bind(NULL); } #endif @@ -1604,42 +1603,42 @@ const void *RB_PostProcess(const void *data) { ivec4_t dstBox; VectorSet4(dstBox, 0, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 128, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 384, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); } if (0 && r_shadows->integer == 4) { ivec4_t dstBox; VectorSet4(dstBox, 512 + 0, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.pshadowMaps[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.pshadowMaps[0], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512 + 128, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.pshadowMaps[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.pshadowMaps[1], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512 + 256, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.pshadowMaps[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.pshadowMaps[2], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512 + 384, glConfig.vidHeight - 128, 128, 128); - FBO_BlitFromTexture(tr.pshadowMaps[3], NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.pshadowMaps[3], NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); } if (0) { ivec4_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); } if (0) { ivec4_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); - FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, NULL, dstBox, NULL, NULL, 0); + FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, dstFbo, dstBox, NULL, NULL, 0); } #if 0 @@ -1651,8 +1650,8 @@ const void *RB_PostProcess(const void *data) if (cubemapIndex) { VectorSet4(dstBox, 0, glConfig.vidHeight - 256, 256, 256); - //FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0); - FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1].image, NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0); + //FBO_BlitFromTexture(tr.renderCubeImage, NULL, NULL, dstFbo, dstBox, &tr.testcubeShader, NULL, 0); + FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1].image, NULL, NULL, dstFbo, dstBox, &tr.testcubeShader, NULL, 0); } } #endif diff --git a/code/renderergl2/tr_image.c b/code/renderergl2/tr_image.c index 09ceff083..101513b63 100644 --- a/code/renderergl2/tr_image.c +++ b/code/renderergl2/tr_image.c @@ -2766,7 +2766,7 @@ void R_CreateBuiltinImages( void ) { tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); - if (r_shadowBlur->integer) + if (r_shadowBlur->integer || r_hdr->integer) tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); if (r_shadowBlur->integer || r_ssao->integer) diff --git a/code/renderergl2/tr_postprocess.c b/code/renderergl2/tr_postprocess.c index 9931757b8..3d71f3041 100644 --- a/code/renderergl2/tr_postprocess.c +++ b/code/renderergl2/tr_postprocess.c @@ -447,7 +447,7 @@ static void RB_VBlur(FBO_t *srcFbo, FBO_t *dstFbo, float strength) RB_BlurAxis(srcFbo, dstFbo, strength, qfalse); } -void RB_GaussianBlur(float blur) +void RB_GaussianBlur(FBO_t *srcFbo, FBO_t *dstFbo, float blur) { //float mul = 1.f; float factor = Com_Clamp(0.f, 1.f, blur); @@ -462,7 +462,7 @@ void RB_GaussianBlur(float blur) VectorSet4(color, 1, 1, 1, 1); // first, downsample the framebuffer - FBO_FastBlit(NULL, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); + FBO_FastBlit(srcFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); // set the alpha channel @@ -478,6 +478,6 @@ void RB_GaussianBlur(float blur) VectorSet4(srcBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height); VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); color[3] = factor; - FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, NULL, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } } diff --git a/code/renderergl2/tr_postprocess.h b/code/renderergl2/tr_postprocess.h index 09daf1346..a2d6d0b3f 100644 --- a/code/renderergl2/tr_postprocess.h +++ b/code/renderergl2/tr_postprocess.h @@ -28,6 +28,6 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA void RB_ToneMap(FBO_t *hdrFbo, ivec4_t hdrBox, FBO_t *ldrFbo, ivec4_t ldrBox, int autoExposure); void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float blur); void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox); -void RB_GaussianBlur(float blur); +void RB_GaussianBlur(FBO_t *srcFbo, FBO_t *dstFbo, float blur); #endif