/* ================= R_CreateLightRefs ================= */ void R_CreateLightRefs( idRenderLightLocal* light ) { // derive light data R_DeriveLightData( light ); // determine the areaNum for the light origin, which may let us // cull the light if it is behind a closed door // it is debatable if we want to use the entity origin or the center offset origin, // but we definitely don't want to use a parallel offset origin light->areaNum = light->world->PointInArea( light->globalLightOrigin ); if( light->areaNum == -1 ) { light->areaNum = light->world->PointInArea( light->parms.origin ); } // bump the view count so we can tell if an // area already has a reference tr.viewCount++; // if we have a prelight model that includes all the shadows for the major world occluders, // we can limit the area references to those visible through the portals from the light center. // We can't do this in the normal case, because shadows are cast from back facing triangles, which // may be in areas not directly visible to the light projection center. if( light->parms.prelightModel != NULL && r_useLightPortalFlow.GetBool() && light->lightShader->LightCastsShadows() ) { light->world->FlowLightThroughPortals( light ); } else { // push the light frustum down the BSP tree into areas light->world->PushFrustumIntoTree( NULL, light, light->inverseBaseLightProject, bounds_zeroOneCube ); } R_CreateLightDefFogPortals( light ); }
/* ============== CreateMapLight ============== */ static void CreateMapLight( const idMapEntity *mapEnt ) { mapLight_t *light; bool dynamic; // designers can add the "noPrelight" flag to signal that // the lights will move around, so we don't want // to bother chopping up the surfaces under it or creating // shadow volumes mapEnt->epairs.GetBool( "noPrelight", "0", dynamic ); if( dynamic ) { return; } light = new mapLight_t; light->name[0] = '\0'; light->shadowTris = NULL; // parse parms exactly as the game do // use the game's epair parsing code so // we can use the same renderLight generation gameEdit->ParseSpawnArgsToRenderLight( &mapEnt->epairs, &light->def.parms ); R_DeriveLightData( &light->def ); // get the name for naming the shadow surfaces const char *name; mapEnt->epairs.GetString( "name", "", &name ); idStr::Copynz( light->name, name, sizeof( light->name ) ); if( !light->name[0] ) { common->Error( "Light at (%f,%f,%f) didn't have a name", light->def.parms.origin[0], light->def.parms.origin[1], light->def.parms.origin[2] ); } #if 0 // use the renderer code to get the bounding planes for the light // based on all the parameters R_RenderLightFrustum( light->parms, light->frustum ); light->lightShader = light->parms.shader; #endif dmapGlobals.mapLights.Append( light ); }
/* =============== R_RenderLightFrustum Called by the editor and dmap to operate on light volumes =============== */ void R_RenderLightFrustum( const renderLight_t &renderLight, idPlane lightFrustum[6] ) { idRenderLightLocal fakeLight; memset( &fakeLight, 0, sizeof( fakeLight ) ); fakeLight.parms = renderLight; R_DeriveLightData( &fakeLight ); }
// RB begin void R_RenderLightFrustum( const renderLight_t& renderLight, idPlane lightFrustum[6] ) { idRenderLightLocal fakeLight; fakeLight.parms = renderLight; R_DeriveLightData( &fakeLight ); idRenderMatrix::GetFrustumPlanes( lightFrustum, fakeLight.baseLightProject, true, true ); // the DOOM 3 frustum planes point outside the frustum for( int i = 0; i < 6; i++ ) { lightFrustum[i] = -lightFrustum[i]; } }