mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-21 20:11:12 +00:00
Use palette index 255 for transparency
This commit is contained in:
parent
7cc0dd1eff
commit
dd5f030b16
12 changed files with 440 additions and 37 deletions
|
@ -756,7 +756,7 @@ static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap)
|
||||||
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
|
Z_ChangeTag(mipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||||
}
|
}
|
||||||
|
|
||||||
GLMapTexture_t *HWR_GetTexture(INT32 tex)
|
GLMapTexture_t *HWR_GetTexture(INT32 tex, boolean chromakeyed)
|
||||||
{
|
{
|
||||||
if (tex < 0 || tex >= (signed)gl_numtextures)
|
if (tex < 0 || tex >= (signed)gl_numtextures)
|
||||||
{
|
{
|
||||||
|
@ -769,7 +769,43 @@ 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->data && !originalMipmap->downloaded)
|
||||||
|
HWR_GenerateTexture(tex, grtex, originalMipmap);
|
||||||
|
|
||||||
|
// If chroma-keyed, create or use a different mipmap for the variant
|
||||||
|
if (chromakeyed && !textures[tex]->transparency && originalMipmap->data)
|
||||||
|
{
|
||||||
|
// 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_GetLevelFlat");
|
||||||
|
|
||||||
|
newMipmap->flags = TF_WRAPXY | TF_CHROMAKEYED;
|
||||||
|
newMipmap->width = (UINT16)textures[tex]->width;
|
||||||
|
newMipmap->height = (UINT16)textures[tex]->height;
|
||||||
|
newMipmap->format = textureformat;
|
||||||
|
originalMipmap->nextcolormap = newMipmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Upload and bind the variant texture instead of the original one
|
||||||
|
grMipmap = originalMipmap->nextcolormap;
|
||||||
|
|
||||||
|
// Use the original texture's pixel data
|
||||||
|
// It can just be a pointer to it, since the r_opengl backend deals with the pixels
|
||||||
|
// that are supposed to be transparent.
|
||||||
|
grMipmap->data = originalMipmap->data;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!grMipmap->downloaded)
|
||||||
|
HWD.pfnSetTexture(grMipmap);
|
||||||
|
HWR_SetCurrentTexture(grMipmap);
|
||||||
|
|
||||||
|
Z_ChangeTag(grMipmap->data, PU_HWRCACHE_UNLOCKED);
|
||||||
|
|
||||||
return grtex;
|
return grtex;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -1556,8 +1556,41 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo)
|
||||||
}
|
}
|
||||||
else if (pTexInfo->format == GL_TEXFMT_RGBA)
|
else if (pTexInfo->format == GL_TEXFMT_RGBA)
|
||||||
{
|
{
|
||||||
// Directly upload the texture data without any kind of conversion.
|
if (pTexInfo->flags & TF_CHROMAKEYED)
|
||||||
ptex = pImgData;
|
{
|
||||||
|
RGBA_t *color = (RGBA_t *)pTexInfo->data;
|
||||||
|
|
||||||
|
AllocTextureBuffer(pTexInfo);
|
||||||
|
ptex = tex = textureBuffer;
|
||||||
|
|
||||||
|
for (j = 0; j < h; j++)
|
||||||
|
{
|
||||||
|
for (i = 0; i < w; i++)
|
||||||
|
{
|
||||||
|
if (color->rgba == myPaletteData[HWR_PATCHES_CHROMAKEY_COLORINDEX].rgba)
|
||||||
|
{
|
||||||
|
tex[w*j+i].s.red = 0;
|
||||||
|
tex[w*j+i].s.green = 0;
|
||||||
|
tex[w*j+i].s.blue = 0;
|
||||||
|
tex[w*j+i].s.alpha = 0;
|
||||||
|
pTexInfo->flags |= TF_TRANSPARENT; // there is a hole in it
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
tex[w*j+i].s.red = color->s.red;
|
||||||
|
tex[w*j+i].s.green = color->s.green;
|
||||||
|
tex[w*j+i].s.blue = color->s.blue;
|
||||||
|
tex[w*j+i].s.alpha = color->s.alpha;
|
||||||
|
}
|
||||||
|
color++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Directly upload the texture data without any kind of conversion.
|
||||||
|
ptex = pImgData;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88)
|
else if (pTexInfo->format == GL_TEXFMT_ALPHA_INTENSITY_88)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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
|
||||||
{
|
{
|
||||||
|
|
|
@ -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);
|
||||||
|
|
183
src/r_draw8.c
183
src/r_draw8.c
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
|
144
src/r_segs.c
144
src/r_segs.c
|
@ -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);
|
||||||
|
|
||||||
if (vertflip) // vertically flipped?
|
// 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?
|
||||||
|
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);
|
||||||
|
|
||||||
if (vertflip) // vertically flipped?
|
// 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?
|
||||||
|
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,21 +1004,25 @@ void R_RenderThickSideRange(drawseg_t *ds, INT32 x1, INT32 x2, ffloor_t *pfloor)
|
||||||
{
|
{
|
||||||
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
dc_iscale = 0xffffffffu / (unsigned)spryscale;
|
||||||
|
|
||||||
// Column has a single post and it matches the texture height, use regular column drawers
|
// Skip if texture is multipatch
|
||||||
if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight)
|
if (textures[texnum]->transparency)
|
||||||
{
|
{
|
||||||
if (fuzzy)
|
// Column has a single post and it matches the texture height, use regular column drawers
|
||||||
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
if (col->num_posts == 1 && col->posts[0].topdelta == 0 && col->posts[0].length == (unsigned)dc_texheight)
|
||||||
|
{
|
||||||
|
if (fuzzy)
|
||||||
|
colfunc = colfuncs[COLDRAWFUNC_FUZZY];
|
||||||
|
else
|
||||||
|
colfunc = colfuncs[BASEDRAWFUNC];
|
||||||
|
}
|
||||||
else
|
else
|
||||||
colfunc = colfuncs[BASEDRAWFUNC];
|
{
|
||||||
}
|
// Otherwise use column drawers with extra checks
|
||||||
else
|
if (fuzzy)
|
||||||
{
|
colfunc = colfuncs[COLDRAWFUNC_CLAMPEDTRANS];
|
||||||
// Otherwise use column drawers with extra checks
|
else
|
||||||
if (fuzzy)
|
colfunc = colfuncs[COLDRAWFUNC_CLAMPED];
|
||||||
colfunc = R_DrawTranslucentColumnClamped_8;
|
}
|
||||||
else
|
|
||||||
colfunc = R_DrawColumnClamped_8;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
|
|
|
@ -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.
|
||||||
|
|
|
@ -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;
|
||||||
|
|
|
@ -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
|
||||||
|
|
Loading…
Reference in a new issue