Merge remote-tracking branch 'gzdoom/master' into big_beautiful_merge
This commit is contained in:
commit
17dacefc9b
41 changed files with 466 additions and 331 deletions
|
|
@ -1060,6 +1060,7 @@ set (PCH_SOURCES
|
|||
common/utility/r_memory.cpp
|
||||
common/utility/bounds.cpp
|
||||
common/utility/writezip.cpp
|
||||
common/utility/vga2ansi.cpp
|
||||
common/thirdparty/base64.cpp
|
||||
common/thirdparty/md5.cpp
|
||||
common/thirdparty/superfasthash.cpp
|
||||
|
|
|
|||
|
|
@ -58,13 +58,16 @@
|
|||
|
||||
extern FILE* Logfile;
|
||||
|
||||
void ConsoleEndoom();
|
||||
CCMD (quit)
|
||||
{
|
||||
ConsoleEndoom();
|
||||
throw CExitEvent(0);
|
||||
}
|
||||
|
||||
CCMD (exit)
|
||||
{
|
||||
ConsoleEndoom();
|
||||
throw CExitEvent(0);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -50,7 +50,7 @@ public:
|
|||
|
||||
virtual ~FStartupScreen() = default;
|
||||
|
||||
virtual void Progress() {}
|
||||
virtual void Progress(int advance = 1) {}
|
||||
virtual void AppendStatusLine(const char* status) {}
|
||||
virtual void LoadingStatus(const char* message, int colors) {}
|
||||
|
||||
|
|
@ -77,7 +77,7 @@ public:
|
|||
FBasicStartupScreen(int max_progress);
|
||||
~FBasicStartupScreen();
|
||||
|
||||
void Progress() override;
|
||||
void Progress(int advance = 1) override;
|
||||
|
||||
void NetInit(const char* message, bool host) override;
|
||||
void NetMessage(const char* message) override;
|
||||
|
|
|
|||
|
|
@ -84,13 +84,9 @@ FBasicStartupScreen::~FBasicStartupScreen()
|
|||
}
|
||||
|
||||
|
||||
void FBasicStartupScreen::Progress()
|
||||
void FBasicStartupScreen::Progress(int advance)
|
||||
{
|
||||
if (CurPos < MaxPos)
|
||||
{
|
||||
++CurPos;
|
||||
}
|
||||
|
||||
CurPos = min(CurPos + advance, MaxPos);
|
||||
FConsoleWindow::GetInstance().Progress(CurPos, MaxPos);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,10 +220,15 @@ void CleanProgressBar()
|
|||
}
|
||||
|
||||
static int ProgressBarCurPos, ProgressBarMaxPos;
|
||||
static bool ProgressBarComplete;
|
||||
|
||||
void RedrawProgressBar(int CurPos, int MaxPos)
|
||||
{
|
||||
if (!isatty(STDOUT_FILENO)) return;
|
||||
|
||||
if (ProgressBarComplete && CurPos >= MaxPos) return;
|
||||
ProgressBarComplete = CurPos >= MaxPos; // draw once
|
||||
|
||||
CleanProgressBar();
|
||||
struct winsize sizeOfWindow;
|
||||
ioctl(STDOUT_FILENO, TIOCGWINSZ, &sizeOfWindow);
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@ class FTTYStartupScreen : public FStartupScreen
|
|||
FTTYStartupScreen(int max_progress);
|
||||
~FTTYStartupScreen();
|
||||
|
||||
void Progress() override;
|
||||
void Progress(int amount = 1) override;
|
||||
|
||||
void NetInit(const char* message, bool host) override;
|
||||
void NetMessage(const char* message) override;
|
||||
|
|
@ -137,12 +137,9 @@ FTTYStartupScreen::~FTTYStartupScreen()
|
|||
//
|
||||
//===========================================================================
|
||||
|
||||
void FTTYStartupScreen::Progress()
|
||||
void FTTYStartupScreen::Progress(int advance)
|
||||
{
|
||||
if (CurPos < MaxPos)
|
||||
{
|
||||
++CurPos;
|
||||
}
|
||||
CurPos = min(CurPos + advance, MaxPos);
|
||||
RedrawProgressBar(CurPos, MaxPos);
|
||||
}
|
||||
|
||||
|
|
@ -240,6 +237,7 @@ void FTTYStartupScreen::NetProgress(int cur, int limit)
|
|||
|
||||
void FTTYStartupScreen::NetDone()
|
||||
{
|
||||
CurPos = MaxPos;
|
||||
CleanProgressBar();
|
||||
// Restore stdin settings
|
||||
if (DidNetInit)
|
||||
|
|
|
|||
|
|
@ -115,12 +115,9 @@ FBasicStartupScreen::~FBasicStartupScreen()
|
|||
//
|
||||
//==========================================================================
|
||||
|
||||
void FBasicStartupScreen::Progress()
|
||||
void FBasicStartupScreen::Progress(int advance)
|
||||
{
|
||||
if (CurPos < MaxPos)
|
||||
{
|
||||
CurPos++;
|
||||
}
|
||||
CurPos = min(CurPos + advance, MaxPos);
|
||||
}
|
||||
|
||||
//==========================================================================
|
||||
|
|
|
|||
|
|
@ -73,6 +73,12 @@ CUSTOM_CVAR(Int, showendoom, 0, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
|||
else if (self > 2) self=2;
|
||||
}
|
||||
|
||||
CVAR(Bool, consoleendoom, true, CVAR_ARCHIVE|CVAR_GLOBALCONFIG)
|
||||
|
||||
#ifdef _WIN32
|
||||
extern bool FancyStdOut;
|
||||
#endif
|
||||
|
||||
// PRIVATE DATA DEFINITIONS ------------------------------------------------
|
||||
|
||||
// CODE --------------------------------------------------------------------
|
||||
|
|
@ -192,9 +198,36 @@ int RunEndoom()
|
|||
return 0;
|
||||
}
|
||||
|
||||
void vga_to_ansi(const uint8_t *buf);
|
||||
|
||||
void ConsoleEndoom()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
// old versions of Windows don't get an ansi endoom
|
||||
if (!FancyStdOut)
|
||||
return;
|
||||
#endif
|
||||
|
||||
if (!consoleendoom || endoomName.Len() == 0)
|
||||
return;
|
||||
|
||||
uint8_t buffer[4000];
|
||||
|
||||
int endoom_lump = fileSystem.CheckNumForFullName (endoomName.GetChars(), true);
|
||||
|
||||
if (endoom_lump < 0 || fileSystem.FileLength (endoom_lump) != 4000)
|
||||
{
|
||||
return;
|
||||
}
|
||||
fileSystem.ReadFile(endoom_lump, buffer);
|
||||
|
||||
vga_to_ansi(buffer);
|
||||
}
|
||||
|
||||
[[noreturn]]
|
||||
void ST_Endoom()
|
||||
{
|
||||
ConsoleEndoom();
|
||||
int code = RunEndoom();
|
||||
throw CExitEvent(code);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -765,3 +765,33 @@ void FStartScreen::ValidateTexture()
|
|||
}
|
||||
}
|
||||
|
||||
void unicode_to_utf8(char* result, uint16_t code_point)
|
||||
{
|
||||
if (code_point <= 0x7F)
|
||||
{
|
||||
// 1-byte sequence (ASCII)
|
||||
result[0] = (unsigned char)code_point;
|
||||
result[1] = 0;
|
||||
}
|
||||
else if (code_point <= 0x7FF)
|
||||
{
|
||||
// 2-byte sequence
|
||||
result[0] = (unsigned char)(0xC0 | ((code_point >> 6) & 0x1F));
|
||||
result[1] = (unsigned char)(0x80 | (code_point & 0x3F));
|
||||
result[2] = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
// 3-byte sequence (up to U+FFFF)
|
||||
result[0] = (unsigned char)(0xE0 | ((code_point >> 12) & 0x0F));
|
||||
result[1] = (unsigned char)(0x80 | ((code_point >> 6) & 0x3F));
|
||||
result[2] = (unsigned char)(0x80 | (code_point & 0x3F));
|
||||
result[3] = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void ibm437_to_utf8(char* result, char in)
|
||||
{
|
||||
unicode_to_utf8(result, IBM437ToUnicode[(unsigned char)in]);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -405,7 +405,7 @@ public:
|
|||
// exact = false returns the closest match, to be used for, ex., insertions, exact = true returns Size() when no match, like Find does
|
||||
unsigned int SortedFind(const T& item, bool exact = true) const
|
||||
{
|
||||
unsigned int index = (std::lower_bound(begin(), end(), item) - begin());
|
||||
unsigned int index = (unsigned int)(std::lower_bound(begin(), end(), item) - begin());
|
||||
if(exact)
|
||||
{
|
||||
return (index < Count && Array[index] == item) ? index : Count;
|
||||
|
|
|
|||
158
src/common/utility/vga2ansi.cpp
Normal file
158
src/common/utility/vga2ansi.cpp
Normal file
|
|
@ -0,0 +1,158 @@
|
|||
// Copyright (c) 2025 Rachael Alexanderson
|
||||
//
|
||||
// Redistribution and use in source and binary forms, with or without
|
||||
// modification, are permitted provided that the following conditions are met:
|
||||
//
|
||||
// 1. Redistributions of source code must retain the above copyright notice,
|
||||
// this list of conditions and the following disclaimer.
|
||||
//
|
||||
// 2. Redistributions in binary form must reproduce the above copyright notice,
|
||||
// this list of conditions and the following disclaimer in the documentation
|
||||
// and/or other materials provided with the distribution.
|
||||
//
|
||||
// 3. Neither the name of the copyright holder nor the names of its
|
||||
// contributors may be used to endorse or promote products derived from this
|
||||
// software without specific prior written permission.
|
||||
//
|
||||
// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS “AS IS”
|
||||
// AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
// IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
// ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
|
||||
// LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||
// CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||
// SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||
// INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||
// CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||
// ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||
// POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef _WIN32
|
||||
// windows platform code uses special stdout handling, let's make sure to use that
|
||||
#include <windows.h>
|
||||
extern HANDLE StdOut;
|
||||
static void CPrint(const char* in)
|
||||
{
|
||||
DWORD bytes_written;
|
||||
if (!StdOut)
|
||||
return;
|
||||
WriteFile(StdOut, in, strlen(in), &bytes_written, NULL);
|
||||
}
|
||||
#else
|
||||
static void CPrint(const char* in)
|
||||
{
|
||||
fputs(in, stdout);
|
||||
}
|
||||
#endif
|
||||
|
||||
static const char *ansi_esc[2] = {"\x1b[", ";"};
|
||||
static const char *ansi_end[2] = {"", "m"};
|
||||
|
||||
// Map DOS color to ANSI escape code
|
||||
static const char *ansi_fg[16] =
|
||||
{
|
||||
"30", "34", "32", "36", "31", "35", "33", "37",
|
||||
"90", "94", "92", "96", "91", "95", "93", "97"
|
||||
};
|
||||
// Only standard backgrounds (no bright backgrounds in classic ANSI)
|
||||
static const char *ansi_bg[8] =
|
||||
{
|
||||
"40", "44", "42", "46",
|
||||
"41", "45", "43", "47"
|
||||
};
|
||||
// ANSI codes for truecolor DOS colors
|
||||
static const char *ansi_tc_fg[16] =
|
||||
{
|
||||
"38;2;0;0;0", "38;2;0;0;170", "38;2;0;170;0", "38;2;0;170;170",
|
||||
"38;2;170;0;0", "38;2;170;0;170", "38;2;170;85;0", "38;2;170;170;170",
|
||||
"38;2;85;85;85", "38;2;85;85;255", "38;2;85;255;0", "38;2;85;255;255",
|
||||
"38;2;255;85;85", "38;2;255;85;255", "38;2;255;255;85", "38;2;255;255;255"
|
||||
};
|
||||
static const char *ansi_tc_bg[8] =
|
||||
{
|
||||
"48;2;0;0;0", "48;2;0;0;170", "48;2;0;170;0", "48;2;0;170;170",
|
||||
"48;2;170;0;0", "48;2;170;0;170", "48;2;170;85;0", "48;2;170;170;170"
|
||||
};
|
||||
|
||||
static const char *ansi_flash[2] = { "25", "5" };
|
||||
|
||||
inline void ansi_ctrl(bool open)
|
||||
{
|
||||
static bool is_ansi_open = false;
|
||||
if (open)
|
||||
CPrint(ansi_esc[is_ansi_open]);
|
||||
else
|
||||
CPrint(ansi_end[is_ansi_open]);
|
||||
is_ansi_open = open;
|
||||
}
|
||||
|
||||
void ibm437_to_utf8(char* result, char in);
|
||||
|
||||
void vga_to_ansi(const uint8_t *buf)
|
||||
{
|
||||
#ifdef _WIN32
|
||||
bool truecolor = true;
|
||||
#else
|
||||
const char *ct = getenv("COLORTERM");
|
||||
bool truecolor = ct && (strcmp(ct, "truecolor") || strcmp(ct, "24bit"));
|
||||
#endif
|
||||
|
||||
for (int row = 0; row < 25; ++row)
|
||||
{
|
||||
int last_fg = -1, last_bg = -1;
|
||||
bool last_blink = false;
|
||||
for (int col = 0; col < 80; ++col)
|
||||
{
|
||||
int off = (row * 80 + col) * 2;
|
||||
uint8_t ch = buf[off];
|
||||
uint8_t attr = buf[off + 1];
|
||||
int fg = attr & 0x0F;
|
||||
int bg = (attr >> 4) & 0x07;
|
||||
bool blink = !!(attr & 0x80);
|
||||
bool spacer = (ch == 0) || (ch == 32) || (ch == 255);
|
||||
|
||||
// Output color if changed
|
||||
if ((fg != last_fg) && !spacer)
|
||||
{
|
||||
ansi_ctrl(1);
|
||||
if (truecolor)
|
||||
CPrint(ansi_tc_fg[fg]);
|
||||
else
|
||||
CPrint(ansi_fg[fg]);
|
||||
last_fg = fg;
|
||||
}
|
||||
if (bg != last_bg)
|
||||
{
|
||||
ansi_ctrl(1);
|
||||
if (truecolor)
|
||||
CPrint(ansi_tc_bg[bg]);
|
||||
else
|
||||
CPrint(ansi_bg[bg]);
|
||||
last_bg = bg;
|
||||
}
|
||||
if (blink != last_blink)
|
||||
{
|
||||
ansi_ctrl(1);
|
||||
CPrint(ansi_flash[blink]);
|
||||
last_blink = blink;
|
||||
}
|
||||
ansi_ctrl(0);
|
||||
|
||||
// Output character, convert CP437 to UTF-8
|
||||
if (spacer)
|
||||
CPrint(" ");
|
||||
else
|
||||
{
|
||||
char result[4];
|
||||
ibm437_to_utf8(result, ch);
|
||||
CPrint(result);
|
||||
}
|
||||
}
|
||||
CPrint("\x1b[0m\n"); // Reset colors and end the line
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -3420,7 +3420,7 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector<std::string>& allw
|
|||
if (!batchrun && !RunningAsTool) Printf ("ST_Init: Init startup screen.\n");
|
||||
if (!restart)
|
||||
{
|
||||
StartWindow = FStartupScreen::CreateInstance (TexMan.GuesstimateNumTextures() + 5);
|
||||
StartWindow = FStartupScreen::CreateInstance(max_progress);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
@ -3635,10 +3635,12 @@ static int D_InitGame(const FIWADInfo* iwad_info, std::vector<std::string>& allw
|
|||
}
|
||||
|
||||
S_Sound (CHAN_BODY, 0, "misc/startupdone", 1, ATTN_NONE);
|
||||
if (!batchrun) Printf ("Init complete.\n");
|
||||
|
||||
if (RunningAsTool)
|
||||
return 0;
|
||||
|
||||
StartWindow->Progress(max_progress);
|
||||
if (StartScreen)
|
||||
{
|
||||
StartScreen->Progress(max_progress); // advance progress bar to the end.
|
||||
|
|
@ -3916,7 +3918,7 @@ int D_DoomMain_Game()
|
|||
// Now that we have the IWADINFO, initialize the autoload ini sections.
|
||||
GameConfig->DoAutoloadSetup(iwad_man);
|
||||
|
||||
bool should_debug = vm_debug.get();
|
||||
bool should_debug = vm_debug;
|
||||
const char * debug_port_arg = Args->CheckValue("-debug");
|
||||
if (debug_port_arg) {
|
||||
should_debug = true;
|
||||
|
|
|
|||
|
|
@ -76,31 +76,12 @@ CCMD(listlights)
|
|||
if (dl->target)
|
||||
{
|
||||
FTextureID spr = sprites[dl->target->sprite].GetSpriteFrame(dl->target->frame, 0, nullAngle, nullptr);
|
||||
Printf(", frame = %s ", TexMan.GetGameTexture(spr)->GetName().GetChars());
|
||||
Printf(", frame = %s\n", TexMan.GetGameTexture(spr)->GetName().GetChars());
|
||||
}
|
||||
|
||||
|
||||
FLightNode * node;
|
||||
|
||||
node=dl->touching_sides;
|
||||
|
||||
while (node)
|
||||
{
|
||||
walls++;
|
||||
allwalls++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
|
||||
|
||||
node = dl->touching_sector;
|
||||
|
||||
while (node)
|
||||
{
|
||||
allsectors++;
|
||||
sectors++;
|
||||
node = node->nextTarget;
|
||||
}
|
||||
/*
|
||||
Printf("- %d walls, %d sectors\n", walls, sectors);
|
||||
*/
|
||||
|
||||
}
|
||||
Printf("%i dynamic lights, %d shadowmapped, %d walls, %d sectors\n\n\n", i, shadowcount, allwalls, allsectors);
|
||||
|
|
|
|||
|
|
@ -583,6 +583,9 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
bool wantFast;
|
||||
unsigned int i;
|
||||
|
||||
primaryLevel->lightlists.wall_dlist.Clear();
|
||||
primaryLevel->lightlists.flat_dlist.Clear();
|
||||
|
||||
// did we have any level before?
|
||||
if (primaryLevel->info != nullptr)
|
||||
staticEventManager.WorldUnloaded(FString()); // [MK] don't pass the new map, as it's not a level transition
|
||||
|
|
@ -647,9 +650,6 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
primaryLevel->totaltime = 0;
|
||||
primaryLevel->spawnindex = 0;
|
||||
|
||||
primaryLevel->lightlists.wall_dlist.Clear();
|
||||
primaryLevel->lightlists.flat_dlist.Clear();
|
||||
|
||||
if (!multiplayer || !deathmatch)
|
||||
{
|
||||
InitPlayerClasses ();
|
||||
|
|
|
|||
|
|
@ -61,8 +61,9 @@
|
|||
|
||||
struct FGlobalDLightLists
|
||||
{
|
||||
TMap<FSection*, TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> flat_dlist;
|
||||
TMap<side_t*, TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> wall_dlist;
|
||||
//TODO add TSet and switch from TMap to TSet
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> flat_dlist;
|
||||
TArray<TMap<FDynamicLight*, std::unique_ptr<FLightNode>>> wall_dlist;
|
||||
};
|
||||
|
||||
#include "common/rendering/hwrenderer/data/hw_lightprobe.h"
|
||||
|
|
|
|||
|
|
@ -3517,12 +3517,6 @@ void MapLoader::LoadLevel(MapData *map, const char *lumpname, int position)
|
|||
|
||||
SpawnThings(position);
|
||||
|
||||
// Load and link lightmaps - must be done after P_Spawn3DFloors (and SpawnThings? Potentially for baking static model actors?)
|
||||
if (!ForceNodeBuild)
|
||||
{
|
||||
LoadLightmap(map);
|
||||
}
|
||||
|
||||
for (unsigned int i = 0; i < MAXPLAYERS; ++i)
|
||||
{
|
||||
if (Level->PlayerInGame(i) && Level->Players[i]->mo != nullptr)
|
||||
|
|
|
|||
|
|
@ -74,20 +74,22 @@ static FCRandom randLight;
|
|||
extern TArray<FLightDefaults *> StateLights;
|
||||
|
||||
|
||||
static void MarkTilesForUpdate(FLevelLocals * Level, FLightNode * touching_sides, FLightNode * touching_sector)
|
||||
void FDynamicLight::MarkTilesForUpdate()
|
||||
{
|
||||
if(Level->levelMesh)
|
||||
{
|
||||
while(touching_sides)
|
||||
for (int i = 0; i < touchlists.wall_tlist.SSize(); i++)
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(touching_sides->targLine);
|
||||
touching_sides = touching_sides->nextTarget;
|
||||
auto sidedef = touchlists.wall_tlist[i];
|
||||
if (sidedef)
|
||||
LevelMeshUpdater->SideLightListChanged(sidedef);
|
||||
}
|
||||
|
||||
while(touching_sector)
|
||||
|
||||
for (int i = 0; i < touchlists.flat_tlist.SSize(); i++)
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(touching_sector->targSection->sector);
|
||||
touching_sector = touching_sector->nextTarget;
|
||||
auto sec = touchlists.flat_tlist[i];
|
||||
if (sec)
|
||||
LevelMeshUpdater->SectorLightListChanged(sec->sector);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -315,7 +317,7 @@ void FDynamicLight::Tick()
|
|||
{
|
||||
if(markTiles && m_active != wasactive)
|
||||
{
|
||||
MarkTilesForUpdate(Level, touching_sides, touching_sector);
|
||||
MarkTilesForUpdate();
|
||||
}
|
||||
wasactive = m_active;
|
||||
return;
|
||||
|
|
@ -418,7 +420,7 @@ void FDynamicLight::Tick()
|
|||
{
|
||||
if(markTiles)
|
||||
{
|
||||
MarkTilesForUpdate(Level, touching_sides, touching_sector);
|
||||
MarkTilesForUpdate();
|
||||
}
|
||||
|
||||
updated = true;
|
||||
|
|
@ -521,69 +523,48 @@ bool FDynamicLight::UpdateLocation()
|
|||
//
|
||||
//=============================================================================
|
||||
|
||||
|
||||
int FSection::Index() const
|
||||
{
|
||||
return int(this - §or->Level->sections.allSections[0]);
|
||||
}
|
||||
|
||||
void FDynamicLight::AddLightNode(FSection *section, side_t *sidedef)
|
||||
{
|
||||
auto updateFlatTList = [&](FSection *sec)
|
||||
{
|
||||
touchlists.flat_tlist.TryEmplace(sec, sec);
|
||||
};
|
||||
auto updateWallTList = [&](side_t *sidedef)
|
||||
{
|
||||
touchlists.wall_tlist.TryEmplace(sidedef, sidedef);
|
||||
};
|
||||
|
||||
if (section)
|
||||
{
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(section);
|
||||
if (flatLightList)
|
||||
if(Level->lightlists.flat_dlist.SSize() <= section->Index())
|
||||
{
|
||||
if (!flatLightList->CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = section;
|
||||
|
||||
flatLightList->TryEmplace(this, node);
|
||||
updateFlatTList(section);
|
||||
}
|
||||
Level->lightlists.flat_dlist.Resize(section->Index() + 1);
|
||||
}
|
||||
else
|
||||
|
||||
auto &flatLightList = Level->lightlists.flat_dlist[section->Index()];
|
||||
|
||||
if (!flatLightList.CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = section;
|
||||
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>> u;
|
||||
u.TryEmplace(this, node);
|
||||
Level->lightlists.flat_dlist.TryEmplace(section, std::move(u));
|
||||
updateFlatTList(section);
|
||||
flatLightList.TryEmplace(this, node);
|
||||
touchlists.flat_tlist.SortedAddUnique(section);
|
||||
}
|
||||
}
|
||||
else if (sidedef)
|
||||
{
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(sidedef);
|
||||
if (wallLightList)
|
||||
if(Level->lightlists.wall_dlist.SSize() <= sidedef->Index())
|
||||
{
|
||||
if (!wallLightList->CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = sidedef;
|
||||
|
||||
wallLightList->TryEmplace(this, node);
|
||||
updateWallTList(sidedef);
|
||||
}
|
||||
Level->lightlists.wall_dlist.Resize(sidedef->Index() + 1);
|
||||
}
|
||||
else
|
||||
|
||||
auto &wallLightList = Level->lightlists.wall_dlist[sidedef->Index()];
|
||||
|
||||
if (!wallLightList.CheckKey(this))
|
||||
{
|
||||
FLightNode * node = new FLightNode;
|
||||
node->lightsource = this;
|
||||
node->targ = sidedef;
|
||||
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>> u;
|
||||
u.TryEmplace(this, node);
|
||||
Level->lightlists.wall_dlist.TryEmplace(sidedef, std::move(u));
|
||||
updateWallTList(sidedef);
|
||||
wallLightList.TryEmplace(this, node);
|
||||
touchlists.wall_tlist.SortedAddUnique(sidedef);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -768,7 +749,6 @@ void FDynamicLight::CollectWithinRadius(const DVector3 &opos, FSection *section,
|
|||
void FDynamicLight::LinkLight()
|
||||
{
|
||||
UnlinkLight();
|
||||
|
||||
if (radius>0)
|
||||
{
|
||||
// passing in radius*radius allows us to do a distance check without any calls to sqrt
|
||||
|
|
@ -786,35 +766,29 @@ void FDynamicLight::LinkLight()
|
|||
// Deletes the link lists
|
||||
//
|
||||
//==========================================================================
|
||||
void FDynamicLight::UnlinkLight ()
|
||||
void FDynamicLight::UnlinkLight()
|
||||
{
|
||||
TMap<side_t *, side_t *>::Iterator wit(touchlists.wall_tlist);
|
||||
TMap<side_t *, side_t *>::Pair *wpair;
|
||||
while (wit.NextPair(wpair))
|
||||
for(int i = 0; i < touchlists.wall_tlist.SSize(); i++)
|
||||
{
|
||||
auto sidedef = wpair->Value;
|
||||
auto sidedef = touchlists.wall_tlist[i];
|
||||
if (!sidedef) continue;
|
||||
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(sidedef);
|
||||
if (wallLightList)
|
||||
if(Level->lightlists.wall_dlist.SSize() > sidedef->Index())
|
||||
{
|
||||
LevelMeshUpdater->SideLightListChanged(sidedef);
|
||||
wallLightList->Remove(this);
|
||||
Level->lightlists.wall_dlist[sidedef->Index()].Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
TMap<FSection *, FSection *>::Iterator fit(touchlists.flat_tlist);
|
||||
TMap<FSection *, FSection *>::Pair *fpair;
|
||||
while (fit.NextPair(fpair))
|
||||
for(int i = 0; i < touchlists.flat_tlist.SSize(); i++)
|
||||
{
|
||||
auto sec = fpair->Value;
|
||||
auto sec = touchlists.flat_tlist[i];
|
||||
if (!sec) continue;
|
||||
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
|
||||
if(Level->lightlists.flat_dlist.SSize() > sec->Index())
|
||||
{
|
||||
LevelMeshUpdater->SectorLightListChanged(sec->sector);
|
||||
flatLightList->Remove(this);
|
||||
Level->lightlists.flat_dlist[sec->Index()].Remove(this);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,23 +196,13 @@ protected:
|
|||
|
||||
struct FLightNode
|
||||
{
|
||||
FLightNode ** prevTarget;
|
||||
FLightNode * nextTarget;
|
||||
FLightNode ** prevLight;
|
||||
FLightNode * nextLight;
|
||||
FDynamicLight * lightsource;
|
||||
union
|
||||
{
|
||||
side_t * targLine;
|
||||
FSection* targSection;
|
||||
void * targ;
|
||||
};
|
||||
};
|
||||
|
||||
struct FDynamicLightTouchLists
|
||||
{
|
||||
TMap<FSection*, FSection*> flat_tlist;
|
||||
TMap<side_t*, side_t*> wall_tlist;
|
||||
TArray<FSection*> flat_tlist;
|
||||
TArray<side_t*> wall_tlist;
|
||||
};
|
||||
|
||||
struct FDynamicLight
|
||||
|
|
@ -279,6 +269,7 @@ struct FDynamicLight
|
|||
private:
|
||||
double DistToSeg(const DVector3 &pos, vertex_t *start, vertex_t *end);
|
||||
void CollectWithinRadius(const DVector3 &pos, FSection *section, float radius);
|
||||
void MarkTilesForUpdate();
|
||||
|
||||
public:
|
||||
FCycler m_cycler;
|
||||
|
|
@ -301,8 +292,7 @@ public:
|
|||
sector_t *Sector;
|
||||
FLevelLocals *Level;
|
||||
TObjPtr<AActor *> target;
|
||||
FLightNode * touching_sides;
|
||||
FLightNode * touching_sector;
|
||||
|
||||
float radius; // The maximum size the light can be with its current settings.
|
||||
float m_currentRadius; // The current light size.
|
||||
int m_tickCount;
|
||||
|
|
|
|||
|
|
@ -120,6 +120,8 @@ struct FSection
|
|||
short mapsection;
|
||||
char hacked; // 1: is part of a render hack
|
||||
char flags;
|
||||
|
||||
int Index() const;
|
||||
};
|
||||
|
||||
class FSectionContainer
|
||||
|
|
|
|||
|
|
@ -1046,7 +1046,7 @@ void DoomLevelMesh::UpdateLightShadows(sector_t* sector)
|
|||
{
|
||||
for (FSection& section : level.sections.SectionsForSector(sector))
|
||||
{
|
||||
auto flatLightList = level.lightlists.flat_dlist.CheckKey(§ion);
|
||||
auto flatLightList = level.lightlists.flat_dlist.SSize() > section.Index() ? &level.lightlists.flat_dlist[section.Index()] : nullptr;
|
||||
if (flatLightList)
|
||||
{
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
|
|
@ -1066,18 +1066,18 @@ void DoomLevelMesh::UpdateLightShadows(sector_t* sector)
|
|||
|
||||
void DoomLevelMesh::UpdateLightShadows(FDynamicLight* light)
|
||||
{
|
||||
auto touching_sector = light->touching_sector;
|
||||
while (touching_sector)
|
||||
for (int i = 0; i < light->touchlists.flat_tlist.SSize(); i++)
|
||||
{
|
||||
UpdateFlat(touching_sector->targSection->sector->Index(), SurfaceUpdateType::LightList);
|
||||
touching_sector = touching_sector->nextTarget;
|
||||
auto sec = light->touchlists.flat_tlist[i];
|
||||
if (sec)
|
||||
UpdateFlat(sec->sector->Index(), SurfaceUpdateType::LightList);
|
||||
}
|
||||
|
||||
auto touching_sides = light->touching_sides;
|
||||
while (touching_sides)
|
||||
for (int i = 0; i < light->touchlists.wall_tlist.SSize(); i++)
|
||||
{
|
||||
UpdateSide(touching_sides->targLine->Index(), SurfaceUpdateType::LightList);
|
||||
touching_sides = touching_sides->nextTarget;
|
||||
auto sidedef = light->touchlists.wall_tlist[i];
|
||||
if (sidedef)
|
||||
UpdateSide(sidedef->Index(), SurfaceUpdateType::LightList);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1315,9 +1315,13 @@ void DoomLevelMesh::UpdateFlat(unsigned int sectorIndex, SurfaceUpdateType updat
|
|||
|
||||
LightListAllocInfo DoomLevelMesh::CreateLightList(FSection* section, side_t* side, int portalgroup)
|
||||
{
|
||||
int lightcount = 0;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* srcLightList = nullptr;
|
||||
if (section && level.lightlists.flat_dlist.SSize() > section->Index())
|
||||
srcLightList = &level.lightlists.flat_dlist[section->Index()];
|
||||
else if (side && level.lightlists.wall_dlist.SSize() > side->Index())
|
||||
srcLightList = &level.lightlists.wall_dlist[side->Index()];
|
||||
|
||||
auto srcLightList = section ? level.lightlists.flat_dlist.CheckKey(section) : level.lightlists.wall_dlist.CheckKey(side);
|
||||
int lightcount = 0;
|
||||
if (srcLightList)
|
||||
{
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*srcLightList);
|
||||
|
|
|
|||
|
|
@ -270,6 +270,8 @@ void HWDrawInfo::UnclipSubsector(subsector_t *sub)
|
|||
|
||||
void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
||||
{
|
||||
const bool doOob = Viewpoint.bDoOob;
|
||||
|
||||
#ifdef _DEBUG
|
||||
if (seg->linedef && seg->linedef->Index() == 38)
|
||||
{
|
||||
|
|
@ -293,7 +295,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
angle_t endAngleR = 0;
|
||||
angle_t paddingR = 0x00200000; // Make radar clipping more aggressive (reveal less)
|
||||
|
||||
if(Viewpoint.IsAllowedOoB() && r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR))
|
||||
if(doOob && r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR))
|
||||
{
|
||||
startAngleR = clipperr.PointToPseudoAngle(seg->v2->fX(), seg->v2->fY());
|
||||
endAngleR = clipperr.PointToPseudoAngle(seg->v1->fX(), seg->v1->fY());
|
||||
|
|
@ -321,11 +323,11 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
{
|
||||
if (!(currentsubsector->flags & SSECMF_DRAWN))
|
||||
{
|
||||
if (clipper.SafeCheckRange(startAngle, endAngle) && !Viewpoint.IsAllowedOoB())
|
||||
if (clipper.SafeCheckRange(startAngle, endAngle) && !doOob)
|
||||
{
|
||||
currentsubsector->flags |= SSECMF_DRAWN;
|
||||
}
|
||||
if (Viewpoint.IsAllowedOoB() && (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR)) && clipperr.SafeCheckRange(startAngleR, endAngleR))
|
||||
if (doOob && (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR)) && clipperr.SafeCheckRange(startAngleR, endAngleR))
|
||||
{
|
||||
currentsubsector->flags |= SSECMF_DRAWN;
|
||||
}
|
||||
|
|
@ -338,14 +340,14 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!Viewpoint.IsAllowedOoB() || (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR)))
|
||||
if (!doOob || (!r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || clipperr.SafeCheckRange(startAngleR, endAngleR)))
|
||||
currentsubsector->flags |= SSECMF_DRAWN;
|
||||
|
||||
uint8_t ispoly = uint8_t(seg->sidedef->Flags & WALLF_POLYOBJ);
|
||||
|
||||
if (!seg->backsector)
|
||||
{
|
||||
if(!Viewpoint.IsAllowedOoB())
|
||||
if(!doOob)
|
||||
if (!(seg->sidedef->Flags & WALLF_DITHERTRANS_MID)) clipper.SafeAddClipRange(startAngle, endAngle);
|
||||
}
|
||||
else if (!ispoly) // Two-sided polyobjects never obstruct the view
|
||||
|
|
@ -373,7 +375,7 @@ void HWDrawInfo::AddLine (seg_t *seg, bool portalclip, FRenderState& state)
|
|||
|
||||
if (hw_CheckClip(seg->sidedef, currentsector, backsector, !outer ? &ClipFrustum : nullptr))
|
||||
{
|
||||
if(!Viewpoint.IsAllowedOoB() && !(seg->sidedef->Flags & WALLF_DITHERTRANS_MID))
|
||||
if(!doOob && !(seg->sidedef->Flags & WALLF_DITHERTRANS_MID))
|
||||
clipper.SafeAddClipRange(startAngle, endAngle);
|
||||
}
|
||||
}
|
||||
|
|
@ -590,7 +592,7 @@ void HWDrawInfo::RenderThings(subsector_t * sub, sector_t * sector, FRenderState
|
|||
if (thing->validcount == validcount) continue;
|
||||
thing->validcount = validcount;
|
||||
|
||||
if(Viewpoint.IsAllowedOoB() && thing->Sector->isSecret() && thing->Sector->wasSecret() && !r_radarclipper) continue; // This covers things that are touching non-secret sectors
|
||||
if(Viewpoint.bDoOob && thing->Sector->isSecret() && thing->Sector->wasSecret() && !r_radarclipper) continue; // This covers things that are touching non-secret sectors
|
||||
FIntCVar *cvar = thing->GetInfo()->distancecheck;
|
||||
if (cvar != nullptr && *cvar >= 0)
|
||||
{
|
||||
|
|
@ -695,6 +697,7 @@ void HWDrawInfo::RenderParticles(subsector_t *sub, sector_t *front, FRenderState
|
|||
|
||||
void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
||||
{
|
||||
const bool doOob = Viewpoint.bDoOob;
|
||||
sector_t * sector;
|
||||
sector_t * fakesector;
|
||||
|
||||
|
|
@ -723,10 +726,10 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
|
||||
fakesector=hw_FakeFlat(drawctx, sector, in_area, false);
|
||||
|
||||
if(Viewpoint.IsAllowedOoB() && sector->isSecret() && sector->wasSecret() && !r_radarclipper) return;
|
||||
if(doOob && sector->isSecret() && sector->wasSecret() && !r_radarclipper) return;
|
||||
|
||||
// cull everything if subsector outside all relevant clippers
|
||||
if (Viewpoint.IsAllowedOoB() && (sub->polys == nullptr))
|
||||
if (doOob && (sub->polys == nullptr))
|
||||
{
|
||||
auto &clipper = *mClipper;
|
||||
auto &clipperv = *vClipper;
|
||||
|
|
@ -734,11 +737,10 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
int count = sub->numlines;
|
||||
seg_t * seg = sub->firstline;
|
||||
bool anglevisible = false;
|
||||
bool pitchvisible = !(Viewpoint.IsAllowedOoB()); // No vertical clipping if viewpoint is not allowed out of bounds
|
||||
bool radarvisible = !(Viewpoint.IsAllowedOoB()) || !r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || ((sub->flags & SSECMF_DRAWN) && !deathmatch);
|
||||
bool ceilreflect = (mCurrentPortal && strcmp(mCurrentPortal->GetName(), "Planemirror ceiling"));
|
||||
bool floorreflect = (mCurrentPortal && strcmp(mCurrentPortal->GetName(), "Planemirror floor"));
|
||||
double planez = (ceilreflect ? sector->ceilingplane.ZatPoint(Viewpoint.Pos) : sector->floorplane.ZatPoint(Viewpoint.Pos));
|
||||
bool pitchvisible = false;
|
||||
bool radarvisible = !r_radarclipper || (Level->flags3 & LEVEL3_NOFOGOFWAR) || ((sub->flags & SSECMF_DRAWN) && !deathmatch);
|
||||
const int reflect = mCurrentPortal ? mCurrentPortal->GetMirrorSide() : 0; // -1 = ceiling, 1 = floor, 0 = none
|
||||
const double planez = (reflect < 0 ? sector->ceilingplane.ZatPoint(Viewpoint.Pos) : sector->floorplane.ZatPoint(Viewpoint.Pos));
|
||||
angle_t pitchtemp;
|
||||
angle_t pitchmin = ANGLE_90;
|
||||
angle_t pitchmax = 0;
|
||||
|
|
@ -763,11 +765,11 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
if (!pitchvisible)
|
||||
{
|
||||
pitchmin = clipperv.PointToPseudoPitch(seg->v1->fX(), seg->v1->fY(),
|
||||
(ceilreflect || floorreflect) ?
|
||||
(reflect != 0) ?
|
||||
2 * planez - sector->floorplane.ZatPoint(seg->v1) :
|
||||
sector->floorplane.ZatPoint(seg->v1));
|
||||
pitchmax = clipperv.PointToPseudoPitch(seg->v1->fX(), seg->v1->fY(),
|
||||
(ceilreflect || floorreflect) ?
|
||||
(reflect != 0) ?
|
||||
2 * planez - sector->ceilingplane.ZatPoint(seg->v1) :
|
||||
sector->ceilingplane.ZatPoint(seg->v1));
|
||||
pitchvisible |= clipperv.SafeCheckRange(pitchmin, pitchmax);
|
||||
|
|
@ -776,12 +778,12 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
if (!pitchvisible)
|
||||
{
|
||||
pitchtemp = clipperv.PointToPseudoPitch(seg->v2->fX(), seg->v2->fY(),
|
||||
(ceilreflect || floorreflect) ?
|
||||
(reflect != 0) ?
|
||||
2 * planez - sector->floorplane.ZatPoint(seg->v2) :
|
||||
sector->floorplane.ZatPoint(seg->v2));
|
||||
if (int(pitchmin) > int(pitchtemp)) pitchmin = pitchtemp;
|
||||
pitchtemp = clipperv.PointToPseudoPitch(seg->v2->fX(), seg->v2->fY(),
|
||||
(ceilreflect || floorreflect) ?
|
||||
(reflect != 0) ?
|
||||
2 * planez - sector->ceilingplane.ZatPoint(seg->v2) :
|
||||
sector->ceilingplane.ZatPoint(seg->v2));
|
||||
if (int(pitchmax) < int(pitchtemp)) pitchmax = pitchtemp;
|
||||
|
|
@ -852,7 +854,7 @@ void HWDrawInfo::DoSubsector(subsector_t * sub, FRenderState& state)
|
|||
SetupSprite.Unclock();
|
||||
}
|
||||
}
|
||||
if (r_dithertransparency && Viewpoint.IsAllowedOoB() && (RTnum < MAXDITHERACTORS) && mCurrentPortal == nullptr)
|
||||
if (r_dithertransparency && doOob && (RTnum < MAXDITHERACTORS) && mCurrentPortal == nullptr)
|
||||
{
|
||||
// [DVR] Not parallelizable due to variables RTnum and RenderedTargets[]
|
||||
for (auto p = sector->touching_renderthings; p != nullptr; p = p->m_snext)
|
||||
|
|
@ -999,7 +1001,7 @@ void HWDrawInfo::RenderBSPNode (void *node, FRenderState& state)
|
|||
if (!(no_renderflags[bsp->Index()] & SSRF_SEEN))
|
||||
return;
|
||||
}
|
||||
if (Viewpoint.IsOrtho())
|
||||
if (Viewpoint.bDoOrtho)
|
||||
{
|
||||
if (!vClipper->CheckBoxOrthoPitch(bsp->bbox[side]))
|
||||
{
|
||||
|
|
@ -1016,7 +1018,7 @@ void HWDrawInfo::RenderBSPNode (void *node, FRenderState& state)
|
|||
// No need for clipping inside frustum if no fog of war (How is this faster!)
|
||||
void HWDrawInfo::RenderOrthoNoFog(FRenderState& state)
|
||||
{
|
||||
if (Viewpoint.IsOrtho() && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper))
|
||||
if (Viewpoint.bDoOrtho && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper))
|
||||
{
|
||||
double vxdbl = Viewpoint.OffPos.X;
|
||||
double vydbl = Viewpoint.OffPos.Y;
|
||||
|
|
@ -1042,7 +1044,7 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
|
|||
// Give the DrawInfo the viewpoint in fixed point because that's what the nodes are.
|
||||
viewx = FLOAT2FIXED(Viewpoint.Pos.X);
|
||||
viewy = FLOAT2FIXED(Viewpoint.Pos.Y);
|
||||
if (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR) && Viewpoint.IsAllowedOoB())
|
||||
if (r_radarclipper && !(Level->flags3 & LEVEL3_NOFOGOFWAR) && Viewpoint.bDoOob)
|
||||
{
|
||||
viewx = FLOAT2FIXED(Viewpoint.OffPos.X);
|
||||
viewy = FLOAT2FIXED(Viewpoint.OffPos.Y);
|
||||
|
|
@ -1068,7 +1070,7 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
|
|||
auto future = renderPool.push([&](int id) {
|
||||
WorkerThread();
|
||||
});
|
||||
if (Viewpoint.IsOrtho() && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper)) RenderOrthoNoFog(state);
|
||||
if (Viewpoint.bDoOrtho && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper)) RenderOrthoNoFog(state);
|
||||
else RenderBSPNode(node, state);
|
||||
|
||||
jobQueue.AddJob(RenderJob::TerminateJob, nullptr, nullptr);
|
||||
|
|
@ -1079,7 +1081,7 @@ void HWDrawInfo::RenderBSP(void *node, bool drawpsprites, FRenderState& state)
|
|||
}
|
||||
else
|
||||
{
|
||||
if (Viewpoint.IsOrtho() && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper)) RenderOrthoNoFog(state);
|
||||
if (Viewpoint.bDoOrtho && ((Level->flags3 & LEVEL3_NOFOGOFWAR) || !r_radarclipper)) RenderOrthoNoFog(state);
|
||||
else RenderBSPNode(node, state);
|
||||
Bsp.Unclock();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -397,7 +397,7 @@ angle_t Clipper::PointToPseudoAngle(double x, double y)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
else if (!amRadar && viewpoint->IsOrtho())
|
||||
else if (!amRadar && viewpoint->bDoOrtho)
|
||||
{
|
||||
return PointToPseudoOrthoAngle(x, y);
|
||||
}
|
||||
|
|
@ -424,7 +424,7 @@ angle_t Clipper::PointToPseudoPitch(double x, double y, double z)
|
|||
{
|
||||
return 0;
|
||||
}
|
||||
else if (viewpoint->IsOrtho())
|
||||
else if (viewpoint->bDoOrtho)
|
||||
{
|
||||
return PointToPseudoOrthoPitch(x, y, z);
|
||||
}
|
||||
|
|
@ -538,7 +538,7 @@ bool Clipper::CheckBox(const float *bspcoord)
|
|||
angle1 = PointToPseudoAngle (bspcoord[check[0]], bspcoord[check[1]]);
|
||||
angle2 = PointToPseudoAngle (bspcoord[check[2]], bspcoord[check[3]]);
|
||||
|
||||
if (vp->IsOrtho())
|
||||
if (vp->bDoOrtho)
|
||||
{
|
||||
if (angle2 != angle1) return true;
|
||||
switch (boxpos) // Check if the closer corner is poking into the view area
|
||||
|
|
@ -563,7 +563,7 @@ bool Clipper::CheckBoxOrthoPitch(const float *bspcoord)
|
|||
{
|
||||
angle_t pitchmin, pitchmax;
|
||||
auto &vp = viewpoint;
|
||||
if (!vp->IsOrtho()) return true;
|
||||
if (!vp->bDoOrtho) return true;
|
||||
|
||||
angle_t pitchtemp;
|
||||
double padding = 1.0/viewpoint->ScreenProj/viewpoint->PitchCos;
|
||||
|
|
|
|||
|
|
@ -762,7 +762,7 @@ int HWDecalCreateInfo::SetupLights(HWDrawInfo* di, FRenderState& state, FDynLigh
|
|||
p.Set(normal, -normal.X * glseg.x1 - normal.Z * glseg.y1);
|
||||
|
||||
// Iterate through all dynamic lights which touch this wall and render them
|
||||
auto wallLightList = di->Level->lightlists.wall_dlist.CheckKey(side);
|
||||
auto wallLightList = di->Level->lightlists.flat_dlist.SSize() > side->Index() ? &di->Level->lightlists.wall_dlist[side->Index()] : nullptr;
|
||||
|
||||
if (wallLightList)
|
||||
{
|
||||
|
|
|
|||
|
|
@ -242,7 +242,7 @@ void HWDrawInfo::ClearBuffers()
|
|||
void HWDrawInfo::UpdateCurrentMapSection()
|
||||
{
|
||||
int mapsection = Level->PointInRenderSubsector(Viewpoint.Pos)->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB() || Viewpoint.IsOrtho())
|
||||
if (Viewpoint.bDoOob || Viewpoint.bDoOrtho)
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.OffPos)->mapsection;
|
||||
CurrentMapSections.Set(mapsection);
|
||||
}
|
||||
|
|
@ -259,8 +259,8 @@ void HWDrawInfo::SetViewArea()
|
|||
auto &vp = Viewpoint;
|
||||
// The render_sector is better suited to represent the current position in GL
|
||||
vp.sector = Level->PointInRenderSubsector(vp.Pos)->render_sector;
|
||||
if (Viewpoint.IsAllowedOoB())
|
||||
vp.sector = Level->PointInRenderSubsector(vp.camera->Pos())->render_sector;
|
||||
if (Viewpoint.bDoOob)
|
||||
vp.sector = Level->PointInRenderSubsector(vp.camera->Pos())->render_sector;
|
||||
|
||||
// Get the heightsec state from the render sector, not the current one!
|
||||
if (vp.sector->GetHeightSec())
|
||||
|
|
@ -359,7 +359,7 @@ angle_t OoBFrustumAngle(FRenderViewpoint* Viewpoint)
|
|||
|
||||
angle_t HWDrawInfo::FrustumAngle()
|
||||
{
|
||||
if (Viewpoint.IsAllowedOoB())
|
||||
if (Viewpoint.bDoOob)
|
||||
{
|
||||
return OoBFrustumAngle(&Viewpoint);
|
||||
}
|
||||
|
|
@ -610,7 +610,7 @@ void HWDrawInfo::CreateScene(bool drawpsprites, FRenderState& state)
|
|||
angle_t a1 = FrustumAngle();
|
||||
mClipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + a1, vp.Angles.Yaw.BAMs() - a1);
|
||||
Viewpoint.FrustAngle = a1;
|
||||
if (Viewpoint.IsAllowedOoB()) // No need for vertical clipper if viewpoint not allowed out of bounds
|
||||
if (Viewpoint.bDoOob) // No need for vertical clipper if viewpoint not allowed out of bounds
|
||||
{
|
||||
double a2 = 20.0 + 0.5*Viewpoint.FieldOfView.Degrees(); // FrustumPitch for vertical clipping
|
||||
if (a2 > 179.0) a2 = 179.0;
|
||||
|
|
@ -1253,7 +1253,7 @@ void HWDrawInfo::SetDitherTransFlags(AActor* actor)
|
|||
double horiy = Viewpoint.Cos * actor->radius;
|
||||
DVector3 actorpos = actor->Pos();
|
||||
DVector3 vvec = actorpos - Viewpoint.Pos;
|
||||
if (Viewpoint.IsOrtho())
|
||||
if (Viewpoint.bDoOrtho)
|
||||
{
|
||||
vvec = 5.0 * Viewpoint.camera->ViewPos->Offset.Length() * Viewpoint.ViewVector3D; // Should be 4.0? (since zNear is behind screen by 3*dist in VREyeInfo::GetProjection())
|
||||
}
|
||||
|
|
@ -1448,7 +1448,7 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
{
|
||||
ssao_portals_available = gl_ssao_portals;
|
||||
applySSAO = true;
|
||||
if (r_dithertransparency && vp.IsAllowedOoB())
|
||||
if (r_dithertransparency && vp.bDoOob)
|
||||
{
|
||||
if (vp.camera->tracer)
|
||||
SetDitherTransFlags(vp.camera->tracer);
|
||||
|
|
@ -1526,7 +1526,7 @@ void HWDrawInfo::ProcessScene(bool toscreen, FRenderState& state)
|
|||
drawctx->portalState.BeginScene();
|
||||
|
||||
int mapsection = Level->PointInRenderSubsector(Viewpoint.Pos)->mapsection;
|
||||
if (Viewpoint.IsAllowedOoB() || Viewpoint.IsOrtho())
|
||||
if (Viewpoint.bDoOob || Viewpoint.bDoOrtho)
|
||||
mapsection = Level->PointInRenderSubsector(Viewpoint.OffPos)->mapsection;
|
||||
CurrentMapSections.Set(mapsection);
|
||||
DrawScene(toscreen ? DM_MAINVIEW : DM_OFFSCREEN, state);
|
||||
|
|
|
|||
|
|
@ -176,11 +176,9 @@ void HWFlat::SetupLights(HWFlatDispatcher *di, FRenderState& state, FDynLightDat
|
|||
return; // no lights on additively blended surfaces.
|
||||
}
|
||||
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(section);
|
||||
|
||||
if (flatLightList)
|
||||
if (di->Level->lightlists.flat_dlist.SSize() > section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.flat_dlist[section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
@ -579,7 +577,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
//
|
||||
//
|
||||
//
|
||||
if ((which & SSRF_RENDERFLOOR) && ((di->di && vp->IsOrtho()) ? vp->ViewVector3D.dot(frontsector->floorplane.Normal()) < 0.0 : (!di->di || (frontsector->floorplane.ZatPoint(vp->Pos) <= vp->Pos.Z))) && (!section || !(section->flags & FSection::DONTRENDERFLOOR)))
|
||||
if ((which & SSRF_RENDERFLOOR) && (vp && vp->bDoOrtho ? vp->ViewVector3D.dot(frontsector->floorplane.Normal()) < 0.0 : (!vp || frontsector->floorplane.ZatPoint(vp->Pos) <= vp->Pos.Z)) && (!section || !(section->flags & FSection::DONTRENDERFLOOR)))
|
||||
{
|
||||
// process the original floor first.
|
||||
|
||||
|
|
@ -637,7 +635,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
//
|
||||
//
|
||||
//
|
||||
if ((which & SSRF_RENDERCEILING) && ((di->di && vp->IsOrtho()) ? vp->ViewVector3D.dot(frontsector->ceilingplane.Normal()) < 0.0 : (!di->di || (frontsector->ceilingplane.ZatPoint(vp->Pos) >= vp->Pos.Z))) && (!section || !(section->flags & FSection::DONTRENDERCEILING)))
|
||||
if ((which & SSRF_RENDERCEILING) && (vp && vp->bDoOrtho ? vp->ViewVector3D.dot(frontsector->ceilingplane.Normal()) < 0.0 : !vp || frontsector->ceilingplane.ZatPoint(vp->Pos) >= vp->Pos.Z) && (!section || !(section->flags & FSection::DONTRENDERCEILING)))
|
||||
{
|
||||
// process the original ceiling first.
|
||||
|
||||
|
|
@ -722,7 +720,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
double ff_top = rover->top.plane->ZatPoint(sector->centerspot);
|
||||
if (ff_top < lastceilingheight)
|
||||
{
|
||||
if (!di->di || (vp->IsOrtho() ? vp->ViewVector3D.dot(rover->top.plane->Normal()) > 0.0 : vp->Pos.Z <= rover->top.plane->ZatPoint(vp->Pos)))
|
||||
if (!vp || ((vp->bDoOrtho ? vp->ViewVector3D.dot(rover->top.plane->Normal()) > 0.0 : vp->Pos.Z <= rover->top.plane->ZatPoint(vp->Pos))))
|
||||
{
|
||||
SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG));
|
||||
Colormap.FadeColor = frontsector->Colormap.FadeColor;
|
||||
|
|
@ -736,7 +734,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot);
|
||||
if (ff_bottom < lastceilingheight)
|
||||
{
|
||||
if (!di->di || (vp->IsOrtho() ? vp->ViewVector3D.dot(rover->bottom.plane->Normal()) > 0.0 : vp->Pos.Z <= rover->bottom.plane->ZatPoint(vp->Pos)))
|
||||
if (!vp || (vp->bDoOrtho ? vp->ViewVector3D.dot(rover->bottom.plane->Normal()) > 0.0 : vp->Pos.Z <= rover->bottom.plane->ZatPoint(vp->Pos)))
|
||||
{
|
||||
SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG));
|
||||
Colormap.FadeColor = frontsector->Colormap.FadeColor;
|
||||
|
|
@ -762,7 +760,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
double ff_bottom = rover->bottom.plane->ZatPoint(sector->centerspot);
|
||||
if (ff_bottom > lastfloorheight || (rover->flags&FF_FIX))
|
||||
{
|
||||
if (!di->di || (vp->IsOrtho() ? vp->ViewVector3D.dot(rover->bottom.plane->Normal()) > 0.0 : vp->Pos.Z >= rover->bottom.plane->ZatPoint(vp->Pos)))
|
||||
if (!vp || (vp->bDoOrtho ? vp->ViewVector3D.dot(rover->bottom.plane->Normal()) > 0.0 : vp->Pos.Z >= rover->bottom.plane->ZatPoint(vp->Pos)))
|
||||
{
|
||||
SetFrom3DFloor(rover, false, !(rover->flags&FF_FOG));
|
||||
Colormap.FadeColor = frontsector->Colormap.FadeColor;
|
||||
|
|
@ -783,7 +781,7 @@ void HWFlat::ProcessSector(HWFlatDispatcher *di, FRenderState& state, sector_t *
|
|||
double ff_top = rover->top.plane->ZatPoint(sector->centerspot);
|
||||
if (ff_top > lastfloorheight)
|
||||
{
|
||||
if (!di->di || (vp->IsOrtho() ? vp->ViewVector3D.dot(rover->top.plane->Normal()) > 0.0 : vp->Pos.Z >= rover->top.plane->ZatPoint(vp->Pos)))
|
||||
if (!vp || (vp->bDoOrtho ? vp->ViewVector3D.dot(rover->top.plane->Normal()) > 0.0 : vp->Pos.Z >= rover->top.plane->ZatPoint(vp->Pos)))
|
||||
{
|
||||
SetFrom3DFloor(rover, true, !!(rover->flags&FF_FOG));
|
||||
Colormap.FadeColor = frontsector->Colormap.FadeColor;
|
||||
|
|
|
|||
|
|
@ -125,7 +125,7 @@ bool FPortalSceneState::RenderFirstSkyPortal(int recursion, HWDrawInfo *outer_di
|
|||
{
|
||||
HWPortal * best = nullptr;
|
||||
unsigned bestindex = 0;
|
||||
bool usestencil = outer_di->Viewpoint.IsAllowedOoB();
|
||||
bool usestencil = outer_di->Viewpoint.bDoOob;
|
||||
|
||||
// Find the one with the highest amount of lines.
|
||||
// Normally this is also the one that saves the largest amount
|
||||
|
|
@ -504,7 +504,7 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
|||
}
|
||||
|
||||
auto &vp = di->Viewpoint;
|
||||
state->vpIsAllowedOoB = vp.IsAllowedOoB();
|
||||
state->vpIsAllowedOoB = vp.bDoOob;
|
||||
di->UpdateCurrentMapSection();
|
||||
|
||||
di->mClipPortal = this;
|
||||
|
|
@ -573,7 +573,7 @@ bool HWMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
|||
angle_t af = di->FrustumAngle();
|
||||
if (af < ANGLE_180) clipper->SafeAddClipRangeRealAngles(vp.Angles.Yaw.BAMs() + af, vp.Angles.Yaw.BAMs() - af);
|
||||
|
||||
if (!di->Viewpoint.IsAllowedOoB())
|
||||
if(!di->Viewpoint.bDoOob)
|
||||
clipper->SafeAddClipRange(linedef->v1, linedef->v2);
|
||||
return true;
|
||||
}
|
||||
|
|
@ -609,7 +609,7 @@ bool HWLineToLinePortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *cl
|
|||
return false;
|
||||
}
|
||||
auto &vp = di->Viewpoint;
|
||||
state->vpIsAllowedOoB = vp.IsAllowedOoB();
|
||||
state->vpIsAllowedOoB = vp.bDoOob;
|
||||
di->mClipPortal = this;
|
||||
|
||||
line_t *origin = glport->lines[0]->mOrigin;
|
||||
|
|
@ -689,7 +689,7 @@ bool HWSkyboxPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *clippe
|
|||
return false;
|
||||
}
|
||||
auto &vp = di->Viewpoint;
|
||||
state->vpIsAllowedOoB = vp.IsAllowedOoB();
|
||||
state->vpIsAllowedOoB = vp.bDoOob;
|
||||
|
||||
state->skyboxrecursion++;
|
||||
state->PlaneMirrorMode = 0;
|
||||
|
|
@ -801,7 +801,7 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
|||
|
||||
FSectorPortalGroup *portal = origin;
|
||||
auto &vp = di->Viewpoint;
|
||||
state->vpIsAllowedOoB = vp.IsAllowedOoB();
|
||||
state->vpIsAllowedOoB = vp.bDoOob;
|
||||
|
||||
vp.Pos += origin->mDisplacement;
|
||||
vp.ActorPos += origin->mDisplacement;
|
||||
|
|
@ -810,7 +810,7 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
|||
|
||||
// avoid recursions!
|
||||
if (origin->plane != -1) screen->instack[origin->plane]++;
|
||||
if (vp.IsAllowedOoB() && lines.Size() > 0)
|
||||
if (vp.bDoOob && lines.Size() > 0)
|
||||
{
|
||||
flat.plane.GetFromSector(lines[0].sub->sector, origin->plane);
|
||||
di->SetClipHeight(flat.plane.plane.ZatPoint(vp.Pos),
|
||||
|
|
@ -823,7 +823,7 @@ bool HWSectorStackPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
|||
// If the viewpoint is not within the portal, we need to invalidate the entire clip area.
|
||||
// The portal will re-validate the necessary parts when its subsectors get traversed.
|
||||
subsector_t *sub = di->Level->PointInRenderSubsector(vp.Pos);
|
||||
if (vp.IsAllowedOoB()) sub = di->Level->PointInRenderSubsector(vp.OffPos);
|
||||
if (vp.bDoOob) sub = di->Level->PointInRenderSubsector(vp.OffPos);
|
||||
if (!(di->ss_renderflags[sub->Index()] & SSRF_SEEN))
|
||||
{
|
||||
clipper->SafeAddClipRange(0, ANGLE_MAX);
|
||||
|
|
@ -891,7 +891,7 @@ bool HWPlaneMirrorPortal::Setup(HWDrawInfo *di, FRenderState &rstate, Clipper *c
|
|||
std::swap(screen->instack[sector_t::floor], screen->instack[sector_t::ceiling]);
|
||||
|
||||
auto &vp = di->Viewpoint;
|
||||
state->vpIsAllowedOoB = vp.IsAllowedOoB();
|
||||
state->vpIsAllowedOoB = vp.bDoOob;
|
||||
old_pm = state->PlaneMirrorMode;
|
||||
|
||||
// the player is always visible in a mirror.
|
||||
|
|
@ -947,6 +947,8 @@ void HWPlaneMirrorPortal::Shutdown(HWDrawInfo *di, FRenderState &rstate)
|
|||
|
||||
const char *HWPlaneMirrorPortal::GetName() { return origin->fC() < 0? "Planemirror ceiling" : "Planemirror floor"; }
|
||||
|
||||
int HWPlaneMirrorPortal::GetMirrorSide() const { return origin->fC() < 0 ? -1 : 1; };
|
||||
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -71,6 +71,7 @@ public:
|
|||
{
|
||||
}
|
||||
virtual ~HWPortal() {}
|
||||
virtual int GetMirrorSide() const { return 0; };
|
||||
virtual int ClipSeg(seg_t *seg, const DVector3 &viewpos) { return PClip_Inside; }
|
||||
virtual int ClipSubsector(subsector_t *sub) { return PClip_Inside; }
|
||||
virtual int ClipPoint(const DVector2 &pos) { return PClip_Inside; }
|
||||
|
|
@ -148,7 +149,7 @@ public:
|
|||
virtual bool NeedDepthBuffer() { return true; }
|
||||
virtual void DrawContents(HWDrawInfo *di, FRenderState &state)
|
||||
{
|
||||
if (Setup(di, state, (di->Viewpoint.IsAllowedOoB() ? di->rClipper : di->mClipper)))
|
||||
if (Setup(di, state, (di->Viewpoint.bDoOob ? di->rClipper : di->mClipper)))
|
||||
{
|
||||
di->DrawScene(DM_PORTAL, state);
|
||||
Shutdown(di, state);
|
||||
|
|
@ -304,6 +305,8 @@ protected:
|
|||
|
||||
public:
|
||||
|
||||
int GetMirrorSide() const override;
|
||||
|
||||
HWPlaneMirrorPortal(FPortalSceneState *state, secplane_t * pt) : HWScenePortalBase(state)
|
||||
{
|
||||
origin = pt;
|
||||
|
|
|
|||
|
|
@ -121,11 +121,9 @@ int HWDrawInfo::SetupLightsForOtherPlane(subsector_t * sub, FDynLightData &light
|
|||
|
||||
lightdata.Clear();
|
||||
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
if (flatLightList)
|
||||
if (Level->lightlists.flat_dlist.SSize() > sub->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sub->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -157,10 +157,10 @@ void HWWall::SkyPlane(HWWallDispatcher *di, FRenderState& state, sector_t *secto
|
|||
case PORTS_PORTAL:
|
||||
case PORTS_LINKEDPORTAL:
|
||||
{
|
||||
if (di->di && di->di->Viewpoint.IsAllowedOoB())
|
||||
if (di->di && di->di->Viewpoint.bDoOob)
|
||||
{
|
||||
secplane_t myplane = plane ? sector->ceilingplane : sector->floorplane;
|
||||
if (di->di->Viewpoint.IsOrtho() && di->di->Viewpoint.ViewVector3D.dot(myplane.Normal()) > 0.0) return;
|
||||
if (di->di->Viewpoint.bDoOrtho && di->di->Viewpoint.ViewVector3D.dot(myplane.Normal()) > 0.0) return;
|
||||
else if (plane==1 && di->di->Viewpoint.Pos.Z >= myplane.ZatPoint(di->di->Viewpoint.Pos)) return;
|
||||
else if (plane==0 && di->di->Viewpoint.Pos.Z <= myplane.ZatPoint(di->di->Viewpoint.Pos)) return;
|
||||
}
|
||||
|
|
@ -323,7 +323,7 @@ void HWWall::SkyTop(HWWallDispatcher *di, FRenderState& state, seg_t * seg,secto
|
|||
// if (backreflect > 0 && bs->ceilingplane.fD() == fs->ceilingplane.fD() && !bs->isClosed())
|
||||
// {
|
||||
// Don't add intra-portal line to the portal.
|
||||
// if (!(di->di && di->di->Viewpoint.IsAllowedOoB()))
|
||||
// if (!(di->di && di->di->Viewpoint.bDoOob))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
|
@ -406,7 +406,7 @@ void HWWall::SkyBottom(HWWallDispatcher *di, FRenderState& state, seg_t * seg,se
|
|||
// if (backreflect > 0 && bs->floorplane.fD() == fs->floorplane.fD() && !bs->isClosed())
|
||||
// {
|
||||
// // Don't add intra-portal line to the portal.
|
||||
// if (!(di->di && di->di->Viewpoint.IsAllowedOoB()))
|
||||
// if (!(di->di && di->di->Viewpoint.bDoOob))
|
||||
// {
|
||||
// return;
|
||||
// }
|
||||
|
|
|
|||
|
|
@ -158,12 +158,10 @@ void HWDrawInfo::GetDynSpriteLight(AActor* self, sun_trace_cache_t* traceCache,
|
|||
}
|
||||
|
||||
// Go through both light lists
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
|
||||
if (flatLightList)
|
||||
if (Level->lightlists.flat_dlist.SSize() > sec->Index())
|
||||
{
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sec->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto node = pair->Value.get();
|
||||
|
|
@ -312,11 +310,10 @@ void HWDrawInfo::GetDynSpriteLightList(AActor *self, double x, double y, double
|
|||
auto section = subsector->section;
|
||||
if (section->validcount == dl_validcount) return; // already done from a previous subsector.
|
||||
|
||||
auto flatLightList = level.lightlists.flat_dlist.CheckKey(subsector->section);
|
||||
if (flatLightList)
|
||||
if (level.lightlists.flat_dlist.SSize() > subsector->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>::Pair* pair;
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(level.lightlists.flat_dlist[subsector->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{ // check all lights touching a subsector
|
||||
auto node = pair->Value.get();
|
||||
|
|
|
|||
|
|
@ -651,7 +651,7 @@ bool HWSprite::CalculateVertices(HWDrawInfo* di, FVector3* v, DVector3* vp)
|
|||
mat.Translate(-center.X, -center.Z, -center.Y);
|
||||
}
|
||||
|
||||
if (actor && (actor->renderflags2 & RF2_ISOMETRICSPRITES) && di->Viewpoint.IsOrtho())
|
||||
if (actor && (actor->renderflags2 & RF2_ISOMETRICSPRITES) && di->Viewpoint.bDoOrtho)
|
||||
{
|
||||
float angleRad = (FAngle::fromDeg(270.) - HWAngles.Yaw).Radians();
|
||||
mat.Translate(center.X, center.Z, center.Y);
|
||||
|
|
@ -1063,7 +1063,7 @@ void HWSprite::Process(HWDrawInfo *di, FRenderState& state, AActor* thing, secto
|
|||
bool mirror = false;
|
||||
bool backfaced = false;
|
||||
DAngle ang = (thingpos - vp.Pos).Angle();
|
||||
if (di->Viewpoint.IsOrtho()) ang = vp.Angles.Yaw;
|
||||
if (di->Viewpoint.bDoOrtho) ang = vp.Angles.Yaw;
|
||||
else if (actor && thing->renderflags2 & RF2_ANGLEDROLL)
|
||||
{
|
||||
Matrix3x4 rolltilt;
|
||||
|
|
|
|||
|
|
@ -430,11 +430,9 @@ void HWWall::SetupLights(HWDrawInfo*di, FRenderState& state, FDynLightData &ligh
|
|||
if ((seg->sidedef->Flags & WALLF_POLYOBJ) && sub)
|
||||
{
|
||||
// Polobject segs cannot be checked per sidedef so use the subsector instead.
|
||||
auto flatLightList = di->Level->lightlists.flat_dlist.CheckKey(sub->section);
|
||||
|
||||
if (flatLightList)
|
||||
if (di->Level->lightlists.flat_dlist.SSize() > sub->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.flat_dlist[sub->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
@ -495,11 +493,9 @@ void HWWall::SetupLights(HWDrawInfo*di, FRenderState& state, FDynLightData &ligh
|
|||
}
|
||||
else
|
||||
{
|
||||
auto wallLightList = di->Level->lightlists.wall_dlist.CheckKey(seg->sidedef);
|
||||
|
||||
if (wallLightList)
|
||||
if (di->Level->lightlists.wall_dlist.SSize() > seg->sidedef->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(di->Level->lightlists.wall_dlist[seg->sidedef->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
@ -694,7 +690,7 @@ void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int
|
|||
break;
|
||||
|
||||
case PORTALTYPE_PLANEMIRROR:
|
||||
if (ddi->Viewpoint.IsOrtho() ? (ddi->Viewpoint.ViewVector3D.dot(planemirror->Normal()) < 0)
|
||||
if (ddi->Viewpoint.bDoOrtho ? (ddi->Viewpoint.ViewVector3D.dot(planemirror->Normal()) < 0)
|
||||
: (ddi->drawctx->portalState.PlaneMirrorMode * planemirror->fC() <= 0))
|
||||
{
|
||||
planemirror = ddi->drawctx->portalState.UniquePlaneMirrors.Get(planemirror);
|
||||
|
|
|
|||
|
|
@ -550,7 +550,7 @@ void R_InterpolateView(FRenderViewpoint& viewPoint, const player_t* const player
|
|||
const int prevPortalGroup = viewLvl->PointInRenderSubsector(iView->Old.Pos)->sector->PortalGroup;
|
||||
const int curPortalGroup = viewLvl->PointInRenderSubsector(iView->New.Pos)->sector->PortalGroup;
|
||||
|
||||
if (viewPoint.IsAllowedOoB() && prevPortalGroup != curPortalGroup) viewPoint.Pos = iView->New.Pos;
|
||||
if (viewPoint.bDoOob && prevPortalGroup != curPortalGroup) viewPoint.Pos = iView->New.Pos;
|
||||
else
|
||||
{
|
||||
const DVector2 portalOffset = viewLvl->Displacements.getOffset(prevPortalGroup, curPortalGroup);
|
||||
|
|
@ -567,7 +567,7 @@ void R_InterpolateView(FRenderViewpoint& viewPoint, const player_t* const player
|
|||
|
||||
// Due to interpolation this is not necessarily the same as the sector the camera is in.
|
||||
viewPoint.sector = viewLvl->PointInRenderSubsector(viewPoint.Pos)->sector;
|
||||
if (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer())
|
||||
if (!viewPoint.bDoOob || !V_IsHardwareRenderer())
|
||||
{
|
||||
bool moved = false;
|
||||
while (!viewPoint.sector->PortalBlocksMovement(sector_t::ceiling))
|
||||
|
|
@ -712,7 +712,7 @@ void FRenderViewpoint::SetViewAngle(const FViewWindow& viewWindow)
|
|||
ViewVector3D.Y = v.Y * PitchCos;
|
||||
ViewVector3D.Z = -PitchSin;
|
||||
|
||||
if (IsOrtho() || IsAllowedOoB()) // These auto-ensure that camera and camera->ViewPos exist
|
||||
if (bDoOrtho || bDoOob) // These auto-ensure that camera and camera->ViewPos exist
|
||||
{
|
||||
if (camera->tracer != NULL)
|
||||
{
|
||||
|
|
@ -724,7 +724,7 @@ void FRenderViewpoint::SetViewAngle(const FViewWindow& viewWindow)
|
|||
}
|
||||
}
|
||||
|
||||
if (IsOrtho() && (camera->ViewPos->Offset.XY().Length() > 0.0))
|
||||
if (bDoOrtho && (camera->ViewPos->Offset.XY().Length() > 0.0))
|
||||
{
|
||||
ScreenProj = 1.34396 / camera->ViewPos->Offset.Length() / tan (FieldOfView.Radians()*0.5); // [DVR] Estimated. +/-1 should be top/bottom of screen.
|
||||
ScreenProjX = ScreenProj * 0.5 / viewWindow.WidescreenRatio;
|
||||
|
|
@ -953,6 +953,9 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA
|
|||
if (viewPoint.camera == nullptr)
|
||||
I_Error("You lost your body. Bad dehacked work is likely to blame.");
|
||||
|
||||
viewPoint.bDoOob = viewPoint.IsAllowedOoB();
|
||||
viewPoint.bDoOrtho = viewPoint.IsOrtho();
|
||||
|
||||
InterpolationViewer* const iView = FindPastViewer(viewPoint.camera);
|
||||
// Always reset these back to zero.
|
||||
iView->ViewOffset.Zero();
|
||||
|
|
@ -1136,14 +1139,14 @@ void R_SetupFrame(FRenderViewpoint& viewPoint, const FViewWindow& viewWindow, AA
|
|||
|
||||
// Keep the view within the sector's floor and ceiling
|
||||
// But allow VPSF_ALLOWOUTOFBOUNDS camera viewpoints to go out of bounds when using hardware renderer
|
||||
if (viewPoint.sector->PortalBlocksMovement(sector_t::ceiling) && (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer()))
|
||||
if (viewPoint.sector->PortalBlocksMovement(sector_t::ceiling) && (!viewPoint.bDoOob || !V_IsHardwareRenderer()))
|
||||
{
|
||||
const double z = viewPoint.sector->ceilingplane.ZatPoint(viewPoint.Pos) - 4.0;
|
||||
if (viewPoint.Pos.Z > z)
|
||||
viewPoint.Pos.Z = z;
|
||||
}
|
||||
|
||||
if (viewPoint.sector->PortalBlocksMovement(sector_t::floor) && (!viewPoint.IsAllowedOoB() || !V_IsHardwareRenderer()))
|
||||
if (viewPoint.sector->PortalBlocksMovement(sector_t::floor) && (!viewPoint.bDoOob || !V_IsHardwareRenderer()))
|
||||
{
|
||||
const double z = viewPoint.sector->floorplane.ZatPoint(viewPoint.Pos) + 4.0;
|
||||
if (viewPoint.Pos.Z < z)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,8 @@ struct FRenderViewpoint
|
|||
int extralight; // extralight to be added to this viewpoint
|
||||
bool showviewer; // show the camera actor?
|
||||
bool bForceNoViewer; // Never show the camera Actor.
|
||||
bool bDoOob;
|
||||
bool bDoOrtho;
|
||||
void SetViewAngle(const FViewWindow& viewWindow);
|
||||
bool IsAllowedOoB(); // Checks if camera actor exists, has viewpos, and viewpos has VPSF_ALLOWOUTOFBOUNDS flag set
|
||||
bool IsOrtho(); // Checks if camera actor exists, has viewpos, and viewpos has VPSF_ORTHOGRAPHIC flag set
|
||||
|
|
|
|||
|
|
@ -241,46 +241,48 @@ namespace swrenderer
|
|||
|
||||
drawerargs.dc_num_lights = 0;
|
||||
|
||||
// Setup lights for column
|
||||
FLightNode* cur_node = drawerargs.LightList();
|
||||
while (cur_node)
|
||||
if(drawerargs.LightList())
|
||||
{
|
||||
if (cur_node->lightsource->IsActive())
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*drawerargs.LightList());
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
double lightX = cur_node->lightsource->X() - wallargs.ViewpointPos.X;
|
||||
double lightY = cur_node->lightsource->Y() - wallargs.ViewpointPos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - wallargs.ViewpointPos.Z;
|
||||
|
||||
float lx = (float)(lightX * wallargs.Sin - lightY * wallargs.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * wallargs.TanCos + lightY * wallargs.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
auto cur_node = pair->Value.get();
|
||||
if (cur_node->lightsource->IsActive())
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
double lightX = cur_node->lightsource->X() - wallargs.ViewpointPos.X;
|
||||
double lightY = cur_node->lightsource->Y() - wallargs.ViewpointPos.Y;
|
||||
double lightZ = cur_node->lightsource->Z() - wallargs.ViewpointPos.Z;
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
float lx = (float)(lightX * wallargs.Sin - lightY * wallargs.Cos) - drawerargs.dc_viewpos.X;
|
||||
float ly = (float)(lightX * wallargs.TanCos + lightY * wallargs.TanSin) - drawerargs.dc_viewpos.Y;
|
||||
float lz = (float)lightZ;
|
||||
|
||||
if (drawerargs.dc_num_lights == WallColumnDrawerArgs::MAX_DRAWER_LIGHTS)
|
||||
break;
|
||||
// Precalculate the constant part of the dot here so the drawer doesn't have to.
|
||||
bool is_point_light = cur_node->lightsource->IsAttenuated();
|
||||
float lconstant = lx * lx + ly * ly;
|
||||
float nlconstant = is_point_light ? lx * drawerargs.dc_normal.X + ly * drawerargs.dc_normal.Y : 0.0f;
|
||||
|
||||
// Include light only if it touches this column
|
||||
float radius = cur_node->lightsource->GetRadius();
|
||||
if (radius * radius >= lconstant && nlconstant >= 0.0f)
|
||||
{
|
||||
uint32_t red = cur_node->lightsource->GetRed();
|
||||
uint32_t green = cur_node->lightsource->GetGreen();
|
||||
uint32_t blue = cur_node->lightsource->GetBlue();
|
||||
|
||||
auto& light = drawerargs.dc_lights[drawerargs.dc_num_lights++];
|
||||
light.x = lconstant;
|
||||
light.y = nlconstant;
|
||||
light.z = lz;
|
||||
light.radius = 256.0f / cur_node->lightsource->GetRadius();
|
||||
light.color = (red << 16) | (green << 8) | blue;
|
||||
|
||||
if (drawerargs.dc_num_lights == WallColumnDrawerArgs::MAX_DRAWER_LIGHTS)
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
cur_node = cur_node->nextLight;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -86,7 +86,7 @@ namespace swrenderer
|
|||
ShadeConstants ColormapConstants() const { return wallargs->ColormapConstants(); }
|
||||
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
|
||||
|
||||
FLightNode* LightList() const { return wallargs->lightlist; }
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* LightList() const { return wallargs->lightlist; }
|
||||
|
||||
const WallDrawerArgs* wallargs;
|
||||
|
||||
|
|
|
|||
|
|
@ -207,60 +207,23 @@ namespace swrenderer
|
|||
drawerargs.DrawWall(Thread);
|
||||
}
|
||||
|
||||
FLightNode* RenderWallPart::GetLightList()
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* RenderWallPart::GetLightList()
|
||||
{
|
||||
while (light_list)
|
||||
{
|
||||
// Clear out the wall part light list
|
||||
FLightNode *next = nullptr;
|
||||
if (light_list->nextLight) next = light_list->nextLight;
|
||||
delete light_list;
|
||||
if (next) light_list = next;
|
||||
}
|
||||
|
||||
CameraLight* cameraLight = CameraLight::Instance();
|
||||
if ((cameraLight->FixedLightLevel() >= 0) || cameraLight->FixedColormap())
|
||||
{
|
||||
return nullptr; // [SP] Don't draw dynlights if invul/lightamp active
|
||||
}
|
||||
else if (curline && curline->sidedef)
|
||||
{
|
||||
auto Level = curline->Subsector->sector->Level;
|
||||
auto wallLightList = Level->lightlists.wall_dlist.CheckKey(curline->sidedef);
|
||||
if (wallLightList)
|
||||
|
||||
if (Level->lightlists.wall_dlist.SSize() > curline->sidedef->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*wallLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
auto node = pair->Value.get();
|
||||
if (!node) continue;
|
||||
|
||||
if (node->lightsource->IsActive())
|
||||
{
|
||||
bool found = false;
|
||||
FLightNode *light_node = light_list;
|
||||
while (light_node)
|
||||
{
|
||||
if (light_node->lightsource == node->lightsource)
|
||||
{
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
light_node = light_node->nextLight;
|
||||
}
|
||||
if (!found)
|
||||
{
|
||||
FLightNode *newlight = new FLightNode;
|
||||
newlight->nextLight = light_list;
|
||||
newlight->lightsource = node->lightsource;
|
||||
light_list = newlight;
|
||||
}
|
||||
}
|
||||
}
|
||||
return &Level->lightlists.wall_dlist[curline->sidedef->Index()];
|
||||
}
|
||||
|
||||
return light_list;
|
||||
}
|
||||
else
|
||||
return nullptr;
|
||||
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -62,7 +62,7 @@ namespace swrenderer
|
|||
private:
|
||||
void ProcessStripedWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
void ProcessNormalWall(const short *uwal, const short *dwal, const ProjectedWallTexcoords& texcoords);
|
||||
FLightNode* GetLightList();
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* GetLightList();
|
||||
|
||||
RenderThread* Thread = nullptr;
|
||||
|
||||
|
|
@ -76,7 +76,7 @@ namespace swrenderer
|
|||
|
||||
ProjectedWallLight mLight;
|
||||
|
||||
FLightNode *light_list = nullptr;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>> *light_list = nullptr;
|
||||
bool mask = false;
|
||||
bool additive = false;
|
||||
fixed_t alpha = 0;
|
||||
|
|
|
|||
|
|
@ -76,10 +76,10 @@ namespace swrenderer
|
|||
return; // [SP] no dynlights if invul or lightamp
|
||||
|
||||
auto Level = sec->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(sec);
|
||||
if (flatLightList)
|
||||
|
||||
if (Level->lightlists.flat_dlist.SSize() > sec->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[sec->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -209,10 +209,10 @@ namespace swrenderer
|
|||
float lit_green = 0;
|
||||
float lit_blue = 0;
|
||||
auto Level = vis->sector->Level;
|
||||
auto flatLightList = Level->lightlists.flat_dlist.CheckKey(vis->section);
|
||||
if (flatLightList)
|
||||
|
||||
if (Level->lightlists.flat_dlist.SSize() > vis->section->Index())
|
||||
{
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(*flatLightList);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Iterator it(Level->lightlists.flat_dlist[vis->section->Index()]);
|
||||
TMap<FDynamicLight *, std::unique_ptr<FLightNode>>::Pair *pair;
|
||||
while (it.NextPair(pair))
|
||||
{
|
||||
|
|
|
|||
|
|
@ -31,7 +31,7 @@ namespace swrenderer
|
|||
short* dwal;
|
||||
FWallCoords WallC;
|
||||
ProjectedWallTexcoords texcoords;
|
||||
FLightNode* lightlist = nullptr;
|
||||
TMap<FDynamicLight*, std::unique_ptr<FLightNode>>* lightlist = nullptr;
|
||||
|
||||
float lightpos;
|
||||
float lightstep;
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue