DWORD WINAPI LightThread (LPVOID *data) { int i; // only print on the first thread threadinfo_t *threadinfo = (threadinfo_t *) data; if (NewLine) fprintf (logfile, "\n"); else logprintf ("\n"); if (SimpPercent) printf ("\n"); ShowPercent (threadinfo->threadnum, "Light", 0, 0); // reduce thread locking overhead by partitioning the BSP faces for (i = threadinfo->firstface; i < threadinfo->lastface; i++) { ShowPercent (threadinfo->threadnum, NULL, (i - threadinfo->firstface), (threadinfo->lastface - threadinfo->firstface)); LightFace (i, faceoffset[i]); } ShowPercent (threadinfo->threadnum, NULL, 100, 100); LOCK; finished++; UNLOCK; return 0; }
static void * LightThread(void *junk) { int facenum; while (1) { facenum = GetThreadWork(); if (facenum == -1) return NULL; LightFace(facenum, nolightface[facenum], faceoffset[facenum]); } return NULL; }
void LightThread (void *junk) { int i; while (1) { LOCK; i = bspfileface++; UNLOCK; if (i >= numfaces) return; LightFace (i); } }
void LightThread (void *junk) { int i; printf("Thread %d started\n", (int)(intptr_t)junk); while (1) { ThreadLock(); i = bspfileface++; ThreadUnlock(); if (i >= numfaces) return; LightFace (i); } }
/* ============= LightWorld ============= */ void LightWorld( void ) { int i, k, n, m, count; unsigned short *mark; time_t lightstarttime, oldtime, newtime; directlight_t *light; dleaf_t *leaf; int lightcount = 0, castcount = 0, emptycount = 0, solidcount = 0, watercount = 0, slimecount = 0, lavacount = 0, skycount = 0, misccount = 0, ignorevis; vec3_t org; char name[8]; entity_t *ent; if( !relight ) lightdatasize = 0; rgblightdatasize = 0; lightstarttime = time( NULL ); lightchainbufindex = 0; novislights = alllights = 0; memset( surfacelightchain, 0, sizeof( surfacelightchain ) ); // LordHavoc: find the right leaf for each entity for( i = 0, light = directlights; i < num_directlights; i++, light++ ) { lightcount++; alllight[alllights++] = light; leaf = Light_PointInLeaf(light->origin); ignorevis = false; switch( leaf->contents ) { case CONTENTS_EMPTY: emptycount++; break; case CONTENTS_SOLID: solidcount++; ignorevis = true; break; case CONTENTS_WATER: watercount++; break; case CONTENTS_SLIME: slimecount++; break; case CONTENTS_LAVA: lavacount++; break; case CONTENTS_SKY: skycount++; ignorevis = true; break; default: misccount++; break; } if( ignorevis ) printf( "light at origin '%f %f %f' is in solid or sky, ignoring vis\n", light->origin[0], light->origin[1], light->origin[2] ); if( leaf->visofs == -1 || ignorevis || !lightvis || light->type == LIGHTTYPE_SUN ) { /* if ((lightchainbufindex + numfaces) > LIGHTCHAINS) Error("LightWorld: ran out of light chains! complain to maintainer of hlight\n"); for (m = 0;m < numfaces;m++) { castcount++; lightchainbuf[lightchainbufindex].light = entity; lightchainbuf[lightchainbufindex].next = surfacelightchain[m]; surfacelightchain[m] = &lightchainbuf[lightchainbufindex++]; } */ castcount += numfaces; novislight[novislights++] = light; } else { DecompressVis( dvisdata + leaf->visofs, currentvis, (dmodels[0].visleafs + 7) >> 3 ); memset( surfacehit, 0, numfaces ); for( n = 0, leaf = dleafs + 1; n < numleafs; n++, leaf++ ) { // leafs begin at 1 if( !leaf->nummarksurfaces ) continue; if( !(currentvis[n >> 3] & (1 << (n & 7))) ) continue; if( (lightchainbufindex + leaf->nummarksurfaces) > LIGHTCHAINS ) Error( "LightWorld: ran out of light chains! complain to maintainer of hlight\n" ); for( m = 0, mark = dmarksurfaces + leaf->firstmarksurface; m < leaf->nummarksurfaces; m++, mark++ ) { if( surfacehit[*mark] ) continue; surfacehit[*mark] = true; castcount++; lightchainbuf[lightchainbufindex].light = light; lightchainbuf[lightchainbufindex].next = surfacelightchain[*mark]; surfacelightchain[*mark] = &lightchainbuf[lightchainbufindex++]; } } } } printf( "%4i lights, %4i air, %4i solid, %4i water, %4i slime, %4i lava, %4i sky, %4i unknown\n", lightcount, emptycount, solidcount, watercount, slimecount, lavacount, skycount, misccount ); i = 0; for( m = 0; m < numfaces; m++ ) { if( surfacelightchain[m] ) i++; } printf( "%5i faces, %5i (%3i%%) may receive light\n", numfaces, i, i * 100 / numfaces ); if( solidcount || skycount ) printf( "warning: %4i lights of %4i lights (%3i%%) were found in sky or solid and will not be accelerated using vis, move them out of the solid or sky to accelerate compiling\n", solidcount+skycount, lightcount, (solidcount+skycount) * 100 / lightcount ); printf( "%4i lights will be cast onto %5i surfaces, %10i casts will be performed\n", lightcount, numfaces, castcount ); // LordHavoc: let there be light count = dmodels[0].numfaces; org[0] = org[1] = org[2] = 0; oldtime = time( NULL ); c_occluded = 0; for( m = 0; m < count; ) { LightFace( dfaces + m + dmodels[0].firstface, surfacelightchain[m + dmodels[0].firstface], novislight, novislights, org ); m++; newtime = time( NULL ); if( newtime != oldtime ) { printf( "\rworld face %5i of %5i (%3i%%), estimated time left: %5i ", m, count, (int) (m*100)/count, (int) (((count-m)*(newtime-lightstarttime))/m) ); fflush( stdout ); oldtime = newtime; } } printf( "\n%5i faces done\nlightdatasize: %i\n", numfaces, lightdatasize ); printf( "c_occluded: %i\n", c_occluded ); printf( "\nlighting %5i submodels:\n", nummodels ); fflush( stdout ); c_occluded = 0; // LordHavoc: light bmodels for( k = 1; k < nummodels; k++ ) { newtime = time( NULL ); if( newtime != oldtime ) { m = k; count = nummodels; printf( "\rsubmodel %3i of %3i (%3i%%), estimated time left: %5i ", m, count, (int) (m*100)/count, (int) (((count-m)*(newtime-lightstarttime))/m) ); fflush( stdout ); oldtime = newtime; } sprintf( name, "*%d", k ); ent = FindEntityWithKeyPair( "model", name ); if( !ent ) Error( "FindFaceOffsets: Couldn't find entity for model %s.\n", name ); // LordHavoc: changed this to support origins on all submodels GetVectorForKey( ent, "origin", org ); for( m = 0; m < dmodels[k].numfaces; m++ ) LightFace( dfaces + m + dmodels[k].firstface, NULL, alllight, alllights, org ); } printf( "\n%5i submodels done\nlightdatasize: %i\n", nummodels, lightdatasize ); printf( "c_occluded: %i\n", c_occluded ); }