From 8579a99f191bfaca20e096493ada7351793fde0b Mon Sep 17 00:00:00 2001 From: havoc Date: Wed, 3 Mar 2004 05:25:07 +0000 Subject: [PATCH] realtime dlight shadows are now nearly the speed of compiled lights git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3957 d7cf8633-e32d-0410-b094-e92efae38249 --- gl_rsurf.c | 142 ++++++++++++++++++++++++++++++++++++++----------- model_brush.c | 111 ++++++++++++++++++++++++++++++++++++++ model_brush.h | 3 ++ model_shared.h | 3 ++ r_shadow.c | 16 ++++-- todo | 4 ++ 6 files changed, 244 insertions(+), 35 deletions(-) diff --git a/gl_rsurf.c b/gl_rsurf.c index 5fdbd9c7..21ab7454 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -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; + } + } + } } } } diff --git a/model_brush.c b/model_brush.c index e9bcca80..ca02eaad 100644 --- a/model_brush.c +++ b/model_brush.c @@ -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); diff --git a/model_brush.h b/model_brush.h index b4f76ac0..62448da2 100644 --- a/model_brush.h +++ b/model_brush.h @@ -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; diff --git a/model_shared.h b/model_shared.h index b16ee206..a8fac65a 100644 --- a/model_shared.h +++ b/model_shared.h @@ -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; diff --git a/r_shadow.c b/r_shadow.c index a9440ac8..4f5e1caa 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -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 b98d5adf..cf4fcb54 100644 --- 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) -- 2.39.2