mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-03 01:13:22 +00:00
Add menu option to enable dynamic lights (independent of the OpenGL setting so that you can have it on in OpenGL and off in Software)
This commit is contained in:
parent
06bc911828
commit
2bb2395569
6 changed files with 109 additions and 87 deletions
|
@ -53,6 +53,8 @@
|
||||||
#include "r_draw_pal.h"
|
#include "r_draw_pal.h"
|
||||||
#include "r_thread.h"
|
#include "r_thread.h"
|
||||||
|
|
||||||
|
CVAR(Bool, r_dynlights, 1, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
// Needed by R_DrawFogBoundary (which probably shouldn't be part of this file)
|
// Needed by R_DrawFogBoundary (which probably shouldn't be part of this file)
|
||||||
|
|
|
@ -16,6 +16,7 @@ EXTERN_CVAR(Int, r_drawfuzz);
|
||||||
EXTERN_CVAR(Bool, r_drawtrans);
|
EXTERN_CVAR(Bool, r_drawtrans);
|
||||||
EXTERN_CVAR(Float, transsouls);
|
EXTERN_CVAR(Float, transsouls);
|
||||||
EXTERN_CVAR(Int, r_columnmethod);
|
EXTERN_CVAR(Int, r_columnmethod);
|
||||||
|
EXTERN_CVAR(Bool, r_dynlights);
|
||||||
|
|
||||||
namespace swrenderer
|
namespace swrenderer
|
||||||
{
|
{
|
||||||
|
|
|
@ -258,54 +258,61 @@ void R_MapPlane (int y, int x1)
|
||||||
|
|
||||||
if (r_swtruecolor)
|
if (r_swtruecolor)
|
||||||
{
|
{
|
||||||
// Find row position in view space
|
if (r_dynlights)
|
||||||
float zspan = planeheight / (fabs(y + 0.5 - CenterY) / InvZtoScale);
|
|
||||||
dc_viewpos.X = (float)((x1 + 0.5 - CenterX) / CenterX * zspan);
|
|
||||||
dc_viewpos.Y = zspan;
|
|
||||||
dc_viewpos.Z = (float)((CenterY - y - 0.5) / InvZtoScale * zspan);
|
|
||||||
dc_viewpos_step.X = (float)(zspan / CenterX);
|
|
||||||
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
// Find row position in view space
|
||||||
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
float zspan = planeheight / (fabs(y + 0.5 - CenterY) / InvZtoScale);
|
||||||
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
dc_viewpos.X = (float)((x1 + 0.5 - CenterX) / CenterX * zspan);
|
||||||
|
dc_viewpos.Y = zspan;
|
||||||
|
dc_viewpos.Z = (float)((CenterY - y - 0.5) / InvZtoScale * zspan);
|
||||||
|
dc_viewpos_step.X = (float)(zspan / CenterX);
|
||||||
|
|
||||||
float lx = (float)(lightX * ViewSin - lightY * ViewCos);
|
static TriLight lightbuffer[64 * 1024];
|
||||||
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
static int nextlightindex = 0;
|
||||||
float lz = (float)lightZ - dc_viewpos.Z;
|
|
||||||
|
|
||||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
// Setup lights for column
|
||||||
float lconstant = ly * ly + lz * lz;
|
dc_num_lights = 0;
|
||||||
|
dc_lights = lightbuffer + nextlightindex;
|
||||||
// Include light only if it touches this row
|
visplane_light *cur_node = ds_light_list;
|
||||||
float radius = cur_node->lightsource->GetRadius();
|
while (cur_node && nextlightindex < 64 * 1024)
|
||||||
if (radius * radius >= lconstant)
|
|
||||||
{
|
{
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
||||||
|
|
||||||
nextlightindex++;
|
float lx = (float)(lightX * ViewSin - lightY * ViewCos);
|
||||||
auto &light = dc_lights[dc_num_lights++];
|
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
||||||
light.x = lx;
|
float lz = (float)lightZ - dc_viewpos.Z;
|
||||||
light.y = lconstant;
|
|
||||||
light.radius = 256.0f / radius;
|
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
float lconstant = ly * ly + lz * lz;
|
||||||
|
|
||||||
|
// Include light only if it touches this row
|
||||||
|
float radius = cur_node->lightsource->GetRadius();
|
||||||
|
if (radius * radius >= lconstant)
|
||||||
|
{
|
||||||
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
|
nextlightindex++;
|
||||||
|
auto &light = dc_lights[dc_num_lights++];
|
||||||
|
light.x = lx;
|
||||||
|
light.y = lconstant;
|
||||||
|
light.radius = 256.0f / radius;
|
||||||
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_node = cur_node->next;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_node = cur_node->next;
|
if (nextlightindex == 64 * 1024)
|
||||||
|
nextlightindex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc_num_lights = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextlightindex == 64 * 1024)
|
|
||||||
nextlightindex = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ds_y = y;
|
ds_y = y;
|
||||||
|
@ -348,6 +355,9 @@ namespace
|
||||||
|
|
||||||
void R_AddPlaneLights(visplane_t *plane, FLightNode *node)
|
void R_AddPlaneLights(visplane_t *plane, FLightNode *node)
|
||||||
{
|
{
|
||||||
|
if (!r_dynlights)
|
||||||
|
return;
|
||||||
|
|
||||||
while (node)
|
while (node)
|
||||||
{
|
{
|
||||||
if (!(node->lightsource->flags2&MF2_DORMANT))
|
if (!(node->lightsource->flags2&MF2_DORMANT))
|
||||||
|
|
|
@ -539,61 +539,68 @@ 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
|
if (r_dynlights)
|
||||||
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;
|
|
||||||
dc_viewpos.X = (float)((x + 0.5 - CenterX) / CenterX * zcol);
|
|
||||||
dc_viewpos.Y = zcol;
|
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
// 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;
|
||||||
|
dc_viewpos.X = (float)((x + 0.5 - CenterX) / CenterX * zcol);
|
||||||
|
dc_viewpos.Y = zcol;
|
||||||
|
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)
|
||||||
{
|
{
|
||||||
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
if (!(cur_node->lightsource->flags2&MF2_DORMANT))
|
||||||
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
|
||||||
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
|
||||||
|
|
||||||
float lx = (float)(lightX * ViewSin - lightY * ViewCos) - dc_viewpos.X;
|
|
||||||
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
|
||||||
float lz = (float)lightZ;
|
|
||||||
|
|
||||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
|
||||||
float lconstant = lx * lx + ly * ly;
|
|
||||||
|
|
||||||
// Include light only if it touches this column
|
|
||||||
float radius = cur_node->lightsource->GetRadius();
|
|
||||||
if (radius * radius >= lconstant)
|
|
||||||
{
|
{
|
||||||
uint32_t red = cur_node->lightsource->GetRed();
|
double lightX = cur_node->lightsource->X() - ViewPos.X;
|
||||||
uint32_t green = cur_node->lightsource->GetGreen();
|
double lightY = cur_node->lightsource->Y() - ViewPos.Y;
|
||||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
double lightZ = cur_node->lightsource->Z() - ViewPos.Z;
|
||||||
|
|
||||||
nextlightindex++;
|
float lx = (float)(lightX * ViewSin - lightY * ViewCos) - dc_viewpos.X;
|
||||||
auto &light = dc_lights[dc_num_lights++];
|
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - dc_viewpos.Y;
|
||||||
light.x = lconstant;
|
float lz = (float)lightZ;
|
||||||
light.z = lz;
|
|
||||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||||
light.color = (red << 16) | (green << 8) | blue;
|
float lconstant = lx * lx + ly * ly;
|
||||||
|
|
||||||
|
// Include light only if it touches this column
|
||||||
|
float radius = cur_node->lightsource->GetRadius();
|
||||||
|
if (radius * radius >= lconstant)
|
||||||
|
{
|
||||||
|
uint32_t red = cur_node->lightsource->GetRed();
|
||||||
|
uint32_t green = cur_node->lightsource->GetGreen();
|
||||||
|
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||||
|
|
||||||
|
nextlightindex++;
|
||||||
|
auto &light = dc_lights[dc_num_lights++];
|
||||||
|
light.x = lconstant;
|
||||||
|
light.z = lz;
|
||||||
|
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||||
|
light.color = (red << 16) | (green << 8) | blue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
cur_node = cur_node->nextLight;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_node = cur_node->nextLight;
|
if (nextlightindex == 64 * 1024)
|
||||||
|
nextlightindex = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dc_num_lights = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (nextlightindex == 64 * 1024)
|
|
||||||
nextlightindex = 0;
|
|
||||||
|
|
||||||
int count = y2 - y1;
|
int count = y2 - y1;
|
||||||
|
|
||||||
|
|
|
@ -2754,4 +2754,5 @@ TCMNU_TRUECOLOR = "True color output";
|
||||||
TCMNU_MINFILTER = "Linear filter when downscaling";
|
TCMNU_MINFILTER = "Linear filter when downscaling";
|
||||||
TCMNU_MAGFILTER = "Linear filter when upscaling";
|
TCMNU_MAGFILTER = "Linear filter when upscaling";
|
||||||
TCMNU_MIPMAP = "Use mipmapped textures";
|
TCMNU_MIPMAP = "Use mipmapped textures";
|
||||||
|
TCMNU_DYNLIGHTS = "Dynamic lights";
|
||||||
|
|
||||||
|
|
|
@ -675,6 +675,7 @@ OptionMenu "TrueColorOptions"
|
||||||
Option "$TCMNU_MINFILTER", "r_minfilter", "OnOff"
|
Option "$TCMNU_MINFILTER", "r_minfilter", "OnOff"
|
||||||
Option "$TCMNU_MAGFILTER", "r_magfilter", "OnOff"
|
Option "$TCMNU_MAGFILTER", "r_magfilter", "OnOff"
|
||||||
Option "$TCMNU_MIPMAP", "r_mipmap", "OnOff"
|
Option "$TCMNU_MIPMAP", "r_mipmap", "OnOff"
|
||||||
|
Option "$TCMNU_DYNLIGHTS", "r_dynlights", "OnOff"
|
||||||
}
|
}
|
||||||
|
|
||||||
OptionMenu "VideoOptions"
|
OptionMenu "VideoOptions"
|
||||||
|
|
Loading…
Reference in a new issue