summaryrefslogtreecommitdiff
path: root/src/renderergl2/tr_backend.c
diff options
context:
space:
mode:
authorTim Angus <tim@ngus.net>2016-04-09 17:57:28 +0100
committerTim Angus <tim@ngus.net>2016-04-09 17:57:28 +0100
commitf45fbef604e05144057dec8d1dbfc5d4f5a2a822 (patch)
tree152d2a428b078f7a89756ea9e156695fc69f1686 /src/renderergl2/tr_backend.c
parent7f9e97d611b4b267d9dd913144cb9632f96c90c2 (diff)
parent87abdd914988724e164ffb16380ad26be8420b84 (diff)
Merge branch 'master' into gpp
Diffstat (limited to 'src/renderergl2/tr_backend.c')
-rw-r--r--src/renderergl2/tr_backend.c439
1 files changed, 236 insertions, 203 deletions
diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c
index 6c03db3c..0e331752 100644
--- a/src/renderergl2/tr_backend.c
+++ b/src/renderergl2/tr_backend.c
@@ -21,6 +21,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
===========================================================================
*/
#include "tr_local.h"
+#include "tr_fbo.h"
+#include "tr_dsa.h"
backEndData_t *backEndData;
backEndState_t backEnd;
@@ -37,80 +39,27 @@ static float s_flipMatrix[16] = {
/*
-** GL_Bind
-*/
-void GL_Bind( image_t *image ) {
- int texnum;
-
- if ( !image ) {
- ri.Printf( PRINT_WARNING, "GL_Bind: NULL image\n" );
- texnum = tr.defaultImage->texnum;
- } else {
- texnum = image->texnum;
- }
-
- if ( r_nobind->integer && tr.dlightImage ) { // performance evaluation option
- texnum = tr.dlightImage->texnum;
- }
-
- if ( glState.currenttextures[glState.currenttmu] != texnum ) {
- if ( image ) {
- image->frameUsed = tr.frameCount;
- }
- glState.currenttextures[glState.currenttmu] = texnum;
- if (image && image->flags & IMGFLAG_CUBEMAP)
- qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
- else
- qglBindTexture( GL_TEXTURE_2D, texnum );
- }
-}
-
-/*
-** GL_SelectTexture
-*/
-void GL_SelectTexture( int unit )
-{
- if ( glState.currenttmu == unit )
- {
- return;
- }
-
- if (!(unit >= 0 && unit <= 31))
- ri.Error( ERR_DROP, "GL_SelectTexture: unit = %i", unit );
-
- if (!qglActiveTextureARB)
- ri.Error( ERR_DROP, "GL_SelectTexture: multitexture disabled" );
-
- qglActiveTextureARB( GL_TEXTURE0_ARB + unit );
-
- glState.currenttmu = unit;
-}
-
-/*
** GL_BindToTMU
*/
void GL_BindToTMU( image_t *image, int tmu )
{
- int texnum;
- int oldtmu = glState.currenttmu;
+ GLuint texture = (tmu == TB_COLORMAP) ? tr.defaultImage->texnum : 0;
+ GLenum target = GL_TEXTURE_2D;
- if (!image)
- texnum = 0;
- else
- texnum = image->texnum;
-
- if ( glState.currenttextures[tmu] != texnum ) {
- GL_SelectTexture( tmu );
- if (image)
- image->frameUsed = tr.frameCount;
- glState.currenttextures[tmu] = texnum;
+ if (image)
+ {
+ if (image->flags & IMGFLAG_CUBEMAP)
+ target = GL_TEXTURE_CUBE_MAP;
- if (image && (image->flags & IMGFLAG_CUBEMAP))
- qglBindTexture( GL_TEXTURE_CUBE_MAP, texnum );
- else
- qglBindTexture( GL_TEXTURE_2D, texnum );
- GL_SelectTexture( oldtmu );
+ image->frameUsed = tr.frameCount;
+ texture = image->texnum;
+ }
+ else
+ {
+ ri.Printf(PRINT_WARNING, "GL_BindToTMU: NULL image\n");
}
+
+ GL_BindMultiTexture(GL_TEXTURE0_ARB + tmu, target, texture);
}
@@ -143,39 +92,6 @@ void GL_Cull( int cullType ) {
}
/*
-** GL_TexEnv
-*/
-void GL_TexEnv( int env )
-{
- if ( env == glState.texEnv[glState.currenttmu] )
- {
- return;
- }
-
- glState.texEnv[glState.currenttmu] = env;
-
-
- switch ( env )
- {
- case GL_MODULATE:
- qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
- break;
- case GL_REPLACE:
- qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE );
- break;
- case GL_DECAL:
- qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_DECAL );
- break;
- case GL_ADD:
- qglTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_ADD );
- break;
- default:
- ri.Error( ERR_DROP, "GL_TexEnv: invalid env '%d' passed", env );
- break;
- }
-}
-
-/*
** GL_State
**
** This routine is responsible for setting the most commonly changed state
@@ -463,30 +379,20 @@ void RB_BeginDrawingView (void) {
if (glRefConfig.framebufferObject)
{
+ FBO_t *fbo = backEnd.viewParms.targetFbo;
+
// FIXME: HUGE HACK: render to the screen fbo if we've already postprocessed the frame and aren't drawing more world
// drawing more world check is in case of double renders, such as skyportals
- if (backEnd.viewParms.targetFbo == NULL)
+ if (fbo == NULL && !(backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
+ fbo = tr.renderFbo;
+
+ if (tr.renderCubeFbo && fbo == tr.renderCubeFbo)
{
- if (!tr.renderFbo || (backEnd.framePostProcessed && (backEnd.refdef.rdflags & RDF_NOWORLDMODEL)))
- {
- FBO_Bind(NULL);
- }
- else
- {
- FBO_Bind(tr.renderFbo);
- }
+ cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
+ FBO_AttachImage(fbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, backEnd.viewParms.targetFboLayer);
}
- else
- {
- FBO_Bind(backEnd.viewParms.targetFbo);
- // FIXME: hack for cubemap testing
- if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
- {
- //qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, backEnd.viewParms.targetFbo->colorImage[0]->texnum, 0);
- qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]->texnum, 0);
- }
- }
+ FBO_Bind(fbo);
}
//
@@ -550,8 +456,6 @@ void RB_BeginDrawingView (void) {
}
-#define MAC_EVENT_PUMP_MSEC 5
-
/*
==================
RB_RenderDrawSurfList
@@ -857,6 +761,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
}
RE_UploadCinematic (w, h, cols, rows, data, client, dirty);
+ GL_BindToTMU(tr.scratchImage[client], TB_COLORMAP);
if ( r_speeds->integer ) {
end = ri.Milliseconds();
@@ -866,14 +771,7 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
// FIXME: HUGE hack
if (glRefConfig.framebufferObject)
{
- if (!tr.renderFbo || backEnd.framePostProcessed)
- {
- FBO_Bind(NULL);
- }
- else
- {
- FBO_Bind(tr.renderFbo);
- }
+ FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
}
RB_SetGL2D();
@@ -897,23 +795,30 @@ void RE_StretchRaw (int x, int y, int w, int h, int cols, int rows, const byte *
}
void RE_UploadCinematic (int w, int h, int cols, int rows, const byte *data, int client, qboolean dirty) {
+ GLuint texture;
+
+ if (!tr.scratchImage[client])
+ {
+ ri.Printf(PRINT_WARNING, "RE_UploadCinematic: scratch images not initialized\n");
+ return;
+ }
- GL_Bind( tr.scratchImage[client] );
+ texture = tr.scratchImage[client]->texnum;
// if the scratchImage isn't in the format we want, specify it as a new texture
if ( cols != tr.scratchImage[client]->width || rows != tr.scratchImage[client]->height ) {
tr.scratchImage[client]->width = tr.scratchImage[client]->uploadWidth = cols;
tr.scratchImage[client]->height = tr.scratchImage[client]->uploadHeight = rows;
- qglTexImage2D( GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE );
- qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE );
+ qglTextureImage2D(texture, GL_TEXTURE_2D, 0, GL_RGB8, cols, rows, 0, GL_RGBA, GL_UNSIGNED_BYTE, data);
+ qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
+ qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
+ qglTextureParameterf(texture, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
} else {
if (dirty) {
// otherwise, just subimage upload it so that drivers can tell we are going to be changing
// it and don't try and do a texture compression
- qglTexSubImage2D( GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data );
+ qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, 0, 0, cols, rows, GL_RGBA, GL_UNSIGNED_BYTE, data);
}
}
}
@@ -952,16 +857,7 @@ const void *RB_StretchPic ( const void *data ) {
// FIXME: HUGE hack
if (glRefConfig.framebufferObject)
- {
- if (!tr.renderFbo || backEnd.framePostProcessed)
- {
- FBO_Bind(NULL);
- }
- else
- {
- FBO_Bind(tr.renderFbo);
- }
- }
+ FBO_Bind(backEnd.framePostProcessed ? NULL : tr.renderFbo);
RB_SetGL2D();
@@ -1061,6 +957,9 @@ const void *RB_DrawSurfs( const void *data ) {
if (glRefConfig.framebufferObject && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL) && (r_depthPrepass->integer || (backEnd.viewParms.flags & VPF_DEPTHSHADOW)))
{
FBO_t *oldFbo = glState.currentFBO;
+ vec4_t viewInfo;
+
+ VectorSet4(viewInfo, backEnd.viewParms.zFar / r_znear->value, backEnd.viewParms.zFar, 0.0, 0.0);
backEnd.depthFill = qtrue;
qglColorMask(GL_FALSE, GL_FALSE, GL_FALSE, GL_FALSE);
@@ -1073,17 +972,20 @@ const void *RB_DrawSurfs( const void *data ) {
// If we're using multisampling, resolve the depth first
FBO_FastBlit(tr.renderFbo, NULL, tr.msaaResolveFbo, NULL, GL_DEPTH_BUFFER_BIT, GL_NEAREST);
}
- else if (tr.renderFbo == NULL)
+ else if (tr.renderFbo == NULL && tr.renderDepthImage)
{
// If we're rendering directly to the screen, copy the depth to a texture
- GL_BindToTMU(tr.renderDepthImage, 0);
- qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
+ qglCopyTextureImage2D(tr.renderDepthImage->texnum, GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT24, 0, 0, glConfig.vidWidth, glConfig.vidHeight, 0);
}
- if (r_ssao->integer)
+ if (tr.hdrDepthFbo)
{
// need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image
- FBO_BlitFromTexture(tr.renderDepthImage, NULL, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
+ vec4_t srcTexCoords;
+
+ VectorSet4(srcTexCoords, 0.0f, 0.0f, 1.0f, 1.0f);
+
+ FBO_BlitFromTexture(tr.renderDepthImage, srcTexCoords, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0);
}
if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT)
@@ -1148,15 +1050,12 @@ const void *RB_DrawSurfs( const void *data ) {
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWORIGIN, backEnd.refdef.vieworg);
{
- vec4_t viewInfo;
vec3_t viewVector;
float zmax = backEnd.viewParms.zFar;
float ymax = zmax * tan(backEnd.viewParms.fovY * M_PI / 360.0f);
float xmax = zmax * tan(backEnd.viewParms.fovX * M_PI / 360.0f);
- float zmin = r_znear->value;
-
VectorScale(backEnd.refdef.viewaxis[0], zmax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWFORWARD, viewVector);
VectorScale(backEnd.refdef.viewaxis[1], xmax, viewVector);
@@ -1164,13 +1063,38 @@ const void *RB_DrawSurfs( const void *data ) {
VectorScale(backEnd.refdef.viewaxis[2], ymax, viewVector);
GLSL_SetUniformVec3(&tr.shadowmaskShader, UNIFORM_VIEWUP, viewVector);
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
GLSL_SetUniformVec4(&tr.shadowmaskShader, UNIFORM_VIEWINFO, viewInfo);
}
-
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
+
+ if (r_shadowBlur->integer)
+ {
+ viewInfo[2] = 1.0f / (float)(tr.screenScratchFbo->width);
+ viewInfo[3] = 1.0f / (float)(tr.screenScratchFbo->height);
+
+ FBO_Bind(tr.screenScratchFbo);
+
+ GLSL_BindProgram(&tr.depthBlurShader[0]);
+
+ GL_BindToTMU(tr.screenShadowImage, TB_COLORMAP);
+ GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
+
+ GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
+
+ RB_InstantQuad2(quadVerts, texCoords);
+
+ FBO_Bind(tr.screenShadowFbo);
+
+ GLSL_BindProgram(&tr.depthBlurShader[1]);
+
+ GL_BindToTMU(tr.screenScratchImage, TB_COLORMAP);
+ GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
+
+ GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
+
+ RB_InstantQuad2(quadVerts, texCoords);
+ }
}
if (r_ssao->integer)
@@ -1178,6 +1102,10 @@ const void *RB_DrawSurfs( const void *data ) {
vec4_t quadVerts[4];
vec2_t texCoords[4];
+ viewInfo[2] = 1.0f / ((float)(tr.quarterImage[0]->width) * tan(backEnd.viewParms.fovX * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] = 1.0f / ((float)(tr.quarterImage[0]->height) * tan(backEnd.viewParms.fovY * M_PI / 360.0f) * 2.0f);
+ viewInfo[3] *= (float)backEnd.viewParms.viewportHeight / (float)backEnd.viewParms.viewportWidth;
+
FBO_Bind(tr.quarterFbo[0]);
qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height);
@@ -1199,20 +1127,14 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.hdrDepthImage, TB_COLORMAP);
- {
- vec4_t viewInfo;
-
- float zmax = backEnd.viewParms.zFar;
- float zmin = r_znear->value;
-
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
- GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
- }
+ GLSL_SetUniformVec4(&tr.ssaoShader, UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
+ viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width);
+ viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height);
+
FBO_Bind(tr.quarterFbo[1]);
qglViewport(0, 0, tr.quarterFbo[1]->width, tr.quarterFbo[1]->height);
@@ -1223,16 +1145,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[0], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- vec4_t viewInfo;
-
- float zmax = backEnd.viewParms.zFar;
- float zmin = r_znear->value;
-
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
- GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[0], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -1247,16 +1160,7 @@ const void *RB_DrawSurfs( const void *data ) {
GL_BindToTMU(tr.quarterImage[1], TB_COLORMAP);
GL_BindToTMU(tr.hdrDepthImage, TB_LIGHTMAP);
- {
- vec4_t viewInfo;
-
- float zmax = backEnd.viewParms.zFar;
- float zmin = r_znear->value;
-
- VectorSet4(viewInfo, zmax / zmin, zmax, 0.0, 0.0);
-
- GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
- }
+ GLSL_SetUniformVec4(&tr.depthBlurShader[1], UNIFORM_VIEWINFO, viewInfo);
RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes);
@@ -1314,11 +1218,11 @@ const void *RB_DrawSurfs( const void *data ) {
if (glRefConfig.framebufferObject && tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo)
{
+ cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex];
+
FBO_Bind(NULL);
- GL_SelectTexture(TB_CUBEMAP);
- GL_BindToTMU(tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex], TB_CUBEMAP);
- qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP);
- GL_SelectTexture(0);
+ if (cubemap && cubemap->image)
+ qglGenerateTextureMipmap(cubemap->image->texnum, GL_TEXTURE_CUBE_MAP);
}
return (const void *)(cmd + 1);
@@ -1395,7 +1299,7 @@ void RB_ShowImages( void ) {
{
vec4_t quadVerts[4];
- GL_Bind(image);
+ GL_BindToTMU(image, TB_COLORMAP);
VectorSet4(quadVerts[0], x, y, 0, 1);
VectorSet4(quadVerts[1], x + w, y, 0, 1);
@@ -1571,21 +1475,18 @@ const void *RB_CapShadowMap(const void *data)
if (cmd->map != -1)
{
- GL_SelectTexture(0);
if (cmd->cubeSide != -1)
{
if (tr.shadowCubemaps[cmd->map])
{
- GL_Bind(tr.shadowCubemaps[cmd->map]);
- qglCopyTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
+ qglCopyTextureImage2D(tr.shadowCubemaps[cmd->map]->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X + cmd->cubeSide, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
}
}
else
{
if (tr.pshadowMaps[cmd->map])
{
- GL_Bind(tr.pshadowMaps[cmd->map]);
- qglCopyTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - ( backEnd.refdef.y + PSHADOW_MAP_SIZE ), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
+ qglCopyTextureImage2D(tr.pshadowMaps[cmd->map]->texnum, GL_TEXTURE_2D, 0, GL_RGBA8, backEnd.refdef.x, glConfig.vidHeight - (backEnd.refdef.y + PSHADOW_MAP_SIZE), PSHADOW_MAP_SIZE, PSHADOW_MAP_SIZE, 0);
}
}
}
@@ -1644,10 +1545,6 @@ const void *RB_PostProcess(const void *data)
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);
}
@@ -1658,7 +1555,7 @@ const void *RB_PostProcess(const void *data)
if (srcFbo)
{
- if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer) && qglActiveTextureARB)
+ if (r_hdr->integer && (r_toneMap->integer || r_forceToneMap->integer))
{
autoExposure = r_autoExposure->integer || r_forceAutoExposure->integer;
RB_ToneMap(srcFbo, srcBox, NULL, dstBox, autoExposure);
@@ -1688,6 +1585,71 @@ const void *RB_PostProcess(const void *data)
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;
@@ -1727,7 +1689,7 @@ const void *RB_PostProcess(const void *data)
{
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);
+ FBO_BlitFromTexture(tr.cubemaps[cubemapIndex - 1].image, NULL, NULL, NULL, dstBox, &tr.testcubeShader, NULL, 0);
}
}
#endif
@@ -1737,6 +1699,74 @@ const void *RB_PostProcess(const void *data)
return (const void *)(cmd + 1);
}
+// FIXME: put this function declaration elsewhere
+void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth);
+
+/*
+=============
+RB_ExportCubemaps
+
+=============
+*/
+const void *RB_ExportCubemaps(const void *data)
+{
+ const exportCubemapsCommand_t *cmd = data;
+
+ // finish any 2D drawing if needed
+ if (tess.numIndexes)
+ RB_EndSurface();
+
+ if (!glRefConfig.framebufferObject || !tr.world || tr.numCubemaps == 0)
+ {
+ // do nothing
+ ri.Printf(PRINT_ALL, "Nothing to export!\n");
+ return (const void *)(cmd + 1);
+ }
+
+ if (cmd)
+ {
+ FBO_t *oldFbo = glState.currentFBO;
+ int sideSize = r_cubemapSize->integer * r_cubemapSize->integer * 4;
+ byte *cubemapPixels = ri.Malloc(sideSize * 6);
+ int i, j;
+
+ FBO_Bind(tr.renderCubeFbo);
+
+ for (i = 0; i < tr.numCubemaps; i++)
+ {
+ char filename[MAX_QPATH];
+ cubemap_t *cubemap = &tr.cubemaps[i];
+ byte *p = cubemapPixels;
+
+ for (j = 0; j < 6; j++)
+ {
+ FBO_AttachImage(tr.renderCubeFbo, cubemap->image, GL_COLOR_ATTACHMENT0_EXT, j);
+ qglReadPixels(0, 0, r_cubemapSize->integer, r_cubemapSize->integer, GL_RGBA, GL_UNSIGNED_BYTE, p);
+ p += sideSize;
+ }
+
+ if (cubemap->name[0])
+ {
+ COM_StripExtension(cubemap->name, filename, MAX_QPATH);
+ Q_strcat(filename, MAX_QPATH, ".dds");
+ }
+ else
+ {
+ Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i);
+ }
+
+ R_SaveDDS(filename, cubemapPixels, r_cubemapSize->integer, r_cubemapSize->integer, 6);
+ ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename);
+ }
+
+ FBO_Bind(oldFbo);
+
+ ri.Free(cubemapPixels);
+ }
+
+ return (const void *)(cmd + 1);
+}
+
/*
====================
@@ -1785,6 +1815,9 @@ void RB_ExecuteRenderCommands( const void *data ) {
case RC_POSTPROCESS:
data = RB_PostProcess(data);
break;
+ case RC_EXPORT_CUBEMAPS:
+ data = RB_ExportCubemaps(data);
+ break;
case RC_END_OF_LIST:
default:
// finish any 2D drawing if needed