]> git.rm.cloudns.org Git - xonotic/darkplaces.git/commitdiff
dpsoftrast: support r_shadow_glossexact
authordivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 30 Mar 2011 05:47:58 +0000 (05:47 +0000)
committerdivverent <divverent@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 30 Mar 2011 05:47:58 +0000 (05:47 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@10985 d7cf8633-e32d-0410-b094-e92efae38249

dpsoftrast.c
dpsoftrast.h
gl_rmain.c

index 419a2ffce09d5b6f506ef77ef764967f8e877e25..8edf425769a0601d926e1eea1e26ba33ad8cb47b 100644 (file)
@@ -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
index 7d9ecef05887d06148e938cafce79d957fb41880..a1b562e4d3da7107b59335a40a54c7339a945924 100644 (file)
@@ -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)
index d5e82c56a515cdeac5e44212e3d5fe056b321f26..4795d64ab17e24abec0c8fc647ad0939d0c0ae7e 100644 (file)
@@ -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);