light: dynamically allocate memory for lighting each face

This commit is contained in:
Eric Wasylishen 2016-02-17 01:04:48 -07:00
parent 22dd1726de
commit 4e74e530c0
3 changed files with 50 additions and 23 deletions

View File

@ -107,7 +107,7 @@ typedef struct {
#define MAXDIMENSION (255+1)
/* Allow space for 4x4 oversampling */
#define SINGLEMAP (MAXDIMENSION*MAXDIMENSION*4*4)
//#define SINGLEMAP (MAXDIMENSION*MAXDIMENSION*4*4)
/*Warning: this stuff needs explicit initialisation*/
typedef struct {
@ -125,14 +125,14 @@ typedef struct {
vec_t exactmid[2];
int numpoints;
vec3_t points[SINGLEMAP];
vec3_t normals[SINGLEMAP];
vec3_t *points; // malloc'ed array of numpoints
vec3_t *normals; // malloc'ed array of numpoints
/*
raw ambient occlusion amount per sample point, 0-1, where 1 is
fully occluded. dirtgain/dirtscale are not applied yet
*/
vec_t occlusion[SINGLEMAP];
vec_t *occlusion; // malloc'ed array of numpoints
/* for sphere culling */
vec3_t origin;
@ -141,7 +141,7 @@ typedef struct {
typedef struct {
int style;
lightsample_t samples[SINGLEMAP]; //FIXME: this is stupid, we shouldn't need to allocate extra data here for -extra4
lightsample_t *samples; // malloc'ed array of numpoints //FIXME: this is stupid, we shouldn't need to allocate extra data here for -extra4
} lightmap_t;
struct ltface_ctx

View File

@ -150,18 +150,13 @@ LightThread(void *arg)
const modelinfo_t *face_modelinfo;
struct ltface_ctx *ctx;
ctx = LightFaceInit(bsp);
if (!ctx)
{
logprint("warning: not enough memory for thread context\n");
return NULL;
}
while (1) {
facenum = GetThreadWork();
if (facenum == -1)
break;
ctx = LightFaceInit(bsp);
/* Find the correct model offset */
face_modelinfo = ModelInfoForFace(bsp, facenum);
if (face_modelinfo == NULL) {
@ -190,8 +185,9 @@ LightThread(void *arg)
LightFace(bsp->dfaces + facenum, NULL, face_modelinfo, ctx);
LightFace(bsp->dfaces + facenum, faces_sup + facenum, face_modelinfo, ctx);
}
}
LightFaceShutdown(ctx);
}
return NULL;
}

View File

@ -663,9 +663,12 @@ CalcPoints(const dmodel_t *model, const vec3_t offset, const texorg_t *texorg, l
startt = (surf->texmins[1] - 0.5 + (0.5 / oversample)) * surf->lightmapscale;
step = surf->lightmapscale / oversample;
/* Allocate surf->points */
surf->numpoints = width * height;
surf->points = calloc(surf->numpoints, sizeof(vec3_t));
surf->normals = calloc(surf->numpoints, sizeof(vec3_t));
point = surf->points[0];
norm = surf->normals[0];
surf->numpoints = width * height;
for (t = 0; t < height; t++) {
for (s = 0; s < width; s++, point += 3, norm += 3) {
us = starts + s * step;
@ -787,10 +790,13 @@ Lightsurf_Init(const modelinfo_t *modelinfo, const bsp2_dface_t *face,
/* Correct bounding sphere */
VectorAdd(lightsurf->origin, modelinfo->offset, lightsurf->origin);
/* Allocate occlusion array */
lightsurf->occlusion = calloc(lightsurf->numpoints, sizeof(float));
}
static void
Lightmaps_Init(lightmap_t *lightmaps, const int count)
Lightmaps_Init(const lightsurf_t *lightsurf, lightmap_t *lightmaps, const int count)
{
int i;
@ -798,7 +804,10 @@ Lightmaps_Init(lightmap_t *lightmaps, const int count)
memset(lightmaps, 0, sizeof(lightmap_t) * count); */
for (i = 0; i < count; i++)
{
lightmaps[i].style = 255;
lightmaps[i].samples = NULL;
}
}
/*
@ -821,8 +830,13 @@ Lightmap_ForStyle(lightmap_t *lightmaps, const int style, const lightsurf_t *lig
break;
}
if (lightmap->samples == NULL) {
/* first use of this lightmap, allocate the storage for it. */
lightmap->samples = calloc(lightsurf->numpoints, sizeof(lightsample_t));
} else {
/* clear only the data that is going to be merged to it. there's no point clearing more */
memset(lightmap->samples, 0, sizeof(*lightmap->samples)*lightsurf->numpoints);
}
lightmap->style = 255;
return lightmap;
@ -860,13 +874,15 @@ Lightmap_Soften(lightmap_t *lightmap, const lightsurf_t *lightsurf)
int s, t, starts, startt, ends, endt;
const lightsample_t *src;
lightsample_t *dst;
lightmap_t *softmap = calloc(1, sizeof(lightmap_t));
lightsample_t *softmap;
const int width = (lightsurf->texsize[0] + 1) * oversample;
const int height = (lightsurf->texsize[1] + 1) * oversample;
const int fullsamples = (2 * softsamples + 1) * (2 * softsamples + 1);
dst = softmap->samples;
softmap = calloc(lightsurf->numpoints, sizeof(lightsample_t));
dst = softmap;
for (i = 0; i < lightsurf->numpoints; i++, dst++) {
startt = qmax((i / width) - softsamples, 0);
endt = qmin((i / width) + softsamples + 1, height);
@ -901,8 +917,7 @@ Lightmap_Soften(lightmap_t *lightmap, const lightsurf_t *lightsurf)
VectorScale(dst->direction, 1.0 / samples, dst->direction);
}
softmap->style = lightmap->style;
memcpy(lightmap, softmap, sizeof(*softmap));
memcpy(lightmap->samples, softmap, lightsurf->numpoints * sizeof(lightsample_t));
free(softmap);
}
@ -1762,13 +1777,29 @@ struct ltface_ctx *LightFaceInit(const bsp2_t *bsp)
{
//windows stack probes can get expensive when its 64mb...
//also, this avoids stack overflows, or the need to guess stack sizes.
struct ltface_ctx *ctx = malloc(sizeof(*ctx));
struct ltface_ctx *ctx = calloc(1, sizeof(*ctx));
if (ctx)
ctx->bsp = bsp;
return ctx;
}
void LightFaceShutdown(struct ltface_ctx *ctx)
{
int i;
for (i = 0; i < MAXLIGHTMAPS + 1; i++)
{
if (ctx->lightmaps[i].samples)
free(ctx->lightmaps[i].samples);
}
if (ctx->lightsurf.points)
free(ctx->lightsurf.points);
if (ctx->lightsurf.normals)
free(ctx->lightsurf.normals);
if (ctx->lightsurf.occlusion)
free(ctx->lightsurf.occlusion);
free(ctx);
}
@ -1832,7 +1863,7 @@ LightFace(bsp2_dface_t *face, facesup_t *facesup, const modelinfo_t *modelinfo,
}
Lightsurf_Init(modelinfo, face, bsp, lightsurf, facesup);
Lightmaps_Init(lightmaps, MAXLIGHTMAPS + 1);
Lightmaps_Init(lightsurf, lightmaps, MAXLIGHTMAPS + 1);
/* calculate dirt (ambient occlusion) but don't use it yet */
if (dirty)