Added MSAA. Set r_ext_framebuffer_multisample to desired strength.

Fixed buggy stretched shadows in cg_shadows 4.
Improved LDR to HDR lightmap promotion in dark areas.
This commit is contained in:
James Canete 2012-02-23 10:54:10 +00:00
parent 053a51c3db
commit e244db27e5
11 changed files with 4805 additions and 4667 deletions

View file

@ -281,6 +281,30 @@ extern void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint
#define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867 #define GL_QUERY_RESULT_AVAILABLE_ARB 0x8867
#endif #endif
// GL_EXT_framebuffer_blit
void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
#ifndef GL_EXT_framebuffer_blit
#define GL_EXT_framebuffer_blit
#define GL_READ_FRAMEBUFFER_EXT 0x8CA8
#define GL_DRAW_FRAMEBUFFER_EXT 0x8CA9
#define GL_DRAW_FRAMEBUFFER_BINDING_EXT 0x8CA6
#define GL_READ_FRAMEBUFFER_BINDING_EXT 0x8CAA
#endif
// GL_EXT_framebuffer_multisample
void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
#ifndef GL_EXT_framebuffer_multisample
#define GL_EXT_framebuffer_multisample
#define GL_RENDERBUFFER_SAMPLES_EXT 0x8CAB
#define GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT 0x8D56
#define GL_MAX_SAMPLES_EXT 0x8D57
#endif
#if defined(WIN32) #if defined(WIN32)
// WGL_ARB_create_context // WGL_ARB_create_context
#ifndef WGL_ARB_create_context #ifndef WGL_ARB_create_context

View file

@ -538,6 +538,7 @@ void RB_BeginDrawingView (void) {
// clip to the plane of the portal // clip to the plane of the portal
if ( backEnd.viewParms.isPortal ) { if ( backEnd.viewParms.isPortal ) {
#if 0
float plane[4]; float plane[4];
double plane2[4]; double plane2[4];
@ -550,7 +551,7 @@ void RB_BeginDrawingView (void) {
plane2[1] = DotProduct (backEnd.viewParms.or.axis[1], plane); plane2[1] = DotProduct (backEnd.viewParms.or.axis[1], plane);
plane2[2] = DotProduct (backEnd.viewParms.or.axis[2], plane); plane2[2] = DotProduct (backEnd.viewParms.or.axis[2], plane);
plane2[3] = DotProduct (plane, backEnd.viewParms.or.origin) - plane[3]; plane2[3] = DotProduct (plane, backEnd.viewParms.or.origin) - plane[3];
#endif
GL_SetModelviewMatrix( s_flipMatrix ); GL_SetModelviewMatrix( s_flipMatrix );
} }
} }
@ -950,8 +951,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
tess.xyz[tess.numVertexes][3] = 1; tess.xyz[tess.numVertexes][3] = 1;
tess.texCoords[tess.numVertexes][0][0] = 0.5f / cols; tess.texCoords[tess.numVertexes][0][0] = 0.5f / cols;
tess.texCoords[tess.numVertexes][0][1] = 0.5f / rows; tess.texCoords[tess.numVertexes][0][1] = 0.5f / rows;
tess.texCoords[tess.numVertexes][0][2] = 0; tess.texCoords[tess.numVertexes][1][0] = 0;
tess.texCoords[tess.numVertexes][0][3] = 1; tess.texCoords[tess.numVertexes][1][1] = 1;
tess.numVertexes++; tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = x + w; tess.xyz[tess.numVertexes][0] = x + w;
@ -960,8 +961,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
tess.xyz[tess.numVertexes][3] = 1; tess.xyz[tess.numVertexes][3] = 1;
tess.texCoords[tess.numVertexes][0][0] = (cols - 0.5f) / cols; tess.texCoords[tess.numVertexes][0][0] = (cols - 0.5f) / cols;
tess.texCoords[tess.numVertexes][0][1] = 0.5f / rows; tess.texCoords[tess.numVertexes][0][1] = 0.5f / rows;
tess.texCoords[tess.numVertexes][0][2] = 0; tess.texCoords[tess.numVertexes][1][0] = 0;
tess.texCoords[tess.numVertexes][0][3] = 1; tess.texCoords[tess.numVertexes][1][1] = 1;
tess.numVertexes++; tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = x + w; tess.xyz[tess.numVertexes][0] = x + w;
@ -970,8 +971,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
tess.xyz[tess.numVertexes][3] = 1; tess.xyz[tess.numVertexes][3] = 1;
tess.texCoords[tess.numVertexes][0][0] = (cols - 0.5f) / cols; tess.texCoords[tess.numVertexes][0][0] = (cols - 0.5f) / cols;
tess.texCoords[tess.numVertexes][0][1] = (rows - 0.5f) / rows; tess.texCoords[tess.numVertexes][0][1] = (rows - 0.5f) / rows;
tess.texCoords[tess.numVertexes][0][2] = 0; tess.texCoords[tess.numVertexes][1][0] = 0;
tess.texCoords[tess.numVertexes][0][3] = 1; tess.texCoords[tess.numVertexes][1][1] = 1;
tess.numVertexes++; tess.numVertexes++;
tess.xyz[tess.numVertexes][0] = x; tess.xyz[tess.numVertexes][0] = x;
@ -980,8 +981,8 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
tess.xyz[tess.numVertexes][3] = 1; tess.xyz[tess.numVertexes][3] = 1;
tess.texCoords[tess.numVertexes][0][0] = 0.5f / cols; tess.texCoords[tess.numVertexes][0][0] = 0.5f / cols;
tess.texCoords[tess.numVertexes][0][1] = (rows - 0.5f) / rows; tess.texCoords[tess.numVertexes][0][1] = (rows - 0.5f) / rows;
tess.texCoords[tess.numVertexes][0][2] = 0; tess.texCoords[tess.numVertexes][1][0] = 0;
tess.texCoords[tess.numVertexes][0][3] = 1; tess.texCoords[tess.numVertexes][1][1] = 1;
tess.numVertexes++; tess.numVertexes++;
tess.indexes[tess.numIndexes++] = 0; tess.indexes[tess.numIndexes++] = 0;
@ -1356,10 +1357,21 @@ const void *RB_SwapBuffers( const void *data ) {
} }
else else
{ {
// frame still in render fbo, copy from there // frame still in render fbo, possibly resolve then copy from there
VectorSet4(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); FBO_t *hdrFbo;
FBO_Blit(tr.renderFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0); if (tr.msaaResolveFbo)
{
// Resolve the MSAA before anything else
FBO_ResolveMSAA(tr.renderFbo, tr.msaaResolveFbo);
hdrFbo = tr.msaaResolveFbo;
}
else
hdrFbo = tr.renderFbo;
VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height);
FBO_Blit(hdrFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0);
} }
} }
@ -1416,14 +1428,21 @@ RB_PostProcess
const void *RB_PostProcess(const void *data) const void *RB_PostProcess(const void *data)
{ {
const postProcessCommand_t *cmd = data; const postProcessCommand_t *cmd = data;
vec4_t white; FBO_t *hdrFbo;
vec2_t texScale; vec2_t texScale;
qboolean autoExposure; qboolean autoExposure;
texScale[0] = texScale[0] =
texScale[1] = 1.0f; texScale[1] = 1.0f;
VectorSet4(white, 1, 1, 1, 1); if (tr.msaaResolveFbo)
{
// Resolve the MSAA before anything else
FBO_ResolveMSAA(tr.renderFbo, tr.msaaResolveFbo);
hdrFbo = tr.msaaResolveFbo;
}
else
hdrFbo = tr.renderFbo;
if (!r_postProcess->integer) if (!r_postProcess->integer)
{ {
@ -1432,7 +1451,7 @@ const void *RB_PostProcess(const void *data)
{ {
vec4_t srcBox, dstBox, color; vec4_t srcBox, dstBox, color;
VectorSet4(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height);
//VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); //VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height);
@ -1441,8 +1460,8 @@ const void *RB_PostProcess(const void *data)
color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value);
color[3] = 1.0f; color[3] = 1.0f;
//FBO_Blit(tr.renderFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, 0); //FBO_Blit(hdrFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, color, 0);
FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0);
} }
backEnd.framePostProcessed = qtrue; backEnd.framePostProcessed = qtrue;
@ -1462,13 +1481,13 @@ const void *RB_PostProcess(const void *data)
if (r_hdr->integer && (r_toneMap->integer == 2 || (r_toneMap->integer == 1 && tr.autoExposure))) 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); autoExposure = (r_autoExposure->integer == 1 && tr.autoExposure) || (r_autoExposure->integer == 2);
RB_ToneMap(autoExposure); RB_ToneMap(hdrFbo, autoExposure);
} }
else else
{ {
vec4_t srcBox, dstBox, color; vec4_t srcBox, dstBox, color;
VectorSet4(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height);
VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height);
color[0] = color[0] =
@ -1476,7 +1495,7 @@ const void *RB_PostProcess(const void *data)
color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value); color[2] = pow(2, r_cameraExposure->value); //exp2(r_cameraExposure->value);
color[3] = 1.0f; color[3] = 1.0f;
FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0);
} }
#ifdef REACTION #ifdef REACTION
@ -1487,18 +1506,7 @@ const void *RB_PostProcess(const void *data)
else else
RB_GaussianBlur(backEnd.refdef.blurFactor); RB_GaussianBlur(backEnd.refdef.blurFactor);
#endif #endif
/*
if (glRefConfig.framebufferObject)
{
// copy final image to screen
vec4_t srcBox, dstBox;
VectorSet4(srcBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height);
VectorSet4(dstBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight);
FBO_Blit(tr.screenScratchFbo, srcBox, texScale, NULL, dstBox, &tr.textureColorShader, white, 0);
}
*/
backEnd.framePostProcessed = qtrue; backEnd.framePostProcessed = qtrue;
return (const void *)(cmd + 1); return (const void *)(cmd + 1);

View file

@ -405,6 +405,16 @@ static void R_LoadLightmaps( lump_t *l, lump_t *surfs ) {
color[0] = (buf_p[j*3+0] + 1.0f); color[0] = (buf_p[j*3+0] + 1.0f);
color[1] = (buf_p[j*3+1] + 1.0f); color[1] = (buf_p[j*3+1] + 1.0f);
color[2] = (buf_p[j*3+2] + 1.0f); color[2] = (buf_p[j*3+2] + 1.0f);
// if under an arbitrary value (say 12) grey it out
// this prevents weird splotches in dimly lit areas
if (color[0] + color[1] + color[2] < 12)
{
float avg = (color[0] + color[1] + color[2]) * 0.3333f;
color[0] = avg;
color[1] = avg;
color[2] = avg;
}
} }
VectorScale(color, lightScale, color); VectorScale(color, lightScale, color);
@ -683,7 +693,8 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low); cv->verts = ri.Hunk_Alloc(numVerts * sizeof(cv->verts[0]), h_low);
// copy vertexes // copy vertexes
ClearBounds(cv->bounds[0], cv->bounds[1]); surf->cullinfo.type = CULLINFO_PLANE | CULLINFO_BOX;
ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
verts += LittleLong(ds->firstVert); verts += LittleLong(ds->firstVert);
for(i = 0; i < numVerts; i++) for(i = 0; i < numVerts; i++)
{ {
@ -694,7 +705,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]); cv->verts[i].xyz[j] = LittleFloat(verts[i].xyz[j]);
cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]); cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
} }
AddPointToBounds(cv->verts[i].xyz, cv->bounds[0], cv->bounds[1]); AddPointToBounds(cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
for(j = 0; j < 2; j++) for(j = 0; j < 2; j++)
{ {
cv->verts[i].st[j] = LittleFloat(verts[i].st[j]); cv->verts[i].st[j] = LittleFloat(verts[i].st[j]);
@ -753,6 +764,7 @@ static void ParseFace( dsurface_t *ds, drawVert_t *verts, float *hdrVertColors,
cv->plane.dist = DotProduct( cv->verts[0].xyz, cv->plane.normal ); cv->plane.dist = DotProduct( cv->verts[0].xyz, cv->plane.normal );
SetPlaneSignbits( &cv->plane ); SetPlaneSignbits( &cv->plane );
cv->plane.type = PlaneTypeForNormal( cv->plane.normal ); cv->plane.type = PlaneTypeForNormal( cv->plane.normal );
surf->cullinfo.plane = cv->plane;
surf->data = (surfaceType_t *)cv; surf->data = (surfaceType_t *)cv;
@ -911,7 +923,8 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
surf->data = (surfaceType_t *) cv; surf->data = (surfaceType_t *) cv;
// copy vertexes // copy vertexes
ClearBounds(cv->bounds[0], cv->bounds[1]); surf->cullinfo.type = CULLINFO_BOX;
ClearBounds(surf->cullinfo.bounds[0], surf->cullinfo.bounds[1]);
verts += LittleLong(ds->firstVert); verts += LittleLong(ds->firstVert);
for(i = 0; i < numVerts; i++) for(i = 0; i < numVerts; i++)
{ {
@ -923,7 +936,7 @@ static void ParseTriSurf( dsurface_t *ds, drawVert_t *verts, float *hdrVertColor
cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]); cv->verts[i].normal[j] = LittleFloat(verts[i].normal[j]);
} }
AddPointToBounds( cv->verts[i].xyz, cv->bounds[0], cv->bounds[1] ); AddPointToBounds( cv->verts[i].xyz, surf->cullinfo.bounds[0], surf->cullinfo.bounds[1] );
for(j = 0; j < 2; j++) for(j = 0; j < 2; j++)
{ {
@ -2175,25 +2188,10 @@ static void R_LoadSurfaces( lump_t *surfs, lump_t *verts, lump_t *indexLump ) {
break; break;
case MST_TRIANGLE_SOUP: case MST_TRIANGLE_SOUP:
ParseTriSurf( in, dv, hdrVertColors, out, indexes ); ParseTriSurf( in, dv, hdrVertColors, out, indexes );
{
srfTriangles_t *surface = (srfTriangles_t *)out->data;
out->cullinfo.type = CULLINFO_BOX;
VectorCopy(surface->bounds[0], out->cullinfo.bounds[0]);
VectorCopy(surface->bounds[1], out->cullinfo.bounds[1]);
}
numTriSurfs++; numTriSurfs++;
break; break;
case MST_PLANAR: case MST_PLANAR:
ParseFace( in, dv, hdrVertColors, out, indexes ); ParseFace( in, dv, hdrVertColors, out, indexes );
{
srfSurfaceFace_t *surface = (srfSurfaceFace_t *)out->data;
out->cullinfo.type = CULLINFO_PLANE | CULLINFO_BOX;
VectorCopy(surface->bounds[0], out->cullinfo.bounds[0]);
VectorCopy(surface->bounds[1], out->cullinfo.bounds[1]);
out->cullinfo.plane = surface->plane;
}
numFaces++; numFaces++;
break; break;
case MST_FLARE: case MST_FLARE:

View file

@ -164,6 +164,14 @@ void (APIENTRY * qglGetQueryivARB)(GLenum target, GLenum pname, GLint *params);
void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params); void (APIENTRY * qglGetQueryObjectivARB)(GLuint id, GLenum pname, GLint *params);
void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params); void (APIENTRY * qglGetQueryObjectuivARB)(GLuint id, GLenum pname, GLuint *params);
// GL_EXT_framebuffer_blit
void (APIENTRY * qglBlitFramebufferEXT)(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1,
GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1,
GLbitfield mask, GLenum filter);
// GL_EXT_framebuffer_multisample
void (APIENTRY * qglRenderbufferStorageMultisampleEXT)(GLenum target, GLsizei samples,
GLenum internalformat, GLsizei width, GLsizei height);
static qboolean GLimp_HaveExtension(const char *ext) static qboolean GLimp_HaveExtension(const char *ext)
{ {
@ -519,4 +527,33 @@ void GLimp_InitExtraExtensions()
{ {
ri.Printf(PRINT_ALL, "...%s not found\n", extension); ri.Printf(PRINT_ALL, "...%s not found\n", extension);
} }
// GL_EXT_framebuffer_blit
extension = "GL_EXT_framebuffer_blit";
glRefConfig.framebufferBlit = qfalse;
if (GLimp_HaveExtension(extension))
{
qglBlitFramebufferEXT = (void *)SDL_GL_GetProcAddress("glBlitFramebufferEXT");
glRefConfig.framebufferBlit = qtrue;
ri.Printf(PRINT_ALL, "...%s %s\n", action[glRefConfig.framebufferBlit], extension);
}
else
{
ri.Printf(PRINT_ALL, "...%s not found\n", extension);
}
// GL_EXT_framebuffer_multisample
extension = "GL_EXT_framebuffer_multisample";
glRefConfig.framebufferMultisample = qfalse;
if (GLimp_HaveExtension(extension))
{
qglRenderbufferStorageMultisampleEXT = (void *)SDL_GL_GetProcAddress("glRenderbufferStorageMultisampleEXT");
glRefConfig.framebufferMultisample = qtrue;
ri.Printf(PRINT_ALL, "...%s %s\n", action[glRefConfig.framebufferMultisample], extension);
}
else
{
ri.Printf(PRINT_ALL, "...%s not found\n", extension);
}
} }

View file

@ -136,7 +136,7 @@ FBO_t *FBO_Create(const char *name, int width, int height)
return fbo; return fbo;
} }
void FBO_CreateBuffer(FBO_t *fbo, int format, int index) void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample)
{ {
uint32_t *pRenderBuffer; uint32_t *pRenderBuffer;
GLenum attachment; GLenum attachment;
@ -193,7 +193,14 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index)
qglGenRenderbuffersEXT(1, pRenderBuffer); qglGenRenderbuffersEXT(1, pRenderBuffer);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer); qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer);
if (multisample && glRefConfig.framebufferMultisample)
{
qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, format, fbo->width, fbo->height);
}
else
{
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height); qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height);
}
if(absent) if(absent)
{ {
@ -350,7 +357,7 @@ FBO_Init
void FBO_Init(void) void FBO_Init(void)
{ {
int i; int i;
int width, height, hdrFormat; int width, height, hdrFormat, multisample;
ri.Printf(PRINT_ALL, "------- FBO_Init -------\n"); ri.Printf(PRINT_ALL, "------- FBO_Init -------\n");
@ -381,15 +388,52 @@ void FBO_Init(void)
hdrFormat = GL_RGBA16F_ARB; hdrFormat = GL_RGBA16F_ARB;
} }
qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample);
if (r_ext_framebuffer_multisample->integer < multisample)
{
multisample = r_ext_framebuffer_multisample->integer;
}
if (multisample < 2)
multisample = 0;
if (multisample != r_ext_framebuffer_multisample->integer)
{
ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample);
}
if (multisample && glRefConfig.framebufferMultisample)
{ {
//tr.renderFbo = FBO_Create("_render", width, height);
tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height); tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_Bind(tr.renderFbo); FBO_Bind(tr.renderFbo);
FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0); FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, multisample);
FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
R_CheckFBO(tr.renderFbo);
tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_Bind(tr.msaaResolveFbo);
FBO_CreateBuffer(tr.msaaResolveFbo, hdrFormat, 0, 0);
FBO_AttachTextureImage(tr.renderImage, 0); FBO_AttachTextureImage(tr.renderImage, 0);
FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0); FBO_CreateBuffer(tr.msaaResolveFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
R_CheckFBO(tr.msaaResolveFbo);
}
else
{
tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_Bind(tr.renderFbo);
FBO_CreateBuffer(tr.renderFbo, hdrFormat, 0, 0);
FBO_AttachTextureImage(tr.renderImage, 0);
FBO_CreateBuffer(tr.renderFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
R_CheckFBO(tr.renderFbo); R_CheckFBO(tr.renderFbo);
@ -400,10 +444,10 @@ void FBO_Init(void)
tr.godRaysFbo = FBO_Create("_godRays", tr.renderDepthImage->width, tr.renderDepthImage->height); tr.godRaysFbo = FBO_Create("_godRays", tr.renderDepthImage->width, tr.renderDepthImage->height);
FBO_Bind(tr.godRaysFbo); FBO_Bind(tr.godRaysFbo);
FBO_CreateBuffer(tr.godRaysFbo, GL_RGBA8, 0); FBO_CreateBuffer(tr.godRaysFbo, GL_RGBA8, 0, multisample);
FBO_AttachTextureImage(tr.godRaysImage, 0); FBO_AttachTextureImage(tr.godRaysImage, 0);
FBO_CreateBuffer(tr.godRaysFbo, GL_DEPTH_COMPONENT24_ARB, 0); FBO_CreateBuffer(tr.godRaysFbo, GL_DEPTH_COMPONENT24_ARB, 0, multisample);
R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
R_CheckFBO(tr.godRaysFbo); R_CheckFBO(tr.godRaysFbo);
@ -416,10 +460,10 @@ void FBO_Init(void)
tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height); tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height);
FBO_Bind(tr.pshadowFbos[i]); FBO_Bind(tr.pshadowFbos[i]);
FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0); FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0);
FBO_AttachTextureImage(tr.pshadowMaps[i], 0); FBO_AttachTextureImage(tr.pshadowMaps[i], 0);
FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0); FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0);
R_AttachFBOTextureDepth(tr.textureDepthImage->texnum); R_AttachFBOTextureDepth(tr.textureDepthImage->texnum);
R_CheckFBO(tr.pshadowFbos[i]); R_CheckFBO(tr.pshadowFbos[i]);
@ -430,7 +474,7 @@ void FBO_Init(void)
tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height);
FBO_Bind(tr.textureScratchFbo[i]); FBO_Bind(tr.textureScratchFbo[i]);
FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0); FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0, 0);
FBO_AttachTextureImage(tr.textureScratchImage[i], 0); FBO_AttachTextureImage(tr.textureScratchImage[i], 0);
R_CheckFBO(tr.textureScratchFbo[i]); R_CheckFBO(tr.textureScratchFbo[i]);
@ -440,7 +484,7 @@ void FBO_Init(void)
tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height); tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height);
FBO_Bind(tr.calcLevelsFbo); FBO_Bind(tr.calcLevelsFbo);
FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0); FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0, 0);
FBO_AttachTextureImage(tr.calcLevelsImage, 0); FBO_AttachTextureImage(tr.calcLevelsImage, 0);
R_CheckFBO(tr.calcLevelsFbo); R_CheckFBO(tr.calcLevelsFbo);
@ -451,11 +495,11 @@ void FBO_Init(void)
tr.screenScratchFbo = FBO_Create("_screenscratch", tr.screenScratchImage->width, tr.screenScratchImage->height); tr.screenScratchFbo = FBO_Create("_screenscratch", tr.screenScratchImage->width, tr.screenScratchImage->height);
FBO_Bind(tr.screenScratchFbo); FBO_Bind(tr.screenScratchFbo);
FBO_CreateBuffer(tr.screenScratchFbo, GL_RGBA8, 0); FBO_CreateBuffer(tr.screenScratchFbo, GL_RGBA8, 0, 0);
FBO_AttachTextureImage(tr.screenScratchImage, 0); FBO_AttachTextureImage(tr.screenScratchImage, 0);
// FIXME: hack: share zbuffer between render fbo and pre-screen fbo // FIXME: hack: share zbuffer between render fbo and pre-screen fbo
FBO_CreateBuffer(tr.screenScratchFbo, GL_DEPTH_COMPONENT24_ARB, 0); FBO_CreateBuffer(tr.screenScratchFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0);
R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); R_AttachFBOTextureDepth(tr.renderDepthImage->texnum);
R_CheckFBO(tr.screenScratchFbo); R_CheckFBO(tr.screenScratchFbo);
@ -466,7 +510,7 @@ void FBO_Init(void)
tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height);
FBO_Bind(tr.quarterFbo[i]); FBO_Bind(tr.quarterFbo[i]);
FBO_CreateBuffer(tr.quarterFbo[i], GL_RGBA8, 0); FBO_CreateBuffer(tr.quarterFbo[i], GL_RGBA8, 0, 0);
FBO_AttachTextureImage(tr.quarterImage[i], 0); FBO_AttachTextureImage(tr.quarterImage[i], 0);
R_CheckFBO(tr.quarterFbo[i]); R_CheckFBO(tr.quarterFbo[i]);
@ -586,3 +630,17 @@ void FBO_Blit(FBO_t *src, vec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4_t
FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend); FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend);
} }
} }
void FBO_ResolveMSAA(FBO_t *src, FBO_t *dst)
{
// get to a neutral state first
FBO_Bind(NULL);
qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, src->frameBuffer);
qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dst->frameBuffer);
qglBlitFramebufferEXT(0, 0, src->width, src->height, 0, 0, dst->width, dst->height, GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, GL_NEAREST);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0);
glState.currentFBO = NULL;
}

View file

@ -58,6 +58,7 @@ void FBO_Shutdown(void);
void FBO_BlitFromTexture(struct image_s *src, vec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend); void FBO_BlitFromTexture(struct image_s *src, vec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
void FBO_Blit(FBO_t *src, vec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend); void FBO_Blit(FBO_t *src, vec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, vec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend);
void FBO_ResolveMSAA(FBO_t *src, FBO_t *dst);
#endif #endif

View file

@ -174,12 +174,12 @@ static const char *fallbackFogPassShader_vp =
"n, u_FogDistance);\r\n\tfloat t = dot(position, u_FogDepth);\r\n\r\n\tif (t" "n, u_FogDistance);\r\n\tfloat t = dot(position, u_FogDepth);\r\n\r\n\tif (t"
" >= 1.0)\r\n\t{\r\n\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t}\r\n\telse" " >= 1.0)\r\n\t{\r\n\t\ts *= t / (t - min(u_FogEyeT, 0.0));\r\n\t}\r\n\telse"
"\r\n\t{\r\n\t\ts *= max(t + sign(u_FogEyeT), 0.0);\r\n\t}\r\n\r\n\tvar_Scal" "\r\n\t{\r\n\t\ts *= max(t + sign(u_FogEyeT), 0.0);\r\n\t}\r\n\r\n\tvar_Scal"
"e = clamp(s * 8.0, 0.0, 1.0);\r\n}\r\n"; "e = s * 8.0;\r\n}\r\n";
static const char *fallbackFogPassShader_fp = static const char *fallbackFogPassShader_fp =
"uniform vec4 u_Color;\r\n\r\nvarying float var_Scale;\r\n\r\nvoid main()\r" "uniform vec4 u_Color;\r\n\r\nvarying float var_Scale;\r\n\r\nvoid main()\r"
"\n{\r\n\tgl_FragColor = u_Color;\r\n\tgl_FragColor.a *= sqrt(var_Scale);\r" "\n{\r\n\tgl_FragColor = u_Color;\r\n\tgl_FragColor.a *= sqrt(clamp(var_Scal"
"\n}\r\n"; "e, 0.0, 1.0));\r\n}\r\n";
static const char *fallbackDlightShader_vp = static const char *fallbackDlightShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattribut" "attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\nattribut"
@ -470,34 +470,37 @@ static const char *fallbackPshadowShader_fp =
"3 var_Position;\r\nvarying vec3 var_Normal;\r\n\r\nfloat sampleDi" "3 var_Position;\r\nvarying vec3 var_Normal;\r\n\r\nfloat sampleDi"
"stMap(sampler2D texMap, vec2 uv, float scale)\r\n{\r\n\tvec3 distv = textur" "stMap(sampler2D texMap, vec2 uv, float scale)\r\n{\r\n\tvec3 distv = textur"
"e2D(texMap, uv).xyz;\r\n\treturn dot(distv, vec3(1.0 / (256.0 * 256.0), 1.0" "e2D(texMap, uv).xyz;\r\n\treturn dot(distv, vec3(1.0 / (256.0 * 256.0), 1.0"
" / 256.0, 1.0)) * scale;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec2 st;\r\n\t\r" " / 256.0, 1.0)) * scale;\r\n}\r\n\r\nvoid main()\r\n{\r\n\tvec3 lightToPos "
"\n\tvec3 lightToPos = var_Position - u_LightOrigin.xyz;\r\n\t\r\n\tst.s = -" "= var_Position - u_LightOrigin.xyz;\r\n\tvec2 st = vec2(-dot(u_LightRight, "
"dot(u_LightRight, lightToPos);\r\n\tst.t = dot(u_LightUp, lightToPos);\r\n" "lightToPos), dot(u_LightUp, lightToPos));\r\n\t\r\n\tfloat fade = length(st"
"\t\r\n\tst = st * 0.5 + vec2(0.5);\r\n\r\n#if defined(USE_SOLID_PSHADOWS)\r" ");\r\n\t\r\n#if defined(USE_DISCARD)\r\n\tif (fade >= 1.0)\r\n\t{\r\n\t\tdi"
"\n\tfloat intensity = max(sign(u_LightRadius - length(lightToPos)), 0.0);\r" "scard;\r\n\t}\r\n#endif\r\n\r\n\tfade = clamp(8.0 - fade * 8.0, 0.0, 1.0);"
"\n#else\r\n\tfloat intensity = clamp((1.0 - dot(lightToPos, lightToPos) / (" "\r\n\t\r\n\tst = st * 0.5 + vec2(0.5);\r\n\r\n#if defined(USE_SOLID_PSHADOW"
"u_LightRadius * u_LightRadius)) * 2.0, 0.0, 1.0);\r\n#endif\r\n\t\r\n\tfloa" "S)\r\n\tfloat intensity = max(sign(u_LightRadius - length(lightToPos)), 0.0"
"t lightDist = length(lightToPos);\r\n\tfloat dist;\r\n\r\n#if defined(USE_D" ");\r\n#else\r\n\tfloat intensity = clamp((1.0 - dot(lightToPos, lightToPos)"
"ISCARD)\r\n\tif (dot(u_LightForward, lightToPos) <= 0.0)\r\n\t{\r\n\t\tdisc" " / (u_LightRadius * u_LightRadius)) * 2.0, 0.0, 1.0);\r\n#endif\r\n\t\r\n\t"
"ard;\r\n\t}\r\n\r\n\tif (dot(var_Normal, lightToPos) > 0.0)\r\n\t{\r\n\t\td" "float lightDist = length(lightToPos);\r\n\tfloat dist;\r\n\r\n#if defined(U"
"iscard;\r\n\t}\r\n#else\r\n\tintensity *= max(sign(dot(u_LightForward, ligh" "SE_DISCARD)\r\n\tif (dot(u_LightForward, lightToPos) <= 0.0)\r\n\t{\r\n\t\t"
"tToPos)), 0.0);\r\n\tintensity *= max(sign(-dot(var_Normal, lightToPos)), 0" "discard;\r\n\t}\r\n\r\n\tif (dot(var_Normal, lightToPos) > 0.0)\r\n\t{\r\n"
".0);\r\n#endif\r\n\t\r\n#if defined(USE_PCF)\r\n\tfloat part;\r\n\t\r\n\tdi" "\t\tdiscard;\r\n\t}\r\n#else\r\n\tintensity *= max(sign(dot(u_LightForward,"
"st = sampleDistMap(u_ShadowMap, st + vec2(-1.0/256.0, -1.0/256.0), u_LightR" " lightToPos)), 0.0);\r\n\tintensity *= max(sign(-dot(var_Normal, lightToPos"
"adius);\r\n\tpart = max(sign(lightDist - dist), 0.0);\r\n\r\n\tdist = samp" ")), 0.0);\r\n#endif\r\n\r\n\tintensity *= fade;\r\n\t\r\n#if defined(USE_PC"
"leDistMap(u_ShadowMap, st + vec2( 1.0/256.0, -1.0/256.0), u_LightRadius);\r" "F)\r\n\tfloat part;\r\n\t\r\n\tdist = sampleDistMap(u_ShadowMap, st + vec2("
"\n\tpart += max(sign(lightDist - dist), 0.0);\r\n\r\n\tdist = sampleDistMap" "-1.0/256.0, -1.0/256.0), u_LightRadius);\r\n\tpart = max(sign(lightDist - "
"(u_ShadowMap, st + vec2(-1.0/256.0, 1.0/256.0), u_LightRadius);\r\n\tpart " "dist), 0.0);\r\n\r\n\tdist = sampleDistMap(u_ShadowMap, st + vec2( 1.0/256."
"+= max(sign(lightDist - dist), 0.0);\r\n\r\n\tdist = sampleDistMap(u_Shadow" "0, -1.0/256.0), u_LightRadius);\r\n\tpart += max(sign(lightDist - dist), 0."
"Map, st + vec2( 1.0/256.0, 1.0/256.0), u_LightRadius);\r\n\tpart += max(si" "0);\r\n\r\n\tdist = sampleDistMap(u_ShadowMap, st + vec2(-1.0/256.0, 1.0/2"
"gn(lightDist - dist), 0.0);\r\n\r\n #if defined(USE_DISCARD)\r\n\tif (part " "56.0), u_LightRadius);\r\n\tpart += max(sign(lightDist - dist), 0.0);\r\n\r"
"<= 0.0)\r\n\t{\r\n\t\tdiscard;\r\n\t}\r\n #endif\r\n\r\n\tintensity *= part" "\n\tdist = sampleDistMap(u_ShadowMap, st + vec2( 1.0/256.0, 1.0/256.0), u_"
" * 0.25;\r\n#else\r\n\tdist = sampleDistMap(u_ShadowMap, st, u_LightRadius)" "LightRadius);\r\n\tpart += max(sign(lightDist - dist), 0.0);\r\n\r\n #if de"
";\r\n\r\n #if defined(USE_DISCARD)\r\n\tif (lightDist - dist <= 0.0)\r\n\t{" "fined(USE_DISCARD)\r\n\tif (part <= 0.0)\r\n\t{\r\n\t\tdiscard;\r\n\t}\r\n "
"\r\n\t\tdiscard;\r\n\t}\r\n #endif\r\n\t\t\t\r\n\t//intensity *= max(sign(2" "#endif\r\n\r\n\tintensity *= part * 0.25;\r\n#else\r\n\tdist = sampleDistMa"
"54.0 / 255.0 - dist / u_LightRadius), 0.0);\r\n\tintensity *= max(sign(ligh" "p(u_ShadowMap, st, u_LightRadius);\r\n\r\n #if defined(USE_DISCARD)\r\n\tif"
"tDist - dist), 0.0);\r\n#endif\r\n\t\t\r\n\tgl_FragColor.rgb = vec3(0);\r\n" " (lightDist - dist <= 0.0)\r\n\t{\r\n\t\tdiscard;\r\n\t}\r\n #endif\r\n\t\t"
"\tgl_FragColor.a = clamp(intensity, 0.0, 0.75);\r\n}\r\n"; "\t\r\n\t//intensity *= max(sign(254.0 / 255.0 - dist / u_LightRadius), 0.0)"
";\r\n\tintensity *= max(sign(lightDist - dist), 0.0);\r\n#endif\r\n\t\t\r\n"
"\tgl_FragColor.rgb = vec3(0);\r\n\tgl_FragColor.a = clamp(intensity, 0.0, 0"
".75);\r\n}\r\n";
static const char *fallbackDown4xShader_vp = static const char *fallbackDown4xShader_vp =
"attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\n\r\nunif" "attribute vec4 attr_Position;\r\nattribute vec4 attr_TexCoord0;\r\n\r\nunif"

View file

@ -96,6 +96,7 @@ cvar_t *r_ext_multi_draw_arrays;
cvar_t *r_ext_framebuffer_object; cvar_t *r_ext_framebuffer_object;
cvar_t *r_ext_texture_float; cvar_t *r_ext_texture_float;
cvar_t *r_arb_half_float_pixel; cvar_t *r_arb_half_float_pixel;
cvar_t *r_ext_framebuffer_multisample;
cvar_t *r_mergeMultidraws; cvar_t *r_mergeMultidraws;
cvar_t *r_mergeLeafSurfaces; cvar_t *r_mergeLeafSurfaces;
@ -1079,6 +1080,7 @@ void R_Register( void )
r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_framebuffer_object = ri.Cvar_Get( "r_ext_framebuffer_object", "1", CVAR_ARCHIVE | CVAR_LATCH);
r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_float = ri.Cvar_Get( "r_ext_texture_float", "1", CVAR_ARCHIVE | CVAR_LATCH);
r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_half_float_pixel = ri.Cvar_Get( "r_arb_half_float_pixel", "1", CVAR_ARCHIVE | CVAR_LATCH);
r_ext_framebuffer_multisample = ri.Cvar_Get( "r_ext_framebuffer_multisample", "0", CVAR_ARCHIVE | CVAR_LATCH);
r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic",
"0", CVAR_ARCHIVE | CVAR_LATCH ); "0", CVAR_ARCHIVE | CVAR_LATCH );

View file

@ -1100,7 +1100,7 @@ typedef struct
// culling information // culling information
cplane_t plane; cplane_t plane;
vec3_t bounds[2]; // vec3_t bounds[2];
// triangle definitions // triangle definitions
int numTriangles; int numTriangles;
@ -1129,7 +1129,7 @@ typedef struct
int pshadowBits[SMP_FRAMES]; int pshadowBits[SMP_FRAMES];
// culling information // culling information
vec3_t bounds[2]; // vec3_t bounds[2];
// triangle definitions // triangle definitions
int numTriangles; int numTriangles;
@ -1599,6 +1599,9 @@ typedef struct {
qboolean textureFloat; qboolean textureFloat;
qboolean halfFloatPixel; qboolean halfFloatPixel;
qboolean packedDepthStencil; qboolean packedDepthStencil;
qboolean framebufferMultisample;
qboolean framebufferBlit;
} glRefConfig_t; } glRefConfig_t;
@ -1716,6 +1719,7 @@ typedef struct {
image_t *textureDepthImage; image_t *textureDepthImage;
FBO_t *renderFbo; FBO_t *renderFbo;
FBO_t *msaaResolveFbo;
FBO_t *godRaysFbo; FBO_t *godRaysFbo;
FBO_t *depthFbo; FBO_t *depthFbo;
FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS]; FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS];
@ -1909,6 +1913,7 @@ extern cvar_t *r_ext_multi_draw_arrays;
extern cvar_t *r_ext_framebuffer_object; extern cvar_t *r_ext_framebuffer_object;
extern cvar_t *r_ext_texture_float; extern cvar_t *r_ext_texture_float;
extern cvar_t *r_arb_half_float_pixel; extern cvar_t *r_arb_half_float_pixel;
extern cvar_t *r_ext_framebuffer_multisample;
extern cvar_t *r_nobind; // turns off binding to appropriate textures extern cvar_t *r_nobind; // turns off binding to appropriate textures
extern cvar_t *r_singleShader; // make most world faces use default shader extern cvar_t *r_singleShader; // make most world faces use default shader

View file

@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#include "tr_local.h" #include "tr_local.h"
void RB_ToneMap(int autoExposure) void RB_ToneMap(FBO_t *hdrFbo, int autoExposure)
{ {
vec4_t white; vec4_t white;
vec2_t texScale; vec2_t texScale;
@ -38,10 +38,10 @@ void RB_ToneMap(int autoExposure)
vec4_t srcBox, dstBox, color; vec4_t srcBox, dstBox, color;
int size = 256, currentScratch, nextScratch, tmp; int size = 256, currentScratch, nextScratch, tmp;
VectorSet4(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height);
VectorSet4(dstBox, 0, 0, 256, 256); VectorSet4(dstBox, 0, 0, 256, 256);
FBO_Blit(tr.renderFbo, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.calclevels4xShader[0], white, 0); FBO_Blit(hdrFbo, srcBox, texScale, tr.textureScratchFbo[0], dstBox, &tr.calclevels4xShader[0], white, 0);
currentScratch = 0; currentScratch = 0;
nextScratch = 1; nextScratch = 1;
@ -79,7 +79,7 @@ void RB_ToneMap(int autoExposure)
// tonemap // tonemap
vec4_t srcBox, dstBox, color; vec4_t srcBox, dstBox, color;
VectorSet4(srcBox, 0, 0, tr.renderFbo->width, tr.renderFbo->height); VectorSet4(srcBox, 0, 0, hdrFbo->width, hdrFbo->height);
VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height); VectorSet4(dstBox, 0, 0, tr.screenScratchFbo->width, tr.screenScratchFbo->height);
color[0] = color[0] =
@ -93,9 +93,9 @@ void RB_ToneMap(int autoExposure)
GL_BindToTMU(tr.fixedLevelsImage, TB_LEVELSMAP); GL_BindToTMU(tr.fixedLevelsImage, TB_LEVELSMAP);
if (r_hdr->integer) if (r_hdr->integer)
FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.tonemapShader, color, 0); FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.tonemapShader, color, 0);
else else
FBO_Blit(tr.renderFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0); FBO_Blit(hdrFbo, srcBox, texScale, tr.screenScratchFbo, dstBox, &tr.textureColorShader, color, 0);
} }
} }

View file

@ -23,7 +23,9 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
#ifndef TR_POSTPROCESS_H #ifndef TR_POSTPROCESS_H
#define TR_POSTPROCESS_H #define TR_POSTPROCESS_H
void RB_ToneMap(int autoExposure); #include "tr_fbo.h"
void RB_ToneMap(FBO_t *hdrFbo, int autoExposure);
void RB_BokehBlur(float blur); void RB_BokehBlur(float blur);
void RB_GodRays(void); void RB_GodRays(void);
void RB_GaussianBlur(float blur); void RB_GaussianBlur(float blur);