ProtoTank/Engine/Graphics/InfoScreen.cpp

100 lines
4.0 KiB
C++

#include "InfoScreen.hpp"
#include "../Utils/MeshHelper.hpp"
#define SF_COLOR_4CHEX(h) sf::Color((uint32_t)h)
InfoScreen::InfoScreen() : mRTOffset(sf::Vector2f(8.f, 464.f)) {
if (mCamera == nullptr) {
mCamera = std::make_unique<Camera>();
mCamera->SetFrustrumOrthographic(304.f / 100, 220.f / 100, 0.1f, 20.f);
mCamera->SetPosition(0.f, 0.f, -8.f);
mCamera->UpdateCamView();
}
mRTSize.x = 304.f; mRTSize.y = 220.f;
if (mTankHolo == nullptr) {
mTankHolo = std::make_unique<Tank>();
mTankHolo->SetPosition(0.f, 0.f, 0.f);
mTankHolo->SetRotation(0.f, M3D_Deg2Rad(90.f), M3D_Deg2Rad(90.f));
mTankHolo->SetScale(2.0f);
}
}
InfoScreen::~InfoScreen() {}
void InfoScreen::SetRTSize(unsigned int w, unsigned int h) {
mRTSize.x = w; mRTSize.y = h;
mCamera->SetFrustrumOrthographic(mRTSize.x, mRTSize.y, 0.1f, 20.f);
}
void InfoScreen::Draw(sf::RenderTexture& context) {
sf::BlendMode sBM = sf::BlendNone;
sf::RenderStates sRS(sBM);
// Get global (camera and projection) matrixes
M3D_MATRIX viewProjMat = mCamera->GetView() * mCamera->GetProj();
const size_t vCount = mTankHolo->GetObjectVerticesCount();
std::vector<M3D_F4> projVertices(vCount);
auto& oMesh = mTankHolo->GetObjectMesh();
// Vertices homogeneous clip space (NDC) transformation
M3D_V3Transform(
projVertices.data(), sizeof(M3D_F4),
reinterpret_cast<const M3D_F3*>(oMesh.vertices.data()), sizeof(Vertex),
vCount,
mTankHolo->GetTransform() * viewProjMat
);
sf::Vertex drawPoints[4];
for (auto& objPt : oMesh.parts) {
auto indicePtr = static_cast<const uint32_t*>(objPt.indices.data());
for (uint32_t i = 0; i < objPt.GetIndicesCount(); i += 3) {
// Indices failsafe - discard triangle rendering
if ((i+2 > objPt.GetIndicesCount()) || indicePtr[i] >= vCount || indicePtr[i+1] >= vCount || indicePtr[i+2] >= vCount) {
//log.PrintWarning()
break;
}
M3D_VECTOR V1 = M3D_V4LoadF4(&projVertices[indicePtr[i]]);
M3D_VECTOR V2 = M3D_V4LoadF4(&projVertices[indicePtr[i+1]]);
M3D_VECTOR V3 = M3D_V4LoadF4(&projVertices[indicePtr[i+2]]);
// Back-face culling in LH-z system
// (front when (triangle normal . projected vertice) < 0)
//if (M3D_V4GetX(M3D_V3Dot(M3D_Tri3DNormal(V1,V2,V3), V1)) < 0)
// NOT USED - Too heavy computation resources usage
// Do the perspective divide
V1 = M3D_V4Divide(V1, M3D_V4SplatW(V1));
V2 = M3D_V4Divide(V2, M3D_V4SplatW(V2));
V3 = M3D_V4Divide(V3, M3D_V4SplatW(V3));
// Finally project from NDC to the screen
V1 = M3D_V3TransformNDCToViewport(V1, mRTOffset.x, mRTOffset.y, mRTSize.x, mRTSize.y, 0.1f, 20.f);
V2 = M3D_V3TransformNDCToViewport(V2, mRTOffset.x, mRTOffset.y, mRTSize.x, mRTSize.y, 0.1f, 20.f);
V3 = M3D_V3TransformNDCToViewport(V3, mRTOffset.x, mRTOffset.y, mRTSize.x, mRTSize.y, 0.1f, 20.f);
// Simplified back-face culling on 2D viewport triangle
//if (M3D_V4GetX(M3D_Tri2DNormal(V1,V2,V3)) > 0)
{
// Set pixels color depending of states (WIP... A long time)
// if (player.components.main_canon.state == failure)
{
drawPoints[0].color = sf::Color::White;
drawPoints[1].color = sf::Color::White;
drawPoints[2].color = sf::Color::White;
}
drawPoints[1].position = sf::Vector2f(M3D_V4GetX(V2), M3D_V4GetY(V2));
drawPoints[0].position = sf::Vector2f(M3D_V4GetX(V1), M3D_V4GetY(V1));
drawPoints[2].position = sf::Vector2f(M3D_V4GetX(V3), M3D_V4GetY(V3));
drawPoints[3] = drawPoints[0];
context.draw(drawPoints, 4, sf::LineStrip, sRS);
}
}
}
}