]> de.git.xonotic.org Git - xonotic/darkplaces.git/commitdiff
realtime dlight shadows are now nearly the speed of compiled lights
authorhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Mar 2004 05:25:07 +0000 (05:25 +0000)
committerhavoc <havoc@d7cf8633-e32d-0410-b094-e92efae38249>
Wed, 3 Mar 2004 05:25:07 +0000 (05:25 +0000)
git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3957 d7cf8633-e32d-0410-b094-e92efae38249

gl_rsurf.c
model_brush.c
model_brush.h
model_shared.h
r_shadow.c
todo

index 5fdbd9c70473b073badc41e94092a57b2cb69994..21ab74541d69cc10ad8c2a1161a20f14572a4f10 100644 (file)
@@ -39,6 +39,24 @@ cvar_t r_drawcollisionbrushes_polygonfactor = {0, "r_drawcollisionbrushes_polygo
 cvar_t r_drawcollisionbrushes_polygonoffset = {0, "r_drawcollisionbrushes_polygonoffset", "0"};
 cvar_t gl_lightmaps = {0, "gl_lightmaps", "0"};
 
+/*
+// FIXME: these arrays are huge!
+int r_q1bsp_maxmarkleafs;
+int r_q1bsp_nummarkleafs;
+mleaf_t *r_q1bsp_maxleaflist[65536];
+int r_q1bsp_maxmarksurfaces;
+int r_q1bsp_nummarksurfaces;
+msurface_t *r_q1bsp_maxsurfacelist[65536];
+
+// FIXME: these arrays are huge!
+int r_q3bsp_maxmarkleafs;
+int r_q3bsp_nummarkleafs;
+q3mleaf_t *r_q3bsp_maxleaflist[65536];
+int r_q3bsp_maxmarksurfaces;
+int r_q3bsp_nummarksurfaces;
+q3mface_t *r_q3bsp_maxsurfacelist[65536];
+*/
+
 static int dlightdivtable[32768];
 
 static int R_IntAddDynamicLights (const matrix4x4_t *matrix, msurface_t *surf)
@@ -1852,9 +1870,11 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
                }
        }
 #else
-       int i, j, t;
+       int t, leafnum, marksurfnum, trianglenum;
        const int *e;
        msurface_t *surf;
+       mleaf_t *leaf;
+       const qbyte *pvs;
        float projectdistance;
        const float *v[3];
        vec3_t lightmins, lightmaxs;
@@ -1863,25 +1883,60 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
        R_Mesh_Matrix(&ent->matrix);
        R_UpdateTextureInfo(ent);
        projectdistance = lightradius + ent->model->radius;//projectdistance = 1000000000.0f;//lightradius + ent->model->radius;
-       //projectdistance = 1000000000.0f;//lightradius + ent->model->radius;
        lightmins[0] = relativelightorigin[0] - lightradius;
        lightmins[1] = relativelightorigin[1] - lightradius;
        lightmins[2] = relativelightorigin[2] - lightradius;
        lightmaxs[0] = relativelightorigin[0] + lightradius;
        lightmaxs[1] = relativelightorigin[1] + lightradius;
        lightmaxs[2] = relativelightorigin[2] + lightradius;
+       /*
        R_Shadow_PrepareShadowMark(ent->model->brush.shadowmesh->numtriangles);
-       for (i = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;i < ent->model->brushq1.nummodelsurfaces;i++, surf++)
+       maxmarksurfaces = sizeof(surfacelist) / sizeof(surfacelist[0]);
+       ent->model->brushq1.GetVisible(ent->model, relativelightorigin, lightmins, lightmaxs, 0, NULL, NULL, maxmarkleafs, markleaf, &nummarkleafs);
+       for (marksurfacenum = 0;marksurfacenum < nummarksurfaces;marksurfacenum++)
        {
-               if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
+               surf = marksurface[marksurfacenum];
+               if (surf->shadowmark != shadowmarkcount)
                {
-                       for (j = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;j < surf->mesh.num_triangles;j++, t++, e += 3)
+                       surf->shadowmark = shadowmarkcount;
+                       if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
                        {
-                               v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
-                               v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
-                               v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
-                               if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                       shadowmarklist[numshadowmark++] = t;
+                               for (trianglenum = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;trianglenum < surf->mesh.num_triangles;trianglenum++, t++, e += 3)
+                               {
+                                       v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                       v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                       v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                               shadowmarklist[numshadowmark++] = t;
+                               }
+                       }
+               }
+       }
+       */
+       R_Shadow_PrepareShadowMark(ent->model->brush.shadowmesh->numtriangles);
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       for (leafnum = 0, leaf = ent->model->brushq1.data_leafs;leafnum < ent->model->brushq1.num_leafs;leafnum++, leaf++)
+       {
+               if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+               {
+                       for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++)
+                       {
+                               surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum];
+                               if (surf->shadowmark != shadowmarkcount)
+                               {
+                                       surf->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST))
+                                       {
+                                               for (trianglenum = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;trianglenum < surf->mesh.num_triangles;trianglenum++, t++, e += 3)
+                                               {
+                                                       v[0] = ent->model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                                       v[1] = ent->model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                                       v[2] = ent->model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                                               shadowmarklist[numshadowmark++] = t;
+                                               }
+                                       }
+                               }
                        }
                }
        }
@@ -1891,10 +1946,12 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto
 
 void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t relativeeyeorigin, float lightradius, float *lightcolor, const matrix4x4_t *matrix_modeltolight, const matrix4x4_t *matrix_modeltoattenuationxyz, const matrix4x4_t *matrix_modeltoattenuationz, rtexture_t *lightcubemap)
 {
-       int surfnum;
+       int leafnum, marksurfnum;
        msurface_t *surf;
+       mleaf_t *leaf;
+       const qbyte *pvs;
        texture_t *t;
-       float f, lightmins[3], lightmaxs[3];
+       float lightmins[3], lightmaxs[3];
        if (ent->model == NULL)
                return;
        R_Mesh_Matrix(&ent->matrix);
@@ -1905,20 +1962,27 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v
        lightmaxs[1] = relativelightorigin[1] + lightradius;
        lightmaxs[2] = relativelightorigin[2] + lightradius;
        R_UpdateTextureInfo(ent);
-       for (surfnum = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;surfnum < ent->model->brushq1.nummodelsurfaces;surfnum++, surf++)
+       shadowmarkcount++;
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       for (leafnum = 0, leaf = ent->model->brushq1.data_leafs;leafnum < ent->model->brushq1.num_leafs;leafnum++, leaf++)
        {
-               if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(surf->poly_mins, surf->poly_maxs, lightmins, lightmaxs))
+               if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
                {
-                       f = PlaneDiff(relativelightorigin, surf->plane);
-                       if (surf->flags & SURF_PLANEBACK)
-                               f = -f;
-                       if (f >= -0.1 && f < lightradius)
+                       for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++)
                        {
-                               t = surf->texinfo->texture->currentframe;
-                               if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+                               surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum];
+                               if (surf->shadowmark != shadowmarkcount)
                                {
-                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
-                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
+                                       surf->shadowmark = shadowmarkcount;
+                                       if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs))
+                                       {
+                                               t = surf->texinfo->texture->currentframe;
+                                               if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT)
+                                               {
+                                                       R_Shadow_DiffuseLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.base, t->skin.nmap, lightcubemap);
+                                                       R_Shadow_SpecularLighting(surf->mesh.num_vertices, surf->mesh.num_triangles, surf->mesh.data_element3i, surf->mesh.data_vertex3f, surf->mesh.data_svector3f, surf->mesh.data_tvector3f, surf->mesh.data_normal3f, surf->mesh.data_texcoordtexture2f, relativelightorigin, relativeeyeorigin, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, t->skin.gloss, t->skin.nmap, lightcubemap);
+                                               }
+                                       }
                                }
                        }
                }
@@ -2433,9 +2497,12 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                                        R_Shadow_VolumeFromSphere(face->num_vertices, face->num_triangles, face->data_vertex3f, face->data_element3i, face->data_neighbor3i, relativelightorigin, projectdistance, lightradius);
        }
 #else
-       int i, j, t;
+       int j, t, leafnum, marksurfnum;
        const int *e;
+       const qbyte *pvs;
+       const float *v[3];
        q3mface_t *face;
+       q3mleaf_t *leaf;
        vec3_t modelorg, lightmins, lightmaxs;
        model_t *model;
        float projectdistance;
@@ -2452,18 +2519,29 @@ void R_Q3BSP_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin,
                lightmaxs[1] = relativelightorigin[1] + lightradius;
                lightmaxs[2] = relativelightorigin[2] + lightradius;
                R_Shadow_PrepareShadowMark(model->brush.shadowmesh->numtriangles);
-               for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++)
+               pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+               for (leafnum = 0, leaf = ent->model->brushq3.data_leafs;leafnum < ent->model->brushq3.num_leafs;leafnum++, leaf++)
                {
-                       if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
+                       if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
                        {
-                               for (j = 0, t = face->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < face->num_triangles;j++, t++, e += 3)
+                               for (marksurfnum = 0;marksurfnum < leaf->numleaffaces;marksurfnum++)
                                {
-                                       const float *v[3];
-                                       v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
-                                       v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
-                                       v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
-                                       if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
-                                               shadowmarklist[numshadowmark++] = t;
+                                       face = leaf->firstleafface[marksurfnum];
+                                       if (face->shadowmark != shadowmarkcount)
+                                       {
+                                               face->shadowmark = shadowmarkcount;
+                                               if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs))
+                                               {
+                                                       for (j = 0, t = face->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < face->num_triangles;j++, t++, e += 3)
+                                                       {
+                                                               v[0] = model->brush.shadowmesh->vertex3f + e[0] * 3;
+                                                               v[1] = model->brush.shadowmesh->vertex3f + e[1] * 3;
+                                                               v[2] = model->brush.shadowmesh->vertex3f + e[2] * 3;
+                                                               if (PointInfrontOfTriangle(relativelightorigin, v[0], v[1], v[2]) && lightmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && lightmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && lightmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && lightmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && lightmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && lightmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                                                       shadowmarklist[numshadowmark++] = t;
+                                                       }
+                                               }
+                                       }
                                }
                        }
                }
index e9bcca803ae2fa36822fb1512c88a100fa549c83..ca02eaad64c3f5879baa35b7b7c281c7ae9d31e9 100644 (file)
@@ -2814,6 +2814,54 @@ static void Mod_Q1BSP_RoundUpToHullSize(model_t *cmodel, const vec3_t inmins, co
        VectorAdd(inmins, hull->clip_size, outmaxs);
 }
 
+/*
+void Mod_Q1BSP_RecursiveGetVisible(mnode_t *node, model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, mleaf_t *leaflist, int *numleafs, int maxsurfaces, msurface_t *surfacelist, int *numsurfaces, const qbyte *pvs)
+{
+       mleaf_t *leaf;
+       for (;;)
+       {
+               if (!BoxesOverlap(node->mins, node->maxs, mins, maxs))
+                       return;
+               if (!node->plane)
+                       break;
+               Mod_Q1BSP_RecursiveGetVisible(node->children[0], model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+               node = node->children[1];
+       }
+       leaf = (mleaf_t *)node;
+       if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+       {
+               int marksurfacenum;
+               msurface_t *surf;
+               if (maxleafs && *numleafs < maxleafs)
+                       leaflist[(*numleafs)++] = leaf;
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               surf = model->brushq1.surfaces + leaf->firstmarksurface[marksurfacenum];
+                               if (surf->shadowmark != shadowmarkcount)
+                               {
+                                       surf->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(mins, maxs, surf->poly_mins, surf->poly_maxs) && ((surf->flags & SURF_PLANEBACK) ? PlaneDiff(point, surf->plane) < 0 : PlaneDiff(point, surf->plane) > 0) && *numsurfaces < maxsurfaces)
+                                               surfacelist[(*numsurfaces)++] = surf;
+                               }
+                       }
+               }
+       }
+}
+
+void Mod_Q1BSP_GetVisible(model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, mleaf_t *leaflist, int *numleafs, int maxsurfaces, msurface_t *surfacelist, int *numsurfaces)
+{
+       // FIXME: support portals
+       if (maxsurfaces)
+               *numsurfaces = 0;
+       if (maxleafs)
+               *numleafs = 0;
+       pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+       Mod_Q1BSP_RecursiveGetVisible(ent->model->brushq1.nodes + ent->model->brushq1.firstclipnode, model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces);
+}
+*/
+
 extern void R_Model_Brush_DrawSky(entity_render_t *ent);
 extern void R_Model_Brush_Draw(entity_render_t *ent);
 extern void R_Model_Brush_DrawShadowVolume(entity_render_t *ent, vec3_t relativelightorigin, float lightradius);
@@ -5301,6 +5349,69 @@ static int Mod_Q3BSP_NativeContentsFromSuperContents(model_t *model, int superco
        return nativecontents;
 }
 
+/*
+void Mod_Q3BSP_RecursiveGetVisible(q3mnode_t *node, model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, q3mleaf_t *leaflist, int *numleafs, int maxsurfaces, q3msurface_t *surfacelist, int *numsurfaces, const qbyte *pvs)
+{
+       mleaf_t *leaf;
+       for (;;)
+       {
+               if (!BoxesOverlap(node->mins, node->maxs, mins, maxs))
+                       return;
+               if (!node->plane)
+                       break;
+               Mod_Q3BSP_RecursiveGetVisible(node->children[0], model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+               node = node->children[1];
+       }
+       leaf = (mleaf_t *)node;
+       if ((pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex)))
+       {
+               int marksurfacenum;
+               q3mface_t *surf;
+               if (maxleafs && *numleafs < maxleafs)
+                       leaflist[(*numleaf)++] = leaf;
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               face = leaf->firstleafface[marksurfacenum];
+                               if (face->shadowmark != shadowmarkcount)
+                               {
+                                       face->shadowmark = shadowmarkcount;
+                                       if (BoxesOverlap(mins, maxs, face->mins, face->maxs) && *numsurfaces < maxsurfaces)
+                                               surfacelist[(*numsurfaces)++] = face;
+                               }
+                       }
+               }
+       }
+}
+
+void Mod_Q3BSP_GetVisible(model_t *model, const vec3_t point, const vec3_t mins, const vec3_t maxs, int maxleafs, q3mleaf_t *leaflist, int *numleafs, int maxsurfaces, q3msurface_t *surfacelist, int *numsurfaces)
+{
+       // FIXME: support portals
+       if (maxsurfaces)
+               *numsurfaces = 0;
+       if (maxleafs)
+               *numleafs = 0;
+       if (model->submodel)
+       {
+               if (maxsurfaces)
+               {
+                       for (marksurfacenum = 0;marksurfacenum < leaf->nummarksurfaces;marksurfacenum++)
+                       {
+                               face = ent->model->brushq3.surfaces + leaf->firstmarksurface[marksurfacenum];
+                               if (BoxesOverlap(mins, maxs, face->mins, face->maxs) && *numsurfaces < maxsurfaces)
+                                       surfacelist[(*numsurfaces)++] = face;
+                       }
+               }
+       }
+       else
+       {
+               pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin);
+               Mod_Q3BSP_RecursiveGetVisible(ent->model->brushq3.data_nodes, model, point, mins, maxs, maxleafs, leaflist, numleafs, maxsurfaces, surfacelist, numsurfaces, pvs);
+       }
+}
+*/
+
 extern void R_Q3BSP_DrawSky(struct entity_render_s *ent);
 extern void R_Q3BSP_Draw(struct entity_render_s *ent);
 extern void R_Q3BSP_DrawShadowVolume(struct entity_render_s *ent, vec3_t relativelightorigin, float lightradius);
index b4f76ac09b7c203e54f04cf8f662e1904eb0c7a0..62448da2c73079ba9acb6267e6f38187ae7b1f8e 100644 (file)
@@ -227,6 +227,9 @@ typedef struct msurface_s
        //struct msurface_s **neighborsurfaces;
        // currently used only for generating static shadow volumes
        int lighttemp_castshadow;
+
+       // avoid redundent surface shadows
+       int shadowmark;
 }
 msurface_t;
 
index b16ee206e7f45404918e7ad79fe9220fb1d3cf61..a8fac65ae4c2f15ecfc258df951453d0fe75902a 100644 (file)
@@ -450,6 +450,9 @@ typedef struct q3mface_s
 
        // index into model->brush.shadowmesh
        int num_firstshadowmeshtriangle;
+       
+       // used for shadow volume generation
+       int shadowmark;
 
        // temporary use by light processing
        int lighttemp_castshadow;
index a9440ac81e6ed508930b47131f159b39c7085da3..4f5e1caaa462c09d12477445dbe3f0d1e54ee7c2 100644 (file)
@@ -1698,7 +1698,6 @@ void R_RTLight_UpdateFromDLight(rtlight_t *rtlight, const dlight_t *light, int i
 // (undone by R_FreeCompiledRTLight, which R_UpdateLight calls)
 void R_RTLight_Compile(rtlight_t *rtlight)
 {
-#if 0
        int i, j, k, l, maxverts = 256, tris;
        float *vertex3f = NULL, mins[3], maxs[3];
        shadowmesh_t *mesh, *castmesh = NULL;
@@ -1908,7 +1907,19 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                        for (mesh = castmesh;mesh;mesh = mesh->next)
                        {
                                Mod_BuildTriangleNeighbors(mesh->neighbor3i, mesh->element3i, mesh->numtriangles);
-                               if ((tris = R_Shadow_ConstructShadowVolume(castmesh->numverts, 0, castmesh->numtriangles, castmesh->element3i, castmesh->neighbor3i, castmesh->vertex3f, NULL, shadowelements, vertex3f, rtlight->shadoworigin, r_shadow_projectdistance.value)))
+                               R_Shadow_PrepareShadowMark(mesh->numtriangles);
+                               for (i = 0;i < mesh->numtriangles;i++)
+                               {
+                                       const float *v[3];
+                                       v[0] = mesh->vertex3f + mesh->element3i[i*3+0] * 3;
+                                       v[1] = mesh->vertex3f + mesh->element3i[i*3+1] * 3;
+                                       v[2] = mesh->vertex3f + mesh->element3i[i*3+2] * 3;
+                                       if (PointInfrontOfTriangle(rtlight->shadoworigin, v[0], v[1], v[2]) && rtlight->cullmaxs[0] > min(v[0][0], min(v[1][0], v[2][0])) && rtlight->cullmins[0] < max(v[0][0], max(v[1][0], v[2][0])) && rtlight->cullmaxs[1] > min(v[0][1], min(v[1][1], v[2][1])) && rtlight->cullmins[1] < max(v[0][1], max(v[1][1], v[2][1])) && rtlight->cullmaxs[2] > min(v[0][2], min(v[1][2], v[2][2])) && rtlight->cullmins[2] < max(v[0][2], max(v[1][2], v[2][2])))
+                                               shadowmarklist[numshadowmark++] = i;
+                               }
+                               if (maxshadowelements < numshadowmark * 24)
+                                       R_Shadow_ResizeShadowElements((numshadowmark + 256) * 24);
+                               if ((tris = R_Shadow_ConstructShadowVolume(mesh->numverts, mesh->numtriangles, mesh->element3i, mesh->neighbor3i, mesh->vertex3f, NULL, shadowelements, vertex3f, rtlight->shadoworigin, r_shadow_projectdistance.value, numshadowmark, shadowmarklist)))
                                        Mod_ShadowMesh_AddMesh(r_shadow_mempool, rtlight->static_meshchain_shadow, NULL, NULL, NULL, vertex3f, NULL, NULL, NULL, NULL, tris, shadowelements);
                        }
                        Mem_Free(vertex3f);
@@ -1930,7 +1941,6 @@ void R_RTLight_Compile(rtlight_t *rtlight)
                for (mesh = rtlight->static_meshchain_light;mesh;mesh = mesh->next)
                        l += mesh->numtriangles;
        Con_DPrintf("static light built: %f %f %f : %f %f %f box, %i shadow volume triangles, %i light triangles\n", rtlight->cullmins[0], rtlight->cullmins[1], rtlight->cullmins[2], rtlight->cullmaxs[0], rtlight->cullmaxs[1], rtlight->cullmaxs[2], k, l);
-#endif
 }
 
 void R_RTLight_Uncompile(rtlight_t *rtlight)
diff --git a/todo b/todo
index b98d5adf980fb10dd3f26b35ec786ce0c6854e41..cf4fcb54ebdfa1760ebafb7e8b36a250ccda2821 100644 (file)
--- a/todo
+++ b/todo
@@ -95,6 +95,10 @@ d darkplaces: add tenebrae light entity properties, like cubemap and style and s
 -n darkplaces: implement cubemap support on rtlights (romi, Vermeulen, Mitchell)
 d darkplaces: add r_shadow_realtime_world_lightmaps cvar to control lightmap brightness (Mitchell)
 -n darkplaces: add gl_lightmaps cvar to disable texturing except lightmaps for testing (Vic)
+0 darkplaces: adaptive patch subdivision levels on X and Y based on r_subdivisions cvar
+0 darkplaces: put patches on a delayed queue in q3bsp collision code so the trace is first clipped by brushes
+2 darkplaces: do culling traces against patch bbox
+0 darkplaces: cap packet size at 1k for non-local connections, regardless of their rate setting
 0 hmap2: release hmap2 (Vic, Supajoe)
 4 darkplaces: add capability for qc entities to act as bones in a model, and send them as compressed origins in the parent entity's updates, with perhaps a limit of 16 bones, this would allow some simple serverside ragdoll (Mitchell, Deej)
 d darkplaces: worked around Intel precision bug with view blends (they were not covering one line of the screen, due to being so huge that it had precision problems, on ATI and NVIDIA) (Sajt)