Calculate sprite dynamic light contribution and pass it along to the sprite drawer

This commit is contained in:
Magnus Norddahl 2017-02-14 06:37:06 +01:00
parent 5ef8ecce2a
commit eac98ac226
3 changed files with 57 additions and 0 deletions

View file

@ -56,6 +56,7 @@
#include "swrenderer/viewport/r_viewport.h"
#include "swrenderer/r_memory.h"
#include "swrenderer/r_renderthread.h"
#include "gl/dynlights/gl_dynlight.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
@ -225,6 +226,54 @@ namespace swrenderer
bool fullbright = !vis->foggy && ((renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
bool fadeToBlack = (vis->RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
if (r_dynlights)
{
float lit_red = 0;
float lit_green = 0;
float lit_blue = 0;
auto node = vis->sector->lighthead;
while (node != nullptr)
{
ADynamicLight *light = node->lightsource;
if (light->visibletoplayer && !(light->flags2&MF2_DORMANT) && (!(light->flags4&MF4_DONTLIGHTSELF) || light->target != thing))
{
double lightX = light->X() - ViewPos.X;
double lightY = light->Y() - ViewPos.Y;
double lightZ = light->Z() - ViewPos.Z;
float lx = (float)(lightX * ViewSin - lightY * ViewCos) - pos.X;
float ly = (float)(lightX * ViewTanCos + lightY * ViewTanSin) - pos.Y;
float lz = (float)lightZ - pos.Z;
bool is_point_light = (node->lightsource->flags4 & MF4_ATTENUATE) != 0;
float LdotL = lx * lx + ly * ly + lz * lz;
float NdotL = is_point_light ? -ly : 0.0f;
float radius = node->lightsource->GetRadius();
if (radius * radius >= LdotL && NdotL > 0.0f)
{
uint32_t red = light->GetRed();
uint32_t green = light->GetGreen();
uint32_t blue = light->GetBlue();
float distance = sqrt(LdotL);
float attenuation = distance / radius * NdotL;
lit_red += red * attenuation;
lit_red += green * attenuation;
lit_red += blue * attenuation;
}
}
node = node->nextLight;
}
lit_red = MIN(lit_red, 255.0f);
lit_green = MIN(lit_green, 255.0f);
lit_blue = MIN(lit_blue, 255.0f);
vis->dynlightcolor = (((uint32_t)lit_red) << 16) | (((uint32_t)lit_green) << 8) | ((uint32_t)lit_blue);
}
else
{
vis->dynlightcolor = 0;
}
vis->Light.SetColormap(LightVisibility::Instance()->SpriteGlobVis() / MAX(tz, MINZ), spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
@ -250,6 +299,7 @@ namespace swrenderer
SpriteDrawerArgs drawerargs;
drawerargs.SetLight(vis->Light.BaseColormap, 0, vis->Light.ColormapNum << FRACBITS);
drawerargs.SetDynamicLight(dynlightcolor);
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(vis->Light.BaseColormap);

View file

@ -32,5 +32,7 @@ namespace swrenderer
uint32_t Translation = 0;
uint32_t FillColor = 0;
uint32_t dynlightcolor = 0;
};
}

View file

@ -21,6 +21,7 @@ namespace swrenderer
void SetDest(int x, int y);
void SetCount(int count) { dc_count = count; }
void SetSolidColor(int color) { dc_color = color; }
void SetDynamicLight(uint32_t color) { dynlightcolor = color; }
void DrawMaskedColumn(RenderThread *thread, int x, fixed_t iscale, FTexture *texture, fixed_t column, double spryscale, double sprtopscreen, bool sprflipvert, const short *mfloorclip, const short *mceilingclip, bool unmasked = false);
void FillColumn(RenderThread *thread);
@ -50,6 +51,8 @@ namespace swrenderer
uint32_t *DestBlend() const { return dc_destblend; }
fixed_t SrcAlpha() const { return dc_srcalpha; }
fixed_t DestAlpha() const { return dc_destalpha; }
uint32_t DynamicLight() const { return dynlightcolor; }
private:
bool SetBlendFunc(int op, fixed_t fglevel, fixed_t bglevel, int flags);
@ -81,6 +84,8 @@ namespace swrenderer
int dc_color = 0;
uint32_t dc_srccolor = 0;
uint32_t dc_srccolor_bgra = 0;
uint32_t dynlightcolor = 0;
typedef void(SWPixelFormatDrawers::*SpriteDrawerFunc)(const SpriteDrawerArgs &args);
SpriteDrawerFunc colfunc;