]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
don't skip nearclip plane in R_CullBox as it is possible that the view
[xonotic/darkplaces.git] / gl_rmain.c
index 76931c357033927c4a79cf27b092438d881776ba..db34414d2793f7012039eb5869112304c698299a 100644 (file)
@@ -881,8 +881,9 @@ enum
        SHADERSTATICPARM_SHADOWSAMPLER = 10, ///< sampler
        SHADERSTATICPARM_CELSHADING = 11, ///< celshading (alternative diffuse and specular math)
        SHADERSTATICPARM_CELOUTLINES = 12, ///< celoutline (depth buffer analysis to produce outlines)
+       SHADERSTATICPARM_FXAA = 13 ///< fast approximate anti aliasing
 };
-#define SHADERSTATICPARMS_COUNT 13
+#define SHADERSTATICPARMS_COUNT 14
 
 static const char *shaderstaticparmstrings_list[SHADERSTATICPARMS_COUNT];
 static int shaderstaticparms_count = 0;
@@ -916,6 +917,8 @@ qboolean R_CompileShader_CheckStaticParms(void)
                if (r_glsl_postprocess_uservec4_enable.integer)
                        R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_POSTPROCESS_USERVEC4);
        }
+       if (r_fxaa.integer)
+               R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_FXAA);
        if (r_glsl_offsetmapping_lod.integer && r_glsl_offsetmapping_lod_distance.integer > 0)
                R_COMPILESHADER_STATICPARM_ENABLE(SHADERSTATICPARM_OFFSETMAPPING_USELOD);
 
@@ -956,6 +959,7 @@ static void R_CompileShader_AddStaticParms(unsigned int mode, unsigned int permu
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_SHADOWSAMPLER, "USESHADOWSAMPLER");
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELSHADING, "USECELSHADING");
        R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_CELOUTLINES, "USECELOUTLINES");
+       R_COMPILESHADER_STATICPARM_EMIT(SHADERSTATICPARM_FXAA, "USEFXAA");
 }
 
 /// information about each possible shader permutation
@@ -4489,9 +4493,6 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs)
                return false;
        for (i = 0;i < r_refdef.view.numfrustumplanes;i++)
        {
-               // skip nearclip plane, it often culls portals when you are very close, and is almost never useful
-               if (i == 4)
-                       continue;
                p = r_refdef.view.frustum + i;
                switch(p->signbits)
                {
@@ -6157,7 +6158,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                                        memset(r_refdef.viewcache.world_pvsbits, 0xFF, r_refdef.scene.worldmodel->brush.num_pvsclusterbytes);
                        }
 
-                       r_fb.water.hideplayer = r_water_hideplayer.integer >= 2;
+                       r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 2) && !chase_active.integer);
                        R_ResetViewRendering3D(p->fbo_reflection, r_fb.water.depthtexture, p->texture_reflection);
                        R_ClearScreen(r_refdef.fogenabled);
                        if(r_water_scissormode.integer & 2)
@@ -6186,7 +6187,7 @@ static void R_Water_ProcessPlanes(int fbo, rtexture_t *depthtexture, rtexture_t
                                        continue; // FIXME the plane then still may get rendered but with broken texture, but it sure won't be visible
                        }
 
-                       r_fb.water.hideplayer = r_water_hideplayer.integer >= 1;
+                       r_fb.water.hideplayer = ((r_water_hideplayer.integer >= 1) && !chase_active.integer);
 
                        r_refdef.view.clipplane = p->plane;
                        VectorNegate(r_refdef.view.clipplane.normal, r_refdef.view.clipplane.normal);
@@ -8003,6 +8004,7 @@ static void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcm
        int w, h, idx;
        float shadertime;
        float f;
+       float offsetd[2];
        float tcmat[12];
        matrix4x4_t matrix, temp;
        // if shadertime exceeds about 9 hours (32768 seconds), just wrap it,
@@ -8039,10 +8041,12 @@ static void R_tcMod_ApplyToMatrix(matrix4x4_t *texmatrix, q3shaderinfo_layer_tcm
                        Matrix4x4_CreateScale3(&matrix, tcmod->parms[0], tcmod->parms[1], 1);
                        break;
                case Q3TCMOD_SCROLL:
-                       // this particular tcmod is the most prone to precision breakdown
-                       // at large values, but as we wrap shadertime it won't be obvious
-                       // in practice.
-                       Matrix4x4_CreateTranslate(&matrix, tcmod->parms[0] * rsurface.shadertime, tcmod->parms[1] * rsurface.shadertime, 0);
+                       // this particular tcmod is a "bug for bug" compatible one with regards to
+                       // Quake3, the wrapping is unnecessary with our shadetime fix but quake3
+                       // specifically did the wrapping and so we must mimic that...
+                       offsetd[0] = tcmod->parms[0] * rsurface.shadertime;
+                       offsetd[1] = tcmod->parms[1] * rsurface.shadertime;
+                       Matrix4x4_CreateTranslate(&matrix, offsetd[0] - floor(offsetd[0]), offsetd[1] - floor(offsetd[1]), 0);
                        break;
                case Q3TCMOD_PAGE: // poor man's animmap (to store animations into a single file, useful for HTTP downloaded textures)
                        w = (int) tcmod->parms[0];
@@ -10087,77 +10091,80 @@ void RSurf_PrepareVerticesForBatch(int batchneed, int texturenumsurfaces, const
                }
        }
 
-       // generate texcoords based on the chosen texcoord source
-       switch(rsurface.texture->tcgen.tcgen)
+       if (rsurface.batchtexcoordtexture2f)
        {
-       default:
-       case Q3TCGEN_TEXTURE:
-               break;
-       case Q3TCGEN_LIGHTMAP:
-//             rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
-//             rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
-//             rsurface.batchtexcoordtexture2f_bufferoffset = 0;
-               if (rsurface.batchtexcoordlightmap2f)
-                       memcpy(rsurface.batchtexcoordlightmap2f, rsurface.batchtexcoordtexture2f, batchnumvertices * sizeof(float[2]));
-               break;
-       case Q3TCGEN_VECTOR:
-//             rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
-//             rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
-//             rsurface.batchtexcoordtexture2f_bufferoffset = 0;
-               for (j = 0;j < batchnumvertices;j++)
-               {
-                       rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
-                       rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
-               }
-               break;
-       case Q3TCGEN_ENVIRONMENT:
-               // make environment reflections using a spheremap
-               rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
-               rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
-               rsurface.batchtexcoordtexture2f_bufferoffset = 0;
-               for (j = 0;j < batchnumvertices;j++)
+       // generate texcoords based on the chosen texcoord source
+               switch(rsurface.texture->tcgen.tcgen)
                {
-                       // identical to Q3A's method, but executed in worldspace so
-                       // carried models can be shiny too
+               default:
+               case Q3TCGEN_TEXTURE:
+                       break;
+               case Q3TCGEN_LIGHTMAP:
+       //              rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+       //              rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+       //              rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+                       if (rsurface.batchtexcoordlightmap2f)
+                               memcpy(rsurface.batchtexcoordtexture2f, rsurface.batchtexcoordlightmap2f, batchnumvertices * sizeof(float[2]));
+                       break;
+               case Q3TCGEN_VECTOR:
+       //              rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+       //              rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+       //              rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+                       for (j = 0;j < batchnumvertices;j++)
+                       {
+                               rsurface.batchtexcoordtexture2f[j*2+0] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms);
+                               rsurface.batchtexcoordtexture2f[j*2+1] = DotProduct(rsurface.batchvertex3f + 3*j, rsurface.texture->tcgen.parms + 3);
+                       }
+                       break;
+               case Q3TCGEN_ENVIRONMENT:
+                       // make environment reflections using a spheremap
+                       rsurface.batchtexcoordtexture2f = (float *)R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+                       rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+                       rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+                       for (j = 0;j < batchnumvertices;j++)
+                       {
+                               // identical to Q3A's method, but executed in worldspace so
+                               // carried models can be shiny too
 
-                       float viewer[3], d, reflected[3], worldreflected[3];
+                               float viewer[3], d, reflected[3], worldreflected[3];
 
-                       VectorSubtract(rsurface.localvieworigin, rsurface.batchvertex3f + 3*j, viewer);
-                       // VectorNormalize(viewer);
+                               VectorSubtract(rsurface.localvieworigin, rsurface.batchvertex3f + 3*j, viewer);
+                               // VectorNormalize(viewer);
 
-                       d = DotProduct(rsurface.batchnormal3f + 3*j, viewer);
+                               d = DotProduct(rsurface.batchnormal3f + 3*j, viewer);
 
-                       reflected[0] = rsurface.batchnormal3f[j*3+0]*2*d - viewer[0];
-                       reflected[1] = rsurface.batchnormal3f[j*3+1]*2*d - viewer[1];
-                       reflected[2] = rsurface.batchnormal3f[j*3+2]*2*d - viewer[2];
-                       // note: this is proportinal to viewer, so we can normalize later
+                               reflected[0] = rsurface.batchnormal3f[j*3+0]*2*d - viewer[0];
+                               reflected[1] = rsurface.batchnormal3f[j*3+1]*2*d - viewer[1];
+                               reflected[2] = rsurface.batchnormal3f[j*3+2]*2*d - viewer[2];
+                               // note: this is proportinal to viewer, so we can normalize later
 
-                       Matrix4x4_Transform3x3(&rsurface.matrix, reflected, worldreflected);
-                       VectorNormalize(worldreflected);
+                               Matrix4x4_Transform3x3(&rsurface.matrix, reflected, worldreflected);
+                               VectorNormalize(worldreflected);
 
-                       // note: this sphere map only uses world x and z!
-                       // so positive and negative y will LOOK THE SAME.
-                       rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
-                       rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
+                               // note: this sphere map only uses world x and z!
+                               // so positive and negative y will LOOK THE SAME.
+                               rsurface.batchtexcoordtexture2f[j*2+0] = 0.5 + 0.5 * worldreflected[1];
+                               rsurface.batchtexcoordtexture2f[j*2+1] = 0.5 - 0.5 * worldreflected[2];
+                       }
+                       break;
                }
-               break;
-       }
-       // the only tcmod that needs software vertex processing is turbulent, so
-       // check for it here and apply the changes if needed
-       // and we only support that as the first one
-       // (handling a mixture of turbulent and other tcmods would be problematic
-       //  without punting it entirely to a software path)
-       if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
-       {
-               amplitude = rsurface.texture->tcmods[0].parms[1];
-               animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3];
-//             rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
-//             rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
-//             rsurface.batchtexcoordtexture2f_bufferoffset = 0;
-               for (j = 0;j < batchnumvertices;j++)
-               {
-                       rsurface.batchtexcoordtexture2f[j*2+0] += amplitude * sin(((rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+2]) * 1.0 / 1024.0f + animpos) * M_PI * 2);
-                       rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1]                                ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
+               // the only tcmod that needs software vertex processing is turbulent, so
+               // check for it here and apply the changes if needed
+               // and we only support that as the first one
+               // (handling a mixture of turbulent and other tcmods would be problematic
+               //  without punting it entirely to a software path)
+               if (rsurface.texture->tcmods[0].tcmod == Q3TCMOD_TURBULENT)
+               {
+                       amplitude = rsurface.texture->tcmods[0].parms[1];
+                       animpos = rsurface.texture->tcmods[0].parms[2] + rsurface.shadertime * rsurface.texture->tcmods[0].parms[3];
+       //              rsurface.batchtexcoordtexture2f = R_FrameData_Alloc(batchnumvertices * sizeof(float[2]));
+       //              rsurface.batchtexcoordtexture2f_vertexbuffer = NULL;
+       //              rsurface.batchtexcoordtexture2f_bufferoffset = 0;
+                       for (j = 0;j < batchnumvertices;j++)
+                       {
+                               rsurface.batchtexcoordtexture2f[j*2+0] += amplitude * sin(((rsurface.batchvertex3f[j*3+0] + rsurface.batchvertex3f[j*3+2]) * 1.0 / 1024.0f + animpos) * M_PI * 2);
+                               rsurface.batchtexcoordtexture2f[j*2+1] += amplitude * sin(((rsurface.batchvertex3f[j*3+1]                                ) * 1.0 / 1024.0f + animpos) * M_PI * 2);
+                       }
                }
        }