From 12b892df81b3d3aa36266598ce7cd3a5c5dfb28d Mon Sep 17 00:00:00 2001 From: divverent Date: Wed, 30 Mar 2011 05:47:58 +0000 Subject: [PATCH] dpsoftrast: support r_shadow_glossexact git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10985 d7cf8633-e32d-0410-b094-e92efae38249 --- dpsoftrast.c | 101 ++++++++++++++++++++++++++++++++++++++------------- dpsoftrast.h | 2 +- gl_rmain.c | 2 +- 3 files changed, 78 insertions(+), 27 deletions(-) diff --git a/dpsoftrast.c b/dpsoftrast.c index 419a2ffc..8edf4257 100644 --- a/dpsoftrast.c +++ b/dpsoftrast.c @@ -234,6 +234,7 @@ typedef ATOMIC(struct DPSOFTRAST_State_Thread_s int shader_mode; int shader_permutation; + int shader_exactspecularmath; DPSOFTRAST_Texture *texbound[DPSOFTRAST_MAXTEXTUREUNITS]; @@ -311,6 +312,7 @@ typedef ATOMIC(struct DPSOFTRAST_State_s int shader_mode; int shader_permutation; + int shader_exactspecularmath; int texture_max; int texture_end; @@ -1308,20 +1310,23 @@ void DPSOFTRAST_SetTexCoordPointer(int unitnum, int numcomponents, size_t stride dpsoftrast.stride_texcoord[unitnum] = stride; } -DEFCOMMAND(18, SetShader, int mode; int permutation;) +DEFCOMMAND(18, SetShader, int mode; int permutation; int exactspecularmath;) static void DPSOFTRAST_Interpret_SetShader(DPSOFTRAST_State_Thread *thread, DPSOFTRAST_Command_SetShader *command) { thread->shader_mode = command->mode; thread->shader_permutation = command->permutation; + thread->shader_exactspecularmath = command->exactspecularmath; } -void DPSOFTRAST_SetShader(int mode, int permutation) +void DPSOFTRAST_SetShader(int mode, int permutation, int exactspecularmath) { DPSOFTRAST_Command_SetShader *command = DPSOFTRAST_ALLOCATECOMMAND(SetShader); command->mode = mode; command->permutation = permutation; + command->exactspecularmath = exactspecularmath; dpsoftrast.shader_mode = mode; dpsoftrast.shader_permutation = permutation; + dpsoftrast.shader_exactspecularmath = exactspecularmath; } DEFCOMMAND(19, Uniform4f, DPSOFTRAST_UNIFORM index; float val[4];) @@ -3742,7 +3747,7 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons lightnormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; lightnormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; lightnormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; - DPSOFTRAST_Vector3Normalize(eyenormal); + DPSOFTRAST_Vector3Normalize(lightnormal); LightColor[0] = 1.0; LightColor[1] = 1.0; @@ -3756,18 +3761,41 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons DPSOFTRAST_Vector3Normalize(lightnormal); } - eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; - eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; - eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; - DPSOFTRAST_Vector3Normalize(eyenormal); + diffuse = DPSOFTRAST_Vector3Dot(surfacenormal, lightnormal);if (diffuse < 0.0f) diffuse = 0.0f; - specularnormal[0] = lightnormal[0] + eyenormal[0]; - specularnormal[1] = lightnormal[1] + eyenormal[1]; - specularnormal[2] = lightnormal[2] + eyenormal[2]; - DPSOFTRAST_Vector3Normalize(specularnormal); + if(thread->shader_exactspecularmath) + { + // reflect lightnormal at surfacenormal, take the negative of that + // i.e. we want (2*dot(N, i) * N - I) for N=surfacenormal, I=lightnormal + float f; + f = DPSOFTRAST_Vector3Dot(lightnormal, surfacenormal); + specularnormal[0] = 2*f*surfacenormal[0] - lightnormal[0]; + specularnormal[1] = 2*f*surfacenormal[1] - lightnormal[1]; + specularnormal[2] = 2*f*surfacenormal[2] - lightnormal[2]; + + // dot of this and normalize(EyeVectorFogDepth.xyz) + eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; + eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; + eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; + DPSOFTRAST_Vector3Normalize(eyenormal); + + specular = DPSOFTRAST_Vector3Dot(eyenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; + } + else + { + eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; + eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; + eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; + DPSOFTRAST_Vector3Normalize(eyenormal); + + specularnormal[0] = lightnormal[0] + eyenormal[0]; + specularnormal[1] = lightnormal[1] + eyenormal[1]; + specularnormal[2] = lightnormal[2] + eyenormal[2]; + DPSOFTRAST_Vector3Normalize(specularnormal); + + specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; + } - diffuse = DPSOFTRAST_Vector3Dot(surfacenormal, lightnormal);if (diffuse < 0.0f) diffuse = 0.0f; - specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; specular = pow(specular, SpecularPower * glosstex[3]); if (thread->shader_permutation & SHADERPERMUTATION_GLOW) { @@ -3817,7 +3845,7 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons } else if(thread->shader_mode == SHADERMODE_FAKELIGHT) { - // nothing of this needed + DPSOFTRAST_CALCATTRIB4F(triangle, span, EyeVectordata, EyeVectorslope, DPSOFTRAST_ARRAY_TEXCOORD6); } else { @@ -3886,7 +3914,7 @@ void DPSOFTRAST_PixelShader_LightDirection(DPSOFTRAST_State_Thread *thread, cons lightnormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; lightnormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; lightnormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; - DPSOFTRAST_Vector3Normalize(eyenormal); + DPSOFTRAST_Vector3Normalize(lightnormal); LightColor[0] = 1.0; LightColor[1] = 1.0; @@ -4142,19 +4170,42 @@ void DPSOFTRAST_PixelShader_LightSource(DPSOFTRAST_State_Thread *thread, const D lightnormal[2] = (LightVectordata[2] + LightVectorslope[2]*x) * z; DPSOFTRAST_Vector3Normalize(lightnormal); - eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; - eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; - eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; - DPSOFTRAST_Vector3Normalize(eyenormal); + diffuse = DPSOFTRAST_Vector3Dot(surfacenormal, lightnormal);if (diffuse < 0.0f) diffuse = 0.0f; - specularnormal[0] = lightnormal[0] + eyenormal[0]; - specularnormal[1] = lightnormal[1] + eyenormal[1]; - specularnormal[2] = lightnormal[2] + eyenormal[2]; - DPSOFTRAST_Vector3Normalize(specularnormal); + if(thread->shader_exactspecularmath) + { + // reflect lightnormal at surfacenormal, take the negative of that + // i.e. we want (2*dot(N, i) * N - I) for N=surfacenormal, I=lightnormal + float f; + f = DPSOFTRAST_Vector3Dot(lightnormal, surfacenormal); + specularnormal[0] = 2*f*surfacenormal[0] - lightnormal[0]; + specularnormal[1] = 2*f*surfacenormal[1] - lightnormal[1]; + specularnormal[2] = 2*f*surfacenormal[2] - lightnormal[2]; + + // dot of this and normalize(EyeVectorFogDepth.xyz) + eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; + eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; + eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; + DPSOFTRAST_Vector3Normalize(eyenormal); - diffuse = DPSOFTRAST_Vector3Dot(surfacenormal, lightnormal);if (diffuse < 0.0f) diffuse = 0.0f; - specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; + specular = DPSOFTRAST_Vector3Dot(eyenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; + } + else + { + eyenormal[0] = (EyeVectordata[0] + EyeVectorslope[0]*x) * z; + eyenormal[1] = (EyeVectordata[1] + EyeVectorslope[1]*x) * z; + eyenormal[2] = (EyeVectordata[2] + EyeVectorslope[2]*x) * z; + DPSOFTRAST_Vector3Normalize(eyenormal); + + specularnormal[0] = lightnormal[0] + eyenormal[0]; + specularnormal[1] = lightnormal[1] + eyenormal[1]; + specularnormal[2] = lightnormal[2] + eyenormal[2]; + DPSOFTRAST_Vector3Normalize(specularnormal); + + specular = DPSOFTRAST_Vector3Dot(surfacenormal, specularnormal);if (specular < 0.0f) specular = 0.0f; + } specular = pow(specular, SpecularPower * glosstex[3]); + if (thread->shader_permutation & SHADERPERMUTATION_CUBEFILTER) { // scale down the attenuation to account for the cubefilter multiplying everything by 255 diff --git a/dpsoftrast.h b/dpsoftrast.h index 7d9ecef0..a1b562e4 100644 --- a/dpsoftrast.h +++ b/dpsoftrast.h @@ -310,7 +310,7 @@ typedef enum DPSOFTRAST_UNIFORM_e } DPSOFTRAST_UNIFORM; -void DPSOFTRAST_SetShader(int mode, int permutation); +void DPSOFTRAST_SetShader(int mode, int permutation, int exactspecularmath); #define DPSOFTRAST_Uniform1f(index, v0) DPSOFTRAST_Uniform4f(index, v0, 0, 0, 0) #define DPSOFTRAST_Uniform2f(index, v0, v1) DPSOFTRAST_Uniform4f(index, v0, v1, 0, 0) #define DPSOFTRAST_Uniform3f(index, v0, v1, v2) DPSOFTRAST_Uniform4f(index, v0, v1, v2, 0) diff --git a/gl_rmain.c b/gl_rmain.c index d5e82c56..4795d64a 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -1772,7 +1772,7 @@ void R_SetupShader_SetPermutationHLSL(unsigned int mode, unsigned int permutatio void R_SetupShader_SetPermutationSoft(unsigned int mode, unsigned int permutation) { - DPSOFTRAST_SetShader(mode, permutation); + DPSOFTRAST_SetShader(mode, permutation, r_shadow_glossexact.integer); DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewProjectionMatrixM1, 1, false, gl_modelviewprojection16f); DPSOFTRAST_UniformMatrix4fv(DPSOFTRAST_UNIFORM_ModelViewMatrixM1, 1, false, gl_modelview16f); DPSOFTRAST_Uniform1f(DPSOFTRAST_UNIFORM_ClientTime, cl.time); -- 2.39.2