Plane dynlight setup

This commit is contained in:
Magnus Norddahl 2016-12-22 07:06:18 +01:00
parent 5cfe0cc955
commit fcbacf8cac
5 changed files with 120 additions and 0 deletions

View file

@ -1129,6 +1129,9 @@ void R_Subsector (subsector_t *sub)
portal
) : NULL;
if (ceilingplane)
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
if (fixedlightlev < 0 && frontsector->e && frontsector->e->XFloor.lightlist.Size())
{
light = P_GetPlaneLight(frontsector, &frontsector->floorplane, false);
@ -1166,6 +1169,9 @@ void R_Subsector (subsector_t *sub)
portal
) : NULL;
if (floorplane)
R_AddPlaneLights(floorplane, frontsector->lighthead);
// kg3D - fake planes rendering
if (r_3dfloors && frontsector->e && frontsector->e->XFloor.ffloors.Size())
{
@ -1223,6 +1229,9 @@ void R_Subsector (subsector_t *sub)
frontsector->sky,
NULL);
if (floorplane)
R_AddPlaneLights(floorplane, frontsector->lighthead);
R_FakeDrawLoop(sub);
fake3D = 0;
frontsector = sub->sector;
@ -1284,6 +1293,9 @@ void R_Subsector (subsector_t *sub)
frontsector->sky,
NULL);
if (ceilingplane)
R_AddPlaneLights(ceilingplane, frontsector->lighthead);
R_FakeDrawLoop(sub);
fake3D = 0;
frontsector = sub->sector;

View file

@ -63,6 +63,7 @@ namespace swrenderer
double dc_texturemid;
FLightNode *dc_light_list;
visplane_light *ds_light_list;
int ylookup[MAXHEIGHT];
uint8_t shadetables[NUMCOLORMAPS * 16 * 256];

View file

@ -20,6 +20,7 @@ EXTERN_CVAR(Int, r_columnmethod);
namespace swrenderer
{
struct vissprite_t;
struct visplane_light;
struct ShadeConstants
{
@ -37,6 +38,7 @@ namespace swrenderer
extern double dc_texturemid;
extern FLightNode *dc_light_list;
extern visplane_light *ds_light_list;
namespace drawerargs
{

View file

@ -59,6 +59,7 @@
#include "v_palette.h"
#include "r_data/colormaps.h"
#include "r_draw_rgba.h"
#include "gl/dynlights/gl_dynlight.h"
#ifdef _MSC_VER
#pragma warning(disable:4244)
@ -255,6 +256,50 @@ void R_MapPlane (int y, int x1)
R_SetDSColorMapLight(basecolormap, GlobVis * fabs(CenterY - y), planeshade);
}
if (r_swtruecolor)
{
// Find row position in view space
float zspan = (float)((CenterY - y - 0.5) * InvZtoScale / planeheight);
dc_viewpos.X = (float)((x1 + 0.5 - CenterX) / CenterX * zspan);
dc_viewpos.Y = zspan;
dc_viewpos.Z = (float)planeheight;
dc_viewpos_step.X = (float)(-zspan / InvZtoScale);
static TriLight lightbuffer[64 * 1024];
static int nextlightindex = 0;
// Setup lights for column
dc_num_lights = 0;
dc_lights = lightbuffer + nextlightindex;
visplane_light *cur_node = ds_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);
light.y = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
light.z = (float)(lightZ - dc_viewpos.Z);
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.y = light.y * light.y + light.z * light.z;
cur_node = cur_node->next;
}
if (nextlightindex == 64 * 1024)
nextlightindex = 0;
}
ds_y = y;
ds_x1 = x1;
ds_x2 = x2;
@ -284,6 +329,47 @@ void R_MapColoredPlane(int y, int x1)
R_DrawColoredSpan(y, x1, spanend[y]);
}
//==========================================================================
namespace
{
enum { max_plane_lights = 32 * 1024 };
visplane_light plane_lights[max_plane_lights];
int next_plane_light = 0;
}
void R_AddPlaneLights(visplane_t *plane, FLightNode *node)
{
while (node)
{
if (!(node->lightsource->flags2&MF2_DORMANT))
{
bool found = false;
visplane_light *light_node = plane->lights;
while (light_node)
{
if (light_node->lightsource == node->lightsource)
{
found = true;
break;
}
light_node = light_node->next;
}
if (!found)
{
if (next_plane_light == max_plane_lights)
return;
visplane_light *newlight = &plane_lights[next_plane_light++];
newlight->next = plane->lights;
newlight->lightsource = node->lightsource;
plane->lights = newlight;
}
}
node = node->nextLight;
}
}
//==========================================================================
//
// R_ClearPlanes
@ -336,6 +422,8 @@ void R_ClearPlanes (bool fullclear)
? (ConBottom - viewwindowy) : 0);
lastopening = 0;
next_plane_light = 0;
}
}
@ -363,6 +451,8 @@ static visplane_t *new_visplane (unsigned hash)
freehead = &freetail;
}
check->lights = nullptr;
check->next = visplanes[hash];
visplanes[hash] = check;
return check;
@ -1815,6 +1905,8 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
int t2 = pl->top[x];
int b2 = pl->bottom[x];
ds_light_list = pl->lights;
if (b2 > t2)
{
fillshort (spanend+t2, b2-t2, x);
@ -1861,6 +1953,8 @@ void R_MapVisPlane (visplane_t *pl, void (*mapfunc)(int y, int x1))
{
mapfunc (--b2, pl->left);
}
ds_light_list = nullptr;
}
//==========================================================================

View file

@ -26,10 +26,18 @@
#include <stddef.h>
class ASkyViewpoint;
class ADynamicLight;
struct FLightNode;
namespace swrenderer
{
struct visplane_light
{
ADynamicLight *lightsource;
visplane_light *next;
};
//
// The infamous visplane
//
@ -39,6 +47,7 @@ struct visplane_s
FDynamicColormap *colormap; // [RH] Support multiple colormaps
FSectorPortal *portal; // [RH] Support sky boxes
visplane_light *lights;
FTransform xform;
secplane_t height;
@ -89,6 +98,8 @@ void R_InitPlanes ();
void R_DeinitPlanes ();
void R_ClearPlanes (bool fullclear);
void R_AddPlaneLights(visplane_t *plane, FLightNode *light_head);
int R_DrawPlanes ();
void R_DrawPortals ();
void R_DrawSkyPlane (visplane_t *pl);