From e0efcc0e5cb921cc5d8323339ee8ddae07dd9131 Mon Sep 17 00:00:00 2001 From: Jack Andersen Date: Thu, 10 Aug 2017 15:16:58 -1000 Subject: [PATCH] Implement triangle fan-to-strip stream converter --- .appveyor.yml | 6 +++ Runtime/Graphics/CGraphics.hpp | 41 ++++++++++++++++ .../Graphics/Shaders/CFluidPlaneShader.cpp | 14 +++--- .../Graphics/Shaders/CFluidPlaneShader.hpp | 6 +-- Runtime/World/CFluidPlaneCPU.cpp | 49 +++++++++++++------ 5 files changed, 91 insertions(+), 25 deletions(-) diff --git a/.appveyor.yml b/.appveyor.yml index 27ede3788..120443ca5 100644 --- a/.appveyor.yml +++ b/.appveyor.yml @@ -61,6 +61,12 @@ notifications: - provider: Slack incoming_webhook: secure: uoO0I0PWyCx0KLjBOG6d17aSVuEEvYztB/UiF8J0LmTb2O735mAdWcuZHTImDFUGZxeI34/qzOB2JKqF+h8dZA5yiprSTkWIookqQjUokAM= + - provider: Webhook + url: https://discordapp.com/api/webhooks/345359672326356993/M8kBYpqr1JyVNhnAHBwNN5TnZmtWy9_msxAQoeOlaa73UhPn8gLU5uYZCjU1qsAi3sGN + method: POST + on_build_success: true + on_build_failure: true + on_build_status_changed: false # Uncomment this to debug AppVeyor failures. #on_finish: diff --git a/Runtime/Graphics/CGraphics.hpp b/Runtime/Graphics/CGraphics.hpp index 6c1e42faf..e88c88db3 100644 --- a/Runtime/Graphics/CGraphics.hpp +++ b/Runtime/Graphics/CGraphics.hpp @@ -350,6 +350,47 @@ public: } }; +template +class TriFanToStrip +{ + std::vector& m_vec; + size_t m_start; + size_t m_added = 0; +public: + explicit TriFanToStrip(std::vector& vec) : m_vec(vec), m_start(vec.size()) {} + + void AddVert(const VTX& vert) + { + ++m_added; + if (m_added > 3) + { + const VTX& last = m_vec.back(); + m_vec.reserve(m_vec.size() + 4); + m_vec.push_back(m_vec[m_start]); + m_vec.push_back(m_vec[m_start]); + m_vec.push_back(last); + } + m_vec.push_back(vert); + } + + template + void EmplaceVert(_Args&&... args) + { + ++m_added; + if (m_added > 3) + { + const VTX& last = m_vec.back(); + m_vec.reserve(m_vec.size() + 4); + m_vec.push_back(m_vec[m_start]); + m_vec.push_back(m_vec[m_start]); + m_vec.push_back(last); + } + m_vec.emplace_back(std::forward<_Args>(args)...); + } + + void Draw() const { CGraphics::DrawArray(m_start, m_vec.size() - m_start); } +}; + } #endif // __URDE_CGRAPHICS_HPP__ diff --git a/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp b/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp index 77832c61c..063313cdb 100644 --- a/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp +++ b/Runtime/Graphics/Shaders/CFluidPlaneShader.cpp @@ -177,9 +177,8 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type, }); } -void CFluidPlaneShader::draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale, - const std::vector& lights, const zeus::CColor kColors[4], - const std::vector& verts) +void CFluidPlaneShader::prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale, + const std::vector& lights, const zeus::CColor* kColors) { Uniform& uni = *reinterpret_cast(m_uniBuf->map(sizeof(Uniform))); uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); @@ -193,11 +192,12 @@ void CFluidPlaneShader::draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatr uni.m_lighting.mulColor = kColors[3]; uni.m_lighting.fog.m_rangeScale = indScale; m_uniBuf->unmap(); - - m_vbo->load(verts.data(), verts.size() * sizeof(Vertex)); - CGraphics::SetShaderDataBinding(m_dataBind); - CGraphics::DrawArray(0, verts.size()); +} + +void CFluidPlaneShader::loadVerts(const std::vector& verts) +{ + m_vbo->load(verts.data(), verts.size() * sizeof(Vertex)); } } diff --git a/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp b/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp index f12079b15..742e3b53e 100644 --- a/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp +++ b/Runtime/Graphics/Shaders/CFluidPlaneShader.hpp @@ -115,9 +115,9 @@ public: const std::experimental::optional>& envBumpMap, const std::experimental::optional>& lightmap, bool doubleLightmapBlend, bool additive); - void draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale, - const std::vector& lights, const zeus::CColor kColors[4], - const std::vector& verts); + void prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale, + const std::vector& lights, const zeus::CColor* kColors); + void loadVerts(const std::vector& verts); }; } diff --git a/Runtime/World/CFluidPlaneCPU.cpp b/Runtime/World/CFluidPlaneCPU.cpp index 99b033fb0..a1c0e3a31 100644 --- a/Runtime/World/CFluidPlaneCPU.cpp +++ b/Runtime/World/CFluidPlaneCPU.cpp @@ -886,17 +886,25 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, switch (info.x37_normalMode) { case CFluidPlaneCPURender::NormalMode::None: + { + size_t start = vOut.size(); vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f)); vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f)); vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f)); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f)); + CGraphics::DrawArray(start, 4); break; + } case CFluidPlaneCPURender::NormalMode::NoNormals: + { + size_t start = vOut.size(); vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack); + CGraphics::DrawArray(start, 4); break; + } case CFluidPlaneCPURender::NormalMode::Normals: { int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1; @@ -913,16 +921,18 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, { if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile) { - vOut.emplace_back(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize, - yMax + 0.5f * info.x14_tileSize, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + TriFanToStrip toStrip(vOut); + + toStrip.EmplaceVert(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize, + yMax + 0.5f * info.x14_tileSize, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); float tmp = xMax; for (int v=0 ; v<((curYTile == 1) ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) { - vOut.emplace_back(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); tmp += info.x18_rippleResolution; } @@ -930,8 +940,8 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, for (int v=0 ; v<((xTiles - 1 == curXTile) ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) { - vOut.emplace_back(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + toStrip.EmplaceVert(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); tmp -= info.x18_rippleResolution; } @@ -939,8 +949,8 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, for (int v=0 ; v<((curYTile == yTiles) ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) { - vOut.emplace_back(zeus::CVector3f(tmp, yMax, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); tmp -= info.x18_rippleResolution; } @@ -948,13 +958,15 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, for (int v=0 ; v<((curXTile == 0) ? CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) { - vOut.emplace_back(zeus::CVector3f(xMax, tmp, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + toStrip.EmplaceVert(zeus::CVector3f(xMax, tmp, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); tmp += info.x18_rippleResolution; } - vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), - zeus::CVector3f::skUp, zeus::CColor::skBlack); + toStrip.EmplaceVert(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), + zeus::CVector3f::skUp, zeus::CColor::skBlack); + + toStrip.Draw(); nextXTile = curXTile + 1; xMax += info.x14_tileSize; @@ -966,6 +978,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, (!info.x30_gridFlags || info.x30_gridFlags[xTileStart+nextXTile])) ++nextXTile; + size_t start = vOut.size(); for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v) { vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack); @@ -973,6 +986,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, zeus::CColor::skBlack); xMax += info.x14_tileSize; } + CGraphics::DrawArray(start, vOut.size() - start); ++nextXTile; if (nextXTile == xTiles) @@ -1000,6 +1014,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, { if (flagIs1 || !info.x30_gridFlags) { + size_t start = vOut.size(); vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CVector3f::skUp, zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CVector3f::skUp, @@ -1008,6 +1023,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CVector3f::skUp, zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack); + CGraphics::DrawArray(start, 4); } else { @@ -1030,6 +1046,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, ++tile; } + size_t start = vOut.size(); for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v) { vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp, @@ -1040,6 +1057,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info, zeus::CVector3f::skRight, zeus::CColor::skBlack); xMax += info.x14_tileSize; } + CGraphics::DrawArray(start, vOut.size() - start); } else { @@ -1143,6 +1161,8 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128; m_verts.clear(); + m_shader->prepareDraw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, + setupInfo.lights, setupInfo.kColors); u32 tileY = 0; float curY = aabb.min.y; @@ -1199,8 +1219,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C tileY += CFluidPlaneCPURender::numTilesInHField; } - m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, - setupInfo.lights, setupInfo.kColors, m_verts); + m_shader->loadVerts(m_verts); } void CFluidPlaneCPU::RenderCleanup() const