Implement triangle fan-to-strip stream converter

This commit is contained in:
Jack Andersen 2017-08-10 15:16:58 -10:00
parent 5e10f2e7ad
commit e0efcc0e5c
5 changed files with 91 additions and 25 deletions

View File

@ -61,6 +61,12 @@ notifications:
- provider: Slack - provider: Slack
incoming_webhook: incoming_webhook:
secure: uoO0I0PWyCx0KLjBOG6d17aSVuEEvYztB/UiF8J0LmTb2O735mAdWcuZHTImDFUGZxeI34/qzOB2JKqF+h8dZA5yiprSTkWIookqQjUokAM= 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. # Uncomment this to debug AppVeyor failures.
#on_finish: #on_finish:

View File

@ -350,6 +350,47 @@ public:
} }
}; };
template<class VTX>
class TriFanToStrip
{
std::vector<VTX>& m_vec;
size_t m_start;
size_t m_added = 0;
public:
explicit TriFanToStrip(std::vector<VTX>& 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<class... _Args>
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__ #endif // __URDE_CGRAPHICS_HPP__

View File

@ -177,9 +177,8 @@ CFluidPlaneShader::CFluidPlaneShader(CFluidPlane::EFluidType type,
}); });
} }
void CFluidPlaneShader::draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale, void CFluidPlaneShader::prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor kColors[4], const std::vector<CLight>& lights, const zeus::CColor* kColors)
const std::vector<Vertex>& verts)
{ {
Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform))); Uniform& uni = *reinterpret_cast<Uniform*>(m_uniBuf->map(sizeof(Uniform)));
uni.m_mv = CGraphics::g_GXModelView.toMatrix4f(); 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.mulColor = kColors[3];
uni.m_lighting.fog.m_rangeScale = indScale; uni.m_lighting.fog.m_rangeScale = indScale;
m_uniBuf->unmap(); m_uniBuf->unmap();
m_vbo->load(verts.data(), verts.size() * sizeof(Vertex));
CGraphics::SetShaderDataBinding(m_dataBind); CGraphics::SetShaderDataBinding(m_dataBind);
CGraphics::DrawArray(0, verts.size()); }
void CFluidPlaneShader::loadVerts(const std::vector<Vertex>& verts)
{
m_vbo->load(verts.data(), verts.size() * sizeof(Vertex));
} }
} }

View File

@ -115,9 +115,9 @@ public:
const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap, const std::experimental::optional<TLockedToken<CTexture>>& envBumpMap,
const std::experimental::optional<TLockedToken<CTexture>>& lightmap, const std::experimental::optional<TLockedToken<CTexture>>& lightmap,
bool doubleLightmapBlend, bool additive); bool doubleLightmapBlend, bool additive);
void draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale, void prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor kColors[4], const std::vector<CLight>& lights, const zeus::CColor* kColors);
const std::vector<Vertex>& verts); void loadVerts(const std::vector<Vertex>& verts);
}; };
} }

View File

@ -886,17 +886,25 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
switch (info.x37_normalMode) switch (info.x37_normalMode)
{ {
case CFluidPlaneCPURender::NormalMode::None: case CFluidPlaneCPURender::NormalMode::None:
{
size_t start = vOut.size();
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f)); vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f));
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 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, yMin, 0.f));
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f)); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f));
CGraphics::DrawArray(start, 4);
break; break;
}
case CFluidPlaneCPURender::NormalMode::NoNormals: 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, yMin, 0.f), zeus::CColor::skBlack);
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 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, yMin, 0.f), zeus::CColor::skBlack);
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack); vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack);
CGraphics::DrawArray(start, 4);
break; break;
}
case CFluidPlaneCPURender::NormalMode::Normals: case CFluidPlaneCPURender::NormalMode::Normals:
{ {
int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1; int yTiles = (info.x1_ySubdivs - 3) / CFluidPlaneCPURender::numSubdivisionsInTile + 1;
@ -913,7 +921,9 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
{ {
if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile) if (curYTile == yTiles || curYTile == 1 || curXTile == 0 || xTiles - 1 == curXTile)
{ {
vOut.emplace_back(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize, TriFanToStrip<CFluidPlaneShader::Vertex> toStrip(vOut);
toStrip.EmplaceVert(zeus::CVector3f(xMax + 0.5f * info.x14_tileSize,
yMax + 0.5f * info.x14_tileSize, 0.f), yMax + 0.5f * info.x14_tileSize, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
@ -921,7 +931,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
for (int v=0 ; v<((curYTile == 1) ? for (int v=0 ; v<((curYTile == 1) ?
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f), toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax + info.x14_tileSize, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
tmp += info.x18_rippleResolution; tmp += info.x18_rippleResolution;
} }
@ -930,7 +940,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
for (int v=0 ; v<((xTiles - 1 == curXTile) ? for (int v=0 ; v<((xTiles - 1 == curXTile) ?
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f), toStrip.EmplaceVert(zeus::CVector3f(xMax + info.x14_tileSize, tmp, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
tmp -= info.x18_rippleResolution; tmp -= info.x18_rippleResolution;
} }
@ -939,7 +949,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
for (int v=0 ; v<((curYTile == yTiles) ? for (int v=0 ; v<((curYTile == yTiles) ?
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(tmp, yMax, 0.f), toStrip.EmplaceVert(zeus::CVector3f(tmp, yMax, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
tmp -= info.x18_rippleResolution; tmp -= info.x18_rippleResolution;
} }
@ -948,14 +958,16 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
for (int v=0 ; v<((curXTile == 0) ? for (int v=0 ; v<((curXTile == 0) ?
CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v) CFluidPlaneCPURender::numSubdivisionsInTile : 1) ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(xMax, tmp, 0.f), toStrip.EmplaceVert(zeus::CVector3f(xMax, tmp, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
tmp += info.x18_rippleResolution; tmp += info.x18_rippleResolution;
} }
vOut.emplace_back(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f), toStrip.EmplaceVert(zeus::CVector3f(xMax, yMax + info.x14_tileSize, 0.f),
zeus::CVector3f::skUp, zeus::CColor::skBlack); zeus::CVector3f::skUp, zeus::CColor::skBlack);
toStrip.Draw();
nextXTile = curXTile + 1; nextXTile = curXTile + 1;
xMax += info.x14_tileSize; xMax += info.x14_tileSize;
} }
@ -966,6 +978,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
(!info.x30_gridFlags || info.x30_gridFlags[xTileStart+nextXTile])) (!info.x30_gridFlags || info.x30_gridFlags[xTileStart+nextXTile]))
++nextXTile; ++nextXTile;
size_t start = vOut.size();
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v) for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CColor::skBlack); 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); zeus::CColor::skBlack);
xMax += info.x14_tileSize; xMax += info.x14_tileSize;
} }
CGraphics::DrawArray(start, vOut.size() - start);
++nextXTile; ++nextXTile;
if (nextXTile == xTiles) if (nextXTile == xTiles)
@ -1000,6 +1014,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
{ {
if (flagIs1 || !info.x30_gridFlags) if (flagIs1 || !info.x30_gridFlags)
{ {
size_t start = vOut.size();
vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CVector3f::skUp, vOut.emplace_back(zeus::CVector3f(xMin, yMin, 0.f), zeus::CVector3f::skUp,
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack); zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
vOut.emplace_back(zeus::CVector3f(xMin, yMax, 0.f), zeus::CVector3f::skUp, 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); zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CVector3f::skUp, vOut.emplace_back(zeus::CVector3f(xMax, yMax, 0.f), zeus::CVector3f::skUp,
zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack); zeus::CVector3f::skForward, zeus::CVector3f::skRight, zeus::CColor::skBlack);
CGraphics::DrawArray(start, 4);
} }
else else
{ {
@ -1030,6 +1046,7 @@ static void RenderPatch(const CFluidPlaneCPURender::SPatchInfo& info,
++tile; ++tile;
} }
size_t start = vOut.size();
for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v) for (int v = 0 ; v < nextXTile - curXTile + 1 ; ++v)
{ {
vOut.emplace_back(zeus::CVector3f(xMax, yMin, 0.f), zeus::CVector3f::skUp, 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); zeus::CVector3f::skRight, zeus::CColor::skBlack);
xMax += info.x14_tileSize; xMax += info.x14_tileSize;
} }
CGraphics::DrawArray(start, vOut.size() - start);
} }
else else
{ {
@ -1143,6 +1161,8 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128; u32 patchDimY = (water && water->GetPatchDimensionY()) ? water->GetPatchDimensionY() : 128;
m_verts.clear(); m_verts.clear();
m_shader->prepareDraw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale,
setupInfo.lights, setupInfo.kColors);
u32 tileY = 0; u32 tileY = 0;
float curY = aabb.min.y; float curY = aabb.min.y;
@ -1199,8 +1219,7 @@ void CFluidPlaneCPU::Render(const CStateManager& mgr, float alpha, const zeus::C
tileY += CFluidPlaneCPURender::numTilesInHField; tileY += CFluidPlaneCPURender::numTilesInHField;
} }
m_shader->draw(setupInfo.texMtxs, setupInfo.normMtx, setupInfo.indScale, m_shader->loadVerts(m_verts);
setupInfo.lights, setupInfo.kColors, m_verts);
} }
void CFluidPlaneCPU::RenderCleanup() const void CFluidPlaneCPU::RenderCleanup() const