Merge branch 'texture-index-255-is-transparent' into 'next'

Use palette index 255 for transparency

Closes #1259

See merge request STJr/SRB2!2471
This commit is contained in:
sphere 2024-06-24 10:24:13 +00:00
commit 2ac80138a8
11 changed files with 418 additions and 66 deletions

View file

@ -450,15 +450,10 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
texture = textures[texnum]; texture = textures[texnum];
mipmap->flags = TF_WRAPXY;
mipmap->width = (UINT16)texture->width;
mipmap->height = (UINT16)texture->height;
mipmap->format = textureformat;
blockwidth = texture->width; blockwidth = texture->width;
blockheight = texture->height; blockheight = texture->height;
blocksize = (blockwidth * blockheight); blocksize = blockwidth * blockheight;
block = MakeBlock(&grtex->mipmap); block = MakeBlock(mipmap);
// 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++)
@ -488,7 +483,7 @@ static void HWR_GenerateTexture(INT32 texnum, GLMapTexture_t *grtex, GLMipmap_t
realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH); realpatch = W_CachePatchNumPwad(wadnum, lumpnum, PU_PATCH);
} }
HWR_DrawTexturePatchInCache(&grtex->mipmap, blockwidth, blockheight, texture, patch, realpatch); HWR_DrawTexturePatchInCache(mipmap, blockwidth, blockheight, texture, patch, realpatch);
if (free_patch) if (free_patch)
Patch_Free(realpatch); Patch_Free(realpatch);
@ -680,25 +675,24 @@ void HWR_InitMapTextures(void)
gl_maptexturesloaded = false; gl_maptexturesloaded = false;
} }
static void DeleteTextureMipmap(GLMipmap_t *grMipmap) static void DeleteTextureMipmap(GLMipmap_t *grMipmap, boolean delete_mipmap)
{ {
HWD.pfnDeleteTexture(grMipmap); HWD.pfnDeleteTexture(grMipmap);
// Chroma-keyed textures do not own their texture data, so do not free it if (delete_mipmap)
if (!(grMipmap->flags & TF_CHROMAKEYED))
Z_Free(grMipmap->data); Z_Free(grMipmap->data);
} }
static void FreeMapTexture(GLMapTexture_t *tex) static void FreeMapTexture(GLMapTexture_t *tex, boolean delete_chromakeys)
{ {
if (tex->mipmap.nextcolormap) if (tex->mipmap.nextcolormap)
{ {
DeleteTextureMipmap(tex->mipmap.nextcolormap); DeleteTextureMipmap(tex->mipmap.nextcolormap, delete_chromakeys);
free(tex->mipmap.nextcolormap); free(tex->mipmap.nextcolormap);
tex->mipmap.nextcolormap = NULL; tex->mipmap.nextcolormap = NULL;
} }
DeleteTextureMipmap(&tex->mipmap); DeleteTextureMipmap(&tex->mipmap, true);
} }
void HWR_FreeMapTextures(void) void HWR_FreeMapTextures(void)
@ -707,8 +701,8 @@ void HWR_FreeMapTextures(void)
for (i = 0; i < gl_numtextures; i++) for (i = 0; i < gl_numtextures; i++)
{ {
FreeMapTexture(&gl_textures[i]); FreeMapTexture(&gl_textures[i], true);
FreeMapTexture(&gl_flats[i]); FreeMapTexture(&gl_flats[i], false);
} }
// now the heap don't have any 'user' pointing to our // now the heap don't have any 'user' pointing to our
@ -741,22 +735,7 @@ void HWR_LoadMapTextures(size_t pnumtextures)
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
// Make sure texture is downloaded and set it as the source // Make sure texture is downloaded and set it as the source
// -------------------------------------------------------------------------- // --------------------------------------------------------------------------
static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap) GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
{
// Generate texture if missing from the cache
if (!mipmap->data && !mipmap->downloaded)
HWR_GenerateTexture(tex, grtex, mipmap);
// If hardware does not have the texture, then call pfnSetTexture to upload it
if (!mipmap->downloaded)
HWD.pfnSetTexture(mipmap);
HWR_SetCurrentTexture(mipmap);
// The system-memory data can be purged now.
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
}
GLMapTexture_t *HWR_GetTexture(INT32 tex)
{ {
if (tex < 0 || tex >= (signed)gl_numtextures) if (tex < 0 || tex >= (signed)gl_numtextures)
{ {
@ -769,7 +748,46 @@ GLMapTexture_t *HWR_GetTexture(INT32 tex)
GLMapTexture_t *grtex = &gl_textures[tex]; GLMapTexture_t *grtex = &gl_textures[tex];
GetMapTexture(tex, grtex, &grtex->mipmap); GLMipmap_t *grMipmap = &grtex->mipmap;
GLMipmap_t *originalMipmap = grMipmap;
if (!originalMipmap->downloaded)
{
originalMipmap->flags = TF_WRAPXY;
originalMipmap->width = (UINT16)textures[tex]->width;
originalMipmap->height = (UINT16)textures[tex]->height;
originalMipmap->format = textureformat;
}
// If chroma-keyed, create or use a different mipmap for the variant
if (chromakeyed && !textures[tex]->transparency)
{
// Allocate it if it wasn't already
if (!originalMipmap->nextcolormap)
{
GLMipmap_t *newMipmap = calloc(1, sizeof (*grMipmap));
if (newMipmap == NULL)
I_Error("%s: Out of memory", "HWR_GetTexture");
newMipmap->flags = originalMipmap->flags | TF_CHROMAKEYED;
newMipmap->width = originalMipmap->width;
newMipmap->height = originalMipmap->height;
newMipmap->format = originalMipmap->format;
originalMipmap->nextcolormap = newMipmap;
}
// Generate, upload and bind the variant texture instead of the original one
grMipmap = originalMipmap->nextcolormap;
}
if (!grMipmap->data)
HWR_GenerateTexture(tex, grtex, grMipmap);
if (!grMipmap->downloaded)
HWD.pfnSetTexture(grMipmap);
HWR_SetCurrentTexture(grMipmap);
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
return grtex; return grtex;
} }

View file

@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch);
void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap); void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap);
void HWR_GetFadeMask(lumpnum_t fademasklumpnum); void HWR_GetFadeMask(lumpnum_t fademasklumpnum);
GLMapTexture_t *HWR_GetTexture(INT32 tex); GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed);
void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed); void HWR_GetLevelFlat(levelflat_t *levelflat, boolean chromakeyed);
void HWR_GetRawFlat(lumpnum_t flatlumpnum); void HWR_GetRawFlat(lumpnum_t flatlumpnum);

View file

@ -951,7 +951,7 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph
else else
repeats = 1; repeats = 1;
GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture); GLMapTexture_t *grTex = HWR_GetTexture(gl_midtexture, true);
float xscale = FixedToFloat(gl_sidedef->scalex_mid); float xscale = FixedToFloat(gl_sidedef->scalex_mid);
float yscale = FixedToFloat(gl_sidedef->scaley_mid); float yscale = FixedToFloat(gl_sidedef->scaley_mid);
@ -1210,7 +1210,7 @@ static void HWR_ProcessSeg(void)
// check TOP TEXTURE // check TOP TEXTURE
if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture) if ((worldhighslope < worldtopslope || worldhigh < worldtop) && gl_toptexture)
{ {
grTex = HWR_GetTexture(gl_toptexture); grTex = HWR_GetTexture(gl_toptexture, false);
xscale = FixedToFloat(abs(gl_sidedef->scalex_top)); xscale = FixedToFloat(abs(gl_sidedef->scalex_top));
yscale = FixedToFloat(abs(gl_sidedef->scaley_top)); yscale = FixedToFloat(abs(gl_sidedef->scaley_top));
@ -1300,7 +1300,7 @@ static void HWR_ProcessSeg(void)
// check BOTTOM TEXTURE // check BOTTOM TEXTURE
if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture) if ((worldlowslope > worldbottomslope || worldlow > worldbottom) && gl_bottomtexture)
{ {
grTex = HWR_GetTexture(gl_bottomtexture); grTex = HWR_GetTexture(gl_bottomtexture, false);
xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom)); xscale = FixedToFloat(abs(gl_sidedef->scalex_bottom));
yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom)); yscale = FixedToFloat(abs(gl_sidedef->scaley_bottom));
@ -1414,7 +1414,7 @@ static void HWR_ProcessSeg(void)
// Single sided line... Deal only with the middletexture (if one exists) // Single sided line... Deal only with the middletexture (if one exists)
if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL) if (gl_midtexture && gl_linedef->special != SPECIAL_HORIZON_LINE) // (Ignore horizon line for OGL)
{ {
grTex = HWR_GetTexture(gl_midtexture); grTex = HWR_GetTexture(gl_midtexture, false);
xscale = FixedToFloat(gl_sidedef->scalex_mid); xscale = FixedToFloat(gl_sidedef->scalex_mid);
yscale = FixedToFloat(gl_sidedef->scaley_mid); yscale = FixedToFloat(gl_sidedef->scaley_mid);
@ -1588,7 +1588,7 @@ static void HWR_ProcessSeg(void)
// -- Monster Iestyn 26/06/18 // -- Monster Iestyn 26/06/18
fixed_t texturevpeg = side->rowoffset + side->offsety_mid; fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum, true);
xscale = FixedToFloat(side->scalex_mid); xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_mid); yscale = FixedToFloat(side->scaley_mid);
@ -1745,7 +1745,7 @@ static void HWR_ProcessSeg(void)
// -- Monster Iestyn 26/06/18 // -- Monster Iestyn 26/06/18
fixed_t texturevpeg = side->rowoffset + side->offsety_mid; fixed_t texturevpeg = side->rowoffset + side->offsety_mid;
grTex = HWR_GetTexture(texnum); grTex = HWR_GetTexture(texnum, true);
xscale = FixedToFloat(side->scalex_mid); xscale = FixedToFloat(side->scalex_mid);
yscale = FixedToFloat(side->scaley_mid); yscale = FixedToFloat(side->scaley_mid);
@ -4086,7 +4086,7 @@ static void HWR_CreateDrawNodes(void)
else if (sortnode[sortindex[i]].wall) else if (sortnode[sortindex[i]].wall)
{ {
if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture)) if (!(sortnode[sortindex[i]].wall->blend & PF_NoTexture))
HWR_GetTexture(sortnode[sortindex[i]].wall->texnum); HWR_GetTexture(sortnode[sortindex[i]].wall->texnum, true);
HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall, HWR_RenderWall(sortnode[sortindex[i]].wall->wallVerts, &sortnode[sortindex[i]].wall->Surf, sortnode[sortindex[i]].wall->blend, sortnode[sortindex[i]].wall->fogwall,
sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap); sortnode[sortindex[i]].wall->lightlevel, sortnode[sortindex[i]].wall->wallcolormap);
} }
@ -5066,6 +5066,8 @@ static void HWR_DrawSkyBackground(player_t *player)
HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated); HWD.pfnSetBlend(PF_Translucent|PF_NoDepthTest|PF_Modulated);
HWR_GetTexture(texturetranslation[skytexture], false);
if (cv_glskydome.value) if (cv_glskydome.value)
{ {
FTransform dometransform; FTransform dometransform;
@ -5081,8 +5083,6 @@ static void HWR_DrawSkyBackground(player_t *player)
HWR_SetTransformAiming(&dometransform, player, false); HWR_SetTransformAiming(&dometransform, player, false);
dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES);
HWR_GetTexture(texturetranslation[skytexture]);
if (gl_sky.texture != texturetranslation[skytexture]) if (gl_sky.texture != texturetranslation[skytexture])
{ {
HWR_ClearSkyDome(); HWR_ClearSkyDome();
@ -5102,7 +5102,6 @@ static void HWR_DrawSkyBackground(player_t *player)
float aspectratio; float aspectratio;
float angleturn; float angleturn;
HWR_GetTexture(texturetranslation[skytexture]);
aspectratio = (float)vid.width/(float)vid.height; aspectratio = (float)vid.width/(float)vid.height;
//Hurdler: the sky is the only texture who need 4.0f instead of 1.0 //Hurdler: the sky is the only texture who need 4.0f instead of 1.0

View file

@ -60,6 +60,8 @@ typedef UINT8 lighttable_t;
#define CMF_FADEFULLBRIGHTSPRITES 1 #define CMF_FADEFULLBRIGHTSPRITES 1
#define CMF_FOG 4 #define CMF_FOG 4
#define TEXTURE_255_IS_TRANSPARENT
// ExtraColormap type. Use for extra_colormaps from now on. // ExtraColormap type. Use for extra_colormaps from now on.
typedef struct extracolormap_s typedef struct extracolormap_s
{ {

View file

@ -154,9 +154,11 @@ void R_VideoErase(size_t ofs, INT32 count);
void R_DrawColumn_8(void); void R_DrawColumn_8(void);
void R_DrawColumnClamped_8(void); void R_DrawColumnClamped_8(void);
void R_Draw2sMultiPatchColumn_8(void);
void R_DrawShadeColumn_8(void); void R_DrawShadeColumn_8(void);
void R_DrawTranslucentColumn_8(void); void R_DrawTranslucentColumn_8(void);
void R_DrawTranslucentColumnClamped_8(void); void R_DrawTranslucentColumnClamped_8(void);
void R_Draw2sMultiPatchTranslucentColumn_8(void);
void R_DrawDropShadowColumn_8(void); void R_DrawDropShadowColumn_8(void);
void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedColumn_8(void);
void R_DrawTranslatedTranslucentColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void);

View file

@ -192,6 +192,189 @@ void R_DrawColumnClamped_8(void)
} }
} }
void R_Draw2sMultiPatchColumn_8(void)
{
INT32 count;
register UINT8 *dest;
register fixed_t frac;
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0) // Zero length, column does not exceed a pixel.
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
return;
#endif
// Framebuffer destination address.
dest = &topleft[dc_yl*vid.width + dc_x];
count++;
// Determine scaling, which is the only mapping to be done.
fracstep = dc_iscale;
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
{
register const UINT8 *source = dc_source;
register const lighttable_t *colormap = dc_colormap;
register INT32 heightmask = dc_texheight-1;
register UINT8 val;
if (dc_texheight & heightmask) // not a power of 2 -- killough
{
heightmask++;
heightmask <<= FRACBITS;
if (frac < 0)
while ((frac += heightmask) < 0);
else
while (frac >= heightmask)
frac -= heightmask;
do
{
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
val = source[frac>>FRACBITS];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest += vid.width;
// Avoid overflow.
if (fracstep > 0x7FFFFFFF - frac)
frac += fracstep - heightmask;
else
frac += fracstep;
while (frac >= heightmask)
frac -= heightmask;
} while (--count);
}
else
{
while ((count -= 2) >= 0) // texture height is a power of 2
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest += vid.width;
frac += fracstep;
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = colormap[val];
}
}
}
}
void R_Draw2sMultiPatchTranslucentColumn_8(void)
{
INT32 count;
register UINT8 *dest;
register fixed_t frac;
fixed_t fracstep;
count = dc_yh - dc_yl;
if (count < 0) // Zero length, column does not exceed a pixel.
return;
#ifdef RANGECHECK
if ((unsigned)dc_x >= (unsigned)vid.width || dc_yl < 0 || dc_yh >= vid.height)
return;
#endif
// Framebuffer destination address.
dest = &topleft[dc_yl*vid.width + dc_x];
count++;
// Determine scaling, which is the only mapping to be done.
fracstep = dc_iscale;
frac = dc_texturemid + FixedMul((dc_yl << FRACBITS) - centeryfrac, fracstep);
// Inner loop that does the actual texture mapping, e.g. a DDA-like scaling.
// This is as fast as it gets.
{
register const UINT8 *source = dc_source;
register const UINT8 *transmap = dc_transmap;
register const lighttable_t *colormap = dc_colormap;
register INT32 heightmask = dc_texheight-1;
register UINT8 val;
if (dc_texheight & heightmask) // not a power of 2 -- killough
{
heightmask++;
heightmask <<= FRACBITS;
if (frac < 0)
while ((frac += heightmask) < 0);
else
while (frac >= heightmask)
frac -= heightmask;
do
{
// Re-map color indices from wall texture column
// using a lighting/special effects LUT.
// heightmask is the Tutti-Frutti fix
val = source[frac>>FRACBITS];
if (val != TRANSPARENTPIXEL)
*dest = *(transmap + (colormap[val]<<8) + (*dest));
dest += vid.width;
// Avoid overflow.
if (fracstep > 0x7FFFFFFF - frac)
frac += fracstep - heightmask;
else
frac += fracstep;
while (frac >= heightmask)
frac -= heightmask;
} while (--count);
}
else
{
while ((count -= 2) >= 0) // texture height is a power of 2
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = *(transmap + (colormap[val]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = *(transmap + (colormap[val]<<8) + (*dest));
dest += vid.width;
frac += fracstep;
}
if (count & 1)
{
val = source[(frac>>FRACBITS) & heightmask];
if (val != TRANSPARENTPIXEL)
*dest = *(transmap + (colormap[val]<<8) + (*dest));
}
}
}
}
/** \brief The R_DrawShadeColumn_8 function /** \brief The R_DrawShadeColumn_8 function
Experiment to make software go faster. Taken from the Boom source Experiment to make software go faster. Taken from the Boom source
*/ */

View file

@ -94,6 +94,98 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha)
return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1); return (20*(FRACUNIT - alpha - 1) + FRACUNIT) >> (FRACBITS+1);
} }
// If we have a multi-patch texture on a 2sided wall (rare) then we draw
// it using R_DrawColumn, else we draw it using R_DrawMaskedColumn, this
// way we don't have to store extra post_t info with each column for
// multi-patch textures. They are not normally needed as multi-patch
// textures don't have holes in it. At least not for now.
static void R_Render2sidedMultiPatchColumn(column_t *column, unsigned lengthcol)
{
INT32 topscreen, bottomscreen;
post_t *post = &column->posts[0];
if (!post->length)
return;
topscreen = sprtopscreen;
bottomscreen = topscreen + spryscale * lengthcol;
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
{
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
dc_yh = (windowbottom - 1)>>FRACBITS;
}
if (dc_yh >= mfloorclip[dc_x])
dc_yh = mfloorclip[dc_x] - 1;
if (dc_yl <= mceilingclip[dc_x])
dc_yl = mceilingclip[dc_x] + 1;
if (dc_yl >= vid.height || dc_yh < 0)
return;
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
{
dc_source = column->pixels + post->data_offset;
dc_postlength = post->length;
if (colfunc == colfuncs[BASEDRAWFUNC])
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCH])();
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
(colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS])();
else
colfunc();
}
}
static void R_RenderFlipped2sidedMultiPatchColumn(column_t *column, unsigned lengthcol)
{
INT32 topscreen, bottomscreen;
void (*localcolfunc)(void);
post_t *post = &column->posts[0];
if (!post->length)
return;
topscreen = sprtopscreen;
bottomscreen = topscreen + spryscale * lengthcol;
dc_yl = (sprtopscreen+FRACUNIT-1)>>FRACBITS;
dc_yh = (bottomscreen-1)>>FRACBITS;
if (windowtop != INT32_MAX && windowbottom != INT32_MAX)
{
dc_yl = ((windowtop + FRACUNIT)>>FRACBITS);
dc_yh = (windowbottom - 1)>>FRACBITS;
}
if (dc_yh >= mfloorclip[dc_x])
dc_yh = mfloorclip[dc_x] - 1;
if (dc_yl <= mceilingclip[dc_x])
dc_yl = mceilingclip[dc_x] + 1;
if (dc_yl >= vid.height || dc_yh < 0)
return;
if (dc_yl <= dc_yh && dc_yh < vid.height && dc_yh > 0)
{
dc_postlength = post->length;
if (colfunc == colfuncs[BASEDRAWFUNC])
localcolfunc = colfuncs[COLDRAWFUNC_TWOSMULTIPATCH];
else if (colfunc == colfuncs[COLDRAWFUNC_FUZZY])
localcolfunc = colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS];
else
localcolfunc = colfunc;
R_DrawFlippedPost(column->pixels + post->data_offset, post->length, localcolfunc);
}
}
void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
{ {
size_t pindex; size_t pindex;
@ -181,7 +273,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2)
// Texture must be cached // Texture must be cached
R_CheckTextureCache(texnum); R_CheckTextureCache(texnum);
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info in SRB2
if (!textures[texnum]->transparency)
{
if (vertflip) // vertically flipped? if (vertflip) // vertically flipped?
colfunc_2s = R_RenderFlipped2sidedMultiPatchColumn;
else
colfunc_2s = R_Render2sidedMultiPatchColumn;
}
else if (vertflip) // vertically flipped?
colfunc_2s = R_DrawFlippedMaskedColumn; colfunc_2s = R_DrawFlippedMaskedColumn;
else else
colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture colfunc_2s = R_DrawMaskedColumn; // render the usual 2sided single-patch packed texture
@ -811,7 +912,16 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
// Texture must be cached // Texture must be cached
R_CheckTextureCache(texnum); R_CheckTextureCache(texnum);
// handle case where multipatch texture is drawn on a 2sided wall, multi-patch textures
// are not stored per-column with post info in SRB2
if (!textures[texnum]->transparency)
{
if (vertflip) // vertically flipped? if (vertflip) // vertically flipped?
colfunc_2s = R_RenderFlipped2sidedMultiPatchColumn;
else
colfunc_2s = R_Render2sidedMultiPatchColumn;
}
else if (vertflip) // vertically flipped?
colfunc_2s = R_DrawRepeatFlippedMaskedColumn; colfunc_2s = R_DrawRepeatFlippedMaskedColumn;
else else
colfunc_2s = R_DrawRepeatMaskedColumn; colfunc_2s = R_DrawRepeatMaskedColumn;
@ -894,6 +1004,9 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
dc_iscale = 0xffffffffu / (unsigned)spryscale; dc_iscale = 0xffffffffu / (unsigned)spryscale;
// Skip if texture is multipatch
if (textures[texnum]->transparency)
{
// Column has a single post and it matches the texture height, use regular column drawers // Column has a single post and it matches the texture height, use regular column drawers
if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight) if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight)
{ {
@ -906,9 +1019,10 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
{ {
// Otherwise use column drawers with extra checks // Otherwise use column drawers with extra checks
if (fuzzy) if (fuzzy)
colfunc = R_DrawTranslucentColumnClamped_8; colfunc = colfuncs[COLDRAWFUNC_CLAMPEDTRANS];
else else
colfunc = R_DrawColumnClamped_8; colfunc = colfuncs[COLDRAWFUNC_CLAMPED];
}
} }
} }

View file

@ -147,9 +147,9 @@ static void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_
if (count > 0) if (count > 0)
{ {
for (; dest < cache + position + count; --source, is_opaque++) for (; dest < cache + position + count; --source, dest++, is_opaque++)
{ {
*dest++ = *source; *dest = *source;
*is_opaque = true; *is_opaque = true;
} }
} }
@ -295,7 +295,6 @@ UINT8 *R_GenerateTexture(size_t texnum)
UINT16 lumpnum = patch->lump; UINT16 lumpnum = patch->lump;
UINT8 *pdata; UINT8 *pdata;
softwarepatch_t *realpatch; softwarepatch_t *realpatch;
boolean holey = false;
#ifndef NO_PNG_LUMPS #ifndef NO_PNG_LUMPS
UINT8 header[PNG_HEADER_SIZE]; UINT8 header[PNG_HEADER_SIZE];
@ -310,9 +309,11 @@ UINT8 *R_GenerateTexture(size_t texnum)
pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE);
realpatch = (softwarepatch_t *)pdata; realpatch = (softwarepatch_t *)pdata;
texture->transparency = false;
// Check the patch for holes. // Check the patch for holes.
if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height))
holey = true; texture->transparency = true;
else else
{ {
UINT8 *colofs = (UINT8 *)realpatch->columnofs; UINT8 *colofs = (UINT8 *)realpatch->columnofs;
@ -332,12 +333,12 @@ UINT8 *R_GenerateTexture(size_t texnum)
col = (doompost_t *)((UINT8 *)col + col->length + 4); col = (doompost_t *)((UINT8 *)col + col->length + 4);
} }
if (y < texture->height) if (y < texture->height)
holey = true; // this texture is HOLEy! D: texture->transparency = true; // this texture is HOLEy! D:
} }
} }
// If the patch uses transparency, we have to save it this way. // If the patch uses transparency, we have to save it this way.
if (holey) if (texture->transparency)
{ {
texture->flip = patch->flip; texture->flip = patch->flip;
@ -378,6 +379,15 @@ UINT8 *R_GenerateTexture(size_t texnum)
temp_columns = Z_Calloc(sizeof(column_t) * texture->width, PU_STATIC, NULL); temp_columns = Z_Calloc(sizeof(column_t) * texture->width, PU_STATIC, NULL);
temp_block = Z_Calloc(total_pixels, PU_STATIC, NULL); temp_block = Z_Calloc(total_pixels, PU_STATIC, NULL);
#ifdef TEXTURE_255_IS_TRANSPARENT
texture->transparency = false;
// Transparency hack
memset(temp_block, TRANSPARENTPIXEL, total_pixels);
#else
texture->transparency = true;
#endif
for (x = 0; x < texture->width; x++) for (x = 0; x < texture->width; x++)
{ {
column_t *column = &temp_columns[x]; column_t *column = &temp_columns[x];
@ -474,13 +484,27 @@ UINT8 *R_GenerateTexture(size_t texnum)
// Now write the columns // Now write the columns
column_posts = Z_Calloc(sizeof(unsigned) * texture->width, PU_STATIC, NULL); column_posts = Z_Calloc(sizeof(unsigned) * texture->width, PU_STATIC, NULL);
#ifdef TEXTURE_255_IS_TRANSPARENT
total_posts = texture->width;
temp_posts = Z_Realloc(temp_posts, sizeof(post_t) * total_posts, PU_CACHE, NULL);
#endif
for (x = 0; x < texture->width; x++) for (x = 0; x < texture->width; x++)
{ {
post_t *post = NULL; post_t *post = NULL;
boolean was_opaque = false;
column_t *column = &temp_columns[x]; column_t *column = &temp_columns[x];
#ifdef TEXTURE_255_IS_TRANSPARENT
post = &temp_posts[x];
post->topdelta = 0;
post->length = texture->height;
post->data_offset = 0;
column_posts[x] = x;
column->num_posts = 1;
#else
boolean was_opaque = false;
column_posts[x] = (unsigned)-1; column_posts[x] = (unsigned)-1;
for (INT32 y = 0; y < texture->height; y++) for (INT32 y = 0; y < texture->height; y++)
@ -510,6 +534,7 @@ UINT8 *R_GenerateTexture(size_t texnum)
post->length++; post->length++;
} }
#endif
} }
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);

View file

@ -54,6 +54,7 @@ typedef struct
char name[8]; char name[8];
UINT32 hash; UINT32 hash;
UINT8 type; // TEXTURETYPE_* UINT8 type; // TEXTURETYPE_*
boolean transparency;
INT16 width, height; INT16 width, height;
UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both
void *flat; // The texture, as a flat. void *flat; // The texture, as a flat.

View file

@ -112,6 +112,10 @@ void SCR_SetDrawFuncs(void)
colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8;
colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8; colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_8;
colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8; colfuncs[COLDRAWFUNC_TRANSTRANS] = R_DrawTranslatedTranslucentColumn_8;
colfuncs[COLDRAWFUNC_CLAMPED] = R_DrawColumnClamped_8;
colfuncs[COLDRAWFUNC_CLAMPEDTRANS] = R_DrawTranslucentColumnClamped_8;
colfuncs[COLDRAWFUNC_TWOSMULTIPATCH] = R_Draw2sMultiPatchColumn_8;
colfuncs[COLDRAWFUNC_TWOSMULTIPATCHTRANS] = R_Draw2sMultiPatchTranslucentColumn_8;
colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8; colfuncs[COLDRAWFUNC_FOG] = R_DrawFogColumn_8;
spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8;

View file

@ -97,6 +97,10 @@ enum
COLDRAWFUNC_SHADE, COLDRAWFUNC_SHADE,
COLDRAWFUNC_SHADOWED, COLDRAWFUNC_SHADOWED,
COLDRAWFUNC_TRANSTRANS, COLDRAWFUNC_TRANSTRANS,
COLDRAWFUNC_CLAMPED,
COLDRAWFUNC_CLAMPEDTRANS,
COLDRAWFUNC_TWOSMULTIPATCH,
COLDRAWFUNC_TWOSMULTIPATCHTRANS,
COLDRAWFUNC_FOG, COLDRAWFUNC_FOG,
COLDRAWFUNC_MAX COLDRAWFUNC_MAX