From ec6dd5edf7290360f59fe1d6345af69875fbea81 Mon Sep 17 00:00:00 2001 From: havoc Date: Mon, 7 Apr 2003 01:28:47 +0000 Subject: [PATCH] split r_shadow_realtime into r_shadow_realtime_world (which requires stencil) and r_shadow_realtime_dlight (which works without stencil) one bug remains with scissoring dlights without stencil, I'll try to figure out this problem soon git-svn-id: svn://svn.icculus.org/twilight/trunk/darkplaces@2924 d7cf8633-e32d-0410-b094-e92efae38249 --- cl_screen.c | 19 +-- gl_rmain.c | 432 ++++++++++++++++++++++++++-------------------------- gl_rsurf.c | 4 +- r_light.c | 220 +++++++++++++------------- r_shadow.c | 101 ++++++------ r_shadow.h | 9 +- 6 files changed, 392 insertions(+), 393 deletions(-) diff --git a/cl_screen.c b/cl_screen.c index eca31c2e..ceffda76 100644 --- a/cl_screen.c +++ b/cl_screen.c @@ -355,7 +355,6 @@ void R_TimeReport(char *desc) extern int c_rt_lights, c_rt_clears, c_rt_scissored; extern int c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris; extern int c_rtcached_shadowmeshes, c_rtcached_shadowtris; -extern int r_shadow_lightingmode; void R_TimeReport_Start(void) { r_timereport_active = r_speeds.integer && cls.signon == SIGNONS && cls.state == ca_connected; @@ -373,16 +372,14 @@ void R_TimeReport_Start(void) c_faces, c_nodes, c_leafs, c_light_polys, c_models, c_bmodels, c_sprites, c_particles, c_dlights, c_alias_polys, c_meshs, c_meshelements / 3); - if (r_shadow_lightingmode) - { - sprintf(r_speeds_string + strlen(r_speeds_string), - "realtime lighting:%4i lights%4i clears%4i scissored\n" - "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n" - "precomputed: %6i shadowmeshes%6i shadowtris\n", - c_rt_lights, c_rt_clears, c_rt_scissored, - c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris, - c_rtcached_shadowmeshes, c_rtcached_shadowtris); - } + + sprintf(r_speeds_string + strlen(r_speeds_string), + "realtime lighting:%4i lights%4i clears%4i scissored\n" + "dynamic: %6i shadowmeshes%6i shadowtris%6i lightmeshes%6i lighttris\n" + "precomputed: %6i shadowmeshes%6i shadowtris\n", + c_rt_lights, c_rt_clears, c_rt_scissored, + c_rt_shadowmeshes, c_rt_shadowtris, c_rt_lightmeshes, c_rt_lighttris, + c_rtcached_shadowmeshes, c_rtcached_shadowtris); c_alias_polys = 0; c_light_polys = 0; diff --git a/gl_rmain.c b/gl_rmain.c index fc8a8d1f..0ce87d35 100644 --- a/gl_rmain.c +++ b/gl_rmain.c @@ -722,7 +722,7 @@ int LightAndVis_CullPointCloud(int numpoints, const float *points) } -void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t lightmins, vec3_t lightmaxs, vec3_t clipmins, vec3_t clipmaxs) +void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float cullradius, float lightradius, vec3_t lightmins, vec3_t lightmaxs, vec3_t clipmins, vec3_t clipmaxs, int lightmarked) { vec3_t relativelightorigin; #if 0 @@ -739,7 +739,7 @@ void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float c if (ent->maxs[0] < lightmins[0] || ent->mins[0] > lightmaxs[0] || ent->maxs[1] < lightmins[1] || ent->mins[1] > lightmaxs[1] || ent->maxs[2] < lightmins[2] || ent->mins[2] > lightmaxs[2] - || Light_CullBox(ent->mins, ent->maxs)) + || (lightmarked && Light_CullBox(ent->mins, ent->maxs))) return; } #if 0 @@ -755,7 +755,7 @@ void R_TestAndDrawShadowVolume(entity_render_t *ent, vec3_t lightorigin, float c Matrix4x4_Transform(&ent->matrix, temp, points[i]); VectorSubtract(points[i], lightorigin, temp); dist = projectdistance / sqrt(DotProduct(temp, temp)); - VectorMA(points[i], dist, temp, points[i+8]); + VectorMA(lightorigin, dist, temp, points[i+8]); } if (LightAndVis_CullPointCloud(16, points[0])) return; @@ -819,7 +819,7 @@ void R_ShadowVolumeLighting (int visiblevolumes) memset(&m, 0, sizeof(m)); m.blendfunc1 = GL_ONE; m.blendfunc2 = GL_ONE; - if (r_shadow_realtime.integer >= 3) + if (r_shadow_visiblevolumes.integer >= 2) m.depthdisable = true; R_Mesh_State(&m); qglDisable(GL_CULL_FACE); @@ -828,223 +828,235 @@ void R_ShadowVolumeLighting (int visiblevolumes) else R_Shadow_Stage_Begin(); shadowframecount++; - for (lnum = 0, wl = r_shadow_worldlightchain;wl;wl = wl->next, lnum++) + if (r_shadow_realtime_world.integer) { - if (d_lightstylevalue[wl->style] <= 0) - continue; - if (R_CullBox(wl->mins, wl->maxs)) - //if (R_CullSphere(wl->origin, cullradius)) - continue; - //if (R_CullBox(wl->mins, wl->maxs) || R_CullSphere(wl->origin, lightradius)) - // continue; - //if (VIS_CullBox(wl->mins, wl->maxs) || VIS_CullSphere(wl->origin, lightradius)) - // continue; - if (r_shadow_debuglight.integer >= 0 && lnum != r_shadow_debuglight.integer) - continue; - - cullradius = wl->cullradius; - lightradius = wl->lightradius; - - if (cl.worldmodel != NULL) + R_Shadow_LoadWorldLightsIfNeeded(); + for (lnum = 0, wl = r_shadow_worldlightchain;wl;wl = wl->next, lnum++) { - for (i = 0;i < wl->numleafs;i++) - if (wl->leafs[i]->visframe == r_framecount) - break; - if (i == wl->numleafs) + if (d_lightstylevalue[wl->style] <= 0) continue; - leaf = wl->leafs[i++]; - VectorCopy(leaf->mins, clipmins); - VectorCopy(leaf->maxs, clipmaxs); - for (;i < wl->numleafs;i++) + if (R_CullBox(wl->mins, wl->maxs)) + //if (R_CullSphere(wl->origin, cullradius)) + continue; + //if (R_CullBox(wl->mins, wl->maxs) || R_CullSphere(wl->origin, lightradius)) + // continue; + //if (VIS_CullBox(wl->mins, wl->maxs) || VIS_CullSphere(wl->origin, lightradius)) + // continue; + if (r_shadow_debuglight.integer >= 0 && lnum != r_shadow_debuglight.integer) + continue; + + cullradius = wl->cullradius; + lightradius = wl->lightradius; + + if (cl.worldmodel != NULL) { - leaf = wl->leafs[i]; - if (leaf->visframe == r_framecount) + for (i = 0;i < wl->numleafs;i++) + if (wl->leafs[i]->visframe == r_framecount) + break; + if (i == wl->numleafs) + continue; + leaf = wl->leafs[i++]; + VectorCopy(leaf->mins, clipmins); + VectorCopy(leaf->maxs, clipmaxs); + for (;i < wl->numleafs;i++) { - if (clipmins[0] > leaf->mins[0]) clipmins[0] = leaf->mins[0]; - if (clipmaxs[0] < leaf->maxs[0]) clipmaxs[0] = leaf->maxs[0]; - if (clipmins[1] > leaf->mins[1]) clipmins[1] = leaf->mins[1]; - if (clipmaxs[1] < leaf->maxs[1]) clipmaxs[1] = leaf->maxs[1]; - if (clipmins[2] > leaf->mins[2]) clipmins[2] = leaf->mins[2]; - if (clipmaxs[2] < leaf->maxs[2]) clipmaxs[2] = leaf->maxs[2]; + leaf = wl->leafs[i]; + if (leaf->visframe == r_framecount) + { + if (clipmins[0] > leaf->mins[0]) clipmins[0] = leaf->mins[0]; + if (clipmaxs[0] < leaf->maxs[0]) clipmaxs[0] = leaf->maxs[0]; + if (clipmins[1] > leaf->mins[1]) clipmins[1] = leaf->mins[1]; + if (clipmaxs[1] < leaf->maxs[1]) clipmaxs[1] = leaf->maxs[1]; + if (clipmins[2] > leaf->mins[2]) clipmins[2] = leaf->mins[2]; + if (clipmaxs[2] < leaf->maxs[2]) clipmaxs[2] = leaf->maxs[2]; + } } + if (clipmins[0] < wl->mins[0]) clipmins[0] = wl->mins[0]; + if (clipmaxs[0] > wl->maxs[0]) clipmaxs[0] = wl->maxs[0]; + if (clipmins[1] < wl->mins[1]) clipmins[1] = wl->mins[1]; + if (clipmaxs[1] > wl->maxs[1]) clipmaxs[1] = wl->maxs[1]; + if (clipmins[2] < wl->mins[2]) clipmins[2] = wl->mins[2]; + if (clipmaxs[2] > wl->maxs[2]) clipmaxs[2] = wl->maxs[2]; + } + else + { + VectorCopy(wl->mins, clipmins); + VectorCopy(wl->maxs, clipmaxs); } - if (clipmins[0] < wl->mins[0]) clipmins[0] = wl->mins[0]; - if (clipmaxs[0] > wl->maxs[0]) clipmaxs[0] = wl->maxs[0]; - if (clipmins[1] < wl->mins[1]) clipmins[1] = wl->mins[1]; - if (clipmaxs[1] > wl->maxs[1]) clipmaxs[1] = wl->maxs[1]; - if (clipmins[2] < wl->mins[2]) clipmins[2] = wl->mins[2]; - if (clipmaxs[2] > wl->maxs[2]) clipmaxs[2] = wl->maxs[2]; - } - else - { - VectorCopy(wl->mins, clipmins); - VectorCopy(wl->maxs, clipmaxs); - } - //if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, wl->origin, wl->cullradius)) - if (R_CullBox(clipmins, clipmaxs) || R_Shadow_ScissorForBBox(clipmins, clipmaxs)) - continue; + //if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, wl->origin, wl->cullradius)) + if (R_CullBox(clipmins, clipmaxs) || R_Shadow_ScissorForBBox(clipmins, clipmaxs)) + continue; - // mark the leafs we care about so only things in those leafs will matter - if (cl.worldmodel != NULL) - for (i = 0;i < wl->numleafs;i++) - wl->leafs[i]->worldnodeframe = shadowframecount; + // mark the leafs we care about so only things in those leafs will matter + if (cl.worldmodel != NULL) + for (i = 0;i < wl->numleafs;i++) + wl->leafs[i]->worldnodeframe = shadowframecount; - f = d_lightstylevalue[wl->style] * (1.0f / 256.0f); - VectorScale(wl->light, f, lightcolor); - if (wl->selected) - { - f = 2 + sin(realtime * M_PI * 4.0); - VectorScale(lightcolor, f, lightcolor); - } - - if (wl->castshadows) - { - if (!visiblevolumes) - R_Shadow_Stage_ShadowVolumes(); - ent = &cl_entities[0].render; - if (wl->shadowvolume && r_shadow_staticworldlights.integer) - R_Shadow_DrawWorldLightShadowVolume(&ent->matrix, wl); - else - R_TestAndDrawShadowVolume(ent, wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs); - if (r_drawentities.integer) - for (i = 0;i < r_refdef.numentities;i++) - R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs); - } + f = d_lightstylevalue[wl->style] * (1.0f / 256.0f); + VectorScale(wl->light, f, lightcolor); + if (wl->selected) + { + f = 2 + sin(realtime * M_PI * 4.0); + VectorScale(lightcolor, f, lightcolor); + } - if (!visiblevolumes) - { - if (wl->castshadows) - R_Shadow_Stage_LightWithShadows(); - else - R_Shadow_Stage_LightWithoutShadows(); - - // calculate world to filter matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - - ent = &cl_entities[0].render; - if (ent->model && ent->model->DrawLight) + if (wl->castshadows && (gl_stencil || visiblevolumes)) { - Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - if (wl->numsurfaces) - R_Model_Brush_DrawLightForSurfaceList(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, wl->surfaces, wl->numsurfaces, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + if (!visiblevolumes) + R_Shadow_Stage_ShadowVolumes(); + ent = &cl_entities[0].render; + if (wl->shadowvolume && r_shadow_staticworldlights.integer) + R_Shadow_DrawWorldLightShadowVolume(&ent->matrix, wl); else - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + R_TestAndDrawShadowVolume(ent, wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs, true); + if (r_drawentities.integer) + for (i = 0;i < r_refdef.numentities;i++) + R_TestAndDrawShadowVolume(r_refdef.entities[i], wl->origin, cullradius, lightradius, wl->mins, wl->maxs, clipmins, clipmaxs, true); } - if (r_drawentities.integer) + + if (!visiblevolumes) { - for (i = 0;i < r_refdef.numentities;i++) + if (wl->castshadows && gl_stencil) + R_Shadow_Stage_LightWithShadows(); + else + R_Shadow_Stage_LightWithoutShadows(); + + // calculate world to filter matrix + Matrix4x4_CreateFromQuakeEntity(&matrix, wl->origin[0], wl->origin[1], wl->origin[2], wl->angles[0], wl->angles[1], wl->angles[2], lightradius); + Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); + // calculate world to attenuationxyz/xy matrix + Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); + Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); + // calculate world to attenuationz matrix + matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; + matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; + matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; + matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; + Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); + + ent = &cl_entities[0].render; + if (ent->model && ent->model->DrawLight) { - ent = r_refdef.entities[i]; - if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight - && ent->maxs[0] >= clipmins[0] && ent->mins[0] <= clipmaxs[0] - && ent->maxs[1] >= clipmins[1] && ent->mins[1] <= clipmaxs[1] - && ent->maxs[2] >= clipmins[2] && ent->mins[2] <= clipmaxs[2] - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) - { - Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); + Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); + Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + if (wl->numsurfaces) + R_Model_Brush_DrawLightForSurfaceList(ent, relativelightorigin, relativeeyeorigin, lightradius, lightcolor, wl->surfaces, wl->numsurfaces, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + else ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + } + if (r_drawentities.integer) + { + for (i = 0;i < r_refdef.numentities;i++) + { + ent = r_refdef.entities[i]; + if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight + && ent->maxs[0] >= clipmins[0] && ent->mins[0] <= clipmaxs[0] + && ent->maxs[1] >= clipmins[1] && ent->mins[1] <= clipmaxs[1] + && ent->maxs[2] >= clipmins[2] && ent->mins[2] <= clipmaxs[2] + && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) + { + Matrix4x4_Transform(&ent->inversematrix, wl->origin, relativelightorigin); + Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); + Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + } } } } } } - for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++) + if (r_shadow_realtime_dlight.integer) { - lightradius = rd->cullradius; - clipmins[0] = rd->origin[0] - lightradius; - clipmins[1] = rd->origin[1] - lightradius; - clipmins[2] = rd->origin[2] - lightradius; - clipmaxs[0] = rd->origin[0] + lightradius; - clipmaxs[1] = rd->origin[1] + lightradius; - clipmaxs[2] = rd->origin[2] + lightradius; - if (VIS_CullBox(clipmins, clipmaxs)) - continue; - - //if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, rd->origin, cullradius)) - if (R_Shadow_ScissorForBBox(clipmins, clipmaxs)) - continue; - - if (!visiblevolumes) - R_Shadow_Stage_ShadowVolumes(); - - cullradius = RadiusFromBoundsAndOrigin(clipmins, clipmaxs, rd->origin); - VectorScale(rd->light, (1.0f / 4096.0f), lightcolor); - - ent = &cl_entities[0].render; - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs); - if (r_drawentities.integer) + for (lnum = 0, rd = r_dlight;lnum < r_numdlights;lnum++, rd++) { - for (i = 0;i < r_refdef.numentities;i++) - { - ent = r_refdef.entities[i]; - if (ent != rd->ent) - R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs); - } - } + lightradius = rd->cullradius; + clipmins[0] = rd->origin[0] - lightradius; + clipmins[1] = rd->origin[1] - lightradius; + clipmins[2] = rd->origin[2] - lightradius; + clipmaxs[0] = rd->origin[0] + lightradius; + clipmaxs[1] = rd->origin[1] + lightradius; + clipmaxs[2] = rd->origin[2] + lightradius; + if (VIS_CullBox(clipmins, clipmaxs)) + continue; - if (!visiblevolumes) - { - R_Shadow_Stage_LightWithShadows(); - - // calculate world to filter matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, rd->origin[0], rd->origin[1], rd->origin[2], 0, 0, 0, lightradius); - Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); - // calculate world to attenuationxyz/xy matrix - Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); - Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); - // calculate world to attenuationz matrix - matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; - matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; - matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; - matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; - Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); - - ent = &cl_entities[0].render; - if (ent->model && ent->model->DrawLight) + //if (R_Shadow_ScissorForBBoxAndSphere(clipmins, clipmaxs, rd->origin, cullradius)) + if (R_Shadow_ScissorForBBox(clipmins, clipmaxs)) + continue; + + cullradius = RadiusFromBoundsAndOrigin(clipmins, clipmaxs, rd->origin); + VectorScale(rd->light, (1.0f / 4096.0f), lightcolor); + + if (gl_stencil || visiblevolumes) { - Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + if (!visiblevolumes) + R_Shadow_Stage_ShadowVolumes(); + ent = &cl_entities[0].render; + R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs, false); + if (r_drawentities.integer) + { + for (i = 0;i < r_refdef.numentities;i++) + { + ent = r_refdef.entities[i]; + if (ent != rd->ent) + R_TestAndDrawShadowVolume(ent, rd->origin, cullradius, lightradius, clipmins, clipmaxs, clipmins, clipmaxs, false); + } + } } - if (r_drawentities.integer) + + if (!visiblevolumes) { - for (i = 0;i < r_refdef.numentities;i++) + if (gl_stencil) + R_Shadow_Stage_LightWithShadows(); + else + R_Shadow_Stage_LightWithoutShadows(); + + // calculate world to filter matrix + Matrix4x4_CreateFromQuakeEntity(&matrix, rd->origin[0], rd->origin[1], rd->origin[2], 0, 0, 0, lightradius); + Matrix4x4_Invert_Simple(&matrix_worldtofilter, &matrix); + // calculate world to attenuationxyz/xy matrix + Matrix4x4_CreateFromQuakeEntity(&matrix, 0.5, 0.5, 0.5, 0, 0, 0, 0.5); + Matrix4x4_Concat(&matrix_worldtoattenuationxyz, &matrix, &matrix_worldtofilter); + // calculate world to attenuationz matrix + matrix.m[0][0] = 0;matrix.m[0][1] = 0;matrix.m[0][2] = 0.5;matrix.m[0][3] = 0.5; + matrix.m[1][0] = 0;matrix.m[1][1] = 0;matrix.m[1][2] = 0 ;matrix.m[1][3] = 0.5; + matrix.m[2][0] = 0;matrix.m[2][1] = 0;matrix.m[2][2] = 0 ;matrix.m[2][3] = 0.5; + matrix.m[3][0] = 0;matrix.m[3][1] = 0;matrix.m[3][2] = 0 ;matrix.m[3][3] = 1; + Matrix4x4_Concat(&matrix_worldtoattenuationz, &matrix, &matrix_worldtofilter); + + ent = &cl_entities[0].render; + if (ent->model && ent->model->DrawLight) + { + Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); + Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); + Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + } + if (r_drawentities.integer) { - ent = r_refdef.entities[i]; - if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight - && ent->maxs[0] >= clipmins[0] && ent->mins[0] <= clipmaxs[0] - && ent->maxs[1] >= clipmins[1] && ent->mins[1] <= clipmaxs[1] - && ent->maxs[2] >= clipmins[2] && ent->mins[2] <= clipmaxs[2] - && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) + for (i = 0;i < r_refdef.numentities;i++) { - Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); - Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); - Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); - Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); - ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + ent = r_refdef.entities[i]; + if (ent->visframe == r_framecount && ent->model && ent->model->DrawLight + && ent->maxs[0] >= clipmins[0] && ent->mins[0] <= clipmaxs[0] + && ent->maxs[1] >= clipmins[1] && ent->mins[1] <= clipmaxs[1] + && ent->maxs[2] >= clipmins[2] && ent->mins[2] <= clipmaxs[2] + && !(ent->effects & EF_ADDITIVE) && ent->alpha == 1) + { + Matrix4x4_Transform(&ent->inversematrix, rd->origin, relativelightorigin); + Matrix4x4_Transform(&ent->inversematrix, r_origin, relativeeyeorigin); + Matrix4x4_Concat(&matrix_modeltofilter, &matrix_worldtofilter, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationxyz, &matrix_worldtoattenuationxyz, &ent->matrix); + Matrix4x4_Concat(&matrix_modeltoattenuationz, &matrix_worldtoattenuationz, &ent->matrix); + ent->model->DrawLight(ent, relativelightorigin, relativeeyeorigin, lightradius / ent->scale, lightcolor, &matrix_modeltofilter, &matrix_modeltoattenuationxyz, &matrix_modeltoattenuationz); + } } } } @@ -1155,35 +1167,15 @@ void R_RenderView (void) if (!r_refdef.entities/* || !cl.worldmodel*/) return; //Host_Error ("R_RenderView: NULL worldmodel"); - if (r_shadow_realtime.integer == 1) + if (r_shadow_realtime_world.integer) { -#if 0 - if (!gl_texturecubemap) - { - Con_Printf("Cubemap texture support not detected, turning off r_shadow_realtime\n"); - Cvar_SetValueQuick(&r_shadow_realtime, 0); - } - else if (!gl_dot3arb) - { - Con_Printf("Bumpmapping support not detected, turning off r_shadow_realtime\n"); - Cvar_SetValueQuick(&r_shadow_realtime, 0); - } - else if (!gl_combine.integer) - { - Con_Printf("Combine disabled, please turn on gl_combine, turning off r_shadow_realtime\n"); - Cvar_SetValueQuick(&r_shadow_realtime, 0); - } - else -#endif if (!gl_stencil) { - Con_Printf("Stencil not enabled, turning off r_shadow_realtime, please type vid_stencil 1;vid_bitsperpixel 32;vid_restart and try again\n"); - Cvar_SetValueQuick(&r_shadow_realtime, 0); + Con_Printf("Stencil not enabled, turning off r_shadow_realtime_world, please type vid_stencil 1;vid_bitsperpixel 32;vid_restart and try again\n"); + Cvar_SetValueQuick(&r_shadow_realtime_world, 0); } } - R_Shadow_UpdateLightingMode(); - world = &cl_entities[0].render; // FIXME: move to client @@ -1207,7 +1199,7 @@ void R_RenderView (void) R_TimeReport("markentity"); GL_SetupView_ViewPort(r_refdef.x, r_refdef.y, r_refdef.width, r_refdef.height); - if (r_shadow_lightingmode > 0) + if (r_shadow_realtime_world.integer || gl_stencil) GL_SetupView_Mode_PerspectiveInfiniteFarClip(r_refdef.fov_x, r_refdef.fov_y, 1.0f); else GL_SetupView_Mode_Perspective(r_refdef.fov_x, r_refdef.fov_y, 1.0f, r_farclip); @@ -1230,16 +1222,16 @@ void R_RenderView (void) if (!intimerefresh && !r_speeds.integer) S_ExtraUpdate (); - R_DrawModels(r_shadow_lightingmode > 0); + R_DrawModels(r_shadow_realtime_world.integer); R_TimeReport("models"); - if (r_shadows.integer == 1 && r_shadow_lightingmode <= 0) + if (r_shadows.integer == 1 && !r_shadow_realtime_world.integer) { R_DrawFakeShadows(); R_TimeReport("fakeshadow"); } - if (r_shadow_lightingmode > 0) + if (r_shadow_realtime_world.integer || r_shadow_realtime_dlight.integer) { R_ShadowVolumeLighting(false); R_TimeReport("dynlight"); @@ -1268,11 +1260,13 @@ void R_RenderView (void) R_MeshQueue_Render(); R_MeshQueue_EndScene(); - if (r_shadow_realtime.integer >= 2) + + if (r_shadow_visiblevolumes.integer) { R_ShadowVolumeLighting(true); R_TimeReport("shadowvolume"); } + R_Mesh_Finish(); R_TimeReport("meshfinish"); } diff --git a/gl_rsurf.c b/gl_rsurf.c index 8ace2fa8..ad2b93f3 100644 --- a/gl_rsurf.c +++ b/gl_rsurf.c @@ -1314,7 +1314,7 @@ static void RSurfShader_Wall_Lightmap(const entity_render_t *ent, const texture_ } } } - else if (r_shadow_lightingmode >= 2) + else if (r_shadow_realtime_world.integer) { // opaque base lighting RSurfShader_OpaqueWall_Pass_OpaqueGlow(ent, texture, surfchain); @@ -1425,7 +1425,7 @@ void R_PrepareSurfaces(entity_render_t *ent) R_UpdateTextureInfo(ent); - if (r_dynamic.integer && r_shadow_lightingmode < 1) + if (r_dynamic.integer && !r_shadow_realtime_dlight.integer) R_MarkLights(ent); if (model->light_ambient != r_ambient.value || model->light_scalebit != r_lightmapscalebit) diff --git a/r_light.c b/r_light.c index 2824929d..8de4bdf7 100644 --- a/r_light.c +++ b/r_light.c @@ -647,7 +647,7 @@ void R_ModelLightPoint (const entity_render_t *ent, vec3_t color, const vec3_t p } color[0] = color[1] = color[2] = r_ambient.value * (2.0f / 128.0f); - if (!cl.worldmodel->numlights && r_shadow_lightingmode < 2) + if (!cl.worldmodel->numlights) RecursiveLightPoint (color, cl.worldmodel->nodes, p[0], p[1], p[2], p[2] - 65536); } @@ -676,137 +676,135 @@ void R_LightModel(const entity_render_t *ent, int numverts, float *vertices, flo // make the mscale squared so it can scale the squared distance results mscale = ent->scale * ent->scale; if (r_fullbright.integer || (ent->effects & EF_FULLBRIGHT)) - VectorSet(basecolor, 1, 1, 1); - else if (maxnearlights == 0 && r_shadow_lightingmode < 2) + basecolor[0] = basecolor[1] = basecolor[2] = 1.0f; + else if (r_shadow_realtime_world.integer) + basecolor[0] = basecolor[1] = basecolor[2] = r_ambient.value * (2.0f / 128.0f); + else if (maxnearlights == 0) R_CompleteLightPoint (basecolor, ent->origin, true, NULL); else { R_ModelLightPoint(ent, basecolor, ent->origin); - - if (r_shadow_lightingmode < 2) + nl = &nearlight[0]; + for (i = 0;i < ent->numentlights;i++) { - nl = &nearlight[0]; - for (i = 0;i < ent->numentlights;i++) + sl = cl.worldmodel->lights + ent->entlights[i]; + stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f); + VectorSubtract (ent->origin, sl->origin, v); + f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale; + VectorScale(sl->light, f, ambientcolor); + intensity = DotProduct(ambientcolor, ambientcolor); + if (f < 0) + intensity *= -1.0f; + if (nearlights < maxnearlights) + j = nearlights++; + else { - sl = cl.worldmodel->lights + ent->entlights[i]; - stylescale = d_lightstylevalue[sl->style] * (1.0f / 65536.0f); - VectorSubtract (ent->origin, sl->origin, v); - f = ((1.0f / (DotProduct(v, v) * sl->falloff + sl->distbias)) - sl->subtract) * stylescale; - VectorScale(sl->light, f, ambientcolor); - intensity = DotProduct(ambientcolor, ambientcolor); - if (f < 0) - intensity *= -1.0f; - if (nearlights < maxnearlights) - j = nearlights++; - else + for (j = 0;j < maxnearlights;j++) { - for (j = 0;j < maxnearlights;j++) + if (nearlight[j].intensity < intensity) { - if (nearlight[j].intensity < intensity) - { - if (nearlight[j].intensity > 0) - VectorAdd(basecolor, nearlight[j].ambientlight, basecolor); - break; - } + if (nearlight[j].intensity > 0) + VectorAdd(basecolor, nearlight[j].ambientlight, basecolor); + break; } } - if (j >= maxnearlights) - { - // this light is less significant than all others, - // add it to ambient - if (intensity > 0) - VectorAdd(basecolor, ambientcolor, basecolor); - } + } + if (j >= maxnearlights) + { + // this light is less significant than all others, + // add it to ambient + if (intensity > 0) + VectorAdd(basecolor, ambientcolor, basecolor); + } + else + { + nl = nearlight + j; + nl->intensity = intensity; + // transform the light into the model's coordinate system + if (worldcoords) + VectorCopy(sl->origin, nl->origin); else - { - nl = nearlight + j; - nl->intensity = intensity; - // transform the light into the model's coordinate system - if (worldcoords) - VectorCopy(sl->origin, nl->origin); - else - Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin); - // integrate mscale into falloff, for maximum speed - nl->falloff = sl->falloff * mscale; - VectorCopy(ambientcolor, nl->ambientlight); - nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f; - nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f; - nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f; - nl->subtract = sl->subtract; - nl->offset = sl->distbias; - } + Matrix4x4_Transform(&ent->inversematrix, sl->origin, nl->origin); + // integrate mscale into falloff, for maximum speed + nl->falloff = sl->falloff * mscale; + VectorCopy(ambientcolor, nl->ambientlight); + nl->light[0] = sl->light[0] * stylescale * colorr * 4.0f; + nl->light[1] = sl->light[1] * stylescale * colorg * 4.0f; + nl->light[2] = sl->light[2] * stylescale * colorb * 4.0f; + nl->subtract = sl->subtract; + nl->offset = sl->distbias; } - if (r_shadow_lightingmode < 1) + } + if (!r_shadow_realtime_dlight.integer) + { + for (i = 0;i < r_numdlights;i++) { - for (i = 0;i < r_numdlights;i++) + rd = r_dlight + i; + VectorCopy(rd->origin, v); + if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0]; + if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1]; + if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2]; + VectorSubtract (v, rd->origin, v); + if (DotProduct(v, v) < rd->cullradius2) { - rd = r_dlight + i; - VectorCopy(rd->origin, v); - if (v[0] < ent->mins[0]) v[0] = ent->mins[0];if (v[0] > ent->maxs[0]) v[0] = ent->maxs[0]; - if (v[1] < ent->mins[1]) v[1] = ent->mins[1];if (v[1] > ent->maxs[1]) v[1] = ent->maxs[1]; - if (v[2] < ent->mins[2]) v[2] = ent->mins[2];if (v[2] > ent->maxs[2]) v[2] = ent->maxs[2]; - VectorSubtract (v, rd->origin, v); - if (DotProduct(v, v) < rd->cullradius2) + if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1) + continue; + VectorSubtract (ent->origin, rd->origin, v); + f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract); + VectorScale(rd->light, f, ambientcolor); + intensity = DotProduct(ambientcolor, ambientcolor); + if (f < 0) + intensity *= -1.0f; + if (nearlights < maxnearlights) + j = nearlights++; + else { - if (CL_TraceLine(ent->origin, rd->origin, NULL, NULL, 0, false, NULL) != 1) - continue; - VectorSubtract (ent->origin, rd->origin, v); - f = ((1.0f / (DotProduct(v, v) + LIGHTOFFSET)) - rd->subtract); - VectorScale(rd->light, f, ambientcolor); - intensity = DotProduct(ambientcolor, ambientcolor); - if (f < 0) - intensity *= -1.0f; - if (nearlights < maxnearlights) - j = nearlights++; - else + for (j = 0;j < maxnearlights;j++) { - for (j = 0;j < maxnearlights;j++) + if (nearlight[j].intensity < intensity) { - if (nearlight[j].intensity < intensity) - { - if (nearlight[j].intensity > 0) - VectorAdd(basecolor, nearlight[j].ambientlight, basecolor); - break; - } + if (nearlight[j].intensity > 0) + VectorAdd(basecolor, nearlight[j].ambientlight, basecolor); + break; } } - if (j >= maxnearlights) - { - // this light is less significant than all others, - // add it to ambient - if (intensity > 0) - VectorAdd(basecolor, ambientcolor, basecolor); - } + } + if (j >= maxnearlights) + { + // this light is less significant than all others, + // add it to ambient + if (intensity > 0) + VectorAdd(basecolor, ambientcolor, basecolor); + } + else + { + nl = nearlight + j; + nl->intensity = intensity; + // transform the light into the model's coordinate system + if (worldcoords) + VectorCopy(rd->origin, nl->origin); else { - nl = nearlight + j; - nl->intensity = intensity; - // transform the light into the model's coordinate system - if (worldcoords) - VectorCopy(rd->origin, nl->origin); - else - { - Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin); - /* - Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" - , rd - r_dlight, ent->model->name - , rd->origin[0], rd->origin[1], rd->origin[2] - , nl->origin[0], nl->origin[1], nl->origin[2] - , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3] - , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3] - , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3] - , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]); - */ - } - // integrate mscale into falloff, for maximum speed - nl->falloff = mscale; - VectorCopy(ambientcolor, nl->ambientlight); - nl->light[0] = rd->light[0] * colorr * 4.0f; - nl->light[1] = rd->light[1] * colorg * 4.0f; - nl->light[2] = rd->light[2] * colorb * 4.0f; - nl->subtract = rd->subtract; - nl->offset = LIGHTOFFSET; + Matrix4x4_Transform(&ent->inversematrix, rd->origin, nl->origin); + /* + Con_Printf("%i %s : %f %f %f : %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n%f %f %f %f\n" + , rd - r_dlight, ent->model->name + , rd->origin[0], rd->origin[1], rd->origin[2] + , nl->origin[0], nl->origin[1], nl->origin[2] + , ent->inversematrix.m[0][0], ent->inversematrix.m[0][1], ent->inversematrix.m[0][2], ent->inversematrix.m[0][3] + , ent->inversematrix.m[1][0], ent->inversematrix.m[1][1], ent->inversematrix.m[1][2], ent->inversematrix.m[1][3] + , ent->inversematrix.m[2][0], ent->inversematrix.m[2][1], ent->inversematrix.m[2][2], ent->inversematrix.m[2][3] + , ent->inversematrix.m[3][0], ent->inversematrix.m[3][1], ent->inversematrix.m[3][2], ent->inversematrix.m[3][3]); + */ } + // integrate mscale into falloff, for maximum speed + nl->falloff = mscale; + VectorCopy(ambientcolor, nl->ambientlight); + nl->light[0] = rd->light[0] * colorr * 4.0f; + nl->light[1] = rd->light[1] * colorg * 4.0f; + nl->light[2] = rd->light[2] * colorb * 4.0f; + nl->subtract = rd->subtract; + nl->offset = LIGHTOFFSET; } } } @@ -874,7 +872,7 @@ void R_UpdateEntLights(entity_render_t *ent) int i; const mlight_t *sl; vec3_t v; - if (r_shadow_lightingmode >= 2) + if (r_shadow_realtime_dlight.integer) return; VectorSubtract(ent->origin, ent->entlightsorigin, v); if (ent->entlightsframe != (r_framecount - 1) || (realtime > ent->entlightstime && DotProduct(v,v) >= 1.0f)) diff --git a/r_shadow.c b/r_shadow.c index 59e94363..162f1d9a 100644 --- a/r_shadow.c +++ b/r_shadow.c @@ -14,8 +14,6 @@ extern void R_Shadow_EditLights_Init(void); int r_shadowstage = SHADOWSTAGE_NONE; int r_shadow_reloadlights = false; -int r_shadow_lightingmode = 0; - mempool_t *r_shadow_mempool; int maxshadowelements; @@ -41,7 +39,9 @@ rtexture_t *r_shadow_blankwhitetexture; cvar_t r_shadow_lightattenuationpower = {0, "r_shadow_lightattenuationpower", "0.5"}; cvar_t r_shadow_lightattenuationscale = {0, "r_shadow_lightattenuationscale", "1"}; cvar_t r_shadow_lightintensityscale = {0, "r_shadow_lightintensityscale", "1"}; -cvar_t r_shadow_realtime = {0, "r_shadow_realtime", "0"}; +cvar_t r_shadow_realtime_world = {0, "r_shadow_realtime_world", "0"}; +cvar_t r_shadow_realtime_dlight = {0, "r_shadow_realtime_dlight", "0"}; +cvar_t r_shadow_visiblevolumes = {0, "r_shadow_visiblevolumes", "0"}; cvar_t r_shadow_gloss = {0, "r_shadow_gloss", "1"}; cvar_t r_shadow_debuglight = {0, "r_shadow_debuglight", "-1"}; cvar_t r_shadow_scissor = {0, "r_shadow_scissor", "1"}; @@ -122,7 +122,9 @@ void R_Shadow_Init(void) Cvar_RegisterVariable(&r_shadow_lightattenuationpower); Cvar_RegisterVariable(&r_shadow_lightattenuationscale); Cvar_RegisterVariable(&r_shadow_lightintensityscale); - Cvar_RegisterVariable(&r_shadow_realtime); + Cvar_RegisterVariable(&r_shadow_realtime_world); + Cvar_RegisterVariable(&r_shadow_realtime_dlight); + Cvar_RegisterVariable(&r_shadow_visiblevolumes); Cvar_RegisterVariable(&r_shadow_gloss); Cvar_RegisterVariable(&r_shadow_debuglight); Cvar_RegisterVariable(&r_shadow_scissor); @@ -534,6 +536,21 @@ void R_Shadow_Stage_Begin(void) || r_shadow_lightattenuationpower.value != r_shadow_attenpower || r_shadow_lightattenuationscale.value != r_shadow_attenscale) R_Shadow_MakeTextures(); + + memset(&m, 0, sizeof(m)); + m.blendfunc1 = GL_ONE; + m.blendfunc2 = GL_ZERO; + R_Mesh_State(&m); + GL_Color(0, 0, 0, 1); + r_shadowstage = SHADOWSTAGE_NONE; + + c_rt_lights = c_rt_clears = c_rt_scissored = 0; + c_rt_shadowmeshes = c_rt_shadowtris = c_rt_lightmeshes = c_rt_lighttris = 0; + c_rtcached_shadowmeshes = c_rtcached_shadowtris = 0; +} + +void R_Shadow_LoadWorldLightsIfNeeded(void) +{ if (r_shadow_reloadlights && cl.worldmodel) { R_Shadow_ClearWorldLights(); @@ -546,17 +563,6 @@ void R_Shadow_Stage_Begin(void) R_Shadow_LoadWorldLightsFromMap_LightArghliteTyrlite(); } } - - memset(&m, 0, sizeof(m)); - m.blendfunc1 = GL_ONE; - m.blendfunc2 = GL_ZERO; - R_Mesh_State(&m); - GL_Color(0, 0, 0, 1); - r_shadowstage = SHADOWSTAGE_NONE; - - c_rt_lights = c_rt_clears = c_rt_scissored = 0; - c_rt_shadowmeshes = c_rt_shadowtris = c_rt_lightmeshes = c_rt_lighttris = 0; - c_rtcached_shadowmeshes = c_rtcached_shadowtris = 0; } void R_Shadow_Stage_ShadowVolumes(void) @@ -972,19 +978,28 @@ int R_Shadow_ScissorForBBox(const float *mins, const float *maxs) return false; } -void R_Shadow_VertexLighting(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const float *relativelightorigin, float lightradius) +void R_Shadow_VertexLighting(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const matrix4x4_t *m) { float *color4f = varray_color4f; - float dist, dot, intensity, iradius = 1.0f / lightradius, radius2 = lightradius * lightradius, v[3]; + float dist, dot, intensity, v[3], n[3]; for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4) { - VectorSubtract(vertex3f, relativelightorigin, v); - if ((dot = DotProduct(normal3f, v)) > 0 && (dist = DotProduct(v, v)) < radius2) + Matrix4x4_Transform(m, vertex3f, v); + if ((dist = DotProduct(v, v)) < 1) { - dist = sqrt(dist); - intensity = pow(1 - (dist * iradius), r_shadow_attenpower) * r_shadow_attenscale * dot / dist; - VectorScale(lightcolor, intensity, color4f); - color4f[3] = 1; + Matrix4x4_Transform3x3(m, normal3f, n); + if ((dot = DotProduct(n, v)) > 0) + { + dist = sqrt(dist); + intensity = pow(1 - dist, r_shadow_attenpower) * r_shadow_attenscale * dot / sqrt(DotProduct(n,n)); + VectorScale(lightcolor, intensity, color4f); + color4f[3] = 1; + } + else + { + VectorClear(color4f); + color4f[3] = 1; + } } else { @@ -994,18 +1009,27 @@ void R_Shadow_VertexLighting(int numverts, const float *vertex3f, const float *n } } -void R_Shadow_VertexLightingWithXYAttenuationTexture(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const float *relativelightorigin, float lightradius, const float *zdir) +void R_Shadow_VertexLightingWithXYAttenuationTexture(int numverts, const float *vertex3f, const float *normal3f, const float *lightcolor, const matrix4x4_t *m) { float *color4f = varray_color4f; - float dist, dot, intensity, iradius = 1.0f / lightradius, v[3]; + float dist, dot, intensity, v[3], n[3]; for (;numverts > 0;numverts--, vertex3f += 3, normal3f += 3, color4f += 4) { - VectorSubtract(vertex3f, relativelightorigin, v); - if ((dot = DotProduct(normal3f, v)) > 0 && (dist = fabs(DotProduct(zdir, v))) < lightradius) + Matrix4x4_Transform(m, vertex3f, v); + if ((dist = fabs(v[2])) < 1) { - intensity = pow(1 - (dist * iradius), r_shadow_attenpower) * r_shadow_attenscale * dot / sqrt(DotProduct(v,v)); - VectorScale(lightcolor, intensity, color4f); - color4f[3] = 1; + Matrix4x4_Transform3x3(m, normal3f, n); + if ((dot = DotProduct(n, v)) > 0) + { + intensity = pow(1 - dist, r_shadow_attenpower) * r_shadow_attenscale * dot / sqrt(DotProduct(n,n)); + VectorScale(lightcolor, intensity, color4f); + color4f[3] = 1; + } + else + { + VectorClear(color4f); + color4f[3] = 1; + } } else { @@ -1377,7 +1401,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_CopyVertex3f(vertex3f, numverts); R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); R_Shadow_Transform_Vertex3f_TexCoord2f(varray_texcoord2f[1], numverts, vertex3f, matrix_modeltoattenuationxyz); - R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color2, relativelightorigin, lightradius, matrix_modeltofilter->m[2]); + R_Shadow_VertexLightingWithXYAttenuationTexture(numverts, vertex3f, normal3f, color, relativelightorigin, lightradius, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); } } @@ -1405,8 +1429,7 @@ void R_Shadow_DiffuseLighting(int numverts, int numtriangles, const int *element R_Mesh_GetSpace(numverts); R_Mesh_CopyVertex3f(vertex3f, numverts); R_Mesh_CopyTexCoord2f(0, texcoord2f, numverts); - VectorScale(lightcolor, r_colorscale * r_shadow_lightintensityscale.value, color); - R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, relativelightorigin, lightradius); + R_Shadow_VertexLighting(numverts, vertex3f, normal3f, color, relativelightorigin, lightradius, matrix_modeltofilter); R_Mesh_Draw(numverts, numtriangles, elements); } } @@ -2273,18 +2296,6 @@ void R_Shadow_SetCursorLocationForView(void) r_editlights_cursorlocation[2] = floor(endpos[2] / r_editlights_cursorgrid.value + 0.5f) * r_editlights_cursorgrid.value; } -void R_Shadow_UpdateLightingMode(void) -{ - r_shadow_lightingmode = 0; - if (r_shadow_realtime.integer) - { - if (r_shadow_worldlightchain) - r_shadow_lightingmode = 2; - else - r_shadow_lightingmode = 1; - } -} - void R_Shadow_UpdateWorldLightSelection(void) { R_Shadow_SetCursorLocationForView(); diff --git a/r_shadow.h b/r_shadow.h index ca623469..6df1db9b 100644 --- a/r_shadow.h +++ b/r_shadow.h @@ -4,7 +4,9 @@ extern cvar_t r_shadow_lightattenuationscale; extern cvar_t r_shadow_lightintensityscale; -extern cvar_t r_shadow_realtime; +extern cvar_t r_shadow_realtime_world; +extern cvar_t r_shadow_realtime_dlight; +extern cvar_t r_shadow_visiblevolumes; extern cvar_t r_shadow_gloss; extern cvar_t r_shadow_debuglight; extern cvar_t r_shadow_bumpscale_bumpmap; @@ -21,6 +23,7 @@ float *R_Shadow_VertexBuffer(int numvertices); void R_Shadow_RenderShadowMeshVolume(shadowmesh_t *mesh); void R_Shadow_Stage_Begin(void); +void R_Shadow_LoadWorldLightsIfNeeded(void); void R_Shadow_Stage_ShadowVolumes(void); void R_Shadow_Stage_LightWithShadows(void); void R_Shadow_Stage_LightWithoutShadows(void); @@ -68,10 +71,6 @@ worldlight_t; extern worldlight_t *r_shadow_worldlightchain; -// 0 = normal, 1 = dynamic light shadows, 2 = world and dynamic light shadows -extern int r_shadow_lightingmode; -void R_Shadow_UpdateLightingMode(void); - void R_Shadow_UpdateWorldLightSelection(void); #endif -- 2.39.2