//-----------------------------------------------------------------------------
//
// Copyright 1993-1996 id Software
// Copyright 1999-2016 Randy Heit
// Copyright 2016 Magnus Norddahl
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program. If not, see http://www.gnu.org/licenses/
//
//-----------------------------------------------------------------------------
#pragma once
#include "tarray.h"
#include <stddef.h>
#include "r_defs.h"
#include "swrenderer/line/r_line.h"
#include "swrenderer/scene/r_3dfloors.h"
#include <set>
struct FVoxelDef;
namespace swrenderer
{
class RenderThread;
struct VisiblePlane;
// The 32 below is just an arbitrary value picked to avoid
// drawing lines the player is too close to that would overflow
// the texture calculations.
#define TOO_CLOSE_Z (32.0 / (1 << 12))
enum class WaterFakeSide
{
Center,
BelowFloor,
AboveCeiling
};
struct ThingSprite
{
DVector3 pos;
int spritenum;
FSoftwareTexture *tex;
FVoxelDef *voxel;
FTextureID picnum;
DVector2 spriteScale;
int renderflags;
};
class RenderOpaquePass
{
public:
RenderOpaquePass(RenderThread *thread);
void ClearClip();
void RenderScene(FLevelLocals *Level);
void ResetFakingUnderwater() { r_fakingunderwater = false; }
sector_t *FakeFlat(sector_t *sec, sector_t *tempsec, int *floorlightlevel, int *ceilinglightlevel, seg_t *backline, int backx1, int backx2, double frontcz1, double frontcz2);
void ClearSeenSprites() { SeenSpriteSectors.clear(); SeenActors.clear(); }
uint32_t GetSubsectorDepth(int index) const { return SubsectorDepths[index]; }
short floorclip[MAXWIDTH];
short ceilingclip[MAXWIDTH];
RenderThread *Thread = nullptr;
private:
void RenderBSPNode(void *node);
void RenderSubsector(subsector_t *sub);
bool CheckBBox(float *bspcoord);
void AddPolyobjs(subsector_t *sub);
void Add3DFloorPlanes(subsector_t *sub, sector_t *frontsector, FDynamicColormap *basecolormap, bool foggy, int adjusted_ceilinglightlevel, int adjusted_floorlightlevel);
void FakeDrawLoop(subsector_t *sub, sector_t *frontsector, VisiblePlane *floorplane, VisiblePlane *ceilingplane, Fake3DOpaque opaque3dfloor);
void Add3DFloorLine(seg_t *line, sector_t *frontsector);
void AddSprites(sector_t *sec, int lightlevel, WaterFakeSide fakeside, bool foggy, FDynamicColormap *basecolormap);
bool IsPotentiallyVisible(AActor *thing);
bool GetThingSprite(AActor *thing, ThingSprite &sprite);
subsector_t *InSubsector = nullptr;
WaterFakeSide FakeSide = WaterFakeSide::Center;
bool r_fakingunderwater = false;
SWRenderLine renderline;
std::set<sector_t*> SeenSpriteSectors;
std::set<AActor*> SeenActors;
std::vector<uint32_t> PvsSubsectors;
std::vector<uint32_t> SubsectorDepths;
};
}