mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-12-16 07:21:28 +00:00
191 lines
4 KiB
C++
191 lines
4 KiB
C++
#ifndef __GLC_DYNLIGHT_H
|
|
#define __GLC_DYNLIGHT_H
|
|
|
|
#include "c_cvars.h"
|
|
#include "gl/utility/gl_geometric.h"
|
|
#include "gl/utility/gl_cycler.h"
|
|
|
|
|
|
EXTERN_CVAR(Bool, gl_lights)
|
|
EXTERN_CVAR(Bool, gl_attachedlights)
|
|
|
|
class ADynamicLight;
|
|
class FArchive;
|
|
|
|
|
|
|
|
enum
|
|
{
|
|
LIGHT_RED = 0,
|
|
LIGHT_GREEN = 1,
|
|
LIGHT_BLUE = 2,
|
|
LIGHT_INTENSITY = 3,
|
|
LIGHT_SECONDARY_INTENSITY = 4,
|
|
LIGHT_SCALE = 3,
|
|
};
|
|
|
|
// This is as good as something new - and it can be set directly in the ActorInfo!
|
|
#define MF4_SUBTRACTIVE MF4_MISSILEEVENMORE
|
|
#define MF4_ADDITIVE MF4_MISSILEMORE
|
|
#define MF4_DONTLIGHTSELF MF4_SEESDAGGERS
|
|
|
|
enum ELightType
|
|
{
|
|
PointLight,
|
|
PulseLight,
|
|
FlickerLight,
|
|
RandomFlickerLight,
|
|
SectorLight,
|
|
SpotLight,
|
|
ColorPulseLight,
|
|
ColorFlickerLight,
|
|
RandomColorFlickerLight
|
|
};
|
|
|
|
|
|
struct FLightNode
|
|
{
|
|
FLightNode ** prevTarget;
|
|
FLightNode * nextTarget;
|
|
FLightNode ** prevLight;
|
|
FLightNode * nextLight;
|
|
ADynamicLight * lightsource;
|
|
union
|
|
{
|
|
side_t * targLine;
|
|
subsector_t * targSubsector;
|
|
void * targ;
|
|
};
|
|
};
|
|
|
|
|
|
//
|
|
// Base class
|
|
//
|
|
// [CO] I merged everything together in this one class so that I don't have
|
|
// to create and re-create an excessive amount of objects
|
|
//
|
|
|
|
class ADynamicLight : public AActor
|
|
{
|
|
DECLARE_CLASS (ADynamicLight, AActor)
|
|
public:
|
|
virtual void Tick();
|
|
void Serialize(FArchive &arc);
|
|
BYTE GetRed() const { return args[LIGHT_RED]; }
|
|
BYTE GetGreen() const { return args[LIGHT_GREEN]; }
|
|
BYTE GetBlue() const { return args[LIGHT_BLUE]; }
|
|
float GetRadius() const { return (IsActive() ? m_currentRadius * 2.f : 0.f); }
|
|
void LinkLight();
|
|
void UnlinkLight();
|
|
size_t PointerSubstitution (DObject *old, DObject *notOld);
|
|
|
|
void BeginPlay();
|
|
void SetOrigin (double x, double y, double z, bool moving = false);
|
|
void PostBeginPlay();
|
|
void Destroy();
|
|
void Activate(AActor *activator);
|
|
void Deactivate(AActor *activator);
|
|
void SetOffset(const DVector3 &pos);
|
|
void UpdateLocation();
|
|
bool IsOwned() const { return owned; }
|
|
bool IsActive() const { return !(flags2&MF2_DORMANT); }
|
|
bool IsSubtractive() { return !!(flags4&MF4_SUBTRACTIVE); }
|
|
bool IsAdditive() { return !!(flags4&MF4_ADDITIVE); }
|
|
FState *targetState;
|
|
FLightNode * touching_sides;
|
|
FLightNode * touching_subsectors;
|
|
FLightNode * touching_sector;
|
|
|
|
private:
|
|
double DistToSeg(const DVector3 &pos, seg_t *seg);
|
|
void CollectWithinRadius(const DVector3 &pos, subsector_t *subSec, float radius);
|
|
|
|
protected:
|
|
DVector3 m_off;
|
|
float m_currentRadius;
|
|
int m_tickCount;
|
|
unsigned int m_lastUpdate;
|
|
FCycler m_cycler;
|
|
subsector_t * subsector;
|
|
|
|
public:
|
|
int m_Radius[2];
|
|
BYTE lightflags;
|
|
BYTE lighttype;
|
|
bool owned;
|
|
bool halo;
|
|
BYTE color2[3];
|
|
bool visibletoplayer;
|
|
int bufferindex;
|
|
|
|
// intermediate texture coordinate data
|
|
// this is stored in the light object to avoid recalculating it
|
|
// several times during rendering of a flat
|
|
Vector nearPt, up, right;
|
|
float scale;
|
|
|
|
};
|
|
|
|
class AVavoomLight : public ADynamicLight
|
|
{
|
|
DECLARE_CLASS (AVavoomLight, ADynamicLight)
|
|
public:
|
|
virtual void BeginPlay();
|
|
};
|
|
|
|
class AVavoomLightWhite : public AVavoomLight
|
|
{
|
|
DECLARE_CLASS (AVavoomLightWhite, AVavoomLight)
|
|
public:
|
|
virtual void BeginPlay();
|
|
};
|
|
|
|
class AVavoomLightColor : public AVavoomLight
|
|
{
|
|
DECLARE_CLASS (AVavoomLightColor, AVavoomLight)
|
|
public:
|
|
void BeginPlay();
|
|
};
|
|
|
|
|
|
enum
|
|
{
|
|
STAT_DLIGHT=64
|
|
};
|
|
|
|
struct FDynLightData
|
|
{
|
|
TArray<float> arrays[3];
|
|
|
|
void Clear()
|
|
{
|
|
arrays[0].Clear();
|
|
arrays[1].Clear();
|
|
arrays[2].Clear();
|
|
}
|
|
|
|
void Combine(int *siz, int max)
|
|
{
|
|
siz[0] = arrays[0].Size();
|
|
siz[1] = siz[0] + arrays[1].Size();
|
|
siz[2] = siz[1] + arrays[2].Size();
|
|
arrays[0].Resize(arrays[0].Size() + arrays[1].Size() + arrays[2].Size());
|
|
memcpy(&arrays[0][siz[0]], &arrays[1][0], arrays[1].Size() * sizeof(float));
|
|
memcpy(&arrays[0][siz[1]], &arrays[2][0], arrays[2].Size() * sizeof(float));
|
|
siz[0]>>=2;
|
|
siz[1]>>=2;
|
|
siz[2]>>=2;
|
|
if (siz[0] > max) siz[0] = max;
|
|
if (siz[1] > max) siz[1] = max;
|
|
if (siz[2] > max) siz[2] = max;
|
|
}
|
|
};
|
|
|
|
|
|
|
|
bool gl_GetLight(int group, Plane & p, ADynamicLight * light, bool checkside, bool forceadditive, FDynLightData &data);
|
|
void gl_UploadLights(FDynLightData &data);
|
|
|
|
|
|
#endif
|