/* ===================== RE_AddLightToScene ===================== */ void RE_AddLightToScene( const vec3_t org, float intensity, float r, float g, float b, int overdraw ) { dlight_t *dl; if ( !tr.registered ) { return; } if ( r_numdlights >= MAX_DLIGHTS ) { return; } if ( intensity <= 0 ) { return; } // these cards don't have the correct blend mode if ( glConfig.hardwareType == GLHW_RIVA128 || glConfig.hardwareType == GLHW_PERMEDIA2 ) { return; } // RF, allow us to force some dlights under all circumstances if ( !( overdraw & REF_FORCE_DLIGHT ) ) { if ( r_dynamiclight->integer == 0 ) { return; } if ( r_dynamiclight->integer == 2 && !( backEndData[tr.smpFrame]->dlights[r_numdlights].forced ) ) { return; } } overdraw &= ~REF_FORCE_DLIGHT; overdraw &= ~REF_JUNIOR_DLIGHT; //----(SA) added dl = &backEndData[tr.smpFrame]->dlights[r_numdlights++]; VectorCopy( org, dl->origin ); dl->radius = intensity; dl->color[0] = r; dl->color[1] = g; dl->color[2] = b; dl->dlshader = NULL; dl->overdraw = 0; if ( overdraw == 10 ) { // sorry, hijacking 10 for a quick hack (SA) dl->dlshader = R_GetShaderByHandle( RE_RegisterShader( "negdlightshader" ) ); } else if ( overdraw == 11 ) { // 11 is flames dl->dlshader = R_GetShaderByHandle( RE_RegisterShader( "flamedlightshader" ) ); } else { dl->overdraw = overdraw; } }
qhandle_t R_GetShaderByNum(int shaderNum, world_t &worldData) { qhandle_t shader; if ( (shaderNum < 0) || (shaderNum >= worldData.numShaders) ) { Com_Printf( "Warning: Bad index for R_GetShaderByNum - %i", shaderNum ); return(0); } shader = RE_RegisterShader(worldData.shaders[ shaderNum ].shader); return(shader); }
void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { #else static void R_SetupEntityLightingGrid( trRefEntity_t *ent ) { #endif vec3_t lightOrigin; int pos[3]; int i, j; float frac[3]; int gridStep[3]; vec3_t direction; float totalFactor; unsigned short *startGridPos; if (r_fullbright->integer || (tr.refdef.rdflags & RDF_doLAGoggles) ) { ent->ambientLight[0] = ent->ambientLight[1] = ent->ambientLight[2] = 255.0; ent->directedLight[0] = ent->directedLight[1] = ent->directedLight[2] = 255.0; VectorCopy( tr.sunDirection, ent->lightDir ); return; } if ( ent->e.renderfx & RF_LIGHTING_ORIGIN ) { // seperate lightOrigins are needed so an object that is // sinking into the ground can still be lit, and so // multi-part models can be lit identically VectorCopy( ent->e.lightingOrigin, lightOrigin ); } else { VectorCopy( ent->e.origin, lightOrigin ); } #define ACCURATE_LIGHTGRID_SAMPLING 1 #if ACCURATE_LIGHTGRID_SAMPLING vec3_t startLightOrigin; VectorCopy( lightOrigin, startLightOrigin ); #endif VectorSubtract( lightOrigin, tr.world->lightGridOrigin, lightOrigin ); for ( i = 0 ; i < 3 ; i++ ) { float v; v = lightOrigin[i]*tr.world->lightGridInverseSize[i]; pos[i] = floor( v ); frac[i] = v - pos[i]; if ( pos[i] < 0 ) { pos[i] = 0; } else if ( pos[i] >= tr.world->lightGridBounds[i] - 1 ) { pos[i] = tr.world->lightGridBounds[i] - 1; } } VectorClear( ent->ambientLight ); VectorClear( ent->directedLight ); VectorClear( direction ); // trilerp the light value gridStep[0] = 1; gridStep[1] = tr.world->lightGridBounds[0]; gridStep[2] = tr.world->lightGridBounds[0] * tr.world->lightGridBounds[1]; startGridPos = tr.world->lightGridArray + pos[0] * gridStep[0] + pos[1] * gridStep[1] + pos[2] * gridStep[2]; #if ACCURATE_LIGHTGRID_SAMPLING vec3_t startGridOrg; VectorCopy( tr.world->lightGridOrigin, startGridOrg ); startGridOrg[0] += pos[0] * tr.world->lightGridSize[0]; startGridOrg[1] += pos[1] * tr.world->lightGridSize[1]; startGridOrg[2] += pos[2] * tr.world->lightGridSize[2]; #endif totalFactor = 0; for ( i = 0 ; i < 8 ; i++ ) { float factor; mgrid_t *data; unsigned short *gridPos; int lat, lng; vec3_t normal; #if ACCURATE_LIGHTGRID_SAMPLING vec3_t gridOrg; VectorCopy( startGridOrg, gridOrg ); #endif factor = 1.0; gridPos = startGridPos; for ( j = 0 ; j < 3 ; j++ ) { if ( i & (1<<j) ) { factor *= frac[j]; gridPos += gridStep[j]; #if ACCURATE_LIGHTGRID_SAMPLING gridOrg[j] += tr.world->lightGridSize[j]; #endif } else { factor *= (1.0 - frac[j]); } } if (gridPos >= tr.world->lightGridArray + tr.world->numGridArrayElements) {//we've gone off the array somehow continue; } data = tr.world->lightGridData + *gridPos; if ( data->styles[0] == LS_NONE ) { continue; // ignore samples in walls } #if 0 if ( !SV_inPVS( startLightOrigin, gridOrg ) ) { continue; } #endif totalFactor += factor; for(j=0;j<MAXLIGHTMAPS;j++) { if (data->styles[j] != LS_NONE) { const byte style= data->styles[j]; ent->ambientLight[0] += factor * data->ambientLight[j][0] * styleColors[style][0] / 255.0f; ent->ambientLight[1] += factor * data->ambientLight[j][1] * styleColors[style][1] / 255.0f; ent->ambientLight[2] += factor * data->ambientLight[j][2] * styleColors[style][2] / 255.0f; ent->directedLight[0] += factor * data->directLight[j][0] * styleColors[style][0] / 255.0f; ent->directedLight[1] += factor * data->directLight[j][1] * styleColors[style][1] / 255.0f; ent->directedLight[2] += factor * data->directLight[j][2] * styleColors[style][2] / 255.0f; } else { break; } } lat = data->latLong[1]; lng = data->latLong[0]; lat *= (FUNCTABLE_SIZE/256); lng *= (FUNCTABLE_SIZE/256); // decode X as cos( lat ) * sin( long ) // decode Y as sin( lat ) * sin( long ) // decode Z as cos( long ) normal[0] = tr.sinTable[(lat+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK] * tr.sinTable[lng]; normal[1] = tr.sinTable[lat] * tr.sinTable[lng]; normal[2] = tr.sinTable[(lng+(FUNCTABLE_SIZE/4))&FUNCTABLE_MASK]; VectorMA( direction, factor, normal, direction ); #if ACCURATE_LIGHTGRID_SAMPLING if ( r_debugLight->integer && ent->e.hModel == -1 ) { //draw refEntity_t refEnt; refEnt.hModel = 0; refEnt.ghoul2 = NULL; refEnt.renderfx = 0; VectorCopy( gridOrg, refEnt.origin ); vectoangles( normal, refEnt.angles ); AnglesToAxis( refEnt.angles, refEnt.axis ); refEnt.reType = RT_MODEL; RE_AddRefEntityToScene( &refEnt ); refEnt.renderfx = RF_DEPTHHACK; refEnt.reType = RT_SPRITE; refEnt.customShader = RE_RegisterShader( "gfx/misc/debugAmbient" ); refEnt.shaderRGBA[0] = data->ambientLight[0][0]; refEnt.shaderRGBA[1] = data->ambientLight[0][1]; refEnt.shaderRGBA[2] = data->ambientLight[0][2]; refEnt.shaderRGBA[3] = 255; refEnt.radius = factor*50+2.0f; // maybe always give it a minimum size? refEnt.rotation = 0; // don't let the sprite wobble around RE_AddRefEntityToScene( &refEnt ); refEnt.reType = RT_LINE; refEnt.customShader = RE_RegisterShader( "gfx/misc/debugArrow" ); refEnt.shaderRGBA[0] = data->directLight[0][0]; refEnt.shaderRGBA[1] = data->directLight[0][1]; refEnt.shaderRGBA[2] = data->directLight[0][2]; refEnt.shaderRGBA[3] = 255; VectorCopy( refEnt.origin, refEnt.oldorigin ); VectorMA( gridOrg, (factor*-255) - 2.0f, normal, refEnt.origin ); // maybe always give it a minimum length refEnt.radius = 1.5f; RE_AddRefEntityToScene( &refEnt ); } #endif } if ( totalFactor > 0 && totalFactor < 0.99 ) { totalFactor = 1.0 / totalFactor; VectorScale( ent->ambientLight, totalFactor, ent->ambientLight ); VectorScale( ent->directedLight, totalFactor, ent->directedLight ); } VectorScale( ent->ambientLight, r_ambientScale->value, ent->ambientLight ); VectorScale( ent->directedLight, r_directedScale->value, ent->directedLight ); VectorNormalize2( direction, ent->lightDir ); }