mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2025-02-01 06:00:45 +00:00
Always generate composite textures with post data
This commit is contained in:
parent
72b63a1305
commit
861d22fd44
2 changed files with 156 additions and 60 deletions
|
@ -520,13 +520,22 @@ void *Picture_FlatConvert(
|
||||||
for (x = 0; x < inwidth; x++)
|
for (x = 0; x < inwidth; x++)
|
||||||
{
|
{
|
||||||
void *input = NULL;
|
void *input = NULL;
|
||||||
size_t offs = ((y * inwidth) + x);
|
int sx = x;
|
||||||
|
int sy = y;
|
||||||
|
|
||||||
|
if (flags & PICFLAGS_XFLIP)
|
||||||
|
sx = inwidth - x - 1;
|
||||||
|
if (flags & PICFLAGS_YFLIP)
|
||||||
|
sy = inheight - y - 1;
|
||||||
|
|
||||||
|
size_t in_offs = ((sy * inwidth) + sx);
|
||||||
|
size_t out_offs = ((y * inwidth) + x);
|
||||||
|
|
||||||
// Read pixel
|
// Read pixel
|
||||||
if (Picture_IsPatchFormat(informat))
|
if (Picture_IsPatchFormat(informat))
|
||||||
input = Picture_GetPatchPixel(inpatch, informat, x, y, flags);
|
input = Picture_GetPatchPixel(inpatch, informat, sx, sy, 0);
|
||||||
else if (Picture_IsFlatFormat(informat))
|
else if (Picture_IsFlatFormat(informat))
|
||||||
input = (UINT8 *)picture + (offs * (inbpp / 8));
|
input = (UINT8 *)picture + (in_offs * (inbpp / 8));
|
||||||
else
|
else
|
||||||
I_Error("Picture_FlatConvert: unsupported input format!");
|
I_Error("Picture_FlatConvert: unsupported input format!");
|
||||||
|
|
||||||
|
@ -541,17 +550,17 @@ void *Picture_FlatConvert(
|
||||||
if (inbpp == PICDEPTH_32BPP)
|
if (inbpp == PICDEPTH_32BPP)
|
||||||
{
|
{
|
||||||
RGBA_t out = *(RGBA_t *)input;
|
RGBA_t out = *(RGBA_t *)input;
|
||||||
f32[offs] = out.rgba;
|
f32[out_offs] = out.rgba;
|
||||||
}
|
}
|
||||||
else if (inbpp == PICDEPTH_16BPP)
|
else if (inbpp == PICDEPTH_16BPP)
|
||||||
{
|
{
|
||||||
RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
|
RGBA_t out = pMasterPalette[*((UINT16 *)input) & 0xFF];
|
||||||
f32[offs] = out.rgba;
|
f32[out_offs] = out.rgba;
|
||||||
}
|
}
|
||||||
else // PICFMT_PATCH
|
else // PICFMT_PATCH
|
||||||
{
|
{
|
||||||
RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
|
RGBA_t out = pMasterPalette[*((UINT8 *)input) & 0xFF];
|
||||||
f32[offs] = out.rgba;
|
f32[out_offs] = out.rgba;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -562,12 +571,12 @@ void *Picture_FlatConvert(
|
||||||
{
|
{
|
||||||
RGBA_t in = *(RGBA_t *)input;
|
RGBA_t in = *(RGBA_t *)input;
|
||||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||||
f16[offs] = (0xFF00 | out);
|
f16[out_offs] = (0xFF00 | out);
|
||||||
}
|
}
|
||||||
else if (inbpp == PICDEPTH_16BPP)
|
else if (inbpp == PICDEPTH_16BPP)
|
||||||
f16[offs] = *(UINT16 *)input;
|
f16[out_offs] = *(UINT16 *)input;
|
||||||
else // PICFMT_PATCH
|
else // PICFMT_PATCH
|
||||||
f16[offs] = (0xFF00 | *((UINT8 *)input));
|
f16[out_offs] = (0xFF00 | *((UINT8 *)input));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case PICFMT_FLAT:
|
case PICFMT_FLAT:
|
||||||
|
@ -577,15 +586,15 @@ void *Picture_FlatConvert(
|
||||||
{
|
{
|
||||||
RGBA_t in = *(RGBA_t *)input;
|
RGBA_t in = *(RGBA_t *)input;
|
||||||
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
UINT8 out = NearestColor(in.s.red, in.s.green, in.s.blue);
|
||||||
f8[offs] = out;
|
f8[out_offs] = out;
|
||||||
}
|
}
|
||||||
else if (inbpp == PICDEPTH_16BPP)
|
else if (inbpp == PICDEPTH_16BPP)
|
||||||
{
|
{
|
||||||
UINT16 out = *(UINT16 *)input;
|
UINT16 out = *(UINT16 *)input;
|
||||||
f8[offs] = (out & 0xFF);
|
f8[out_offs] = (out & 0xFF);
|
||||||
}
|
}
|
||||||
else // PICFMT_PATCH
|
else // PICFMT_PATCH
|
||||||
f8[offs] = *(UINT8 *)input;
|
f8[out_offs] = *(UINT8 *)input;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
|
@ -613,17 +622,18 @@ void *Picture_GetPatchPixel(
|
||||||
INT32 inbpp = Picture_FormatBPP(informat);
|
INT32 inbpp = Picture_FormatBPP(informat);
|
||||||
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
|
softwarepatch_t *doompatch = (softwarepatch_t *)patch;
|
||||||
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
|
boolean isdoompatch = Picture_IsDoomPatchFormat(informat);
|
||||||
INT16 width;
|
|
||||||
|
|
||||||
if (patch == NULL)
|
if (patch == NULL)
|
||||||
I_Error("Picture_GetPatchPixel: patch == NULL");
|
I_Error("Picture_GetPatchPixel: patch == NULL");
|
||||||
|
|
||||||
width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
|
INT16 width = (isdoompatch ? SHORT(doompatch->width) : patch->width);
|
||||||
|
INT16 height = (isdoompatch ? SHORT(doompatch->height) : patch->height);
|
||||||
|
|
||||||
if (x < 0 || x >= width)
|
if (x < 0 || x >= width || y < 0 || y >= height)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
INT32 colx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
|
INT32 sx = (flags & PICFLAGS_XFLIP) ? (width-1)-x : x;
|
||||||
|
INT32 sy = (flags & PICFLAGS_YFLIP) ? (height-1)-y : y;
|
||||||
UINT8 *s8 = NULL;
|
UINT8 *s8 = NULL;
|
||||||
UINT16 *s16 = NULL;
|
UINT16 *s16 = NULL;
|
||||||
UINT32 *s32 = NULL;
|
UINT32 *s32 = NULL;
|
||||||
|
@ -631,7 +641,7 @@ void *Picture_GetPatchPixel(
|
||||||
if (isdoompatch)
|
if (isdoompatch)
|
||||||
{
|
{
|
||||||
INT32 prevdelta = -1;
|
INT32 prevdelta = -1;
|
||||||
INT32 colofs = LONG(doompatch->columnofs[colx]);
|
INT32 colofs = LONG(doompatch->columnofs[sx]);
|
||||||
|
|
||||||
// Column offsets are pointers, so no casting is required.
|
// Column offsets are pointers, so no casting is required.
|
||||||
doompost_t *column = (doompost_t *)((UINT8 *)doompatch + colofs);
|
doompost_t *column = (doompost_t *)((UINT8 *)doompatch + colofs);
|
||||||
|
@ -643,9 +653,9 @@ void *Picture_GetPatchPixel(
|
||||||
topdelta += prevdelta;
|
topdelta += prevdelta;
|
||||||
prevdelta = topdelta;
|
prevdelta = topdelta;
|
||||||
|
|
||||||
size_t ofs = y - topdelta;
|
size_t ofs = sy - topdelta;
|
||||||
|
|
||||||
if (y >= topdelta && ofs < column->length)
|
if (sy >= topdelta && ofs < column->length)
|
||||||
{
|
{
|
||||||
s8 = (UINT8 *)(column) + 3;
|
s8 = (UINT8 *)(column) + 3;
|
||||||
switch (inbpp)
|
switch (inbpp)
|
||||||
|
@ -672,14 +682,14 @@ void *Picture_GetPatchPixel(
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
column_t *column = &patch->columns[colx];
|
column_t *column = &patch->columns[sx];
|
||||||
for (unsigned i = 0; i < column->num_posts; i++)
|
for (unsigned i = 0; i < column->num_posts; i++)
|
||||||
{
|
{
|
||||||
post_t *post = &column->posts[i];
|
post_t *post = &column->posts[i];
|
||||||
|
|
||||||
size_t ofs = y - post->topdelta;
|
size_t ofs = sy - post->topdelta;
|
||||||
|
|
||||||
if (y >= (INT32)post->topdelta && ofs < post->length)
|
if (sy >= (INT32)post->topdelta && ofs < post->length)
|
||||||
{
|
{
|
||||||
s8 = column->pixels + post->data_offset;
|
s8 = column->pixels + post->data_offset;
|
||||||
switch (inbpp)
|
switch (inbpp)
|
||||||
|
|
162
src/r_textures.c
162
src/r_textures.c
|
@ -79,7 +79,7 @@ static INT32 tidcachelen = 0;
|
||||||
// R_DrawColumnInCache
|
// R_DrawColumnInCache
|
||||||
// Clip and draw a column from a patch into a cached post.
|
// Clip and draw a column from a patch into a cached post.
|
||||||
//
|
//
|
||||||
static inline void R_DrawColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static void R_DrawColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight, UINT8 *opaque_pixels)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source;
|
UINT8 *source;
|
||||||
|
@ -105,7 +105,10 @@ static inline void R_DrawColumnInCache(column_t *column, UINT8 *cache, texpatch_
|
||||||
count = cacheheight - position;
|
count = cacheheight - position;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
|
{
|
||||||
M_Memcpy(cache + position, source, count);
|
M_Memcpy(cache + position, source, count);
|
||||||
|
memset(opaque_pixels + position, true, count);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -113,12 +116,13 @@ static inline void R_DrawColumnInCache(column_t *column, UINT8 *cache, texpatch_
|
||||||
// R_DrawFlippedColumnInCache
|
// R_DrawFlippedColumnInCache
|
||||||
// Similar to R_DrawColumnInCache; it draws the column inverted, however.
|
// Similar to R_DrawColumnInCache; it draws the column inverted, however.
|
||||||
//
|
//
|
||||||
static inline void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight, UINT8 *opaque_pixels)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source, *dest;
|
UINT8 *source, *dest;
|
||||||
INT32 originy = originPatch->originy;
|
INT32 originy = originPatch->originy;
|
||||||
INT32 topdelta;
|
INT32 topdelta;
|
||||||
|
UINT8 *is_opaque;
|
||||||
|
|
||||||
for (unsigned i = 0; i < column->num_posts; i++)
|
for (unsigned i = 0; i < column->num_posts; i++)
|
||||||
{
|
{
|
||||||
|
@ -139,10 +143,15 @@ static inline void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, te
|
||||||
count = cacheheight - position;
|
count = cacheheight - position;
|
||||||
|
|
||||||
dest = cache + position;
|
dest = cache + position;
|
||||||
|
is_opaque = opaque_pixels + position;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
for (; dest < cache + position + count; --source)
|
for (; dest < cache + position + count; --source)
|
||||||
|
{
|
||||||
*dest++ = *source;
|
*dest++ = *source;
|
||||||
|
*is_opaque = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,11 +160,12 @@ static inline void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, te
|
||||||
// R_DrawBlendColumnInCache
|
// R_DrawBlendColumnInCache
|
||||||
// Draws a translucent column into the cache.
|
// Draws a translucent column into the cache.
|
||||||
//
|
//
|
||||||
static inline void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight, UINT8 *opaque_pixels)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source, *dest;
|
UINT8 *source, *dest;
|
||||||
INT32 originy = originPatch->originy;
|
INT32 originy = originPatch->originy;
|
||||||
|
UINT8 *is_opaque;
|
||||||
|
|
||||||
(void)patchheight; // This parameter is unused
|
(void)patchheight; // This parameter is unused
|
||||||
|
|
||||||
|
@ -177,11 +187,15 @@ static inline void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texp
|
||||||
count = cacheheight - position;
|
count = cacheheight - position;
|
||||||
|
|
||||||
dest = cache + position;
|
dest = cache + position;
|
||||||
|
is_opaque = opaque_pixels + position;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
for (; dest < cache + position + count; source++, dest++)
|
for (; dest < cache + position + count; source++, dest++)
|
||||||
if (*source != 0xFF)
|
{
|
||||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||||
|
*is_opaque = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -190,12 +204,13 @@ static inline void R_DrawBlendColumnInCache(column_t *column, UINT8 *cache, texp
|
||||||
// R_DrawBlendFlippedColumnInCache
|
// R_DrawBlendFlippedColumnInCache
|
||||||
// Similar to the one above except that the column is inverted.
|
// Similar to the one above except that the column is inverted.
|
||||||
//
|
//
|
||||||
static inline void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight)
|
static void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_t *originPatch, INT32 cacheheight, INT32 patchheight, UINT8 *opaque_pixels)
|
||||||
{
|
{
|
||||||
INT32 count, position;
|
INT32 count, position;
|
||||||
UINT8 *source, *dest;
|
UINT8 *source, *dest;
|
||||||
INT32 originy = originPatch->originy;
|
INT32 originy = originPatch->originy;
|
||||||
INT32 topdelta;
|
INT32 topdelta;
|
||||||
|
UINT8 *is_opaque;
|
||||||
|
|
||||||
for (unsigned i = 0; i < column->num_posts; i++)
|
for (unsigned i = 0; i < column->num_posts; i++)
|
||||||
{
|
{
|
||||||
|
@ -216,11 +231,15 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cach
|
||||||
count = cacheheight - position;
|
count = cacheheight - position;
|
||||||
|
|
||||||
dest = cache + position;
|
dest = cache + position;
|
||||||
|
is_opaque = opaque_pixels + position;
|
||||||
|
|
||||||
if (count > 0)
|
if (count > 0)
|
||||||
{
|
{
|
||||||
for (; dest < cache + position + count; --source, dest++)
|
for (; dest < cache + position + count; --source, dest++)
|
||||||
if (*source != 0xFF)
|
{
|
||||||
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
*dest = ASTBlendPaletteIndexes(*dest, *source, originPatch->style, originPatch->alpha);
|
||||||
|
*is_opaque = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -231,7 +250,7 @@ static inline void R_DrawBlendFlippedColumnInCache(column_t *column, UINT8 *cach
|
||||||
// Allocate space for full size texture, either single patch or 'composite'
|
// Allocate space for full size texture, either single patch or 'composite'
|
||||||
// Build the full textures from patches.
|
// Build the full textures from patches.
|
||||||
// The texture caching system is a little more hungry of memory, but has
|
// The texture caching system is a little more hungry of memory, but has
|
||||||
// been simplified for the sake of highcolor (lol), dynamic ligthing, & speed.
|
// been simplified for the sake of highcolor, dynamic lighting, & speed.
|
||||||
//
|
//
|
||||||
// This is not optimised, but it's supposed to be executed only once
|
// This is not optimised, but it's supposed to be executed only once
|
||||||
// per level, when enough memory is available.
|
// per level, when enough memory is available.
|
||||||
|
@ -240,15 +259,23 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
{
|
{
|
||||||
UINT8 *block;
|
UINT8 *block;
|
||||||
UINT8 *blocktex;
|
UINT8 *blocktex;
|
||||||
|
UINT8 *temp_block;
|
||||||
texture_t *texture;
|
texture_t *texture;
|
||||||
texpatch_t *patch;
|
texpatch_t *patch;
|
||||||
int x, x1, x2, i, width, height;
|
int x, x1, x2, i, width, height;
|
||||||
size_t blocksize;
|
size_t blocksize;
|
||||||
|
unsigned *column_posts;
|
||||||
|
UINT8 *opaque_pixels;
|
||||||
|
column_t *columns, *temp_columns;
|
||||||
|
post_t *posts, *temp_posts = NULL;
|
||||||
|
size_t total_posts = 0;
|
||||||
|
size_t total_pixels = 0;
|
||||||
|
|
||||||
I_Assert(texnum <= (size_t)numtextures);
|
I_Assert(texnum <= (size_t)numtextures);
|
||||||
texture = textures[texnum];
|
texture = textures[texnum];
|
||||||
I_Assert(texture != NULL);
|
I_Assert(texture != NULL);
|
||||||
|
|
||||||
|
// Just create a composite one
|
||||||
if (texture->type == TEXTURETYPE_FLAT)
|
if (texture->type == TEXTURETYPE_FLAT)
|
||||||
goto multipatch;
|
goto multipatch;
|
||||||
|
|
||||||
|
@ -268,7 +295,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
softwarepatch_t *realpatch = (softwarepatch_t *)pdata;
|
softwarepatch_t *realpatch = (softwarepatch_t *)pdata;
|
||||||
|
|
||||||
#ifndef NO_PNG_LUMPS
|
#ifndef NO_PNG_LUMPS
|
||||||
// TODO: Is it worth converting those?
|
// Not worth converting
|
||||||
if (Picture_IsLumpPNG(pdata, lumplength))
|
if (Picture_IsLumpPNG(pdata, lumplength))
|
||||||
goto multipatch;
|
goto multipatch;
|
||||||
#endif
|
#endif
|
||||||
|
@ -302,9 +329,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
texture->holes = true;
|
texture->holes = true;
|
||||||
texture->flip = patch->flip;
|
texture->flip = patch->flip;
|
||||||
|
|
||||||
size_t total_pixels = 0;
|
|
||||||
size_t total_posts = 0;
|
|
||||||
|
|
||||||
Patch_CalcDataSizes(realpatch, &total_pixels, &total_posts);
|
Patch_CalcDataSizes(realpatch, &total_pixels, &total_posts);
|
||||||
|
|
||||||
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
|
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
|
||||||
|
@ -313,13 +337,12 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
block = Z_Calloc(blocksize, PU_STATIC, &texturecache[texnum]);
|
block = Z_Calloc(blocksize, PU_STATIC, &texturecache[texnum]);
|
||||||
blocktex = block;
|
blocktex = block;
|
||||||
|
|
||||||
UINT8 *pixels = block;
|
columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
|
||||||
column_t *columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
|
posts = (post_t *)(block + (sizeof(UINT8) * total_pixels) + (sizeof(column_t) * texture->width));
|
||||||
post_t *posts = (post_t *)(block + (sizeof(UINT8) * total_pixels) + (sizeof(column_t) * texture->width));
|
|
||||||
|
|
||||||
texturecolumns[texnum] = columns;
|
texturecolumns[texnum] = columns;
|
||||||
|
|
||||||
Patch_MakeColumns(realpatch, texture->width, texture->width, pixels, columns, posts, texture->flip);
|
Patch_MakeColumns(realpatch, texture->width, texture->width, blocktex, columns, posts, texture->flip);
|
||||||
|
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
@ -329,35 +352,28 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
|
|
||||||
// multi-patch textures (or 'composite')
|
// multi-patch textures (or 'composite')
|
||||||
multipatch:
|
multipatch:
|
||||||
texture->holes = false;
|
texture->holes = true;
|
||||||
texture->flip = 0;
|
texture->flip = 0;
|
||||||
|
|
||||||
size_t total_pixels = texture->width * texture->height;
|
// To make things easier, I just allocate WxH always
|
||||||
|
total_pixels = texture->width * texture->height;
|
||||||
|
|
||||||
blocksize = (sizeof(column_t) * texture->width) + (sizeof(UINT8) * total_pixels);
|
opaque_pixels = Z_Calloc(total_pixels * sizeof(UINT8), PU_STATIC, NULL);
|
||||||
texturememory += blocksize;
|
temp_columns = Z_Calloc(sizeof(column_t) * texture->width, PU_STATIC, NULL);
|
||||||
|
temp_block = Z_Calloc(total_pixels, PU_STATIC, NULL);
|
||||||
|
|
||||||
block = Z_Malloc(blocksize, PU_STATIC, &texturecache[texnum]);
|
|
||||||
blocktex = block;
|
|
||||||
memset(blocktex, TRANSPARENTPIXEL, total_pixels); // Transparency hack
|
|
||||||
|
|
||||||
column_t *columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
|
|
||||||
texturecolumns[texnum] = columns;
|
|
||||||
|
|
||||||
size_t data_offset = 0;
|
|
||||||
for (x = 0; x < texture->width; x++)
|
for (x = 0; x < texture->width; x++)
|
||||||
{
|
{
|
||||||
column_t *column = &columns[x];
|
column_t *column = &temp_columns[x];
|
||||||
column->num_posts = 0;
|
column->num_posts = 0;
|
||||||
column->posts = NULL;
|
column->posts = NULL;
|
||||||
column->pixels = blocktex + data_offset;
|
column->pixels = temp_block + (texture->height * x);
|
||||||
data_offset += texture->height;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// Composite the columns together.
|
// Composite the columns together.
|
||||||
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
for (i = 0, patch = texture->patches; i < texture->patchcount; i++, patch++)
|
||||||
{
|
{
|
||||||
static void (*columnDrawer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32); // Column drawing function pointer.
|
static void (*columnDrawer)(column_t *, UINT8 *, texpatch_t *, INT32, INT32, UINT8 *);
|
||||||
if (patch->style != AST_COPY)
|
if (patch->style != AST_COPY)
|
||||||
columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
|
columnDrawer = (patch->flip & 2) ? R_DrawBlendFlippedColumnInCache : R_DrawBlendColumnInCache;
|
||||||
else
|
else
|
||||||
|
@ -376,7 +392,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
else
|
else
|
||||||
#endif
|
#endif
|
||||||
if (texture->type == TEXTURETYPE_FLAT)
|
if (texture->type == TEXTURETYPE_FLAT)
|
||||||
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, 0);
|
realpatch = (patch_t *)Picture_Convert(PICFMT_FLAT, pdata, PICFMT_PATCH, 0, NULL, texture->width, texture->height, 0, 0, PICFLAGS_USE_TRANSPARENTPIXEL);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// If this patch has already been loaded, we just use it from the cache.
|
// If this patch has already been loaded, we just use it from the cache.
|
||||||
|
@ -422,20 +438,90 @@ UINT8 *R_GenerateTexture(size_t texnum)
|
||||||
|
|
||||||
for (; x < x2; x++)
|
for (; x < x2; x++)
|
||||||
{
|
{
|
||||||
column_t *patchcol;
|
INT32 colx;
|
||||||
|
|
||||||
if (patch->flip & 1)
|
if (patch->flip & 1)
|
||||||
patchcol = &realpatch->columns[(x1+width-1)-x];
|
colx = (x1+width-1)-x;
|
||||||
else
|
else
|
||||||
patchcol = &realpatch->columns[x-x1];
|
colx = x-x1;
|
||||||
|
|
||||||
|
column_t *patchcol = &realpatch->columns[colx];
|
||||||
|
|
||||||
if (patchcol->num_posts > 0)
|
if (patchcol->num_posts > 0)
|
||||||
columnDrawer(patchcol, columns[x].pixels, patch, texture->height, height);
|
columnDrawer(patchcol, temp_columns[x].pixels, patch, texture->height, height, &opaque_pixels[x * texture->height]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (free_patch)
|
if (free_patch)
|
||||||
Patch_Free(realpatch);
|
Patch_Free(realpatch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Now write the columns
|
||||||
|
column_posts = Z_Calloc(sizeof(unsigned) * texture->width, PU_STATIC, NULL);
|
||||||
|
|
||||||
|
for (x = 0; x < texture->width; x++)
|
||||||
|
{
|
||||||
|
post_t *post;
|
||||||
|
boolean was_opaque = false;
|
||||||
|
|
||||||
|
column_t *column = &temp_columns[x];
|
||||||
|
|
||||||
|
column_posts[x] = (unsigned)-1;
|
||||||
|
|
||||||
|
for (INT32 y = 0; y < texture->height; y++)
|
||||||
|
{
|
||||||
|
// End span if we have a transparent pixel
|
||||||
|
if (!opaque_pixels[(x * texture->height) + y])
|
||||||
|
{
|
||||||
|
was_opaque = false;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!was_opaque)
|
||||||
|
{
|
||||||
|
total_posts++;
|
||||||
|
|
||||||
|
temp_posts = Z_Realloc(temp_posts, sizeof(post_t) * total_posts, PU_CACHE, NULL);
|
||||||
|
post = &temp_posts[total_posts - 1];
|
||||||
|
post->topdelta = (size_t)y;
|
||||||
|
post->length = 0;
|
||||||
|
post->data_offset = (size_t)y;
|
||||||
|
if (column_posts[x] == (unsigned)-1)
|
||||||
|
column_posts[x] = total_posts - 1;
|
||||||
|
column->num_posts++;
|
||||||
|
}
|
||||||
|
|
||||||
|
was_opaque = true;
|
||||||
|
|
||||||
|
post->length++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels);
|
||||||
|
texturememory += blocksize;
|
||||||
|
|
||||||
|
block = Z_Calloc(blocksize, PU_STATIC, &texturecache[texnum]);
|
||||||
|
blocktex = block;
|
||||||
|
|
||||||
|
memcpy(blocktex, temp_block, total_pixels);
|
||||||
|
|
||||||
|
Z_Free(temp_block);
|
||||||
|
|
||||||
|
columns = (column_t *)(block + (sizeof(UINT8) * total_pixels));
|
||||||
|
posts = (post_t *)(block + (sizeof(UINT8) * total_pixels) + (sizeof(column_t) * texture->width));
|
||||||
|
|
||||||
|
memcpy(columns, temp_columns, sizeof(column_t) * texture->width);
|
||||||
|
memcpy(posts, temp_posts, sizeof(post_t) * total_posts);
|
||||||
|
|
||||||
|
texturecolumns[texnum] = columns;
|
||||||
|
|
||||||
|
for (x = 0; x < texture->width; x++)
|
||||||
|
{
|
||||||
|
column_t *column = &columns[x];
|
||||||
|
if (column->num_posts > 0)
|
||||||
|
column->posts = &posts[column_posts[x]];
|
||||||
|
column->pixels = blocktex + (texture->height * x);
|
||||||
|
}
|
||||||
|
|
||||||
done:
|
done:
|
||||||
// Now that the texture has been built in column cache, it is purgable from zone memory.
|
// Now that the texture has been built in column cache, it is purgable from zone memory.
|
||||||
Z_ChangeTag(block, PU_CACHE);
|
Z_ChangeTag(block, PU_CACHE);
|
||||||
|
|
Loading…
Reference in a new issue