metaforce/Runtime/Graphics/CLineRenderer.cpp

364 lines
17 KiB
C++
Raw Normal View History

#include "Runtime/Graphics/CLineRenderer.hpp"
#include "Runtime/Graphics/Shaders/CLineRendererShaders.hpp"
#include <logvisor/logvisor.hpp>
2021-04-10 08:42:06 +00:00
namespace metaforce {
logvisor::Module LineRendererLog("metaforce::CLineRenderer");
2018-12-08 05:30:43 +00:00
void CLineRenderer::Initialize() { CLineRendererShaders::Initialize(); }
2018-12-08 05:30:43 +00:00
void CLineRenderer::Shutdown() {
CLineRendererShaders::Shutdown();
2022-02-01 00:06:54 +00:00
// s_vertPoolTex.doDestroy();
// s_vertPoolNoTex.doDestroy();
// s_uniformPool.doDestroy();
}
2022-02-01 00:06:54 +00:00
//hecl::VertexBufferPool<CLineRenderer::SDrawVertTex> CLineRenderer::s_vertPoolTex = {};
//hecl::VertexBufferPool<CLineRenderer::SDrawVertNoTex> CLineRenderer::s_vertPoolNoTex = {};
//hecl::UniformBufferPool<CLineRenderer::SDrawUniform> CLineRenderer::s_uniformPool = {};
2022-02-18 00:38:31 +00:00
CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, const aurora::gfx::TextureHandle& texture,
bool additive, bool zTest, bool zGEqual)
2018-12-08 05:30:43 +00:00
: m_mode(mode), m_maxVerts(maxVerts) {
2021-04-03 16:48:39 +00:00
OPTICK_EVENT();
2018-12-08 05:30:43 +00:00
if (maxVerts < 2) {
LineRendererLog.report(logvisor::Fatal, FMT_STRING("maxVerts < 2, maxVerts = {}"), maxVerts);
2018-12-08 05:30:43 +00:00
return;
}
2019-08-19 01:49:54 +00:00
m_textured = bool(texture);
2018-12-08 05:30:43 +00:00
u32 maxTriVerts = 0;
2018-12-08 05:30:43 +00:00
switch (mode) {
case EPrimitiveMode::Lines:
case EPrimitiveMode::LineStrip:
maxTriVerts = maxVerts * 4;
break;
case EPrimitiveMode::LineLoop:
maxTriVerts = maxVerts * 4 + 4;
break;
}
2022-02-01 00:06:54 +00:00
// if (texture) {
// m_vertBufTex = s_vertPoolTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts);
// } else {
// m_vertBufNoTex = s_vertPoolNoTex.allocateBlock(CGraphics::g_BooFactory, maxTriVerts);
// }
//
// m_uniformBuf = s_uniformPool.allocateBlock(CGraphics::g_BooFactory);
//
// CGraphics::CommitResources([&](boo::IGraphicsDataFactory::Context& ctx) {
// CLineRendererShaders::BuildShaderDataBinding(ctx, *this, texture, additive, zTest, zGEqual);
// return true;
// } BooTrace);
}
2022-02-01 00:06:54 +00:00
//rstl::reserved_vector<CLineRenderer::SDrawVertTex, 1024> CLineRenderer::g_StaticLineVertsTex = {};
//rstl::reserved_vector<CLineRenderer::SDrawVertNoTex, 1024> CLineRenderer::g_StaticLineVertsNoTex = {};
2018-12-08 05:30:43 +00:00
static bool IntersectLines(const zeus::CVector2f& pa1, const zeus::CVector2f& pa2, const zeus::CVector2f& pb1,
const zeus::CVector2f& pb2, zeus::CVector3f& intersect) {
zeus::CVector2f deltaA = pa1 - pa2;
zeus::CVector2f deltaB = pb1 - pb2;
float det = deltaA.cross(deltaB);
if (std::fabs(det) < 0.000001f)
return false;
float c0 = pa1.cross(pa2);
float c1 = pb1.cross(pb2);
intersect = (c0 * (pb1 - pb2) - c1 * (pa1 - pa2)) / det;
return true;
}
2018-12-08 05:30:43 +00:00
void CLineRenderer::Reset() {
m_nextVert = 0;
m_final = false;
2022-02-01 00:06:54 +00:00
// if (m_textured)
// g_StaticLineVertsTex.clear();
// else
// g_StaticLineVertsNoTex.clear();
}
2016-03-04 23:04:53 +00:00
void CLineRenderer::AddVertex(const zeus::CVector3f& position, const zeus::CColor& color, float width,
2018-12-08 05:30:43 +00:00
const zeus::CVector2f& uv) {
2022-02-01 00:06:54 +00:00
if (m_final /*|| !m_shaderBind[0]*/ || m_nextVert >= m_maxVerts)
2018-12-08 05:30:43 +00:00
return;
float adjWidth = width / 480.f;
float w;
zeus::CVector3f projPt = CGraphics::ProjectModelPointToViewportSpace(position, w);
if (m_mode == EPrimitiveMode::LineLoop) {
if (m_nextVert == 0) {
m_firstPos = projPt;
m_firstW = w;
m_secondPos = projPt;
m_firstUV = uv;
m_firstColor = color;
m_firstWidth = adjWidth;
} else if (m_nextVert == 1) {
m_secondPos = projPt;
}
}
if (m_nextVert > 1) {
zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
if (!dva.canBeNormalized())
dva = {0.f, 1.f};
dva = dva.normalized().perpendicularVector() * m_lastWidth;
dva.x() /= CGraphics::g_ProjAspect;
zeus::CVector2f dvb = (projPt - m_lastPos).toVec2f();
if (!dvb.canBeNormalized())
dvb = {0.f, 1.f};
dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
dvb.x() /= CGraphics::g_ProjAspect;
if (m_textured) {
if (m_mode == EPrimitiveMode::Lines) {
if (m_nextVert & 1) {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back());
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back());
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
}
} else {
zeus::CVector3f intersect1;
bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, m_lastPos.toVec2f() + dvb,
projPt.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good1 = false;
zeus::CVector3f intersect2;
bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, m_lastPos.toVec2f() - dvb,
projPt.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good2 = false;
if (good1 && good2) {
intersect1.z() = float(m_lastPos.z());
intersect2.z() = float(m_lastPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV});
}
2018-12-08 05:30:43 +00:00
}
} else {
if (m_mode == EPrimitiveMode::Lines) {
if (m_nextVert & 1) {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back());
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back());
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor});
}
2018-12-08 05:30:43 +00:00
} else {
zeus::CVector3f intersect1;
bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, m_lastPos.toVec2f() + dvb,
projPt.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good1 = false;
zeus::CVector3f intersect2;
bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, m_lastPos.toVec2f() - dvb,
projPt.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good2 = false;
if (good1 && good2) {
intersect1.z() = float(m_lastPos.z());
intersect2.z() = float(m_lastPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
}
}
}
} else if (m_nextVert == 1) {
zeus::CVector2f dv = (projPt - m_lastPos).toVec2f();
if (!dv.canBeNormalized())
dv = {0.f, 1.f};
dv = dv.normalized().perpendicularVector() * m_lastWidth;
dv.x() /= CGraphics::g_ProjAspect;
if (m_textured) {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor});
}
2018-12-08 05:30:43 +00:00
}
m_lastPos2 = m_lastPos;
m_lastPos = projPt;
m_lastW = w;
m_lastUV = uv;
m_lastColor = color;
m_lastWidth = adjWidth;
++m_nextVert;
}
2019-03-03 06:19:42 +00:00
void CLineRenderer::Render(bool alphaWrite, const zeus::CColor& moduColor) {
2019-07-21 08:42:52 +00:00
SCOPED_GRAPHICS_DEBUG_GROUP("CLineRenderer::Render", zeus::skGrey);
2018-12-08 05:30:43 +00:00
if (!m_final && m_nextVert > 1) {
if (m_mode == EPrimitiveMode::LineLoop) {
{
2016-03-04 23:04:53 +00:00
zeus::CVector2f dva = (m_lastPos - m_lastPos2).toVec2f();
if (!dva.canBeNormalized())
2018-12-08 05:30:43 +00:00
dva = {0.f, 1.f};
dva = dva.normalized().perpendicularVector() * m_lastWidth;
2018-12-08 01:49:15 +00:00
dva.x() /= CGraphics::g_ProjAspect;
2018-12-08 05:30:43 +00:00
zeus::CVector2f dvb = (m_firstPos - m_lastPos).toVec2f();
if (!dvb.canBeNormalized())
2018-12-08 05:30:43 +00:00
dvb = {0.f, 1.f};
dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
2018-12-08 01:49:15 +00:00
dvb.x() /= CGraphics::g_ProjAspect;
2018-12-08 05:30:43 +00:00
zeus::CVector3f intersect1;
bool good1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva, m_lastPos.toVec2f() + dvb,
m_firstPos.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good1 = false;
zeus::CVector3f intersect2;
bool good2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva, m_lastPos.toVec2f() - dvb,
m_firstPos.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_lastPos.toVec2f()).magnitude() > m_lastWidth * 2.f)
good2 = false;
if (m_textured) {
if (good1 && good2) {
intersect1.z() = float(m_lastPos.z());
intersect2.z() = float(m_lastPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
}
} else {
if (good1 && good2) {
intersect1.z() = float(m_lastPos.z());
intersect2.z() = float(m_lastPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dvb, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dvb, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
}
}
2018-12-08 05:30:43 +00:00
}
{
zeus::CVector2f dva = (m_firstPos - m_lastPos).toVec2f();
if (!dva.canBeNormalized())
dva = {0.f, 1.f};
dva = dva.normalized().perpendicularVector() * m_firstWidth;
dva.x() /= CGraphics::g_ProjAspect;
2018-12-08 05:30:43 +00:00
zeus::CVector2f dvb = (m_secondPos - m_firstPos).toVec2f();
if (!dvb.canBeNormalized())
dvb = {0.f, 1.f};
dvb = dvb.normalized().perpendicularVector() * m_firstWidth;
dvb.x() /= CGraphics::g_ProjAspect;
2018-12-08 05:30:43 +00:00
zeus::CVector3f intersect1;
bool good1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva, m_firstPos.toVec2f() + dvb,
m_secondPos.toVec2f() + dvb, intersect1);
if ((intersect1.toVec2f() - m_firstPos.toVec2f()).magnitude() > m_firstWidth * 2.f)
good1 = false;
zeus::CVector3f intersect2;
bool good2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva, m_firstPos.toVec2f() - dvb,
m_secondPos.toVec2f() - dvb, intersect2);
if ((intersect2.toVec2f() - m_firstPos.toVec2f()).magnitude() > m_firstWidth * 2.f)
good2 = false;
if (m_textured) {
if (good1 && good2) {
intersect1.z() = float(m_firstPos.z());
intersect2.z() = float(m_firstPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor, m_lastUV});
2018-12-08 05:30:43 +00:00
}
} else {
if (good1 && good2) {
intersect1.z() = float(m_firstPos.z());
intersect2.z() = float(m_firstPos.z());
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect1, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(intersect2, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dva, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos + dvb, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_firstPos - dvb, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
}
}
2018-12-08 05:30:43 +00:00
}
} else {
zeus::CVector2f dv = (m_lastPos - m_lastPos2).toVec2f();
if (!dv.canBeNormalized())
dv = {0.f, 1.f};
dv = dv.normalized().perpendicularVector() * m_lastWidth;
dv.x() /= CGraphics::g_ProjAspect;
if (m_textured) {
if (m_mode == EPrimitiveMode::Lines && (m_nextVert & 1)) {
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor, m_lastUV});
// g_StaticLineVertsTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor, m_lastUV});
}
2018-12-08 05:30:43 +00:00
} else {
if (m_mode == EPrimitiveMode::Lines && (m_nextVert & 1)) {
} else {
2022-02-01 00:06:54 +00:00
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos + dv, m_lastW), m_lastColor});
// g_StaticLineVertsNoTex.push_back({zeus::CVector4f::ToClip(m_lastPos - dv, m_lastW), m_lastColor});
2018-12-08 05:30:43 +00:00
}
}
}
2018-12-08 05:30:43 +00:00
m_final = true;
}
2022-02-01 00:06:54 +00:00
// m_uniformBuf.access() = SDrawUniform{moduColor, CGraphics::g_Fog};
// if (m_textured) {
// if (!g_StaticLineVertsTex.empty()) {
// memmove(m_vertBufTex.access(), g_StaticLineVertsTex.data(), sizeof(SDrawVertTex) * g_StaticLineVertsTex.size());
// CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]);
// CGraphics::DrawArray(0, g_StaticLineVertsTex.size());
// }
// } else {
// if (!g_StaticLineVertsNoTex.empty()) {
// memmove(m_vertBufNoTex.access(), g_StaticLineVertsNoTex.data(),
// sizeof(SDrawVertNoTex) * g_StaticLineVertsNoTex.size());
// CGraphics::SetShaderDataBinding(m_shaderBind[alphaWrite]);
// CGraphics::DrawArray(0, g_StaticLineVertsNoTex.size());
// }
// }
}
2021-04-10 08:42:06 +00:00
} // namespace metaforce