]> git.xonotic.org Git - xonotic/darkplaces.git/blobdiff - gl_rmain.c
446
[xonotic/darkplaces.git] / gl_rmain.c
index 6564b4c0b23d1265ad4dfa4e3199b78c8f222a46..7f96334fec4f7d13b39265fbcbcaf801241eab3d 100644 (file)
@@ -98,7 +98,7 @@ cvar_t developer_texturelogging = {0, "developer_texturelogging", "0", "produces
 
 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0", "draws only lightmaps, no texture (for level designers)"};
 
-cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"}; // used for testing renderer code changes, otherwise does nothing
+cvar_t r_test = {0, "r_test", "0", "internal development use only, leave it alone (usually does nothing anyway)"};
 cvar_t r_batchmode = {0, "r_batchmode", "1", "selects method of rendering multiple surfaces with one driver call (values are 0, 1, 2, etc...)"};
 
 typedef struct r_glsl_bloomshader_s
@@ -1122,7 +1122,7 @@ void GL_Main_Init(void)
 {
        r_main_mempool = Mem_AllocPool("Renderer", 0, NULL);
 
-       Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed\n");
+       Cmd_AddCommand("r_glsl_restart", R_GLSL_Restart_f, "unloads GLSL shaders, they will then be reloaded as needed");
        FOG_registercvars(); // FIXME: move this fog stuff to client?
        Cvar_RegisterVariable(&r_nearclip);
        Cvar_RegisterVariable(&r_showsurfaces);
@@ -1276,6 +1276,53 @@ int R_CullBox(const vec3_t mins, const vec3_t maxs)
        return false;
 }
 
+int R_CullBoxCustomPlanes(const vec3_t mins, const vec3_t maxs, int numplanes, const mplane_t *planes)
+{
+       int i;
+       const mplane_t *p;
+       for (i = 0;i < numplanes;i++)
+       {
+               p = planes + i;
+               switch(p->signbits)
+               {
+               default:
+               case 0:
+                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
+                               return true;
+                       break;
+               case 1:
+                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*maxs[2] < p->dist)
+                               return true;
+                       break;
+               case 2:
+                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
+                               return true;
+                       break;
+               case 3:
+                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*maxs[2] < p->dist)
+                               return true;
+                       break;
+               case 4:
+                       if (p->normal[0]*maxs[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
+                               return true;
+                       break;
+               case 5:
+                       if (p->normal[0]*mins[0] + p->normal[1]*maxs[1] + p->normal[2]*mins[2] < p->dist)
+                               return true;
+                       break;
+               case 6:
+                       if (p->normal[0]*maxs[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
+                               return true;
+                       break;
+               case 7:
+                       if (p->normal[0]*mins[0] + p->normal[1]*mins[1] + p->normal[2]*mins[2] < p->dist)
+                               return true;
+                       break;
+               }
+       }
+       return false;
+}
+
 //==================================================================================
 
 static void R_UpdateEntityLighting(entity_render_t *ent)
@@ -1402,6 +1449,8 @@ void R_DrawModels(void)
 
 static void R_View_SetFrustum(void)
 {
+       double slopex, slopey;
+
        // break apart the view matrix into vectors for various purposes
        Matrix4x4_ToVectors(&r_view.matrix, r_view.forward, r_view.left, r_view.up, r_view.origin);
        VectorNegate(r_view.left, r_view.right);
@@ -1470,10 +1519,12 @@ static void R_View_SetFrustum(void)
 
 
 
-       VectorMAM(1, r_view.forward, 1.0 / -r_view.frustum_x, r_view.left, r_view.frustum[0].normal);
-       VectorMAM(1, r_view.forward, 1.0 /  r_view.frustum_x, r_view.left, r_view.frustum[1].normal);
-       VectorMAM(1, r_view.forward, 1.0 / -r_view.frustum_y, r_view.up, r_view.frustum[2].normal);
-       VectorMAM(1, r_view.forward, 1.0 /  r_view.frustum_y, r_view.up, r_view.frustum[3].normal);
+       slopex = 1.0 / r_view.frustum_x;
+       slopey = 1.0 / r_view.frustum_y;
+       VectorMA(r_view.forward, -slopex, r_view.left, r_view.frustum[0].normal);
+       VectorMA(r_view.forward,  slopex, r_view.left, r_view.frustum[1].normal);
+       VectorMA(r_view.forward, -slopey, r_view.up  , r_view.frustum[2].normal);
+       VectorMA(r_view.forward,  slopey, r_view.up  , r_view.frustum[3].normal);
        VectorCopy(r_view.forward, r_view.frustum[4].normal);
        VectorNormalize(r_view.frustum[0].normal);
        VectorNormalize(r_view.frustum[1].normal);
@@ -1490,6 +1541,12 @@ static void R_View_SetFrustum(void)
        PlaneClassify(&r_view.frustum[3]);
        PlaneClassify(&r_view.frustum[4]);
 
+       // calculate frustum corners, which are used to calculate deformed frustum planes for shadow caster culling
+       VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward, -1024 * slopex, r_view.left, -1024 * slopey, r_view.up, r_view.frustumcorner[0]);
+       VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward,  1024 * slopex, r_view.left, -1024 * slopey, r_view.up, r_view.frustumcorner[1]);
+       VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward, -1024 * slopex, r_view.left,  1024 * slopey, r_view.up, r_view.frustumcorner[2]);
+       VectorMAMAMAM(1, r_view.origin, 1024, r_view.forward,  1024 * slopex, r_view.left,  1024 * slopey, r_view.up, r_view.frustumcorner[3]);
+
        // LordHavoc: note to all quake engine coders, Quake had a special case
        // for 90 degrees which assumed a square view (wrong), so I removed it,
        // Quake2 has it disabled as well.
@@ -2132,6 +2189,8 @@ void R_RenderView(void)
 extern void R_DrawLightningBeams (void);
 extern void VM_CL_AddPolygonsToMeshQueue (void);
 extern void R_DrawPortals (void);
+extern cvar_t cl_locs_show;
+static void R_DrawLocs(void);
 void R_RenderScene(void)
 {
        // don't let sound skip if going slow
@@ -2222,6 +2281,13 @@ void R_RenderScene(void)
        }
        VM_CL_AddPolygonsToMeshQueue();
 
+       if (cl_locs_show.integer)
+       {
+               R_DrawLocs();
+               if (r_timereport_active)
+                       R_TimeReport("showlocs");
+       }
+
        if (r_drawportals.integer)
        {
                R_DrawPortals();
@@ -3886,6 +3952,80 @@ void R_QueueSurfaceList(int numsurfaces, msurface_t **surfacelist, int flagsmask
        }
 }
 
+float locboxvertex3f[6*4*3] =
+{
+       1,0,1, 1,0,0, 1,1,0, 1,1,1,
+       0,1,1, 0,1,0, 0,0,0, 0,0,1,
+       1,1,1, 1,1,0, 0,1,0, 0,1,1,
+       0,0,1, 0,0,0, 1,0,0, 1,0,1,
+       0,0,1, 1,0,1, 1,1,1, 0,1,1,
+       1,0,0, 0,0,0, 0,1,0, 1,1,0
+};
+
+int locboxelement3i[6*2*3] =
+{
+        0, 1, 2, 0, 2, 3,
+        4, 5, 6, 4, 6, 7,
+        8, 9,10, 8,10,11,
+       12,13,14, 12,14,15,
+       16,17,18, 16,18,19,
+       20,21,22, 20,22,23
+};
+
+void R_DrawLoc_Callback(const entity_render_t *ent, const rtlight_t *rtlight, int numsurfaces, int *surfacelist)
+{
+       int i, j;
+       cl_locnode_t *loc = (cl_locnode_t *)ent;
+       vec3_t mins, size;
+       float vertex3f[6*4*3];
+       CHECKGLERROR
+       GL_BlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
+       GL_DepthMask(false);
+       GL_DepthTest(true);
+       GL_CullFace(GL_NONE);
+       R_Mesh_Matrix(&identitymatrix);
+
+       R_Mesh_VertexPointer(vertex3f);
+       R_Mesh_ColorPointer(NULL);
+       R_Mesh_ResetTextureState();
+
+       i = surfacelist[0];
+       GL_Color(((i & 0x0007) >> 0) * (1.0f / 7.0f) * r_view.colorscale,
+                        ((i & 0x0038) >> 3) * (1.0f / 7.0f) * r_view.colorscale,
+                        ((i & 0x01C0) >> 6) * (1.0f / 7.0f) * r_view.colorscale,
+                       surfacelist[0] < 0 ? 0.5f : 0.125f);
+
+       if (VectorCompare(loc->mins, loc->maxs))
+       {
+               VectorSet(size, 2, 2, 2);
+               VectorMA(loc->mins, -0.5f, size, mins);
+       }
+       else
+       {
+               VectorCopy(loc->mins, mins);
+               VectorSubtract(loc->maxs, loc->mins, size);
+       }
+
+       for (i = 0;i < 6*4*3;)
+               for (j = 0;j < 3;j++, i++)
+                       vertex3f[i] = mins[j] + size[j] * locboxvertex3f[i];
+
+       R_Mesh_Draw(0, 6*4, 6*2, locboxelement3i);
+}
+
+void R_DrawLocs(void)
+{
+       int index;
+       cl_locnode_t *loc, *nearestloc;
+       vec3_t center;
+       nearestloc = CL_Locs_FindNearest(cl.movement_origin);
+       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);
+       }
+}
+
 void R_DrawCollisionBrushes(entity_render_t *ent)
 {
        int i;