mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2025-01-18 14:41:40 +00:00
Merge commit 'c8eabe5'
This commit is contained in:
commit
2338fe7e66
55 changed files with 1319 additions and 1605 deletions
|
@ -872,7 +872,6 @@ set( POLYRENDER_SOURCES
|
|||
polyrenderer/drawers/poly_draw_args.cpp
|
||||
polyrenderer/drawers/screen_triangle.cpp
|
||||
polyrenderer/math/tri_matrix.cpp
|
||||
polyrenderer/math/poly_intersection.cpp
|
||||
)
|
||||
|
||||
# These files will be flagged as "headers" so that they appear in project files
|
||||
|
|
|
@ -2569,7 +2569,13 @@ void D_DoomMain (void)
|
|||
P_SetupWeapons_ntohton();
|
||||
|
||||
//SBarInfo support.
|
||||
SBarInfo::Load();
|
||||
// This needs special checking because there are two distinct methods of defining status bars.
|
||||
// SBARINFO should only be picked if it is the most recently defined one, so that both
|
||||
// methods can override each other if loaded in sequence.
|
||||
if (gameinfo.statusbarfile > gameinfo.statusbarclassfile)
|
||||
{
|
||||
SBarInfo::Load();
|
||||
}
|
||||
HUD_InitHud();
|
||||
|
||||
if (!batchrun)
|
||||
|
|
|
@ -435,59 +435,7 @@ void G_InitNew (const char *mapname, bool bTitleLevel)
|
|||
S_ResumeSound (false);
|
||||
}
|
||||
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->Destroy();
|
||||
StatusBar = NULL;
|
||||
}
|
||||
auto cls = PClass::FindClass("DoomStatusBar");
|
||||
|
||||
if (bTitleLevel)
|
||||
{
|
||||
StatusBar = new DBaseStatusBar ();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
else if (cls && gameinfo.gametype == GAME_Doom)
|
||||
{
|
||||
StatusBar = (DBaseStatusBar*)cls->CreateNew();
|
||||
}
|
||||
else if (SBarInfoScript[SCRIPT_CUSTOM] != NULL)
|
||||
{
|
||||
int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType();
|
||||
|
||||
//Did the user specify a "base"
|
||||
if(cstype == GAME_Strife)
|
||||
{
|
||||
StatusBar = CreateStrifeStatusBar();
|
||||
}
|
||||
else if(cstype == GAME_Any) //Use the default, empty or custom.
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT);
|
||||
}
|
||||
}
|
||||
if (StatusBar == NULL)
|
||||
{
|
||||
if (gameinfo.gametype & (GAME_DoomChex|GAME_Heretic|GAME_Hexen))
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar (SCRIPT_DEFAULT);
|
||||
}
|
||||
else if (gameinfo.gametype == GAME_Strife)
|
||||
{
|
||||
StatusBar = CreateStrifeStatusBar ();
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar = new DBaseStatusBar();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
}
|
||||
GC::WriteBarrier(StatusBar);
|
||||
StatusBar->AttachToPlayer (&players[consoleplayer]);
|
||||
StatusBar->NewGame ();
|
||||
ST_CreateStatusBar(bTitleLevel);
|
||||
setsizeneeded = true;
|
||||
|
||||
if (gameinfo.gametype == GAME_Strife || (SBarInfoScript[SCRIPT_CUSTOM] != NULL && SBarInfoScript[SCRIPT_CUSTOM]->GetGameType() == GAME_Strife))
|
||||
|
|
|
@ -390,6 +390,7 @@ public:
|
|||
void DrawTopStuff (EHudState state);
|
||||
void FlashItem (const PClass *itemtype);
|
||||
void AttachToPlayer(player_t *player);
|
||||
DVector2 GetHUDScale() const;
|
||||
virtual void FlashCrosshair ();
|
||||
virtual void BlendView (float blend[4]);
|
||||
void NewGame ();
|
||||
|
@ -406,12 +407,9 @@ public:
|
|||
|
||||
void DrawString(FFont *font, const FString &cstring, double x, double y, double Alpha, int translation, int align, int screenalign, int spacing = 0, bool monospaced = false, int shadowX = 0, int shadowY = 0);
|
||||
|
||||
void GetCoords(int &x, int &y)
|
||||
{
|
||||
x = ST_X;
|
||||
y = ST_Y;
|
||||
}
|
||||
|
||||
void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
|
||||
void BeginHUD(int resW, int resH, double Alpha, bool forceScaled = false);
|
||||
void ForceHUDScale(bool on) { ForcedScale = on; } // This is for SBARINFO which should not use BeginStatusBar or BeginHUD.
|
||||
|
||||
//protected:
|
||||
void DrawPowerups ();
|
||||
|
@ -423,10 +421,14 @@ public:
|
|||
AInventory *ValidateInvFirst (int numVisible) const;
|
||||
void DrawCrosshair ();
|
||||
|
||||
// Sizing info for ths status bar.
|
||||
int ST_X, ST_Y;
|
||||
int RelTop;
|
||||
int HorizontalResolution, VerticalResolution;
|
||||
bool Scaled;
|
||||
bool Scaled; // This needs to go away.
|
||||
DVector2 defaultScale; // factor for fully scaled fullscreen display.
|
||||
bool ForcedScale = false;
|
||||
|
||||
bool Centering;
|
||||
bool FixedOrigin;
|
||||
bool CompleteBorder;
|
||||
|
@ -442,7 +444,6 @@ public:
|
|||
DVector2 drawOffset = { 0,0 }; // can be set by subclasses to offset drawing operations
|
||||
double drawClip[4] = { 0,0,0,0 }; // defines a clipping rectangle (not used yet)
|
||||
bool fullscreenOffsets = false; // current screen is displayed with fullscreen behavior.
|
||||
DVector2 cleanScale; // factor for scaled fullscreen display.
|
||||
FMugShot mugshot;
|
||||
|
||||
private:
|
||||
|
@ -458,7 +459,6 @@ extern DBaseStatusBar *StatusBar;
|
|||
|
||||
// Status bar factories -----------------------------------------------------
|
||||
|
||||
DBaseStatusBar *CreateStrifeStatusBar();
|
||||
DBaseStatusBar *CreateCustomStatusBar(int script=0);
|
||||
|
||||
// Crosshair stuff ----------------------------------------------------------
|
||||
|
@ -466,6 +466,7 @@ DBaseStatusBar *CreateCustomStatusBar(int script=0);
|
|||
void ST_FormatMapName(FString &mapname, const char *mapnamecolor = "");
|
||||
void ST_LoadCrosshair(bool alwaysload=false);
|
||||
void ST_Clear();
|
||||
void ST_CreateStatusBar(bool bTitleLevel);
|
||||
extern FTexture *CrosshairImage;
|
||||
|
||||
FTextureID GetInventoryIcon(AInventory *item, uint32_t flags, bool *applyscale);
|
||||
|
|
|
@ -47,6 +47,7 @@
|
|||
#include "a_keys.h"
|
||||
#include "templates.h"
|
||||
#include "i_system.h"
|
||||
#include "sbar.h"
|
||||
#include "sbarinfo.h"
|
||||
#include "gi.h"
|
||||
#include "r_data/r_translate.h"
|
||||
|
@ -72,11 +73,11 @@ enum
|
|||
EXTERN_CVAR(Int, fraglimit)
|
||||
EXTERN_CVAR(Int, screenblocks)
|
||||
EXTERN_CVAR(Bool, vid_fps)
|
||||
EXTERN_CVAR(Bool, hud_scale)
|
||||
|
||||
class DSBarInfo;
|
||||
static double nulclip[] = { 0,0,0,0 };
|
||||
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/**
|
||||
|
@ -629,10 +630,10 @@ void SBarInfo::ParseSBarInfo(int lump)
|
|||
break;
|
||||
case SBARINFO_RESOLUTION:
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
resW = sc.Number;
|
||||
_resW = sc.Number;
|
||||
sc.MustGetToken(',');
|
||||
sc.MustGetToken(TK_IntConst);
|
||||
resH = sc.Number;
|
||||
_resH = sc.Number;
|
||||
sc.MustGetToken(';');
|
||||
break;
|
||||
case SBARINFO_STATUSBAR:
|
||||
|
@ -818,10 +819,8 @@ void SBarInfo::Init()
|
|||
height = 0;
|
||||
spacingCharacter = '\0';
|
||||
spacingAlignment = ALIGN_CENTER;
|
||||
resW = 320;
|
||||
resH = 200;
|
||||
cleanX = -1;
|
||||
cleanY = -1;
|
||||
_resW = 320;
|
||||
_resH = 200;
|
||||
|
||||
for(unsigned int i = 0;i < NUMHUDS;i++)
|
||||
huds[i] = new SBarInfoMainBlock(this);
|
||||
|
@ -957,14 +956,14 @@ void Popup::close()
|
|||
|
||||
////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, const double &xScale, const double &yScale)
|
||||
inline void adjustRelCenter(bool relX, bool relY, const double &x, const double &y, double &outX, double &outY, double ScaleX, double ScaleY)
|
||||
{
|
||||
if(relX)
|
||||
outX = x + (SCREENWIDTH/(hud_scale ? xScale*2 : 2));
|
||||
outX = x + (SCREENWIDTH/(ScaleX*2));
|
||||
else
|
||||
outX = x;
|
||||
if(relY)
|
||||
outY = y + (SCREENHEIGHT/(hud_scale ? yScale*2 : 2));
|
||||
outY = y + (SCREENHEIGHT/(ScaleY*2));
|
||||
else
|
||||
outY = y;
|
||||
}
|
||||
|
@ -1016,25 +1015,8 @@ public:
|
|||
CPlayer = player;
|
||||
}
|
||||
|
||||
void _ScreenSizeChanged()
|
||||
{
|
||||
if (uiscale > 0)
|
||||
{
|
||||
script->cleanX = uiscale;
|
||||
script->cleanY = uiscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
V_CalcCleanFacs(script->resW, script->resH, SCREENWIDTH, SCREENHEIGHT, &script->cleanX, &script->cleanY);
|
||||
}
|
||||
}
|
||||
|
||||
void _Draw (EHudState state)
|
||||
{
|
||||
if (script->cleanX <= 0)
|
||||
{ // Calculate cleanX and cleanY
|
||||
wrapper->CallScreenSizeChanged();
|
||||
}
|
||||
int hud = STBAR_NORMAL;
|
||||
if(state == HUD_StatusBar)
|
||||
{
|
||||
|
@ -1055,11 +1037,10 @@ public:
|
|||
{
|
||||
hud = STBAR_NONE;
|
||||
}
|
||||
bool oldhud_scale = hud_scale;
|
||||
if(script->huds[hud]->ForceScaled()) //scale the statusbar
|
||||
{
|
||||
if(script->huds[hud]->FullScreenOffsets())
|
||||
hud_scale = true;
|
||||
wrapper->ForceHUDScale(true);
|
||||
else if(!Scaled)
|
||||
{
|
||||
scalingWasForced = true;
|
||||
|
@ -1145,8 +1126,8 @@ public:
|
|||
else
|
||||
lastPopup = NULL;
|
||||
|
||||
// Reset hud_scale
|
||||
hud_scale = oldhud_scale;
|
||||
// Reset hud scale
|
||||
wrapper->ForceHUDScale(false);
|
||||
}
|
||||
|
||||
void _NewGame ()
|
||||
|
@ -1161,14 +1142,8 @@ public:
|
|||
return script->huds[STBAR_POPUPLOG]->NumCommands() == 0;
|
||||
}
|
||||
|
||||
void _SetMugShotState (const char *state_name, bool wait_till_done, bool reset)
|
||||
{
|
||||
script->MugShot.SetState(state_name, wait_till_done, reset);
|
||||
}
|
||||
|
||||
void _Tick ()
|
||||
{
|
||||
script->MugShot.Tick(CPlayer);
|
||||
if(currentPopup != DBaseStatusBar::POP_None)
|
||||
{
|
||||
script->popups[currentPopup-1].tick();
|
||||
|
@ -1188,11 +1163,6 @@ public:
|
|||
lastInventoryBar->Tick(NULL, this, false);
|
||||
}
|
||||
|
||||
void _ReceivedWeapon(AWeapon *weapon)
|
||||
{
|
||||
script->MugShot.Grin();
|
||||
}
|
||||
|
||||
// void DSBarInfo::FlashItem(const PClass *itemtype) - Is defined with CommandDrawSelectedInventory
|
||||
void _FlashItem(const PClass *itemtype);
|
||||
|
||||
|
@ -1240,10 +1210,10 @@ public:
|
|||
if(!fullScreenOffsets)
|
||||
{
|
||||
double tmp = 0;
|
||||
int stX, stY;
|
||||
wrapper->GetCoords(stX, stY);
|
||||
dx += stX;
|
||||
dy += stY - (Scaled ? script->resH : 200) + script->height;
|
||||
int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution;
|
||||
|
||||
dx += wrapper->ST_X;
|
||||
dy += wrapper->ST_Y - (Scaled ? barH : 200) + script->height;
|
||||
w = forceWidth < 0 ? texture->GetScaledWidthDouble() : forceWidth;
|
||||
h = forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight;
|
||||
double dcx = clip[0] == 0 ? 0 : dx + clip[0] - texture->GetScaledLeftOffsetDouble();
|
||||
|
@ -1255,19 +1225,19 @@ public:
|
|||
{
|
||||
if(clip[0] != 0 || clip[1] != 0)
|
||||
{
|
||||
screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(dcx, dcy, tmp, tmp, barW, barH, true);
|
||||
if (clip[0] == 0) dcx = 0;
|
||||
if (clip[1] == 0) dcy = 0;
|
||||
}
|
||||
if(clip[2] != 0 || clip[3] != 0 || clearDontDraw)
|
||||
screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(dx, dy, w, h, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(dcr, dcb, tmp, tmp, barW, barH, true);
|
||||
screen->VirtualToRealCoords(dx, dy, w, h, barW, barH, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
dy += 200 - script->resH;
|
||||
dcy += 200 - script->resH;
|
||||
dcb += 200 - script->resH;
|
||||
dy += 200 - barH;
|
||||
dcy += 200 - barH;
|
||||
dcb += 200 - barH;
|
||||
}
|
||||
|
||||
if(clearDontDraw)
|
||||
|
@ -1312,10 +1282,9 @@ public:
|
|||
{
|
||||
double rx, ry, rcx=0, rcy=0, rcr=INT_MAX, rcb=INT_MAX;
|
||||
|
||||
double xScale = !hud_scale ? 1 : script->cleanX;
|
||||
double yScale = !hud_scale ? 1 : script->cleanY;
|
||||
DVector2 Scale = wrapper->GetHUDScale();
|
||||
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, xScale, yScale);
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), dx, dy, rx, ry, Scale.X, Scale.Y);
|
||||
|
||||
// Translation: No high res.
|
||||
bool xright = *x < 0 && !x.RelCenter();
|
||||
|
@ -1325,13 +1294,12 @@ public:
|
|||
h = (forceHeight < 0 ? texture->GetScaledHeightDouble() : forceHeight);
|
||||
if(vid_fps && rx < 0 && ry >= 0)
|
||||
ry += 10;
|
||||
if(hud_scale)
|
||||
{
|
||||
rx *= xScale;
|
||||
ry *= yScale;
|
||||
w *= xScale;
|
||||
h *= yScale;
|
||||
}
|
||||
|
||||
rx *= Scale.X;
|
||||
ry *= Scale.Y;
|
||||
w *= Scale.X;
|
||||
h *= Scale.Y;
|
||||
|
||||
if(xright)
|
||||
rx = SCREENWIDTH + rx;
|
||||
if(ybot)
|
||||
|
@ -1340,10 +1308,10 @@ public:
|
|||
// Check for clipping
|
||||
if(clip[0] != 0 || clip[1] != 0 || clip[2] != 0 || clip[3] != 0)
|
||||
{
|
||||
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*xScale);
|
||||
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*yScale);
|
||||
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*xScale);
|
||||
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*yScale);
|
||||
rcx = clip[0] == 0 ? 0 : rx+((clip[0] - texture->GetScaledLeftOffsetDouble())*Scale.X);
|
||||
rcy = clip[1] == 0 ? 0 : ry+((clip[1] - texture->GetScaledTopOffsetDouble())*Scale.Y);
|
||||
rcr = clip[2] == 0 ? INT_MAX : rx+w-((clip[2] + texture->GetScaledLeftOffsetDouble())*Scale.X);
|
||||
rcb = clip[3] == 0 ? INT_MAX : ry+h-((clip[3] + texture->GetScaledTopOffsetDouble())*Scale.Y);
|
||||
}
|
||||
|
||||
if(clearDontDraw)
|
||||
|
@ -1392,8 +1360,7 @@ public:
|
|||
double ax = *x;
|
||||
double ay = *y;
|
||||
|
||||
double xScale = 1.0;
|
||||
double yScale = 1.0;
|
||||
DVector2 Scale;
|
||||
|
||||
const uint8_t* str = (const uint8_t*) cstring;
|
||||
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
|
||||
|
@ -1401,12 +1368,12 @@ public:
|
|||
|
||||
if(fullScreenOffsets)
|
||||
{
|
||||
if(hud_scale)
|
||||
{
|
||||
xScale = script->cleanX;
|
||||
yScale = script->cleanY;
|
||||
}
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, xScale, yScale);
|
||||
Scale = wrapper->GetHUDScale();
|
||||
adjustRelCenter(x.RelCenter(), y.RelCenter(), *x, *y, ax, ay, Scale.X, Scale.Y);
|
||||
}
|
||||
else
|
||||
{
|
||||
Scale = { 1.,1. };
|
||||
}
|
||||
while(*str != '\0')
|
||||
{
|
||||
|
@ -1467,15 +1434,15 @@ public:
|
|||
|
||||
if(!fullScreenOffsets)
|
||||
{
|
||||
int stX, stY;
|
||||
wrapper->GetCoords(stX, stY);
|
||||
rx += stX;
|
||||
ry += stY - (Scaled ? script->resH : 200) + script->height;
|
||||
|
||||
int barW = wrapper->HorizontalResolution, barH = wrapper->VerticalResolution;
|
||||
rx += wrapper->ST_X;
|
||||
ry += wrapper->ST_Y - (Scaled ? barH : 200) + script->height;
|
||||
if(Scaled)
|
||||
screen->VirtualToRealCoords(rx, ry, rw, rh, script->resW, script->resH, true);
|
||||
screen->VirtualToRealCoords(rx, ry, rw, rh, barW, barH, true);
|
||||
else
|
||||
{
|
||||
ry += (200 - script->resH);
|
||||
ry += (200 - barH);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1486,13 +1453,11 @@ public:
|
|||
bool xright = rx < 0;
|
||||
bool ybot = ry < 0;
|
||||
|
||||
if(hud_scale)
|
||||
{
|
||||
rx *= xScale;
|
||||
ry *= yScale;
|
||||
rw *= xScale;
|
||||
rh *= yScale;
|
||||
}
|
||||
rx *= Scale.X;
|
||||
ry *= Scale.Y;
|
||||
rw *= Scale.X;
|
||||
rh *= Scale.Y;
|
||||
|
||||
if(xright)
|
||||
rx = SCREENWIDTH + rx;
|
||||
if(ybot)
|
||||
|
@ -1501,8 +1466,8 @@ public:
|
|||
if(drawshadow)
|
||||
{
|
||||
double salpha = (Alpha *HR_SHADOW);
|
||||
double srx = rx + (shadowX*xScale);
|
||||
double sry = ry + (shadowY*yScale);
|
||||
double srx = rx + (shadowX*Scale.X);
|
||||
double sry = ry + (shadowY*Scale.Y);
|
||||
screen->DrawChar(font, CR_UNTRANSLATED, srx, sry, character,
|
||||
DTA_DestWidthF, rw,
|
||||
DTA_DestHeightF, rh,
|
||||
|
@ -1558,11 +1523,8 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu
|
|||
{
|
||||
if(FullScreenOffsets())
|
||||
{
|
||||
if(!hud_scale)
|
||||
{
|
||||
rescale = true;
|
||||
hud_scale = true;
|
||||
}
|
||||
rescale = true;
|
||||
statusBar->wrapper->ForceHUDScale(true);
|
||||
}
|
||||
else if(!statusBar->Scaled)
|
||||
{
|
||||
|
@ -1576,7 +1538,7 @@ void SBarInfoMainBlock::DrawAux(const SBarInfoMainBlock *block, DSBarInfo *statu
|
|||
if(rescale)
|
||||
{
|
||||
if(FullScreenOffsets())
|
||||
hud_scale = false;
|
||||
statusBar->wrapper->ForceHUDScale(false);
|
||||
else
|
||||
statusBar->wrapper->SetScaled(false);
|
||||
}
|
||||
|
@ -1615,13 +1577,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, AttachToPlayer)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, ScreenSizeChanged)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
self->_ScreenSizeChanged();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, Draw)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
|
@ -1644,16 +1599,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, MustDrawLog)
|
|||
ACTION_RETURN_BOOL(self->_MustDrawLog((EHudState)State));
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, SetMugshotState)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
PARAM_STRING(name);
|
||||
PARAM_BOOL(wait);
|
||||
PARAM_BOOL(reset);
|
||||
self->_SetMugShotState(name, wait, reset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, Tick)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
|
@ -1661,14 +1606,6 @@ DEFINE_ACTION_FUNCTION(DSBarInfo, Tick)
|
|||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, ReceivedWeapon)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
PARAM_OBJECT(w, AWeapon);
|
||||
self->_ReceivedWeapon(w);
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DSBarInfo, FlashItem)
|
||||
{
|
||||
PARAM_SELF_STRUCT_PROLOGUE(DSBarInfo);
|
||||
|
@ -1695,7 +1632,7 @@ DBaseStatusBar *CreateCustomStatusBar(int scriptno)
|
|||
auto sbar = (DBaseStatusBar*)PClass::FindClass("SBarInfoWrapper")->CreateNew();
|
||||
auto core = new DSBarInfo(sbar, script);
|
||||
sbar->PointerVar<DSBarInfo>("core") = core;
|
||||
sbar->SetSize(script->height, script->resW, script->resH);
|
||||
sbar->SetSize(script->height, script->_resW, script->_resH);
|
||||
core->_SetScaled(sbar->Scaled);
|
||||
sbar->CompleteBorder = script->completeBorder;
|
||||
return sbar;
|
||||
|
|
|
@ -106,11 +106,9 @@ struct SBarInfo
|
|||
int armorInterpolationSpeed;
|
||||
int height;
|
||||
int gameType;
|
||||
FMugShot MugShot;
|
||||
int resW;
|
||||
int resH;
|
||||
int cleanX;
|
||||
int cleanY;
|
||||
|
||||
int _resW;
|
||||
int _resH;
|
||||
|
||||
int GetGameType() { return gameType; }
|
||||
void ParseSBarInfo(int lump);
|
||||
|
|
|
@ -1616,7 +1616,7 @@ class CommandDrawMugShot : public SBarInfoCommand
|
|||
|
||||
void Draw(const SBarInfoMainBlock *block, const DSBarInfo *statusBar)
|
||||
{
|
||||
FTexture *face = script->MugShot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags);
|
||||
FTexture *face = statusBar->wrapper->mugshot.GetFace(statusBar->CPlayer, defaultFace, accuracy, stateFlags);
|
||||
if (face != NULL)
|
||||
statusBar->DrawGraphic(face, x, y, block->XOffset(), block->YOffset(), block->Alpha(), block->FullScreenOffsets());
|
||||
}
|
||||
|
@ -1661,7 +1661,6 @@ class CommandDrawMugShot : public SBarInfoCommand
|
|||
}
|
||||
void Reset()
|
||||
{
|
||||
script->MugShot.Reset();
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
**
|
||||
**---------------------------------------------------------------------------
|
||||
** Copyright 1998-2006 Randy Heit
|
||||
** Copyright 2017 Christoph Oelckers
|
||||
** All rights reserved.
|
||||
**
|
||||
** Redistribution and use in source and binary forms, with or without
|
||||
|
@ -59,6 +60,7 @@
|
|||
#include "virtual.h"
|
||||
#include "p_acs.h"
|
||||
#include "r_data/r_translate.h"
|
||||
#include "sbarinfo.h"
|
||||
|
||||
#include "../version.h"
|
||||
|
||||
|
@ -81,8 +83,8 @@ EXTERN_CVAR (Bool, am_showtime)
|
|||
EXTERN_CVAR (Bool, am_showtotaltime)
|
||||
EXTERN_CVAR (Bool, noisedebug)
|
||||
EXTERN_CVAR (Int, con_scaletext)
|
||||
EXTERN_CVAR(Bool, hud_scale)
|
||||
EXTERN_CVAR(Bool, vid_fps)
|
||||
CVAR(Int, hud_scale, -1, CVAR_ARCHIVE);
|
||||
|
||||
int active_con_scaletext();
|
||||
|
||||
|
@ -90,7 +92,7 @@ DBaseStatusBar *StatusBar;
|
|||
|
||||
extern int setblocks;
|
||||
|
||||
int gST_X, gST_Y;
|
||||
int gST_Y;
|
||||
|
||||
FTexture *CrosshairImage;
|
||||
static int CrosshairNum;
|
||||
|
@ -222,6 +224,85 @@ void ST_Clear()
|
|||
CrosshairNum = 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// create a new status bar
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void ST_CreateStatusBar(bool bTitleLevel)
|
||||
{
|
||||
if (StatusBar != NULL)
|
||||
{
|
||||
StatusBar->Destroy();
|
||||
StatusBar = NULL;
|
||||
}
|
||||
|
||||
if (bTitleLevel)
|
||||
{
|
||||
StatusBar = new DBaseStatusBar();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
else if (gameinfo.statusbarclassfile >= gameinfo.statusbarfile)
|
||||
{
|
||||
auto cls = PClass::FindClass(gameinfo.statusbarclass);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StatusBar == nullptr && SBarInfoScript[SCRIPT_CUSTOM] != nullptr)
|
||||
{
|
||||
int cstype = SBarInfoScript[SCRIPT_CUSTOM]->GetGameType();
|
||||
|
||||
//Did the user specify a "base"
|
||||
if (cstype == GAME_Any) //Use the default, empty or custom.
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar(SCRIPT_CUSTOM);
|
||||
}
|
||||
else
|
||||
{
|
||||
StatusBar = CreateCustomStatusBar(SCRIPT_DEFAULT);
|
||||
}
|
||||
}
|
||||
if (StatusBar == nullptr)
|
||||
{
|
||||
FName defname;
|
||||
|
||||
if (gameinfo.gametype & GAME_DoomChex) defname = "DoomStatusBar";
|
||||
else if (gameinfo.gametype == GAME_Heretic) defname = "HereticStatusBar";
|
||||
else if (gameinfo.gametype == GAME_Hexen) defname = "HexenStatusBar";
|
||||
else if (gameinfo.gametype == GAME_Strife) defname = "StrifeStatusBar";
|
||||
if (defname != NAME_None)
|
||||
{
|
||||
auto cls = PClass::FindClass(defname);
|
||||
if (cls != nullptr)
|
||||
{
|
||||
|
||||
StatusBar = (DBaseStatusBar *)cls->CreateNew();
|
||||
IFVIRTUALPTR(StatusBar, DBaseStatusBar, Init)
|
||||
{
|
||||
VMValue params[] = { StatusBar };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
if (StatusBar == nullptr)
|
||||
{
|
||||
StatusBar = new DBaseStatusBar();
|
||||
StatusBar->SetSize(0);
|
||||
}
|
||||
|
||||
GC::WriteBarrier(StatusBar);
|
||||
StatusBar->AttachToPlayer(&players[consoleplayer]);
|
||||
StatusBar->NewGame();
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// Constructor
|
||||
|
@ -238,8 +319,7 @@ DBaseStatusBar::DBaseStatusBar ()
|
|||
Displacement = 0;
|
||||
CPlayer = NULL;
|
||||
ShowLog = false;
|
||||
cleanScale = { (double)CleanXfac, (double)CleanYfac };
|
||||
|
||||
defaultScale = { (double)CleanXfac, (double)CleanYfac };
|
||||
}
|
||||
|
||||
void DBaseStatusBar::SetSize(int reltop, int hres, int vres)
|
||||
|
@ -327,7 +407,6 @@ void DBaseStatusBar::SetScaled (bool scale, bool force)
|
|||
}
|
||||
Displacement = 0;
|
||||
}
|
||||
gST_X = ST_X;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetScaled)
|
||||
|
@ -349,6 +428,96 @@ void DBaseStatusBar::CallSetScaled(bool scale, bool force)
|
|||
else SetScaled(scale, force);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC GetHUDScale
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
DVector2 DBaseStatusBar::GetHUDScale() const
|
||||
{
|
||||
int scale;
|
||||
if (hud_scale < 0 || ForcedScale) // a negative value is the equivalent to the old boolean hud_scale. This can yield different values for x and y for higher resolutions.
|
||||
{
|
||||
return defaultScale;
|
||||
}
|
||||
if (hud_scale > 0) // use the scale as an absolute value, but also factor in the specified resolution of the HUD
|
||||
{
|
||||
scale = hud_scale;
|
||||
}
|
||||
else if (uiscale == 0)
|
||||
{
|
||||
return defaultScale;
|
||||
}
|
||||
else
|
||||
{
|
||||
scale = MAX<int>(1, uiscale);
|
||||
}
|
||||
|
||||
// Since status bars and HUDs can be designed for non 320x200 screens this needs to be factored in here.
|
||||
// The global scaling factors are for resources at 320x200, so if the actual ones are higher resolution
|
||||
// the resulting scaling factor needs to be reduced accordingly.
|
||||
int realscale = MAX<int>(1, (320 * scale) / HorizontalResolution);
|
||||
return{ double(realscale), double(realscale) };
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, GetHUDScale)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
ACTION_RETURN_VEC2(self->GetHUDScale());
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC GetHUDScale
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::BeginStatusBar(int resW, int resH, int relTop, bool completeborder, bool forceScaled)
|
||||
{
|
||||
SetSize(relTop, resW, resH);
|
||||
SetScaled(st_scale, forceScaled);
|
||||
CompleteBorder = completeborder;
|
||||
fullscreenOffsets = false;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginStatusBar)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
PARAM_INT(r);
|
||||
PARAM_BOOL_DEF(cb);
|
||||
PARAM_BOOL_DEF(fs);
|
||||
self->BeginStatusBar(w, h, r, cb, fs);
|
||||
return 0;
|
||||
}
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC GetHUDScale
|
||||
//
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
void DBaseStatusBar::BeginHUD(int resW, int resH, double Alpha, bool forcescaled)
|
||||
{
|
||||
SetSize(0, resW, resH); // this intentionally resets the relative top to force the caller to go through BeginStatusBar and not just reset some variables.
|
||||
this->Alpha = Alpha;
|
||||
ForcedScale = forcescaled;
|
||||
CompleteBorder = false;
|
||||
fullscreenOffsets = true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, BeginHUD)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_INT(w);
|
||||
PARAM_INT(h);
|
||||
PARAM_FLOAT(a);
|
||||
PARAM_BOOL_DEF(fs);
|
||||
self->BeginHUD(w, h, a, fs);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
//
|
||||
// PROC AttachToPlayer
|
||||
|
@ -1016,6 +1185,16 @@ bool DBaseStatusBar::MustDrawLog(EHudState state)
|
|||
return true;
|
||||
}
|
||||
|
||||
DEFINE_ACTION_FUNCTION(DBaseStatusBar, SetMugshotState)
|
||||
{
|
||||
PARAM_SELF_PROLOGUE(DBaseStatusBar);
|
||||
PARAM_STRING(statename);
|
||||
PARAM_BOOL(wait);
|
||||
PARAM_BOOL(reset);
|
||||
self->mugshot.SetState(statename, wait, reset);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, bool reset)
|
||||
{
|
||||
IFVIRTUAL(DBaseStatusBar, SetMugShotState)
|
||||
|
@ -1024,7 +1203,6 @@ void DBaseStatusBar::SetMugShotState(const char *stateName, bool waitTillDone, b
|
|||
VMValue params[] = { (DObject*)this, &statestring, waitTillDone, reset };
|
||||
GlobalVMStack.Call(func, params, countof(params), nullptr, 0);
|
||||
}
|
||||
mugshot.SetState(stateName, waitTillDone, reset);
|
||||
}
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
|
@ -1223,7 +1401,7 @@ void DBaseStatusBar::ScreenSizeChanged ()
|
|||
|
||||
int x, y;
|
||||
V_CalcCleanFacs(HorizontalResolution, VerticalResolution, SCREENWIDTH, SCREENHEIGHT, &x, &y);
|
||||
cleanScale = { (double)x, (double)y };
|
||||
defaultScale = { (double)x, (double)y };
|
||||
|
||||
for (size_t i = 0; i < countof(Messages); ++i)
|
||||
{
|
||||
|
@ -1423,13 +1601,12 @@ void DBaseStatusBar::DrawGraphic(FTextureID texture, bool animate, double x, dou
|
|||
|
||||
if (screenalign == (RIGHT | TOP) && vid_fps) y += 10;
|
||||
|
||||
if (hud_scale)
|
||||
{
|
||||
x *= cleanScale.X;
|
||||
y *= cleanScale.Y;
|
||||
width *= cleanScale.X;
|
||||
height *= cleanScale.Y;
|
||||
}
|
||||
DVector2 Scale = GetHUDScale();
|
||||
|
||||
x *= Scale.X;
|
||||
y *= Scale.Y;
|
||||
width *= Scale.X;
|
||||
height *= Scale.Y;
|
||||
x += orgx;
|
||||
y += orgy;
|
||||
}
|
||||
|
@ -1495,14 +1672,13 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
const EColorRange boldTranslation = EColorRange(translation ? translation - 1 : NumTextColors - 1);
|
||||
int fontcolor = translation;
|
||||
double orgx = 0, orgy = 0;
|
||||
DVector2 Scale;
|
||||
|
||||
if (fullscreenOffsets)
|
||||
{
|
||||
if (hud_scale)
|
||||
{
|
||||
shadowX *= (int)cleanScale.X;
|
||||
shadowY *= (int)cleanScale.Y;
|
||||
}
|
||||
Scale = GetHUDScale();
|
||||
shadowX *= (int)Scale.X;
|
||||
shadowY *= (int)Scale.Y;
|
||||
|
||||
switch (screenalign & HMASK)
|
||||
{
|
||||
|
@ -1520,6 +1696,10 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
|
||||
if (screenalign == (RIGHT | TOP) && vid_fps) orgy += 10;
|
||||
}
|
||||
else
|
||||
{
|
||||
Scale = { 1.,1. };
|
||||
}
|
||||
int ch;
|
||||
while (ch = *str++, ch != '\0')
|
||||
{
|
||||
|
@ -1582,13 +1762,11 @@ void DBaseStatusBar::DrawString(FFont *font, const FString &cstring, double x, d
|
|||
}
|
||||
else
|
||||
{
|
||||
if (hud_scale)
|
||||
{
|
||||
rx *= cleanScale.X;
|
||||
ry *= cleanScale.Y;
|
||||
rw *= cleanScale.X;
|
||||
rh *= cleanScale.Y;
|
||||
}
|
||||
rx *= Scale.X;
|
||||
ry *= Scale.Y;
|
||||
rw *= Scale.X;
|
||||
rh *= Scale.Y;
|
||||
|
||||
rx += orgx;
|
||||
ry += orgy;
|
||||
}
|
||||
|
@ -1697,23 +1875,11 @@ DEFINE_FIELD(DBaseStatusBar, Alpha);
|
|||
DEFINE_FIELD(DBaseStatusBar, drawOffset);
|
||||
DEFINE_FIELD(DBaseStatusBar, drawClip);
|
||||
DEFINE_FIELD(DBaseStatusBar, fullscreenOffsets);
|
||||
DEFINE_FIELD(DBaseStatusBar, cleanScale);
|
||||
DEFINE_FIELD(DBaseStatusBar, defaultScale);
|
||||
|
||||
DEFINE_GLOBAL(StatusBar);
|
||||
|
||||
|
||||
DBaseStatusBar *CreateStrifeStatusBar()
|
||||
{
|
||||
auto sb = (DBaseStatusBar *)PClass::FindClass("StrifeStatusBar")->CreateNew();
|
||||
IFVIRTUALPTR(sb, DBaseStatusBar, Init)
|
||||
{
|
||||
VMValue params[] = { sb };
|
||||
GlobalVMStack.Call(func, params, 1, nullptr, 0);
|
||||
}
|
||||
return sb;
|
||||
}
|
||||
|
||||
|
||||
static DObject *InitObject(PClass *type, int paramnum, VM_ARGS)
|
||||
{
|
||||
auto obj = type->CreateNew();
|
||||
|
|
|
@ -354,6 +354,21 @@ void FGameConfigFile::DoGlobalSetup ()
|
|||
SetValueForKey ("5", "use ArtiInvulnerability2");
|
||||
}
|
||||
}
|
||||
if (last < 212)
|
||||
{
|
||||
FBaseCVar *var = FindCVar("hud_scale", NULL);
|
||||
if (var != NULL)
|
||||
{
|
||||
var->ResetToDefault();
|
||||
}
|
||||
var = FindCVar("snd_channels", NULL);
|
||||
if (var != NULL)
|
||||
{
|
||||
// old settings were default 32, minimum 8, new settings are default 128, minimum 64.
|
||||
UCVarValue v = var->GetGenericRep(CVAR_Int);
|
||||
if (v.Int < 64) var->ResetToDefault();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
11
src/gi.cpp
11
src/gi.cpp
|
@ -153,6 +153,14 @@ const char* GameInfoBorders[] =
|
|||
gameinfo.key = sc.String; \
|
||||
}
|
||||
|
||||
#define GAMEINFOKEY_STRING_STAMPED(key, variable, stampvar) \
|
||||
else if(nextKey.CompareNoCase(variable) == 0) \
|
||||
{ \
|
||||
sc.MustGetToken(TK_StringConst); \
|
||||
gameinfo.key = sc.String; \
|
||||
gameinfo.stampvar = Wads.GetLumpFile(sc.LumpNum); \
|
||||
}
|
||||
|
||||
#define GAMEINFOKEY_INT(key, variable) \
|
||||
else if(nextKey.CompareNoCase(variable) == 0) \
|
||||
{ \
|
||||
|
@ -358,7 +366,8 @@ void FMapInfoParser::ParseGameInfo()
|
|||
GAMEINFOKEY_COLOR(defaultbloodcolor, "defaultbloodcolor")
|
||||
GAMEINFOKEY_COLOR(defaultbloodparticlecolor, "defaultbloodparticlecolor")
|
||||
GAMEINFOKEY_STRING(backpacktype, "backpacktype")
|
||||
GAMEINFOKEY_STRING(statusbar, "statusbar")
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbar, "statusbar", statusbarfile)
|
||||
GAMEINFOKEY_STRING_STAMPED(statusbarclass, "statusbarclass", statusbarclassfile)
|
||||
GAMEINFOKEY_MUSIC(intermissionMusic, intermissionOrder, "intermissionMusic")
|
||||
GAMEINFOKEY_STRING(CursorPic, "CursorPic")
|
||||
GAMEINFOKEY_BOOL(noloopfinalemusic, "noloopfinalemusic")
|
||||
|
|
5
src/gi.h
5
src/gi.h
|
@ -148,8 +148,11 @@ struct gameinfo_t
|
|||
FString translator;
|
||||
uint32_t defaultbloodcolor;
|
||||
uint32_t defaultbloodparticlecolor;
|
||||
FName backpacktype;
|
||||
FString statusbar;
|
||||
int statusbarfile = -1;
|
||||
FName statusbarclass;
|
||||
int statusbarclassfile = -1;
|
||||
FName backpacktype;
|
||||
FString intermissionMusic;
|
||||
int intermissionOrder;
|
||||
FString CursorPic;
|
||||
|
|
|
@ -37,23 +37,23 @@
|
|||
#include "poly_draw_args.h"
|
||||
#include "swrenderer/viewport/r_viewport.h"
|
||||
|
||||
void PolyDrawArgs::SetClipPlane(float a, float b, float c, float d)
|
||||
void PolyDrawArgs::SetClipPlane(const PolyClipPlane &plane)
|
||||
{
|
||||
clipPlane[0] = a;
|
||||
clipPlane[1] = b;
|
||||
clipPlane[2] = c;
|
||||
clipPlane[3] = d;
|
||||
mClipPlane[0] = plane.A;
|
||||
mClipPlane[1] = plane.B;
|
||||
mClipPlane[2] = plane.C;
|
||||
mClipPlane[3] = plane.D;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture)
|
||||
{
|
||||
textureWidth = texture->GetWidth();
|
||||
textureHeight = texture->GetHeight();
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
texturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||
mTexturePixels = (const uint8_t *)texture->GetPixelsBgra();
|
||||
else
|
||||
texturePixels = texture->GetPixels();
|
||||
translation = nullptr;
|
||||
mTexturePixels = texture->GetPixels();
|
||||
mTranslation = nullptr;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool forcePal)
|
||||
|
@ -64,22 +64,22 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
|
|||
if (table != nullptr && !table->Inactive)
|
||||
{
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
translation = (uint8_t*)table->Palette;
|
||||
mTranslation = (uint8_t*)table->Palette;
|
||||
else
|
||||
translation = table->Remap;
|
||||
mTranslation = table->Remap;
|
||||
|
||||
textureWidth = texture->GetWidth();
|
||||
textureHeight = texture->GetHeight();
|
||||
texturePixels = texture->GetPixels();
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (forcePal)
|
||||
{
|
||||
textureWidth = texture->GetWidth();
|
||||
textureHeight = texture->GetHeight();
|
||||
texturePixels = texture->GetPixels();
|
||||
mTextureWidth = texture->GetWidth();
|
||||
mTextureHeight = texture->GetHeight();
|
||||
mTexturePixels = texture->GetPixels();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -87,21 +87,48 @@ void PolyDrawArgs::SetTexture(FTexture *texture, uint32_t translationID, bool fo
|
|||
}
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetColormap(FSWColormap *base_colormap)
|
||||
void PolyDrawArgs::SetLight(FSWColormap *base_colormap, uint32_t lightlevel, double globVis, bool fixed)
|
||||
{
|
||||
uniforms.light_red = base_colormap->Color.r * 256 / 255;
|
||||
uniforms.light_green = base_colormap->Color.g * 256 / 255;
|
||||
uniforms.light_blue = base_colormap->Color.b * 256 / 255;
|
||||
uniforms.light_alpha = base_colormap->Color.a * 256 / 255;
|
||||
uniforms.fade_red = base_colormap->Fade.r;
|
||||
uniforms.fade_green = base_colormap->Fade.g;
|
||||
uniforms.fade_blue = base_colormap->Fade.b;
|
||||
uniforms.fade_alpha = base_colormap->Fade.a;
|
||||
uniforms.desaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
|
||||
bool simple_shade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
|
||||
if (simple_shade)
|
||||
uniforms.flags |= TriUniforms::simple_shade;
|
||||
else
|
||||
uniforms.flags &= ~TriUniforms::simple_shade;
|
||||
colormaps = base_colormap->Maps;
|
||||
mGlobVis = (float)globVis;
|
||||
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
{
|
||||
lightlevel = cameraLight->FixedLightLevel() >= 0 ? cameraLight->FixedLightLevel() : 255;
|
||||
fixed = true;
|
||||
}
|
||||
|
||||
mLight = clamp<uint32_t>(lightlevel, 0, 255);
|
||||
mFixedLight = fixed;
|
||||
mLightRed = base_colormap->Color.r * 256 / 255;
|
||||
mLightGreen = base_colormap->Color.g * 256 / 255;
|
||||
mLightBlue = base_colormap->Color.b * 256 / 255;
|
||||
mLightAlpha = base_colormap->Color.a * 256 / 255;
|
||||
mFadeRed = base_colormap->Fade.r;
|
||||
mFadeGreen = base_colormap->Fade.g;
|
||||
mFadeBlue = base_colormap->Fade.b;
|
||||
mFadeAlpha = base_colormap->Fade.a;
|
||||
mDesaturate = MIN(abs(base_colormap->Desaturate), 255) * 255 / 256;
|
||||
mSimpleShade = (base_colormap->Color.d == 0x00ffffff && base_colormap->Fade.d == 0x00000000 && base_colormap->Desaturate == 0);
|
||||
mColormaps = base_colormap->Maps;
|
||||
}
|
||||
|
||||
void PolyDrawArgs::SetColor(uint32_t bgra, uint8_t palindex)
|
||||
{
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
mColor = bgra;
|
||||
}
|
||||
else
|
||||
{
|
||||
mColor = palindex;
|
||||
}
|
||||
}
|
||||
|
||||
void PolyDrawArgs::DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode)
|
||||
{
|
||||
mVertices = vertices;
|
||||
mVertexCount = vcount;
|
||||
mDrawMode = mode;
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(*this, PolyTriangleDrawer::is_mirror());
|
||||
}
|
||||
|
|
|
@ -27,43 +27,123 @@
|
|||
#include "screen_triangle.h"
|
||||
|
||||
class FTexture;
|
||||
struct TriMatrix;
|
||||
|
||||
enum class TriangleDrawMode
|
||||
enum class PolyDrawMode
|
||||
{
|
||||
Normal,
|
||||
Fan,
|
||||
Strip
|
||||
Triangles,
|
||||
TriangleFan,
|
||||
TriangleStrip
|
||||
};
|
||||
|
||||
struct TriDrawTriangleArgs;
|
||||
struct TriMatrix;
|
||||
class PolyClipPlane
|
||||
{
|
||||
public:
|
||||
PolyClipPlane() : A(0.0f), B(0.0f), C(0.0f), D(1.0f) { }
|
||||
PolyClipPlane(float a, float b, float c, float d) : A(a), B(b), C(c), D(d) { }
|
||||
|
||||
float A, B, C, D;
|
||||
};
|
||||
|
||||
class PolyDrawArgs
|
||||
{
|
||||
public:
|
||||
TriUniforms uniforms;
|
||||
const TriMatrix *objectToClip = nullptr;
|
||||
const TriVertex *vinput = nullptr;
|
||||
int vcount = 0;
|
||||
TriangleDrawMode mode = TriangleDrawMode::Normal;
|
||||
bool ccw = false;
|
||||
// bool stencilTest = true; // Always true for now
|
||||
bool subsectorTest = false;
|
||||
bool writeStencil = true;
|
||||
bool writeColor = true;
|
||||
bool writeSubsector = true;
|
||||
const uint8_t *texturePixels = nullptr;
|
||||
int textureWidth = 0;
|
||||
int textureHeight = 0;
|
||||
const uint8_t *translation = nullptr;
|
||||
uint8_t stenciltestvalue = 0;
|
||||
uint8_t stencilwritevalue = 0;
|
||||
const uint8_t *colormaps = nullptr;
|
||||
float clipPlane[4];
|
||||
TriBlendMode blendmode = TriBlendMode::Copy;
|
||||
|
||||
void SetClipPlane(float a, float b, float c, float d);
|
||||
void SetClipPlane(const PolyClipPlane &plane);
|
||||
void SetTexture(FTexture *texture);
|
||||
void SetTexture(FTexture *texture, uint32_t translationID, bool forcePal = false);
|
||||
void SetColormap(FSWColormap *base_colormap);
|
||||
void SetLight(FSWColormap *basecolormap, uint32_t lightlevel, double globVis, bool fixed);
|
||||
void SetSubsectorDepth(uint32_t subsectorDepth) { mSubsectorDepth = subsectorDepth; }
|
||||
void SetSubsectorDepthTest(bool enable) { mSubsectorTest = enable; }
|
||||
void SetStencilTestValue(uint8_t stencilTestValue) { mStencilTestValue = stencilTestValue; }
|
||||
void SetWriteColor(bool enable) { mWriteColor = enable; }
|
||||
void SetWriteStencil(bool enable, uint8_t stencilWriteValue = 0) { mWriteStencil = enable; mStencilWriteValue = stencilWriteValue; }
|
||||
void SetWriteSubsectorDepth(bool enable) { mWriteSubsector = enable; }
|
||||
void SetFaceCullCCW(bool counterclockwise) { mFaceCullCCW = counterclockwise; }
|
||||
void SetStyle(TriBlendMode blendmode, double srcalpha = 1.0, double destalpha = 1.0) { mBlendMode = blendmode; mSrcAlpha = (uint32_t)(srcalpha * 256.0 + 0.5); mDestAlpha = (uint32_t)(destalpha * 256.0 + 0.5); }
|
||||
void SetTransform(const TriMatrix *objectToClip) { mObjectToClip = objectToClip; }
|
||||
void SetColor(uint32_t bgra, uint8_t palindex);
|
||||
void DrawArray(const TriVertex *vertices, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
|
||||
|
||||
const TriMatrix *ObjectToClip() const { return mObjectToClip; }
|
||||
const float *ClipPlane() const { return mClipPlane; }
|
||||
|
||||
const TriVertex *Vertices() const { return mVertices; }
|
||||
int VertexCount() const { return mVertexCount; }
|
||||
PolyDrawMode DrawMode() const { return mDrawMode; }
|
||||
|
||||
bool FaceCullCCW() const { return mFaceCullCCW; }
|
||||
bool WriteColor() const { return mWriteColor; }
|
||||
|
||||
const uint8_t *TexturePixels() const { return mTexturePixels; }
|
||||
int TextureWidth() const { return mTextureWidth; }
|
||||
int TextureHeight() const { return mTextureHeight; }
|
||||
const uint8_t *Translation() const { return mTranslation; }
|
||||
|
||||
bool WriteStencil() const { return mWriteStencil; }
|
||||
uint8_t StencilTestValue() const { return mStencilTestValue; }
|
||||
uint8_t StencilWriteValue() const { return mStencilWriteValue; }
|
||||
|
||||
bool SubsectorTest() const { return mSubsectorTest; }
|
||||
bool WriteSubsector() const { return mWriteSubsector; }
|
||||
uint32_t SubsectorDepth() const { return mSubsectorDepth; }
|
||||
|
||||
TriBlendMode BlendMode() const { return mBlendMode; }
|
||||
uint32_t Color() const { return mColor; }
|
||||
uint32_t SrcAlpha() const { return mSrcAlpha; }
|
||||
uint32_t DestAlpha() const { return mDestAlpha; }
|
||||
|
||||
float GlobVis() const { return mGlobVis; }
|
||||
uint32_t Light() const { return mLight; }
|
||||
const uint8_t *BaseColormap() const { return mColormaps; }
|
||||
uint16_t ShadeLightAlpha() const { return mLightAlpha; }
|
||||
uint16_t ShadeLightRed() const { return mLightRed; }
|
||||
uint16_t ShadeLightGreen() const { return mLightGreen; }
|
||||
uint16_t ShadeLightBlue() const { return mLightBlue; }
|
||||
uint16_t ShadeFadeAlpha() const { return mFadeAlpha; }
|
||||
uint16_t ShadeFadeRed() const { return mFadeRed; }
|
||||
uint16_t ShadeFadeGreen() const { return mFadeGreen; }
|
||||
uint16_t ShadeFadeBlue() const { return mFadeBlue; }
|
||||
uint16_t ShadeDesaturate() const { return mDesaturate; }
|
||||
|
||||
bool SimpleShade() const { return mSimpleShade; }
|
||||
bool NearestFilter() const { return mNearestFilter; }
|
||||
bool FixedLight() const { return mFixedLight; }
|
||||
|
||||
private:
|
||||
const TriMatrix *mObjectToClip = nullptr;
|
||||
const TriVertex *mVertices = nullptr;
|
||||
int mVertexCount = 0;
|
||||
PolyDrawMode mDrawMode = PolyDrawMode::Triangles;
|
||||
bool mFaceCullCCW = false;
|
||||
bool mSubsectorTest = false;
|
||||
bool mWriteStencil = true;
|
||||
bool mWriteColor = true;
|
||||
bool mWriteSubsector = true;
|
||||
const uint8_t *mTexturePixels = nullptr;
|
||||
int mTextureWidth = 0;
|
||||
int mTextureHeight = 0;
|
||||
const uint8_t *mTranslation = nullptr;
|
||||
uint8_t mStencilTestValue = 0;
|
||||
uint8_t mStencilWriteValue = 0;
|
||||
const uint8_t *mColormaps = nullptr;
|
||||
float mClipPlane[4] = { 0.0f, 0.0f, 0.0f, 1.0f };
|
||||
TriBlendMode mBlendMode = TriBlendMode::Copy;
|
||||
uint32_t mLight = 0;
|
||||
uint32_t mSubsectorDepth = 0;
|
||||
uint32_t mColor = 0;
|
||||
uint32_t mSrcAlpha = 0;
|
||||
uint32_t mDestAlpha = 0;
|
||||
uint16_t mLightAlpha = 0;
|
||||
uint16_t mLightRed = 0;
|
||||
uint16_t mLightGreen = 0;
|
||||
uint16_t mLightBlue = 0;
|
||||
uint16_t mFadeAlpha = 0;
|
||||
uint16_t mFadeRed = 0;
|
||||
uint16_t mFadeGreen = 0;
|
||||
uint16_t mFadeBlue = 0;
|
||||
uint16_t mDesaturate = 0;
|
||||
float mGlobVis = 0.0f;
|
||||
bool mSimpleShade = true;
|
||||
bool mNearestFilter = true;
|
||||
bool mFixedLight = false;
|
||||
};
|
||||
|
|
|
@ -32,12 +32,11 @@ public:
|
|||
{
|
||||
using namespace TriScreenDrawerModes;
|
||||
|
||||
auto flags = args->uniforms->flags;
|
||||
bool is_simple_shade = (flags & TriUniforms::simple_shade) == TriUniforms::simple_shade;
|
||||
bool is_simple_shade = args->uniforms->SimpleShade();
|
||||
|
||||
if (SamplerT::Mode == (int)Samplers::Texture)
|
||||
{
|
||||
bool is_nearest_filter = (flags & TriUniforms::nearest_filter) == TriUniforms::nearest_filter;
|
||||
bool is_nearest_filter = args->uniforms->NearestFilter();
|
||||
|
||||
if (is_simple_shade)
|
||||
{
|
||||
|
@ -79,11 +78,10 @@ public:
|
|||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
auto flags = args->uniforms->flags;
|
||||
bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light;
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
uint32_t srcalpha = args->uniforms->srcalpha;
|
||||
uint32_t destalpha = args->uniforms->destalpha;
|
||||
uint32_t srcalpha = args->uniforms->SrcAlpha();
|
||||
uint32_t destalpha = args->uniforms->DestAlpha();
|
||||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
|
@ -107,16 +105,17 @@ public:
|
|||
int pitch = args->pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->light;
|
||||
float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f;
|
||||
float globVis = args->uniforms->globvis * (1.0f / 32.0f);
|
||||
uint32_t light = args->uniforms->Light();
|
||||
float shade = 2.0f - (light + 12.0f) / 128.0f;
|
||||
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
|
||||
light += (light >> 7); // 255 -> 256
|
||||
|
||||
// Sampling stuff
|
||||
uint32_t color = args->uniforms->color;
|
||||
const uint32_t * RESTRICT translation = (const uint32_t *)args->translation;
|
||||
const uint32_t * RESTRICT texPixels = (const uint32_t *)args->texturePixels;
|
||||
uint32_t texWidth = args->textureWidth;
|
||||
uint32_t texHeight = args->textureHeight;
|
||||
uint32_t color = args->uniforms->Color();
|
||||
const uint32_t * RESTRICT translation = (const uint32_t *)args->uniforms->Translation();
|
||||
const uint32_t * RESTRICT texPixels = (const uint32_t *)args->uniforms->TexturePixels();
|
||||
uint32_t texWidth = args->uniforms->TextureWidth();
|
||||
uint32_t texHeight = args->uniforms->TextureHeight();
|
||||
uint32_t oneU, oneV;
|
||||
if (SamplerT::Mode != (int)Samplers::Fill)
|
||||
{
|
||||
|
@ -134,10 +133,10 @@ public:
|
|||
int desaturate;
|
||||
if (ShadeModeT::Mode == (int)ShadeMode::Advanced)
|
||||
{
|
||||
inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate, 256 - args->uniforms->desaturate);
|
||||
shade_fade = _mm_set_epi16(args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue, args->uniforms->fade_alpha, args->uniforms->fade_red, args->uniforms->fade_green, args->uniforms->fade_blue);
|
||||
shade_light = _mm_set_epi16(args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue, args->uniforms->light_alpha, args->uniforms->light_red, args->uniforms->light_green, args->uniforms->light_blue);
|
||||
desaturate = args->uniforms->desaturate;
|
||||
inv_desaturate = _mm_setr_epi16(256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256, 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate(), 256 - args->uniforms->ShadeDesaturate());
|
||||
shade_fade = _mm_set_epi16(args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue(), args->uniforms->ShadeFadeAlpha(), args->uniforms->ShadeFadeRed(), args->uniforms->ShadeFadeGreen(), args->uniforms->ShadeFadeBlue());
|
||||
shade_light = _mm_set_epi16(args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue(), args->uniforms->ShadeLightAlpha(), args->uniforms->ShadeLightRed(), args->uniforms->ShadeLightGreen(), args->uniforms->ShadeLightBlue());
|
||||
desaturate = args->uniforms->ShadeDesaturate();
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -39,12 +39,11 @@ public:
|
|||
int startX = thread->StartX;
|
||||
int startY = thread->StartY;
|
||||
|
||||
auto flags = args->uniforms->flags;
|
||||
bool is_fixed_light = (flags & TriUniforms::fixed_light) == TriUniforms::fixed_light;
|
||||
bool is_fixed_light = args->uniforms->FixedLight();
|
||||
uint32_t lightmask = is_fixed_light ? 0 : 0xffffffff;
|
||||
auto colormaps = args->colormaps;
|
||||
uint32_t srcalpha = args->uniforms->srcalpha;
|
||||
uint32_t destalpha = args->uniforms->destalpha;
|
||||
auto colormaps = args->uniforms->BaseColormap();
|
||||
uint32_t srcalpha = args->uniforms->SrcAlpha();
|
||||
uint32_t destalpha = args->uniforms->DestAlpha();
|
||||
|
||||
// Calculate gradients
|
||||
const TriVertex &v1 = *args->v1;
|
||||
|
@ -68,16 +67,17 @@ public:
|
|||
int pitch = args->pitch;
|
||||
|
||||
// Light
|
||||
uint32_t light = args->uniforms->light;
|
||||
float shade = (64.0f - (light * 255 / 256 + 12.0f) * 32.0f / 128.0f) / 32.0f;
|
||||
float globVis = args->uniforms->globvis * (1.0f / 32.0f);
|
||||
uint32_t light = args->uniforms->Light();
|
||||
float shade = 2.0f - (light + 12.0f) / 128.0f;
|
||||
float globVis = args->uniforms->GlobVis() * (1.0f / 32.0f);
|
||||
light += light >> 7; // 255 -> 256
|
||||
|
||||
// Sampling stuff
|
||||
uint32_t color = args->uniforms->color;
|
||||
const uint8_t * RESTRICT translation = args->translation;
|
||||
const uint8_t * RESTRICT texPixels = args->texturePixels;
|
||||
uint32_t texWidth = args->textureWidth;
|
||||
uint32_t texHeight = args->textureHeight;
|
||||
uint32_t color = args->uniforms->Color();
|
||||
const uint8_t * RESTRICT translation = args->uniforms->Translation();
|
||||
const uint8_t * RESTRICT texPixels = args->uniforms->TexturePixels();
|
||||
uint32_t texWidth = args->uniforms->TextureWidth();
|
||||
uint32_t texHeight = args->uniforms->TextureHeight();
|
||||
|
||||
for (int i = 0; i < numSpans; i++)
|
||||
{
|
||||
|
|
|
@ -80,35 +80,35 @@ void PolyTriangleDrawer::toggle_mirror()
|
|||
mirror = !mirror;
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::draw(const PolyDrawArgs &args)
|
||||
bool PolyTriangleDrawer::is_mirror()
|
||||
{
|
||||
PolyRenderer::Instance()->DrawQueue->Push<DrawPolyTrianglesCommand>(args, mirror);
|
||||
return mirror;
|
||||
}
|
||||
|
||||
void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadData *thread)
|
||||
{
|
||||
if (drawargs.vcount < 3)
|
||||
if (drawargs.VertexCount() < 3)
|
||||
return;
|
||||
|
||||
PolyDrawFuncPtr drawfuncs[4];
|
||||
int num_drawfuncs = 0;
|
||||
|
||||
drawfuncs[num_drawfuncs++] = drawargs.subsectorTest ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal;
|
||||
drawfuncs[num_drawfuncs++] = drawargs.SubsectorTest() ? &ScreenTriangle::SetupSubsector : &ScreenTriangle::SetupNormal;
|
||||
|
||||
if (!r_debug_trisetup) // For profiling how much time is spent in setup vs drawal
|
||||
{
|
||||
int bmode = (int)drawargs.blendmode;
|
||||
int bmode = (int)drawargs.BlendMode();
|
||||
|
||||
if (drawargs.writeColor && drawargs.texturePixels)
|
||||
if (drawargs.WriteColor() && drawargs.TexturePixels())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriDraw32[bmode] : ScreenTriangle::TriDraw8[bmode];
|
||||
else if (drawargs.writeColor)
|
||||
else if (drawargs.WriteColor())
|
||||
drawfuncs[num_drawfuncs++] = dest_bgra ? ScreenTriangle::TriFill32[bmode] : ScreenTriangle::TriFill8[bmode];
|
||||
}
|
||||
|
||||
if (drawargs.writeStencil)
|
||||
if (drawargs.WriteStencil())
|
||||
drawfuncs[num_drawfuncs++] = &ScreenTriangle::StencilWrite;
|
||||
|
||||
if (drawargs.writeSubsector)
|
||||
if (drawargs.WriteSubsector())
|
||||
drawfuncs[num_drawfuncs++] = &ScreenTriangle::SubsectorWrite;
|
||||
|
||||
TriDrawTriangleArgs args;
|
||||
|
@ -118,53 +118,44 @@ void PolyTriangleDrawer::draw_arrays(const PolyDrawArgs &drawargs, WorkerThreadD
|
|||
args.clipright = dest_width;
|
||||
args.cliptop = 0;
|
||||
args.clipbottom = dest_height;
|
||||
args.texturePixels = drawargs.texturePixels;
|
||||
args.textureWidth = drawargs.textureWidth;
|
||||
args.textureHeight = drawargs.textureHeight;
|
||||
args.translation = drawargs.translation;
|
||||
args.uniforms = &drawargs.uniforms;
|
||||
args.stencilTestValue = drawargs.stenciltestvalue;
|
||||
args.stencilWriteValue = drawargs.stencilwritevalue;
|
||||
args.uniforms = &drawargs;
|
||||
args.stencilPitch = PolyStencilBuffer::Instance()->BlockWidth();
|
||||
args.stencilValues = PolyStencilBuffer::Instance()->Values();
|
||||
args.stencilMasks = PolyStencilBuffer::Instance()->Masks();
|
||||
args.subsectorGBuffer = PolySubsectorGBuffer::Instance()->Values();
|
||||
args.colormaps = drawargs.colormaps;
|
||||
args.RGB256k = RGB256k.All;
|
||||
args.BaseColors = (const uint8_t *)GPalette.BaseColors;
|
||||
|
||||
bool ccw = drawargs.ccw;
|
||||
const TriVertex *vinput = drawargs.vinput;
|
||||
int vcount = drawargs.vcount;
|
||||
bool ccw = drawargs.FaceCullCCW();
|
||||
const TriVertex *vinput = drawargs.Vertices();
|
||||
int vcount = drawargs.VertexCount();
|
||||
|
||||
ShadedTriVertex vert[3];
|
||||
if (drawargs.mode == TriangleDrawMode::Normal)
|
||||
if (drawargs.DrawMode() == PolyDrawMode::Triangles)
|
||||
{
|
||||
for (int i = 0; i < vcount / 3; i++)
|
||||
{
|
||||
for (int j = 0; j < 3; j++)
|
||||
vert[j] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[j] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
}
|
||||
}
|
||||
else if (drawargs.mode == TriangleDrawMode::Fan)
|
||||
else if (drawargs.DrawMode() == PolyDrawMode::TriangleFan)
|
||||
{
|
||||
vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
for (int i = 2; i < vcount; i++)
|
||||
{
|
||||
vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
vert[1] = vert[2];
|
||||
}
|
||||
}
|
||||
else // TriangleDrawMode::Strip
|
||||
else // TriangleDrawMode::TriangleStrip
|
||||
{
|
||||
vert[0] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[1] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[0] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
vert[1] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
for (int i = 2; i < vcount; i++)
|
||||
{
|
||||
vert[2] = shade_vertex(*drawargs.objectToClip, drawargs.clipPlane, *(vinput++));
|
||||
vert[2] = shade_vertex(*drawargs.ObjectToClip(), drawargs.ClipPlane(), *(vinput++));
|
||||
draw_shaded_triangle(vert, ccw, &args, thread, drawfuncs, num_drawfuncs);
|
||||
vert[0] = vert[1];
|
||||
vert[1] = vert[2];
|
||||
|
@ -448,7 +439,7 @@ DrawPolyTrianglesCommand::DrawPolyTrianglesCommand(const PolyDrawArgs &args, boo
|
|||
: args(args)
|
||||
{
|
||||
if (mirror)
|
||||
this->args.ccw = !this->args.ccw;
|
||||
this->args.SetFaceCullCCW(!this->args.FaceCullCCW());
|
||||
}
|
||||
|
||||
void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
|
||||
|
@ -461,32 +452,3 @@ void DrawPolyTrianglesCommand::Execute(DrawerThread *thread)
|
|||
|
||||
PolyTriangleDrawer::draw_arrays(args, &thread_data);
|
||||
}
|
||||
|
||||
FString DrawPolyTrianglesCommand::DebugInfo()
|
||||
{
|
||||
FString blendmodestr;
|
||||
switch (args.blendmode)
|
||||
{
|
||||
default: blendmodestr = "Unknown"; break;
|
||||
case TriBlendMode::Copy: blendmodestr = "Copy"; break;
|
||||
case TriBlendMode::AlphaBlend: blendmodestr = "AlphaBlend"; break;
|
||||
case TriBlendMode::AddSolid: blendmodestr = "AddSolid"; break;
|
||||
case TriBlendMode::Add: blendmodestr = "Add"; break;
|
||||
case TriBlendMode::Sub: blendmodestr = "Sub"; break;
|
||||
case TriBlendMode::RevSub: blendmodestr = "RevSub"; break;
|
||||
case TriBlendMode::Stencil: blendmodestr = "Stencil"; break;
|
||||
case TriBlendMode::Shaded: blendmodestr = "Shaded"; break;
|
||||
case TriBlendMode::TranslateCopy: blendmodestr = "TranslateCopy"; break;
|
||||
case TriBlendMode::TranslateAlphaBlend: blendmodestr = "TranslateAlphaBlend"; break;
|
||||
case TriBlendMode::TranslateAdd: blendmodestr = "TranslateAdd"; break;
|
||||
case TriBlendMode::TranslateSub: blendmodestr = "TranslateSub"; break;
|
||||
case TriBlendMode::TranslateRevSub: blendmodestr = "TranslateRevSub"; break;
|
||||
case TriBlendMode::AddSrcColorOneMinusSrcColor: blendmodestr = "AddSrcColorOneMinusSrcColor"; break;
|
||||
}
|
||||
|
||||
FString info;
|
||||
info.Format("DrawPolyTriangles: blend mode = %s, color = %d, light = %d, textureWidth = %d, textureHeight = %d, texture = %s, translation = %s, colormaps = %s",
|
||||
blendmodestr.GetChars(), args.uniforms.color, args.uniforms.light, args.textureWidth, args.textureHeight,
|
||||
args.texturePixels ? "ptr" : "null", args.translation ? "ptr" : "null", args.colormaps ? "ptr" : "null");
|
||||
return info;
|
||||
}
|
||||
|
|
|
@ -40,8 +40,8 @@ class PolyTriangleDrawer
|
|||
{
|
||||
public:
|
||||
static void set_viewport(int x, int y, int width, int height, DCanvas *canvas);
|
||||
static void draw(const PolyDrawArgs &args);
|
||||
static void toggle_mirror();
|
||||
static bool is_mirror();
|
||||
|
||||
private:
|
||||
static ShadedTriVertex shade_vertex(const TriMatrix &objectToClip, const float *clipPlane, const TriVertex &v);
|
||||
|
@ -66,7 +66,7 @@ public:
|
|||
DrawPolyTrianglesCommand(const PolyDrawArgs &args, bool mirror);
|
||||
|
||||
void Execute(DrawerThread *thread) override;
|
||||
FString DebugInfo() override;
|
||||
FString DebugInfo() override { return "DrawPolyTriangles"; }
|
||||
|
||||
private:
|
||||
PolyDrawArgs args;
|
||||
|
|
|
@ -52,7 +52,7 @@ void ScreenTriangle::SetupNormal(const TriDrawTriangleArgs *args, WorkerThreadDa
|
|||
int stencilPitch = args->stencilPitch;
|
||||
uint8_t * RESTRICT stencilValues = args->stencilValues;
|
||||
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
|
||||
uint8_t stencilTestValue = args->stencilTestValue;
|
||||
uint8_t stencilTestValue = args->uniforms->StencilTestValue();
|
||||
|
||||
TriFullSpan * RESTRICT span = thread->FullSpans;
|
||||
TriPartialBlock * RESTRICT partial = thread->PartialBlocks;
|
||||
|
@ -389,10 +389,10 @@ void ScreenTriangle::SetupSubsector(const TriDrawTriangleArgs *args, WorkerThrea
|
|||
int stencilPitch = args->stencilPitch;
|
||||
uint8_t * RESTRICT stencilValues = args->stencilValues;
|
||||
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
|
||||
uint8_t stencilTestValue = args->stencilTestValue;
|
||||
uint8_t stencilTestValue = args->uniforms->StencilTestValue();
|
||||
|
||||
uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer;
|
||||
uint32_t subsectorDepth = args->uniforms->subsectorDepth;
|
||||
uint32_t subsectorDepth = args->uniforms->SubsectorDepth();
|
||||
int32_t pitch = args->pitch;
|
||||
|
||||
TriFullSpan * RESTRICT span = thread->FullSpans;
|
||||
|
@ -800,7 +800,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD
|
|||
{
|
||||
uint8_t * RESTRICT stencilValues = args->stencilValues;
|
||||
uint32_t * RESTRICT stencilMasks = args->stencilMasks;
|
||||
uint32_t stencilWriteValue = args->stencilWriteValue;
|
||||
uint32_t stencilWriteValue = args->uniforms->StencilWriteValue();
|
||||
uint32_t stencilPitch = args->stencilPitch;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
|
@ -869,7 +869,7 @@ void ScreenTriangle::StencilWrite(const TriDrawTriangleArgs *args, WorkerThreadD
|
|||
void ScreenTriangle::SubsectorWrite(const TriDrawTriangleArgs *args, WorkerThreadData *thread)
|
||||
{
|
||||
uint32_t * RESTRICT subsectorGBuffer = args->subsectorGBuffer;
|
||||
uint32_t subsectorDepth = args->uniforms->subsectorDepth;
|
||||
uint32_t subsectorDepth = args->uniforms->SubsectorDepth();
|
||||
int pitch = args->pitch;
|
||||
|
||||
int numSpans = thread->NumFullSpans;
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include <vector>
|
||||
|
||||
class FString;
|
||||
class PolyDrawArgs;
|
||||
|
||||
struct TriFullSpan
|
||||
{
|
||||
|
@ -67,32 +68,6 @@ struct TriVertex
|
|||
float varying[NumVarying];
|
||||
};
|
||||
|
||||
struct TriUniforms
|
||||
{
|
||||
uint32_t light;
|
||||
uint32_t subsectorDepth;
|
||||
uint32_t color;
|
||||
uint32_t srcalpha;
|
||||
uint32_t destalpha;
|
||||
uint16_t light_alpha;
|
||||
uint16_t light_red;
|
||||
uint16_t light_green;
|
||||
uint16_t light_blue;
|
||||
uint16_t fade_alpha;
|
||||
uint16_t fade_red;
|
||||
uint16_t fade_green;
|
||||
uint16_t fade_blue;
|
||||
uint16_t desaturate;
|
||||
float globvis;
|
||||
uint32_t flags;
|
||||
enum Flags
|
||||
{
|
||||
simple_shade = 1,
|
||||
nearest_filter = 2,
|
||||
fixed_light = 4
|
||||
};
|
||||
};
|
||||
|
||||
struct TriDrawTriangleArgs
|
||||
{
|
||||
uint8_t *dest;
|
||||
|
@ -104,20 +79,11 @@ struct TriDrawTriangleArgs
|
|||
int32_t clipright;
|
||||
int32_t cliptop;
|
||||
int32_t clipbottom;
|
||||
const uint8_t *texturePixels;
|
||||
uint32_t textureWidth;
|
||||
uint32_t textureHeight;
|
||||
const uint8_t *translation;
|
||||
const TriUniforms *uniforms;
|
||||
uint8_t *stencilValues;
|
||||
uint32_t *stencilMasks;
|
||||
int32_t stencilPitch;
|
||||
uint8_t stencilTestValue;
|
||||
uint8_t stencilWriteValue;
|
||||
uint32_t *subsectorGBuffer;
|
||||
const uint8_t *colormaps;
|
||||
const uint8_t *RGB256k;
|
||||
const uint8_t *BaseColors;
|
||||
const PolyDrawArgs *uniforms;
|
||||
};
|
||||
|
||||
enum class TriBlendMode
|
||||
|
|
|
@ -1,235 +0,0 @@
|
|||
/*
|
||||
** Various 3D intersection tests
|
||||
** Copyright (c) 1997-2015 The UICore Team
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
**
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include "templates.h"
|
||||
#include "doomdef.h"
|
||||
#include "poly_intersection.h"
|
||||
|
||||
IntersectionTest::Result IntersectionTest::plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f center = aabb.center();
|
||||
Vec3f extents = aabb.extents();
|
||||
float e = extents.x * std::abs(plane.x) + extents.y * std::abs(plane.y) + extents.z * std::abs(plane.z);
|
||||
float s = center.x * plane.x + center.y * plane.y + center.z * plane.z + plane.w;
|
||||
if (s - e > 0)
|
||||
return inside;
|
||||
else if (s + e < 0)
|
||||
return outside;
|
||||
else
|
||||
return intersecting;
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb)
|
||||
{
|
||||
Vec3f n(plane);
|
||||
float d = plane.w;
|
||||
float e = obb.extents.x * std::abs(Vec3f::dot(obb.axis_x, n)) + obb.extents.y * std::abs(Vec3f::dot(obb.axis_y, n)) + obb.extents.z * std::abs(Vec3f::dot(obb.axis_z, n));
|
||||
float s = Vec3f::dot(obb.center, n) + d;
|
||||
if (s - e > 0)
|
||||
return inside;
|
||||
else if (s + e < 0)
|
||||
return outside;
|
||||
else
|
||||
return intersecting;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2)
|
||||
{
|
||||
Vec3f h = center1 - center2;
|
||||
float square_distance = Vec3f::dot(h, h);
|
||||
float radius_sum = radius1 + radius2;
|
||||
if (square_distance > radius_sum * radius_sum)
|
||||
return disjoint;
|
||||
else
|
||||
return overlap;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f a = aabb.aabb_min - center;
|
||||
Vec3f b = center - aabb.aabb_max;
|
||||
a.x = std::max(a.x, 0.0f);
|
||||
a.y = std::max(a.y, 0.0f);
|
||||
a.z = std::max(a.z, 0.0f);
|
||||
b.x = std::max(b.x, 0.0f);
|
||||
b.y = std::max(b.y, 0.0f);
|
||||
b.z = std::max(b.z, 0.0f);
|
||||
Vec3f e = a + b;
|
||||
float d = Vec3f::dot(e, e);
|
||||
if (d > radius * radius)
|
||||
return disjoint;
|
||||
else
|
||||
return overlap;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b)
|
||||
{
|
||||
if (a.aabb_min.x > b.aabb_max.x || b.aabb_min.x > a.aabb_max.x ||
|
||||
a.aabb_min.y > b.aabb_max.y || b.aabb_min.y > a.aabb_max.y ||
|
||||
a.aabb_min.z > b.aabb_max.z || b.aabb_min.z > a.aabb_max.z)
|
||||
{
|
||||
return disjoint;
|
||||
}
|
||||
else
|
||||
{
|
||||
return overlap;
|
||||
}
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box)
|
||||
{
|
||||
bool is_intersecting = false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Result result = plane_aabb(frustum.planes[i], box);
|
||||
if (result == outside)
|
||||
return outside;
|
||||
else if (result == intersecting)
|
||||
is_intersecting = true;
|
||||
break;
|
||||
}
|
||||
if (is_intersecting)
|
||||
return intersecting;
|
||||
else
|
||||
return inside;
|
||||
}
|
||||
|
||||
IntersectionTest::Result IntersectionTest::frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box)
|
||||
{
|
||||
bool is_intersecting = false;
|
||||
for (int i = 0; i < 6; i++)
|
||||
{
|
||||
Result result = plane_obb(frustum.planes[i], box);
|
||||
if (result == outside)
|
||||
return outside;
|
||||
else if (result == intersecting)
|
||||
is_intersecting = true;
|
||||
}
|
||||
if (is_intersecting)
|
||||
return intersecting;
|
||||
else
|
||||
return inside;
|
||||
}
|
||||
|
||||
IntersectionTest::OverlapResult IntersectionTest::ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &aabb)
|
||||
{
|
||||
Vec3f c = (ray_start + ray_end) * 0.5f;
|
||||
Vec3f w = ray_end - c;
|
||||
Vec3f h = aabb.extents();
|
||||
|
||||
c -= aabb.center();
|
||||
|
||||
Vec3f v(std::abs(w.x), std::abs(w.y), std::abs(w.z));
|
||||
|
||||
if (std::abs(c.x) > v.x + h.x || std::abs(c.y) > v.y + h.y || std::abs(c.z) > v.z + h.z)
|
||||
return disjoint;
|
||||
|
||||
if (std::abs(c.y * w.z - c.z * w.y) > h.y * v.z + h.z * v.y ||
|
||||
std::abs(c.x * w.z - c.z * w.x) > h.x * v.z + h.z * v.x ||
|
||||
std::abs(c.x * w.y - c.y * w.x) > h.x * v.y + h.y * v.x)
|
||||
return disjoint;
|
||||
|
||||
return overlap;
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
FrustumPlanes::FrustumPlanes()
|
||||
{
|
||||
}
|
||||
|
||||
FrustumPlanes::FrustumPlanes(const Mat4f &world_to_projection)
|
||||
{
|
||||
planes[0] = near_frustum_plane(world_to_projection);
|
||||
planes[1] = far_frustum_plane(world_to_projection);
|
||||
planes[2] = left_frustum_plane(world_to_projection);
|
||||
planes[3] = right_frustum_plane(world_to_projection);
|
||||
planes[4] = top_frustum_plane(world_to_projection);
|
||||
planes[5] = bottom_frustum_plane(world_to_projection);
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::left_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[0 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[0 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[0 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[0 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::right_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[0 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[0 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[0 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[0 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::top_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[1 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[1 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[1 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[1 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::bottom_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[1 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[1 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[1 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[1 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::near_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] + m.matrix[2 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] + m.matrix[2 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] + m.matrix[2 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] + m.matrix[2 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
||||
|
||||
Vec4f FrustumPlanes::far_frustum_plane(const Mat4f &m)
|
||||
{
|
||||
Vec4f plane(
|
||||
m.matrix[3 + 0 * 4] - m.matrix[2 + 0 * 4],
|
||||
m.matrix[3 + 1 * 4] - m.matrix[2 + 1 * 4],
|
||||
m.matrix[3 + 2 * 4] - m.matrix[2 + 2 * 4],
|
||||
m.matrix[3 + 3 * 4] - m.matrix[2 + 3 * 4]);
|
||||
plane /= plane.length3();
|
||||
return plane;
|
||||
}
|
|
@ -1,179 +0,0 @@
|
|||
/*
|
||||
** Various 3D intersection tests
|
||||
** Copyright (c) 1997-2015 The UICore Team
|
||||
**
|
||||
** This software is provided 'as-is', without any express or implied
|
||||
** warranty. In no event will the authors be held liable for any damages
|
||||
** arising from the use of this software.
|
||||
**
|
||||
** Permission is granted to anyone to use this software for any purpose,
|
||||
** including commercial applications, and to alter it and redistribute it
|
||||
** freely, subject to the following restrictions:
|
||||
**
|
||||
** 1. The origin of this software must not be misrepresented; you must not
|
||||
** claim that you wrote the original software. If you use this software
|
||||
** in a product, an acknowledgment in the product documentation would be
|
||||
** appreciated but is not required.
|
||||
** 2. Altered source versions must be plainly marked as such, and must not be
|
||||
** misrepresented as being the original software.
|
||||
** 3. This notice may not be removed or altered from any source distribution.
|
||||
**
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include <algorithm>
|
||||
#include <cmath>
|
||||
|
||||
class Vec3f;
|
||||
|
||||
class Vec4f
|
||||
{
|
||||
public:
|
||||
Vec4f() = default;
|
||||
Vec4f(const Vec4f &) = default;
|
||||
Vec4f(float x, float y, float z, float w) : x(x), y(y), z(z), w(w) { }
|
||||
Vec4f(float v) : x(v), y(v), z(v), w(v) { }
|
||||
Vec4f(const Vec3f &xyz, float w);
|
||||
|
||||
static float dot(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z + a.w * b.w; }
|
||||
static float dot3(const Vec4f &a, const Vec4f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||
float length3() const { return std::sqrt(dot3(*this, *this)); }
|
||||
float magnitude() const { return std::sqrt(dot(*this, *this)); }
|
||||
|
||||
Vec4f &operator+=(const Vec4f &b) { *this = Vec4f(x + b.x, y + b.y, z + b.z, w + b.w); return *this; }
|
||||
Vec4f &operator-=(const Vec4f &b) { *this = Vec4f(x - b.x, y - b.y, z - b.z, w - b.w); return *this; }
|
||||
Vec4f &operator*=(const Vec4f &b) { *this = Vec4f(x * b.x, y * b.y, z * b.z, w * b.w); return *this; }
|
||||
Vec4f &operator/=(const Vec4f &b) { *this = Vec4f(x / b.x, y / b.y, z / b.z, w / b.w); return *this; }
|
||||
Vec4f &operator+=(float b) { *this = Vec4f(x + b, y + b, z + b, w + b); return *this; }
|
||||
Vec4f &operator-=(float b) { *this = Vec4f(x - b, y - b, z - b, w - b); return *this; }
|
||||
Vec4f &operator*=(float b) { *this = Vec4f(x * b, y * b, z * b, w * b); return *this; }
|
||||
Vec4f &operator/=(float b) { *this = Vec4f(x / b, y / b, z / b, w / b); return *this; }
|
||||
|
||||
float x, y, z, w;
|
||||
};
|
||||
|
||||
inline bool operator==(const Vec4f &a, const Vec4f &b) { return a.x == b.x && a.y == b.y && a.z == b.z && a.w == b.w; }
|
||||
inline bool operator!=(const Vec4f &a, const Vec4f &b) { return a.x != b.x || a.y != b.y || a.z != b.z || a.w == b.w; }
|
||||
|
||||
class Vec3f
|
||||
{
|
||||
public:
|
||||
Vec3f() = default;
|
||||
Vec3f(const Vec3f &) = default;
|
||||
Vec3f(const Vec4f &v) : x(v.x), y(v.y), z(v.z) { }
|
||||
Vec3f(float x, float y, float z) : x(x), y(y), z(z) { }
|
||||
Vec3f(float v) : x(v), y(v), z(v) { }
|
||||
|
||||
static float dot(const Vec3f &a, const Vec3f &b) { return a.x * b.x + a.y * b.y + a.z * b.z; }
|
||||
float length() const { return std::sqrt(dot(*this, *this)); }
|
||||
|
||||
Vec3f &operator+=(const Vec3f &b) { *this = Vec3f(x + b.x, y + b.y, z + b.z); return *this; }
|
||||
Vec3f &operator-=(const Vec3f &b) { *this = Vec3f(x - b.x, y - b.y, z - b.z); return *this; }
|
||||
Vec3f &operator*=(const Vec3f &b) { *this = Vec3f(x * b.x, y * b.y, z * b.z); return *this; }
|
||||
Vec3f &operator/=(const Vec3f &b) { *this = Vec3f(x / b.x, y / b.y, z / b.z); return *this; }
|
||||
Vec3f &operator+=(float b) { *this = Vec3f(x + b, y + b, z + b); return *this; }
|
||||
Vec3f &operator-=(float b) { *this = Vec3f(x - b, y - b, z - b); return *this; }
|
||||
Vec3f &operator*=(float b) { *this = Vec3f(x * b, y * b, z * b); return *this; }
|
||||
Vec3f &operator/=(float b) { *this = Vec3f(x / b, y / b, z / b); return *this; }
|
||||
|
||||
float x, y, z;
|
||||
};
|
||||
|
||||
inline bool operator==(const Vec3f &a, const Vec3f &b) { return a.x == b.x && a.y == b.y && a.z == b.z; }
|
||||
inline bool operator!=(const Vec3f &a, const Vec3f &b) { return a.x != b.x || a.y != b.y || a.z != b.z; }
|
||||
|
||||
inline Vec3f operator+(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x + b.x, a.y + b.y, a.z + b.z); }
|
||||
inline Vec3f operator-(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x - b.x, a.y - b.y, a.z - b.z); }
|
||||
inline Vec3f operator*(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x * b.x, a.y * b.y, a.z * b.z); }
|
||||
inline Vec3f operator/(const Vec3f &a, const Vec3f &b) { return Vec3f(a.x / b.x, a.y / b.y, a.z / b.z); }
|
||||
|
||||
inline Vec3f operator+(const Vec3f &a, float b) { return Vec3f(a.x + b, a.y + b, a.z + b); }
|
||||
inline Vec3f operator-(const Vec3f &a, float b) { return Vec3f(a.x - b, a.y - b, a.z - b); }
|
||||
inline Vec3f operator*(const Vec3f &a, float b) { return Vec3f(a.x * b, a.y * b, a.z * b); }
|
||||
inline Vec3f operator/(const Vec3f &a, float b) { return Vec3f(a.x / b, a.y / b, a.z / b); }
|
||||
|
||||
inline Vec3f operator+(float a, const Vec3f &b) { return Vec3f(a + b.x, a + b.y, a + b.z); }
|
||||
inline Vec3f operator-(float a, const Vec3f &b) { return Vec3f(a - b.x, a - b.y, a - b.z); }
|
||||
inline Vec3f operator*(float a, const Vec3f &b) { return Vec3f(a * b.x, a * b.y, a * b.z); }
|
||||
inline Vec3f operator/(float a, const Vec3f &b) { return Vec3f(a / b.x, a / b.y, a / b.z); }
|
||||
|
||||
inline Vec4f::Vec4f(const Vec3f &xyz, float w) : x(xyz.x), y(xyz.y), z(xyz.z), w(w) { }
|
||||
|
||||
typedef TriMatrix Mat4f;
|
||||
|
||||
class AxisAlignedBoundingBox
|
||||
{
|
||||
public:
|
||||
AxisAlignedBoundingBox() : aabb_min(), aabb_max() {}
|
||||
AxisAlignedBoundingBox(const Vec3f &aabb_min, const Vec3f &aabb_max) : aabb_min(aabb_min), aabb_max(aabb_max) { }
|
||||
AxisAlignedBoundingBox(const AxisAlignedBoundingBox &aabb, const Vec3f &barycentric_min, const Vec3f &barycentric_max)
|
||||
: aabb_min(mix(aabb.aabb_min, aabb.aabb_max, barycentric_min)), aabb_max(mix(aabb.aabb_min, aabb.aabb_max, barycentric_max)) { }
|
||||
|
||||
Vec3f center() const { return (aabb_max + aabb_min) * 0.5f; }
|
||||
Vec3f extents() const { return (aabb_max - aabb_min) * 0.5f; }
|
||||
|
||||
Vec3f aabb_min;
|
||||
Vec3f aabb_max;
|
||||
|
||||
private:
|
||||
template<typename A, typename B, typename C>
|
||||
inline A mix(A a, B b, C mix)
|
||||
{
|
||||
return a * (C(1) - mix) + b * mix;
|
||||
}
|
||||
};
|
||||
|
||||
class OrientedBoundingBox
|
||||
{
|
||||
public:
|
||||
Vec3f center;
|
||||
Vec3f extents;
|
||||
Vec3f axis_x;
|
||||
Vec3f axis_y;
|
||||
Vec3f axis_z;
|
||||
};
|
||||
|
||||
class FrustumPlanes
|
||||
{
|
||||
public:
|
||||
FrustumPlanes();
|
||||
explicit FrustumPlanes(const Mat4f &world_to_projection);
|
||||
|
||||
Vec4f planes[6];
|
||||
|
||||
private:
|
||||
static Vec4f left_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f right_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f top_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f bottom_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f near_frustum_plane(const Mat4f &matrix);
|
||||
static Vec4f far_frustum_plane(const Mat4f &matrix);
|
||||
};
|
||||
|
||||
class IntersectionTest
|
||||
{
|
||||
public:
|
||||
enum Result
|
||||
{
|
||||
outside,
|
||||
inside,
|
||||
intersecting,
|
||||
};
|
||||
|
||||
enum OverlapResult
|
||||
{
|
||||
disjoint,
|
||||
overlap
|
||||
};
|
||||
|
||||
static Result plane_aabb(const Vec4f &plane, const AxisAlignedBoundingBox &aabb);
|
||||
static Result plane_obb(const Vec4f &plane, const OrientedBoundingBox &obb);
|
||||
static OverlapResult sphere(const Vec3f ¢er1, float radius1, const Vec3f ¢er2, float radius2);
|
||||
static OverlapResult sphere_aabb(const Vec3f ¢er, float radius, const AxisAlignedBoundingBox &aabb);
|
||||
static OverlapResult aabb(const AxisAlignedBoundingBox &a, const AxisAlignedBoundingBox &b);
|
||||
static Result frustum_aabb(const FrustumPlanes &frustum, const AxisAlignedBoundingBox &box);
|
||||
static Result frustum_obb(const FrustumPlanes &frustum, const OrientedBoundingBox &box);
|
||||
static OverlapResult ray_aabb(const Vec3f &ray_start, const Vec3f &ray_end, const AxisAlignedBoundingBox &box);
|
||||
};
|
|
@ -3,7 +3,6 @@
|
|||
#include "drawers/poly_draw_args.cpp"
|
||||
#include "drawers/poly_triangle.cpp"
|
||||
#include "drawers/screen_triangle.cpp"
|
||||
#include "math/poly_intersection.cpp"
|
||||
#include "math/tri_matrix.cpp"
|
||||
#include "scene/poly_cull.cpp"
|
||||
#include "scene/poly_decal.cpp"
|
||||
|
|
|
@ -135,7 +135,7 @@ void PolyRenderer::RenderActorView(AActor *actor, bool dontmaplines)
|
|||
ClearBuffers();
|
||||
SetSceneViewport();
|
||||
SetupPerspectiveMatrix();
|
||||
MainPortal.SetViewpoint(WorldToClip, Vec4f(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
|
||||
MainPortal.SetViewpoint(WorldToClip, PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f), GetNextStencilValue());
|
||||
MainPortal.Render(0);
|
||||
Skydome.Render(WorldToClip);
|
||||
MainPortal.RenderTranslucent(0);
|
||||
|
|
|
@ -28,10 +28,9 @@
|
|||
#include "poly_cull.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
|
||||
void PolyCull::CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane)
|
||||
void PolyCull::CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane)
|
||||
{
|
||||
PvsSectors.clear();
|
||||
frustumPlanes = FrustumPlanes(worldToClip);
|
||||
PortalClipPlane = portalClipPlane;
|
||||
|
||||
// Cull front to back
|
||||
|
@ -210,20 +209,6 @@ int PolyCull::PointOnSide(const DVector2 &pos, const node_t *node)
|
|||
|
||||
bool PolyCull::CheckBBox(float *bspcoord)
|
||||
{
|
||||
#if 0 // This doesn't work because it creates gaps in the angle based clipper segment list :(
|
||||
// Start using a quick frustum AABB test:
|
||||
|
||||
AxisAlignedBoundingBox aabb(Vec3f(bspcoord[BOXLEFT], bspcoord[BOXBOTTOM], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z - 1000.0f), Vec3f(bspcoord[BOXRIGHT], bspcoord[BOXTOP], (float)PolyRenderer::Instance()->Viewpoint.Pos.Z + 1000.0f));
|
||||
auto result = IntersectionTest::frustum_aabb(frustumPlanes, aabb);
|
||||
if (result == IntersectionTest::outside)
|
||||
return false;
|
||||
|
||||
// Skip if its in front of the portal:
|
||||
|
||||
if (IntersectionTest::plane_aabb(PortalClipPlane, aabb) == IntersectionTest::outside)
|
||||
return false;
|
||||
#endif
|
||||
|
||||
// Occlusion test using solid segments:
|
||||
static const uint8_t checkcoord[12][4] =
|
||||
{
|
||||
|
|
|
@ -23,13 +23,12 @@
|
|||
#pragma once
|
||||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include "polyrenderer/math/poly_intersection.h"
|
||||
|
||||
class PolyCull
|
||||
{
|
||||
public:
|
||||
void ClearSolidSegments();
|
||||
void CullScene(const TriMatrix &worldToClip, const Vec4f &portalClipPlane);
|
||||
void CullScene(const TriMatrix &worldToClip, const PolyClipPlane &portalClipPlane);
|
||||
|
||||
bool GetAnglesForLine(double x1, double y1, double x2, double y2, angle_t &angle1, angle_t &angle2) const;
|
||||
void MarkSegmentCulled(angle_t angle1, angle_t angle2);
|
||||
|
@ -61,8 +60,7 @@ private:
|
|||
const int SolidCullScale = 3000;
|
||||
bool FirstSkyHeight = true;
|
||||
|
||||
FrustumPlanes frustumPlanes;
|
||||
Vec4f PortalClipPlane;
|
||||
PolyClipPlane PortalClipPlane;
|
||||
|
||||
static angle_t PointToPseudoAngle(double x, double y);
|
||||
static angle_t AngleToPseudo(angle_t ang);
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
#include "a_sharedglobal.h"
|
||||
#include "swrenderer/scene/r_scene.h"
|
||||
|
||||
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
{
|
||||
if (line->linedef == nullptr && line->sidedef == nullptr)
|
||||
return;
|
||||
|
@ -43,7 +43,7 @@ void RenderPolyDecal::RenderWallDecals(const TriMatrix &worldToClip, const Vec4f
|
|||
}
|
||||
}
|
||||
|
||||
void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
void RenderPolyDecal::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
{
|
||||
if (decal->RenderFlags & RF_INVISIBLE || !viewactive || !decal->PicNum.isValid())
|
||||
return;
|
||||
|
@ -130,49 +130,21 @@ void RenderPolyDecal::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
|||
}
|
||||
|
||||
bool fullbrightSprite = (decal->RenderFlags & RF_FULLBRIGHT) == RF_FULLBRIGHT;
|
||||
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
int lightlevel = fullbrightSprite ? 255 : front->lightlevel + actualextralight;
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
args.SetColormap(GetColorTable(front->Colormap));
|
||||
args.SetLight(GetColorTable(front->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
|
||||
args.SetTexture(tex, decal->Translation, true);
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
|
||||
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
{
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags |= TriUniforms::fixed_light;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.light = (uint32_t)((front->lightlevel + actualextralight) / 255.0f * 256.0f);
|
||||
}
|
||||
args.uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
args.uniforms.color = 0xff000000 | decal->AlphaColor;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.color = ((uint32_t)decal->AlphaColor) >> 24;
|
||||
}
|
||||
|
||||
args.uniforms.srcalpha = (uint32_t)(decal->Alpha * 256.0 + 0.5);
|
||||
args.uniforms.destalpha = 256 - args.uniforms.srcalpha;
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = 4;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue;
|
||||
//mode = R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
args.blendmode = TriBlendMode::Shaded;
|
||||
args.subsectorTest = true;
|
||||
args.writeStencil = false;
|
||||
args.writeSubsector = false;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetColor(0xff000000 | decal->AlphaColor, decal->AlphaColor >> 24);
|
||||
args.SetStyle(TriBlendMode::Shaded, decal->Alpha, 1.0 - decal->Alpha); // R_SetPatchStyle (decal->RenderStyle, (float)decal->Alpha, decal->Translation, decal->AlphaColor);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue);
|
||||
args.SetClipPlane(clipPlane);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -24,13 +24,11 @@
|
|||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolyDecal
|
||||
{
|
||||
public:
|
||||
static void RenderWallDecals(const TriMatrix &worldToClip, const Vec4f &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
static void RenderWallDecals(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
|
||||
private:
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, DBaseDecal *decal, const seg_t *line, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
};
|
||||
|
|
|
@ -25,6 +25,7 @@
|
|||
#include "doomdef.h"
|
||||
#include "sbar.h"
|
||||
#include "poly_light.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
|
||||
fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
|
||||
{
|
||||
|
@ -41,3 +42,8 @@ fixed_t PolyLightVisibility::LightLevelToShade(int lightlevel, bool foggy)
|
|||
return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128));
|
||||
}
|
||||
}
|
||||
|
||||
double PolyLightVisibility::FocalTangent()
|
||||
{
|
||||
return PolyRenderer::Instance()->Viewwindow.FocalTangent;
|
||||
}
|
||||
|
|
|
@ -31,9 +31,9 @@ typedef swrenderer::CameraLight PolyCameraLight;
|
|||
class PolyLightVisibility
|
||||
{
|
||||
public:
|
||||
double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; }
|
||||
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : WallVisibility; }
|
||||
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0f : (WallVisibility * 0.5); }
|
||||
double WallGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); }
|
||||
double SpriteGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility / FocalTangent(); }
|
||||
double ParticleGlobVis(bool foggy) const { return (NoLightFade && !foggy) ? 0.0 : WallVisibility * 0.5 / FocalTangent(); }
|
||||
|
||||
// The vis value to pass into the GETPALOOKUP or LIGHTSCALE macros
|
||||
double WallVis(double screenZ, bool foggy) const { return WallGlobVis(foggy) / screenZ; }
|
||||
|
@ -43,6 +43,8 @@ public:
|
|||
static fixed_t LightLevelToShade(int lightlevel, bool foggy);
|
||||
|
||||
private:
|
||||
static double FocalTangent();
|
||||
|
||||
// 1706 is the value for walls on 1080p 16:9 displays.
|
||||
double WallVisibility = 1706.0;
|
||||
bool NoLightFade = false;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
void RenderPolyParticle::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
{
|
||||
DVector3 pos = particle->Pos;
|
||||
double psize = particle->size / 8.0;
|
||||
|
@ -68,51 +68,20 @@ void RenderPolyParticle::Render(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
vertices[i].varying[1] = (float)(1.0f - offsets[i].second);
|
||||
}
|
||||
|
||||
// int color = (particle->color >> 24) & 0xff; // pal index, I think
|
||||
bool fullbrightSprite = particle->bright != 0;
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
int lightlevel = fullbrightSprite ? 255 : sub->sector->lightlevel + actualextralight;
|
||||
|
||||
PolyDrawArgs args;
|
||||
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.ParticleGlobVis(foggy);
|
||||
|
||||
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
{
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.light = (uint32_t)((sub->sector->lightlevel + actualextralight) / 255.0f * 256.0f);
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
}
|
||||
args.uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
uint32_t alpha = (uint32_t)clamp(particle->alpha * 255.0f + 0.5f, 0.0f, 255.0f);
|
||||
|
||||
if (PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
args.uniforms.color = (alpha << 24) | (particle->color & 0xffffff);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.color = ((uint32_t)particle->color) >> 24;
|
||||
args.uniforms.srcalpha = alpha;
|
||||
args.uniforms.destalpha = 255 - alpha;
|
||||
}
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = 4;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue;
|
||||
args.SetColormap(GetColorTable(sub->sector->Colormap));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
args.subsectorTest = true;
|
||||
args.writeStencil = false;
|
||||
args.writeSubsector = false;
|
||||
args.blendmode = TriBlendMode::AlphaBlend;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.ParticleGlobVis(foggy), fullbrightSprite);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetColor(particle->color | 0xff000000, particle->color >> 24);
|
||||
args.SetStyle(TriBlendMode::AlphaBlend, particle->alpha, 1.0 - particle->alpha);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetClipPlane(clipPlane);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -25,10 +25,8 @@
|
|||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include "p_effect.h"
|
||||
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolyParticle
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, particle_t *particle, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
};
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
|
||||
EXTERN_CVAR(Int, r_3dfloors)
|
||||
|
||||
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
{
|
||||
RenderPolyPlane plane;
|
||||
|
||||
|
@ -91,7 +91,7 @@ void RenderPolyPlane::RenderPlanes(const TriMatrix &worldToClip, const Vec4f &cl
|
|||
plane.Render(worldToClip, clipPlane, cull, sub, subsectorDepth, stencilValue, false, skyFloorHeight, sectorPortals);
|
||||
}
|
||||
|
||||
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
|
||||
void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakeFloor)
|
||||
{
|
||||
FTextureID picnum = ceiling ? *fakeFloor->bottom.texture : *fakeFloor->top.texture;
|
||||
FTexture *tex = TexMan(picnum);
|
||||
|
@ -111,16 +111,7 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
|
|||
|
||||
UVTransform xform(ceiling ? fakeFloor->top.model->planes[sector_t::ceiling].xform : fakeFloor->top.model->planes[sector_t::floor].xform, tex);
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy); // .SlopePlaneGlobVis(foggy) * 48.0f;
|
||||
args.uniforms.light = (uint32_t)(lightlevel / 255.0f * 256.0f);
|
||||
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
args.uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
||||
|
||||
if (ceiling)
|
||||
{
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
|
@ -138,21 +129,20 @@ void RenderPolyPlane::Render3DFloor(const TriMatrix &worldToClip, const Vec4f &c
|
|||
}
|
||||
}
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = sub->numlines;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue + 1;
|
||||
PolyDrawArgs args;
|
||||
args.SetLight(GetColorTable(sub->sector->Colormap), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
args.SetTexture(tex);
|
||||
args.SetColormap(GetColorTable(sub->sector->Colormap));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
args.blendmode = TriBlendMode::Copy;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetClipPlane(clipPlane);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
void RenderPolyPlane::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals)
|
||||
{
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
bool foggy = false;
|
||||
|
@ -291,16 +281,6 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
|||
|
||||
UVTransform transform(ceiling ? frontsector->planes[sector_t::ceiling].xform : frontsector->planes[sector_t::floor].xform, tex);
|
||||
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);// ->SlopePlaneGlobVis(foggy) * 48.0f;
|
||||
args.uniforms.light = (uint32_t)(frontsector->lightlevel / 255.0f * 256.0f);
|
||||
if (cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
args.uniforms.subsectorDepth = isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth;
|
||||
|
||||
TriVertex *vertices = PolyRenderer::Instance()->FrameMemory.AllocMemory<TriVertex>(sub->numlines);
|
||||
|
||||
if (ceiling)
|
||||
|
@ -320,37 +300,36 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
|||
}
|
||||
}
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = sub->numlines;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = ccw;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue + 1;
|
||||
args.SetColormap(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
PolyDrawArgs args;
|
||||
args.SetLight(GetColorTable(frontsector->Colormap, frontsector->SpecialColors[ceiling]), frontsector->lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
||||
args.SetSubsectorDepth(isSky ? RenderPolyScene::SkySubsectorDepth : subsectorDepth);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(ccw);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue + 1);
|
||||
args.SetClipPlane(clipPlane);
|
||||
|
||||
if (!isSky)
|
||||
{
|
||||
args.SetTexture(tex);
|
||||
args.blendmode = TriBlendMode::Copy;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (portal)
|
||||
{
|
||||
args.stencilwritevalue = polyportal->StencilValue;
|
||||
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
||||
args.SetWriteStencil(true, polyportal->StencilValue);
|
||||
polyportal->Shape.push_back({ vertices, (int)sub->numlines, ccw, subsectorDepth });
|
||||
}
|
||||
else
|
||||
{
|
||||
args.stencilwritevalue = 255;
|
||||
args.SetWriteStencil(true, 255);
|
||||
}
|
||||
|
||||
args.writeColor = false;
|
||||
args.writeSubsector = false;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetWriteColor(false);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.DrawArray(vertices, sub->numlines, PolyDrawMode::TriangleFan);
|
||||
|
||||
for (uint32_t i = 0; i < sub->numlines; i++)
|
||||
{
|
||||
|
@ -414,13 +393,11 @@ void RenderPolyPlane::Render(const TriMatrix &worldToClip, const Vec4f &clipPlan
|
|||
wallvert[3] = PlaneVertex(line->v1, skyHeight, transform);
|
||||
}
|
||||
|
||||
args.vinput = wallvert;
|
||||
args.vcount = 4;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.DrawArray(wallvert, 4, PolyDrawMode::TriangleFan);
|
||||
|
||||
if (portal)
|
||||
{
|
||||
polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, subsectorDepth });
|
||||
polyportal->Shape.push_back({ wallvert, 4, ccw, subsectorDepth });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,12 +26,11 @@
|
|||
|
||||
class PolyDrawSectorPortal;
|
||||
class PolyCull;
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolyPlane
|
||||
{
|
||||
public:
|
||||
static void RenderPlanes(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
static void RenderPlanes(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, double skyCeilingHeight, double skyFloorHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
|
||||
private:
|
||||
struct UVTransform
|
||||
|
@ -48,7 +47,7 @@ private:
|
|||
float xOffs, yOffs;
|
||||
};
|
||||
|
||||
void Render3DFloor(const TriMatrix &worldToClip, const Vec4f &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
void Render3DFloor(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, F3DFloor *fakefloor);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, bool ceiling, double skyHeight, std::vector<std::unique_ptr<PolyDrawSectorPortal>> §orPortals);
|
||||
TriVertex PlaneVertex(vertex_t *v1, double height, const UVTransform &transform);
|
||||
};
|
||||
|
|
|
@ -28,7 +28,6 @@
|
|||
#include "poly_playersprite.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "d_player.h"
|
||||
#include "swrenderer/viewport/r_viewport.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
EXTERN_CVAR(Bool, r_drawplayersprites)
|
||||
|
@ -44,6 +43,14 @@ void RenderPolyPlayerSprites::Render()
|
|||
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
int i;
|
||||
int lightnum;
|
||||
DPSprite* psp;
|
||||
DPSprite* weapon;
|
||||
sector_t* sec = nullptr;
|
||||
int floorlight, ceilinglight;
|
||||
F3DFloor *rover;
|
||||
|
||||
if (!r_drawplayersprites ||
|
||||
!viewpoint.camera ||
|
||||
!viewpoint.camera->player ||
|
||||
|
@ -51,282 +58,427 @@ void RenderPolyPlayerSprites::Render()
|
|||
(r_deathcamera && viewpoint.camera->health <= 0))
|
||||
return;
|
||||
|
||||
float bobx, boby;
|
||||
P_BobWeapon(viewpoint.camera->player, &bobx, &boby, viewpoint.TicFrac);
|
||||
|
||||
// Interpolate the main weapon layer once so as to be able to add it to other layers.
|
||||
double wx, wy;
|
||||
DPSprite *weapon = viewpoint.camera->player->FindPSprite(PSP_WEAPON);
|
||||
if (weapon)
|
||||
FDynamicColormap *basecolormap;
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
if (cameraLight->FixedLightLevel() < 0 && viewpoint.sector->e && viewpoint.sector->e->XFloor.lightlist.Size())
|
||||
{
|
||||
if (weapon->firstTic)
|
||||
for (i = viewpoint.sector->e->XFloor.lightlist.Size() - 1; i >= 0; i--)
|
||||
{
|
||||
wx = weapon->x;
|
||||
wy = weapon->y;
|
||||
if (viewpoint.Pos.Z <= viewpoint.sector->e->XFloor.lightlist[i].plane.Zat0())
|
||||
{
|
||||
rover = viewpoint.sector->e->XFloor.lightlist[i].caster;
|
||||
if (rover)
|
||||
{
|
||||
if (rover->flags & FF_DOUBLESHADOW && viewpoint.Pos.Z <= rover->bottom.plane->Zat0())
|
||||
break;
|
||||
sec = rover->model;
|
||||
if (rover->flags & FF_FADEWALLS)
|
||||
basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true);
|
||||
else
|
||||
basecolormap = GetColorTable(viewpoint.sector->e->XFloor.lightlist[i].extra_colormap, sec->SpecialColors[sector_t::sprites], true);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!sec)
|
||||
{
|
||||
sec = viewpoint.sector;
|
||||
basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true);
|
||||
}
|
||||
floorlight = ceilinglight = sec->lightlevel;
|
||||
}
|
||||
else
|
||||
{ // This used to use camera->Sector but due to interpolation that can be incorrect
|
||||
// when the interpolated viewpoint is in a different sector than the camera.
|
||||
//sec = FakeFlat(viewpoint.sector, &tempsec, &floorlight, &ceilinglight, nullptr, 0, 0, 0, 0);
|
||||
// Softpoly has no FakeFlat (its FAKE! Everything is FAKE in Doom. Sigh. Might as well call it FooFlat!)
|
||||
sec = viewpoint.camera->Sector;
|
||||
floorlight = ceilinglight = sec->lightlevel;
|
||||
|
||||
// [RH] set basecolormap
|
||||
basecolormap = GetColorTable(sec->Colormap, sec->SpecialColors[sector_t::sprites], true);
|
||||
}
|
||||
|
||||
// [RH] set foggy flag
|
||||
bool foggy = (level.fadeto || basecolormap->Fade || (level.flags & LEVEL_HASFADETABLE));
|
||||
|
||||
// get light level
|
||||
lightnum = ((floorlight + ceilinglight) >> 1) + (foggy ? 0 : viewpoint.extralight << 4);
|
||||
int spriteshade = LightLevelToShade(lightnum, foggy) - 24 * FRACUNIT;
|
||||
|
||||
if (viewpoint.camera->player != nullptr)
|
||||
{
|
||||
double wx, wy;
|
||||
float bobx, boby;
|
||||
|
||||
P_BobWeapon(viewpoint.camera->player, &bobx, &boby, viewpoint.TicFrac);
|
||||
|
||||
// Interpolate the main weapon layer once so as to be able to add it to other layers.
|
||||
if ((weapon = viewpoint.camera->player->FindPSprite(PSP_WEAPON)) != nullptr)
|
||||
{
|
||||
if (weapon->firstTic)
|
||||
{
|
||||
wx = weapon->x;
|
||||
wy = weapon->y;
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = weapon->oldx + (weapon->x - weapon->oldx) * viewpoint.TicFrac;
|
||||
wy = weapon->oldy + (weapon->y - weapon->oldy) * viewpoint.TicFrac;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = weapon->oldx + (weapon->x - weapon->oldx) * viewpoint.TicFrac;
|
||||
wy = weapon->oldy + (weapon->y - weapon->oldy) * viewpoint.TicFrac;
|
||||
wx = 0;
|
||||
wy = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
wx = 0;
|
||||
wy = 0;
|
||||
}
|
||||
|
||||
for (DPSprite *sprite = viewpoint.camera->player->psprites; sprite != nullptr; sprite = sprite->GetNext())
|
||||
{
|
||||
// [RH] Don't draw the targeter's crosshair if the player already has a crosshair set.
|
||||
// It's possible this psprite's caller is now null but the layer itself hasn't been destroyed
|
||||
// because it didn't tick yet (if we typed 'take all' while in the console for example).
|
||||
// In this case let's simply not draw it to avoid crashing.
|
||||
if ((sprite->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && sprite->GetCaller() != nullptr)
|
||||
// add all active psprites
|
||||
psp = viewpoint.camera->player->psprites;
|
||||
while (psp)
|
||||
{
|
||||
RenderSprite(sprite, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac);
|
||||
// [RH] Don't draw the targeter's crosshair if the player already has a crosshair set.
|
||||
// It's possible this psprite's caller is now null but the layer itself hasn't been destroyed
|
||||
// because it didn't tick yet (if we typed 'take all' while in the console for example).
|
||||
// In this case let's simply not draw it to avoid crashing.
|
||||
|
||||
if ((psp->GetID() != PSP_TARGETCENTER || CrosshairImage == nullptr) && psp->GetCaller() != nullptr)
|
||||
{
|
||||
RenderSprite(psp, viewpoint.camera, bobx, boby, wx, wy, viewpoint.TicFrac, spriteshade, basecolormap, foggy);
|
||||
}
|
||||
|
||||
psp = psp->GetNext();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void RenderPolyPlayerSprites::RenderRemainingSprites()
|
||||
{
|
||||
for (auto &sprite : ScreenSprites)
|
||||
sprite.Render();
|
||||
ScreenSprites.clear();
|
||||
for (const PolyHWAccelPlayerSprite &sprite : AcceleratedSprites)
|
||||
{
|
||||
screen->DrawTexture(sprite.pic,
|
||||
viewwindowx + sprite.x1,
|
||||
viewwindowy + viewheight / 2 - sprite.texturemid * sprite.yscale - 0.5,
|
||||
DTA_DestWidthF, FIXED2DBL(sprite.pic->GetWidth() * sprite.xscale),
|
||||
DTA_DestHeightF, sprite.pic->GetHeight() * sprite.yscale,
|
||||
DTA_TranslationIndex, sprite.Translation,
|
||||
DTA_FlipX, sprite.flip,
|
||||
DTA_TopOffset, 0,
|
||||
DTA_LeftOffset, 0,
|
||||
DTA_ClipLeft, viewwindowx,
|
||||
DTA_ClipTop, viewwindowy,
|
||||
DTA_ClipRight, viewwindowx + viewwidth,
|
||||
DTA_ClipBottom, viewwindowy + viewheight,
|
||||
DTA_Alpha, sprite.Alpha,
|
||||
DTA_RenderStyle, sprite.RenderStyle,
|
||||
DTA_FillColor, sprite.FillColor,
|
||||
DTA_SpecialColormap, sprite.special,
|
||||
DTA_ColorOverlay, sprite.overlay.d,
|
||||
DTA_ColormapStyle, sprite.usecolormapstyle ? &sprite.colormapstyle : nullptr,
|
||||
TAG_DONE);
|
||||
}
|
||||
|
||||
AcceleratedSprites.Clear();
|
||||
}
|
||||
|
||||
void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac)
|
||||
void RenderPolyPlayerSprites::RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy)
|
||||
{
|
||||
double tx;
|
||||
int x1;
|
||||
int x2;
|
||||
double sx, sy;
|
||||
spritedef_t* sprdef;
|
||||
spriteframe_t* sprframe;
|
||||
FTextureID picnum;
|
||||
uint16_t flip;
|
||||
FTexture* tex;
|
||||
bool noaccel;
|
||||
double alpha = owner->Alpha;
|
||||
|
||||
// decide which patch to use
|
||||
if ((unsigned)sprite->GetSprite() >= (unsigned)sprites.Size())
|
||||
if ((unsigned)pspr->GetSprite() >= (unsigned)sprites.Size())
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "RenderPlayerSprite: invalid sprite number %i\n", sprite->GetSprite());
|
||||
DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite number %i\n", pspr->GetSprite());
|
||||
return;
|
||||
}
|
||||
sprdef = &sprites[pspr->GetSprite()];
|
||||
if (pspr->GetFrame() >= sprdef->numframes)
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "R_DrawPSprite: invalid sprite frame %i : %i\n", pspr->GetSprite(), pspr->GetFrame());
|
||||
return;
|
||||
}
|
||||
|
||||
spritedef_t *def = &sprites[sprite->GetSprite()];
|
||||
if (sprite->GetFrame() >= def->numframes)
|
||||
{
|
||||
DPrintf(DMSG_ERROR, "RenderPlayerSprite: invalid sprite frame %i : %i\n", sprite->GetSprite(), sprite->GetFrame());
|
||||
return;
|
||||
}
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
const auto &viewwindow = PolyRenderer::Instance()->Viewwindow;
|
||||
DCanvas *renderTarget = PolyRenderer::Instance()->RenderTarget;
|
||||
|
||||
spriteframe_t *frame = &SpriteFrames[def->spriteframes + sprite->GetFrame()];
|
||||
FTextureID picnum = frame->Texture[0];
|
||||
bool flip = (frame->Flip & 1) != 0;
|
||||
sprframe = &SpriteFrames[sprdef->spriteframes + pspr->GetFrame()];
|
||||
|
||||
FTexture *tex = TexMan(picnum);
|
||||
if (tex->UseType == FTexture::TEX_Null)
|
||||
picnum = sprframe->Texture[0];
|
||||
flip = sprframe->Flip & 1;
|
||||
tex = TexMan(picnum);
|
||||
|
||||
if (tex->UseType == FTexture::TEX_Null || pspr->RenderStyle == STYLE_None)
|
||||
return;
|
||||
|
||||
// Can't interpolate the first tic.
|
||||
if (sprite->firstTic)
|
||||
{
|
||||
sprite->firstTic = false;
|
||||
sprite->oldx = sprite->x;
|
||||
sprite->oldy = sprite->y;
|
||||
if (pspr->firstTic)
|
||||
{ // Can't interpolate the first tic.
|
||||
pspr->firstTic = false;
|
||||
pspr->oldx = pspr->x;
|
||||
pspr->oldy = pspr->y;
|
||||
}
|
||||
|
||||
double sx = sprite->oldx + (sprite->x - sprite->oldx) * ticfrac;
|
||||
double sy = sprite->oldy + (sprite->y - sprite->oldy) * ticfrac;
|
||||
sx = pspr->oldx + (pspr->x - pspr->oldx) * ticfrac;
|
||||
sy = pspr->oldy + (pspr->y - pspr->oldy) * ticfrac + WEAPON_FUDGE_Y;
|
||||
|
||||
if (sprite->Flags & PSPF_ADDBOB)
|
||||
if (pspr->Flags & PSPF_ADDBOB)
|
||||
{
|
||||
sx += bobx;
|
||||
sy += boby;
|
||||
}
|
||||
|
||||
if (sprite->Flags & PSPF_ADDWEAPON && sprite->GetID() != PSP_WEAPON)
|
||||
if (pspr->Flags & PSPF_ADDWEAPON && pspr->GetID() != PSP_WEAPON)
|
||||
{
|
||||
sx += wx;
|
||||
sy += wy;
|
||||
}
|
||||
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
auto renderTarget = PolyRenderer::Instance()->RenderTarget;
|
||||
double YaspectMul = 1.2f;
|
||||
|
||||
double pspritexscale = PolyRenderer::Instance()->Viewwindow.centerxwide / 160.0;
|
||||
double pspriteyscale = pspritexscale * YaspectMul;
|
||||
double yaspectMul = 1.2;// 320.0 * SCREENHEIGHT / (r_Yaspect * SCREENWIDTH);
|
||||
|
||||
double pspritexscale = viewwindow.centerxwide / 160.0;
|
||||
double pspriteyscale = pspritexscale * yaspectMul;
|
||||
double pspritexiscale = 1 / pspritexscale;
|
||||
|
||||
// calculate edges of the shape
|
||||
double tx = sx - BaseXCenter;
|
||||
tx = sx - BASEXCENTER;
|
||||
|
||||
tx -= tex->GetScaledLeftOffset();
|
||||
int x1 = xs_RoundToInt(renderTarget->GetWidth() * 0.5 + tx * pspritexscale);
|
||||
x1 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale);
|
||||
|
||||
// off the right side
|
||||
if (x1 > viewwidth)
|
||||
return;
|
||||
|
||||
tx += tex->GetScaledWidth();
|
||||
int x2 = xs_RoundToInt(renderTarget->GetWidth() * 0.5 + tx * pspritexscale);
|
||||
x2 = xs_RoundToInt(viewwindow.centerx + tx * pspritexscale);
|
||||
|
||||
// off the left side
|
||||
if (x2 <= 0)
|
||||
return;
|
||||
|
||||
double texturemid = (BaseYCenter - sy) * tex->Scale.Y + tex->TopOffset;
|
||||
// store information in a vissprite
|
||||
PolyNoAccelPlayerSprite vis;
|
||||
|
||||
// Adjust PSprite for fullscreen views
|
||||
if (viewpoint.camera->player && (renderTarget != screen || viewheight == renderTarget->GetHeight() || (renderTarget->GetWidth() > (BaseXCenter * 2) && !st_scale)))
|
||||
{
|
||||
AWeapon *weapon = dyn_cast<AWeapon>(sprite->GetCaller());
|
||||
vis.renderflags = owner->renderflags;
|
||||
|
||||
vis.texturemid = (BASEYCENTER - sy) * tex->Scale.Y + tex->TopOffset;
|
||||
|
||||
if (viewpoint.camera->player && (renderTarget != screen ||
|
||||
viewheight == renderTarget->GetHeight() ||
|
||||
(renderTarget->GetWidth() > (BASEXCENTER * 2) && !st_scale)))
|
||||
{ // Adjust PSprite for fullscreen views
|
||||
AWeapon *weapon = dyn_cast<AWeapon>(pspr->GetCaller());
|
||||
if (weapon != nullptr && weapon->YAdjust != 0)
|
||||
{
|
||||
if (renderTarget != screen || viewheight == renderTarget->GetHeight())
|
||||
{
|
||||
texturemid -= weapon->YAdjust;
|
||||
vis.texturemid -= weapon->YAdjust;
|
||||
}
|
||||
else
|
||||
{
|
||||
texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust;
|
||||
vis.texturemid -= StatusBar->GetDisplacement() * weapon->YAdjust;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Move the weapon down for 1280x1024.
|
||||
if (sprite->GetID() < PSP_TARGETCENTER)
|
||||
{
|
||||
texturemid -= AspectPspriteOffset(PolyRenderer::Instance()->Viewwindow.WidescreenRatio);
|
||||
if (pspr->GetID() < PSP_TARGETCENTER)
|
||||
{ // Move the weapon down for 1280x1024.
|
||||
vis.texturemid -= AspectPspriteOffset(viewwindow.WidescreenRatio);
|
||||
}
|
||||
vis.x1 = x1 < 0 ? 0 : x1;
|
||||
vis.x2 = x2 >= viewwidth ? viewwidth : x2;
|
||||
vis.xscale = FLOAT2FIXED(pspritexscale / tex->Scale.X);
|
||||
vis.yscale = float(pspriteyscale / tex->Scale.Y);
|
||||
vis.pic = tex;
|
||||
|
||||
int clipped_x1 = MAX(x1, 0);
|
||||
int clipped_x2 = MIN(x2, viewwidth);
|
||||
double xscale = pspritexscale / tex->Scale.X;
|
||||
double yscale = pspriteyscale / tex->Scale.Y;
|
||||
uint32_t translation = 0; // [RH] Use default colors
|
||||
|
||||
double xiscale, startfrac;
|
||||
if (flip)
|
||||
// If flip is used, provided that it's not already flipped (that would just invert itself)
|
||||
// (It's an XOR...)
|
||||
if (!(flip) != !(pspr->Flags & PSPF_FLIP))
|
||||
{
|
||||
xiscale = -pspritexiscale * tex->Scale.X;
|
||||
startfrac = 1;
|
||||
vis.xiscale = -FLOAT2FIXED(pspritexiscale * tex->Scale.X);
|
||||
vis.startfrac = (tex->GetWidth() << FRACBITS) - 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
xiscale = pspritexiscale * tex->Scale.X;
|
||||
startfrac = 0;
|
||||
vis.xiscale = FLOAT2FIXED(pspritexiscale * tex->Scale.X);
|
||||
vis.startfrac = 0;
|
||||
}
|
||||
|
||||
if (clipped_x1 > x1)
|
||||
startfrac += xiscale * (clipped_x1 - x1);
|
||||
if (vis.x1 > x1)
|
||||
vis.startfrac += vis.xiscale*(vis.x1 - x1);
|
||||
|
||||
bool noaccel = false;
|
||||
|
||||
FDynamicColormap *basecolormap = GetColorTable(viewpoint.sector->Colormap, viewpoint.sector->SpecialColors[sector_t::sprites], true);
|
||||
FDynamicColormap *colormap_to_use = basecolormap;
|
||||
|
||||
int ColormapNum = 0;
|
||||
FSWColormap *BaseColormap = basecolormap;
|
||||
float Alpha = 0;
|
||||
FRenderStyle RenderStyle;
|
||||
RenderStyle = STYLE_Normal;
|
||||
|
||||
bool foggy = false;
|
||||
int actualextralight = foggy ? 0 : viewpoint.extralight << 4;
|
||||
int spriteshade = PolyLightVisibility::LightLevelToShade(owner->Sector->lightlevel + actualextralight, foggy);
|
||||
double minz = double((2048 * 4) / double(1 << 20));
|
||||
ColormapNum = GETPALOOKUP(PolyRenderer::Instance()->Light.SpriteGlobVis(foggy) / minz, spriteshade);
|
||||
|
||||
if (sprite->GetID() < PSP_TARGETCENTER)
|
||||
noaccel = false;
|
||||
FDynamicColormap *colormap_to_use = nullptr;
|
||||
if (pspr->GetID() < PSP_TARGETCENTER)
|
||||
{
|
||||
Alpha = float(owner->Alpha);
|
||||
RenderStyle = owner->RenderStyle;
|
||||
// [MC] Set the render style
|
||||
|
||||
if (pspr->Flags & PSPF_RENDERSTYLE)
|
||||
{
|
||||
const int rs = clamp<int>(pspr->RenderStyle, 0, STYLE_Count);
|
||||
|
||||
if (pspr->Flags & PSPF_FORCESTYLE)
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[rs];
|
||||
}
|
||||
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_Fuzzy];
|
||||
}
|
||||
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_OptFuzzy];
|
||||
vis.RenderStyle.CheckFuzz();
|
||||
}
|
||||
else if (owner->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_Subtract];
|
||||
}
|
||||
else
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[rs];
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vis.RenderStyle = owner->RenderStyle;
|
||||
}
|
||||
|
||||
// Set the alpha based on if using the overlay's own or not. Also adjust
|
||||
// and override the alpha if not forced.
|
||||
if (pspr->Flags & PSPF_ALPHA)
|
||||
{
|
||||
if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy])
|
||||
{
|
||||
alpha = owner->Alpha;
|
||||
}
|
||||
else if (vis.RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy])
|
||||
{
|
||||
FRenderStyle style = vis.RenderStyle;
|
||||
style.CheckFuzz();
|
||||
switch (style.BlendOp)
|
||||
{
|
||||
default:
|
||||
alpha = pspr->alpha * owner->Alpha;
|
||||
break;
|
||||
case STYLEOP_Fuzz:
|
||||
case STYLEOP_Sub:
|
||||
alpha = owner->Alpha;
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
alpha = owner->Alpha;
|
||||
}
|
||||
else if (vis.RenderStyle == LegacyRenderStyles[STYLE_Add] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_Translucent] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_AddStencil] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
|
||||
{
|
||||
alpha = owner->Alpha * pspr->alpha;
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = owner->Alpha;
|
||||
}
|
||||
}
|
||||
|
||||
// Should normal renderstyle come out on top at the end and we desire alpha,
|
||||
// switch it to translucent. Normal never applies any sort of alpha.
|
||||
if ((pspr->Flags & PSPF_ALPHA) &&
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_Normal] &&
|
||||
vis.Alpha < 1.0)
|
||||
{
|
||||
vis.RenderStyle = LegacyRenderStyles[STYLE_Translucent];
|
||||
alpha = owner->Alpha * pspr->alpha;
|
||||
}
|
||||
|
||||
// ALWAYS take priority if asked for, except fuzz. Fuzz does absolutely nothing
|
||||
// no matter what way it's changed.
|
||||
if (pspr->Flags & PSPF_FORCEALPHA)
|
||||
{
|
||||
//Due to lack of != operators...
|
||||
if (vis.RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_SoulTrans] ||
|
||||
vis.RenderStyle == LegacyRenderStyles[STYLE_Stencil])
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
alpha = pspr->alpha;
|
||||
vis.RenderStyle.Flags |= STYLEF_ForceAlpha;
|
||||
}
|
||||
}
|
||||
vis.Alpha = clamp<float>(float(alpha), 0.f, 1.f);
|
||||
|
||||
// Due to how some of the effects are handled, going to 0 or less causes some
|
||||
// weirdness to display. There's no point rendering it anyway if it's 0.
|
||||
if (vis.Alpha <= 0.)
|
||||
return;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The software renderer cannot invert the source without inverting the overlay
|
||||
// too. That means if the source is inverted, we need to do the reverse of what
|
||||
// the invert overlay flag says to do.
|
||||
INTBOOL invertcolormap = (RenderStyle.Flags & STYLEF_InvertOverlay);
|
||||
bool invertcolormap = (vis.RenderStyle.Flags & STYLEF_InvertOverlay) != 0;
|
||||
|
||||
if (RenderStyle.Flags & STYLEF_InvertSource)
|
||||
if (vis.RenderStyle.Flags & STYLEF_InvertSource)
|
||||
{
|
||||
invertcolormap = !invertcolormap;
|
||||
}
|
||||
|
||||
FDynamicColormap *mybasecolormap = basecolormap;
|
||||
bool fullbright = !foggy && pspr->GetState()->GetFullbright();
|
||||
bool fadeToBlack = (vis.RenderStyle.Flags & STYLEF_FadeToBlack) != 0;
|
||||
|
||||
if (RenderStyle.Flags & STYLEF_FadeToBlack)
|
||||
{
|
||||
if (invertcolormap)
|
||||
{ // Fade to white
|
||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(255, 255, 255), mybasecolormap->Desaturate);
|
||||
invertcolormap = false;
|
||||
}
|
||||
else
|
||||
{ // Fade to black
|
||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, MAKERGB(0, 0, 0), mybasecolormap->Desaturate);
|
||||
}
|
||||
}
|
||||
vis.Light.SetColormap(0, spriteshade, basecolormap, fullbright, invertcolormap, fadeToBlack);
|
||||
|
||||
/*
|
||||
if (realfixedcolormap != nullptr && (!r_swtruecolor || (r_shadercolormaps && screen->Accel2D)))
|
||||
{ // fixed color
|
||||
BaseColormap = realfixedcolormap;
|
||||
ColormapNum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (invertcolormap)
|
||||
{
|
||||
mybasecolormap = GetSpecialLights(mybasecolormap->Color, mybasecolormap->Fade.InverseColor(), mybasecolormap->Desaturate);
|
||||
}
|
||||
if (fixedlightlev >= 0)
|
||||
{
|
||||
BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap;
|
||||
ColormapNum = fixedlightlev >> COLORMAPSHIFT;
|
||||
}
|
||||
else if (!foggy && sprite->GetState()->GetFullbright())
|
||||
{ // full bright
|
||||
BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : mybasecolormap; // [RH] use basecolormap
|
||||
ColormapNum = 0;
|
||||
}
|
||||
else
|
||||
{ // local light
|
||||
BaseColormap = mybasecolormap;
|
||||
ColormapNum = GETPALOOKUP(0, spriteshade);
|
||||
}
|
||||
}
|
||||
*/
|
||||
colormap_to_use = (FDynamicColormap*)vis.Light.BaseColormap;
|
||||
|
||||
if (viewpoint.camera->Inventory != nullptr)
|
||||
{
|
||||
visstyle_t visstyle;
|
||||
visstyle.Alpha = Alpha;
|
||||
visstyle.Alpha = vis.Alpha;
|
||||
visstyle.RenderStyle = STYLE_Count;
|
||||
visstyle.Invert = false;
|
||||
|
||||
viewpoint.camera->Inventory->AlterWeaponSprite(&visstyle);
|
||||
|
||||
Alpha = visstyle.Alpha;
|
||||
vis.Alpha = visstyle.Alpha;
|
||||
|
||||
if (visstyle.RenderStyle != STYLE_Count)
|
||||
{
|
||||
RenderStyle = visstyle.RenderStyle;
|
||||
vis.RenderStyle = visstyle.RenderStyle;
|
||||
}
|
||||
|
||||
if (visstyle.Invert)
|
||||
{
|
||||
BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP];
|
||||
ColormapNum = 0;
|
||||
if (BaseColormap->Maps < mybasecolormap->Maps || BaseColormap->Maps >= mybasecolormap->Maps + NUMCOLORMAPS * 256)
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
vis.Light.BaseColormap = &SpecialSWColormaps[INVERSECOLORMAP];
|
||||
vis.Light.ColormapNum = 0;
|
||||
noaccel = true;
|
||||
}
|
||||
}
|
||||
|
||||
// If we're drawing with a special colormap, but shaders for them are disabled, do
|
||||
// not accelerate.
|
||||
if (!r_shadercolormaps && (BaseColormap >= &SpecialSWColormaps[0] &&
|
||||
BaseColormap <= &SpecialSWColormaps.Last()))
|
||||
if (!r_shadercolormaps && (vis.Light.BaseColormap >= &SpecialSWColormaps[0] &&
|
||||
vis.Light.BaseColormap <= &SpecialSWColormaps.Last()))
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
// If drawing with a BOOM colormap, disable acceleration.
|
||||
if (mybasecolormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps)
|
||||
if (vis.Light.BaseColormap == &NormalLight && NormalLight.Maps != realcolormaps.Maps)
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
|
@ -334,116 +486,185 @@ void RenderPolyPlayerSprites::RenderSprite(DPSprite *sprite, AActor *owner, floa
|
|||
// colormap, disable acceleration so that the lights can remain fixed.
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
if (!noaccel && cameraLight->ShaderColormap() == nullptr &&
|
||||
NormalLightHasFixedLights && mybasecolormap == &NormalLight &&
|
||||
tex->UseBasePalette())
|
||||
NormalLightHasFixedLights && vis.Light.BaseColormap == &NormalLight &&
|
||||
vis.pic->UseBasePalette())
|
||||
{
|
||||
noaccel = true;
|
||||
}
|
||||
// [SP] If emulating GZDoom fullbright, disable acceleration
|
||||
if (r_fullbrightignoresectorcolor && cameraLight->FixedLightLevel() >= 0)
|
||||
mybasecolormap = &FullNormalLight;
|
||||
if (r_fullbrightignoresectorcolor && !foggy && sprite->GetState()->GetFullbright())
|
||||
mybasecolormap = &FullNormalLight;
|
||||
colormap_to_use = mybasecolormap;
|
||||
}
|
||||
else
|
||||
{
|
||||
colormap_to_use = basecolormap;
|
||||
|
||||
vis.Light.BaseColormap = basecolormap;
|
||||
vis.Light.ColormapNum = 0;
|
||||
}
|
||||
|
||||
// Check for hardware-assisted 2D. If it's available, and this sprite is not
|
||||
// fuzzy, don't draw it until after the switch to 2D mode.
|
||||
if (!noaccel && renderTarget == screen && (DFrameBuffer *)screen->Accel2D)
|
||||
{
|
||||
FRenderStyle style = RenderStyle;
|
||||
FRenderStyle style = vis.RenderStyle;
|
||||
style.CheckFuzz();
|
||||
if (style.BlendOp != STYLEOP_Fuzz)
|
||||
{
|
||||
PolyScreenSprite screenSprite;
|
||||
screenSprite.Pic = tex;
|
||||
screenSprite.X1 = viewwindowx + x1;
|
||||
screenSprite.Y1 = viewwindowy + viewheight / 2 - texturemid * yscale - 0.5;
|
||||
screenSprite.Width = tex->GetWidth() * xscale;
|
||||
screenSprite.Height = tex->GetHeight() * yscale;
|
||||
screenSprite.Translation = TranslationToTable(translation);
|
||||
//screenSprite.Translation = translation;
|
||||
screenSprite.Flip = xiscale < 0;
|
||||
screenSprite.Alpha = Alpha;
|
||||
screenSprite.RenderStyle = RenderStyle;
|
||||
screenSprite.BaseColormap = BaseColormap;
|
||||
screenSprite.ColormapNum = ColormapNum;
|
||||
screenSprite.Colormap = colormap_to_use;
|
||||
ScreenSprites.push_back(screenSprite);
|
||||
PolyHWAccelPlayerSprite accelSprite;
|
||||
|
||||
accelSprite.pic = vis.pic;
|
||||
accelSprite.texturemid = vis.texturemid;
|
||||
accelSprite.yscale = vis.yscale;
|
||||
accelSprite.xscale = vis.xscale;
|
||||
|
||||
accelSprite.Alpha = vis.Alpha;
|
||||
accelSprite.RenderStyle = vis.RenderStyle;
|
||||
accelSprite.Translation = vis.Translation;
|
||||
accelSprite.FillColor = vis.FillColor;
|
||||
|
||||
accelSprite.basecolormap = colormap_to_use;
|
||||
accelSprite.x1 = x1;
|
||||
accelSprite.flip = vis.xiscale < 0;
|
||||
|
||||
if (vis.Light.BaseColormap >= &SpecialSWColormaps[0] &&
|
||||
vis.Light.BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()])
|
||||
{
|
||||
accelSprite.special = &SpecialColormaps[vis.Light.BaseColormap - &SpecialSWColormaps[0]];
|
||||
}
|
||||
else if (PolyCameraLight::Instance()->ShaderColormap())
|
||||
{
|
||||
accelSprite.special = PolyCameraLight::Instance()->ShaderColormap();
|
||||
}
|
||||
else if (colormap_to_use->Color == PalEntry(255, 255, 255) &&
|
||||
colormap_to_use->Desaturate == 0)
|
||||
{
|
||||
accelSprite.overlay = colormap_to_use->Fade;
|
||||
accelSprite.overlay.a = uint8_t(vis.Light.ColormapNum * 255 / NUMCOLORMAPS);
|
||||
}
|
||||
else
|
||||
{
|
||||
accelSprite.usecolormapstyle = true;
|
||||
accelSprite.colormapstyle.Color = colormap_to_use->Color;
|
||||
accelSprite.colormapstyle.Fade = colormap_to_use->Fade;
|
||||
accelSprite.colormapstyle.Desaturate = colormap_to_use->Desaturate;
|
||||
accelSprite.colormapstyle.FadeLevel = vis.Light.ColormapNum / float(NUMCOLORMAPS);
|
||||
}
|
||||
|
||||
AcceleratedSprites.Push(accelSprite);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
// To do: draw sprite same way as R_DrawVisSprite(vis) here
|
||||
|
||||
// Draw the fuzzy weapon:
|
||||
FRenderStyle style = RenderStyle;
|
||||
style.CheckFuzz();
|
||||
if (style.BlendOp == STYLEOP_Fuzz)
|
||||
{
|
||||
RenderStyle = LegacyRenderStyles[STYLE_Shadow];
|
||||
|
||||
PolyScreenSprite screenSprite;
|
||||
screenSprite.Pic = tex;
|
||||
screenSprite.X1 = viewwindowx + x1;
|
||||
screenSprite.Y1 = viewwindowy + viewheight / 2 - texturemid * yscale - 0.5;
|
||||
screenSprite.Width = tex->GetWidth() * xscale;
|
||||
screenSprite.Height = tex->GetHeight() * yscale;
|
||||
screenSprite.Translation = TranslationToTable(translation);
|
||||
screenSprite.Flip = xiscale < 0;
|
||||
screenSprite.Alpha = Alpha;
|
||||
screenSprite.RenderStyle = RenderStyle;
|
||||
screenSprite.BaseColormap = BaseColormap;
|
||||
screenSprite.ColormapNum = ColormapNum;
|
||||
screenSprite.Colormap = colormap_to_use;
|
||||
ScreenSprites.push_back(screenSprite);
|
||||
}
|
||||
vis.Render();
|
||||
}
|
||||
|
||||
void PolyScreenSprite::Render()
|
||||
fixed_t RenderPolyPlayerSprites::LightLevelToShade(int lightlevel, bool foggy)
|
||||
{
|
||||
FSpecialColormap *special = nullptr;
|
||||
FColormapStyle colormapstyle;
|
||||
PalEntry overlay = 0;
|
||||
bool usecolormapstyle = false;
|
||||
if (BaseColormap >= &SpecialSWColormaps[0] &&
|
||||
BaseColormap < &SpecialSWColormaps[SpecialColormaps.Size()])
|
||||
bool nolightfade = !foggy && ((level.flags3 & LEVEL3_NOLIGHTFADE));
|
||||
if (nolightfade)
|
||||
{
|
||||
special = &SpecialColormaps[BaseColormap - &SpecialSWColormaps[0]];
|
||||
}
|
||||
else if (Colormap->Color == PalEntry(255, 255, 255) &&
|
||||
Colormap->Desaturate == 0)
|
||||
{
|
||||
overlay = Colormap->Fade;
|
||||
overlay.a = uint8_t(ColormapNum * 255 / NUMCOLORMAPS);
|
||||
return (MAX(255 - lightlevel, 0) * NUMCOLORMAPS) << (FRACBITS - 8);
|
||||
}
|
||||
else
|
||||
{
|
||||
usecolormapstyle = true;
|
||||
colormapstyle.Color = Colormap->Color;
|
||||
colormapstyle.Fade = Colormap->Fade;
|
||||
colormapstyle.Desaturate = Colormap->Desaturate;
|
||||
colormapstyle.FadeLevel = ColormapNum / float(NUMCOLORMAPS);
|
||||
// Convert a light level into an unbounded colormap index (shade). Result is
|
||||
// fixed point. Why the +12? I wish I knew, but experimentation indicates it
|
||||
// is necessary in order to best reproduce Doom's original lighting.
|
||||
return (NUMCOLORMAPS * 2 * FRACUNIT) - ((lightlevel + 12) * (FRACUNIT*NUMCOLORMAPS / 128));
|
||||
}
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PolyNoAccelPlayerSprite::Render()
|
||||
{
|
||||
#if 0
|
||||
if (xscale == 0 || fabs(yscale) < (1.0f / 32000.0f))
|
||||
{ // scaled to 0; can't see
|
||||
return;
|
||||
}
|
||||
|
||||
screen->DrawTexture(Pic,
|
||||
X1,
|
||||
Y1,
|
||||
DTA_DestWidthF, Width,
|
||||
DTA_DestHeightF, Height,
|
||||
DTA_TranslationIndex, Translation,
|
||||
DTA_FlipX, Flip,
|
||||
DTA_TopOffset, 0,
|
||||
DTA_LeftOffset, 0,
|
||||
DTA_ClipLeft, viewwindowx,
|
||||
DTA_ClipTop, viewwindowy,
|
||||
DTA_ClipRight, viewwindowx + viewwidth,
|
||||
DTA_ClipBottom, viewwindowy + viewheight,
|
||||
DTA_Alpha, Alpha,
|
||||
DTA_RenderStyle, RenderStyle,
|
||||
DTA_FillColor, FillColor,
|
||||
DTA_SpecialColormap, special,
|
||||
DTA_ColorOverlay, overlay.d,
|
||||
DTA_ColormapStyle, usecolormapstyle ? &colormapstyle : nullptr,
|
||||
TAG_DONE);
|
||||
SpriteDrawerArgs drawerargs;
|
||||
drawerargs.SetLight(Light.BaseColormap, 0, Light.ColormapNum << FRACBITS);
|
||||
|
||||
FDynamicColormap *basecolormap = static_cast<FDynamicColormap*>(Light.BaseColormap);
|
||||
|
||||
bool visible = drawerargs.SetStyle(RenderStyle, Alpha, Translation, FillColor, basecolormap, Light.ColormapNum << FRACBITS);
|
||||
if (!visible)
|
||||
return;
|
||||
|
||||
double spryscale = yscale;
|
||||
bool sprflipvert = false;
|
||||
fixed_t iscale = FLOAT2FIXED(1 / yscale);
|
||||
|
||||
double centerY = viewheight / 2;
|
||||
|
||||
double sprtopscreen;
|
||||
if (renderflags & RF_YFLIP)
|
||||
{
|
||||
sprflipvert = true;
|
||||
spryscale = -spryscale;
|
||||
iscale = -iscale;
|
||||
sprtopscreen = centerY + (texturemid - pic->GetHeight()) * spryscale;
|
||||
}
|
||||
else
|
||||
{
|
||||
sprflipvert = false;
|
||||
sprtopscreen = centerY - texturemid * spryscale;
|
||||
}
|
||||
|
||||
// clip to screen bounds
|
||||
short *mfloorclip = screenheightarray;
|
||||
short *mceilingclip = zeroarray;
|
||||
|
||||
fixed_t frac = startfrac;
|
||||
for (int x = x1; x < x2; x++)
|
||||
{
|
||||
drawerargs.DrawMaskedColumn(x, iscale, pic, frac, spryscale, sprtopscreen, sprflipvert, mfloorclip, mceilingclip, false);
|
||||
frac += xiscale;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void PolyColormapLight::SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack)
|
||||
{
|
||||
if (fadeToBlack)
|
||||
{
|
||||
if (invertColormap) // Fade to white
|
||||
{
|
||||
basecolormap = GetSpecialLights(basecolormap->Color, MAKERGB(255, 255, 255), basecolormap->Desaturate);
|
||||
invertColormap = false;
|
||||
}
|
||||
else // Fade to black
|
||||
{
|
||||
basecolormap = GetSpecialLights(basecolormap->Color, MAKERGB(0, 0, 0), basecolormap->Desaturate);
|
||||
}
|
||||
}
|
||||
|
||||
if (invertColormap)
|
||||
{
|
||||
basecolormap = GetSpecialLights(basecolormap->Color, basecolormap->Fade.InverseColor(), basecolormap->Desaturate);
|
||||
}
|
||||
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
if (cameraLight->FixedColormap())
|
||||
{
|
||||
BaseColormap = cameraLight->FixedColormap();
|
||||
ColormapNum = 0;
|
||||
}
|
||||
else if (cameraLight->FixedLightLevel() >= 0)
|
||||
{
|
||||
BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap;
|
||||
ColormapNum = cameraLight->FixedLightLevel() >> COLORMAPSHIFT;
|
||||
}
|
||||
else if (fullbright)
|
||||
{
|
||||
BaseColormap = (r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap;
|
||||
ColormapNum = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
BaseColormap = basecolormap;
|
||||
ColormapNum = GETPALOOKUP(visibility, shade);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -24,9 +24,68 @@
|
|||
|
||||
#include "r_defs.h"
|
||||
|
||||
class PolyScreenSprite;
|
||||
class DPSprite;
|
||||
struct FSWColormap;
|
||||
struct FDynamicColormap;
|
||||
|
||||
class PolyColormapLight
|
||||
{
|
||||
public:
|
||||
int ColormapNum = 0;
|
||||
FSWColormap *BaseColormap = nullptr;
|
||||
|
||||
void SetColormap(double visibility, int shade, FDynamicColormap *basecolormap, bool fullbright, bool invertColormap, bool fadeToBlack);
|
||||
};
|
||||
|
||||
class PolyNoAccelPlayerSprite
|
||||
{
|
||||
public:
|
||||
short x1 = 0;
|
||||
short x2 = 0;
|
||||
|
||||
double texturemid = 0.0;
|
||||
|
||||
fixed_t xscale = 0;
|
||||
float yscale = 0.0f;
|
||||
|
||||
FTexture *pic = nullptr;
|
||||
|
||||
fixed_t xiscale = 0;
|
||||
fixed_t startfrac = 0;
|
||||
|
||||
float Alpha = 0.0f;
|
||||
FRenderStyle RenderStyle;
|
||||
uint32_t Translation = 0;
|
||||
uint32_t FillColor = 0;
|
||||
|
||||
PolyColormapLight Light;
|
||||
|
||||
short renderflags = 0;
|
||||
|
||||
void Render();
|
||||
};
|
||||
|
||||
class PolyHWAccelPlayerSprite
|
||||
{
|
||||
public:
|
||||
FTexture *pic = nullptr;
|
||||
double texturemid = 0.0;
|
||||
float yscale = 0.0f;
|
||||
fixed_t xscale = 0;
|
||||
|
||||
float Alpha = 0.0f;
|
||||
FRenderStyle RenderStyle;
|
||||
uint32_t Translation = 0;
|
||||
uint32_t FillColor = 0;
|
||||
|
||||
FDynamicColormap *basecolormap = nullptr;
|
||||
int x1 = 0;
|
||||
|
||||
bool flip = false;
|
||||
FSpecialColormap *special = nullptr;
|
||||
PalEntry overlay = 0;
|
||||
FColormapStyle colormapstyle;
|
||||
bool usecolormapstyle = false;
|
||||
};
|
||||
|
||||
class RenderPolyPlayerSprites
|
||||
{
|
||||
|
@ -35,31 +94,12 @@ public:
|
|||
void RenderRemainingSprites();
|
||||
|
||||
private:
|
||||
void RenderSprite(DPSprite *sprite, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac);
|
||||
void RenderSprite(DPSprite *pspr, AActor *owner, float bobx, float boby, double wx, double wy, double ticfrac, int spriteshade, FDynamicColormap *basecolormap, bool foggy);
|
||||
static fixed_t LightLevelToShade(int lightlevel, bool foggy);
|
||||
|
||||
const int BaseXCenter = 160;
|
||||
const int BaseYCenter = 100;
|
||||
enum { BASEXCENTER = 160 };
|
||||
enum { BASEYCENTER = 100 };
|
||||
|
||||
std::vector<PolyScreenSprite> ScreenSprites;
|
||||
};
|
||||
|
||||
// DScreen accelerated sprite to be rendered
|
||||
class PolyScreenSprite
|
||||
{
|
||||
public:
|
||||
void Render();
|
||||
|
||||
FTexture *Pic = nullptr;
|
||||
double X1 = 0.0;
|
||||
double Y1 = 0.0;
|
||||
double Width = 0.0;
|
||||
double Height = 0.0;
|
||||
FRemapTable *Translation = nullptr;
|
||||
bool Flip = false;
|
||||
float Alpha = 1;
|
||||
FRenderStyle RenderStyle;
|
||||
FSWColormap *BaseColormap = nullptr;
|
||||
int ColormapNum = 0;
|
||||
uint32_t FillColor = 0;
|
||||
FDynamicColormap *Colormap = nullptr;
|
||||
TArray<PolyHWAccelPlayerSprite> AcceleratedSprites;
|
||||
sector_t tempsec;
|
||||
};
|
||||
|
|
|
@ -45,7 +45,7 @@ void PolyDrawSectorPortal::Render(int portalDepth)
|
|||
|
||||
const auto &viewpoint = PolyRenderer::Instance()->Viewpoint;
|
||||
|
||||
Vec4f portalPlane = Vec4f(0.0f);
|
||||
PolyClipPlane portalPlane(0.0f, 0.0f, 0.0f, 1.0f);
|
||||
if (Portal->mType != PORTS_SKYVIEWPOINT)
|
||||
{
|
||||
float minHeight;
|
||||
|
@ -71,17 +71,11 @@ void PolyDrawSectorPortal::Render(int portalDepth)
|
|||
|
||||
if (!first && minHeight > viewpoint.Pos.Z)
|
||||
{
|
||||
portalPlane.x = 0.0f;
|
||||
portalPlane.y = 0.0f;
|
||||
portalPlane.z = 1.0f;
|
||||
portalPlane.w = -minHeight;
|
||||
portalPlane = PolyClipPlane(0.0f, 0.0f, 1.0f, -minHeight);
|
||||
}
|
||||
else if (!first && maxHeight < viewpoint.Pos.Z)
|
||||
{
|
||||
portalPlane.x = 0.0f;
|
||||
portalPlane.y = 0.0f;
|
||||
portalPlane.z = -1.0f;
|
||||
portalPlane.w = maxHeight;
|
||||
portalPlane = PolyClipPlane(0.0f, 0.0f, -1.0f, maxHeight);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -223,7 +217,7 @@ void PolyDrawLinePortal::Render(int portalDepth)
|
|||
DVector2 planeNormal = (clipLine->v2->fPos() - clipLine->v1->fPos()).Rotated90CW();
|
||||
planeNormal.MakeUnit();
|
||||
double planeD = -(planeNormal | (planePos + planeNormal * 0.001));
|
||||
Vec4f portalPlane((float)planeNormal.X, (float)planeNormal.Y, 0.0f, (float)planeD);
|
||||
PolyClipPlane portalPlane((float)planeNormal.X, (float)planeNormal.Y, (float)0.0f, (float)planeD);
|
||||
|
||||
RenderPortal.SetViewpoint(worldToClip, portalPlane, StencilValue);
|
||||
RenderPortal.SetPortalSegments(Segments);
|
||||
|
|
|
@ -43,7 +43,7 @@ RenderPolyScene::~RenderPolyScene()
|
|||
{
|
||||
}
|
||||
|
||||
void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue)
|
||||
void RenderPolyScene::SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue)
|
||||
{
|
||||
WorldToClip = worldToClip;
|
||||
StencilValue = stencilValue;
|
||||
|
@ -249,40 +249,33 @@ void RenderPolyScene::RenderPortals(int portalDepth)
|
|||
else // Fill with black
|
||||
{
|
||||
PolyDrawArgs args;
|
||||
args.objectToClip = &WorldToClip;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
|
||||
args.uniforms.color = 0;
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::fixed_light;
|
||||
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
|
||||
args.SetTransform(&WorldToClip);
|
||||
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(foggy), true);
|
||||
args.SetColor(0, 0);
|
||||
args.SetClipPlane(PortalPlane);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
|
||||
for (auto &portal : SectorPortals)
|
||||
{
|
||||
args.stenciltestvalue = portal->StencilValue;
|
||||
args.stencilwritevalue = portal->StencilValue + 1;
|
||||
args.SetStencilTestValue(portal->StencilValue);
|
||||
args.SetWriteStencil(true, portal->StencilValue + 1);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.vinput = verts.Vertices;
|
||||
args.vcount = verts.Count;
|
||||
args.ccw = verts.Ccw;
|
||||
args.uniforms.subsectorDepth = verts.SubsectorDepth;
|
||||
args.blendmode = TriBlendMode::Copy;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetSubsectorDepth(verts.SubsectorDepth);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
|
||||
for (auto &portal : LinePortals)
|
||||
{
|
||||
args.stenciltestvalue = portal->StencilValue;
|
||||
args.stencilwritevalue = portal->StencilValue + 1;
|
||||
args.SetStencilTestValue(portal->StencilValue);
|
||||
args.SetWriteStencil(true, portal->StencilValue + 1);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.vinput = verts.Vertices;
|
||||
args.vcount = verts.Count;
|
||||
args.ccw = verts.Ccw;
|
||||
args.uniforms.subsectorDepth = verts.SubsectorDepth;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetSubsectorDepth(verts.SubsectorDepth);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -298,19 +291,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
portal->RenderTranslucent(portalDepth + 1);
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.objectToClip = &WorldToClip;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.stenciltestvalue = portal->StencilValue + 1;
|
||||
args.stencilwritevalue = StencilValue + 1;
|
||||
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
|
||||
args.SetTransform(&WorldToClip);
|
||||
args.SetStencilTestValue(portal->StencilValue + 1);
|
||||
args.SetWriteStencil(true, StencilValue + 1);
|
||||
args.SetClipPlane(PortalPlane);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.vinput = verts.Vertices;
|
||||
args.vcount = verts.Count;
|
||||
args.ccw = verts.Ccw;
|
||||
args.uniforms.subsectorDepth = verts.SubsectorDepth;
|
||||
args.writeColor = false;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetSubsectorDepth(verts.SubsectorDepth);
|
||||
args.SetWriteColor(false);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -320,19 +310,16 @@ void RenderPolyScene::RenderTranslucent(int portalDepth)
|
|||
portal->RenderTranslucent(portalDepth + 1);
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.objectToClip = &WorldToClip;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.stenciltestvalue = portal->StencilValue + 1;
|
||||
args.stencilwritevalue = StencilValue + 1;
|
||||
args.SetClipPlane(PortalPlane.x, PortalPlane.y, PortalPlane.z, PortalPlane.w);
|
||||
args.SetTransform(&WorldToClip);
|
||||
args.SetStencilTestValue(portal->StencilValue + 1);
|
||||
args.SetWriteStencil(true, StencilValue + 1);
|
||||
args.SetClipPlane(PortalPlane);
|
||||
for (const auto &verts : portal->Shape)
|
||||
{
|
||||
args.vinput = verts.Vertices;
|
||||
args.vcount = verts.Count;
|
||||
args.ccw = verts.Ccw;
|
||||
args.uniforms.subsectorDepth = verts.SubsectorDepth;
|
||||
args.writeColor = false;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(verts.Ccw);
|
||||
args.SetSubsectorDepth(verts.SubsectorDepth);
|
||||
args.SetWriteColor(false);
|
||||
args.DrawArray(verts.Vertices, verts.Count, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,7 +29,6 @@
|
|||
#include "doomdata.h"
|
||||
#include "r_utility.h"
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
#include "polyrenderer/math/poly_intersection.h"
|
||||
#include "poly_wall.h"
|
||||
#include "poly_sprite.h"
|
||||
#include "poly_wallsprite.h"
|
||||
|
@ -74,7 +73,7 @@ class RenderPolyScene
|
|||
public:
|
||||
RenderPolyScene();
|
||||
~RenderPolyScene();
|
||||
void SetViewpoint(const TriMatrix &worldToClip, const Vec4f &portalPlane, uint32_t stencilValue);
|
||||
void SetViewpoint(const TriMatrix &worldToClip, const PolyClipPlane &portalPlane, uint32_t stencilValue);
|
||||
void SetPortalSegments(const std::vector<PolyPortalSegment> &segments);
|
||||
void Render(int portalDepth);
|
||||
void RenderTranslucent(int portalDepth);
|
||||
|
@ -91,7 +90,7 @@ private:
|
|||
void RenderSprite(AActor *thing, double sortDistance, DVector2 left, DVector2 right, double t1, double t2, void *node);
|
||||
|
||||
TriMatrix WorldToClip;
|
||||
Vec4f PortalPlane;
|
||||
PolyClipPlane PortalPlane;
|
||||
uint32_t StencilValue = 0;
|
||||
PolyCull Cull;
|
||||
uint32_t NextSubsectorDepth = 0;
|
||||
|
|
|
@ -38,7 +38,6 @@ PolySkyDome::PolySkyDome()
|
|||
void PolySkyDome::Render(const TriMatrix &worldToClip)
|
||||
{
|
||||
FTextureID sky1tex, sky2tex;
|
||||
bool foggy = false;
|
||||
if ((level.flags & LEVEL_SWAPSKIES) && !(level.flags & LEVEL_DOUBLESKY))
|
||||
sky1tex = sky2texture;
|
||||
else
|
||||
|
@ -57,15 +56,12 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
|||
int rc = mRows + 1;
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
args.uniforms.subsectorDepth = RenderPolyScene::SkySubsectorDepth;
|
||||
args.objectToClip = &objectToClip;
|
||||
args.stenciltestvalue = 255;
|
||||
args.stencilwritevalue = 1;
|
||||
args.SetColormap(&NormalLight);
|
||||
args.SetClipPlane(0.0f, 0.0f, 0.0f, 0.0f);
|
||||
args.SetLight(&NormalLight, 255, PolyRenderer::Instance()->Light.WallGlobVis(false), true);
|
||||
args.SetSubsectorDepth(RenderPolyScene::SkySubsectorDepth);
|
||||
args.SetTransform(&objectToClip);
|
||||
args.SetStencilTestValue(255);
|
||||
args.SetWriteStencil(true, 1);
|
||||
args.SetClipPlane(PolyClipPlane(0.0f, 0.0f, 0.0f, 1.0f));
|
||||
|
||||
RenderCapColorRow(args, frontskytex, 0, false);
|
||||
RenderCapColorRow(args, frontskytex, rc, true);
|
||||
|
@ -84,28 +80,21 @@ void PolySkyDome::Render(const TriMatrix &worldToClip)
|
|||
|
||||
void PolySkyDome::RenderRow(PolyDrawArgs &args, int row, uint32_t capcolor)
|
||||
{
|
||||
args.vinput = &mVertices[mPrimStart[row]];
|
||||
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
|
||||
args.mode = TriangleDrawMode::Strip;
|
||||
args.ccw = false;
|
||||
args.uniforms.color = capcolor;
|
||||
args.blendmode = TriBlendMode::Skycap;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(false);
|
||||
args.SetColor(capcolor, 0);
|
||||
args.SetStyle(TriBlendMode::Skycap);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleStrip);
|
||||
}
|
||||
|
||||
void PolySkyDome::RenderCapColorRow(PolyDrawArgs &args, FTexture *skytex, int row, bool bottomCap)
|
||||
{
|
||||
uint32_t solid = skytex->GetSkyCapColor(bottomCap);
|
||||
if (!PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
solid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
|
||||
uint8_t palsolid = RGB32k.RGB[(RPART(solid) >> 3)][(GPART(solid) >> 3)][(BPART(solid) >> 3)];
|
||||
|
||||
args.vinput = &mVertices[mPrimStart[row]];
|
||||
args.vcount = mPrimStart[row + 1] - mPrimStart[row];
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = bottomCap;
|
||||
args.uniforms.color = solid;
|
||||
args.blendmode = TriBlendMode::Copy;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetFaceCullCCW(bottomCap);
|
||||
args.SetColor(solid, palsolid);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.DrawArray(&mVertices[mPrimStart[row]], mPrimStart[row + 1] - mPrimStart[row], PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
void PolySkyDome::CreateDome()
|
||||
|
|
|
@ -27,7 +27,6 @@
|
|||
#include "r_data/r_translate.h"
|
||||
#include "poly_sprite.h"
|
||||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/math/poly_intersection.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
EXTERN_CVAR(Float, transsouls)
|
||||
|
@ -65,7 +64,7 @@ bool RenderPolySprite::GetLine(AActor *thing, DVector2 &left, DVector2 &right)
|
|||
return true;
|
||||
}
|
||||
|
||||
void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2)
|
||||
void RenderPolySprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2)
|
||||
{
|
||||
DVector2 line[2];
|
||||
if (!GetLine(thing, line[0], line[1]))
|
||||
|
@ -136,136 +135,80 @@ void RenderPolySprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPla
|
|||
}
|
||||
|
||||
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.SpriteGlobVis(foggy);
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
{
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags |= TriUniforms::fixed_light;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f);
|
||||
}
|
||||
args.uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = 4;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue;
|
||||
args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.SpriteGlobVis(foggy), fullbrightSprite);
|
||||
args.SetSubsectorDepth(subsectorDepth);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetWriteStencil(true, stencilValue);
|
||||
args.SetTexture(tex, thing->Translation);
|
||||
args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
args.SetClipPlane(clipPlane);
|
||||
|
||||
TriBlendMode blendmode;
|
||||
|
||||
if (thing->RenderStyle == LegacyRenderStyles[STYLE_Normal] ||
|
||||
(r_drawfuzz == 0 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
args.uniforms.destalpha = 0;
|
||||
args.uniforms.srcalpha = 256;
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 1.0, 0.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && args.translation == nullptr)
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add] && fullbrightSprite && thing->Alpha == 1.0 && !args.Translation())
|
||||
{
|
||||
args.uniforms.destalpha = 256;
|
||||
args.uniforms.srcalpha = 256;
|
||||
blendmode = TriBlendMode::AddSrcColorOneMinusSrcColor;
|
||||
args.SetStyle(TriBlendMode::AddSrcColorOneMinusSrcColor, 1.0, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Add])
|
||||
{
|
||||
args.uniforms.destalpha = (uint32_t)(1.0 * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Subtract])
|
||||
{
|
||||
args.uniforms.destalpha = (uint32_t)(1.0 * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
blendmode = args.translation ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateRevSub : TriBlendMode::RevSub, thing->Alpha, 1.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_SoulTrans])
|
||||
{
|
||||
args.uniforms.destalpha = (uint32_t)(256 - transsouls * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(transsouls * 256);
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, transsouls, 1.0 - transsouls);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Fuzzy] ||
|
||||
(r_drawfuzz == 2 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{ // NYI - Fuzzy - for now, just a copy of "Shadow"
|
||||
args.uniforms.destalpha = 160;
|
||||
args.uniforms.srcalpha = 0;
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shadow] ||
|
||||
(r_drawfuzz == 1 && thing->RenderStyle == LegacyRenderStyles[STYLE_OptFuzzy]))
|
||||
{
|
||||
args.uniforms.destalpha = 160;
|
||||
args.uniforms.srcalpha = 0;
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, 0.0, 160 / 255.0);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_TranslucentStencil])
|
||||
{
|
||||
args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
args.uniforms.color = 0xff000000 | thing->fillcolor;
|
||||
blendmode = TriBlendMode::Stencil;
|
||||
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
|
||||
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddStencil])
|
||||
{
|
||||
args.uniforms.destalpha = 256;
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
args.uniforms.color = 0xff000000 | thing->fillcolor;
|
||||
blendmode = TriBlendMode::Stencil;
|
||||
args.SetColor(0xff000000 | thing->fillcolor, thing->fillcolor >> 24);
|
||||
args.SetStyle(TriBlendMode::Stencil, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_Shaded])
|
||||
{
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
args.uniforms.destalpha = 256 - args.uniforms.srcalpha;
|
||||
args.uniforms.color = 0;
|
||||
blendmode = TriBlendMode::Shaded;
|
||||
args.SetColor(0, 0);
|
||||
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
|
||||
args.SetTexture(tex, thing->Translation, true);
|
||||
}
|
||||
else if (thing->RenderStyle == LegacyRenderStyles[STYLE_AddShaded])
|
||||
{
|
||||
args.uniforms.destalpha = 256;
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
args.uniforms.color = 0;
|
||||
blendmode = TriBlendMode::Shaded;
|
||||
args.SetColor(0, 0);
|
||||
args.SetStyle(TriBlendMode::Shaded, thing->Alpha, 1.0 - thing->Alpha);
|
||||
args.SetTexture(tex, thing->Translation, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.destalpha = (uint32_t)(256 - thing->Alpha * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(thing->Alpha * 256);
|
||||
blendmode = args.translation ? TriBlendMode::TranslateAdd : TriBlendMode::Add;
|
||||
args.SetStyle(args.Translation() ? TriBlendMode::TranslateAdd : TriBlendMode::Add, thing->Alpha, 1.0 - thing->Alpha);
|
||||
}
|
||||
|
||||
if (blendmode == TriBlendMode::Shaded)
|
||||
{
|
||||
args.SetTexture(tex, thing->Translation, true);
|
||||
}
|
||||
|
||||
if (!PolyRenderer::Instance()->RenderTarget->IsBgra())
|
||||
{
|
||||
uint32_t r = (args.uniforms.color >> 16) & 0xff;
|
||||
uint32_t g = (args.uniforms.color >> 8) & 0xff;
|
||||
uint32_t b = args.uniforms.color & 0xff;
|
||||
args.uniforms.color = RGB32k.RGB[r >> 3][g >> 3][b >> 3];
|
||||
|
||||
if (blendmode == TriBlendMode::Sub) // Sub crashes in pal mode for some weird reason.
|
||||
blendmode = TriBlendMode::Add;
|
||||
}
|
||||
|
||||
args.subsectorTest = true;
|
||||
args.writeSubsector = false;
|
||||
args.writeStencil = false;
|
||||
args.blendmode = blendmode;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
bool RenderPolySprite::IsThingCulled(AActor *thing)
|
||||
|
|
|
@ -24,12 +24,10 @@
|
|||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolySprite
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue, float t1, float t2);
|
||||
|
||||
static bool GetLine(AActor *thing, DVector2 &left, DVector2 &right);
|
||||
static bool IsThingCulled(AActor *thing);
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
EXTERN_CVAR(Bool, r_drawmirrors)
|
||||
|
||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
||||
bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals)
|
||||
{
|
||||
PolyDrawLinePortal *polyportal = nullptr;
|
||||
if (line->backsector == nullptr && line->linedef && line->sidedef == line->linedef->sidedef[0] && (line->linedef->special == Line_Mirror && r_drawmirrors))
|
||||
|
@ -165,7 +165,7 @@ bool RenderPolyWall::RenderLine(const TriMatrix &worldToClip, const Vec4f &clipP
|
|||
return polyportal != nullptr;
|
||||
}
|
||||
|
||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
|
||||
void RenderPolyWall::Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput)
|
||||
{
|
||||
double frontceilz1 = fakeFloor->top.plane->ZatPoint(line->v1);
|
||||
double frontfloorz1 = fakeFloor->bottom.plane->ZatPoint(line->v1);
|
||||
|
@ -198,7 +198,7 @@ void RenderPolyWall::SetCoords(const DVector2 &v1, const DVector2 &v2, double ce
|
|||
this->floor2 = floor2;
|
||||
}
|
||||
|
||||
void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull)
|
||||
void RenderPolyWall::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull)
|
||||
{
|
||||
bool foggy = false;
|
||||
FTexture *tex = GetTexture();
|
||||
|
@ -248,32 +248,23 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
|
|||
}
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
|
||||
args.uniforms.light = (uint32_t)(GetLightLevel() / 255.0f * 256.0f);
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
args.uniforms.subsectorDepth = SubsectorDepth;
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = 4;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = StencilValue;
|
||||
args.stencilwritevalue = StencilValue + 1;
|
||||
args.SetLight(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]), GetLightLevel(), PolyRenderer::Instance()->Light.WallGlobVis(foggy), false);
|
||||
args.SetSubsectorDepth(SubsectorDepth);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(StencilValue);
|
||||
args.SetWriteStencil(true, StencilValue + 1);
|
||||
if (tex)
|
||||
args.SetTexture(tex);
|
||||
args.SetColormap(GetColorTable(Line->frontsector->Colormap, Line->frontsector->SpecialColors[sector_t::walltop]));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
|
||||
//if (Side && Side->lighthead)
|
||||
// args.uniforms.light = 255; // Make walls touched by a light fullbright!
|
||||
args.SetClipPlane(clipPlane);
|
||||
|
||||
if (Polyportal)
|
||||
{
|
||||
args.stencilwritevalue = Polyportal->StencilValue;
|
||||
args.writeColor = false;
|
||||
args.writeSubsector = false;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
Polyportal->Shape.push_back({ args.vinput, args.vcount, args.ccw, args.uniforms.subsectorDepth });
|
||||
args.SetWriteStencil(true, Polyportal->StencilValue);
|
||||
args.SetWriteColor(false);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
Polyportal->Shape.push_back({ vertices, 4, true, SubsectorDepth });
|
||||
|
||||
angle_t angle1, angle2;
|
||||
if (cull.GetAnglesForLine(v1.X, v1.Y, v2.X, v2.Y, angle1, angle2))
|
||||
|
@ -281,21 +272,16 @@ void RenderPolyWall::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane
|
|||
}
|
||||
else if (!Masked)
|
||||
{
|
||||
args.blendmode = TriBlendMode::Copy;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetStyle(TriBlendMode::Copy);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.destalpha = (Line->flags & ML_ADDTRANS) ? 256 : (uint32_t)(256 - Line->alpha * 256);
|
||||
args.uniforms.srcalpha = (uint32_t)(Line->alpha * 256);
|
||||
args.subsectorTest = true;
|
||||
args.writeSubsector = false;
|
||||
args.writeStencil = false;
|
||||
if (args.uniforms.destalpha == 0 && args.uniforms.srcalpha == 256)
|
||||
args.blendmode = TriBlendMode::AlphaBlend;
|
||||
else
|
||||
args.blendmode = TriBlendMode::Add;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetStyle((Line->flags & ML_ADDTRANS) ? TriBlendMode::Add : TriBlendMode::AlphaBlend, Line->alpha, 1.0);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(true);
|
||||
args.SetWriteStencil(false);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
||||
RenderPolyDecal::RenderWallDecals(worldToClip, clipPlane, LineSeg, SubsectorDepth, StencilValue);
|
||||
|
|
|
@ -27,16 +27,15 @@
|
|||
class PolyTranslucentObject;
|
||||
class PolyDrawLinePortal;
|
||||
class PolyCull;
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolyWall
|
||||
{
|
||||
public:
|
||||
static bool RenderLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
|
||||
static bool RenderLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, std::vector<PolyTranslucentObject*> &translucentWallsOutput, std::vector<std::unique_ptr<PolyDrawLinePortal>> &linePortals);
|
||||
static void Render3DFloorLine(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull, seg_t *line, sector_t *frontsector, uint32_t subsectorDepth, uint32_t stencilValue, F3DFloor *fakeFloor, std::vector<PolyTranslucentObject*> &translucentWallsOutput);
|
||||
|
||||
void SetCoords(const DVector2 &v1, const DVector2 &v2, double ceil1, double floor1, double ceil2, double floor2);
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, PolyCull &cull);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, PolyCull &cull);
|
||||
|
||||
DVector2 v1;
|
||||
DVector2 v2;
|
||||
|
|
|
@ -29,7 +29,7 @@
|
|||
#include "polyrenderer/poly_renderer.h"
|
||||
#include "polyrenderer/scene/poly_light.h"
|
||||
|
||||
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue)
|
||||
{
|
||||
if (RenderPolySprite::IsThingCulled(thing))
|
||||
return;
|
||||
|
@ -97,35 +97,18 @@ void RenderPolyWallSprite::Render(const TriMatrix &worldToClip, const Vec4f &cli
|
|||
}
|
||||
|
||||
bool fullbrightSprite = ((thing->renderflags & RF_FULLBRIGHT) || (thing->flags5 & MF5_BRIGHT));
|
||||
PolyCameraLight *cameraLight = PolyCameraLight::Instance();
|
||||
int lightlevel = fullbrightSprite ? 255 : thing->Sector->lightlevel + actualextralight;
|
||||
|
||||
PolyDrawArgs args;
|
||||
args.uniforms.globvis = (float)PolyRenderer::Instance()->Light.WallGlobVis(foggy);
|
||||
if (fullbrightSprite || cameraLight->FixedLightLevel() >= 0 || cameraLight->FixedColormap())
|
||||
{
|
||||
args.uniforms.light = 256;
|
||||
args.uniforms.flags = TriUniforms::fixed_light | TriUniforms::nearest_filter;
|
||||
}
|
||||
else
|
||||
{
|
||||
args.uniforms.light = (uint32_t)((thing->Sector->lightlevel + actualextralight) / 255.0f * 256.0f);
|
||||
args.uniforms.flags = TriUniforms::nearest_filter;
|
||||
}
|
||||
args.uniforms.subsectorDepth = subsectorDepth;
|
||||
|
||||
args.objectToClip = &worldToClip;
|
||||
args.vinput = vertices;
|
||||
args.vcount = 4;
|
||||
args.mode = TriangleDrawMode::Fan;
|
||||
args.ccw = true;
|
||||
args.stenciltestvalue = stencilValue;
|
||||
args.stencilwritevalue = stencilValue;
|
||||
args.SetLight(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true), lightlevel, PolyRenderer::Instance()->Light.WallGlobVis(foggy), fullbrightSprite);
|
||||
args.SetTransform(&worldToClip);
|
||||
args.SetFaceCullCCW(true);
|
||||
args.SetStencilTestValue(stencilValue);
|
||||
args.SetTexture(tex);
|
||||
args.SetColormap(GetColorTable(sub->sector->Colormap, sub->sector->SpecialColors[sector_t::sprites], true));
|
||||
args.SetClipPlane(clipPlane.x, clipPlane.y, clipPlane.z, clipPlane.w);
|
||||
args.subsectorTest = true;
|
||||
args.writeSubsector = false;
|
||||
args.writeStencil = false;
|
||||
args.blendmode = TriBlendMode::AlphaBlend;
|
||||
PolyTriangleDrawer::draw(args);
|
||||
args.SetClipPlane(clipPlane);
|
||||
args.SetSubsectorDepthTest(true);
|
||||
args.SetWriteSubsectorDepth(false);
|
||||
args.SetWriteStencil(false);
|
||||
args.SetStyle(TriBlendMode::AlphaBlend);
|
||||
args.DrawArray(vertices, 4, PolyDrawMode::TriangleFan);
|
||||
}
|
||||
|
|
|
@ -24,10 +24,8 @@
|
|||
|
||||
#include "polyrenderer/drawers/poly_triangle.h"
|
||||
|
||||
class Vec4f;
|
||||
|
||||
class RenderPolyWallSprite
|
||||
{
|
||||
public:
|
||||
void Render(const TriMatrix &worldToClip, const Vec4f &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
void Render(const TriMatrix &worldToClip, const PolyClipPlane &clipPlane, AActor *thing, subsector_t *sub, uint32_t subsectorDepth, uint32_t stencilValue);
|
||||
};
|
||||
|
|
|
@ -84,6 +84,7 @@ int I_PickIWad_Gtk (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
|||
int I_PickIWad_Cocoa (WadStuff *wads, int numwads, bool showwin, int defaultiwad);
|
||||
#endif
|
||||
|
||||
double PerfToSec, PerfToMillisec;
|
||||
uint32_t LanguageIDs[4];
|
||||
|
||||
int (*I_GetTime) (bool saveMS);
|
||||
|
|
|
@ -26,7 +26,6 @@
|
|||
|
||||
struct event_t;
|
||||
|
||||
extern int gST_X;
|
||||
extern int gST_Y;
|
||||
|
||||
bool ST_Responder(event_t* ev);
|
||||
|
|
|
@ -99,7 +99,7 @@ namespace swrenderer
|
|||
v = v - floor(v);
|
||||
double v_step = uv_stepd / texture->GetHeight();
|
||||
|
||||
if (std::isnan(v) || std::isnan(v_step)) // this should never happen, but it apparently does..
|
||||
if (isnan(v) || isnan(v_step)) // this should never happen, but it apparently does..
|
||||
{
|
||||
uv_stepd = 0.0;
|
||||
v = 0.0;
|
||||
|
|
|
@ -81,7 +81,6 @@ int CleanWidth, CleanHeight;
|
|||
// Above minus 1 (or 1, if they are already 1)
|
||||
int CleanXfac_1, CleanYfac_1, CleanWidth_1, CleanHeight_1;
|
||||
|
||||
CVAR (Bool, hud_scale, true, CVAR_ARCHIVE);
|
||||
|
||||
DEFINE_ACTION_FUNCTION(_Screen, GetWidth)
|
||||
{
|
||||
|
@ -210,33 +209,21 @@ bool DCanvas::SetTextureParms(DrawParms *parms, FTexture *img, double xx, double
|
|||
case DTA_HUDRules:
|
||||
case DTA_HUDRulesC:
|
||||
{
|
||||
// Note that this has been deprecated because it cannot intelligently decide what scale
|
||||
// actually needs to be used in conjunction with the active status bar.
|
||||
// Note that this has been deprecated because the HUD should be drawn by the status bar.
|
||||
bool xright = parms->x < 0;
|
||||
bool ybot = parms->y < 0;
|
||||
DVector2 scale = StatusBar->GetHUDScale();
|
||||
|
||||
if (hud_scale)
|
||||
{
|
||||
parms->x *= CleanXfac;
|
||||
if (parms->cleanmode == DTA_HUDRulesC)
|
||||
parms->x += Width * 0.5;
|
||||
else if (xright)
|
||||
parms->x = Width + parms->x;
|
||||
parms->y *= CleanYfac;
|
||||
if (ybot)
|
||||
parms->y = Height + parms->y;
|
||||
parms->destwidth = parms->texwidth * CleanXfac;
|
||||
parms->destheight = parms->texheight * CleanYfac;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (parms->cleanmode == DTA_HUDRulesC)
|
||||
parms->x += Width * 0.5;
|
||||
else if (xright)
|
||||
parms->x = Width + parms->x;
|
||||
if (ybot)
|
||||
parms->y = Height + parms->y;
|
||||
}
|
||||
parms->x *= scale.X;
|
||||
if (parms->cleanmode == DTA_HUDRulesC)
|
||||
parms->x += Width * 0.5;
|
||||
else if (xright)
|
||||
parms->x = Width + parms->x;
|
||||
parms->y *= scale.Y;
|
||||
if (ybot)
|
||||
parms->y = Height + parms->y;
|
||||
parms->destwidth = parms->texwidth * scale.X;
|
||||
parms->destheight = parms->texheight * scale.Y;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -513,7 +500,7 @@ bool DCanvas::ParseDrawTextureTags(FTexture *img, double x, double y, uint32_t t
|
|||
|
||||
case DTA_FillColor:
|
||||
parms->fillcolor = ListGetInt(tags);
|
||||
if (parms->fillcolor != -1)
|
||||
if (parms->fillcolor != ~0u)
|
||||
{
|
||||
fillcolorset = true;
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ const char *GetVersionString();
|
|||
// Version stored in the ini's [LastRun] section.
|
||||
// Bump it if you made some configuration change that you want to
|
||||
// be able to migrate in FGameConfigFile::DoGlobalSetup().
|
||||
#define LASTRUNVERSION "211"
|
||||
#define LASTRUNVERSION "212"
|
||||
|
||||
// Protocol version used in demos.
|
||||
// Bump it if you change existing DEM_ commands or add new ones.
|
||||
|
|
|
@ -27,6 +27,7 @@ gameinfo
|
|||
backpacktype = "Backpack"
|
||||
armoricons = "ARM1A0", 0.5, "ARM2A0"
|
||||
statusbar = "sbarinfo/doom.txt"
|
||||
//statusbarclass = "DoomStatusBar"
|
||||
intermissionmusic = "$MUSIC_DM2INT"
|
||||
intermissioncounter = true
|
||||
weaponslot = 1, "Fist", "Chainsaw"
|
||||
|
|
|
@ -67,6 +67,7 @@ gameinfo
|
|||
statscreen_coop = "CoopStatusScreen"
|
||||
statscreen_dm = "DeathmatchStatusScreen"
|
||||
statscreen_single = "RavenStatusScreen"
|
||||
statusbarclass = "StrifeStatusBar"
|
||||
}
|
||||
|
||||
DoomEdNums
|
||||
|
|
|
@ -843,7 +843,6 @@ OptionMenu "HUDOptions"
|
|||
Option "$HUDMNU_NAMETAGS", "displaynametags", "DisplayTagsTypes"
|
||||
Option "$HUDMNU_NAMETAGCOLOR", "nametagcolor", "TextColors", "displaynametags"
|
||||
Option "$HUDMNU_SCALESTATBAR", "st_scale", "OnOff"
|
||||
Option "$HUDMNU_SCALEFULLSCREENHUD", "hud_scale", "OnOff"
|
||||
Option "$HUDMNU_OLDOUCH", "st_oldouch", "OnOff"
|
||||
StaticText " "
|
||||
Option "$HUDMNU_HEXENFLASHES", "pf_hexenweaps", "ZDoomHexen"
|
||||
|
|
|
@ -4,13 +4,10 @@ struct SBarInfo native ui
|
|||
native void SetScaled(bool scaled);
|
||||
native void Destroy();
|
||||
native void AttachToPlayer(PlayerInfo player);
|
||||
native void ScreenSizeChanged();
|
||||
native void Draw(int state);
|
||||
native void NewGame();
|
||||
native bool MustDrawLog(int state);
|
||||
native void SetMugShotState(String state_name, bool wait_till_done, bool reset);
|
||||
native void Tick();
|
||||
native clearscope void ReceivedWeapon(Weapon weapon);
|
||||
native void FlashItem(class<Inventory> itemtype);
|
||||
native void ShowPop(int popnum);
|
||||
}
|
||||
|
@ -41,12 +38,6 @@ class SBarInfoWrapper : BaseStatusBar
|
|||
core.AttachToPlayer(player);
|
||||
}
|
||||
|
||||
override void ScreenSizeChanged()
|
||||
{
|
||||
Super.ScreenSizeChanged();
|
||||
core.ScreenSizeChanged();
|
||||
}
|
||||
|
||||
override void Draw(int state, double TicFrac)
|
||||
{
|
||||
Super.Draw(state, TicFrac);
|
||||
|
@ -68,22 +59,12 @@ class SBarInfoWrapper : BaseStatusBar
|
|||
return core.MustDrawLog(state);
|
||||
}
|
||||
|
||||
override void SetMugShotState(String state_name, bool wait_till_done, bool reset)
|
||||
{
|
||||
core.SetMugShotState(state_name, wait_till_done, reset);
|
||||
}
|
||||
|
||||
override void Tick()
|
||||
{
|
||||
Super.Tick();
|
||||
core.Tick();
|
||||
}
|
||||
|
||||
override void ReceivedWeapon(Weapon weapon)
|
||||
{
|
||||
core.ReceivedWeapon(weapon);
|
||||
}
|
||||
|
||||
override void FlashItem(class<Inventory> itemtype)
|
||||
{
|
||||
core.FlashItem(itemtype);
|
||||
|
|
|
@ -157,16 +157,20 @@ class BaseStatusBar native ui
|
|||
native double Displacement;
|
||||
native PlayerInfo CPlayer;
|
||||
native bool ShowLog;
|
||||
native Vector2 defaultScale; // factor for fully scaled fullscreen display.
|
||||
|
||||
// These are block properties for the drawers. A child class can set them to have a block of items use the same settings.
|
||||
native double Alpha;
|
||||
native Vector2 drawOffset; // can be set by subclasses to offset drawing operations
|
||||
native double drawClip[4]; // defines a clipping rectangle (not used yet)
|
||||
native bool fullscreenOffsets; // current screen is displayed with fullscreen behavior.
|
||||
native Vector2 cleanScale; // factor for scaled fullscreen display.
|
||||
|
||||
|
||||
native void SetSize(int height, int vwidth, int vheight);
|
||||
native Vector2 GetHUDScale();
|
||||
native void BeginStatusBar(int resW, int resH, int relTop, bool completeborder = false, bool forceScaled = false);
|
||||
native void BeginHUD(int resW, int resH, double Alpha, bool forcescaled = false);
|
||||
|
||||
virtual void Init() {}
|
||||
|
||||
native virtual void SetScaled(bool scale, bool force = false);
|
||||
|
@ -174,6 +178,7 @@ class BaseStatusBar native ui
|
|||
native virtual void Draw (int state, double TicFrac);
|
||||
native virtual void ScreenSizeChanged ();
|
||||
native virtual clearscope void ReceivedWeapon (Weapon weapn);
|
||||
native virtual clearscope void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false);
|
||||
|
||||
virtual void FlashItem (class<Inventory> itemtype) {}
|
||||
virtual void AttachToPlayer (PlayerInfo player) { CPlayer = player; }
|
||||
|
@ -181,7 +186,6 @@ class BaseStatusBar native ui
|
|||
virtual void NewGame () {}
|
||||
virtual void ShowPop (int popnum) { ShowLog = (popnum == POP_Log && !ShowLog); }
|
||||
virtual bool MustDrawLog(int state) { return true; }
|
||||
virtual void SetMugShotState (String state_name, bool wait_till_done=false, bool reset=false) {}
|
||||
|
||||
native void RefreshBackground () const;
|
||||
native TextureID GetMugshot(PlayerInfo player, String default_face, int accuracy, int stateflags=MugShot.STANDARD);
|
||||
|
|
Loading…
Reference in a new issue