From e2a018227f3392dbcfe47e8e22c30258316f23fe Mon Sep 17 00:00:00 2001 From: Randy Heit Date: Thu, 9 Aug 2012 04:31:31 +0000 Subject: [PATCH] - Added additive blending for floors and ceilings. SVN r3813 (trunk) --- src/r_bsp.cpp | 4 +- src/r_draw.cpp | 150 ++++++++++++++++++++++++++++++++++++++++++++++++ src/r_draw.h | 6 ++ src/r_plane.cpp | 38 ++++++++---- 4 files changed, 185 insertions(+), 13 deletions(-) diff --git a/src/r_bsp.cpp b/src/r_bsp.cpp index 689977911..c7f6d8497 100644 --- a/src/r_bsp.cpp +++ b/src/r_bsp.cpp @@ -1185,7 +1185,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::floor), floorlightlevel + r_actualextralight, // killough 3/16/98 frontsector->GetAlpha(sector_t::floor), - !!(frontsector->GetFlags(sector_t::floor) & PLANEF_ADDITIVE), + !!(fakeFloor->flags && FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), @@ -1250,7 +1250,7 @@ void R_Subsector (subsector_t *sub) frontsector->GetTexture(sector_t::ceiling), ceilinglightlevel + r_actualextralight, // killough 4/11/98 frontsector->GetAlpha(sector_t::ceiling), - !!(frontsector->GetFlags(sector_t::ceiling) & PLANEF_ADDITIVE), + !!(fakeFloor->flags && FF_ADDITIVETRANS), frontsector->GetXOffset(position), // killough 3/7/98 frontsector->GetYOffset(position), // killough 3/7/98 frontsector->GetXScale(position), diff --git a/src/r_draw.cpp b/src/r_draw.cpp index cc9bc9b26..60a0e46e4 100644 --- a/src/r_draw.cpp +++ b/src/r_draw.cpp @@ -79,6 +79,8 @@ void (*R_DrawSpan)(void); void (*R_DrawSpanMasked)(void); void (*R_DrawSpanTranslucent)(void); void (*R_DrawSpanMaskedTranslucent)(void); +void (*R_DrawSpanAddClamp)(void); +void (*R_DrawSpanMaskedAddClamp)(void); void (STACK_ARGS *rt_map4cols)(int,int,int); // @@ -1324,6 +1326,152 @@ void R_DrawSpanMaskedTranslucentP_C (void) } } +void R_DrawSpanAddClampP_C (void) +{ + dsfixed_t xfrac; + dsfixed_t yfrac; + dsfixed_t xstep; + dsfixed_t ystep; + BYTE* dest; + const BYTE* source = ds_source; + const BYTE* colormap = ds_colormap; + int count; + int spot; + DWORD *fg2rgb = dc_srcblend; + DWORD *bg2rgb = dc_destblend; + + xfrac = ds_xfrac; + yfrac = ds_yfrac; + + dest = ylookup[ds_y] + ds_x1 + dc_destorg; + + count = ds_x2 - ds_x1 + 1; + + xstep = ds_xstep; + ystep = ds_ystep; + + if (ds_xbits == 6 && ds_ybits == 6) + { + // 64x64 is the most common case by far, so special case it. + do + { + spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); + DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest++ = RGB32k[0][0][a & (a>>15)]; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } + else + { + BYTE yshift = 32 - ds_ybits; + BYTE xshift = yshift - ds_xbits; + int xmask = ((1 << ds_xbits) - 1) << ds_ybits; + do + { + spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + DWORD a = fg2rgb[colormap[source[spot]]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest++ = RGB32k[0][0][a & (a>>15)]; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } +} + +void R_DrawSpanMaskedAddClampP_C (void) +{ + dsfixed_t xfrac; + dsfixed_t yfrac; + dsfixed_t xstep; + dsfixed_t ystep; + BYTE* dest; + const BYTE* source = ds_source; + const BYTE* colormap = ds_colormap; + int count; + int spot; + DWORD *fg2rgb = dc_srcblend; + DWORD *bg2rgb = dc_destblend; + + xfrac = ds_xfrac; + yfrac = ds_yfrac; + + dest = ylookup[ds_y] + ds_x1 + dc_destorg; + + count = ds_x2 - ds_x1 + 1; + + xstep = ds_xstep; + ystep = ds_ystep; + + if (ds_xbits == 6 && ds_ybits == 6) + { + // 64x64 is the most common case by far, so special case it. + do + { + BYTE texdata; + + spot = ((xfrac>>(32-6-6))&(63*64)) + (yfrac>>(32-6)); + texdata = source[spot]; + if (texdata != 0) + { + DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest = RGB32k[0][0][a & (a>>15)]; + } + dest++; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } + else + { + BYTE yshift = 32 - ds_ybits; + BYTE xshift = yshift - ds_xbits; + int xmask = ((1 << ds_xbits) - 1) << ds_ybits; + do + { + BYTE texdata; + + spot = ((xfrac >> xshift) & xmask) + (yfrac >> yshift); + texdata = source[spot]; + if (texdata != 0) + { + DWORD a = fg2rgb[colormap[texdata]] + bg2rgb[*dest]; + DWORD b = a; + + a |= 0x01f07c1f; + b &= 0x40100400; + a &= 0x3fffffff; + b = b - (b >> 5); + a |= b; + *dest = RGB32k[0][0][a & (a>>15)]; + } + dest++; + xfrac += xstep; + yfrac += ystep; + } while (--count); + } +} + // [RH] Just fill a span with a color void R_FillSpan (void) { @@ -2040,6 +2188,8 @@ void R_InitColumnDrawers () #endif R_DrawSpanTranslucent = R_DrawSpanTranslucentP_C; R_DrawSpanMaskedTranslucent = R_DrawSpanMaskedTranslucentP_C; + R_DrawSpanAddClamp = R_DrawSpanAddClampP_C; + R_DrawSpanMaskedAddClamp = R_DrawSpanMaskedAddClampP_C; } // [RH] Choose column drawers in a single place diff --git a/src/r_draw.h b/src/r_draw.h index ace6bde0b..c8a7f2d47 100644 --- a/src/r_draw.h +++ b/src/r_draw.h @@ -106,6 +106,12 @@ extern void (*R_DrawSpanTranslucent)(void); // Span drawing for masked, translucent textures. extern void (*R_DrawSpanMaskedTranslucent)(void); +// Span drawing for translucent, additive textures. +extern void (*R_DrawSpanAddClamp)(void); + +// Span drawing for masked, translucent, additive textures. +extern void (*R_DrawSpanMaskedAddClamp)(void); + // [RH] Span blit into an interleaved intermediate buffer extern void (*R_DrawColumnHoriz)(void); void R_DrawMaskedColumnHoriz (const BYTE *column, const FTexture::Span *spans); diff --git a/src/r_plane.cpp b/src/r_plane.cpp index 0652121f7..0e8237cb6 100644 --- a/src/r_plane.cpp +++ b/src/r_plane.cpp @@ -596,7 +596,6 @@ visplane_t *R_FindPlane (const secplane_t &height, FTextureID picnum, int lightl else sky = 0; // not skyflatnum so it can't be a sky skybox = NULL; alpha = FRACUNIT; - additive = false; } // New visplane algorithm uses hash table -- killough @@ -1047,7 +1046,7 @@ void R_DrawHeightPlanes(fixed_t height) viewy = pl->viewy; viewangle = pl->viewangle; MirrorFlags = pl->MirrorFlags; - R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, false, true); + R_DrawSinglePlane (pl, pl->sky & 0x7FFFFFFF, pl->Additive, true); } } } @@ -1528,16 +1527,24 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske else plane_shade = true; - // Additive not supported yet because the drawer function doesn't look like it can handle it. if (spanfunc != R_FillSpan) { if (masked) { - if (alpha < OPAQUE) + if (alpha < OPAQUE || additive) { - spanfunc = R_DrawSpanMaskedTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + if (!additive) + { + spanfunc = R_DrawSpanMaskedTranslucent; + dc_srcblend = Col2RGB8[alpha>>10]; + dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + } + else + { + spanfunc = R_DrawSpanMaskedAddClamp; + dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; + dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + } } else { @@ -1546,11 +1553,20 @@ void R_DrawNormalPlane (visplane_t *pl, fixed_t alpha, bool additive, bool maske } else { - if (alpha < OPAQUE) + if (alpha < OPAQUE || additive) { - spanfunc = R_DrawSpanTranslucent; - dc_srcblend = Col2RGB8[alpha>>10]; - dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + if (!additive) + { + spanfunc = R_DrawSpanTranslucent; + dc_srcblend = Col2RGB8[alpha>>10]; + dc_destblend = Col2RGB8[(OPAQUE-alpha)>>10]; + } + else + { + spanfunc = R_DrawSpanAddClamp; + dc_srcblend = Col2RGB8_LessPrecision[alpha>>10]; + dc_destblend = Col2RGB8_LessPrecision[FRACUNIT>>10]; + } } else {