Merge remote-tracking branch 'gzdoom/master' into newmaster

This commit is contained in:
Major Cooke 2020-01-18 11:33:52 -06:00
commit c4ccbaa1ce
36 changed files with 2558 additions and 2554 deletions

View file

@ -713,7 +713,6 @@ set( POLYRENDER_SOURCES
rendering/polyrenderer/drawers/screen_scanline_setup.cpp
rendering/polyrenderer/drawers/screen_shader.cpp
rendering/polyrenderer/drawers/screen_blend.cpp
rendering/polyrenderer/math/gpu_types.cpp
)
# These files will be flagged as "headers" so that they appear in project files

View file

@ -1252,7 +1252,7 @@ FString C_GetMassCVarString (uint32_t filter, bool compact)
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
{
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE|CVAR_IGNORE|CVAR_NOSAVEGAME)))
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE|CVAR_IGNORE)))
{
UCVarValue val = cvar->GetGenericRep(CVAR_String);
dump << '\\' << cvar->GetName() << '\\' << val.String;
@ -1273,7 +1273,7 @@ void C_SerializeCVars(FSerializer &arc, const char *label, uint32_t filter)
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
{
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_NOSAVEGAME)))
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{
UCVarValue val = cvar->GetGenericRep(CVAR_String);
char* c = const_cast<char*>(val.String);
@ -1285,7 +1285,7 @@ void C_SerializeCVars(FSerializer &arc, const char *label, uint32_t filter)
{
for (cvar = CVars; cvar != NULL; cvar = cvar->m_Next)
{
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_NOSAVEGAME)))
if ((cvar->Flags & filter) && !(cvar->Flags & (CVAR_NOSAVE | CVAR_IGNORE | CVAR_CONFIG_ONLY)))
{
UCVarValue val;
char *c = nullptr;
@ -1593,7 +1593,7 @@ void C_ArchiveCVars (FConfigFile *f, uint32_t filter)
while (cvar)
{
if ((cvar->Flags &
(CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_MOD|CVAR_AUTO|CVAR_USERINFO|CVAR_SERVERINFO|CVAR_NOSAVE))
(CVAR_GLOBALCONFIG|CVAR_ARCHIVE|CVAR_MOD|CVAR_AUTO|CVAR_USERINFO|CVAR_SERVERINFO|CVAR_NOSAVE|CVAR_CONFIG_ONLY))
== filter)
{
cvarlist.Push(cvar);

View file

@ -48,26 +48,29 @@ CVARS (console variables)
enum
{
CVAR_ARCHIVE = 1, // set to cause it to be saved to config
CVAR_USERINFO = 2, // added to userinfo when changed
CVAR_SERVERINFO = 4, // added to serverinfo when changed
CVAR_NOSET = 8, // don't allow change from console at all,
// but can be set from the command line
CVAR_LATCH = 16, // save changes until server restart
CVAR_UNSETTABLE = 32, // can unset this var from console
CVAR_DEMOSAVE = 64, // save the value of this cvar in a demo
CVAR_ISDEFAULT = 128, // is cvar unchanged since creation?
CVAR_AUTO = 256, // allocated; needs to be freed when destroyed
CVAR_NOINITCALL = 512, // don't call callback at game start
CVAR_GLOBALCONFIG = 1024, // cvar is saved to global config section
CVAR_VIDEOCONFIG = 2048, // cvar is saved to video config section (not implemented)
CVAR_NOSAVE = 4096, // when used with CVAR_SERVERINFO, do not save var to savegame and config.
CVAR_MOD = 8192, // cvar was defined by a mod
CVAR_IGNORE = 16384,// do not send cvar across the network/inaccesible from ACS (dummy mod cvar)
CVAR_CHEAT = 32768,// can be set only when sv_cheats is enabled
CVAR_UNSAFECONTEXT = 65536,// cvar value came from unsafe context
CVAR_VIRTUAL = 0x20000, // do not invoke the callback recursively so it can be used to mirror an external variable.
CVAR_NOSAVEGAME = 0x40000, // do not save var to savegame.
CVAR_ARCHIVE = 1, // set to cause it to be saved to config.
CVAR_USERINFO = 1 << 1, // added to userinfo when changed.
CVAR_SERVERINFO = 1 << 2, // added to serverinfo when changed.
CVAR_NOSET = 1 << 3, // don't allow change from console at all,
// but can be set from the command line.
CVAR_LATCH = 1 << 4, // save changes until server restart.
CVAR_UNSETTABLE = 1 << 5, // can unset this var from console.
CVAR_DEMOSAVE = 1 << 6, // save the value of this cvar in a demo.
CVAR_ISDEFAULT = 1 << 7, // is cvar unchanged since creation?
CVAR_AUTO = 1 << 8, // allocated; needs to be freed when destroyed.
CVAR_NOINITCALL = 1 << 9, // don't call callback at game start.
CVAR_GLOBALCONFIG = 1 << 10, // cvar is saved to global config section.
CVAR_VIDEOCONFIG = 1 << 11, // cvar is saved to video config section (not implemented).
CVAR_NOSAVE = 1 << 12, // when used with CVAR_SERVERINFO, do not save var to savegame
// and config.
CVAR_MOD = 1 << 13, // cvar was defined by a mod.
CVAR_IGNORE = 1 << 14, // do not send cvar across the network/inaccesible from ACS
// (dummy mod cvar).
CVAR_CHEAT = 1 << 15, // can be set only when sv_cheats is enabled.
CVAR_UNSAFECONTEXT = 1 << 16, // cvar value came from unsafe context.
CVAR_VIRTUAL = 1 << 17, // do not invoke the callback recursively so it can be used to
// mirror an external variable.
CVAR_CONFIG_ONLY = 1 << 18, // do not save var to savegame and do not send it across network.
};
union UCVarValue

View file

@ -1479,7 +1479,7 @@ void ParseCVarInfo()
}
else if (stricmp(sc.String, "nosave") == 0)
{
cvarflags |= CVAR_NOSAVEGAME;
cvarflags |= CVAR_CONFIG_ONLY;
}
else
{
@ -1487,11 +1487,22 @@ void ParseCVarInfo()
}
sc.MustGetAnyToken();
}
// Possibility of defining a cvar as 'server nosave' or 'user nosave' is kept for
// compatibility reasons.
if (cvarflags & CVAR_CONFIG_ONLY)
{
cvarflags &= ~CVAR_SERVERINFO;
cvarflags &= ~CVAR_USERINFO;
}
// Do some sanity checks.
if ((cvarflags & (CVAR_SERVERINFO|CVAR_USERINFO)) == 0 ||
// No need to check server-nosave and user-nosave combinations because they
// are made impossible right above.
if ((cvarflags & (CVAR_SERVERINFO|CVAR_USERINFO|CVAR_CONFIG_ONLY)) == 0 ||
(cvarflags & (CVAR_SERVERINFO|CVAR_USERINFO)) == (CVAR_SERVERINFO|CVAR_USERINFO))
{
sc.ScriptError("One of 'server' or 'user' must be specified");
sc.ScriptError("One of 'server', 'user', or 'nosave' must be specified");
}
// The next token must be the cvar type.
if (sc.TokenType == TK_Bool)
@ -2762,7 +2773,7 @@ static int D_DoomMain_Internal (void)
// enable custom invulnerability map here
if (cl_customizeinvulmap)
R_InitColormaps(true);
R_UpdateInvulnerabilityColormap();
if (!restart)
{

View file

@ -579,6 +579,12 @@ void FGameConfigFile::DoGameSetup (const char *gamename)
ReadCVars (0);
}
strncpy (subsection, "ConfigOnlyVariables", sublen);
if (SetSection (section))
{
ReadCVars (0);
}
strncpy (subsection, "ConsoleVariables", sublen);
if (SetSection (section))
{
@ -671,6 +677,11 @@ void FGameConfigFile::DoModSetup(const char *gamename)
{
ReadCVars (CVAR_MOD|CVAR_SERVERINFO|CVAR_IGNORE);
}
mysnprintf(section, countof(section), "%s.ConfigOnlyVariables.Mod", gamename);
if (SetSection (section))
{
ReadCVars (CVAR_MOD|CVAR_CONFIG_ONLY|CVAR_IGNORE);
}
// Signal that these sections should be rewritten when saving the config.
bModSetup = true;
}
@ -756,6 +767,19 @@ void FGameConfigFile::ArchiveGameData (const char *gamename)
}
}
strncpy (subsection, "ConfigOnlyVariables", sublen);
SetSection (section, true);
ClearCurrentSection ();
C_ArchiveCVars (this, CVAR_ARCHIVE|CVAR_AUTO|CVAR_CONFIG_ONLY);
if (bModSetup)
{
strncpy (subsection, "ConfigOnlyVariables.Mod", sublen);
SetSection (section, true);
ClearCurrentSection ();
C_ArchiveCVars (this, CVAR_ARCHIVE|CVAR_AUTO|CVAR_MOD|CVAR_CONFIG_ONLY);
}
strncpy (subsection, "UnknownConsoleVariables", sublen);
SetSection (section, true);
ClearCurrentSection ();

View file

@ -46,17 +46,17 @@
CUSTOM_CVAR(Bool, cl_customizeinvulmap, false, CVAR_ARCHIVE|CVAR_NOINITCALL)
{
R_InitColormaps(true);
R_UpdateInvulnerabilityColormap();
}
CUSTOM_CVAR(Color, cl_custominvulmapcolor1, 0x00001a, CVAR_ARCHIVE|CVAR_NOINITCALL)
{
if (cl_customizeinvulmap)
R_InitColormaps(true);
R_UpdateInvulnerabilityColormap();
}
CUSTOM_CVAR(Color, cl_custominvulmapcolor2, 0xa6a67a, CVAR_ARCHIVE|CVAR_NOINITCALL)
{
if (cl_customizeinvulmap)
R_InitColormaps(true);
R_UpdateInvulnerabilityColormap();
}
@ -99,6 +99,8 @@ static void FreeSpecialLights();
//
//==========================================================================
static void UpdateSpecialColormap(unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2);
int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b2)
{
// Clamp these in range for the hardware shader.
@ -123,8 +125,15 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b
}
}
FSpecialColormap *cm = &SpecialColormaps[SpecialColormaps.Reserve(1)];
UpdateSpecialColormap(SpecialColormaps.Reserve(1), r1, g1, b1, r2, g2, b2);
return SpecialColormaps.Size() - 1;
}
static void UpdateSpecialColormap(unsigned int index, float r1, float g1, float b1, float r2, float g2, float b2)
{
assert(index < SpecialColormaps.Size());
FSpecialColormap *cm = &SpecialColormaps[index];
cm->ColorizeStart[0] = float(r1);
cm->ColorizeStart[1] = float(g1);
cm->ColorizeStart[2] = float(b1);
@ -159,7 +168,6 @@ int AddSpecialColormap(float r1, float g1, float b1, float r2, float g2, float b
MIN(255, int(g1 + i*g2)),
MIN(255, int(b1 + i*b2)));
}
return SpecialColormaps.Size() - 1;
}
//==========================================================================
@ -258,25 +266,6 @@ void R_InitColormaps (bool allowCustomColormap)
}
}
// some of us really don't like Doom's idea of an invulnerability sphere colormap
// this hack will override that
if (allowCustomColormap && cl_customizeinvulmap)
{
uint32_t color1 = cl_custominvulmapcolor1;
uint32_t color2 = cl_custominvulmapcolor2;
float r1 = (float)((color1 & 0xff0000) >> 16) / 128.f;
float g1 = (float)((color1 & 0x00ff00) >> 8) / 128.f;
float b1 = (float)((color1 & 0x0000ff) >> 0) / 128.f;
float r2 = (float)((color2 & 0xff0000) >> 16) / 128.f;
float g2 = (float)((color2 & 0x00ff00) >> 8) / 128.f;
float b2 = (float)((color2 & 0x0000ff) >> 0) / 128.f;
SpecialColormapParms[0] = {{r1, g1, b1}, {r2, g2, b2}};
}
else
{
SpecialColormapParms[0] = {{1.0, 1.0, 1.0}, {0.0, 0.0, 0.0}};
}
// build default special maps (e.g. invulnerability)
for (unsigned i = 0; i < countof(SpecialColormapParms); ++i)
@ -341,3 +330,41 @@ uint32_t R_BlendForColormap (uint32_t map)
map < fakecmaps.Size() ? uint32_t(fakecmaps[map].blend) : 0;
}
//==========================================================================
//
// R_UpdateInvulnerabilityColormap
//
//==========================================================================
void R_UpdateInvulnerabilityColormap()
{
float r1, g1, b1, r2, g2, b2;
// some of us really don't like Doom's idea of an invulnerability sphere colormap
// this hack will override that
if (cl_customizeinvulmap)
{
uint32_t color1 = cl_custominvulmapcolor1;
uint32_t color2 = cl_custominvulmapcolor2;
r1 = (float)((color1 & 0xff0000) >> 16) / 128.f;
g1 = (float)((color1 & 0x00ff00) >> 8) / 128.f;
b1 = (float)((color1 & 0x0000ff) >> 0) / 128.f;
r2 = (float)((color2 & 0xff0000) >> 16) / 128.f;
g2 = (float)((color2 & 0x00ff00) >> 8) / 128.f;
b2 = (float)((color2 & 0x0000ff) >> 0) / 128.f;
}
else
{
FSpecialColormapParameters &defaultColors = SpecialColormapParms[0];
r1 = defaultColors.Start[0];
g1 = defaultColors.Start[1];
b1 = defaultColors.Start[2];
r2 = defaultColors.End[0];
g2 = defaultColors.End[1];
b2 = defaultColors.End[2];
}
UpdateSpecialColormap(0, r1, g1, b1, r2, g2, b2);
}

View file

@ -8,6 +8,8 @@ struct lightlist_t;
void R_InitColormaps (bool allowCustomColormap = false);
void R_DeinitColormaps ();
void R_UpdateInvulnerabilityColormap ();
uint32_t R_ColormapNumForName(const char *name); // killough 4/4/98
void R_SetDefaultColormap (const char *name); // [RH] change normal fadetable
uint32_t R_BlendForColormap (uint32_t map); // [RH] return calculated blend for a colormap

View file

@ -136,7 +136,7 @@ void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *v
if ((UseVertexData & 2) == 0)
{
const auto &n = thread->mainVertexShader.Data.uVertexNormal;
thread->mainVertexShader.aNormal = Vec4f(n.X, n.Y, n.Z, 1.0);
thread->mainVertexShader.aNormal = FVector4(n.X, n.Y, n.Z, 1.0);
thread->mainVertexShader.aNormal2 = thread->mainVertexShader.aNormal;
}
else
@ -149,8 +149,8 @@ void PolyVertexInputAssembly::Load(PolyTriangleThreadData *thread, const void *v
float x2 = ((n2 << 22) >> 22) / 512.0f;
float y2 = ((n2 << 12) >> 22) / 512.0f;
float z2 = ((n2 << 2) >> 22) / 512.0f;
thread->mainVertexShader.aNormal = Vec4f(x, y, z, 0.0f);
thread->mainVertexShader.aNormal2 = Vec4f(x2, y2, z2, 0.0f);
thread->mainVertexShader.aNormal = FVector4(x, y, z, 0.0f);
thread->mainVertexShader.aNormal2 = FVector4(x2, y2, z2, 0.0f);
}
}

View file

@ -85,6 +85,9 @@ PolyFrameBuffer::~PolyFrameBuffer()
PolyBuffer::ResetAll();
PPResource::ResetAll();
delete mScreenQuad.VertexBuffer;
delete mScreenQuad.IndexBuffer;
delete mVertexData;
delete mSkyData;
delete mViewpoints;
@ -111,6 +114,21 @@ void PolyFrameBuffer::InitializeState()
mViewpoints = new HWViewpointBuffer;
mLights = new FLightBuffer();
static const FVertexBufferAttribute format[] =
{
{ 0, VATTR_VERTEX, VFmt_Float3, (int)myoffsetof(ScreenQuadVertex, x) },
{ 0, VATTR_TEXCOORD, VFmt_Float2, (int)myoffsetof(ScreenQuadVertex, u) },
{ 0, VATTR_COLOR, VFmt_Byte4, (int)myoffsetof(ScreenQuadVertex, color0) }
};
uint32_t indices[6] = { 0, 1, 2, 1, 3, 2 };
mScreenQuad.VertexBuffer = screen->CreateVertexBuffer();
mScreenQuad.VertexBuffer->SetFormat(1, 3, sizeof(ScreenQuadVertex), format);
mScreenQuad.IndexBuffer = screen->CreateIndexBuffer();
mScreenQuad.IndexBuffer->SetData(6 * sizeof(uint32_t), indices, false);
CheckCanvas();
}
@ -436,9 +454,54 @@ void PolyFrameBuffer::DrawScene(HWDrawInfo *di, int drawmode)
di->RenderTranslucent(*GetRenderState());
}
static uint8_t ToIntColorComponent(float v)
{
return clamp((int)(v * 255.0f + 0.5f), 0, 255);
}
void PolyFrameBuffer::PostProcessScene(int fixedcm, const std::function<void()> &afterBloomDrawEndScene2D)
{
afterBloomDrawEndScene2D();
if (fixedcm >= CM_FIRSTSPECIALCOLORMAP && fixedcm < CM_MAXCOLORMAP)
{
FSpecialColormap* scm = &SpecialColormaps[fixedcm - CM_FIRSTSPECIALCOLORMAP];
mRenderState->SetViewport(mScreenViewport.left, mScreenViewport.top, mScreenViewport.width, mScreenViewport.height);
screen->mViewpoints->Set2D(*mRenderState, screen->GetWidth(), screen->GetHeight());
ScreenQuadVertex vertices[4] =
{
{ 0.0f, 0.0f, 0.0f, 0.0f },
{ (float)mScreenViewport.width, 0.0f, 1.0f, 0.0f },
{ 0.0f, (float)mScreenViewport.height, 0.0f, 1.0f },
{ (float)mScreenViewport.width, (float)mScreenViewport.height, 1.0f, 1.0f }
};
mScreenQuad.VertexBuffer->SetData(4 * sizeof(ScreenQuadVertex), vertices, false);
mRenderState->SetVertexBuffer(mScreenQuad.VertexBuffer, 0, 0);
mRenderState->SetIndexBuffer(mScreenQuad.IndexBuffer);
mRenderState->SetObjectColor(PalEntry(255, int(scm->ColorizeStart[0] * 127.5f), int(scm->ColorizeStart[1] * 127.5f), int(scm->ColorizeStart[2] * 127.5f)));
mRenderState->SetAddColor(PalEntry(255, int(scm->ColorizeEnd[0] * 127.5f), int(scm->ColorizeEnd[1] * 127.5f), int(scm->ColorizeEnd[2] * 127.5f)));
mRenderState->EnableDepthTest(false);
mRenderState->EnableMultisampling(false);
mRenderState->SetCulling(Cull_None);
mRenderState->SetScissor(-1, -1, -1, -1);
mRenderState->SetColor(1, 1, 1, 1);
mRenderState->AlphaFunc(Alpha_GEqual, 0.f);
mRenderState->EnableTexture(false);
mRenderState->SetColormapShader(true);
mRenderState->DrawIndexed(DT_Triangles, 0, 6);
mRenderState->SetColormapShader(false);
mRenderState->SetObjectColor(0xffffffff);
mRenderState->SetAddColor(0);
mRenderState->SetVertexBuffer(screen->mVertexData);
mRenderState->EnableTexture(true);
mRenderState->ResetColor();
}
}
uint32_t PolyFrameBuffer::GetCaps()
@ -560,15 +623,24 @@ TArray<uint8_t> PolyFrameBuffer::GetScreenshotBuffer(int &pitch, ESSType &color_
int w = SCREENWIDTH;
int h = SCREENHEIGHT;
IntRect box;
box.left = 0;
box.top = 0;
box.width = w;
box.height = h;
//mPostprocess->DrawPresentTexture(box, true, true);
TArray<uint8_t> ScreenshotBuffer(w * h * 3, true);
//CopyScreenToBuffer(w, h, ScreenshotBuffer.Data());
const uint8_t* pixels = GetCanvas()->GetPixels();
int dindex = 0;
// Convert to RGB
for (int y = 0; y < h; y++)
{
int sindex = y * w * 4;
for (int x = 0; x < w; x++)
{
ScreenshotBuffer[dindex ] = pixels[sindex + 2];
ScreenshotBuffer[dindex + 1] = pixels[sindex + 1];
ScreenshotBuffer[dindex + 2] = pixels[sindex ];
dindex += 3;
sindex += 4;
}
}
pitch = w * 3;
color_type = SS_RGB;

View file

@ -84,6 +84,22 @@ private:
std::unique_ptr<PolyCommandBuffer> mDrawCommands;
RenderMemory mFrameMemory;
struct ScreenQuadVertex
{
float x, y, z;
float u, v;
PalEntry color0;
ScreenQuadVertex() = default;
ScreenQuadVertex(float x, float y, float u, float v) : x(x), y(y), z(1.0f), u(u), v(v), color0(0xffffffff) { }
};
struct ScreenQuad
{
IVertexBuffer* VertexBuffer = nullptr;
IIndexBuffer* IndexBuffer = nullptr;
} mScreenQuad;
bool cur_vsync = false;
};

View file

@ -204,6 +204,12 @@ void PolyRenderState::EnableDrawBuffers(int count)
{
}
void PolyRenderState::SetColormapShader(bool enable)
{
mNeedApply = true;
mColormapShader = enable;
}
void PolyRenderState::EndRenderPass()
{
mDrawCommands = nullptr;
@ -260,14 +266,18 @@ void PolyRenderState::Apply()
mDrawCommands->SetInputAssembly(static_cast<PolyVertexBuffer*>(mVertexBuffer)->VertexFormat);
mDrawCommands->SetRenderStyle(mRenderStyle);
if (mSpecialEffect > EFF_NONE)
if (mColormapShader)
{
mDrawCommands->SetShader(mSpecialEffect, 0, false);
mDrawCommands->SetShader(EFF_NONE, 0, false, true);
}
else if (mSpecialEffect > EFF_NONE)
{
mDrawCommands->SetShader(mSpecialEffect, 0, false, false);
}
else
{
int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0);
mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, mAlphaThreshold >= 0.f);
mDrawCommands->SetShader(EFF_NONE, mTextureEnabled ? effectState : SHADER_NoTexture, mAlphaThreshold >= 0.f, false);
}
PolyPushConstants constants;

View file

@ -45,6 +45,8 @@ public:
PolyVertexInputAssembly *GetVertexFormat(int numBindingPoints, int numAttributes, size_t stride, const FVertexBufferAttribute *attrs);
void EndRenderPass();
void SetColormapShader(bool enable);
private:
void Apply();
void ApplyMaterial();
@ -92,6 +94,7 @@ private:
int mStencilOp = SOP_Keep;
int mCulling = Cull_None;
bool mColorMask[4] = { true, true, true, true };
bool mColormapShader = false;
PolyCommandBuffer* mDrawCommands = nullptr;
};

View file

@ -248,11 +248,12 @@ void PolyTriangleThreadData::SetRenderStyle(FRenderStyle style)
RenderStyle = style;
}
void PolyTriangleThreadData::SetShader(int specialEffect, int effectState, bool alphaTest)
void PolyTriangleThreadData::SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader)
{
SpecialEffect = specialEffect;
EffectState = effectState;
AlphaTest = alphaTest;
ColormapShader = colormapShader;
}
void PolyTriangleThreadData::SetTexture(int unit, const void *pixels, int width, int height, bool bgra)

View file

@ -60,7 +60,7 @@ public:
void SetScissor(int x, int y, int w, int h);
void SetRenderStyle(FRenderStyle style);
void SetTexture(int unit, const void *pixels, int width, int height, bool bgra);
void SetShader(int specialEffect, int effectState, bool alphaTest);
void SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader);
void UpdateClip();
@ -141,6 +141,7 @@ public:
int SpecialEffect = EFF_NONE;
int EffectState = 0;
bool AlphaTest = false;
bool ColormapShader = false;
uint32_t AlphaThreshold = 0x7f000000;
const PolyPushConstants* PushConstants = nullptr;

View file

@ -183,13 +183,14 @@ private:
class PolySetShaderCommand : public PolyDrawerCommand
{
public:
PolySetShaderCommand(int specialEffect, int effectState, bool alphaTest) : specialEffect(specialEffect), effectState(effectState), alphaTest(alphaTest) { }
void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetShader(specialEffect, effectState, alphaTest); }
PolySetShaderCommand(int specialEffect, int effectState, bool alphaTest, bool colormapShader) : specialEffect(specialEffect), effectState(effectState), alphaTest(alphaTest), colormapShader(colormapShader) { }
void Execute(DrawerThread* thread) override { PolyTriangleThreadData::Get(thread)->SetShader(specialEffect, effectState, alphaTest, colormapShader); }
private:
int specialEffect;
int effectState;
bool alphaTest;
bool colormapShader;
};
class PolySetVertexBufferCommand : public PolyDrawerCommand
@ -429,9 +430,9 @@ void PolyCommandBuffer::SetTexture(int unit, void *pixels, int width, int height
mQueue->Push<PolySetTextureCommand>(unit, pixels, width, height, bgra);
}
void PolyCommandBuffer::SetShader(int specialEffect, int effectState, bool alphaTest)
void PolyCommandBuffer::SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader)
{
mQueue->Push<PolySetShaderCommand>(specialEffect, effectState, alphaTest);
mQueue->Push<PolySetShaderCommand>(specialEffect, effectState, alphaTest, colormapShader);
}
void PolyCommandBuffer::PushStreamData(const StreamData &data, const PolyPushConstants &constants)

View file

@ -25,7 +25,6 @@
#include "swrenderer/drawers/r_draw.h"
#include "swrenderer/drawers/r_thread.h"
#include "polyrenderer/drawers/screen_triangle.h"
#include "polyrenderer/math/gpu_types.h"
#include "polyrenderer/drawers/poly_vertex_shader.h"
class DCanvas;
@ -67,7 +66,7 @@ public:
void SetScissor(int x, int y, int w, int h);
void SetRenderStyle(FRenderStyle style);
void SetTexture(int unit, void *pixels, int width, int height, bool bgra);
void SetShader(int specialEffect, int effectState, bool alphaTest);
void SetShader(int specialEffect, int effectState, bool alphaTest, bool colormapShader);
void PushStreamData(const StreamData &data, const PolyPushConstants &constants);
void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
void ClearDepth(float value);
@ -101,7 +100,7 @@ struct PolyPushConstants
{
int uTextureMode;
float uAlphaThreshold;
Vec2f uClipSplit;
FVector2 uClipSplit;
// Lighting + Fog
float uLightLevel;

View file

@ -1,7 +1,6 @@
#pragma once
#include "polyrenderer/math/gpu_types.h"
#include "hwrenderer/scene/hw_viewpointuniforms.h"
#include "hwrenderer/scene/hw_renderstate.h"
@ -12,27 +11,27 @@
class ShadedTriVertex
{
public:
Vec4f gl_Position;
FVector4 gl_Position;
float gl_ClipDistance[5];
Vec4f vTexCoord;
Vec4f vColor;
Vec4f pixelpos;
//Vec3f glowdist;
Vec3f gradientdist;
//Vec4f vEyeNormal;
Vec4f vWorldNormal;
FVector4 vTexCoord;
FVector4 vColor;
FVector4 pixelpos;
//FVector3 glowdist;
FVector3 gradientdist;
//FVector4 vEyeNormal;
FVector4 vWorldNormal;
};
class PolyMainVertexShader : public ShadedTriVertex
{
public:
// Input
Vec4f aPosition;
Vec2f aTexCoord;
Vec4f aColor;
Vec4f aVertex2;
Vec4f aNormal;
Vec4f aNormal2;
FVector4 aPosition;
FVector2 aTexCoord;
FVector4 aColor;
FVector4 aVertex2;
FVector4 aNormal;
FVector4 aNormal2;
// Defines
bool SIMPLE = false;
@ -43,21 +42,21 @@ public:
VSMatrix NormalModelMatrix;
VSMatrix TextureMatrix;
StreamData Data;
Vec2f uClipSplit;
FVector2 uClipSplit;
const HWViewpointUniforms *Viewpoint = nullptr;
void main()
{
Vec2f parmTexCoord = aTexCoord;
Vec4f parmPosition = aPosition;
FVector2 parmTexCoord = aTexCoord;
FVector4 parmPosition = aPosition;
Vec4f worldcoord;
FVector4 worldcoord;
if (SIMPLE)
worldcoord = mul(ModelMatrix, mix(parmPosition, aVertex2, Data.uInterpolationFactor));
else
worldcoord = mul(ModelMatrix, parmPosition);
Vec4f eyeCoordPos = mul(Viewpoint->mViewMatrix, worldcoord);
FVector4 eyeCoordPos = mul(Viewpoint->mViewMatrix, worldcoord);
vColor = aColor;
@ -92,19 +91,19 @@ public:
gl_ClipDistance[4] = worldcoord.Y - ((Data.uSplitBottomPlane.W + Data.uSplitBottomPlane.X * worldcoord.X + Data.uSplitBottomPlane.Y * worldcoord.Z) * Data.uSplitBottomPlane.Z);
}
vWorldNormal = mul(NormalModelMatrix, Vec4f(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
vWorldNormal = mul(NormalModelMatrix, FVector4(normalize(mix3(aNormal, aNormal2, Data.uInterpolationFactor)), 1.0f));
//vEyeNormal = mul(Viewpoint->mNormalViewMatrix, vWorldNormal);
}
if (!SPHEREMAP)
{
vTexCoord = mul(TextureMatrix, Vec4f(parmTexCoord, 0.0f, 1.0f));
vTexCoord = mul(TextureMatrix, FVector4(parmTexCoord.X, parmTexCoord.Y, 0.0f, 1.0f));
}
else
{
Vec3f u = normalize3(eyeCoordPos);
Vec3f n = normalize3(mul(Viewpoint->mNormalViewMatrix, Vec4f(parmTexCoord.X, 0.0f, parmTexCoord.Y, 0.0f)));
Vec3f r = reflect(u, n);
FVector3 u = normalize3(eyeCoordPos);
FVector3 n = normalize3(mul(Viewpoint->mNormalViewMatrix, FVector4(parmTexCoord.X, 0.0f, parmTexCoord.Y, 0.0f)));
FVector3 r = reflect(u, n);
float m = 2.0f * sqrt(r.X*r.X + r.Y*r.Y + (r.Z + 1.0f)*(r.Z + 1.0f));
vTexCoord.X = r.X / m + 0.5f;
vTexCoord.Y = r.Y / m + 0.5f;
@ -137,41 +136,41 @@ public:
}
private:
static Vec3f normalize(const Vec3f &a)
static FVector3 normalize(const FVector3 &a)
{
float rcplen = 1.0f / sqrt(a.X * a.X + a.Y * a.Y + a.Z * a.Z);
return Vec3f(a.X * rcplen, a.Y * rcplen, a.Z * rcplen);
return FVector3(a.X * rcplen, a.Y * rcplen, a.Z * rcplen);
}
static Vec3f normalize3(const Vec4f &a)
static FVector3 normalize3(const FVector4 &a)
{
float rcplen = 1.0f / sqrt(a.X * a.X + a.Y * a.Y + a.Z * a.Z);
return Vec3f(a.X * rcplen, a.Y * rcplen, a.Z * rcplen);
return FVector3(a.X * rcplen, a.Y * rcplen, a.Z * rcplen);
}
static Vec4f mix(const Vec4f &a, const Vec4f &b, float t)
static FVector4 mix(const FVector4 &a, const FVector4 &b, float t)
{
float invt = 1.0f - t;
return Vec4f(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t, a.W * invt + b.W * t);
return FVector4(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t, a.W * invt + b.W * t);
}
static Vec3f mix3(const Vec4f &a, const Vec4f &b, float t)
static FVector3 mix3(const FVector4 &a, const FVector4 &b, float t)
{
float invt = 1.0f - t;
return Vec3f(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t);
return FVector3(a.X * invt + b.X * t, a.Y * invt + b.Y * t, a.Z * invt + b.Z * t);
}
static Vec3f reflect(const Vec3f &u, const Vec3f &n)
static FVector3 reflect(const FVector3 &u, const FVector3 &n)
{
float d = 2.0f * (n.X * u.X + n.Y * u.Y + n.Z * u.Z);
return Vec3f(u.X - d * n.X, u.Y - d * n.Y, u.Z - d * n.Z);
return FVector3(u.X - d * n.X, u.Y - d * n.Y, u.Z - d * n.Z);
}
static Vec4f mul(const VSMatrix &mat, const Vec4f &v)
static FVector4 mul(const VSMatrix &mat, const FVector4 &v)
{
const float *m = mat.get();
Vec4f result;
FVector4 result;
#ifdef NO_SSE
result.X = m[0 * 4 + 0] * v.X + m[1 * 4 + 0] * v.Y + m[2 * 4 + 0] * v.Z + m[3 * 4 + 0] * v.W;
result.Y = m[0 * 4 + 1] * v.X + m[1 * 4 + 1] * v.Y + m[2 * 4 + 1] * v.Z + m[3 * 4 + 1] * v.W;

View file

@ -519,10 +519,50 @@ void BlendColorRevSub_Src_One(int y, int x0, int x1, PolyTriangleThreadData* thr
}
}
void BlendColorColormap(int y, int x0, int x1, PolyTriangleThreadData* thread)
{
uint32_t* line = (uint32_t*)thread->dest + y * (ptrdiff_t)thread->dest_pitch;
uint32_t startR = (int)((thread->mainVertexShader.Data.uObjectColor.r) * 255.0f);
uint32_t startG = (int)((thread->mainVertexShader.Data.uObjectColor.g) * 255.0f);
uint32_t startB = (int)((thread->mainVertexShader.Data.uObjectColor.b) * 255.0f);
uint32_t rangeR = (int)((thread->mainVertexShader.Data.uAddColor.r) * 255.0f) - startR;
uint32_t rangeG = (int)((thread->mainVertexShader.Data.uAddColor.g) * 255.0f) - startG;
uint32_t rangeB = (int)((thread->mainVertexShader.Data.uAddColor.b) * 255.0f) - startB;
int sseend = x0;
for (int x = sseend; x < x1; x++)
{
uint32_t dst = line[x];
uint32_t a = APART(dst);
uint32_t r = RPART(dst);
uint32_t g = GPART(dst);
uint32_t b = BPART(dst);
uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8;
gray += (gray >> 7); // gray*=256/255
r = (startR + ((gray * rangeR) >> 8)) << 1;
g = (startG + ((gray * rangeG) >> 8)) << 1;
b = (startB + ((gray * rangeB) >> 8)) << 1;
r = MIN(r, (uint32_t)255);
g = MIN(g, (uint32_t)255);
b = MIN(b, (uint32_t)255);
line[x] = MAKEARGB(a, r, g, b);
}
}
void SelectWriteColorFunc(PolyTriangleThreadData* thread)
{
FRenderStyle style = thread->RenderStyle;
if (style.BlendOp == STYLEOP_Add)
if (thread->ColormapShader)
{
thread->WriteColorFunc = &BlendColorColormap;
}
else if (style.BlendOp == STYLEOP_Add)
{
if (style.SrcAlpha == STYLEALPHA_One && style.DestAlpha == STYLEALPHA_Zero)
{

View file

@ -532,13 +532,41 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
auto vColorA = thread->scanline.vColorA;
uint32_t* fragcolor = thread->scanline.FragColor;
if (constants->uTextureMode == TM_FOGLAYER)
if (constants->uTextureMode == TM_FIXEDCOLORMAP)
{
// float gray = grayscale(frag);
// vec4 cm = (uObjectColor + gray * (uAddColor - uObjectColor)) * 2;
// frag = vec4(clamp(cm.rgb, 0.0, 1.0), frag.a);
// frag = frag * vColor;
// frag.rgb = frag.rgb + uFogColor.rgb;
uint32_t startR = (int)((thread->mainVertexShader.Data.uObjectColor.r) * 255.0f);
uint32_t startG = (int)((thread->mainVertexShader.Data.uObjectColor.g) * 255.0f);
uint32_t startB = (int)((thread->mainVertexShader.Data.uObjectColor.b) * 255.0f);
uint32_t rangeR = (int)((thread->mainVertexShader.Data.uAddColor.r) * 255.0f) - startR;
uint32_t rangeG = (int)((thread->mainVertexShader.Data.uAddColor.g) * 255.0f) - startG;
uint32_t rangeB = (int)((thread->mainVertexShader.Data.uAddColor.b) * 255.0f) - startB;
for (int x = x0; x < x1; x++)
{
uint32_t a = APART(fragcolor[x]);
uint32_t r = RPART(fragcolor[x]);
uint32_t g = GPART(fragcolor[x]);
uint32_t b = BPART(fragcolor[x]);
uint32_t gray = (r * 77 + g * 143 + b * 37) >> 8;
gray += (gray >> 7); // gray*=256/255
r = (startR + ((gray * rangeR) >> 8)) << 1;
g = (startG + ((gray * rangeG) >> 8)) << 1;
b = (startB + ((gray * rangeB) >> 8)) << 1;
r = MIN(r, (uint32_t)255);
g = MIN(g, (uint32_t)255);
b = MIN(b, (uint32_t)255);
fragcolor[x] = MAKEARGB(a, r, g, b);
}
}
else
{
@ -570,11 +598,20 @@ static void MainFP(int x0, int x1, PolyTriangleThreadData* thread)
}
}
void ColormapFP(int x0, int x1, PolyTriangleThreadData* thread)
{
// This is implemented in BlendColorColormap.
}
void SelectFragmentShader(PolyTriangleThreadData* thread)
{
void (*fragshader)(int x0, int x1, PolyTriangleThreadData * thread);
if (thread->SpecialEffect == EFF_FOGBOUNDARY) // fogboundary.fp
if (thread->ColormapShader)
{
fragshader = &ColormapFP;
}
else if (thread->SpecialEffect == EFF_FOGBOUNDARY) // fogboundary.fp
{
fragshader = &EffectFogBoundary;
}

View file

@ -1,271 +0,0 @@
/*
** GPU math utility classes
** Copyright (c) 2016-2020 Magnus Norddahl
**
** 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 "gpu_types.h"
#include "doomtype.h"
#include <cmath>
Mat4f Mat4f::Null()
{
Mat4f m;
memset(m.Matrix, 0, sizeof(m.Matrix));
return m;
}
Mat4f Mat4f::Identity()
{
Mat4f m = Null();
m.Matrix[0] = 1.0f;
m.Matrix[5] = 1.0f;
m.Matrix[10] = 1.0f;
m.Matrix[15] = 1.0f;
return m;
}
Mat4f Mat4f::FromValues(const float *matrix)
{
Mat4f m;
memcpy(m.Matrix, matrix, sizeof(m.Matrix));
return m;
}
Mat4f Mat4f::Transpose(const Mat4f &matrix)
{
Mat4f m;
for (int y = 0; y < 4; y++)
for (int x = 0; x < 4; x++)
m.Matrix[x + y * 4] = matrix.Matrix[y + x * 4];
return m;
}
Mat4f Mat4f::Translate(float x, float y, float z)
{
Mat4f m = Identity();
m.Matrix[0 + 3 * 4] = x;
m.Matrix[1 + 3 * 4] = y;
m.Matrix[2 + 3 * 4] = z;
return m;
}
Mat4f Mat4f::Scale(float x, float y, float z)
{
Mat4f m = Null();
m.Matrix[0 + 0 * 4] = x;
m.Matrix[1 + 1 * 4] = y;
m.Matrix[2 + 2 * 4] = z;
m.Matrix[3 + 3 * 4] = 1;
return m;
}
Mat4f Mat4f::Rotate(float angle, float x, float y, float z)
{
float c = cosf(angle);
float s = sinf(angle);
Mat4f m = Null();
m.Matrix[0 + 0 * 4] = (x*x*(1.0f - c) + c);
m.Matrix[0 + 1 * 4] = (x*y*(1.0f - c) - z*s);
m.Matrix[0 + 2 * 4] = (x*z*(1.0f - c) + y*s);
m.Matrix[1 + 0 * 4] = (y*x*(1.0f - c) + z*s);
m.Matrix[1 + 1 * 4] = (y*y*(1.0f - c) + c);
m.Matrix[1 + 2 * 4] = (y*z*(1.0f - c) - x*s);
m.Matrix[2 + 0 * 4] = (x*z*(1.0f - c) - y*s);
m.Matrix[2 + 1 * 4] = (y*z*(1.0f - c) + x*s);
m.Matrix[2 + 2 * 4] = (z*z*(1.0f - c) + c);
m.Matrix[3 + 3 * 4] = 1.0f;
return m;
}
Mat4f Mat4f::SwapYZ()
{
Mat4f m = Null();
m.Matrix[0 + 0 * 4] = 1.0f;
m.Matrix[1 + 2 * 4] = 1.0f;
m.Matrix[2 + 1 * 4] = -1.0f;
m.Matrix[3 + 3 * 4] = 1.0f;
return m;
}
Mat4f Mat4f::Perspective(float fovy, float aspect, float z_near, float z_far, Handedness handedness, ClipZRange clipZ)
{
float f = (float)(1.0 / tan(fovy * M_PI / 360.0));
Mat4f m = Null();
m.Matrix[0 + 0 * 4] = f / aspect;
m.Matrix[1 + 1 * 4] = f;
m.Matrix[2 + 2 * 4] = (z_far + z_near) / (z_near - z_far);
m.Matrix[2 + 3 * 4] = (2.0f * z_far * z_near) / (z_near - z_far);
m.Matrix[3 + 2 * 4] = -1.0f;
if (handedness == Handedness::Left)
{
m = m * Mat4f::Scale(1.0f, 1.0f, -1.0f);
}
if (clipZ == ClipZRange::ZeroPositiveW)
{
Mat4f scale_translate = Identity();
scale_translate.Matrix[2 + 2 * 4] = 0.5f;
scale_translate.Matrix[2 + 3 * 4] = 0.5f;
m = scale_translate * m;
}
return m;
}
Mat4f Mat4f::Frustum(float left, float right, float bottom, float top, float near, float far, Handedness handedness, ClipZRange clipZ)
{
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float c = -(far + near) / (far - near);
float d = -(2.0f * far) / (far - near);
Mat4f m = Null();
m.Matrix[0 + 0 * 4] = 2.0f * near / (right - left);
m.Matrix[1 + 1 * 4] = 2.0f * near / (top - bottom);
m.Matrix[0 + 2 * 4] = a;
m.Matrix[1 + 2 * 4] = b;
m.Matrix[2 + 2 * 4] = c;
m.Matrix[2 + 3 * 4] = d;
m.Matrix[3 + 2 * 4] = -1;
if (handedness == Handedness::Left)
{
m = m * Mat4f::Scale(1.0f, 1.0f, -1.0f);
}
if (clipZ == ClipZRange::ZeroPositiveW)
{
Mat4f scale_translate = Identity();
scale_translate.Matrix[2 + 2 * 4] = 0.5f;
scale_translate.Matrix[2 + 3 * 4] = 0.5f;
m = scale_translate * m;
}
return m;
}
Mat4f Mat4f::operator*(const Mat4f &mult) const
{
Mat4f result;
for (int x = 0; x < 4; x++)
{
for (int y = 0; y < 4; y++)
{
result.Matrix[x + y * 4] =
Matrix[0 * 4 + x] * mult.Matrix[y * 4 + 0] +
Matrix[1 * 4 + x] * mult.Matrix[y * 4 + 1] +
Matrix[2 * 4 + x] * mult.Matrix[y * 4 + 2] +
Matrix[3 * 4 + x] * mult.Matrix[y * 4 + 3];
}
}
return result;
}
Vec4f Mat4f::operator*(const Vec4f &v) const
{
Vec4f result;
#ifdef NO_SSE
result.X = Matrix[0 * 4 + 0] * v.X + Matrix[1 * 4 + 0] * v.Y + Matrix[2 * 4 + 0] * v.Z + Matrix[3 * 4 + 0] * v.W;
result.Y = Matrix[0 * 4 + 1] * v.X + Matrix[1 * 4 + 1] * v.Y + Matrix[2 * 4 + 1] * v.Z + Matrix[3 * 4 + 1] * v.W;
result.Z = Matrix[0 * 4 + 2] * v.X + Matrix[1 * 4 + 2] * v.Y + Matrix[2 * 4 + 2] * v.Z + Matrix[3 * 4 + 2] * v.W;
result.W = Matrix[0 * 4 + 3] * v.X + Matrix[1 * 4 + 3] * v.Y + Matrix[2 * 4 + 3] * v.Z + Matrix[3 * 4 + 3] * v.W;
#else
__m128 m0 = _mm_loadu_ps(Matrix);
__m128 m1 = _mm_loadu_ps(Matrix + 4);
__m128 m2 = _mm_loadu_ps(Matrix + 8);
__m128 m3 = _mm_loadu_ps(Matrix + 12);
__m128 mv = _mm_loadu_ps(&v.X);
m0 = _mm_mul_ps(m0, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(0, 0, 0, 0)));
m1 = _mm_mul_ps(m1, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(1, 1, 1, 1)));
m2 = _mm_mul_ps(m2, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(2, 2, 2, 2)));
m3 = _mm_mul_ps(m3, _mm_shuffle_ps(mv, mv, _MM_SHUFFLE(3, 3, 3, 3)));
mv = _mm_add_ps(_mm_add_ps(_mm_add_ps(m0, m1), m2), m3);
Vec4f sv;
_mm_storeu_ps(&result.X, mv);
#endif
return result;
}
/////////////////////////////////////////////////////////////////////////////
Mat3f::Mat3f(const Mat4f &matrix)
{
for (int y = 0; y < 3; y++)
for (int x = 0; x < 3; x++)
Matrix[x + y * 3] = matrix.Matrix[x + y * 4];
}
Mat3f Mat3f::Null()
{
Mat3f m;
memset(m.Matrix, 0, sizeof(m.Matrix));
return m;
}
Mat3f Mat3f::Identity()
{
Mat3f m = Null();
m.Matrix[0] = 1.0f;
m.Matrix[4] = 1.0f;
m.Matrix[8] = 1.0f;
return m;
}
Mat3f Mat3f::FromValues(float *matrix)
{
Mat3f m;
memcpy(m.Matrix, matrix, sizeof(m.Matrix));
return m;
}
Mat3f Mat3f::Transpose(const Mat3f &matrix)
{
Mat3f m;
for (int y = 0; y < 3; y++)
for (int x = 0; x < 3; x++)
m.Matrix[x + y * 3] = matrix.Matrix[y + x * 3];
return m;
}
Mat3f Mat3f::operator*(const Mat3f &mult) const
{
Mat3f result;
for (int x = 0; x < 3; x++)
{
for (int y = 0; y < 3; y++)
{
result.Matrix[x + y * 3] =
Matrix[0 * 3 + x] * mult.Matrix[y * 3 + 0] +
Matrix[1 * 3 + x] * mult.Matrix[y * 3 + 1] +
Matrix[2 * 3 + x] * mult.Matrix[y * 3 + 2];
}
}
return result;
}
Vec3f Mat3f::operator*(const Vec3f &v) const
{
Vec3f result;
result.X = Matrix[0 * 3 + 0] * v.X + Matrix[1 * 3 + 0] * v.Y + Matrix[2 * 3 + 0] * v.Z;
result.Y = Matrix[0 * 3 + 1] * v.X + Matrix[1 * 3 + 1] * v.Y + Matrix[2 * 3 + 1] * v.Z;
result.Z = Matrix[0 * 3 + 2] * v.X + Matrix[1 * 3 + 2] * v.Y + Matrix[2 * 3 + 2] * v.Z;
return result;
}

View file

@ -1,148 +0,0 @@
/*
** Hardpoly renderer
** Copyright (c) 2016 Magnus Norddahl
**
** 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 <memory>
template<typename Type> class Vec4;
template<typename Type> class Vec3;
template<typename Type>
class Vec2
{
public:
Vec2() : X(Type(0)), Y(Type(0)) { }
Vec2(float v) : X(v), Y(v) { }
Vec2(float x, float y) : X(x), Y(y) { }
float X, Y;
bool operator==(const Vec2 &other) const { return X == other.X && Y == other.Y; }
bool operator!=(const Vec2 &other) const { return X != other.X || Y != other.Y; }
};
template<typename Type>
class Vec3
{
public:
Vec3() : X(Type(0)), Y(Type(0)), Z(Type(0)) { }
Vec3(float v) : X(v), Y(v), Z(v) { }
Vec3(float x, float y, float z) : X(x), Y(y), Z(z) { }
Vec3(const Vec2<Type> &v, float z) : X(v.X), Y(v.Y), Z(z) { }
float X, Y, Z;
bool operator==(const Vec3 &other) const { return X == other.X && Y == other.Y && Z == other.Z; }
bool operator!=(const Vec3 &other) const { return X != other.X || Y != other.Y || Z != other.Z; }
};
template<typename Type>
class Vec4
{
public:
Vec4() : X(Type(0)), Y(Type(0)), Z(Type(0)), W(Type(0)) { }
Vec4(Type v) : X(v), Y(v), Z(v), W(v) { }
Vec4(Type x, Type y, Type z, Type w = 1.0f) : X(x), Y(y), Z(z), W(w) { }
Vec4(const Vec2<Type> &v, Type z, Type w) : X(v.X), Y(v.Y), Z(z), W(w) { }
Vec4(const Vec3<Type> &v, Type w) : X(v.X), Y(v.Y), Z(v.Z), W(w) { }
Type X, Y, Z, W;
bool operator==(const Vec4 &other) const { return X == other.X && Y == other.Y && Z == other.Z && W == other.W; }
bool operator!=(const Vec4 &other) const { return X != other.X || Y != other.Y || Z != other.Z || W != other.W; }
};
typedef Vec4<double> Vec4d;
typedef Vec3<double> Vec3d;
typedef Vec2<double> Vec2d;
typedef Vec4<float> Vec4f;
typedef Vec3<float> Vec3f;
typedef Vec2<float> Vec2f;
typedef Vec4<int32_t> Vec4i;
typedef Vec3<int32_t> Vec3i;
typedef Vec2<int32_t> Vec2i;
typedef Vec4<int16_t> Vec4s;
typedef Vec3<int16_t> Vec3s;
typedef Vec2<int16_t> Vec2s;
typedef Vec4<int8_t> Vec4b;
typedef Vec3<int8_t> Vec3b;
typedef Vec2<int8_t> Vec2b;
typedef Vec4<uint32_t> Vec4ui;
typedef Vec3<uint32_t> Vec3ui;
typedef Vec2<uint32_t> Vec2ui;
typedef Vec4<uint16_t> Vec4us;
typedef Vec3<uint16_t> Vec3us;
typedef Vec2<uint16_t> Vec2us;
typedef Vec4<uint8_t> Vec4ub;
typedef Vec3<uint8_t> Vec3ub;
typedef Vec2<uint8_t> Vec2ub;
enum class Handedness
{
Left,
Right
};
enum class ClipZRange
{
NegativePositiveW, // OpenGL, -wclip <= zclip <= wclip
ZeroPositiveW // Direct3D, 0 <= zclip <= wclip
};
class Mat4f
{
public:
static Mat4f Null();
static Mat4f Identity();
static Mat4f FromValues(const float *matrix);
static Mat4f Transpose(const Mat4f &matrix);
static Mat4f Translate(float x, float y, float z);
static Mat4f Scale(float x, float y, float z);
static Mat4f Rotate(float angle, float x, float y, float z);
static Mat4f SwapYZ();
static Mat4f Perspective(float fovy, float aspect, float near, float far, Handedness handedness, ClipZRange clipZ);
static Mat4f Frustum(float left, float right, float bottom, float top, float near, float far, Handedness handedness, ClipZRange clipZ);
Vec4f operator*(const Vec4f &v) const;
Mat4f operator*(const Mat4f &m) const;
float Matrix[16];
};
class Mat3f
{
public:
Mat3f() { }
Mat3f(const Mat4f &matrix);
static Mat3f Null();
static Mat3f Identity();
static Mat3f FromValues(float *matrix);
static Mat3f Transpose(const Mat3f &matrix);
Vec3f operator*(const Vec3f &v) const;
Mat3f operator*(const Mat3f &m) const;
float Matrix[9];
};

View file

@ -5,4 +5,3 @@
#include "drawers/screen_scanline_setup.cpp"
#include "drawers/screen_shader.cpp"
#include "drawers/screen_blend.cpp"
#include "math/gpu_types.cpp"

View file

@ -232,8 +232,6 @@ namespace swrenderer
WallColumnDrawerArgs& drawerargs = *thread->columndrawer.get();
drawerargs.wallargs = &wallargs;
bool fixed = wallargs.fixedlight;
bool haslights = r_dynlights && wallargs.lightlist;
if (haslights)
{
@ -249,7 +247,13 @@ namespace swrenderer
float curlight = wallargs.lightpos;
float lightstep = wallargs.lightstep;
int shade = wallargs.mShade;
int shade = wallargs.Shade();
if (wallargs.fixedlight)
{
curlight = wallargs.FixedLight();
lightstep = 0;
}
float upos = wallargs.texcoords.upos, ustepX = wallargs.texcoords.ustepX, ustepY = wallargs.texcoords.ustepY;
float vpos = wallargs.texcoords.vpos, vstepX = wallargs.texcoords.vstepX, vstepY = wallargs.texcoords.vstepY;
@ -274,7 +278,7 @@ namespace swrenderer
int y2 = dwal[x];
if (y2 > y1)
{
if (!fixed) drawerargs.SetLight(curlight, shade);
drawerargs.SetLight(curlight, shade);
if (haslights)
SetLights(drawerargs, x, y1);
else

View file

@ -52,6 +52,8 @@
#include "swrenderer/r_renderthread.h"
#include "swrenderer/r_memory.h"
EXTERN_CVAR(Bool, r_fullbrightignoresectorcolor)
namespace swrenderer
{
RenderWallPart::RenderWallPart(RenderThread* thread)
@ -130,11 +132,30 @@ namespace swrenderer
// Textures that aren't masked can use the faster opaque drawer
if (!pic->GetTexture()->isMasked() && mask && alpha >= OPAQUE && !additive)
{
drawerargs.SetStyle(true, false, OPAQUE, mLight.GetBaseColormap(), light_list);
drawerargs.SetStyle(true, false, OPAQUE, light_list);
}
else
{
drawerargs.SetStyle(mask, additive, alpha, mLight.GetBaseColormap(), light_list);
drawerargs.SetStyle(mask, additive, alpha, light_list);
}
if (cameraLight->FixedLightLevel() >= 0)
{
drawerargs.SetBaseColormap((r_fullbrightignoresectorcolor) ? &FullNormalLight : mLight.GetBaseColormap());
drawerargs.SetLight(0.0f, cameraLight->FixedLightLevelShade());
drawerargs.fixedlight = true;
}
else if (cameraLight->FixedColormap())
{
drawerargs.SetBaseColormap(cameraLight->FixedColormap());
drawerargs.SetLight(0.0f, 0);
drawerargs.fixedlight = true;
}
else
{
drawerargs.SetBaseColormap(mLight.GetBaseColormap());
drawerargs.SetLight(0.0f, mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
drawerargs.fixedlight = false;
}
int count = x2 - x1;
@ -151,7 +172,7 @@ namespace swrenderer
drawerargs.lightpos = mLight.GetLightPos(x1);
drawerargs.lightstep = mLight.GetLightStep();
drawerargs.mShade = LightVisibility::LightLevelToShade(mLight.GetLightLevel(), mLight.GetFoggy(), viewport);
drawerargs.lightlist = light_list;
drawerargs.texwidth = pic->GetPhysicalWidth();
@ -183,7 +204,6 @@ namespace swrenderer
drawerargs.TanCos = Thread->Viewport->viewpoint.TanCos;
drawerargs.TanSin = Thread->Viewport->viewpoint.TanSin;
drawerargs.PortalMirrorFlags = Thread->Portal->MirrorFlags;
drawerargs.fixedlight = (cameraLight->FixedColormap() || cameraLight->FixedLightLevel() >= 0);
drawerargs.DrawWall(Thread);
}

View file

@ -126,9 +126,16 @@ sector_t *SWSceneDrawer::RenderView(player_t *player)
}
else
{
// With softpoly truecolor we render directly to the target framebuffer
DCanvas *canvas = screen->GetCanvas();
SWRenderer->RenderView(player, canvas, canvas->GetPixels(), canvas->GetPitch());
// To do: apply swrenderer::CameraLight::Instance()->ShaderColormap();
int cm = CM_DEFAULT;
auto map = swrenderer::CameraLight::Instance()->ShaderColormap();
if (map) cm = (int)(ptrdiff_t)(map - SpecialColormaps.Data()) + CM_FIRSTSPECIALCOLORMAP;
screen->PostProcessScene(cm, [&]() { });
SWRenderer->DrawRemainingPlayerSprites();
screen->Draw2D();
screen->Clear2D();

View file

@ -49,7 +49,7 @@ namespace swrenderer
float x, y, z;
FSpriteModelFrame *smf;
AActor *actor;
Mat4f WorldToClip;
VSMatrix WorldToClip;
bool MirrorWorldToClip;
};

View file

@ -43,6 +43,9 @@ namespace swrenderer
ShadeConstants ColormapConstants() const;
fixed_t Light() const { return LIGHTSCALE(mLight, mShade); }
float FixedLight() const { return mLight; }
int Shade() const { return mShade; }
protected:
void SetLight(const ColormapLight &light);

View file

@ -64,25 +64,32 @@ namespace swrenderer
WorldToView = SoftwareWorldToView(viewpoint);
if (thread->Portal->MirrorFlags & RF_XFLIP)
WorldToView = Mat4f::Scale(-1.0f, 1.0f, 1.0f) * WorldToView;
{
WorldToView.scale(-1.0f, 1.0f, 1.0f);
}
ViewToClip = SoftwareViewToClip();
WorldToClip = ViewToClip * WorldToView;
WorldToClip.multMatrix(ViewToClip);
}
Mat4f RenderViewport::SoftwareWorldToView(const FRenderViewpoint &viewpoint)
VSMatrix RenderViewport::SoftwareWorldToView(const FRenderViewpoint &viewpoint)
{
Mat4f m = Mat4f::Null();
m.Matrix[0 + 0 * 4] = (float)viewpoint.Sin;
m.Matrix[0 + 1 * 4] = (float)-viewpoint.Cos;
m.Matrix[1 + 2 * 4] = 1.0f;
m.Matrix[2 + 0 * 4] = (float)-viewpoint.Cos;
m.Matrix[2 + 1 * 4] = (float)-viewpoint.Sin;
m.Matrix[3 + 3 * 4] = 1.0f;
return m * Mat4f::Translate((float)-viewpoint.Pos.X, (float)-viewpoint.Pos.Y, (float)-viewpoint.Pos.Z);
float m[16] = { 0.0f };
m[0 + 0 * 4] = (float)viewpoint.Sin;
m[0 + 1 * 4] = (float)-viewpoint.Cos;
m[1 + 2 * 4] = 1.0f;
m[2 + 0 * 4] = (float)-viewpoint.Cos;
m[2 + 1 * 4] = (float)-viewpoint.Sin;
m[3 + 3 * 4] = 1.0f;
VSMatrix matrix;
matrix.loadIdentity();
matrix.translate((float)-viewpoint.Pos.X, (float)-viewpoint.Pos.Y, (float)-viewpoint.Pos.Z);
matrix.multMatrix(m);
return matrix;
}
Mat4f RenderViewport::SoftwareViewToClip()
VSMatrix RenderViewport::SoftwareViewToClip()
{
float near = 5.0f;
float far = 65536.0f;
@ -92,7 +99,27 @@ namespace swrenderer
width *= near;
height *= near;
offset *= near;
return Mat4f::Frustum(-width, width, -height + offset, height + offset, near, far, Handedness::Right, ClipZRange::NegativePositiveW);
float left = -width;
float right = width;
float bottom = -height + offset;
float top = height + offset;
float a = (right + left) / (right - left);
float b = (top + bottom) / (top - bottom);
float c = -(far + near) / (far - near);
float d = -(2.0f * far) / (far - near);
float m[16] = { 0.0f };
m[0 + 0 * 4] = 2.0f * near / (right - left);
m[1 + 1 * 4] = 2.0f * near / (top - bottom);
m[0 + 2 * 4] = a;
m[1 + 2 * 4] = b;
m[2 + 2 * 4] = c;
m[2 + 3 * 4] = d;
m[3 + 2 * 4] = -1;
VSMatrix matrix;
matrix.loadMatrix(m);
return matrix;
}
void RenderViewport::SetViewport(FLevelLocals *Level, RenderThread *thread, int fullWidth, int fullHeight, float trueratio)

View file

@ -7,7 +7,7 @@
#include "r_defs.h"
#include "r_utility.h"
#include "actorinlines.h"
#include "polyrenderer/math/gpu_types.h"
#include "utility/matrix.h"
#define MINZ double((2048*4) / double(1 << 20))
@ -28,9 +28,9 @@ namespace swrenderer
void SetupPolyViewport(RenderThread *thread);
Mat4f WorldToView;
Mat4f ViewToClip;
Mat4f WorldToClip;
VSMatrix WorldToView;
VSMatrix ViewToClip;
VSMatrix WorldToClip;
DCanvas *RenderTarget = nullptr;
bool RenderingToCanvas = false;
@ -93,8 +93,8 @@ namespace swrenderer
void InitTextureMapping();
void SetupBuffer();
static Mat4f SoftwareWorldToView(const FRenderViewpoint &viewpoint);
static VSMatrix SoftwareWorldToView(const FRenderViewpoint &viewpoint);
Mat4f SoftwareViewToClip();
VSMatrix SoftwareViewToClip();
};
}

View file

@ -35,7 +35,7 @@ namespace swrenderer
(thread->Drawers(dc_viewport)->*wallfunc)(*this);
}
void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap, bool dynlights)
void WallDrawerArgs::SetStyle(bool masked, bool additive, fixed_t alpha, bool dynlights)
{
if (alpha < OPAQUE || additive)
{
@ -72,21 +72,5 @@ namespace swrenderer
{
wallfunc = &SWPixelFormatDrawers::DrawWall;
}
CameraLight *cameraLight = CameraLight::Instance();
if (cameraLight->FixedLightLevel() >= 0)
{
SetBaseColormap((r_fullbrightignoresectorcolor) ? &FullNormalLight : basecolormap);
SetLight(0.0f, cameraLight->FixedLightLevelShade());
}
else if (cameraLight->FixedColormap() != nullptr)
{
SetBaseColormap(cameraLight->FixedColormap());
SetLight(0.0f, 0);
}
else
{
SetBaseColormap(basecolormap);
}
}
}

View file

@ -15,7 +15,7 @@ namespace swrenderer
class WallDrawerArgs : public DrawerArgs
{
public:
void SetStyle(bool masked, bool additive, fixed_t alpha, FDynamicColormap *basecolormap, bool dynlights);
void SetStyle(bool masked, bool additive, fixed_t alpha, bool dynlights);
void SetDest(RenderViewport *viewport);
void DrawWall(RenderThread *thread);
@ -35,7 +35,6 @@ namespace swrenderer
float lightpos;
float lightstep;
int mShade;
int texwidth;
int texheight;

View file

@ -169,6 +169,7 @@ $alias menu/clear PlatformStop
// Hexen does not have ripslop sound like Heretic
misc/ripslop dsempty
misc/netnotch blddrp1
misc/secret dssecret
$alias intermission/cooptotal *death
$alias intermission/nextstage DoorCloseLight

File diff suppressed because it is too large Load diff

View file

@ -4,6 +4,7 @@ Gameinfo
{
CheatKey = "maparrows/key.txt"
EasyKey = "maparrows/ravenkey.txt"
PrecacheSounds = "misc/secret", "misc/teleport", "misc/fallingsplat", "misc/ripslop"
}
DoomEdNums

View file

@ -2195,7 +2195,7 @@ OptionValue Ratios
}
OptionValue ScaleModes
{
0, "$OPTVAL_SCALENEAREST"
0, "$OPTVAL_NORMAL"
6, "320x200"
2, "640x400"
3, "960x600"

View file

@ -21,7 +21,7 @@ class os_AnyOrAllOption : OptionMenuItemOption
{
bool result = Super.MenuEvent(mkey, fromcontroller);
if (mKey == Menu.MKEY_Left || mKey == Menu.MKEY_Right)
if (mKey == Menu.MKEY_Left || mKey == Menu.MKEY_Right || mkey == Menu.MKEY_Enter)
{
mMenu.search();
}