light: dynamically allocate memory for lighting each face
This commit is contained in:
parent
22dd1726de
commit
4e74e530c0
|
|
@ -107,7 +107,7 @@ typedef struct {
|
||||||
#define MAXDIMENSION (255+1)
|
#define MAXDIMENSION (255+1)
|
||||||
|
|
||||||
/* Allow space for 4x4 oversampling */
|
/* Allow space for 4x4 oversampling */
|
||||||
#define SINGLEMAP (MAXDIMENSION*MAXDIMENSION*4*4)
|
//#define SINGLEMAP (MAXDIMENSION*MAXDIMENSION*4*4)
|
||||||
|
|
||||||
/*Warning: this stuff needs explicit initialisation*/
|
/*Warning: this stuff needs explicit initialisation*/
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
|
@ -125,14 +125,14 @@ typedef struct {
|
||||||
vec_t exactmid[2];
|
vec_t exactmid[2];
|
||||||
|
|
||||||
int numpoints;
|
int numpoints;
|
||||||
vec3_t points[SINGLEMAP];
|
vec3_t *points; // malloc'ed array of numpoints
|
||||||
vec3_t normals[SINGLEMAP];
|
vec3_t *normals; // malloc'ed array of numpoints
|
||||||
|
|
||||||
/*
|
/*
|
||||||
raw ambient occlusion amount per sample point, 0-1, where 1 is
|
raw ambient occlusion amount per sample point, 0-1, where 1 is
|
||||||
fully occluded. dirtgain/dirtscale are not applied yet
|
fully occluded. dirtgain/dirtscale are not applied yet
|
||||||
*/
|
*/
|
||||||
vec_t occlusion[SINGLEMAP];
|
vec_t *occlusion; // malloc'ed array of numpoints
|
||||||
|
|
||||||
/* for sphere culling */
|
/* for sphere culling */
|
||||||
vec3_t origin;
|
vec3_t origin;
|
||||||
|
|
@ -141,7 +141,7 @@ typedef struct {
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int style;
|
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;
|
} lightmap_t;
|
||||||
|
|
||||||
struct ltface_ctx
|
struct ltface_ctx
|
||||||
|
|
|
||||||
|
|
@ -150,18 +150,13 @@ LightThread(void *arg)
|
||||||
const modelinfo_t *face_modelinfo;
|
const modelinfo_t *face_modelinfo;
|
||||||
struct ltface_ctx *ctx;
|
struct ltface_ctx *ctx;
|
||||||
|
|
||||||
ctx = LightFaceInit(bsp);
|
|
||||||
if (!ctx)
|
|
||||||
{
|
|
||||||
logprint("warning: not enough memory for thread context\n");
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
while (1) {
|
while (1) {
|
||||||
facenum = GetThreadWork();
|
facenum = GetThreadWork();
|
||||||
if (facenum == -1)
|
if (facenum == -1)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
ctx = LightFaceInit(bsp);
|
||||||
|
|
||||||
/* Find the correct model offset */
|
/* Find the correct model offset */
|
||||||
face_modelinfo = ModelInfoForFace(bsp, facenum);
|
face_modelinfo = ModelInfoForFace(bsp, facenum);
|
||||||
if (face_modelinfo == NULL) {
|
if (face_modelinfo == NULL) {
|
||||||
|
|
@ -190,8 +185,9 @@ LightThread(void *arg)
|
||||||
LightFace(bsp->dfaces + facenum, NULL, face_modelinfo, ctx);
|
LightFace(bsp->dfaces + facenum, NULL, face_modelinfo, ctx);
|
||||||
LightFace(bsp->dfaces + facenum, faces_sup + facenum, face_modelinfo, ctx);
|
LightFace(bsp->dfaces + facenum, faces_sup + facenum, face_modelinfo, ctx);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LightFaceShutdown(ctx);
|
||||||
}
|
}
|
||||||
LightFaceShutdown(ctx);
|
|
||||||
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -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;
|
startt = (surf->texmins[1] - 0.5 + (0.5 / oversample)) * surf->lightmapscale;
|
||||||
step = surf->lightmapscale / oversample;
|
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];
|
point = surf->points[0];
|
||||||
norm = surf->normals[0];
|
norm = surf->normals[0];
|
||||||
surf->numpoints = width * height;
|
|
||||||
for (t = 0; t < height; t++) {
|
for (t = 0; t < height; t++) {
|
||||||
for (s = 0; s < width; s++, point += 3, norm += 3) {
|
for (s = 0; s < width; s++, point += 3, norm += 3) {
|
||||||
us = starts + s * step;
|
us = starts + s * step;
|
||||||
|
|
@ -787,10 +790,13 @@ Lightsurf_Init(const modelinfo_t *modelinfo, const bsp2_dface_t *face,
|
||||||
|
|
||||||
/* Correct bounding sphere */
|
/* Correct bounding sphere */
|
||||||
VectorAdd(lightsurf->origin, modelinfo->offset, lightsurf->origin);
|
VectorAdd(lightsurf->origin, modelinfo->offset, lightsurf->origin);
|
||||||
|
|
||||||
|
/* Allocate occlusion array */
|
||||||
|
lightsurf->occlusion = calloc(lightsurf->numpoints, sizeof(float));
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
Lightmaps_Init(lightmap_t *lightmaps, const int count)
|
Lightmaps_Init(const lightsurf_t *lightsurf, lightmap_t *lightmaps, const int count)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
|
|
@ -798,7 +804,10 @@ Lightmaps_Init(lightmap_t *lightmaps, const int count)
|
||||||
memset(lightmaps, 0, sizeof(lightmap_t) * count); */
|
memset(lightmaps, 0, sizeof(lightmap_t) * count); */
|
||||||
|
|
||||||
for (i = 0; i < count; i++)
|
for (i = 0; i < count; i++)
|
||||||
|
{
|
||||||
lightmaps[i].style = 255;
|
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;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*clear only the data that is going to be merged to it. there's no point clearing more*/
|
if (lightmap->samples == NULL) {
|
||||||
memset(lightmap->samples, 0, sizeof(*lightmap->samples)*lightsurf->numpoints);
|
/* 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;
|
lightmap->style = 255;
|
||||||
|
|
||||||
return lightmap;
|
return lightmap;
|
||||||
|
|
@ -860,13 +874,15 @@ Lightmap_Soften(lightmap_t *lightmap, const lightsurf_t *lightsurf)
|
||||||
int s, t, starts, startt, ends, endt;
|
int s, t, starts, startt, ends, endt;
|
||||||
const lightsample_t *src;
|
const lightsample_t *src;
|
||||||
lightsample_t *dst;
|
lightsample_t *dst;
|
||||||
lightmap_t *softmap = calloc(1, sizeof(lightmap_t));
|
lightsample_t *softmap;
|
||||||
|
|
||||||
const int width = (lightsurf->texsize[0] + 1) * oversample;
|
const int width = (lightsurf->texsize[0] + 1) * oversample;
|
||||||
const int height = (lightsurf->texsize[1] + 1) * oversample;
|
const int height = (lightsurf->texsize[1] + 1) * oversample;
|
||||||
const int fullsamples = (2 * softsamples + 1) * (2 * softsamples + 1);
|
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++) {
|
for (i = 0; i < lightsurf->numpoints; i++, dst++) {
|
||||||
startt = qmax((i / width) - softsamples, 0);
|
startt = qmax((i / width) - softsamples, 0);
|
||||||
endt = qmin((i / width) + softsamples + 1, height);
|
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);
|
VectorScale(dst->direction, 1.0 / samples, dst->direction);
|
||||||
}
|
}
|
||||||
|
|
||||||
softmap->style = lightmap->style;
|
memcpy(lightmap->samples, softmap, lightsurf->numpoints * sizeof(lightsample_t));
|
||||||
memcpy(lightmap, softmap, sizeof(*softmap));
|
|
||||||
free(softmap);
|
free(softmap);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1762,13 +1777,29 @@ struct ltface_ctx *LightFaceInit(const bsp2_t *bsp)
|
||||||
{
|
{
|
||||||
//windows stack probes can get expensive when its 64mb...
|
//windows stack probes can get expensive when its 64mb...
|
||||||
//also, this avoids stack overflows, or the need to guess stack sizes.
|
//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)
|
if (ctx)
|
||||||
ctx->bsp = bsp;
|
ctx->bsp = bsp;
|
||||||
return ctx;
|
return ctx;
|
||||||
}
|
}
|
||||||
void LightFaceShutdown(struct ltface_ctx *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);
|
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);
|
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 */
|
/* calculate dirt (ambient occlusion) but don't use it yet */
|
||||||
if (dirty)
|
if (dirty)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue