From: havoc Date: Wed, 3 Mar 2004 06:50:56 +0000 (+0000) Subject: fixed bmodel realtime lighting/shadowing render crashes (and bogus shadows from them) X-Git-Tag: xonotic-v0.1.0preview~6044 X-Git-Url: http://de.git.xonotic.org/?p=xonotic%2Fdarkplaces.git;a=commitdiff_plain;h=c568680b774f2205b8d44babcc69e88cfddb7dc0 fixed bmodel realtime lighting/shadowing render crashes (and bogus shadows from them) git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@3959 d7cf8633-e32d-0410-b094-e92efae38249 --- diff --git a/gl_rsurf.c b/gl_rsurf.c index 21ab7454..bdff5312 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1914,32 +1914,53 @@ void R_Model_Brush_DrawShadowVolume (entity_render_t *ent, vec3_t relativelighto } */ 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 (ent->model->brush.GetPVS && (pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin))) { - if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex))) + pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin); + // FIXME: use BSP recursion in q1bsp as dlights are often small + for (leafnum = 0, leaf = ent->model->brushq1.data_leafs;leafnum < ent->model->brushq1.num_leafs;leafnum++, leaf++) { - for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++) + if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && CHECKPVSBIT(pvs, leaf->clusterindex)) { - surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum]; - if (surf->shadowmark != shadowmarkcount) + for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++) { - surf->shadowmark = shadowmarkcount; - if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && surf->texinfo->texture->rendertype == SURFRENDER_OPAQUE && (surf->flags & SURF_SHADOWCAST)) + surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum]; + if (surf->shadowmark != shadowmarkcount) { - for (trianglenum = 0, t = surf->num_firstshadowmeshtriangle, e = ent->model->brush.shadowmesh->element3i + t * 3;trianglenum < surf->mesh.num_triangles;trianglenum++, 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; + } } } } } } } + else + { + for (marksurfnum = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;marksurfnum < ent->model->brushq1.nummodelsurfaces;marksurfnum++, surf++) + { + 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; + } + } + } + } R_Shadow_VolumeFromList(ent->model->brush.shadowmesh->numverts, ent->model->brush.shadowmesh->numtriangles, ent->model->brush.shadowmesh->vertex3f, ent->model->brush.shadowmesh->element3i, ent->model->brush.shadowmesh->neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist); #endif } @@ -1963,30 +1984,48 @@ void R_Model_Brush_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, v lightmaxs[2] = relativelightorigin[2] + lightradius; R_UpdateTextureInfo(ent); 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->model->brush.GetPVS && (pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin))) { - if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex))) + 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++) { - for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++) + if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && CHECKPVSBIT(pvs, leaf->clusterindex)) { - surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum]; - if (surf->shadowmark != shadowmarkcount) + for (marksurfnum = 0;marksurfnum < leaf->nummarksurfaces;marksurfnum++) { - surf->shadowmark = shadowmarkcount; - if ((ent != &cl_entities[0].render || surf->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs)) + surf = ent->model->brushq1.surfaces + leaf->firstmarksurface[marksurfnum]; + if (surf->shadowmark != shadowmarkcount) { - t = surf->texinfo->texture->currentframe; - if (t->rendertype == SURFRENDER_OPAQUE && t->flags & SURF_SHADOWLIGHT) + surf->shadowmark = shadowmarkcount; + if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && (ent != &cl_entities[0].render || surf->visframe == r_framecount)) { - 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); + 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); + } } } } } } } + else + { + for (marksurfnum = 0, surf = ent->model->brushq1.surfaces + ent->model->brushq1.firstmodelsurface;marksurfnum < ent->model->brushq1.nummodelsurfaces;marksurfnum++, surf++) + { + if (BoxesOverlap(lightmins, lightmaxs, surf->poly_mins, surf->poly_maxs) && (ent != &cl_entities[0].render || surf->visframe == r_framecount)) + { + 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); + } + } + } + } } void R_DrawCollisionBrush(colbrushf_t *brush) @@ -2519,32 +2558,51 @@ 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); - 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, leaf->mins, leaf->maxs) && (pvs == NULL || CHECKPVSBIT(pvs, leaf->clusterindex))) + if (ent->model->brush.GetPVS && (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++) { - for (marksurfnum = 0;marksurfnum < leaf->numleaffaces;marksurfnum++) + if (BoxesOverlap(lightmins, lightmaxs, leaf->mins, leaf->maxs) && CHECKPVSBIT(pvs, leaf->clusterindex)) { - face = leaf->firstleafface[marksurfnum]; - if (face->shadowmark != shadowmarkcount) + for (marksurfnum = 0;marksurfnum < leaf->numleaffaces;marksurfnum++) { - face->shadowmark = shadowmarkcount; - if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs)) + face = leaf->firstleafface[marksurfnum]; + if (face->shadowmark != shadowmarkcount) { - for (j = 0, t = face->num_firstshadowmeshtriangle, e = model->brush.shadowmesh->element3i + t * 3;j < face->num_triangles;j++, t++, e += 3) + face->shadowmark = shadowmarkcount; + if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs)) { - 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; + 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; + } } } } } } } + else + { + for (marksurfnum = 0, face = model->brushq3.data_thismodel->firstface;marksurfnum < model->brushq3.data_thismodel->numfaces;marksurfnum++, face++) + { + 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; + } + } + } + } R_Shadow_VolumeFromList(model->brush.shadowmesh->numverts, model->brush.shadowmesh->numtriangles, model->brush.shadowmesh->vertex3f, model->brush.shadowmesh->element3i, model->brush.shadowmesh->neighbor3i, relativelightorigin, projectdistance, numshadowmark, shadowmarklist); } #endif @@ -2560,8 +2618,10 @@ void R_Q3BSP_DrawFaceLight(entity_render_t *ent, q3mface_t *face, vec3_t relativ void R_Q3BSP_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 i; + int leafnum, marksurfnum; + const qbyte *pvs; q3mface_t *face; + q3mleaf_t *leaf; vec3_t modelorg, lightmins, lightmaxs; model_t *model; //qbyte *pvs; @@ -2577,12 +2637,33 @@ void R_Q3BSP_DrawLight(entity_render_t *ent, vec3_t relativelightorigin, vec3_t lightmaxs[0] = relativelightorigin[0] + lightradius; lightmaxs[1] = relativelightorigin[1] + lightradius; lightmaxs[2] = relativelightorigin[2] + lightradius; - //if (ent == &cl_entities[0].render && model->brush.num_pvsclusters && !r_novis.integer && (pvs = model->brush.GetPVS(model, modelorg))) - // R_Q3BSP_RecursiveWorldNode(ent, model->brushq3.data_nodes, modelorg, pvs, ++markframe); - //else - for (i = 0, face = model->brushq3.data_thismodel->firstface;i < model->brushq3.data_thismodel->numfaces;i++, face++) - if ((ent != &cl_entities[0].render || face->visframe == r_framecount) && BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs)) + + if (ent->model->brush.GetPVS && (pvs = ent->model->brush.GetPVS(ent->model, relativelightorigin))) + { + 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, leaf->mins, leaf->maxs) && CHECKPVSBIT(pvs, leaf->clusterindex)) + { + for (marksurfnum = 0;marksurfnum < leaf->numleaffaces;marksurfnum++) + { + face = leaf->firstleafface[marksurfnum]; + if (face->shadowmark != shadowmarkcount) + { + face->shadowmark = shadowmarkcount; + if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs) && (ent != &cl_entities[0].render || face->visframe == r_framecount)) + R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap); + } + } + } + } + } + else + { + for (marksurfnum = 0, face = model->brushq3.data_thismodel->firstface;marksurfnum < model->brushq3.data_thismodel->numfaces;marksurfnum++, face++) + if (BoxesOverlap(lightmins, lightmaxs, face->mins, face->maxs) && (ent != &cl_entities[0].render || face->visframe == r_framecount)) R_Q3BSP_DrawFaceLight(ent, face, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, matrix_modeltolight, matrix_modeltoattenuationxyz, matrix_modeltoattenuationz, lightcubemap); + } } } diff --git a/todo b/todo index 223691e2..2179f2dd 100644 --- a/todo +++ b/todo @@ -37,6 +37,7 @@ d darkplaces: revert noclip movement to match nq for compatibility with mods tha d darkplaces: make light_lev dlights from qc require PFLAGS_FULLDYNAMIC flag d darkplaces: improve tenebrae compatibility by handling EF_FULLDYNAMIC flag in tenebrae mode, also make all sprites render additive d darkplaces: add r_showtris cvar (Riot) +0 darkplaces: fix model lighting with r_shadow_realtime_world_lightmaps mode, it seems to be adding dlights to vertices? (Mitchell) 3 darkplaces: figure out BoxOnPlaneSide crash that happens in dpmod dpdm2 deathmatch 7 occasionally 2 darkplaces: add q2 sprite support sometime 0 dpmod: fix tilted corpse bug