add gl_wireframe and gl_wireframecolor
This commit is contained in:
parent
d8c0e4284f
commit
c72bad053f
14 changed files with 151 additions and 64 deletions
|
|
@ -399,6 +399,8 @@ public:
|
|||
|
||||
GraphicsPipelineBuilder& AddDynamicState(VkDynamicState state);
|
||||
|
||||
GraphicsPipelineBuilder& PolygonMode(VkPolygonMode mode) {rasterizer.polygonMode = mode; return *this;};
|
||||
|
||||
GraphicsPipelineBuilder& DebugName(const char* name) { debugName = name; return *this; }
|
||||
|
||||
std::unique_ptr<VulkanPipeline> Create(VulkanDevice *device);
|
||||
|
|
|
|||
|
|
@ -994,6 +994,22 @@ int FColorCVar::ToInt2 (UCVarValue value, ECVarType type)
|
|||
return ret;
|
||||
}
|
||||
|
||||
DVector4 FColorCVar::asDV4() const
|
||||
{
|
||||
PalEntry col;
|
||||
col.d = Value;
|
||||
|
||||
return {col.r / 255.0, col.g / 255.0, col.b / 255.0, col.a / 255.0};
|
||||
}
|
||||
|
||||
FVector4 FColorCVar::asFV4() const
|
||||
{
|
||||
PalEntry col;
|
||||
col.d = Value;
|
||||
|
||||
return {col.r / 255.0f, col.g / 255.0f, col.b / 255.0f, col.a / 255.0f};
|
||||
}
|
||||
|
||||
//
|
||||
// More base cvar stuff
|
||||
//
|
||||
|
|
|
|||
|
|
@ -38,6 +38,7 @@
|
|||
#include "autosegs.h"
|
||||
#include "name.h"
|
||||
#include "dobjgc.h"
|
||||
#include "vectors.h"
|
||||
|
||||
class FSerializer; // this needs to go away.
|
||||
/*
|
||||
|
|
@ -452,6 +453,10 @@ public:
|
|||
inline operator uint32_t () const { return Value; }
|
||||
inline uint32_t operator *() const { return Value; }
|
||||
|
||||
DVector4 asDV4() const;
|
||||
|
||||
FVector4 asFV4() const;
|
||||
|
||||
protected:
|
||||
virtual void DoSet (UCVarValue value, ECVarType type);
|
||||
|
||||
|
|
|
|||
|
|
@ -159,4 +159,7 @@ CUSTOM_CVAR(Int, gl_shadowmap_quality, 512, CVAR_ARCHIVE | CVAR_GLOBALCONFIG)
|
|||
}
|
||||
}
|
||||
|
||||
CVAR(Bool, gl_strict_gldefs, true, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
CVAR(Bool, gl_strict_gldefs, true, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
|
||||
CVAR(Int, gl_wireframe, 0, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
CVAR(Color, gl_wireframecolor, -1, CVAR_GLOBALCONFIG | CVAR_ARCHIVE)
|
||||
|
|
@ -59,4 +59,6 @@ EXTERN_CVAR(Bool, gl_notexturefill)
|
|||
EXTERN_CVAR(Bool, r_radarclipper)
|
||||
EXTERN_CVAR(Bool, r_dithertransparency)
|
||||
|
||||
EXTERN_CVAR(Bool, gl_strict_gldefs)
|
||||
EXTERN_CVAR(Bool, gl_strict_gldefs)
|
||||
EXTERN_CVAR(Int, gl_wireframe)
|
||||
EXTERN_CVAR(Color, gl_wireframecolor)
|
||||
|
|
@ -24,7 +24,7 @@ void MeshBuilder::SetShadowData(const TArray<FFlatVertex>& vertices, const TArra
|
|||
mIndexes = indexes;
|
||||
}
|
||||
|
||||
void MeshBuilder::Draw(int dt, int index, int count, bool apply)
|
||||
void MeshBuilder::DoDraw(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
Apply();
|
||||
|
|
@ -37,7 +37,7 @@ void MeshBuilder::Draw(int dt, int index, int count, bool apply)
|
|||
mDrawLists->mDraws.Push(command);
|
||||
}
|
||||
|
||||
void MeshBuilder::DrawIndexed(int dt, int index, int count, bool apply)
|
||||
void MeshBuilder::DoDrawIndexed(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply)
|
||||
Apply();
|
||||
|
|
|
|||
|
|
@ -83,8 +83,8 @@ public:
|
|||
int UploadFogballs(const TArray<Fogball>& balls) override { return -1; }
|
||||
|
||||
// Draw commands
|
||||
void Draw(int dt, int index, int count, bool apply = true) override;
|
||||
void DrawIndexed(int dt, int index, int count, bool apply = true) override;
|
||||
void DoDraw(int dt, int index, int count, bool apply = true) override;
|
||||
void DoDrawIndexed(int dt, int index, int count, bool apply = true) override;
|
||||
|
||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||
void SetDepthFunc(int func) override;
|
||||
|
|
|
|||
|
|
@ -138,6 +138,10 @@ protected:
|
|||
uint8_t mGradientEnabled : 1;
|
||||
uint8_t mSplitEnabled : 1;
|
||||
uint8_t mBrightmapEnabled : 1;
|
||||
uint8_t mWireframe : 2;
|
||||
|
||||
FVector4 mWireframeColor;
|
||||
FVector4 uObjectColor;
|
||||
|
||||
int mLightIndex;
|
||||
int mBoneIndexBase;
|
||||
|
|
@ -166,12 +170,16 @@ protected:
|
|||
|
||||
EPassType mPassType = NORMAL_PASS;
|
||||
|
||||
virtual void DoDraw(int dt, int index, int count, bool apply) = 0;
|
||||
virtual void DoDrawIndexed(int dt, int index, int count, bool apply) = 0;
|
||||
public:
|
||||
|
||||
uint64_t firstFrame = 0;
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mWireframe = 0;
|
||||
mWireframeColor = toFVector4(PalEntry(0xffffffff));
|
||||
mTextureEnabled = true;
|
||||
mBrightmapEnabled = mGradientEnabled = mFogEnabled = mGlowEnabled = false;
|
||||
mFogColor = 0xffffffff;
|
||||
|
|
@ -183,7 +191,7 @@ public:
|
|||
mSurfaceUniforms.uAlphaThreshold = 0.5f;
|
||||
mSplitEnabled = false;
|
||||
mSurfaceUniforms.uAddColor = toFVector4(PalEntry(0));
|
||||
mSurfaceUniforms.uObjectColor = toFVector4(PalEntry(0xffffffff));
|
||||
uObjectColor = toFVector4(PalEntry(0xffffffff));
|
||||
mSurfaceUniforms.uObjectColor2 = toFVector4(PalEntry(0));
|
||||
mSurfaceUniforms.uTextureBlendColor = toFVector4(PalEntry(0));
|
||||
mSurfaceUniforms.uTextureAddColor = toFVector4(PalEntry(0));
|
||||
|
|
@ -233,6 +241,12 @@ public:
|
|||
mSurfaceUniforms.uVertexNormal = { norm.X, norm.Y, norm.Z, 0.f };
|
||||
}
|
||||
|
||||
void SetWireframe(int mode, FVector4 color)
|
||||
{
|
||||
mWireframe = mode;
|
||||
mWireframeColor = color;
|
||||
}
|
||||
|
||||
void SetNormal(float x, float y, float z)
|
||||
{
|
||||
mSurfaceUniforms.uVertexNormal = { x, y, z, 0.f };
|
||||
|
|
@ -409,7 +423,7 @@ public:
|
|||
|
||||
void SetObjectColor(PalEntry pe)
|
||||
{
|
||||
mSurfaceUniforms.uObjectColor = toFVector4(pe);
|
||||
uObjectColor = toFVector4(pe);
|
||||
}
|
||||
|
||||
void SetObjectColor2(PalEntry pe)
|
||||
|
|
@ -672,8 +686,59 @@ public:
|
|||
|
||||
// Draw commands
|
||||
virtual void ClearScreen() = 0;
|
||||
virtual void Draw(int dt, int index, int count, bool apply = true) = 0;
|
||||
virtual void DrawIndexed(int dt, int index, int count, bool apply = true) = 0;
|
||||
|
||||
void Draw(int dt, int index, int count, bool apply = true)
|
||||
{
|
||||
if(mWireframe == 0)
|
||||
{
|
||||
mSurfaceUniforms.uObjectColor = uObjectColor;
|
||||
DoDraw(dt, index, count, apply);
|
||||
}
|
||||
else if(mWireframe == 1)
|
||||
{
|
||||
mSurfaceUniforms.uObjectColor = mWireframeColor;
|
||||
DoDraw(dt, index, count, apply);
|
||||
}
|
||||
else //if(mWireframe == 2)
|
||||
{
|
||||
mWireframe = 0;
|
||||
mSurfaceUniforms.uObjectColor = uObjectColor;
|
||||
DoDraw(dt, index, count, true);
|
||||
|
||||
mWireframe = 1;
|
||||
mSurfaceUniforms.uObjectColor = mWireframeColor;
|
||||
DoDraw(dt, index, count, true);
|
||||
|
||||
mWireframe = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void DrawIndexed(int dt, int index, int count, bool apply = true)
|
||||
{
|
||||
if(mWireframe == 0)
|
||||
{
|
||||
mSurfaceUniforms.uObjectColor = uObjectColor;
|
||||
DoDrawIndexed(dt, index, count, apply);
|
||||
}
|
||||
else if(mWireframe == 1)
|
||||
{
|
||||
mSurfaceUniforms.uObjectColor = mWireframeColor;
|
||||
DoDrawIndexed(dt, index, count, apply);
|
||||
}
|
||||
else //if(mWireframe == 2)
|
||||
{
|
||||
mWireframe = 0;
|
||||
mSurfaceUniforms.uObjectColor = uObjectColor;
|
||||
DoDrawIndexed(dt, index, count, true);
|
||||
|
||||
mWireframe = 1;
|
||||
mSurfaceUniforms.uObjectColor = mWireframeColor;
|
||||
DoDrawIndexed(dt, index, count, true);
|
||||
|
||||
mWireframe = 2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||
virtual bool SetDepthClamp(bool on) = 0; // Deactivated only by skyboxes.
|
||||
|
|
|
|||
|
|
@ -302,6 +302,8 @@ std::unique_ptr<VulkanPipeline> VkRenderPassSetup::CreatePipeline(const VkPipeli
|
|||
GraphicsPipelineBuilder builder;
|
||||
builder.Cache(fb->GetRenderPassManager()->GetCache());
|
||||
|
||||
builder.PolygonMode(key.DrawLine ? VK_POLYGON_MODE_LINE : VK_POLYGON_MODE_FILL);
|
||||
|
||||
VkShaderProgram *program = fb->GetShaderManager()->Get(key.ShaderKey);
|
||||
builder.AddVertexShader(program->vert.get());
|
||||
if (program->frag)
|
||||
|
|
|
|||
|
|
@ -34,7 +34,8 @@ public:
|
|||
uint64_t DepthFunc : 2;
|
||||
uint64_t StencilTest : 1;
|
||||
uint64_t StencilPassOp : 2;
|
||||
uint64_t Unused : 46;
|
||||
uint64_t DrawLine : 1;
|
||||
uint64_t Unused : 45;
|
||||
};
|
||||
uint64_t AsQWORD = 0;
|
||||
};
|
||||
|
|
|
|||
|
|
@ -252,11 +252,7 @@ void VulkanRenderDevice::InitializeState()
|
|||
|
||||
mDescriptorSetManager->Init();
|
||||
|
||||
#ifdef __APPLE__
|
||||
mRenderState = std::make_unique<VkRenderStateMolten>(this);
|
||||
#else
|
||||
mRenderState = std::make_unique<VkRenderState>(this);
|
||||
#endif
|
||||
}
|
||||
|
||||
void VulkanRenderDevice::Update()
|
||||
|
|
|
|||
|
|
@ -71,15 +71,37 @@ void VkRenderState::ClearScreen()
|
|||
mCommandBuffer->draw(4, 1, vertices.second, 0);
|
||||
}
|
||||
|
||||
void VkRenderState::Draw(int dt, int index, int count, bool apply)
|
||||
void VkRenderState::DoDraw(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply || mNeedApply)
|
||||
Apply(dt);
|
||||
#ifdef __APPLE__
|
||||
// moltenvk doesn't support drawing triangle fans
|
||||
if (dt == DT_TriangleFan)
|
||||
{
|
||||
IBuffer* oldIndexBuffer = mIndexBuffer;
|
||||
mIndexBuffer = fb->GetBufferManager()->FanToTrisIndexBuffer.get();
|
||||
|
||||
mCommandBuffer->draw(count, 1, index, 0);
|
||||
if (apply || mNeedApply)
|
||||
Apply(DT_Triangles);
|
||||
else
|
||||
ApplyVertexBuffers();
|
||||
|
||||
mCommandBuffer->drawIndexed((count - 2) * 3, 1, 0, index, 0);
|
||||
|
||||
mIndexBuffer = oldIndexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
#endif
|
||||
if (apply || mNeedApply)
|
||||
Apply(dt);
|
||||
|
||||
mCommandBuffer->draw(count, 1, index, 0);
|
||||
#ifdef __APPLE__
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void VkRenderState::DrawIndexed(int dt, int index, int count, bool apply)
|
||||
void VkRenderState::DoDrawIndexed(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (apply || mNeedApply)
|
||||
Apply(dt);
|
||||
|
|
@ -226,10 +248,11 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
// Find a pipeline that matches our state
|
||||
VkPipelineKey pipelineKey;
|
||||
pipelineKey.DrawType = dt;
|
||||
pipelineKey.DrawLine = mDrawLine || mWireframe;
|
||||
pipelineKey.VertexFormat = mVertexBuffer ? static_cast<VkHardwareVertexBuffer*>(mVertexBuffer)->VertexFormat : mRSBuffers->Flatbuffer.VertexFormat;
|
||||
pipelineKey.RenderStyle = mRenderStyle;
|
||||
pipelineKey.DepthTest = mDepthTest;
|
||||
pipelineKey.DepthWrite = mDepthTest && mDepthWrite;
|
||||
pipelineKey.DepthTest = mDepthTest && !mWireframe;
|
||||
pipelineKey.DepthWrite = mDepthTest && !mWireframe && mDepthWrite;
|
||||
pipelineKey.DepthFunc = mDepthFunc;
|
||||
pipelineKey.DepthClamp = mDepthClamp;
|
||||
pipelineKey.DepthBias = !(mBias.mFactor == 0 && mBias.mUnits == 0);
|
||||
|
|
@ -247,7 +270,7 @@ void VkRenderState::ApplyRenderPass(int dt)
|
|||
{
|
||||
int effectState = mMaterial.mOverrideShader >= 0 ? mMaterial.mOverrideShader : (mMaterial.mMaterial ? mMaterial.mMaterial->GetShaderIndex() : 0);
|
||||
pipelineKey.ShaderKey.SpecialEffect = EFF_NONE;
|
||||
pipelineKey.ShaderKey.EffectState = mTextureEnabled ? effectState : SHADER_NoTexture;
|
||||
pipelineKey.ShaderKey.EffectState = (mTextureEnabled && !mWireframe) ? effectState : SHADER_NoTexture;
|
||||
if (r_skipmats && pipelineKey.ShaderKey.EffectState >= 3 && pipelineKey.ShaderKey.EffectState <= 4)
|
||||
pipelineKey.ShaderKey.EffectState = 0;
|
||||
pipelineKey.ShaderKey.AlphaTest = mSurfaceUniforms.uAlphaThreshold >= 0.f;
|
||||
|
|
@ -1080,15 +1103,16 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
|
|||
pipelineKey.ShaderKey.GBufferPass = mRenderTarget.DrawBuffers > 1;
|
||||
|
||||
// State overridden by the renderstate drawing the mesh
|
||||
pipelineKey.DepthTest = mDepthTest;
|
||||
pipelineKey.DepthWrite = mDepthTest && mDepthWrite;
|
||||
pipelineKey.DrawLine = mDrawLine || mWireframe;
|
||||
pipelineKey.DepthTest = mDepthTest && !mWireframe;
|
||||
pipelineKey.DepthWrite = mDepthTest && !mWireframe && mDepthWrite;
|
||||
pipelineKey.DepthClamp = mDepthClamp;
|
||||
pipelineKey.DepthBias = !(mBias.mFactor == 0 && mBias.mUnits == 0);
|
||||
pipelineKey.StencilTest = mStencilTest;
|
||||
pipelineKey.StencilPassOp = mStencilOp;
|
||||
pipelineKey.ColorMask = mColorMask;
|
||||
pipelineKey.CullMode = mCullMode;
|
||||
if (!mTextureEnabled)
|
||||
if (!mTextureEnabled || mWireframe)
|
||||
pipelineKey.ShaderKey.EffectState = SHADER_NoTexture;
|
||||
|
||||
mPipelineKey = pipelineKey;
|
||||
|
|
@ -1110,30 +1134,3 @@ void VkRenderState::ApplyLevelMeshPipeline(VulkanCommandBuffer* cmdbuffer, VkPip
|
|||
cmdbuffer->bindDescriptorSet(VK_PIPELINE_BIND_POINT_GRAPHICS, layout, 2, descriptors->GetBindlessSet());
|
||||
cmdbuffer->pushConstants(layout, VK_SHADER_STAGE_VERTEX_BIT | VK_SHADER_STAGE_FRAGMENT_BIT, 0, (uint32_t)sizeof(PushConstants), &pushConstants);
|
||||
}
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
void VkRenderStateMolten::Draw(int dt, int index, int count, bool apply)
|
||||
{
|
||||
if (dt == DT_TriangleFan)
|
||||
{
|
||||
IBuffer* oldIndexBuffer = mIndexBuffer;
|
||||
mIndexBuffer = fb->GetBufferManager()->FanToTrisIndexBuffer.get();
|
||||
|
||||
if (apply || mNeedApply)
|
||||
Apply(DT_Triangles);
|
||||
else
|
||||
ApplyVertexBuffers();
|
||||
|
||||
mCommandBuffer->drawIndexed((count - 2) * 3, 1, 0, index, 0);
|
||||
|
||||
mIndexBuffer = oldIndexBuffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (apply || mNeedApply)
|
||||
Apply(dt);
|
||||
|
||||
mCommandBuffer->draw(count, 1, index, 0);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -22,8 +22,8 @@ public:
|
|||
|
||||
// Draw commands
|
||||
void ClearScreen() override;
|
||||
void Draw(int dt, int index, int count, bool apply = true) override;
|
||||
void DrawIndexed(int dt, int index, int count, bool apply = true) override;
|
||||
void DoDraw(int dt, int index, int count, bool apply) override;
|
||||
void DoDrawIndexed(int dt, int index, int count, bool apply) override;
|
||||
|
||||
// Immediate render state change commands. These only change infrequently and should not clutter the render state.
|
||||
bool SetDepthClamp(bool on) override;
|
||||
|
|
@ -105,6 +105,7 @@ protected:
|
|||
VkRenderPassSetup* mPassSetup = nullptr;
|
||||
int mClearTargets = 0;
|
||||
bool mNeedApply = true;
|
||||
bool mDrawLine = false;
|
||||
|
||||
int mScissorX = 0, mScissorY = 0, mScissorWidth = -1, mScissorHeight = -1;
|
||||
int mViewportX = 0, mViewportY = 0, mViewportWidth = -1, mViewportHeight = -1;
|
||||
|
|
@ -154,12 +155,4 @@ protected:
|
|||
} mRenderTarget;
|
||||
|
||||
TArray<uint32_t> mQueryResultsBuffer;
|
||||
};
|
||||
|
||||
class VkRenderStateMolten : public VkRenderState
|
||||
{
|
||||
public:
|
||||
using VkRenderState::VkRenderState;
|
||||
|
||||
void Draw(int dt, int index, int count, bool apply = true) override;
|
||||
};
|
||||
};
|
||||
|
|
@ -1215,6 +1215,8 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
state.SetDepthMask(true);
|
||||
if (!gl_no_skyclear && !gl_levelmesh) drawctx->portalState.RenderFirstSkyPortal(recursion, this, state);
|
||||
|
||||
state.SetWireframe(gl_wireframe, gl_wireframecolor.get()->asFV4());
|
||||
|
||||
RenderScene(state);
|
||||
|
||||
screen->UpdateLinearDepthTexture();
|
||||
|
|
@ -1237,6 +1239,9 @@ void HWDrawInfo::DrawScene(int drawmode, FRenderState& state)
|
|||
{
|
||||
state.SetFogballIndex(-1);
|
||||
}
|
||||
|
||||
state.SetWireframe(0, {});
|
||||
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue