#include "light.h"
Include dependency graph for light.c:

Go to the source code of this file.
|
|
|
|
|
Definition at line 1590 of file light.c. Referenced by TraceGrid(). |
|
|
|
|
|
|
|
|
|
|
|
|
|
||||||||||||
|
Definition at line 1167 of file light.c. References byte, max, vec3_t, VectorCopy, and VectorScale. Referenced by TraceGrid(), TraceLtm(), VL_StoreLightmap(), and VS_StoreLightmap(). 01167 {
01168 float max;
01169 vec3_t sample;
01170
01171 VectorCopy( color, sample );
01172
01173 // clamp with color normalization
01174 max = sample[0];
01175 if ( sample[1] > max ) {
01176 max = sample[1];
01177 }
01178 if ( sample[2] > max ) {
01179 max = sample[2];
01180 }
01181 if ( max > 255 ) {
01182 VectorScale( sample, 255/max, sample );
01183 }
01184 colorBytes[ 0 ] = sample[0];
01185 colorBytes[ 1 ] = sample[1];
01186 colorBytes[ 2 ] = sample[2];
01187 }
|
|
|
Definition at line 225 of file light.c. References count, drawSurfaces, Error(), i, LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapNum, numDrawSurfaces, numLightBytes, and qprintf(). Referenced by LightMain(), VLightMain(), and VSoundMain(). 00225 {
00226 int count;
00227 int i;
00228 dsurface_t *ds;
00229
00230 qprintf ("--- CountLightmaps ---\n");
00231 count = 0;
00232 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
00233 // see if this surface is light emiting
00234 ds = &drawSurfaces[i];
00235 if ( ds->lightmapNum > count ) {
00236 count = ds->lightmapNum;
00237 }
00238 }
00239
00240 count++;
00241 numLightBytes = count * LIGHTMAP_WIDTH * LIGHTMAP_HEIGHT * 3;
00242 if ( numLightBytes > MAX_MAP_LIGHTING ) {
00243 Error("MAX_MAP_LIGHTING exceeded");
00244 }
00245
00246 qprintf( "%5i drawSurfaces\n", numDrawSurfaces );
00247 qprintf( "%5i lightmaps\n", count );
00248 }
|
Here is the call graph for this function:

|
|
Definition at line 464 of file light.c. References _printf(), light_s::color, ColorNormalize(), e, entities, FindTargetEntity(), FloatForKey(), GetVectorForKey(), i, light_t, lights, light_s::linearLight, malloc(), memset(), name, light_s::next, numPointLights, entity_t::origin, light_s::photons, sscanf(), strncmp(), light_s::style, light_s::type, ValueForKey(), vec3_t, VectorNormalize(), and VectorSubtract. Referenced by GridAndVertexLighting(), and LightWorld(). 00465 {
00466 int i;
00467 light_t *dl;
00468 entity_t *e, *e2;
00469 const char *name;
00470 const char *target;
00471 vec3_t dest;
00472 const char *_color;
00473 float intensity;
00474 int spawnflags;
00475
00476 //
00477 // entities
00478 //
00479 for ( i = 0 ; i < num_entities ; i++ ) {
00480 e = &entities[i];
00481 name = ValueForKey (e, "classname");
00482 if (strncmp (name, "light", 5))
00483 continue;
00484
00485 numPointLights++;
00486 dl = malloc(sizeof(*dl));
00487 memset (dl, 0, sizeof(*dl));
00488 dl->next = lights;
00489 lights = dl;
00490
00491 spawnflags = FloatForKey (e, "spawnflags");
00492 if ( spawnflags & 1 ) {
00493 dl->linearLight = qtrue;
00494 }
00495
00496 GetVectorForKey (e, "origin", dl->origin);
00497 dl->style = FloatForKey (e, "_style");
00498 if (!dl->style)
00499 dl->style = FloatForKey (e, "style");
00500 if (dl->style < 0)
00501 dl->style = 0;
00502
00503 intensity = FloatForKey (e, "light");
00504 if (!intensity)
00505 intensity = FloatForKey (e, "_light");
00506 if (!intensity)
00507 intensity = 300;
00508 _color = ValueForKey (e, "_color");
00509 if (_color && _color[0])
00510 {
00511 sscanf (_color, "%f %f %f", &dl->color[0],&dl->color[1],&dl->color[2]);
00512 ColorNormalize (dl->color, dl->color);
00513 }
00514 else
00515 dl->color[0] = dl->color[1] = dl->color[2] = 1.0;
00516
00517 intensity = intensity * pointScale;
00518 dl->photons = intensity;
00519
00520 dl->type = emit_point;
00521
00522 // lights with a target will be spotlights
00523 target = ValueForKey (e, "target");
00524
00525 if ( target[0] ) {
00526 float radius;
00527 float dist;
00528
00529 e2 = FindTargetEntity (target);
00530 if (!e2) {
00531 _printf ("WARNING: light at (%i %i %i) has missing target\n",
00532 (int)dl->origin[0], (int)dl->origin[1], (int)dl->origin[2]);
00533 } else {
00534 GetVectorForKey (e2, "origin", dest);
00535 VectorSubtract (dest, dl->origin, dl->normal);
00536 dist = VectorNormalize (dl->normal, dl->normal);
00537 radius = FloatForKey (e, "radius");
00538 if ( !radius ) {
00539 radius = 64;
00540 }
00541 if ( !dist ) {
00542 dist = 64;
00543 }
00544 dl->radiusByDist = (radius + 16) / dist;
00545 dl->type = emit_spotlight;
00546 }
00547 }
00548 }
00549 }
|
Here is the call graph for this function:

|
|
Definition at line 1845 of file light.c. References _printf(), CrossProduct(), d, DotProduct, drawSurfaces, drawVerts, dshaders, Error(), f, fabs(), filters, dsurface_t::firstVert, i, numFilters, dsurface_t::numVerts, filter_t::origin, dsurface_t::patchHeight, dsurface_t::patchWidth, filter_t::plane, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, filter_t::si, v1, v2, vec3_t, VectorNormalize(), filter_t::vectors, VectorSubtract, and drawVert_t::xyz. Referenced by GridAndVertexLighting(), and LightMain(). 01845 {
01846 int i;
01847 filter_t *f;
01848 dsurface_t *ds;
01849 shaderInfo_t *si;
01850 drawVert_t *v1, *v2, *v3;
01851 vec3_t d1, d2;
01852 int vertNum;
01853
01854 numFilters = 0;
01855
01856 return;
01857
01858 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
01859 ds = &drawSurfaces[i];
01860 if ( !ds->patchWidth ) {
01861 continue;
01862 }
01863 si = ShaderInfoForShader( dshaders[ ds->shaderNum ].shader );
01864 /*
01865 if ( !(si->surfaceFlags & SURF_LIGHTFILTER) ) {
01866 continue;
01867 }
01868 */
01869
01870 // we have a filter patch
01871 v1 = &drawVerts[ ds->firstVert ];
01872
01873 if ( ds->patchWidth != 3 || ds->patchHeight != 3 ) {
01874 _printf("WARNING: patch at %i %i %i has SURF_LIGHTFILTER but isn't a 3 by 3\n",
01875 v1->xyz[0], v1->xyz[1], v1->xyz[2] );
01876 continue;
01877 }
01878
01879 if ( numFilters == MAX_FILTERS ) {
01880 Error( "MAX_FILTERS" );
01881 }
01882 f = &filters[ numFilters ];
01883 numFilters++;
01884
01885 v2 = &drawVerts[ ds->firstVert + 2 ];
01886 v3 = &drawVerts[ ds->firstVert + 6 ];
01887
01888 VectorSubtract( v2->xyz, v1->xyz, d1 );
01889 VectorSubtract( v3->xyz, v1->xyz, d2 );
01890 VectorNormalize( d1, d1 );
01891 VectorNormalize( d2, d2 );
01892 CrossProduct( d1, d2, f->plane );
01893 f->plane[3] = DotProduct( v1->xyz, f->plane );
01894
01895 // make sure all the control points are on the plane
01896 for ( vertNum = 0 ; vertNum < ds->numVerts ; vertNum++ ) {
01897 float d;
01898
01899 d = DotProduct( drawVerts[ ds->firstVert + vertNum ].xyz, f->plane ) - f->plane[3];
01900 if ( fabs( d ) > PLANAR_PATCH_EPSILON ) {
01901 break;
01902 }
01903 }
01904 if ( vertNum != ds->numVerts ) {
01905 numFilters--;
01906 _printf("WARNING: patch at %i %i %i has SURF_LIGHTFILTER but isn't flat\n",
01907 v1->xyz[0], v1->xyz[1], v1->xyz[2] );
01908 continue;
01909 }
01910 }
01911
01912 f = &filters[0];
01913 numFilters = 1;
01914
01915 f->plane[0] = 1;
01916 f->plane[1] = 0;
01917 f->plane[2] = 0;
01918 f->plane[3] = 448;
01919
01920 f->origin[0] = 448;
01921 f->origin[1] = 192;
01922 f->origin[2] = 0;
01923
01924 f->vectors[0][0] = 0;
01925 f->vectors[0][1] = -1.0 / 128;
01926 f->vectors[0][2] = 0;
01927
01928 f->vectors[1][0] = 0;
01929 f->vectors[1][1] = 0;
01930 f->vectors[1][2] = 1.0 / 128;
01931
01932 f->si = ShaderInfoForShader( "textures/hell/blocks11ct" );
01933 }
|
Here is the call graph for this function:

|
|
Definition at line 257 of file light.c. References _printf(), AllocWinding(), shaderInfo_s::autosprite, cFacet_t, shaderInfo_s::color, drawSurfaces, drawVerts, dshaders, f, surfaceTest_t::facets, dsurface_t::firstVert, FreeWinding(), i, j, light_t, dsurface_t::lightmapVecs, lights, shaderInfo_s::lightSubdivide, malloc(), memcpy(), memset(), light_s::next, cFacet_s::numBoundaries, surfaceTest_t::numFacets, numPointLights, winding_t::numpoints, dsurface_t::numVerts, winding_t::p, light_s::photons, cFacet_s::points, qprintf(), qtrue, ReverseWinding(), shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, SubdivideAreaLight(), cFacet_s::surface, surfaceTest, t, shaderInfo_s::twoSided, shaderInfo_s::value, vec3_origin, vec3_t, VectorAdd, VectorCopy, VectorScale, VectorSubtract, w, and drawVert_t::xyz. Referenced by GridAndVertexLighting(), and LightMain(). 00257 {
00258 int i, j, side;
00259 dsurface_t *ds;
00260 shaderInfo_t *ls;
00261 winding_t *w;
00262 cFacet_t *f;
00263 light_t *dl;
00264 vec3_t origin;
00265 drawVert_t *dv;
00266 int c_lightSurfaces;
00267 float lightSubdivide;
00268 vec3_t normal;
00269
00270 qprintf ("--- CreateSurfaceLights ---\n");
00271 c_lightSurfaces = 0;
00272
00273 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
00274 // see if this surface is light emiting
00275 ds = &drawSurfaces[i];
00276
00277 ls = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
00278 if ( ls->value == 0 ) {
00279 continue;
00280 }
00281
00282 // determine how much we need to chop up the surface
00283 if ( ls->lightSubdivide ) {
00284 lightSubdivide = ls->lightSubdivide;
00285 } else {
00286 lightSubdivide = defaultLightSubdivide;
00287 }
00288
00289 c_lightSurfaces++;
00290
00291 // an autosprite shader will become
00292 // a point light instead of an area light
00293 if ( ls->autosprite ) {
00294 // autosprite geometry should only have four vertexes
00295 if ( surfaceTest[i] ) {
00296 // curve or misc_model
00297 f = surfaceTest[i]->facets;
00298 if ( surfaceTest[i]->numFacets != 1 || f->numBoundaries != 4 ) {
00299 _printf( "WARNING: surface at (%i %i %i) has autosprite shader but isn't a quad\n",
00300 (int)f->points[0], (int)f->points[1], (int)f->points[2] );
00301 }
00302 VectorAdd( f->points[0], f->points[1], origin );
00303 VectorAdd( f->points[2], origin, origin );
00304 VectorAdd( f->points[3], origin, origin );
00305 VectorScale( origin, 0.25, origin );
00306 } else {
00307 // normal polygon
00308 dv = &drawVerts[ ds->firstVert ];
00309 if ( ds->numVerts != 4 ) {
00310 _printf( "WARNING: surface at (%i %i %i) has autosprite shader but %i verts\n",
00311 (int)dv->xyz[0], (int)dv->xyz[1], (int)dv->xyz[2] );
00312 continue;
00313 }
00314
00315 VectorAdd( dv[0].xyz, dv[1].xyz, origin );
00316 VectorAdd( dv[2].xyz, origin, origin );
00317 VectorAdd( dv[3].xyz, origin, origin );
00318 VectorScale( origin, 0.25, origin );
00319 }
00320
00321
00322 numPointLights++;
00323 dl = malloc(sizeof(*dl));
00324 memset (dl, 0, sizeof(*dl));
00325 dl->next = lights;
00326 lights = dl;
00327
00328 VectorCopy( origin, dl->origin );
00329 VectorCopy( ls->color, dl->color );
00330 dl->photons = ls->value * pointScale;
00331 dl->type = emit_point;
00332 continue;
00333 }
00334
00335 // possibly create for both sides of the polygon
00336 for ( side = 0 ; side <= ls->twoSided ; side++ ) {
00337 // create area lights
00338 if ( surfaceTest[i] ) {
00339 // curve or misc_model
00340 for ( j = 0 ; j < surfaceTest[i]->numFacets ; j++ ) {
00341 f = surfaceTest[i]->facets + j;
00342 w = AllocWinding( f->numBoundaries );
00343 w->numpoints = f->numBoundaries;
00344 memcpy( w->p, f->points, f->numBoundaries * 12 );
00345
00346 VectorCopy( f->surface, normal );
00347 if ( side ) {
00348 winding_t *t;
00349
00350 t = w;
00351 w = ReverseWinding( t );
00352 FreeWinding( t );
00353 VectorSubtract( vec3_origin, normal, normal );
00354 }
00355 SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
00356 }
00357 } else {
00358 // normal polygon
00359
00360 w = AllocWinding( ds->numVerts );
00361 w->numpoints = ds->numVerts;
00362 for ( j = 0 ; j < ds->numVerts ; j++ ) {
00363 VectorCopy( drawVerts[ds->firstVert+j].xyz, w->p[j] );
00364 }
00365 VectorCopy( ds->lightmapVecs[2], normal );
00366 if ( side ) {
00367 winding_t *t;
00368
00369 t = w;
00370 w = ReverseWinding( t );
00371 FreeWinding( t );
00372 VectorSubtract( vec3_origin, normal, normal );
00373 }
00374 SubdivideAreaLight( ls, w, normal, lightSubdivide, qtrue );
00375 }
00376 }
00377 }
00378
00379 _printf( "%5i light emitting surfaces\n", c_lightSurfaces );
00380 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 671 of file light.c. References byte, DotProduct, f, filters, shaderInfo_s::height, i, filter_t::origin, shaderInfo_s::pixels, filter_t::plane, point, s, filter_t::si, t, v, vec3_t, VectorClear, VectorLength(), filter_t::vectors, VectorSubtract, shaderInfo_s::width, x, and y. 00671 {
00672 float d1, d2;
00673 filter_t *f;
00674 int filterNum;
00675 vec3_t point;
00676 float frac;
00677 int i;
00678 float s, t;
00679 int u, v;
00680 int x, y;
00681 byte *pixel;
00682 float radius;
00683 float len;
00684 vec3_t total;
00685
00686 filter[0] = 1.0;
00687 filter[1] = 1.0;
00688 filter[2] = 1.0;
00689
00690 for ( filterNum = 0 ; filterNum < numFilters ; filterNum++ ) {
00691 f = &filters[ filterNum ];
00692
00693 // see if the plane is crossed
00694 d1 = DotProduct( start, f->plane ) - f->plane[3];
00695 d2 = DotProduct( end, f->plane ) - f->plane[3];
00696
00697 if ( ( d1 < 0 ) == ( d2 < 0 ) ) {
00698 continue;
00699 }
00700
00701 // calculate the crossing point
00702 frac = d1 / ( d1 - d2 );
00703
00704 for ( i = 0 ; i < 3 ; i++ ) {
00705 point[i] = start[i] + frac * ( end[i] - start[i] );
00706 }
00707
00708 VectorSubtract( point, f->origin, point );
00709
00710 s = DotProduct( point, f->vectors[0] );
00711 t = 1.0 - DotProduct( point, f->vectors[1] );
00712 if ( s < 0 || s >= 1.0 || t < 0 || t >= 1.0 ) {
00713 continue;
00714 }
00715
00716 // decide the filter size
00717 radius = 10 * frac;
00718 len = VectorLength( f->vectors[0] );
00719 if ( !len ) {
00720 continue;
00721 }
00722 radius = radius * len * f->si->width;
00723
00724 // look up the filter, taking multiple samples
00725 VectorClear( total );
00726 for ( u = -1 ; u <= 1 ; u++ ) {
00727 for ( v = -1 ; v <=1 ; v++ ) {
00728 x = s * f->si->width + u * radius;
00729 if ( x < 0 ) {
00730 x = 0;
00731 }
00732 if ( x >= f->si->width ) {
00733 x = f->si->width - 1;
00734 }
00735 y = t * f->si->height + v * radius;
00736 if ( y < 0 ) {
00737 y = 0;
00738 }
00739 if ( y >= f->si->height ) {
00740 y = f->si->height - 1;
00741 }
00742
00743 pixel = f->si->pixels + ( y * f->si->width + x ) * 4;
00744 total[0] += pixel[0];
00745 total[1] += pixel[1];
00746 total[2] += pixel[2];
00747 }
00748 }
00749
00750 filter[0] *= total[0]/(255.0*9);
00751 filter[1] *= total[1]/(255.0*9);
00752 filter[2] *= total[2]/(255.0*9);
00753 }
00754
00755 }
|
Here is the call graph for this function:

|
|
Definition at line 389 of file light.c. References skyBrush_t::b, b, skyBrush_t::bounds, dbrushes, dbrushsides, dplane_t::dist, dplanes, drawSurfaces, dshaders, dbrush_t::firstSide, i, j, dbrush_t::numSides, numSkyBrushes, dbrushside_t::planeNum, s, shaderInfo_t, ShaderInfoForShader(), dbrushside_t::shaderNum, skyBrushes, shaderInfo_s::sunDirection, sunDirection, sunLight, shaderInfo_s::sunLight, shaderInfo_s::surfaceFlags, dshader_t::surfaceFlags, VectorCopy, and VectorNormalize(). Referenced by GridAndVertexLighting(), and LightMain(). 00389 {
00390 int i, j;
00391 dbrush_t *b;
00392 skyBrush_t *sb;
00393 shaderInfo_t *si;
00394 dbrushside_t *s;
00395
00396 // find the brushes
00397 for ( i = 0 ; i < numbrushes ; i++ ) {
00398 b = &dbrushes[i];
00399 for ( j = 0 ; j < b->numSides ; j++ ) {
00400 s = &dbrushsides[ b->firstSide + j ];
00401 if ( dshaders[ s->shaderNum ].surfaceFlags & SURF_SKY ) {
00402 sb = &skyBrushes[ numSkyBrushes ];
00403 sb->b = b;
00404 sb->bounds[0][0] = -dplanes[ dbrushsides[ b->firstSide + 0 ].planeNum ].dist - 1;
00405 sb->bounds[1][0] = dplanes[ dbrushsides[ b->firstSide + 1 ].planeNum ].dist + 1;
00406 sb->bounds[0][1] = -dplanes[ dbrushsides[ b->firstSide + 2 ].planeNum ].dist - 1;
00407 sb->bounds[1][1] = dplanes[ dbrushsides[ b->firstSide + 3 ].planeNum ].dist + 1;
00408 sb->bounds[0][2] = -dplanes[ dbrushsides[ b->firstSide + 4 ].planeNum ].dist - 1;
00409 sb->bounds[1][2] = dplanes[ dbrushsides[ b->firstSide + 5 ].planeNum ].dist + 1;
00410 numSkyBrushes++;
00411 break;
00412 }
00413 }
00414 }
00415
00416 // default
00417 VectorNormalize( sunDirection, sunDirection );
00418
00419 // find the sky shader
00420 for ( i = 0 ; i < numDrawSurfaces ; i++ ) {
00421 si = ShaderInfoForShader( dshaders[ drawSurfaces[i].shaderNum ].shader );
00422 if ( si->surfaceFlags & SURF_SKY ) {
00423 VectorCopy( si->sunLight, sunLight );
00424 VectorCopy( si->sunDirection, sunDirection );
00425 break;
00426 }
00427 }
00428 }
|
Here is the call graph for this function:

|
|
Definition at line 443 of file light.c. References entities, i, n, strcmp(), and ValueForKey(). Referenced by CreateEntityLights(), VL_CreateEntityLights(), and VS_CreateEntitySpeakers(). 00443 {
00444 int i;
00445 const char *n;
00446
00447 for ( i = 0 ; i < num_entities ; i++ ) {
00448 n = ValueForKey (&entities[i], "targetname");
00449 if ( !strcmp (n, target) ) {
00450 return &entities[i];
00451 }
00452 }
00453
00454 return NULL;
00455 }
|
Here is the call graph for this function:

|
|
Definition at line 1989 of file light.c. References _printf(), CreateEntityLights(), CreateFilters(), CreateSurfaceLights(), FindSkyBrushes(), InitTrace(), numDrawSurfaces, numGridPoints, qtrue, RunThreadsOnIndividual(), SetupGrid(), TraceGrid(), TriSoupLightingThread(), and VertexLightingThread(). Referenced by VLightMain(), and VSoundMain(). 01989 {
01990 SetupGrid();
01991
01992 FindSkyBrushes();
01993 CreateFilters();
01994 InitTrace();
01995 CreateEntityLights ();
01996 CreateSurfaceLights();
01997
01998 if (!nogridlighting) {
01999 _printf ("--- TraceGrid ---\n");
02000 RunThreadsOnIndividual( numGridPoints, qtrue, TraceGrid );
02001 }
02002
02003 if (!novertexlighting) {
02004 _printf ("--- Vertex Lighting ---\n");
02005 RunThreadsOnIndividual( numDrawSurfaces, qtrue, VertexLightingThread );
02006 }
02007
02008 _printf("--- Model Lighting ---\n");
02009 RunThreadsOnIndividual( numDrawSurfaces, qtrue, TriSoupLightingThread );
02010 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 1487 of file light.c. References add, light_s::color, d, light_s::dist, DotProduct, emit_point, light_s::emitColor, exactPointToPolygon, light_t, light_s::linearLight, linearScale, light_s::normal, light_s::origin, trace_t::passSolid, light_s::photons, PointToPolygonFormFactor(), qboolean, qfalse, TraceLine(), light_s::twosided, light_s::type, vec3_t, VectorClear, VectorLength(), VectorNormalize(), VectorScale, VectorSubtract, and light_s::w. Referenced by TraceGrid(). 01488 {
01489 trace_t trace;
01490 float add;
01491
01492 add = 0;
01493
01494 VectorClear( color );
01495
01496 // testing exact PTPFF
01497 if ( exactPointToPolygon && light->type == emit_area ) {
01498 float factor;
01499 float d;
01500 vec3_t normal;
01501
01502 // see if the point is behind the light
01503 d = DotProduct( origin, light->normal ) - light->dist;
01504 if ( !light->twosided ) {
01505 if ( d < 1 ) {
01506 return qfalse; // point is behind light
01507 }
01508 }
01509
01510 // test occlusion
01511 // clip the line, tracing from the surface towards the light
01512 TraceLine( origin, light->origin, &trace, qfalse, tw );
01513 if ( trace.passSolid ) {
01514 return qfalse;
01515 }
01516
01517 // calculate the contribution
01518 VectorSubtract( light->origin, origin, normal );
01519 if ( VectorNormalize( normal, normal ) == 0 ) {
01520 return qfalse;
01521 }
01522 factor = PointToPolygonFormFactor( origin, normal, light->w );
01523 if ( factor <= 0 ) {
01524 if ( light->twosided ) {
01525 factor = -factor;
01526 } else {
01527 return qfalse;
01528 }
01529 }
01530 VectorScale( light->emitColor, factor, color );
01531 return qtrue;
01532 }
01533
01534 // calculate the amount of light at this sample
01535 if ( light->type == emit_point || light->type == emit_spotlight ) {
01536 vec3_t dir;
01537 float dist;
01538
01539 VectorSubtract( light->origin, origin, dir );
01540 dist = VectorLength( dir );
01541 // clamp the distance to prevent super hot spots
01542 if ( dist < 16 ) {
01543 dist = 16;
01544 }
01545 if ( light->linearLight ) {
01546 add = light->photons * linearScale - dist;
01547 if ( add < 0 ) {
01548 add = 0;
01549 }
01550 } else {
01551 add = light->photons / ( dist * dist );
01552 }
01553 } else {
01554 return qfalse;
01555 }
01556
01557 if ( add <= 1.0 ) {
01558 return qfalse;
01559 }
01560
01561 // clip the line, tracing from the surface towards the light
01562 TraceLine( origin, light->origin, &trace, qfalse, tw );
01563
01564 // other light rays must not hit anything
01565 if ( trace.passSolid ) {
01566 return qfalse;
01567 }
01568
01569 // add the result
01570 color[0] = add * light->color[0];
01571 color[1] = add * light->color[1];
01572 color[2] = add * light->color[2];
01573
01574 return qtrue;
01575 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||||||
|
Definition at line 843 of file light.c. References add, ambientColor, light_s::color, d, light_s::dist, DotProduct, light_s::emitColor, exactPointToPolygon, trace_t::filter, light_t, light_s::linearLight, linearScale, light_s::next, light_s::normal, notrace, light_s::origin, trace_t::passSolid, light_s::photons, PointToPolygonFormFactor(), qfalse, light_s::radiusByDist, SunToPlane(), TraceLine(), light_s::twosided, light_s::type, vec3_t, VectorCopy, VectorLength(), VectorMA, VectorNormalize(), VectorSubtract, and light_s::w. Referenced by TraceLtm(), and VertexLighting(). 00844 {
00845 light_t *light;
00846 trace_t trace;
00847 float angle;
00848 float add;
00849 float dist;
00850 vec3_t dir;
00851
00852 VectorCopy( ambientColor, color );
00853
00854 // trace to all the lights
00855 for ( light = lights ; light ; light = light->next ) {
00856
00857 //MrE: if the light is behind the surface
00858 if ( DotProduct(light->origin, normal) - DotProduct(normal, origin) < 0 )
00859 continue;
00860 // testing exact PTPFF
00861 if ( exactPointToPolygon && light->type == emit_area ) {
00862 float factor;
00863 float d;
00864 vec3_t pushedOrigin;
00865
00866 // see if the point is behind the light
00867 d = DotProduct( origin, light->normal ) - light->dist;
00868 if ( !light->twosided ) {
00869 if ( d < -1 ) {
00870 continue; // point is behind light
00871 }
00872 }
00873
00874 // test occlusion and find light filters
00875 // clip the line, tracing from the surface towards the light
00876 if ( !notrace && testOcclusion ) {
00877 TraceLine( origin, light->origin, &trace, qfalse, tw );
00878
00879 // other light rays must not hit anything
00880 if ( trace.passSolid ) {
00881 continue;
00882 }
00883 } else {
00884 trace.filter[0] = 1.0;
00885 trace.filter[1] = 1.0;
00886 trace.filter[2] = 1.0;
00887 }
00888
00889 // nudge the point so that it is clearly forward of the light
00890 // so that surfaces meeting a light emiter don't get black edges
00891 if ( d > -8 && d < 8 ) {
00892 VectorMA( origin, (8-d), light->normal, pushedOrigin );
00893 } else {
00894 VectorCopy( origin, pushedOrigin );
00895 }
00896
00897 // calculate the contribution
00898 factor = PointToPolygonFormFactor( pushedOrigin, normal, light->w );
00899 if ( factor <= 0 ) {
00900 if ( light->twosided ) {
00901 factor = -factor;
00902 } else {
00903 continue;
00904 }
00905 }
00906 color[0] += factor * light->emitColor[0] * trace.filter[0];
00907 color[1] += factor * light->emitColor[1] * trace.filter[1];
00908 color[2] += factor * light->emitColor[2] * trace.filter[2];
00909
00910 continue;
00911 }
00912
00913 // calculate the amount of light at this sample
00914 if ( light->type == emit_point ) {
00915 VectorSubtract( light->origin, origin, dir );
00916 dist = VectorNormalize( dir, dir );
00917 // clamp the distance to prevent super hot spots
00918 if ( dist < 16 ) {
00919 dist = 16;
00920 }
00921 angle = DotProduct( normal, dir );
00922 if ( light->linearLight ) {
00923 add = angle * light->photons * linearScale - dist;
00924 if ( add < 0 ) {
00925 add = 0;
00926 }
00927 } else {
00928 add = light->photons / ( dist * dist ) * angle;
00929 }
00930 } else if ( light->type == emit_spotlight ) {
00931 float distByNormal;
00932 vec3_t pointAtDist;
00933 float radiusAtDist;
00934 float sampleRadius;
00935 vec3_t distToSample;
00936 float coneScale;
00937
00938 VectorSubtract( light->origin, origin, dir );
00939
00940 distByNormal = -DotProduct( dir, light->normal );
00941 if ( distByNormal < 0 ) {
00942 continue;
00943 }
00944 VectorMA( light->origin, distByNormal, light->normal, pointAtDist );
00945 radiusAtDist = light->radiusByDist * distByNormal;
00946
00947 VectorSubtract( origin, pointAtDist, distToSample );
00948 sampleRadius = VectorLength( distToSample );
00949
00950 if ( sampleRadius >= radiusAtDist ) {
00951 continue; // outside the cone
00952 }
00953 if ( sampleRadius <= radiusAtDist - 32 ) {
00954 coneScale = 1.0; // fully inside
00955 } else {
00956 coneScale = ( radiusAtDist - sampleRadius ) / 32.0;
00957 }
00958
00959 dist = VectorNormalize( dir, dir );
00960 // clamp the distance to prevent super hot spots
00961 if ( dist < 16 ) {
00962 dist = 16;
00963 }
00964 angle = DotProduct( normal, dir );
00965 add = light->photons / ( dist * dist ) * angle * coneScale;
00966
00967 } else if ( light->type == emit_area ) {
00968 VectorSubtract( light->origin, origin, dir );
00969 dist = VectorNormalize( dir, dir );
00970 // clamp the distance to prevent super hot spots
00971 if ( dist < 16 ) {
00972 dist = 16;
00973 }
00974 angle = DotProduct( normal, dir );
00975 if ( angle <= 0 ) {
00976 continue;
00977 }
00978 angle *= -DotProduct( light->normal, dir );
00979 if ( angle <= 0 ) {
00980 continue;
00981 }
00982
00983 if ( light->linearLight ) {
00984 add = angle * light->photons * linearScale - dist;
00985 if ( add < 0 ) {
00986 add = 0;
00987 }
00988 } else {
00989 add = light->photons / ( dist * dist ) * angle;
00990 }
00991 }
00992
00993 if ( add <= 1.0 ) {
00994 continue;
00995 }
00996
00997 // clip the line, tracing from the surface towards the light
00998 if ( !notrace && testOcclusion ) {
00999 TraceLine( origin, light->origin, &trace, qfalse, tw );
01000
01001 // other light rays must not hit anything
01002 if ( trace.passSolid ) {
01003 continue;
01004 }
01005 } else {
01006 trace.filter[0] = 1;
01007 trace.filter[1] = 1;
01008 trace.filter[2] = 1;
01009 }
01010
01011 // add the result
01012 color[0] += add * light->color[0] * trace.filter[0];
01013 color[1] += add * light->color[1] * trace.filter[1];
01014 color[2] += add * light->color[2] * trace.filter[2];
01015 }
01016
01017 //
01018 // trace directly to the sun
01019 //
01020 if ( testOcclusion || forceSunLight ) {
01021 SunToPlane( origin, normal, color, tw );
01022 }
01023 }
|
Here is the call graph for this function:

|
||||||||||||
|
Definition at line 2018 of file light.c. References _printf(), areaScale, argc, argv, atof(), atoi, CountLightmaps(), CreateFilters(), CreateSurfaceLights(), DefaultExtension(), dump, entities, exit(), ExpandArg(), extra, extraWide, FindSkyBrushes(), gamedir, gridSize, i, I_FloatTime(), InitPakFile(), InitTrace(), lightmapBorder, LightWorld(), LoadBSPFile(), LoadShaderInfo(), nogridlighting, noSurfaces, notrace, novertexlighting, NULL, numthreads, ParseEntities(), patchshadows, pointScale, samplesize, SetEntityOrigins(), SetQdirFromPath(), source, sscanf(), strcmp(), strcpy(), StripExtension(), strlen(), ThreadSetDefault(), value, ValueForKey(), verbose, and WriteBSPFile(). Referenced by main(). 02018 {
02019 int i;
02020 double start, end;
02021 const char *value;
02022
02023 _printf ("----- Lighting ----\n");
02024
02025 verbose = qfalse;
02026
02027 for (i=1 ; i<argc ; i++) {
02028 if (!strcmp(argv[i],"-tempname"))
02029 {
02030 i++;
02031 } else if (!strcmp(argv[i],"-v")) {
02032 verbose = qtrue;
02033 } else if (!strcmp(argv[i],"-threads")) {
02034 numthreads = atoi (argv[i+1]);
02035 i++;
02036 } else if (!strcmp(argv[i],"-area")) {
02037 areaScale *= atof(argv[i+1]);
02038 _printf ("area light scaling at %f\n", areaScale);
02039 i++;
02040 } else if (!strcmp(argv[i],"-point")) {
02041 pointScale *= atof(argv[i+1]);
02042 _printf ("point light scaling at %f\n", pointScale);
02043 i++;
02044 } else if (!strcmp(argv[i],"-notrace")) {
02045 notrace = qtrue;
02046 _printf ("No occlusion tracing\n");
02047 } else if (!strcmp(argv[i],"-patchshadows")) {
02048 patchshadows = qtrue;
02049 _printf ("Patch shadow casting enabled\n");
02050 } else if (!strcmp(argv[i],"-extra")) {
02051 extra = qtrue;
02052 _printf ("Extra detail tracing\n");
02053 } else if (!strcmp(argv[i],"-extrawide")) {
02054 extra = qtrue;
02055 extraWide = qtrue;
02056 _printf ("Extra wide detail tracing\n");
02057 } else if (!strcmp(argv[i], "-samplesize")) {
02058 samplesize = atoi(argv[i+1]);
02059 if (samplesize < 1) samplesize = 1;
02060 i++;
02061 _printf("lightmap sample size is %dx%d units\n", samplesize, samplesize);
02062 } else if (!strcmp(argv[i], "-novertex")) {
02063 novertexlighting = qtrue;
02064 _printf("no vertex lighting = true\n");
02065 } else if (!strcmp(argv[i], "-nogrid")) {
02066 nogridlighting = qtrue;
02067 _printf("no grid lighting = true\n");
02068 } else if (!strcmp(argv[i],"-border")) {
02069 lightmapBorder = qtrue;
02070 _printf ("Adding debug border to lightmaps\n");
02071 } else if (!strcmp(argv[i],"-nosurf")) {
02072 noSurfaces = qtrue;
02073 _printf ("Not tracing against surfaces\n" );
02074 } else if (!strcmp(argv[i],"-dump")) {
02075 dump = qtrue;
02076 _printf ("Dumping occlusion maps\n");
02077 } else {
02078 break;
02079 }
02080 }
02081
02082 ThreadSetDefault ();
02083
02084 if (i != argc - 1) {
02085 _printf("usage: q3map -light [-<switch> [-<switch> ...]] <mapname>\n"
02086 "\n"
02087 "Switches:\n"
02088 " v = verbose output\n"
02089 " threads <X> = set number of threads to X\n"
02090 " area <V> = set the area light scale to V\n"
02091 " point <W> = set the point light scale to W\n"
02092 " notrace = don't cast any shadows\n"
02093 " extra = enable super sampling for anti-aliasing\n"
02094 " extrawide = same as extra but smoothen more\n"
02095 " nogrid = don't calculate light grid for dynamic model lighting\n"
02096 " novertex = don't calculate vertex lighting\n"
02097 " samplesize <N> = set the lightmap pixel size to NxN units\n");
02098 exit(0);
02099 }
02100
02101 start = I_FloatTime ();
02102
02103 SetQdirFromPath (argv[i]);
02104
02105 #ifdef _WIN32
02106 InitPakFile(gamedir, NULL);
02107 #endif
02108
02109 strcpy (source, ExpandArg(argv[i]));
02110 StripExtension (source);
02111 DefaultExtension (source, ".bsp");
02112
02113 LoadShaderInfo();
02114
02115 _printf ("reading %s\n", source);
02116
02117 LoadBSPFile (source);
02118
02119 FindSkyBrushes();
02120
02121 ParseEntities();
02122
02123 value = ValueForKey( &entities[0], "gridsize" );
02124 if (strlen(value)) {
02125 sscanf( value, "%f %f %f", &gridSize[0], &gridSize[1], &gridSize[2] );
02126 _printf("grid size = {%1.1f, %1.1f, %1.1f}\n", gridSize[0], gridSize[1], gridSize[2]);
02127 }
02128
02129 CreateFilters();
02130
02131 InitTrace();
02132
02133 SetEntityOrigins();
02134
02135 CountLightmaps();
02136
02137 CreateSurfaceLights();
02138
02139 LightWorld();
02140
02141 _printf ("writing %s\n", source);
02142 WriteBSPFile (source);
02143
02144 end = I_FloatTime ();
02145 _printf ("%5.0f seconds elapsed\n", end-start);
02146
02147 return 0;
02148 }
|
Here is the call graph for this function:

|
|
Definition at line 1803 of file light.c. References ambientColor, c_occluded, c_visible, CreateEntityLights(), entities, f, FloatForKey(), GetVectorForKey(), gridBounds, numAreaLights, numDrawSurfaces, numGridPoints, numPointLights, qprintf(), qtrue, RunThreadsOnIndividual(), SetupGrid(), TraceGrid(), TraceLtm(), and VectorScale. Referenced by LightMain(). 01803 {
01804 float f;
01805
01806 // determine the number of grid points
01807 SetupGrid();
01808
01809 // find the optional world ambient
01810 GetVectorForKey( &entities[0], "_color", ambientColor );
01811 f = FloatForKey( &entities[0], "ambient" );
01812 VectorScale( ambientColor, f, ambientColor );
01813
01814 // create lights out of patches and lights
01815 qprintf ("--- CreateLights ---\n");
01816 CreateEntityLights ();
01817 qprintf ("%i point lights\n", numPointLights);
01818 qprintf ("%i area lights\n", numAreaLights);
01819
01820 if (!nogridlighting) {
01821 qprintf ("--- TraceGrid ---\n");
01822 RunThreadsOnIndividual( numGridPoints, qtrue, TraceGrid );
01823 qprintf( "%i x %i x %i = %i grid\n", gridBounds[0], gridBounds[1],
01824 gridBounds[2], numGridPoints);
01825 }
01826
01827 qprintf ("--- TraceLtm ---\n");
01828 RunThreadsOnIndividual( numDrawSurfaces, qtrue, TraceLtm );
01829 qprintf( "%5i visible samples\n", c_visible );
01830 qprintf( "%5i occluded samples\n", c_occluded );
01831 }
|
Here is the call graph for this function:

|
|
Definition at line 1114 of file light.c. References FreeMesh(), mesh_t::height, i, in, j, malloc(), drawVert_t::normal, v1, v2, VectorNormalize(), mesh_t::verts, mesh_t::width, and drawVert_t::xyz. Referenced by TraceLtm(). 01114 {
01115 int i, j;
01116 mesh_t *out;
01117 drawVert_t *v1, *v2, *vout;
01118
01119 out = malloc( sizeof( *out ) );
01120
01121 out->width = in->width * 2;
01122 out->height = in->height;
01123 out->verts = malloc( out->width * out->height * sizeof(*out->verts) );
01124 for ( j = 0 ; j < in->height ; j++ ) {
01125 out->verts[ j * out->width + 0 ] = in->verts[ j * in->width + 0 ];
01126 out->verts[ j * out->width + out->width - 1 ] = in->verts[ j * in->width + in->width - 1 ];
01127 for ( i = 1 ; i < out->width - 1 ; i+= 2 ) {
01128 v1 = in->verts + j * in->width + (i >> 1);
01129 v2 = v1 + 1;
01130 vout = out->verts + j * out->width + i;
01131
01132 vout->xyz[0] = 0.75 * v1->xyz[0] + 0.25 * v2->xyz[0];
01133 vout->xyz[1] = 0.75 * v1->xyz[1] + 0.25 * v2->xyz[1];
01134 vout->xyz[2] = 0.75 * v1->xyz[2] + 0.25 * v2->xyz[2];
01135
01136 vout->normal[0] = 0.75 * v1->normal[0] + 0.25 * v2->normal[0];
01137 vout->normal[1] = 0.75 * v1->normal[1] + 0.25 * v2->normal[1];
01138 vout->normal[2] = 0.75 * v1->normal[2] + 0.25 * v2->normal[2];
01139
01140 VectorNormalize( vout->normal, vout->normal );
01141
01142 vout++;
01143
01144 vout->xyz[0] = 0.25 * v1->xyz[0] + 0.75 * v2->xyz[0];
01145 vout->xyz[1] = 0.25 * v1->xyz[1] + 0.75 * v2->xyz[1];
01146 vout->xyz[2] = 0.25 * v1->xyz[2] + 0.75 * v2->xyz[2];
01147
01148 vout->normal[0] = 0.25 * v1->normal[0] + 0.75 * v2->normal[0];
01149 vout->normal[1] = 0.25 * v1->normal[1] + 0.75 * v2->normal[1];
01150 vout->normal[2] = 0.25 * v1->normal[2] + 0.75 * v2->normal[2];
01151
01152 VectorNormalize( vout->normal, vout->normal );
01153
01154 }
01155 }
01156
01157 FreeMesh( in );
01158
01159 return out;
01160 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 610 of file light.c. References _printf(), acos(), CrossProduct(), dirs, DotProduct, i, j, winding_t::numpoints, winding_t::p, point, printed(), qboolean, vec3_t, VectorCopy, VectorNormalize(), VectorSubtract, and w. Referenced by LightContributionToPoint(), LightingAtSample(), VL_LightSurfaceWithVolume(), and VS_LightSurfaceWithVolume(). 00610 {
00611 vec3_t triVector, triNormal;
00612 int i, j;
00613 vec3_t dirs[MAX_POINTS_ON_WINDING];
00614 float total;
00615 float dot, angle, facing;
00616
00617 for ( i = 0 ; i < w->numpoints ; i++ ) {
00618 VectorSubtract( w->p[i], point, dirs[i] );
00619 VectorNormalize( dirs[i], dirs[i] );
00620 }
00621
00622 // duplicate first vertex to avoid mod operation
00623 VectorCopy( dirs[0], dirs[i] );
00624
00625 total = 0;
00626 for ( i = 0 ; i < w->numpoints ; i++ ) {
00627 j = i+1;
00628 dot = DotProduct( dirs[i], dirs[j] );
00629
00630 // roundoff can cause slight creep, which gives an IND from acos
00631 if ( dot > 1.0 ) {
00632 dot = 1.0;
00633 } else if ( dot < -1.0 ) {
00634 dot = -1.0;
00635 }
00636
00637 angle = acos( dot );
00638 CrossProduct( dirs[i], dirs[j], triVector );
00639 if ( VectorNormalize( triVector, triNormal ) < 0.0001 ) {
00640 continue;
00641 }
00642 facing = DotProduct( normal, triNormal );
00643 total += facing * angle;
00644
00645 if ( total > 6.3 || total < -6.3 ) {
00646 static qboolean printed;
00647
00648 if ( !printed ) {
00649 printed = qtrue;
00650 _printf( "WARNING: bad PointToPolygonFormFactor: %f at %1.1f %1.1f %1.1f from %1.1f %1.1f %1.1f\n", total,
00651 w->p[i][0], w->p[i][1], w->p[i][2], point[0], point[1], point[2]);
00652 }
00653 return 0;
00654 }
00655
00656 }
00657
00658 total /= 2*3.141592657; // now in the range of 0 to 1 over the entire incoming hemisphere
00659
00660 return total;
00661 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 1032 of file light.c. References _printf(), byte, i, and j. Referenced by TraceLtm(). 01033 {
01034 int i, j;
01035
01036 _printf( "\n" );
01037
01038 for ( i = 0 ; i < height ; i++ ) {
01039 for ( j = 0 ; j < width ; j++ ) {
01040 _printf("%i", (int)occluded[j][i] );
01041 }
01042 _printf( "\n" );
01043 }
01044 }
|
Here is the call graph for this function:

|
|
Definition at line 1769 of file light.c. References _printf(), free(), FreeWinding(), light_t, lights, light_s::next, light_s::origin, PointInSolid(), and light_s::w. 01770 {
01771 light_t *light, *prev;
01772 int numsolid = 0;
01773
01774 prev = NULL;
01775 for ( light = lights ; light ; ) {
01776 if (PointInSolid(light->origin))
01777 {
01778 if (prev) prev->next = light->next;
01779 else lights = light->next;
01780 if (light->w)
01781 FreeWinding(light->w);
01782 free(light);
01783 numsolid++;
01784 if (prev)
01785 light = prev->next;
01786 else
01787 light = lights;
01788 }
01789 else
01790 {
01791 prev = light;
01792 light = light->next;
01793 }
01794 }
01795 _printf (" %7i lights in solid\n", numsolid);
01796 }
|
Here is the call graph for this function:

|
|
Definition at line 560 of file light.c. References atoi, dmodels, e, entities, entitySurface, dmodel_t::firstSurface, GetVectorForKey(), i, j, dmodel_t::numSurfaces, surfaceOrigin, ValueForKey(), vec3_t, and VectorCopy. Referenced by LightMain(), VLightMain(), and VSoundMain(). 00560 {
00561 int i, j;
00562 entity_t *e;
00563 vec3_t origin;
00564 const char *key;
00565 int modelnum;
00566 dmodel_t *dm;
00567
00568 for ( i=0 ; i < num_entities ; i++ ) {
00569 e = &entities[i];
00570 key = ValueForKey (e, "model");
00571 if ( key[0] != '*' ) {
00572 continue;
00573 }
00574 modelnum = atoi( key + 1 );
00575 dm = &dmodels[ modelnum ];
00576
00577 // set entity surface to true for all surfaces for this model
00578 for ( j = 0 ; j < dm->numSurfaces ; j++ ) {
00579 entitySurface[ dm->firstSurface + j ] = qtrue;
00580 }
00581
00582 key = ValueForKey (e, "origin");
00583 if ( !key[0] ) {
00584 continue;
00585 }
00586 GetVectorForKey ( e, "origin", origin );
00587
00588 // set origin for all surfaces for this model
00589 for ( j = 0 ; j < dm->numSurfaces ; j++ ) {
00590 VectorCopy( origin, surfaceOrigin[ dm->firstSurface + j ] );
00591 }
00592 }
00593 }
|
Here is the call graph for this function:

|
|
Definition at line 1746 of file light.c. References ceil(), dmodels, Error(), floor(), gridBounds, gridMins, gridSize, i, numGridPoints, qprintf(), and vec3_t. Referenced by GridAndVertexLighting(), and LightWorld(). 01746 {
01747 int i;
01748 vec3_t maxs;
01749
01750 for ( i = 0 ; i < 3 ; i++ ) {
01751 gridMins[i] = gridSize[i] * ceil( dmodels[0].mins[i] / gridSize[i] );
01752 maxs[i] = gridSize[i] * floor( dmodels[0].maxs[i] / gridSize[i] );
01753 gridBounds[i] = (maxs[i] - gridMins[i])/gridSize[i] + 1;
01754 }
01755
01756 numGridPoints = gridBounds[0] * gridBounds[1] * gridBounds[2];
01757 if (numGridPoints * 8 >= MAX_MAP_LIGHTGRID)
01758 Error("MAX_MAP_LIGHTGRID");
01759 qprintf( "%5i gridPoints\n", numGridPoints );
01760 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 137 of file light.c. References areaScale, shaderInfo_s::backsplashDistance, shaderInfo_s::backsplashFraction, ClipWindingEpsilon(), shaderInfo_s::color, shaderInfo_s::contents, DotProduct, formFactorValueScale, FreeWinding(), light_t, lights, malloc(), memset(), light_s::next, numAreaLights, ON_EPSILON, light_s::photons, qfalse, shaderInfo_t, light_s::type, shaderInfo_s::value, value, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorScale, light_s::w, w, WindingArea(), WindingBounds(), and WindingCenter(). Referenced by CreateSurfaceLights(). 00138 {
00139 float area, value, intensity;
00140 light_t *dl, *dl2;
00141 vec3_t mins, maxs;
00142 int axis;
00143 winding_t *front, *back;
00144 vec3_t planeNormal;
00145 float planeDist;
00146
00147 if ( !w ) {
00148 return;
00149 }
00150
00151 WindingBounds( w, mins, maxs );
00152
00153 // check for subdivision
00154 for ( axis = 0 ; axis < 3 ; axis++ ) {
00155 if ( maxs[axis] - mins[axis] > areaSubdivide ) {
00156 VectorClear( planeNormal );
00157 planeNormal[axis] = 1;
00158 planeDist = ( maxs[axis] + mins[axis] ) * 0.5;
00159 ClipWindingEpsilon ( w, planeNormal, planeDist, ON_EPSILON, &front, &back );
00160 SubdivideAreaLight( ls, front, normal, areaSubdivide, qfalse );
00161 SubdivideAreaLight( ls, back, normal, areaSubdivide, qfalse );
00162 FreeWinding( w );
00163 return;
00164 }
00165 }
00166
00167 // create a light from this
00168 area = WindingArea (w);
00169 if ( area <= 0 || area > 20000000 ) {
00170 return;
00171 }
00172
00173 numAreaLights++;
00174 dl = malloc(sizeof(*dl));
00175 memset (dl, 0, sizeof(*dl));
00176 dl->next = lights;
00177 lights = dl;
00178 dl->type = emit_area;
00179
00180 WindingCenter( w, dl->origin );
00181 dl->w = w;
00182 VectorCopy ( normal, dl->normal);
00183 dl->dist = DotProduct( dl->origin, normal );
00184
00185 value = ls->value;
00186 intensity = value * area * areaScale;
00187 VectorAdd( dl->origin, dl->normal, dl->origin );
00188
00189 VectorCopy( ls->color, dl->color );
00190
00191 dl->photons = intensity;
00192
00193 // emitColor is irrespective of the area
00194 VectorScale( ls->color, value*formFactorValueScale*areaScale, dl->emitColor );
00195
00196 dl->si = ls;
00197
00198 if ( ls->contents & CONTENTS_FOG ) {
00199 dl->twosided = qtrue;
00200 }
00201
00202 // optionally create a point backsplash light
00203 if ( backsplash && ls->backsplashFraction > 0 ) {
00204 dl2 = malloc(sizeof(*dl));
00205 memset (dl2, 0, sizeof(*dl2));
00206 dl2->next = lights;
00207 lights = dl2;
00208 dl2->type = emit_point;
00209
00210 VectorMA( dl->origin, ls->backsplashDistance, normal, dl2->origin );
00211
00212 VectorCopy( ls->color, dl2->color );
00213
00214 dl2->photons = dl->photons * ls->backsplashFraction;
00215 dl2->si = ls;
00216 }
00217 }
|
Here is the call graph for this function:

|
||||||||||||||||||||
|
Definition at line 821 of file light.c. References DotProduct, sunDirection, SunToPoint(), vec3_t, and VectorMA. Referenced by LightingAtSample(). 00821 {
00822 float angle;
00823 vec3_t sunColor;
00824
00825 if ( !numSkyBrushes ) {
00826 return;
00827 }
00828
00829 angle = DotProduct( normal, sunDirection );
00830 if ( angle <= 0 ) {
00831 return; // facing away
00832 }
00833
00834 SunToPoint( origin, tw, sunColor );
00835 VectorMA( color, angle, sunColor, color );
00836 }
|
Here is the call graph for this function:

|
||||||||||||||||
|
Definition at line 765 of file light.c. References b, skyBrush_t::bounds, c_sunHit, c_sunMiss, trace_t::filter, trace_t::hit, i, MAX_WORLD_COORD, numthreads, qtrue, skyBrushes, sunDirection, sunLight, TraceLine(), vec3_t, VectorClear, and VectorMA. Referenced by SunToPlane(), and TraceGrid(). 00765 {
00766 int i;
00767 trace_t trace;
00768 skyBrush_t *b;
00769 vec3_t end;
00770
00771 if ( !numSkyBrushes ) {
00772 VectorClear( addLight );
00773 return;
00774 }
00775
00776 VectorMA( origin, MAX_WORLD_COORD * 2, sunDirection, end );
00777
00778 TraceLine( origin, end, &trace, qtrue, tw );
00779
00780 // see if trace.hit is inside a sky brush
00781 for ( i = 0 ; i < numSkyBrushes ; i++) {
00782 b = &skyBrushes[ i ];
00783
00784 // this assumes that sky brushes are axial...
00785 if ( trace.hit[0] < b->bounds[0][0]
00786 || trace.hit[0] > b->bounds[1][0]
00787 || trace.hit[1] < b->bounds[0][1]
00788 || trace.hit[1] > b->bounds[1][1]
00789 || trace.hit[2] < b->bounds[0][2]
00790 || trace.hit[2] > b->bounds[1][2] ) {
00791 continue;
00792 }
00793
00794
00795 // trace again to get intermediate filters
00796 TraceLine( origin, trace.hit, &trace, qtrue, tw );
00797
00798 // we hit the sky, so add sunlight
00799 if ( numthreads == 1 ) {
00800 c_sunHit++;
00801 }
00802 addLight[0] = trace.filter[0] * sunLight[0];
00803 addLight[1] = trace.filter[1] * sunLight[1];
00804 addLight[2] = trace.filter[2] * sunLight[2];
00805
00806 return;
00807 }
00808
00809 if ( numthreads == 1 ) {
00810 c_sunMiss++;
00811 }
00812
00813 VectorClear( addLight );
00814 }
|
Here is the call graph for this function:

|
|
Definition at line 1591 of file light.c. References add, ambientColor, ColorToBytes(), d, DotProduct, gridBounds, gridData, gridMins, gridSize, i, light_t, LightContributionToPoint(), MAX_CONTRIBUTIONS, light_s::next, NormalToLatLong(), light_s::origin, PointInSolid(), sunDirection, SunToPoint(), vec3_t, VectorClear, VectorCopy, VectorLength(), VectorMA, VectorNormalize(), VectorSubtract, x, y, and z. Referenced by GridAndVertexLighting(), and LightWorld(). 01591 {
01592 int x, y, z;
01593 vec3_t origin;
01594 light_t *light;
01595 vec3_t color;
01596 int mod;
01597 vec3_t directedColor;
01598 vec3_t summedDir;
01599 contribution_t contributions[MAX_CONTRIBUTIONS];
01600 int numCon;
01601 int i;
01602 traceWork_t tw;
01603 float addSize;
01604
01605 mod = num;
01606 z = mod / ( gridBounds[0] * gridBounds[1] );
01607 mod -= z * ( gridBounds[0] * gridBounds[1] );
01608
01609 y = mod / gridBounds[0];
01610 mod -= y * gridBounds[0];
01611
01612 x = mod;
01613
01614 origin[0] = gridMins[0] + x * gridSize[0];
01615 origin[1] = gridMins[1] + y * gridSize[1];
01616 origin[2] = gridMins[2] + z * gridSize[2];
01617
01618 if ( PointInSolid( origin ) ) {
01619 vec3_t baseOrigin;
01620 int step;
01621
01622 VectorCopy( origin, baseOrigin );
01623
01624 // try to nudge the origin around to find a valid point
01625 for ( step = 9 ; step <= 18 ; step += 9 ) {
01626 for ( i = 0 ; i < 8 ; i++ ) {
01627 VectorCopy( baseOrigin, origin );
01628 if ( i & 1 ) {
01629 origin[0] += step;
01630 } else {
01631 origin[0] -= step;
01632 }
01633 if ( i & 2 ) {
01634 origin[1] += step;
01635 } else {
01636 origin[1] -= step;
01637 }
01638 if ( i & 4 ) {
01639 origin[2] += step;
01640 } else {
01641 origin[2] -= step;
01642 }
01643
01644 if ( !PointInSolid( origin ) ) {
01645 break;
01646 }
01647 }
01648 if ( i != 8 ) {
01649 break;
01650 }
01651 }
01652 if ( step > 18 ) {
01653 // can't find a valid point at all
01654 for ( i = 0 ; i < 8 ; i++ ) {
01655 gridData[ num*8 + i ] = 0;
01656 }
01657 return;
01658 }
01659 }
01660
01661 VectorClear( summedDir );
01662
01663 // trace to all the lights
01664
01665 // find the major light direction, and divide the
01666 // total light between that along the direction and
01667 // the remaining in the ambient
01668 numCon = 0;
01669 for ( light = lights ; light ; light = light->next ) {
01670 vec3_t add;
01671 vec3_t dir;
01672 float addSize;
01673
01674 if ( !LightContributionToPoint( light, origin, add, &tw ) ) {
01675 continue;
01676 }
01677
01678 VectorSubtract( light->origin, origin, dir );
01679 VectorNormalize( dir, dir );
01680
01681 VectorCopy( add, contributions[numCon].color );
01682 VectorCopy( dir, contributions[numCon].dir );
01683 numCon++;
01684
01685 addSize = VectorLength( add );
01686 VectorMA( summedDir, addSize, dir, summedDir );
01687
01688 if ( numCon == MAX_CONTRIBUTIONS-1 ) {
01689 break;
01690 }
01691 }
01692
01693 //
01694 // trace directly to the sun
01695 //
01696 SunToPoint( origin, &tw, color );
01697 addSize = VectorLength( color );
01698 if ( addSize > 0 ) {
01699 VectorCopy( color, contributions[numCon].color );
01700 VectorCopy( sunDirection, contributions[numCon].dir );
01701 VectorMA( summedDir, addSize, sunDirection, summedDir );
01702 numCon++;
01703 }
01704
01705
01706 // now that we have identified the primary light direction,
01707 // go back and seperate all the light into directed and ambient
01708 VectorNormalize( summedDir, summedDir );
01709 VectorCopy( ambientColor, color );
01710 VectorClear( directedColor );
01711
01712 for ( i = 0 ; i < numCon ; i++ ) {
01713 float d;
01714
01715 d = DotProduct( contributions[i].dir, summedDir );
01716 if ( d < 0 ) {
01717 d = 0;
01718 }
01719
01720 VectorMA( directedColor, d, contributions[i].color, directedColor );
01721
01722 // the ambient light will be at 1/4 the value of directed light
01723 d = 0.25 * ( 1.0 - d );
01724 VectorMA( color, d, contributions[i].color, color );
01725 }
01726
01727 // now do some fudging to keep the ambient from being too low
01728 VectorMA( color, 0.25, directedColor, color );
01729
01730 //
01731 // save the resulting value out
01732 //
01733 ColorToBytes( color, gridData + num*8 );
01734 ColorToBytes( directedColor, gridData + num*8 + 3 );
01735
01736 VectorNormalize( summedDir, summedDir );
01737 NormalToLatLong( summedDir, gridData + num*8 + 6);
01738 }
|
Here is the call graph for this function:

|
|
Definition at line 1196 of file light.c. References byte, c_occluded, c_visible, ColorToBytes(), count, drawSurfaces, drawVerts, dshaders, Error(), dsurface_t::firstVert, shaderInfo_s::forceSunLight, FreeMesh(), mesh_t::height, i, j, k, lightBytes, LightingAtSample(), LIGHTMAP_HEIGHT, LIGHTMAP_WIDTH, dsurface_t::lightmapHeight, dsurface_t::lightmapNum, dsurface_t::lightmapOrigin, shaderInfo_s::lightmapSampleSize, dsurface_t::lightmapVecs, dsurface_t::lightmapWidth, dsurface_t::lightmapX, dsurface_t::lightmapY, LinearSubdivideMesh(), MakeMeshNormals(), MakeNormalVectors(), memset(), shaderInfo_s::noVertexShadows, numthreads, dsurface_t::patchHeight, shaderInfo_s::patchShadows, traceWork_t::patchshadows, dsurface_t::patchWidth, PointInSolid(), PrintOccluded(), PutMeshOnCurve(), qfalse, qtrue, RemoveLinearMeshColumnsRows(), shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, SubdivideMesh(), SubdivideMeshQuads(), surfaceOrigin, dsurface_t::surfaceType, TransposeMesh(), value, vec3_t, VectorAdd, VectorClear, VectorCopy, VectorMA, VectorScale, VertexLighting(), shaderInfo_s::vertexScale, shaderInfo_s::vertexShadows, mesh_t::verts, mesh_t::width, x, and y. Referenced by LightWorld(), VL_DoForcedTraceLight(), and VS_DoForcedTraceLight(). 01196 {
01197 dsurface_t *ds;
01198 int i, j, k;
01199 int x, y;
01200 int position, numPositions;
01201 vec3_t base, origin, normal;
01202 byte occluded[LIGHTMAP_WIDTH*EXTRASCALE][LIGHTMAP_HEIGHT*EXTRASCALE];
01203 vec3_t color[LIGHTMAP_WIDTH*EXTRASCALE][LIGHTMAP_HEIGHT*EXTRASCALE];
01204 traceWork_t tw;
01205 vec3_t average;
01206 int count;
01207 mesh_t srcMesh, *mesh, *subdivided;
01208 shaderInfo_t *si;
01209 static float nudge[2][9] = {
01210 { 0, -1, 0, 1, -1, 1, -1, 0, 1 },
01211 { 0, -1, -1, -1, 0, 0, 1, 1, 1 }
01212 };
01213 int sampleWidth, sampleHeight, ssize;
01214 vec3_t lightmapOrigin, lightmapVecs[2];
01215 int widthtable[LIGHTMAP_WIDTH], heighttable[LIGHTMAP_WIDTH];
01216
01217 ds = &drawSurfaces[num];
01218 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01219
01220 // vertex-lit triangle model
01221 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
01222 VertexLighting( ds, !si->noVertexShadows, si->forceSunLight, 1.0, &tw );
01223 return;
01224 }
01225
01226 if ( ds->lightmapNum == -1 ) {
01227 return; // doesn't need lighting at all
01228 }
01229
01230 if (!novertexlighting) {
01231 // calculate the vertex lighting for gouraud shade mode
01232 VertexLighting( ds, si->vertexShadows, si->forceSunLight, si->vertexScale, &tw );
01233 }
01234
01235 if ( ds->lightmapNum < 0 ) {
01236 return; // doesn't need lightmap lighting
01237 }
01238
01239 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01240 ssize = samplesize;
01241 if (si->lightmapSampleSize)
01242 ssize = si->lightmapSampleSize;
01243
01244 if (si->patchShadows)
01245 tw.patchshadows = qtrue;
01246 else
01247 tw.patchshadows = patchshadows;
01248
01249 if ( ds->surfaceType == MST_PATCH ) {
01250 srcMesh.width = ds->patchWidth;
01251 srcMesh.height = ds->patchHeight;
01252 srcMesh.verts = drawVerts + ds->firstVert;
01253 mesh = SubdivideMesh( srcMesh, 8, 999 );
01254 PutMeshOnCurve( *mesh );
01255 MakeMeshNormals( *mesh );
01256
01257 subdivided = RemoveLinearMeshColumnsRows( mesh );
01258 FreeMesh(mesh);
01259
01260 mesh = SubdivideMeshQuads( subdivided, ssize, LIGHTMAP_WIDTH, widthtable, heighttable);
01261 if ( mesh->width != ds->lightmapWidth || mesh->height != ds->lightmapHeight ) {
01262 Error( "Mesh lightmap miscount");
01263 }
01264
01265 if ( extra ) {
01266 mesh_t *mp;
01267
01268 // chop it up for more light samples (leaking memory...)
01269 mp = mesh;//CopyMesh( mesh );
01270 mp = LinearSubdivideMesh( mp );
01271 mp = TransposeMesh( mp );
01272 mp = LinearSubdivideMesh( mp );
01273 mp = TransposeMesh( mp );
01274
01275 mesh = mp;
01276 }
01277 } else {
01278 VectorCopy( ds->lightmapVecs[2], normal );
01279
01280 if ( !extra ) {
01281 VectorCopy( ds->lightmapOrigin, lightmapOrigin );
01282 VectorCopy( ds->lightmapVecs[0], lightmapVecs[0] );
01283 VectorCopy( ds->lightmapVecs[1], lightmapVecs[1] );
01284 } else {
01285 // sample at a closer spacing for antialiasing
01286 VectorCopy( ds->lightmapOrigin, lightmapOrigin );
01287 VectorScale( ds->lightmapVecs[0], 0.5, lightmapVecs[0] );
01288 VectorScale( ds->lightmapVecs[1], 0.5, lightmapVecs[1] );
01289 VectorMA( lightmapOrigin, -0.5, lightmapVecs[0], lightmapOrigin );
01290 VectorMA( lightmapOrigin, -0.5, lightmapVecs[1], lightmapOrigin );
01291 }
01292 }
01293
01294 if ( extra ) {
01295 sampleWidth = ds->lightmapWidth * 2;
01296 sampleHeight = ds->lightmapHeight * 2;
01297 } else {
01298 sampleWidth = ds->lightmapWidth;
01299 sampleHeight = ds->lightmapHeight;
01300 }
01301
01302 memset ( color, 0, sizeof( color ) );
01303
01304 // determine which samples are occluded
01305 memset ( occluded, 0, sizeof( occluded ) );
01306 for ( i = 0 ; i < sampleWidth ; i++ ) {
01307 for ( j = 0 ; j < sampleHeight ; j++ ) {
01308
01309 if ( ds->patchWidth ) {
01310 numPositions = 9;
01311 VectorCopy( mesh->verts[j*mesh->width+i].normal, normal );
01312 // VectorNormalize( normal, normal );
01313 // push off of the curve a bit
01314 VectorMA( mesh->verts[j*mesh->width+i].xyz, 1, normal, base );
01315
01316 MakeNormalVectors( normal, lightmapVecs[0], lightmapVecs[1] );
01317 } else {
01318 numPositions = 9;
01319 for ( k = 0 ; k < 3 ; k++ ) {
01320 base[k] = lightmapOrigin[k] + normal[k]
01321 + i * lightmapVecs[0][k]
01322 + j * lightmapVecs[1][k];
01323 }
01324 }
01325 VectorAdd( base, surfaceOrigin[ num ], base );
01326
01327 // we may need to slightly nudge the sample point
01328 // if directly on a wall
01329 for ( position = 0 ; position < numPositions ; position++ ) {
01330 // calculate lightmap sample position
01331 for ( k = 0 ; k < 3 ; k++ ) {
01332 origin[k] = base[k] +
01333 + ( nudge[0][position]/16 ) * lightmapVecs[0][k]
01334 + ( nudge[1][position]/16 ) * lightmapVecs[1][k];
01335 }
01336
01337 if ( notrace ) {
01338 break;
01339 }
01340 if ( !PointInSolid( origin ) ) {
01341 break;
01342 }
01343 }
01344
01345 // if none of the nudges worked, this sample is occluded
01346 if ( position == numPositions ) {
01347 occluded[i][j] = qtrue;
01348 if ( numthreads == 1 ) {
01349 c_occluded++;
01350 }
01351 continue;
01352 }
01353
01354 if ( numthreads == 1 ) {
01355 c_visible++;
01356 }
01357 occluded[i][j] = qfalse;
01358 LightingAtSample( origin, normal, color[i][j], qtrue, qfalse, &tw );
01359 }
01360 }
01361
01362 if ( dump ) {
01363 PrintOccluded( occluded, sampleWidth, sampleHeight );
01364 }
01365
01366 // calculate average values for occluded samples
01367 for ( i = 0 ; i < sampleWidth ; i++ ) {
01368 for ( j = 0 ; j < sampleHeight ; j++ ) {
01369 if ( !occluded[i][j] ) {
01370 continue;
01371 }
01372 // scan all surrounding samples
01373 count = 0;
01374 VectorClear( average );
01375 for ( x = -1 ; x <= 1; x++ ) {
01376 for ( y = -1 ; y <= 1 ; y++ ) {
01377 if ( i + x < 0 || i + x >= sampleWidth ) {
01378 continue;
01379 }
01380 if ( j + y < 0 || j + y >= sampleHeight ) {
01381 continue;
01382 }
01383 if ( occluded[i+x][j+y] ) {
01384 continue;
01385 }
01386 count++;
01387 VectorAdd( color[i+x][j+y], average, average );
01388 }
01389 }
01390 if ( count ) {
01391 VectorScale( average, 1.0/count, color[i][j] );
01392 }
01393 }
01394 }
01395
01396 // average together the values if we are extra sampling
01397 if ( ds->lightmapWidth != sampleWidth ) {
01398 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01399 for ( j = 0 ; j < ds->lightmapHeight ; j++ ) {
01400 for ( k = 0 ; k < 3 ; k++ ) {
01401 float value, coverage;
01402
01403 value = color[i*2][j*2][k] + color[i*2][j*2+1][k] +
01404 color[i*2+1][j*2][k] + color[i*2+1][j*2+1][k];
01405 coverage = 4;
01406 if ( extraWide ) {
01407 // wider than box filter
01408 if ( i > 0 ) {
01409 value += color[i*2-1][j*2][k] + color[i*2-1][j*2+1][k];
01410 value += color[i*2-2][j*2][k] + color[i*2-2][j*2+1][k];
01411 coverage += 4;
01412 }
01413 if ( i < ds->lightmapWidth - 1 ) {
01414 value += color[i*2+2][j*2][k] + color[i*2+2][j*2+1][k];
01415 value += color[i*2+3][j*2][k] + color[i*2+3][j*2+1][k];
01416 coverage += 4;
01417 }
01418 if ( j > 0 ) {
01419 value += color[i*2][j*2-1][k] + color[i*2+1][j*2-1][k];
01420 value += color[i*2][j*2-2][k] + color[i*2+1][j*2-2][k];
01421 coverage += 4;
01422 }
01423 if ( j < ds->lightmapHeight - 1 ) {
01424 value += color[i*2][j*2+2][k] + color[i*2+1][j*2+2][k];
01425 value += color[i*2][j*2+3][k] + color[i*2+1][j*2+3][k];
01426 coverage += 2;
01427 }
01428 }
01429
01430 color[i][j][k] = value / coverage;
01431 }
01432 }
01433 }
01434 }
01435
01436 // optionally create a debugging border around the lightmap
01437 if ( lightmapBorder ) {
01438 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01439 color[i][0][0] = 255;
01440 color[i][0][1] = 0;
01441 color[i][0][2] = 0;
01442
01443 color[i][ds->lightmapHeight-1][0] = 255;
01444 color[i][ds->lightmapHeight-1][1] = 0;
01445 color[i][ds->lightmapHeight-1][2] = 0;
01446 }
01447 for ( i = 0 ; i < ds->lightmapHeight ; i++ ) {
01448 color[0][i][0] = 255;
01449 color[0][i][1] = 0;
01450 color[0][i][2] = 0;
01451
01452 color[ds->lightmapWidth-1][i][0] = 255;
01453 color[ds->lightmapWidth-1][i][1] = 0;
01454 color[ds->lightmapWidth-1][i][2] = 0;
01455 }
01456 }
01457
01458 // clamp the colors to bytes and store off
01459 for ( i = 0 ; i < ds->lightmapWidth ; i++ ) {
01460 for ( j = 0 ; j < ds->lightmapHeight ; j++ ) {
01461 k = ( ds->lightmapNum * LIGHTMAP_HEIGHT + ds->lightmapY + j)
01462 * LIGHTMAP_WIDTH + ds->lightmapX + i;
01463
01464 ColorToBytes( color[i][j], lightBytes + k*3 );
01465 }
01466 }
01467
01468 if (ds->surfaceType == MST_PATCH)
01469 {
01470 FreeMesh(mesh);
01471 }
01472 }
|
Here is the call graph for this function:

|
|
Definition at line 1970 of file light.c. References drawSurfaces, dshaders, shaderInfo_s::forceSunLight, shaderInfo_s::noVertexShadows, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, dsurface_t::surfaceType, and VertexLighting(). Referenced by GridAndVertexLighting(). 01970 {
01971 dsurface_t *ds;
01972 traceWork_t tw;
01973 shaderInfo_t *si;
01974
01975 ds = &drawSurfaces[num];
01976 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01977
01978 // vertex-lit triangle model
01979 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
01980 VertexLighting( ds, !si->noVertexShadows, si->forceSunLight, 1.0, &tw );
01981 }
01982 }
|
Here is the call graph for this function:

|
||||||||||||||||||||||||
|
Definition at line 1055 of file light.c. References drawVert_t::color, drawVerts, dsurface_t::firstVert, i, j, LightingAtSample(), dsurface_t::lightmapVecs, max, drawVert_t::normal, dsurface_t::numVerts, dsurface_t::patchWidth, dsurface_t::surfaceType, vec3_t, VectorCopy, VectorScale, and drawVert_t::xyz. Referenced by TraceLtm(), TriSoupLightingThread(), and VertexLightingThread(). 01055 {
01056 int i, j;
01057 drawVert_t *dv;
01058 vec3_t sample, normal;
01059 float max;
01060
01061 VectorCopy( ds->lightmapVecs[2], normal );
01062
01063 // generate vertex lighting
01064 for ( i = 0 ; i < ds->numVerts ; i++ ) {
01065 dv = &drawVerts[ ds->firstVert + i ];
01066
01067 if ( ds->patchWidth ) {
01068 LightingAtSample( dv->xyz, dv->normal, sample, testOcclusion, forceSunLight, tw );
01069 }
01070 else if (ds->surfaceType == MST_TRIANGLE_SOUP) {
01071 LightingAtSample( dv->xyz, dv->normal, sample, testOcclusion, forceSunLight, tw );
01072 }
01073 else {
01074 LightingAtSample( dv->xyz, normal, sample, testOcclusion, forceSunLight, tw );
01075 }
01076
01077 if (scale >= 0)
01078 VectorScale(sample, scale, sample);
01079 // clamp with color normalization
01080 max = sample[0];
01081 if ( sample[1] > max ) {
01082 max = sample[1];
01083 }
01084 if ( sample[2] > max ) {
01085 max = sample[2];
01086 }
01087 if ( max > 255 ) {
01088 VectorScale( sample, 255/max, sample );
01089 }
01090
01091 // save the sample
01092 for ( j = 0 ; j < 3 ; j++ ) {
01093 if ( sample[j] > 255 ) {
01094 sample[j] = 255;
01095 }
01096 dv->color[j] = sample[j];
01097 }
01098
01099 // Don't bother writing alpha since it will already be set to 255,
01100 // plus we don't want to write over alpha generated by SetTerrainTextures
01101 //dv->color[3] = 255;
01102 }
01103 }
|
Here is the call graph for this function:

|
|
Definition at line 1940 of file light.c. References drawSurfaces, dshaders, shaderInfo_s::forceSunLight, dsurface_t::lightmapNum, shaderInfo_t, ShaderInfoForShader(), dsurface_t::shaderNum, dsurface_t::surfaceType, VertexLighting(), shaderInfo_s::vertexScale, and shaderInfo_s::vertexShadows. Referenced by GridAndVertexLighting(). 01940 {
01941 dsurface_t *ds;
01942 traceWork_t tw;
01943 shaderInfo_t *si;
01944
01945 ds = &drawSurfaces[num];
01946
01947 // vertex-lit triangle model
01948 if ( ds->surfaceType == MST_TRIANGLE_SOUP ) {
01949 return;
01950 }
01951
01952 if (novertexlighting)
01953 return;
01954
01955 if ( ds->lightmapNum == -1 ) {
01956 return; // doesn't need lighting at all
01957 }
01958
01959 si = ShaderInfoForShader( dshaders[ ds->shaderNum].shader );
01960
01961 // calculate the vertex lighting for gouraud shade mode
01962 VertexLighting( ds, si->vertexShadows, si->forceSunLight, si->vertexScale, &tw );
01963 }
|
Here is the call graph for this function:

|
|
Definition at line 85 of file light.c. Referenced by LightingAtSample(), LightWorld(), and TraceGrid(). |
|
|
Definition at line 63 of file light.c. Referenced by LightMain(), and SubdivideAreaLight(). |
|
|
Definition at line 80 of file light.c. Referenced by LightWorld(), and TraceLtm(). |
|
|
Definition at line 764 of file light.c. Referenced by SunToPoint(). |
|
|
Definition at line 764 of file light.c. Referenced by SunToPoint(). |
|
|
Definition at line 80 of file light.c. Referenced by LightWorld(), and TraceLtm(). |
|
|
|
|
|
Definition at line 51 of file light.c. Referenced by LightMain(), S_StartBackgroundTrack(), and Z_LogZoneHeap(). |
|
|
|
|
|
|
|
|
Definition at line 68 of file light.c. Referenced by LightContributionToPoint(), and LightingAtSample(). |
|
|
Definition at line 52 of file light.c. Referenced by LightMain(), and Z_TagMalloc(). |
|
|
Definition at line 53 of file light.c. Referenced by LightMain(). |
|
|
Definition at line 44 of file light.c. Referenced by CreateFilters(), and FilterTrace(). |
|
|
Definition at line 70 of file light.c. Referenced by SubdivideAreaLight(). |
|
|
Definition at line 1479 of file light.c. Referenced by LightWorld(), SetupGrid(), and TraceGrid(). |
|
|
Definition at line 1477 of file light.c. Referenced by SetupGrid(), and TraceGrid(). |
|
|
Definition at line 1478 of file light.c. Referenced by LightMain(), SetupGrid(), TraceGrid(), VLightMain(), and VSoundMain(). |
|
|
Definition at line 54 of file light.c. Referenced by LightMain(). |
|
|
Definition at line 74 of file light.c. Referenced by CreateEntityLights(), CreateSurfaceLights(), RemoveLightsInSolid(), and SubdivideAreaLight(). |
|
|
Definition at line 72 of file light.c. Referenced by LightContributionToPoint(), and LightingAtSample(). |
|
|
Definition at line 60 of file light.c. Referenced by LightMain(), and VLightMain(). |
|
|
Definition at line 56 of file light.c. Referenced by LightMain(). |
|
|
Definition at line 49 of file light.c. Referenced by LightingAtSample(), and LightMain(). |
|
|
Definition at line 59 of file light.c. Referenced by LightMain(), and VLightMain(). |
|
|
Definition at line 76 of file light.c. Referenced by LightWorld(), and SubdivideAreaLight(). |
|
|
Definition at line 45 of file light.c. Referenced by CreateFilters(). |
|
|
Definition at line 75 of file light.c. Referenced by CreateEntityLights(), CreateSurfaceLights(), and LightWorld(). |
|
|
Definition at line 106 of file light.c. Referenced by FindSkyBrushes(). |
|
|
Definition at line 50 of file light.c. Referenced by LightMain(). |
|
|
Definition at line 66 of file light.c. Referenced by LightMain(). |
|
|
Definition at line 58 of file light.c. Referenced by LightMain(), main(), VLightMain(), and VSoundMain(). |
|
|
Definition at line 107 of file light.c. Referenced by FindSkyBrushes(), and SunToPoint(). |
|
|
|
|
|
Definition at line 96 of file light.c. Referenced by FindSkyBrushes(), SunToPlane(), SunToPoint(), and TraceGrid(). |
|
|
Definition at line 97 of file light.c. Referenced by FindSkyBrushes(), and SunToPoint(). |
|
|
Definition at line 87 of file light.c. Referenced by SetEntityOrigins(), TraceLtm(), VL_GenerateFacetFor3Points(), VL_GenerateFacetFor4Points(), VL_LightmapMatrixFromPoints(), VS_GenerateFacetFor3Points(), VS_GenerateFacetFor4Points(), and VS_LightmapMatrixFromPoints(). |
1.3.9.1