- add PolyTriangleDrawer functions for the operations needed by PolyRenderState

This commit is contained in:
Magnus Norddahl 2019-05-27 07:57:27 +02:00
commit 8db5e72254
6 changed files with 517 additions and 298 deletions

View file

@ -57,37 +57,50 @@ bool PolyRenderState::SetDepthClamp(bool on)
{
bool lastValue = mDepthClamp;
mDepthClamp = on;
PolyTriangleDrawer::SetDepthClamp(GetPolyFrameBuffer()->GetDrawCommands(), on);
return lastValue;
}
void PolyRenderState::SetDepthMask(bool on)
{
args.SetWriteDepth(on);
PolyTriangleDrawer::SetDepthMask(GetPolyFrameBuffer()->GetDrawCommands(), on);
}
void PolyRenderState::SetDepthFunc(int func)
{
PolyTriangleDrawer::SetDepthFunc(GetPolyFrameBuffer()->GetDrawCommands(), func);
}
void PolyRenderState::SetDepthRange(float min, float max)
{
PolyTriangleDrawer::SetDepthRange(GetPolyFrameBuffer()->GetDrawCommands(), min, max);
}
void PolyRenderState::SetColorMask(bool r, bool g, bool b, bool a)
{
args.SetWriteColor(r || g || b || a);
PolyTriangleDrawer::SetColorMask(GetPolyFrameBuffer()->GetDrawCommands(), r, g, b, a);
}
void PolyRenderState::SetStencil(int offs, int op, int flags)
{
PolyTriangleDrawer::SetStencil(GetPolyFrameBuffer()->GetDrawCommands(), screen->stencilValue + offs, op);
if (flags != -1)
{
bool cmon = !(flags & SF_ColorMaskOff);
SetColorMask(cmon, cmon, cmon, cmon); // don't write to the graphics buffer
SetDepthMask(!(flags & SF_DepthMaskOff));
}
}
void PolyRenderState::SetCulling(int mode)
{
PolyTriangleDrawer::SetCulling(GetPolyFrameBuffer()->GetDrawCommands(), mode);
}
void PolyRenderState::EnableClipDistance(int num, bool state)
{
PolyTriangleDrawer::EnableClipDistance(GetPolyFrameBuffer()->GetDrawCommands(), num, state);
}
void PolyRenderState::Clear(int targets)
@ -102,21 +115,38 @@ void PolyRenderState::Clear(int targets)
void PolyRenderState::EnableStencil(bool on)
{
PolyTriangleDrawer::EnableStencil(GetPolyFrameBuffer()->GetDrawCommands(), on);
}
void PolyRenderState::SetScissor(int x, int y, int w, int h)
{
auto fb = GetPolyFrameBuffer();
if (w < 0)
{
x = 0;
y = 0;
w = fb->GetCanvas()->GetWidth();
h = fb->GetCanvas()->GetHeight();
}
PolyTriangleDrawer::SetScissor(fb->GetDrawCommands(), x, y, w, h);
}
void PolyRenderState::SetViewport(int x, int y, int w, int h)
{
auto fb = GetPolyFrameBuffer();
if (w < 0)
{
x = 0;
y = 0;
w = fb->GetCanvas()->GetWidth();
h = fb->GetCanvas()->GetHeight();
}
PolyTriangleDrawer::SetViewport(fb->GetDrawCommands(), x, y, w, h, fb->GetCanvas());
}
void PolyRenderState::EnableDepthTest(bool on)
{
args.SetDepthTest(on);
PolyTriangleDrawer::EnableDepthTest(GetPolyFrameBuffer()->GetDrawCommands(), on);
}
void PolyRenderState::EnableMultisampling(bool on)
@ -134,58 +164,71 @@ void PolyRenderState::EnableDrawBuffers(int count)
void PolyRenderState::Apply()
{
drawcalls.Clock();
auto fb = GetPolyFrameBuffer();
args.SetStencilTest(false);
args.SetWriteStencil(false);
PolyPushConstants constants;
FColormap cm;
cm.Clear();
args.SetLight(GetColorTable(cm), (int)(mLightParms[3] * 255.0f), mViewpointUniforms->mGlobVis, true);
int fogset = 0;
if (mFogEnabled)
{
if (mFogEnabled == 2)
{
fogset = -3; // 2D rendering with 'foggy' overlay.
}
else if ((GetFogColor() & 0xffffff) == 0)
{
fogset = gl_fogmode;
}
else
{
fogset = -gl_fogmode;
}
}
args.SetColor(MAKEARGB(
static_cast<uint32_t>(mStreamData.uVertexColor.W * 255.0f + 0.5f),
static_cast<uint32_t>(mStreamData.uVertexColor.X * 255.0f + 0.5f),
static_cast<uint32_t>(mStreamData.uVertexColor.Y * 255.0f + 0.5f),
static_cast<uint32_t>(mStreamData.uVertexColor.Z * 255.0f + 0.5f)), 0);
int tempTM = TM_NORMAL;
if (mMaterial.mMaterial && mMaterial.mMaterial->tex && mMaterial.mMaterial->tex->isHardwareCanvas())
tempTM = TM_OPAQUE;
constants.uFogEnabled = fogset;
constants.uTextureMode = mTextureMode == TM_NORMAL && tempTM == TM_OPAQUE ? TM_OPAQUE : mTextureMode;
constants.uLightDist = mLightParms[0];
constants.uLightFactor = mLightParms[1];
constants.uFogDensity = mLightParms[2];
constants.uLightLevel = mLightParms[3];
constants.uAlphaThreshold = mAlphaThreshold;
constants.uClipSplit = { mClipSplit[0], mClipSplit[1] };
constants.uLightIndex = mLightIndex;
if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory());
if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory());
PolyTriangleDrawer::SetInputAssembly(fb->GetDrawCommands(), static_cast<PolyVertexBuffer*>(mVertexBuffer));
PolyTriangleDrawer::SetRenderStyle(fb->GetDrawCommands(), mRenderStyle);
PolyTriangleDrawer::PushStreamData(fb->GetDrawCommands(), mStreamData, constants);
ApplyMatrices();
ApplyMaterial();
if (mBias.mChanged)
{
PolyTriangleDrawer::SetDepthBias(fb->GetDrawCommands(), mBias.mUnits, mBias.mFactor);
mBias.mChanged = false;
}
drawcalls.Unclock();
}
void PolyRenderState::ApplyMaterial()
{
if (mMaterial.mChanged && mMaterial.mMaterial)
{
auto base = static_cast<PolyHardwareTexture*>(mMaterial.mMaterial->GetLayer(0, mMaterial.mTranslation));
if (base)
{
DCanvas *texcanvas = base->GetImage(mMaterial);
args.SetTexture(texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth());
if (mRenderStyle == LegacyRenderStyles[STYLE_Normal])
args.SetStyle(TriBlendMode::Normal);
else if (mRenderStyle == LegacyRenderStyles[STYLE_Add])
args.SetStyle(TriBlendMode::Add);
else if (mRenderStyle == LegacyRenderStyles[STYLE_Translucent])
args.SetStyle(TriBlendMode::Translucent);
else
args.SetStyle(TriBlendMode::Opaque);
}
else
{
args.SetStyle(TriBlendMode::Fill);
PolyTriangleDrawer::SetTexture(GetPolyFrameBuffer()->GetDrawCommands(), texcanvas->GetPixels(), texcanvas->GetHeight(), texcanvas->GetWidth());
}
mMaterial.mChanged = false;
}
auto fb = GetPolyFrameBuffer();
if (mVertexBuffer) PolyTriangleDrawer::SetVertexBuffer(fb->GetDrawCommands(), mVertexBuffer->Memory());
if (mIndexBuffer) PolyTriangleDrawer::SetIndexBuffer(fb->GetDrawCommands(), mIndexBuffer->Memory());
PolyTriangleDrawer::SetInputAssembly(fb->GetDrawCommands(), static_cast<PolyVertexBuffer*>(mVertexBuffer));
ApplyMatrices();
PolyTriangleDrawer::PushStreamData(fb->GetDrawCommands(), mStreamData, { mClipSplit[0], mClipSplit[1] });
PolyTriangleDrawer::SetTwoSided(fb->GetDrawCommands(), true);
PolyTriangleDrawer::PushConstants(fb->GetDrawCommands(), args);
drawcalls.Unclock();
}
template<typename T>