mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 21:51:09 +00:00
Hooked up dynamic light on walls
This commit is contained in:
parent
578e3270e2
commit
4e56c9a41a
6 changed files with 99 additions and 26 deletions
|
@ -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];
|
||||||
|
|
|
@ -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;
|
||||||
|
|
||||||
|
|
|
@ -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);
|
||||||
}
|
}
|
||||||
|
|
|
@ -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));
|
||||||
}
|
}
|
||||||
|
|
|
@ -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))
|
||||||
|
|
|
@ -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);
|
||||||
|
|
Loading…
Reference in a new issue