- add PolyTriangleDrawer functions for the operations needed by PolyRenderState

This commit is contained in:
Magnus Norddahl 2019-05-27 07:57:27 +02:00
parent 3a3de13abd
commit 8db5e72254
6 changed files with 521 additions and 302 deletions

View file

@ -92,8 +92,6 @@ void PolyFrameBuffer::InitializeState()
mRenderState.reset(new PolyRenderState());
CheckCanvas();
PolyTriangleDrawer::SetTransform(GetDrawCommands(), GetFrameMemory()->NewObject<Mat4f>(Mat4f::Identity()), nullptr);
}
void PolyFrameBuffer::CheckCanvas()
@ -149,7 +147,6 @@ void PolyFrameBuffer::Update()
}
CheckCanvas();
PolyTriangleDrawer::SetTransform(GetDrawCommands(), GetFrameMemory()->NewObject<Mat4f>(Mat4f::Identity()), nullptr);
Super::Update();
}

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>

View file

@ -44,6 +44,7 @@ public:
private:
void Apply();
void ApplyMaterial();
void ApplyMatrices();
struct Matrices
@ -58,5 +59,4 @@ private:
HWViewpointUniforms *mViewpointUniforms = nullptr;
bool mDepthClamp = true;
PolyDrawArgs args;
};

View file

@ -126,14 +126,84 @@ void PolyTriangleDrawer::SetIndexBuffer(const DrawerCommandQueuePtr &queue, cons
queue->Push<PolySetIndexBufferCommand>(elements);
}
void PolyTriangleDrawer::PushConstants(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args)
void PolyTriangleDrawer::PushDrawArgs(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args)
{
queue->Push<PolyPushConstantsCommand>(args);
queue->Push<PolyPushDrawArgsCommand>(args);
}
void PolyTriangleDrawer::PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const Vec2f &uClipSplit)
void PolyTriangleDrawer::SetDepthClamp(const DrawerCommandQueuePtr &queue, bool on)
{
queue->Push<PolyPushStreamDataCommand>(data, uClipSplit);
queue->Push<PolySetDepthClampCommand>(on);
}
void PolyTriangleDrawer::SetDepthMask(const DrawerCommandQueuePtr &queue, bool on)
{
queue->Push<PolySetDepthMaskCommand>(on);
}
void PolyTriangleDrawer::SetDepthFunc(const DrawerCommandQueuePtr &queue, int func)
{
queue->Push<PolySetDepthFuncCommand>(func);
}
void PolyTriangleDrawer::SetDepthRange(const DrawerCommandQueuePtr &queue, float min, float max)
{
queue->Push<PolySetDepthRangeCommand>(min, max);
}
void PolyTriangleDrawer::SetDepthBias(const DrawerCommandQueuePtr &queue, float depthBiasConstantFactor, float depthBiasSlopeFactor)
{
queue->Push<PolySetDepthBiasCommand>(depthBiasConstantFactor, depthBiasSlopeFactor);
}
void PolyTriangleDrawer::SetColorMask(const DrawerCommandQueuePtr &queue, bool r, bool g, bool b, bool a)
{
queue->Push<PolySetColorMaskCommand>(r, g, b, a);
}
void PolyTriangleDrawer::SetStencil(const DrawerCommandQueuePtr &queue, int stencilRef, int op)
{
queue->Push<PolySetStencilCommand>(stencilRef, op);
}
void PolyTriangleDrawer::SetCulling(const DrawerCommandQueuePtr &queue, int mode)
{
queue->Push<PolySetCullingCommand>(mode);
}
void PolyTriangleDrawer::EnableClipDistance(const DrawerCommandQueuePtr &queue, int num, bool state)
{
queue->Push<PolyEnableClipDistanceCommand>(num, state);
}
void PolyTriangleDrawer::EnableStencil(const DrawerCommandQueuePtr &queue, bool on)
{
queue->Push<PolyEnableStencilCommand>(on);
}
void PolyTriangleDrawer::SetScissor(const DrawerCommandQueuePtr &queue, int x, int y, int w, int h)
{
queue->Push<PolySetScissorCommand>(x, y, w, h);
}
void PolyTriangleDrawer::EnableDepthTest(const DrawerCommandQueuePtr &queue, bool on)
{
queue->Push<PolyEnableDepthTestCommand>(on);
}
void PolyTriangleDrawer::SetRenderStyle(const DrawerCommandQueuePtr &queue, FRenderStyle style)
{
queue->Push<PolySetRenderStyleCommand>(style);
}
void PolyTriangleDrawer::SetTexture(const DrawerCommandQueuePtr &queue, void *pixels, int width, int height)
{
queue->Push<PolySetTextureCommand>(pixels, width, height);
}
void PolyTriangleDrawer::PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants)
{
queue->Push<PolyPushStreamDataCommand>(data, constants);
}
void PolyTriangleDrawer::PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
@ -216,15 +286,25 @@ void PolyTriangleThreadData::SetTransform(const Mat4f *newObjectToClip, const Ma
swVertexShader.objectToWorld = newObjectToWorld;
}
void PolyTriangleThreadData::PushConstants(const PolyDrawArgs &args)
void PolyTriangleThreadData::PushDrawArgs(const PolyDrawArgs &args)
{
drawargs = args;
}
void PolyTriangleThreadData::PushStreamData(const StreamData &data, const Vec2f &uClipSplit)
void PolyTriangleThreadData::PushStreamData(const StreamData &data, const PolyPushConstants &constants)
{
mainVertexShader.Data = data;
mainVertexShader.uClipSplit = uClipSplit;
mainVertexShader.uClipSplit = constants.uClipSplit;
FColormap cm;
cm.Clear();
drawargs.SetLight(GetColorTable(cm), (int)(constants.uLightLevel * 255.0f), mainVertexShader.Viewpoint->mGlobVis, true);
drawargs.SetColor(MAKEARGB(
static_cast<uint32_t>(mainVertexShader.Data.uVertexColor.W * 255.0f + 0.5f),
static_cast<uint32_t>(mainVertexShader.Data.uVertexColor.X * 255.0f + 0.5f),
static_cast<uint32_t>(mainVertexShader.Data.uVertexColor.Y * 255.0f + 0.5f),
static_cast<uint32_t>(mainVertexShader.Data.uVertexColor.Z * 255.0f + 0.5f)), 0);
}
void PolyTriangleThreadData::PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
@ -239,6 +319,102 @@ void PolyTriangleThreadData::SetViewpointUniforms(const HWViewpointUniforms *uni
mainVertexShader.Viewpoint = uniforms;
}
void PolyTriangleThreadData::SetDepthClamp(bool on)
{
}
void PolyTriangleThreadData::SetDepthMask(bool on)
{
drawargs.SetWriteDepth(on);
}
void PolyTriangleThreadData::SetDepthFunc(int func)
{
}
void PolyTriangleThreadData::SetDepthRange(float min, float max)
{
}
void PolyTriangleThreadData::SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor)
{
}
void PolyTriangleThreadData::SetColorMask(bool r, bool g, bool b, bool a)
{
drawargs.SetWriteColor(r || g || b || a);
}
void PolyTriangleThreadData::SetStencil(int stencilRef, int op)
{
drawargs.SetStencilTestValue(stencilRef);
if (op == SOP_Increment)
{
drawargs.SetWriteStencil(drawargs.StencilTest(), MIN(stencilRef + 1, (int)255));
}
else if (op == SOP_Decrement)
{
drawargs.SetWriteStencil(drawargs.StencilTest(), MAX(stencilRef - 1, (int)0));
}
else // SOP_Keep
{
drawargs.SetWriteStencil(false, stencilRef);
}
}
void PolyTriangleThreadData::SetCulling(int mode)
{
SetTwoSided(mode == Cull_None);
SetCullCCW(mode == Cull_CCW);
}
void PolyTriangleThreadData::EnableClipDistance(int num, bool state)
{
}
void PolyTriangleThreadData::EnableStencil(bool on)
{
drawargs.SetStencilTest(on);
drawargs.SetWriteStencil(on && drawargs.StencilTestValue() != drawargs.StencilWriteValue(), drawargs.StencilWriteValue());
}
void PolyTriangleThreadData::SetScissor(int x, int y, int w, int h)
{
}
void PolyTriangleThreadData::EnableDepthTest(bool on)
{
drawargs.SetDepthTest(on);
}
void PolyTriangleThreadData::SetRenderStyle(FRenderStyle style)
{
if (style == LegacyRenderStyles[STYLE_Normal]) drawargs.SetStyle(TriBlendMode::Normal);
else if (style == LegacyRenderStyles[STYLE_Fuzzy]) drawargs.SetStyle(TriBlendMode::Fuzzy);
//else if (style == LegacyRenderStyles[STYLE_SoulTrans]) drawargs.SetStyle(TriBlendMode::SoulTrans);
//else if (style == LegacyRenderStyles[STYLE_OptFuzzy]) drawargs.SetStyle(TriBlendMode::OptFuzzy);
else if (style == LegacyRenderStyles[STYLE_Stencil]) drawargs.SetStyle(TriBlendMode::Stencil);
else if (style == LegacyRenderStyles[STYLE_Translucent]) drawargs.SetStyle(TriBlendMode::Translucent);
else if (style == LegacyRenderStyles[STYLE_Add]) drawargs.SetStyle(TriBlendMode::Add);
//else if (style == LegacyRenderStyles[STYLE_Shaded]) drawargs.SetStyle(TriBlendMode::Shaded);
else if (style == LegacyRenderStyles[STYLE_TranslucentStencil]) drawargs.SetStyle(TriBlendMode::TranslucentStencil);
else if (style == LegacyRenderStyles[STYLE_Shadow]) drawargs.SetStyle(TriBlendMode::Shadow);
else if (style == LegacyRenderStyles[STYLE_Subtract]) drawargs.SetStyle(TriBlendMode::Subtract);
else if (style == LegacyRenderStyles[STYLE_AddStencil]) drawargs.SetStyle(TriBlendMode::AddStencil);
else if (style == LegacyRenderStyles[STYLE_AddShaded]) drawargs.SetStyle(TriBlendMode::AddShaded);
//else if (style == LegacyRenderStyles[STYLE_Multiply]) drawargs.SetStyle(TriBlendMode::Multiply);
//else if (style == LegacyRenderStyles[STYLE_InverseMultiply]) drawargs.SetStyle(TriBlendMode::InverseMultiply);
//else if (style == LegacyRenderStyles[STYLE_ColorBlend]) drawargs.SetStyle(TriBlendMode::ColorBlend);
//else if (style == LegacyRenderStyles[STYLE_Source]) drawargs.SetStyle(TriBlendMode::Source);
//else if (style == LegacyRenderStyles[STYLE_ColorAdd]) drawargs.SetStyle(TriBlendMode::ColorAdd);
else drawargs.SetStyle(TriBlendMode::Opaque);
}
void PolyTriangleThreadData::SetTexture(void *pixels, int width, int height)
{
drawargs.SetTexture((uint8_t*)pixels, width, height);
}
void PolyTriangleThreadData::DrawIndexed(int index, int vcount, PolyDrawMode drawmode)
{
if (vcount < 3)
@ -682,192 +858,3 @@ PolyTriangleThreadData *PolyTriangleThreadData::Get(DrawerThread *thread)
thread->poly = std::make_shared<PolyTriangleThreadData>(thread->core, thread->num_cores, thread->numa_node, thread->num_numa_nodes, thread->numa_start_y, thread->numa_end_y);
return thread->poly.get();
}
/////////////////////////////////////////////////////////////////////////////
PolySetVertexBufferCommand::PolySetVertexBufferCommand(const void *vertices) : vertices(vertices)
{
}
void PolySetVertexBufferCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetVertexBuffer(vertices);
}
/////////////////////////////////////////////////////////////////////////////
PolySetIndexBufferCommand::PolySetIndexBufferCommand(const void *indices) : indices(indices)
{
}
void PolySetIndexBufferCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetIndexBuffer(indices);
}
/////////////////////////////////////////////////////////////////////////////
PolySetInputAssemblyCommand::PolySetInputAssemblyCommand(PolyInputAssembly *input) : input(input)
{
}
void PolySetInputAssemblyCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetInputAssembly(input);
}
/////////////////////////////////////////////////////////////////////////////
PolySetTransformCommand::PolySetTransformCommand(const Mat4f *objectToClip, const Mat4f *objectToWorld) : objectToClip(objectToClip), objectToWorld(objectToWorld)
{
}
void PolySetTransformCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetTransform(objectToClip, objectToWorld);
}
/////////////////////////////////////////////////////////////////////////////
PolySetCullCCWCommand::PolySetCullCCWCommand(bool ccw) : ccw(ccw)
{
}
void PolySetCullCCWCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetCullCCW(ccw);
}
/////////////////////////////////////////////////////////////////////////////
PolySetTwoSidedCommand::PolySetTwoSidedCommand(bool twosided) : twosided(twosided)
{
}
void PolySetTwoSidedCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetTwoSided(twosided);
}
/////////////////////////////////////////////////////////////////////////////
PolySetWeaponSceneCommand::PolySetWeaponSceneCommand(bool value) : value(value)
{
}
void PolySetWeaponSceneCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetWeaponScene(value);
}
/////////////////////////////////////////////////////////////////////////////
PolySetModelVertexShaderCommand::PolySetModelVertexShaderCommand(int frame1, int frame2, float interpolationFactor) : frame1(frame1), frame2(frame2), interpolationFactor(interpolationFactor)
{
}
void PolySetModelVertexShaderCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetModelVertexShader(frame1, frame2, interpolationFactor);
}
/////////////////////////////////////////////////////////////////////////////
PolyClearDepthCommand::PolyClearDepthCommand(float value) : value(value)
{
}
void PolyClearDepthCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->ClearDepth(value);
}
/////////////////////////////////////////////////////////////////////////////
PolyClearStencilCommand::PolyClearStencilCommand(uint8_t value) : value(value)
{
}
void PolyClearStencilCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->ClearStencil(value);
}
/////////////////////////////////////////////////////////////////////////////
PolySetViewportCommand::PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra)
: x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra)
{
}
void PolySetViewportCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra);
}
/////////////////////////////////////////////////////////////////////////////
PolySetViewpointUniformsCommand::PolySetViewpointUniformsCommand(const HWViewpointUniforms *uniforms) : uniforms(uniforms)
{
}
void PolySetViewpointUniformsCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->SetViewpointUniforms(uniforms);
}
/////////////////////////////////////////////////////////////////////////////
PolyPushMatricesCommand::PolyPushMatricesCommand(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
: modelMatrix(modelMatrix), normalModelMatrix(normalModelMatrix), textureMatrix(textureMatrix)
{
}
void PolyPushMatricesCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->PushMatrices(modelMatrix, normalModelMatrix, textureMatrix);
}
/////////////////////////////////////////////////////////////////////////////
PolyPushStreamDataCommand::PolyPushStreamDataCommand(const StreamData &data, const Vec2f &uClipSplit) : data(data), uClipSplit(uClipSplit)
{
}
void PolyPushStreamDataCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->PushStreamData(data, uClipSplit);
}
/////////////////////////////////////////////////////////////////////////////
PolyPushConstantsCommand::PolyPushConstantsCommand(const PolyDrawArgs &args) : args(args)
{
}
void PolyPushConstantsCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->PushConstants(args);
}
/////////////////////////////////////////////////////////////////////////////
PolyDrawCommand::PolyDrawCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode)
{
}
void PolyDrawCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->Draw(index, count, mode);
}
/////////////////////////////////////////////////////////////////////////////
PolyDrawIndexedCommand::PolyDrawIndexedCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode)
{
}
void PolyDrawIndexedCommand::Execute(DrawerThread *thread)
{
PolyTriangleThreadData::Get(thread)->DrawIndexed(index, count, mode);
}

View file

@ -33,6 +33,8 @@
class DCanvas;
class PolyDrawerCommand;
class PolyInputAssembly;
class PolyPipeline;
struct PolyPushConstants;
class PolyTriangleDrawer
{
@ -42,20 +44,53 @@ public:
static void ClearStencil(const DrawerCommandQueuePtr &queue, uint8_t value);
static void SetViewport(const DrawerCommandQueuePtr &queue, int x, int y, int width, int height, DCanvas *canvas);
static void SetInputAssembly(const DrawerCommandQueuePtr &queue, PolyInputAssembly *input);
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
static void SetViewpointUniforms(const DrawerCommandQueuePtr &queue, const HWViewpointUniforms *uniforms);
static void SetDepthClamp(const DrawerCommandQueuePtr &queue, bool on);
static void SetDepthMask(const DrawerCommandQueuePtr &queue, bool on);
static void SetDepthFunc(const DrawerCommandQueuePtr &queue, int func);
static void SetDepthRange(const DrawerCommandQueuePtr &queue, float min, float max);
static void SetDepthBias(const DrawerCommandQueuePtr &queue, float depthBiasConstantFactor, float depthBiasSlopeFactor);
static void SetColorMask(const DrawerCommandQueuePtr &queue, bool r, bool g, bool b, bool a);
static void SetStencil(const DrawerCommandQueuePtr &queue, int stencilRef, int op);
static void SetCulling(const DrawerCommandQueuePtr &queue, int mode);
static void EnableClipDistance(const DrawerCommandQueuePtr &queue, int num, bool state);
static void EnableStencil(const DrawerCommandQueuePtr &queue, bool on);
static void SetScissor(const DrawerCommandQueuePtr &queue, int x, int y, int w, int h);
static void EnableDepthTest(const DrawerCommandQueuePtr &queue, bool on);
static void SetRenderStyle(const DrawerCommandQueuePtr &queue, FRenderStyle style);
static void SetTexture(const DrawerCommandQueuePtr &queue, void *pixels, int width, int height);
static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const PolyPushConstants &constants);
static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
static bool IsBgra();
// Old softpoly/swrenderer interface
static void SetCullCCW(const DrawerCommandQueuePtr &queue, bool ccw);
static void SetTwoSided(const DrawerCommandQueuePtr &queue, bool twosided);
static void SetWeaponScene(const DrawerCommandQueuePtr &queue, bool enable);
static void SetModelVertexShader(const DrawerCommandQueuePtr &queue, int frame1, int frame2, float interpolationFactor);
static void SetTransform(const DrawerCommandQueuePtr &queue, const Mat4f *objectToClip, const Mat4f *objectToWorld);
static void SetVertexBuffer(const DrawerCommandQueuePtr &queue, const void *vertices);
static void SetIndexBuffer(const DrawerCommandQueuePtr &queue, const void *elements);
static void SetViewpointUniforms(const DrawerCommandQueuePtr &queue, const HWViewpointUniforms *uniforms);
static void PushConstants(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args);
static void PushStreamData(const DrawerCommandQueuePtr &queue, const StreamData &data, const Vec2f &uClipSplit);
static void PushMatrices(const DrawerCommandQueuePtr &queue, const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
static void Draw(const DrawerCommandQueuePtr &queue, int index, int vcount, PolyDrawMode mode = PolyDrawMode::Triangles);
static void DrawIndexed(const DrawerCommandQueuePtr &queue, int index, int count, PolyDrawMode mode = PolyDrawMode::Triangles);
static bool IsBgra();
static void PushDrawArgs(const DrawerCommandQueuePtr &queue, const PolyDrawArgs &args);
};
struct PolyPushConstants
{
int uTextureMode;
float uAlphaThreshold;
Vec2f uClipSplit;
// Lighting + Fog
float uLightLevel;
float uFogDensity;
float uLightFactor;
float uLightDist;
int uFogEnabled;
// dynamic lights
int uLightIndex;
};
class PolyInputAssembly
@ -93,9 +128,23 @@ public:
void SetVertexBuffer(const void *data) { vertices = data; }
void SetIndexBuffer(const void *data) { elements = (const unsigned int *)data; }
void SetViewpointUniforms(const HWViewpointUniforms *uniforms);
void SetDepthClamp(bool on);
void SetDepthMask(bool on);
void SetDepthFunc(int func);
void SetDepthRange(float min, float max);
void SetDepthBias(float depthBiasConstantFactor, float depthBiasSlopeFactor);
void SetColorMask(bool r, bool g, bool b, bool a);
void SetStencil(int stencilRef, int op);
void SetCulling(int mode);
void EnableClipDistance(int num, bool state);
void EnableStencil(bool on);
void SetScissor(int x, int y, int w, int h);
void EnableDepthTest(bool on);
void SetRenderStyle(FRenderStyle style);
void SetTexture(void *pixels, int width, int height);
void PushConstants(const PolyDrawArgs &args);
void PushStreamData(const StreamData &data, const Vec2f &uClipSplit);
void PushDrawArgs(const PolyDrawArgs &args);
void PushStreamData(const StreamData &data, const PolyPushConstants &constants);
void PushMatrices(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
void DrawIndexed(int index, int count, PolyDrawMode mode);
@ -171,7 +220,7 @@ private:
int viewport_width = 0;
int viewport_height = 0;
bool ccw = true;
bool twosided = false;
bool twosided = true;
PolyInputAssembly *inputAssembly = nullptr;
enum { max_additional_vertices = 16 };
@ -184,11 +233,163 @@ class PolyDrawerCommand : public DrawerCommand
public:
};
class PolySetDepthClampCommand : public PolyDrawerCommand
{
public:
PolySetDepthClampCommand(bool on) : on(on) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetDepthClamp(on); }
private:
bool on;
};
class PolySetDepthMaskCommand : public PolyDrawerCommand
{
public:
PolySetDepthMaskCommand(bool on) : on(on) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetDepthMask(on); }
private:
bool on;
};
class PolySetDepthFuncCommand : public PolyDrawerCommand
{
public:
PolySetDepthFuncCommand(int func) : func(func) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetDepthFunc(func); }
private:
int func;
};
class PolySetDepthRangeCommand : public PolyDrawerCommand
{
public:
PolySetDepthRangeCommand(float min, float max) : min(min), max(max) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetDepthRange(min, max); }
private:
float min;
float max;
};
class PolySetDepthBiasCommand : public PolyDrawerCommand
{
public:
PolySetDepthBiasCommand(float depthBiasConstantFactor, float depthBiasSlopeFactor) : depthBiasConstantFactor(depthBiasConstantFactor), depthBiasSlopeFactor(depthBiasSlopeFactor) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetDepthBias(depthBiasConstantFactor, depthBiasSlopeFactor); }
private:
float depthBiasConstantFactor;
float depthBiasSlopeFactor;
};
class PolySetColorMaskCommand : public PolyDrawerCommand
{
public:
PolySetColorMaskCommand(bool r, bool g, bool b, bool a) : r(r), g(g), b(b), a(a) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetColorMask(r, g, b, a); }
private:
bool r;
bool g;
bool b;
bool a;
};
class PolySetStencilCommand : public PolyDrawerCommand
{
public:
PolySetStencilCommand(int stencilRef, int op) : stencilRef(stencilRef), op(op) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetStencil(stencilRef, op); }
private:
int stencilRef;
int op;
};
class PolySetCullingCommand : public PolyDrawerCommand
{
public:
PolySetCullingCommand(int mode) : mode(mode) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetCulling(mode); }
private:
int mode;
};
class PolyEnableClipDistanceCommand : public PolyDrawerCommand
{
public:
PolyEnableClipDistanceCommand(int num, bool state) : num(num), state(state) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->EnableClipDistance(num, state); }
private:
int num;
bool state;
};
class PolyEnableStencilCommand : public PolyDrawerCommand
{
public:
PolyEnableStencilCommand(bool on) : on(on) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->EnableStencil(on); }
private:
bool on;
};
class PolySetScissorCommand : public PolyDrawerCommand
{
public:
PolySetScissorCommand(int x, int y, int w, int h) : x(x), y(y), w(w), h(h) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetScissor(x, y, w, h); }
private:
int x;
int y;
int w;
int h;
};
class PolyEnableDepthTestCommand : public PolyDrawerCommand
{
public:
PolyEnableDepthTestCommand(bool on) : on(on) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->EnableDepthTest(on); }
private:
bool on;
};
class PolySetRenderStyleCommand : public PolyDrawerCommand
{
public:
PolySetRenderStyleCommand(FRenderStyle style) : style(style) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetRenderStyle(style); }
private:
FRenderStyle style;
};
class PolySetTextureCommand : public PolyDrawerCommand
{
public:
PolySetTextureCommand(void *pixels, int width, int height) : pixels(pixels), width(width), height(height) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTexture(pixels, width, height); }
private:
void *pixels;
int width;
int height;
};
class PolySetVertexBufferCommand : public PolyDrawerCommand
{
public:
PolySetVertexBufferCommand(const void *vertices);
void Execute(DrawerThread *thread) override;
PolySetVertexBufferCommand(const void *vertices) : vertices(vertices) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetVertexBuffer(vertices); }
private:
const void *vertices;
@ -197,8 +398,8 @@ private:
class PolySetIndexBufferCommand : public PolyDrawerCommand
{
public:
PolySetIndexBufferCommand(const void *indices);
void Execute(DrawerThread *thread) override;
PolySetIndexBufferCommand(const void *indices) : indices(indices) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetIndexBuffer(indices); }
private:
const void *indices;
@ -207,8 +408,8 @@ private:
class PolySetInputAssemblyCommand : public PolyDrawerCommand
{
public:
PolySetInputAssemblyCommand(PolyInputAssembly *input);
void Execute(DrawerThread *thread) override;
PolySetInputAssemblyCommand(PolyInputAssembly *input) : input(input) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetInputAssembly(input); }
private:
PolyInputAssembly *input;
@ -217,9 +418,8 @@ private:
class PolySetTransformCommand : public PolyDrawerCommand
{
public:
PolySetTransformCommand(const Mat4f *objectToClip, const Mat4f *objectToWorld);
void Execute(DrawerThread *thread) override;
PolySetTransformCommand(const Mat4f *objectToClip, const Mat4f *objectToWorld) : objectToClip(objectToClip), objectToWorld(objectToWorld) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTransform(objectToClip, objectToWorld); }
private:
const Mat4f *objectToClip;
@ -229,9 +429,8 @@ private:
class PolySetCullCCWCommand : public PolyDrawerCommand
{
public:
PolySetCullCCWCommand(bool ccw);
void Execute(DrawerThread *thread) override;
PolySetCullCCWCommand(bool ccw) : ccw(ccw) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetCullCCW(ccw); }
private:
bool ccw;
@ -240,9 +439,8 @@ private:
class PolySetTwoSidedCommand : public PolyDrawerCommand
{
public:
PolySetTwoSidedCommand(bool twosided);
void Execute(DrawerThread *thread) override;
PolySetTwoSidedCommand(bool twosided) : twosided(twosided) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetTwoSided(twosided); }
private:
bool twosided;
@ -251,9 +449,8 @@ private:
class PolySetWeaponSceneCommand : public PolyDrawerCommand
{
public:
PolySetWeaponSceneCommand(bool value);
void Execute(DrawerThread *thread) override;
PolySetWeaponSceneCommand(bool value) : value(value) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetWeaponScene(value); }
private:
bool value;
@ -262,9 +459,8 @@ private:
class PolySetModelVertexShaderCommand : public PolyDrawerCommand
{
public:
PolySetModelVertexShaderCommand(int frame1, int frame2, float interpolationFactor);
void Execute(DrawerThread *thread) override;
PolySetModelVertexShaderCommand(int frame1, int frame2, float interpolationFactor) : frame1(frame1), frame2(frame2), interpolationFactor(interpolationFactor) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetModelVertexShader(frame1, frame2, interpolationFactor); }
private:
int frame1;
@ -275,9 +471,8 @@ private:
class PolyClearDepthCommand : public PolyDrawerCommand
{
public:
PolyClearDepthCommand(float value);
void Execute(DrawerThread *thread) override;
PolyClearDepthCommand(float value) : value(value) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->ClearDepth(value); }
private:
float value;
@ -286,9 +481,8 @@ private:
class PolyClearStencilCommand : public PolyDrawerCommand
{
public:
PolyClearStencilCommand(uint8_t value);
void Execute(DrawerThread *thread) override;
PolyClearStencilCommand(uint8_t value) : value(value) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->ClearStencil(value); }
private:
uint8_t value;
@ -297,9 +491,9 @@ private:
class PolySetViewportCommand : public PolyDrawerCommand
{
public:
PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra);
void Execute(DrawerThread *thread) override;
PolySetViewportCommand(int x, int y, int width, int height, uint8_t *dest, int dest_width, int dest_height, int dest_pitch, bool dest_bgra)
: x(x), y(y), width(width), height(height), dest(dest), dest_width(dest_width), dest_height(dest_height), dest_pitch(dest_pitch), dest_bgra(dest_bgra) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetViewport(x, y, width, height, dest, dest_width, dest_height, dest_pitch, dest_bgra); }
private:
int x;
@ -316,8 +510,8 @@ private:
class PolySetViewpointUniformsCommand : public PolyDrawerCommand
{
public:
PolySetViewpointUniformsCommand(const HWViewpointUniforms *uniforms);
void Execute(DrawerThread *thread) override;
PolySetViewpointUniformsCommand(const HWViewpointUniforms *uniforms) : uniforms(uniforms) {}
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->SetViewpointUniforms(uniforms); }
private:
const HWViewpointUniforms *uniforms;
@ -326,8 +520,9 @@ private:
class PolyPushMatricesCommand : public PolyDrawerCommand
{
public:
PolyPushMatricesCommand(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix);
void Execute(DrawerThread *thread) override;
PolyPushMatricesCommand(const VSMatrix &modelMatrix, const VSMatrix &normalModelMatrix, const VSMatrix &textureMatrix)
: modelMatrix(modelMatrix), normalModelMatrix(normalModelMatrix), textureMatrix(textureMatrix) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->PushMatrices(modelMatrix, normalModelMatrix, textureMatrix); }
private:
VSMatrix modelMatrix;
@ -338,20 +533,19 @@ private:
class PolyPushStreamDataCommand : public PolyDrawerCommand
{
public:
PolyPushStreamDataCommand(const StreamData &data, const Vec2f &uClipSplit);
void Execute(DrawerThread *thread) override;
PolyPushStreamDataCommand(const StreamData &data, const PolyPushConstants &constants) : data(data), constants(constants) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->PushStreamData(data, constants); }
private:
StreamData data;
Vec2f uClipSplit;
PolyPushConstants constants;
};
class PolyPushConstantsCommand : public PolyDrawerCommand
class PolyPushDrawArgsCommand : public PolyDrawerCommand
{
public:
PolyPushConstantsCommand(const PolyDrawArgs &args);
void Execute(DrawerThread *thread) override;
PolyPushDrawArgsCommand(const PolyDrawArgs &args) : args(args) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->PushDrawArgs(args); }
private:
PolyDrawArgs args;
@ -360,9 +554,8 @@ private:
class PolyDrawCommand : public PolyDrawerCommand
{
public:
PolyDrawCommand(int index, int count, PolyDrawMode mode);
void Execute(DrawerThread *thread) override;
PolyDrawCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->Draw(index, count, mode); }
private:
int index;
@ -373,9 +566,8 @@ private:
class PolyDrawIndexedCommand : public PolyDrawerCommand
{
public:
PolyDrawIndexedCommand(int index, int count, PolyDrawMode mode);
void Execute(DrawerThread *thread) override;
PolyDrawIndexedCommand(int index, int count, PolyDrawMode mode) : index(index), count(count), mode(mode) { }
void Execute(DrawerThread *thread) override { PolyTriangleThreadData::Get(thread)->DrawIndexed(index, count, mode); }
private:
int index;

View file

@ -367,7 +367,7 @@ namespace swrenderer
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
PolyTriangleDrawer::PushConstants(Thread->DrawQueue, args);
PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args);
PolyTriangleDrawer::Draw(Thread->DrawQueue, start, count);
}
@ -386,7 +386,7 @@ namespace swrenderer
args.SetClipPlane(1, ClipTop);
args.SetClipPlane(2, ClipBottom);
PolyTriangleDrawer::PushConstants(Thread->DrawQueue, args);
PolyTriangleDrawer::PushDrawArgs(Thread->DrawQueue, args);
PolyTriangleDrawer::DrawIndexed(Thread->DrawQueue, static_cast<int>(offset / sizeof(unsigned int)), numIndices);
}