mirror of
https://github.com/ZDoom/qzdoom.git
synced 2024-11-10 23:02:08 +00:00
- reduced gl_spritelight.cpp to pure data setup so that it can be moved out of gl/.
- added thread_local to some static arrays being used for setting up dynamic lights. Right now it's of little consequence but these will have to be maintained per thread if the render data setup is done by worker tasks.
This commit is contained in:
parent
64b108ff44
commit
819ea8f937
10 changed files with 79 additions and 52 deletions
|
@ -2,7 +2,7 @@
|
|||
#define __GL_LIGHTBUFFER_H
|
||||
|
||||
#include "tarray.h"
|
||||
struct FDynLightData;
|
||||
#include "hwrenderer/dynlights/hw_dynlightdata.h"
|
||||
|
||||
class FLightBuffer
|
||||
{
|
||||
|
@ -35,5 +35,9 @@ public:
|
|||
int GetIndex(int i) const { return mIndices[i]; }
|
||||
};
|
||||
|
||||
int gl_SetDynModelLight(AActor *self, int dynlightindex);
|
||||
|
||||
extern thread_local FDynLightData lightdata;
|
||||
|
||||
#endif
|
||||
|
||||
|
|
|
@ -535,7 +535,7 @@ public:
|
|||
|
||||
void SetPlaneTextureRotation(GLSectorPlane *plane, FMaterial *texture)
|
||||
{
|
||||
if (gl_SetPlaneTextureRotation(plane, texture, mTextureMatrix))
|
||||
if (hw_SetPlaneTextureRotation(plane, texture, mTextureMatrix))
|
||||
{
|
||||
EnableTextureMatrix(true);
|
||||
}
|
||||
|
|
|
@ -53,7 +53,6 @@
|
|||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
extern FDynLightData lightdata;
|
||||
|
||||
void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub, int *dli)
|
||||
{
|
||||
|
@ -63,7 +62,7 @@ void FDrawInfo::SetupSubsectorLights(GLFlat *flat, int pass, subsector_t * sub,
|
|||
(*dli)++;
|
||||
return;
|
||||
}
|
||||
if (flat->SetupSubsectorLights(pass, sub))
|
||||
if (flat->SetupSubsectorLights(pass, sub, lightdata))
|
||||
{
|
||||
int d = GLRenderer->mLights->UploadLights(lightdata);
|
||||
if (pass == GLPASS_LIGHTSONLY)
|
||||
|
|
|
@ -42,6 +42,7 @@
|
|||
|
||||
#include "gl/system/gl_interface.h"
|
||||
#include "hwrenderer/utility/hw_cvars.h"
|
||||
#include "hwrenderer/scene/hw_drawstructs.h"
|
||||
#include "gl/renderer/gl_lightdata.h"
|
||||
#include "gl/renderer/gl_renderstate.h"
|
||||
#include "gl/renderer/gl_renderer.h"
|
||||
|
@ -49,6 +50,7 @@
|
|||
#include "gl/scene/gl_scenedrawer.h"
|
||||
#include "gl/models/gl_models.h"
|
||||
#include "gl/renderer/gl_quaddrawer.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
extern uint32_t r_renderercaps;
|
||||
|
||||
|
@ -62,6 +64,36 @@ void gl_SetRenderStyle(FRenderStyle style, bool drawopaque, bool allowcolorblend
|
|||
gl_RenderState.SetTextureMode(tm);
|
||||
}
|
||||
|
||||
int gl_SetDynModelLight(AActor *self, int dynlightindex)
|
||||
{
|
||||
if (gl.legacyMode)
|
||||
{
|
||||
float out[3];
|
||||
hw_GetDynSpriteLight(self, nullptr, out);
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
return -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
|
||||
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
|
||||
{
|
||||
gl_RenderState.SetDynLight(0, 0, 0);
|
||||
return dynlightindex;
|
||||
}
|
||||
hw_GetDynModelLight(self, lightdata);
|
||||
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(lightdata);
|
||||
|
||||
if (gl.lightmethod != LM_DEFERRED)
|
||||
{
|
||||
gl_RenderState.SetDynLight(0, 0, 0);
|
||||
}
|
||||
return dynlightindex;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
//
|
||||
|
@ -164,7 +196,11 @@ void FDrawInfo::DrawSprite(GLSprite *sprite, int pass)
|
|||
if (sprite->modelframe && !sprite->particle)
|
||||
sprite->dynlightindex = gl_SetDynModelLight(gl_light_sprites ? sprite->actor : nullptr, sprite->dynlightindex);
|
||||
else
|
||||
gl_SetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr);
|
||||
{
|
||||
float out[3];
|
||||
hw_GetDynSpriteLight(gl_light_sprites ? sprite->actor : nullptr, gl_light_particles ? sprite->particle : nullptr, out);
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
}
|
||||
sector_t *cursec = sprite->actor ? sprite->actor->Sector : sprite->particle ? sprite->particle->subsector->sector : nullptr;
|
||||
if (cursec != nullptr)
|
||||
|
|
|
@ -54,13 +54,13 @@ T smoothstep(const T edge0, const T edge1, const T x)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec)
|
||||
void hw_GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t * subsec, float *out)
|
||||
{
|
||||
ADynamicLight *light;
|
||||
float frac, lr, lg, lb;
|
||||
float radius;
|
||||
float out[3] = { 0.0f, 0.0f, 0.0f };
|
||||
|
||||
out[0] = out[1] = out[2] = 0.f;
|
||||
// Go through both light lists
|
||||
FLightNode * node = subsec->lighthead;
|
||||
while (node)
|
||||
|
@ -131,18 +131,17 @@ void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *
|
|||
}
|
||||
node = node->nextLight;
|
||||
}
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *thing, particle_t *particle)
|
||||
void hw_GetDynSpriteLight(AActor *thing, particle_t *particle, float *out)
|
||||
{
|
||||
if (thing != NULL)
|
||||
{
|
||||
gl_SetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector);
|
||||
hw_GetDynSpriteLight(thing, thing->X(), thing->Y(), thing->Center(), thing->subsector, out);
|
||||
}
|
||||
else if (particle != NULL)
|
||||
{
|
||||
gl_SetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector);
|
||||
hw_GetDynSpriteLight(NULL, particle->Pos.X, particle->Pos.Y, particle->Pos.Z, particle->subsector, out);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -189,31 +188,19 @@ void BSPWalkCircle(float x, float y, float radiusSquared, const Callback &callba
|
|||
BSPNodeWalkCircle(level.HeadNode(), x, y, radiusSquared, callback);
|
||||
}
|
||||
|
||||
int gl_SetDynModelLight(AActor *self, int dynlightindex)
|
||||
// static so that we build up a reserve (memory allocations stop)
|
||||
// For multithread processing each worker thread needs its own copy, though.
|
||||
static thread_local TArray<ADynamicLight*> addedLightsArray;
|
||||
|
||||
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata)
|
||||
{
|
||||
static FDynLightData modellightdata; // If this ever gets multithreaded, this variable must either be made non-static or thread_local.
|
||||
|
||||
// For deferred light mode this function gets called twice. First time for list upload, and second for draw.
|
||||
if (gl.lightmethod == LM_DEFERRED && dynlightindex != -1)
|
||||
{
|
||||
gl_RenderState.SetDynLight(0, 0, 0);
|
||||
return dynlightindex;
|
||||
}
|
||||
|
||||
// Legacy render path gets the old flat model light
|
||||
if (gl.lightmethod == LM_LEGACY)
|
||||
{
|
||||
gl_SetDynSpriteLight(self, nullptr);
|
||||
return -1;
|
||||
}
|
||||
|
||||
modellightdata.Clear();
|
||||
|
||||
if (self)
|
||||
{
|
||||
static std::vector<ADynamicLight*> addedLights; // static so that we build up a reserve (memory allocations stop)
|
||||
auto &addedLights = addedLightsArray; // avoid going through the thread local storage for each use.
|
||||
|
||||
addedLights.clear();
|
||||
addedLights.Clear();
|
||||
|
||||
float x = self->X();
|
||||
float y = self->Y();
|
||||
|
@ -240,7 +227,7 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex)
|
|||
if (std::find(addedLights.begin(), addedLights.end(), light) == addedLights.end()) // Check if we already added this light from a different subsector
|
||||
{
|
||||
modellightdata.AddLightToList(group, light);
|
||||
addedLights.push_back(light);
|
||||
addedLights.Push(light);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -248,12 +235,4 @@ int gl_SetDynModelLight(AActor *self, int dynlightindex)
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
dynlightindex = GLRenderer->mLights->UploadLights(modellightdata);
|
||||
|
||||
if (gl.lightmethod != LM_DEFERRED)
|
||||
{
|
||||
gl_RenderState.SetDynLight(0, 0, 0);
|
||||
}
|
||||
return dynlightindex;
|
||||
}
|
||||
|
|
|
@ -19,8 +19,5 @@ struct particle_t;
|
|||
|
||||
// Light + color
|
||||
|
||||
void gl_SetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec);
|
||||
void gl_SetDynSpriteLight(AActor *actor, particle_t *particle);
|
||||
int gl_SetDynModelLight(AActor *self, int dynlightindex);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -42,8 +42,8 @@
|
|||
|
||||
EXTERN_CVAR(Bool, gl_seamless)
|
||||
|
||||
FDynLightData lightdata;
|
||||
|
||||
// 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;
|
||||
|
||||
//==========================================================================
|
||||
//
|
||||
|
@ -489,8 +489,10 @@ void FDrawInfo::DrawDecal(GLDecal *gldecal)
|
|||
{
|
||||
// Note: This should be replaced with proper shader based lighting.
|
||||
double x, y;
|
||||
float out[3];
|
||||
decal->GetXY(seg->sidedef, x, y);
|
||||
gl_SetDynSpriteLight(nullptr, x, y, gldecal->zcenter, wall->sub);
|
||||
hw_GetDynSpriteLight(nullptr, x, y, gldecal->zcenter, wall->sub, out);
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
|
||||
// alpha color only has an effect when using an alpha texture.
|
||||
|
|
|
@ -44,6 +44,7 @@
|
|||
#include "gl/models/gl_models.h"
|
||||
#include "gl/renderer/gl_quaddrawer.h"
|
||||
#include "gl/stereo3d/gl_stereo3d.h"
|
||||
#include "gl/dynlights/gl_lightbuffer.h"
|
||||
|
||||
EXTERN_CVAR (Bool, r_drawplayersprites)
|
||||
EXTERN_CVAR(Float, transsouls)
|
||||
|
@ -449,10 +450,16 @@ void GLSceneDrawer::DrawPlayerSprites(sector_t * viewsector, bool hudModelStep)
|
|||
if (gl_lights && GLRenderer->mLightCount && FixedColormap == CM_DEFAULT && gl_light_sprites)
|
||||
{
|
||||
FSpriteModelFrame *smf = playermo->player->ReadyWeapon ? gl_FindModelFrame(playermo->player->ReadyWeapon->GetClass(), psp->GetState()->sprite, psp->GetState()->GetFrame(), false) : nullptr;
|
||||
if (smf)
|
||||
if (smf && !gl.legacyMode)
|
||||
{
|
||||
gl_SetDynModelLight(playermo, weapondynlightindex[psp]);
|
||||
}
|
||||
else
|
||||
gl_SetDynSpriteLight(playermo, NULL);
|
||||
{
|
||||
float out[3];
|
||||
hw_GetDynSpriteLight(playermo, nullptr, out);
|
||||
gl_RenderState.SetDynLight(out[0], out[1], out[2]);
|
||||
}
|
||||
}
|
||||
SetColor(ll, 0, cmc, trans, true);
|
||||
}
|
||||
|
|
|
@ -311,7 +311,7 @@ public:
|
|||
|
||||
int dynlightindex;
|
||||
|
||||
bool SetupSubsectorLights(int pass, subsector_t * sub);
|
||||
bool SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata);
|
||||
|
||||
void PutFlat(HWDrawInfo *di, bool fog = false);
|
||||
void Process(HWDrawInfo *di, sector_t * model, int whichplane, bool notexture);
|
||||
|
@ -431,5 +431,9 @@ inline float Dist2(float x1,float y1,float x2,float y2)
|
|||
return sqrtf((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2));
|
||||
}
|
||||
|
||||
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &mat);
|
||||
bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &mat);
|
||||
void hw_GetDynSpriteLight(AActor *self, float x, float y, float z, subsector_t *subsec, float *out);
|
||||
void hw_GetDynSpriteLight(AActor *actor, particle_t *particle, float *out);
|
||||
void hw_GetDynModelLight(AActor *self, FDynLightData &modellightdata);
|
||||
|
||||
extern const float LARGE_VALUE;
|
||||
|
|
|
@ -54,7 +54,7 @@ CVAR(Int, gl_breaksec, -1, 0)
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &dest)
|
||||
bool hw_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * gltexture, VSMatrix &dest)
|
||||
{
|
||||
// only manipulate the texture matrix if needed.
|
||||
if (!secplane->Offs.isZero() ||
|
||||
|
@ -92,9 +92,8 @@ bool gl_SetPlaneTextureRotation(const GLSectorPlane * secplane, FMaterial * glte
|
|||
// Flats
|
||||
//
|
||||
//==========================================================================
|
||||
extern FDynLightData lightdata;
|
||||
|
||||
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub)
|
||||
bool GLFlat::SetupSubsectorLights(int pass, subsector_t * sub, FDynLightData &lightdata)
|
||||
{
|
||||
Plane p;
|
||||
|
||||
|
|
Loading…
Reference in a new issue