X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=blobdiff_plain;f=gl_rmain.c;h=6c26b8de7040514c4269c65a585f824a9255e8cf;hp=8b04c0fe15887d403aad667debc652972bf874da;hb=93ee242c05da6c2b71a6eaf4e393435988ca6c5a;hpb=7ebc321c860bd7705dd56ca2c5b2eb69babcee6e diff --git a/gl_rmain.c b/gl_rmain.c index 8b04c0fe..6c26b8de 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -77,6 +77,8 @@ cvar_t r_nearclip = {0, "r_nearclip", "1", "distance from camera of nearclip pla cvar_t r_deformvertexes = {0, "r_deformvertexes", "1", "allows use of deformvertexes in shader files (can be turned off to check performance impact)"}; cvar_t r_transparent = {0, "r_transparent", "1", "allows use of transparent surfaces (can be turned off to check performance impact)"}; cvar_t r_transparent_alphatocoverage = {0, "r_transparent_alphatocoverage", "1", "enables GL_ALPHA_TO_COVERAGE antialiasing technique on alphablend and alphatest surfaces when using vid_samples 2 or higher"}; +cvar_t r_transparent_sortsurfacesbynearest = {0, "r_transparent_sortsurfacesbynearest", "1", "sort entity and world surfaces by nearest point on bounding box instead of using the center of the bounding box, usually reduces sorting artifacts"}; +cvar_t r_transparent_useplanardistance = {0, "r_transparent_useplanardistance", "0", "sort transparent meshes by distance from view plane rather than spherical distance to the chosen point"}; cvar_t r_showoverdraw = {0, "r_showoverdraw", "0", "shows overlapping geometry"}; cvar_t r_showbboxes = {0, "r_showbboxes", "0", "shows bounding boxes of server entities, value controls opacity scaling (1 = 10%, 10 = 100%)"}; cvar_t r_showsurfaces = {0, "r_showsurfaces", "0", "1 shows surfaces as different colors, or a value of 2 shows triangle draw order (for analyzing whether meshes are optimized for vertex cache)"}; @@ -147,6 +149,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", "1", "use depth texture instead of depth renderbuffer where possible, uses less video memory but may render slower (or faster) depending on 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"}; @@ -642,18 +645,19 @@ shaderpermutationinfo_t shaderpermutationinfo[SHADERPERMUTATION_COUNT] = {"#define USEOFFSETMAPPING\n", " offsetmapping"}, {"#define USEOFFSETMAPPING_RELIEFMAPPING\n", " reliefmapping"}, {"#define USESHADOWMAP2D\n", " shadowmap2d"}, - {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"}, - {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"}, - {"#define USESHADOWSAMPLER\n", " shadowsampler"}, - {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, + {"#define USESHADOWMAPPCF 1\n", " shadowmappcf"}, // TODO make this a static parm + {"#define USESHADOWMAPPCF 2\n", " shadowmappcf2"}, // TODO make this a static parm + {"#define USESHADOWSAMPLER\n", " shadowsampler"}, // TODO make this a static parm + {"#define USESHADOWMAPVSDCT\n", " shadowmapvsdct"}, // TODO make this a static parm {"#define USESHADOWMAPORTHO\n", " shadowmaportho"}, {"#define USEDEFERREDLIGHTMAP\n", " deferredlightmap"}, {"#define USEALPHAKILL\n", " alphakill"}, {"#define USEREFLECTCUBE\n", " reflectcube"}, {"#define USENORMALMAPSCROLLBLEND\n", " normalmapscrollblend"}, {"#define USEBOUNCEGRID\n", " bouncegrid"}, - {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, + {"#define USEBOUNCEGRIDDIRECTIONAL\n", " bouncegriddirectional"}, // TODO make this a static parm {"#define USETRIPPY\n", " trippy"}, + {"#define USEDEPTHRGB\n", " depthrgb"}, }; // NOTE: MUST MATCH ORDER OF SHADERMODE_* ENUMS! @@ -737,7 +741,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 +771,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 +980,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 +1093,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 +1180,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 +1210,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 +1589,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 +1963,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 +2049,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 +2221,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 +2265,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 +2322,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 +2384,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 +2445,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,13 +2653,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 ); @@ -2810,13 +2819,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 +2960,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 +3014,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); @@ -3021,9 +3030,9 @@ void R_SetupShader_DeferredLight(const rtlight_t *rtlight) R_SetupShader_SetPermutationHLSL(mode, permutation); hlslPSSetParameter3f(D3DPSREGISTER_LightPosition, viewlightorigin[0], viewlightorigin[1], viewlightorigin[2]); hlslPSSetParameter16f(D3DPSREGISTER_ViewToLight, viewtolight16f); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale * range, lightcolorbase[1] * ambientscale * range, lightcolorbase[2] * ambientscale * range); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale * range, lightcolorbase[1] * diffusescale * range, lightcolorbase[2] * diffusescale * range); - hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale * range, lightcolorbase[1] * specularscale * range, lightcolorbase[2] * specularscale * range); + hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Ambient , lightcolorbase[0] * ambientscale , lightcolorbase[1] * ambientscale , lightcolorbase[2] * ambientscale ); + hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Diffuse , lightcolorbase[0] * diffusescale , lightcolorbase[1] * diffusescale , lightcolorbase[2] * diffusescale ); + hlslPSSetParameter3f(D3DPSREGISTER_DeferredColor_Specular, lightcolorbase[0] * specularscale, lightcolorbase[1] * specularscale, lightcolorbase[2] * specularscale); hlslPSSetParameter2f(D3DPSREGISTER_ShadowMap_TextureScale, r_shadow_shadowmap_texturescale[0], r_shadow_shadowmap_texturescale[1]); hlslPSSetParameter4f(D3DPSREGISTER_ShadowMap_Parameters, r_shadow_shadowmap_parameters[0], r_shadow_shadowmap_parameters[1], r_shadow_shadowmap_parameters[2], r_shadow_shadowmap_parameters[3]); hlslPSSetParameter1f(D3DPSREGISTER_SpecularPower, (r_shadow_gloss.integer == 2 ? r_shadow_gloss2exponent.value : r_shadow_glossexponent.value) * (r_shadow_glossexact.integer ? 0.25f : 1.0f) - 1.0f); @@ -3031,10 +3040,9 @@ 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 ); + R_Mesh_TexBind(GL20TU_SHADOWMAP2D , r_shadow_shadowmap2ddepthtexture ); R_Mesh_TexBind(GL20TU_CUBEPROJECTION , r_shadow_shadowmapvsdcttexture ); #endif break; @@ -3059,10 +3067,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 +3090,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; } @@ -4182,6 +4188,8 @@ void GL_Main_Init(void) Cvar_RegisterVariable(&r_deformvertexes); Cvar_RegisterVariable(&r_transparent); Cvar_RegisterVariable(&r_transparent_alphatocoverage); + Cvar_RegisterVariable(&r_transparent_sortsurfacesbynearest); + Cvar_RegisterVariable(&r_transparent_useplanardistance); Cvar_RegisterVariable(&r_showoverdraw); Cvar_RegisterVariable(&r_showbboxes); Cvar_RegisterVariable(&r_showsurfaces); @@ -4236,6 +4244,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); @@ -4736,7 +4745,7 @@ static void R_View_UpdateEntityLighting (void) continue; // skip bsp models - if (ent->model && ent->model->brush.num_leafs) + if (ent->model && (ent->model == cl.worldmodel || ent->model->brush.parentmodel == cl.worldmodel)) { // TODO: use modellight for r_ambient settings on world? VectorSet(ent->modellight_ambient, 0, 0, 0); @@ -5381,13 +5390,14 @@ void R_EntityMatrix(const matrix4x4_t *matrix) } } -void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +void R_ResetViewRendering2D_Common(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture, float x2, float y2) { r_viewport_t viewport; - DrawQ_Finish(); + + CHECKGLERROR // GL is weird because it's bottom to top, r_refdef.view.y is top to bottom - R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, 1, 1, -10, 100, NULL); + R_Viewport_InitOrtho(&viewport, &identitymatrix, r_refdef.view.x, vid.height - r_refdef.view.height - r_refdef.view.y, r_refdef.view.width, r_refdef.view.height, 0, 0, x2, y2, -10, 100, NULL); R_Mesh_SetRenderTargets(fbo, depthtexture, colortexture, NULL, NULL, NULL); R_SetViewport(&viewport); GL_Scissor(viewport.x, viewport.y, viewport.width, viewport.height); @@ -5419,6 +5429,15 @@ void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *color break; } GL_CullFace(GL_NONE); + + CHECKGLERROR +} + +void R_ResetViewRendering2D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) +{ + DrawQ_Finish(); + + R_ResetViewRendering2D_Common(fbo, depthtexture, colortexture, 1, 1); } void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *colortexture) @@ -5462,7 +5481,7 @@ void R_ResetViewRendering3D(int fbo, rtexture_t *depthtexture, rtexture_t *color R_RenderView_UpdateViewVectors ================ */ -static void R_RenderView_UpdateViewVectors(void) +void R_RenderView_UpdateViewVectors(void) { // break apart the view matrix into vectors for various purposes // it is important that this occurs outside the RenderScene function because that can be called from reflection renders, where the vectors come out wrong @@ -5736,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_refraction == 0) p->fbo_refraction = R_Mesh_CreateFramebufferObject(r_fb.water.depthtexture, p->texture_refraction, NULL, NULL, NULL); } @@ -5750,7 +5769,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 +5784,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 +5988,7 @@ static void R_Bloom_StartFrame(void) switch (vid.renderpath) { case RENDERPATH_GL20: - case RENDERPATH_GLES2: + r_fb.usedepthtextures = r_usedepthtextures.integer != 0; if (vid.support.ext_framebuffer_object) { if (r_viewfbo.integer == 2) textype = TEXTYPE_COLORBUFFER16F; @@ -5979,10 +5998,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 +6133,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 } } @@ -6861,6 +6871,11 @@ void R_RenderView(void) r_refdef.view.colorscale = r_hdr_scenebrightness.value * r_hdr_irisadaptation_value.value; + if(vid_sRGB.integer && vid_sRGB_fallback.integer && !vid.sRGB3D) + // in sRGB fallback, behave similar to true sRGB: convert this + // value from linear to sRGB + r_refdef.view.colorscale = Image_sRGBFloatFromLinearFloat(r_refdef.view.colorscale); + R_RenderView_UpdateViewVectors(); R_Shadow_UpdateWorldLightSelection(); @@ -7293,7 +7308,7 @@ static void R_DrawEntityBBoxes(void) if(PRVM_serveredictedict(edict, viewmodelforclient) != 0) continue; VectorLerp(edict->priv.server->areamins, 0.5f, edict->priv.server->areamaxs, center); - R_MeshQueue_AddTransparent(center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawEntityBBoxes_Callback, (entity_render_t *)NULL, i, (rtlight_t *)NULL); } } @@ -7401,7 +7416,7 @@ void R_DrawNoModel(entity_render_t *ent) vec3_t org; Matrix4x4_OriginFromMatrix(&ent->matrix, org); if ((ent->flags & RENDER_ADDITIVE) || (ent->alpha < 1)) - R_MeshQueue_AddTransparent(ent->flags & RENDER_NODEPTHTEST ? r_refdef.view.origin : org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); + R_MeshQueue_AddTransparent((ent->flags & RENDER_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : MESHQUEUE_SORT_DISTANCE, org, R_DrawNoModel_TransparentCallback, ent, 0, rsurface.rtlight); else R_DrawNoModel_TransparentCallback(ent, rsurface.rtlight, 0, NULL); } @@ -9722,7 +9737,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 +10355,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); @@ -10399,7 +10414,7 @@ static void R_DrawSurface_TransparentCallback(const entity_render_t *ent, const rsurface.entity = NULL; // used only by R_GetCurrentTexture and RSurf_ActiveWorldEntity/RSurf_ActiveModelEntity } -static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, const entity_render_t *queueentity) +static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist) { // transparent surfaces get pushed off into the transparent queue int surfacelistindex; @@ -10408,17 +10423,26 @@ static void R_ProcessTransparentTextureSurfaceList(int texturenumsurfaces, const for (surfacelistindex = 0;surfacelistindex < texturenumsurfaces;surfacelistindex++) { surface = texturesurfacelist[surfacelistindex]; - tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; - tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; - tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + if (r_transparent_sortsurfacesbynearest.integer) + { + tempcenter[0] = bound(surface->mins[0], rsurface.localvieworigin[0], surface->maxs[0]); + tempcenter[1] = bound(surface->mins[1], rsurface.localvieworigin[1], surface->maxs[1]); + tempcenter[2] = bound(surface->mins[2], rsurface.localvieworigin[2], surface->maxs[2]); + } + else + { + tempcenter[0] = (surface->mins[0] + surface->maxs[0]) * 0.5f; + tempcenter[1] = (surface->mins[1] + surface->maxs[1]) * 0.5f; + tempcenter[2] = (surface->mins[2] + surface->maxs[2]) * 0.5f; + } Matrix4x4_Transform(&rsurface.matrix, tempcenter, center); - if (queueentity->transparent_offset) // transparent offset + if (rsurface.entity->transparent_offset) // transparent offset { - center[0] += r_refdef.view.forward[0]*queueentity->transparent_offset; - center[1] += r_refdef.view.forward[1]*queueentity->transparent_offset; - center[2] += r_refdef.view.forward[2]*queueentity->transparent_offset; + center[0] += r_refdef.view.forward[0]*rsurface.entity->transparent_offset; + center[1] += r_refdef.view.forward[1]*rsurface.entity->transparent_offset; + center[2] += r_refdef.view.forward[2]*rsurface.entity->transparent_offset; } - R_MeshQueue_AddTransparent(rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST ? r_refdef.view.origin : center, R_DrawSurface_TransparentCallback, queueentity, surface - rsurface.modelsurfaces, rsurface.rtlight); + R_MeshQueue_AddTransparent((rsurface.texture->currentmaterialflags & MATERIALFLAG_NODEPTHTEST) ? MESHQUEUE_SORT_HUD : ((rsurface.entity->flags & RENDER_WORLDOBJECT) ? MESHQUEUE_SORT_SKY : MESHQUEUE_SORT_DISTANCE), center, R_DrawSurface_TransparentCallback, rsurface.entity, surface - rsurface.modelsurfaces, rsurface.rtlight); } } @@ -10439,7 +10463,6 @@ static void R_DrawTextureSurfaceList_DepthOnly(int texturenumsurfaces, const msu static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { - const entity_render_t *queueentity = r_refdef.scene.worldentity; CHECKGLERROR if (depthonly) R_DrawTextureSurfaceList_DepthOnly(texturenumsurfaces, texturesurfacelist); @@ -10448,7 +10471,7 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf if (!rsurface.texture->currentnumlayers) return; if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); else R_DrawWorldTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } @@ -10456,11 +10479,11 @@ static void R_ProcessWorldTextureSurfaceList(int texturenumsurfaces, const msurf R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity) + else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) { // in the deferred case, transparent surfaces were queued during prepass if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); } else { @@ -10516,7 +10539,7 @@ static void R_QueueWorldSurfaceList(int numsurfaces, const msurface_t **surfacel R_FrameData_ReturnToMark(); } -static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, const entity_render_t *queueentity, qboolean prepass) +static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurface_t **texturesurfacelist, qboolean writedepth, qboolean depthonly, qboolean prepass) { CHECKGLERROR if (depthonly) @@ -10526,7 +10549,7 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf if (!rsurface.texture->currentnumlayers) return; if (rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); else R_DrawModelTextureSurfaceList(texturenumsurfaces, texturesurfacelist, writedepth, prepass); } @@ -10534,11 +10557,11 @@ static void R_ProcessModelTextureSurfaceList(int texturenumsurfaces, const msurf R_DrawTextureSurfaceList_Sky(texturenumsurfaces, texturesurfacelist); else if (!rsurface.texture->currentnumlayers) return; - else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST))) && queueentity) + else if (((rsurface.texture->currentmaterialflags & MATERIALFLAGMASK_DEPTHSORTED) || (r_showsurfaces.integer == 3 && (rsurface.texture->currentmaterialflags & MATERIALFLAG_ALPHATEST)))) { // in the deferred case, transparent surfaces were queued during prepass if (!r_shadow_usingdeferredprepass) - R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist, queueentity); + R_ProcessTransparentTextureSurfaceList(texturenumsurfaces, texturesurfacelist); } else { @@ -10589,7 +10612,7 @@ static void R_QueueModelSurfaceList(entity_render_t *ent, int numsurfaces, const ; } // render the range of surfaces - R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, ent, prepass); + R_ProcessModelTextureSurfaceList(j - i, surfacelist + i, writedepth, depthonly, prepass); } R_FrameData_ReturnToMark(); } @@ -10666,7 +10689,7 @@ void R_DrawLocs(void) for (loc = cl.locnodes, index = 0;loc;loc = loc->next, index++) { VectorLerp(loc->mins, 0.5f, loc->maxs, center); - R_MeshQueue_AddTransparent(center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); + R_MeshQueue_AddTransparent(MESHQUEUE_SORT_DISTANCE, center, R_DrawLoc_Callback, (entity_render_t *)loc, loc == nearestloc ? -1 : index, NULL); } }