renderer -> renderergl1, rend2 -> renderergl2
This commit is contained in:
parent
bff574e04e
commit
f6fb9eb602
120 changed files with 1277 additions and 1294 deletions
488
code/renderergl2/tr_postprocess.c
Normal file
488
code/renderergl2/tr_postprocess.c
Normal file
|
@ -0,0 +1,488 @@
|
|||
/*
|
||||
===========================================================================
|
||||
Copyright (C) 2011 Andrei Drexler, Richard Allen, James Canete
|
||||
|
||||
This file is part of Reaction source code.
|
||||
|
||||
Reaction source code is free software; you can redistribute it
|
||||
and/or modify it under the terms of the GNU General Public License as
|
||||
published by the Free Software Foundation; either version 2 of the License,
|
||||
or (at your option) any later version.
|
||||
|
||||
Reaction source code is distributed in the hope that it will be
|
||||
useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
GNU General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU General Public License
|
||||
along with Reaction source code; if not, write to the Free Software
|
||||
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
|
||||
===========================================================================
|
||||
*/
|
||||
|
||||
#include "tr_local.h"
|
||||
|
||||
void RB_ToneMap(FBO_t *hdrFbo, int autoExposure)
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
static int lastFrameCount = 0;
|
||||
|
||||
if (autoExposure)
|
||||
{
|
||||
if (lastFrameCount == 0 || tr.frameCount < lastFrameCount || tr.frameCount - lastFrameCount > 5)
|
||||
{
|
||||
// determine average log luminance
|
||||
FBO_t *srcFbo, *dstFbo, *tmp;
|
||||
int size = 256;
|
||||
|
||||
lastFrameCount = tr.frameCount;
|
||||
|
||||
VectorSet4(dstBox, 0, 0, size, size);
|
||||
|
||||
srcFbo = hdrFbo;
|
||||
dstFbo = tr.textureScratchFbo[0];
|
||||
FBO_Blit(srcFbo, NULL, NULL, dstFbo, dstBox, &tr.calclevels4xShader[0], NULL, 0);
|
||||
|
||||
srcFbo = tr.textureScratchFbo[0];
|
||||
dstFbo = tr.textureScratchFbo[1];
|
||||
|
||||
// downscale to 1x1 texture
|
||||
while (size > 1)
|
||||
{
|
||||
VectorSet4(srcBox, 0, 0, size, size);
|
||||
//size >>= 2;
|
||||
size >>= 1;
|
||||
VectorSet4(dstBox, 0, 0, size, size);
|
||||
|
||||
if (size == 1)
|
||||
dstFbo = tr.targetLevelsFbo;
|
||||
|
||||
//FBO_Blit(targetFbo, srcBox, NULL, tr.textureScratchFbo[nextScratch], dstBox, &tr.calclevels4xShader[1], NULL, 0);
|
||||
FBO_FastBlit(srcFbo, srcBox, dstFbo, dstBox, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
|
||||
tmp = srcFbo;
|
||||
srcFbo = dstFbo;
|
||||
dstFbo = tmp;
|
||||
}
|
||||
}
|
||||
|
||||
// blend with old log luminance for gradual change
|
||||
VectorSet4(srcBox, 0, 0, 0, 0);
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = 1.0f;
|
||||
if (glRefConfig.textureFloat)
|
||||
color[3] = 0.03f;
|
||||
else
|
||||
color[3] = 0.1f;
|
||||
|
||||
FBO_Blit(tr.targetLevelsFbo, srcBox, NULL, tr.calcLevelsFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
// tonemap
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value);
|
||||
color[3] = 1.0f;
|
||||
|
||||
if (autoExposure)
|
||||
GL_BindToTMU(tr.calcLevelsImage, TB_LEVELSMAP);
|
||||
else
|
||||
GL_BindToTMU(tr.fixedLevelsImage, TB_LEVELSMAP);
|
||||
|
||||
FBO_Blit(hdrFbo, NULL, NULL, tr.screenScratchFbo, NULL, &tr.tonemapShader, color, 0);
|
||||
}
|
||||
|
||||
|
||||
void RB_BokehBlur(float blur)
|
||||
{
|
||||
// vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
|
||||
blur *= 10.0f;
|
||||
|
||||
if (blur < 0.004f)
|
||||
return;
|
||||
|
||||
if (glRefConfig.framebufferObject)
|
||||
{
|
||||
// bokeh blur
|
||||
if (blur > 0.0f)
|
||||
{
|
||||
// create a quarter texture
|
||||
//FBO_Blit(NULL, NULL, NULL, tr.quarterFbo[0], NULL, NULL, NULL, 0);
|
||||
FBO_FastBlit(tr.screenScratchFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
}
|
||||
|
||||
#ifndef HQ_BLUR
|
||||
if (blur > 1.0f)
|
||||
{
|
||||
// create a 1/16th texture
|
||||
//FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.textureScratchFbo[0], NULL, NULL, NULL, 0);
|
||||
FBO_FastBlit(tr.quarterFbo[0], NULL, tr.textureScratchFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (blur > 0.0f && blur <= 1.0f)
|
||||
{
|
||||
// Crossfade original with quarter texture
|
||||
VectorSet4(color, 1, 1, 1, blur);
|
||||
|
||||
FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
#ifndef HQ_BLUR
|
||||
// ok blur, but can see some pixelization
|
||||
else if (blur > 1.0f && blur <= 2.0f)
|
||||
{
|
||||
// crossfade quarter texture with 1/16th texture
|
||||
FBO_Blit(tr.quarterFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, NULL, 0);
|
||||
|
||||
VectorSet4(color, 1, 1, 1, blur - 1.0f);
|
||||
|
||||
FBO_Blit(tr.textureScratchFbo[0], NULL, NULL, tr.screenScratchFbo, NULL, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
else if (blur > 2.0f)
|
||||
{
|
||||
// blur 1/16th texture then replace
|
||||
int i;
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
vec2_t blurTexScale;
|
||||
float subblur;
|
||||
|
||||
subblur = ((blur - 2.0f) / 2.0f) / 3.0f * (float)(i + 1);
|
||||
|
||||
blurTexScale[0] =
|
||||
blurTexScale[1] = subblur;
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = 0.5f;
|
||||
color[3] = 1.0f;
|
||||
|
||||
if (i != 0)
|
||||
FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
|
||||
else
|
||||
FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0);
|
||||
}
|
||||
|
||||
FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, tr.screenScratchFbo, NULL, &tr.textureColorShader, NULL, 0);
|
||||
}
|
||||
#else // higher quality blur, but slower
|
||||
else if (blur > 1.0f)
|
||||
{
|
||||
// blur quarter texture then replace
|
||||
int i;
|
||||
|
||||
src = tr.quarterFbo[0];
|
||||
dst = tr.quarterFbo[1];
|
||||
|
||||
VectorSet4(color, 0.5f, 0.5f, 0.5f, 1);
|
||||
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
vec2_t blurTexScale;
|
||||
float subblur;
|
||||
|
||||
subblur = (blur - 1.0f) / 2.0f * (float)(i + 1);
|
||||
|
||||
blurTexScale[0] =
|
||||
blurTexScale[1] = subblur;
|
||||
|
||||
color[0] =
|
||||
color[1] =
|
||||
color[2] = 1.0f;
|
||||
if (i != 0)
|
||||
color[3] = 1.0f;
|
||||
else
|
||||
color[3] = 0.5f;
|
||||
|
||||
FBO_Blit(tr.quarterFbo[0], NULL, blurTexScale, tr.quarterFbo[1], NULL, &tr.bokehShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
|
||||
FBO_Blit(tr.quarterFbo[1], NULL, NULL, tr.screenScratchFbo, NULL, &tr.textureColorShader, NULL, 0);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretch, float x, float y, float w, float h, float xcenter, float ycenter, float alpha)
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
const float inc = 1.f / passes;
|
||||
const float mul = powf(stretch, inc);
|
||||
float scale;
|
||||
|
||||
{
|
||||
vec2_t texScale;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
alpha *= inc;
|
||||
VectorSet4(color, alpha, alpha, alpha, 1.0f);
|
||||
|
||||
VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
|
||||
VectorSet4(dstBox, x, y, w, h);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0);
|
||||
|
||||
--passes;
|
||||
scale = mul;
|
||||
while (passes > 0)
|
||||
{
|
||||
float iscale = 1.f / scale;
|
||||
float s0 = xcenter * (1.f - iscale);
|
||||
float t0 = (1.0f - ycenter) * (1.f - iscale);
|
||||
float s1 = iscale + s0;
|
||||
float t1 = iscale + t0;
|
||||
|
||||
srcBox[0] = s0 * srcFbo->width;
|
||||
srcBox[1] = t0 * srcFbo->height;
|
||||
srcBox[2] = (s1 - s0) * srcFbo->width;
|
||||
srcBox[3] = (t1 - t0) * srcFbo->height;
|
||||
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
|
||||
scale *= mul;
|
||||
--passes;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static qboolean RB_UpdateSunFlareVis(void)
|
||||
{
|
||||
GLuint sampleCount = 0;
|
||||
if (!glRefConfig.occlusionQuery)
|
||||
return qtrue;
|
||||
|
||||
tr.sunFlareQueryIndex ^= 1;
|
||||
if (!tr.sunFlareQueryActive[tr.sunFlareQueryIndex])
|
||||
return qtrue;
|
||||
|
||||
/* debug code */
|
||||
if (0)
|
||||
{
|
||||
int iter;
|
||||
for (iter=0 ; ; ++iter)
|
||||
{
|
||||
GLint available = 0;
|
||||
qglGetQueryObjectivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_AVAILABLE_ARB, &available);
|
||||
if (available)
|
||||
break;
|
||||
}
|
||||
|
||||
ri.Printf(PRINT_DEVELOPER, "Waited %d iterations\n", iter);
|
||||
}
|
||||
|
||||
qglGetQueryObjectuivARB(tr.sunFlareQuery[tr.sunFlareQueryIndex], GL_QUERY_RESULT_ARB, &sampleCount);
|
||||
return sampleCount > 0;
|
||||
}
|
||||
|
||||
void RB_SunRays(void)
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
float dot;
|
||||
const float cutoff = 0.25f;
|
||||
qboolean colorize = qtrue;
|
||||
|
||||
// float w, h, w2, h2;
|
||||
matrix_t mvp;
|
||||
vec4_t pos, hpos;
|
||||
|
||||
dot = DotProduct(tr.sunDirection, backEnd.viewParms.or.axis[0]);
|
||||
if (dot < cutoff)
|
||||
return;
|
||||
|
||||
if (!RB_UpdateSunFlareVis())
|
||||
return;
|
||||
|
||||
// From RB_DrawSun()
|
||||
{
|
||||
float dist;
|
||||
matrix_t trans, model, mvp;
|
||||
|
||||
Matrix16Translation( backEnd.viewParms.or.origin, trans );
|
||||
Matrix16Multiply( backEnd.viewParms.world.modelMatrix, trans, model );
|
||||
Matrix16Multiply(backEnd.viewParms.projectionMatrix, model, mvp);
|
||||
|
||||
dist = backEnd.viewParms.zFar / 1.75; // div sqrt(3)
|
||||
|
||||
VectorScale( tr.sunDirection, dist, pos );
|
||||
}
|
||||
|
||||
// project sun point
|
||||
//Matrix16Multiply(backEnd.viewParms.projectionMatrix, backEnd.viewParms.world.modelMatrix, mvp);
|
||||
Matrix16Transform(mvp, pos, hpos);
|
||||
|
||||
// transform to UV coords
|
||||
hpos[3] = 0.5f / hpos[3];
|
||||
|
||||
pos[0] = 0.5f + hpos[0] * hpos[3];
|
||||
pos[1] = 0.5f - hpos[1] * hpos[3];
|
||||
|
||||
// viewport dimensions
|
||||
// JBravo: Apparently not used
|
||||
/* w = glConfig.vidWidth;
|
||||
h = glConfig.vidHeight;
|
||||
w2 = glConfig.vidWidth / 2;
|
||||
h2 = glConfig.vidHeight / 2; */
|
||||
|
||||
// initialize quarter buffers
|
||||
{
|
||||
float mul = 1.f;
|
||||
vec2_t texScale;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
VectorSet4(color, mul, mul, mul, 1);
|
||||
|
||||
// first, downsample the framebuffer
|
||||
if (colorize)
|
||||
{
|
||||
FBO_FastBlit(tr.screenScratchFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
FBO_Blit(tr.sunRaysFbo, NULL, NULL, tr.quarterFbo[0], NULL, NULL, color, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO);
|
||||
}
|
||||
else
|
||||
{
|
||||
FBO_FastBlit(tr.sunRaysFbo, NULL, tr.quarterFbo[0], NULL, GL_COLOR_BUFFER_BIT, GL_LINEAR);
|
||||
}
|
||||
}
|
||||
|
||||
// radial blur passes, ping-ponging between the two quarter-size buffers
|
||||
{
|
||||
const float stretch_add = 2.f/3.f;
|
||||
float stretch = 1.f + stretch_add;
|
||||
int i;
|
||||
for (i=0; i<2; ++i)
|
||||
{
|
||||
RB_RadialBlur(tr.quarterFbo[i&1], tr.quarterFbo[(~i) & 1], 5, stretch, 0.f, 0.f, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height, pos[0], pos[1], 1.125f);
|
||||
stretch += stretch_add;
|
||||
}
|
||||
}
|
||||
|
||||
// add result back on top of the main buffer
|
||||
{
|
||||
float mul = 1.f;
|
||||
vec2_t texScale;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
VectorSet4(color, mul, mul, mul, 1);
|
||||
|
||||
VectorSet4(srcBox, 0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height);
|
||||
VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
|
||||
FBO_Blit(tr.quarterFbo[0], srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE);
|
||||
}
|
||||
}
|
||||
|
||||
static void RB_BlurAxis(FBO_t *srcFbo, FBO_t *dstFbo, float strength, qboolean horizontal)
|
||||
{
|
||||
float dx, dy;
|
||||
float xmul, ymul;
|
||||
float weights[3] = {
|
||||
0.227027027f,
|
||||
0.316216216f,
|
||||
0.070270270f,
|
||||
};
|
||||
float offsets[3] = {
|
||||
0.f,
|
||||
1.3846153846f,
|
||||
3.2307692308f,
|
||||
};
|
||||
|
||||
xmul = horizontal;
|
||||
ymul = 1.f - xmul;
|
||||
|
||||
xmul *= strength;
|
||||
ymul *= strength;
|
||||
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
vec2_t texScale;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
VectorSet4(color, weights[0], weights[0], weights[0], 1.0f);
|
||||
VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height);
|
||||
VectorSet4(dstBox, 0, 0, dstFbo->width, dstFbo->height);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, 0 );
|
||||
|
||||
VectorSet4(color, weights[1], weights[1], weights[1], 1.0f);
|
||||
dx = offsets[1] * xmul;
|
||||
dy = offsets[1] * ymul;
|
||||
VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
|
||||
VectorSet4(color, weights[2], weights[2], weights[2], 1.0f);
|
||||
dx = offsets[2] * xmul;
|
||||
dy = offsets[2] * ymul;
|
||||
VectorSet4(srcBox, dx, dy, srcFbo->width, srcFbo->height);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
VectorSet4(srcBox, -dx, -dy, srcFbo->width, srcFbo->height);
|
||||
FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE );
|
||||
}
|
||||
}
|
||||
|
||||
static void RB_HBlur(FBO_t *srcFbo, FBO_t *dstFbo, float strength)
|
||||
{
|
||||
RB_BlurAxis(srcFbo, dstFbo, strength, qtrue);
|
||||
}
|
||||
|
||||
static void RB_VBlur(FBO_t *srcFbo, FBO_t *dstFbo, float strength)
|
||||
{
|
||||
RB_BlurAxis(srcFbo, dstFbo, strength, qfalse);
|
||||
}
|
||||
|
||||
void RB_GaussianBlur(float blur)
|
||||
{
|
||||
//float mul = 1.f;
|
||||
float factor = Com_Clamp(0.f, 1.f, blur);
|
||||
|
||||
if (factor <= 0.f)
|
||||
return;
|
||||
|
||||
{
|
||||
vec4i_t srcBox, dstBox;
|
||||
vec4_t color;
|
||||
vec2_t texScale;
|
||||
|
||||
texScale[0] =
|
||||
texScale[1] = 1.0f;
|
||||
|
||||
VectorSet4(color, 1, 1, 1, 1);
|
||||
|
||||
// first, downsample the framebuffer
|
||||
FBO_FastBlit(tr.screenScratchFbo, 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
|
||||
VectorSet4(srcBox, 0, 0, tr.whiteImage->width, tr.whiteImage->height);
|
||||
VectorSet4(dstBox, 0, 0, tr.textureScratchFbo[0]->width, tr.textureScratchFbo[0]->height);
|
||||
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_TRUE);
|
||||
FBO_BlitFromTexture(tr.whiteImage, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.textureColorShader, color, GLS_DEPTHTEST_DISABLE);
|
||||
qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE);
|
||||
|
||||
// blur the tiny buffer horizontally and vertically
|
||||
RB_HBlur(tr.textureScratchFbo[0], tr.textureScratchFbo[1], factor);
|
||||
RB_VBlur(tr.textureScratchFbo[1], tr.textureScratchFbo[0], factor);
|
||||
|
||||
// finally, merge back to framebuffer
|
||||
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, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA);
|
||||
}
|
||||
}
|
Loading…
Add table
Add a link
Reference in a new issue