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
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:

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__

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,
const std::vector<CLight>& lights, const zeus::CColor kColors[4],
const std::vector<Vertex>& verts)
void CFluidPlaneShader::prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor* kColors)
{
Uniform& uni = *reinterpret_cast<Uniform*>(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<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>>& lightmap,
bool doubleLightmapBlend, bool additive);
void draw(const zeus::CMatrix4f texMtxs[6], const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor kColors[4],
const std::vector<Vertex>& verts);
void prepareDraw(const zeus::CMatrix4f* texMtxs, const zeus::CMatrix4f& normMtx, float indScale,
const std::vector<CLight>& lights, const zeus::CColor* kColors);
void loadVerts(const std::vector<Vertex>& verts);
};
}

View File

@ -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<CFluidPlaneShader::Vertex> 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