mirror of https://github.com/AxioDL/metaforce.git
Implement line renderer (OpenGL only for now)
This commit is contained in:
parent
cfee7b61bb
commit
365f6ac9e7
|
@ -54,6 +54,7 @@ target_link_libraries(urde
|
||||||
RuntimeCommonCharacter
|
RuntimeCommonCharacter
|
||||||
RuntimeCommonInput
|
RuntimeCommonInput
|
||||||
RuntimeCommonParticle
|
RuntimeCommonParticle
|
||||||
|
RuntimeCommonGraphics
|
||||||
RuntimeCommon
|
RuntimeCommon
|
||||||
DNAMP3 DNAMP2 DNAMP1
|
DNAMP3 DNAMP2 DNAMP1
|
||||||
DNACommon Specter SpecterFonts freetype ${DATA_SPEC_LIBS}
|
DNACommon Specter SpecterFonts freetype ${DATA_SPEC_LIBS}
|
||||||
|
|
|
@ -10,6 +10,7 @@
|
||||||
#include "Runtime/Particle/CElectricDescription.hpp"
|
#include "Runtime/Particle/CElectricDescription.hpp"
|
||||||
#include "Runtime/Particle/CSwooshDescription.hpp"
|
#include "Runtime/Particle/CSwooshDescription.hpp"
|
||||||
#include "Runtime/CModel.hpp"
|
#include "Runtime/CModel.hpp"
|
||||||
|
#include "Runtime/CGraphics.hpp"
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
|
|
||||||
using YAMLNode = Athena::io::YAMLNode;
|
using YAMLNode = Athena::io::YAMLNode;
|
||||||
|
@ -17,6 +18,49 @@ using YAMLNode = Athena::io::YAMLNode;
|
||||||
namespace URDE
|
namespace URDE
|
||||||
{
|
{
|
||||||
|
|
||||||
|
void ViewManager::BuildTestPART(pshag::IObjectStore& objStore)
|
||||||
|
{
|
||||||
|
m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x1E348530});
|
||||||
|
m_partGen.reset(new pshag::CElementGen(m_partGenDesc,
|
||||||
|
pshag::CElementGen::EModelOrientationType::Normal,
|
||||||
|
pshag::CElementGen::EOptionalSystemFlags::None));
|
||||||
|
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
|
||||||
|
m_lineRenderer.reset(new pshag::CLineRenderer(pshag::CLineRenderer::EPrimitiveMode::LineStrip, 4, nullptr, true));
|
||||||
|
|
||||||
|
m_rootView->accessContentViews().push_back(m_particleView.get());
|
||||||
|
m_rootView->updateSize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewManager::ParticleView::resized(const boo::SWindowRect& root, const boo::SWindowRect& sub)
|
||||||
|
{
|
||||||
|
Specter::View::resized(root, sub);
|
||||||
|
pshag::CGraphics::SetViewportResolution({sub.size[0], sub.size[1]});
|
||||||
|
}
|
||||||
|
|
||||||
|
void ViewManager::ParticleView::draw(boo::IGraphicsCommandQueue *gfxQ)
|
||||||
|
{
|
||||||
|
if (m_vm.m_partGen)
|
||||||
|
{
|
||||||
|
m_vm.m_partGen->Update(1.0 / 60.0);
|
||||||
|
pshag::CGraphics::SetModelMatrix(Zeus::CTransform::Identity());
|
||||||
|
pshag::CGraphics::SetViewPointMatrix(Zeus::CTransform::Identity() + Zeus::CVector3f(0.f, -10.f, 0.f));
|
||||||
|
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
||||||
|
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
||||||
|
pshag::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
||||||
|
//gfxQ->clearTarget(false, true);
|
||||||
|
m_vm.m_partGen->Render();
|
||||||
|
|
||||||
|
/*
|
||||||
|
m_vm.m_lineRenderer->Reset();
|
||||||
|
m_vm.m_lineRenderer->AddVertex({-0.5f, 0.f, -0.5f}, Zeus::CColor::skBlue, 1.f);
|
||||||
|
m_vm.m_lineRenderer->AddVertex({-0.5f, 0.f, 0.5f}, Zeus::CColor::skBlue, 1.f);
|
||||||
|
m_vm.m_lineRenderer->AddVertex({0.5f, 10.f, 0.5f}, Zeus::CColor::skRed, 3.f);
|
||||||
|
m_vm.m_lineRenderer->AddVertex({0.5f, 0.f, -0.5f}, Zeus::CColor::skBlue, 1.f);
|
||||||
|
m_vm.m_lineRenderer->Render();
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Specter::View* ViewManager::BuildSpaceViews()
|
Specter::View* ViewManager::BuildSpaceViews()
|
||||||
{
|
{
|
||||||
m_rootSpaceView = m_rootSpace->buildSpaceView(m_viewResources);
|
m_rootSpaceView = m_rootSpace->buildSpaceView(m_viewResources);
|
||||||
|
@ -80,16 +124,6 @@ void ViewManager::DismissSplash()
|
||||||
m_splash->close();
|
m_splash->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
void ViewManager::BuildTestPART(pshag::IObjectStore& objStore)
|
|
||||||
{
|
|
||||||
m_partGenDesc = objStore.GetObj({HECL::FOURCC('PART'), 0x273375E3});
|
|
||||||
m_partGen.reset(new pshag::CElementGen(m_partGenDesc,
|
|
||||||
pshag::CElementGen::EModelOrientationType::Normal,
|
|
||||||
pshag::CElementGen::EOptionalSystemFlags::None));
|
|
||||||
m_particleView.reset(new ParticleView(*this, m_viewResources, *m_rootView));
|
|
||||||
m_rootView->accessContentViews().push_back(m_particleView.get());
|
|
||||||
}
|
|
||||||
|
|
||||||
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
ViewManager::ViewManager(HECL::Runtime::FileStoreManager& fileMgr, HECL::CVarManager& cvarMgr)
|
||||||
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
|
: m_fileStoreManager(fileMgr), m_cvarManager(cvarMgr), m_projManager(*this),
|
||||||
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish()),
|
m_fontCache(fileMgr), m_translator(URDE::SystemLocaleOrEnglish()),
|
||||||
|
@ -185,6 +219,7 @@ void ViewManager::init(boo::IApplication* app)
|
||||||
|
|
||||||
pshag::CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue());
|
pshag::CGraphics::InitializeBoo(gf, m_mainWindow->getCommandQueue());
|
||||||
pshag::CElementGen::Initialize();
|
pshag::CElementGen::Initialize();
|
||||||
|
pshag::CLineRenderer::Initialize();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ViewManager::proc()
|
bool ViewManager::proc()
|
||||||
|
@ -236,6 +271,7 @@ bool ViewManager::proc()
|
||||||
void ViewManager::stop()
|
void ViewManager::stop()
|
||||||
{
|
{
|
||||||
pshag::CElementGen::Shutdown();
|
pshag::CElementGen::Shutdown();
|
||||||
|
pshag::CLineRenderer::Shutdown();
|
||||||
m_mainWindow->getCommandQueue()->stopRenderer();
|
m_mainWindow->getCommandQueue()->stopRenderer();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -6,6 +6,7 @@
|
||||||
#include "Space.hpp"
|
#include "Space.hpp"
|
||||||
|
|
||||||
#include "Runtime/Particle/CElementGen.hpp"
|
#include "Runtime/Particle/CElementGen.hpp"
|
||||||
|
#include "Runtime/Graphics/CLineRenderer.hpp"
|
||||||
|
|
||||||
namespace URDE
|
namespace URDE
|
||||||
{
|
{
|
||||||
|
@ -39,24 +40,13 @@ class ViewManager : public Specter::IViewManager
|
||||||
public:
|
public:
|
||||||
ParticleView(ViewManager& vm, Specter::ViewResources& res, Specter::View& parent)
|
ParticleView(ViewManager& vm, Specter::ViewResources& res, Specter::View& parent)
|
||||||
: View(res, parent), m_vm(vm) {}
|
: View(res, parent), m_vm(vm) {}
|
||||||
void draw(boo::IGraphicsCommandQueue* gfxQ)
|
void resized(const boo::SWindowRect& root, const boo::SWindowRect& sub);
|
||||||
{
|
void draw(boo::IGraphicsCommandQueue* gfxQ);
|
||||||
if (m_vm.m_partGen)
|
|
||||||
{
|
|
||||||
m_vm.m_partGen->Update(1.0 / 60.0);
|
|
||||||
pshag::CGraphics::SetModelMatrix(Zeus::CTransform::Identity());
|
|
||||||
pshag::CGraphics::SetViewPointMatrix(Zeus::CTransform::Identity() + Zeus::CVector3f(0.f, -10.f, 0.f));
|
|
||||||
boo::SWindowRect windowRect = m_vm.m_mainWindow->getWindowFrame();
|
|
||||||
float aspect = windowRect.size[0] / float(windowRect.size[1]);
|
|
||||||
pshag::CGraphics::SetPerspective(55.0, aspect, 0.001f, 1000.f);
|
|
||||||
//gfxQ->clearTarget(false, true);
|
|
||||||
m_vm.m_partGen->Render();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
std::unique_ptr<ParticleView> m_particleView;
|
std::unique_ptr<ParticleView> m_particleView;
|
||||||
pshag::TLockedToken<pshag::CGenDescription> m_partGenDesc;
|
pshag::TLockedToken<pshag::CGenDescription> m_partGenDesc;
|
||||||
std::unique_ptr<pshag::CElementGen> m_partGen;
|
std::unique_ptr<pshag::CElementGen> m_partGen;
|
||||||
|
std::unique_ptr<pshag::CLineRenderer> m_lineRenderer;
|
||||||
|
|
||||||
HECL::SystemString m_recentProjectsPath;
|
HECL::SystemString m_recentProjectsPath;
|
||||||
std::vector<HECL::SystemString> m_recentProjects;
|
std::vector<HECL::SystemString> m_recentProjects;
|
||||||
|
|
|
@ -8,6 +8,7 @@ namespace pshag
|
||||||
{
|
{
|
||||||
|
|
||||||
CGraphics::CProjectionState CGraphics::g_Proj;
|
CGraphics::CProjectionState CGraphics::g_Proj;
|
||||||
|
float CGraphics::g_ProjAspect = 1.f;
|
||||||
u32 CGraphics::g_NumLightsActive = 0;
|
u32 CGraphics::g_NumLightsActive = 0;
|
||||||
ERglLight CGraphics::g_LightActive = ERglLight::None;
|
ERglLight CGraphics::g_LightActive = ERglLight::None;
|
||||||
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
|
ERglLight CGraphics::g_LightsWereOn = ERglLight::None;
|
||||||
|
@ -119,6 +120,8 @@ void CGraphics::SetProjectionState(const CGraphics::CProjectionState& proj)
|
||||||
|
|
||||||
void CGraphics::SetPerspective(float fovy, float aspect, float near, float far)
|
void CGraphics::SetPerspective(float fovy, float aspect, float near, float far)
|
||||||
{
|
{
|
||||||
|
g_ProjAspect = aspect;
|
||||||
|
|
||||||
float tfov = tanf(fovy * 0.5f * M_PI / 180.f);
|
float tfov = tanf(fovy * 0.5f * M_PI / 180.f);
|
||||||
g_Proj.x0_persp = true;
|
g_Proj.x0_persp = true;
|
||||||
g_Proj.x14_near = near;
|
g_Proj.x14_near = near;
|
||||||
|
@ -151,11 +154,11 @@ Zeus::CVector2i CGraphics::ProjectPoint(const Zeus::CVector3f& point)
|
||||||
SClipScreenRect CGraphics::ClipScreenRectFromMS(const Zeus::CVector3f& p1,
|
SClipScreenRect CGraphics::ClipScreenRectFromMS(const Zeus::CVector3f& p1,
|
||||||
const Zeus::CVector3f& p2)
|
const Zeus::CVector3f& p2)
|
||||||
{
|
{
|
||||||
Zeus::CVector3f xfExt = (g_GXModelMatrix * p2) - g_ViewMatrix.m_origin;
|
Zeus::CVector3f xf2 = (g_GXModelMatrix * p2) - g_ViewMatrix.m_origin;
|
||||||
xfExt = g_ViewMatrix.transposeRotate(xfExt);
|
xf2 = g_ViewMatrix.transposeRotate(xf2);
|
||||||
Zeus::CVector3f xfPos = (g_GXModelMatrix * p1) - g_ViewMatrix.m_origin;
|
Zeus::CVector3f xf1 = (g_GXModelMatrix * p1) - g_ViewMatrix.m_origin;
|
||||||
xfPos = g_ViewMatrix.transposeRotate(xfPos);
|
xf1 = g_ViewMatrix.transposeRotate(xf1);
|
||||||
return ClipScreenRectFromVS(xfPos, xfExt);
|
return ClipScreenRectFromVS(xf1, xf2);
|
||||||
}
|
}
|
||||||
|
|
||||||
SClipScreenRect CGraphics::ClipScreenRectFromVS(const Zeus::CVector3f& p1,
|
SClipScreenRect CGraphics::ClipScreenRectFromVS(const Zeus::CVector3f& p1,
|
||||||
|
@ -210,6 +213,19 @@ SClipScreenRect CGraphics::ClipScreenRectFromVS(const Zeus::CVector3f& p1,
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Zeus::CVector3f CGraphics::ProjectModelPointToViewportSpace(const Zeus::CVector3f& point)
|
||||||
|
{
|
||||||
|
CProjectionState& pst = g_Proj;
|
||||||
|
Zeus::CVector3f pt = g_GXModelView * point;
|
||||||
|
return GetPerspectiveProjectionMatrix().multiplyOneOverW(pt);
|
||||||
|
}
|
||||||
|
|
||||||
|
void CGraphics::SetViewportResolution(const Zeus::CVector2i& res)
|
||||||
|
{
|
||||||
|
g_ViewportResolution = res;
|
||||||
|
g_ViewportResolutionHalf = {res.x / 2, res.y / 2};
|
||||||
|
}
|
||||||
|
|
||||||
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
|
boo::IGraphicsDataFactory* CGraphics::g_BooFactory = nullptr;
|
||||||
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
|
boo::IGraphicsCommandQueue* CGraphics::g_BooMainCommandQueue = nullptr;
|
||||||
boo::ITextureR* CGraphics::g_SpareTexture = nullptr;
|
boo::ITextureR* CGraphics::g_SpareTexture = nullptr;
|
||||||
|
|
|
@ -148,6 +148,7 @@ public:
|
||||||
float x18_far;
|
float x18_far;
|
||||||
};
|
};
|
||||||
static CProjectionState g_Proj;
|
static CProjectionState g_Proj;
|
||||||
|
static float g_ProjAspect;
|
||||||
static u32 g_NumLightsActive;
|
static u32 g_NumLightsActive;
|
||||||
static ERglLight g_LightActive;
|
static ERglLight g_LightActive;
|
||||||
static ERglLight g_LightsWereOn;
|
static ERglLight g_LightsWereOn;
|
||||||
|
@ -180,6 +181,8 @@ public:
|
||||||
static Zeus::CVector2i ProjectPoint(const Zeus::CVector3f& point);
|
static Zeus::CVector2i ProjectPoint(const Zeus::CVector3f& point);
|
||||||
static SClipScreenRect ClipScreenRectFromMS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
|
static SClipScreenRect ClipScreenRectFromMS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
|
||||||
static SClipScreenRect ClipScreenRectFromVS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
|
static SClipScreenRect ClipScreenRectFromVS(const Zeus::CVector3f& p1, const Zeus::CVector3f& p2);
|
||||||
|
static Zeus::CVector3f ProjectModelPointToViewportSpace(const Zeus::CVector3f& point);
|
||||||
|
static void SetViewportResolution(const Zeus::CVector2i& res);
|
||||||
|
|
||||||
static boo::IGraphicsDataFactory* g_BooFactory;
|
static boo::IGraphicsDataFactory* g_BooFactory;
|
||||||
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
|
static boo::IGraphicsCommandQueue* g_BooMainCommandQueue;
|
||||||
|
@ -208,6 +211,11 @@ public:
|
||||||
g_BooMainCommandQueue->setDrawPrimitive(prim);
|
g_BooMainCommandQueue->setDrawPrimitive(prim);
|
||||||
g_BooMainCommandQueue->drawInstances(start, count, instCount);
|
g_BooMainCommandQueue->drawInstances(start, count, instCount);
|
||||||
}
|
}
|
||||||
|
static void DrawArray(boo::Primitive prim, size_t start, size_t count)
|
||||||
|
{
|
||||||
|
g_BooMainCommandQueue->setDrawPrimitive(prim);
|
||||||
|
g_BooMainCommandQueue->draw(start, count);
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,398 @@
|
||||||
|
#include "CLineRenderer.hpp"
|
||||||
|
#include "CLineRendererShaders.hpp"
|
||||||
|
|
||||||
|
namespace pshag
|
||||||
|
{
|
||||||
|
|
||||||
|
boo::IShaderPipeline* CLineRendererShaders::m_texAlpha = nullptr;
|
||||||
|
boo::IShaderPipeline* CLineRendererShaders::m_texAdditive = nullptr;
|
||||||
|
|
||||||
|
boo::IShaderPipeline* CLineRendererShaders::m_noTexAlpha = nullptr;
|
||||||
|
boo::IShaderPipeline* CLineRendererShaders::m_noTexAdditive = nullptr;
|
||||||
|
|
||||||
|
std::unique_ptr<CLineRendererShaders::IDataBindingFactory> CLineRendererShaders::m_bindFactory;
|
||||||
|
boo::GraphicsDataToken CLineRendererShaders::m_gfxToken;
|
||||||
|
|
||||||
|
void CLineRendererShaders::Initialize()
|
||||||
|
{
|
||||||
|
if (!CGraphics::g_BooFactory)
|
||||||
|
return;
|
||||||
|
|
||||||
|
switch (CGraphics::g_BooFactory->platform())
|
||||||
|
{
|
||||||
|
case boo::IGraphicsDataFactory::Platform::OGL:
|
||||||
|
m_bindFactory.reset(Initialize(*static_cast<boo::GLDataFactory*>(CGraphics::g_BooFactory)));
|
||||||
|
break;
|
||||||
|
#if _WIN32
|
||||||
|
case boo::IGraphicsDataFactory::Platform::D3D11:
|
||||||
|
case boo::IGraphicsDataFactory::Platform::D3D12:
|
||||||
|
m_bindFactory.reset(Initialize(*static_cast<boo::ID3DDataFactory*>(CGraphics::g_BooFactory)));
|
||||||
|
break;
|
||||||
|
#elif BOO_HAS_METAL
|
||||||
|
case boo::IGraphicsDataFactory::Platform::Metal:
|
||||||
|
m_bindFactory.reset(Initialize(*static_cast<boo::MetalDataFactory*>(CGraphics::g_BooFactory)));
|
||||||
|
break;
|
||||||
|
#endif
|
||||||
|
default: break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_gfxToken = CGraphics::CommitResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRenderer::Initialize()
|
||||||
|
{
|
||||||
|
CLineRendererShaders::Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRendererShaders::Shutdown()
|
||||||
|
{
|
||||||
|
m_gfxToken.doDestroy();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRenderer::Shutdown()
|
||||||
|
{
|
||||||
|
CLineRendererShaders::Shutdown();
|
||||||
|
}
|
||||||
|
|
||||||
|
struct SDrawVertTex
|
||||||
|
{
|
||||||
|
Zeus::CVector4f pos;
|
||||||
|
Zeus::CColor color;
|
||||||
|
Zeus::CVector2f uv;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SDrawVertNoTex
|
||||||
|
{
|
||||||
|
Zeus::CVector4f pos;
|
||||||
|
Zeus::CColor color;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct SDrawUniform
|
||||||
|
{
|
||||||
|
Zeus::CColor moduColor;
|
||||||
|
};
|
||||||
|
|
||||||
|
void CLineRendererShaders::BuildShaderDataBinding(CLineRenderer& renderer,
|
||||||
|
boo::ITexture* texture, bool additive)
|
||||||
|
{
|
||||||
|
boo::IShaderPipeline* pipeline = nullptr;
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
if (additive)
|
||||||
|
pipeline = m_texAdditive;
|
||||||
|
else
|
||||||
|
pipeline = m_texAlpha;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (additive)
|
||||||
|
pipeline = m_noTexAdditive;
|
||||||
|
else
|
||||||
|
pipeline = m_noTexAlpha;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_bindFactory->BuildShaderDataBinding(renderer, pipeline, texture);
|
||||||
|
}
|
||||||
|
|
||||||
|
CLineRenderer::CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive)
|
||||||
|
: m_mode(mode), m_maxVerts(maxVerts)
|
||||||
|
{
|
||||||
|
if (maxVerts < 2)
|
||||||
|
return;
|
||||||
|
m_textured = texture != nullptr;
|
||||||
|
|
||||||
|
u32 maxTriVerts;
|
||||||
|
switch (mode)
|
||||||
|
{
|
||||||
|
case EPrimitiveMode::Lines:
|
||||||
|
maxTriVerts = maxVerts * 3;
|
||||||
|
break;
|
||||||
|
case EPrimitiveMode::LineStrip:
|
||||||
|
maxTriVerts = maxVerts * 2;
|
||||||
|
break;
|
||||||
|
case EPrimitiveMode::LineLoop:
|
||||||
|
maxTriVerts = maxVerts * 2 + 2;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
m_vertBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Vertex,
|
||||||
|
texture ? sizeof(SDrawVertTex) : sizeof(SDrawVertNoTex),
|
||||||
|
maxTriVerts);
|
||||||
|
m_uniformBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Uniform, sizeof(SDrawUniform), 1);
|
||||||
|
CLineRendererShaders::BuildShaderDataBinding(*this, texture, additive);
|
||||||
|
m_gfxToken = CGraphics::CommitResources();
|
||||||
|
}
|
||||||
|
|
||||||
|
static rstl::reserved_vector<SDrawVertTex, 256> g_StaticLineVertsTex;
|
||||||
|
static rstl::reserved_vector<SDrawVertNoTex, 256> g_StaticLineVertsNoTex;
|
||||||
|
|
||||||
|
static Zeus::CVector2f IntersectLines(const Zeus::CVector2f& pa1, const Zeus::CVector2f& pa2,
|
||||||
|
const Zeus::CVector2f& pb1, const Zeus::CVector2f& pb2)
|
||||||
|
{
|
||||||
|
Zeus::CVector2f pa1mpa2 = pa1 - pa2;
|
||||||
|
Zeus::CVector2f pb1mpb2 = pb1 - pb2;
|
||||||
|
float denom = pa1mpa2.x * pb1mpb2.y - pa1mpa2.y * pb1mpb2.x;
|
||||||
|
float numt1 = pa1.x * pa2.y - pa1.y * pa2.x;
|
||||||
|
float numt2 = pb1.x * pb2.y - pb1.y * pb2.x;
|
||||||
|
return {(numt1 * pb1mpb2.x - pa1mpa2.x * numt2) / denom,
|
||||||
|
(numt1 * pb1mpb2.y - pa1mpa2.y * numt2) / denom};
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRenderer::Reset()
|
||||||
|
{
|
||||||
|
m_nextVert = 0;
|
||||||
|
m_final = false;
|
||||||
|
if (m_textured)
|
||||||
|
g_StaticLineVertsTex.clear();
|
||||||
|
else
|
||||||
|
g_StaticLineVertsNoTex.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRenderer::AddVertex(const Zeus::CVector3f& position, const Zeus::CColor& color, float width,
|
||||||
|
const Zeus::CVector2f& uv)
|
||||||
|
{
|
||||||
|
if (!m_shaderBind || m_nextVert >= m_maxVerts)
|
||||||
|
return;
|
||||||
|
|
||||||
|
float adjWidth = width / 480.f;
|
||||||
|
Zeus::CVector3f projPt = CGraphics::ProjectModelPointToViewportSpace(position);
|
||||||
|
|
||||||
|
if (m_mode == EPrimitiveMode::LineLoop)
|
||||||
|
{
|
||||||
|
if (m_nextVert == 0)
|
||||||
|
{
|
||||||
|
m_firstPos = projPt;
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back());
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos + dvb, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back(g_StaticLineVertsTex.back());
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos - dvb, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos + dva, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos - dva, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||||
|
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb);
|
||||||
|
intersect1.z = m_lastPos.z;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||||
|
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb);
|
||||||
|
intersect2.z = m_lastPos.z;
|
||||||
|
|
||||||
|
g_StaticLineVertsTex.push_back({intersect1, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back({intersect2, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_mode == EPrimitiveMode::Lines)
|
||||||
|
{
|
||||||
|
if (m_nextVert & 1)
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back());
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos + dvb, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back(g_StaticLineVertsNoTex.back());
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos - dvb, m_lastColor});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos + dva, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos - dva, m_lastColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||||
|
m_lastPos.toVec2f() + dvb, projPt.toVec2f() + dvb);
|
||||||
|
intersect1.z = m_lastPos.z;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||||
|
m_lastPos.toVec2f() - dvb, projPt.toVec2f() - dvb);
|
||||||
|
intersect2.z = m_lastPos.z;
|
||||||
|
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect1, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect2, m_lastColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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)
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos + dv, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos - dv, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos + dv, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos - dv, m_lastColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_lastPos2 = m_lastPos;
|
||||||
|
m_lastPos = projPt;
|
||||||
|
m_lastUV = uv;
|
||||||
|
m_lastColor = color;
|
||||||
|
m_lastWidth = adjWidth;
|
||||||
|
++m_nextVert;
|
||||||
|
}
|
||||||
|
|
||||||
|
void CLineRenderer::Render(const Zeus::CColor& moduColor)
|
||||||
|
{
|
||||||
|
if (!m_final && m_nextVert > 1)
|
||||||
|
{
|
||||||
|
if (m_mode == EPrimitiveMode::LineLoop)
|
||||||
|
{
|
||||||
|
{
|
||||||
|
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 = (m_firstPos - m_lastPos).toVec2f();
|
||||||
|
if (!dvb.canBeNormalized())
|
||||||
|
dvb = {0.f, 1.f};
|
||||||
|
dvb = dvb.normalized().perpendicularVector() * m_lastWidth;
|
||||||
|
dvb.x /= CGraphics::g_ProjAspect;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos2.toVec2f() + dva, m_lastPos.toVec2f() + dva,
|
||||||
|
m_lastPos.toVec2f() + dvb, m_firstPos.toVec2f() + dvb);
|
||||||
|
intersect1.z = m_lastPos.z;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos2.toVec2f() - dva, m_lastPos.toVec2f() - dva,
|
||||||
|
m_lastPos.toVec2f() - dvb, m_firstPos.toVec2f() - dvb);
|
||||||
|
intersect2.z = m_lastPos.z;
|
||||||
|
|
||||||
|
if (m_textured)
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back({intersect1, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back({intersect2, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect1, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect2, m_lastColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
|
||||||
|
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;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect1 = IntersectLines(m_lastPos.toVec2f() + dva, m_firstPos.toVec2f() + dva,
|
||||||
|
m_firstPos.toVec2f() + dvb, m_secondPos.toVec2f() + dvb);
|
||||||
|
intersect1.z = m_firstPos.z;
|
||||||
|
|
||||||
|
Zeus::CVector3f intersect2 = IntersectLines(m_lastPos.toVec2f() - dva, m_firstPos.toVec2f() - dva,
|
||||||
|
m_firstPos.toVec2f() - dvb, m_secondPos.toVec2f() - dvb);
|
||||||
|
intersect2.z = m_firstPos.z;
|
||||||
|
|
||||||
|
if (m_textured)
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back({intersect1, m_firstColor, m_firstUV});
|
||||||
|
g_StaticLineVertsTex.push_back({intersect2, m_firstColor, m_firstUV});
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect1, m_firstColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({intersect2, m_firstColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
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
|
||||||
|
{
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos + dv, m_lastColor, m_lastUV});
|
||||||
|
g_StaticLineVertsTex.push_back({m_lastPos - dv, m_lastColor, m_lastUV});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (m_mode == EPrimitiveMode::Lines && (m_nextVert & 1))
|
||||||
|
{}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos + dv, m_lastColor});
|
||||||
|
g_StaticLineVertsNoTex.push_back({m_lastPos - dv, m_lastColor});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
m_final = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDrawUniform uniformData = {moduColor};
|
||||||
|
m_uniformBuf->load(&uniformData, sizeof(SDrawUniform));
|
||||||
|
CGraphics::SetShaderDataBinding(m_shaderBind);
|
||||||
|
if (m_textured)
|
||||||
|
{
|
||||||
|
m_vertBuf->load(g_StaticLineVertsTex.data(), sizeof(SDrawVertTex) * g_StaticLineVertsTex.size());
|
||||||
|
CGraphics::DrawArray(boo::Primitive::TriStrips, 0, g_StaticLineVertsTex.size());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
m_vertBuf->load(g_StaticLineVertsNoTex.data(), sizeof(SDrawVertNoTex) * g_StaticLineVertsNoTex.size());
|
||||||
|
CGraphics::DrawArray(boo::Primitive::TriStrips, 0, g_StaticLineVertsNoTex.size());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
#ifndef __PSHAG_CLINERENDERER_HPP__
|
||||||
|
#define __PSHAG_CLINERENDERER_HPP__
|
||||||
|
|
||||||
|
#include "RetroTypes.hpp"
|
||||||
|
#include "CVector3f.hpp"
|
||||||
|
#include "CColor.hpp"
|
||||||
|
#include "boo/graphicsdev/IGraphicsDataFactory.hpp"
|
||||||
|
|
||||||
|
namespace pshag
|
||||||
|
{
|
||||||
|
|
||||||
|
class CLineRenderer
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
enum class EPrimitiveMode
|
||||||
|
{
|
||||||
|
Lines,
|
||||||
|
LineStrip,
|
||||||
|
LineLoop
|
||||||
|
};
|
||||||
|
|
||||||
|
public:
|
||||||
|
EPrimitiveMode m_mode;
|
||||||
|
u32 m_maxVerts;
|
||||||
|
u32 m_nextVert = 0;
|
||||||
|
bool m_final = false;
|
||||||
|
bool m_textured;
|
||||||
|
|
||||||
|
Zeus::CVector3f m_firstPos;
|
||||||
|
Zeus::CVector3f m_secondPos;
|
||||||
|
Zeus::CVector2f m_firstUV;
|
||||||
|
Zeus::CColor m_firstColor;
|
||||||
|
float m_firstWidth;
|
||||||
|
|
||||||
|
Zeus::CVector3f m_lastPos;
|
||||||
|
Zeus::CVector3f m_lastPos2;
|
||||||
|
Zeus::CVector2f m_lastUV;
|
||||||
|
Zeus::CColor m_lastColor;
|
||||||
|
float m_lastWidth;
|
||||||
|
|
||||||
|
public:
|
||||||
|
boo::GraphicsDataToken m_gfxToken;
|
||||||
|
boo::IGraphicsBufferD* m_vertBuf;
|
||||||
|
boo::IGraphicsBufferD* m_uniformBuf;
|
||||||
|
boo::IShaderDataBinding* m_shaderBind = nullptr;
|
||||||
|
|
||||||
|
CLineRenderer(EPrimitiveMode mode, u32 maxVerts, boo::ITexture* texture, bool additive);
|
||||||
|
|
||||||
|
void Reset();
|
||||||
|
void AddVertex(const Zeus::CVector3f& position, const Zeus::CColor& color, float width,
|
||||||
|
const Zeus::CVector2f& uv=Zeus::CVector2f::skZero);
|
||||||
|
void Render(const Zeus::CColor& moduColor=Zeus::CColor::skWhite);
|
||||||
|
|
||||||
|
static void Initialize();
|
||||||
|
static void Shutdown();
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __PSHAG_CLINERENDERER_HPP__
|
|
@ -0,0 +1,47 @@
|
||||||
|
#ifndef __PSHAG_CLINERENDERERSHADERS_HPP__
|
||||||
|
#define __PSHAG_CLINERENDERERSHADERS_HPP__
|
||||||
|
|
||||||
|
#include "CGraphics.hpp"
|
||||||
|
#include "boo/graphicsdev/GL.hpp"
|
||||||
|
#include "boo/graphicsdev/D3D.hpp"
|
||||||
|
#include "boo/graphicsdev/Metal.hpp"
|
||||||
|
|
||||||
|
namespace pshag
|
||||||
|
{
|
||||||
|
class CLineRenderer;
|
||||||
|
|
||||||
|
class CLineRendererShaders
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
struct IDataBindingFactory
|
||||||
|
{
|
||||||
|
virtual void BuildShaderDataBinding(CLineRenderer& renderer, boo::IShaderPipeline* pipeline,
|
||||||
|
boo::ITexture* texture)=0;
|
||||||
|
};
|
||||||
|
|
||||||
|
private:
|
||||||
|
static boo::IShaderPipeline* m_texAlpha;
|
||||||
|
static boo::IShaderPipeline* m_texAdditive;
|
||||||
|
|
||||||
|
static boo::IShaderPipeline* m_noTexAlpha;
|
||||||
|
static boo::IShaderPipeline* m_noTexAdditive;
|
||||||
|
|
||||||
|
static std::unique_ptr<IDataBindingFactory> m_bindFactory;
|
||||||
|
static boo::GraphicsDataToken m_gfxToken;
|
||||||
|
|
||||||
|
public:
|
||||||
|
static IDataBindingFactory* Initialize(boo::GLDataFactory& factory);
|
||||||
|
#if _WIN32
|
||||||
|
static IDataBindingFactory* Initialize(boo::ID3DDataFactory& factory);
|
||||||
|
#elif BOO_HAS_METAL
|
||||||
|
static IDataBindingFactory* Initialize(boo::MetalDataFactory& factory);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
static void Initialize();
|
||||||
|
static void Shutdown();
|
||||||
|
static void BuildShaderDataBinding(CLineRenderer& renderer, boo::ITexture* texture, bool additive);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __PSHAG_CLINERENDERERSHADERS_HPP__
|
|
@ -0,0 +1,142 @@
|
||||||
|
#include "CLineRendererShaders.hpp"
|
||||||
|
#include "CLineRenderer.hpp"
|
||||||
|
|
||||||
|
namespace pshag
|
||||||
|
{
|
||||||
|
|
||||||
|
static const char* VS_GLSL_TEX =
|
||||||
|
"#version 330\n"
|
||||||
|
"layout(location=0) in vec4 posIn;\n"
|
||||||
|
"layout(location=1) in vec4 colorIn;\n"
|
||||||
|
"layout(location=2) in vec4 uvIn;\n"
|
||||||
|
"\n"
|
||||||
|
"uniform LineUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 moduColor;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\n"
|
||||||
|
" vec2 uv;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"out VertToFrag vtf;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vtf.color = colorIn * moduColor;\n"
|
||||||
|
" vtf.uv = uvIn.xy;\n"
|
||||||
|
" gl_Position = posIn;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FS_GLSL_TEX =
|
||||||
|
"#version 330\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\n"
|
||||||
|
" vec2 uv;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"in VertToFrag vtf;\n"
|
||||||
|
"layout(location=0) out vec4 colorOut;\n"
|
||||||
|
"uniform sampler2D texs[1];\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" colorOut = vtf.color * texture(texs[0], vtf.uv);\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char* VS_GLSL_NOTEX =
|
||||||
|
"#version 330\n"
|
||||||
|
"layout(location=0) in vec4 posIn;\n"
|
||||||
|
"layout(location=1) in vec4 colorIn;\n"
|
||||||
|
"\n"
|
||||||
|
"uniform LineUniform\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 moduColor;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"out VertToFrag vtf;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" vtf.color = colorIn * moduColor;\n"
|
||||||
|
" gl_Position = posIn;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
static const char* FS_GLSL_NOTEX =
|
||||||
|
"#version 330\n"
|
||||||
|
"struct VertToFrag\n"
|
||||||
|
"{\n"
|
||||||
|
" vec4 color;\n"
|
||||||
|
"};\n"
|
||||||
|
"\n"
|
||||||
|
"in VertToFrag vtf;\n"
|
||||||
|
"layout(location=0) out vec4 colorOut;\n"
|
||||||
|
"void main()\n"
|
||||||
|
"{\n"
|
||||||
|
" colorOut = vtf.color;\n"
|
||||||
|
"}\n";
|
||||||
|
|
||||||
|
struct GLSLLineDataBindingFactory : CLineRendererShaders::IDataBindingFactory
|
||||||
|
{
|
||||||
|
void BuildShaderDataBinding(CLineRenderer& renderer, boo::IShaderPipeline* pipeline, boo::ITexture* texture)
|
||||||
|
{
|
||||||
|
boo::IVertexFormat* vtxFmt = nullptr;
|
||||||
|
int texCount = 0;
|
||||||
|
boo::ITexture* textures[1];
|
||||||
|
|
||||||
|
if (texture)
|
||||||
|
{
|
||||||
|
textures[0] = texture;
|
||||||
|
texCount = 1;
|
||||||
|
const boo::VertexElementDescriptor TexFmtTex[] =
|
||||||
|
{
|
||||||
|
{renderer.m_vertBuf, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{renderer.m_vertBuf, nullptr, boo::VertexSemantic::Color},
|
||||||
|
{renderer.m_vertBuf, nullptr, boo::VertexSemantic::UV4}
|
||||||
|
};
|
||||||
|
vtxFmt = CGraphics::g_BooFactory->newVertexFormat(3, TexFmtTex);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
const boo::VertexElementDescriptor TexFmtNoTex[] =
|
||||||
|
{
|
||||||
|
{renderer.m_vertBuf, nullptr, boo::VertexSemantic::Position4},
|
||||||
|
{renderer.m_vertBuf, nullptr, boo::VertexSemantic::Color}
|
||||||
|
};
|
||||||
|
vtxFmt = CGraphics::g_BooFactory->newVertexFormat(2, TexFmtNoTex);
|
||||||
|
}
|
||||||
|
|
||||||
|
boo::IGraphicsBuffer* uniforms[] = {renderer.m_uniformBuf};
|
||||||
|
|
||||||
|
renderer.m_shaderBind = CGraphics::g_BooFactory->newShaderDataBinding(pipeline, vtxFmt, renderer.m_vertBuf,
|
||||||
|
nullptr, nullptr, 1, uniforms,
|
||||||
|
texCount, textures);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
CLineRendererShaders::IDataBindingFactory* CLineRendererShaders::Initialize(boo::GLDataFactory& factory)
|
||||||
|
{
|
||||||
|
static const char* UniNames[] = {"LineUniform"};
|
||||||
|
|
||||||
|
m_texAlpha = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, "texs", 1, UniNames,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
false, true, false);
|
||||||
|
m_texAdditive = factory.newShaderPipeline(VS_GLSL_TEX, FS_GLSL_TEX, 1, "texs", 1, UniNames,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||||
|
false, false, false);
|
||||||
|
m_noTexAlpha = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 1, nullptr, 1, UniNames,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::InvSrcAlpha,
|
||||||
|
false, true, false);
|
||||||
|
m_noTexAdditive = factory.newShaderPipeline(VS_GLSL_NOTEX, FS_GLSL_NOTEX, 1, nullptr, 1, UniNames,
|
||||||
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||||
|
false, false, false);
|
||||||
|
|
||||||
|
return new struct GLSLLineDataBindingFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
|
@ -1,5 +1,7 @@
|
||||||
add_library(RuntimeCommonGraphics
|
add_library(RuntimeCommonGraphics
|
||||||
IRenderer.hpp
|
IRenderer.hpp
|
||||||
CBooRenderer.hpp CBooRenderer.cpp
|
CBooRenderer.hpp CBooRenderer.cpp
|
||||||
|
CLineRenderer.hpp CLineRenderer.cpp
|
||||||
|
CLineRendererShaders.hpp CLineRendererShadersGLSL.cpp
|
||||||
CMetroidModelInstance.hpp
|
CMetroidModelInstance.hpp
|
||||||
CLight.hpp)
|
CLight.hpp)
|
||||||
|
|
|
@ -12,6 +12,7 @@ target_link_libraries(mp1
|
||||||
RuntimeCommonCharacter
|
RuntimeCommonCharacter
|
||||||
RuntimeCommonInput
|
RuntimeCommonInput
|
||||||
RuntimeCommonParticle
|
RuntimeCommonParticle
|
||||||
|
RuntimeCommonGraphics
|
||||||
RuntimeCommon
|
RuntimeCommon
|
||||||
DNAMP1
|
DNAMP1
|
||||||
DNACommon
|
DNACommon
|
||||||
|
|
|
@ -13,7 +13,7 @@
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("Retro::CElementGen");
|
static LogVisor::LogModule Log("pshag::CElementGen");
|
||||||
|
|
||||||
static bool s_inCreateNewParticles = false;
|
static bool s_inCreateNewParticles = false;
|
||||||
|
|
||||||
|
@ -413,18 +413,30 @@ CElementGen::CElementGen(const TToken<CGenDescription>& gen,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
m_shaderClass = CElementGenShaders::GetShaderClass(*this);
|
if (x225_26_LINE)
|
||||||
static const size_t ShadClsSizes[] =
|
|
||||||
{
|
{
|
||||||
sizeof(SParticleInstanceTex),
|
CUVElement* texr = desc->x54_TEXR.get();
|
||||||
sizeof(SParticleInstanceIndTex),
|
boo::ITexture* tex = nullptr;
|
||||||
sizeof(SParticleInstanceNoTex)
|
if (texr)
|
||||||
};
|
tex = texr->GetValueTexture(0).GetObj()->GetBooTexture();
|
||||||
size_t maxInsts = x224_29_MBLR ? (m_maxMBSP * x70_MAXP) : x70_MAXP;
|
m_lineRenderer.reset(new CLineRenderer(CLineRenderer::EPrimitiveMode::Lines,
|
||||||
m_instBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Vertex, ShadClsSizes[int(m_shaderClass)], maxInsts);
|
x70_MAXP * 2, tex, x224_26_AAPH));
|
||||||
m_uniformBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1);
|
}
|
||||||
CElementGenShaders::BuildShaderDataBinding(*this);
|
else
|
||||||
m_gfxToken = CGraphics::CommitResources();
|
{
|
||||||
|
m_shaderClass = CElementGenShaders::GetShaderClass(*this);
|
||||||
|
static const size_t ShadClsSizes[] =
|
||||||
|
{
|
||||||
|
sizeof(SParticleInstanceTex),
|
||||||
|
sizeof(SParticleInstanceIndTex),
|
||||||
|
sizeof(SParticleInstanceNoTex)
|
||||||
|
};
|
||||||
|
size_t maxInsts = x224_29_MBLR ? (m_maxMBSP * x70_MAXP) : x70_MAXP;
|
||||||
|
m_instBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Vertex, ShadClsSizes[int(m_shaderClass)], maxInsts);
|
||||||
|
m_uniformBuf = CGraphics::NewDynamicGPUBuffer(boo::BufferUse::Uniform, sizeof(SParticleUniforms), 1);
|
||||||
|
CElementGenShaders::BuildShaderDataBinding(*this);
|
||||||
|
m_gfxToken = CGraphics::CommitResources();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
CElementGen::~CElementGen()
|
CElementGen::~CElementGen()
|
||||||
|
@ -1378,7 +1390,6 @@ void CElementGen::RenderModels()
|
||||||
|
|
||||||
void CElementGen::RenderLines()
|
void CElementGen::RenderLines()
|
||||||
{
|
{
|
||||||
return;
|
|
||||||
CGenDescription* desc = x1c_genDesc.GetObj();
|
CGenDescription* desc = x1c_genDesc.GetObj();
|
||||||
CGlobalRandom gr(x230_randState);
|
CGlobalRandom gr(x230_randState);
|
||||||
|
|
||||||
|
@ -1411,6 +1422,7 @@ void CElementGen::RenderLines()
|
||||||
bool constTexr = true;
|
bool constTexr = true;
|
||||||
bool constUVs = true;
|
bool constUVs = true;
|
||||||
CTexture* cachedTex = nullptr;
|
CTexture* cachedTex = nullptr;
|
||||||
|
Zeus::CColor moduColor = Zeus::CColor::skWhite;
|
||||||
if (texr)
|
if (texr)
|
||||||
{
|
{
|
||||||
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
CParticle& target = g_StaticParticleList[x2c_particleLists[0].x0_partIdx];
|
||||||
|
@ -1423,30 +1435,23 @@ void CElementGen::RenderLines()
|
||||||
if (x30c_moduColor != Zeus::CColor::skBlack)
|
if (x30c_moduColor != Zeus::CColor::skBlack)
|
||||||
{
|
{
|
||||||
/* Add RASC * PREVC pass for MODU color loaded into channel mat-color */
|
/* Add RASC * PREVC pass for MODU color loaded into channel mat-color */
|
||||||
}
|
moduColor = x30c_moduColor;
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Pass-thru */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
constTexr = texr->HasConstantTexture();
|
constTexr = texr->HasConstantTexture();
|
||||||
texr->GetValueUV(partFrame, uvs);
|
texr->GetValueUV(partFrame, uvs);
|
||||||
constUVs = texr->HasConstantUV();
|
constUVs = texr->HasConstantUV();
|
||||||
}
|
}
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Pass-thru */
|
|
||||||
}
|
|
||||||
|
|
||||||
|
float constWidth = 1.f;
|
||||||
if (widtConst)
|
if (widtConst)
|
||||||
{
|
{
|
||||||
float width = 1.f;
|
widt->GetValue(0, constWidth);
|
||||||
widt->GetValue(0, width);
|
constWidth = std::max(0.f, std::min(constWidth, 42.5f));
|
||||||
width = std::max(0.f, std::min(width, 42.5f));
|
|
||||||
/* Set line width */
|
|
||||||
/* Start line draw of x2c_particleLists.size() * 2 */
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_lineRenderer->Reset();
|
||||||
|
|
||||||
for (CParticleListItem& item : x2c_particleLists)
|
for (CParticleListItem& item : x2c_particleLists)
|
||||||
{
|
{
|
||||||
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
CParticle& particle = g_StaticParticleList[item.x0_partIdx];
|
||||||
|
@ -1475,32 +1480,20 @@ void CElementGen::RenderLines()
|
||||||
|
|
||||||
if (widtConst)
|
if (widtConst)
|
||||||
{
|
{
|
||||||
/* Draw: */
|
m_lineRenderer->AddVertex(p1, particle.x34_color, constWidth, {uvs.xMin, uvs.yMin});
|
||||||
/* Pos: p1 Color: particle.color UV0: {uv[0], uv[1]} */
|
m_lineRenderer->AddVertex(p2, particle.x34_color, constWidth, {uvs.xMax, uvs.yMax});
|
||||||
/* Pos: p2 Color: particle.color UV0: {uv[2], uv[3]} */
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
float width = 1.f;
|
float width = 1.f;
|
||||||
widt->GetValue(0, width);
|
widt->GetValue(0, width);
|
||||||
width = std::max(0.f, std::min(width, 42.5f));
|
width = std::max(0.f, std::min(width, 42.5f));
|
||||||
/* Set line width */
|
m_lineRenderer->AddVertex(p1, particle.x34_color, width, {uvs.xMin, uvs.yMin});
|
||||||
/* Start line draw of 2 */
|
m_lineRenderer->AddVertex(p2, particle.x34_color, width, {uvs.xMax, uvs.yMax});
|
||||||
|
|
||||||
/* Draw: */
|
|
||||||
/* Pos: p1 Color: particle.color UV0: {uv[0], uv[1]} */
|
|
||||||
/* Pos: p2 Color: particle.color UV0: {uv[2], uv[3]} */
|
|
||||||
/* EndDraw */
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (widtConst)
|
m_lineRenderer->Render(moduColor);
|
||||||
{
|
|
||||||
/* EndDraw */
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Restore line-width to 1.0 */
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void CElementGen::RenderParticles()
|
void CElementGen::RenderParticles()
|
||||||
|
|
|
@ -12,6 +12,7 @@
|
||||||
#include "CRandom16.hpp"
|
#include "CRandom16.hpp"
|
||||||
#include "CParticleGen.hpp"
|
#include "CParticleGen.hpp"
|
||||||
#include "CElementGenShaders.hpp"
|
#include "CElementGenShaders.hpp"
|
||||||
|
#include "Graphics/CLineRenderer.hpp"
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
|
@ -149,6 +150,7 @@ private:
|
||||||
float x308_LSLA = 45.f;
|
float x308_LSLA = 45.f;
|
||||||
Zeus::CColor x30c_moduColor = {1.f, 1.f, 1.f, 1.f};
|
Zeus::CColor x30c_moduColor = {1.f, 1.f, 1.f, 1.f};
|
||||||
|
|
||||||
|
std::unique_ptr<CLineRenderer> m_lineRenderer;
|
||||||
CElementGenShaders::EShaderClass m_shaderClass;
|
CElementGenShaders::EShaderClass m_shaderClass;
|
||||||
|
|
||||||
void AccumulateBounds(Zeus::CVector3f& pos, float size);
|
void AccumulateBounds(Zeus::CVector3f& pos, float size);
|
||||||
|
|
|
@ -177,7 +177,7 @@ static const char* FS_GLSL_NOTEX =
|
||||||
" colorOut = vtf.color;\n"
|
" colorOut = vtf.color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
struct GLSLDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
struct GLSLElementDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
||||||
{
|
{
|
||||||
void BuildShaderDataBinding(CElementGen& gen,
|
void BuildShaderDataBinding(CElementGen& gen,
|
||||||
boo::IShaderPipeline* regPipeline,
|
boo::IShaderPipeline* regPipeline,
|
||||||
|
@ -333,7 +333,7 @@ CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::GLD
|
||||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||||
false, false, false);
|
false, false, false);
|
||||||
|
|
||||||
return new struct GLSLDataBindingFactory;
|
return new struct GLSLElementDataBindingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -187,7 +187,7 @@ static const char* FS_HLSL_NOTEX =
|
||||||
" return vtf.color;\n"
|
" return vtf.color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
struct D3DDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
struct D3DElementDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
||||||
{
|
{
|
||||||
void BuildShaderDataBinding(CElementGen& gen,
|
void BuildShaderDataBinding(CElementGen& gen,
|
||||||
boo::IShaderPipeline* regPipeline,
|
boo::IShaderPipeline* regPipeline,
|
||||||
|
@ -356,7 +356,7 @@ CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::ID3
|
||||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||||
false, false, false);
|
false, false, false);
|
||||||
|
|
||||||
return new struct D3DDataBindingFactory;
|
return new struct D3DElementDataBindingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -209,7 +209,7 @@ static const char* FS_METAL_NOTEX =
|
||||||
" return vtf.color;\n"
|
" return vtf.color;\n"
|
||||||
"}\n";
|
"}\n";
|
||||||
|
|
||||||
struct MetalDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
struct MetalElementDataBindingFactory : CElementGenShaders::IDataBindingFactory
|
||||||
{
|
{
|
||||||
void BuildShaderDataBinding(CElementGen& gen,
|
void BuildShaderDataBinding(CElementGen& gen,
|
||||||
boo::IShaderPipeline* regPipeline,
|
boo::IShaderPipeline* regPipeline,
|
||||||
|
@ -378,7 +378,7 @@ CElementGenShaders::IDataBindingFactory* CElementGenShaders::Initialize(boo::Met
|
||||||
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
boo::BlendFactor::SrcAlpha, boo::BlendFactor::One,
|
||||||
false, false, false);
|
false, false, false);
|
||||||
|
|
||||||
return new struct MetalDataBindingFactory;
|
return new struct MetalElementDataBindingFactory;
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("Retro::CParticleDataFactory");
|
static LogVisor::LogModule Log("pshag::CParticleDataFactory");
|
||||||
|
|
||||||
float CParticleDataFactory::GetReal(CInputStream& in)
|
float CParticleDataFactory::GetReal(CInputStream& in)
|
||||||
{
|
{
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("Retro::CParticleElectricDataFactory");
|
static LogVisor::LogModule Log("pshag::CParticleElectricDataFactory");
|
||||||
|
|
||||||
using CPF = CParticleDataFactory;
|
using CPF = CParticleDataFactory;
|
||||||
|
|
||||||
|
|
|
@ -8,7 +8,7 @@
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("Retro::CParticleSwooshDataFactory");
|
static LogVisor::LogModule Log("pshag::CParticleSwooshDataFactory");
|
||||||
|
|
||||||
using CPF = CParticleDataFactory;
|
using CPF = CParticleDataFactory;
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,7 @@
|
||||||
|
|
||||||
namespace pshag
|
namespace pshag
|
||||||
{
|
{
|
||||||
static LogVisor::LogModule Log("Retro::CProjectileWeaponDataFactory");
|
static LogVisor::LogModule Log("pshag::CProjectileWeaponDataFactory");
|
||||||
|
|
||||||
using CPF = CParticleDataFactory;
|
using CPF = CParticleDataFactory;
|
||||||
|
|
||||||
|
|
|
@ -1 +1 @@
|
||||||
Subproject commit a5d6f9f2624d86a92f1438dda89695f47789995c
|
Subproject commit 38b3396e0853e9bf446859a9d8b042044d9fd78e
|
Loading…
Reference in New Issue