diff --git a/src/hardware/hw_cache.c b/src/hardware/hw_cache.c index 56f5416cf..0022897d6 100644 --- a/src/hardware/hw_cache.c +++ b/src/hardware/hw_cache.c @@ -756,7 +756,7 @@ static void GetMapTexture(INT32 tex, GLMapTexture_t *grtex, GLMipmap_t *mipmap) 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) { @@ -769,7 +769,43 @@ GLMapTexture_t *HWR_GetTexture(INT32 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; } diff --git a/src/hardware/hw_glob.h b/src/hardware/hw_glob.h index 807c70989..5678cd593 100644 --- a/src/hardware/hw_glob.h +++ b/src/hardware/hw_glob.h @@ -120,7 +120,7 @@ void HWR_GetPatch(patch_t *patch); void HWR_GetMappedPatch(patch_t *patch, const UINT8 *colormap); 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_GetRawFlat(lumpnum_t flatlumpnum); diff --git a/src/hardware/hw_main.c b/src/hardware/hw_main.c index 68681295e..91b2e2c50 100644 --- a/src/hardware/hw_main.c +++ b/src/hardware/hw_main.c @@ -951,7 +951,7 @@ static void HWR_RenderMidtexture(INT32 gl_midtexture, float cliplow, float cliph else 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 yscale = FixedToFloat(gl_sidedef->scaley_mid); @@ -1210,7 +1210,7 @@ static void HWR_ProcessSeg(void) // check TOP TEXTURE 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)); yscale = FixedToFloat(abs(gl_sidedef->scaley_top)); @@ -1300,7 +1300,7 @@ static void HWR_ProcessSeg(void) // check BOTTOM TEXTURE 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)); 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) 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); yscale = FixedToFloat(gl_sidedef->scaley_mid); @@ -1588,7 +1588,7 @@ static void HWR_ProcessSeg(void) // -- Monster Iestyn 26/06/18 fixed_t texturevpeg = side->rowoffset + side->offsety_mid; - grTex = HWR_GetTexture(texnum); + grTex = HWR_GetTexture(texnum, true); xscale = FixedToFloat(side->scalex_mid); yscale = FixedToFloat(side->scaley_mid); @@ -1745,7 +1745,7 @@ static void HWR_ProcessSeg(void) // -- Monster Iestyn 26/06/18 fixed_t texturevpeg = side->rowoffset + side->offsety_mid; - grTex = HWR_GetTexture(texnum); + grTex = HWR_GetTexture(texnum, true); xscale = FixedToFloat(side->scalex_mid); yscale = FixedToFloat(side->scaley_mid); @@ -4086,7 +4086,7 @@ static void HWR_CreateDrawNodes(void) else if (sortnode[sortindex[i]].wall) { 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, 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); + HWR_GetTexture(texturetranslation[skytexture], false); + if (cv_glskydome.value) { FTransform dometransform; @@ -5081,8 +5083,6 @@ static void HWR_DrawSkyBackground(player_t *player) HWR_SetTransformAiming(&dometransform, player, false); dometransform.angley = (float)((viewangle-ANGLE_270)>>ANGLETOFINESHIFT)*(360.0f/(float)FINEANGLES); - HWR_GetTexture(texturetranslation[skytexture]); - if (gl_sky.texture != texturetranslation[skytexture]) { HWR_ClearSkyDome(); @@ -5102,7 +5102,6 @@ static void HWR_DrawSkyBackground(player_t *player) float aspectratio; float angleturn; - HWR_GetTexture(texturetranslation[skytexture]); aspectratio = (float)vid.width/(float)vid.height; //Hurdler: the sky is the only texture who need 4.0f instead of 1.0 diff --git a/src/hardware/r_opengl/r_opengl.c b/src/hardware/r_opengl/r_opengl.c index 75a92c2fb..fa6b48b4f 100644 --- a/src/hardware/r_opengl/r_opengl.c +++ b/src/hardware/r_opengl/r_opengl.c @@ -1556,8 +1556,41 @@ EXPORT void HWRAPI(UpdateTexture) (GLMipmap_t *pTexInfo) } else if (pTexInfo->format == GL_TEXFMT_RGBA) { - // Directly upload the texture data without any kind of conversion. - ptex = pImgData; + if (pTexInfo->flags & TF_CHROMAKEYED) + { + 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) { diff --git a/src/r_defs.h b/src/r_defs.h index da4dd2d70..a363d99ff 100644 --- a/src/r_defs.h +++ b/src/r_defs.h @@ -60,6 +60,8 @@ typedef UINT8 lighttable_t; #define CMF_FADEFULLBRIGHTSPRITES 1 #define CMF_FOG 4 +#define TEXTURE_255_IS_TRANSPARENT + // ExtraColormap type. Use for extra_colormaps from now on. typedef struct extracolormap_s { diff --git a/src/r_draw.h b/src/r_draw.h index 77588d7de..6a6ab2db1 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -154,9 +154,11 @@ void R_VideoErase(size_t ofs, INT32 count); void R_DrawColumn_8(void); void R_DrawColumnClamped_8(void); +void R_Draw2sMultiPatchColumn_8(void); void R_DrawShadeColumn_8(void); void R_DrawTranslucentColumn_8(void); void R_DrawTranslucentColumnClamped_8(void); +void R_Draw2sMultiPatchTranslucentColumn_8(void); void R_DrawDropShadowColumn_8(void); void R_DrawTranslatedColumn_8(void); void R_DrawTranslatedTranslucentColumn_8(void); diff --git a/src/r_draw8.c b/src/r_draw8.c index 735127f88..2011e4640 100644 --- a/src/r_draw8.c +++ b/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 Experiment to make software go faster. Taken from the Boom source */ diff --git a/src/r_segs.c b/src/r_segs.c index 75c95aa93..8e9368baf 100644 --- a/src/r_segs.c +++ b/src/r_segs.c @@ -94,6 +94,98 @@ transnum_t R_GetLinedefTransTable(fixed_t alpha) 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) { size_t pindex; @@ -181,7 +273,16 @@ void R_RenderMaskedSegRange(drawseg_t *ds, INT32 x1, INT32 x2) // Texture must be cached 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; else 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 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; else 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; - // 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) + // Skip if texture is multipatch + if (textures[texnum]->transparency) { - if (fuzzy) - colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + // 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 (fuzzy) + colfunc = colfuncs[COLDRAWFUNC_FUZZY]; + else + colfunc = colfuncs[BASEDRAWFUNC]; + } else - colfunc = colfuncs[BASEDRAWFUNC]; - } - else - { - // Otherwise use column drawers with extra checks - if (fuzzy) - colfunc = R_DrawTranslucentColumnClamped_8; - else - colfunc = R_DrawColumnClamped_8; + { + // Otherwise use column drawers with extra checks + if (fuzzy) + colfunc = colfuncs[COLDRAWFUNC_CLAMPEDTRANS]; + else + colfunc = colfuncs[COLDRAWFUNC_CLAMPED]; + } } } diff --git a/src/r_textures.c b/src/r_textures.c index 5d3fe24db..6e01d5641 100644 --- a/src/r_textures.c +++ b/src/r_textures.c @@ -147,9 +147,9 @@ static void R_DrawFlippedColumnInCache(column_t *column, UINT8 *cache, texpatch_ 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; } } @@ -295,7 +295,6 @@ UINT8 *R_GenerateTexture(size_t texnum) UINT16 lumpnum = patch->lump; UINT8 *pdata; softwarepatch_t *realpatch; - boolean holey = false; #ifndef NO_PNG_LUMPS UINT8 header[PNG_HEADER_SIZE]; @@ -310,9 +309,11 @@ UINT8 *R_GenerateTexture(size_t texnum) pdata = W_CacheLumpNumPwad(wadnum, lumpnum, PU_CACHE); realpatch = (softwarepatch_t *)pdata; + texture->transparency = false; + // Check the patch for holes. if (texture->width > SHORT(realpatch->width) || texture->height > SHORT(realpatch->height)) - holey = true; + texture->transparency = true; else { UINT8 *colofs = (UINT8 *)realpatch->columnofs; @@ -332,12 +333,12 @@ UINT8 *R_GenerateTexture(size_t texnum) col = (doompost_t *)((UINT8 *)col + col->length + 4); } 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 (holey) + if (texture->transparency) { 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_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++) { column_t *column = &temp_columns[x]; @@ -474,13 +484,27 @@ UINT8 *R_GenerateTexture(size_t texnum) // Now write the columns 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++) { post_t *post = NULL; - boolean was_opaque = false; 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; for (INT32 y = 0; y < texture->height; y++) @@ -510,6 +534,7 @@ UINT8 *R_GenerateTexture(size_t texnum) post->length++; } +#endif } blocksize = (sizeof(column_t) * texture->width) + (sizeof(post_t) * total_posts) + (sizeof(UINT8) * total_pixels); diff --git a/src/r_textures.h b/src/r_textures.h index eb68ec09f..7e1588851 100644 --- a/src/r_textures.h +++ b/src/r_textures.h @@ -54,6 +54,7 @@ typedef struct char name[8]; UINT32 hash; UINT8 type; // TEXTURETYPE_* + boolean transparency; INT16 width, height; UINT8 flip; // 1 = flipx, 2 = flipy, 3 = both void *flat; // The texture, as a flat. diff --git a/src/screen.c b/src/screen.c index 9a82a1561..014a20117 100644 --- a/src/screen.c +++ b/src/screen.c @@ -112,6 +112,10 @@ void SCR_SetDrawFuncs(void) colfuncs[COLDRAWFUNC_SHADE] = R_DrawShadeColumn_8; colfuncs[COLDRAWFUNC_SHADOWED] = R_DrawColumnShadowed_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; spanfuncs[SPANDRAWFUNC_TRANS] = R_DrawTranslucentSpan_8; diff --git a/src/screen.h b/src/screen.h index 8b952e553..e23e8cbd6 100644 --- a/src/screen.h +++ b/src/screen.h @@ -97,6 +97,10 @@ enum COLDRAWFUNC_SHADE, COLDRAWFUNC_SHADOWED, COLDRAWFUNC_TRANSTRANS, + COLDRAWFUNC_CLAMPED, + COLDRAWFUNC_CLAMPEDTRANS, + COLDRAWFUNC_TWOSMULTIPATCH, + COLDRAWFUNC_TWOSMULTIPATCHTRANS, COLDRAWFUNC_FOG, COLDRAWFUNC_MAX