Merge remote-tracking branch 'gzdoom/master'

This commit is contained in:
Magnus Norddahl 2023-10-25 22:25:12 +02:00
commit 4665f8ff79
32 changed files with 365 additions and 154 deletions

View file

@ -318,7 +318,7 @@ else()
if( APPLE )
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.12")
set(CMAKE_OSX_DEPLOYMENT_TARGET "10.13")
if( CMAKE_CXX_COMPILER_ID STREQUAL "GNU" )
# If we're compiling with a custom GCC on the Mac (which we know since g++-4.2 doesn't support C++11) statically link libgcc.
set( ALL_C_FLAGS "-static-libgcc" )

View file

@ -233,6 +233,12 @@ Note: All <bool> fields default to false unless mentioned otherwise.
lm_sampledist_top = <int>; // ZDRay customizable sampling distance for this sidedef's top part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0
lm_sampledist_mid = <int>; // ZDRay customizable sampling distance for this sidedef's middle part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0
lm_sampledist_bot = <int>; // ZDRay customizable sampling distance for this sidedef's bottom part. Defines the map units each lightmap texel covers. Must be in powers of two. Default = 0
skew_top = <int>; // enables skewing of wall textures, the skewing angle will be aligned to one of the 4 planes touching the floor.
skew_middle = <int>; // Vertical texture alignment defines the position at the leftmost point of the wall.
skew_bottom = <int>; // Possible values: 0 = no skewing, 1 = align to front floor, 2 = align to front ceiling, 3 = align to back floor, 4 = align to back ceiling.
// Front/Back are relative to the sidedef, not the owning linedef. Default = 0.
}
sector
@ -542,6 +548,9 @@ Added/updated ZDRay/lightmap-related properties.
1.35 15.09.2023
fixed omissions: Blocklandmonsters and Blockfloaters line flags.
1.36 20.10.2023
Sidedef skewing properties
===============================================================================
EOF
===============================================================================

View file

@ -1,4 +1,5 @@
/*
/*
** serializer.cpp
** Savegame wrapper around RapidJSON
**

View file

@ -17,8 +17,8 @@ public:
virtual VSMatrix GetViewToWorldMatrix() = 0;
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) = 0;
virtual void EndDrawHUDModel(FRenderStyle style) = 0;
virtual void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) = 0;
virtual void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) = 0;
virtual void SetInterpolation(double interpolation) = 0;
virtual void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) = 0;

View file

@ -1892,9 +1892,9 @@ bool G_CheckSaveGameWads (FSerializer &arc, bool printwarn)
bool printRequires = false;
FString text;
arc("Game WAD", text);
text = arc.GetString("Game WAD");
CheckSingleWad (text.GetChars(), printRequires, printwarn);
arc("Map WAD", text);
text = arc.GetString("Map WAD");
CheckSingleWad (text.GetChars(), printRequires, printwarn);
if (printRequires)

View file

@ -1201,6 +1201,15 @@ struct side_t
walltop = 0,
wallbottom = 1,
};
enum ESkew
{
skew_none = 0,
skew_front_floor = 1,
skew_front_ceiling = 2,
skew_back_floor = 3,
skew_back_ceiling = 4
};
struct part
{
enum EPartFlags
@ -1216,7 +1225,8 @@ struct side_t
double xScale;
double yScale;
TObjPtr<DInterpolation*> interpolation;
int flags;
int16_t flags;
int8_t skew;
FTextureID texture;
TextureManipulation TextureFx;
PalEntry SpecialColors[2];

View file

@ -443,11 +443,13 @@ void CommitUMapinfo(level_info_t *defaultinfo)
if (map.partime > 0) levelinfo->partime = map.partime;
if (map.enterpic[0]) levelinfo->EnterPic = map.enterpic;
if (map.exitpic[0]) levelinfo->ExitPic = map.exitpic;
/* UMAPINFO's intermusic is for the text screen, not the summary.
if (map.intermusic[0])
{
levelinfo->InterMusic = map.intermusic;
levelinfo->intermusicorder = 0;
}
*/
if (map.BossActions.Size() > 0 || map.BossCleared)
{
// Setting a boss action will deactivate the flag based monster actions.

View file

@ -82,7 +82,7 @@ struct FBoomTranslator
{
uint16_t FirstLinetype = 0;
uint16_t LastLinetype = 0;
uint8_t NewSpecial = 0;
uint16_t NewSpecial = 0;
TArray<FBoomArg> Args;
} ;

View file

@ -104,6 +104,26 @@ static char HexenSectorSpecialOk[256]={
1,1,1,1,1,
};
#if 0
static const char* udmfsolidskewtypes[] =
{
"none",
"front",
"back",
nullptr
};
static const char* udmfmaskedskewtypes[] =
{
"none",
"front_floor",
"front_ceiling",
"back_floor",
"back_ceiling",
nullptr
};
#endif
static inline bool P_IsThingSpecial(int specnum)
{
return (specnum >= Thing_Projectile && specnum <= Thing_SpawnNoFog) ||
@ -282,6 +302,20 @@ const char *UDMFParserBase::CheckString(FName key)
return parsedString.GetChars();
}
int UDMFParserBase::MatchString(FName key, const char* const* strings, int defval)
{
const char* string = CheckString(key);
for (int i = 0; *strings != nullptr; i++, strings++)
{
if (!stricmp(string, *strings))
{
return i;
}
}
sc.ScriptMessage("Unknown value %s for key '%s'", string, key.GetChars());
return defval;
}
//===========================================================================
//
// Storage of UDMF user properties
@ -1537,6 +1571,38 @@ public:
sd->textures[side_t::bottom].LightmapSampleDistance = CheckInt(key);
break;
#if 0 // specs are to rough and too vague - needs to be cleared first how this works.
case NAME_skew_top_type:
CHECK_N(Zd | Zdt)
sd->textures[side_t::top].skew = MatchString(key, udmfsolidskewtypes, 0);
break;
case NAME_skew_middle_type:
CHECK_N(Zd | Zdt)
sd->textures[side_t::mid].skew = MatchString(key, udmfmaskedskewtypes, 0);
break;
case NAME_skew_bottom_type:
CHECK_N(Zd | Zdt)
sd->textures[side_t::bottom].skew = MatchString(key, udmfsolidskewtypes, 0);
break;
#endif
case NAME_skew_top:
CHECK_N(Zd | Zdt)
sd->textures[side_t::top].skew = CheckInt(key);
break;
case NAME_skew_middle:
CHECK_N(Zd | Zdt)
sd->textures[side_t::mid].skew = CheckInt(key);
break;
case NAME_skew_bottom:
CHECK_N(Zd | Zdt)
sd->textures[side_t::bottom].skew = CheckInt(key);
break;
default:
if (strnicmp("user_", key.GetChars(), 5))
DPrintf(DMSG_WARNING, "Unknown UDMF sidedef key %s\n", key.GetChars());
@ -2262,6 +2328,19 @@ public:
sides[side].sector = &Level->sectors[intptr_t(sides[side].sector)];
lines[line].sidedef[sd] = &sides[side];
#if 0
if (sd == 1)
{
// fix flags for backside. The definition is linedef relative, not sidedef relative.
static const uint8_t swaps[] = { 0, side_t::skew_back, side_t::skew_front };
static const uint8_t swapsm[] = {0, side_t::skew_back_floor, side_t::skew_back_ceiling, side_t::skew_front_floor, side_t::skew_front_ceiling};
sides[side].textures[side_t::top].skew = swaps[sides[side].textures[side_t::top].skew];
sides[side].textures[side_t::bottom].skew = swaps[sides[side].textures[side_t::bottom].skew];
sides[side].textures[side_t::mid].skew = swapsm[sides[side].textures[side_t::mid].skew];
}
#endif
loader->ProcessSideTextures(!isExtended, &sides[side], sides[side].sector, &ParsedSideTextures[mapside],
lines[line].special, lines[line].args[0], &tempalpha[sd], missingTex);

View file

@ -21,6 +21,7 @@ protected:
DAngle CheckAngle(FName key);
bool CheckBool(FName key);
const char *CheckString(FName key);
int MatchString(FName key, const char* const* strings, int defval);
template<typename T>
bool Flag(T &value, int mask, FName key)

View file

@ -858,4 +858,11 @@ xx(lm_sampledist_ceiling)
xx(lm_suncolor)
xx(lm_dynamic)
xx(skew_bottom_type)
xx(skew_middle_type)
xx(skew_top_type)
xx(skew_bottom)
xx(skew_middle)
xx(skew_top)
xx(Corona)

View file

@ -140,6 +140,7 @@ FSerializer &Serialize(FSerializer &arc, const char *key, side_t::part &part, si
("texture", part.texture, def->texture)
("interpolation", part.interpolation)
("flags", part.flags, def->flags)
("skew", part.skew, def->skew)
("color1", part.SpecialColors[0], def->SpecialColors[0])
("color2", part.SpecialColors[1], def->SpecialColors[1])
("addcolor", part.AdditiveColor, def->AdditiveColor)

View file

@ -44,6 +44,7 @@
#include "g_levellocals.h"
#include "actor.h"
#include "texturemanager.h"
#include "vm.h"
//============================================================================
@ -258,6 +259,20 @@ bool P_GetMidTexturePosition(const line_t *line, int sideno, double *ptextop, do
return true;
}
DEFINE_ACTION_FUNCTION(_Line, GetMidTexturePosition)
{
PARAM_SELF_STRUCT_PROLOGUE(line_t);
PARAM_INT(side);
double top = 0.0;
double bottom = 0.0;
bool res = P_GetMidTexturePosition(self,side,&top,&bottom);
if (numret > 2) ret[2].SetFloat(bottom);
if (numret > 1) ret[1].SetFloat(top);
if (numret > 0) ret[0].SetInt(int(res));
return numret;
}
//============================================================================
//
// P_LineOpening_3dMidtex

View file

@ -261,11 +261,11 @@ void RenderHUDModel(FModelRenderer *renderer, DPSprite *psp, FVector3 translatio
float orientation = smf->xscale * smf->yscale * smf->zscale;
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0);
renderer->BeginDrawHUDModel(playermo->RenderStyle, objectToWorldMatrix, orientation < 0, smf);
uint32_t trans = psp->GetTranslation() != 0 ? psp->GetTranslation() : 0;
if ((psp->Flags & PSPF_PLAYERTRANSLATED)) trans = psp->Owner->mo->Translation;
RenderFrameModels(renderer, playermo->Level, smf, psp->GetState(), psp->GetTics(), psp->Caller->modelData != nullptr ? psp->Caller->modelData->modelDef != NAME_None ? PClass::FindActor(psp->Caller->modelData->modelDef) : psp->Caller->GetClass() : psp->Caller->GetClass(), trans, psp->Caller);
renderer->EndDrawHUDModel(playermo->RenderStyle);
renderer->EndDrawHUDModel(playermo->RenderStyle, smf);
}
void RenderFrameModels(FModelRenderer *renderer, FLevelLocals *Level, const FSpriteModelFrame *smf, const FState *curState, const int curTics, const PClass *ti, int translation, AActor* actor)

View file

@ -88,7 +88,7 @@ void FHWModelRenderer::EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf)
state.SetCulling(Cull_None);
}
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored)
void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf)
{
state.SetDepthFunc(DF_LEqual);
state.SetDepthClamp(true);
@ -104,7 +104,7 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
// [BB] In case the model should be rendered translucent, do back face culling.
// This solves a few of the problems caused by the lack of depth sorting.
// TO-DO: Implement proper depth sorting.
if (!(style == DefaultRenderStyle()))
if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES))
{
state.SetCulling((mirrored ^ di->drawctx->portalState.isMirrored()) ? Cull_CW : Cull_CCW);
}
@ -114,13 +114,13 @@ void FHWModelRenderer::BeginDrawHUDModel(FRenderStyle style, const VSMatrix &obj
state.SetModelMatrix(objectToWorldMatrix, normalModelMatrix);
}
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style)
void FHWModelRenderer::EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf)
{
state.SetBoneIndexBase(-1);
state.SetModelMatrix(VSMatrix::identity(), VSMatrix::identity());
state.SetDepthFunc(DF_Less);
if (!(style == DefaultRenderStyle()))
if (!(style == DefaultRenderStyle()) || (smf->flags & MDL_FORCECULLBACKFACES))
state.SetCulling(Cull_None);
}

View file

@ -50,8 +50,8 @@ public:
void EndDrawModel(FRenderStyle style, FSpriteModelFrame *smf) override;
IModelVertexBuffer *CreateVertexBuffer(bool needindex, bool singleframe) override;
VSMatrix GetViewToWorldMatrix() override;
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored) override;
void EndDrawHUDModel(FRenderStyle style) override;
void BeginDrawHUDModel(FRenderStyle style, const VSMatrix &objectToWorldMatrix, bool mirrored, FSpriteModelFrame *smf) override;
void EndDrawHUDModel(FRenderStyle style, FSpriteModelFrame *smf) override;
void SetInterpolation(double interpolation) override;
void SetMaterial(FGameTexture *skin, bool clampNoFilter, int translation) override;
void DrawArrays(int start, int count) override;

View file

@ -35,6 +35,7 @@
#include "hwrenderer/scene/hw_drawinfo.h"
#include "hw_lighting.h"
#include "hw_clock.h"
#include "hw_drawcontext.h"
#include "flatvertices.h"
#include "hw_renderstate.h"
#include "texturemanager.h"
@ -70,7 +71,7 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
else state.AlphaFunc(Alpha_Greater, 0.f);
di->SetColor(state, lightlevel, rellight, di->isFullbrightScene(), Colormap, alpha);
SetColor(state, di->Level, di->lightmode, lightlevel, rellight, di->isFullbrightScene(), Colormap, alpha);
// for additively drawn decals we must temporarily set the fog color to black.
PalEntry fc = state.GetFogColor();
if (decal->RenderStyle.BlendOp == STYLEOP_Add && decal->RenderStyle.DestAlpha == STYLEALPHA_One)
@ -101,9 +102,9 @@ void HWDecal::DrawDecal(HWDrawInfo *di, FRenderState &state)
FColormap thiscm;
thiscm.FadeColor = Colormap.FadeColor;
CopyFrom3DLight(thiscm, &lightlist[k]);
di->SetColor(state, thisll, rellight, di->isFullbrightScene(), thiscm, alpha);
SetColor(state, di->Level, di->lightmode, thisll, rellight, di->isFullbrightScene(), thiscm, alpha);
if (di->Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) thiscm.Decolorize();
di->SetFog(state, thisll, rellight, di->isFullbrightScene(), &thiscm, false);
SetFog(state, di->Level, di->lightmode, thisll, rellight, di->isFullbrightScene(), &thiscm, false, di->drawctx->portalState.inskybox);
SetSplitPlanes(state, lightlist[k].plane, lowplane);
state.Draw(DT_TriangleStrip, vertindex, 4);
@ -142,7 +143,7 @@ void HWDrawInfo::DrawDecals(FRenderState &state, TArray<HWDecal *> &decals)
else
{
state.EnableSplit(false);
SetFog(state, gldecal->lightlevel, gldecal->rellight, isFullbrightScene(), &gldecal->Colormap, false);
SetFog(state, Level, lightmode, gldecal->lightlevel, gldecal->rellight, isFullbrightScene(), &gldecal->Colormap, false, drawctx->portalState.inskybox);
}
}
gldecal->DrawDecal(this, state);
@ -164,7 +165,7 @@ void HWWall::DrawDecalsForMirror(HWDrawInfo *di, FRenderState &state, TArray<HWD
{
state.SetDepthMask(false);
state.SetDepthBias(-1, -128);
di->SetFog(state, lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false);
SetFog(state, di->Level, di->lightmode, lightlevel, rellight + getExtraLight(), di->isFullbrightScene(), &Colormap, false, di->drawctx->portalState.inskybox);
for (auto gldecal : decals)
{
if (gldecal->decal->Side == seg->sidedef)

View file

@ -599,7 +599,7 @@ void HWDrawInfo::DrawCorona(FRenderState& state, AActor* corona, float coronaFad
alpha *= distFade;
state.SetColorAlpha(0xffffff, alpha, 0);
if (isSoftwareLighting()) state.SetSoftLightLevel(255);
if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(255);
else state.SetNoSoftLightLevel();
state.SetLightIndex(-1);

View file

@ -199,13 +199,6 @@ struct HWDrawInfo
void RenderParticles(subsector_t *sub, sector_t *front);
void DoSubsector(subsector_t * sub);
void DrawPSprite(HUDSprite* huds, FRenderState& state);
void SetColor(FRenderState& state, int sectorlightlevel, int rellight, bool fullbright, const FColormap& cm, float alpha, bool weapon = false);
void SetFog(FRenderState& state, int lightlevel, int rellight, bool fullbright, const FColormap* cmap, bool isadditive);
void SetShaderLight(FRenderState& state, float level, float olight);
int CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor);
PalEntry CalcLightColor(int light, PalEntry pe, int blendfactor);
float GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
bool CheckFog(sector_t* frontsector, sector_t* backsector);
WeaponLighting GetWeaponLighting(sector_t* viewsector, const DVector3& pos, int cm, area_t in_area, const DVector3& playerpos);
void PreparePlayerSprites2D(sector_t* viewsector, area_t in_area, FRenderState& state);
@ -334,26 +327,6 @@ public:
HWDecal *AddDecal(bool onmirror);
bool isSoftwareLighting() const
{
return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware || lightmode == ELightMode::Build;
}
bool isBuildSoftwareLighting() const
{
return lightmode == ELightMode::Build;
}
bool isDoomSoftwareLighting() const
{
return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware;
}
bool isDarkLightMode() const
{
return lightmode == ELightMode::Doom || lightmode == ELightMode::DoomDark;
}
void SetFallbackLightMode()
{
lightmode = ELightMode::Doom;
@ -384,3 +357,30 @@ void WriteSavePic(player_t* player, FileWriter* file, int width, int height);
sector_t* RenderView(player_t* player);
inline bool isSoftwareLighting(ELightMode lightmode)
{
return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware || lightmode == ELightMode::Build;
}
inline bool isBuildSoftwareLighting(ELightMode lightmode)
{
return lightmode == ELightMode::Build;
}
inline bool isDoomSoftwareLighting(ELightMode lightmode)
{
return lightmode == ELightMode::ZDoomSoftware || lightmode == ELightMode::DoomSoftware;
}
inline bool isDarkLightMode(ELightMode lightmode)
{
return lightmode == ELightMode::Doom || lightmode == ELightMode::DoomDark;
}
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor);
PalEntry CalcLightColor(ELightMode lightmode, int light, PalEntry pe, int blendfactor);
float GetFogDensity(FLevelLocals* Level, ELightMode lightmode, int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor);
bool CheckFog(FLevelLocals* Level, sector_t* frontsector, sector_t* backsector, ELightMode lightmode);
void SetColor(FRenderState& state, FLevelLocals* Level, ELightMode lightmode, int sectorlightlevel, int rellight, bool fullbright, const FColormap& cm, float alpha, bool weapon = false);
void SetShaderLight(FRenderState& state, FLevelLocals* Level, float level, float olight);
void SetFog(FRenderState& state, FLevelLocals* Level, ELightMode lightmode, int lightlevel, int rellight, bool fullbright, const FColormap* cmap, bool isadditive, bool inskybox);

View file

@ -38,6 +38,7 @@
#include "hw_drawinfo.h"
#include "hw_fakeflat.h"
#include "hw_drawcontext.h"
#include "hw_walldispatcher.h"
//==========================================================================
//
@ -373,8 +374,8 @@ void HWDrawList::SortWallIntoWall(HWDrawInfo *di, FRenderState& state, SortNode
w->zbottom[0]=ws->zbottom[1]=izb;
w->tcs[HWWall::LOLFT].u = w->tcs[HWWall::UPLFT].u = ws->tcs[HWWall::LORGT].u = ws->tcs[HWWall::UPRGT].u = iu;
w->lightuv[HWWall::LOLFT].u = w->lightuv[HWWall::UPLFT].u = ws->lightuv[HWWall::LORGT].u = ws->lightuv[HWWall::UPRGT].u = iu;
ws->MakeVertices(di, state, false);
w->MakeVertices(di, state, false);
ws->MakeVertices(state, false);
w->MakeVertices(state, false);
SortNode * sort2=drawctx->SortNodes.GetNew();
memset(sort2,0,sizeof(SortNode));
@ -722,8 +723,9 @@ void HWDrawList::DoDraw(HWDrawInfo *di, FRenderState &state, bool translucent, i
case DrawType_WALL:
{
HWWall * w= walls[drawitems[i].index];
HWWallDispatcher dis(di);
RenderWall.Clock();
w->DrawWall(di, state, translucent);
w->DrawWall(&dis, state, translucent);
RenderWall.Unclock();
}
break;
@ -759,10 +761,11 @@ void HWDrawList::Draw(HWDrawInfo *di, FRenderState &state, bool translucent)
//==========================================================================
void HWDrawList::DrawWalls(HWDrawInfo *di, FRenderState &state, bool translucent)
{
HWWallDispatcher dis(di);
RenderWall.Clock();
for (auto &item : drawitems)
{
walls[item.index]->DrawWall(di, state, translucent);
walls[item.index]->DrawWall(&dis, state, translucent);
}
RenderWall.Unclock();
}

View file

@ -80,7 +80,7 @@ void HWDrawInfo::AddMirrorSurface(HWWall *w, FRenderState& state)
auto tcs = newwall->tcs;
tcs[HWWall::LOLFT].u = tcs[HWWall::LORGT].u = tcs[HWWall::UPLFT].u = tcs[HWWall::UPRGT].u = v.X;
tcs[HWWall::LOLFT].v = tcs[HWWall::LORGT].v = tcs[HWWall::UPLFT].v = tcs[HWWall::UPRGT].v = v.Z;
newwall->MakeVertices(this, state, false);
newwall->MakeVertices(state, false);
bool hasDecals = newwall->seg->sidedef && newwall->seg->sidedef->AttachedDecals;
if (hasDecals && Level->HasDynamicLights && !isFullbrightScene())

View file

@ -226,7 +226,7 @@ public:
void SetupLights(HWDrawInfo* di, FRenderState& state, FDynLightData& lightdata);
void MakeVertices(HWDrawInfo* di, FRenderState& state, bool nosplit);
void MakeVertices(FRenderState& state, bool nosplit);
void SkyPlane(HWWallDispatcher* di, FRenderState& state, sector_t* sector, int plane, bool allowmirror);
void SkyLine(HWWallDispatcher* di, FRenderState& state, sector_t* sec, line_t* line);
@ -237,19 +237,19 @@ public:
bool DoHorizon(HWWallDispatcher* di, FRenderState& state, seg_t* seg, sector_t* fs, vertex_t* v1, vertex_t* v2);
bool SetWallCoordinates(seg_t* seg, FTexCoordInfo* tci, float ceilingrefheight,
float topleft, float topright, float bottomleft, float bottomright, float t_ofs);
float topleft, float topright, float bottomleft, float bottomright, float t_ofs, float skew);
void DoTexture(HWWallDispatcher* di, FRenderState& state, int type, seg_t* seg, int peg,
float ceilingrefheight, float floorrefheight,
float CeilingHeightstart, float CeilingHeightend,
float FloorHeightstart, float FloorHeightend,
float v_offset);
float v_offset, float skew);
void DoMidTexture(HWWallDispatcher* di, FRenderState& state, seg_t* seg, bool drawfogboundary,
sector_t* front, sector_t* back,
sector_t* realfront, sector_t* realback,
float fch1, float fch2, float ffh1, float ffh2,
float bch1, float bch2, float bfh1, float bfh2, float zalign);
float bch1, float bch2, float bfh1, float bfh2, float zalign, float skew);
void GetPlanePos(F3DFloor::planeref* planeref, float& left, float& right);
@ -280,11 +280,11 @@ public:
int CountVertices();
void RenderWall(HWDrawInfo* di, FRenderState& state, int textured);
void RenderFogBoundary(HWDrawInfo* di, FRenderState& state);
void RenderMirrorSurface(HWDrawInfo* di, FRenderState& state);
void RenderTexturedWall(HWDrawInfo* di, FRenderState& state, int rflags);
void RenderTranslucentWall(HWDrawInfo* di, FRenderState& state);
void RenderWall(FRenderState& state, int textured);
void RenderFogBoundary(HWWallDispatcher* di, FRenderState& state);
void RenderMirrorSurface(HWWallDispatcher* di, FRenderState& state);
void RenderTexturedWall(HWWallDispatcher* di, FRenderState& state, int rflags);
void RenderTranslucentWall(HWWallDispatcher* di, FRenderState& state);
void DrawDecalsForMirror(HWDrawInfo* di, FRenderState& state, TArray<HWDecal*>& decals);
public:
@ -296,7 +296,7 @@ public:
return -((y - glseg.y1) * (glseg.x2 - glseg.x1) - (x - glseg.x1) * (glseg.y2 - glseg.y1));
}
void DrawWall(HWDrawInfo* di, FRenderState& state, bool translucent);
void DrawWall(HWWallDispatcher* di, FRenderState& state, bool translucent);
};

View file

@ -41,6 +41,7 @@
#include "hw_clock.h"
#include "hw_lighting.h"
#include "hw_material.h"
#include "hw_drawcontext.h"
#include "hwrenderer/scene/hw_drawinfo.h"
#include "flatvertices.h"
#include "hw_drawstructs.h"
@ -321,8 +322,8 @@ void HWFlat::DrawFlat(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetNormal(plane.plane.Normal().X, plane.plane.Normal().Z, plane.plane.Normal().Y);
di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, alpha);
di->SetFog(state, lightlevel, rel, di->isFullbrightScene(), &Colormap, false);
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->drawctx->portalState.inskybox);
state.SetObjectColor(FlatColor | 0xff000000);
state.SetAddColor(AddColor | 0xff000000);
state.ApplyTextureManipulation(TextureFx);

View file

@ -76,13 +76,13 @@ CUSTOM_CVAR(Int, gl_distfog, 70, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
//
//==========================================================================
int HWDrawInfo::CalcLightLevel(int lightlevel, int rellight, bool weapon, int blendfactor)
int CalcLightLevel(ELightMode lightmode, int lightlevel, int rellight, bool weapon, int blendfactor)
{
int light;
if (lightlevel <= 0) return 0;
bool darklightmode = (isDarkLightMode()) || (isSoftwareLighting() && blendfactor > 0);
bool darklightmode = (isDarkLightMode(lightmode)) || (isSoftwareLighting(lightmode) && blendfactor > 0);
if (darklightmode && lightlevel < 192 && !weapon)
{
@ -119,13 +119,13 @@ int HWDrawInfo::CalcLightLevel(int lightlevel, int rellight, bool weapon, int bl
//
//==========================================================================
PalEntry HWDrawInfo::CalcLightColor(int light, PalEntry pe, int blendfactor)
PalEntry CalcLightColor(ELightMode lightmode, int light, PalEntry pe, int blendfactor)
{
int r,g,b;
if (blendfactor == 0)
{
if (isSoftwareLighting())
if (isSoftwareLighting(lightmode))
{
return pe;
}
@ -165,12 +165,12 @@ PalEntry HWDrawInfo::CalcLightColor(int light, PalEntry pe, int blendfactor)
//
//==========================================================================
float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor)
float GetFogDensity(FLevelLocals* Level, ELightMode lightmode, int lightlevel, PalEntry fogcolor, int sectorfogdensity, int blendfactor)
{
float density;
auto oldlightmode = lightmode;
if (isSoftwareLighting() && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting.
if (isSoftwareLighting(lightmode) && blendfactor > 0) lightmode = ELightMode::Doom; // The blendfactor feature does not work with software-style lighting.
if (lightmode == ELightMode::DoomLegacy)
{
@ -185,7 +185,7 @@ float HWDrawInfo::GetFogDensity(int lightlevel, PalEntry fogcolor, int sectorfog
else if ((fogcolor.d & 0xffffff) == 0)
{
// case 2: black fog
if ((!isDoomSoftwareLighting() || blendfactor > 0) && !(Level->flags3 & LEVEL3_NOLIGHTFADE))
if ((!isDoomSoftwareLighting(lightmode) || blendfactor > 0) && !(Level->flags3 & LEVEL3_NOLIGHTFADE))
{
density = distfogtable[lightmode != ELightMode::LinearStandard][hw_ClampLight(lightlevel)];
}

View file

@ -36,6 +36,7 @@
#include "flatvertices.h"
#include "hw_clock.h"
#include "hw_lighting.h"
#include "hw_drawcontext.h"
#include "texturemanager.h"
EXTERN_CVAR(Int, r_mirror_recursions)
@ -969,14 +970,14 @@ void HWHorizonPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
if (texture->isFullbright())
{
// glowing textures are always drawn full bright without color
di->SetColor(state, 255, 0, false, origin->colormap, 1.f);
di->SetFog(state, 255, 0, false, &origin->colormap, false);
SetColor(state, di->Level, di->lightmode, 255, 0, false, origin->colormap, 1.f);
SetFog(state, di->Level, di->lightmode, 255, 0, false, &origin->colormap, false, di->drawctx->portalState.inskybox);
}
else
{
int rel = getExtraLight();
di->SetColor(state, origin->lightlevel, rel, di->isFullbrightScene(), origin->colormap, 1.0f);
di->SetFog(state, origin->lightlevel, rel, di->isFullbrightScene(), &origin->colormap, false);
SetColor(state, di->Level, di->lightmode, origin->lightlevel, rel, di->isFullbrightScene(), origin->colormap, 1.0f);
SetFog(state, di->Level, di->lightmode, origin->lightlevel, rel, di->isFullbrightScene(), &origin->colormap, false, di->drawctx->portalState.inskybox);
}

View file

@ -38,20 +38,20 @@
// set current light color
//
//==========================================================================
void HWDrawInfo::SetColor(FRenderState &state, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon)
void SetColor(FRenderState &state, FLevelLocals* Level, ELightMode lightmode, int sectorlightlevel, int rellight, bool fullbright, const FColormap &cm, float alpha, bool weapon)
{
if (fullbright)
{
state.SetColorAlpha(0xffffff, alpha, 0);
if (isSoftwareLighting()) state.SetSoftLightLevel(255);
if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(255);
else state.SetNoSoftLightLevel();
}
else
{
int hwlightlevel = CalcLightLevel(sectorlightlevel, rellight, weapon, cm.BlendFactor);
PalEntry pe = CalcLightColor(hwlightlevel, cm.LightColor, cm.BlendFactor);
int hwlightlevel = CalcLightLevel(lightmode, sectorlightlevel, rellight, weapon, cm.BlendFactor);
PalEntry pe = CalcLightColor(lightmode, hwlightlevel, cm.LightColor, cm.BlendFactor);
state.SetColorAlpha(pe, alpha, cm.Desaturation);
if (isSoftwareLighting()) state.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight), cm.BlendFactor);
if (isSoftwareLighting(lightmode)) state.SetSoftLightLevel(hw_ClampLight(sectorlightlevel + rellight), cm.BlendFactor);
else state.SetNoSoftLightLevel();
}
}
@ -62,7 +62,7 @@ void HWDrawInfo::SetColor(FRenderState &state, int sectorlightlevel, int relligh
//
//==========================================================================
void HWDrawInfo::SetShaderLight(FRenderState &state, float level, float olight)
void SetShaderLight(FRenderState &state, FLevelLocals* Level, float level, float olight)
{
const float MAXDIST = 256.f;
const float THRESHOLD = 96.f;
@ -96,7 +96,7 @@ void HWDrawInfo::SetShaderLight(FRenderState &state, float level, float olight)
//
//==========================================================================
void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive)
void SetFog(FRenderState &state, FLevelLocals* Level, ELightMode lightmode, int lightlevel, int rellight, bool fullbright, const FColormap *cmap, bool isadditive, bool inskybox)
{
PalEntry fogcolor;
float fogdensity;
@ -109,7 +109,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool
else if (cmap != nullptr && !fullbright)
{
fogcolor = cmap->FadeColor;
fogdensity = GetFogDensity(lightlevel, fogcolor, cmap->FogDensity, cmap->BlendFactor);
fogdensity = GetFogDensity(Level, lightmode, lightlevel, fogcolor, cmap->FogDensity, cmap->BlendFactor);
fogcolor.a = 0;
}
else
@ -119,7 +119,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool
}
// Make fog a little denser when inside a skybox
if (drawctx->portalState.inskybox) fogdensity += fogdensity / 2;
if (inskybox) fogdensity += fogdensity / 2;
// no fog in enhanced vision modes!
@ -130,10 +130,10 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool
}
else
{
if ((lightmode == ELightMode::Doom || (isSoftwareLighting() && cmap && cmap->BlendFactor > 0)) && fogcolor == 0)
if ((lightmode == ELightMode::Doom || (isSoftwareLighting(lightmode) && cmap && cmap->BlendFactor > 0)) && fogcolor == 0)
{
float light = (float)CalcLightLevel(lightlevel, rellight, false, cmap->BlendFactor);
SetShaderLight(state, light, lightlevel);
float light = (float)CalcLightLevel(lightmode, lightlevel, rellight, false, cmap->BlendFactor);
SetShaderLight(state, Level, light, lightlevel);
}
else if (lightmode == ELightMode::Build)
{
@ -155,7 +155,7 @@ void HWDrawInfo::SetFog(FRenderState &state, int lightlevel, int rellight, bool
state.SetFog(fogcolor, fogdensity);
// Korshun: fullbright fog like in software renderer.
if (isSoftwareLighting() && cmap && cmap->BlendFactor == 0 && Level->brightfog && fogdensity != 0 && fogcolor != 0)
if (isSoftwareLighting(lightmode) && cmap && cmap->BlendFactor == 0 && Level->brightfog && fogdensity != 0 && fogcolor != 0)
{
state.SetSoftLightLevel(255);
}

View file

@ -43,7 +43,7 @@ void HWSkyPortal::DrawContents(HWDrawInfo *di, FRenderState &state)
// We have no use for Doom lighting special handling here, so disable it for this function.
auto oldlightmode = di->lightmode;
if (di->isSoftwareLighting())
if (isSoftwareLighting(oldlightmode))
{
di->SetFallbackLightMode();
state.SetNoSoftLightLevel();

View file

@ -56,6 +56,7 @@
#include "hw_material.h"
#include "hw_dynlightdata.h"
#include "hw_renderstate.h"
#include "hw_drawcontext.h"
extern TArray<spritedef_t> sprites;
extern TArray<spriteframe_t> SpriteFrames;
@ -144,7 +145,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
if (!Colormap.FadeColor.isBlack())
{
float dist = Dist2(vp.Pos.X, vp.Pos.Y, x, y);
int fogd = di->GetFogDensity(lightlevel, Colormap.FadeColor, Colormap.FogDensity, Colormap.BlendFactor);
int fogd = GetFogDensity(di->Level, di->lightmode, lightlevel, Colormap.FadeColor, Colormap.FogDensity, Colormap.BlendFactor);
// this value was determined by trial and error and is scale dependent!
float factor = 0.05f + exp(-fogd * dist / 62500.f);
@ -189,7 +190,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetObjectColor(finalcol);
state.SetAddColor(cursec->AdditiveColors[sector_t::sprites] | 0xff000000);
}
di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, trans);
SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, trans);
}
@ -216,7 +217,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
else RenderStyle.BlendOp = STYLEOP_Fuzz; // subtractive with models is not going to work.
}
if (!foglayer) di->SetFog(state, foglevel, rel, di->isFullbrightScene(), &Colormap, additivefog);
if (!foglayer) SetFog(state, di->Level, di->lightmode, foglevel, rel, di->isFullbrightScene(), &Colormap, additivefog, di->drawctx->portalState.inskybox);
else
{
state.EnableFog(false);
@ -257,10 +258,10 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
thiscm.Decolorize();
}
di->SetColor(state, thisll, rel, di->isFullbrightScene(), thiscm, trans);
SetColor(state, di->Level, di->lightmode, thisll, rel, di->isFullbrightScene(), thiscm, trans);
if (!foglayer)
{
di->SetFog(state, thislight, rel, di->isFullbrightScene(), &thiscm, additivefog);
SetFog(state, di->Level, di->lightmode, thislight, rel, di->isFullbrightScene(), &thiscm, additivefog, di->drawctx->portalState.inskybox);
}
SetSplitPlanes(state, *topplane, *lowplane);
}
@ -285,7 +286,7 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
if (foglayer)
{
// If we get here we know that we have colored fog and no fixed colormap.
di->SetFog(state, foglevel, rel, false, &Colormap, additivefog);
SetFog(state, di->Level, di->lightmode, foglevel, rel, false, &Colormap, additivefog, di->drawctx->portalState.inskybox);
state.SetTextureMode(TM_FOGLAYER);
state.SetRenderStyle(STYLE_Translucent);
state.Draw(DT_TriangleStrip, vertexindex, 4);
@ -347,8 +348,8 @@ void HWSprite::DrawSprite(HWDrawInfo *di, FRenderState &state, bool translucent)
state.SetDynLight(0, 0, 0);
state.SetRenderStyle(STYLE_Normal);
state.SetTextureMode(TM_NORMAL);
di->SetFog(state, 0, 0, false, &Colormap, true);
di->SetColor(state, 255, 0, true, Colormap, true);
SetFog(state, di->Level, di->lightmode, 0, 0, false, &Colormap, true, di->drawctx->portalState.inskybox);
SetColor(state, di->Level, di->lightmode, 255, 0, true, Colormap, true);
state.EnableTexture(false);
int scales[12][6] =

View file

@ -82,7 +82,7 @@ void SetSplitPlanes(FRenderState& state, const secplane_t& top, const secplane_t
//
//==========================================================================
void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured)
void HWWall::RenderWall(FRenderState &state, int textured)
{
assert(vertcount > 0);
state.SetLightIndex(dynlightindex);
@ -96,17 +96,17 @@ void HWWall::RenderWall(HWDrawInfo*di, FRenderState &state, int textured)
//
//==========================================================================
void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state)
void HWWall::RenderFogBoundary(HWWallDispatcher*di, FRenderState &state)
{
if (gl_fogmode && !di->isFullbrightScene())
{
int rel = rellight + getExtraLight();
state.EnableDrawBufferAttachments(false);
di->SetFog(state, lightlevel, rel, false, &Colormap, false);
SetFog(state, di->Level, di->lightmode, lightlevel, rel, false, &Colormap, false, di->di ? di->di->drawctx->portalState.inskybox : false);
state.SetEffect(EFF_FOGBOUNDARY);
state.AlphaFunc(Alpha_GEqual, 0.f);
state.SetDepthBias(-1, -128);
RenderWall(di, state, HWWall::RWF_BLANK);
RenderWall(state, HWWall::RWF_BLANK);
state.ClearDepthBias();
state.SetEffect(EFF_NONE);
state.EnableDrawBufferAttachments(true);
@ -119,7 +119,7 @@ void HWWall::RenderFogBoundary(HWDrawInfo*di, FRenderState &state)
//
//
//==========================================================================
void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state)
void HWWall::RenderMirrorSurface(HWWallDispatcher*di, FRenderState &state)
{
if (!TexMan.mirrorTexture.isValid()) return;
@ -127,8 +127,8 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state)
// Use sphere mapping for this
state.SetEffect(EFF_SPHEREMAP);
di->SetColor(state, lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f);
di->SetFog(state, lightlevel, 0, di->isFullbrightScene(), &Colormap, true);
SetColor(state, di->Level, di->lightmode, lightlevel, 0, di->isFullbrightScene(), Colormap, 0.1f);
SetFog(state, di->Level, di->lightmode, lightlevel, 0, di->isFullbrightScene(), &Colormap, true, di->di ? di->di->drawctx->portalState.inskybox : false);
state.SetRenderStyle(STYLE_Add);
state.AlphaFunc(Alpha_Greater, 0);
@ -136,7 +136,7 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state)
state.SetMaterial(tex, UF_None, 0, CLAMP_NONE, 0, -1); // do not upscale the mirror texture.
flags &= ~HWWall::HWF_GLOW;
RenderWall(di, state, HWWall::RWF_BLANK);
RenderWall(state, HWWall::RWF_BLANK);
state.SetTextureMatrix(VSMatrix::identity());
state.SetEffect(EFF_NONE);
@ -147,9 +147,9 @@ void HWWall::RenderMirrorSurface(HWDrawInfo*di, FRenderState &state)
// This is drawn in the translucent pass which is done after the decal pass
// As a result the decals have to be drawn here, right after the wall they are on,
// because the depth buffer won't get set by translucent items.
if (seg->sidedef->AttachedDecals)
if (di->di && seg->sidedef->AttachedDecals)
{
DrawDecalsForMirror(di, state, di->Decals[1]);
DrawDecalsForMirror(di->di, state, di->di->Decals[1]);
}
state.SetRenderStyle(STYLE_Translucent);
}
@ -178,7 +178,7 @@ static const uint8_t renderwalltotier[] =
CVAR(Bool, hw_npottest, false, 0)
#endif
void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
void HWWall::RenderTexturedWall(HWWallDispatcher*di, FRenderState &state, int rflags)
{
int tmode = state.GetTextureMode();
int rel = rellight + getExtraLight();
@ -214,7 +214,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
if (type == RENDERWALL_M2SNF)
{
di->SetFog(state, 255, 0, di->isFullbrightScene(), nullptr, false);
SetFog(state, di->Level, di->lightmode, 255, 0, di->isFullbrightScene(), nullptr, false, di->di ? di->di->drawctx->portalState.inskybox : false);
}
if (type != RENDERWALL_COLOR && seg->sidedef != nullptr)
{
@ -262,9 +262,9 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
float absalpha = fabsf(alpha);
if (lightlist == nullptr)
{
if (type != RENDERWALL_M2SNF) di->SetFog(state, lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add);
di->SetColor(state, lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha);
RenderWall(di, state, rflags);
if (type != RENDERWALL_M2SNF) SetFog(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), &Colormap, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false);
SetColor(state, di->Level, di->lightmode, lightlevel, rel, di->isFullbrightScene(), Colormap, absalpha);
RenderWall(state, rflags);
}
else
{
@ -284,10 +284,10 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
thiscm.FadeColor = Colormap.FadeColor;
thiscm.FogDensity = Colormap.FogDensity;
CopyFrom3DLight(thiscm, &(*lightlist)[i]);
di->SetColor(state, thisll, rel, false, thiscm, absalpha);
if (type != RENDERWALL_M2SNF) di->SetFog(state, thisll, rel, false, &thiscm, RenderStyle == STYLE_Add);
SetColor(state, di->Level, di->lightmode, thisll, rel, false, thiscm, absalpha);
if (type != RENDERWALL_M2SNF) SetFog(state, di->Level, di->lightmode, thisll, rel, false, &thiscm, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false);
SetSplitPlanes(state, (*lightlist)[i].plane, lowplane);
RenderWall(di, state, rflags);
RenderWall(state, rflags);
}
if (low1 <= zbottom[0] && low2 <= zbottom[1]) break;
}
@ -311,7 +311,7 @@ void HWWall::RenderTexturedWall(HWDrawInfo*di, FRenderState &state, int rflags)
//
//==========================================================================
void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state)
void HWWall::RenderTranslucentWall(HWWallDispatcher*di, FRenderState &state)
{
state.SetRenderStyle(RenderStyle);
if (texture)
@ -323,10 +323,10 @@ void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state)
else
{
state.AlphaFunc(Alpha_GEqual, 0.f);
di->SetColor(state, lightlevel, 0, false, Colormap, fabsf(alpha));
di->SetFog(state, lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add);
SetColor(state, di->Level, di->lightmode, lightlevel, 0, false, Colormap, fabsf(alpha));
SetFog(state, di->Level, di->lightmode, lightlevel, 0, false, &Colormap, RenderStyle == STYLE_Add, di->di ? di->di->drawctx->portalState.inskybox : false);
state.EnableTexture(false);
RenderWall(di, state, HWWall::RWF_NOSPLIT);
RenderWall(state, HWWall::RWF_NOSPLIT);
state.EnableTexture(true);
}
state.SetRenderStyle(STYLE_Translucent);
@ -337,13 +337,13 @@ void HWWall::RenderTranslucentWall(HWDrawInfo*di, FRenderState &state)
//
//
//==========================================================================
void HWWall::DrawWall(HWDrawInfo*di, FRenderState &state, bool translucent)
void HWWall::DrawWall(HWWallDispatcher*di, FRenderState &state, bool translucent)
{
if (di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
if (di->di && di->Level->HasDynamicLights && !di->isFullbrightScene() && texture != nullptr)
{
SetupLights(di, state, lightdata);
SetupLights(di->di, state, lightdata);
}
MakeVertices(di, state, !!(flags & HWWall::HWF_TRANSLUCENT));
MakeVertices(state, !!(flags & HWWall::HWF_TRANSLUCENT));
state.SetNormal(glseg.Normal());
if (!translucent)
@ -567,7 +567,7 @@ void HWWall::PutPortal(HWWallDispatcher *di, FRenderState& state, int ptype, int
auto ddi = di->di;
if (ddi)
{
MakeVertices(ddi, state, false);
MakeVertices(state, false);
switch (ptype)
{
// portals don't go into the draw list.
@ -893,7 +893,7 @@ static float ZeroLightmapUVs[8] = { 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.0f, 0.
//
//==========================================================================
bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float texturetop,
float topleft, float topright, float bottomleft, float bottomright, float t_ofs)
float topleft, float topright, float bottomleft, float bottomright, float t_ofs, float skew)
{
//
//
@ -986,8 +986,8 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
if (tci)
{
tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop);
tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop + skew);
tcs[LORGT].v = tci->FloatToTexV(-zbottom[1] + texturetop + skew);
}
lightuv[UPRGT].v = srclightuv[UPRGT].v;
@ -1009,7 +1009,7 @@ bool HWWall::SetWallCoordinates(seg_t * seg, FTexCoordInfo *tci, float textureto
zbottom[1] = ztop[1] = inter_y;
if (tci)
{
tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop);
tcs[LORGT].v = tcs[UPRGT].v = tci->FloatToTexV(-ztop[1] + texturetop + skew);
}
lightuv[UPRGT].v = srclightuv[UPRGT].v + inter_x * (srclightuv[UPRGT].v - srclightuv[UPLFT].v);
@ -1135,7 +1135,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_
float ceilingrefheight,float floorrefheight,
float topleft,float topright,
float bottomleft,float bottomright,
float v_offset)
float v_offset, float skew)
{
if (topleft<=bottomleft && topright<=bottomright) return;
@ -1181,7 +1181,7 @@ void HWWall::DoTexture(HWWallDispatcher *di, FRenderState& state, int _type,seg_
if (peg) floatceilingref += tci.mRenderHeight - flh - v_offset;
if (!SetWallCoordinates(seg, &tci, floatceilingref, topleft, topright, bottomleft, bottomright,
seg->sidedef->GetTextureXOffset(texpos))) return;
seg->sidedef->GetTextureXOffset(texpos), skew)) return;
if (seg->linedef->special == Line_Mirror && _type == RENDERWALL_M1S && gl_mirrors && !(di->Level->ib_compatflags & BCOMPATF_NOMIRRORS))
{
@ -1213,7 +1213,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
sector_t * front, sector_t * back,
sector_t * realfront, sector_t * realback,
float fch1, float fch2, float ffh1, float ffh2,
float bch1, float bch2, float bfh1, float bfh2, float zalign)
float bch1, float bch2, float bfh1, float bfh2, float zalign, float skew)
{
FTexCoordInfo tci;
@ -1339,10 +1339,10 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
// if we don't need a fog sheet let's clip away some unnecessary parts of the polygon
//
//
if (!drawfogboundary && !wrap)
if (!drawfogboundary && !wrap && skew == 0)
{
if (texturetop<topleft && texturetop<topright) topleft=topright=texturetop;
if (texturebottom>bottomleft && texturebottom>bottomright) bottomleft=bottomright=texturebottom;
if (texturetop < topleft && texturetop < topright) topleft = topright = texturetop;
if (texturebottom > bottomleft && texturebottom > bottomright) bottomleft = bottomright = texturebottom;
}
}
else
@ -1355,8 +1355,10 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
// unwanted side effects.
//
//
topleft=topright=texturetop;
bottomleft=bottomright=texturebottom;
topleft = texturetop;
topright = texturetop + skew;
bottomleft = texturebottom;
bottomright = texturebottom + skew;
}
// nothing visible - skip the rest
@ -1419,7 +1421,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
// mid textures on portal lines need the same offsetting as mid textures on sky lines
flags |= HWF_SKYHACK;
}
SetWallCoordinates(seg, &tci, texturetop, topleft, topright, bottomleft, bottomright, t_ofs);
SetWallCoordinates(seg, &tci, texturetop, topleft, topright, bottomleft, bottomright, t_ofs, skew);
//
//
@ -1478,7 +1480,7 @@ void HWWall::DoMidTexture(HWWallDispatcher *di, FRenderState& state, seg_t * seg
FloatRect *splitrect;
int v = texture->GetAreas(&splitrect);
if (seg->frontsector == seg->backsector) flags |= HWF_NOSPLIT; // we don't need to do vertex splits if a line has both sides in the same sector
if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX) && !(flags & HWF_NOSLICE))
if (v>0 && !drawfogboundary && !(seg->linedef->flags&ML_WRAP_MIDTEX) && !(flags & HWF_NOSLICE) && skew == 0)
{
// split the poly!
int i,t=0;
@ -1934,6 +1936,10 @@ inline int CalcRelLight(int lightlevel, int orglightlevel, int rel)
}
}
CVAR(Int, topskew, 0, 0)
CVAR(Int, midskew, 0, 0)
CVAR(Int, bottomskew, 0, 0)
//==========================================================================
//
//
@ -2090,9 +2096,14 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::mid), true);
if (texture && texture->isValid())
{
int skewflag = seg->sidedef->textures[side_t::mid].skew;
if (skewflag == 0) skewflag = midskew;
float skew =
skewflag == side_t::skew_front_ceiling ? fch2 - fch1 :
skewflag == side_t::skew_front_floor ? ffh2 - ffh1 : 0.;
DoTexture(di, state, RENDERWALL_M1S, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
crefz, frefz, // must come from the original!
fch1, fch2, ffh1, ffh2, 0);
fch1, fch2, ffh1, ffh2, 0, skew);
}
}
}
@ -2160,9 +2171,31 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::top), true);
if (texture && texture->isValid())
{
int skewflag = seg->sidedef->textures[side_t::top].skew;
float skew;
if (skewflag == 0) skewflag = topskew;
switch (skewflag)
{
default:
skew = 0;
break;
case side_t::skew_front_ceiling:
skew = fch2 - fch1;
break;
case side_t::skew_back_ceiling:
skew = bch2 - bch1;
break;
case side_t::skew_front_floor:
skew = bfh2 - bfh1;
break;
case side_t::skew_back_floor:
skew = ffh2 - ffh1;
break;
}
DoTexture(di, state, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
crefz, realback->GetPlaneTexZ(sector_t::ceiling),
fch1, fch2, bch1a, bch2a, 0);
fch1, fch2, bch1a, bch2a, 0, skew);
}
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
{
@ -2175,7 +2208,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
{
DoTexture(di, state, RENDERWALL_TOP, seg, (seg->linedef->flags & (ML_DONTPEGTOP)) == 0,
crefz, realback->GetPlaneTexZ(sector_t::ceiling),
fch1, fch2, bch1a, bch2a, 0);
fch1, fch2, bch1a, bch2a, 0, 0);
}
}
else
@ -2210,6 +2243,28 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
lightlevel = hw_ClampLight(seg->sidedef->GetLightLevel(foggy, orglightlevel, side_t::mid, false, &rel));
rellight = CalcRelLight(lightlevel, orglightlevel, rel);
float skew;
int skewflag = seg->sidedef->textures[side_t::mid].skew;
if (skewflag == 0) skewflag = midskew;
switch (skewflag)
{
default:
skew = 0;
break;
case side_t::skew_front_ceiling:
skew = fch2 - fch1;
break;
case side_t::skew_back_ceiling:
skew = bch2 - bch1;
break;
case side_t::skew_front_floor:
skew = bfh2 - bfh1;
break;
case side_t::skew_back_floor:
skew = ffh2 - ffh1;
break;
}
if (isportal)
{
lineportal = seg->linedef->getPortal()->mGroup;
@ -2222,7 +2277,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
if (texture && seg->backsector != nullptr)
{
DoMidTexture(di, state, seg, drawfogboundary, frontsector, backsector, realfront, realback,
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign);
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign, skew);
}
}
else
@ -2231,7 +2286,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
if (texture || drawfogboundary)
{
DoMidTexture(di, state, seg, drawfogboundary, frontsector, backsector, realfront, realback,
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign);
fch1, fch2, ffh1, ffh2, bch1, bch2, bfh1, bfh2, zalign, skew);
}
if (backsector->e->XFloor.ffloors.Size() || frontsector->e->XFloor.ffloors.Size())
@ -2244,6 +2299,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
/* bottom texture */
// the back sector's ceiling obstructs part of this wall (specially important for sky sectors)
float bfh1a = bch1, bfh2a = bch2;
if (fch1 < bfh1 && fch2 < bfh2 && (seg->linedef->flags & ML_DRAWFULLHEIGHT) == 0)
{
bfh1 = fch1;
@ -2257,12 +2313,34 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
texture = TexMan.GetGameTexture(seg->sidedef->GetTexture(side_t::bottom), true);
if (texture && texture->isValid())
{
int skewflag = seg->sidedef->textures[side_t::bottom].skew;
if (skewflag == 0) skewflag = bottomskew;
float skew;
switch (skewflag)
{
default:
skew = 0;
break;
case side_t::skew_front_ceiling:
skew = fch2 - fch1;
break;
case side_t::skew_back_ceiling:
skew = bch2 - bch1;
break;
case side_t::skew_front_floor:
skew = bfh2a - bfh1a;
break;
case side_t::skew_back_floor:
skew = ffh2 - ffh1;
break;
}
DoTexture(di, state, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
realback->GetPlaneTexZ(sector_t::floor), frefz,
bfh1, bfh2, ffh1, ffh2,
frontsector->GetTexture(sector_t::ceiling) == skyflatnum && backsector->GetTexture(sector_t::ceiling) == skyflatnum ?
frefz - realback->GetPlaneTexZ(sector_t::ceiling) :
frefz - crefz);
frefz - crefz, skew);
}
else if (!(seg->sidedef->Flags & WALLF_POLYOBJ))
{
@ -2278,7 +2356,7 @@ void HWWall::Process(HWWallDispatcher *di, FRenderState& state, seg_t *seg, sect
{
DoTexture(di, state, RENDERWALL_BOTTOM, seg, (seg->linedef->flags & ML_DONTPEGBOTTOM) > 0,
realback->GetPlaneTexZ(sector_t::floor), frefz,
bfh1, bfh2, ffh1, ffh2, frefz - crefz);
bfh1, bfh2, ffh1, ffh2, frefz - crefz, 0);
}
}
else if (backsector->GetTexture(sector_t::floor) != skyflatnum)
@ -2350,7 +2428,7 @@ void HWWall::ProcessLowerMiniseg(HWWallDispatcher *di, FRenderState& state, seg_
FTexCoordInfo tci;
type = RENDERWALL_BOTTOM;
tci.GetFromTexture(texture, 1, 1, false);
SetWallCoordinates(seg, &tci, bfh, bfh, bfh, ffh, ffh, 0);
SetWallCoordinates(seg, &tci, bfh, bfh, bfh, ffh, ffh, 0, 0);
PutWall(di, state, false);
}
}

View file

@ -283,7 +283,7 @@ int HWWall::CountVertices()
//
//==========================================================================
void HWWall::MakeVertices(HWDrawInfo *di, FRenderState& state, bool nosplit)
void HWWall::MakeVertices(FRenderState& state, bool nosplit)
{
if (vertcount == 0)
{

View file

@ -68,7 +68,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
}
else
{
SetColor(state, huds->lightlevel, 0, isFullbrightScene(), huds->cm, huds->alpha, true);
SetColor(state, Level, lightmode, huds->lightlevel, 0, isFullbrightScene(), huds->cm, huds->alpha, true);
}
state.SetLightIndex(-1);
state.SetRenderStyle(huds->RenderStyle);
@ -120,7 +120,7 @@ void HWDrawInfo::DrawPSprite(HUDSprite *huds, FRenderState &state)
void HWDrawInfo::DrawPlayerSprites(bool hudModelStep, FRenderState &state)
{
auto oldlightmode = lightmode;
if (!hudModelStep && isSoftwareLighting()) SetFallbackLightMode(); // Software lighting cannot handle 2D content.
if (!hudModelStep && isSoftwareLighting(oldlightmode)) SetFallbackLightMode(); // Software lighting cannot handle 2D content.
for (auto &hudsprite : hudsprites)
{
if ((!!hudsprite.mframe) == hudModelStep)
@ -352,9 +352,9 @@ WeaponLighting HWDrawInfo::GetWeaponLighting(sector_t *viewsector, const DVector
if (Level->flags3 & LEVEL3_NOCOLOREDSPRITELIGHTING) l.cm.ClearColor();
}
l.lightlevel = CalcLightLevel(l.lightlevel, getExtraLight(), true, 0);
l.lightlevel = CalcLightLevel(lightmode, l.lightlevel, getExtraLight(), true, 0);
if (isSoftwareLighting() || l.lightlevel < 92)
if (isSoftwareLighting(lightmode) || l.lightlevel < 92)
{
// Korshun: the way based on max possible light level for sector like in software renderer.
double min_L = 36.0 / 31.0 - ((l.lightlevel / 255.0) * (63.0 / 31.0)); // Lightlevel in range 0-63
@ -702,7 +702,7 @@ void HWDrawInfo::PreparePlayerSprites2D(sector_t * viewsector, area_t in_area, F
// hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change
// light mode here to draw the weapon sprite.
auto oldlightmode = lightmode;
if (isSoftwareLighting()) SetFallbackLightMode();
if (isSoftwareLighting(oldlightmode)) SetFallbackLightMode();
for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
{
@ -788,7 +788,7 @@ void HWDrawInfo::PreparePlayerSprites3D(sector_t * viewsector, area_t in_area, F
// hack alert! Rather than changing everything in the underlying lighting code let's just temporarily change
// light mode here to draw the weapon sprite.
auto oldlightmode = lightmode;
if (isSoftwareLighting()) SetFallbackLightMode();
if (isSoftwareLighting(oldlightmode)) SetFallbackLightMode();
for (DPSprite *psp = player->psprites; psp != nullptr && psp->GetID() < PSP_TARGETCENTER; psp = psp->GetNext())
{

View file

@ -238,6 +238,7 @@ struct Line native play
native clearscope int Index() const;
native bool Activate(Actor activator, int side, int type);
native bool RemoteActivate(Actor activator, int side, int type, Vector3 pos);
native bool, double, double GetMidTexturePosition (int side);
clearscope int GetUDMFInt(Name nm) const
{