Add CCMD addlightprobe and support simple binding of light probes to sides+sectors
This commit is contained in:
parent
46d6a5dfd0
commit
88115cfedd
6 changed files with 114 additions and 0 deletions
|
|
@ -888,6 +888,7 @@ set (PCH_SOURCES
|
|||
rendering/hwrenderer/hw_vertexbuilder.cpp
|
||||
rendering/hwrenderer/doom_aabbtree.cpp
|
||||
rendering/hwrenderer/doom_levelmesh.cpp
|
||||
rendering/hwrenderer/doom_lightprobes.cpp
|
||||
rendering/hwrenderer/hw_models.cpp
|
||||
rendering/hwrenderer/hw_precache.cpp
|
||||
rendering/hwrenderer/scene/hw_lighting.cpp
|
||||
|
|
|
|||
|
|
@ -7,3 +7,8 @@ struct LightProbe
|
|||
FVector3 position;
|
||||
int index = 0;
|
||||
};
|
||||
|
||||
struct LightProbeTarget
|
||||
{
|
||||
int index = 0; // parameter for renderstate.SetLightProbe
|
||||
};
|
||||
|
|
|
|||
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "hwrenderer/data/buffers.h"
|
||||
#include "hwrenderer/data/hw_levelmesh.h"
|
||||
#include "hwrenderer/data/hw_lightprobe.h"
|
||||
|
||||
// Some more or less basic data types
|
||||
// we depend on.
|
||||
|
|
@ -785,6 +786,8 @@ struct sector_t
|
|||
int healthceilinggroup;
|
||||
int health3dgroup;
|
||||
|
||||
LightProbeTarget lightProbe; // TODO split individual flats in the sector including 3d floors
|
||||
|
||||
// Member functions
|
||||
|
||||
private:
|
||||
|
|
@ -1295,6 +1298,7 @@ struct side_t
|
|||
int UDMFIndex; // needed to access custom UDMF fields which are stored in loading order.
|
||||
FLightNode * lighthead; // all dynamic lights that may affect this wall
|
||||
TArrayView<int> LightmapTiles; // all lightmap tiles belonging to this sidedef
|
||||
LightProbeTarget lightProbe; // TODO use different probe per each part (and 3D floors)
|
||||
seg_t **segs; // all segs belonging to this sidedef in ascending order. Used for precise rendering
|
||||
int numsegs;
|
||||
int sidenum;
|
||||
|
|
|
|||
102
src/rendering/hwrenderer/doom_lightprobes.cpp
Normal file
102
src/rendering/hwrenderer/doom_lightprobes.cpp
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
#include "c_dispatch.h"
|
||||
#include "g_levellocals.h"
|
||||
|
||||
static int FindClosestProbe(FVector3 pos)
|
||||
{
|
||||
float bestDist = std::numeric_limits<float>::max();
|
||||
int best = 0;
|
||||
|
||||
for (int i = 0, size = level.lightProbes.size(); i < size; ++i)
|
||||
{
|
||||
const auto& probe = level.lightProbes[i];
|
||||
|
||||
const auto probeDist = (probe.position - pos).LengthSquared();
|
||||
|
||||
if (probeDist < bestDist)
|
||||
{
|
||||
best = i;
|
||||
bestDist = probeDist;
|
||||
}
|
||||
}
|
||||
|
||||
return best;
|
||||
}
|
||||
|
||||
static void RecalculateLightProbeTargets()
|
||||
{
|
||||
for (int i = 0, size = level.sectors.size(); i < size; ++i)
|
||||
{
|
||||
auto& sector = level.sectors[i];
|
||||
const auto origin = FVector3(sector.centerspot.X, sector.centerspot.Y, float(sector.floorplane.ZatPoint(sector.centerspot) + 64.0));
|
||||
|
||||
sector.lightProbe.index = FindClosestProbe(origin);
|
||||
}
|
||||
|
||||
for (int i = 0, size = level.sides.size(); i < size; ++i)
|
||||
{
|
||||
auto& side = level.sides[i];
|
||||
|
||||
const auto sector = side.sector;
|
||||
|
||||
if (!sector) // better safe than sorry
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
const auto xy = side.linedef->v1->fPos() + side.linedef->delta * 0.5;
|
||||
const auto origin = FVector3(xy.X, xy.Y, float(sector->floorplane.ZatPoint(sector->centerspot) + 64.0));
|
||||
|
||||
side.lightProbe.index = FindClosestProbe(origin);
|
||||
}
|
||||
}
|
||||
|
||||
static void DumpLightProbeTargets()
|
||||
{
|
||||
for (int i = 0, size = level.sectors.size(); i < size; ++i)
|
||||
{
|
||||
const auto& sector = level.sectors[i];
|
||||
Printf("Sector %d = %d\n", i, sector.lightProbe.index);
|
||||
}
|
||||
|
||||
for (int i = 0, size = level.sides.size(); i < size; ++i)
|
||||
{
|
||||
const auto& side = level.sides[i];
|
||||
Printf("Side %d = %d\n", i, side.lightProbe.index);
|
||||
}
|
||||
}
|
||||
|
||||
static void DumpLightProbes()
|
||||
{
|
||||
for (int i = 0, size = level.lightProbes.size(); i < size; ++i)
|
||||
{
|
||||
const auto& probe = level.lightProbes[i];
|
||||
Printf("Probe %d: (%.1f, %.1f, %.1f)\n", i, probe.position.X, probe.position.Y, probe.position.Z);
|
||||
}
|
||||
}
|
||||
|
||||
static void AddLightProbe(FVector3 position)
|
||||
{
|
||||
LightProbe probe;
|
||||
probe.position = position;
|
||||
probe.index = static_cast<int>(level.lightProbes.size());
|
||||
level.lightProbes.Push(probe);
|
||||
}
|
||||
|
||||
CCMD(dumplightprobes)
|
||||
{
|
||||
DumpLightProbes();
|
||||
}
|
||||
|
||||
CCMD(dumplightprobetargets)
|
||||
{
|
||||
DumpLightProbeTargets();
|
||||
}
|
||||
|
||||
CCMD(addlightprobe)
|
||||
{
|
||||
const auto pos = FVector3(players[0].mo->Pos().X, players[0].mo->Pos().Y, players[0].viewz);
|
||||
AddLightProbe(pos);
|
||||
RecalculateLightProbeTargets();
|
||||
|
||||
Printf("Spawned probe at %.1f, %.1f, %.1f\n", pos.X, pos.Y, pos.Z);
|
||||
}
|
||||
|
|
@ -330,6 +330,7 @@ void HWFlat::DrawFlat(HWFlatDispatcher *di, FRenderState &state, bool translucen
|
|||
int rel = getExtraLight();
|
||||
|
||||
state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y);
|
||||
state.SetLightProbeIndex(sector->lightProbe.index);
|
||||
|
||||
SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha);
|
||||
SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, false, di->di ? di->di->drawctx->portalState.inskybox : false);
|
||||
|
|
|
|||
|
|
@ -87,6 +87,7 @@ void HWWall::RenderWall(FRenderState &state, int textured)
|
|||
if (seg->sidedef->Flags & WALLF_DITHERTRANS) state.SetEffect(EFF_DITHERTRANS);
|
||||
assert(vertcount > 0);
|
||||
state.SetLightIndex(dynlightindex);
|
||||
state.SetLightProbeIndex(seg->sidedef->lightProbe.index);
|
||||
state.Draw(DT_TriangleFan, vertindex, vertcount);
|
||||
vertexcount += vertcount;
|
||||
if (seg->sidedef->Flags & WALLF_DITHERTRANS)
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue