mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-25 13:41:05 +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;
|
||||
|
||||
double dc_texturemid;
|
||||
FLightNode *dc_light_list;
|
||||
|
||||
int ylookup[MAXHEIGHT];
|
||||
uint8_t shadetables[NUMCOLORMAPS * 16 * 256];
|
||||
|
@ -100,6 +101,10 @@ namespace swrenderer
|
|||
uint8_t *dc_destorg;
|
||||
int dc_destheight;
|
||||
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_iscale[4];
|
||||
uint8_t *dc_wall_colormap[4];
|
||||
|
|
|
@ -4,6 +4,8 @@
|
|||
#include "r_defs.h"
|
||||
|
||||
struct FSWColormap;
|
||||
struct FLightNode;
|
||||
struct TriLight;
|
||||
|
||||
EXTERN_CVAR(Bool, r_multithreaded);
|
||||
EXTERN_CVAR(Bool, r_magfilter);
|
||||
|
@ -34,6 +36,7 @@ namespace swrenderer
|
|||
};
|
||||
|
||||
extern double dc_texturemid;
|
||||
extern FLightNode *dc_light_list;
|
||||
|
||||
namespace drawerargs
|
||||
{
|
||||
|
@ -63,6 +66,10 @@ namespace swrenderer
|
|||
extern uint8_t *dc_destorg;
|
||||
extern int dc_destheight;
|
||||
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;
|
||||
|
||||
|
|
|
@ -221,26 +221,11 @@ namespace swrenderer
|
|||
if (args.source2[0] == nullptr)
|
||||
args.flags |= DrawWallArgs::nearest_filter;
|
||||
|
||||
args.z = 0.0f;
|
||||
args.step_z = 0.0f;
|
||||
args.dynlights = nullptr;
|
||||
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);
|
||||
}
|
||||
|
||||
|
@ -299,10 +284,10 @@ namespace swrenderer
|
|||
if (args.source2[0] == nullptr)
|
||||
args.flags |= DrawWallArgs::nearest_filter;
|
||||
|
||||
args.z = 0.0f;
|
||||
args.step_z = 0.0f;
|
||||
args.dynlights = nullptr;
|
||||
args.num_dynlights = 0;
|
||||
args.z = dc_viewpos.Z;
|
||||
args.step_z = dc_viewpos_step.Z;
|
||||
args.dynlights = dc_lights;
|
||||
args.num_dynlights = dc_num_lights;
|
||||
|
||||
DetectRangeError(args.dest, args.dest_y, args.count);
|
||||
}
|
||||
|
|
|
@ -60,7 +60,7 @@ namespace swrenderer
|
|||
{
|
||||
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);
|
||||
|
||||
#define HEIGHTBITS 12
|
||||
|
@ -1139,6 +1139,8 @@ void R_RenderSegLoop ()
|
|||
}
|
||||
if(fake3D & 7) return;
|
||||
|
||||
FLightNode *light_list = (curline && curline->sidedef) ? curline->sidedef->lighthead : nullptr;
|
||||
|
||||
// draw the wall tiers
|
||||
if (midtexture)
|
||||
{ // one sided line
|
||||
|
@ -1165,7 +1167,7 @@ void R_RenderSegLoop ()
|
|||
{
|
||||
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 (floorclip+x1, x2-x1, 0xffff);
|
||||
|
@ -1201,7 +1203,7 @@ void R_RenderSegLoop ()
|
|||
{
|
||||
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));
|
||||
}
|
||||
|
@ -1240,7 +1242,7 @@ void R_RenderSegLoop ()
|
|||
{
|
||||
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));
|
||||
}
|
||||
|
|
|
@ -42,6 +42,8 @@
|
|||
#include "r_3dfloors.h"
|
||||
#include "v_palette.h"
|
||||
#include "r_data/colormaps.h"
|
||||
#include "gl/dynlights/gl_dynlight.h"
|
||||
#include "r_drawers.h"
|
||||
|
||||
namespace swrenderer
|
||||
{
|
||||
|
@ -537,6 +539,53 @@ static void Draw1Column(int x, int y1, int y2, WallSampler &sampler, void(*draw1
|
|||
{
|
||||
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;
|
||||
|
||||
dc_source = sampler.source;
|
||||
|
@ -738,6 +787,25 @@ static void ProcessWallWorker(
|
|||
|
||||
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:
|
||||
int aligned_x1 = clamp((x1 + 3) / 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);
|
||||
Draw1Column(x, y1, y2, sampler, draw1column);
|
||||
}
|
||||
#endif
|
||||
|
||||
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)
|
||||
{
|
||||
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);
|
||||
}
|
||||
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))
|
||||
|
|
|
@ -107,6 +107,9 @@ void DrawWallCodegen::Generate(DrawWallVariant variant, bool fourColumns, SSAVal
|
|||
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;
|
||||
branch.if_block(is_simple_shade);
|
||||
LoopShade(variant, fourColumns, true);
|
||||
|
|
Loading…
Reference in a new issue