From 96218fbe352690c1092b46731be16bda117b2b93 Mon Sep 17 00:00:00 2001 From: divverent Date: Wed, 8 Jun 2011 19:35:54 +0000 Subject: [PATCH] use subtractive blend equation to support negative v_brightness; support smaller-than-1 contrast git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@11191 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_backend.c | 58 ++++++++++++++++++++++++++++ gl_backend.h | 1 + gl_draw.c | 55 ++++++++++++++++++++++++--- r_shadow.c | 104 ++------------------------------------------------- vid_shared.c | 4 +- 5 files changed, 115 insertions(+), 107 deletions(-) diff --git a/gl_backend.c b/gl_backend.c index 0a08f161..0c3e7391 100644 --- a/gl_backend.c +++ b/gl_backend.c @@ -4396,3 +4396,61 @@ void R_Mesh_PrepareVertices_Mesh(int numvertices, const r_vertexmesh_t *vertex, break; } } + +void GL_BlendEquationSubtract(qboolean negated) +{ + if(negated) + { + switch(vid.renderpath) + { + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GL20: + case RENDERPATH_GLES1: + case RENDERPATH_GLES2: + qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); + break; + case RENDERPATH_D3D9: +#ifdef SUPPORTD3D + IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); +#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: + DPSOFTRAST_BlendSubtract(true); + break; + } + } + else + { + switch(vid.renderpath) + { + case RENDERPATH_GL11: + case RENDERPATH_GL13: + case RENDERPATH_GL20: + case RENDERPATH_GLES1: + case RENDERPATH_GLES2: + qglBlendEquationEXT(GL_FUNC_ADD_EXT); + break; + case RENDERPATH_D3D9: +#ifdef SUPPORTD3D + IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD); +#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: + DPSOFTRAST_BlendSubtract(false); + break; + } + } +} diff --git a/gl_backend.h b/gl_backend.h index 44418d97..0a352336 100644 --- a/gl_backend.h +++ b/gl_backend.h @@ -31,6 +31,7 @@ void R_GetViewport(r_viewport_t *v); void GL_Finish(void); void GL_BlendFunc(int blendfunc1, int blendfunc2); +void GL_BlendEquationSubtract(qboolean negated); void GL_DepthMask(int state); void GL_DepthTest(int state); void GL_DepthFunc(int state); diff --git a/gl_draw.c b/gl_draw.c index 705253b0..01329fcb 100644 --- a/gl_draw.c +++ b/gl_draw.c @@ -2159,6 +2159,36 @@ void R_DrawGamma(void) GL_DepthRange(0, 1); GL_PolygonOffset(0, 0); GL_DepthTest(false); + + // interpretation of brightness and contrast: + // color range := brightness .. (brightness + contrast) + // i.e. "c *= contrast; c += brightness" + // plausible values for brightness thus range from -contrast to 1 + + // apply pre-brightness (subtractive brightness, for where contrast was >= 1) + if (vid.support.ext_blend_subtract) + { + if (v_color_enable.integer) + { + c[0] = -v_color_black_r.value / v_color_white_r.value; + c[1] = -v_color_black_g.value / v_color_white_g.value; + c[2] = -v_color_black_b.value / v_color_white_b.value; + } + else + c[0] = c[1] = c[2] = -v_brightness.value / v_contrast.value; + if (c[0] >= 0.01f || c[1] >= 0.01f || c[2] >= 0.01f) + { + // need SUBTRACTIVE blending to do this! + GL_BlendEquationSubtract(true); + GL_BlendFunc(GL_ONE, GL_ONE); + GL_Color(c[0], c[1], c[2], 1); + R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); + R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); + GL_BlendEquationSubtract(false); + } + } + + // apply contrast if (v_color_enable.integer) { c[0] = v_color_white_r.value; @@ -2167,17 +2197,32 @@ void R_DrawGamma(void) } else c[0] = c[1] = c[2] = v_contrast.value; - if (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) + if (c[0] >= 1.003f || c[1] >= 1.003f || c[2] >= 1.003f) { GL_BlendFunc(GL_DST_COLOR, GL_ONE); - while (c[0] >= 1.01f || c[1] >= 1.01f || c[2] >= 1.01f) + while (c[0] >= 1.003f || c[1] >= 1.003f || c[2] >= 1.003f) { - GL_Color(c[0] - 1, c[1] - 1, c[2] - 1, 1); + float cc[4]; + cc[0] = bound(0, c[0] - 1, 1); + cc[1] = bound(0, c[1] - 1, 1); + cc[2] = bound(0, c[2] - 1, 1); + GL_Color(cc[0], cc[1], cc[2], 1); R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); - VectorScale(c, 0.5, c); + c[0] /= 1 + cc[0]; + c[1] /= 1 + cc[1]; + c[2] /= 1 + cc[2]; } } + if (c[0] <= 0.997f || c[1] <= 0.997f || c[2] <= 0.997f) + { + GL_BlendFunc(GL_DST_COLOR, GL_ZERO); + GL_Color(c[0], c[1], c[2], 1); + R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); + R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); + } + + // apply post-brightness (additive brightness, for where contrast was <= 1) if (v_color_enable.integer) { c[0] = v_color_black_r.value; @@ -2189,7 +2234,7 @@ void R_DrawGamma(void) if (c[0] >= 0.01f || c[1] >= 0.01f || c[2] >= 0.01f) { GL_BlendFunc(GL_ONE, GL_ONE); - GL_Color(c[0] - 1, c[1] - 1, c[2] - 1, 1); + GL_Color(c[0], c[1], c[2], 1); R_Mesh_PrepareVertices_Generic_Arrays(3, blendvertex3f, NULL, NULL); R_Mesh_Draw(0, 3, 0, 1, polygonelement3i, NULL, 0, polygonelement3s, NULL, 0); } diff --git a/r_shadow.c b/r_shadow.c index 7de402e8..9915a113 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -3351,30 +3351,7 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures if(negated) { VectorNegate(lightcolor, lightcolor); - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - case RENDERPATH_GLES1: - case RENDERPATH_GLES2: - qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); - break; - case RENDERPATH_D3D9: -#ifdef SUPPORTD3D - IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); -#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: - DPSOFTRAST_BlendSubtract(true); - break; - } + GL_BlendEquationSubtract(true); } RSurf_SetupDepthAndCulling(); switch (r_shadow_rendermode) @@ -3397,32 +3374,7 @@ void R_Shadow_RenderLighting(int texturenumsurfaces, const msurface_t **textures break; } if(negated) - { - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - case RENDERPATH_GLES1: - case RENDERPATH_GLES2: - qglBlendEquationEXT(GL_FUNC_ADD_EXT); - break; - case RENDERPATH_D3D9: -#ifdef SUPPORTD3D - IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD); -#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: - DPSOFTRAST_BlendSubtract(false); - break; - } - } + GL_BlendEquationSubtract(false); } void R_RTLight_Update(rtlight_t *rtlight, int isstatic, matrix4x4_t *matrix, vec3_t color, int style, const char *cubemapname, int shadow, vec_t corona, vec_t coronasizescale, vec_t ambientscale, vec_t diffusescale, vec_t specularscale, int flags) @@ -5255,61 +5207,13 @@ void R_DrawCorona(rtlight_t *rtlight, float cscale, float scale) if(negated) { VectorNegate(color, color); - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - case RENDERPATH_GLES1: - case RENDERPATH_GLES2: - qglBlendEquationEXT(GL_FUNC_REVERSE_SUBTRACT_EXT); - break; - case RENDERPATH_D3D9: -#ifdef SUPPORTD3D - IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_SUBTRACT); -#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: - DPSOFTRAST_BlendSubtract(true); - break; - } + GL_BlendEquationSubtract(true); } R_CalcSprite_Vertex3f(vertex3f, rtlight->shadoworigin, r_refdef.view.right, r_refdef.view.up, scale, -scale, -scale, scale); RSurf_ActiveCustomEntity(&identitymatrix, &identitymatrix, RENDER_NODEPTHTEST, 0, color[0], color[1], color[2], 1, 4, vertex3f, spritetexcoord2f, NULL, NULL, NULL, NULL, 2, polygonelement3i, polygonelement3s, false, false); R_DrawCustomSurface(r_shadow_lightcorona, &identitymatrix, MATERIALFLAG_ADD | MATERIALFLAG_BLENDED | MATERIALFLAG_FULLBRIGHT | MATERIALFLAG_NOCULLFACE, 0, 4, 0, 2, false, false); if(negated) - { - switch(vid.renderpath) - { - case RENDERPATH_GL11: - case RENDERPATH_GL13: - case RENDERPATH_GL20: - case RENDERPATH_GLES1: - case RENDERPATH_GLES2: - qglBlendEquationEXT(GL_FUNC_ADD_EXT); - break; - case RENDERPATH_D3D9: -#ifdef SUPPORTD3D - IDirect3DDevice9_SetRenderState(vid_d3d9dev, D3DRS_BLENDOP, D3DBLENDOP_ADD); -#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: - DPSOFTRAST_BlendSubtract(false); - break; - } - } + GL_BlendEquationSubtract(false); } } diff --git a/vid_shared.c b/vid_shared.c index 873d4328..4539f9d8 100644 --- a/vid_shared.c +++ b/vid_shared.c @@ -1458,8 +1458,8 @@ void VID_UpdateGamma(qboolean force, int rampsize) wantgamma = 0; #define BOUNDCVAR(cvar, m1, m2) c = &(cvar);f = bound(m1, c->value, m2);if (c->value != f) Cvar_SetValueQuick(c, f); BOUNDCVAR(v_gamma, 0.1, 5); - BOUNDCVAR(v_contrast, 1, 5); - BOUNDCVAR(v_brightness, 0, 0.8); + BOUNDCVAR(v_contrast, 0.2, 5); + BOUNDCVAR(v_brightness, -v_contrast.value * 0.8, 0.8); //BOUNDCVAR(v_contrastboost, 0.0625, 16); BOUNDCVAR(v_color_black_r, 0, 0.8); BOUNDCVAR(v_color_black_g, 0, 0.8); -- 2.39.2