/* * RB_PostProcess * */ const void * RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; Vec4 white; Vec2 texScale; qbool autoExposure; texScale[0] = texScale[1] = 1.0f; setv34(white, 1, 1, 1, 1); if(!r_postProcess->integer){ /* if we have an FBO, just copy it out, otherwise, do nothing. */ if(glRefConfig.framebufferObject){ Vec4 srcBox, dstBox, color; setv34(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); /* setv34(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); */ setv34(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); color[0] = color[1] = color[2] = pow(2, r_cameraExposure->value); /* exp2(r_cameraExposure->value); */ color[3] = 1.0f; /* FBO_Blit(tr.renderFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, 0); */ FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); } backEnd.framePostProcessed = qtrue; return (const void*)(cmd + 1); } #if 0 if(!glRefConfig.framebufferObject){ /* we couldn't render straight to it, so just cap the screen instead */ GL_Bind(tr.renderImage); qglCopyTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, 0, 0, glConfig.vidWidth, glConfig.vidHeight); } #endif if(r_hdr->integer && (r_toneMap->integer == 2 || (r_toneMap->integer == 1 && tr.autoExposure))){ autoExposure = (r_autoExposure->integer == 1 && tr.autoExposure) || (r_autoExposure->integer == 2); RB_ToneMap(autoExposure); }else{ Vec4 srcBox, dstBox, color; setv34(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); setv34(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); color[0] = color[1] = color[2] = pow(2, r_cameraExposure->value); /* exp2(r_cameraExposure->value); */ color[3] = 1.0f; FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); } #ifdef REACTION RB_GodRays(); if(1) RB_BokehBlur(backEnd.refdef.blurFactor); else RB_GaussianBlur(backEnd.refdef.blurFactor); #endif /* * if (glRefConfig.framebufferObject) * { * // copy final image to screen * Vec4 srcBox, dstBox; * * setv34(srcBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); * setv34(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); * * FBO_Blit(tr.screenScratchFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0); * } */ backEnd.framePostProcessed = qtrue; return (const void*)(cmd + 1); }
/* ============= RB_PostProcess ============= */ const void *RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; FBO_t *srcFbo; ivec4_t srcBox, dstBox; qboolean autoExposure; // finish any 2D drawing if needed if(tess.numIndexes) RB_EndSurface(); if (!glRefConfig.framebufferObject || !r_postProcess->integer) { // do nothing return (const void *)(cmd + 1); } if (cmd) { backEnd.refdef = cmd->refdef; backEnd.viewParms = cmd->viewParms; } srcFbo = tr.renderFbo; if (tr.msaaResolveFbo) { // Resolve the MSAA before anything else // Can't resolve just part of the MSAA FBO, so multiple views will suffer a performance hit here FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); srcFbo = tr.msaaResolveFbo; } dstBox[0] = backEnd.viewParms.viewportX; dstBox[1] = backEnd.viewParms.viewportY; dstBox[2] = backEnd.viewParms.viewportWidth; dstBox[3] = backEnd.viewParms.viewportHeight; if (r_ssao->integer) { srcBox[0] = backEnd.viewParms.viewportX * tr.screenSsaoImage->width / (float)glConfig.vidWidth; srcBox[1] = backEnd.viewParms.viewportY * tr.screenSsaoImage->height / (float)glConfig.vidHeight; srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth; srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight; FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } srcBox[0] = backEnd.viewParms.viewportX; srcBox[1] = backEnd.viewParms.viewportY; srcBox[2] = backEnd.viewParms.viewportWidth; srcBox[3] = backEnd.viewParms.viewportHeight; if (srcFbo) { if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); } else if (r_cameraExposure->value == 0.0f) { FBO_FastBlit(srcFbo, srcBox, NULL, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { vec4_t color; color[0] = color[1] = 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); } } if (r_drawSunRays->integer) RB_SunRays(NULL, srcBox, NULL, dstBox); if (1) RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor); else RB_GaussianBlur(backEnd.refdef.blurFactor); #if 0 if (0) { vec4_t quadVerts[4]; vec2_t texCoords[4]; ivec4_t iQtrBox; vec4_t box; vec4_t viewInfo; static float scale = 5.0f; scale -= 0.005f; if (scale < 0.01f) scale = 5.0f; FBO_FastBlit(NULL, 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; iQtrBox[2] = backEnd.viewParms.viewportWidth * tr.quarterImage[0]->width / (float)glConfig.vidWidth; iQtrBox[3] = backEnd.viewParms.viewportHeight * tr.quarterImage[0]->height / (float)glConfig.vidHeight; qglViewport(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]); qglScissor(iQtrBox[0], iQtrBox[1], iQtrBox[2], iQtrBox[3]); VectorSet4(box, 0.0f, 0.0f, 1.0f, 1.0f); texCoords[0][0] = box[0]; texCoords[0][1] = box[3]; texCoords[1][0] = box[2]; texCoords[1][1] = box[3]; texCoords[2][0] = box[2]; texCoords[2][1] = box[1]; texCoords[3][0] = box[0]; texCoords[3][1] = box[1]; VectorSet4(box, -1.0f, -1.0f, 1.0f, 1.0f); VectorSet4(quadVerts[0], box[0], box[3], 0, 1); VectorSet4(quadVerts[1], box[2], box[3], 0, 1); VectorSet4(quadVerts[2], box[2], box[1], 0, 1); VectorSet4(quadVerts[3], box[0], box[1], 0, 1); GL_State(GLS_DEPTHTEST_DISABLE); VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0); viewInfo[2] = scale / (float)(tr.quarterImage[0]->width); viewInfo[3] = scale / (float)(tr.quarterImage[0]->height); FBO_Bind(tr.quarterFbo[1]); GLSL_BindProgram(&tr.depthBlurShader[2]); GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP); GLSL_SetUniformVec4(&tr.depthBlurShader[2], UNIFORM_VIEWINFO, viewInfo); RB_InstantQuad2(quadVerts, texCoords); FBO_Bind(tr.quarterFbo[0]); GLSL_BindProgram(&tr.depthBlurShader[3]); GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP); GLSL_SetUniformVec4(&tr.depthBlurShader[3], UNIFORM_VIEWINFO, viewInfo); RB_InstantQuad2(quadVerts, texCoords); SetViewportAndScissor(); FBO_FastBlit(tr.quarterFbo[1], NULL, NULL, NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR); FBO_Bind(NULL); } #endif if (0 && r_sunlightMode->integer) { ivec4_t dstBox; VectorSet4(dstBox, 0, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 128, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 384, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, NULL, 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); VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256); FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, NULL, 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); } #if 0 if (r_cubeMapping->integer && tr.numCubemaps) { ivec4_t dstBox; int cubemapIndex = R_CubemapForPoint( backEnd.viewParms.or.origin ); 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); } } #endif backEnd.framePostProcessed = qtrue; return (const void *)(cmd + 1); }
/* ============= RB_PostProcess ============= */ const void *RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; FBO_t *srcFbo; ivec4_t srcBox, dstBox; qboolean autoExposure; // finish any 2D drawing if needed if(tess.numIndexes) RB_EndSurface(); if (!glRefConfig.framebufferObject || !r_postProcess->integer) { // do nothing return (const void *)(cmd + 1); } if (cmd) { backEnd.refdef = cmd->refdef; backEnd.viewParms = cmd->viewParms; } srcFbo = tr.renderFbo; if (tr.msaaResolveFbo) { // Resolve the MSAA before anything else // Can't resolve just part of the MSAA FBO, so multiple views will suffer a performance hit here FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); srcFbo = tr.msaaResolveFbo; } dstBox[0] = backEnd.viewParms.viewportX; dstBox[1] = backEnd.viewParms.viewportY; dstBox[2] = backEnd.viewParms.viewportWidth; dstBox[3] = backEnd.viewParms.viewportHeight; if (r_ssao->integer) { srcBox[0] = backEnd.viewParms.viewportX * tr.screenSsaoImage->width / (float)glConfig.vidWidth; srcBox[1] = backEnd.viewParms.viewportY * tr.screenSsaoImage->height / (float)glConfig.vidHeight; srcBox[2] = backEnd.viewParms.viewportWidth * tr.screenSsaoImage->width / (float)glConfig.vidWidth; srcBox[3] = backEnd.viewParms.viewportHeight * tr.screenSsaoImage->height / (float)glConfig.vidHeight; //FBO_BlitFromTexture(tr.screenSsaoImage, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); srcBox[1] = tr.screenSsaoImage->height - srcBox[1]; srcBox[3] = -srcBox[3]; FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } srcBox[0] = backEnd.viewParms.viewportX; srcBox[1] = backEnd.viewParms.viewportY; srcBox[2] = backEnd.viewParms.viewportWidth; srcBox[3] = backEnd.viewParms.viewportHeight; if (srcFbo) { if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure); } else if (r_cameraExposure->value == 0.0f) { FBO_FastBlit(srcFbo, srcBox, NULL, dstBox, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { vec4_t color; color[0] = color[1] = 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); } } if (r_drawSunRays->integer) RB_SunRays(NULL, srcBox, NULL, dstBox); if (1) RB_BokehBlur(NULL, srcBox, NULL, dstBox, backEnd.refdef.blurFactor); else RB_GaussianBlur(backEnd.refdef.blurFactor); if (0 && r_sunlightMode->integer) { ivec4_t dstBox; VectorSet4(dstBox, 0, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 128, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, NULL, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 384, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[3], NULL, NULL, NULL, 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); VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256); FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, NULL, 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); } #if 0 if (r_cubeMapping->integer && tr.numCubemaps) { ivec4_t dstBox; int cubemapIndex = R_CubemapForPoint( backEnd.viewParms.or.origin ); 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], NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0); } } #endif backEnd.framePostProcessed = qtrue; return (const void *)(cmd + 1); }
/* ============= RB_PostProcess ============= */ const void *RB_PostProcess(const void *data) { const postProcessCommand_t *cmd = data; FBO_t *srcFbo; qboolean autoExposure; // finish any 2D drawing if needed if(tess.numIndexes) RB_EndSurface(); if (!glRefConfig.framebufferObject || !r_postProcess->integer) { // do nothing return (const void *)(cmd + 1); } srcFbo = tr.renderFbo; if (tr.msaaResolveFbo) { // Resolve the MSAA before anything else FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST); srcFbo = tr.msaaResolveFbo; } if (r_ssao->integer) { FBO_BlitFromTexture(tr.screenSsaoImage, NULL, NULL, srcFbo, NULL, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } if (srcFbo) { if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer)) { autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer; RB_ToneMap(srcFbo, autoExposure); } else if (r_cameraExposure->value == 0.0f) { FBO_FastBlit(srcFbo, NULL, tr.screenScratchFbo, NULL, GL_COLOR_BUFFER_BIT, GL_NEAREST); } else { vec4_t color; color[0] = color[1] = color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[3] = 1.0f; FBO_Blit(srcFbo, NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, 0); } } if (r_drawSunRays->integer) RB_SunRays(); if (1) RB_BokehBlur(backEnd.refdef.blurFactor); else RB_GaussianBlur(backEnd.refdef.blurFactor); if (0) { vec4i_t dstBox; VectorSet4(dstBox, 0, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[0], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 128, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[1], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 256, 0, 128, 128); FBO_BlitFromTexture(tr.sunShadowDepthImage[2], NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); } if (0) { vec4i_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); VectorSet4(dstBox, 512, glConfig.vidHeight - 256, 256, 256); FBO_BlitFromTexture(tr.screenShadowImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); } if (0) { vec4i_t dstBox; VectorSet4(dstBox, 256, glConfig.vidHeight - 256, 256, 256); FBO_BlitFromTexture(tr.sunRaysImage, NULL, NULL, tr.screenScratchFbo, dstBox, NULL, NULL, 0); } backEnd.framePostProcessed = qtrue; return (const void *)(cmd + 1); }