2016-09-14 18:01:13 +00:00
|
|
|
//
|
|
|
|
//---------------------------------------------------------------------------
|
|
|
|
//
|
2018-04-16 07:02:48 +00:00
|
|
|
// Copyright(C) 2002-2018 Christoph Oelckers
|
2016-09-14 18:01:13 +00:00
|
|
|
// All rights reserved.
|
|
|
|
//
|
|
|
|
// This program is free software: you can redistribute it and/or modify
|
|
|
|
// it under the terms of the GNU Lesser General Public License as published by
|
|
|
|
// the Free Software Foundation, either version 3 of the License, or
|
|
|
|
// (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful,
|
|
|
|
// but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
// GNU Lesser General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU Lesser General Public License
|
|
|
|
// along with this program. If not, see http://www.gnu.org/licenses/
|
|
|
|
//
|
|
|
|
//--------------------------------------------------------------------------
|
|
|
|
//
|
2013-06-23 07:49:34 +00:00
|
|
|
/*
|
|
|
|
** gl_dynlight1.cpp
|
|
|
|
** dynamic light application
|
|
|
|
**
|
2016-09-14 18:01:13 +00:00
|
|
|
**/
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2017-03-11 18:18:31 +00:00
|
|
|
#include "actorinlines.h"
|
2020-04-25 19:08:07 +00:00
|
|
|
#include "a_dynlight.h"
|
2018-04-16 07:02:48 +00:00
|
|
|
#include "hw_dynlightdata.h"
|
2020-04-26 17:58:17 +00:00
|
|
|
#include"hw_cvars.h"
|
2021-08-11 08:06:22 +00:00
|
|
|
#include "v_video.h"
|
2020-04-25 19:08:07 +00:00
|
|
|
#include "hwrenderer/scene/hw_drawstructs.h"
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2018-05-03 19:27:45 +00:00
|
|
|
// If we want to share the array to avoid constant allocations it needs to be thread local unless it'd be littered with expensive synchronization.
|
|
|
|
thread_local FDynLightData lightdata;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Light related CVARs
|
|
|
|
//
|
|
|
|
//==========================================================================
|
|
|
|
|
2018-04-16 06:55:13 +00:00
|
|
|
// These shouldn't be called 'gl...' anymore...
|
2013-06-23 07:49:34 +00:00
|
|
|
CVAR (Bool, gl_light_sprites, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
|
|
|
CVAR (Bool, gl_light_particles, true, CVAR_ARCHIVE | CVAR_GLOBALCONFIG);
|
|
|
|
|
2019-01-01 18:35:55 +00:00
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Sets up the parameters to render one dynamic light onto one plane
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2020-04-25 19:08:07 +00:00
|
|
|
bool GetLight(FDynLightData& dld, int group, Plane & p, FDynamicLight * light, bool checkside)
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2016-03-30 18:01:44 +00:00
|
|
|
DVector3 pos = light->PosRelative(group);
|
2016-09-04 10:45:09 +00:00
|
|
|
float radius = (light->GetRadius());
|
2017-07-25 21:00:09 +00:00
|
|
|
|
2018-05-16 21:34:52 +00:00
|
|
|
auto dist = fabs(p.DistToPoint((float)pos.X, (float)pos.Z, (float)pos.Y));
|
2017-07-31 22:43:58 +00:00
|
|
|
|
|
|
|
if (radius <= 0.f) return false;
|
|
|
|
if (dist > radius) return false;
|
2018-05-16 21:34:52 +00:00
|
|
|
if (checkside && p.PointOnSide((float)pos.X, (float)pos.Z, (float)pos.Y))
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
2017-07-31 22:43:58 +00:00
|
|
|
return false;
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|
2020-04-25 19:08:07 +00:00
|
|
|
AddLightToList(dld, group, light, false);
|
2017-07-31 22:43:58 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
//==========================================================================
|
|
|
|
//
|
|
|
|
// Add one dynamic light to the light data list
|
|
|
|
//
|
|
|
|
//==========================================================================
|
2020-04-25 19:08:07 +00:00
|
|
|
void AddLightToList(FDynLightData &dld, int group, FDynamicLight * light, bool forceAttenuate)
|
2017-07-31 22:43:58 +00:00
|
|
|
{
|
|
|
|
int i = 0;
|
|
|
|
|
|
|
|
DVector3 pos = light->PosRelative(group);
|
|
|
|
float radius = light->GetRadius();
|
|
|
|
|
2013-06-23 07:49:34 +00:00
|
|
|
float cs;
|
2016-09-04 10:35:26 +00:00
|
|
|
if (light->IsAdditive())
|
2013-06-23 07:49:34 +00:00
|
|
|
{
|
|
|
|
cs = 0.2f;
|
|
|
|
i = 2;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
cs = 1.0f;
|
|
|
|
}
|
|
|
|
|
2025-04-29 18:37:28 +00:00
|
|
|
if (light->target && (light->target->renderflags2 & RF2_LIGHTMULTALPHA))
|
2024-12-25 10:22:43 +00:00
|
|
|
cs *= (float)light->target->Alpha;
|
|
|
|
|
2016-09-04 10:45:09 +00:00
|
|
|
float r = light->GetRed() / 255.0f * cs;
|
|
|
|
float g = light->GetGreen() / 255.0f * cs;
|
|
|
|
float b = light->GetBlue() / 255.0f * cs;
|
2013-06-23 07:49:34 +00:00
|
|
|
|
|
|
|
if (light->IsSubtractive())
|
|
|
|
{
|
2017-03-12 18:44:00 +00:00
|
|
|
DVector3 v(r, g, b);
|
|
|
|
float length = (float)v.Length();
|
2013-06-23 07:49:34 +00:00
|
|
|
|
2017-03-12 18:44:00 +00:00
|
|
|
r = length - r;
|
|
|
|
g = length - g;
|
|
|
|
b = length - b;
|
2013-06-23 07:49:34 +00:00
|
|
|
i = 1;
|
|
|
|
}
|
|
|
|
|
2020-04-26 17:58:17 +00:00
|
|
|
float shadowIndex;
|
2021-08-11 08:06:22 +00:00
|
|
|
if (screen->mShadowMap.Enabled()) // note: with shadowmaps switched off, we cannot rely on properly set indices anymore.
|
2020-04-26 17:58:17 +00:00
|
|
|
{
|
|
|
|
shadowIndex = light->mShadowmapIndex + 1.0f;
|
|
|
|
}
|
|
|
|
else shadowIndex = 1025.f;
|
2020-06-12 13:16:50 +00:00
|
|
|
// Store attenuate flag in the sign bit of the float.
|
|
|
|
if (light->IsAttenuated() || forceAttenuate) shadowIndex = -shadowIndex;
|
2017-03-02 17:07:47 +00:00
|
|
|
|
2018-01-04 16:58:11 +00:00
|
|
|
float lightType = 0.0f;
|
|
|
|
float spotInnerAngle = 0.0f;
|
|
|
|
float spotOuterAngle = 0.0f;
|
|
|
|
float spotDirX = 0.0f;
|
|
|
|
float spotDirY = 0.0f;
|
|
|
|
float spotDirZ = 0.0f;
|
|
|
|
if (light->IsSpot())
|
|
|
|
{
|
|
|
|
lightType = 1.0f;
|
2019-01-01 18:35:55 +00:00
|
|
|
spotInnerAngle = (float)light->pSpotInnerAngle->Cos();
|
|
|
|
spotOuterAngle = (float)light->pSpotOuterAngle->Cos();
|
2018-01-04 16:58:11 +00:00
|
|
|
|
2019-01-01 18:35:55 +00:00
|
|
|
DAngle negPitch = -*light->pPitch;
|
|
|
|
DAngle Angle = light->target->Angles.Yaw;
|
2018-01-04 18:27:03 +00:00
|
|
|
double xzLen = negPitch.Cos();
|
2019-01-01 18:35:55 +00:00
|
|
|
spotDirX = float(-Angle.Cos() * xzLen);
|
2018-05-16 21:34:52 +00:00
|
|
|
spotDirY = float(-negPitch.Sin());
|
2019-01-01 18:35:55 +00:00
|
|
|
spotDirZ = float(-Angle.Sin() * xzLen);
|
2018-01-04 16:58:11 +00:00
|
|
|
}
|
|
|
|
|
2020-04-25 19:08:07 +00:00
|
|
|
float *data = &dld.arrays[i][dld.arrays[i].Reserve(16)];
|
2018-05-16 21:34:52 +00:00
|
|
|
data[0] = float(pos.X);
|
|
|
|
data[1] = float(pos.Z);
|
|
|
|
data[2] = float(pos.Y);
|
2013-06-23 07:49:34 +00:00
|
|
|
data[3] = radius;
|
|
|
|
data[4] = r;
|
|
|
|
data[5] = g;
|
|
|
|
data[6] = b;
|
2017-03-02 17:07:47 +00:00
|
|
|
data[7] = shadowIndex;
|
2018-01-04 16:58:11 +00:00
|
|
|
data[8] = spotDirX;
|
|
|
|
data[9] = spotDirY;
|
|
|
|
data[10] = spotDirZ;
|
|
|
|
data[11] = lightType;
|
|
|
|
data[12] = spotInnerAngle;
|
|
|
|
data[13] = spotOuterAngle;
|
|
|
|
data[14] = 0.0f; // unused
|
|
|
|
data[15] = 0.0f; // unused
|
2013-06-23 07:49:34 +00:00
|
|
|
}
|
|
|
|
|