- Improved fuzz rendering in software renderer by scaling it relative to 320x200

This commit is contained in:
Magnus Norddahl 2017-06-25 00:35:15 +02:00
parent 279b1e27dc
commit f34ededdef
9 changed files with 206 additions and 6 deletions

View file

@ -53,6 +53,7 @@
#include "swrenderer/scene/r_light.h"
CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
CVAR(Bool, r_fuzzscale, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
namespace swrenderer
{
@ -64,6 +65,20 @@ namespace swrenderer
int fuzzpos;
int fuzzviewheight;
int fuzz_random_x_offset[FUZZ_RANDOM_X_SIZE] =
{
75, 76, 21, 91, 56, 33, 62, 99, 61, 79,
95, 54, 41, 18, 69, 43, 49, 59, 10, 84,
94, 17, 57, 46, 9, 39, 55, 34,100, 81,
73, 88, 92, 3, 63, 36, 7, 28, 13, 80,
16, 96, 78, 29, 71, 58, 89, 24, 1, 35,
52, 82, 4, 14, 22, 53, 38, 66, 12, 72,
90, 44, 77, 83, 6, 27, 48, 30, 42, 32,
65, 15, 97, 20, 67, 74, 98, 85, 60, 68,
19, 26, 8, 87, 86, 64, 11, 37, 31, 47,
25, 5, 50, 51, 23, 2, 93, 70, 40, 45
};
uint32_t particle_texture[NUM_PARTICLE_TEXTURES][PARTICLE_TEXTURE_SIZE * PARTICLE_TEXTURE_SIZE];
short zeroarray[MAXWIDTH];
@ -176,11 +191,28 @@ namespace swrenderer
}
}
void R_UpdateFuzzPosFrameStart()
{
if (r_fuzzscale)
{
int next_random = 0;
fuzzpos = (fuzzpos + fuzz_random_x_offset[next_random] * FUZZTABLE / 100) % FUZZTABLE;
next_random++;
if (next_random == FUZZ_RANDOM_X_SIZE)
next_random = 0;
}
}
void R_UpdateFuzzPos(const SpriteDrawerArgs &args)
{
int yl = MAX(args.FuzzY1(), 1);
int yh = MIN(args.FuzzY2(), fuzzviewheight);
if (yl <= yh)
fuzzpos = (fuzzpos + yh - yl + 1) % FUZZTABLE;
if (!r_fuzzscale)
{
int yl = MAX(args.FuzzY1(), 1);
int yh = MIN(args.FuzzY2(), fuzzviewheight);
if (yl <= yh)
fuzzpos = (fuzzpos + yh - yl + 1) % FUZZTABLE;
}
}
}

View file

@ -17,6 +17,7 @@ EXTERN_CVAR(Int, r_drawfuzz);
EXTERN_CVAR(Bool, r_drawtrans);
EXTERN_CVAR(Float, transsouls);
EXTERN_CVAR(Bool, r_dynlights);
EXTERN_CVAR(Bool, r_fuzzscale);
class DrawerCommandQueue;
typedef std::shared_ptr<DrawerCommandQueue> DrawerCommandQueuePtr;
@ -41,7 +42,9 @@ namespace swrenderer
// Spectre/Invisibility.
#define FUZZTABLE 50
#define FUZZ_RANDOM_X_SIZE 100
extern int fuzzoffset[FUZZTABLE + 1];
extern int fuzz_random_x_offset[FUZZ_RANDOM_X_SIZE];
extern int fuzzpos;
extern int fuzzviewheight;
@ -99,5 +102,6 @@ namespace swrenderer
void R_InitFuzzTable(int fuzzoff);
void R_InitParticleTexture();
void R_UpdateFuzzPosFrameStart();
void R_UpdateFuzzPos(const SpriteDrawerArgs &args);
}

View file

@ -1834,6 +1834,60 @@ namespace swrenderer
}
}
/////////////////////////////////////////////////////////////////////////////
DrawScaledFuzzColumnPalCommand::DrawScaledFuzzColumnPalCommand(const SpriteDrawerArgs &drawerargs)
{
_x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight;
}
void DrawScaledFuzzColumnPalCommand::Execute(DrawerThread *thread)
{
int x = _x;
int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight);
int count = thread->count_for_thread(yl, yh - yl + 1);
if (count <= 0) return;
int pitch = _pitch;
uint8_t *dest = _pitch * yl + x + (uint8_t*)_destorg;
int scaled_x = x * 200 / _fuzzviewheight;
int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + _fuzzpos;
fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight;
fixed_t fuzzcount = FUZZTABLE << FRACBITS;
fixed_t fuzz = (fuzz_x << FRACBITS) + yl * fuzzstep;
dest = thread->dest_for_thread(yl, pitch, dest);
pitch *= thread->num_cores;
fuzz += fuzzstep * thread->skipped_by_thread(yl);
fuzz %= fuzzcount;
fuzzstep *= thread->num_cores;
uint8_t *map = NormalLight.Maps;
while (count > 0)
{
int offset = fuzzoffset[fuzz >> FRACBITS] << 8;
*dest = map[offset + *dest];
dest += pitch;
fuzz += fuzzstep;
if (fuzz >= fuzzcount) fuzz -= fuzzcount;
count--;
}
}
/////////////////////////////////////////////////////////////////////////
DrawFuzzColumnPalCommand::DrawFuzzColumnPalCommand(const SpriteDrawerArgs &args)

View file

@ -90,6 +90,23 @@ namespace swrenderer
int _fuzzviewheight;
};
class DrawScaledFuzzColumnPalCommand : public DrawerCommand
{
public:
DrawScaledFuzzColumnPalCommand(const SpriteDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
FString DebugInfo() override { return "DrawScaledFuzzColumnPalCommand"; }
private:
int _x;
int _yl;
int _yh;
uint8_t *_destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
};
class PalSpanCommand : public DrawerCommand
{
public:
@ -245,7 +262,14 @@ namespace swrenderer
void FillAddClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnAddClampPalCommand>(args); }
void FillSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnSubClampPalCommand>(args); }
void FillRevSubClampColumn(const SpriteDrawerArgs &args) override { Queue->Push<FillColumnRevSubClampPalCommand>(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawFuzzColumnPalCommand>(args); R_UpdateFuzzPos(args); }
void DrawFuzzColumn(const SpriteDrawerArgs &args) override
{
if (r_fuzzscale)
Queue->Push<DrawScaledFuzzColumnPalCommand>(args);
else
Queue->Push<DrawFuzzColumnPalCommand>(args);
R_UpdateFuzzPos(args);
}
void DrawAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnAddPalCommand>(args); }
void DrawTranslatedColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTranslatedPalCommand>(args); }
void DrawTranslatedAddColumn(const SpriteDrawerArgs &args) override { Queue->Push<DrawColumnTlatedAddPalCommand>(args); }

View file

@ -142,7 +142,10 @@ namespace swrenderer
void SWTruecolorDrawers::DrawFuzzColumn(const SpriteDrawerArgs &args)
{
Queue->Push<DrawFuzzColumnRGBACommand>(args);
if (r_fuzzscale)
Queue->Push<DrawScaledFuzzColumnRGBACommand>(args);
else
Queue->Push<DrawFuzzColumnRGBACommand>(args);
R_UpdateFuzzPos(args);
}
@ -248,6 +251,69 @@ namespace swrenderer
/////////////////////////////////////////////////////////////////////////////
DrawScaledFuzzColumnRGBACommand::DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs)
{
_x = drawerargs.FuzzX();
_yl = drawerargs.FuzzY1();
_yh = drawerargs.FuzzY2();
_destorg = drawerargs.Viewport()->GetDest(0, 0);
_pitch = drawerargs.Viewport()->RenderTarget->GetPitch();
_fuzzpos = fuzzpos;
_fuzzviewheight = fuzzviewheight;
}
void DrawScaledFuzzColumnRGBACommand::Execute(DrawerThread *thread)
{
int x = _x;
int yl = MAX(_yl, 1);
int yh = MIN(_yh, _fuzzviewheight);
int count = thread->count_for_thread(yl, yh - yl + 1);
if (count <= 0) return;
int pitch = _pitch;
uint32_t *dest = _pitch * yl + x + (uint32_t*)_destorg;
int scaled_x = x * 200 / _fuzzviewheight;
int fuzz_x = fuzz_random_x_offset[scaled_x % FUZZ_RANDOM_X_SIZE] + _fuzzpos;
fixed_t fuzzstep = (200 << FRACBITS) / _fuzzviewheight;
fixed_t fuzzcount = FUZZTABLE << FRACBITS;
fixed_t fuzz = (fuzz_x << FRACBITS) + yl * fuzzstep;
dest = thread->dest_for_thread(yl, pitch, dest);
pitch *= thread->num_cores;
fuzz += fuzzstep * thread->skipped_by_thread(yl);
fuzz %= fuzzcount;
fuzzstep *= thread->num_cores;
while (count > 0)
{
int alpha = 32 - fuzzoffset[fuzz >> FRACBITS];
uint32_t bg = *dest;
uint32_t red = (RPART(bg) * alpha) >> 5;
uint32_t green = (GPART(bg) * alpha) >> 5;
uint32_t blue = (BPART(bg) * alpha) >> 5;
*dest = 0xff000000 | (red << 16) | (green << 8) | blue;
dest += pitch;
fuzz += fuzzstep;
if (fuzz >= fuzzcount) fuzz -= fuzzcount;
count--;
}
}
FString DrawScaledFuzzColumnRGBACommand::DebugInfo()
{
return "DrawScaledFuzzColumn";
}
/////////////////////////////////////////////////////////////////////////////
DrawFuzzColumnRGBACommand::DrawFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs)
{
_x = drawerargs.FuzzX();

View file

@ -86,6 +86,22 @@ namespace swrenderer
FString DebugInfo() override;
};
class DrawScaledFuzzColumnRGBACommand : public DrawerCommand
{
int _x;
int _yl;
int _yh;
uint8_t * RESTRICT _destorg;
int _pitch;
int _fuzzpos;
int _fuzzviewheight;
public:
DrawScaledFuzzColumnRGBACommand(const SpriteDrawerArgs &drawerargs);
void Execute(DrawerThread *thread) override;
FString DebugInfo() override;
};
class FillSpanRGBACommand : public DrawerCommand
{
int _x1;

View file

@ -152,6 +152,8 @@ namespace swrenderer
// Link the polyobjects right before drawing the scene to reduce the amounts of calls to this function
PO_LinkToSubsectors();
R_UpdateFuzzPosFrameStart();
ActorRenderFlags savedflags = MainThread()->Viewport->viewpoint.camera->renderflags;
// Never draw the player unless in chasecam mode
if (!MainThread()->Viewport->viewpoint.showviewer)

View file

@ -1816,6 +1816,7 @@ DSPLYMNU_ATTACHEDSURFACES = "Use attached surfaces"; // Not used
DSPLYMNU_SKYMODE = "Sky render mode";
DSPLYMNU_LINEARSKY = "Linear skies";
DSPLYMNU_GZDFULLBRIGHT = "Fullbright overrides sector color";
DSPLYMNU_SCALEFUZZ = "Scale fuzz effect";
DSPLYMNU_DRAWFUZZ = "Use fuzz effect";
DSPLYMNU_OLDTRANS = "Classic Transparency";
DSPLYMNU_TRANSSOUL = "Lost Soul translucency";

View file

@ -725,6 +725,7 @@ OptionMenu "SWROptions" protected
Option "$DSPLYMNU_SKYMODE", "r_skymode", "SkyModes"
Option "$DSPLYMNU_LINEARSKY", "r_linearsky", "OnOff"
Option "$DSPLYMNU_GZDFULLBRIGHT", "r_fullbrightignoresectorcolor", "OnOff"
Option "$DSPLYMNU_SCALEFUZZ", "r_fuzzscale", "OnOff"
}
OptionMenu "VideoOptions" protected