From 7b1fa0e3cc8c106a08ab8d7e12a0c40d2e2a7791 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Fri, 12 Jun 2015 14:22:37 -0500 Subject: Move image load function prototypes to tr_common.h The functions themselves are in code/renderercommon/tr_image_*.c --- src/renderergl2/tr_local.h | 14 -------------- 1 file changed, 14 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 95d87165..76cbe9c7 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -2278,20 +2278,6 @@ int R_IQMLerpTag( orientation_t *tag, iqmData_t *data, int startFrame, int endFrame, float frac, const char *tagName ); -/* -============================================================= - -IMAGE LOADERS - -============================================================= -*/ - -void R_LoadBMP( const char *name, byte **pic, int *width, int *height ); -void R_LoadJPG( const char *name, byte **pic, int *width, int *height ); -void R_LoadPCX( const char *name, byte **pic, int *width, int *height ); -void R_LoadPNG( const char *name, byte **pic, int *width, int *height ); -void R_LoadTGA( const char *name, byte **pic, int *width, int *height ); - /* ============================================================= ============================================================= -- cgit From 00a83e798f7934962facba8e7864b215e1d94701 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 4 Jul 2015 19:17:58 -0500 Subject: Apply greyscaling to fog blocks --- src/renderergl2/tr_shader.c | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index 4143b246..68b5cb60 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -1857,6 +1857,23 @@ static qboolean ParseShader( char **text ) return qfalse; } + if ( r_greyscale->integer ) + { + float luminance; + + luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] ); + VectorSet( shader.fogParms.color, luminance, luminance, luminance ); + } + else if ( r_greyscale->value ) + { + float luminance; + + luminance = LUMA( shader.fogParms.color[0], shader.fogParms.color[1], shader.fogParms.color[2] ); + shader.fogParms.color[0] = LERP( shader.fogParms.color[0], luminance, r_greyscale->value ); + shader.fogParms.color[1] = LERP( shader.fogParms.color[1], luminance, r_greyscale->value ); + shader.fogParms.color[2] = LERP( shader.fogParms.color[2], luminance, r_greyscale->value ); + } + token = COM_ParseExt( text, qfalse ); if ( !token[0] ) { -- cgit From a1cb4046bef1a81e8d19a1b2556c285da5cf3229 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 4 Jul 2015 19:33:28 -0500 Subject: Don't fog 3D crosshair sprite --- src/renderergl2/tr_main.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 132ef309..287f95d3 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -1680,6 +1680,10 @@ int R_SpriteFogNum( trRefEntity_t *ent ) { return 0; } + if ( ent->e.renderfx & RF_CROSSHAIR ) { + return 0; + } + for ( i = 1 ; i < tr.world->numfogs ; i++ ) { fog = &tr.world->fogs[i]; for ( j = 0 ; j < 3 ; j++ ) { -- cgit From 17abbc7123b1f79467d18c64b67235ce41c115c4 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Thu, 9 Jul 2015 22:28:08 -0500 Subject: Fix OpenGL2 ignoring last light grid point on each axis Also change light grid bounds clamping to make it more clear what invalid values are. --- src/renderergl2/tr_light.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_light.c b/src/renderergl2/tr_light.c index 5993959e..ec54eab4 100644 --- a/src/renderergl2/tr_light.c +++ b/src/renderergl2/tr_light.c @@ -157,7 +157,7 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) { frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; - } else if ( pos[i] >= world->lightGridBounds[i] - 1 ) { + } else if ( pos[i] > world->lightGridBounds[i] - 1 ) { pos[i] = world->lightGridBounds[i] - 1; } } @@ -190,7 +190,7 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) { ignore = qfalse; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1<= world->lightGridBounds[j] - 1) + if ((pos[j] + 1) > world->lightGridBounds[j] - 1) { ignore = qtrue; // ignore values outside lightgrid } -- cgit From 3021d2b30e8d2b8456484cc9cd8adc30bda0a98e Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 12 Jul 2015 17:53:17 -0500 Subject: Backport ignoring values outside lightgrid to OpenGL1 Fixes possibly of reading memory past end of lightGridData or reading wrong light grid data (wrapping around to next row). --- src/renderergl2/tr_light.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_light.c b/src/renderergl2/tr_light.c index ec54eab4..317f4585 100644 --- a/src/renderergl2/tr_light.c +++ b/src/renderergl2/tr_light.c @@ -181,18 +181,15 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) { byte *data; int lat, lng; vec3_t normal; - qboolean ignore; #if idppc float d0, d1, d2, d3, d4, d5; #endif factor = 1.0; data = gridData; - ignore = qfalse; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1< world->lightGridBounds[j] - 1) - { - ignore = qtrue; // ignore values outside lightgrid + if ( pos[j] + 1 > world->lightGridBounds[j] - 1 ) { + break; // ignore values outside lightgrid } factor *= frac[j]; data += gridStep[j]; @@ -201,8 +198,9 @@ static void R_SetupEntityLightingGrid( trRefEntity_t *ent, world_t *world ) { } } - if ( ignore ) + if ( j != 3 ) { continue; + } if (world->hdrLightGrid) { -- cgit From 948b565a2b0105d7c0530c78de7a4e005f73e6e8 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 12 Jul 2015 20:35:22 -0500 Subject: Remove logically dead code in R_CheckFBO Found by Coverity. --- src/renderergl2/tr_fbo.c | 3 --- 1 file changed, 3 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index f02e6cc7..c8ea0aeb 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -47,9 +47,6 @@ qboolean R_CheckFBO(const FBO_t * fbo) // an error occured switch (code) { - case GL_FRAMEBUFFER_COMPLETE_EXT: - break; - case GL_FRAMEBUFFER_UNSUPPORTED_EXT: ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) Unsupported framebuffer format\n", fbo->name); break; -- cgit From 7ebcf42f808b8c1a209cabdaa6f879b8e1790036 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sun, 12 Jul 2015 20:41:41 -0500 Subject: Fix alloc size for default skin and single shader skin Found by Coverity. --- src/renderergl2/tr_image.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 08894a4a..ef244d56 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -3121,7 +3121,7 @@ qhandle_t RE_RegisterSkin( const char *name ) { // If not a .skin file, load as a single shader if ( strcmp( name + strlen( name ) - 5, ".skin" ) ) { skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof(skin->surfaces[0]), h_low ); + skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); skin->surfaces[0]->shader = R_FindShader( name, LIGHTMAP_NONE, qtrue ); return hSkin; } @@ -3192,7 +3192,7 @@ void R_InitSkins( void ) { skin = tr.skins[0] = ri.Hunk_Alloc( sizeof( skin_t ), h_low ); Q_strncpyz( skin->name, "", sizeof( skin->name ) ); skin->numSurfaces = 1; - skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces ), h_low ); + skin->surfaces[0] = ri.Hunk_Alloc( sizeof( *skin->surfaces[0] ), h_low ); skin->surfaces[0]->shader = tr.defaultShader; } -- cgit From 0bb0fb2bac331ce4d4a9756b7f62969a6278ee5b Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Mon, 28 Sep 2015 01:12:17 -0500 Subject: Remove unused define MAC_EVENT_PUMP_MSEC --- src/renderergl2/tr_backend.c | 2 -- 1 file changed, 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 6c03db3c..2a61e114 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -550,8 +550,6 @@ void RB_BeginDrawingView (void) { } -#define MAC_EVENT_PUMP_MSEC 5 - /* ================== RB_RenderDrawSurfList -- cgit From 27b955ed8aae71e0a4a15d75e1c06ffa6516fbe5 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Fri, 16 Oct 2015 19:18:38 -0500 Subject: Fix not swapping buffers because out of cmd buffer space Reserve space for end of list and swap buffer commands. These are absolutely required and cannot be dropped. Dropping swap buffer command causes screen to not update and possible crash from drawsurf buffer overflow if not enough cmd buffer space for many continous frames. --- src/renderergl2/tr_cmds.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_cmds.c b/src/renderergl2/tr_cmds.c index 07fe146f..4599511b 100644 --- a/src/renderergl2/tr_cmds.c +++ b/src/renderergl2/tr_cmds.c @@ -122,19 +122,19 @@ void R_IssuePendingRenderCommands( void ) { /* ============ -R_GetCommandBuffer +R_GetCommandBufferReserved make sure there is enough command space ============ */ -void *R_GetCommandBuffer( int bytes ) { +void *R_GetCommandBufferReserved( int bytes, int reservedBytes ) { renderCommandList_t *cmdList; cmdList = &backEndData->commands; bytes = PAD(bytes, sizeof(void *)); // always leave room for the end of list command - if ( cmdList->used + bytes + 4 > MAX_RENDER_COMMANDS ) { + if ( cmdList->used + bytes + 4 + reservedBytes > MAX_RENDER_COMMANDS ) { if ( bytes > MAX_RENDER_COMMANDS - 4 ) { ri.Error( ERR_FATAL, "R_GetCommandBuffer: bad size %i", bytes ); } @@ -147,6 +147,17 @@ void *R_GetCommandBuffer( int bytes ) { return cmdList->cmds + cmdList->used - bytes; } +/* +============= +R_GetCommandBuffer + +returns NULL if there is not enough space for important commands +============= +*/ +void *R_GetCommandBuffer( int bytes ) { + return R_GetCommandBufferReserved( bytes, sizeof ( swapBuffersCommand_t ) ); +} + /* ============= @@ -611,7 +622,7 @@ void RE_EndFrame( int *frontEndMsec, int *backEndMsec ) { if ( !tr.registered ) { return; } - cmd = R_GetCommandBuffer( sizeof( *cmd ) ); + cmd = R_GetCommandBufferReserved( sizeof( *cmd ), 0 ); if ( !cmd ) { return; } -- cgit From 0972dc8edfdadae375ab0a517e324178f8ec99f0 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Fri, 16 Oct 2015 20:12:51 -0500 Subject: Fix crash from reading past end of tr.refdef.drawSurfs The number of draw surfaces was range checked against number of surfaces for the current view but needs to check total for the frame otherwise can read past the end of the tr.refdef.drawSurfs array when there are multiple views. --- src/renderergl2/tr_main.c | 18 ++++++++++-------- 1 file changed, 10 insertions(+), 8 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 287f95d3..2682d471 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -1821,13 +1821,6 @@ void R_SortDrawSurfs( drawSurf_t *drawSurfs, int numDrawSurfs ) { return; } - // if we overflowed MAX_DRAWSURFS, the drawsurfs - // wrapped around in the buffer and we will be missing - // the first surfaces, not the last ones - if ( numDrawSurfs > MAX_DRAWSURFS ) { - numDrawSurfs = MAX_DRAWSURFS; - } - // sort the drawsurfs by sort type, then orientation, then shader R_RadixSort( drawSurfs, numDrawSurfs ); @@ -2054,6 +2047,7 @@ or a mirror / remote location */ void R_RenderView (viewParms_t *parms) { int firstDrawSurf; + int numDrawSurfs; if ( parms->viewportWidth <= 0 || parms->viewportHeight <= 0 ) { return; @@ -2076,7 +2070,15 @@ void R_RenderView (viewParms_t *parms) { R_GenerateDrawSurfs(); - R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, tr.refdef.numDrawSurfs - firstDrawSurf ); + // if we overflowed MAX_DRAWSURFS, the drawsurfs + // wrapped around in the buffer and we will be missing + // the first surfaces, not the last ones + numDrawSurfs = tr.refdef.numDrawSurfs; + if ( numDrawSurfs > MAX_DRAWSURFS ) { + numDrawSurfs = MAX_DRAWSURFS; + } + + R_SortDrawSurfs( tr.refdef.drawSurfs + firstDrawSurf, numDrawSurfs - firstDrawSurf ); // draw main system development information (surface outlines, etc) R_DebugGraphics(); -- cgit From 6c232efd91fd288342bc6865a36fa1c8c0a23575 Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Fri, 16 Oct 2015 20:50:25 -0500 Subject: Fix reserved size for swap buffer command being too small on x86_64 --- src/renderergl2/tr_cmds.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_cmds.c b/src/renderergl2/tr_cmds.c index 4599511b..fe0ee82b 100644 --- a/src/renderergl2/tr_cmds.c +++ b/src/renderergl2/tr_cmds.c @@ -155,7 +155,7 @@ returns NULL if there is not enough space for important commands ============= */ void *R_GetCommandBuffer( int bytes ) { - return R_GetCommandBufferReserved( bytes, sizeof ( swapBuffersCommand_t ) ); + return R_GetCommandBufferReserved( bytes, PAD( sizeof( swapBuffersCommand_t ), sizeof(void *) ) ); } -- cgit From 802eb6dfaffb6efba11705fcce16eed8a6e34bad Mon Sep 17 00:00:00 2001 From: Zack Middleton Date: Sat, 17 Oct 2015 21:57:16 -0500 Subject: Replace 4 with sizeof( int ) in R_GetCommandBufferReserved --- src/renderergl2/tr_cmds.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_cmds.c b/src/renderergl2/tr_cmds.c index fe0ee82b..5d27c52d 100644 --- a/src/renderergl2/tr_cmds.c +++ b/src/renderergl2/tr_cmds.c @@ -134,8 +134,8 @@ void *R_GetCommandBufferReserved( int bytes, int reservedBytes ) { bytes = PAD(bytes, sizeof(void *)); // always leave room for the end of list command - if ( cmdList->used + bytes + 4 + reservedBytes > MAX_RENDER_COMMANDS ) { - if ( bytes > MAX_RENDER_COMMANDS - 4 ) { + if ( cmdList->used + bytes + sizeof( int ) + reservedBytes > MAX_RENDER_COMMANDS ) { + if ( bytes > MAX_RENDER_COMMANDS - sizeof( int ) ) { ri.Error( ERR_FATAL, "R_GetCommandBuffer: bad size %i", bytes ); } // if we run out of room, just start dropping commands -- cgit From 2bdf7e48b4eae30a1194887725e872c0c4053399 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 2 Dec 2015 17:08:40 -0800 Subject: OpenGL2: automatically load textures with a _s suffix as specular. --- src/renderergl2/tr_shader.c | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index 68b5cb60..98e8776e 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -2213,12 +2213,33 @@ static void CollapseStagesToLightall(shaderStage_t *diffuse, if (r_specularMapping->integer) { + image_t *diffuseImg; if (specular) { //ri.Printf(PRINT_ALL, ", specularmap %s", specular->bundle[0].image[0]->imgName); diffuse->bundle[TB_SPECULARMAP] = specular->bundle[0]; VectorCopy4(specular->specularScale, diffuse->specularScale); } + else if ((lightmap || useLightVector || useLightVertex) && (diffuseImg = diffuse->bundle[TB_DIFFUSEMAP].image[0])) + { + char specularName[MAX_QPATH]; + image_t *specularImg; + imgFlags_t specularFlags = (diffuseImg->flags & ~(IMGFLAG_GENNORMALMAP | IMGFLAG_SRGB)) | IMGFLAG_NOLIGHTSCALE; + + COM_StripExtension(diffuseImg->imgName, specularName, MAX_QPATH); + Q_strcat(specularName, MAX_QPATH, "_s"); + + specularImg = R_FindImageFile(specularName, IMGTYPE_COLORALPHA, specularFlags); + + if (specularImg) + { + diffuse->bundle[TB_SPECULARMAP] = diffuse->bundle[0]; + diffuse->bundle[TB_SPECULARMAP].numImageAnimations = 0; + diffuse->bundle[TB_SPECULARMAP].image[0] = specularImg; + + VectorSet4(diffuse->specularScale, 1.0f, 1.0f, 1.0f, 1.0f); + } + } } if (tcgen || diffuse->bundle[0].numTexMods) -- cgit From e8a31f6a628ca309d1c5119d6d52c391e225445d Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 3 Dec 2015 02:44:33 -0800 Subject: OpenGL2: Remove some rendering options for simplicity. --- src/renderergl2/glsl/lightall_fp.glsl | 224 ++++++---------------------------- src/renderergl2/tr_glsl.c | 35 ------ src/renderergl2/tr_init.c | 2 - src/renderergl2/tr_local.h | 1 - 4 files changed, 35 insertions(+), 227 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index d1182781..c0d2bc80 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -150,156 +150,35 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, vec3 N, vec3 L, vec3 E, float NE, float NL, float shininess) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r) { - #if defined(USE_OREN_NAYAR) || defined(USE_TRIACE_OREN_NAYAR) - float gamma = dot(E, L) - NE * NL; - float B = 2.22222 + 0.1 * shininess; - - #if defined(USE_OREN_NAYAR) - float A = 1.0 - 1.0 / (2.0 + 0.33 * shininess); - gamma = clamp(gamma, 0.0, 1.0); - #endif - - #if defined(USE_TRIACE_OREN_NAYAR) - float A = 1.0 - 1.0 / (2.0 + 0.65 * shininess); - - if (gamma >= 0.0) - #endif - { - B = max(B * max(NL, NE), EPSILON); - } - - return diffuseAlbedo * (A + gamma / B); - #else - return diffuseAlbedo; - #endif -} - -vec3 EnvironmentBRDF(float gloss, float NE, vec3 specular) -{ - #if 1 - // from http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - vec4 t = vec4( 1.0/0.96, 0.475, (0.0275 - 0.25 * 0.04)/0.96,0.25 ) * gloss; - t += vec4( 0.0, 0.0, (0.015 - 0.75 * 0.04)/0.96,0.75 ); - float a0 = t.x * min( t.y, exp2( -9.28 * NE ) ) + t.z; - float a1 = t.w; - return clamp( a0 + specular * ( a1 - a0 ), 0.0, 1.0 ); - #elif 0 - // from http://seblagarde.wordpress.com/2011/08/17/hello-world/ - return specular + CalcFresnel(NE) * clamp(vec3(gloss) - specular, 0.0, 1.0); - #else - // from http://advances.realtimerendering.com/s2011/Lazarov-Physically-Based-Lighting-in-Black-Ops%20%28Siggraph%202011%20Advances%20in%20Real-Time%20Rendering%20Course%29.pptx - return mix(specular.rgb, vec3(1.0), CalcFresnel(NE) / (4.0 - 3.0 * gloss)); - #endif -} - -float CalcBlinn(float NH, float shininess) -{ -#if defined(USE_BLINN) || defined(USE_BLINN_FRESNEL) - // Normalized Blinn-Phong - float norm = shininess * 0.125 + 1.0; -#elif defined(USE_MCAULEY) - // Cook-Torrance as done by Stephen McAuley - // http://blog.selfshadow.com/publications/s2012-shading-course/mcauley/s2012_pbs_farcry3_notes_v2.pdf - float norm = shininess * 0.25 + 0.125; -#elif defined(USE_GOTANDA) - // Neumann-Neumann as done by Yoshiharu Gotanda - // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf - float norm = shininess * 0.124858 + 0.269182; -#elif defined(USE_LAZAROV) - // Cook-Torrance as done by Dimitar Lazarov - // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - float norm = shininess * 0.125 + 0.25; -#else - float norm = 1.0; -#endif - -#if 0 - // from http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ - float a = shininess + 0.775; - return norm * exp(a * NH - a); -#else - return norm * pow(NH, shininess); -#endif -} - -float CalcGGX(float NH, float gloss) -{ - // from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf - float a_sq = exp2(gloss * -13.0 + 1.0); - float d = ((NH * NH) * (a_sq - 1.0) + 1.0); - return a_sq / (d * d); -} - -float CalcFresnel(float EH) -{ -#if 1 - // From http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - // not accurate, but fast - return exp2(-10.0 * EH); -#elif 0 - // From http://seblagarde.wordpress.com/2012/06/03/spherical-gaussien-approximation-for-blinn-phong-phong-and-fresnel/ - return exp2((-5.55473 * EH - 6.98316) * EH); -#elif 0 - float blend = 1.0 - EH; - float blend2 = blend * blend; - blend *= blend2 * blend2; - - return blend; +#if defined(USE_BURLEY) + // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf + float fd90 = -0.5 + EH * EH * r; + float burley = 1.0 + fd90 * 0.04 / NH; + burley *= burley; + return diffuseAlbedo * burley; #else - return pow(1.0 - EH, 5.0); + return diffuseAlbedo; #endif } -float CalcVisibility(float NH, float NL, float NE, float EH, float gloss) +vec3 EnvironmentBRDF(float r, float NE, vec3 specular) { -#if defined(USE_GOTANDA) - // Neumann-Neumann as done by Yoshiharu Gotanda - // http://research.tri-ace.com/Data/s2012_beyond_CourseNotes.pdf - return 1.0 / max(max(NL, NE), EPSILON); -#elif defined(USE_LAZAROV) - // Cook-Torrance as done by Dimitar Lazarov - // http://blog.selfshadow.com/publications/s2013-shading-course/lazarov/s2013_pbs_black_ops_2_notes.pdf - float k = min(1.0, gloss + 0.545); - return 1.0 / (k * (EH * EH - 1.0) + 1.0); -#elif defined(USE_GGX) - float roughness = exp2(gloss * -6.5); - - // Modified from http://blog.selfshadow.com/publications/s2013-shading-course/karis/s2013_pbs_epic_notes_v2.pdf - // NL, NE in numerator factored out from cook-torrance - float k = roughness + 1.0; - k *= k * 0.125; - - float k2 = 1.0 - k; - - float invGeo1 = NL * k2 + k; - float invGeo2 = NE * k2 + k; - - return 1.0 / (invGeo1 * invGeo2); -#else - return 1.0; -#endif + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float v = 1.0 - max(r, NE); + v *= v * v; + return vec3(v) + specular; } - -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float gloss, float shininess) +vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float r) { -#if defined(USE_GGX) - float distrib = CalcGGX(NH, gloss); -#else - float distrib = CalcBlinn(NH, shininess); -#endif - -#if defined(USE_BLINN) - vec3 fSpecular = specular; -#else - vec3 fSpecular = mix(specular, vec3(1.0), CalcFresnel(EH)); -#endif - - float vis = CalcVisibility(NH, NL, NE, EH, gloss); - - return fSpecular * (distrib * vis); + // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf + float rr = r*r; + float rrrr = rr*rr; + float d = (NH * NH) * (rrrr - 1.0) + 1.0; + float v = (EH * EH) * (r + 0.5); + return specular * (rrrr / (4.0 * d * d * v)); } @@ -421,14 +300,7 @@ void main() shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0); #if defined(SHADOWMAP_MODULATE) - //vec3 shadowColor = min(u_PrimaryLightAmbient, lightColor); - vec3 shadowColor = u_PrimaryLightAmbient * lightColor; - - #if 0 - // Only shadow when the world light is parallel to the primary light - shadowValue = 1.0 + (shadowValue - 1.0) * clamp(dot(L, var_PrimaryLightDir.xyz), 0.0, 1.0); - #endif - lightColor = mix(shadowColor, lightColor, shadowValue); + lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; #endif #endif @@ -465,65 +337,39 @@ void main() #if defined(r_materialGamma) diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); + #if !defined(SPECULAR_IS_METALLIC) specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); + #endif #endif float gloss = specular.a; - float shininess = exp2(gloss * 13.0); + float r = exp2(-3.0 * gloss); #if defined(SPECULAR_IS_METALLIC) - // diffuse is actually base color, and red of specular is metallicness - float metallic = specular.r; + // diffuse is actually base color, and green of specular is metallicness + float metallic = specular.g; - specular.rgb = (0.96 * metallic) * diffuse.rgb + vec3(0.04); + specular.rgb = metallic * diffuse.rgb + vec3(0.04 - 0.04 * metallic); diffuse.rgb *= 1.0 - metallic; #else // adjust diffuse by specular reflectance, to maintain energy conservation diffuse.rgb *= vec3(1.0) - specular.rgb; #endif - reflectance = CalcDiffuse(diffuse.rgb, N, L, E, NE, NL, shininess); - - #if defined(r_deluxeSpecular) || defined(USE_LIGHT_VECTOR) - float adjGloss = gloss; - float adjShininess = shininess; - - #if !defined(USE_LIGHT_VECTOR) - adjGloss *= r_deluxeSpecular; - adjShininess = exp2(adjGloss * 13.0); - #endif - - H = normalize(L + E); - + reflectance = CalcDiffuse(diffuse.rgb, EH, NH, r); + #if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE) + // bit of a hack, with modulated shadowmaps, add specular to sunlight + H = normalize(var_PrimaryLightDir.xyz + E); EH = clamp(dot(E, H), 0.0, 1.0); NH = clamp(dot(N, H), 0.0, 1.0); - - #if !defined(USE_LIGHT_VECTOR) - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess) * r_deluxeSpecular; - #else - reflectance += CalcSpecular(specular.rgb, NH, NL, NE, EH, adjGloss, adjShininess); - #endif + reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, r); #endif gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); - -#if 0 - vec3 aSpecular = EnvironmentBRDF(gloss, NE, specular.rgb); - - // do ambient as two hemisphere lights, one straight up one straight down - float hemiDiffuseUp = N.z * 0.5 + 0.5; - float hemiDiffuseDown = 1.0 - hemiDiffuseUp; - float hemiSpecularUp = mix(hemiDiffuseUp, float(N.z >= 0.0), gloss); - float hemiSpecularDown = 1.0 - hemiSpecularUp; - - gl_FragColor.rgb += ambientColor * 0.75 * (diffuse.rgb * hemiDiffuseUp + aSpecular * hemiSpecularUp); - gl_FragColor.rgb += ambientColor * 0.25 * (diffuse.rgb * hemiDiffuseDown + aSpecular * hemiSpecularDown); -#else gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); -#endif #if defined(USE_CUBEMAP) - reflectance = EnvironmentBRDF(gloss, NE, specular.rgb); + reflectance = EnvironmentBRDF(r, NE, specular.rgb); vec3 R = reflect(E, N); @@ -565,8 +411,8 @@ void main() EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcDiffuse(diffuse.rgb, N, L2, E, NE, NL2, shininess); - reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, gloss, shininess); + reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, r); + reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, r); lightColor = u_PrimaryLightColor * var_Color.rgb; diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index f526b8c6..3fcb9350 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1022,9 +1022,6 @@ void GLSL_InitGPUShaders(void) extradefines[0] = '\0'; - if (r_deluxeSpecular->value > 0.000001f) - Q_strcat(extradefines, 1024, va("#define r_deluxeSpecular %f\n", r_deluxeSpecular->value)); - if (r_specularIsMetallic->value) Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); @@ -1067,12 +1064,6 @@ void GLSL_InitGPUShaders(void) { Q_strcat(extradefines, 1024, "#define USE_NORMALMAP\n"); - if (r_normalMapping->integer == 2) - Q_strcat(extradefines, 1024, "#define USE_OREN_NAYAR\n"); - - if (r_normalMapping->integer == 3) - Q_strcat(extradefines, 1024, "#define USE_TRIACE_OREN_NAYAR\n"); - #ifdef USE_VERT_TANGENT_SPACE Q_strcat(extradefines, 1024, "#define USE_VERT_TANGENT_SPACE\n"); attribs |= ATTR_TANGENT; @@ -1087,34 +1078,8 @@ void GLSL_InitGPUShaders(void) } if (r_specularMapping->integer) - { Q_strcat(extradefines, 1024, "#define USE_SPECULARMAP\n"); - switch (r_specularMapping->integer) - { - case 1: - default: - Q_strcat(extradefines, 1024, "#define USE_BLINN\n"); - break; - - case 2: - Q_strcat(extradefines, 1024, "#define USE_BLINN_FRESNEL\n"); - break; - - case 3: - Q_strcat(extradefines, 1024, "#define USE_MCAULEY\n"); - break; - - case 4: - Q_strcat(extradefines, 1024, "#define USE_GOTANDA\n"); - break; - - case 5: - Q_strcat(extradefines, 1024, "#define USE_LAZAROV\n"); - break; - } - } - if (r_cubeMapping->integer) Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); } diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index ea62249a..a5d4c465 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -141,7 +141,6 @@ cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; -cvar_t *r_deluxeSpecular; cvar_t *r_specularIsMetallic; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; @@ -1141,7 +1140,6 @@ void R_Register( void ) r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); - r_deluxeSpecular = ri.Cvar_Get( "r_deluxeSpecular", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 76cbe9c7..02d0887e 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1786,7 +1786,6 @@ extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; -extern cvar_t *r_deluxeSpecular; extern cvar_t *r_specularIsMetallic; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; -- cgit From 3372e9eaf5c21e1e44f000e09a94584231ba9550 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 8 Dec 2015 05:17:05 -0800 Subject: OpenGL2: Add option in code for alternate overbright method. --- src/renderergl2/tr_bsp.c | 10 ++++++++++ src/renderergl2/tr_image.c | 4 ++++ src/renderergl2/tr_local.h | 1 + src/renderergl2/tr_scene.c | 4 ++++ src/renderergl2/tr_shade.c | 23 ++++++++++++++++------- 5 files changed, 35 insertions(+), 7 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index beb07fe3..d1508051 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -102,7 +102,11 @@ static void R_ColorShiftLightingBytes( byte in[4], byte out[4] ) { int shift, r, g, b; // shift the color data based on overbright range +#if defined(USE_OVERBRIGHT) shift = r_mapOverBrightBits->integer - tr.overbrightBits; +#else + shift = 0; +#endif // shift the data based on overbright range r = in[0] << shift; @@ -137,7 +141,9 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale ) { float r, g, b; +#if defined(USE_OVERBRIGHT) scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits); +#endif r = in[0] * scale; g = in[1] * scale; @@ -2756,7 +2762,11 @@ void R_LoadLightGrid( lump_t *l ) { if (hdrLightGrid) { +#if defined(USE_OVERBRIGHT) float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits); +#else + float lightScale = 1.0f; +#endif //ri.Printf(PRINT_ALL, "found!\n"); diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index ef244d56..541b1a38 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2856,7 +2856,11 @@ void R_SetColorMappings( void ) { int inf; // setup the overbright lighting +#if defined(USE_OVERBRIGHT) tr.overbrightBits = r_overBrightBits->integer; +#else + tr.overbrightBits = 0; +#endif // allow 2 overbright bits if ( tr.overbrightBits > 2 ) { diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 02d0887e..a38cf7fc 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -59,6 +59,7 @@ typedef unsigned int glIndex_t; #define CUBE_MAP_SIZE (1 << CUBE_MAP_MIPS) #define USE_VERT_TANGENT_SPACE +#define USE_OVERBRIGHT typedef struct dlight_s { vec3_t origin; diff --git a/src/renderergl2/tr_scene.c b/src/renderergl2/tr_scene.c index 51bb412e..94997a8c 100644 --- a/src/renderergl2/tr_scene.c +++ b/src/renderergl2/tr_scene.c @@ -350,7 +350,11 @@ void RE_BeginScene(const refdef_t *fd) } else { +#if defined(USE_OVERBRIGHT) float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); +#else + float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; +#endif if (r_forceSun->integer) { VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol); diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index 9853313c..e7a73842 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -445,9 +445,22 @@ static void ProjectDlightTexture( void ) { static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor, int blend ) { + qboolean isBlend = ((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_DST_COLOR) + || ((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR) + || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) + || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR); + + qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); + +#if defined(USE_OVERBRIGHT) + float exactLight = 1.0f; +#else + float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer); +#endif + baseColor[0] = baseColor[1] = - baseColor[2] = + baseColor[2] = exactLight; baseColor[3] = 1.0f; vertColor[0] = @@ -474,7 +487,7 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t vertColor[0] = vertColor[1] = - vertColor[2] = + vertColor[2] = exactLight; vertColor[3] = 1.0f; break; case CGEN_CONST: @@ -602,11 +615,7 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t } // multiply color by overbrightbits if this isn't a blend - if (tr.overbrightBits - && !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_DST_COLOR) - && !((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR) - && !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) - && !((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR)) + if (tr.overbrightBits && !isBlend) { float scale = 1 << tr.overbrightBits; -- cgit From e3ac1437c4e4df764cc3279324fab7e3ee032e2a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 8 Dec 2015 21:23:50 -0800 Subject: OpenGL2: Add r_glossIsRoughness. --- src/renderergl2/glsl/lightall_fp.glsl | 44 ++++++++++++++++++------------- src/renderergl2/tr_glsl.c | 3 +++ src/renderergl2/tr_init.c | 2 ++ src/renderergl2/tr_local.h | 1 + src/renderergl2/tr_shade.c | 3 +-- src/renderergl2/tr_shader.c | 49 ++++++++++++++++++++++++++++++----- 6 files changed, 76 insertions(+), 26 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index c0d2bc80..6c8977e1 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -150,11 +150,11 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness) { #if defined(USE_BURLEY) // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf - float fd90 = -0.5 + EH * EH * r; + float fd90 = -0.5 + EH * EH * roughness; float burley = 1.0 + fd90 * 0.04 / NH; burley *= burley; return diffuseAlbedo * burley; @@ -163,21 +163,21 @@ vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float r) #endif } -vec3 EnvironmentBRDF(float r, float NE, vec3 specular) +vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf - float v = 1.0 - max(r, NE); + float v = 1.0 - max(roughness, NE); v *= v * v; return vec3(v) + specular; } -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float r) +vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf - float rr = r*r; + float rr = roughness*roughness; float rrrr = rr*rr; float d = (NH * NH) * (rrrr - 1.0) + 1.0; - float v = (EH * EH) * (r + 0.5); + float v = (EH * EH) * (roughness + 0.5); return specular * (rrrr / (4.0 * d * d * v)); } @@ -276,6 +276,11 @@ void main() attenuation = 1.0; #endif + #if defined(r_lightGamma) + lightColor = pow(lightColor, vec3(r_lightGamma)); + ambientColor = pow(ambientColor, vec3(r_lightGamma)); + #endif + #if defined(USE_NORMALMAP) #if defined(SWIZZLE_NORMALMAP) N.xy = texture2D(u_NormalMap, texCoords).ag - vec2(0.5); @@ -304,11 +309,6 @@ void main() #endif #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - ambientColor = pow(ambientColor, vec3(r_lightGamma)); - #endif - #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); @@ -343,7 +343,11 @@ void main() #endif float gloss = specular.a; - float r = exp2(-3.0 * gloss); + #if defined(GLOSS_IS_ROUGHNESS) + float roughness = gloss; + #else + float roughness = exp2(-3.0 * gloss); + #endif #if defined(SPECULAR_IS_METALLIC) // diffuse is actually base color, and green of specular is metallicness @@ -356,20 +360,20 @@ void main() diffuse.rgb *= vec3(1.0) - specular.rgb; #endif - reflectance = CalcDiffuse(diffuse.rgb, EH, NH, r); + reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness); #if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE) // bit of a hack, with modulated shadowmaps, add specular to sunlight H = normalize(var_PrimaryLightDir.xyz + E); EH = clamp(dot(E, H), 0.0, 1.0); NH = clamp(dot(N, H), 0.0, 1.0); - reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, r); + reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, roughness); #endif gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); #if defined(USE_CUBEMAP) - reflectance = EnvironmentBRDF(r, NE, specular.rgb); + reflectance = EnvironmentBRDF(roughness, NE, specular.rgb); vec3 R = reflect(E, N); @@ -377,7 +381,11 @@ void main() // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; + #if defined(GLOSS_IS_ROUGHNESS) + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, roughness).rgb * u_EnableTextures.w; + #else vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; + #endif // normalize cubemap based on lowest mip (~diffuse) // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation @@ -411,8 +419,8 @@ void main() EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, r); - reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, r); + reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); + reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); lightColor = u_PrimaryLightColor * var_Color.rgb; diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index 3fcb9350..8ce3a4e7 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1025,6 +1025,9 @@ void GLSL_InitGPUShaders(void) if (r_specularIsMetallic->value) Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); + if (r_glossIsRoughness->value) + Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); + if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index a5d4c465..2828270e 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -142,6 +142,7 @@ cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_specularIsMetallic; +cvar_t *r_glossIsRoughness; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; cvar_t *r_baseParallax; @@ -1141,6 +1142,7 @@ void R_Register( void ) r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index a38cf7fc..f69aec19 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1788,6 +1788,7 @@ extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_specularIsMetallic; +extern cvar_t *r_glossIsRoughness; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index e7a73842..f0a6d34b 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -450,11 +450,10 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR); - qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); - #if defined(USE_OVERBRIGHT) float exactLight = 1.0f; #else + qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer); #endif diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index 98e8776e..b4a120ca 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -955,17 +955,23 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) exponent = atof( token ); - // Change shininess to gloss - // FIXME: assumes max exponent of 8192 and min of 1, must change here if altered in lightall_fp.glsl - exponent = CLAMP(exponent, 1.0, 8192.0); - - stage->specularScale[3] = log(exponent) / log(8192.0); + if (r_glossIsRoughness->integer) + stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); + else + { + // Change shininess to gloss + // Assumes max exponent of 8190 and min of 0, must change here if altered in lightall_fp.glsl + exponent = CLAMP(exponent, 0.0f, 8190.0f); + stage->specularScale[3] = (log2f(exponent + 2.0f) - 1.0f) / 12.0f; + } } // // gloss // else if (!Q_stricmp(token, "gloss")) { + float gloss; + token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { @@ -973,7 +979,38 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) continue; } - stage->specularScale[3] = atof( token ); + gloss = atof(token); + + if (r_glossIsRoughness->integer) + stage->specularScale[3] = exp2f(-3.0f * gloss); + else + stage->specularScale[3] = gloss; + } + // + // roughness + // + else if (!Q_stricmp(token, "roughness")) + { + float roughness; + + token = COM_ParseExt(text, qfalse); + if (token[0] == 0) + { + ri.Printf(PRINT_WARNING, "WARNING: missing parameter for roughness in shader '%s'\n", shader.name); + continue; + } + + roughness = atof(token); + + if (r_glossIsRoughness->integer) + stage->specularScale[3] = roughness; + else + { + if (roughness >= 0.125) + stage->specularScale[3] = log2f(1.0f / roughness) / 3.0f; + else + stage->specularScale[3] = 1.0f; + } } // // parallaxDepth -- cgit From 6f6ca6d529e1739565dbc64891fa7f1b478b8460 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 9 Dec 2015 02:00:40 -0800 Subject: OpenGL2: Parse radius entries from misc_cubemap entities. --- src/renderergl2/tr_backend.c | 9 ++++++--- src/renderergl2/tr_bsp.c | 20 +++++++++++++------- src/renderergl2/tr_light.c | 2 +- src/renderergl2/tr_local.h | 9 +++++++-- src/renderergl2/tr_main.c | 2 +- src/renderergl2/tr_shade.c | 9 ++++----- 6 files changed, 32 insertions(+), 19 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 2a61e114..ad43e5b2 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -483,8 +483,9 @@ void RB_BeginDrawingView (void) { // FIXME: hack for cubemap testing if (tr.renderCubeFbo && backEnd.viewParms.targetFbo == tr.renderCubeFbo) { + cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; //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); + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + backEnd.viewParms.targetFboLayer, cubemap->image->texnum, 0); } } } @@ -1312,9 +1313,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); + GL_BindToTMU(cubemap->image, TB_CUBEMAP); qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); GL_SelectTexture(0); } @@ -1725,7 +1728,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 diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index d1508051..d2a5f5f2 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -2997,16 +2997,17 @@ void R_LoadCubemapEntities(char *cubemapEntityName) return; tr.numCubemaps = numCubemaps; - tr.cubemapOrigins = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemapOrigins), h_low); - tr.cubemaps = ri.Hunk_Alloc( tr.numCubemaps * sizeof(*tr.cubemaps), h_low); + tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low); + memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps)); numCubemaps = 0; while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars)) { int i; qboolean isCubemap = qfalse; - qboolean positionSet = qfalse; + qboolean originSet = qfalse; vec3_t origin; + float parallaxRadius = 1000.0f; for (i = 0; i < numSpawnVars; i++) { @@ -3016,14 +3017,19 @@ void R_LoadCubemapEntities(char *cubemapEntityName) if (!Q_stricmp(spawnVars[i][0], "origin")) { sscanf(spawnVars[i][1], "%f %f %f", &origin[0], &origin[1], &origin[2]); - positionSet = qtrue; + originSet = qtrue; + } + else if (!Q_stricmp(spawnVars[i][0], "radius")) + { + sscanf(spawnVars[i][1], "%f", ¶llaxRadius); } } - if (isCubemap && positionSet) + if (isCubemap && originSet) { //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]); - VectorCopy(origin, tr.cubemapOrigins[numCubemaps]); + VectorCopy(origin, tr.cubemaps[numCubemaps].origin); + tr.cubemaps[numCubemaps].parallaxRadius = parallaxRadius; numCubemaps++; } } @@ -3069,7 +3075,7 @@ void R_RenderAllCubemaps(void) for (i = 0; i < tr.numCubemaps; i++) { - tr.cubemaps[i] = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); + tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); } for (i = 0; i < tr.numCubemaps; i++) diff --git a/src/renderergl2/tr_light.c b/src/renderergl2/tr_light.c index 317f4585..7c661dd5 100644 --- a/src/renderergl2/tr_light.c +++ b/src/renderergl2/tr_light.c @@ -472,7 +472,7 @@ int R_CubemapForPoint( vec3_t point ) vec3_t diff; vec_t length; - VectorSubtract(point, tr.cubemapOrigins[i], diff); + VectorSubtract(point, tr.cubemaps[i].origin, diff); length = DotProduct(diff, diff); if (shortest > length) diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index f69aec19..73681f32 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -61,6 +61,12 @@ typedef unsigned int glIndex_t; #define USE_VERT_TANGENT_SPACE #define USE_OVERBRIGHT +typedef struct cubemap_s { + vec3_t origin; + float parallaxRadius; + image_t *image; +} cubemap_t; + typedef struct dlight_s { vec3_t origin; vec3_t color; // range from 0.0 to 1.0, should be color normalized @@ -1561,8 +1567,7 @@ typedef struct { int fatLightmapStep; int numCubemaps; - vec3_t *cubemapOrigins; - image_t **cubemaps; + cubemap_t *cubemaps; trRefEntity_t *currentEntity; trRefEntity_t worldEntity; // point currentEntity at this when rendering world diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 2682d471..14d18755 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -2863,7 +2863,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) memset( &refdef, 0, sizeof( refdef ) ); refdef.rdflags = 0; - VectorCopy(tr.cubemapOrigins[cubemapIndex], refdef.vieworg); + VectorCopy(tr.cubemaps[cubemapIndex].origin, refdef.vieworg); switch(cubemapSide) { diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index f0a6d34b..04b62517 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -1376,15 +1376,14 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) if (!(tr.viewParms.flags & VPF_NOCUBEMAPS) && input->cubemapIndex && r_cubeMapping->integer) { vec4_t vec; + cubemap_t *cubemap = &tr.cubemaps[input->cubemapIndex - 1]; - GL_BindToTMU( tr.cubemaps[input->cubemapIndex - 1], TB_CUBEMAP); + GL_BindToTMU( cubemap->image, TB_CUBEMAP); - vec[0] = tr.cubemapOrigins[input->cubemapIndex - 1][0] - backEnd.viewParms.or.origin[0]; - vec[1] = tr.cubemapOrigins[input->cubemapIndex - 1][1] - backEnd.viewParms.or.origin[1]; - vec[2] = tr.cubemapOrigins[input->cubemapIndex - 1][2] - backEnd.viewParms.or.origin[2]; + VectorSubtract(cubemap->origin, backEnd.viewParms.or.origin, vec); vec[3] = 1.0f; - VectorScale4(vec, 1.0f / 1000.0f, vec); + VectorScale4(vec, 1.0f / cubemap->parallaxRadius, vec); GLSL_SetUniformVec4(sp, UNIFORM_CUBEMAPINFO, vec); } -- cgit From c9cf340a4eb8d81b44e8c02b167b9ab6319167fd Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 9 Dec 2015 03:42:12 -0800 Subject: OpenGL2: Forgot a multiply. --- src/renderergl2/glsl/lightall_fp.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 6c8977e1..9330b1f8 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -382,7 +382,7 @@ void main() vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; #if defined(GLOSS_IS_ROUGHNESS) - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, roughness).rgb * u_EnableTextures.w; + vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; #else vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; #endif -- cgit From 9cdedf11eff894db8f9f572ab52eae37fdacf473 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 9 Dec 2015 05:25:58 -0800 Subject: OpenGL2: Use correct sunlight color for sunlight specular. --- src/renderergl2/glsl/lightall_fp.glsl | 19 ++++++++----------- src/renderergl2/tr_scene.c | 25 ++++++++++--------------- 2 files changed, 18 insertions(+), 26 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 9330b1f8..17dc9fca 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -361,13 +361,6 @@ void main() #endif reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness); - #if defined(USE_SHADOWMAP) && defined(SHADOWMAP_MODULATE) - // bit of a hack, with modulated shadowmaps, add specular to sunlight - H = normalize(var_PrimaryLightDir.xyz + E); - EH = clamp(dot(E, H), 0.0, 1.0); - NH = clamp(dot(N, H), 0.0, 1.0); - reflectance += shadowValue * CalcSpecular(specular.rgb, NH, NL, NE, EH, roughness); - #endif gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); @@ -403,7 +396,7 @@ void main() gl_FragColor.rgb += cubeLightColor * reflectance; #endif - #if defined(USE_PRIMARY_LIGHT) + #if defined(USE_PRIMARY_LIGHT) || defined(SHADOWMAP_MODULATE) vec3 L2, H2; float NL2, EH2, NH2; @@ -419,10 +412,14 @@ void main() EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); - reflectance += CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); + reflectance = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); + + // bit of a hack, with modulated shadowmaps, ignore diffuse + #if !defined(SHADOWMAP_MODULATE) + reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); + #endif - lightColor = u_PrimaryLightColor * var_Color.rgb; + lightColor = u_PrimaryLightColor; #if defined(r_lightGamma) lightColor = pow(lightColor, vec3(r_lightGamma)); diff --git a/src/renderergl2/tr_scene.c b/src/renderergl2/tr_scene.c index 94997a8c..7e326a88 100644 --- a/src/renderergl2/tr_scene.c +++ b/src/renderergl2/tr_scene.c @@ -336,35 +336,30 @@ void RE_BeginScene(const refdef_t *fd) } else { +#if defined(USE_OVERBRIGHT) + float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); +#else + float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; +#endif tr.refdef.colorScale = r_forceSun->integer ? r_forceSunMapLightScale->value : tr.mapLightScale; + if (r_forceSun->integer) + VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol); + else + VectorScale(tr.sunLight, scale, tr.refdef.sunCol); + if (r_sunlightMode->integer == 1) { - tr.refdef.sunCol[0] = - tr.refdef.sunCol[1] = - tr.refdef.sunCol[2] = 1.0f; - tr.refdef.sunAmbCol[0] = tr.refdef.sunAmbCol[1] = tr.refdef.sunAmbCol[2] = r_forceSun->integer ? r_forceSunAmbientScale->value : tr.sunShadowScale; } else { -#if defined(USE_OVERBRIGHT) - float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); -#else - float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; -#endif if (r_forceSun->integer) - { - VectorScale(tr.sunLight, scale * r_forceSunLightScale->value, tr.refdef.sunCol); VectorScale(tr.sunLight, scale * r_forceSunAmbientScale->value, tr.refdef.sunAmbCol); - } else - { - VectorScale(tr.sunLight, scale, tr.refdef.sunCol); VectorScale(tr.sunLight, scale * tr.sunShadowScale, tr.refdef.sunAmbCol); - } } } -- cgit From f77b9694e3d2870f62b27589c70c2cf254248db3 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 15 Dec 2015 03:23:55 -0800 Subject: OpenGL2: Switch to RGTC from LATC for normal maps. Also added a RGTC compressor as a workaround on Intel graphics. --- src/renderergl2/tr_extensions.c | 26 ++++- src/renderergl2/tr_glsl.c | 2 +- src/renderergl2/tr_image.c | 248 ++++++++++++++++++++++++---------------- src/renderergl2/tr_local.h | 4 +- 4 files changed, 173 insertions(+), 107 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_extensions.c b/src/renderergl2/tr_extensions.c index 811b8377..2c1407b2 100644 --- a/src/renderergl2/tr_extensions.c +++ b/src/renderergl2/tr_extensions.c @@ -585,6 +585,22 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + // GL_ARB_texture_compression + extension = "GL_ARB_texture_compression"; + glRefConfig.arbTextureCompression = qfalse; + if (GLimp_HaveExtension(extension)) + { + qglCompressedTexImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage3DARB"); + qglCompressedTexImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage2DARB"); + qglCompressedTexImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexImage1DARB"); + qglCompressedTexSubImage3DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage3DARB"); + qglCompressedTexSubImage2DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage2DARB"); + qglCompressedTexSubImage1DARB = (void *)SDL_GL_GetProcAddress("glCompressedTexSubImage1DARB"); + qglGetCompressedTexImageARB = (void *)SDL_GL_GetProcAddress("glGetCompressedTexImageARB"); + glRefConfig.arbTextureCompression = qtrue; + ri.Printf(PRINT_ALL, result[glRefConfig.arbTextureCompression], extension); + } + // GL_EXT_framebuffer_multisample extension = "GL_EXT_framebuffer_multisample"; glRefConfig.framebufferMultisample = qfalse; @@ -601,12 +617,12 @@ void GLimp_InitExtraExtensions() glRefConfig.textureCompression = TCR_NONE; - // GL_EXT_texture_compression_latc - extension = "GL_EXT_texture_compression_latc"; + // GL_ARB_texture_compression_rgtc + extension = "GL_ARB_texture_compression_rgtc"; if (GLimp_HaveExtension(extension)) { - if (r_ext_compressed_textures->integer) - glRefConfig.textureCompression |= TCR_LATC; + if (r_ext_compressed_textures->integer && glRefConfig.arbTextureCompression) + glRefConfig.textureCompression |= TCR_RGTC; ri.Printf(PRINT_ALL, result[r_ext_compressed_textures->integer ? 1 : 0], extension); } @@ -615,6 +631,8 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + glRefConfig.swizzleNormalmap = r_ext_compressed_textures->integer && !(glRefConfig.textureCompression & TCR_RGTC); + // GL_ARB_texture_compression_bptc extension = "GL_ARB_texture_compression_bptc"; if (GLimp_HaveExtension(extension)) diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index 8ce3a4e7..14e20105 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1031,7 +1031,7 @@ void GLSL_InitGPUShaders(void) if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); - if (1) + if (glRefConfig.swizzleNormalmap) Q_strcat(extradefines, 1024, "#define SWIZZLE_NORMALMAP\n"); if (r_hdr->integer && !glRefConfig.floatLightmap) diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 541b1a38..93ee28e9 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -177,15 +177,20 @@ void R_ImageList_f( void ) { format = "sBPTC"; // 128 bits per 16 pixels, so 1 byte per pixel break; - case GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT: - format = "LATC "; + case GL_COMPRESSED_RG_RGTC2: + format = "RGTC2"; // 128 bits per 16 pixels, so 1 byte per pixel break; - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: format = "DXT1 "; // 64 bits per 16 pixels, so 4 bits per pixel estSize /= 2; break; + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + format = "DXT1a"; + // 64 bits per 16 pixels, so 4 bits per pixel + estSize /= 2; + break; case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: format = "DXT5 "; // 128 bits per 16 pixels, so 1 byte per pixel @@ -1332,41 +1337,6 @@ static void R_MipMapsRGB( byte *in, int inWidth, int inHeight) } -static void R_MipMapLuminanceAlpha (const byte *in, byte *out, int width, int height) -{ - int i, j, row; - - if ( width == 1 && height == 1 ) { - return; - } - - row = width * 4; - width >>= 1; - height >>= 1; - - if ( width == 0 || height == 0 ) { - width += height; // get largest - for (i=0 ; i> 1; - out[3] = (in[3] + in[7]) >> 1; - } - return; - } - - for (i=0 ; i> 2; - out[3] = (in[3] + in[7] + in[row+3] + in[row+7]) >> 2; - } - } - -} - - static void R_MipMapNormalHeight (const byte *in, byte *out, int width, int height, qboolean swizzle) { int i, j; @@ -1657,13 +1627,13 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light if(normalmap) { - if ((!RawImage_HasAlpha(data, numPixels) || (type == IMGTYPE_NORMAL)) && !forceNoCompression && (glRefConfig.textureCompression & TCR_LATC)) - { - internalFormat = GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT; - } - else + if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels)) { - if ( !forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB ) + if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC) + { + internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + } + else if (!forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB) { internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; } @@ -1680,6 +1650,33 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light internalFormat = GL_RGBA; } } + else + { + if (!forceNoCompression && glRefConfig.textureCompression & TCR_RGTC) + { + internalFormat = GL_COMPRESSED_RG_RGTC2; + } + else if (!forceNoCompression && glRefConfig.textureCompression & TCR_BPTC) + { + internalFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + } + else if (!forceNoCompression && glConfig.textureCompression == TC_S3TC_ARB) + { + internalFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + } + else if (r_texturebits->integer == 16) + { + internalFormat = GL_RGB5; + } + else if (r_texturebits->integer == 32) + { + internalFormat = GL_RGB8; + } + else + { + internalFormat = GL_RGB; + } + } } else if(lightMap) { @@ -1775,10 +1772,101 @@ static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean light return internalFormat; } +static void CompressMonoBlock(byte outdata[8], const byte indata[16]) +{ + int hi, lo, diff, bias, outbyte, shift, i; + byte *p = outdata; + + hi = lo = indata[0]; + for (i = 1; i < 16; i++) + { + hi = MAX(indata[i], hi); + lo = MIN(indata[i], lo); + } + + *p++ = hi; + *p++ = lo; + + diff = hi - lo; + + if (diff == 0) + { + outbyte = (hi == 255) ? 255 : 0; + + for (i = 0; i < 6; i++) + *p++ = outbyte; + + return; + } + + bias = diff / 2 - lo * 7; + outbyte = shift = 0; + for (i = 0; i < 16; i++) + { + const byte fixIndex[8] = { 1, 7, 6, 5, 4, 3, 2, 0 }; + byte index = fixIndex[(indata[i] * 7 + bias) / diff]; + + outbyte |= index << shift; + shift += 3; + if (shift >= 8) + { + *p++ = outbyte & 0xff; + shift -= 8; + outbyte >>= 8; + } + } +} + +static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +{ + int wBlocks, hBlocks, y, x, size; + byte *compressedData, *p; + + wBlocks = (width + 3) / 4; + hBlocks = (height + 3) / 4; + size = wBlocks * hBlocks * 16; + + p = compressedData = ri.Hunk_AllocateTempMemory(size); + for (y = 0; y < height; y += 4) + { + int oh = MIN(4, height - y); + + for (x = 0; x < width; x += 4) + { + byte workingData[16]; + int component; + + int ow = MIN(4, width - x); + + for (component = 0; component < 2; component++) + { + int ox, oy; + + for (oy = 0; oy < oh; oy++) + for (ox = 0; ox < ow; ox++) + workingData[oy * 4 + ox] = data[((y + oy) * width + x + ox) * 4 + component]; + + // dupe data to fill + for (oy = 0; oy < 4; oy++) + for (ox = (oy < oh) ? ow : 0; ox < 4; ox++) + workingData[oy * 4 + ox] = workingData[(oy % oh) * 4 + ox % ow]; + + CompressMonoBlock(p, workingData); + p += 8; + } + } + } + + qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + + ri.Hunk_FreeTempMemory(compressedData); +} + static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; + qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); switch(internalFormat) { @@ -1802,7 +1890,12 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei if ( subtexture ) qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); else - qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data ); + { + if (rgtc) + RawImage_UploadToRgtc2Texture(data, width, height, 0); + else + qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + } if (flags & IMGFLAG_MIPMAP) { @@ -1815,14 +1908,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei { if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { - if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - { - R_MipMapLuminanceAlpha( data, data, width, height ); - } - else - { - R_MipMapNormalHeight( data, data, width, height, qtrue); - } + R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); } else { @@ -1849,7 +1935,10 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei } else { - qglTexImage2D (GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data ); + if (rgtc) + RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + else + qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); } } } @@ -1903,25 +1992,11 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } } - // normals are always swizzled - if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) + if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)) { RawImage_SwizzleRA(data, width, height); } - // LATC2 is only used for normals - if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - { - byte *in = data; - int c = width * height; - while (c--) - { - in[0] = in[1]; - in[2] = in[1]; - in += 4; - } - } - // copy or resample data as appropriate for first MIP level if ( ( scaled_width == width ) && ( scaled_height == height ) ) { @@ -1943,14 +2018,7 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) { - if (internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - { - R_MipMapLuminanceAlpha( data, data, width, height ); - } - else - { - R_MipMapNormalHeight( data, data, width, height, qtrue); - } + R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); } else { @@ -2186,26 +2254,11 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h int scaled_width, scaled_height, scaled_x, scaled_y; byte *data = pic; - // normals are always swizzled - if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT) + if (glRefConfig.swizzleNormalmap && (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT)) { RawImage_SwizzleRA(pic, width, height); } - // LATC2 is only used for normals - if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - { - byte *in = data; - int c = width * height; - while (c--) - { - in[0] = in[1]; - in[2] = in[1]; - in += 4; - } - } - - RawImage_ScaleToPower2(&pic, &width, &height, &scaled_width, &scaled_height, image->type, image->flags, &resampledBuffer); scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); @@ -2238,14 +2291,7 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT) { - if (image->internalFormat == GL_COMPRESSED_LUMINANCE_ALPHA_LATC2_EXT) - { - R_MipMapLuminanceAlpha( data, data, width, height ); - } - else - { - R_MipMapNormalHeight( data, data, width, height, qtrue); - } + R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); } else { diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 73681f32..0a1dc5fe 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1381,7 +1381,7 @@ typedef enum { typedef enum { TCR_NONE = 0x0000, - TCR_LATC = 0x0001, + TCR_RGTC = 0x0001, TCR_BPTC = 0x0002, } textureCompressionRef_t; @@ -1405,7 +1405,9 @@ typedef struct { qboolean textureFloat; qboolean halfFloatPixel; qboolean packedDepthStencil; + qboolean arbTextureCompression; textureCompressionRef_t textureCompression; + qboolean swizzleNormalmap; qboolean framebufferMultisample; qboolean framebufferBlit; -- cgit From fad434534de2f0794f84d6d1c13d8ed171b6a3e1 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 16 Dec 2015 07:12:30 -0800 Subject: OpenGL2: Some tr_image.c cleanup. --- src/renderergl2/tr_image.c | 301 ++++++++++++--------------------------------- 1 file changed, 77 insertions(+), 224 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 93ee28e9..7047a0d6 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1452,7 +1452,7 @@ RawImage_ScaleToPower2 =============== */ -static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_height, int *inout_scaled_width, int *inout_scaled_height, imgType_t type, imgFlags_t flags, byte **resampledBuffer) +static qboolean RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_height, imgType_t type, imgFlags_t flags, byte **resampledBuffer) { int width = *inout_width; int height = *inout_height; @@ -1461,6 +1461,7 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he qboolean picmip = flags & IMGFLAG_PICMIP; qboolean mipmap = flags & IMGFLAG_MIPMAP; qboolean clampToEdge = flags & IMGFLAG_CLAMPTOEDGE; + qboolean notScaled; // // convert to exact power of 2 sizes @@ -1507,22 +1508,9 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he *resampledBuffer = ri.Hunk_AllocateTempMemory( finalwidth * finalheight * 4 ); if (scaled_width != width || scaled_height != height) - { ResampleTexture (*data, width, height, *resampledBuffer, scaled_width, scaled_height); - } else - { - byte *inbyte, *outbyte; - int i; - - inbyte = *data; - outbyte = *resampledBuffer; - - for (i = width * height * 4; i > 0; i--) - { - *outbyte++ = *inbyte++; - } - } + Com_Memcpy(*resampledBuffer, *data, width * height * 4); if (type == IMGTYPE_COLORALPHA) RGBAtoYCoCgA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height); @@ -1536,34 +1524,29 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he } if (type == IMGTYPE_COLORALPHA) - { YCoCgAtoRGBA(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height); - } else if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - { FillInNormalizedZ(*resampledBuffer, *resampledBuffer, scaled_width, scaled_height); - } - //endTime = ri.Milliseconds(); //ri.Printf(PRINT_ALL, "upsampled %dx%d to %dx%d in %dms\n", width, height, scaled_width, scaled_height, endTime - startTime); *data = *resampledBuffer; - width = scaled_width; - height = scaled_height; } - else if ( scaled_width != width || scaled_height != height ) { + else if ( scaled_width != width || scaled_height != height ) + { if (data && resampledBuffer) { *resampledBuffer = ri.Hunk_AllocateTempMemory( scaled_width * scaled_height * 4 ); ResampleTexture (*data, width, height, *resampledBuffer, scaled_width, scaled_height); *data = *resampledBuffer; } - width = scaled_width; - height = scaled_height; } + width = scaled_width; + height = scaled_height; + // // perform optional picmip operation // @@ -1572,16 +1555,6 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he scaled_height >>= r_picmip->integer; } - // - // clamp to minimum size - // - if (scaled_width < 1) { - scaled_width = 1; - } - if (scaled_height < 1) { - scaled_height = 1; - } - // // clamp to the current upper OpenGL limit // scale both axis down equally so we don't have to @@ -1593,10 +1566,35 @@ static void RawImage_ScaleToPower2( byte **data, int *inout_width, int *inout_he scaled_height >>= 1; } - *inout_width = width; - *inout_height = height; - *inout_scaled_width = scaled_width; - *inout_scaled_height = scaled_height; + // + // clamp to minimum size + // + scaled_width = MAX(1, scaled_width); + scaled_height = MAX(1, scaled_height); + + notScaled = (width == scaled_width) && (height == scaled_height); + + // + // rescale texture to new size using existing mipmap functions + // + if (data) + { + while (width > scaled_width || height > scaled_height) + { + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) + R_MipMapNormalHeight(*data, *data, width, height, qfalse); + else + R_MipMapsRGB(*data, width, height); + + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + } + } + + *inout_width = width; + *inout_height = height; + + return notScaled; } @@ -1951,23 +1949,30 @@ Upload32 =============== */ -static void Upload32( byte *data, int width, int height, imgType_t type, imgFlags_t flags, - qboolean lightMap, GLenum internalFormat, int *pUploadWidth, int *pUploadHeight) +static void Upload32(byte *data, int x, int y, int width, int height, image_t *image) { - byte *scaledBuffer = NULL; byte *resampledBuffer = NULL; - int scaled_width, scaled_height; int i, c; byte *scan; - RawImage_ScaleToPower2(&data, &width, &height, &scaled_width, &scaled_height, type, flags, &resampledBuffer); + imgType_t type = image->type; + imgFlags_t flags = image->flags; + GLenum internalFormat = image->internalFormat; + qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height); + qboolean notScaled = qtrue; + qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); - scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + if (!data) + { + RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); + RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse); + goto done; + } + else if (!subtexture) + { + notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); + } - // - // scan the texture for each channel's max values - // and verify if the alpha channel is being used or not - // c = width*height; scan = data; @@ -1993,100 +1998,28 @@ static void Upload32( byte *data, int width, int height, imgType_t type, imgFlag } if (glRefConfig.swizzleNormalmap && (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT)) - { RawImage_SwizzleRA(data, width, height); - } - // copy or resample data as appropriate for first MIP level - if ( ( scaled_width == width ) && - ( scaled_height == height ) ) { - if (!(flags & IMGFLAG_MIPMAP)) - { - RawImage_UploadTexture( data, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse ); - //qglTexImage2D (GL_TEXTURE_2D, 0, internalFormat, scaled_width, scaled_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, data); - *pUploadWidth = scaled_width; - *pUploadHeight = scaled_height; + // This corresponds to what the OpenGL1 renderer does + if (!(flags & IMGFLAG_NOLIGHTSCALE) && (!notScaled || mipmap)) + R_LightScaleTexture(data, width, height, !mipmap); - goto done; - } - Com_Memcpy (scaledBuffer, data, width*height*4); - } - else + if (subtexture) { - // use the normal mip-mapping function to go down from here - while ( width > scaled_width || height > scaled_height ) { - - if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - { - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } - else - { - R_MipMapsRGB( data, width, height ); - } - - width >>= 1; - height >>= 1; - if ( width < 1 ) { - width = 1; - } - if ( height < 1 ) { - height = 1; - } - } - Com_Memcpy( scaledBuffer, data, width * height * 4 ); + // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped + RawImage_UploadTexture(data, x, y, width, height, internalFormat, type, flags, qtrue); + GL_CheckErrors(); + return; } - if (!(flags & IMGFLAG_NOLIGHTSCALE)) - R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !(flags & IMGFLAG_MIPMAP) ); - - *pUploadWidth = scaled_width; - *pUploadHeight = scaled_height; - - RawImage_UploadTexture(scaledBuffer, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(data, 0, 0, width, height, internalFormat, type, flags, qfalse); done: - if (flags & IMGFLAG_MIPMAP) - { - if ( glConfig.textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) ); + image->uploadWidth = width; + image->uploadHeight = height; - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); - } - else - { - if ( glConfig.textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); - - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - } - - GL_CheckErrors(); - - if ( scaledBuffer != 0 ) - ri.Hunk_FreeTempMemory( scaledBuffer ); - if ( resampledBuffer != 0 ) - ri.Hunk_FreeTempMemory( resampledBuffer ); -} - - -static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flags, - qboolean lightMap, GLenum internalFormat, int *pUploadWidth, int *pUploadHeight ) -{ - int scaled_width, scaled_height; - - RawImage_ScaleToPower2(NULL, &width, &height, &scaled_width, &scaled_height, type, flags, NULL); - - *pUploadWidth = scaled_width; - *pUploadHeight = scaled_height; - - RawImage_UploadTexture(NULL, 0, 0, scaled_width, scaled_height, internalFormat, type, flags, qfalse); - - if (flags & IMGFLAG_MIPMAP) + if (mipmap) { if ( glConfig.textureFilterAnisotropic ) qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, @@ -2121,6 +2054,9 @@ static void EmptyTexture( int width, int height, imgType_t type, imgFlags_t flag } GL_CheckErrors(); + + if ( resampledBuffer != NULL ) + ri.Hunk_FreeTempMemory( resampledBuffer ); } @@ -2186,9 +2122,10 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT GL_SelectTexture( image->TMU ); } + GL_Bind(image); + if (image->flags & IMGFLAG_CUBEMAP) { - GL_Bind(image); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); @@ -2219,20 +2156,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT } else { - GL_Bind(image); - - if (pic) - { - Upload32( pic, image->width, image->height, image->type, image->flags, - isLightmap, image->internalFormat, &image->uploadWidth, - &image->uploadHeight ); - } - else - { - EmptyTexture(image->width, image->height, image->type, image->flags, - isLightmap, image->internalFormat, &image->uploadWidth, - &image->uploadHeight ); - } + Upload32( pic, 0, 0, image->width, image->height, image ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); @@ -2249,86 +2173,15 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { - byte *scaledBuffer = NULL; - byte *resampledBuffer = NULL; - int scaled_width, scaled_height, scaled_x, scaled_y; - byte *data = pic; - - if (glRefConfig.swizzleNormalmap && (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT)) - { - RawImage_SwizzleRA(pic, width, height); + if (qglActiveTextureARB) { + GL_SelectTexture(image->TMU); } - RawImage_ScaleToPower2(&pic, &width, &height, &scaled_width, &scaled_height, image->type, image->flags, &resampledBuffer); + GL_Bind(image); - scaledBuffer = ri.Hunk_AllocateTempMemory( sizeof( unsigned ) * scaled_width * scaled_height ); + Upload32(pic, x, y, width, height, image); - if ( qglActiveTextureARB ) { - GL_SelectTexture( image->TMU ); - } - - GL_Bind(image); - - // copy or resample data as appropriate for first MIP level - if ( ( scaled_width == width ) && - ( scaled_height == height ) ) { - if (!(image->flags & IMGFLAG_MIPMAP)) - { - scaled_x = x * scaled_width / width; - scaled_y = y * scaled_height / height; - RawImage_UploadTexture( data, scaled_x, scaled_y, scaled_width, scaled_height, image->internalFormat, image->type, image->flags, qtrue ); - //qglTexSubImage2D( GL_TEXTURE_2D, 0, scaled_x, scaled_y, scaled_width, scaled_height, GL_RGBA, GL_UNSIGNED_BYTE, data ); - - GL_CheckErrors(); - goto done; - } - Com_Memcpy (scaledBuffer, data, width*height*4); - } - else - { - // use the normal mip-mapping function to go down from here - while ( width > scaled_width || height > scaled_height ) { - - if (image->type == IMGTYPE_NORMAL || image->type == IMGTYPE_NORMALHEIGHT) - { - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } - else - { - R_MipMapsRGB( data, width, height ); - } - - width >>= 1; - height >>= 1; - x >>= 1; - y >>= 1; - if ( width < 1 ) { - width = 1; - } - if ( height < 1 ) { - height = 1; - } - } - Com_Memcpy( scaledBuffer, data, width * height * 4 ); - } - - if (!(image->flags & IMGFLAG_NOLIGHTSCALE)) - R_LightScaleTexture (scaledBuffer, scaled_width, scaled_height, !(image->flags & IMGFLAG_MIPMAP) ); - - scaled_x = x * scaled_width / width; - scaled_y = y * scaled_height / height; - RawImage_UploadTexture( (byte *)data, scaled_x, scaled_y, scaled_width, scaled_height, image->internalFormat, image->type, image->flags, qtrue ); - -done: - - GL_SelectTexture( 0 ); - - GL_CheckErrors(); - - if ( scaledBuffer != 0 ) - ri.Hunk_FreeTempMemory( scaledBuffer ); - if ( resampledBuffer != 0 ) - ri.Hunk_FreeTempMemory( resampledBuffer ); + GL_SelectTexture(0); } //=================================================================== -- cgit From 342a3bd68085cdc11f3167253492043459ee9910 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 18 Dec 2015 06:53:20 -0800 Subject: OpenGL2: DDS (compressed textures) support. --- src/renderergl2/tr_image.c | 130 ++++++++++-- src/renderergl2/tr_image_dds.c | 448 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 563 insertions(+), 15 deletions(-) create mode 100644 src/renderergl2/tr_image_dds.c (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 7047a0d6..c35af4c2 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1616,13 +1616,16 @@ static qboolean RawImage_HasAlpha(const byte *scan, int numPixels) return qfalse; } -static GLenum RawImage_GetFormat(const byte *data, int numPixels, qboolean lightMap, imgType_t type, imgFlags_t flags) +static GLenum RawImage_GetFormat(const byte *data, int numPixels, GLenum picFormat, qboolean lightMap, imgType_t type, imgFlags_t flags) { int samples = 3; GLenum internalFormat = GL_RGB; qboolean forceNoCompression = (flags & IMGFLAG_NO_COMPRESSION); qboolean normalmap = (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT); + if (picFormat != GL_RGBA8) + return picFormat; + if(normalmap) { if ((type == IMGTYPE_NORMALHEIGHT) && RawImage_HasAlpha(data, numPixels)) @@ -1861,11 +1864,67 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + { + int bytesPer4x4Block = 0; + int miplevel = 0; + + switch (picFormat) + { + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + bytesPer4x4Block = 8; + break; + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + bytesPer4x4Block = 16; + break; + default: + ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); + return; + break; + } + + for (miplevel = 0; miplevel < numMips; miplevel++) + { + int size; + + size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + + if (subtexture) + qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); + else + qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + + x >>= 1; + y >>= 1; + x -= x % 4; + y -= y % 4; + + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + data += size; + } + + return; + } + switch(internalFormat) { case GL_DEPTH_COMPONENT: @@ -1949,7 +2008,7 @@ Upload32 =============== */ -static void Upload32(byte *data, int x, int y, int width, int height, image_t *image) +static void Upload32(byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, image_t *image) { byte *resampledBuffer = NULL; int i, c; @@ -1965,11 +2024,16 @@ static void Upload32(byte *data, int x, int y, int width, int height, image_t *i if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { + if (picFormat != GL_RGBA8) + { + RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + goto done; + } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); } @@ -2007,12 +2071,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, image_t *i if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2062,12 +2126,12 @@ done: /* ================ -R_CreateImage +R_CreateImage2 This is the only way any image_t are created ================ */ -image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat ) { +image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLenum picFormat, int numMips, imgType_t type, imgFlags_t flags, int internalFormat ) { image_t *image; qboolean isLightmap = qfalse; long hash; @@ -2105,7 +2169,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT if (image->flags & IMGFLAG_CUBEMAP) internalFormat = GL_RGBA8; else - internalFormat = RawImage_GetFormat(pic, width * height, isLightmap, image->type, image->flags); + internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); } image->internalFormat = internalFormat; @@ -2156,7 +2220,7 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT } else { - Upload32( pic, 0, 0, image->width, image->height, image ); + Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); @@ -2171,6 +2235,20 @@ image_t *R_CreateImage( const char *name, byte *pic, int width, int height, imgT return image; } + +/* +================ +R_CreateImage + +Wrapper for R_CreateImage2(), for the old parameters. +================ +*/ +image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgType_t type, imgFlags_t flags, int internalFormat) +{ + return R_CreateImage2(name, pic, width, height, GL_RGBA8, 0, type, flags, internalFormat); +} + + void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { if (qglActiveTextureARB) { @@ -2179,13 +2257,16 @@ void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int h GL_Bind(image); - Upload32(pic, x, y, width, height, image); + Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); GL_SelectTexture(0); } //=================================================================== +// Prototype for dds loader function which isn't common to both renderers +void R_LoadDDS(const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips); + typedef struct { char *ext; @@ -2214,7 +2295,7 @@ Loads any of the supported image types into a cannonical 32 bit format. ================= */ -void R_LoadImage( const char *name, byte **pic, int *width, int *height ) +void R_LoadImage( const char *name, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips ) { qboolean orgNameFailed = qfalse; int orgLoader = -1; @@ -2226,11 +2307,28 @@ void R_LoadImage( const char *name, byte **pic, int *width, int *height ) *pic = NULL; *width = 0; *height = 0; + *picFormat = GL_RGBA8; + *numMips = 0; Q_strncpyz( localName, name, MAX_QPATH ); ext = COM_GetExtension( localName ); + // If compressed textures are enabled, try loading a DDS first, it'll load fastest + if (r_ext_compressed_textures->integer) + { + char ddsName[MAX_QPATH]; + + COM_StripExtension(name, ddsName, MAX_QPATH); + Q_strcat(ddsName, MAX_QPATH, ".dds"); + + R_LoadDDS(ddsName, pic, width, height, picFormat, numMips); + + // If loaded, we're done. + if (*pic) + return; + } + if( *ext ) { // Look for the correct loader and use it @@ -2302,6 +2400,8 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) image_t *image; int width, height; byte *pic; + GLenum picFormat; + int picNumMips; long hash; if (!name) { @@ -2328,12 +2428,12 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) // // load the pic from disk // - R_LoadImage( name, &pic, &width, &height ); + R_LoadImage( name, &pic, &width, &height, &picFormat, &picNumMips ); if ( pic == NULL ) { return NULL; } - if (r_normalMapping->integer && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP)) + if (r_normalMapping->integer && (picFormat == GL_RGBA8) && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP)) { char normalName[MAX_QPATH]; image_t *normalImage; @@ -2436,7 +2536,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) } } - image = R_CreateImage( ( char * ) name, pic, width, height, type, flags, 0 ); + image = R_CreateImage2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0 ); ri.Free( pic ); return image; } diff --git a/src/renderergl2/tr_image_dds.c b/src/renderergl2/tr_image_dds.c new file mode 100644 index 00000000..578b3eda --- /dev/null +++ b/src/renderergl2/tr_image_dds.c @@ -0,0 +1,448 @@ +/* +=========================================================================== +Copyright (C) 1999-2005 Id Software, Inc. + 2015 James Canete + +This file is part of Quake III Arena source code. + +Quake III Arena 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. + +Quake III Arena 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 Quake III Arena source code; if not, write to the Free Software +Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA +=========================================================================== +*/ + +#include "../renderercommon/tr_common.h" + +typedef unsigned int ui32_t; + +typedef struct ddsHeader_s +{ + ui32_t headerSize; + ui32_t flags; + ui32_t height; + ui32_t width; + ui32_t pitchOrFirstMipSize; + ui32_t volumeDepth; + ui32_t numMips; + ui32_t reserved1[11]; + ui32_t always_0x00000020; + ui32_t pixelFormatFlags; + ui32_t fourCC; + ui32_t rgbBitCount; + ui32_t rBitMask; + ui32_t gBitMask; + ui32_t bBitMask; + ui32_t aBitMask; + ui32_t caps; + ui32_t caps2; + ui32_t caps3; + ui32_t caps4; + ui32_t reserved2; +} +ddsHeader_t; + +// flags: +#define _DDSFLAGS_REQUIRED 0x001007 +#define _DDSFLAGS_PITCH 0x8 +#define _DDSFLAGS_MIPMAPCOUNT 0x20000 +#define _DDSFLAGS_FIRSTMIPSIZE 0x80000 +#define _DDSFLAGS_VOLUMEDEPTH 0x800000 + +// pixelFormatFlags: +#define DDSPF_ALPHAPIXELS 0x1 +#define DDSPF_ALPHA 0x2 +#define DDSPF_FOURCC 0x4 +#define DDSPF_RGB 0x40 +#define DDSPF_YUV 0x200 +#define DDSPF_LUMINANCE 0x20000 + +// caps: +#define DDSCAPS_COMPLEX 0x8 +#define DDSCAPS_MIPMAP 0x400000 +#define DDSCAPS_REQUIRED 0x1000 + +// caps2: +#define DDSCAPS2_CUBEMAP 0xFE00 +#define DDSCAPS2_VOLUME 0x200000 + +typedef struct ddsHeaderDxt10_s +{ + ui32_t dxgiFormat; + ui32_t dimensions; + ui32_t miscFlags; + ui32_t arraySize; + ui32_t miscFlags2; +} +ddsHeaderDxt10_t; + +// dxgiFormat +// from http://msdn.microsoft.com/en-us/library/windows/desktop/bb173059%28v=vs.85%29.aspx +typedef enum DXGI_FORMAT { + DXGI_FORMAT_UNKNOWN = 0, + DXGI_FORMAT_R32G32B32A32_TYPELESS = 1, + DXGI_FORMAT_R32G32B32A32_FLOAT = 2, + DXGI_FORMAT_R32G32B32A32_UINT = 3, + DXGI_FORMAT_R32G32B32A32_SINT = 4, + DXGI_FORMAT_R32G32B32_TYPELESS = 5, + DXGI_FORMAT_R32G32B32_FLOAT = 6, + DXGI_FORMAT_R32G32B32_UINT = 7, + DXGI_FORMAT_R32G32B32_SINT = 8, + DXGI_FORMAT_R16G16B16A16_TYPELESS = 9, + DXGI_FORMAT_R16G16B16A16_FLOAT = 10, + DXGI_FORMAT_R16G16B16A16_UNORM = 11, + DXGI_FORMAT_R16G16B16A16_UINT = 12, + DXGI_FORMAT_R16G16B16A16_SNORM = 13, + DXGI_FORMAT_R16G16B16A16_SINT = 14, + DXGI_FORMAT_R32G32_TYPELESS = 15, + DXGI_FORMAT_R32G32_FLOAT = 16, + DXGI_FORMAT_R32G32_UINT = 17, + DXGI_FORMAT_R32G32_SINT = 18, + DXGI_FORMAT_R32G8X24_TYPELESS = 19, + DXGI_FORMAT_D32_FLOAT_S8X24_UINT = 20, + DXGI_FORMAT_R32_FLOAT_X8X24_TYPELESS = 21, + DXGI_FORMAT_X32_TYPELESS_G8X24_UINT = 22, + DXGI_FORMAT_R10G10B10A2_TYPELESS = 23, + DXGI_FORMAT_R10G10B10A2_UNORM = 24, + DXGI_FORMAT_R10G10B10A2_UINT = 25, + DXGI_FORMAT_R11G11B10_FLOAT = 26, + DXGI_FORMAT_R8G8B8A8_TYPELESS = 27, + DXGI_FORMAT_R8G8B8A8_UNORM = 28, + DXGI_FORMAT_R8G8B8A8_UNORM_SRGB = 29, + DXGI_FORMAT_R8G8B8A8_UINT = 30, + DXGI_FORMAT_R8G8B8A8_SNORM = 31, + DXGI_FORMAT_R8G8B8A8_SINT = 32, + DXGI_FORMAT_R16G16_TYPELESS = 33, + DXGI_FORMAT_R16G16_FLOAT = 34, + DXGI_FORMAT_R16G16_UNORM = 35, + DXGI_FORMAT_R16G16_UINT = 36, + DXGI_FORMAT_R16G16_SNORM = 37, + DXGI_FORMAT_R16G16_SINT = 38, + DXGI_FORMAT_R32_TYPELESS = 39, + DXGI_FORMAT_D32_FLOAT = 40, + DXGI_FORMAT_R32_FLOAT = 41, + DXGI_FORMAT_R32_UINT = 42, + DXGI_FORMAT_R32_SINT = 43, + DXGI_FORMAT_R24G8_TYPELESS = 44, + DXGI_FORMAT_D24_UNORM_S8_UINT = 45, + DXGI_FORMAT_R24_UNORM_X8_TYPELESS = 46, + DXGI_FORMAT_X24_TYPELESS_G8_UINT = 47, + DXGI_FORMAT_R8G8_TYPELESS = 48, + DXGI_FORMAT_R8G8_UNORM = 49, + DXGI_FORMAT_R8G8_UINT = 50, + DXGI_FORMAT_R8G8_SNORM = 51, + DXGI_FORMAT_R8G8_SINT = 52, + DXGI_FORMAT_R16_TYPELESS = 53, + DXGI_FORMAT_R16_FLOAT = 54, + DXGI_FORMAT_D16_UNORM = 55, + DXGI_FORMAT_R16_UNORM = 56, + DXGI_FORMAT_R16_UINT = 57, + DXGI_FORMAT_R16_SNORM = 58, + DXGI_FORMAT_R16_SINT = 59, + DXGI_FORMAT_R8_TYPELESS = 60, + DXGI_FORMAT_R8_UNORM = 61, + DXGI_FORMAT_R8_UINT = 62, + DXGI_FORMAT_R8_SNORM = 63, + DXGI_FORMAT_R8_SINT = 64, + DXGI_FORMAT_A8_UNORM = 65, + DXGI_FORMAT_R1_UNORM = 66, + DXGI_FORMAT_R9G9B9E5_SHAREDEXP = 67, + DXGI_FORMAT_R8G8_B8G8_UNORM = 68, + DXGI_FORMAT_G8R8_G8B8_UNORM = 69, + DXGI_FORMAT_BC1_TYPELESS = 70, + DXGI_FORMAT_BC1_UNORM = 71, + DXGI_FORMAT_BC1_UNORM_SRGB = 72, + DXGI_FORMAT_BC2_TYPELESS = 73, + DXGI_FORMAT_BC2_UNORM = 74, + DXGI_FORMAT_BC2_UNORM_SRGB = 75, + DXGI_FORMAT_BC3_TYPELESS = 76, + DXGI_FORMAT_BC3_UNORM = 77, + DXGI_FORMAT_BC3_UNORM_SRGB = 78, + DXGI_FORMAT_BC4_TYPELESS = 79, + DXGI_FORMAT_BC4_UNORM = 80, + DXGI_FORMAT_BC4_SNORM = 81, + DXGI_FORMAT_BC5_TYPELESS = 82, + DXGI_FORMAT_BC5_UNORM = 83, + DXGI_FORMAT_BC5_SNORM = 84, + DXGI_FORMAT_B5G6R5_UNORM = 85, + DXGI_FORMAT_B5G5R5A1_UNORM = 86, + DXGI_FORMAT_B8G8R8A8_UNORM = 87, + DXGI_FORMAT_B8G8R8X8_UNORM = 88, + DXGI_FORMAT_R10G10B10_XR_BIAS_A2_UNORM = 89, + DXGI_FORMAT_B8G8R8A8_TYPELESS = 90, + DXGI_FORMAT_B8G8R8A8_UNORM_SRGB = 91, + DXGI_FORMAT_B8G8R8X8_TYPELESS = 92, + DXGI_FORMAT_B8G8R8X8_UNORM_SRGB = 93, + DXGI_FORMAT_BC6H_TYPELESS = 94, + DXGI_FORMAT_BC6H_UF16 = 95, + DXGI_FORMAT_BC6H_SF16 = 96, + DXGI_FORMAT_BC7_TYPELESS = 97, + DXGI_FORMAT_BC7_UNORM = 98, + DXGI_FORMAT_BC7_UNORM_SRGB = 99, + DXGI_FORMAT_AYUV = 100, + DXGI_FORMAT_Y410 = 101, + DXGI_FORMAT_Y416 = 102, + DXGI_FORMAT_NV12 = 103, + DXGI_FORMAT_P010 = 104, + DXGI_FORMAT_P016 = 105, + DXGI_FORMAT_420_OPAQUE = 106, + DXGI_FORMAT_YUY2 = 107, + DXGI_FORMAT_Y210 = 108, + DXGI_FORMAT_Y216 = 109, + DXGI_FORMAT_NV11 = 110, + DXGI_FORMAT_AI44 = 111, + DXGI_FORMAT_IA44 = 112, + DXGI_FORMAT_P8 = 113, + DXGI_FORMAT_A8P8 = 114, + DXGI_FORMAT_B4G4R4A4_UNORM = 115, + DXGI_FORMAT_FORCE_UINT = 0xffffffffUL +} DXGI_FORMAT; + +#define EncodeFourCC(x) ((((ui32_t)((x)[0])) ) | \ + (((ui32_t)((x)[1])) << 8 ) | \ + (((ui32_t)((x)[2])) << 16) | \ + (((ui32_t)((x)[3])) << 24) ) + + +void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLenum *picFormat, int *numMips ) +{ + union { + byte *b; + void *v; + } buffer; + int len; + ddsHeader_t *ddsHeader = NULL; + ddsHeaderDxt10_t *ddsHeaderDxt10 = NULL; + byte *data; + + if (!picFormat) + { + ri.Printf(PRINT_ERROR, "R_LoadDDS() called without picFormat parameter!"); + return; + } + + if (width) + *width = 0; + if (height) + *height = 0; + if (picFormat) + *picFormat = GL_RGBA8; + if (numMips) + *numMips = 1; + + *pic = NULL; + + // + // load the file + // + len = ri.FS_ReadFile( ( char * ) filename, &buffer.v); + if (!buffer.b || len < 0) { + return; + } + + // + // reject files that are too small to hold even a header + // + if (len < 4 + sizeof(*ddsHeader)) + { + ri.Printf(PRINT_ALL, "File %s is too small to be a DDS file.\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + // + // reject files that don't start with "DDS " + // + if (*((ui32_t *)(buffer.b)) != EncodeFourCC("DDS ")) + { + ri.Printf(PRINT_ALL, "File %s is not a DDS file.\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + // + // parse header and dx10 header if available + // + ddsHeader = (ddsHeader_t *)(buffer.b + 4); + if ((ddsHeader->pixelFormatFlags & DDSPF_FOURCC) && ddsHeader->fourCC == EncodeFourCC("DX10")) + { + if (len < 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10)) + { + ri.Printf(PRINT_ALL, "File %s indicates a DX10 header it is too small to contain.\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + ddsHeaderDxt10 = (ddsHeaderDxt10_t *)(buffer.b + 4 + sizeof(ddsHeader_t)); + data = buffer.b + 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10); + len -= 4 + sizeof(*ddsHeader) + sizeof(*ddsHeaderDxt10); + } + else + { + data = buffer.b + 4 + sizeof(*ddsHeader); + len -= 4 + sizeof(*ddsHeader); + } + + *width = ddsHeader->width; + *height = ddsHeader->height; + + if (ddsHeader->flags & _DDSFLAGS_MIPMAPCOUNT) + *numMips = ddsHeader->numMips; + else + *numMips = 1; + + // FIXME: handle cube map + //if ((ddsHeader->caps2 & DDSCAPS2_CUBEMAP) == DDSCAPS2_CUBEMAP) + + // + // Convert DXGI format/FourCC into OpenGL format + // + if (ddsHeaderDxt10) + { + switch (ddsHeaderDxt10->dxgiFormat) + { + case DXGI_FORMAT_BC1_TYPELESS: + case DXGI_FORMAT_BC1_UNORM: + // FIXME: check for GL_COMPRESSED_RGBA_S3TC_DXT1_EXT + *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + break; + + case DXGI_FORMAT_BC1_UNORM_SRGB: + // FIXME: check for GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT + *picFormat = GL_COMPRESSED_SRGB_S3TC_DXT1_EXT; + break; + + case DXGI_FORMAT_BC2_TYPELESS: + case DXGI_FORMAT_BC2_UNORM: + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + break; + + case DXGI_FORMAT_BC2_UNORM_SRGB: + *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT; + break; + + case DXGI_FORMAT_BC3_TYPELESS: + case DXGI_FORMAT_BC3_UNORM: + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + break; + + case DXGI_FORMAT_BC3_UNORM_SRGB: + *picFormat = GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT; + break; + + case DXGI_FORMAT_BC4_TYPELESS: + case DXGI_FORMAT_BC4_UNORM: + *picFormat = GL_COMPRESSED_RED_RGTC1; + break; + + case DXGI_FORMAT_BC4_SNORM: + *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1; + break; + + case DXGI_FORMAT_BC5_TYPELESS: + case DXGI_FORMAT_BC5_UNORM: + *picFormat = GL_COMPRESSED_RG_RGTC2; + break; + + case DXGI_FORMAT_BC5_SNORM: + *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2; + break; + + case DXGI_FORMAT_BC6H_TYPELESS: + case DXGI_FORMAT_BC6H_UF16: + *picFormat = GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB; + break; + + case DXGI_FORMAT_BC6H_SF16: + *picFormat = GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB; + break; + + case DXGI_FORMAT_BC7_TYPELESS: + case DXGI_FORMAT_BC7_UNORM: + *picFormat = GL_COMPRESSED_RGBA_BPTC_UNORM_ARB; + break; + + case DXGI_FORMAT_BC7_UNORM_SRGB: + *picFormat = GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB; + break; + + case DXGI_FORMAT_R8G8B8A8_UNORM_SRGB: + *picFormat = GL_SRGB8_ALPHA8_EXT; + break; + + case DXGI_FORMAT_R8G8B8A8_UNORM: + case DXGI_FORMAT_R8G8B8A8_SNORM: + *picFormat = GL_RGBA8; + break; + + default: + ri.Printf(PRINT_ALL, "DDS File %s has unsupported DXGI format %d.", filename, ddsHeaderDxt10->dxgiFormat); + ri.FS_FreeFile(buffer.v); + return; + break; + } + } + else + { + if (ddsHeader->pixelFormatFlags & DDSPF_FOURCC) + { + if (ddsHeader->fourCC == EncodeFourCC("DXT1")) + *picFormat = GL_COMPRESSED_RGB_S3TC_DXT1_EXT; + else if (ddsHeader->fourCC == EncodeFourCC("DXT2")) + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + else if (ddsHeader->fourCC == EncodeFourCC("DXT3")) + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT3_EXT; + else if (ddsHeader->fourCC == EncodeFourCC("DXT4")) + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + else if (ddsHeader->fourCC == EncodeFourCC("DXT5")) + *picFormat = GL_COMPRESSED_RGBA_S3TC_DXT5_EXT; + else if (ddsHeader->fourCC == EncodeFourCC("ATI1")) + *picFormat = GL_COMPRESSED_RED_RGTC1; + else if (ddsHeader->fourCC == EncodeFourCC("BC4U")) + *picFormat = GL_COMPRESSED_RED_RGTC1; + else if (ddsHeader->fourCC == EncodeFourCC("BC4S")) + *picFormat = GL_COMPRESSED_SIGNED_RED_RGTC1; + else if (ddsHeader->fourCC == EncodeFourCC("ATI2")) + *picFormat = GL_COMPRESSED_RG_RGTC2; + else if (ddsHeader->fourCC == EncodeFourCC("BC5U")) + *picFormat = GL_COMPRESSED_RG_RGTC2; + else if (ddsHeader->fourCC == EncodeFourCC("BC5S")) + *picFormat = GL_COMPRESSED_SIGNED_RG_RGTC2; + else + { + ri.Printf(PRINT_ALL, "DDS File %s has unsupported FourCC.", filename); + ri.FS_FreeFile(buffer.v); + return; + } + } + else if (ddsHeader->pixelFormatFlags == (DDSPF_RGB | DDSPF_ALPHAPIXELS) + && ddsHeader->rgbBitCount == 32 + && ddsHeader->rBitMask == 0x000000ff + && ddsHeader->gBitMask == 0x0000ff00 + && ddsHeader->bBitMask == 0x00ff0000 + && ddsHeader->aBitMask == 0xff000000) + { + *picFormat = GL_RGBA8; + } + else + { + ri.Printf(PRINT_ALL, "DDS File %s has unsupported RGBA format.", filename); + ri.FS_FreeFile(buffer.v); + return; + } + } + + *pic = ri.Malloc(len); + Com_Memcpy(*pic, data, len); + + ri.FS_FreeFile(buffer.v); +} -- cgit From ab9a49f87ddd323ce1958d0834ddbb7cab199f12 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 18 Dec 2015 19:42:15 -0800 Subject: OpenGL2: Add null dereference checks to DDS loader. --- src/renderergl2/tr_image_dds.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image_dds.c b/src/renderergl2/tr_image_dds.c index 578b3eda..8ad406fd 100644 --- a/src/renderergl2/tr_image_dds.c +++ b/src/renderergl2/tr_image_dds.c @@ -292,13 +292,18 @@ void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLen len -= 4 + sizeof(*ddsHeader); } - *width = ddsHeader->width; - *height = ddsHeader->height; + if (width) + *width = ddsHeader->width; + if (height) + *height = ddsHeader->height; - if (ddsHeader->flags & _DDSFLAGS_MIPMAPCOUNT) - *numMips = ddsHeader->numMips; - else - *numMips = 1; + if (numMips) + { + if (ddsHeader->flags & _DDSFLAGS_MIPMAPCOUNT) + *numMips = ddsHeader->numMips; + else + *numMips = 1; + } // FIXME: handle cube map //if ((ddsHeader->caps2 & DDSCAPS2_CUBEMAP) == DDSCAPS2_CUBEMAP) -- cgit From e78dc015d1c94fbe4fa5014d412a2cdf23f2dc7d Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 21 Dec 2015 20:24:19 -0800 Subject: OpenGL2: Support picmip for DDS textures. --- src/renderergl2/tr_image.c | 44 ++++++++++++++++++++++++-------------------- 1 file changed, 24 insertions(+), 20 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index c35af4c2..74eddfe0 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1869,7 +1869,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); - if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + if (data && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { int bytesPer4x4Block = 0; int miplevel = 0; @@ -1877,6 +1877,7 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei switch (picFormat) { case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: case GL_COMPRESSED_RED_RGTC1: @@ -1901,11 +1902,26 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei break; } - for (miplevel = 0; miplevel < numMips; miplevel++) + if (flags & IMGFLAG_PICMIP) { - int size; + for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) + { + int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; - size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + x >>= 1; + y >>= 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + data += size; + } + } + + if (!(flags & IMGFLAG_MIPMAP)) + numMips = 1; + + for (miplevel = 0; miplevel < numMips; miplevel++) + { + int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; if (subtexture) qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); @@ -1914,9 +1930,6 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei x >>= 1; y >>= 1; - x -= x % 4; - y -= y % 4; - width = MAX(1, width >> 1); height = MAX(1, height >> 1); data += size; @@ -1956,29 +1969,20 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei if (flags & IMGFLAG_MIPMAP) { - int miplevel; + int miplevel = 0; - miplevel = 0; while (width > 1 || height > 1) { if (data) { if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - { R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - } else - { R_MipMapsRGB( data, width, height ); - } } - width >>= 1; - height >>= 1; - if (width < 1) - width = 1; - if (height < 1) - height = 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); miplevel++; if ( data && r_colorMipLevels->integer ) @@ -2029,7 +2033,7 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic } else if (!subtexture) { - if (picFormat != GL_RGBA8) + if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); goto done; -- cgit From 19c44d9c50d6a3057e79007c779552d0eb7fe4ef Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 22 Dec 2015 05:04:07 -0800 Subject: OpenGL2: Add r_exportCubemaps for saving cubemaps on map load. --- src/renderergl2/tr_bsp.c | 37 +++++++++++++++++++++++++++++++++- src/renderergl2/tr_image_dds.c | 45 ++++++++++++++++++++++++++++++++++++++++++ src/renderergl2/tr_init.c | 3 +++ src/renderergl2/tr_local.h | 1 + 4 files changed, 85 insertions(+), 1 deletion(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index d2a5f5f2..81463c66 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3068,16 +3068,23 @@ void R_AssignCubemapsToWorldSurfaces(void) } } +// FIXME: put this function declaration elsewhere +void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth); void R_RenderAllCubemaps(void) { + byte *data = NULL; + int sideSize = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 4; int i, j; for (i = 0; i < tr.numCubemaps; i++) { tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); } - + + if (r_exportCubemaps->integer) + data = ri.Malloc(sideSize * 6); + for (i = 0; i < tr.numCubemaps; i++) { for (j = 0; j < 6; j++) @@ -3087,6 +3094,34 @@ void R_RenderAllCubemaps(void) R_IssuePendingRenderCommands(); R_InitNextFrame(); } + + if (r_exportCubemaps->integer) + { + char filename[MAX_QPATH]; + byte *p; + cubemap_t *cubemap = &tr.cubemaps[i]; + + // FIXME: do this in backEnd + FBO_Bind(tr.renderCubeFbo); + + p = data; + for (j = 0; j < 6; j++) + { + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); + qglReadPixels(0, 0, CUBE_MAP_SIZE, CUBE_MAP_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, p); + p += sideSize; + } + FBO_Bind(NULL); + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, backEnd.viewParms.targetFboCubemapIndex); + R_SaveDDS(filename, data, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6); + } + } + + if (r_exportCubemaps->integer) + { + ri.Cvar_Set("r_exportCubemaps", "0"); + ri.Free(data); } } diff --git a/src/renderergl2/tr_image_dds.c b/src/renderergl2/tr_image_dds.c index 8ad406fd..b509014d 100644 --- a/src/renderergl2/tr_image_dds.c +++ b/src/renderergl2/tr_image_dds.c @@ -451,3 +451,48 @@ void R_LoadDDS ( const char *filename, byte **pic, int *width, int *height, GLen ri.FS_FreeFile(buffer.v); } + +void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth) +{ + byte *data; + ddsHeader_t *ddsHeader; + int picSize, size; + + if (!depth) + depth = 1; + + picSize = width * height * depth * 4; + size = 4 + sizeof(*ddsHeader) + picSize; + data = ri.Malloc(size); + + data[0] = 'D'; + data[1] = 'D'; + data[2] = 'S'; + data[3] = ' '; + + ddsHeader = (ddsHeader_t *)(data + 4); + memset(ddsHeader, 0, sizeof(ddsHeader_t)); + + ddsHeader->headerSize = 0x7c; + ddsHeader->flags = _DDSFLAGS_REQUIRED; + ddsHeader->height = height; + ddsHeader->width = width; + ddsHeader->always_0x00000020 = 0x00000020; + ddsHeader->caps = DDSCAPS_COMPLEX | DDSCAPS_REQUIRED; + + if (depth == 6) + ddsHeader->caps2 = DDSCAPS2_CUBEMAP; + + ddsHeader->pixelFormatFlags = DDSPF_RGB | DDSPF_ALPHAPIXELS; + ddsHeader->rgbBitCount = 32; + ddsHeader->rBitMask = 0x000000ff; + ddsHeader->gBitMask = 0x0000ff00; + ddsHeader->bBitMask = 0x00ff0000; + ddsHeader->aBitMask = 0xff000000; + + Com_Memcpy(data + 4 + sizeof(*ddsHeader), pic, picSize); + + ri.FS_WriteFile(filename, data, size); + + ri.Free(data); +} diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 2828270e..44808639 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -141,6 +141,7 @@ cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; +cvar_t *r_exportCubemaps; cvar_t *r_specularIsMetallic; cvar_t *r_glossIsRoughness; cvar_t *r_baseNormalX; @@ -383,6 +384,7 @@ byte *RB_ReadPixels(int x, int y, int width, int height, size_t *offset, int *pa buffer = ri.Hunk_AllocateTempMemory(padwidth * height + *offset + packAlign - 1); bufstart = PADP((intptr_t) buffer + *offset, packAlign); + qglReadPixels(x, y, width, height, GL_RGB, GL_UNSIGNED_BYTE, bufstart); *offset = bufstart - buffer; @@ -1141,6 +1143,7 @@ void R_Register( void ) r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_exportCubemaps = ri.Cvar_Get("r_exportCubemaps", "0", 0); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 0a1dc5fe..f716065e 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1794,6 +1794,7 @@ extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; +extern cvar_t *r_exportCubemaps; extern cvar_t *r_specularIsMetallic; extern cvar_t *r_glossIsRoughness; extern cvar_t *r_baseNormalX; -- cgit From cedfa02c6b3b17cda26202abf5e4dd32f9720cb5 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 23 Dec 2015 09:58:11 -0800 Subject: OpenGL2: Replace r_exportCubemaps cvar with exportCubemaps command. --- src/renderergl2/tr_backend.c | 62 ++++++++++++++++++++++++++++++++++++++++++++ src/renderergl2/tr_bsp.c | 35 ------------------------- src/renderergl2/tr_init.c | 33 +++++++++++++++++++++-- src/renderergl2/tr_local.h | 8 ++++-- 4 files changed, 99 insertions(+), 39 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index ad43e5b2..4a29c966 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1738,6 +1738,65 @@ 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 = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 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]; + char *p = cubemapPixels; + + for (j = 0; j < 6; j++) + { + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); + qglReadPixels(0, 0, CUBE_MAP_SIZE, CUBE_MAP_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, p); + p += sideSize; + } + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); + R_SaveDDS(filename, cubemapPixels, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6); + ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename); + } + + FBO_Bind(oldFbo); + + ri.Free(cubemapPixels); + } + + return (const void *)(cmd + 1); +} + /* ==================== @@ -1786,6 +1845,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 diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 81463c66..960e9282 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3068,13 +3068,9 @@ void R_AssignCubemapsToWorldSurfaces(void) } } -// FIXME: put this function declaration elsewhere -void R_SaveDDS(const char *filename, byte *pic, int width, int height, int depth); void R_RenderAllCubemaps(void) { - byte *data = NULL; - int sideSize = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 4; int i, j; for (i = 0; i < tr.numCubemaps; i++) @@ -3082,9 +3078,6 @@ void R_RenderAllCubemaps(void) tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); } - if (r_exportCubemaps->integer) - data = ri.Malloc(sideSize * 6); - for (i = 0; i < tr.numCubemaps; i++) { for (j = 0; j < 6; j++) @@ -3094,34 +3087,6 @@ void R_RenderAllCubemaps(void) R_IssuePendingRenderCommands(); R_InitNextFrame(); } - - if (r_exportCubemaps->integer) - { - char filename[MAX_QPATH]; - byte *p; - cubemap_t *cubemap = &tr.cubemaps[i]; - - // FIXME: do this in backEnd - FBO_Bind(tr.renderCubeFbo); - - p = data; - for (j = 0; j < 6; j++) - { - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); - qglReadPixels(0, 0, CUBE_MAP_SIZE, CUBE_MAP_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, p); - p += sideSize; - } - FBO_Bind(NULL); - - Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, backEnd.viewParms.targetFboCubemapIndex); - R_SaveDDS(filename, data, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6); - } - } - - if (r_exportCubemaps->integer) - { - ri.Cvar_Set("r_exportCubemaps", "0"); - ri.Free(data); } } diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 44808639..8a84c1f8 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -141,7 +141,6 @@ cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; -cvar_t *r_exportCubemaps; cvar_t *r_specularIsMetallic; cvar_t *r_glossIsRoughness; cvar_t *r_baseNormalX; @@ -760,6 +759,35 @@ void R_ScreenShotJPEG_f (void) { //============================================================================ +/* +================== +R_ExportCubemaps +================== +*/ +void R_ExportCubemaps() +{ + exportCubemapsCommand_t *cmd; + + cmd = R_GetCommandBuffer(sizeof(*cmd)); + if (!cmd) { + return; + } + cmd->commandId = RC_EXPORT_CUBEMAPS; +} + + +/* +================== +R_ExportCubemaps_f +================== +*/ +void R_ExportCubemaps_f(void) +{ + R_ExportCubemaps(); +} + +//============================================================================ + /* ================== RB_TakeVideoFrameCmd @@ -1143,7 +1171,6 @@ void R_Register( void ) r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); - r_exportCubemaps = ri.Cvar_Get("r_exportCubemaps", "0", 0); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); @@ -1280,6 +1307,7 @@ void R_Register( void ) ri.Cmd_AddCommand( "gfxinfo", GfxInfo_f ); ri.Cmd_AddCommand( "minimize", GLimp_Minimize ); ri.Cmd_AddCommand( "gfxmeminfo", GfxMemInfo_f ); + ri.Cmd_AddCommand( "exportCubemaps", R_ExportCubemaps_f ); } void R_InitQueries(void) @@ -1421,6 +1449,7 @@ void RE_Shutdown( qboolean destroyWindow ) { ri.Cmd_RemoveCommand("minimize"); ri.Cmd_RemoveCommand( "shaderstate" ); ri.Cmd_RemoveCommand( "gfxmeminfo" ); + ri.Cmd_RemoveCommand( "exportCubemaps" ); if ( tr.registered ) { diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index f716065e..a652a396 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1794,7 +1794,6 @@ extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; -extern cvar_t *r_exportCubemaps; extern cvar_t *r_specularIsMetallic; extern cvar_t *r_glossIsRoughness; extern cvar_t *r_baseNormalX; @@ -2422,6 +2421,10 @@ typedef struct { viewParms_t viewParms; } postProcessCommand_t; +typedef struct { + int commandId; +} exportCubemapsCommand_t; + typedef enum { RC_END_OF_LIST, RC_SET_COLOR, @@ -2434,7 +2437,8 @@ typedef enum { RC_COLORMASK, RC_CLEARDEPTH, RC_CAPSHADOWMAP, - RC_POSTPROCESS + RC_POSTPROCESS, + RC_EXPORT_CUBEMAPS } renderCommand_t; -- cgit From fae2cb94e089fabe9a69d0909a5c25e1014cb25f Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 24 Dec 2015 16:34:58 -0800 Subject: OpenGL2: Add r_cubemapSize. --- src/renderergl2/tr_backend.c | 6 +++--- src/renderergl2/tr_bsp.c | 2 +- src/renderergl2/tr_image.c | 2 +- src/renderergl2/tr_init.c | 2 ++ src/renderergl2/tr_local.h | 3 +-- 5 files changed, 8 insertions(+), 7 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 4a29c966..557f553b 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1765,7 +1765,7 @@ const void *RB_ExportCubemaps(const void *data) if (cmd) { FBO_t *oldFbo = glState.currentFBO; - int sideSize = CUBE_MAP_SIZE * CUBE_MAP_SIZE * 4; + int sideSize = r_cubemapSize->integer * r_cubemapSize->integer * 4; byte *cubemapPixels = ri.Malloc(sideSize * 6); int i, j; @@ -1780,12 +1780,12 @@ const void *RB_ExportCubemaps(const void *data) for (j = 0; j < 6; j++) { qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); - qglReadPixels(0, 0, CUBE_MAP_SIZE, CUBE_MAP_SIZE, GL_RGBA, GL_UNSIGNED_BYTE, p); + qglReadPixels(0, 0, r_cubemapSize->integer, r_cubemapSize->integer, GL_RGBA, GL_UNSIGNED_BYTE, p); p += sideSize; } Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); - R_SaveDDS(filename, cubemapPixels, CUBE_MAP_SIZE, CUBE_MAP_SIZE, 6); + R_SaveDDS(filename, cubemapPixels, r_cubemapSize->integer, r_cubemapSize->integer, 6); ri.Printf(PRINT_ALL, "Saved cubemap %d as %s\n", i, filename); } diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 960e9282..e0a97d4d 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3075,7 +3075,7 @@ void R_RenderAllCubemaps(void) for (i = 0; i < tr.numCubemaps; i++) { - tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); + tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); } for (i = 0; i < tr.numCubemaps; i++) diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 74eddfe0..d01f42c4 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2842,7 +2842,7 @@ void R_CreateBuiltinImages( void ) { if (r_cubeMapping->integer) { - tr.renderCubeImage = R_CreateImage("*renderCube", NULL, CUBE_MAP_SIZE, CUBE_MAP_SIZE, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat); + tr.renderCubeImage = R_CreateImage("*renderCube", NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, rgbFormat); } } } diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 8a84c1f8..bf05e210 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -141,6 +141,7 @@ cvar_t *r_specularMapping; cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; +cvar_t *r_cubemapSize; cvar_t *r_specularIsMetallic; cvar_t *r_glossIsRoughness; cvar_t *r_baseNormalX; @@ -1171,6 +1172,7 @@ void R_Register( void ) r_deluxeMapping = ri.Cvar_Get( "r_deluxeMapping", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); + r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH ); r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index a652a396..72f11989 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -55,8 +55,6 @@ typedef unsigned int glIndex_t; #define MAX_CALC_PSHADOWS 64 #define MAX_DRAWN_PSHADOWS 16 // do not increase past 32, because bit flags are used on surfaces #define PSHADOW_MAP_SIZE 512 -#define CUBE_MAP_MIPS 7 -#define CUBE_MAP_SIZE (1 << CUBE_MAP_MIPS) #define USE_VERT_TANGENT_SPACE #define USE_OVERBRIGHT @@ -1794,6 +1792,7 @@ extern cvar_t *r_specularMapping; extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; +extern cvar_t *r_cubemapSize; extern cvar_t *r_specularIsMetallic; extern cvar_t *r_glossIsRoughness; extern cvar_t *r_baseNormalX; -- cgit From ac7296d42f36891d13d7cd475f5ce46fa6ef3d63 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 15 Jan 2016 02:46:30 -0800 Subject: OpenGL2: Remove specular ambient. --- src/renderergl2/glsl/lightall_fp.glsl | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 17dc9fca..b8f3985f 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -363,7 +363,7 @@ void main() reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness); gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); - gl_FragColor.rgb += ambientColor * (diffuse.rgb + specular.rgb); + gl_FragColor.rgb += ambientColor * diffuse.rgb; #if defined(USE_CUBEMAP) reflectance = EnvironmentBRDF(roughness, NE, specular.rgb); -- cgit From 970b21fbcd3d42e641807ac0c5e9a29dc21095e9 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 18 Jan 2016 04:46:01 -0800 Subject: OpenGL2: Direct state access, part 1: Texture binds --- src/renderergl2/tr_backend.c | 161 ++++++++++------------------------------ src/renderergl2/tr_dsa.c | 132 ++++++++++++++++++++++++++++++++ src/renderergl2/tr_dsa.h | 46 ++++++++++++ src/renderergl2/tr_extensions.c | 52 +++++++++++++ src/renderergl2/tr_image.c | 130 ++++++++++++-------------------- src/renderergl2/tr_init.c | 17 ++--- src/renderergl2/tr_local.h | 7 +- src/renderergl2/tr_main.c | 2 +- src/renderergl2/tr_shade.c | 16 ++-- src/renderergl2/tr_shadows.c | 4 +- src/renderergl2/tr_sky.c | 2 +- src/renderergl2/tr_surface.c | 4 +- 12 files changed, 337 insertions(+), 236 deletions(-) create mode 100644 src/renderergl2/tr_dsa.c create mode 100644 src/renderergl2/tr_dsa.h (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 557f553b..e6dd3cfa 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -21,6 +21,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA =========================================================================== */ #include "tr_local.h" +#include "tr_dsa.h" backEndData_t *backEndData; backEndState_t backEnd; @@ -36,81 +37,28 @@ 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); } @@ -142,39 +90,6 @@ void GL_Cull( int cullType ) { glState.faceCulling = 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 ** @@ -856,6 +771,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(); @@ -896,23 +812,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); } } } @@ -1072,11 +995,10 @@ 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) @@ -1316,10 +1238,8 @@ const void *RB_DrawSurfs( const void *data ) { cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; FBO_Bind(NULL); - GL_SelectTexture(TB_CUBEMAP); - GL_BindToTMU(cubemap->image, 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); @@ -1396,7 +1316,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); @@ -1572,21 +1492,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); } } } @@ -1659,7 +1576,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); @@ -1775,7 +1692,7 @@ const void *RB_ExportCubemaps(const void *data) { char filename[MAX_QPATH]; cubemap_t *cubemap = &tr.cubemaps[i]; - char *p = cubemapPixels; + byte *p = cubemapPixels; for (j = 0; j < 6; j++) { diff --git a/src/renderergl2/tr_dsa.c b/src/renderergl2/tr_dsa.c new file mode 100644 index 00000000..55a731d9 --- /dev/null +++ b/src/renderergl2/tr_dsa.c @@ -0,0 +1,132 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#include "tr_local.h" + +#include "tr_dsa.h" + +static struct +{ + GLuint textures[NUM_TEXTURE_BUNDLES]; + GLenum texunit; +} +glDsaState; + +void GL_BindNullTextures() +{ + int i; + + if (glRefConfig.directStateAccess) + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglBindMultiTexture(GL_TEXTURE0_ARB + i, GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + } + else + { + for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) + { + qglActiveTextureARB(GL_TEXTURE0_ARB + i); + qglBindTexture(GL_TEXTURE_2D, 0); + glDsaState.textures[i] = 0; + } + + qglActiveTextureARB(GL_TEXTURE0_ARB); + glDsaState.texunit = GL_TEXTURE0_ARB; + } +} + +void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + GLuint tmu = texunit - GL_TEXTURE0_ARB; + + if (glDsaState.textures[tmu] == texture) + return; + + qglBindMultiTexture(texunit, target, texture); + glDsaState.textures[tmu] = texture; +} + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +{ + if (glDsaState.texunit != texunit) + { + qglActiveTextureARB(texunit); + glDsaState.texunit = texunit; + } + + qglBindTexture(target, texture); +} + +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameterf(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexParameteri(target, pname, param); +} + +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexImage2D(target, level, internalformat, width, height, border, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglTexSubImage2D(target, level, xoffset, yoffset, width, height, format, type, pixels); +} + +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCopyTexImage2D(target, level, internalformat, x, y, width, height, border); +} + +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexImage2DARB(target, level, internalformat, width, height, border, imageSize, data); +} + +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglCompressedTexSubImage2DARB(target, level, xoffset, yoffset, width, height, format, imageSize, data); +} + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target) +{ + GL_BindMultiTexture(glDsaState.texunit, target, texture); + qglGenerateMipmapEXT(target); +} diff --git a/src/renderergl2/tr_dsa.h b/src/renderergl2/tr_dsa.h new file mode 100644 index 00000000..c166b9f3 --- /dev/null +++ b/src/renderergl2/tr_dsa.h @@ -0,0 +1,46 @@ +/* +=========================================================================== +Copyright (C) 2016 James Canete + +This program 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. + +This program 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 this program; if not, write to the Free Software +Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +=========================================================================== +*/ + +#ifndef __TR_DSA_H__ +#define __TR_DSA_H__ + +#include "../renderercommon/qgl.h" + +void GL_BindNullTextures(void); +void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); + +GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); +GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid APIENTRY GLDSA_TextureParameteri(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid APIENTRY GLDSA_TextureImage2D(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_TextureSubImage2D(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid APIENTRY GLDSA_CopyTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid APIENTRY GLDSA_CompressedTextureImage2D(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); + +GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target); + +#endif diff --git a/src/renderergl2/tr_extensions.c b/src/renderergl2/tr_extensions.c index 2c1407b2..abafbf97 100644 --- a/src/renderergl2/tr_extensions.c +++ b/src/renderergl2/tr_extensions.c @@ -28,6 +28,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #endif #include "tr_local.h" +#include "tr_dsa.h" // GL_EXT_draw_range_elements void (APIENTRY * qglDrawRangeElementsEXT) (GLenum mode, GLuint start, GLuint end, GLsizei count, GLenum type, const GLvoid *indices); @@ -184,6 +185,23 @@ void (APIENTRY * qglDeleteVertexArraysARB)(GLsizei n, const GLuint *arrays); void (APIENTRY * qglGenVertexArraysARB)(GLsizei n, GLuint *arrays); GLboolean (APIENTRY * qglIsVertexArrayARB)(GLuint array); +// GL_EXT_direct_state_access +GLvoid (APIENTRY * qglBindMultiTexture)(GLenum texunit, GLenum target, GLuint texture); +GLvoid (APIENTRY * qglTextureParameterf)(GLuint texture, GLenum target, GLenum pname, GLfloat param); +GLvoid (APIENTRY * qglTextureParameteri)(GLuint texture, GLenum target, GLenum pname, GLint param); +GLvoid (APIENTRY * qglTextureImage2D)(GLuint texture, GLenum target, GLint level, GLint internalformat, + GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglTextureSubImage2D)(GLuint texture, GLenum target, GLint level, GLint xoffset, GLint yoffset, + GLsizei width, GLsizei height, GLenum format, GLenum type, const GLvoid *pixels); +GLvoid (APIENTRY * qglCopyTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLint x, GLint y, GLsizei width, GLsizei height, GLint border); +GLvoid (APIENTRY * qglCompressedTextureImage2D)(GLuint texture, GLenum target, GLint level, GLenum internalformat, + GLsizei width, GLsizei height, GLint border, GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target, GLint level, + GLint xoffset, GLint yoffset, GLsizei width, GLsizei height, GLenum format, + GLsizei imageSize, const GLvoid *data); +GLvoid (APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); + static qboolean GLimp_HaveExtension(const char *ext) { const char *ptr = Q_stristr( glConfig.extensions_string, ext ); @@ -750,4 +768,38 @@ void GLimp_InitExtraExtensions() ri.Printf(PRINT_ALL, result[2], extension); } + // GL_EXT_direct_state_access + extension = "GL_EXT_direct_state_access"; + qglBindMultiTexture = GLDSA_BindMultiTexture; + qglTextureParameterf = GLDSA_TextureParameterf; + qglTextureParameteri = GLDSA_TextureParameteri; + qglTextureImage2D = GLDSA_TextureImage2D; + qglTextureSubImage2D = GLDSA_TextureSubImage2D; + qglCopyTextureImage2D = GLDSA_CopyTextureImage2D; + qglCompressedTextureImage2D = GLDSA_CompressedTextureImage2D; + qglCompressedTextureSubImage2D = GLDSA_CompressedTextureSubImage2D; + qglGenerateTextureMipmap = GLDSA_GenerateTextureMipmap; + glRefConfig.directStateAccess = qfalse; + if (GLimp_HaveExtension(extension)) + { + if (r_ext_direct_state_access->integer) + { + glRefConfig.directStateAccess = qtrue; + qglBindMultiTexture = (void *)SDL_GL_GetProcAddress("glBindMultiTextureEXT"); + qglTextureParameterf = (void *)SDL_GL_GetProcAddress("glTextureParameterfEXT"); + qglTextureParameteri = (void *)SDL_GL_GetProcAddress("glTextureParameteriEXT"); + qglTextureImage2D = (void *)SDL_GL_GetProcAddress("glTextureImage2DEXT"); + qglTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glTextureSubImage2DEXT"); + qglCopyTextureImage2D = (void *)SDL_GL_GetProcAddress("glCopyTextureImage2DEXT"); + qglCompressedTextureImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureImage2DEXT"); + qglCompressedTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureSubImage2DEXT"); + qglGenerateTextureMipmap = (void *)SDL_GL_GetProcAddress("glGenerateTextureMipmapEXT"); + } + + ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess ? 1 : 0], extension); + } + else + { + ri.Printf(PRINT_ALL, result[2], extension); + } } diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index d01f42c4..aade799e 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_image.c #include "tr_local.h" +#include "tr_dsa.h" + static byte s_intensitytable[256]; static unsigned char s_gammatable[256]; @@ -115,9 +117,8 @@ void GL_TextureMode( const char *string ) { for ( i = 0 ; i < tr.numImages ; i++ ) { glt = tr.images[ i ]; if ( glt->flags & IMGFLAG_MIPMAP ) { - GL_Bind (glt); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } } } @@ -1818,7 +1819,7 @@ static void CompressMonoBlock(byte outdata[8], const byte indata[16]) } } -static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int mip) +static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, int height, int mip) { int wBlocks, hBlocks, y, x, size; byte *compressedData, *p; @@ -1858,13 +1859,13 @@ static void RawImage_UploadToRgtc2Texture(byte *data, int width, int height, int } } - qglCompressedTexImage2DARB(GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, mip, GL_COMPRESSED_RG_RGTC2, width, height, 0, size, compressedData); ri.Hunk_FreeTempMemory(compressedData); } -static void RawImage_UploadTexture( byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) { int dataFormat, dataType; qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); @@ -1924,9 +1925,9 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; if (subtexture) - qglCompressedTexSubImage2DARB(GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); + qglCompressedTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); else - qglCompressedTexImage2DARB(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); x >>= 1; y >>= 1; @@ -1958,13 +1959,13 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei } if ( subtexture ) - qglTexSubImage2D( GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, 0); + RawImage_UploadToRgtc2Texture(texture, data, width, height, 0); else - qglTexImage2D(GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); } if (flags & IMGFLAG_MIPMAP) @@ -1992,14 +1993,14 @@ static void RawImage_UploadTexture( byte *data, int x, int y, int width, int hei { x >>= 1; y >>= 1; - qglTexSubImage2D( GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); + qglTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); } else { if (rgtc) - RawImage_UploadToRgtc2Texture(data, width, height, miplevel); + RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); else - qglTexImage2D(GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + qglTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); } } } @@ -2028,14 +2029,14 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) { - RawImage_UploadTexture(data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); goto done; } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); @@ -2075,12 +2076,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2090,19 +2091,19 @@ done: if (mipmap) { if ( glConfig.textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp( 1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer ) ); + qglTextureParameteri( image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { if ( glConfig.textureFilterAnisotropic ) - qglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1 ); + qglTextureParameteri(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Fix for sampling depth buffer on old nVidia cards @@ -2113,9 +2114,9 @@ done: case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT32_ARB: - qglTexParameterf(GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST ); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; default: break; @@ -2178,46 +2179,32 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe image->internalFormat = internalFormat; - - // lightmaps are always allocated on TMU 1 - if ( qglActiveTextureARB && isLightmap ) { - image->TMU = 1; - } else { - image->TMU = 0; - } - - if ( qglActiveTextureARB ) { - GL_SelectTexture( image->TMU ); - } - - GL_Bind(image); - if (image->flags & IMGFLAG_CUBEMAP) { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); if (image->flags & IMGFLAG_MIPMAP) { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); } else { - qglTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); } - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); + qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); if (image->flags & IMGFLAG_MIPMAP) - qglGenerateMipmapEXT(GL_TEXTURE_CUBE_MAP); + qglGenerateTextureMipmap(image->texnum, GL_TEXTURE_CUBE_MAP); image->uploadWidth = width; image->uploadHeight = height; @@ -2226,12 +2213,10 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe { Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode ); - qglTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode ); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode); + qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode); } - GL_SelectTexture( 0 ); - hash = generateHashValue(name); image->next = hashTable[hash]; hashTable[hash] = image; @@ -2255,15 +2240,7 @@ image_t *R_CreateImage(const char *name, byte *pic, int width, int height, imgTy void R_UpdateSubImage( image_t *image, byte *pic, int x, int y, int width, int height ) { - if (qglActiveTextureARB) { - GL_SelectTexture(image->TMU); - } - - GL_Bind(image); - Upload32(pic, x, y, width, height, GL_RGBA8, 0, image); - - GL_SelectTexture(0); } //=================================================================== @@ -2830,11 +2807,10 @@ void R_CreateBuiltinImages( void ) { for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); - GL_Bind(tr.sunShadowDepthImage[x]); - 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_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); - qglTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); + qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } tr.screenShadowImage = R_CreateImage("*screenShadow", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); @@ -2947,15 +2923,7 @@ void R_DeleteTextures( void ) { tr.numImages = 0; - Com_Memset( glState.currenttextures, 0, sizeof( glState.currenttextures ) ); - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - GL_SelectTexture( 0 ); - qglBindTexture( GL_TEXTURE_2D, 0 ); - } else { - qglBindTexture( GL_TEXTURE_2D, 0 ); - } + GL_BindNullTextures(); } /* diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index bf05e210..05b00465 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -24,6 +24,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" +#include "tr_dsa.h" + glconfig_t glConfig; glRefConfig_t glRefConfig; qboolean textureFilterAnisotropic = qfalse; @@ -105,6 +107,7 @@ cvar_t *r_ext_framebuffer_multisample; cvar_t *r_arb_seamless_cube_map; cvar_t *r_arb_vertex_type_2_10_10_10_rev; cvar_t *r_arb_vertex_array_object; +cvar_t *r_ext_direct_state_access; cvar_t *r_mergeMultidraws; cvar_t *r_mergeLeafSurfaces; @@ -765,7 +768,7 @@ void R_ScreenShotJPEG_f (void) { R_ExportCubemaps ================== */ -void R_ExportCubemaps() +void R_ExportCubemaps(void) { exportCubemapsCommand_t *cmd; @@ -883,19 +886,10 @@ void GL_SetDefaultState( void ) qglColor4f (1,1,1,1); - // initialize downstream texture unit if we're running - // in a multitexture environment - if ( qglActiveTextureARB ) { - GL_SelectTexture( 1 ); - GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); - qglDisable( GL_TEXTURE_2D ); - GL_SelectTexture( 0 ); - } + GL_BindNullTextures(); qglEnable(GL_TEXTURE_2D); GL_TextureMode( r_textureMode->string ); - GL_TexEnv( GL_MODULATE ); //qglShadeModel( GL_SMOOTH ); qglDepthFunc( GL_LEQUAL ); @@ -1108,6 +1102,7 @@ void R_Register( void ) r_arb_seamless_cube_map = ri.Cvar_Get( "r_arb_seamless_cube_map", "0", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_type_2_10_10_10_rev = ri.Cvar_Get( "r_arb_vertex_type_2_10_10_10_rev", "1", CVAR_ARCHIVE | CVAR_LATCH); r_arb_vertex_array_object = ri.Cvar_Get( "r_arb_vertex_array_object", "1", CVAR_ARCHIVE | CVAR_LATCH); + r_ext_direct_state_access = ri.Cvar_Get("r_ext_direct_state_access", "1", CVAR_ARCHIVE | CVAR_LATCH); r_ext_texture_filter_anisotropic = ri.Cvar_Get( "r_ext_texture_filter_anisotropic", "0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 72f11989..0dd61674 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1352,8 +1352,6 @@ typedef struct { // the renderer front end should never modify glstate_t typedef struct { - int currenttextures[NUM_TEXTURE_BUNDLES]; - int currenttmu; qboolean finishCalled; int texEnv[2]; int faceCulling; @@ -1421,6 +1419,7 @@ typedef struct { qboolean floatLightmap; qboolean vertexArrayObject; + qboolean directStateAccess; } glRefConfig_t; @@ -1720,6 +1719,7 @@ extern cvar_t *r_ext_framebuffer_multisample; extern cvar_t *r_arb_seamless_cube_map; extern cvar_t *r_arb_vertex_type_2_10_10_10_rev; extern cvar_t *r_arb_vertex_array_object; +extern cvar_t *r_ext_direct_state_access; extern cvar_t *r_nobind; // turns off binding to appropriate textures extern cvar_t *r_singleShader; // make most world faces use default shader @@ -1884,17 +1884,14 @@ void R_RotateForEntity( const trRefEntity_t *ent, const viewParms_t *viewParms, /* ** GL wrapper/helper functions */ -void GL_Bind( image_t *image ); void GL_BindToTMU( image_t *image, int tmu ); void GL_SetDefaultState (void); -void GL_SelectTexture( int unit ); void GL_TextureMode( const char *string ); void GL_CheckErrs( char *file, int line ); #define GL_CheckErrors(...) GL_CheckErrs(__FILE__, __LINE__) void GL_State( unsigned long stateVector ); void GL_SetProjectionMatrix(mat4_t matrix); void GL_SetModelviewMatrix(mat4_t matrix); -void GL_TexEnv( int env ); void GL_Cull( int cullType ); #define GLS_SRCBLEND_ZERO 0x00000001 diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 14d18755..63fea5ac 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -2031,7 +2031,7 @@ void R_DebugGraphics( void ) { R_IssuePendingRenderCommands(); - GL_Bind( tr.whiteImage); + GL_BindToTMU(tr.whiteImage, TB_COLORMAP); GL_Cull( CT_FRONT_SIDED ); ri.CM_DrawDebugSurface( R_DebugPolygon ); } diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index 04b62517..f4d32a5e 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -102,11 +102,9 @@ static void R_BindAnimatedImageToTMU( textureBundle_t *bundle, int tmu ) { int index; if ( bundle->isVideoMap ) { - int oldtmu = glState.currenttmu; - GL_SelectTexture(tmu); ri.CIN_RunCinematic(bundle->videoMapHandle); ri.CIN_UploadCinematic(bundle->videoMapHandle); - GL_SelectTexture(oldtmu); + GL_BindToTMU(tr.scratchImage[bundle->videoMapHandle], tmu); return; } @@ -137,7 +135,7 @@ Draws triangle outlines for debugging ================ */ static void DrawTris (shaderCommands_t *input) { - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_POLYMODE_LINE | GLS_DEPTHMASK_TRUE ); qglDepthRange( 0, 0 ); @@ -415,7 +413,7 @@ static void ProjectDlightTexture( void ) { vector[3] = scale; GLSL_SetUniformVec4(sp, UNIFORM_DLIGHTINFO, vector); - GL_Bind( tr.dlightImage ); + GL_BindToTMU( tr.dlightImage, TB_COLORMAP ); // include GLS_DEPTHFUNC_EQUAL so alpha tested surfaces don't add light // where they aren't rendered @@ -863,11 +861,7 @@ static void ForwardDlight( void ) { } if (r_dlightMode->integer >= 2) - { - GL_SelectTexture(TB_SHADOWMAP); - GL_Bind(tr.shadowCubemaps[l]); - GL_SelectTexture(0); - } + GL_BindToTMU(tr.shadowCubemaps[l], TB_SHADOWMAP); ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); @@ -1267,7 +1261,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) if ( backEnd.depthFill ) { if (!(pStage->stateBits & GLS_ATEST_BITS)) - GL_BindToTMU( tr.whiteImage, 0 ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); else if ( pStage->bundle[TB_COLORMAP].image[0] != 0 ) R_BindAnimatedImageToTMU( &pStage->bundle[TB_COLORMAP], TB_COLORMAP ); } diff --git a/src/renderergl2/tr_shadows.c b/src/renderergl2/tr_shadows.c index fdb39091..33bf4bdc 100644 --- a/src/renderergl2/tr_shadows.c +++ b/src/renderergl2/tr_shadows.c @@ -207,7 +207,7 @@ void RB_ShadowTessEnd( void ) { // draw the silhouette edges - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ZERO ); qglColor3f( 0.2f, 0.2f, 0.2f ); @@ -257,7 +257,7 @@ void RB_ShadowFinish( void ) { qglDisable (GL_CLIP_PLANE0); GL_Cull( CT_TWO_SIDED ); - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); qglLoadIdentity (); diff --git a/src/renderergl2/tr_sky.c b/src/renderergl2/tr_sky.c index ae1dc2ab..3545a973 100644 --- a/src/renderergl2/tr_sky.c +++ b/src/renderergl2/tr_sky.c @@ -375,7 +375,7 @@ static void DrawSkySide( struct image_s *image, const int mins[2], const int max //tess.numIndexes = 0; tess.firstIndex = tess.numIndexes; - GL_Bind( image ); + GL_BindToTMU( image, TB_COLORMAP ); GL_Cull( CT_TWO_SIDED ); for ( t = mins[1]+HALF_SKY_SUBDIVISIONS; t <= maxs[1]+HALF_SKY_SUBDIVISIONS; t++ ) diff --git a/src/renderergl2/tr_surface.c b/src/renderergl2/tr_surface.c index e6146eef..92802f38 100644 --- a/src/renderergl2/tr_surface.c +++ b/src/renderergl2/tr_surface.c @@ -576,7 +576,7 @@ static void RB_SurfaceBeam( void ) VectorAdd( start_points[i], direction, end_points[i] ); } - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); @@ -1519,7 +1519,7 @@ Draws x/y/z lines from the origin for orientation debugging static void RB_SurfaceAxis( void ) { // FIXME: implement this #if 0 - GL_Bind( tr.whiteImage ); + GL_BindToTMU( tr.whiteImage, TB_COLORMAP ); GL_State( GLS_DEFAULT ); qglLineWidth( 3 ); qglBegin( GL_LINES ); -- cgit From 95633de9cb7414060e6d7c1102dd85385f203311 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 18 Jan 2016 23:30:36 -0800 Subject: OpenGL2: Direct state access, part 2: Uniforms. --- src/renderergl2/tr_dsa.c | 71 +++++++++++++++++++++++++++++++++- src/renderergl2/tr_dsa.h | 19 +++++++++- src/renderergl2/tr_extensions.c | 32 ++++++++++++++++ src/renderergl2/tr_glsl.c | 84 +++++++---------------------------------- src/renderergl2/tr_init.c | 3 +- src/renderergl2/tr_local.h | 2 - 6 files changed, 133 insertions(+), 78 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_dsa.c b/src/renderergl2/tr_dsa.c index 55a731d9..9472bb40 100644 --- a/src/renderergl2/tr_dsa.c +++ b/src/renderergl2/tr_dsa.c @@ -26,6 +26,8 @@ static struct { GLuint textures[NUM_TEXTURE_BUNDLES]; GLenum texunit; + + GLuint program; } glDsaState; @@ -55,15 +57,16 @@ void GL_BindNullTextures() } } -void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) +int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) { GLuint tmu = texunit - GL_TEXTURE0_ARB; if (glDsaState.textures[tmu] == texture) - return; + return 0; qglBindMultiTexture(texunit, target, texture); glDsaState.textures[tmu] = texture; + return 1; } GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) @@ -130,3 +133,67 @@ GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target) GL_BindMultiTexture(glDsaState.texunit, target, texture); qglGenerateMipmapEXT(target); } + +void GL_BindNullProgram() +{ + qglUseProgramObjectARB(0); + glDsaState.program = 0; +} + +int GL_UseProgramObject(GLuint program) +{ + if (glDsaState.program == program) + return 0; + + qglUseProgramObjectARB(program); + glDsaState.program = program; + return 1; +} + +GLvoid APIENTRY GLDSA_ProgramUniform1i(GLuint program, GLint location, GLint v0) +{ + GL_UseProgramObject(program); + qglUniform1iARB(location, v0); +} + +GLvoid APIENTRY GLDSA_ProgramUniform1f(GLuint program, GLint location, GLfloat v0) +{ + GL_UseProgramObject(program); + qglUniform1fARB(location, v0); +} + +GLvoid APIENTRY GLDSA_ProgramUniform2f(GLuint program, GLint location, + GLfloat v0, GLfloat v1) +{ + GL_UseProgramObject(program); + qglUniform2fARB(location, v0, v1); +} + +GLvoid APIENTRY GLDSA_ProgramUniform3f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2) +{ + GL_UseProgramObject(program); + qglUniform3fARB(location, v0, v1, v2); +} + +GLvoid APIENTRY GLDSA_ProgramUniform4f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3) +{ + GL_UseProgramObject(program); + qglUniform4fARB(location, v0, v1, v2, v3); +} + +GLvoid APIENTRY GLDSA_ProgramUniform1fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value) +{ + GL_UseProgramObject(program); + qglUniform1fvARB(location, count, value); +} + +GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value) +{ + GL_UseProgramObject(program); + qglUniformMatrix4fvARB(location, count, transpose, value); +} diff --git a/src/renderergl2/tr_dsa.h b/src/renderergl2/tr_dsa.h index c166b9f3..164ab065 100644 --- a/src/renderergl2/tr_dsa.h +++ b/src/renderergl2/tr_dsa.h @@ -24,7 +24,7 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. #include "../renderercommon/qgl.h" void GL_BindNullTextures(void); -void GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); +int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); GLvoid APIENTRY GLDSA_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture); GLvoid APIENTRY GLDSA_TextureParameterf(GLuint texture, GLenum target, GLenum pname, GLfloat param); @@ -43,4 +43,21 @@ GLvoid APIENTRY GLDSA_CompressedTextureSubImage2D(GLuint texture, GLenum target, GLvoid APIENTRY GLDSA_GenerateTextureMipmap(GLuint texture, GLenum target); +void GL_BindNullProgram(void); +int GL_UseProgramObject(GLuint program); + +GLvoid APIENTRY GLDSA_ProgramUniform1i(GLuint program, GLint location, GLint v0); +GLvoid APIENTRY GLDSA_ProgramUniform1f(GLuint program, GLint location, GLfloat v0); +GLvoid APIENTRY GLDSA_ProgramUniform2f(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +GLvoid APIENTRY GLDSA_ProgramUniform3f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +GLvoid APIENTRY GLDSA_ProgramUniform4f(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLvoid APIENTRY GLDSA_ProgramUniform1fv(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + #endif diff --git a/src/renderergl2/tr_extensions.c b/src/renderergl2/tr_extensions.c index abafbf97..bb668da2 100644 --- a/src/renderergl2/tr_extensions.c +++ b/src/renderergl2/tr_extensions.c @@ -202,6 +202,20 @@ GLvoid (APIENTRY * qglCompressedTextureSubImage2D)(GLuint texture, GLenum target GLsizei imageSize, const GLvoid *data); GLvoid (APIENTRY * qglGenerateTextureMipmap)(GLuint texture, GLenum target); +GLvoid(APIENTRY * qglProgramUniform1i)(GLuint program, GLint location, GLint v0); +GLvoid(APIENTRY * qglProgramUniform1f)(GLuint program, GLint location, GLfloat v0); +GLvoid(APIENTRY * qglProgramUniform2f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1); +GLvoid(APIENTRY * qglProgramUniform3f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2); +GLvoid(APIENTRY * qglProgramUniform4f)(GLuint program, GLint location, + GLfloat v0, GLfloat v1, GLfloat v2, GLfloat v3); +GLvoid(APIENTRY * qglProgramUniform1fv)(GLuint program, GLint location, + GLsizei count, const GLfloat *value); +GLvoid(APIENTRY * qglProgramUniformMatrix4fv)(GLuint program, GLint location, + GLsizei count, GLboolean transpose, + const GLfloat *value); + static qboolean GLimp_HaveExtension(const char *ext) { const char *ptr = Q_stristr( glConfig.extensions_string, ext ); @@ -770,6 +784,7 @@ void GLimp_InitExtraExtensions() // GL_EXT_direct_state_access extension = "GL_EXT_direct_state_access"; + qglBindMultiTexture = GLDSA_BindMultiTexture; qglTextureParameterf = GLDSA_TextureParameterf; qglTextureParameteri = GLDSA_TextureParameteri; @@ -779,6 +794,15 @@ void GLimp_InitExtraExtensions() qglCompressedTextureImage2D = GLDSA_CompressedTextureImage2D; qglCompressedTextureSubImage2D = GLDSA_CompressedTextureSubImage2D; qglGenerateTextureMipmap = GLDSA_GenerateTextureMipmap; + + qglProgramUniform1i = GLDSA_ProgramUniform1i; + qglProgramUniform1f = GLDSA_ProgramUniform1f; + qglProgramUniform2f = GLDSA_ProgramUniform2f; + qglProgramUniform3f = GLDSA_ProgramUniform3f; + qglProgramUniform4f = GLDSA_ProgramUniform4f; + qglProgramUniform1fv = GLDSA_ProgramUniform1fv; + qglProgramUniformMatrix4fv = GLDSA_ProgramUniformMatrix4fv; + glRefConfig.directStateAccess = qfalse; if (GLimp_HaveExtension(extension)) { @@ -794,6 +818,14 @@ void GLimp_InitExtraExtensions() qglCompressedTextureImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureImage2DEXT"); qglCompressedTextureSubImage2D = (void *)SDL_GL_GetProcAddress("glCompressedTextureSubImage2DEXT"); qglGenerateTextureMipmap = (void *)SDL_GL_GetProcAddress("glGenerateTextureMipmapEXT"); + + qglProgramUniform1i = (void *)SDL_GL_GetProcAddress("glProgramUniform1iEXT"); + qglProgramUniform1f = (void *)SDL_GL_GetProcAddress("glProgramUniform1fEXT"); + qglProgramUniform2f = (void *)SDL_GL_GetProcAddress("glProgramUniform2fEXT"); + qglProgramUniform3f = (void *)SDL_GL_GetProcAddress("glProgramUniform3fEXT"); + qglProgramUniform4f = (void *)SDL_GL_GetProcAddress("glProgramUniform4fEXT"); + qglProgramUniform1fv = (void *)SDL_GL_GetProcAddress("glProgramUniform1fvEXT"); + qglProgramUniformMatrix4fv = (void *)SDL_GL_GetProcAddress("glProgramUniformMatrix4fvEXT"); } ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess ? 1 : 0], extension); diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index 14e20105..eaa7c8f5 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -22,7 +22,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_glsl.c #include "tr_local.h" -void GLSL_BindNullProgram(void); +#include "tr_dsa.h" extern const char *fallbackShader_bokeh_vp; extern const char *fallbackShader_bokeh_fp; @@ -482,11 +482,6 @@ static void GLSL_ShowProgramUniforms(GLhandleARB program) GLenum type; char uniformName[1000]; - // install the executables in the program object as part of current state. - qglUseProgramObjectARB(program); - - // check for GL Errors - // query the number of active uniforms qglGetObjectParameterivARB(program, GL_OBJECT_ACTIVE_UNIFORMS_ARB, &count); @@ -497,8 +492,6 @@ static void GLSL_ShowProgramUniforms(GLhandleARB program) ri.Printf(PRINT_DEVELOPER, "active uniform: '%s'\n", uniformName); } - - qglUseProgramObjectARB(0); } static int GLSL_InitGPUShader2(shaderProgram_t * program, const char *name, int attribs, const char *vpCode, const char *fpCode) @@ -703,7 +696,7 @@ void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value) *compare = value; - qglUniform1iARB(uniforms[uniformNum], value); + qglProgramUniform1i(program->program, uniforms[uniformNum], value); } void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value) @@ -727,7 +720,7 @@ void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat valu *compare = value; - qglUniform1fARB(uniforms[uniformNum], value); + qglProgramUniform1f(program->program, uniforms[uniformNum], value); } void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t v) @@ -752,7 +745,7 @@ void GLSL_SetUniformVec2(shaderProgram_t *program, int uniformNum, const vec2_t compare[0] = v[0]; compare[1] = v[1]; - qglUniform2fARB(uniforms[uniformNum], v[0], v[1]); + qglProgramUniform2f(program->program, uniforms[uniformNum], v[0], v[1]); } void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t v) @@ -776,7 +769,7 @@ void GLSL_SetUniformVec3(shaderProgram_t *program, int uniformNum, const vec3_t VectorCopy(v, compare); - qglUniform3fARB(uniforms[uniformNum], v[0], v[1], v[2]); + qglProgramUniform3f(program->program, uniforms[uniformNum], v[0], v[1], v[2]); } void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t v) @@ -800,7 +793,7 @@ void GLSL_SetUniformVec4(shaderProgram_t *program, int uniformNum, const vec4_t VectorCopy4(v, compare); - qglUniform4fARB(uniforms[uniformNum], v[0], v[1], v[2], v[3]); + qglProgramUniform4f(program->program, uniforms[uniformNum], v[0], v[1], v[2], v[3]); } void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_t v) @@ -824,7 +817,7 @@ void GLSL_SetUniformFloat5(shaderProgram_t *program, int uniformNum, const vec5_ VectorCopy5(v, compare); - qglUniform1fvARB(uniforms[uniformNum], 5, v); + qglProgramUniform1fv(program->program, uniforms[uniformNum], 5, v); } void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t matrix) @@ -848,7 +841,7 @@ void GLSL_SetUniformMat4(shaderProgram_t *program, int uniformNum, const mat4_t Mat4Copy(matrix, compare); - qglUniformMatrix4fvARB(uniforms[uniformNum], 1, GL_FALSE, matrix); + qglProgramUniformMatrix4fv(program->program, uniforms[uniformNum], 1, GL_FALSE, matrix); } void GLSL_DeleteGPUShader(shaderProgram_t *program) @@ -925,10 +918,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.genericShader[i]); - qglUseProgramObjectARB(tr.genericShader[i].program); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.genericShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.genericShader[i]); @@ -945,9 +936,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.textureColorShader); - qglUseProgramObjectARB(tr.textureColorShader.program); GLSL_SetUniformInt(&tr.textureColorShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.textureColorShader); @@ -993,9 +982,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.dlightShader[i]); - qglUseProgramObjectARB(tr.dlightShader[i].program); GLSL_SetUniformInt(&tr.dlightShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.dlightShader[i]); @@ -1123,7 +1110,6 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.lightallShader[i]); - qglUseProgramObjectARB(tr.lightallShader[i].program); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_DIFFUSEMAP, TB_DIFFUSEMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_LIGHTMAP, TB_LIGHTMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_NORMALMAP, TB_NORMALMAP); @@ -1131,7 +1117,6 @@ void GLSL_InitGPUShaders(void) GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SPECULARMAP, TB_SPECULARMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.lightallShader[i], UNIFORM_CUBEMAP, TB_CUBEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.lightallShader[i]); @@ -1164,9 +1149,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.pshadowShader); - qglUseProgramObjectARB(tr.pshadowShader.program); GLSL_SetUniformInt(&tr.pshadowShader, UNIFORM_SHADOWMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.pshadowShader); @@ -1183,9 +1166,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.down4xShader); - qglUseProgramObjectARB(tr.down4xShader.program); GLSL_SetUniformInt(&tr.down4xShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.down4xShader); @@ -1202,9 +1183,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.bokehShader); - qglUseProgramObjectARB(tr.bokehShader.program); GLSL_SetUniformInt(&tr.bokehShader, UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.bokehShader); @@ -1221,10 +1200,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.tonemapShader); - qglUseProgramObjectARB(tr.tonemapShader.program); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.tonemapShader, UNIFORM_LEVELSMAP, TB_LEVELSMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.tonemapShader); @@ -1246,9 +1223,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.calclevels4xShader[i]); - qglUseProgramObjectARB(tr.calclevels4xShader[i].program); GLSL_SetUniformInt(&tr.calclevels4xShader[i], UNIFORM_TEXTUREMAP, TB_DIFFUSEMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.calclevels4xShader[i]); @@ -1279,13 +1254,11 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.shadowmaskShader); - qglUseProgramObjectARB(tr.shadowmaskShader.program); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP, TB_SHADOWMAP); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP2, TB_SHADOWMAP2); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP3, TB_SHADOWMAP3); GLSL_SetUniformInt(&tr.shadowmaskShader, UNIFORM_SHADOWMAP4, TB_SHADOWMAP4); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.shadowmaskShader); @@ -1302,9 +1275,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.ssaoShader); - qglUseProgramObjectARB(tr.ssaoShader.program); GLSL_SetUniformInt(&tr.ssaoShader, UNIFORM_SCREENDEPTHMAP, TB_COLORMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.ssaoShader); @@ -1329,10 +1300,8 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.depthBlurShader[i]); - qglUseProgramObjectARB(tr.depthBlurShader[i].program); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENIMAGEMAP, TB_COLORMAP); GLSL_SetUniformInt(&tr.depthBlurShader[i], UNIFORM_SCREENDEPTHMAP, TB_LIGHTMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.depthBlurShader[i]); @@ -1350,9 +1319,7 @@ void GLSL_InitGPUShaders(void) GLSL_InitUniforms(&tr.testcubeShader); - qglUseProgramObjectARB(tr.testcubeShader.program); GLSL_SetUniformInt(&tr.testcubeShader, UNIFORM_TEXTUREMAP, TB_COLORMAP); - qglUseProgramObjectARB(0); GLSL_FinishGPUShader(&tr.testcubeShader); @@ -1376,7 +1343,7 @@ void GLSL_ShutdownGPUShaders(void) for (i = 0; i < ATTR_INDEX_COUNT; i++) qglDisableVertexAttribArrayARB(i); - GLSL_BindNullProgram(); + GL_BindNullProgram(); for ( i = 0; i < GENERICDEF_COUNT; i++) GLSL_DeleteGPUShader(&tr.genericShader[i]); @@ -1406,47 +1373,22 @@ void GLSL_ShutdownGPUShaders(void) for ( i = 0; i < 2; i++) GLSL_DeleteGPUShader(&tr.depthBlurShader[i]); - - glState.currentProgram = 0; - qglUseProgramObjectARB(0); } void GLSL_BindProgram(shaderProgram_t * program) { - if(!program) - { - GLSL_BindNullProgram(); - return; - } + GLuint programObject = program ? program->program : 0; + char *name = program ? program->name : "NULL"; if(r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! - GLimp_LogComment(va("--- GL_BindProgram( %s ) ---\n", program->name)); + GLimp_LogComment(va("--- GLSL_BindProgram( %s ) ---\n", name)); } - if(glState.currentProgram != program) - { - qglUseProgramObjectARB(program->program); - glState.currentProgram = program; + if (GL_UseProgramObject(programObject)) backEnd.pc.c_glslShaderBinds++; - } -} - - -void GLSL_BindNullProgram(void) -{ - if(r_logFile->integer) - { - GLimp_LogComment("--- GL_BindNullProgram ---\n"); - } - - if(glState.currentProgram) - { - qglUseProgramObjectARB(0); - glState.currentProgram = NULL; - } } diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 05b00465..8e27c620 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -902,8 +902,7 @@ void GL_SetDefaultState( void ) glState.faceCulling = CT_TWO_SIDED; glState.faceCullFront = qtrue; - glState.currentProgram = 0; - qglUseProgramObjectARB(0); + GL_BindNullProgram(); if (glRefConfig.vertexArrayObject) qglBindVertexArrayARB(0); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 0dd61674..f56d5f51 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1361,7 +1361,6 @@ typedef struct { float vertexAttribsInterpolation; qboolean vertexAnimation; uint32_t vertexAttribsEnabled; // global if no VAOs, tess only otherwise - shaderProgram_t *currentProgram; FBO_t *currentFBO; vao_t *currentVao; mat4_t modelview; @@ -2215,7 +2214,6 @@ void GLSL_InitGPUShaders(void); void GLSL_ShutdownGPUShaders(void); void GLSL_VertexAttribPointers(uint32_t attribBits); void GLSL_BindProgram(shaderProgram_t * program); -void GLSL_BindNullProgram(void); void GLSL_SetUniformInt(shaderProgram_t *program, int uniformNum, GLint value); void GLSL_SetUniformFloat(shaderProgram_t *program, int uniformNum, GLfloat value); -- cgit From 1adb3a37252948d4e3bc65fafbb3438cb027458f Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 20 Jan 2016 06:32:50 -0800 Subject: OpenGL2: Direct state access, part 3: Framebuffers. --- src/renderergl2/tr_dsa.c | 85 ++++++++++++ src/renderergl2/tr_dsa.h | 17 +++ src/renderergl2/tr_extensions.c | 25 ++++ src/renderergl2/tr_fbo.c | 287 +++++++--------------------------------- src/renderergl2/tr_init.c | 1 + 5 files changed, 177 insertions(+), 238 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_dsa.c b/src/renderergl2/tr_dsa.c index 9472bb40..aeb39d78 100644 --- a/src/renderergl2/tr_dsa.c +++ b/src/renderergl2/tr_dsa.c @@ -28,6 +28,10 @@ static struct GLenum texunit; GLuint program; + + GLuint drawFramebuffer; + GLuint readFramebuffer; + GLuint renderbuffer; } glDsaState; @@ -197,3 +201,84 @@ GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, GL_UseProgramObject(program); qglUniformMatrix4fvARB(location, count, transpose, value); } + +void GL_BindNullFramebuffers() +{ + qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0; + qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); + glDsaState.readFramebuffer = 0; +} + +void GL_BindFramebuffer(GLenum target, GLuint framebuffer) +{ + switch (target) + { + case GL_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.drawFramebuffer || framebuffer != glDsaState.readFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.drawFramebuffer = glDsaState.readFramebuffer = framebuffer; + } + break; + + case GL_DRAW_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.drawFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.drawFramebuffer = framebuffer; + } + break; + + case GL_READ_FRAMEBUFFER_EXT: + if (framebuffer != glDsaState.readFramebuffer) + { + qglBindFramebufferEXT(target, framebuffer); + glDsaState.readFramebuffer = framebuffer; + } + break; + } +} + +void GL_BindRenderbuffer(GLuint renderbuffer) +{ + if (renderbuffer != glDsaState.renderbuffer) + { + qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, renderbuffer); + glDsaState.renderbuffer = renderbuffer; + } +} + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorage(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height) +{ + GL_BindRenderbuffer(renderbuffer); + qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, internalformat, width, height); +} + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisample(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height) +{ + GL_BindRenderbuffer(renderbuffer); + qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, samples, internalformat, width, height); +} + +GLenum APIENTRY GLDSA_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target) +{ + GL_BindFramebuffer(target, framebuffer); + return qglCheckFramebufferStatusEXT(target); +} + +GLvoid APIENTRY GLDSA_NamedFramebufferTexture2D(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level) +{ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); + qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, attachment, textarget, texture, level); +} + +GLvoid APIENTRY GLDSA_NamedFramebufferRenderbuffer(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer) +{ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, framebuffer); + qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, renderbuffertarget, renderbuffer); +} diff --git a/src/renderergl2/tr_dsa.h b/src/renderergl2/tr_dsa.h index 164ab065..e820fe00 100644 --- a/src/renderergl2/tr_dsa.h +++ b/src/renderergl2/tr_dsa.h @@ -60,4 +60,21 @@ GLvoid APIENTRY GLDSA_ProgramUniformMatrix4fv(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +void GL_BindNullFramebuffers(void); +void GL_BindFramebuffer(GLenum target, GLuint framebuffer); +void GL_BindRenderbuffer(GLuint renderbuffer); + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorage(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +GLvoid APIENTRY GLDSA_NamedRenderbufferStorageMultisample(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +GLenum APIENTRY GLDSA_CheckNamedFramebufferStatus(GLuint framebuffer, GLenum target); +GLvoid APIENTRY GLDSA_NamedFramebufferTexture2D(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLvoid APIENTRY GLDSA_NamedFramebufferRenderbuffer(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + #endif diff --git a/src/renderergl2/tr_extensions.c b/src/renderergl2/tr_extensions.c index bb668da2..2972aaef 100644 --- a/src/renderergl2/tr_extensions.c +++ b/src/renderergl2/tr_extensions.c @@ -216,6 +216,19 @@ GLvoid(APIENTRY * qglProgramUniformMatrix4fv)(GLuint program, GLint location, GLsizei count, GLboolean transpose, const GLfloat *value); +GLvoid(APIENTRY * qglNamedRenderbufferStorage)(GLuint renderbuffer, + GLenum internalformat, GLsizei width, GLsizei height); + +GLvoid(APIENTRY * qglNamedRenderbufferStorageMultisample)(GLuint renderbuffer, + GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height); + +GLenum(APIENTRY * qglCheckNamedFramebufferStatus)(GLuint framebuffer, GLenum target); +GLvoid(APIENTRY * qglNamedFramebufferTexture2D)(GLuint framebuffer, + GLenum attachment, GLenum textarget, GLuint texture, GLint level); +GLvoid(APIENTRY * qglNamedFramebufferRenderbuffer)(GLuint framebuffer, + GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); + + static qboolean GLimp_HaveExtension(const char *ext) { const char *ptr = Q_stristr( glConfig.extensions_string, ext ); @@ -803,6 +816,12 @@ void GLimp_InitExtraExtensions() qglProgramUniform1fv = GLDSA_ProgramUniform1fv; qglProgramUniformMatrix4fv = GLDSA_ProgramUniformMatrix4fv; + qglNamedRenderbufferStorage = GLDSA_NamedRenderbufferStorage; + qglNamedRenderbufferStorageMultisample = GLDSA_NamedRenderbufferStorageMultisample; + qglCheckNamedFramebufferStatus = GLDSA_CheckNamedFramebufferStatus; + qglNamedFramebufferTexture2D = GLDSA_NamedFramebufferTexture2D; + qglNamedFramebufferRenderbuffer = GLDSA_NamedFramebufferRenderbuffer; + glRefConfig.directStateAccess = qfalse; if (GLimp_HaveExtension(extension)) { @@ -826,6 +845,12 @@ void GLimp_InitExtraExtensions() qglProgramUniform4f = (void *)SDL_GL_GetProcAddress("glProgramUniform4fEXT"); qglProgramUniform1fv = (void *)SDL_GL_GetProcAddress("glProgramUniform1fvEXT"); qglProgramUniformMatrix4fv = (void *)SDL_GL_GetProcAddress("glProgramUniformMatrix4fvEXT"); + + qglNamedRenderbufferStorage = (void *)SDL_GL_GetProcAddress("glNamedRenderbufferStorageEXT"); + qglNamedRenderbufferStorageMultisample = (void *)SDL_GL_GetProcAddress("glNamedRenderbufferStorageMultisampleEXT"); + qglCheckNamedFramebufferStatus = (void *)SDL_GL_GetProcAddress("glCheckNamedFramebufferStatusEXT"); + qglNamedFramebufferTexture2D = (void *)SDL_GL_GetProcAddress("glNamedFramebufferTexture2DEXT"); + qglNamedFramebufferRenderbuffer = (void *)SDL_GL_GetProcAddress("glNamedFramebufferRenderbufferEXT"); } ri.Printf(PRINT_ALL, result[glRefConfig.directStateAccess ? 1 : 0], extension); diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index c8ea0aeb..6ee533f3 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -23,6 +23,8 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA // tr_fbo.c #include "tr_local.h" +#include "tr_dsa.h" + /* ============= R_CheckFBO @@ -30,19 +32,10 @@ R_CheckFBO */ qboolean R_CheckFBO(const FBO_t * fbo) { - int code; - int id; - - qglGetIntegerv(GL_FRAMEBUFFER_BINDING_EXT, &id); - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer); - - code = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT); + GLenum code = qglCheckNamedFramebufferStatus(fbo->frameBuffer, GL_FRAMEBUFFER_EXT); if(code == GL_FRAMEBUFFER_COMPLETE_EXT) - { - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); return qtrue; - } // an error occured switch (code) @@ -83,13 +76,9 @@ qboolean R_CheckFBO(const FBO_t * fbo) default: ri.Printf(PRINT_WARNING, "R_CheckFBO: (%s) unknown error 0x%X\n", fbo->name, code); - //ri.Error(ERR_FATAL, "R_CheckFBO: (%s) unknown error 0x%X", fbo->name, code); - //assert(0); break; } - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, id); - return qfalse; } @@ -133,6 +122,11 @@ FBO_t *FBO_Create(const char *name, int width, int height) return fbo; } +/* +================= +FBO_CreateBuffer +================= +*/ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample) { uint32_t *pRenderBuffer; @@ -189,115 +183,45 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample) if (absent) qglGenRenderbuffersEXT(1, pRenderBuffer); - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, *pRenderBuffer); if (multisample && glRefConfig.framebufferMultisample) - { - qglRenderbufferStorageMultisampleEXT(GL_RENDERBUFFER_EXT, multisample, format, fbo->width, fbo->height); - } + qglNamedRenderbufferStorageMultisample(*pRenderBuffer, multisample, format, fbo->width, fbo->height); else - { - qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, format, fbo->width, fbo->height); - } + qglNamedRenderbufferStorage(*pRenderBuffer, format, fbo->width, fbo->height); if(absent) { if (attachment == 0) { - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, GL_STENCIL_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, *pRenderBuffer); } else - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer); + { + qglNamedFramebufferRenderbuffer(fbo->frameBuffer, attachment, GL_RENDERBUFFER_EXT, *pRenderBuffer); + } } } /* ================= -R_AttachFBOTexture1D +FBO_AttachImage ================= */ -void R_AttachFBOTexture1D(int texId, int index) +void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment) { - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture1D: invalid attachment index %i\n", index); - return; - } + GLenum target = GL_TEXTURE_2D; + int index; - qglFramebufferTexture1DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_1D, texId, 0); -} + if (image->flags & IMGFLAG_CUBEMAP) + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; -/* -================= -R_AttachFBOTexture2D -================= -*/ -void R_AttachFBOTexture2D(int target, int texId, int index) -{ - if(target != GL_TEXTURE_2D && (target < GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB || target > GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_ARB)) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid target %i\n", target); - return; - } - - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture2D: invalid attachment index %i\n", index); - return; - } - - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, target, texId, 0); -} - -/* -================= -R_AttachFBOTexture3D -================= -*/ -void R_AttachFBOTexture3D(int texId, int index, int zOffset) -{ - if(index < 0 || index >= glRefConfig.maxColorAttachments) - { - ri.Printf(PRINT_WARNING, "R_AttachFBOTexture3D: invalid attachment index %i\n", index); - return; - } - - qglFramebufferTexture3DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT + index, GL_TEXTURE_3D_EXT, texId, 0, zOffset); -} - -/* -================= -R_AttachFBOTextureDepth -================= -*/ -void R_AttachFBOTextureDepth(int texId) -{ - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); + qglNamedFramebufferTexture2D(fbo->frameBuffer, attachment, target, image->texnum, 0); + index = attachment - GL_COLOR_ATTACHMENT0_EXT; + if (index >= 0 && index <= 15) + fbo->colorImage[index] = image; } -/* -================= -R_AttachFBOTexturePackedDepthStencil -================= -*/ -void R_AttachFBOTexturePackedDepthStencil(int texId) -{ - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_STENCIL_ATTACHMENT_EXT, GL_TEXTURE_2D, texId, 0); -} - -void FBO_AttachTextureImage(image_t *img, int index) -{ - if (!glState.currentFBO) - { - ri.Printf(PRINT_WARNING, "FBO: attempted to attach a texture image with no FBO bound!\n"); - return; - } - - R_AttachFBOTexture2D(GL_TEXTURE_2D, img->texnum, index); - glState.currentFBO->colorImage[index] = img; -} /* ============ @@ -312,38 +236,10 @@ void FBO_Bind(FBO_t * fbo) if (r_logFile->integer) { // don't just call LogComment, or we will get a call to va() every frame! - if (fbo) - GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo->name)); - else - GLimp_LogComment("--- FBO_Bind ( NULL ) ---\n"); - } - - if (!fbo) - { - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); - //qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - glState.currentFBO = NULL; - - return; + GLimp_LogComment(va("--- FBO_Bind( %s ) ---\n", fbo ? fbo->name : "NULL")); } - - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, fbo->frameBuffer); - - /* - if(fbo->colorBuffers[0]) - { - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->colorBuffers[0]); - } - */ - - /* - if(fbo->depthBuffer) - { - qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, fbo->depthBuffer); - qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, fbo->depthBuffer); - } - */ + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, fbo ? fbo->frameBuffer : 0); glState.currentFBO = fbo; } @@ -355,7 +251,6 @@ FBO_Init void FBO_Init(void) { int i; - // int width, height, hdrFormat, multisample; int hdrFormat, multisample; ri.Printf(PRINT_ALL, "------- FBO_Init -------\n"); @@ -369,73 +264,40 @@ void FBO_Init(void) R_IssuePendingRenderCommands(); -/* if(glRefConfig.textureNonPowerOfTwo) - { - width = glConfig.vidWidth; - height = glConfig.vidHeight; - } - else - { - width = NextPowerOfTwo(glConfig.vidWidth); - height = NextPowerOfTwo(glConfig.vidHeight); - } */ - hdrFormat = GL_RGBA8; if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) - { 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 || !glRefConfig.framebufferBlit) multisample = 0; if (multisample != r_ext_framebuffer_multisample->integer) - { ri.Cvar_SetValue("r_ext_framebuffer_multisample", (float)multisample); - } // only create a render FBO if we need to resolve MSAA or do HDR // otherwise just render straight to the screen (tr.renderFbo = NULL) if (multisample && glRefConfig.framebufferMultisample) { tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.renderFbo); - 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_CreateBuffer(tr.msaaResolveFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - + FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); R_CheckFBO(tr.msaaResolveFbo); } else if (r_hdr->integer) { 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); - + FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); R_CheckFBO(tr.renderFbo); } @@ -443,20 +305,15 @@ void FBO_Init(void) // this fixes the corrupt screen bug with r_hdr 1 on older hardware if (tr.renderFbo) { - FBO_Bind(tr.renderFbo); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, tr.renderFbo->frameBuffer); qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); - FBO_Bind(NULL); } if (r_drawSunRays->integer) { tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_Bind(tr.sunRaysFbo); - - FBO_AttachTextureImage(tr.sunRaysImage, 0); - - R_AttachFBOTextureDepth(tr.renderDepthImage->texnum); - + FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); R_CheckFBO(tr.sunRaysFbo); } @@ -466,14 +323,8 @@ void FBO_Init(void) for( i = 0; i < MAX_DRAWN_PSHADOWS; i++) { tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height); - FBO_Bind(tr.pshadowFbos[i]); - - //FBO_CreateBuffer(tr.pshadowFbos[i], GL_RGBA8, 0, 0); - FBO_AttachTextureImage(tr.pshadowMaps[i], 0); - + FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT); FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0); - //R_AttachFBOTextureDepth(tr.textureDepthImage->texnum); - R_CheckFBO(tr.pshadowFbos[i]); } } @@ -483,104 +334,64 @@ void FBO_Init(void) for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); - FBO_Bind(tr.sunShadowFbo[i]); - - //FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0); - //FBO_AttachTextureImage(tr.sunShadowImage, 0); - qglDrawBuffer(GL_NONE); - qglReadBuffer(GL_NONE); - - //FBO_CreateBuffer(tr.sunShadowFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_AttachFBOTextureDepth(tr.sunShadowDepthImage[i]->texnum); - + FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT); R_CheckFBO(tr.sunShadowFbo[i]); - } tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height); - FBO_Bind(tr.screenShadowFbo); - - FBO_AttachTextureImage(tr.screenShadowImage, 0); - + FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.screenShadowFbo); } for (i = 0; i < 2; i++) { tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); - FBO_Bind(tr.textureScratchFbo[i]); - - //FBO_CreateBuffer(tr.textureScratchFbo[i], GL_RGBA8, 0, 0); - FBO_AttachTextureImage(tr.textureScratchImage[i], 0); - + FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.textureScratchFbo[i]); } { tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height); - FBO_Bind(tr.calcLevelsFbo); - - //FBO_CreateBuffer(tr.calcLevelsFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.calcLevelsImage, 0); - + FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.calcLevelsFbo); } { tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height); - FBO_Bind(tr.targetLevelsFbo); - - //FBO_CreateBuffer(tr.targetLevelsFbo, hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.targetLevelsImage, 0); - + FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.targetLevelsFbo); } for (i = 0; i < 2; i++) { tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); - FBO_Bind(tr.quarterFbo[i]); - - //FBO_CreateBuffer(tr.quarterFbo[i], hdrFormat, 0, 0); - FBO_AttachTextureImage(tr.quarterImage[i], 0); - + FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.quarterFbo[i]); } if (r_ssao->integer) { tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height); - FBO_Bind(tr.hdrDepthFbo); - - FBO_AttachTextureImage(tr.hdrDepthImage, 0); - + FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.hdrDepthFbo); tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height); - FBO_Bind(tr.screenSsaoFbo); - - FBO_AttachTextureImage(tr.screenSsaoImage, 0); - + FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT); R_CheckFBO(tr.screenSsaoFbo); } if (tr.renderCubeImage) { tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height); - FBO_Bind(tr.renderCubeFbo); - - //FBO_AttachTextureImage(tr.renderCubeImage, 0); - R_AttachFBOTexture2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB, tr.renderCubeImage->texnum, 0); - glState.currentFBO->colorImage[0] = tr.renderCubeImage; - + FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT); FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); - R_CheckFBO(tr.renderCubeFbo); } GL_CheckErrors(); - FBO_Bind(NULL); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0); + glState.currentFBO = NULL; } /* @@ -849,12 +660,12 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu VectorSet4(dstBoxFinal, dstBox[0], dstBox[1], dstBox[0] + dstBox[2], dstBox[1] + dstBox[3]); } - qglBindFramebufferEXT(GL_READ_FRAMEBUFFER_EXT, srcFb); - qglBindFramebufferEXT(GL_DRAW_FRAMEBUFFER_EXT, dstFb); + GL_BindFramebuffer(GL_READ_FRAMEBUFFER_EXT, srcFb); + GL_BindFramebuffer(GL_DRAW_FRAMEBUFFER_EXT, dstFb); qglBlitFramebufferEXT(srcBoxFinal[0], srcBoxFinal[1], srcBoxFinal[2], srcBoxFinal[3], dstBoxFinal[0], dstBoxFinal[1], dstBoxFinal[2], dstBoxFinal[3], buffers, filter); - qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); + GL_BindFramebuffer(GL_FRAMEBUFFER_EXT, 0); glState.currentFBO = NULL; } diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 8e27c620..0c02f887 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -887,6 +887,7 @@ void GL_SetDefaultState( void ) qglColor4f (1,1,1,1); GL_BindNullTextures(); + GL_BindNullFramebuffers(); qglEnable(GL_TEXTURE_2D); GL_TextureMode( r_textureMode->string ); -- cgit From 8032873df3b9f0ca2498cf79c3874a50406cc427 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 21 Jan 2016 22:31:41 -0800 Subject: OpenGL2: Some FBO related cleanup/fixes. --- src/renderergl2/tr_backend.c | 52 +++++-------------- src/renderergl2/tr_fbo.c | 39 ++++++++------- src/renderergl2/tr_fbo.h | 1 + src/renderergl2/tr_postprocess.c | 105 ++++++++++++++++----------------------- 4 files changed, 77 insertions(+), 120 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index e6dd3cfa..ae475b02 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -21,6 +21,7 @@ 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; @@ -378,31 +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) - { - cubemap_t *cubemap = &tr.cubemaps[backEnd.viewParms.targetFboCubemapIndex]; - //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, cubemap->image->texnum, 0); - } - } + FBO_Bind(fbo); } // @@ -781,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(); @@ -874,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(); @@ -1696,7 +1670,7 @@ const void *RB_ExportCubemaps(const void *data) for (j = 0; j < 6; j++) { - qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_CUBE_MAP_POSITIVE_X + j, cubemap->image->texnum, 0); + 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; } diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index 6ee533f3..59b17032 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -208,13 +208,13 @@ void FBO_CreateBuffer(FBO_t *fbo, int format, int index, int multisample) FBO_AttachImage ================= */ -void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment) +void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside) { GLenum target = GL_TEXTURE_2D; int index; if (image->flags & IMGFLAG_CUBEMAP) - target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB; + target = GL_TEXTURE_CUBE_MAP_POSITIVE_X_ARB + cubemapside; qglNamedFramebufferTexture2D(fbo->frameBuffer, attachment, target, image->texnum, 0); index = attachment - GL_COLOR_ATTACHMENT0_EXT; @@ -289,15 +289,15 @@ void FBO_Init(void) R_CheckFBO(tr.renderFbo); tr.msaaResolveFbo = FBO_Create("_msaaResolve", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT); - FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); + FBO_AttachImage(tr.msaaResolveFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.msaaResolveFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.msaaResolveFbo); } else if (r_hdr->integer) { tr.renderFbo = FBO_Create("_render", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT); - FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); + FBO_AttachImage(tr.renderFbo, tr.renderImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.renderFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.renderFbo); } @@ -312,8 +312,8 @@ void FBO_Init(void) if (r_drawSunRays->integer) { tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); - FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT); - FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT); + FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.sunRaysFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunRaysFbo); } @@ -323,7 +323,7 @@ void FBO_Init(void) for( i = 0; i < MAX_DRAWN_PSHADOWS; i++) { tr.pshadowFbos[i] = FBO_Create(va("_shadowmap%d", i), tr.pshadowMaps[i]->width, tr.pshadowMaps[i]->height); - FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.pshadowFbos[i], tr.pshadowMaps[i], GL_COLOR_ATTACHMENT0_EXT, 0); FBO_CreateBuffer(tr.pshadowFbos[i], GL_DEPTH_COMPONENT24_ARB, 0, 0); R_CheckFBO(tr.pshadowFbos[i]); } @@ -334,56 +334,56 @@ void FBO_Init(void) for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); - FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT); + FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunShadowFbo[i]); } tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height); - FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenShadowFbo); } for (i = 0; i < 2; i++) { tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); - FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.textureScratchFbo[i]); } { tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height); - FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.calcLevelsFbo); } { tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height); - FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.targetLevelsFbo); } for (i = 0; i < 2; i++) { tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); - FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.quarterFbo[i]); } if (r_ssao->integer) { tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height); - FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.hdrDepthFbo); tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height); - FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenSsaoFbo); } if (tr.renderCubeImage) { tr.renderCubeFbo = FBO_Create("_renderCubeFbo", tr.renderCubeImage->width, tr.renderCubeImage->height); - FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT); + FBO_AttachImage(tr.renderCubeFbo, tr.renderCubeImage, GL_COLOR_ATTACHMENT0_EXT, 0); FBO_CreateBuffer(tr.renderCubeFbo, GL_DEPTH_COMPONENT24_ARB, 0, 0); R_CheckFBO(tr.renderCubeFbo); } @@ -474,7 +474,10 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS int width, height; if (!src) + { + ri.Printf(PRINT_WARNING, "Tried to blit from a NULL texture!\n"); return; + } if (inSrcBox) { diff --git a/src/renderergl2/tr_fbo.h b/src/renderergl2/tr_fbo.h index 530fee5c..72b2c911 100644 --- a/src/renderergl2/tr_fbo.h +++ b/src/renderergl2/tr_fbo.h @@ -52,6 +52,7 @@ typedef struct FBO_s int height; } FBO_t; +void FBO_AttachImage(FBO_t *fbo, image_t *image, GLenum attachment, GLuint cubemapside); void FBO_Bind(FBO_t *fbo); void FBO_Init(void); void FBO_Shutdown(void); diff --git a/src/renderergl2/tr_postprocess.c b/src/renderergl2/tr_postprocess.c index 35982fce..1952ae96 100644 --- a/src/renderergl2/tr_postprocess.c +++ b/src/renderergl2/tr_postprocess.c @@ -183,7 +183,7 @@ void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float FBO_Blit(tr.textureScratchFbo[0], NULL, blurTexScale, tr.textureScratchFbo[1], NULL, &tr.bokehShader, color, 0); } - FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, &tr.textureColorShader, NULL, 0); + FBO_Blit(tr.textureScratchFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0); } #else // higher quality blur, but slower else if (blur > 1.0f) @@ -217,7 +217,7 @@ void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float 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, dst, dstBox, &tr.textureColorShader, NULL, 0); + FBO_Blit(tr.quarterFbo[1], NULL, NULL, dst, dstBox, NULL, NULL, 0); } #endif } @@ -232,49 +232,44 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc const float mul = powf(stretch, inc); float scale; - { - vec2_t texScale; + alpha *= inc; + VectorSet4(color, alpha, alpha, alpha, 1.0f); - texScale[0] = - texScale[1] = 1.0f; + if (srcFbo) + VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); + else + VectorSet4(srcBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - alpha *= inc; - VectorSet4(color, alpha, alpha, alpha, 1.0f); + VectorSet4(dstBox, x, y, w, h); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0); - 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); - --passes; - scale = mul; - while (passes > 0) + if (srcFbo) { - 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; - - if (srcFbo) - { - srcBox[0] = s0 * srcFbo->width; - srcBox[1] = t0 * srcFbo->height; - srcBox[2] = (s1 - s0) * srcFbo->width; - srcBox[3] = (t1 - t0) * srcFbo->height; - } - else - { - srcBox[0] = s0 * glConfig.vidWidth; - srcBox[1] = t0 * glConfig.vidHeight; - srcBox[2] = (s1 - s0) * glConfig.vidWidth; - srcBox[3] = (t1 - t0) * glConfig.vidHeight; - } + srcBox[0] = s0 * srcFbo->width; + srcBox[1] = t0 * srcFbo->height; + srcBox[2] = iscale * srcFbo->width; + srcBox[3] = iscale * srcFbo->height; + } + else + { + srcBox[0] = s0 * glConfig.vidWidth; + srcBox[1] = t0 * glConfig.vidHeight; + srcBox[2] = iscale * glConfig.vidWidth; + srcBox[3] = iscale * glConfig.vidHeight; + } - FBO_Blit(srcFbo, srcBox, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); - scale *= mul; - --passes; - } + scale *= mul; + --passes; } } @@ -329,7 +324,7 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // From RB_DrawSun() { float dist; - mat4_t trans, model, mvp; + mat4_t trans, model; Mat4Translation( backEnd.viewParms.or.origin, trans ); Mat4Multiply( backEnd.viewParms.world.modelMatrix, trans, model ); @@ -353,12 +348,8 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // initialize quarter buffers { float mul = 1.f; - vec2_t texScale; ivec4_t rayBox, quarterBox; - texScale[0] = - texScale[1] = 1.0f; - VectorSet4(color, mul, mul, mul, 1); if (srcFbo) @@ -408,14 +399,10 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) // 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); - FBO_Blit(tr.quarterFbo[0], NULL, texScale, dstFbo, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); + FBO_Blit(tr.quarterFbo[0], NULL, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); } } @@ -443,31 +430,27 @@ static void RB_BlurAxis(FBO_t *srcFbo, FBO_t *dstFbo, float strength, qboolean h { ivec4_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 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, 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 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, 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 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, 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 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, 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 ); + FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE); } } @@ -492,10 +475,6 @@ void RB_GaussianBlur(float blur) { ivec4_t srcBox, dstBox; vec4_t color; - vec2_t texScale; - - texScale[0] = - texScale[1] = 1.0f; VectorSet4(color, 1, 1, 1, 1); @@ -507,7 +486,7 @@ void RB_GaussianBlur(float blur) 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); + FBO_BlitFromTexture(tr.whiteImage, srcBox, NULL, tr.textureScratchFbo[0], dstBox, NULL, color, GLS_DEPTHTEST_DISABLE); qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // blur the tiny buffer horizontally and vertically @@ -518,6 +497,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, texScale, NULL, dstBox, &tr.textureColorShader, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); + FBO_Blit(tr.textureScratchFbo[0], srcBox, NULL, NULL, dstBox, NULL, color, GLS_SRCBLEND_SRC_ALPHA | GLS_DSTBLEND_ONE_MINUS_SRC_ALPHA); } } -- cgit From 9f1aa0dfc09915681d66d16c6bce7768a280a08a Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 28 Jan 2016 16:39:42 -0800 Subject: OpenGL2: Load existing per-map cubemaps. --- src/renderergl2/tr_bsp.c | 39 ++++-- src/renderergl2/tr_dsa.c | 3 + src/renderergl2/tr_image.c | 317 +++++++++++++++++++++++---------------------- 3 files changed, 196 insertions(+), 163 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index e0a97d4d..7e5493f3 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -3069,23 +3069,41 @@ void R_AssignCubemapsToWorldSurfaces(void) } -void R_RenderAllCubemaps(void) +void R_LoadCubemaps(void) { - int i, j; + int i; + imgFlags_t flags = IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP; for (i = 0; i < tr.numCubemaps; i++) { - tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_CUBEMAP, GL_RGBA8); + char filename[MAX_QPATH]; + cubemap_t *cubemap = &tr.cubemaps[i]; + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); + + cubemap->image = R_FindImageFile(filename, IMGTYPE_COLORALPHA, flags); } +} + + +void R_RenderMissingCubemaps(void) +{ + int i, j; + imgFlags_t flags = IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE | IMGFLAG_MIPMAP | IMGFLAG_NOLIGHTSCALE | IMGFLAG_CUBEMAP; for (i = 0; i < tr.numCubemaps; i++) { - for (j = 0; j < 6; j++) + if (!tr.cubemaps[i].image) { - RE_ClearScene(); - R_RenderCubemapSide(i, j, qfalse); - R_IssuePendingRenderCommands(); - R_InitNextFrame(); + tr.cubemaps[i].image = R_CreateImage(va("*cubeMap%d", i), NULL, r_cubemapSize->integer, r_cubemapSize->integer, IMGTYPE_COLORALPHA, flags, GL_RGBA8); + + for (j = 0; j < 6; j++) + { + RE_ClearScene(); + R_RenderCubemapSide(i, j, qfalse); + R_IssuePendingRenderCommands(); + R_InitNextFrame(); + } } } } @@ -3426,10 +3444,11 @@ void RE_LoadWorldMap( const char *name ) { // make sure the VAO glState entry is safe R_BindNullVao(); - // Render all cubemaps + // Render or load all cubemaps if (r_cubeMapping->integer && tr.numCubemaps) { - R_RenderAllCubemaps(); + R_LoadCubemaps(); + R_RenderMissingCubemaps(); } ri.FS_FreeFile( buffer.v ); diff --git a/src/renderergl2/tr_dsa.c b/src/renderergl2/tr_dsa.c index aeb39d78..a766263a 100644 --- a/src/renderergl2/tr_dsa.c +++ b/src/renderergl2/tr_dsa.c @@ -68,6 +68,9 @@ int GL_BindMultiTexture(GLenum texunit, GLenum target, GLuint texture) if (glDsaState.textures[tmu] == texture) return 0; + if (target >= GL_TEXTURE_CUBE_MAP_POSITIVE_X && target <= GL_TEXTURE_CUBE_MAP_NEGATIVE_Z) + target = GL_TEXTURE_CUBE_MAP; + qglBindMultiTexture(texunit, target, texture); glDsaState.textures[tmu] = texture; return 1; diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index aade799e..88335b7a 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -1864,82 +1864,57 @@ static void RawImage_UploadToRgtc2Texture(GLuint texture, byte *data, int width, ri.Hunk_FreeTempMemory(compressedData); } - -static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +static int CalculateMipSize(int width, int height, GLenum picFormat) { - int dataFormat, dataType; - qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + int numBlocks = ((width + 3) / 4) * ((height + 3) / 4); + int numPixels = width * height; - if (data && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + switch (picFormat) { - int bytesPer4x4Block = 0; - int miplevel = 0; - - switch (picFormat) - { - case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: - case GL_COMPRESSED_RED_RGTC1: - case GL_COMPRESSED_SIGNED_RED_RGTC1: - bytesPer4x4Block = 8; - break; - case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: - case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: - case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: - case GL_COMPRESSED_RG_RGTC2: - case GL_COMPRESSED_SIGNED_RG_RGTC2: - case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: - case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: - case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: - case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: - bytesPer4x4Block = 16; - break; - default: - ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); - return; - break; - } - - if (flags & IMGFLAG_PICMIP) - { - for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + case GL_COMPRESSED_RGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_S3TC_DXT1_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT1_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT1_EXT: + case GL_COMPRESSED_RED_RGTC1: + case GL_COMPRESSED_SIGNED_RED_RGTC1: + return numBlocks * 8; + + case GL_COMPRESSED_RGBA_S3TC_DXT3_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT3_EXT: + case GL_COMPRESSED_RGBA_S3TC_DXT5_EXT: + case GL_COMPRESSED_SRGB_ALPHA_S3TC_DXT5_EXT: + case GL_COMPRESSED_RG_RGTC2: + case GL_COMPRESSED_SIGNED_RG_RGTC2: + case GL_COMPRESSED_RGB_BPTC_UNSIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGB_BPTC_SIGNED_FLOAT_ARB: + case GL_COMPRESSED_RGBA_BPTC_UNORM_ARB: + case GL_COMPRESSED_SRGB_ALPHA_BPTC_UNORM_ARB: + return numBlocks * 16; + + case GL_RGBA8: + case GL_SRGB8_ALPHA8_EXT: + return numPixels * 4; - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } - } - - if (!(flags & IMGFLAG_MIPMAP)) - numMips = 1; - - for (miplevel = 0; miplevel < numMips; miplevel++) - { - int size = ((width + 3) / 4) * ((height + 3) / 4) * bytesPer4x4Block; + default: + ri.Printf(PRINT_ALL, "Unsupported texture format %08x\n", picFormat); + return 0; + } - if (subtexture) - qglCompressedTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, internalFormat, size, data); - else - qglCompressedTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, size, data); + return 0; +} - x >>= 1; - y >>= 1; - width = MAX(1, width >> 1); - height = MAX(1, height >> 1); - data += size; - } - return; - } +static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int width, int height, GLenum target, GLenum picFormat, int numMips, GLenum internalFormat, imgType_t type, imgFlags_t flags, qboolean subtexture ) +{ + int dataFormat, dataType; + qboolean rgtc = (internalFormat == GL_COMPRESSED_RG_RGTC2); + qboolean compressed = (!(picFormat == GL_RGBA8) || (picFormat == GL_SRGB8_ALPHA8_EXT)); + qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); + qboolean picmip = !!(flags & IMGFLAG_PICMIP); + int size, miplevel; + qboolean lastMip = qfalse; - switch(internalFormat) + switch (internalFormat) { case GL_DEPTH_COMPONENT: case GL_DEPTH_COMPONENT16_ARB: @@ -1958,52 +1933,83 @@ static void RawImage_UploadTexture(GLuint texture, byte *data, int x, int y, int break; } - if ( subtexture ) - qglTextureSubImage2D(texture, GL_TEXTURE_2D, 0, x, y, width, height, dataFormat, dataType, data ); - else + if (!data) { - if (rgtc) - RawImage_UploadToRgtc2Texture(texture, data, width, height, 0); - else - qglTextureImage2D(texture, GL_TEXTURE_2D, 0, internalFormat, width, height, 0, dataFormat, dataType, data); + miplevel = 0; + do + { + lastMip = (width == 1 && height == 1) || !mipmap; + qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, NULL); + + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + miplevel++; + } + while (!lastMip); + + return; } - if (flags & IMGFLAG_MIPMAP) + if (compressed && picmip) { - int miplevel = 0; - - while (width > 1 || height > 1) + for (miplevel = r_picmip->integer; miplevel > 0 && numMips > 1; miplevel--, numMips--) { - if (data) - { - if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) - R_MipMapNormalHeight( data, data, width, height, glRefConfig.swizzleNormalmap ); - else - R_MipMapsRGB( data, width, height ); - } - + size = CalculateMipSize(width, height, picFormat); + x >>= 1; + y >>= 1; width = MAX(1, width >> 1); height = MAX(1, height >> 1); - miplevel++; + data += size; + } + } - if ( data && r_colorMipLevels->integer ) - R_BlendOverTexture( (byte *)data, width * height, mipBlendColors[miplevel] ); + miplevel = 0; + do + { + lastMip = (width == 1 && height == 1) || !mipmap; + size = CalculateMipSize(width, height, picFormat); - if ( subtexture ) - { - x >>= 1; - y >>= 1; - qglTextureSubImage2D(texture, GL_TEXTURE_2D, miplevel, x, y, width, height, dataFormat, dataType, data ); - } + if (compressed) + { + if (subtexture) + qglCompressedTextureSubImage2D(texture, target, miplevel, x, y, width, height, picFormat, size, data); + else + qglCompressedTextureImage2D(texture, target, miplevel, picFormat, width, height, 0, size, data); + } + else + { + if (miplevel != 0 && r_colorMipLevels->integer) + R_BlendOverTexture((byte *)data, width * height, mipBlendColors[miplevel]); + + if (rgtc) + RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); + else if (subtexture) + qglTextureSubImage2D(texture, target, miplevel, x, y, width, height, dataFormat, dataType, data); else + qglTextureImage2D(texture, target, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + + if (!lastMip && numMips < 2) { - if (rgtc) - RawImage_UploadToRgtc2Texture(texture, data, width, height, miplevel); + if (type == IMGTYPE_NORMAL || type == IMGTYPE_NORMALHEIGHT) + R_MipMapNormalHeight(data, data, width, height, glRefConfig.swizzleNormalmap); else - qglTextureImage2D(texture, GL_TEXTURE_2D, miplevel, internalFormat, width, height, 0, dataFormat, dataType, data); + R_MipMapsRGB(data, width, height); } } + + x >>= 1; + y >>= 1; + width = MAX(1, width >> 1); + height = MAX(1, height >> 1); + miplevel++; + + if (numMips > 1) + { + data += size; + numMips--; + } } + while (!lastMip); } @@ -2024,19 +2030,35 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic GLenum internalFormat = image->internalFormat; qboolean subtexture = (x != 0) || (y != 0) || (width != image->width) || (height != image->height); qboolean notScaled = qtrue; - qboolean mipmap = !!(flags & IMGFLAG_MIPMAP); + qboolean compressed = (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT); + qboolean mipmap = !!(flags & IMGFLAG_MIPMAP) && (!compressed || numMips > 1); + qboolean cubemap = !!(flags & IMGFLAG_CUBEMAP); + GLenum uploadTarget = cubemap ? GL_TEXTURE_CUBE_MAP_POSITIVE_X : GL_TEXTURE_2D; + GLenum textureTarget = cubemap ? GL_TEXTURE_CUBE_MAP : GL_TEXTURE_2D; + int depth = cubemap ? 6 : 1; if (!data) { RawImage_ScaleToPower2(NULL, &width, &height, type, flags, NULL); - RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + for (i = 0; i < depth; i++) + RawImage_UploadTexture(image->texnum, NULL, 0, 0, width, height, uploadTarget + i, GL_RGBA8, 0, internalFormat, type, flags, qfalse); goto done; } else if (!subtexture) { - if (picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + if (compressed || cubemap) { - RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, picFormat, numMips, internalFormat, type, flags, qfalse); + for (i = 0; i < depth; i++) + { + int w2 = width, h2 = height; + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget + i, picFormat, numMips, internalFormat, type, flags, qfalse); + for (c = numMips; c; c--) + { + data += CalculateMipSize(w2, h2, picFormat); + w2 = MAX(1, w2 >> 1); + h2 = MAX(1, h2 >> 1); + } + } goto done; } notScaled = RawImage_ScaleToPower2(&data, &width, &height, type, flags, &resampledBuffer); @@ -2076,12 +2098,12 @@ static void Upload32(byte *data, int x, int y, int width, int height, GLenum pic if (subtexture) { // FIXME: Incorrect if original texture was not a power of 2 texture or picmipped - RawImage_UploadTexture(image->texnum, data, x, y, width, height, GL_RGBA8, 0, internalFormat, type, flags, qtrue); + RawImage_UploadTexture(image->texnum, data, x, y, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qtrue); GL_CheckErrors(); return; } - RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, GL_RGBA8, 0, internalFormat, type, flags, qfalse); + RawImage_UploadTexture(image->texnum, data, 0, 0, width, height, uploadTarget, GL_RGBA8, 0, internalFormat, type, flags, qfalse); done: @@ -2090,20 +2112,20 @@ done: if (mipmap) { - if ( glConfig.textureFilterAnisotropic ) - qglTextureParameteri( image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp( 1, maxAnisotropy, r_ext_max_anisotropy->integer ) ); + if (glConfig.textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, + (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer)); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, gl_filter_min); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, gl_filter_max); } else { - if ( glConfig.textureFilterAnisotropic ) - qglTextureParameteri(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); + if (glConfig.textureFilterAnisotropic && !cubemap) + qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, 1); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_LINEAR); } // Fix for sampling depth buffer on old nVidia cards @@ -2114,9 +2136,9 @@ done: case GL_DEPTH_COMPONENT16_ARB: case GL_DEPTH_COMPONENT24_ARB: case GL_DEPTH_COMPONENT32_ARB: - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, textureTarget, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, GL_NEAREST); break; default: break; @@ -2170,49 +2192,20 @@ image_t *R_CreateImage2( const char *name, byte *pic, int width, int height, GLe glWrapClampMode = GL_REPEAT; if (!internalFormat) - { - if (image->flags & IMGFLAG_CUBEMAP) - internalFormat = GL_RGBA8; - else - internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); - } + internalFormat = RawImage_GetFormat(pic, width * height, picFormat, isLightmap, image->type, image->flags); image->internalFormat = internalFormat; + Upload32(pic, 0, 0, image->width, image->height, picFormat, numMips, image); + if (image->flags & IMGFLAG_CUBEMAP) { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, GL_CLAMP_TO_EDGE); - - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - if (image->flags & IMGFLAG_MIPMAP) - { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); - } - else - { - qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - } - - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_X, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Y, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_POSITIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - qglTextureImage2D(image->texnum, GL_TEXTURE_CUBE_MAP_NEGATIVE_Z, 0, GL_RGBA8, width, height, 0, GL_BGRA, GL_UNSIGNED_BYTE, pic); - - if (image->flags & IMGFLAG_MIPMAP) - qglGenerateTextureMipmap(image->texnum, GL_TEXTURE_CUBE_MAP); - - image->uploadWidth = width; - image->uploadHeight = height; + qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_S, glWrapClampMode); + qglTextureParameterf(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_T, glWrapClampMode); + qglTextureParameteri(image->texnum, GL_TEXTURE_CUBE_MAP, GL_TEXTURE_WRAP_R, glWrapClampMode); } else { - Upload32( pic, 0, 0, image->width, image->height, picFormat, numMips, image ); - qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, glWrapClampMode); qglTextureParameterf(image->texnum, GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, glWrapClampMode); } @@ -2384,6 +2377,7 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) GLenum picFormat; int picNumMips; long hash; + imgFlags_t checkFlagsTrue, checkFlagsFalse; if (!name) { return NULL; @@ -2414,7 +2408,10 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) return NULL; } - if (r_normalMapping->integer && (picFormat == GL_RGBA8) && !(type == IMGTYPE_NORMAL) && (flags & IMGFLAG_PICMIP) && (flags & IMGFLAG_MIPMAP) && (flags & IMGFLAG_GENNORMALMAP)) + checkFlagsTrue = IMGFLAG_PICMIP | IMGFLAG_MIPMAP | IMGFLAG_GENNORMALMAP; + checkFlagsFalse = IMGFLAG_CUBEMAP; + if (r_normalMapping->integer && (picFormat == GL_RGBA8) && (type == IMGTYPE_COLORALPHA) && + ((flags & checkFlagsTrue) == checkFlagsTrue) && !(flags & checkFlagsFalse)) { char normalName[MAX_QPATH]; image_t *normalImage; @@ -2517,6 +2514,20 @@ image_t *R_FindImageFile( const char *name, imgType_t type, imgFlags_t flags ) } } + // force mipmaps off if image is compressed but doesn't have enough mips + if ((flags & IMGFLAG_MIPMAP) && picFormat != GL_RGBA8 && picFormat != GL_SRGB8_ALPHA8_EXT) + { + int wh = MAX(width, height); + int neededMips = 0; + while (wh) + { + neededMips++; + wh >>= 1; + } + if (neededMips > picNumMips) + flags &= ~IMGFLAG_MIPMAP; + } + image = R_CreateImage2( ( char * ) name, pic, width, height, picFormat, picNumMips, type, flags, 0 ); ri.Free( pic ); return image; -- cgit From d5ba7bb70ef327c8856165475b58e946c8fbd8ce Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 1 Feb 2016 21:37:23 -0800 Subject: OpenGL2: Merge several cvars into r_pbr. r_glossIsRoughness, r_specularIsMetallic, r_framebufferGamma, r_tonemapGamma, r_materialGamma, r_lightGamma --- src/renderergl2/glsl/calclevels4x_fp.glsl | 4 +-- src/renderergl2/glsl/lightall_fp.glsl | 48 ++++++++++--------------- src/renderergl2/glsl/tonemap_fp.glsl | 8 ++--- src/renderergl2/tr_bsp.c | 4 +-- src/renderergl2/tr_glsl.c | 19 ++-------- src/renderergl2/tr_image.c | 5 +++ src/renderergl2/tr_init.c | 18 ++-------- src/renderergl2/tr_local.h | 8 +---- src/renderergl2/tr_scene.c | 2 +- src/renderergl2/tr_shader.c | 60 ++++++++++++++++++++++--------- 10 files changed, 82 insertions(+), 94 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/calclevels4x_fp.glsl b/src/renderergl2/glsl/calclevels4x_fp.glsl index 1de59e9f..0d298b62 100644 --- a/src/renderergl2/glsl/calclevels4x_fp.glsl +++ b/src/renderergl2/glsl/calclevels4x_fp.glsl @@ -14,8 +14,8 @@ vec3 GetValues(vec2 offset, vec3 current) #ifdef FIRST_PASS - #if defined(r_framebufferGamma) - minAvgMax = pow(minAvgMax, vec3(r_framebufferGamma)); + #if defined(USE_PBR) + minAvgMax = pow(minAvgMax, vec3(2.2)); #endif float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index b8f3985f..eb8ba900 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -276,9 +276,9 @@ void main() attenuation = 1.0; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - ambientColor = pow(ambientColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); + ambientColor = pow(ambientColor, vec3(2.2)); #endif #if defined(USE_NORMALMAP) @@ -319,7 +319,7 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface - ambientColor = clamp(ambientColor - lightColor * surfNL, 0.0, 1.0); + ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); #endif vec3 reflectance; @@ -335,21 +335,18 @@ void main() specular *= u_SpecularScale; - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #if !defined(SPECULAR_IS_METALLIC) - specular.rgb = pow(specular.rgb, vec3(r_materialGamma)); - #endif + #if defined(USE_PBR) + diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); #endif float gloss = specular.a; - #if defined(GLOSS_IS_ROUGHNESS) - float roughness = gloss; + #if defined(USE_PBR) + float roughness = 1.0 - specular.r; #else float roughness = exp2(-3.0 * gloss); #endif - #if defined(SPECULAR_IS_METALLIC) + #if defined(USE_PBR) // diffuse is actually base color, and green of specular is metallicness float metallic = specular.g; @@ -374,7 +371,7 @@ void main() // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - #if defined(GLOSS_IS_ROUGHNESS) + #if defined(USE_PBR) vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; #else vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; @@ -385,8 +382,8 @@ void main() //vec3 cubeLightDiffuse = max(textureCubeLod(u_CubeMap, N, 6.0).rgb, 0.5 / 255.0); //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); - #if defined(r_framebufferGamma) - cubeLightColor = pow(cubeLightColor, vec3(r_framebufferGamma)); + #if defined(USE_PBR) + cubeLightColor = pow(cubeLightColor, vec3(2.2)); #endif // multiply cubemap values by lighting @@ -421,8 +418,8 @@ void main() lightColor = u_PrimaryLightColor; - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); + #if defined(USE_PBR) + lightColor = pow(lightColor, vec3(2.2)); #endif #if defined(USE_SHADOWMAP) @@ -434,6 +431,11 @@ void main() gl_FragColor.rgb += lightColor * reflectance * NL2; #endif + + #if defined(USE_PBR) + gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); + #endif + #else lightColor = var_Color.rgb; @@ -441,21 +443,9 @@ void main() lightColor *= lightmapColor.rgb; #endif - #if defined(r_lightGamma) - lightColor = pow(lightColor, vec3(r_lightGamma)); - #endif - - #if defined(r_materialGamma) - diffuse.rgb = pow(diffuse.rgb, vec3(r_materialGamma)); - #endif - gl_FragColor.rgb = diffuse.rgb * lightColor; #endif -#if defined(r_framebufferGamma) - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / r_framebufferGamma)); -#endif - gl_FragColor.a = diffuse.a * var_Color.a; } diff --git a/src/renderergl2/glsl/tonemap_fp.glsl b/src/renderergl2/glsl/tonemap_fp.glsl index 1368c5bd..5d8841d6 100644 --- a/src/renderergl2/glsl/tonemap_fp.glsl +++ b/src/renderergl2/glsl/tonemap_fp.glsl @@ -28,8 +28,8 @@ void main() { vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; -#if defined(r_framebufferGamma) - color.rgb = pow(color.rgb, vec3(r_framebufferGamma)); +#if defined(USE_PBR) + color.rgb = pow(color.rgb, vec3(2.2)); #endif vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; @@ -46,8 +46,8 @@ void main() color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0); -#if defined(r_tonemapGamma) - color.rgb = pow(color.rgb, vec3(1.0 / r_tonemapGamma)); +#if defined(USE_PBR) + color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); #endif gl_FragColor = color; diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 7e5493f3..2238cdaf 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -142,7 +142,7 @@ static void R_ColorShiftLightingFloats(float in[4], float out[4], float scale ) float r, g, b; #if defined(USE_OVERBRIGHT) - scale *= pow(2.0f, r_mapOverBrightBits->integer - tr.overbrightBits); + scale *= 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #endif r = in[0] * scale; @@ -2763,7 +2763,7 @@ void R_LoadLightGrid( lump_t *l ) { if (hdrLightGrid) { #if defined(USE_OVERBRIGHT) - float lightScale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits); + float lightScale = 1 << (r_mapOverBrightBits->integer - tr.overbrightBits); #else float lightScale = 1.0f; #endif diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index eaa7c8f5..f8637a66 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -322,17 +322,8 @@ static void GLSL_GetShaderHeader( GLenum shaderType, const GLcharARB *extra, cha Q_strcat(dest, size, va("#ifndef r_FBufScale\n#define r_FBufScale vec2(%f, %f)\n#endif\n", fbufWidthScale, fbufHeightScale)); - if (r_materialGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_materialGamma\n#define r_materialGamma %f\n#endif\n", r_materialGamma->value)); - - if (r_lightGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_lightGamma\n#define r_lightGamma %f\n#endif\n", r_lightGamma->value)); - - if (r_framebufferGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_framebufferGamma\n#define r_framebufferGamma %f\n#endif\n", r_framebufferGamma->value)); - - if (r_tonemapGamma->value != 1.0f) - Q_strcat(dest, size, va("#ifndef r_tonemapGamma\n#define r_tonemapGamma %f\n#endif\n", r_tonemapGamma->value)); + if (r_pbr->integer) + Q_strcat(dest, size, "#define USE_PBR\n"); if (extra) { @@ -1009,12 +1000,6 @@ void GLSL_InitGPUShaders(void) extradefines[0] = '\0'; - if (r_specularIsMetallic->value) - Q_strcat(extradefines, 1024, "#define SPECULAR_IS_METALLIC\n"); - - if (r_glossIsRoughness->value) - Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); - if (r_dlightMode->integer >= 2) Q_strcat(extradefines, 1024, "#define USE_SHADOWMAP\n"); diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 88335b7a..47843fe2 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2859,6 +2859,11 @@ void R_SetColorMappings( void ) { tr.overbrightBits = 0; } + // don't allow more overbright bits than map overbright bits + if ( tr.overbrightBits > r_mapOverBrightBits->integer ) { + tr.overbrightBits = r_mapOverBrightBits->integer; + } + tr.identityLight = 1.0f / ( 1 << tr.overbrightBits ); tr.identityLightByte = 255 * tr.identityLight; diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 0c02f887..18eecf0b 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -131,11 +131,6 @@ cvar_t *r_forceAutoExposure; cvar_t *r_forceAutoExposureMin; cvar_t *r_forceAutoExposureMax; -cvar_t *r_materialGamma; -cvar_t *r_lightGamma; -cvar_t *r_framebufferGamma; -cvar_t *r_tonemapGamma; - cvar_t *r_depthPrepass; cvar_t *r_ssao; @@ -145,8 +140,7 @@ cvar_t *r_deluxeMapping; cvar_t *r_parallaxMapping; cvar_t *r_cubeMapping; cvar_t *r_cubemapSize; -cvar_t *r_specularIsMetallic; -cvar_t *r_glossIsRoughness; +cvar_t *r_pbr; cvar_t *r_baseNormalX; cvar_t *r_baseNormalY; cvar_t *r_baseParallax; @@ -1141,7 +1135,7 @@ void R_Register( void ) r_floatLightmap = ri.Cvar_Get( "r_floatLightmap", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_postProcess = ri.Cvar_Get( "r_postProcess", "1", CVAR_ARCHIVE ); - r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE | CVAR_LATCH ); + r_toneMap = ri.Cvar_Get( "r_toneMap", "1", CVAR_ARCHIVE ); r_forceToneMap = ri.Cvar_Get( "r_forceToneMap", "0", CVAR_CHEAT ); r_forceToneMapMin = ri.Cvar_Get( "r_forceToneMapMin", "-8.0", CVAR_CHEAT ); r_forceToneMapAvg = ri.Cvar_Get( "r_forceToneMapAvg", "-2.0", CVAR_CHEAT ); @@ -1154,11 +1148,6 @@ void R_Register( void ) r_cameraExposure = ri.Cvar_Get( "r_cameraExposure", "0", CVAR_CHEAT ); - r_materialGamma = ri.Cvar_Get( "r_materialGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_lightGamma = ri.Cvar_Get( "r_lightGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_framebufferGamma = ri.Cvar_Get( "r_framebufferGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_tonemapGamma = ri.Cvar_Get( "r_tonemapGamma", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); - r_depthPrepass = ri.Cvar_Get( "r_depthPrepass", "1", CVAR_ARCHIVE ); r_ssao = ri.Cvar_Get( "r_ssao", "0", CVAR_LATCH | CVAR_ARCHIVE ); @@ -1168,8 +1157,7 @@ void R_Register( void ) r_parallaxMapping = ri.Cvar_Get( "r_parallaxMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubeMapping = ri.Cvar_Get( "r_cubeMapping", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_cubemapSize = ri.Cvar_Get( "r_cubemapSize", "128", CVAR_ARCHIVE | CVAR_LATCH ); - r_specularIsMetallic = ri.Cvar_Get( "r_specularIsMetallic", "0", CVAR_ARCHIVE | CVAR_LATCH ); - r_glossIsRoughness = ri.Cvar_Get("r_glossIsRoughness", "0", CVAR_ARCHIVE | CVAR_LATCH); + r_pbr = ri.Cvar_Get("r_pbr", "0", CVAR_ARCHIVE | CVAR_LATCH); r_baseNormalX = ri.Cvar_Get( "r_baseNormalX", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseNormalY = ri.Cvar_Get( "r_baseNormalY", "1.0", CVAR_ARCHIVE | CVAR_LATCH ); r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index f56d5f51..9da87e6e 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1778,11 +1778,6 @@ extern cvar_t *r_forceAutoExposureMax; extern cvar_t *r_cameraExposure; -extern cvar_t *r_materialGamma; -extern cvar_t *r_lightGamma; -extern cvar_t *r_framebufferGamma; -extern cvar_t *r_tonemapGamma; - extern cvar_t *r_depthPrepass; extern cvar_t *r_ssao; @@ -1792,8 +1787,7 @@ extern cvar_t *r_deluxeMapping; extern cvar_t *r_parallaxMapping; extern cvar_t *r_cubeMapping; extern cvar_t *r_cubemapSize; -extern cvar_t *r_specularIsMetallic; -extern cvar_t *r_glossIsRoughness; +extern cvar_t *r_pbr; extern cvar_t *r_baseNormalX; extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; diff --git a/src/renderergl2/tr_scene.c b/src/renderergl2/tr_scene.c index 7e326a88..2578e7b9 100644 --- a/src/renderergl2/tr_scene.c +++ b/src/renderergl2/tr_scene.c @@ -337,7 +337,7 @@ void RE_BeginScene(const refdef_t *fd) else { #if defined(USE_OVERBRIGHT) - float scale = pow(2, r_mapOverBrightBits->integer - tr.overbrightBits - 8); + float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f;; #else float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; #endif diff --git a/src/renderergl2/tr_shader.c b/src/renderergl2/tr_shader.c index b4a120ca..2cac0495 100644 --- a/src/renderergl2/tr_shader.c +++ b/src/renderergl2/tr_shader.c @@ -935,9 +935,18 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) ri.Printf( PRINT_WARNING, "WARNING: missing parameter for specular reflectance in shader '%s'\n", shader.name ); continue; } - stage->specularScale[0] = - stage->specularScale[1] = - stage->specularScale[2] = atof( token ); + + if (r_pbr->integer) + { + // interpret specularReflectance < 0.5 as nonmetal + stage->specularScale[1] = (atof(token) < 0.5f) ? 0.0f : 1.0f; + } + else + { + stage->specularScale[0] = + stage->specularScale[1] = + stage->specularScale[2] = atof( token ); + } } // // specularExponent @@ -955,8 +964,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) exponent = atof( token ); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = powf(2.0f / (exponent + 2.0), 0.25); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - powf(2.0f / (exponent + 2.0), 0.25); else { // Change shininess to gloss @@ -981,8 +990,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) gloss = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = exp2f(-3.0f * gloss); + if (r_pbr->integer) + stage->specularScale[0] = 1.0f - exp2f(-3.0f * gloss); else stage->specularScale[3] = gloss; } @@ -1002,8 +1011,8 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) roughness = atof(token); - if (r_glossIsRoughness->integer) - stage->specularScale[3] = roughness; + if (r_pbr->integer) + stage->specularScale[0] = 1.0 - roughness; else { if (roughness >= 0.125) @@ -1063,6 +1072,7 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) } // // specularScale + // or specularScale with r_pbr 1 // or specularScale // or specularScale // @@ -1089,10 +1099,19 @@ static qboolean ParseStage( shaderStage_t *stage, char **text ) token = COM_ParseExt(text, qfalse); if ( token[0] == 0 ) { - // two values, rgb then gloss - stage->specularScale[3] = stage->specularScale[1]; - stage->specularScale[1] = - stage->specularScale[2] = stage->specularScale[0]; + if (r_pbr->integer) + { + // two values, metallic then smoothness + float smoothness = stage->specularScale[1]; + stage->specularScale[1] = (stage->specularScale[0] < 0.5f) ? 0.0f : 1.0f; + stage->specularScale[0] = smoothness; + } + { + // two values, rgb then gloss + stage->specularScale[3] = stage->specularScale[1]; + stage->specularScale[1] = + stage->specularScale[2] = stage->specularScale[0]; + } continue; } @@ -2858,10 +2877,17 @@ static void InitShader( const char *name, int lightmapIndex ) { // default normal/specular VectorSet4(stages[i].normalScale, 0.0f, 0.0f, 0.0f, 0.0f); - stages[i].specularScale[0] = - stages[i].specularScale[1] = - stages[i].specularScale[2] = r_baseSpecular->value; - stages[i].specularScale[3] = r_baseGloss->value; + if (r_pbr->integer) + { + stages[i].specularScale[0] = r_baseGloss->value; + } + else + { + stages[i].specularScale[0] = + stages[i].specularScale[1] = + stages[i].specularScale[2] = r_baseSpecular->value; + stages[i].specularScale[3] = r_baseGloss->value; + } } } -- cgit From e4a4b0b57899bde1f35565e18bcb9bb1b06f6320 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 10 Feb 2016 16:25:32 -0800 Subject: OpenGL2: Add named cubemaps and per-map env.json parsing. --- src/renderergl2/tr_backend.c | 11 ++++- src/renderergl2/tr_bsp.c | 97 ++++++++++++++++++++++++++++++++++++++++++-- src/renderergl2/tr_local.h | 1 + src/renderergl2/tr_main.c | 2 +- 4 files changed, 105 insertions(+), 6 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index ae475b02..f7720443 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1675,7 +1675,16 @@ const void *RB_ExportCubemaps(const void *data) p += sideSize; } - Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/%03d.dds", tr.world->baseName, i); + 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); } diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 2238cdaf..9a03f991 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -24,6 +24,10 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" +#define JSON_IMPLEMENTATION +#include "..\qcommon\json.h" +#undef JSON_IMPLEMENTATION + /* Loads and prepares a map file for scene rendering. @@ -2973,6 +2977,78 @@ qboolean R_ParseSpawnVars( char *spawnVarChars, int maxSpawnVarChars, int *numSp return qtrue; } +void R_LoadEnvironmentJson(const char *baseName) +{ + char filename[MAX_QPATH]; + + union { + char *c; + void *v; + } buffer; + char *bufferEnd; + + const char *cubemapArrayJson; + int filelen, i; + + Com_sprintf(filename, MAX_QPATH, "cubemaps/%s/env.json", baseName); + + filelen = ri.FS_ReadFile(filename, &buffer.v); + if (!buffer.c) + return; + bufferEnd = buffer.c + filelen; + + if (JSON_ValueGetType(buffer.c, bufferEnd) != JSONTYPE_OBJECT) + { + ri.Printf(PRINT_ALL, "Bad %s: does not start with a object\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + cubemapArrayJson = JSON_ObjectGetNamedValue(buffer.c, bufferEnd, "Cubemaps"); + if (!cubemapArrayJson) + { + ri.Printf(PRINT_ALL, "Bad %s: no Cubemaps\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + if (JSON_ValueGetType(cubemapArrayJson, bufferEnd) != JSONTYPE_ARRAY) + { + ri.Printf(PRINT_ALL, "Bad %s: Cubemaps not an array\n", filename); + ri.FS_FreeFile(buffer.v); + return; + } + + tr.numCubemaps = JSON_ArrayGetIndex(cubemapArrayJson, bufferEnd, NULL, 0); + tr.cubemaps = ri.Hunk_Alloc(tr.numCubemaps * sizeof(*tr.cubemaps), h_low); + memset(tr.cubemaps, 0, tr.numCubemaps * sizeof(*tr.cubemaps)); + + for (i = 0; i < tr.numCubemaps; i++) + { + cubemap_t *cubemap = &tr.cubemaps[i]; + const char *cubemapJson, *keyValueJson, *indexes[3]; + int j; + + cubemapJson = JSON_ArrayGetValue(cubemapArrayJson, bufferEnd, i); + + keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Name"); + if (!JSON_ValueGetString(keyValueJson, bufferEnd, cubemap->name, MAX_QPATH)) + cubemap->name[0] = '\0'; + + keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Position"); + JSON_ArrayGetIndex(keyValueJson, bufferEnd, indexes, 3); + for (j = 0; j < 3; j++) + cubemap->origin[j] = JSON_ValueGetFloat(indexes[j], bufferEnd); + + cubemap->parallaxRadius = 1000.0f; + keyValueJson = JSON_ObjectGetNamedValue(cubemapJson, bufferEnd, "Radius"); + if (keyValueJson) + cubemap->parallaxRadius = JSON_ValueGetFloat(keyValueJson, bufferEnd); + } + + ri.FS_FreeFile(buffer.v); +} + void R_LoadCubemapEntities(char *cubemapEntityName) { char spawnVarChars[2048]; @@ -3004,16 +3080,21 @@ void R_LoadCubemapEntities(char *cubemapEntityName) while(R_ParseSpawnVars(spawnVarChars, sizeof(spawnVarChars), &numSpawnVars, spawnVars)) { int i; + char name[MAX_QPATH]; qboolean isCubemap = qfalse; qboolean originSet = qfalse; vec3_t origin; float parallaxRadius = 1000.0f; + name[0] = '\0'; for (i = 0; i < numSpawnVars; i++) { if (!Q_stricmp(spawnVars[i][0], "classname") && !Q_stricmp(spawnVars[i][1], cubemapEntityName)) isCubemap = qtrue; + if (!Q_stricmp(spawnVars[i][0], "name")) + Q_strncpyz(name, spawnVars[i][1], MAX_QPATH); + if (!Q_stricmp(spawnVars[i][0], "origin")) { sscanf(spawnVars[i][1], "%f %f %f", &origin[0], &origin[1], &origin[2]); @@ -3027,9 +3108,10 @@ void R_LoadCubemapEntities(char *cubemapEntityName) if (isCubemap && originSet) { - //ri.Printf(PRINT_ALL, "cubemap at %f %f %f\n", origin[0], origin[1], origin[2]); - VectorCopy(origin, tr.cubemaps[numCubemaps].origin); - tr.cubemaps[numCubemaps].parallaxRadius = parallaxRadius; + cubemap_t *cubemap = &tr.cubemaps[numCubemaps]; + Q_strncpyz(cubemap->name, name, MAX_QPATH); + VectorCopy(origin, cubemap->origin); + cubemap->parallaxRadius = parallaxRadius; numCubemaps++; } } @@ -3420,7 +3502,14 @@ void RE_LoadWorldMap( const char *name ) { // load cubemaps if (r_cubeMapping->integer) { - R_LoadCubemapEntities("misc_cubemap"); + // Try loading an env.json file first + R_LoadEnvironmentJson(s_worldData.baseName); + + if (!tr.numCubemaps) + { + R_LoadCubemapEntities("misc_cubemap"); + } + if (!tr.numCubemaps) { // use deathmatch spawn points as cubemaps diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 9da87e6e..62bf1e03 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -60,6 +60,7 @@ typedef unsigned int glIndex_t; #define USE_OVERBRIGHT typedef struct cubemap_s { + char name[MAX_QPATH]; vec3_t origin; float parallaxRadius; image_t *image; diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index 63fea5ac..f4261033 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -2937,7 +2937,7 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) // only print message for first side if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0) { - ri.Printf(PRINT_ALL, "cubemap %d (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]); + ri.Printf(PRINT_ALL, "cubemap %d %s (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.cubemaps[cubemapIndex].name, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]); } } -- cgit From 93a760743f4949330e301ca6729c1d88ba8484c1 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 12 Feb 2016 18:34:31 -0800 Subject: OpenGL2: Typos. --- src/renderergl2/tr_bsp.c | 2 +- src/renderergl2/tr_scene.c | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_bsp.c b/src/renderergl2/tr_bsp.c index 9a03f991..8429d8cb 100644 --- a/src/renderergl2/tr_bsp.c +++ b/src/renderergl2/tr_bsp.c @@ -25,7 +25,7 @@ Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA #include "tr_local.h" #define JSON_IMPLEMENTATION -#include "..\qcommon\json.h" +#include "../qcommon/json.h" #undef JSON_IMPLEMENTATION /* diff --git a/src/renderergl2/tr_scene.c b/src/renderergl2/tr_scene.c index 2578e7b9..24108046 100644 --- a/src/renderergl2/tr_scene.c +++ b/src/renderergl2/tr_scene.c @@ -337,7 +337,7 @@ void RE_BeginScene(const refdef_t *fd) else { #if defined(USE_OVERBRIGHT) - float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f;; + float scale = (1 << (r_mapOverBrightBits->integer - tr.overbrightBits)) / 255.0f; #else float scale = (1 << r_mapOverBrightBits->integer) / 255.0f; #endif -- cgit From 3043117bd95828ddc350a296f93489869474c4ea Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 17 Feb 2016 19:49:21 -0800 Subject: OpenGL2: Fix some GL errors and no sun shadows on older OpenGLs. --- src/renderergl2/tr_dsa.c | 2 +- src/renderergl2/tr_fbo.c | 8 ++++++-- src/renderergl2/tr_image.c | 4 +--- 3 files changed, 8 insertions(+), 6 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_dsa.c b/src/renderergl2/tr_dsa.c index a766263a..9cd481bd 100644 --- a/src/renderergl2/tr_dsa.c +++ b/src/renderergl2/tr_dsa.c @@ -210,7 +210,7 @@ void GL_BindNullFramebuffers() qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0); glDsaState.drawFramebuffer = glDsaState.readFramebuffer = 0; qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, 0); - glDsaState.readFramebuffer = 0; + glDsaState.renderbuffer = 0; } void GL_BindFramebuffer(GLenum target, GLuint framebuffer) diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index 59b17032..12293766 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -251,7 +251,7 @@ FBO_Init void FBO_Init(void) { int i; - int hdrFormat, multisample; + int hdrFormat, multisample = 0; ri.Printf(PRINT_ALL, "------- FBO_Init -------\n"); @@ -268,7 +268,8 @@ void FBO_Init(void) if (r_hdr->integer && glRefConfig.framebufferObject && glRefConfig.textureFloat) hdrFormat = GL_RGBA16F_ARB; - qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample); + if (glRefConfig.framebufferMultisample) + qglGetIntegerv(GL_MAX_SAMPLES_EXT, &multisample); if (r_ext_framebuffer_multisample->integer < multisample) multisample = r_ext_framebuffer_multisample->integer; @@ -334,6 +335,9 @@ void FBO_Init(void) for ( i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); + // FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments + // This at least gets sun shadows working on older GPUs (Intel) + FBO_CreateBuffer(tr.sunShadowFbo[i], GL_RGBA8, 0, 0); FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunShadowFbo[i]); } diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 47843fe2..d567193b 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -116,7 +116,7 @@ void GL_TextureMode( const char *string ) { // change all the existing mipmap texture objects for ( i = 0 ; i < tr.numImages ; i++ ) { glt = tr.images[ i ]; - if ( glt->flags & IMGFLAG_MIPMAP ) { + if ( glt->flags & IMGFLAG_MIPMAP && !(glt->flags & IMGFLAG_CUBEMAP)) { qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTextureParameterf(glt->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, gl_filter_max); } @@ -2818,8 +2818,6 @@ void R_CreateBuiltinImages( void ) { for ( x = 0; x < 4; x++) { tr.sunShadowDepthImage[x] = R_CreateImage(va("*sunshadowdepth%i", x), NULL, r_shadowMapSize->integer, r_shadowMapSize->integer, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_DEPTH_COMPONENT24_ARB); - qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_R_TO_TEXTURE); qglTextureParameterf(tr.sunShadowDepthImage[x]->texnum, GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL); } -- cgit From fdf6b74c210f7cc1fd54472308fc61c9341c4de1 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 17 Feb 2016 20:06:18 -0800 Subject: OpenGL2: Shader optimization, and add dither to tonemap. --- src/renderergl2/glsl/calclevels4x_fp.glsl | 2 +- src/renderergl2/glsl/lightall_fp.glsl | 106 +++++++++++------------------- src/renderergl2/glsl/lightall_vp.glsl | 21 ++++-- src/renderergl2/glsl/tonemap_fp.glsl | 7 +- src/renderergl2/tr_shade.c | 14 +++- 5 files changed, 76 insertions(+), 74 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/calclevels4x_fp.glsl b/src/renderergl2/glsl/calclevels4x_fp.glsl index 0d298b62..8246c4b3 100644 --- a/src/renderergl2/glsl/calclevels4x_fp.glsl +++ b/src/renderergl2/glsl/calclevels4x_fp.glsl @@ -15,7 +15,7 @@ vec3 GetValues(vec2 offset, vec3 current) #ifdef FIRST_PASS #if defined(USE_PBR) - minAvgMax = pow(minAvgMax, vec3(2.2)); + minAvgMax *= minAvgMax; #endif float lumi = max(dot(LUMINANCE_VECTOR, minAvgMax), 0.000001); diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index eb8ba900..6a0a5155 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -29,11 +29,6 @@ uniform samplerCube u_CubeMap; uniform vec4 u_EnableTextures; #endif -#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) -uniform vec3 u_DirectedLight; -uniform vec3 u_AmbientLight; -#endif - #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) uniform vec3 u_PrimaryLightColor; uniform vec3 u_PrimaryLightAmbient; @@ -53,6 +48,9 @@ uniform vec4 u_CubeMapInfo; varying vec4 var_TexCoords; varying vec4 var_Color; +#if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) +varying vec4 var_ColorAmbient; +#endif #if (defined(USE_LIGHT) && !defined(USE_FAST_LIGHT)) #if defined(USE_VERT_TANGENT_SPACE) @@ -150,7 +148,7 @@ float RayIntersectDisplaceMap(vec2 dp, vec2 ds, sampler2D normalMap) } #endif -vec3 CalcDiffuse(vec3 diffuseAlbedo, float EH, float NH, float roughness) +vec3 CalcDiffuse(vec3 diffuseAlbedo, float NH, float EH, float roughness) { #if defined(USE_BURLEY) // modified from https://disney-animation.s3.amazonaws.com/library/s2012_pbs_disney_brdf_notes_v2.pdf @@ -171,7 +169,7 @@ vec3 EnvironmentBRDF(float roughness, float NE, vec3 specular) return vec3(v) + specular; } -vec3 CalcSpecular(vec3 specular, float NH, float NL, float NE, float EH, float roughness) +vec3 CalcSpecular(vec3 specular, float NH, float EH, float roughness) { // from http://community.arm.com/servlet/JiveServlet/download/96891546-19496/siggraph2015-mmg-renaldas-slides.pdf float rr = roughness*roughness; @@ -220,7 +218,7 @@ mat3 cotangent_frame( vec3 N, vec3 p, vec2 uv ) void main() { - vec3 viewDir, lightColor, ambientColor; + vec3 viewDir, lightColor, ambientColor, reflectance; vec3 L, N, E, H; float NL, NH, NE, EH, attenuation; @@ -232,21 +230,20 @@ void main() mat3 tangentToWorld = cotangent_frame(var_Normal, -var_ViewDir, var_TexCoords.xy); viewDir = var_ViewDir; #endif - E = normalize(viewDir); - - L = var_LightDir.xyz; - #if defined(USE_DELUXEMAP) - L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y; - #endif - float sqrLightDist = dot(L, L); #endif + lightColor = var_Color.rgb; + #if defined(USE_LIGHTMAP) vec4 lightmapColor = texture2D(u_LightMap, var_TexCoords.zw); #if defined(RGBM_LIGHTMAP) lightmapColor.rgb *= lightmapColor.a; #endif + #if defined(USE_PBR) && !defined(USE_FAST_LIGHT) + lightmapColor.rgb *= lightmapColor.rgb; + #endif + lightColor *= lightmapColor.rgb; #endif vec2 texCoords = var_TexCoords.xy; @@ -262,23 +259,17 @@ void main() vec4 diffuse = texture2D(u_DiffuseMap, texCoords); #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) - #if defined(USE_LIGHTMAP) - lightColor = lightmapColor.rgb * var_Color.rgb; - ambientColor = vec3(0.0); - attenuation = 1.0; - #elif defined(USE_LIGHT_VECTOR) - lightColor = u_DirectedLight * var_Color.rgb; - ambientColor = u_AmbientLight * var_Color.rgb; - attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); - #elif defined(USE_LIGHT_VERTEX) - lightColor = var_Color.rgb; - ambientColor = vec3(0.0); - attenuation = 1.0; + L = var_LightDir.xyz; + #if defined(USE_DELUXEMAP) + L += (texture2D(u_DeluxeMap, var_TexCoords.zw).xyz - vec3(0.5)) * u_EnableTextures.y; #endif + float sqrLightDist = dot(L, L); + L /= sqrt(sqrLightDist); - #if defined(USE_PBR) - lightColor = pow(lightColor, vec3(2.2)); - ambientColor = pow(ambientColor, vec3(2.2)); + #if defined(USE_LIGHT_VECTOR) + attenuation = CalcLightAttenuation(float(var_LightDir.w > 0.0), var_LightDir.w / sqrLightDist); + #else + attenuation = 1.0; #endif #if defined(USE_NORMALMAP) @@ -295,21 +286,20 @@ void main() #endif N = normalize(N); - L /= sqrt(sqrLightDist); #if defined(USE_SHADOWMAP) vec2 shadowTex = gl_FragCoord.xy * r_FBufScale; float shadowValue = texture2D(u_ShadowMap, shadowTex).r; // surfaces not facing the light are always shadowed - shadowValue *= float(dot(var_Normal.xyz, var_PrimaryLightDir.xyz) > 0.0); + shadowValue *= clamp(dot(var_Normal.xyz, var_PrimaryLightDir.xyz), 0.0, 1.0); #if defined(SHADOWMAP_MODULATE) lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; #endif #endif - #if defined(USE_LIGHTMAP) || defined(USE_LIGHT_VERTEX) + #if !defined(USE_LIGHT_VECTOR) ambientColor = lightColor; float surfNL = clamp(dot(var_Normal.xyz, L), 0.0, 1.0); @@ -320,9 +310,9 @@ void main() // Recover any unused light as ambient, in case attenuation is over 4x or // light is below the surface ambientColor = max(ambientColor - lightColor * surfNL, vec3(0.0)); + #else + ambientColor = var_ColorAmbient.rgb; #endif - - vec3 reflectance; NL = clamp(dot(N, L), 0.0, 1.0); NE = clamp(dot(N, E), 0.0, 1.0); @@ -332,32 +322,30 @@ void main() #else vec4 specular = vec4(1.0); #endif - specular *= u_SpecularScale; #if defined(USE_PBR) - diffuse.rgb = pow(diffuse.rgb, vec3(2.2)); + diffuse.rgb *= diffuse.rgb; #endif - float gloss = specular.a; #if defined(USE_PBR) + // diffuse rgb is base color + // specular red is smoothness + // specular green is metallicness float roughness = 1.0 - specular.r; + specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); + diffuse.rgb *= 1.0 - specular.g; #else - float roughness = exp2(-3.0 * gloss); - #endif + // diffuse rgb is diffuse + // specular rgb is specular reflectance at normal incidence + // specular alpha is gloss + float roughness = exp2(-3.0 * specular.a); - #if defined(USE_PBR) - // diffuse is actually base color, and green of specular is metallicness - float metallic = specular.g; - - specular.rgb = metallic * diffuse.rgb + vec3(0.04 - 0.04 * metallic); - diffuse.rgb *= 1.0 - metallic; - #else // adjust diffuse by specular reflectance, to maintain energy conservation diffuse.rgb *= vec3(1.0) - specular.rgb; #endif - reflectance = CalcDiffuse(diffuse.rgb, EH, NH, roughness); + reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness); gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); gl_FragColor.rgb += ambientColor * diffuse.rgb; @@ -371,11 +359,7 @@ void main() // from http://seblagarde.wordpress.com/2012/09/29/image-based-lighting-approaches-and-parallax-corrected-cubemap/ vec3 parallax = u_CubeMapInfo.xyz + u_CubeMapInfo.w * viewDir; - #if defined(USE_PBR) vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 * roughness).rgb * u_EnableTextures.w; - #else - vec3 cubeLightColor = textureCubeLod(u_CubeMap, R + parallax, 7.0 - gloss * 7.0).rgb * u_EnableTextures.w; - #endif // normalize cubemap based on lowest mip (~diffuse) // multiplying cubemap values by lighting below depends on either this or the cubemap being normalized at generation @@ -383,7 +367,7 @@ void main() //cubeLightColor /= dot(cubeLightDiffuse, vec3(0.2125, 0.7154, 0.0721)); #if defined(USE_PBR) - cubeLightColor = pow(cubeLightColor, vec3(2.2)); + cubeLightColor *= cubeLightColor; #endif // multiply cubemap values by lighting @@ -404,24 +388,19 @@ void main() //L2 /= sqrt(sqrLightDist); NL2 = clamp(dot(N, L2), 0.0, 1.0); - H2 = normalize(L2 + E); EH2 = clamp(dot(E, H2), 0.0, 1.0); NH2 = clamp(dot(N, H2), 0.0, 1.0); - reflectance = CalcSpecular(specular.rgb, NH2, NL2, NE, EH2, roughness); + reflectance = CalcSpecular(specular.rgb, NH2, EH2, roughness); // bit of a hack, with modulated shadowmaps, ignore diffuse #if !defined(SHADOWMAP_MODULATE) - reflectance += CalcDiffuse(diffuse.rgb, EH2, NH2, roughness); + reflectance += CalcDiffuse(diffuse.rgb, NH2, EH2, roughness); #endif lightColor = u_PrimaryLightColor; - #if defined(USE_PBR) - lightColor = pow(lightColor, vec3(2.2)); - #endif - #if defined(USE_SHADOWMAP) lightColor *= shadowValue; #endif @@ -433,15 +412,10 @@ void main() #endif #if defined(USE_PBR) - gl_FragColor.rgb = pow(gl_FragColor.rgb, vec3(1.0 / 2.2)); + gl_FragColor.rgb = sqrt(gl_FragColor.rgb); #endif #else - lightColor = var_Color.rgb; - - #if defined(USE_LIGHTMAP) - lightColor *= lightmapColor.rgb; - #endif gl_FragColor.rgb = diffuse.rgb * lightColor; diff --git a/src/renderergl2/glsl/lightall_vp.glsl b/src/renderergl2/glsl/lightall_vp.glsl index 59051d7c..783885e9 100644 --- a/src/renderergl2/glsl/lightall_vp.glsl +++ b/src/renderergl2/glsl/lightall_vp.glsl @@ -57,10 +57,8 @@ uniform float u_VertexLerp; #if defined(USE_LIGHT_VECTOR) uniform vec4 u_LightOrigin; uniform float u_LightRadius; - #if defined(USE_FAST_LIGHT) uniform vec3 u_DirectedLight; uniform vec3 u_AmbientLight; - #endif #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) @@ -71,6 +69,9 @@ uniform float u_PrimaryLightRadius; varying vec4 var_TexCoords; varying vec4 var_Color; +#if defined(USE_LIGHT_VECTOR) && !defined(USE_FAST_LIGHT) +varying vec4 var_ColorAmbient; +#endif #if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) #if defined(USE_VERT_TANGENT_SPACE) @@ -208,12 +209,24 @@ void main() var_Color = u_VertColor * attr_Color + u_BaseColor; -#if defined(USE_LIGHT_VECTOR) && defined(USE_FAST_LIGHT) +#if defined(USE_LIGHT_VECTOR) + #if defined(USE_FAST_LIGHT) float sqrLightDist = dot(L, L); - float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist); float NL = clamp(dot(normalize(normal), L) / sqrt(sqrLightDist), 0.0, 1.0); + float attenuation = CalcLightAttenuation(u_LightOrigin.w, u_LightRadius * u_LightRadius / sqrLightDist); var_Color.rgb *= u_DirectedLight * (attenuation * NL) + u_AmbientLight; + #else + var_ColorAmbient.rgb = u_AmbientLight * var_Color.rgb; + var_Color.rgb *= u_DirectedLight; + #if defined(USE_PBR) + var_ColorAmbient.rgb *= var_ColorAmbient.rgb; + #endif + #endif +#endif + +#if defined(USE_LIGHT) && !defined(USE_FAST_LIGHT) && defined(USE_PBR) + var_Color.rgb *= var_Color.rgb; #endif #if defined(USE_PRIMARY_LIGHT) || defined(USE_SHADOWMAP) diff --git a/src/renderergl2/glsl/tonemap_fp.glsl b/src/renderergl2/glsl/tonemap_fp.glsl index 5d8841d6..9e24e24a 100644 --- a/src/renderergl2/glsl/tonemap_fp.glsl +++ b/src/renderergl2/glsl/tonemap_fp.glsl @@ -29,7 +29,7 @@ void main() vec4 color = texture2D(u_TextureMap, var_TexCoords) * u_Color; #if defined(USE_PBR) - color.rgb = pow(color.rgb, vec3(2.2)); + color.rgb *= color.rgb; #endif vec3 minAvgMax = texture2D(u_LevelsMap, var_TexCoords).rgb; @@ -47,8 +47,11 @@ void main() color.rgb = clamp(color.rgb * var_InvWhite, 0.0, 1.0); #if defined(USE_PBR) - color.rgb = pow(color.rgb, vec3(1.0 / 2.2)); + color.rgb = sqrt(color.rgb); #endif + // add a bit of dither to reduce banding + color.rgb += vec3(1.0/510.0 * mod(gl_FragCoord.x + gl_FragCoord.y, 2.0) - 1.0/1020.0); + gl_FragColor = color; } diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index f4d32a5e..b8295657 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -1274,7 +1274,19 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { GL_BindToTMU(tr.screenShadowImage, TB_SHADOWMAP); GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTAMBIENT, backEnd.refdef.sunAmbCol); - GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol); + if (r_pbr->integer) + { + vec3_t color; + + color[0] = backEnd.refdef.sunCol[0] * backEnd.refdef.sunCol[0]; + color[1] = backEnd.refdef.sunCol[1] * backEnd.refdef.sunCol[1]; + color[2] = backEnd.refdef.sunCol[2] * backEnd.refdef.sunCol[2]; + GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, color); + } + else + { + GLSL_SetUniformVec3(sp, UNIFORM_PRIMARYLIGHTCOLOR, backEnd.refdef.sunCol); + } GLSL_SetUniformVec4(sp, UNIFORM_PRIMARYLIGHTORIGIN, backEnd.refdef.sunDir); } -- cgit From 5d1223366351d7ed9ee537d8f4245ab29b550d2c Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 7 Mar 2016 02:27:03 -0800 Subject: OpenGL2: Add r_shadowBlur. --- src/renderergl2/glsl/depthblur_fp.glsl | 20 ++++++--- src/renderergl2/tr_backend.c | 74 +++++++++++++++++----------------- src/renderergl2/tr_fbo.c | 8 ++++ src/renderergl2/tr_image.c | 7 +++- src/renderergl2/tr_init.c | 4 +- src/renderergl2/tr_local.h | 3 ++ 6 files changed, 73 insertions(+), 43 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl index 93895b4e..15f7be27 100644 --- a/src/renderergl2/glsl/depthblur_fp.glsl +++ b/src/renderergl2/glsl/depthblur_fp.glsl @@ -1,13 +1,13 @@ uniform sampler2D u_ScreenImageMap; uniform sampler2D u_ScreenDepthMap; -uniform vec4 u_ViewInfo; // zfar / znear, zfar +uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height varying vec2 var_ScreenTex; //float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033); float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); //float gauss[3] = float[3](0.60, 0.19, 0.0066); -#define GAUSS_SIZE 4 +#define BLUR_SIZE 4 float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { @@ -17,7 +17,7 @@ float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNea vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar) { - float scale = 1.0 / 256.0; + vec2 scale = u_ViewInfo.zw; #if defined(USE_HORIZONTAL_BLUR) vec2 direction = vec2(1.0, 0.0) * scale; @@ -27,22 +27,32 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); - + +#if defined(USE_GAUSS) vec4 result = texture2D(imageMap, tex) * gauss[0]; float total = gauss[0]; +#else + vec4 result = texture2D(imageMap, tex); + float total = 1.0; +#endif int i, j; for (i = 0; i < 2; i++) { - for (j = 1; j < GAUSS_SIZE; j++) + for (j = 1; j < BLUR_SIZE; j++) { vec2 offset = direction * j; float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear); float depthExpected = depthCenter + dot(centerSlope, offset); if(abs(depthSample - depthExpected) < 5.0) { +#if defined(USE_GAUSS) result += texture2D(imageMap, tex + offset) * gauss[j]; total += gauss[j]; +#else + result += texture2D(imageMap, tex + offset); + total += 1.0; +#endif } } diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index f7720443..e0715d04 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -957,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); @@ -1043,15 +1046,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); @@ -1059,13 +1059,39 @@ 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) @@ -1073,6 +1099,9 @@ const void *RB_DrawSurfs( const void *data ) { vec4_t quadVerts[4]; vec2_t texCoords[4]; + viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width); + viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height); + FBO_Bind(tr.quarterFbo[0]); qglViewport(0, 0, tr.quarterFbo[0]->width, tr.quarterFbo[0]->height); @@ -1094,16 +1123,7 @@ 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); @@ -1118,16 +1138,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); @@ -1142,16 +1153,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); diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index 12293766..80d59f62 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -310,6 +310,14 @@ void FBO_Init(void) qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); } + if (r_shadowBlur->integer) + { + tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height); + FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0); + FBO_AttachImage(tr.screenScratchFbo, tr.renderDepthImage, GL_DEPTH_ATTACHMENT_EXT, 0); + R_CheckFBO(tr.screenScratchFbo); + } + if (r_drawSunRays->integer) { tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index d567193b..7e2d452e 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2755,6 +2755,12 @@ void R_CreateBuiltinImages( void ) { tr.renderImage = R_CreateImage("_render", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, hdrFormat); + if (r_shadowBlur->integer) + tr.screenScratchImage = R_CreateImage("screenScratch", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); + + if (r_shadowBlur->integer || r_ssao->integer) + tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB); + if (r_drawSunRays->integer) tr.sunRaysImage = R_CreateImage("*sunRays", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, rgbFormat); @@ -2802,7 +2808,6 @@ void R_CreateBuiltinImages( void ) { if (r_ssao->integer) { tr.screenSsaoImage = R_CreateImage("*screenSsao", NULL, width / 2, height / 2, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_RGBA8); - tr.hdrDepthImage = R_CreateImage("*hdrDepth", NULL, width, height, IMGTYPE_COLORALPHA, IMGFLAG_NO_COMPRESSION | IMGFLAG_CLAMPTOEDGE, GL_INTENSITY32F_ARB); } if (r_shadows->integer == 4) diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 18eecf0b..06c4f0ae 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -161,6 +161,7 @@ cvar_t *r_sunlightMode; cvar_t *r_drawSunRays; cvar_t *r_sunShadows; cvar_t *r_shadowFilter; +cvar_t *r_shadowBlur; cvar_t *r_shadowMapSize; cvar_t *r_shadowCascadeZNear; cvar_t *r_shadowCascadeZFar; @@ -1180,7 +1181,8 @@ void R_Register( void ) r_sunShadows = ri.Cvar_Get( "r_sunShadows", "1", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowFilter = ri.Cvar_Get( "r_shadowFilter", "1", CVAR_ARCHIVE | CVAR_LATCH ); - r_shadowMapSize = ri.Cvar_Get( "r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH ); + r_shadowBlur = ri.Cvar_Get("r_shadowBlur", "0", CVAR_ARCHIVE | CVAR_LATCH); + r_shadowMapSize = ri.Cvar_Get("r_shadowMapSize", "1024", CVAR_ARCHIVE | CVAR_LATCH); r_shadowCascadeZNear = ri.Cvar_Get( "r_shadowCascadeZNear", "8", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowCascadeZFar = ri.Cvar_Get( "r_shadowCascadeZFar", "1024", CVAR_ARCHIVE | CVAR_LATCH ); r_shadowCascadeZBias = ri.Cvar_Get( "r_shadowCascadeZBias", "0", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index 62bf1e03..e2a3fe17 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1521,6 +1521,7 @@ typedef struct { image_t *sunRaysImage; image_t *renderDepthImage; image_t *pshadowMaps[MAX_DRAWN_PSHADOWS]; + image_t *screenScratchImage; image_t *textureScratchImage[2]; image_t *quarterImage[2]; image_t *calcLevelsImage; @@ -1539,6 +1540,7 @@ typedef struct { FBO_t *sunRaysFbo; FBO_t *depthFbo; FBO_t *pshadowFbos[MAX_DRAWN_PSHADOWS]; + FBO_t *screenScratchFbo; FBO_t *textureScratchFbo[2]; FBO_t *quarterFbo[2]; FBO_t *calcLevelsFbo; @@ -1809,6 +1811,7 @@ extern cvar_t *r_sunlightMode; extern cvar_t *r_drawSunRays; extern cvar_t *r_sunShadows; extern cvar_t *r_shadowFilter; +extern cvar_t *r_shadowBlur; extern cvar_t *r_shadowMapSize; extern cvar_t *r_shadowCascadeZNear; extern cvar_t *r_shadowCascadeZFar; -- cgit From 7c858dafb7941be2ea6522a2a267252abf2d4fe7 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 7 Mar 2016 03:30:16 -0800 Subject: OpenGL2: Add r_glossType. --- src/renderergl2/glsl/lightall_fp.glsl | 14 ++++++++++++-- src/renderergl2/tr_glsl.c | 17 +++++++++++++++++ src/renderergl2/tr_init.c | 2 ++ src/renderergl2/tr_local.h | 1 + 4 files changed, 32 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 6a0a5155..8edbebda 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -332,19 +332,29 @@ void main() // diffuse rgb is base color // specular red is smoothness // specular green is metallicness - float roughness = 1.0 - specular.r; + float gloss = specular.r; specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); diffuse.rgb *= 1.0 - specular.g; #else // diffuse rgb is diffuse // specular rgb is specular reflectance at normal incidence // specular alpha is gloss - float roughness = exp2(-3.0 * specular.a); + float gloss = specular.a; // adjust diffuse by specular reflectance, to maintain energy conservation diffuse.rgb *= vec3(1.0) - specular.rgb; #endif + #if defined(GLOSS_IS_GLOSS) + float roughness = exp2(-3.0 * gloss); + #elif defined(GLOSS_IS_SMOOTHNESS) + float roughness = 1.0 - gloss; + #elif defined(GLOSS_IS_ROUGHNESS) + float roughness = gloss; + #elif defined(GLOSS_IS_SHININESS) + float roughness = pow(2.0 / (8190.0 * gloss + 2.0), 0.25); + #endif + reflectance = CalcDiffuse(diffuse.rgb, NH, EH, roughness); gl_FragColor.rgb = lightColor * reflectance * (attenuation * NL); diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index f8637a66..b825c19e 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1057,6 +1057,23 @@ void GLSL_InitGPUShaders(void) if (r_cubeMapping->integer) Q_strcat(extradefines, 1024, "#define USE_CUBEMAP\n"); + + switch (r_glossType->integer) + { + case 0: + default: + Q_strcat(extradefines, 1024, "#define GLOSS_IS_GLOSS\n"); + break; + case 1: + Q_strcat(extradefines, 1024, "#define GLOSS_IS_SMOOTHNESS\n"); + break; + case 2: + Q_strcat(extradefines, 1024, "#define GLOSS_IS_ROUGHNESS\n"); + break; + case 3: + Q_strcat(extradefines, 1024, "#define GLOSS_IS_SHININESS\n"); + break; + } } if (i & LIGHTDEF_USE_SHADOWMAP) diff --git a/src/renderergl2/tr_init.c b/src/renderergl2/tr_init.c index 06c4f0ae..4f0a53f4 100644 --- a/src/renderergl2/tr_init.c +++ b/src/renderergl2/tr_init.c @@ -146,6 +146,7 @@ cvar_t *r_baseNormalY; cvar_t *r_baseParallax; cvar_t *r_baseSpecular; cvar_t *r_baseGloss; +cvar_t *r_glossType; cvar_t *r_mergeLightmaps; cvar_t *r_dlightMode; cvar_t *r_pshadowDist; @@ -1164,6 +1165,7 @@ void R_Register( void ) r_baseParallax = ri.Cvar_Get( "r_baseParallax", "0.05", CVAR_ARCHIVE | CVAR_LATCH ); r_baseSpecular = ri.Cvar_Get( "r_baseSpecular", "0.04", CVAR_ARCHIVE | CVAR_LATCH ); r_baseGloss = ri.Cvar_Get( "r_baseGloss", "0.3", CVAR_ARCHIVE | CVAR_LATCH ); + r_glossType = ri.Cvar_Get("r_glossType", "1", CVAR_ARCHIVE | CVAR_LATCH); r_dlightMode = ri.Cvar_Get( "r_dlightMode", "0", CVAR_ARCHIVE | CVAR_LATCH ); r_pshadowDist = ri.Cvar_Get( "r_pshadowDist", "128", CVAR_ARCHIVE ); r_mergeLightmaps = ri.Cvar_Get( "r_mergeLightmaps", "1", CVAR_ARCHIVE | CVAR_LATCH ); diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index e2a3fe17..d11c4870 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1796,6 +1796,7 @@ extern cvar_t *r_baseNormalY; extern cvar_t *r_baseParallax; extern cvar_t *r_baseSpecular; extern cvar_t *r_baseGloss; +extern cvar_t *r_glossType; extern cvar_t *r_dlightMode; extern cvar_t *r_pshadowDist; extern cvar_t *r_mergeLightmaps; -- cgit From c1ec25db8442cacf87df39d1e8e54b819b83a047 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 8 Mar 2016 18:30:51 -0800 Subject: OpenGL2: Speedup for SSAO & blur shaders, fix sunlight normals in lightall. --- src/renderergl2/glsl/depthblur_fp.glsl | 46 ++++++++++++++--------------- src/renderergl2/glsl/lightall_fp.glsl | 4 +-- src/renderergl2/glsl/ssao_fp.glsl | 54 +++++++++++++++++----------------- src/renderergl2/tr_backend.c | 7 +++-- 4 files changed, 57 insertions(+), 54 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl index 15f7be27..60a261c5 100644 --- a/src/renderergl2/glsl/depthblur_fp.glsl +++ b/src/renderergl2/glsl/depthblur_fp.glsl @@ -11,22 +11,23 @@ float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; - return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); + float sampleZDivW = texture2D(depthMap, tex).r; + return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } -vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar) +vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale) { - vec2 scale = u_ViewInfo.zw; + float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); + //scale /= zFarDivZNear * depthCenter; + //int blurSteps = int(float(BLUR_SIZE) / (zFarDivZNear * depthCenter)); #if defined(USE_HORIZONTAL_BLUR) - vec2 direction = vec2(1.0, 0.0) * scale; + vec2 direction = vec2(scale.x, 0.0); #else // if defined(USE_VERTICAL_BLUR) - vec2 direction = vec2(0.0, 1.0) * scale; + vec2 direction = vec2(0.0, scale.y); #endif - - float depthCenter = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); - vec2 centerSlope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); + + vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); #if defined(USE_GAUSS) vec4 result = texture2D(imageMap, tex) * gauss[0]; @@ -36,33 +37,32 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa float total = 1.0; #endif + float zLimit = 5.0 / zFar; int i, j; for (i = 0; i < 2; i++) { for (j = 1; j < BLUR_SIZE; j++) { vec2 offset = direction * j; - float depthSample = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear); - float depthExpected = depthCenter + dot(centerSlope, offset); - if(abs(depthSample - depthExpected) < 5.0) - { + float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear); + float depthExpected = depthCenter + dot(slope, offset); + float useSample = float(abs(depthSample - depthExpected) < zLimit); #if defined(USE_GAUSS) - result += texture2D(imageMap, tex + offset) * gauss[j]; - total += gauss[j]; + result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample); + total += gauss[j] * useSample; #else - result += texture2D(imageMap, tex + offset); - total += 1.0; + result += texture2D(imageMap, tex + offset) * useSample; + total += useSample; #endif - } } - + direction = -direction; - } - + } + return result / total; } void main() -{ - gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y); +{ + gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw); } diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index 8edbebda..f16298a3 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -292,7 +292,7 @@ void main() float shadowValue = texture2D(u_ShadowMap, shadowTex).r; // surfaces not facing the light are always shadowed - shadowValue *= clamp(dot(var_Normal.xyz, var_PrimaryLightDir.xyz), 0.0, 1.0); + shadowValue *= clamp(dot(N, var_PrimaryLightDir.xyz), 0.0, 1.0); #if defined(SHADOWMAP_MODULATE) lightColor *= shadowValue * (1.0 - u_PrimaryLightAmbient.r) + u_PrimaryLightAmbient.r; @@ -330,7 +330,7 @@ void main() #if defined(USE_PBR) // diffuse rgb is base color - // specular red is smoothness + // specular red is gloss // specular green is metallicness float gloss = specular.r; specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); diff --git a/src/renderergl2/glsl/ssao_fp.glsl b/src/renderergl2/glsl/ssao_fp.glsl index 6263284c..84f18cb7 100644 --- a/src/renderergl2/glsl/ssao_fp.glsl +++ b/src/renderergl2/glsl/ssao_fp.glsl @@ -1,6 +1,6 @@ uniform sampler2D u_ScreenDepthMap; -uniform vec4 u_ViewInfo; // zfar / znear, zfar +uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height varying vec2 var_ScreenTex; @@ -11,6 +11,7 @@ vec2(0.5784913, -0.002528916), vec2(0.192888, 0.4064181), vec2(-0.6335801, -0.5247476), vec2(-0.5579782, 0.7491854), vec2(0.7320465, 0.6317794) ); +#define NUM_SAMPLES 3 // Input: It uses texture coords as the random number seed. // Output: Random number: [0,1), that is between 0.0 and 0.999999... inclusive. @@ -39,48 +40,47 @@ mat2 randomRotation( const vec2 p ) float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; - return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); + float sampleZDivW = texture2D(depthMap, tex).r; + return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } -float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar) +float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZNear, const float zFar, const vec2 scale) { float result = 0; - float sampleZ = zFar * getLinearDepth(depthMap, tex, zFarDivZNear); + float sampleZ = getLinearDepth(depthMap, tex, zFarDivZNear); + float scaleZ = zFarDivZNear * sampleZ; - vec2 expectedSlope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y)); - - if (length(expectedSlope) > 5000.0) + vec2 slope = vec2(dFdx(sampleZ), dFdy(sampleZ)) / vec2(dFdx(tex.x), dFdy(tex.y)); + + if (length(slope) * zFar > 5000.0) return 1.0; - - vec2 offsetScale = vec2(3.0 / sampleZ); - + + vec2 offsetScale = vec2(scale * 1024.0 / scaleZ); + mat2 rmat = randomRotation(tex); - + + float invZFar = 1.0 / zFar; + float zLimit = 20.0 * invZFar; int i; - for (i = 0; i < 3; i++) + for (i = 0; i < NUM_SAMPLES; i++) { vec2 offset = rmat * poissonDisc[i] * offsetScale; - float sampleZ2 = zFar * getLinearDepth(depthMap, tex + offset, zFarDivZNear); - - if (abs(sampleZ - sampleZ2) > 20.0) - result += 1.0; - else - { - float expectedZ = sampleZ + dot(expectedSlope, offset); - result += step(expectedZ - 1.0, sampleZ2); - } + float sampleDiff = getLinearDepth(depthMap, tex + offset, zFarDivZNear) - sampleZ; + + bool s1 = abs(sampleDiff) > zLimit; + bool s2 = sampleDiff + invZFar > dot(slope, offset); + result += float(s1 || s2); } - - result *= 0.33333; - + + result *= 1.0 / float(NUM_SAMPLES); + return result; } void main() { - float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y); - + float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw); + gl_FragColor = vec4(vec3(result), 1.0); } diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index e0715d04..420c785b 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -1099,8 +1099,8 @@ const void *RB_DrawSurfs( const void *data ) { vec4_t quadVerts[4]; vec2_t texCoords[4]; - viewInfo[2] = 1.0f / (float)(tr.quarterImage[0]->width); - viewInfo[3] = 1.0f / (float)(tr.quarterImage[0]->height); + 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); FBO_Bind(tr.quarterFbo[0]); @@ -1128,6 +1128,9 @@ const void *RB_DrawSurfs( const void *data ) { 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); -- cgit From 026f8e89306cc9783c40d75f300c77ab8688cf9b Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Wed, 9 Mar 2016 18:03:23 -0800 Subject: OpenGL2: Create FBOs if target image exists, not cvar settings. --- src/renderergl2/tr_fbo.c | 38 ++++++++++++++++++++++++++------------ 1 file changed, 26 insertions(+), 12 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index 80d59f62..d013748e 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -310,7 +310,7 @@ void FBO_Init(void) qglClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); } - if (r_shadowBlur->integer) + if (tr.screenScratchImage) { tr.screenScratchFbo = FBO_Create("screenScratch", tr.screenScratchImage->width, tr.screenScratchImage->height); FBO_AttachImage(tr.screenScratchFbo, tr.screenScratchImage, GL_COLOR_ATTACHMENT0_EXT, 0); @@ -318,7 +318,7 @@ void FBO_Init(void) R_CheckFBO(tr.screenScratchFbo); } - if (r_drawSunRays->integer) + if (tr.sunRaysImage) { tr.sunRaysFbo = FBO_Create("_sunRays", tr.renderDepthImage->width, tr.renderDepthImage->height); FBO_AttachImage(tr.sunRaysFbo, tr.sunRaysImage, GL_COLOR_ATTACHMENT0_EXT, 0); @@ -340,7 +340,7 @@ void FBO_Init(void) if (tr.sunShadowDepthImage[0]) { - for ( i = 0; i < 4; i++) + for (i = 0; i < 4; i++) { tr.sunShadowFbo[i] = FBO_Create("_sunshadowmap", tr.sunShadowDepthImage[i]->width, tr.sunShadowDepthImage[i]->height); // FIXME: this next line wastes 16mb with 4x1024x1024 sun shadow maps, skip if OpenGL 4.3+ or ARB_framebuffer_no_attachments @@ -349,44 +349,58 @@ void FBO_Init(void) FBO_AttachImage(tr.sunShadowFbo[i], tr.sunShadowDepthImage[i], GL_DEPTH_ATTACHMENT_EXT, 0); R_CheckFBO(tr.sunShadowFbo[i]); } + } + if (tr.screenShadowImage) + { tr.screenShadowFbo = FBO_Create("_screenshadow", tr.screenShadowImage->width, tr.screenShadowImage->height); FBO_AttachImage(tr.screenShadowFbo, tr.screenShadowImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenShadowFbo); } - for (i = 0; i < 2; i++) + if (tr.textureScratchImage[0]) { - tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); - FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); - R_CheckFBO(tr.textureScratchFbo[i]); + for (i = 0; i < 2; i++) + { + tr.textureScratchFbo[i] = FBO_Create(va("_texturescratch%d", i), tr.textureScratchImage[i]->width, tr.textureScratchImage[i]->height); + FBO_AttachImage(tr.textureScratchFbo[i], tr.textureScratchImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); + R_CheckFBO(tr.textureScratchFbo[i]); + } } + if (tr.calcLevelsImage) { tr.calcLevelsFbo = FBO_Create("_calclevels", tr.calcLevelsImage->width, tr.calcLevelsImage->height); FBO_AttachImage(tr.calcLevelsFbo, tr.calcLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.calcLevelsFbo); } + if (tr.targetLevelsImage) { tr.targetLevelsFbo = FBO_Create("_targetlevels", tr.targetLevelsImage->width, tr.targetLevelsImage->height); FBO_AttachImage(tr.targetLevelsFbo, tr.targetLevelsImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.targetLevelsFbo); } - for (i = 0; i < 2; i++) + if (tr.quarterImage[0]) { - tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); - FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); - R_CheckFBO(tr.quarterFbo[i]); + for (i = 0; i < 2; i++) + { + tr.quarterFbo[i] = FBO_Create(va("_quarter%d", i), tr.quarterImage[i]->width, tr.quarterImage[i]->height); + FBO_AttachImage(tr.quarterFbo[i], tr.quarterImage[i], GL_COLOR_ATTACHMENT0_EXT, 0); + R_CheckFBO(tr.quarterFbo[i]); + } } - if (r_ssao->integer) + if (tr.hdrDepthImage) { tr.hdrDepthFbo = FBO_Create("_hdrDepth", tr.hdrDepthImage->width, tr.hdrDepthImage->height); FBO_AttachImage(tr.hdrDepthFbo, tr.hdrDepthImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.hdrDepthFbo); + } + if (tr.screenSsaoImage) + { tr.screenSsaoFbo = FBO_Create("_screenssao", tr.screenSsaoImage->width, tr.screenSsaoImage->height); FBO_AttachImage(tr.screenSsaoFbo, tr.screenSsaoImage, GL_COLOR_ATTACHMENT0_EXT, 0); R_CheckFBO(tr.screenSsaoFbo); -- cgit From 46cb9a5112fecbdf152bccf692d89bfca564e987 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Thu, 10 Mar 2016 03:44:21 -0800 Subject: OpenGL2: Fixes to depth blur and ssao. --- src/renderergl2/glsl/depthblur_fp.glsl | 11 +++++++---- src/renderergl2/glsl/ssao_fp.glsl | 5 +++-- src/renderergl2/tr_backend.c | 7 ++----- 3 files changed, 12 insertions(+), 11 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl index 60a261c5..a5b264fd 100644 --- a/src/renderergl2/glsl/depthblur_fp.glsl +++ b/src/renderergl2/glsl/depthblur_fp.glsl @@ -4,6 +4,7 @@ uniform sampler2D u_ScreenDepthMap; uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height varying vec2 var_ScreenTex; +//float gauss[8] = float[8](0.17, 0.17, 0.16, 0.14, 0.12, 0.1, 0.08, 0.06); //float gauss[5] = float[5](0.30, 0.23, 0.097, 0.024, 0.0033); float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); //float gauss[3] = float[3](0.60, 0.19, 0.0066); @@ -11,15 +12,17 @@ float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; + // depth is upside down? + float sampleZDivW = texture2D(depthMap, vec2(tex.x, 1.0 - tex.y)).r; return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale) { float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); - //scale /= zFarDivZNear * depthCenter; - //int blurSteps = int(float(BLUR_SIZE) / (zFarDivZNear * depthCenter)); + + // enable for less blurring for farther objects + //scale /= min(zFarDivZNear * depthCenter / 32.0, 2.0); #if defined(USE_HORIZONTAL_BLUR) vec2 direction = vec2(scale.x, 0.0); @@ -64,5 +67,5 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa void main() { - gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw); + gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz); } diff --git a/src/renderergl2/glsl/ssao_fp.glsl b/src/renderergl2/glsl/ssao_fp.glsl index 84f18cb7..1714c2be 100644 --- a/src/renderergl2/glsl/ssao_fp.glsl +++ b/src/renderergl2/glsl/ssao_fp.glsl @@ -40,7 +40,8 @@ mat2 randomRotation( const vec2 p ) float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - float sampleZDivW = texture2D(depthMap, tex).r; + // depth is upside down? + float sampleZDivW = texture2D(depthMap, vec2(tex.x, 1.0 - tex.y)).r; return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } @@ -80,7 +81,7 @@ float ambientOcclusion(sampler2D depthMap, const vec2 tex, const float zFarDivZN void main() { - float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw); + float result = ambientOcclusion(u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz); gl_FragColor = vec4(vec3(result), 1.0); } diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 420c785b..708b395f 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -978,7 +978,7 @@ const void *RB_DrawSurfs( const void *data ) { 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); @@ -1080,7 +1080,6 @@ const void *RB_DrawSurfs( const void *data ) { RB_InstantQuad2(quadVerts, texCoords); - FBO_Bind(tr.screenShadowFbo); GLSL_BindProgram(&tr.depthBlurShader[1]); @@ -1101,6 +1100,7 @@ const void *RB_DrawSurfs( const void *data ) { 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]); @@ -1542,9 +1542,6 @@ const void *RB_PostProcess(const void *data) 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); } -- cgit From e4c921a3b24d7631af8d119a5175321b6eb1c1f7 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Fri, 11 Mar 2016 04:37:50 -0800 Subject: OpenGL2: More ssao/depth blur improvements. --- src/renderergl2/glsl/depthblur_fp.glsl | 18 +++++++++++------- src/renderergl2/glsl/depthblur_vp.glsl | 5 ++++- src/renderergl2/glsl/ssao_fp.glsl | 3 +-- src/renderergl2/tr_backend.c | 7 +++++-- 4 files changed, 21 insertions(+), 12 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl index a5b264fd..9685f6d7 100644 --- a/src/renderergl2/glsl/depthblur_fp.glsl +++ b/src/renderergl2/glsl/depthblur_fp.glsl @@ -9,11 +9,11 @@ varying vec2 var_ScreenTex; float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); //float gauss[3] = float[3](0.60, 0.19, 0.0066); #define BLUR_SIZE 4 +//#define USE_GAUSS float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - // depth is upside down? - float sampleZDivW = texture2D(depthMap, vec2(tex.x, 1.0 - tex.y)).r; + float sampleZDivW = texture2D(depthMap, tex).r; return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } @@ -22,12 +22,14 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); // enable for less blurring for farther objects - //scale /= min(zFarDivZNear * depthCenter / 32.0, 2.0); + scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0); #if defined(USE_HORIZONTAL_BLUR) - vec2 direction = vec2(scale.x, 0.0); + vec2 direction = vec2(scale.x * 2.0, 0.0); + vec2 nudge = vec2(0.0, scale.y * 0.5); #else // if defined(USE_VERTICAL_BLUR) - vec2 direction = vec2(0.0, scale.y); + vec2 direction = vec2(0.0, scale.y * 2.0); + vec2 nudge = vec2(scale.x * 0.5, 0.0); #endif vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); @@ -46,7 +48,7 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa { for (j = 1; j < BLUR_SIZE; j++) { - vec2 offset = direction * j; + vec2 offset = direction * (float(j) - 0.25) + nudge; float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear); float depthExpected = depthCenter + dot(slope, offset); float useSample = float(abs(depthSample - depthExpected) < zLimit); @@ -57,9 +59,11 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa result += texture2D(imageMap, tex + offset) * useSample; total += useSample; #endif + nudge = -nudge; } direction = -direction; + nudge = -nudge; } return result / total; @@ -67,5 +71,5 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa void main() { - gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.wz); + gl_FragColor = depthGaussian1D(u_ScreenImageMap, u_ScreenDepthMap, var_ScreenTex, u_ViewInfo.x, u_ViewInfo.y, u_ViewInfo.zw); } diff --git a/src/renderergl2/glsl/depthblur_vp.glsl b/src/renderergl2/glsl/depthblur_vp.glsl index 9c46a79f..ba0b6c56 100644 --- a/src/renderergl2/glsl/depthblur_vp.glsl +++ b/src/renderergl2/glsl/depthblur_vp.glsl @@ -1,12 +1,15 @@ attribute vec4 attr_Position; attribute vec4 attr_TexCoord0; +uniform vec4 u_ViewInfo; // zfar / znear, zfar, 1/width, 1/height + varying vec2 var_ScreenTex; void main() { gl_Position = attr_Position; - var_ScreenTex = attr_TexCoord0.xy; + var_ScreenTex = (floor(attr_TexCoord0.xy * (1.0 / u_ViewInfo.zw - vec2(1.0))) + vec2(0.5)) * u_ViewInfo.zw; + //vec2 screenCoords = gl_Position.xy / gl_Position.w; //var_ScreenTex = screenCoords * 0.5 + 0.5; } diff --git a/src/renderergl2/glsl/ssao_fp.glsl b/src/renderergl2/glsl/ssao_fp.glsl index 1714c2be..93f61859 100644 --- a/src/renderergl2/glsl/ssao_fp.glsl +++ b/src/renderergl2/glsl/ssao_fp.glsl @@ -40,8 +40,7 @@ mat2 randomRotation( const vec2 p ) float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { - // depth is upside down? - float sampleZDivW = texture2D(depthMap, vec2(tex.x, 1.0 - tex.y)).r; + float sampleZDivW = texture2D(depthMap, tex).r; return 1.0 / mix(zFarDivZNear, 1.0, sampleZDivW); } diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index 708b395f..f523ab32 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -981,7 +981,11 @@ const void *RB_DrawSurfs( const void *data ) { 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); + ivec4_t srcBox; + + VectorSet4(srcBox, 0, tr.renderDepthImage->height, tr.renderDepthImage->width, -tr.renderDepthImage->height); + + FBO_BlitFromTexture(tr.renderDepthImage, srcBox, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0); } if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT) @@ -1541,7 +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); FBO_Blit(tr.screenSsaoFbo, srcBox, NULL, srcFbo, dstBox, NULL, NULL, GLS_SRCBLEND_DST_COLOR | GLS_DSTBLEND_ZERO); } -- cgit From beefb51f51ab807f89d67f16488240951bb1af68 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 14 Mar 2016 06:45:51 -0700 Subject: OpenGL2: Fix r_lightmap. --- src/renderergl2/tr_shade.c | 41 +++++++++++++++++++++++++++-------------- 1 file changed, 27 insertions(+), 14 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index b8295657..885e2718 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -1142,9 +1142,9 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) index |= LIGHTDEF_USE_SHADOWMAP; } - if (r_lightmap->integer && index & LIGHTDEF_USE_LIGHTMAP) + if (r_lightmap->integer && ((index & LIGHTDEF_LIGHTTYPE_MASK) == LIGHTDEF_USE_LIGHTMAP)) { - index = LIGHTDEF_USE_LIGHTMAP; + index = LIGHTDEF_USE_TCGEN_AND_TCMOD; } sp = &pStage->glslShaderGroup[index]; @@ -1233,19 +1233,32 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformVec4(sp, UNIFORM_FOGCOLORMASK, fogColorMask); } - ComputeTexMods( pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb ); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); - GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); + if (r_lightmap->integer) + { + vec4_t v; + VectorSet4(v, 1.0f, 0.0f, 0.0f, 1.0f); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, v); + VectorSet4(v, 0.0f, 0.0f, 0.0f, 0.0f); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, v); - GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); - if (pStage->bundle[0].tcGen == TCGEN_VECTOR) + GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, TCGEN_LIGHTMAP); + } + else { - vec3_t vec; + ComputeTexMods(pStage, TB_DIFFUSEMAP, texMatrix, texOffTurb); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXMATRIX, texMatrix); + GLSL_SetUniformVec4(sp, UNIFORM_DIFFUSETEXOFFTURB, texOffTurb); - VectorCopy(pStage->bundle[0].tcGenVectors[0], vec); - GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec); - VectorCopy(pStage->bundle[0].tcGenVectors[1], vec); - GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec); + GLSL_SetUniformInt(sp, UNIFORM_TCGEN0, pStage->bundle[0].tcGen); + if (pStage->bundle[0].tcGen == TCGEN_VECTOR) + { + vec3_t vec; + + VectorCopy(pStage->bundle[0].tcGenVectors[0], vec); + GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR0, vec); + VectorCopy(pStage->bundle[0].tcGenVectors[1], vec); + GLSL_SetUniformVec3(sp, UNIFORM_TCGEN0VECTOR1, vec); + } } GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); @@ -1295,7 +1308,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (i == TB_LIGHTMAP) + if (i == TB_COLORMAP) R_BindAnimatedImageToTMU( &pStage->bundle[TB_LIGHTMAP], i); else GL_BindToTMU( tr.whiteImage, i ); @@ -1305,7 +1318,7 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) { for (i = 0; i < NUM_TEXTURE_BUNDLES; i++) { - if (i == TB_LIGHTMAP) + if (i == TB_COLORMAP) R_BindAnimatedImageToTMU( &pStage->bundle[TB_DELUXEMAP], i); else GL_BindToTMU( tr.whiteImage, i ); -- cgit From b74cc1c42c5bfb2a0a17fc3c083a5a488c159d0d Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 15 Mar 2016 05:20:25 -0700 Subject: OpenGL2: Fix horribly broken metallic shader. --- src/renderergl2/glsl/lightall_fp.glsl | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/lightall_fp.glsl b/src/renderergl2/glsl/lightall_fp.glsl index f16298a3..64cae3fa 100644 --- a/src/renderergl2/glsl/lightall_fp.glsl +++ b/src/renderergl2/glsl/lightall_fp.glsl @@ -333,8 +333,9 @@ void main() // specular red is gloss // specular green is metallicness float gloss = specular.r; - specular.rgb = specular.g * diffuse.rgb + vec3(0.04 - 0.04 * specular.g); - diffuse.rgb *= 1.0 - specular.g; + float metal = specular.g; + specular.rgb = metal * diffuse.rgb + vec3(0.04 - 0.04 * metal); + diffuse.rgb *= 1.0 - metal; #else // diffuse rgb is diffuse // specular rgb is specular reflectance at normal incidence -- cgit From 92f4cec8690c90188fed24b0c2b8f0c32d245cbd Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Mon, 28 Mar 2016 22:26:19 -0700 Subject: OpenGL2: Improve cubemap outside error. --- src/renderergl2/tr_main.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_main.c b/src/renderergl2/tr_main.c index f4261033..9751ecb3 100644 --- a/src/renderergl2/tr_main.c +++ b/src/renderergl2/tr_main.c @@ -2932,12 +2932,16 @@ void R_RenderCubemapSide( int cubemapIndex, int cubemapSide, qboolean subscene ) { vec3_t ambient, directed, lightDir; + float scale; + R_LightForPoint(tr.refdef.vieworg, ambient, directed, lightDir); - tr.refdef.colorScale = 1.0f; //766.0f / (directed[0] + directed[1] + directed[2] + 1.0f); + scale = directed[0] + directed[1] + directed[2] + ambient[0] + ambient[1] + ambient[2] + 1.0f; + + tr.refdef.colorScale = 1.0f; //766.0f / scale; // only print message for first side - if (directed[0] + directed[1] + directed[2] == 0 && cubemapSide == 0) + if (scale < 1.0001f && cubemapSide == 0) { - ri.Printf(PRINT_ALL, "cubemap %d %s (%f, %f, %f) is outside the lightgrid!\n", cubemapIndex, tr.cubemaps[cubemapIndex].name, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]); + ri.Printf(PRINT_ALL, "cubemap %d %s (%f, %f, %f) is outside the lightgrid or inside a wall!\n", cubemapIndex, tr.cubemaps[cubemapIndex].name, tr.refdef.vieworg[0], tr.refdef.vieworg[1], tr.refdef.vieworg[2]); } } -- cgit From 137f8bc53e9895826548d0f398d6faaa36215bb5 Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 5 Apr 2016 02:21:14 -0700 Subject: OpenGL2: Render metals as nonmetal on cubemaps, and some ComputeShaderColors cleanup. --- src/renderergl2/tr_shade.c | 44 ++++++++++++++++++++++++++------------------ 1 file changed, 26 insertions(+), 18 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_shade.c b/src/renderergl2/tr_shade.c index 885e2718..2578420c 100644 --- a/src/renderergl2/tr_shade.c +++ b/src/renderergl2/tr_shade.c @@ -447,11 +447,12 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t || ((blend & GLS_SRCBLEND_BITS) == GLS_SRCBLEND_ONE_MINUS_DST_COLOR) || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_SRC_COLOR) || ((blend & GLS_DSTBLEND_BITS) == GLS_DSTBLEND_ONE_MINUS_SRC_COLOR); + qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); + float scale = 1.0f; #if defined(USE_OVERBRIGHT) float exactLight = 1.0f; #else - qboolean isWorldDraw = !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL); float exactLight = (isBlend || !isWorldDraw) ? 1.0f : (float)(1 << r_mapOverBrightBits->integer); #endif @@ -611,17 +612,16 @@ static void ComputeShaderColors( shaderStage_t *pStage, vec4_t baseColor, vec4_t break; } - // multiply color by overbrightbits if this isn't a blend if (tr.overbrightBits && !isBlend) + scale *= 1 << tr.overbrightBits; + + if ((backEnd.refdef.colorScale != 1.0f) && !isBlend && isWorldDraw) + scale *= backEnd.refdef.colorScale; + + if (scale != 1.0f) { - float scale = 1 << tr.overbrightBits; - - baseColor[0] *= scale; - baseColor[1] *= scale; - baseColor[2] *= scale; - vertColor[0] *= scale; - vertColor[1] *= scale; - vertColor[2] *= scale; + VectorScale(baseColor, scale, baseColor); + VectorScale(vertColor, scale, vertColor); } // FIXME: find some way to implement this. @@ -1072,6 +1072,8 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) int deformGen; vec5_t deformParams; + qboolean renderToCubemap = tr.renderCubeFbo && glState.currentFBO == tr.renderCubeFbo; + ComputeDeformValues(&deformGen, deformParams); ComputeFogValues(fogDistanceVector, fogDepthVector, &eyeT); @@ -1187,13 +1189,6 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) ComputeShaderColors(pStage, baseColor, vertColor, pStage->stateBits); - if ((backEnd.refdef.colorScale != 1.0f) && !(backEnd.refdef.rdflags & RDF_NOWORLDMODEL)) - { - // use VectorScale to only scale first three values, not alpha - VectorScale(baseColor, backEnd.refdef.colorScale, baseColor); - VectorScale(vertColor, backEnd.refdef.colorScale, vertColor); - } - GLSL_SetUniformVec4(sp, UNIFORM_BASECOLOR, baseColor); GLSL_SetUniformVec4(sp, UNIFORM_VERTCOLOR, vertColor); } @@ -1264,7 +1259,20 @@ static void RB_IterateStagesGeneric( shaderCommands_t *input ) GLSL_SetUniformMat4(sp, UNIFORM_MODELMATRIX, backEnd.or.transformMatrix); GLSL_SetUniformVec4(sp, UNIFORM_NORMALSCALE, pStage->normalScale); - GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); + + { + vec4_t specularScale; + Vector4Copy(pStage->specularScale, specularScale); + + if (renderToCubemap) + { + // force specular to nonmetal if rendering cubemaps + if (r_pbr->integer) + specularScale[1] = 0.0f; + } + + GLSL_SetUniformVec4(sp, UNIFORM_SPECULARSCALE, pStage->specularScale); + } //GLSL_SetUniformFloat(sp, UNIFORM_MAPLIGHTSCALE, backEnd.refdef.mapLightScale); -- cgit From e1c7b8c9bd19f0e4d9b763d1f30c175e49c5397d Mon Sep 17 00:00:00 2001 From: SmileTheory Date: Tue, 5 Apr 2016 02:37:05 -0700 Subject: OpenGL2: Some FBO cleanup, and add non-depth blur to blur shader. --- src/renderergl2/glsl/depthblur_fp.glsl | 17 +++-- src/renderergl2/glsl/depthblur_vp.glsl | 3 +- src/renderergl2/tr_backend.c | 71 ++++++++++++++++++- src/renderergl2/tr_fbo.c | 120 ++++++++++++--------------------- src/renderergl2/tr_fbo.h | 2 +- src/renderergl2/tr_glsl.c | 7 +- src/renderergl2/tr_local.h | 2 +- src/renderergl2/tr_postprocess.c | 51 +++++--------- 8 files changed, 148 insertions(+), 125 deletions(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/glsl/depthblur_fp.glsl b/src/renderergl2/glsl/depthblur_fp.glsl index 9685f6d7..d71b3487 100644 --- a/src/renderergl2/glsl/depthblur_fp.glsl +++ b/src/renderergl2/glsl/depthblur_fp.glsl @@ -9,7 +9,10 @@ varying vec2 var_ScreenTex; float gauss[4] = float[4](0.40, 0.24, 0.054, 0.0044); //float gauss[3] = float[3](0.60, 0.19, 0.0066); #define BLUR_SIZE 4 + +#if !defined(USE_DEPTH) //#define USE_GAUSS +#endif float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNear) { @@ -19,21 +22,21 @@ float getLinearDepth(sampler2D depthMap, const vec2 tex, const float zFarDivZNea vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFarDivZNear, float zFar, vec2 scale) { - float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); - // enable for less blurring for farther objects +#if defined(USE_DEPTH) + float depthCenter = getLinearDepth(depthMap, tex, zFarDivZNear); + vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); scale /= clamp(zFarDivZNear * depthCenter / 32.0, 1.0, 2.0); +#endif #if defined(USE_HORIZONTAL_BLUR) vec2 direction = vec2(scale.x * 2.0, 0.0); vec2 nudge = vec2(0.0, scale.y * 0.5); #else // if defined(USE_VERTICAL_BLUR) vec2 direction = vec2(0.0, scale.y * 2.0); - vec2 nudge = vec2(scale.x * 0.5, 0.0); + vec2 nudge = vec2(-scale.x * 0.5, 0.0); #endif - vec2 slope = vec2(dFdx(depthCenter), dFdy(depthCenter)) / vec2(dFdx(tex.x), dFdy(tex.y)); - #if defined(USE_GAUSS) vec4 result = texture2D(imageMap, tex) * gauss[0]; float total = gauss[0]; @@ -49,9 +52,13 @@ vec4 depthGaussian1D(sampler2D imageMap, sampler2D depthMap, vec2 tex, float zFa for (j = 1; j < BLUR_SIZE; j++) { vec2 offset = direction * (float(j) - 0.25) + nudge; +#if defined(USE_DEPTH) float depthSample = getLinearDepth(depthMap, tex + offset, zFarDivZNear); float depthExpected = depthCenter + dot(slope, offset); float useSample = float(abs(depthSample - depthExpected) < zLimit); +#else + float useSample = 1.0; +#endif #if defined(USE_GAUSS) result += texture2D(imageMap, tex + offset) * (gauss[j] * useSample); total += gauss[j] * useSample; diff --git a/src/renderergl2/glsl/depthblur_vp.glsl b/src/renderergl2/glsl/depthblur_vp.glsl index ba0b6c56..9c47660c 100644 --- a/src/renderergl2/glsl/depthblur_vp.glsl +++ b/src/renderergl2/glsl/depthblur_vp.glsl @@ -8,7 +8,8 @@ varying vec2 var_ScreenTex; void main() { gl_Position = attr_Position; - var_ScreenTex = (floor(attr_TexCoord0.xy * (1.0 / u_ViewInfo.zw - vec2(1.0))) + vec2(0.5)) * u_ViewInfo.zw; + vec2 wh = vec2(1.0) / u_ViewInfo.zw - vec2(1.0); + var_ScreenTex = (floor(attr_TexCoord0.xy * wh) + vec2(0.5)) * u_ViewInfo.zw; //vec2 screenCoords = gl_Position.xy / gl_Position.w; //var_ScreenTex = screenCoords * 0.5 + 0.5; diff --git a/src/renderergl2/tr_backend.c b/src/renderergl2/tr_backend.c index f523ab32..0e331752 100644 --- a/src/renderergl2/tr_backend.c +++ b/src/renderergl2/tr_backend.c @@ -981,11 +981,11 @@ const void *RB_DrawSurfs( const void *data ) { if (tr.hdrDepthFbo) { // need the depth in a texture we can do GL_LINEAR sampling on, so copy it to an HDR image - ivec4_t srcBox; + vec4_t srcTexCoords; - VectorSet4(srcBox, 0, tr.renderDepthImage->height, tr.renderDepthImage->width, -tr.renderDepthImage->height); + VectorSet4(srcTexCoords, 0.0f, 0.0f, 1.0f, 1.0f); - FBO_BlitFromTexture(tr.renderDepthImage, srcBox, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0); + FBO_BlitFromTexture(tr.renderDepthImage, srcTexCoords, NULL, tr.hdrDepthFbo, NULL, NULL, NULL, 0); } if (r_sunlightMode->integer && backEnd.viewParms.flags & VPF_USESUNLIGHT) @@ -1585,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; diff --git a/src/renderergl2/tr_fbo.c b/src/renderergl2/tr_fbo.c index d013748e..9ba63441 100644 --- a/src/renderergl2/tr_fbo.c +++ b/src/renderergl2/tr_fbo.c @@ -487,10 +487,9 @@ void R_FBOList_f(void) ri.Printf(PRINT_ALL, " %i FBOs\n", tr.numFBOs); } -void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend) +void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend) { - ivec4_t dstBox, srcBox; - vec2_t srcTexScale; + ivec4_t dstBox; vec4_t color; vec4_t quadVerts[4]; vec2_t texCoords[4]; @@ -505,49 +504,44 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS return; } - if (inSrcBox) + width = dst ? dst->width : glConfig.vidWidth; + height = dst ? dst->height : glConfig.vidHeight; + + if (inSrcTexCorners) { - VectorSet4(srcBox, inSrcBox[0], inSrcBox[1], inSrcBox[0] + inSrcBox[2], inSrcBox[1] + inSrcBox[3]); + VectorSet2(texCoords[0], inSrcTexCorners[0], inSrcTexCorners[1]); + VectorSet2(texCoords[1], inSrcTexCorners[2], inSrcTexCorners[1]); + VectorSet2(texCoords[2], inSrcTexCorners[2], inSrcTexCorners[3]); + VectorSet2(texCoords[3], inSrcTexCorners[0], inSrcTexCorners[3]); } else { - VectorSet4(srcBox, 0, 0, src->width, src->height); + VectorSet2(texCoords[0], 0.0f, 1.0f); + VectorSet2(texCoords[1], 1.0f, 1.0f); + VectorSet2(texCoords[2], 1.0f, 0.0f); + VectorSet2(texCoords[3], 0.0f, 0.0f); } // framebuffers are 0 bottom, Y up. if (inDstBox) { - if (dst) - { - dstBox[0] = inDstBox[0]; - dstBox[1] = dst->height - inDstBox[1] - inDstBox[3]; - dstBox[2] = inDstBox[0] + inDstBox[2]; - dstBox[3] = dst->height - inDstBox[1]; - } - else - { - dstBox[0] = inDstBox[0]; - dstBox[1] = glConfig.vidHeight - inDstBox[1] - inDstBox[3]; - dstBox[2] = inDstBox[0] + inDstBox[2]; - dstBox[3] = glConfig.vidHeight - inDstBox[1]; - } - } - else if (dst) - { - VectorSet4(dstBox, 0, dst->height, dst->width, 0); + dstBox[0] = inDstBox[0]; + dstBox[1] = height - inDstBox[1] - inDstBox[3]; + dstBox[2] = inDstBox[0] + inDstBox[2]; + dstBox[3] = height - inDstBox[1]; } else { - VectorSet4(dstBox, 0, glConfig.vidHeight, glConfig.vidWidth, 0); + VectorSet4(dstBox, 0, height, width, 0); } if (inSrcTexScale) { - VectorCopy2(inSrcTexScale, srcTexScale); + VectorCopy2(inSrcTexScale, invTexRes); } else { - srcTexScale[0] = srcTexScale[1] = 1.0f; + VectorSet2(invTexRes, 1.0f, 1.0f); } if (inColor) @@ -566,17 +560,6 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS FBO_Bind(dst); - if (glState.currentFBO) - { - width = glState.currentFBO->width; - height = glState.currentFBO->height; - } - else - { - width = glConfig.vidWidth; - height = glConfig.vidHeight; - } - qglViewport( 0, 0, width, height ); qglScissor( 0, 0, width, height ); @@ -586,18 +569,13 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS GL_BindToTMU(src, TB_COLORMAP); - VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0, 1); - VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0, 1); - VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0, 1); - VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0, 1); + VectorSet4(quadVerts[0], dstBox[0], dstBox[1], 0.0f, 1.0f); + VectorSet4(quadVerts[1], dstBox[2], dstBox[1], 0.0f, 1.0f); + VectorSet4(quadVerts[2], dstBox[2], dstBox[3], 0.0f, 1.0f); + VectorSet4(quadVerts[3], dstBox[0], dstBox[3], 0.0f, 1.0f); - texCoords[0][0] = srcBox[0] / (float)src->width; texCoords[0][1] = 1.0f - srcBox[1] / (float)src->height; - texCoords[1][0] = srcBox[2] / (float)src->width; texCoords[1][1] = 1.0f - srcBox[1] / (float)src->height; - texCoords[2][0] = srcBox[2] / (float)src->width; texCoords[2][1] = 1.0f - srcBox[3] / (float)src->height; - texCoords[3][0] = srcBox[0] / (float)src->width; texCoords[3][1] = 1.0f - srcBox[3] / (float)src->height; - - invTexRes[0] = 1.0f / src->width * srcTexScale[0]; - invTexRes[1] = 1.0f / src->height * srcTexScale[1]; + invTexRes[0] /= src->width; + invTexRes[1] /= src->height; GL_State( blend ); @@ -609,14 +587,14 @@ void FBO_BlitFromTexture(struct image_s *src, ivec4_t inSrcBox, vec2_t inSrcTexS GLSL_SetUniformVec2(shaderProgram, UNIFORM_AUTOEXPOSUREMINMAX, tr.refdef.autoExposureMinMax); GLSL_SetUniformVec3(shaderProgram, UNIFORM_TONEMINAVGMAXLINEAR, tr.refdef.toneMinAvgMaxLinear); - RB_InstantQuad2(quadVerts, texCoords); //, color, shaderProgram, invTexRes); + RB_InstantQuad2(quadVerts, texCoords); FBO_Bind(oldFbo); } void FBO_Blit(FBO_t *src, ivec4_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend) { - ivec4_t srcBox; + vec4_t srcTexCorners; if (!src) { @@ -624,20 +602,19 @@ void FBO_Blit(FBO_t *src, ivec4_t inSrcBox, vec2_t srcTexScale, FBO_t *dst, ivec return; } - // framebuffers are 0 bottom, Y up. if (inSrcBox) { - srcBox[0] = inSrcBox[0]; - srcBox[1] = src->height - inSrcBox[1] - inSrcBox[3]; - srcBox[2] = inSrcBox[2]; - srcBox[3] = inSrcBox[3]; + srcTexCorners[0] = inSrcBox[0] / (float)src->width; + srcTexCorners[1] = (inSrcBox[1] + inSrcBox[3]) / (float)src->height; + srcTexCorners[2] = (inSrcBox[0] + inSrcBox[2]) / (float)src->width; + srcTexCorners[3] = inSrcBox[1] / (float)src->height; } else { - VectorSet4(srcBox, 0, src->height, src->width, -src->height); + VectorSet4(srcTexCorners, 0.0f, 0.0f, 1.0f, 1.0f); } - FBO_BlitFromTexture(src->colorImage[0], srcBox, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE); + FBO_BlitFromTexture(src->colorImage[0], srcTexCorners, srcTexScale, dst, dstBox, shaderProgram, color, blend | GLS_DEPTHTEST_DISABLE); } void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter) @@ -651,22 +628,15 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu return; } - // get to a neutral state first - //FBO_Bind(NULL); - srcFb = src ? src->frameBuffer : 0; dstFb = dst ? dst->frameBuffer : 0; if (!srcBox) { - if (src) - { - VectorSet4(srcBoxFinal, 0, 0, src->width, src->height); - } - else - { - VectorSet4(srcBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - } + int width = src ? src->width : glConfig.vidWidth; + int height = src ? src->height : glConfig.vidHeight; + + VectorSet4(srcBoxFinal, 0, 0, width, height); } else { @@ -675,14 +645,10 @@ void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int bu if (!dstBox) { - if (dst) - { - VectorSet4(dstBoxFinal, 0, 0, dst->width, dst->height); - } - else - { - VectorSet4(dstBoxFinal, 0, 0, glConfig.vidWidth, glConfig.vidHeight); - } + int width = dst ? dst->width : glConfig.vidWidth; + int height = dst ? dst->height : glConfig.vidHeight; + + VectorSet4(dstBoxFinal, 0, 0, width, height); } else { diff --git a/src/renderergl2/tr_fbo.h b/src/renderergl2/tr_fbo.h index 72b2c911..cb14af6b 100644 --- a/src/renderergl2/tr_fbo.h +++ b/src/renderergl2/tr_fbo.h @@ -57,7 +57,7 @@ void FBO_Bind(FBO_t *fbo); void FBO_Init(void); void FBO_Shutdown(void); -void FBO_BlitFromTexture(struct image_s *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend); +void FBO_BlitFromTexture(struct image_s *src, vec4_t inSrcTexCorners, vec2_t inSrcTexScale, FBO_t *dst, ivec4_t inDstBox, struct shaderProgram_s *shaderProgram, vec4_t inColor, int blend); void FBO_Blit(FBO_t *src, ivec4_t srcBox, vec2_t srcTexScale, FBO_t *dst, ivec4_t dstBox, struct shaderProgram_s *shaderProgram, vec4_t color, int blend); void FBO_FastBlit(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, int buffers, int filter); diff --git a/src/renderergl2/tr_glsl.c b/src/renderergl2/tr_glsl.c index b825c19e..683e173d 100644 --- a/src/renderergl2/tr_glsl.c +++ b/src/renderergl2/tr_glsl.c @@ -1284,7 +1284,7 @@ void GLSL_InitGPUShaders(void) numEtcShaders++; - for (i = 0; i < 2; i++) + for (i = 0; i < 4; i++) { attribs = ATTR_POSITION | ATTR_TEXCOORD; extradefines[0] = '\0'; @@ -1294,6 +1294,9 @@ void GLSL_InitGPUShaders(void) else Q_strcat(extradefines, 1024, "#define USE_HORIZONTAL_BLUR\n"); + if (!(i & 2)) + Q_strcat(extradefines, 1024, "#define USE_DEPTH\n"); + if (!GLSL_InitGPUShader(&tr.depthBlurShader[i], "depthBlur", attribs, qtrue, extradefines, qtrue, fallbackShader_depthblur_vp, fallbackShader_depthblur_fp)) { @@ -1373,7 +1376,7 @@ void GLSL_ShutdownGPUShaders(void) GLSL_DeleteGPUShader(&tr.shadowmaskShader); GLSL_DeleteGPUShader(&tr.ssaoShader); - for ( i = 0; i < 2; i++) + for ( i = 0; i < 4; i++) GLSL_DeleteGPUShader(&tr.depthBlurShader[i]); } diff --git a/src/renderergl2/tr_local.h b/src/renderergl2/tr_local.h index d11c4870..5af67a13 100644 --- a/src/renderergl2/tr_local.h +++ b/src/renderergl2/tr_local.h @@ -1592,7 +1592,7 @@ typedef struct { shaderProgram_t calclevels4xShader[2]; shaderProgram_t shadowmaskShader; shaderProgram_t ssaoShader; - shaderProgram_t depthBlurShader[2]; + shaderProgram_t depthBlurShader[4]; shaderProgram_t testcubeShader; diff --git a/src/renderergl2/tr_postprocess.c b/src/renderergl2/tr_postprocess.c index 1952ae96..c4e51554 100644 --- a/src/renderergl2/tr_postprocess.c +++ b/src/renderergl2/tr_postprocess.c @@ -227,6 +227,7 @@ void RB_BokehBlur(FBO_t *src, ivec4_t srcBox, FBO_t *dst, ivec4_t dstBox, float 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) { ivec4_t srcBox, dstBox; + int srcWidth, srcHeight; vec4_t color; const float inc = 1.f / passes; const float mul = powf(stretch, inc); @@ -235,10 +236,10 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc alpha *= inc; VectorSet4(color, alpha, alpha, alpha, 1.0f); - if (srcFbo) - VectorSet4(srcBox, 0, 0, srcFbo->width, srcFbo->height); - else - VectorSet4(srcBox, 0, 0, glConfig.vidWidth, glConfig.vidHeight); + srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth; + srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight; + + VectorSet4(srcBox, 0, 0, srcWidth, srcHeight); VectorSet4(dstBox, x, y, w, h); FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, 0); @@ -251,20 +252,10 @@ static void RB_RadialBlur(FBO_t *srcFbo, FBO_t *dstFbo, int passes, float stretc float s0 = xcenter * (1.f - iscale); float t0 = (1.0f - ycenter) * (1.f - iscale); - if (srcFbo) - { - srcBox[0] = s0 * srcFbo->width; - srcBox[1] = t0 * srcFbo->height; - srcBox[2] = iscale * srcFbo->width; - srcBox[3] = iscale * srcFbo->height; - } - else - { - srcBox[0] = s0 * glConfig.vidWidth; - srcBox[1] = t0 * glConfig.vidHeight; - srcBox[2] = iscale * glConfig.vidWidth; - srcBox[3] = iscale * glConfig.vidHeight; - } + srcBox[0] = s0 * srcWidth; + srcBox[1] = t0 * srcHeight; + srcBox[2] = iscale * srcWidth; + srcBox[3] = iscale * srcHeight; FBO_Blit(srcFbo, srcBox, NULL, dstFbo, dstBox, NULL, color, GLS_SRCBLEND_ONE | GLS_DSTBLEND_ONE ); @@ -349,23 +340,15 @@ void RB_SunRays(FBO_t *srcFbo, ivec4_t srcBox, FBO_t *dstFbo, ivec4_t dstBox) { float mul = 1.f; ivec4_t rayBox, quarterBox; + int srcWidth = srcFbo ? srcFbo->width : glConfig.vidWidth; + int srcHeight = srcFbo ? srcFbo->height : glConfig.vidHeight; VectorSet4(color, mul, mul, mul, 1); - if (srcFbo) - { - rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcFbo->width; - rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcFbo->height; - rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcFbo->width; - rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcFbo->height; - } - else - { - rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / glConfig.vidWidth; - rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / glConfig.vidHeight; - rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / glConfig.vidWidth; - rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / glConfig.vidHeight; - } + rayBox[0] = srcBox[0] * tr.sunRaysFbo->width / srcWidth; + rayBox[1] = srcBox[1] * tr.sunRaysFbo->height / srcHeight; + rayBox[2] = srcBox[2] * tr.sunRaysFbo->width / srcWidth; + rayBox[3] = srcBox[3] * tr.sunRaysFbo->height / srcHeight; quarterBox[0] = 0; quarterBox[1] = tr.quarterFbo[0]->height; @@ -483,10 +466,8 @@ void RB_GaussianBlur(float blur) 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, NULL, tr.textureScratchFbo[0], dstBox, NULL, color, GLS_DEPTHTEST_DISABLE); + FBO_BlitFromTexture(tr.whiteImage, NULL, NULL, tr.textureScratchFbo[0], NULL, NULL, color, GLS_DEPTHTEST_DISABLE); qglColorMask(GL_TRUE, GL_TRUE, GL_TRUE, GL_TRUE); // blur the tiny buffer horizontally and vertically -- cgit From 87abdd914988724e164ffb16380ad26be8420b84 Mon Sep 17 00:00:00 2001 From: Tim Angus Date: Thu, 7 Apr 2016 11:58:19 +0100 Subject: Make it compile --- src/renderergl2/tr_image.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/renderergl2') diff --git a/src/renderergl2/tr_image.c b/src/renderergl2/tr_image.c index 7e2d452e..331e7f61 100644 --- a/src/renderergl2/tr_image.c +++ b/src/renderergl2/tr_image.c @@ -2114,7 +2114,7 @@ done: { if (glConfig.textureFilterAnisotropic && !cubemap) qglTextureParameteri(image->texnum, textureTarget, GL_TEXTURE_MAX_ANISOTROPY_EXT, - (GLint)Com_Clamp(1, maxAnisotropy, r_ext_max_anisotropy->integer)); + (GLint)Com_Clamp(1, glConfig.maxAnisotropy, r_ext_max_anisotropy->integer)); qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MIN_FILTER, gl_filter_min); qglTextureParameterf(image->texnum, textureTarget, GL_TEXTURE_MAG_FILTER, gl_filter_max); -- cgit