diff --git a/include/light/light.h b/include/light/light.h index acd5a41b..48cb8e43 100644 --- a/include/light/light.h +++ b/include/light/light.h @@ -165,6 +165,7 @@ typedef struct { extern const bouncelight_t *bouncelights; extern int numbouncelights; +extern byte thepalette[768]; /* tracelist is a null terminated array of BSP models to use for LOS tests */ extern const modelinfo_t *const *tracelist; diff --git a/light/light.cc b/light/light.cc index 9c41882f..d2c78bc4 100644 --- a/light/light.cc +++ b/light/light.cc @@ -32,6 +32,7 @@ #include #include #include +#include using namespace std; @@ -759,6 +760,7 @@ LoadExtendedTexinfoFlags(const char *sourcefilename, const bsp2_t *bsp) // radiosity +map texturecolors; std::vector radlights; // for access from C @@ -982,6 +984,49 @@ MakeBounceLightsThread (void *arg) return NULL; } +// Returns color in [0,1] +void Texture_AvgColor (const bsp2_t *bsp, const miptex_t *miptex, vec3_t color) +{ + VectorSet(color, 0, 0, 0); + if (!bsp->texdatasize) + return; + + const byte *data = (byte*)miptex + miptex->offsets[0]; + for (int y=0; yheight; y++) { + for (int x=0; xwidth; x++) { + const int i = data[(miptex->width * y) + x]; + + vec3_t samplecolor = { (float)thepalette[3*i], (float)thepalette[3*i + 1], (float)thepalette[3*i + 2] }; + VectorAdd(color, samplecolor, color); + } + } + VectorScale(color, 1.0 / (miptex->width * miptex->height), color); + VectorScale(color, 1.0 / 255.0, color); +} + +void MakeTextureColors (const bsp2_t *bsp) +{ + logprint("--- MakeTextureColors ---\n"); + + if (!bsp->texdatasize) + return; + + for (int i=0; idtexdata.header->nummiptex; i++) { + const int ofs = bsp->dtexdata.header->dataofs[i]; + if (ofs < 0) + continue; + + const miptex_t *miptex = (miptex_t *)(bsp->dtexdata.base + ofs); + + string name { miptex->name }; + vec3_struct_t color; + Texture_AvgColor(bsp, miptex, color.v); + + printf("%s has color %f %f %f\n", name.c_str(), color.v[0], color.v[1], color.v[2]); + texturecolors[name] = color; + } +} + void MakeBounceLights (const bsp2_t *bsp) { logprint("--- MakeBounceLights ---\n"); @@ -1007,8 +1052,17 @@ void MakeBounceLights (const bsp2_t *bsp) VectorCopy(patch->plane.normal, l.surfnormal); l.area = WindingArea(patch->w); l.leaf = Light_PointInLeaf(bsp, l.pos); - radlights.push_back(l); + // scale by texture color + const bsp2_dface_t *f = &bsp->dfaces[mapentry.first]; + const char *facename = Face_TextureName(bsp, f); + if (texturecolors.find(facename) != texturecolors.end()) { + vec3_struct_t texcolor = texturecolors.at(facename); + for (int i=0; i<3; i++) + l.color[i] *= texcolor.v[i]; + } + + radlights.push_back(l); //fprintf(f, "{\n\"classname\" \"light\"\n\"origin\" \"%f %f %f\"\n}\n", l.pos[0], l.pos[1], l.pos[2]); } } @@ -1378,8 +1432,10 @@ main(int argc, const char **argv) MakeTnodes(bsp); - if (bounce) + if (bounce) { + MakeTextureColors(bsp); MakeBounceLights(bsp); + } LightWorld(&bspdata, !!lmscaleoverride); diff --git a/light/ltface.c b/light/ltface.c index f4803471..5319829e 100644 --- a/light/ltface.c +++ b/light/ltface.c @@ -1123,7 +1123,7 @@ CullLight(const entity_t *entity, const lightsurf_t *lightsurf) return fabs(GetLightValue(&entity->light, entity, dist)) <= fadegate; } -static byte thepalette[768] = +byte thepalette[768] = { 0,0,0,15,15,15,31,31,31,47,47,47,63,63,63,75,75,75,91,91,91,107,107,107,123,123,123,139,139,139,155,155,155,171,171,171,187,187,187,203,203,203,219,219,219,235,235,235,15,11,7,23,15,11,31,23,11,39,27,15,47,35,19,55,43,23,63,47,23,75,55,27,83,59,27,91,67,31,99,75,31,107,83,31,115,87,31,123,95,35,131,103,35,143,111,35,11,11,15,19,19,27,27,27,39,39,39,51,47,47,63,55,55,75,63,63,87,71,71,103,79,79,115,91,91,127,99,99, 139,107,107,151,115,115,163,123,123,175,131,131,187,139,139,203,0,0,0,7,7,0,11,11,0,19,19,0,27,27,0,35,35,0,43,43,7,47,47,7,55,55,7,63,63,7,71,71,7,75,75,11,83,83,11,91,91,11,99,99,11,107,107,15,7,0,0,15,0,0,23,0,0,31,0,0,39,0,0,47,0,0,55,0,0,63,0,0,71,0,0,79,0,0,87,0,0,95,0,0,103,0,0,111,0,0,119,0,0,127,0,0,19,19,0,27,27,0,35,35,0,47,43,0,55,47,0,67,