From 0e6f1ee37a279e6224129b8eb4346592cc6b9885 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 31 Oct 2011 17:23:19 +0000 Subject: [PATCH] added R_LoadTextureRenderbuffer for creating renderbuffers rather than textures, now using renderbuffer for depth instead of a texture when doing fbo renders, this seems to give a significant speed gain implemented shadowmap color texture rendering in a general way (no longer D3D specific) when r_usedepthtextures cvar is 0 reworked r_shadow_deferred to rely on r_viewfbo 2 or higher for proper function, this gave a speed boost by eliminating the depth texture git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11501 d7cf8633-e32d-0410-b094-e92efae38249 --- dpsoftrast.h | 7 +- gl_backend.c | 92 +++++++++--- gl_rmain.c | 88 ++++++----- gl_rsurf.c | 2 +- gl_textures.c | 399 ++++++++++++++++++++++++++++++++------------------ r_shadow.c | 222 +++++++++++----------------- r_textures.h | 32 ++-- render.h | 5 +- shader_glsl.h | 126 +++++++++++----- vid_shared.c | 2 - 10 files changed, 573 insertions(+), 402 deletions(-) diff --git a/dpsoftrast.h b/dpsoftrast.h index e00724e8..9bd1d010 100644 --- a/dpsoftrast.h +++ b/dpsoftrast.h @@ -112,7 +112,7 @@ typedef enum gl20_texunit_e GL20TU_SHADOWMAP2D = 15, GL20TU_CUBEPROJECTION = 12, // rtlight prepass data (screenspace depth and normalmap) - GL20TU_SCREENDEPTH = 13, +// GL20TU_UNUSED1 = 13, GL20TU_SCREENNORMALMAP = 14, // lightmap prepass data (screenspace diffuse and specular from lights) GL20TU_SCREENDIFFUSE = 11, @@ -197,8 +197,8 @@ typedef enum shaderpermutation_e SHADERPERMUTATION_BOUNCEGRID = 1<<28, ///< (lightmap) use Texture_BounceGrid as an additional source of ambient light SHADERPERMUTATION_BOUNCEGRIDDIRECTIONAL = 1<<29, ///< (lightmap) use 16-component pixels in bouncegrid texture for directional lighting rather than standard 4-component SHADERPERMUTATION_TRIPPY = 1<<30, ///< use trippy vertex shader effect - SHADERPERMUTATION_LIMIT = 1<<31, ///< size of permutations array - SHADERPERMUTATION_COUNT = 31 ///< size of shaderpermutationinfo array + SHADERPERMUTATION_DEPTHRGB = 1<<31, ///< read/write depth values in RGB color coded format for older hardware without depth samplers + SHADERPERMUTATION_COUNT = 32 ///< size of shaderpermutationinfo array } shaderpermutation_t; @@ -227,7 +227,6 @@ typedef enum DPSOFTRAST_UNIFORM_e DPSOFTRAST_UNIFORM_Texture_Reflection, DPSOFTRAST_UNIFORM_Texture_ShadowMap2D, DPSOFTRAST_UNIFORM_Texture_CubeProjection, - DPSOFTRAST_UNIFORM_Texture_ScreenDepth, DPSOFTRAST_UNIFORM_Texture_ScreenNormalMap, DPSOFTRAST_UNIFORM_Texture_ScreenDiffuse, DPSOFTRAST_UNIFORM_Texture_ScreenSpecular, diff --git a/gl_backend.c b/gl_backend.c index 02ddae2c..c7fca532 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -1249,9 +1249,9 @@ static void GL_BindEBO(int bufferobject) } } +static const GLuint drawbuffers[4] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1, GL_COLOR_ATTACHMENT2, GL_COLOR_ATTACHMENT3}; int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colortexture, rtexture_t *colortexture2, rtexture_t *colortexture3, rtexture_t *colortexture4) { - int temp; switch(vid.renderpath) { case RENDERPATH_GL11: @@ -1259,17 +1259,60 @@ int R_Mesh_CreateFramebufferObject(rtexture_t *depthtexture, rtexture_t *colorte case RENDERPATH_GL20: case RENDERPATH_GLES1: case RENDERPATH_GLES2: - if (!vid.support.ext_framebuffer_object) - return 0; - qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR - R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL); - if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR - if (depthtexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthtexture->gltexturetypeenum, R_GetTexture(depthtexture), 0);CHECKGLERROR - if (colortexture) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, colortexture->gltexturetypeenum, R_GetTexture(colortexture), 0);CHECKGLERROR - if (colortexture2) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1, colortexture2->gltexturetypeenum, R_GetTexture(colortexture2), 0);CHECKGLERROR - if (colortexture3) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2, colortexture3->gltexturetypeenum, R_GetTexture(colortexture3), 0);CHECKGLERROR - if (colortexture4) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3, colortexture4->gltexturetypeenum, R_GetTexture(colortexture4), 0);CHECKGLERROR - return temp; + if (vid.support.ext_framebuffer_object) + { + int temp; + GLuint status; + qglGenFramebuffersEXT(1, (GLuint*)&temp);CHECKGLERROR + R_Mesh_SetRenderTargets(temp, NULL, NULL, NULL, NULL, NULL); + if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR + // if (depthtexture && depthtexture->texnum ) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, depthtexture->gltexturetypeenum , depthtexture->texnum , 0);CHECKGLERROR + if (colortexture && colortexture->texnum ) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , colortexture->gltexturetypeenum , colortexture->texnum , 0);CHECKGLERROR + if (colortexture2 && colortexture2->texnum) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , colortexture2->gltexturetypeenum, colortexture2->texnum, 0);CHECKGLERROR + if (colortexture3 && colortexture3->texnum) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , colortexture3->gltexturetypeenum, colortexture3->texnum, 0);CHECKGLERROR + if (colortexture4 && colortexture4->texnum) qglFramebufferTexture2DEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , colortexture4->gltexturetypeenum, colortexture4->texnum, 0);CHECKGLERROR + if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT , GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR + if (depthtexture && depthtexture->renderbuffernum ) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, depthtexture->renderbuffernum );CHECKGLERROR + if (colortexture && colortexture->renderbuffernum ) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 , GL_RENDERBUFFER, colortexture->renderbuffernum );CHECKGLERROR + if (colortexture2 && colortexture2->renderbuffernum) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT1 , GL_RENDERBUFFER, colortexture2->renderbuffernum);CHECKGLERROR + if (colortexture3 && colortexture3->renderbuffernum) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT2 , GL_RENDERBUFFER, colortexture3->renderbuffernum);CHECKGLERROR + if (colortexture4 && colortexture4->renderbuffernum) qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT3 , GL_RENDERBUFFER, colortexture4->renderbuffernum);CHECKGLERROR + + if (colortexture4 && qglDrawBuffersARB) + { + qglDrawBuffersARB(4, drawbuffers);CHECKGLERROR + qglReadBuffer(GL_NONE);CHECKGLERROR + } + else if (colortexture3 && qglDrawBuffersARB) + { + qglDrawBuffersARB(3, drawbuffers);CHECKGLERROR + qglReadBuffer(GL_NONE);CHECKGLERROR + } + else if (colortexture2 && qglDrawBuffersARB) + { + qglDrawBuffersARB(2, drawbuffers);CHECKGLERROR + qglReadBuffer(GL_NONE);CHECKGLERROR + } + else if (colortexture && qglDrawBuffer) + { + qglDrawBuffer(drawbuffers[0]);CHECKGLERROR + qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR + } + else if (qglDrawBuffer) + { + qglDrawBuffer(GL_NONE);CHECKGLERROR + qglReadBuffer(GL_NONE);CHECKGLERROR + } + status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR + if (status != GL_FRAMEBUFFER_COMPLETE) + { + Con_Printf("R_Mesh_CreateFramebufferObject: glCheckFramebufferStatusEXT returned %i\n", status); + qglDeleteFramebuffersEXT(1, (GLuint*)&temp); + temp = 0; + } + return temp; + } + return 0; case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: @@ -1304,10 +1347,6 @@ void R_Mesh_DestroyFramebufferObject(int fbo) #ifdef SUPPORTD3D void R_Mesh_SetRenderTargetsD3D9(IDirect3DSurface9 *depthsurface, IDirect3DSurface9 *colorsurface0, IDirect3DSurface9 *colorsurface1, IDirect3DSurface9 *colorsurface2, IDirect3DSurface9 *colorsurface3) { -// LordHavoc: for some weird reason the redundant SetDepthStencilSurface calls are necessary (otherwise the lights fail depth test, as if they were using the shadowmap depth surface and render target still) - if (gl_state.d3drt_depthsurface == depthsurface && gl_state.d3drt_colorsurfaces[0] == colorsurface0 && gl_state.d3drt_colorsurfaces[1] == colorsurface1 && gl_state.d3drt_colorsurfaces[2] == colorsurface2 && gl_state.d3drt_colorsurfaces[3] == colorsurface3) - return; - gl_state.framebufferobject = depthsurface != gl_state.d3drt_backbufferdepthsurface || colorsurface0 != gl_state.d3drt_backbuffercolorsurface; if (gl_state.d3drt_depthsurface != depthsurface) { @@ -1370,19 +1409,24 @@ void R_Mesh_SetRenderTargets(int fbo, rtexture_t *depthtexture, rtexture_t *colo // TODO: optimize: keep surface pointer around in rtexture_t until texture is freed or lost if (fbo) { - IDirect3DSurface9 *colorsurfaces[4]; - for (i = 0;i < 4;i++) + IDirect3DSurface9 *surfaces[5]; + for (i = 0;i < 5;i++) { - colorsurfaces[i] = NULL; + surfaces[i] = NULL; if (textures[i]) - IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &colorsurfaces[i]); + { + if (textures[i]->d3dsurface) + surfaces[i] = (IDirect3DSurface9 *)textures[i]->d3dsurface; + else + IDirect3DTexture9_GetSurfaceLevel((IDirect3DTexture9 *)textures[i]->d3dtexture, 0, &surfaces[i]); + } } // set the render targets for real - R_Mesh_SetRenderTargetsD3D9(depthtexture ? (IDirect3DSurface9 *)depthtexture->d3dtexture : NULL, colorsurfaces[0], colorsurfaces[1], colorsurfaces[2], colorsurfaces[3]); + R_Mesh_SetRenderTargetsD3D9(surfaces[4], surfaces[0], surfaces[1], surfaces[2], surfaces[3]); // release the texture surface levels (they won't be lost while bound...) - for (i = 0;i < 4;i++) - if (textures[i]) - IDirect3DSurface9_Release(colorsurfaces[i]); + for (i = 0;i < 5;i++) + if (textures[i] && !textures[i]->d3dsurface) + IDirect3DSurface9_Release(surfaces[i]); } else R_Mesh_SetRenderTargetsD3D9(gl_state.d3drt_backbufferdepthsurface, gl_state.d3drt_backbuffercolorsurface, NULL, NULL, NULL); diff --git a/gl_rmain.c b/gl_rmain.c index 8b04c0fe..5dbeea50 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -147,6 +147,7 @@ cvar_t r_textureunits = {0, "r_textureunits", "32", "number of texture units to static cvar_t gl_combine = {CVAR_READONLY, "gl_combine", "1", "indicates whether the OpenGL 1.3 rendering path is active"}; static cvar_t r_glsl = {CVAR_READONLY, "r_glsl", "1", "indicates whether the OpenGL 2.0 rendering path is active"}; +cvar_t r_usedepthtextures = {CVAR_SAVE, "r_usedepthtextures", "0", "use depth texture instead of depth renderbuffer where possible, may not be slower on some hardware"}; cvar_t r_viewfbo = {CVAR_SAVE, "r_viewfbo", "0", "enables use of an 8bit (1) or 16bit (2) or 32bit (3) per component float framebuffer render, which may be at a different resolution than the video mode"}; cvar_t r_viewscale = {CVAR_SAVE, "r_viewscale", "1", "scaling factor for resolution of the fbo rendering method, must be > 0, can be above 1 for a costly antialiasing behavior, typical values are 0.5 for 1/4th as many pixels rendered, or 1 for normal rendering"}; cvar_t r_viewscale_fpsscaling = {CVAR_SAVE, "r_viewscale_fpsscaling", "0", "change resolution based on framerate"}; @@ -654,6 +655,7 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USEBOUNCEGRID\n", " bouncegrid"}, {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, {"#define USETRIPPY\n", " trippy"}, + {"#define USEDEPTHRGB\n", " depthrgb"}, }; // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS! @@ -737,7 +739,6 @@ typedef struct r_glsl_permutation_s int tex_Texture_Reflection; int tex_Texture_ShadowMap2D; int tex_Texture_CubeProjection; - int tex_Texture_ScreenDepth; int tex_Texture_ScreenNormalMap; int tex_Texture_ScreenDiffuse; int tex_Texture_ScreenSpecular; @@ -768,7 +769,6 @@ typedef struct r_glsl_permutation_s int loc_Texture_Reflection; int loc_Texture_ShadowMap2D; int loc_Texture_CubeProjection; - int loc_Texture_ScreenDepth; int loc_Texture_ScreenNormalMap; int loc_Texture_ScreenDiffuse; int loc_Texture_ScreenSpecular; @@ -978,9 +978,9 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode int vertstrings_count = 0; int geomstrings_count = 0; int fragstrings_count = 0; - const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; - const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; - const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; + const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; + const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; + const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; if (p->compiled) return; @@ -1091,7 +1091,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->loc_Texture_Reflection = qglGetUniformLocation(p->program, "Texture_Reflection"); p->loc_Texture_ShadowMap2D = qglGetUniformLocation(p->program, "Texture_ShadowMap2D"); p->loc_Texture_CubeProjection = qglGetUniformLocation(p->program, "Texture_CubeProjection"); - p->loc_Texture_ScreenDepth = qglGetUniformLocation(p->program, "Texture_ScreenDepth"); p->loc_Texture_ScreenNormalMap = qglGetUniformLocation(p->program, "Texture_ScreenNormalMap"); p->loc_Texture_ScreenDiffuse = qglGetUniformLocation(p->program, "Texture_ScreenDiffuse"); p->loc_Texture_ScreenSpecular = qglGetUniformLocation(p->program, "Texture_ScreenSpecular"); @@ -1179,7 +1178,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode p->tex_Texture_Reflection = -1; p->tex_Texture_ShadowMap2D = -1; p->tex_Texture_CubeProjection = -1; - p->tex_Texture_ScreenDepth = -1; p->tex_Texture_ScreenNormalMap = -1; p->tex_Texture_ScreenDiffuse = -1; p->tex_Texture_ScreenSpecular = -1; @@ -1210,7 +1208,6 @@ static void R_GLSL_CompilePermutation(r_glsl_permutation_t *p, unsigned int mode if (p->loc_Texture_Reflection >= 0) {p->tex_Texture_Reflection = sampler;qglUniform1i(p->loc_Texture_Reflection , sampler);sampler++;} if (p->loc_Texture_ShadowMap2D >= 0) {p->tex_Texture_ShadowMap2D = sampler;qglUniform1i(p->loc_Texture_ShadowMap2D , sampler);sampler++;} if (p->loc_Texture_CubeProjection >= 0) {p->tex_Texture_CubeProjection = sampler;qglUniform1i(p->loc_Texture_CubeProjection , sampler);sampler++;} - if (p->loc_Texture_ScreenDepth >= 0) {p->tex_Texture_ScreenDepth = sampler;qglUniform1i(p->loc_Texture_ScreenDepth , sampler);sampler++;} if (p->loc_Texture_ScreenNormalMap >= 0) {p->tex_Texture_ScreenNormalMap = sampler;qglUniform1i(p->loc_Texture_ScreenNormalMap , sampler);sampler++;} if (p->loc_Texture_ScreenDiffuse >= 0) {p->tex_Texture_ScreenDiffuse = sampler;qglUniform1i(p->loc_Texture_ScreenDiffuse , sampler);sampler++;} if (p->loc_Texture_ScreenSpecular >= 0) {p->tex_Texture_ScreenSpecular = sampler;qglUniform1i(p->loc_Texture_ScreenSpecular , sampler);sampler++;} @@ -1590,9 +1587,9 @@ static void R_HLSL_CompilePermutation(r_hlsl_permutation_t *p, unsigned int mode int vertstrings_count = 0; int geomstrings_count = 0; int fragstrings_count = 0; - const char *vertstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; - const char *geomstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; - const char *fragstrings_list[32+3+SHADERSTATICPARMS_COUNT+1]; + const char *vertstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; + const char *geomstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; + const char *fragstrings_list[32+5+SHADERSTATICPARMS_COUNT+1]; if (p->compiled) return; @@ -1964,11 +1961,13 @@ void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy) R_SetupShader_Generic(NULL, NULL, GL_MODULATE, 1, usegamma, notrippy, false); } -void R_SetupShader_DepthOrShadow(qboolean notrippy) +void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb) { unsigned int permutation = 0; if (r_trippy.integer && !notrippy) permutation |= SHADERPERMUTATION_TRIPPY; + if (depthrgb) + permutation |= SHADERPERMUTATION_DEPTHRGB; if (vid.allowalphatocoverage) GL_AlphaToCoverage(false); switch (vid.renderpath) @@ -2048,16 +2047,15 @@ extern float r_shadow_shadowmap_parameters[4]; extern qboolean r_shadow_shadowmapvsdct; extern qboolean r_shadow_shadowmapsampler; extern int r_shadow_shadowmappcf; -extern rtexture_t *r_shadow_shadowmap2dtexture; -extern rtexture_t *r_shadow_shadowmap2dcolortexture; +extern rtexture_t *r_shadow_shadowmap2ddepthbuffer; +extern rtexture_t *r_shadow_shadowmap2ddepthtexture; extern rtexture_t *r_shadow_shadowmapvsdcttexture; extern matrix4x4_t r_shadow_shadowmapmatrix; extern int r_shadow_shadowmaplod; // changes for each light based on distance extern int r_shadow_prepass_width; extern int r_shadow_prepass_height; -extern rtexture_t *r_shadow_prepassgeometrydepthtexture; +extern rtexture_t *r_shadow_prepassgeometrydepthbuffer; extern rtexture_t *r_shadow_prepassgeometrynormalmaptexture; -extern rtexture_t *r_shadow_prepassgeometrydepthcolortexture; extern rtexture_t *r_shadow_prepasslightingdiffusetexture; extern rtexture_t *r_shadow_prepasslightingspeculartexture; @@ -2221,6 +2219,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (rsurface.texture->reflectmasktexture) permutation |= SHADERPERMUTATION_REFLECTCUBE; @@ -2263,6 +2263,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; @@ -2318,6 +2320,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; @@ -2378,6 +2382,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; @@ -2437,6 +2443,8 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (rsurface.texture->currentmaterialflags & MATERIALFLAG_REFLECTION) permutation |= SHADERPERMUTATION_REFLECTION; @@ -2643,7 +2651,6 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black); } -// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture ); // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture ); if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture ); if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture ); @@ -2810,13 +2817,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (r_glsl_permutation->tex_Texture_Reflection >= 0 && waterplane) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Reflection , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black); } - if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture ); if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture ); if (r_glsl_permutation->tex_Texture_ScreenDiffuse >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDiffuse , r_shadow_prepasslightingdiffusetexture ); if (r_glsl_permutation->tex_Texture_ScreenSpecular >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenSpecular , r_shadow_prepasslightingspeculartexture ); if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))) { - if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2dtexture ); + if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D, r_shadow_shadowmap2ddepthtexture ); if (rsurface.rtlight) { if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap ); @@ -2952,13 +2958,12 @@ void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, { if (permutation & SHADERPERMUTATION_REFLECTION ) R_Mesh_TexBind(GL20TU_REFLECTION , waterplane->texture_reflection ? waterplane->texture_reflection : r_texture_black); } -// if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture ); // if (rsurfacepass == RSURFPASS_DEFERREDLIGHT ) R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture ); if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENDIFFUSE , r_shadow_prepasslightingdiffusetexture ); if (permutation & SHADERPERMUTATION_DEFERREDLIGHTMAP ) R_Mesh_TexBind(GL20TU_SCREENSPECULAR , r_shadow_prepasslightingspeculartexture ); if (rsurface.rtlight || (r_shadow_usingshadowmaportho && !(rsurface.ent_flags & RENDER_NOSELFSHADOW))) { - R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2dcolortexture); + R_Mesh_TexBind(GL20TU_SHADOWMAP2D, r_shadow_shadowmap2ddepthtexture); if (rsurface.rtlight) { if (permutation & SHADERPERMUTATION_CUBEFILTER ) R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap ); @@ -3007,6 +3012,8 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) permutation |= SHADERPERMUTATION_SHADOWMAPPCF2; else if (r_shadow_shadowmappcf) permutation |= SHADERPERMUTATION_SHADOWMAPPCF; + if (r_shadow_shadowmap2ddepthbuffer) + permutation |= SHADERPERMUTATION_DEPTHRGB; } if (vid.allowalphatocoverage) GL_AlphaToCoverage(false); @@ -3031,7 +3038,6 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) hlslPSSetParameter2f(D3DPSREGISTER_PixelToScreenTexCoord, 1.0f/vid.width, 1.0/vid.height); R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture ); - R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthcolortexture ); R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture ); R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap ); R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dcolortexture ); @@ -3059,10 +3065,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) if (r_glsl_permutation->loc_PixelToScreenTexCoord >= 0) qglUniform2f( r_glsl_permutation->loc_PixelToScreenTexCoord , 1.0f/vid.width, 1.0f/vid.height); if (r_glsl_permutation->tex_Texture_Attenuation >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Attenuation , r_shadow_attenuationgradienttexture ); - if (r_glsl_permutation->tex_Texture_ScreenDepth >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenDepth , r_shadow_prepassgeometrydepthtexture ); if (r_glsl_permutation->tex_Texture_ScreenNormalMap >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ScreenNormalMap , r_shadow_prepassgeometrynormalmaptexture ); if (r_glsl_permutation->tex_Texture_Cube >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_Cube , rsurface.rtlight->currentcubemap ); - if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2dtexture ); + if (r_glsl_permutation->tex_Texture_ShadowMap2D >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_ShadowMap2D , r_shadow_shadowmap2ddepthtexture ); if (r_glsl_permutation->tex_Texture_CubeProjection >= 0) R_Mesh_TexBind(r_glsl_permutation->tex_Texture_CubeProjection , r_shadow_shadowmapvsdcttexture ); break; case RENDERPATH_GL11: @@ -3083,10 +3088,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) DPSOFTRAST_Uniform2f(DPSOFTRAST_UNIFORM_PixelToScreenTexCoord, 1.0f/vid.width, 1.0f/vid.height); R_Mesh_TexBind(GL20TU_ATTENUATION , r_shadow_attenuationgradienttexture ); - R_Mesh_TexBind(GL20TU_SCREENDEPTH , r_shadow_prepassgeometrydepthtexture ); R_Mesh_TexBind(GL20TU_SCREENNORMALMAP , r_shadow_prepassgeometrynormalmaptexture ); R_Mesh_TexBind(GL20TU_CUBE , rsurface.rtlight->currentcubemap ); - R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2dtexture ); + R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2ddepthtexture ); R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture ); break; } @@ -4236,6 +4240,7 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_texture_dds_save); Cvar_RegisterVariable(&r_textureunits); Cvar_RegisterVariable(&gl_combine); + Cvar_RegisterVariable(&r_usedepthtextures); Cvar_RegisterVariable(&r_viewfbo); Cvar_RegisterVariable(&r_viewscale); Cvar_RegisterVariable(&r_viewscale_fpsscaling); @@ -5736,7 +5741,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t if (usewaterfbo) { if (r_fb.water.depthtexture == NULL) - r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil); + r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8); if (p->fbo_refraction == 0) p->fbo_refraction = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_refraction, NULL, NULL, NULL); } @@ -5750,7 +5755,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t if (usewaterfbo) { if (r_fb.water.depthtexture == NULL) - r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil); + r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8); if (p->fbo_camera == 0) p->fbo_camera = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_camera, NULL, NULL, NULL); } @@ -5765,7 +5770,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t if (usewaterfbo) { if (r_fb.water.depthtexture == NULL) - r_fb.water.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, 24, false, vid.support.ext_packed_depth_stencil); + r_fb.water.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "waterviewdepth", r_fb.water.texturewidth, r_fb.water.textureheight, TEXTYPE_DEPTHBUFFER24STENCIL8); if (p->fbo_reflection == 0) p->fbo_reflection = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_reflection, NULL, NULL, NULL); } @@ -5969,7 +5974,7 @@ static void R_Bloom_StartFrame(void) switch (vid.renderpath) { case RENDERPATH_GL20: - case RENDERPATH_GLES2: + r_fb.usedepthtextures = r_usedepthtextures.integer; if (vid.support.ext_framebuffer_object) { if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F; @@ -5979,10 +5984,14 @@ static void R_Bloom_StartFrame(void) case RENDERPATH_GL11: case RENDERPATH_GL13: case RENDERPATH_GLES1: + case RENDERPATH_GLES2: case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: + r_fb.usedepthtextures = false; + break; case RENDERPATH_SOFT: + r_fb.usedepthtextures = true; break; } @@ -6110,22 +6119,9 @@ static void R_Bloom_StartFrame(void) r_fb.colortexture = R_LoadTexture2D(r_main_texturepool, "framebuffercolor", r_fb.screentexturewidth, r_fb.screentextureheight, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_FORCELINEAR | TEXF_CLAMP, -1, NULL); if (useviewfbo) { - // FIXME: choose depth bits based on a cvar - r_fb.depthtexture = R_LoadTextureShadowMap2D(r_main_texturepool, "framebufferdepth", r_fb.screentexturewidth, r_fb.screentextureheight, 24, false, vid.support.ext_packed_depth_stencil); + r_fb.depthtexture = R_LoadTextureRenderBuffer(r_main_texturepool, "framebufferdepth", r_fb.screentexturewidth, r_fb.screentextureheight, TEXTYPE_DEPTHBUFFER24STENCIL8); r_fb.fbo = R_Mesh_CreateFramebufferObject(r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL); R_Mesh_SetRenderTargets(r_fb.fbo, r_fb.depthtexture, r_fb.colortexture, NULL, NULL, NULL); -#ifndef USE_GLES2 - // render depth into one texture and color into the other - if (qglDrawBuffer) - { - int status; - qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - qglReadBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - Con_Printf("R_Bloom_StartFrame: glCheckFramebufferStatusEXT returned %i\n", status); - } -#endif } } @@ -9722,7 +9718,7 @@ static void R_DrawTextureSurfaceList_Sky(int texturenumsurfaces, const msurface_ R_Mesh_ResetTextureState(); if (skyrendermasked) { - R_SetupShader_DepthOrShadow(false); + R_SetupShader_DepthOrShadow(false, false); // depth-only (masking) GL_ColorMask(0,0,0,0); // just to make sure that braindead drivers don't draw @@ -10340,7 +10336,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); // R_Mesh_ResetTextureState(); - R_SetupShader_DepthOrShadow(false); + R_SetupShader_DepthOrShadow(false, false); } RSurf_SetupDepthAndCulling(); RSurf_PrepareVerticesForBatch(BATCHNEED_ARRAY_VERTEX, texturenumsurfaces, texturesurfacelist); diff --git a/gl_rsurf.c b/gl_rsurf.c index 8e1c0bce..f392c5f8 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -647,7 +647,7 @@ void R_Q1BSP_DrawDepth(entity_render_t *ent) GL_BlendFunc(GL_ONE, GL_ZERO); GL_DepthMask(true); // R_Mesh_ResetTextureState(); - R_SetupShader_DepthOrShadow(false); + R_SetupShader_DepthOrShadow(false, false); if (ent == r_refdef.scene.worldentity) R_DrawWorldSurfaces(false, false, true, false, false); else diff --git a/gl_textures.c b/gl_textures.c index 3a9fb60f..a24c9067 100644 --- a/gl_textures.c +++ b/gl_textures.c @@ -83,12 +83,16 @@ textypeinfo_t; #ifdef USE_GLES2 // framebuffer texture formats // GLES2 devices rarely support depth textures, so we actually use a renderbuffer there -static textypeinfo_t textype_shadowmap16 = {"shadowmap16", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_shadowmap24 = {"shadowmap24", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_shadowmap24s8 = {"shadowmap24", TEXTYPE_SHADOWMAP_STENCIL, 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; -static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F, 8, 8, 8.0f, GL_RGBA , GL_RGBA , GL_FLOAT }; -static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F, 16, 16, 16.0f, GL_RGBA , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_shadowmap16_comp = {"shadowmap16_comp", TEXTYPE_SHADOWMAP16_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap16_raw = {"shadowmap16_raw", TEXTYPE_SHADOWMAP16_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_comp = {"shadowmap24_comp", TEXTYPE_SHADOWMAP24_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_raw = {"shadowmap24_raw", TEXTYPE_SHADOWMAP24_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth16 = {"depth16", TEXTYPE_DEPTHBUFFER16 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24 = {"depth24", TEXTYPE_DEPTHBUFFER24 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24stencil8 = {"depth24stencil8", TEXTYPE_DEPTHBUFFER24STENCIL8, 2, 2, 2.0f, GL_DEPTH_COMPONENT16 , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; +static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; +static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F , 2, 2, 2.0f, GL_RGB565 , GL_RGBA , GL_UNSIGNED_SHORT_5_6_5}; // image formats: static textypeinfo_t textype_alpha = {"alpha", TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE }; @@ -100,12 +104,16 @@ static textypeinfo_t textype_bgra = {"bgra", static textypeinfo_t textype_bgra_alpha = {"bgra_alpha", TEXTYPE_BGRA , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; #else // framebuffer texture formats -static textypeinfo_t textype_shadowmap16 = {"shadowmap16", TEXTYPE_SHADOWMAP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; -static textypeinfo_t textype_shadowmap24 = {"shadowmap24", TEXTYPE_SHADOWMAP , 4, 4, 4.0f, GL_DEPTH_COMPONENT , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; -static textypeinfo_t textype_shadowmap24s8 = {"shadowmap24", TEXTYPE_SHADOWMAP_STENCIL, 4, 4, 4.0f, GL_DEPTH24_STENCIL8_EXT , GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT}; -static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; -static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F, 8, 8, 8.0f, GL_RGBA16F_ARB , GL_RGBA , GL_FLOAT }; -static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F, 16, 16, 16.0f, GL_RGBA32F_ARB , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_shadowmap16_comp = {"shadowmap16_comp", TEXTYPE_SHADOWMAP16_COMP , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap16_raw = {"shadowmap16_raw", TEXTYPE_SHADOWMAP16_RAW , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_shadowmap24_comp = {"shadowmap24_comp", TEXTYPE_SHADOWMAP24_COMP , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_shadowmap24_raw = {"shadowmap24_raw", TEXTYPE_SHADOWMAP24_RAW , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_depth16 = {"depth16", TEXTYPE_DEPTHBUFFER16 , 2, 2, 2.0f, GL_DEPTH_COMPONENT16_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT}; +static textypeinfo_t textype_depth24 = {"depth24", TEXTYPE_DEPTHBUFFER24 , 4, 4, 4.0f, GL_DEPTH_COMPONENT24_ARB , GL_DEPTH_COMPONENT, GL_UNSIGNED_INT }; +static textypeinfo_t textype_depth24stencil8 = {"depth24stencil8", TEXTYPE_DEPTHBUFFER24STENCIL8, 4, 4, 4.0f, GL_DEPTH24_STENCIL8_EXT , GL_DEPTH_STENCIL_EXT, GL_UNSIGNED_INT_24_8_EXT}; +static textypeinfo_t textype_colorbuffer = {"colorbuffer", TEXTYPE_COLORBUFFER , 4, 4, 4.0f, GL_RGBA , GL_BGRA , GL_UNSIGNED_BYTE }; +static textypeinfo_t textype_colorbuffer16f = {"colorbuffer16f", TEXTYPE_COLORBUFFER16F , 8, 8, 8.0f, GL_RGBA16F_ARB , GL_RGBA , GL_FLOAT }; +static textypeinfo_t textype_colorbuffer32f = {"colorbuffer32f", TEXTYPE_COLORBUFFER32F , 16, 16, 16.0f, GL_RGBA32F_ARB , GL_RGBA , GL_FLOAT }; // image formats: static textypeinfo_t textype_alpha = {"alpha", TEXTYPE_ALPHA , 1, 4, 4.0f, GL_ALPHA , GL_ALPHA , GL_UNSIGNED_BYTE }; @@ -165,12 +173,15 @@ typedef struct gltexture_s // this portion of the struct is exposed to the R_GetTexture macro for // speed reasons, must be identical in rtexture_t! int texnum; // GL texture slot number + int renderbuffernum; // GL renderbuffer slot number qboolean dirty; // indicates that R_RealGetTexture should be called int gltexturetypeenum; // used by R_Mesh_TexBind // d3d stuff the backend needs void *d3dtexture; + void *d3dsurface; #ifdef SUPPORTD3D - qboolean d3disdepthsurface; // for depth/stencil surfaces + qboolean d3disrendertargetsurface; + qboolean d3disdepthstencilsurface; int d3dformat; int d3dusage; int d3dpool; @@ -254,23 +265,6 @@ static const unsigned char *texturebuffer; static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) { -#ifdef USE_GLES2 - switch(textype) - { - case TEXTYPE_PALETTE: return (flags & TEXF_ALPHA) ? &textype_palette_alpha : &textype_palette; - case TEXTYPE_RGBA: return ((flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba); - case TEXTYPE_BGRA: return ((flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra); - case TEXTYPE_ALPHA: return &textype_alpha; - case TEXTYPE_SHADOWMAP: return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24; - case TEXTYPE_SHADOWMAP_STENCIL: return &textype_shadowmap24s8; - case TEXTYPE_COLORBUFFER: return &textype_colorbuffer; - case TEXTYPE_COLORBUFFER16F: return &textype_colorbuffer16f; - case TEXTYPE_COLORBUFFER32F: return &textype_colorbuffer32f; - default: - Host_Error("R_GetTexTypeInfo: unknown texture format"); - break; - } -#else switch(textype) { case TEXTYPE_DXT1: return &textype_dxt1; @@ -281,11 +275,16 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) case TEXTYPE_RGBA: return ((flags & TEXF_COMPRESS) && vid.support.ext_texture_compression_s3tc) ? ((flags & TEXF_ALPHA) ? &textype_rgba_alpha_compress : &textype_rgba_compress) : ((flags & TEXF_ALPHA) ? &textype_rgba_alpha : &textype_rgba); case TEXTYPE_BGRA: return ((flags & TEXF_COMPRESS) && vid.support.ext_texture_compression_s3tc) ? ((flags & TEXF_ALPHA) ? &textype_bgra_alpha_compress : &textype_bgra_compress) : ((flags & TEXF_ALPHA) ? &textype_bgra_alpha : &textype_bgra); case TEXTYPE_ALPHA: return &textype_alpha; - case TEXTYPE_SHADOWMAP: return (flags & TEXF_LOWPRECISION) ? &textype_shadowmap16 : &textype_shadowmap24; - case TEXTYPE_SHADOWMAP_STENCIL: return &textype_shadowmap24s8; case TEXTYPE_COLORBUFFER: return &textype_colorbuffer; case TEXTYPE_COLORBUFFER16F: return &textype_colorbuffer16f; case TEXTYPE_COLORBUFFER32F: return &textype_colorbuffer32f; + case TEXTYPE_DEPTHBUFFER16: return &textype_depth16; + case TEXTYPE_DEPTHBUFFER24: return &textype_depth24; + case TEXTYPE_DEPTHBUFFER24STENCIL8: return &textype_depth24stencil8; + case TEXTYPE_SHADOWMAP16_COMP: return &textype_shadowmap16_comp; + case TEXTYPE_SHADOWMAP16_RAW: return &textype_shadowmap16_raw; + case TEXTYPE_SHADOWMAP24_COMP: return &textype_shadowmap24_comp; + case TEXTYPE_SHADOWMAP24_RAW: return &textype_shadowmap24_raw; case TEXTYPE_SRGB_DXT1: return &textype_sRGB_dxt1; case TEXTYPE_SRGB_DXT1A: return &textype_sRGB_dxt1a; case TEXTYPE_SRGB_DXT3: return &textype_sRGB_dxt3; @@ -297,7 +296,6 @@ static textypeinfo_t *R_GetTexTypeInfo(textype_t textype, int flags) Host_Error("R_GetTexTypeInfo: unknown texture format"); break; } -#endif return NULL; } @@ -369,11 +367,16 @@ void R_FreeTexture(rtexture_t *rt) CHECKGLERROR qglDeleteTextures(1, (GLuint *)&glt->texnum);CHECKGLERROR } + if (glt->renderbuffernum) + { + CHECKGLERROR + qglDeleteRenderbuffersEXT(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR + } break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (glt->d3disdepthsurface) - IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dtexture); + if (glt->d3dsurface) + IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dsurface); else if (glt->tiledepth > 1) IDirect3DVolumeTexture9_Release((IDirect3DVolumeTexture9 *)glt->d3dtexture); else if (glt->sides == 6) @@ -381,6 +384,7 @@ void R_FreeTexture(rtexture_t *rt) else IDirect3DTexture9_Release((IDirect3DTexture9 *)glt->d3dtexture); glt->d3dtexture = NULL; + glt->d3dsurface = NULL; #endif break; case RENDERPATH_D3D10: @@ -561,7 +565,7 @@ static void GL_TextureMode_f (void) for (glt = pool->gltchain;glt;glt = glt->chain) { // only update already uploaded images - if (glt->d3dtexture && !glt->d3disdepthsurface && (gl_filter_force || !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR)))) + if (glt->d3dtexture && !glt->d3dsurface && (gl_filter_force || !(glt->flags & (TEXF_FORCENEAREST | TEXF_FORCELINEAR)))) { if (glt->flags & TEXF_MIPMAP) { @@ -725,7 +729,7 @@ void R_TextureStats_Print(qboolean printeach, qboolean printpool, qboolean print for (glt = pool->gltchain;glt;glt = glt->chain) { glsize = R_CalcTexelDataSize(glt); - isloaded = glt->texnum != 0; + isloaded = glt->texnum != 0 || glt->renderbuffernum != 0 || glt->d3dtexture || glt->d3dsurface; pooltotal++; pooltotalt += glsize; pooltotalp += glt->inputdatasize; @@ -836,8 +840,8 @@ static void r_textures_devicelost(void) break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (glt->d3disdepthsurface) - IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dtexture); + if (glt->d3dsurface) + IDirect3DSurface9_Release((IDirect3DSurface9 *)glt->d3dsurface); else if (glt->tiledepth > 1) IDirect3DVolumeTexture9_Release((IDirect3DVolumeTexture9 *)glt->d3dtexture); else if (glt->sides == 6) @@ -845,6 +849,7 @@ static void r_textures_devicelost(void) else IDirect3DTexture9_Release((IDirect3DTexture9 *)glt->d3dtexture); glt->d3dtexture = NULL; + glt->d3dsurface = NULL; #endif break; case RENDERPATH_D3D10: @@ -881,9 +886,14 @@ static void r_textures_devicerestored(void) #ifdef SUPPORTD3D { HRESULT d3dresult; - if (glt->d3disdepthsurface) + if (glt->d3disrendertargetsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateRenderTarget failed!"); + } + else if (glt->d3disdepthstencilsurface) { - if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dtexture, NULL))) + if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); } else if (glt->tiledepth > 1) @@ -1100,24 +1110,23 @@ static void GL_SetupTextureParameters(int flags, textype_t textype, int texturet qglTexParameteri(textureenum, GL_TEXTURE_MAG_FILTER, gl_filter_mag);CHECKGLERROR } -#ifndef USE_GLES2 - if (textype == TEXTYPE_SHADOWMAP || TEXTYPE_SHADOWMAP_STENCIL) + switch(textype) { - if (vid.support.arb_shadow) - { - if (flags & TEXF_COMPARE) - { - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR - } - else - { - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR - } - qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR - } + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP24_COMP: + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_COMPARE_R_TO_TEXTURE_ARB);CHECKGLERROR + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);CHECKGLERROR + break; + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_RAW: + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_MODE_ARB, GL_NONE);CHECKGLERROR + qglTexParameteri(textureenum, GL_TEXTURE_COMPARE_FUNC_ARB, GL_LEQUAL);CHECKGLERROR + qglTexParameteri(textureenum, GL_DEPTH_TEXTURE_MODE_ARB, GL_LUMINANCE);CHECKGLERROR + break; + default: + break; } -#endif CHECKGLERROR } @@ -1262,90 +1271,93 @@ static void R_UploadFullTexture(gltexture_t *glt, const unsigned char *data) case RENDERPATH_GL20: case RENDERPATH_GLES1: case RENDERPATH_GLES2: - CHECKGLERROR + if (glt->texnum) // not renderbuffers + { + CHECKGLERROR - // we need to restore the texture binding after finishing the upload - GL_ActiveTexture(0); - oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]); - qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR + // we need to restore the texture binding after finishing the upload + GL_ActiveTexture(0); + oldbindtexnum = R_Mesh_TexBound(0, gltexturetypeenums[glt->texturetype]); + qglBindTexture(gltexturetypeenums[glt->texturetype], glt->texnum);CHECKGLERROR #ifdef GL_TEXTURE_COMPRESSION_HINT_ARB - if (qglGetCompressedTexImageARB) - { - if (gl_texturecompression.integer >= 2) - qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST); - else - qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_FASTEST); - CHECKGLERROR - } -#endif - switch(glt->texturetype) - { - case GLTEXTURETYPE_2D: - qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - if (glt->flags & TEXF_MIPMAP) + if (qglGetCompressedTexImageARB) { - while (width > 1 || height > 1 || depth > 1) - { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); - prevbuffer = resizebuffer; - qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - } - } - break; - case GLTEXTURETYPE_3D: -#ifndef USE_GLES2 - qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - if (glt->flags & TEXF_MIPMAP) - { - while (width > 1 || height > 1 || depth > 1) - { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); - prevbuffer = resizebuffer; - qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR - } + if (gl_texturecompression.integer >= 2) + qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_NICEST); + else + qglHint(GL_TEXTURE_COMPRESSION_HINT_ARB, GL_FASTEST); + CHECKGLERROR } #endif - break; - case GLTEXTURETYPE_CUBEMAP: - // convert and upload each side in turn, - // from a continuous block of input texels - texturebuffer = (unsigned char *)prevbuffer; - for (i = 0;i < 6;i++) + switch(glt->texturetype) { - prevbuffer = texturebuffer; - texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel; - if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth) - { - Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer); - prevbuffer = resizebuffer; - } - // picmip/max_size - while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth) + case GLTEXTURETYPE_2D: + qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + if (glt->flags & TEXF_MIPMAP) { - Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth); - prevbuffer = resizebuffer; + while (width > 1 || height > 1 || depth > 1) + { + Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); + prevbuffer = resizebuffer; + qglTexImage2D(GL_TEXTURE_2D, mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + } } - mip = 0; - qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + break; + case GLTEXTURETYPE_3D: +#ifndef USE_GLES2 + qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR if (glt->flags & TEXF_MIPMAP) { while (width > 1 || height > 1 || depth > 1) { Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); prevbuffer = resizebuffer; - qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + qglTexImage3D(GL_TEXTURE_3D, mip++, glt->glinternalformat, width, height, depth, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR } } +#endif + break; + case GLTEXTURETYPE_CUBEMAP: + // convert and upload each side in turn, + // from a continuous block of input texels + texturebuffer = (unsigned char *)prevbuffer; + for (i = 0;i < 6;i++) + { + prevbuffer = texturebuffer; + texturebuffer += glt->inputwidth * glt->inputheight * glt->inputdepth * glt->textype->inputbytesperpixel; + if (glt->inputwidth != width || glt->inputheight != height || glt->inputdepth != depth) + { + Image_Resample32(prevbuffer, glt->inputwidth, glt->inputheight, glt->inputdepth, resizebuffer, width, height, depth, r_lerpimages.integer); + prevbuffer = resizebuffer; + } + // picmip/max_size + while (width > glt->tilewidth || height > glt->tileheight || depth > glt->tiledepth) + { + Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, glt->tilewidth, glt->tileheight, glt->tiledepth); + prevbuffer = resizebuffer; + } + mip = 0; + qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + if (glt->flags & TEXF_MIPMAP) + { + while (width > 1 || height > 1 || depth > 1) + { + Image_MipReduce32(prevbuffer, resizebuffer, &width, &height, &depth, 1, 1, 1); + prevbuffer = resizebuffer; + qglTexImage2D(cubemapside[i], mip++, glt->glinternalformat, width, height, 0, glt->glformat, glt->gltype, prevbuffer);CHECKGLERROR + } + } + } + break; } - break; + GL_SetupTextureParameters(glt->flags, glt->textype->textype, glt->texturetype); + qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR } - GL_SetupTextureParameters(glt->flags, glt->textype->textype, glt->texturetype); - qglBindTexture(gltexturetypeenums[glt->texturetype], oldbindtexnum);CHECKGLERROR break; case RENDERPATH_D3D9: #ifdef SUPPORTD3D - if (!(glt->flags & TEXF_RENDERTARGET)) + if (!(glt->flags & TEXF_RENDERTARGET) && glt->d3dtexture && !glt->d3dsurface) { D3DLOCKED_RECT d3dlockedrect; D3DLOCKED_BOX d3dlockedbox; @@ -1690,8 +1702,10 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden } } break; - case TEXTYPE_SHADOWMAP: - case TEXTYPE_SHADOWMAP_STENCIL: + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_COMP: + case TEXTYPE_SHADOWMAP24_RAW: break; case TEXTYPE_DXT1: case TEXTYPE_SRGB_DXT1: @@ -1785,21 +1799,15 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden case TEXTYPE_COLORBUFFER: d3dformat = D3DFMT_A8R8G8B8;break; case TEXTYPE_COLORBUFFER16F: d3dformat = D3DFMT_A16B16G16R16F;break; case TEXTYPE_COLORBUFFER32F: d3dformat = D3DFMT_A32B32G32R32F;break; - case TEXTYPE_SHADOWMAP: d3dformat = D3DFMT_D24X8;d3dusage = D3DUSAGE_DEPTHSTENCIL;break; // note: can not use D3DUSAGE_RENDERTARGET here - case TEXTYPE_SHADOWMAP_STENCIL: d3dformat = D3DFMT_D24S8;d3dusage = D3DUSAGE_DEPTHSTENCIL;break; // note: can not use D3DUSAGE_RENDERTARGET here case TEXTYPE_ALPHA: d3dformat = D3DFMT_A8;break; default: d3dformat = D3DFMT_A8R8G8B8;Sys_Error("R_LoadTexture: unsupported texture type %i when picking D3DFMT", (int)textype);break; } glt->d3dformat = d3dformat; glt->d3dusage = d3dusage; glt->d3dpool = d3dpool; - glt->d3disdepthsurface = (textype == TEXTYPE_SHADOWMAP || textype == TEXTYPE_SHADOWMAP_STENCIL); - if (glt->d3disdepthsurface) - { - if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dtexture, NULL))) - Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); - } - else if (glt->tiledepth > 1) + glt->d3disrendertargetsurface = false; + glt->d3disdepthstencilsurface = false; + if (glt->tiledepth > 1) { if (FAILED(d3dresult = IDirect3DDevice9_CreateVolumeTexture(vid_d3d9dev, glt->tilewidth, glt->tileheight, glt->tiledepth, glt->miplevels, glt->d3dusage, (D3DFORMAT)glt->d3dformat, (D3DPOOL)glt->d3dpool, (IDirect3DVolumeTexture9 **)&glt->d3dtexture, NULL))) Sys_Error("IDirect3DDevice9_CreateVolumeTexture failed!"); @@ -1834,8 +1842,13 @@ static rtexture_t *R_SetupTexture(rtexturepool_t *rtexturepool, const char *iden case TEXTYPE_COLORBUFFER: tflags = DPSOFTRAST_TEXTURE_FORMAT_BGRA8;break; case TEXTYPE_COLORBUFFER16F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA16F;break; case TEXTYPE_COLORBUFFER32F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA32F;break; - case TEXTYPE_SHADOWMAP: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; - case TEXTYPE_SHADOWMAP_STENCIL: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; + case TEXTYPE_SHADOWMAP16_COMP: + case TEXTYPE_SHADOWMAP16_RAW: + case TEXTYPE_SHADOWMAP24_COMP: + case TEXTYPE_SHADOWMAP24_RAW: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; + case TEXTYPE_DEPTHBUFFER16: + case TEXTYPE_DEPTHBUFFER24: + case TEXTYPE_DEPTHBUFFER24STENCIL8: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH;break; case TEXTYPE_ALPHA: tflags = DPSOFTRAST_TEXTURE_FORMAT_ALPHA8;break; default: Sys_Error("R_LoadTexture: unsupported texture type %i when picking DPSOFTRAST_TEXTURE_FLAGS", (int)textype); } @@ -1878,21 +1891,123 @@ rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *ident return R_SetupTexture(rtexturepool, identifier, width, width, 1, 6, flags, miplevel, textype, GLTEXTURETYPE_CUBEMAP, data, palette); } -static int R_ShadowMapTextureFlags(int precision, qboolean filter) +rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype, qboolean filter) { - int flags = TEXF_RENDERTARGET | TEXF_CLAMP; - if (filter) - flags |= TEXF_FORCELINEAR | TEXF_COMPARE; - else - flags |= TEXF_FORCENEAREST; - if (precision <= 16) - flags |= TEXF_LOWPRECISION; - return flags; + return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, TEXF_RENDERTARGET | TEXF_CLAMP | (filter ? TEXF_FORCELINEAR : TEXF_FORCENEAREST), -1, textype, GLTEXTURETYPE_2D, NULL, NULL); } -rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter, qboolean stencil) +rtexture_t *R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype) { - return R_SetupTexture(rtexturepool, identifier, width, height, 1, 1, R_ShadowMapTextureFlags(precision, filter), -1, stencil ? TEXTYPE_SHADOWMAP_STENCIL : TEXTYPE_SHADOWMAP, GLTEXTURETYPE_2D, NULL, NULL); + gltexture_t *glt; + gltexturepool_t *pool = (gltexturepool_t *)rtexturepool; + textypeinfo_t *texinfo; + + if (cls.state == ca_dedicated) + return NULL; + + texinfo = R_GetTexTypeInfo(textype, TEXF_RENDERTARGET | TEXF_CLAMP); + + glt = (gltexture_t *)Mem_ExpandableArray_AllocRecord(&texturearray); + if (identifier) + strlcpy (glt->identifier, identifier, sizeof(glt->identifier)); + glt->pool = pool; + glt->chain = pool->gltchain; + pool->gltchain = glt; + glt->inputwidth = width; + glt->inputheight = height; + glt->inputdepth = 1; + glt->flags = TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_FORCENEAREST; + glt->miplevel = 0; + glt->textype = texinfo; + glt->texturetype = textype; + glt->inputdatasize = width*height*texinfo->internalbytesperpixel; + glt->palette = NULL; + glt->glinternalformat = texinfo->glinternalformat; + glt->glformat = texinfo->glformat; + glt->gltype = texinfo->gltype; + glt->bytesperpixel = texinfo->internalbytesperpixel; + glt->sides = glt->texturetype == GLTEXTURETYPE_CUBEMAP ? 6 : 1; + glt->texnum = 0; + glt->dirty = false; + glt->gltexturetypeenum = gltexturetypeenums[glt->texturetype]; + // init the dynamic texture attributes, too [11/22/2007 Black] + glt->updatecallback = NULL; + glt->updatacallback_data = NULL; + + GL_Texture_CalcImageSize(glt->texturetype, glt->flags, glt->miplevel, glt->inputwidth, glt->inputheight, glt->inputdepth, &glt->tilewidth, &glt->tileheight, &glt->tiledepth, &glt->miplevels); + + // upload the texture + // data may be NULL (blank texture for dynamic rendering) + switch(vid.renderpath) + { + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GL20: + case RENDERPATH_GLES1: + case RENDERPATH_GLES2: + CHECKGLERROR + qglGenRenderbuffersEXT(1, (GLuint *)&glt->renderbuffernum);CHECKGLERROR + qglBindRenderbufferEXT(GL_RENDERBUFFER, glt->renderbuffernum);CHECKGLERROR + qglRenderbufferStorageEXT(GL_RENDERBUFFER, glt->glinternalformat, glt->tilewidth, glt->tileheight);CHECKGLERROR + // note we can query the renderbuffer for info with glGetRenderbufferParameteriv for GL_WIDTH, GL_HEIGHt, GL_RED_SIZE, GL_GREEN_SIZE, GL_BLUE_SIZE, GL_GL_ALPHA_SIZE, GL_DEPTH_SIZE, GL_STENCIL_SIZE, GL_INTERNAL_FORMAT + qglBindRenderbufferEXT(GL_RENDERBUFFER, 0);CHECKGLERROR + break; + case RENDERPATH_D3D9: +#ifdef SUPPORTD3D + { + D3DFORMAT d3dformat; + HRESULT d3dresult; + glt->d3disrendertargetsurface = false; + glt->d3disdepthstencilsurface = false; + switch(textype) + { + case TEXTYPE_COLORBUFFER: d3dformat = D3DFMT_A8R8G8B8;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_COLORBUFFER16F: d3dformat = D3DFMT_A16B16G16R16F;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_COLORBUFFER32F: d3dformat = D3DFMT_A32B32G32R32F;glt->d3disrendertargetsurface = true;break; + case TEXTYPE_DEPTHBUFFER: d3dformat = D3DFMT_D24S8;glt->d3disdepthstencilsurface = true;break; + default: d3dformat = D3DFMT_A8R8G8B8;Sys_Error("R_LoadTextureRenderbuffer: unsupported texture type %i when picking D3DFMT", (int)textype);break; + } + glt->d3dformat = d3dformat; + glt->d3dusage = 0; + glt->d3dpool = 0; + if (glt->d3disrendertargetsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateRenderTarget(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateRenderTarget failed!"); + } + else if (glt->d3disdepthstencilsurface) + { + if (FAILED(d3dresult = IDirect3DDevice9_CreateDepthStencilSurface(vid_d3d9dev, glt->tilewidth, glt->tileheight, (D3DFORMAT)glt->d3dformat, D3DMULTISAMPLE_NONE, 0, false, (IDirect3DSurface9 **)&glt->d3dsurface, NULL))) + Sys_Error("IDirect3DDevice9_CreateDepthStencilSurface failed!"); + } + } +#endif + break; + case RENDERPATH_D3D10: + Con_DPrintf("FIXME D3D10 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); + break; + case RENDERPATH_D3D11: + Con_DPrintf("FIXME D3D11 %s:%i %s\n", __FILE__, __LINE__, __FUNCTION__); + break; + case RENDERPATH_SOFT: + { + int tflags = 0; + switch(textype) + { + case TEXTYPE_COLORBUFFER: tflags = DPSOFTRAST_TEXTURE_FORMAT_BGRA8 | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_COLORBUFFER16F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA16F | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_COLORBUFFER32F: tflags = DPSOFTRAST_TEXTURE_FORMAT_RGBA32F | DPSOFTRAST_TEXTURE_FLAG_USEALPHA | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + case TEXTYPE_DEPTHBUFFER16: + case TEXTYPE_DEPTHBUFFER24: + case TEXTYPE_DEPTHBUFFER24STENCIL8: tflags = DPSOFTRAST_TEXTURE_FORMAT_DEPTH | DPSOFTRAST_TEXTURE_FLAG_CLAMPTOEDGE;break; + default: Sys_Error("R_LoadTextureRenderbuffer: unsupported texture type %i when picking DPSOFTRAST_TEXTURE_FLAGS", (int)textype); + } + glt->texnum = DPSOFTRAST_Texture_New(tflags, glt->tilewidth, glt->tileheight, glt->tiledepth); + } + break; + } + + return (rtexture_t *)glt; } int R_SaveTextureDDSFile(rtexture_t *rt, const char *filename, qboolean skipuncompressed, qboolean hasalpha) diff --git a/r_shadow.c b/r_shadow.c index c5637d04..49034d00 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -244,8 +244,8 @@ rtexture_t *r_shadow_attenuationgradienttexture; rtexture_t *r_shadow_attenuation2dtexture; rtexture_t *r_shadow_attenuation3dtexture; skinframe_t *r_shadow_lightcorona; -rtexture_t *r_shadow_shadowmap2dtexture; -rtexture_t *r_shadow_shadowmap2dcolortexture; +rtexture_t *r_shadow_shadowmap2ddepthbuffer; +rtexture_t *r_shadow_shadowmap2ddepthtexture; rtexture_t *r_shadow_shadowmapvsdcttexture; int r_shadow_shadowmapsize; // changes for each light based on distance int r_shadow_shadowmaplod; // changes for each light based on distance @@ -255,8 +255,7 @@ GLuint r_shadow_prepasslightingdiffusespecularfbo; GLuint r_shadow_prepasslightingdiffusefbo; int r_shadow_prepass_width; int r_shadow_prepass_height; -rtexture_t *r_shadow_prepassgeometrydepthtexture; -rtexture_t *r_shadow_prepassgeometrydepthcolortexture; +rtexture_t *r_shadow_prepassgeometrydepthbuffer; rtexture_t *r_shadow_prepassgeometrynormalmaptexture; rtexture_t *r_shadow_prepasslightingdiffusetexture; rtexture_t *r_shadow_prepasslightingspeculartexture; @@ -272,10 +271,6 @@ char r_shadow_mapname[MAX_QPATH]; // used only for light filters (cubemaps) rtexturepool_t *r_shadow_filters_texturepool; -#ifndef USE_GLES2 -static const GLenum r_shadow_prepasslightingdrawbuffers[2] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1}; -#endif - cvar_t r_shadow_bumpscale_basetexture = {0, "r_shadow_bumpscale_basetexture", "0", "generate fake bumpmaps from diffuse textures at this bumpyness, try 4 to match tenebrae, higher values increase depth, requires r_restart to take effect"}; cvar_t r_shadow_bumpscale_bumpmap = {0, "r_shadow_bumpscale_bumpmap", "4", "what magnitude to interpret _bump.tga textures as, higher values increase depth, requires r_restart to take effect"}; cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1", "renders only one light, for level design purposes or debugging"}; @@ -446,7 +441,9 @@ static void R_Shadow_SetShadowMode(void) case RENDERPATH_GL20: if(r_shadow_shadowmapfilterquality < 0) { - if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather) + if (!r_fb.usedepthtextures) + r_shadow_shadowmappcf = 1; + else if(vid.support.amd_texture_texture4 || vid.support.arb_texture_gather) r_shadow_shadowmappcf = 1; else if(strstr(gl_vendor, "NVIDIA") || strstr(gl_renderer, "Radeon HD")) { @@ -477,6 +474,8 @@ static void R_Shadow_SetShadowMode(void) break; } } + if (!r_fb.usedepthtextures) + r_shadow_shadowmapsampler = false; r_shadow_shadowmode = R_SHADOW_SHADOWMODE_SHADOWMAP2D; break; case RENDERPATH_D3D9: @@ -515,13 +514,13 @@ static void R_Shadow_FreeShadowMaps(void) r_shadow_fbo2d = 0; - if (r_shadow_shadowmap2dtexture) - R_FreeTexture(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap2dtexture = NULL; + if (r_shadow_shadowmap2ddepthtexture) + R_FreeTexture(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap2ddepthtexture = NULL; - if (r_shadow_shadowmap2dcolortexture) - R_FreeTexture(r_shadow_shadowmap2dcolortexture); - r_shadow_shadowmap2dcolortexture = NULL; + if (r_shadow_shadowmap2ddepthbuffer) + R_FreeTexture(r_shadow_shadowmap2ddepthbuffer); + r_shadow_shadowmap2ddepthbuffer = NULL; if (r_shadow_shadowmapvsdcttexture) R_FreeTexture(r_shadow_shadowmapvsdcttexture); @@ -540,8 +539,8 @@ static void r_shadow_start(void) r_shadow_attenuation2dtexture = NULL; r_shadow_attenuation3dtexture = NULL; r_shadow_shadowmode = R_SHADOW_SHADOWMODE_STENCIL; - r_shadow_shadowmap2dtexture = NULL; - r_shadow_shadowmap2dcolortexture = NULL; + r_shadow_shadowmap2ddepthtexture = NULL; + r_shadow_shadowmap2ddepthbuffer = NULL; r_shadow_shadowmapvsdcttexture = NULL; r_shadow_shadowmapmaxsize = 0; r_shadow_shadowmapsize = 0; @@ -2053,7 +2052,7 @@ void R_Shadow_RenderMode_StencilShadowVolumes(qboolean zpass) GL_ColorMask(0, 0, 0, 0); GL_PolygonOffset(r_refdef.shadowpolygonfactor, r_refdef.shadowpolygonoffset);CHECKGLERROR GL_CullFace(GL_NONE); - R_SetupShader_DepthOrShadow(false); + R_SetupShader_DepthOrShadow(false, false); r_shadow_rendermode = mode; switch(mode) { @@ -2095,43 +2094,23 @@ static void R_Shadow_MakeShadowMap(int side, int size) switch (r_shadow_shadowmode) { case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (r_shadow_shadowmap2dtexture) return; - r_shadow_shadowmap2dtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits, r_shadow_shadowmapsampler, false); - r_shadow_shadowmap2dcolortexture = NULL; - switch(vid.renderpath) + if (r_shadow_shadowmap2ddepthtexture) return; + if (r_fb.usedepthtextures) { -#ifdef SUPPORTD3D - case RENDERPATH_D3D9: - r_shadow_shadowmap2dcolortexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), NULL, TEXTYPE_BGRA, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL); - r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - break; -#endif - default: - r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2dtexture, NULL, NULL, NULL, NULL); - break; + r_shadow_shadowmap2ddepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits >= 24 ? (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP24_COMP : TEXTYPE_SHADOWMAP24_RAW) : (r_shadow_shadowmapsampler ? TEXTYPE_SHADOWMAP16_COMP : TEXTYPE_SHADOWMAP16_RAW), false); + r_shadow_shadowmap2ddepthbuffer = NULL; + r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + } + else + { + r_shadow_shadowmap2ddepthtexture = R_LoadTexture2D(r_shadow_texturepool, "shadowmaprendertarget", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), NULL, TEXTYPE_COLORBUFFER, TEXF_RENDERTARGET | TEXF_FORCENEAREST | TEXF_CLAMP | TEXF_ALPHA, -1, NULL); + r_shadow_shadowmap2ddepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "shadowmap", size*2, size*(vid.support.arb_texture_non_power_of_two ? 3 : 4), r_shadow_shadowmapdepthbits >= 24 ? TEXTYPE_DEPTHBUFFER24 : TEXTYPE_DEPTHBUFFER16); + r_shadow_fbo2d = R_Mesh_CreateFramebufferObject(r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); } break; default: return; } - -#ifndef USE_GLES2 - // render depth into the fbo, do not render color at all - // validate the fbo now - if (qglDrawBuffer) - { - int status; - qglDrawBuffer(GL_NONE);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE && (r_shadow_shadowmapping.integer || r_shadow_deferred.integer)) - { - Con_Printf("R_Shadow_MakeShadowMap: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_shadowmapping, 0); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - } - } -#endif } static void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size) @@ -2157,17 +2136,20 @@ static void R_Shadow_RenderMode_ShadowMap(int side, int clear, int size) // complex unrolled cube approach (more flexible) if (r_shadow_shadowmapvsdct && !r_shadow_shadowmapvsdcttexture) R_Shadow_MakeVSDCT(); - if (!r_shadow_shadowmap2dtexture) + if (!r_shadow_shadowmap2ddepthtexture) R_Shadow_MakeShadowMap(side, r_shadow_shadowmapmaxsize); - if (r_shadow_shadowmap2dtexture) fbo2d = r_shadow_fbo2d; - r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture); + fbo2d = r_shadow_fbo2d; + r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture); r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D; R_Mesh_ResetTextureState(); R_Shadow_RenderMode_Reset(); - R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - R_SetupShader_DepthOrShadow(true); + if (r_shadow_shadowmap2ddepthbuffer) + R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); + else + R_Mesh_SetRenderTargets(fbo2d, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL); GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value); GL_DepthMask(true); GL_DepthTest(true); @@ -2177,6 +2159,17 @@ init_done: flipped = (side & 1) ^ (side >> 2); r_refdef.view.cullface_front = flipped ? r_shadow_cullface_back : r_shadow_cullface_front; r_refdef.view.cullface_back = flipped ? r_shadow_cullface_front : r_shadow_cullface_back; + if (r_shadow_shadowmap2ddepthbuffer) + { + // completely different meaning than in depthtexture approach + r_shadow_shadowmap_parameters[1] = 0; + r_shadow_shadowmap_parameters[3] = -bias; + } + Vector4Set(clearcolor, 1,1,1,1); + if (r_shadow_shadowmap2ddepthbuffer) + GL_ColorMask(1,1,1,1); + else + GL_ColorMask(0,0,0,0); switch(vid.renderpath) { case RENDERPATH_GL11: @@ -2195,33 +2188,30 @@ init_done: int y1 = clear & 0x03 ? 0 : (clear & 0xC ? size : 2 * size); int y2 = clear & 0x30 ? 3 * size : (clear & 0xC ? 2 * size : size); GL_Scissor(x1, y1, x2 - x1, y2 - y1); - GL_Clear(GL_DEPTH_BUFFER_BIT, NULL, 1.0f, 0); + if (clear) + { + if (r_shadow_shadowmap2ddepthbuffer) + GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); + else + GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); + } } GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); break; case RENDERPATH_D3D9: case RENDERPATH_D3D10: case RENDERPATH_D3D11: - Vector4Set(clearcolor, 1,1,1,1); - // completely different meaning than in OpenGL path - r_shadow_shadowmap_parameters[1] = 0; - r_shadow_shadowmap_parameters[3] = -bias; // we invert the cull mode because we flip the projection matrix // NOTE: this actually does nothing because the DrawShadowMap code sets it to doublesided... GL_CullFace(r_refdef.view.cullface_front); // D3D considers it an error to use a scissor larger than the viewport... clear just this view GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); - if (r_shadow_shadowmapsampler) + if (clear) { - GL_ColorMask(0,0,0,0); - if (clear) - GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); - } - else - { - GL_ColorMask(1,1,1,1); - if (clear) + if (r_shadow_shadowmap2ddepthbuffer) GL_Clear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); + else + GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); } break; } @@ -2290,9 +2280,9 @@ void R_Shadow_RenderMode_DrawDeferredLight(qboolean stenciltest, qboolean shadow // stencil is 128 (values other than this mean shadow) R_SetStencil(stenciltest, 255, GL_KEEP, GL_KEEP, GL_KEEP, GL_EQUAL, 128, 255); if (rsurface.rtlight->specularscale > 0 && r_shadow_gloss.integer > 0) - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); else - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); r_shadow_usingshadowmap2d = shadowmapping; @@ -4389,13 +4379,9 @@ static void R_Shadow_FreeDeferred(void) R_Mesh_DestroyFramebufferObject(r_shadow_prepasslightingdiffusefbo); r_shadow_prepasslightingdiffusefbo = 0; - if (r_shadow_prepassgeometrydepthtexture) - R_FreeTexture(r_shadow_prepassgeometrydepthtexture); - r_shadow_prepassgeometrydepthtexture = NULL; - - if (r_shadow_prepassgeometrydepthcolortexture) - R_FreeTexture(r_shadow_prepassgeometrydepthcolortexture); - r_shadow_prepassgeometrydepthcolortexture = NULL; + if (r_shadow_prepassgeometrydepthbuffer) + R_FreeTexture(r_shadow_prepassgeometrydepthbuffer); + r_shadow_prepassgeometrydepthbuffer = NULL; if (r_shadow_prepassgeometrynormalmaptexture) R_FreeTexture(r_shadow_prepassgeometrynormalmaptexture); @@ -4427,7 +4413,7 @@ void R_Shadow_DrawPrepass(void) GL_BlendFunc(GL_ONE, GL_ZERO); GL_Color(1,1,1,1); GL_DepthTest(true); - R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, r_shadow_prepassgeometrydepthcolortexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); Vector4Set(clearcolor, 0.5f,0.5f,0.5f,1.0f); GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); if (r_timereport_active) @@ -4454,7 +4440,7 @@ void R_Shadow_DrawPrepass(void) GL_ColorMask(1,1,1,1); GL_Color(1,1,1,1); GL_DepthTest(true); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); Vector4Set(clearcolor, 0, 0, 0, 0); GL_Clear(GL_COLOR_BUFFER_BIT, clearcolor, 1.0f, 0); if (r_timereport_active) @@ -4500,7 +4486,6 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color dlight_t *light; size_t range; float f; - GLenum status; if (r_shadow_shadowmapmaxsize != bound(1, r_shadow_shadowmapping_maxsize.integer, (int)vid.maxtexturesize_2d / 4) || (r_shadow_shadowmode != R_SHADOW_SHADOWMODE_STENCIL) != (r_shadow_shadowmapping.integer || r_shadow_deferred.integer) || @@ -4540,73 +4525,29 @@ void R_Shadow_PrepareLights(int fbo, rtexture_t *depthtexture, rtexture_t *color r_shadow_usingdeferredprepass = true; r_shadow_prepass_width = vid.width; r_shadow_prepass_height = vid.height; - r_shadow_prepassgeometrydepthtexture = R_LoadTextureShadowMap2D(r_shadow_texturepool, "prepassgeometrydepthmap", vid.width, vid.height, 24, false, false); - switch (vid.renderpath) - { - case RENDERPATH_D3D9: - r_shadow_prepassgeometrydepthcolortexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrydepthcolormap", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); - break; - default: - break; - } + r_shadow_prepassgeometrydepthbuffer = R_LoadTextureRenderBuffer(r_shadow_texturepool, "prepassgeometrydepthbuffer", vid.width, vid.height, TEXTYPE_DEPTHBUFFER24); r_shadow_prepassgeometrynormalmaptexture = R_LoadTexture2D(r_shadow_texturepool, "prepassgeometrynormalmap", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); r_shadow_prepasslightingdiffusetexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingdiffuse", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); r_shadow_prepasslightingspeculartexture = R_LoadTexture2D(r_shadow_texturepool, "prepasslightingspecular", vid.width, vid.height, NULL, r_fb.textype, TEXF_RENDERTARGET | TEXF_CLAMP | TEXF_ALPHA | TEXF_FORCENEAREST, -1, NULL); // set up the geometry pass fbo (depth + normalmap) - r_shadow_prepassgeometryfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepassgeometrynormalmaptexture, r_shadow_prepassgeometrydepthcolortexture, NULL, NULL); - // render depth into one texture and normalmap into the other - if (qglDrawBuffersARB) - { - qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } + r_shadow_prepassgeometryfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepassgeometryfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepassgeometrynormalmaptexture, NULL, NULL, NULL); + // render depth into a renderbuffer and other important properties into the normalmap texture // set up the lighting pass fbo (diffuse + specular) - r_shadow_prepasslightingdiffusespecularfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + r_shadow_prepasslightingdiffusespecularfbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusespecularfbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, r_shadow_prepasslightingspeculartexture, NULL, NULL); // render diffuse into one texture and specular into another, // with depth and normalmap bound as textures, // with depth bound as attachment as well - if (qglDrawBuffersARB) - { - qglDrawBuffersARB(2, r_shadow_prepasslightingdrawbuffers);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } // set up the lighting pass fbo (diffuse) - r_shadow_prepasslightingdiffusefbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); - R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthtexture, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + r_shadow_prepasslightingdiffusefbo = R_Mesh_CreateFramebufferObject(r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); + R_Mesh_SetRenderTargets(r_shadow_prepasslightingdiffusefbo, r_shadow_prepassgeometrydepthbuffer, r_shadow_prepasslightingdiffusetexture, NULL, NULL, NULL); // render diffuse into one texture, // with depth and normalmap bound as textures, // with depth bound as attachment as well - if (qglDrawBuffersARB) - { - qglDrawBuffer(GL_COLOR_ATTACHMENT0);CHECKGLERROR - qglReadBuffer(GL_NONE);CHECKGLERROR - status = qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER);CHECKGLERROR - if (status != GL_FRAMEBUFFER_COMPLETE) - { - Con_Printf("R_PrepareRTLights: glCheckFramebufferStatusEXT returned %i\n", status); - Cvar_SetValueQuick(&r_shadow_deferred, 0); - r_shadow_usingdeferredprepass = false; - } - } } #endif break; @@ -4804,11 +4745,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort switch (r_shadow_shadowmode) { case R_SHADOW_SHADOWMODE_SHADOWMAP2D: - if (!r_shadow_shadowmap2dtexture) + if (!r_shadow_shadowmap2ddepthtexture) R_Shadow_MakeShadowMap(0, r_shadow_shadowmapmaxsize); shadowfbo = r_shadow_fbo2d; - r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2dtexture); - r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2dtexture); + r_shadow_shadowmap_texturescale[0] = 1.0f / R_TextureWidth(r_shadow_shadowmap2ddepthtexture); + r_shadow_shadowmap_texturescale[1] = 1.0f / R_TextureHeight(r_shadow_shadowmap2ddepthtexture); r_shadow_rendermode = R_SHADOW_RENDERMODE_SHADOWMAP2D; break; default: @@ -4856,8 +4797,11 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort VectorMA(shadoworigin, (1.0f - fabs(dot1)) * radius, shadowforward, shadoworigin); - R_Mesh_SetRenderTargets(shadowfbo, r_shadow_shadowmap2dtexture, r_shadow_shadowmap2dcolortexture, NULL, NULL, NULL); - R_SetupShader_DepthOrShadow(true); + if (r_shadow_shadowmap2ddepthbuffer) + R_Mesh_SetRenderTargets(shadowfbo, r_shadow_shadowmap2ddepthbuffer, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL); + else + R_Mesh_SetRenderTargets(shadowfbo, r_shadow_shadowmap2ddepthtexture, NULL, NULL, NULL, NULL); + R_SetupShader_DepthOrShadow(true, r_shadow_shadowmap2ddepthbuffer != NULL); GL_PolygonOffset(r_shadow_shadowmapping_polygonfactor.value, r_shadow_shadowmapping_polygonoffset.value); GL_DepthMask(true); GL_DepthTest(true); @@ -4866,7 +4810,7 @@ void R_DrawModelShadowMaps(int fbo, rtexture_t *depthtexture, rtexture_t *colort Vector4Set(clearcolor, 1,1,1,1); // in D3D9 we have to render to a color texture shadowmap // in GL we render directly to a depth texture only - if (r_shadow_shadowmap2dtexture) + if (r_shadow_shadowmap2ddepthbuffer) GL_Clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); else GL_Clear(GL_DEPTH_BUFFER_BIT, clearcolor, 1.0f, 0); diff --git a/r_textures.h b/r_textures.h index b6b06fe1..a79b607c 100644 --- a/r_textures.h +++ b/r_textures.h @@ -77,10 +77,20 @@ typedef enum textype_e TEXTYPE_COLORBUFFER16F, // this represents an RGBA float texture (4 32bit floats) TEXTYPE_COLORBUFFER32F, - // 32bit D24S8 (24bit depth, 8bit stencil) - TEXTYPE_SHADOWMAP_STENCIL, - // 16bit D16 (16bit depth) or 32bit S8D24 (24bit depth, 8bit stencil unused) - TEXTYPE_SHADOWMAP + // depth-stencil buffer (or texture) + TEXTYPE_DEPTHBUFFER16, + // depth-stencil buffer (or texture) + TEXTYPE_DEPTHBUFFER24, + // 32bit D24S8 buffer (24bit depth, 8bit stencil), not supported on OpenGL ES + TEXTYPE_DEPTHBUFFER24STENCIL8, + // shadowmap-friendly format with depth comparison (not supported on some hardware) + TEXTYPE_SHADOWMAP16_COMP, + // shadowmap-friendly format with raw reading (not supported on some hardware) + TEXTYPE_SHADOWMAP16_RAW, + // shadowmap-friendly format with depth comparison (not supported on some hardware) + TEXTYPE_SHADOWMAP24_COMP, + // shadowmap-friendly format with raw reading (not supported on some hardware) + TEXTYPE_SHADOWMAP24_RAW, } textype_t; @@ -98,13 +108,16 @@ textype_t; typedef struct rtexture_s { // this is exposed (rather than private) for speed reasons only - int texnum; - qboolean dirty; - int gltexturetypeenum; // exposed for use in R_Mesh_TexBind + int texnum; // GL texture slot number + int renderbuffernum; // GL renderbuffer slot number + qboolean dirty; // indicates that R_RealGetTexture should be called + int gltexturetypeenum; // used by R_Mesh_TexBind // d3d stuff the backend needs void *d3dtexture; + void *d3dsurface; #ifdef SUPPORTD3D - qboolean d3disdepthsurface; // for depth/stencil surfaces + qboolean d3disrendertargetsurface; + qboolean d3disdepthstencilsurface; int d3dformat; int d3dusage; int d3dpool; @@ -156,7 +169,8 @@ extern cvar_t r_texture_dds_save; rtexture_t *R_LoadTexture2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette); rtexture_t *R_LoadTexture3D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int depth, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette); rtexture_t *R_LoadTextureCubeMap(rtexturepool_t *rtexturepool, const char *identifier, int width, const unsigned char *data, textype_t textype, int flags, int miplevel, const unsigned int *palette); -rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, int precision, qboolean filter, qboolean stencil); +rtexture_t *R_LoadTextureShadowMap2D(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype, qboolean filter); +rtexture_t *R_LoadTextureRenderBuffer(rtexturepool_t *rtexturepool, const char *identifier, int width, int height, textype_t textype); rtexture_t *R_LoadTextureDDSFile(rtexturepool_t *rtexturepool, const char *filename, qboolean srgb, int flags, qboolean *hasalphaflag, float *avgcolor, int miplevel); // saves a texture to a DDS file diff --git a/render.h b/render.h index 70d5515d..a0406d4b 100644 --- a/render.h +++ b/render.h @@ -442,7 +442,7 @@ rsurfacepass_t; void R_SetupShader_Generic(rtexture_t *first, rtexture_t *second, int texturemode, int rgbscale, qboolean usegamma, qboolean notrippy, qboolean suppresstexalpha); void R_SetupShader_Generic_NoTexture(qboolean usegamma, qboolean notrippy); -void R_SetupShader_DepthOrShadow(qboolean notrippy); +void R_SetupShader_DepthOrShadow(qboolean notrippy, qboolean depthrgb); void R_SetupShader_ShowDepth(qboolean notrippy); void R_SetupShader_Surface(const vec3_t lightcolorbase, qboolean modellighting, float ambientscale, float diffusescale, float specularscale, rsurfacepass_t rsurfacepass, int texturenumsurfaces, const msurface_t **texturesurfacelist, void *waterplane, qboolean notrippy); void R_SetupShader_DeferredLight(const rtlight_t *rtlight); @@ -511,11 +511,14 @@ typedef struct r_framebufferstate_s r_waterstate_t water; qboolean ghosttexture_valid; // don't draw garbage on first frame with motionblur + qboolean usedepthtextures; // use depth texture instead of depth renderbuffer (faster if you need to read it later anyway) } r_framebufferstate_t; extern r_framebufferstate_t r_fb; +extern cvar_t r_viewfbo; + void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); void R_SetupView(qboolean allowwaterclippingplane, int fbo, rtexture_t *depthtexture, rtexture_t *colortexture); diff --git a/shader_glsl.h b/shader_glsl.h index 33cbb95e..c133ba28 100644 --- a/shader_glsl.h +++ b/shader_glsl.h @@ -45,6 +45,12 @@ "#define highp\n" "#endif\n" "\n" +"#ifdef USEDEPTHRGB\n" +" // for 565 RGB we'd need to use different multipliers\n" +"#define decodedepthmacro(d) dot((d).rgb, vec3(1.0, 255.0 / 65536.0, 255.0 / 16777215.0))\n" +"#define encodedepthmacro(d) (vec4(d, d*256.0, d*65536.0, 0.0) - floor(vec4(d, d*256.0, d*65536.0, 0.0)))\n" +"#endif\n" +"\n" "#ifdef VERTEX_SHADER\n" "dp_attribute vec4 Attrib_Position; // vertex\n" "dp_attribute vec4 Attrib_Color; // color\n" @@ -132,6 +138,7 @@ "#endif\n" "\n" "#ifdef MODE_DEPTH_OR_SHADOW\n" +"dp_varying highp float Depth;\n" "#ifdef VERTEX_SHADER\n" "void main(void)\n" "{\n" @@ -139,13 +146,18 @@ "#ifdef USETRIPPY\n" " gl_Position = TrippyVertex(gl_Position);\n" "#endif\n" +" Depth = gl_Position.z;\n" "}\n" "#endif\n" "\n" "#ifdef FRAGMENT_SHADER\n" "void main(void)\n" "{\n" +"#ifdef USEDEPTHRGB\n" +" dp_FragColor = encodedepthmacro(Depth);\n" +"#else\n" " dp_FragColor = vec4(1.0,1.0,1.0,1.0);\n" +"#endif\n" "}\n" "#endif\n" "#else // !MODE_DEPTH_ORSHADOW\n" @@ -589,6 +601,10 @@ "dp_varying highp vec3 BounceGridTexCoord;\n" "#endif\n" "\n" +"#ifdef MODE_DEFERREDGEOMETRY\n" +"dp_varying highp float Depth;\n" +"#endif\n" +"\n" "\n" "\n" "\n" @@ -634,7 +650,6 @@ "#endif\n" "\n" "#ifdef MODE_DEFERREDLIGHTSOURCE\n" -"uniform sampler2D Texture_ScreenDepth;\n" "uniform sampler2D Texture_ScreenNormalMap;\n" "#endif\n" "#ifdef USEDEFERREDLIGHTMAP\n" @@ -753,9 +768,14 @@ "vec3 GetShadowMapTC2D(vec3 dir)\n" "{\n" " vec3 adir = abs(dir);\n" -" vec2 mparams = ShadowMap_Parameters.xy / max(max(adir.x, adir.y), adir.z);\n" +" float m = max(max(adir.x, adir.y), adir.z);\n" +" vec2 mparams = ShadowMap_Parameters.xy / m;\n" " vec4 proj = dp_textureCube(Texture_CubeProjection, dir);\n" +"#ifdef USEDEPTHRGB\n" +" return vec3(mix(dir.xy, dir.zz, proj.xy) * mparams.x + proj.zw * ShadowMap_Parameters.z, m + 64 * ShadowMap_Parameters.w);\n" +"#else\n" " return vec3(mix(dir.xy, dir.zz, proj.xy) * mparams.x + proj.zw * ShadowMap_Parameters.z, mparams.y + ShadowMap_Parameters.w);\n" +"#endif\n" "}\n" "# else\n" "vec3 GetShadowMapTC2D(vec3 dir)\n" @@ -764,8 +784,12 @@ " float m; vec4 proj;\n" " if (adir.x > adir.y) { m = adir.x; proj = vec4(dir.zyx, 0.5); } else { m = adir.y; proj = vec4(dir.xzy, 1.5); }\n" " if (adir.z > m) { m = adir.z; proj = vec4(dir, 2.5); }\n" +"#ifdef USEDEPTHRGB\n" +" return vec3(proj.xy * ShadowMap_Parameters.x / m + vec2(0.5,0.5) + vec2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, m + 64 * ShadowMap_Parameters.w);\n" +"#else\n" " vec2 mparams = ShadowMap_Parameters.xy / m;\n" " return vec3(proj.xy * mparams.x + vec2(proj.z < 0.0 ? 1.5 : 0.5, proj.w) * ShadowMap_Parameters.z, mparams.y + ShadowMap_Parameters.w);\n" +"#endif\n" "}\n" "# endif\n" "# endif\n" @@ -777,24 +801,48 @@ " vec3 shadowmaptc = GetShadowMapTC2D(dir);\n" " float f;\n" "\n" -"# ifdef USESHADOWSAMPLER\n" -"# ifdef USESHADOWMAPPCF\n" -"# define texval(x, y) dp_shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)) \n" -" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n" -" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n" +"# ifdef USEDEPTHRGB\n" +"# ifdef USESHADOWMAPPCF\n" +"# define texval(x, y) decodedepthmacro(dp_texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale))\n" +"# if USESHADOWMAPPCF > 1\n" +" vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n" +" center *= ShadowMap_TextureScale;\n" +" vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n" +" vec4 row2 = step(shadowmaptc.z, vec4(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0), texval( 2.0, 0.0)));\n" +" vec4 row3 = step(shadowmaptc.z, vec4(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0), texval( 2.0, 1.0)));\n" +" vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n" +" vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n" +" f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" "# else\n" -" f = dp_shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z));\n" +" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n" +" vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n" +" vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n" +" vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n" +" vec3 cols = row2 + mix(row1, row3, offset.y);\n" +" f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n" "# endif\n" +"# else\n" +" f = step(shadowmaptc.z, decodedepthmacro(dp_texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale)));\n" +"# endif\n" "# else\n" -"# ifdef USESHADOWMAPPCF\n" -"# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n" -"# ifdef GL_ARB_texture_gather\n" -"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n" -"# else\n" -"# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale)\n" -"# endif\n" +"# ifdef USESHADOWSAMPLER\n" +"# ifdef USESHADOWMAPPCF\n" +"# define texval(x, y) dp_shadow2D(Texture_ShadowMap2D, vec3(center + vec2(x, y)*ShadowMap_TextureScale, shadowmaptc.z)) \n" +" vec2 center = shadowmaptc.xy*ShadowMap_TextureScale;\n" +" f = dot(vec4(0.25), vec4(texval(-0.4, 1.0), texval(-1.0, -0.4), texval(0.4, -1.0), texval(1.0, 0.4)));\n" +"# else\n" +" f = dp_shadow2D(Texture_ShadowMap2D, vec3(shadowmaptc.xy*ShadowMap_TextureScale, shadowmaptc.z));\n" +"# endif\n" +"# else\n" +"# ifdef USESHADOWMAPPCF\n" +"# if defined(GL_ARB_texture_gather) || defined(GL_AMD_texture_texture4)\n" +"# ifdef GL_ARB_texture_gather\n" +"# define texval(x, y) textureGatherOffset(Texture_ShadowMap2D, center, ivec2(x, y))\n" +"# else\n" +"# define texval(x, y) texture4(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale)\n" +"# endif\n" " vec2 offset = fract(shadowmaptc.xy - 0.5), center = (shadowmaptc.xy - offset)*ShadowMap_TextureScale;\n" -"# if USESHADOWMAPPCF > 1\n" +"# if USESHADOWMAPPCF > 1\n" " vec4 group1 = step(shadowmaptc.z, texval(-2.0, -2.0));\n" " vec4 group2 = step(shadowmaptc.z, texval( 0.0, -2.0));\n" " vec4 group3 = step(shadowmaptc.z, texval( 2.0, -2.0));\n" @@ -822,14 +870,14 @@ " vec4 cols = vec4(group1.rg, group2.rg) + vec4(group3.ab, group4.ab) +\n" " mix(vec4(group1.ab, group2.ab), vec4(group3.rg, group4.rg), offset.y);\n" " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" -"# endif\n" -"# else\n" -"# ifdef GL_EXT_gpu_shader4\n" -"# define texval(x, y) dp_textureOffset(Texture_ShadowMap2D, center, x, y).r\n" +"# endif\n" "# else\n" -"# define texval(x, y) dp_texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n" -"# endif\n" -"# if USESHADOWMAPPCF > 1\n" +"# ifdef GL_EXT_gpu_shader4\n" +"# define texval(x, y) dp_textureOffset(Texture_ShadowMap2D, center, x, y).r\n" +"# else\n" +"# define texval(x, y) dp_texture2D(Texture_ShadowMap2D, center + vec2(x, y)*ShadowMap_TextureScale).r \n" +"# endif\n" +"# if USESHADOWMAPPCF > 1\n" " vec2 center = shadowmaptc.xy - 0.5, offset = fract(center);\n" " center *= ShadowMap_TextureScale;\n" " vec4 row1 = step(shadowmaptc.z, vec4(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0), texval( 2.0, -1.0)));\n" @@ -838,18 +886,19 @@ " vec4 row4 = step(shadowmaptc.z, vec4(texval(-1.0, 2.0), texval( 0.0, 2.0), texval( 1.0, 2.0), texval( 2.0, 2.0)));\n" " vec4 cols = row2 + row3 + mix(row1, row4, offset.y);\n" " f = dot(mix(cols.xyz, cols.yzw, offset.x), vec3(1.0/9.0));\n" -"# else\n" +"# else\n" " vec2 center = shadowmaptc.xy*ShadowMap_TextureScale, offset = fract(shadowmaptc.xy);\n" " vec3 row1 = step(shadowmaptc.z, vec3(texval(-1.0, -1.0), texval( 0.0, -1.0), texval( 1.0, -1.0)));\n" " vec3 row2 = step(shadowmaptc.z, vec3(texval(-1.0, 0.0), texval( 0.0, 0.0), texval( 1.0, 0.0)));\n" " vec3 row3 = step(shadowmaptc.z, vec3(texval(-1.0, 1.0), texval( 0.0, 1.0), texval( 1.0, 1.0)));\n" " vec3 cols = row2 + mix(row1, row3, offset.y);\n" " f = dot(mix(cols.xy, cols.yz, offset.x), vec2(0.25));\n" +"# endif\n" "# endif\n" -"# endif\n" -"# else\n" +"# else\n" " f = step(shadowmaptc.z, dp_texture2D(Texture_ShadowMap2D, shadowmaptc.xy*ShadowMap_TextureScale).r);\n" -"# endif\n" +"# endif\n" +"# endif\n" "# endif\n" "# ifdef USESHADOWMAPORTHO\n" " return mix(ShadowMap_Parameters.w, 1.0, f);\n" @@ -895,6 +944,7 @@ "#ifdef USETRIPPY\n" " gl_Position = TrippyVertex(gl_Position);\n" "#endif\n" +" Depth = (ModelViewMatrix * Attrib_Position).z;\n" "}\n" "#endif // VERTEX_SHADER\n" "\n" @@ -931,7 +981,8 @@ " float a = offsetMappedTexture2D(Texture_Gloss).a;\n" "#endif\n" "\n" -" dp_FragColor = vec4(normalize(surfacenormal.x * VectorS.xyz + surfacenormal.y * VectorT.xyz + surfacenormal.z * VectorR.xyz) * 0.5 + vec3(0.5, 0.5, 0.5), a);\n" +" vec3 pixelnormal = normalize(surfacenormal.x * VectorS.xyz + surfacenormal.y * VectorT.xyz + surfacenormal.z * VectorR.xyz);\n" +" dp_FragColor = vec4(pixelnormal.x, pixelnormal.y, Depth, a);\n" "}\n" "#endif // FRAGMENT_SHADER\n" "#else // !MODE_DEFERREDGEOMETRY\n" @@ -965,14 +1016,21 @@ " // calculate viewspace pixel position\n" " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n" " vec3 position;\n" -" position.z = ScreenToDepth.y / (dp_texture2D(Texture_ScreenDepth, ScreenTexCoord).r + ScreenToDepth.x);\n" -" position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n" -" // decode viewspace pixel normal\n" +" // get the geometry information (depth, normal, specular exponent)\n" " myhalf4 normalmap = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord);\n" -" myhalf3 surfacenormal = normalize(normalmap.rgb - cast_myhalf3(0.5,0.5,0.5));\n" +" // decode viewspace pixel normal\n" +"// myhalf3 surfacenormal = normalize(normalmap.rgb - cast_myhalf3(0.5,0.5,0.5));\n" +" myhalf3 surfacenormal = myhalf3(normalmap.rg, sqrt(1.0-dot(normalmap.rg, normalmap.rg)));\n" +" // decode viewspace pixel position\n" +"// position.z = decodedepthmacro(dp_texture2D(Texture_ScreenDepth, ScreenTexCoord));\n" +" position.z = normalmap.b;\n" +"// position.z = ScreenToDepth.y / (dp_texture2D(Texture_ScreenDepth, ScreenTexCoord).r + ScreenToDepth.x);\n" +" position.xy = ModelViewPosition.xy * (position.z / ModelViewPosition.z);\n" +"\n" +" // now do the actual shading\n" " // surfacenormal = pixel normal in viewspace\n" " // LightVector = pixel to light in viewspace\n" -" // CubeVector = position in lightspace\n" +" // CubeVector = pixel in lightspace\n" " // eyevector = pixel to view in viewspace\n" " vec3 CubeVector = vec3(ViewToLight * vec4(position,1));\n" " myhalf fade = cast_myhalf(dp_texture2D(Texture_Attenuation, vec2(length(CubeVector), 0.0)));\n" @@ -1015,7 +1073,6 @@ " gl_FragColor.rgb *= cubecolor;\n" "# endif\n" "#endif\n" -" \n" "}\n" "#endif // FRAGMENT_SHADER\n" "#else // !MODE_DEFERREDLIGHTSOURCE\n" @@ -1361,6 +1418,7 @@ " vec2 ScreenTexCoord = gl_FragCoord.xy * PixelToScreenTexCoord;\n" " color.rgb += diffusetex * cast_myhalf3(dp_texture2D(Texture_ScreenDiffuse, ScreenTexCoord)) * DeferredMod_Diffuse;\n" " color.rgb += glosstex.rgb * cast_myhalf3(dp_texture2D(Texture_ScreenSpecular, ScreenTexCoord)) * DeferredMod_Specular;\n" +"// color.rgb = dp_texture2D(Texture_ScreenNormalMap, ScreenTexCoord).rgb * vec3(1.0, 1.0, 0.001);\n" "#endif\n" "\n" "#ifdef USEBOUNCEGRID\n" diff --git a/vid_shared.c b/vid_shared.c index 4236bb76..f9c56e2c 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -199,8 +199,6 @@ cvar_t v_glslgamma = {CVAR_SAVE, "v_glslgamma", "1", "enables use of GLSL to app cvar_t v_glslgamma_2d = {CVAR_SAVE, "v_glslgamma_2d", "0", "applies GLSL gamma to 2d pictures (HUD, fonts)"}; cvar_t v_psycho = {0, "v_psycho", "0", "easter egg"}; -extern cvar_t r_viewfbo; - // brand of graphics chip const char *gl_vendor; // graphics chip model and other information -- 2.39.2