Move colfunc family of globals into a DrawerStyle class and localize its usage

This commit is contained in:
Magnus Norddahl 2017-01-28 07:08:59 +01:00
parent f9eb06a22e
commit 5f38b15635
17 changed files with 416 additions and 391 deletions

View File

@ -70,12 +70,6 @@ namespace swrenderer
short zeroarray[MAXWIDTH]; short zeroarray[MAXWIDTH];
short screenheightarray[MAXWIDTH]; short screenheightarray[MAXWIDTH];
DrawerFunc colfunc;
DrawerFunc basecolfunc;
DrawerFunc fuzzcolfunc;
DrawerFunc transcolfunc;
DrawerFunc spanfunc;
namespace drawerargs namespace drawerargs
{ {
int dc_pitch; int dc_pitch;
@ -160,11 +154,6 @@ namespace swrenderer
active_drawers = &tc_drawers; active_drawers = &tc_drawers;
else else
active_drawers = &pal_drawers; active_drawers = &pal_drawers;
colfunc = basecolfunc = &SWPixelFormatDrawers::DrawColumn;
fuzzcolfunc = &SWPixelFormatDrawers::DrawFuzzColumn;
transcolfunc = &SWPixelFormatDrawers::DrawTranslatedColumn;
spanfunc = &SWPixelFormatDrawers::DrawSpan;
} }
void R_InitShadeMaps() void R_InitShadeMaps()
@ -252,9 +241,318 @@ namespace swrenderer
} }
} }
namespace void R_SetColorMapLight(FSWColormap *base_colormap, float light, int shade)
{ {
bool R_SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags) using namespace drawerargs;
dc_fcolormap = base_colormap;
if (r_swtruecolor)
{
dc_shade_constants.light_red = dc_fcolormap->Color.r * 256 / 255;
dc_shade_constants.light_green = dc_fcolormap->Color.g * 256 / 255;
dc_shade_constants.light_blue = dc_fcolormap->Color.b * 256 / 255;
dc_shade_constants.light_alpha = dc_fcolormap->Color.a * 256 / 255;
dc_shade_constants.fade_red = dc_fcolormap->Fade.r;
dc_shade_constants.fade_green = dc_fcolormap->Fade.g;
dc_shade_constants.fade_blue = dc_fcolormap->Fade.b;
dc_shade_constants.fade_alpha = dc_fcolormap->Fade.a;
dc_shade_constants.desaturate = MIN(abs(dc_fcolormap->Desaturate), 255) * 255 / 256;
dc_shade_constants.simple_shade = (dc_fcolormap->Color.d == 0x00ffffff && dc_fcolormap->Fade.d == 0x00000000 && dc_fcolormap->Desaturate == 0);
dc_colormap = base_colormap->Maps;
dc_light = LIGHTSCALE(light, shade);
}
else
{
dc_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
}
}
void R_SetDSColorMapLight(FSWColormap *base_colormap, float light, int shade)
{
using namespace drawerargs;
ds_fcolormap = base_colormap;
if (r_swtruecolor)
{
ds_shade_constants.light_red = ds_fcolormap->Color.r * 256 / 255;
ds_shade_constants.light_green = ds_fcolormap->Color.g * 256 / 255;
ds_shade_constants.light_blue = ds_fcolormap->Color.b * 256 / 255;
ds_shade_constants.light_alpha = ds_fcolormap->Color.a * 256 / 255;
ds_shade_constants.fade_red = ds_fcolormap->Fade.r;
ds_shade_constants.fade_green = ds_fcolormap->Fade.g;
ds_shade_constants.fade_blue = ds_fcolormap->Fade.b;
ds_shade_constants.fade_alpha = ds_fcolormap->Fade.a;
ds_shade_constants.desaturate = MIN(abs(ds_fcolormap->Desaturate), 255) * 255 / 256;
ds_shade_constants.simple_shade = (ds_fcolormap->Color.d == 0x00ffffff && ds_fcolormap->Fade.d == 0x00000000 && ds_fcolormap->Desaturate == 0);
ds_colormap = base_colormap->Maps;
ds_light = LIGHTSCALE(light, shade);
}
else
{
ds_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT);
}
}
void R_SetTranslationMap(lighttable_t *translation)
{
using namespace drawerargs;
if (r_swtruecolor)
{
dc_fcolormap = nullptr;
dc_colormap = nullptr;
dc_translation = translation;
dc_shade_constants.light_red = 256;
dc_shade_constants.light_green = 256;
dc_shade_constants.light_blue = 256;
dc_shade_constants.light_alpha = 256;
dc_shade_constants.fade_red = 0;
dc_shade_constants.fade_green = 0;
dc_shade_constants.fade_blue = 0;
dc_shade_constants.fade_alpha = 256;
dc_shade_constants.desaturate = 0;
dc_shade_constants.simple_shade = true;
dc_light = 0;
}
else
{
dc_fcolormap = nullptr;
dc_colormap = translation;
}
}
void R_SetSpanTexture(FTexture *tex)
{
using namespace drawerargs;
tex->GetWidth();
ds_xbits = tex->WidthBits;
ds_ybits = tex->HeightBits;
if ((1 << ds_xbits) > tex->GetWidth())
{
ds_xbits--;
}
if ((1 << ds_ybits) > tex->GetHeight())
{
ds_ybits--;
}
ds_source = r_swtruecolor ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels();
ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1;
}
void R_SetSpanColormap(FDynamicColormap *colormap, int shade)
{
R_SetDSColorMapLight(colormap, 0, shade);
}
void R_UpdateFuzzPos()
{
using namespace drawerargs;
dc_yl = MAX(dc_yl, 1);
dc_yh = MIN(dc_yh, fuzzviewheight);
if (dc_yl <= dc_yh)
fuzzpos = (fuzzpos + dc_yh - dc_yl + 1) % FUZZTABLE;
}
void DrawerStyle::DrawMaskedColumn(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
{
using namespace drawerargs;
// Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom.
if (r_swtruecolor && !drawer_needs_pal_input) // To do: add support to R_DrawColumnHoriz_rgba
{
DrawMaskedColumnBgra(x, iscale, tex, col, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, unmasked);
return;
}
dc_x = x;
dc_iscale = iscale;
dc_textureheight = tex->GetHeight();
const FTexture::Span *span;
const BYTE *column;
if (r_swtruecolor && !drawer_needs_pal_input)
column = (const BYTE *)tex->GetColumnBgra(col >> FRACBITS, &span);
else
column = tex->GetColumn(col >> FRACBITS, &span);
FTexture::Span unmaskedSpan[2];
if (unmasked)
{
span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight();
unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0;
}
int pixelsize = r_swtruecolor ? 4 : 1;
while (span->Length != 0)
{
const int length = span->Length;
const int top = span->TopOffset;
// calculate unclipped screen coordinates for post
dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
if (sprflipvert)
{
swapvalues(dc_yl, dc_yh);
}
if (dc_yh >= mfloorclip[dc_x])
{
dc_yh = mfloorclip[dc_x] - 1;
}
if (dc_yl < mceilingclip[dc_x])
{
dc_yl = mceilingclip[dc_x];
}
if (dc_yl <= dc_yh)
{
dc_texturefrac = FLOAT2FIXED((dc_yl + 0.5 - sprtopscreen) / spryscale);
dc_source = column;
dc_source2 = nullptr;
dc_dest = (ylookup[dc_yl] + dc_x) * pixelsize + dc_destorg;
dc_count = dc_yh - dc_yl + 1;
fixed_t maxfrac = ((top + length) << FRACBITS) - 1;
dc_texturefrac = MAX(dc_texturefrac, 0);
dc_texturefrac = MIN(dc_texturefrac, maxfrac);
if (dc_iscale > 0)
dc_count = MIN(dc_count, (maxfrac - dc_texturefrac + dc_iscale - 1) / dc_iscale);
else if (dc_iscale < 0)
dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale));
(R_Drawers()->*colfunc)();
}
span++;
}
}
void DrawerStyle::DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
{
using namespace drawerargs;
dc_x = x;
dc_iscale = iscale;
// Normalize to 0-1 range:
double uv_stepd = FIXED2DBL(dc_iscale);
double v_step = uv_stepd / tex->GetHeight();
// Convert to uint32:
dc_iscale = (uint32_t)(v_step * (1 << 30));
// Texture mipmap and filter selection:
fixed_t xoffset = col;
double xmagnitude = 1.0; // To do: pass this into R_DrawMaskedColumn
double ymagnitude = fabs(uv_stepd);
double magnitude = MAX(ymagnitude, xmagnitude);
double min_lod = -1000.0;
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
bool magnifying = lod < 0.0f;
int mipmap_offset = 0;
int mip_width = tex->GetWidth();
int mip_height = tex->GetHeight();
uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width);
if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1)
{
int level = (int)lod;
while (level > 0 && mip_width > 1 && mip_height > 1)
{
mipmap_offset += mip_width * mip_height;
level--;
mip_width = MAX(mip_width >> 1, 1);
mip_height = MAX(mip_height >> 1, 1);
}
}
xoffset = (xpos >> FRACBITS) * mip_width;
const uint32_t *pixels = tex->GetPixelsBgra() + mipmap_offset;
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
if (filter_nearest)
{
xoffset = MAX(MIN(xoffset, (mip_width << FRACBITS) - 1), 0);
int tx = xoffset >> FRACBITS;
dc_source = (BYTE*)(pixels + tx * mip_height);
dc_source2 = nullptr;
dc_textureheight = mip_height;
dc_texturefracx = 0;
}
else
{
xoffset = MAX(MIN(xoffset - (FRACUNIT / 2), (mip_width << FRACBITS) - 1), 0);
int tx0 = xoffset >> FRACBITS;
int tx1 = MIN(tx0 + 1, mip_width - 1);
dc_source = (BYTE*)(pixels + tx0 * mip_height);
dc_source2 = (BYTE*)(pixels + tx1 * mip_height);
dc_textureheight = mip_height;
dc_texturefracx = (xoffset >> (FRACBITS - 4)) & 15;
}
// Grab the posts we need to draw
const FTexture::Span *span;
tex->GetColumnBgra(col >> FRACBITS, &span);
FTexture::Span unmaskedSpan[2];
if (unmasked)
{
span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight();
unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0;
}
// Draw each span post
while (span->Length != 0)
{
const int length = span->Length;
const int top = span->TopOffset;
// calculate unclipped screen coordinates for post
dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
if (sprflipvert)
{
swapvalues(dc_yl, dc_yh);
}
if (dc_yh >= mfloorclip[dc_x])
{
dc_yh = mfloorclip[dc_x] - 1;
}
if (dc_yl < mceilingclip[dc_x])
{
dc_yl = mceilingclip[dc_x];
}
if (dc_yl <= dc_yh)
{
dc_dest = (ylookup[dc_yl] + dc_x) * 4 + dc_destorg;
dc_count = dc_yh - dc_yl + 1;
double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight();
dc_texturefrac = (uint32_t)(v * (1 << 30));
(R_Drawers()->*colfunc)();
}
span++;
}
}
bool DrawerStyle::SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags)
{ {
using namespace drawerargs; using namespace drawerargs;
@ -380,7 +678,7 @@ namespace swrenderer
} }
} }
fixed_t GetAlpha(int type, fixed_t alpha) fixed_t DrawerStyle::GetAlpha(int type, fixed_t alpha)
{ {
switch (type) switch (type)
{ {
@ -391,9 +689,8 @@ namespace swrenderer
default: return 0; default: return 0;
} }
} }
}
bool R_SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap) bool DrawerStyle::SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap)
{ {
using namespace drawerargs; using namespace drawerargs;
@ -495,19 +792,19 @@ namespace swrenderer
R_SetColorMapLight(&identitycolormap, 0, 0); R_SetColorMapLight(&identitycolormap, 0, 0);
} }
if (!R_SetBlendFunc(style.BlendOp, fglevel, bglevel, style.Flags)) if (!DrawerStyle::SetBlendFunc(style.BlendOp, fglevel, bglevel, style.Flags))
{ {
return false; return false;
} }
return true; return true;
} }
bool R_SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap) bool DrawerStyle::SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap)
{ {
return R_SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color, basecolormap); return SetPatchStyle(style, FLOAT2FIXED(alpha), translation, color, basecolormap);
} }
DrawerFunc R_GetTransMaskDrawer() DrawerFunc DrawerStyle::GetTransMaskDrawer()
{ {
if (colfunc == &SWPixelFormatDrawers::DrawAddColumn) if (colfunc == &SWPixelFormatDrawers::DrawAddColumn)
{ {
@ -528,314 +825,61 @@ namespace swrenderer
return nullptr; return nullptr;
} }
void R_SetColorMapLight(FSWColormap *base_colormap, float light, int shade) void DrawerStyle::SetSpanStyle(bool masked, bool additive, fixed_t alpha)
{ {
using namespace drawerargs; using namespace drawerargs;
dc_fcolormap = base_colormap; if (masked)
if (r_swtruecolor)
{ {
dc_shade_constants.light_red = dc_fcolormap->Color.r * 256 / 255; if (alpha < OPAQUE || additive)
dc_shade_constants.light_green = dc_fcolormap->Color.g * 256 / 255; {
dc_shade_constants.light_blue = dc_fcolormap->Color.b * 256 / 255; if (!additive)
dc_shade_constants.light_alpha = dc_fcolormap->Color.a * 256 / 255; {
dc_shade_constants.fade_red = dc_fcolormap->Fade.r; spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedTranslucent;
dc_shade_constants.fade_green = dc_fcolormap->Fade.g; dc_srcblend = Col2RGB8[alpha >> 10];
dc_shade_constants.fade_blue = dc_fcolormap->Fade.b; dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
dc_shade_constants.fade_alpha = dc_fcolormap->Fade.a; dc_srcalpha = alpha;
dc_shade_constants.desaturate = MIN(abs(dc_fcolormap->Desaturate), 255) * 255 / 256; dc_destalpha = OPAQUE - alpha;
dc_shade_constants.simple_shade = (dc_fcolormap->Color.d == 0x00ffffff && dc_fcolormap->Fade.d == 0x00000000 && dc_fcolormap->Desaturate == 0);
dc_colormap = base_colormap->Maps;
dc_light = LIGHTSCALE(light, shade);
} }
else else
{ {
dc_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT); spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedAddClamp;
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
dc_srcalpha = alpha;
dc_destalpha = FRACUNIT;
} }
} }
void R_SetDSColorMapLight(FSWColormap *base_colormap, float light, int shade)
{
using namespace drawerargs;
ds_fcolormap = base_colormap;
if (r_swtruecolor)
{
ds_shade_constants.light_red = ds_fcolormap->Color.r * 256 / 255;
ds_shade_constants.light_green = ds_fcolormap->Color.g * 256 / 255;
ds_shade_constants.light_blue = ds_fcolormap->Color.b * 256 / 255;
ds_shade_constants.light_alpha = ds_fcolormap->Color.a * 256 / 255;
ds_shade_constants.fade_red = ds_fcolormap->Fade.r;
ds_shade_constants.fade_green = ds_fcolormap->Fade.g;
ds_shade_constants.fade_blue = ds_fcolormap->Fade.b;
ds_shade_constants.fade_alpha = ds_fcolormap->Fade.a;
ds_shade_constants.desaturate = MIN(abs(ds_fcolormap->Desaturate), 255) * 255 / 256;
ds_shade_constants.simple_shade = (ds_fcolormap->Color.d == 0x00ffffff && ds_fcolormap->Fade.d == 0x00000000 && ds_fcolormap->Desaturate == 0);
ds_colormap = base_colormap->Maps;
ds_light = LIGHTSCALE(light, shade);
}
else else
{ {
ds_colormap = base_colormap->Maps + (GETPALOOKUP(light, shade) << COLORMAPSHIFT); spanfunc = &SWPixelFormatDrawers::DrawSpanMasked;
} }
} }
void R_SetTranslationMap(lighttable_t *translation)
{
using namespace drawerargs;
if (r_swtruecolor)
{
dc_fcolormap = nullptr;
dc_colormap = nullptr;
dc_translation = translation;
dc_shade_constants.light_red = 256;
dc_shade_constants.light_green = 256;
dc_shade_constants.light_blue = 256;
dc_shade_constants.light_alpha = 256;
dc_shade_constants.fade_red = 0;
dc_shade_constants.fade_green = 0;
dc_shade_constants.fade_blue = 0;
dc_shade_constants.fade_alpha = 256;
dc_shade_constants.desaturate = 0;
dc_shade_constants.simple_shade = true;
dc_light = 0;
}
else else
{ {
dc_fcolormap = nullptr; if (alpha < OPAQUE || additive)
dc_colormap = translation;
}
}
void R_SetSpanTexture(FTexture *tex)
{ {
using namespace drawerargs; if (!additive)
tex->GetWidth();
ds_xbits = tex->WidthBits;
ds_ybits = tex->HeightBits;
if ((1 << ds_xbits) > tex->GetWidth())
{ {
ds_xbits--; spanfunc = &SWPixelFormatDrawers::DrawSpanTranslucent;
} dc_srcblend = Col2RGB8[alpha >> 10];
if ((1 << ds_ybits) > tex->GetHeight()) dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
{ dc_srcalpha = alpha;
ds_ybits--; dc_destalpha = OPAQUE - alpha;
}
ds_source = r_swtruecolor ? (const uint8_t*)tex->GetPixelsBgra() : tex->GetPixels();
ds_source_mipmapped = tex->Mipmapped() && tex->GetWidth() > 1 && tex->GetHeight() > 1;
}
void R_SetSpanColormap(FDynamicColormap *colormap, int shade)
{
R_SetDSColorMapLight(colormap, 0, shade);
}
void R_UpdateFuzzPos()
{
using namespace drawerargs;
dc_yl = MAX(dc_yl, 1);
dc_yh = MIN(dc_yh, fuzzviewheight);
if (dc_yl <= dc_yh)
fuzzpos = (fuzzpos + dc_yh - dc_yl + 1) % FUZZTABLE;
}
void R_DrawMaskedColumn(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
{
using namespace drawerargs;
// Handle the linear filtered version in a different function to reduce chances of merge conflicts from zdoom.
if (r_swtruecolor && !drawer_needs_pal_input) // To do: add support to R_DrawColumnHoriz_rgba
{
R_DrawMaskedColumnBgra(x, iscale, tex, col, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, unmasked);
return;
}
dc_x = x;
dc_iscale = iscale;
dc_textureheight = tex->GetHeight();
const FTexture::Span *span;
const BYTE *column;
if (r_swtruecolor && !drawer_needs_pal_input)
column = (const BYTE *)tex->GetColumnBgra(col >> FRACBITS, &span);
else
column = tex->GetColumn(col >> FRACBITS, &span);
FTexture::Span unmaskedSpan[2];
if (unmasked)
{
span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight();
unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0;
}
int pixelsize = r_swtruecolor ? 4 : 1;
while (span->Length != 0)
{
const int length = span->Length;
const int top = span->TopOffset;
// calculate unclipped screen coordinates for post
dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
if (sprflipvert)
{
swapvalues(dc_yl, dc_yh);
}
if (dc_yh >= mfloorclip[dc_x])
{
dc_yh = mfloorclip[dc_x] - 1;
}
if (dc_yl < mceilingclip[dc_x])
{
dc_yl = mceilingclip[dc_x];
}
if (dc_yl <= dc_yh)
{
dc_texturefrac = FLOAT2FIXED((dc_yl + 0.5 - sprtopscreen) / spryscale);
dc_source = column;
dc_source2 = nullptr;
dc_dest = (ylookup[dc_yl] + dc_x) * pixelsize + dc_destorg;
dc_count = dc_yh - dc_yl + 1;
fixed_t maxfrac = ((top + length) << FRACBITS) - 1;
dc_texturefrac = MAX(dc_texturefrac, 0);
dc_texturefrac = MIN(dc_texturefrac, maxfrac);
if (dc_iscale > 0)
dc_count = MIN(dc_count, (maxfrac - dc_texturefrac + dc_iscale - 1) / dc_iscale);
else if (dc_iscale < 0)
dc_count = MIN(dc_count, (dc_texturefrac - dc_iscale) / (-dc_iscale));
(R_Drawers()->*colfunc)();
}
span++;
}
}
void R_DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t col, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked)
{
using namespace drawerargs;
dc_x = x;
dc_iscale = iscale;
// Normalize to 0-1 range:
double uv_stepd = FIXED2DBL(dc_iscale);
double v_step = uv_stepd / tex->GetHeight();
// Convert to uint32:
dc_iscale = (uint32_t)(v_step * (1 << 30));
// Texture mipmap and filter selection:
fixed_t xoffset = col;
double xmagnitude = 1.0; // To do: pass this into R_DrawMaskedColumn
double ymagnitude = fabs(uv_stepd);
double magnitude = MAX(ymagnitude, xmagnitude);
double min_lod = -1000.0;
double lod = MAX(log2(magnitude) + r_lod_bias, min_lod);
bool magnifying = lod < 0.0f;
int mipmap_offset = 0;
int mip_width = tex->GetWidth();
int mip_height = tex->GetHeight();
uint32_t xpos = (uint32_t)((((uint64_t)xoffset) << FRACBITS) / mip_width);
if (r_mipmap && tex->Mipmapped() && mip_width > 1 && mip_height > 1)
{
int level = (int)lod;
while (level > 0 && mip_width > 1 && mip_height > 1)
{
mipmap_offset += mip_width * mip_height;
level--;
mip_width = MAX(mip_width >> 1, 1);
mip_height = MAX(mip_height >> 1, 1);
}
}
xoffset = (xpos >> FRACBITS) * mip_width;
const uint32_t *pixels = tex->GetPixelsBgra() + mipmap_offset;
bool filter_nearest = (magnifying && !r_magfilter) || (!magnifying && !r_minfilter);
if (filter_nearest)
{
xoffset = MAX(MIN(xoffset, (mip_width << FRACBITS) - 1), 0);
int tx = xoffset >> FRACBITS;
dc_source = (BYTE*)(pixels + tx * mip_height);
dc_source2 = nullptr;
dc_textureheight = mip_height;
dc_texturefracx = 0;
} }
else else
{ {
xoffset = MAX(MIN(xoffset - (FRACUNIT / 2), (mip_width << FRACBITS) - 1), 0); spanfunc = &SWPixelFormatDrawers::DrawSpanAddClamp;
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
int tx0 = xoffset >> FRACBITS; dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
int tx1 = MIN(tx0 + 1, mip_width - 1); dc_srcalpha = alpha;
dc_source = (BYTE*)(pixels + tx0 * mip_height); dc_destalpha = FRACUNIT;
dc_source2 = (BYTE*)(pixels + tx1 * mip_height);
dc_textureheight = mip_height;
dc_texturefracx = (xoffset >> (FRACBITS - 4)) & 15;
} }
// Grab the posts we need to draw
const FTexture::Span *span;
tex->GetColumnBgra(col >> FRACBITS, &span);
FTexture::Span unmaskedSpan[2];
if (unmasked)
{
span = unmaskedSpan;
unmaskedSpan[0].TopOffset = 0;
unmaskedSpan[0].Length = tex->GetHeight();
unmaskedSpan[1].TopOffset = 0;
unmaskedSpan[1].Length = 0;
} }
else
// Draw each span post
while (span->Length != 0)
{ {
const int length = span->Length; spanfunc = &SWPixelFormatDrawers::DrawSpan;
const int top = span->TopOffset;
// calculate unclipped screen coordinates for post
dc_yl = (int)(sprtopscreen + spryscale * top + 0.5);
dc_yh = (int)(sprtopscreen + spryscale * (top + length) + 0.5) - 1;
if (sprflipvert)
{
swapvalues(dc_yl, dc_yh);
} }
if (dc_yh >= mfloorclip[dc_x])
{
dc_yh = mfloorclip[dc_x] - 1;
}
if (dc_yl < mceilingclip[dc_x])
{
dc_yl = mceilingclip[dc_x];
}
if (dc_yl <= dc_yh)
{
dc_dest = (ylookup[dc_yl] + dc_x) * 4 + dc_destorg;
dc_count = dc_yh - dc_yl + 1;
double v = ((dc_yl + 0.5 - sprtopscreen) / spryscale) / tex->GetHeight();
dc_texturefrac = (uint32_t)(v * (1 << 30));
(R_Drawers()->*colfunc)();
}
span++;
} }
} }
} }

View File

@ -174,10 +174,6 @@ namespace swrenderer
void R_InitFuzzTable(int fuzzoff); void R_InitFuzzTable(int fuzzoff);
void R_InitParticleTexture(); void R_InitParticleTexture();
bool R_SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap);
bool R_SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap);
DrawerFunc R_GetTransMaskDrawer();
void R_UpdateFuzzPos(); void R_UpdateFuzzPos();
// Sets dc_colormap and dc_light to their appropriate values depending on the output format (pal vs true color) // Sets dc_colormap and dc_light to their appropriate values depending on the output format (pal vs true color)
@ -188,12 +184,36 @@ namespace swrenderer
void R_SetSpanTexture(FTexture *tex); void R_SetSpanTexture(FTexture *tex);
void R_SetSpanColormap(FDynamicColormap *colormap, int shade); void R_SetSpanColormap(FDynamicColormap *colormap, int shade);
void R_DrawMaskedColumn(int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false); class DrawerStyle
void R_DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked); {
public:
DrawerStyle()
{
colfunc = &SWPixelFormatDrawers::DrawColumn;
basecolfunc = &SWPixelFormatDrawers::DrawColumn;
fuzzcolfunc = &SWPixelFormatDrawers::DrawFuzzColumn;
transcolfunc = &SWPixelFormatDrawers::DrawTranslatedColumn;
spanfunc = &SWPixelFormatDrawers::DrawSpan;
}
extern DrawerFunc colfunc; bool SetPatchStyle(FRenderStyle style, fixed_t alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap);
extern DrawerFunc basecolfunc; bool SetPatchStyle(FRenderStyle style, float alpha, int translation, uint32_t color, FDynamicColormap *&basecolormap);
extern DrawerFunc fuzzcolfunc; void SetSpanStyle(bool masked, bool additive, fixed_t alpha);
extern DrawerFunc transcolfunc;
extern DrawerFunc spanfunc; void DrawMaskedColumn(int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false);
DrawerFunc GetTransMaskDrawer();
DrawerFunc colfunc;
DrawerFunc basecolfunc;
DrawerFunc fuzzcolfunc;
DrawerFunc transcolfunc;
DrawerFunc spanfunc;
private:
void DrawMaskedColumnBgra(int x, fixed_t iscale, FTexture *tex, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked);
bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags);
static fixed_t GetAlpha(int type, fixed_t alpha);
};
} }

View File

@ -1045,8 +1045,9 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
DrawerStyle drawerstyle;
RenderWallPart renderWallpart; RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, rw_midtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerstyle, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallbottom.ScreenY, rw_midtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
fillshort(ceilingclip + x1, x2 - x1, viewheight); fillshort(ceilingclip + x1, x2 - x1, viewheight);
fillshort(floorclip + x1, x2 - x1, 0xffff); fillshort(floorclip + x1, x2 - x1, 0xffff);
@ -1082,8 +1083,9 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
DrawerStyle drawerstyle;
RenderWallPart renderWallpart; RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, rw_toptexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerstyle, frontsector, curline, WallC, rw_pic, x1, x2, walltop.ScreenY, wallupper.ScreenY, rw_toptexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short)); memcpy(ceilingclip + x1, wallupper.ScreenY + x1, (x2 - x1) * sizeof(short));
} }
@ -1122,8 +1124,9 @@ namespace swrenderer
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
DrawerStyle drawerstyle;
RenderWallPart renderWallpart; RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, rw_bottomtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap); renderWallpart.Render(drawerstyle, frontsector, curline, WallC, rw_pic, x1, x2, walllower.ScreenY, wallbottom.ScreenY, rw_bottomtexturemid, walltexcoords.VStep, walltexcoords.UPos, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, wallshade, rw_offset, rw_light, rw_lightstep, light_list, foggy, basecolormap);
} }
memcpy(floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short)); memcpy(floorclip + x1, walllower.ScreenY + x1, (x2 - x1) * sizeof(short));
} }

View File

@ -67,7 +67,8 @@ namespace swrenderer
curline = ds->curline; curline = ds->curline;
FDynamicColormap *patchstylecolormap = nullptr; FDynamicColormap *patchstylecolormap = nullptr;
bool visible = R_SetPatchStyle(LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent], DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(LegacyRenderStyles[curline->linedef->flags & ML_ADDTRANS ? STYLE_Add : STYLE_Translucent],
(float)MIN(curline->linedef->alpha, 1.), 0, 0, patchstylecolormap); (float)MIN(curline->linedef->alpha, 1.), 0, 0, patchstylecolormap);
if (!visible && !ds->bFogBoundary && !ds->bFakeBoundary) if (!visible && !ds->bFogBoundary && !ds->bFakeBoundary)
@ -282,7 +283,7 @@ namespace swrenderer
else else
sprtopscreen = CenterY - texturemid * spryscale; sprtopscreen = CenterY - texturemid * spryscale;
R_DrawMaskedColumn(x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); drawerstyle.DrawMaskedColumn(x, iscale, tex, maskedtexturecol[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
rw_light += rw_lightstep; rw_light += rw_lightstep;
spryscale += rw_scalestep; spryscale += rw_scalestep;
@ -348,7 +349,7 @@ namespace swrenderer
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart; RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); renderWallpart.Render(drawerstyle, frontsector, curline, WallC, rw_pic, x1, x2, mceilingclip, mfloorclip, texturemid, MaskedSWall, maskedtexturecol, ds->yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
} }
clearfog: clearfog:
@ -382,7 +383,8 @@ namespace swrenderer
double yscale; double yscale;
fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255); fixed_t Alpha = Scale(rover->alpha, OPAQUE, 255);
bool visible = R_SetPatchStyle(LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent], DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(LegacyRenderStyles[rover->flags & FF_ADDITIVETRANS ? STYLE_Add : STYLE_Translucent],
Alpha, 0, 0, basecolormap); Alpha, 0, 0, basecolormap);
if (!visible) if (!visible)
@ -479,7 +481,7 @@ namespace swrenderer
GetMaskedWallTopBottom(ds, top, bot); GetMaskedWallTopBottom(ds, top, bot);
RenderWallPart renderWallpart; RenderWallPart renderWallpart;
renderWallpart.Render(frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap); renderWallpart.Render(drawerstyle, frontsector, curline, WallC, rw_pic, x1, x2, wallupper.ScreenY, walllower.ScreenY, texturemid, MaskedSWall, walltexcoords.UPos, yscale, top, bot, true, wallshade, rw_offset, rw_light, rw_lightstep, nullptr, ds->foggy, basecolormap);
} }
// kg3D - walls of fake floors // kg3D - walls of fake floors

View File

@ -392,7 +392,7 @@ namespace swrenderer
void RenderWallPart::ProcessTranslucentWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal) void RenderWallPart::ProcessTranslucentWall(const short *uwal, const short *dwal, double texturemid, float *swal, fixed_t *lwal)
{ {
DrawerFunc drawcol1 = R_GetTransMaskDrawer(); DrawerFunc drawcol1 = drawerstyle.GetTransMaskDrawer();
if (drawcol1 == nullptr) if (drawcol1 == nullptr)
{ {
// The current translucency is unsupported, so draw with regular ProcessMaskedWall instead. // The current translucency is unsupported, so draw with regular ProcessMaskedWall instead.
@ -445,7 +445,7 @@ namespace swrenderer
{ {
if (mask) if (mask)
{ {
if (colfunc == basecolfunc) if (drawerstyle.colfunc == drawerstyle.basecolfunc)
{ {
ProcessMaskedWall(uwal, dwal, texturemid, swal, lwal); ProcessMaskedWall(uwal, dwal, texturemid, swal, lwal);
} }
@ -540,8 +540,9 @@ namespace swrenderer
} }
} }
void RenderWallPart::Render(sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap) void RenderWallPart::Render(const DrawerStyle &drawerstyle, sector_t *frontsector, seg_t *curline, const FWallCoords &WallC, FTexture *pic, int x1, int x2, const short *walltop, const short *wallbottom, double texturemid, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, int wallshade, fixed_t xoffset, float light, float lightstep, FLightNode *light_list, bool foggy, FDynamicColormap *basecolormap)
{ {
this->drawerstyle = drawerstyle;
this->x1 = x1; this->x1 = x1;
this->x2 = x2; this->x2 = x2;
this->frontsector = frontsector; this->frontsector = frontsector;

View File

@ -34,6 +34,7 @@ namespace swrenderer
{ {
public: public:
void Render( void Render(
const DrawerStyle &drawerstyle,
sector_t *frontsector, sector_t *frontsector,
seg_t *curline, seg_t *curline,
const FWallCoords &WallC, const FWallCoords &WallC,
@ -83,6 +84,8 @@ namespace swrenderer
FDynamicColormap *basecolormap = nullptr; FDynamicColormap *basecolormap = nullptr;
FLightNode *light_list = nullptr; FLightNode *light_list = nullptr;
bool mask = false; bool mask = false;
DrawerStyle drawerstyle;
}; };
struct WallSampler struct WallSampler

View File

@ -125,61 +125,7 @@ namespace swrenderer
planeshade = LIGHT2SHADE(pl->lightlevel); planeshade = LIGHT2SHADE(pl->lightlevel);
} }
if (spanfunc != &SWPixelFormatDrawers::FillSpan) drawerstyle.SetSpanStyle(masked, additive, alpha);
{
if (masked)
{
if (alpha < OPAQUE || additive)
{
if (!additive)
{
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedTranslucent;
dc_srcblend = Col2RGB8[alpha >> 10];
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
dc_srcalpha = alpha;
dc_destalpha = OPAQUE - alpha;
}
else
{
spanfunc = &SWPixelFormatDrawers::DrawSpanMaskedAddClamp;
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
dc_srcalpha = alpha;
dc_destalpha = FRACUNIT;
}
}
else
{
spanfunc = &SWPixelFormatDrawers::DrawSpanMasked;
}
}
else
{
if (alpha < OPAQUE || additive)
{
if (!additive)
{
spanfunc = &SWPixelFormatDrawers::DrawSpanTranslucent;
dc_srcblend = Col2RGB8[alpha >> 10];
dc_destblend = Col2RGB8[(OPAQUE - alpha) >> 10];
dc_srcalpha = alpha;
dc_destalpha = OPAQUE - alpha;
}
else
{
spanfunc = &SWPixelFormatDrawers::DrawSpanAddClamp;
dc_srcblend = Col2RGB8_LessPrecision[alpha >> 10];
dc_destblend = Col2RGB8_LessPrecision[FRACUNIT >> 10];
dc_srcalpha = alpha;
dc_destalpha = FRACUNIT;
}
}
else
{
spanfunc = &SWPixelFormatDrawers::DrawSpan;
}
}
}
light_list = pl->lights; light_list = pl->lights;
@ -309,7 +255,7 @@ namespace swrenderer
ds_x1 = x1; ds_x1 = x1;
ds_x2 = x2; ds_x2 = x2;
(R_Drawers()->*spanfunc)(); (R_Drawers()->*drawerstyle.spanfunc)();
} }
void RenderFlatPlane::StepColumn() void RenderFlatPlane::StepColumn()

View File

@ -14,6 +14,7 @@
#pragma once #pragma once
#include "r_planerenderer.h" #include "r_planerenderer.h"
#include "swrenderer/drawers/r_draw.h"
namespace swrenderer namespace swrenderer
{ {
@ -41,6 +42,8 @@ namespace swrenderer
double basexfrac, baseyfrac; double basexfrac, baseyfrac;
VisiblePlaneLight *light_list; VisiblePlaneLight *light_list;
DrawerStyle drawerstyle;
static float yslope[MAXHEIGHT]; static float yslope[MAXHEIGHT];
}; };

View File

@ -141,9 +141,6 @@ namespace swrenderer
NetUpdate(); NetUpdate();
colfunc = basecolfunc;
spanfunc = &SWPixelFormatDrawers::DrawSpan;
RenderPortal::Instance()->SetMainPortal(); RenderPortal::Instance()->SetMainPortal();
this->dontmaplines = dontmaplines; this->dontmaplines = dontmaplines;

View File

@ -282,7 +282,8 @@ namespace swrenderer
{ {
int x = x1; int x = x1;
bool visible = R_SetPatchStyle(decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, basecolormap); DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor, basecolormap);
// R_SetPatchStyle can modify basecolormap. // R_SetPatchStyle can modify basecolormap.
if (rereadcolormap) if (rereadcolormap)
@ -298,7 +299,7 @@ namespace swrenderer
{ // calculate lighting { // calculate lighting
R_SetColorMapLight(usecolormap, light, wallshade); R_SetColorMapLight(usecolormap, light, wallshade);
} }
DrawColumn(x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); DrawColumn(drawerstyle, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip);
light += lightstep; light += lightstep;
x++; x++;
} }
@ -311,13 +312,11 @@ namespace swrenderer
mfloorclip = wallbottom; mfloorclip = wallbottom;
} while (needrepeat--); } while (needrepeat--);
colfunc = basecolfunc;
done: done:
WallC = savecoord; WallC = savecoord;
} }
void RenderDecal::DrawColumn(int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) void RenderDecal::DrawColumn(DrawerStyle &drawerstyle, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
{ {
float iscale = walltexcoords.VStep[x] * maskedScaleY; float iscale = walltexcoords.VStep[x] * maskedScaleY;
double spryscale = 1 / iscale; double spryscale = 1 / iscale;
@ -327,6 +326,6 @@ namespace swrenderer
else else
sprtopscreen = CenterY - texturemid * spryscale; sprtopscreen = CenterY - texturemid * spryscale;
R_DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); drawerstyle.DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
} }
} }

View File

@ -20,6 +20,7 @@ namespace swrenderer
{ {
struct DrawSegment; struct DrawSegment;
class ProjectedWallTexcoords; class ProjectedWallTexcoords;
class DrawerStyle;
class RenderDecal class RenderDecal
{ {
@ -28,6 +29,6 @@ namespace swrenderer
private: private:
static void Render(side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, FWallCoords wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass); static void Render(side_t *wall, DBaseDecal *first, DrawSegment *clipper, int wallshade, float lightleft, float lightstep, seg_t *curline, FWallCoords wallC, bool foggy, FDynamicColormap *basecolormap, const short *walltop, const short *wallbottom, int pass);
static void DrawColumn(int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); static void DrawColumn(DrawerStyle &drawerstyle, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
}; };
} }

View File

@ -591,7 +591,8 @@ namespace swrenderer
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
bool visible = R_SetPatchStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap); DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap);
if (RenderStyle == LegacyRenderStyles[STYLE_Shaded]) if (RenderStyle == LegacyRenderStyles[STYLE_Shaded])
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but { // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
@ -628,7 +629,7 @@ namespace swrenderer
fixed_t frac = startfrac; fixed_t frac = startfrac;
for (int x = x1; x < x2; x++) for (int x = x1; x < x2; x++)
{ {
R_DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); drawerstyle.DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
frac += xiscale; frac += xiscale;
} }

View File

@ -250,7 +250,8 @@ namespace swrenderer
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap);
bool visible = R_SetPatchStyle(vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap); DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(vis->RenderStyle, vis->Alpha, vis->Translation, vis->FillColor, basecolormap);
if (vis->RenderStyle == LegacyRenderStyles[STYLE_Shaded]) if (vis->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
{ // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but { // For shaded sprites, R_SetPatchStyle sets a dc_colormap to an alpha table, but
@ -293,7 +294,7 @@ namespace swrenderer
while (x < x2) while (x < x2)
{ {
if (!translucentPass->ClipSpriteColumnWithPortals(x, vis)) if (!translucentPass->ClipSpriteColumnWithPortals(x, vis))
R_DrawMaskedColumn(x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false); drawerstyle.DrawMaskedColumn(x, iscale, tex, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
x++; x++;
frac += xiscale; frac += xiscale;
} }

View File

@ -188,7 +188,8 @@ namespace swrenderer
R_SetColorMapLight(sprite->Light.BaseColormap, 0, sprite->Light.ColormapNum << FRACBITS); R_SetColorMapLight(sprite->Light.BaseColormap, 0, sprite->Light.ColormapNum << FRACBITS);
bool visible = R_SetPatchStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap); DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(sprite->RenderStyle, sprite->Alpha, sprite->Translation, sprite->FillColor, basecolormap);
if (!visible) if (!visible)
return; return;

View File

@ -213,7 +213,8 @@ namespace swrenderer
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->Light.BaseColormap); FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(spr->Light.BaseColormap);
bool visible = R_SetPatchStyle(spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap); DrawerStyle drawerstyle;
bool visible = drawerstyle.SetPatchStyle(spr->RenderStyle, spr->Alpha, spr->Translation, spr->FillColor, basecolormap);
// R_SetPatchStyle can modify basecolormap. // R_SetPatchStyle can modify basecolormap.
if (rereadcolormap) if (rereadcolormap)
@ -236,14 +237,14 @@ namespace swrenderer
R_SetColorMapLight(usecolormap, light, shade); R_SetColorMapLight(usecolormap, light, shade);
} }
if (!translucentPass->ClipSpriteColumnWithPortals(x, spr)) if (!translucentPass->ClipSpriteColumnWithPortals(x, spr))
DrawColumn(x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip); DrawColumn(drawerstyle, x, WallSpriteTile, walltexcoords, texturemid, maskedScaleY, sprflipvert, mfloorclip, mceilingclip);
light += lightstep; light += lightstep;
x++; x++;
} }
} }
} }
void RenderWallSprite::DrawColumn(int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip) void RenderWallSprite::DrawColumn(DrawerStyle &drawerstyle, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip)
{ {
float iscale = walltexcoords.VStep[x] * maskedScaleY; float iscale = walltexcoords.VStep[x] * maskedScaleY;
double spryscale = 1 / iscale; double spryscale = 1 / iscale;
@ -253,6 +254,6 @@ namespace swrenderer
else else
sprtopscreen = CenterY - texturemid * spryscale; sprtopscreen = CenterY - texturemid * spryscale;
R_DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip); drawerstyle.DrawMaskedColumn(x, FLOAT2FIXED(iscale), WallSpriteTile, walltexcoords.UPos[x], spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip);
} }
} }

View File

@ -18,6 +18,7 @@
namespace swrenderer namespace swrenderer
{ {
class ProjectedWallTexcoords; class ProjectedWallTexcoords;
class DrawerStyle;
class RenderWallSprite : public VisibleSprite class RenderWallSprite : public VisibleSprite
{ {
@ -29,7 +30,7 @@ namespace swrenderer
void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override; void Render(short *cliptop, short *clipbottom, int minZ, int maxZ) override;
private: private:
static void DrawColumn(int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip); static void DrawColumn(DrawerStyle &drawerstyle, int x, FTexture *WallSpriteTile, const ProjectedWallTexcoords &walltexcoords, double texturemid, float maskedScaleY, bool sprflipvert, const short *mfloorclip, const short *mceilingclip);
FWallCoords wallc; FWallCoords wallc;
uint32_t Translation = 0; uint32_t Translation = 0;

View File

@ -200,10 +200,11 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
CameraLight::Instance()->fixedcolormap = dc_fcolormap; CameraLight::Instance()->fixedcolormap = dc_fcolormap;
bool visible; bool visible;
FDynamicColormap *basecolormap = nullptr; FDynamicColormap *basecolormap = nullptr;
DrawerStyle drawerstyle;
if (r_swtruecolor) if (r_swtruecolor)
visible = R_SetPatchStyle(parms.style, parms.Alpha, -1, parms.fillcolor, basecolormap); visible = drawerstyle.SetPatchStyle(parms.style, parms.Alpha, -1, parms.fillcolor, basecolormap);
else else
visible = R_SetPatchStyle(parms.style, parms.Alpha, 0, parms.fillcolor, basecolormap); visible = drawerstyle.SetPatchStyle(parms.style, parms.Alpha, 0, parms.fillcolor, basecolormap);
BYTE *destorgsave = dc_destorg; BYTE *destorgsave = dc_destorg;
int destheightsave = dc_destheight; int destheightsave = dc_destheight;
@ -291,7 +292,7 @@ void DCanvas::DrawTextureParms(FTexture *img, DrawParms &parms)
while (x < x2_i) while (x < x2_i)
{ {
R_DrawMaskedColumn(x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked); drawerstyle.DrawMaskedColumn(x, iscale, img, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, !parms.masked);
x++; x++;
frac += xiscale_i; frac += xiscale_i;
} }