Hooked up dynamic light on walls

This commit is contained in:
Magnus Norddahl 2016-12-21 07:33:28 +01:00
parent 578e3270e2
commit 4e56c9a41a
6 changed files with 99 additions and 26 deletions

View file

@ -62,6 +62,7 @@ namespace swrenderer
extern int wallshade; extern int wallshade;
double dc_texturemid; double dc_texturemid;
FLightNode *dc_light_list;
int ylookup[MAXHEIGHT]; int ylookup[MAXHEIGHT];
uint8_t shadetables[NUMCOLORMAPS * 16 * 256]; uint8_t shadetables[NUMCOLORMAPS * 16 * 256];
@ -100,6 +101,10 @@ namespace swrenderer
uint8_t *dc_destorg; uint8_t *dc_destorg;
int dc_destheight; int dc_destheight;
int dc_count; int dc_count;
FVector3 dc_viewpos;
FVector3 dc_viewpos_step;
TriLight *dc_lights;
int dc_num_lights;
uint32_t dc_wall_texturefrac[4]; uint32_t dc_wall_texturefrac[4];
uint32_t dc_wall_iscale[4]; uint32_t dc_wall_iscale[4];
uint8_t *dc_wall_colormap[4]; uint8_t *dc_wall_colormap[4];

View file

@ -4,6 +4,8 @@
#include "r_defs.h" #include "r_defs.h"
struct FSWColormap; struct FSWColormap;
struct FLightNode;
struct TriLight;
EXTERN_CVAR(Bool, r_multithreaded); EXTERN_CVAR(Bool, r_multithreaded);
EXTERN_CVAR(Bool, r_magfilter); EXTERN_CVAR(Bool, r_magfilter);
@ -34,6 +36,7 @@ namespace swrenderer
}; };
extern double dc_texturemid; extern double dc_texturemid;
extern FLightNode *dc_light_list;
namespace drawerargs namespace drawerargs
{ {
@ -63,6 +66,10 @@ namespace swrenderer
extern uint8_t *dc_destorg; extern uint8_t *dc_destorg;
extern int dc_destheight; extern int dc_destheight;
extern int dc_count; extern int dc_count;
extern FVector3 dc_viewpos;
extern FVector3 dc_viewpos_step;
extern TriLight *dc_lights;
extern int dc_num_lights;
extern bool drawer_needs_pal_input; extern bool drawer_needs_pal_input;

View file

@ -221,26 +221,11 @@ namespace swrenderer
if (args.source2[0] == nullptr) if (args.source2[0] == nullptr)
args.flags |= DrawWallArgs::nearest_filter; args.flags |= DrawWallArgs::nearest_filter;
args.z = 0.0f;
args.step_z = 0.0f;
args.dynlights = nullptr; args.dynlights = nullptr;
args.num_dynlights = 0; args.num_dynlights = 0;
/*
static TriLight fakelight;
static bool first = true;
if (first)
{
fakelight.x = 100.0f;
fakelight.y = 0.0f;
fakelight.z = 100.0f;
fakelight.color = 0xffffff00;
fakelight.radius = 256.0f / 1000.0f;
first = false;
}
args.z = 0.0f;
args.step_z = 1.0f;
args.dynlights = &fakelight;
args.num_dynlights = 1;
*/
DetectRangeError(args.dest, args.dest_y, args.count); DetectRangeError(args.dest, args.dest_y, args.count);
} }
@ -299,10 +284,10 @@ namespace swrenderer
if (args.source2[0] == nullptr) if (args.source2[0] == nullptr)
args.flags |= DrawWallArgs::nearest_filter; args.flags |= DrawWallArgs::nearest_filter;
args.z = 0.0f; args.z = dc_viewpos.Z;
args.step_z = 0.0f; args.step_z = dc_viewpos_step.Z;
args.dynlights = nullptr; args.dynlights = dc_lights;
args.num_dynlights = 0; args.num_dynlights = dc_num_lights;
DetectRangeError(args.dest, args.dest_y, args.count); DetectRangeError(args.dest, args.dest_y, args.count);
} }

View file

@ -60,7 +60,7 @@ namespace swrenderer
{ {
using namespace drawerargs; using namespace drawerargs;
void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask); void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, FLightNode *light_list = nullptr);
void R_DrawDrawSeg(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat); void R_DrawDrawSeg(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat);
#define HEIGHTBITS 12 #define HEIGHTBITS 12
@ -1139,6 +1139,8 @@ void R_RenderSegLoop ()
} }
if(fake3D & 7) return; if(fake3D & 7) return;
FLightNode *light_list = (curline && curline->sidedef) ? curline->sidedef->lighthead : nullptr;
// draw the wall tiers // draw the wall tiers
if (midtexture) if (midtexture)
{ // one sided line { // one sided line
@ -1165,7 +1167,7 @@ void R_RenderSegLoop ()
{ {
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
R_DrawWallSegment(rw_pic, x1, x2, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false); R_DrawWallSegment(rw_pic, x1, x2, walltop, wallbottom, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_frontfz1, rw_frontfz2), false, light_list);
} }
fillshort (ceilingclip+x1, x2-x1, viewheight); fillshort (ceilingclip+x1, x2-x1, viewheight);
fillshort (floorclip+x1, x2-x1, 0xffff); fillshort (floorclip+x1, x2-x1, 0xffff);
@ -1201,7 +1203,7 @@ void R_RenderSegLoop ()
{ {
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
R_DrawWallSegment(rw_pic, x1, x2, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false); R_DrawWallSegment(rw_pic, x1, x2, walltop, wallupper, swall, lwall, yscale, MAX(rw_frontcz1, rw_frontcz2), MIN(rw_backcz1, rw_backcz2), false, light_list);
} }
memcpy (ceilingclip+x1, wallupper+x1, (x2-x1)*sizeof(short)); memcpy (ceilingclip+x1, wallupper+x1, (x2-x1)*sizeof(short));
} }
@ -1240,7 +1242,7 @@ void R_RenderSegLoop ()
{ {
rw_offset = -rw_offset; rw_offset = -rw_offset;
} }
R_DrawWallSegment(rw_pic, x1, x2, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false); R_DrawWallSegment(rw_pic, x1, x2, walllower, wallbottom, swall, lwall, yscale, MAX(rw_backfz1, rw_backfz2), MIN(rw_frontfz1, rw_frontfz2), false, light_list);
} }
memcpy (floorclip+x1, walllower+x1, (x2-x1)*sizeof(short)); memcpy (floorclip+x1, walllower+x1, (x2-x1)*sizeof(short));
} }

View file

@ -42,6 +42,8 @@
#include "r_3dfloors.h" #include "r_3dfloors.h"
#include "v_palette.h" #include "v_palette.h"
#include "r_data/colormaps.h" #include "r_data/colormaps.h"
#include "gl/dynlights/gl_dynlight.h"
#include "r_drawers.h"
namespace swrenderer namespace swrenderer
{ {
@ -537,6 +539,53 @@ static void Draw1Column(int x, int y1, int y2, WallSampler &sampler, void(*draw1
{ {
if (r_swtruecolor) if (r_swtruecolor)
{ {
// Find column position in view space
float w1 = 1.0f / WallC.sz1;
float w2 = 1.0f / WallC.sz2;
float t = (x - WallC.sx1 + 0.5f) / (WallC.sx2 - WallC.sx1);
float wcol = w1 * (1.0f - t) + w2 * t;
float zcol = 1.0f / wcol;
float xcol = (WallC.tleft.X * w1 * (1.0f - t) + WallC.tright.X * w2 * t) * zcol;
float ycol = (WallC.tleft.Y * w1 * (1.0f - t) + WallC.tright.Y * w2 * t) * zcol;
dc_viewpos.X = xcol;
dc_viewpos.Y = ycol;
dc_viewpos.Z = (float)((CenterY - y1 - 0.5) / InvZtoScale * zcol);
dc_viewpos_step.Z = (float)(-zcol / InvZtoScale);
static TriLight lightbuffer[64 * 1024];
static int nextlightindex = 0;
// Setup lights for column
dc_num_lights = 0;
dc_lights = lightbuffer + nextlightindex;
FLightNode *cur_node = dc_light_list;
while (cur_node && nextlightindex < 64 * 1024)
{
uint32_t red = cur_node->lightsource->GetRed();
uint32_t green = cur_node->lightsource->GetGreen();
uint32_t blue = cur_node->lightsource->GetBlue();
double lightX = cur_node->lightsource->X() - ViewPos.X;
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
nextlightindex++;
auto &light = dc_lights[dc_num_lights++];
light.x = (float)(lightX * ViewSin - lightY * ViewCos) - dc_viewpos.X;
light.y = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
light.z = (float)lightZ;
light.radius = 256.0f / cur_node->lightsource->GetRadius();
light.color = 0xff000000 | (red << 16) | (green << 8) | blue;
// Precalculate the constant part of the dot here so the drawer doesn't have to.
light.x = light.x * light.x + light.y * light.y;
cur_node = cur_node->nextLight;
}
if (nextlightindex == 64 * 1024)
nextlightindex = 0;
int count = y2 - y1; int count = y2 - y1;
dc_source = sampler.source; dc_source = sampler.source;
@ -738,6 +787,25 @@ static void ProcessWallWorker(
float light = rw_light; float light = rw_light;
double xmagnitude = 1.0;
#if !defined(NO_DYNAMIC_SWLIGHTS)
for (int x = x1; x < x2; x++, light += rw_lightstep)
{
int y1 = uwal[x];
int y2 = dwal[x];
if (y2 <= y1)
continue;
if (!fixed)
R_SetColorMapLight(basecolormap, light, wallshade);
if (x + 1 < x2) xmagnitude = fabs(FIXED2DBL(lwal[x + 1]) - FIXED2DBL(lwal[x]));
WallSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic, getcol);
Draw1Column(x, y1, y2, sampler, draw1column);
}
#else
// Calculate where 4 column alignment begins and ends: // Calculate where 4 column alignment begins and ends:
int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2); int aligned_x1 = clamp((x1 + 3) / 4 * 4, x1, x2);
int aligned_x2 = clamp(x2 / 4 * 4, x1, x2); int aligned_x2 = clamp(x2 / 4 * 4, x1, x2);
@ -872,6 +940,7 @@ static void ProcessWallWorker(
WallSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic, getcol); WallSampler sampler(y1, swal[x], yrepeat, lwal[x] + xoffset, xmagnitude, rw_pic, getcol);
Draw1Column(x, y1, y2, sampler, draw1column); Draw1Column(x, y1, y2, sampler, draw1column);
} }
#endif
NetUpdate(); NetUpdate();
} }
@ -1077,8 +1146,9 @@ void R_DrawDrawSeg(drawseg_t *ds, int x1, int x2, short *uwal, short *dwal, floa
} }
void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask) void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *wallbottom, float *swall, fixed_t *lwall, double yscale, double top, double bottom, bool mask, FLightNode *light_list)
{ {
dc_light_list = light_list;
if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits) if (rw_pic->GetHeight() != 1 << rw_pic->HeightBits)
{ {
ProcessWallNP2(x1, x2, walltop, wallbottom, swall, lwall, yscale, top, bottom, false); ProcessWallNP2(x1, x2, walltop, wallbottom, swall, lwall, yscale, top, bottom, false);
@ -1087,6 +1157,7 @@ void R_DrawWallSegment(FTexture *rw_pic, int x1, int x2, short *walltop, short *
{ {
ProcessWall(x1, x2, walltop, wallbottom, swall, lwall, yscale, false); ProcessWall(x1, x2, walltop, wallbottom, swall, lwall, yscale, false);
} }
dc_light_list = nullptr;
} }
void R_DrawSkySegment(visplane_t *pl, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x)) void R_DrawSkySegment(visplane_t *pl, short *uwal, short *dwal, float *swal, fixed_t *lwal, double yrepeat, const BYTE *(*getcol)(FTexture *tex, int x))

View file

@ -107,6 +107,9 @@ void DrawWallCodegen::Generate(DrawWallVariant variant, bool fourColumns, SSAVal
one[i] = ((0x80000000 + textureheight[i] - 1) / textureheight[i]) * 2 + 1; one[i] = ((0x80000000 + textureheight[i] - 1) / textureheight[i]) * 2 + 1;
} }
start_z = start_z + step_z * SSAFloat(skipped_by_thread(dest_y, thread));
step_z = step_z * SSAFloat(thread.num_cores);
SSAIfBlock branch; SSAIfBlock branch;
branch.if_block(is_simple_shade); branch.if_block(is_simple_shade);
LoopShade(variant, fourColumns, true); LoopShade(variant, fourColumns, true);