From c441ddb884978077220416b1f8dc9685a8772ce3 Mon Sep 17 00:00:00 2001 From: Eric Wasylishen Date: Wed, 8 Feb 2017 15:03:24 -0700 Subject: [PATCH] light: factor out lightmap resampling --- light/ltface.cc | 171 ++++++++++++++++++++++++++++++++---------------- 1 file changed, 116 insertions(+), 55 deletions(-) diff --git a/light/ltface.cc b/light/ltface.cc index 5af821e1..4c7098c5 100644 --- a/light/ltface.cc +++ b/light/ltface.cc @@ -2175,6 +2175,23 @@ DumpFullSizeLightmap(const bsp2_t *bsp, const lightsurf_t *lightsurf) } } +static void +DumpGLMVector(std::string fname, std::vector vec, int width, int height) +{ + std::vector rgbdata; + for (int y=0; y(glm::clamp(sample[j], 0.0f, 255.0f)); + rgbdata.push_back(static_cast(intval)); + } + } + } + Q_assert(rgbdata.size() == (width * height * 3)); + WritePPM(fname, width, height, rgbdata.data()); +} + static void DumpDownscaledLightmap(const bsp2_t *bsp, const bsp2_dface_t *face, int w, int h, const vec3_t *colors) { @@ -2193,6 +2210,97 @@ DumpDownscaledLightmap(const bsp2_t *bsp, const bsp2_dface_t *face, int w, int h WritePPM(std::string{fname}, w, h, rgbdata.data()); } +static std::vector +LightmapColorsToGLMVector(const lightsurf_t *lightsurf, const lightmap_t *lm) +{ + std::vector res; + for (int i=0; inumpoints; i++) { + const vec_t *color = lm->samples[i].color; + res.push_back(glm::vec3(color[0], color[1], color[2])); + } + return res; +} + +static std::vector +LightmapNormalsToGLMVector(const lightsurf_t *lightsurf, const lightmap_t *lm) +{ + std::vector res; + for (int i=0; inumpoints; i++) { + const vec_t *color = lm->samples[i].direction; + res.push_back(glm::vec3(color[0], color[1], color[2])); + } + return res; +} + +static std::vector +LightmapToGLMVector(const bsp2_t *bsp, const lightsurf_t *lightsurf) +{ + const lightmap_t *lm = Lightmap_ForStyle_ReadOnly(lightsurf, 0); + if (lm != nullptr) { + return LightmapColorsToGLMVector(lightsurf, lm); + } + return std::vector(); +} + + +static std::vector +IntegerDownsampleImage(const std::vector &input, int w, int h, int factor) +{ + Q_assert(factor >= 1); + if (factor == 1) + return input; + + int outw = w/factor; + int outh = h/factor; + + std::vector res(static_cast(outw * outh)); + + for (int y=0; y= w) + continue; + if (y1 < 0 || y1 >= h) + continue; + + // read the input sample + const glm::vec3 inSample = input.at((y1 * w) + x1); + + const float kernelextent_float = kernelextent + 1.0f; + const float x_in_kernel_float = x0 + 0.5f; + const float y_in_kernel_float = y0 + 0.5f; + + Q_assert(x_in_kernel_float >= 0 && x_in_kernel_float <= kernelextent_float); + Q_assert(y_in_kernel_float >= 0 && y_in_kernel_float <= kernelextent_float); + + const float weight = 1.0f; + totalColor += weight * inSample; + + totalWeight += weight; + } + } + + totalColor /= totalWeight; + + res[(y * outw) + x] = totalColor; + } + } + + return res; +} + static void WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const lightsurf_t *lightsurf, const lightmapdict_t *lightmaps) @@ -2286,64 +2394,20 @@ WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const const int oversampled_height = (lightsurf->texsize[1] + 1) * oversample; for (int mapnum = 0; mapnum < numstyles; mapnum++) { + const lightmap_t *lm = sorted.at(mapnum); // allocate new float buffers for the output colors and directions // these are the actual output width*height, without oversampling. - vec3_t *output_color = static_cast(calloc(size, sizeof(vec3_t))); - vec3_t *output_dir = static_cast(calloc(size, sizeof(vec3_t))); - - for (int t = 0; t < actual_height; t++) { - for (int s = 0; s < actual_width; s++) { - - /* Take the average of any oversampling */ - vec3_t color, direction; - - VectorCopy(vec3_origin, color); - VectorCopy(vec3_origin, direction); - - float totalWeight = 0.0f; - - for (int i = -softsamples; i < oversample + softsamples; i++) { - for (int j = -softsamples; j < oversample + softsamples; j++) { - const int col = (s*oversample) + j; - const int row = (t*oversample) + i; - - if (col < 0 || col >= oversampled_width) - continue; - if (row < 0 || row >= oversampled_height) - continue; - - const int sample_index = (row * oversampled_width) + col; - - const lightsample_t *sample = &sorted.at(mapnum)->samples[sample_index]; - - - float weight = 1.0f; // box filter - - VectorMA(color, weight, sample->color, color); - VectorMA(direction, weight, sample->direction, direction); - - totalWeight += weight; - } - } - - VectorScale(color, 1.0 / totalWeight, color); - VectorScale(direction, 1.0 / totalWeight, direction); - - // save in the temporary float buffers - const int actual_sampleindex = (t * actual_width) + s; - VectorCopy(color, output_color[actual_sampleindex]); - VectorCopy(direction, output_dir[actual_sampleindex]); - } - } + std::vector output_color = IntegerDownsampleImage(LightmapColorsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); + std::vector output_dir = IntegerDownsampleImage(LightmapNormalsToGLMVector(lightsurf, lm), oversampled_width, oversampled_height, oversample); // copy from the float buffers to byte buffers in .bsp / .lit / .lux for (int t = 0; t < actual_height; t++) { for (int s = 0; s < actual_width; s++) { const int sampleindex = (t * actual_width) + s; - const vec_t *color = static_cast(output_color[sampleindex]); - const vec_t *direction = static_cast(output_dir[sampleindex]); + const glm::vec3 &color = output_color.at(sampleindex); + const glm::vec3 &direction = output_dir.at(sampleindex); *lit++ = color[0]; *lit++ = color[1]; @@ -2362,9 +2426,9 @@ WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const if (lux) { vec3_t temp; int v; - temp[0] = DotProduct(direction, lightsurf->snormal); - temp[1] = DotProduct(direction, lightsurf->tnormal); - temp[2] = DotProduct(direction, lightsurf->plane.normal); + temp[0] = glm::dot(direction, vec3_t_to_glm(lightsurf->snormal)); + temp[1] = glm::dot(direction, vec3_t_to_glm(lightsurf->tnormal)); + temp[2] = glm::dot(direction, vec3_t_to_glm(lightsurf->plane.normal)); if (!temp[0] && !temp[1] && !temp[2]) VectorSet(temp, 0, 0, 1); @@ -2377,9 +2441,6 @@ WriteLightmaps(const bsp2_t *bsp, bsp2_dface_t *face, facesup_t *facesup, const } } } - - free(output_color); - free(output_dir); } }