From 5fc2c0fc882ab8fb0affa77ff033cf4af0212e00 Mon Sep 17 00:00:00 2001 From: JackCarterSmith Date: Fri, 7 Feb 2025 00:34:10 +0100 Subject: [PATCH] New static InfoScreen --- Engine/Graphics/3DRenderer.cpp | 2 +- Engine/Graphics/Camera.cpp | 8 +++ Engine/Graphics/Camera.hpp | 1 + Engine/Graphics/InfoScreen.cpp | 100 ++++++++++++++++++++++++++++++ Engine/Graphics/InfoScreen.hpp | 34 ++++++++++ Engine/Graphics/UI.cpp | 6 ++ Engine/Graphics/UI.hpp | 2 + Engine/Utils/3DMaths.hpp | 2 + Engine/Utils/3DMaths_mat.inl | 110 +++++++++++++++++++++++++++++++++ README.md | 3 +- srcs.list | 2 + 11 files changed, 268 insertions(+), 2 deletions(-) create mode 100644 Engine/Graphics/InfoScreen.cpp create mode 100644 Engine/Graphics/InfoScreen.hpp diff --git a/Engine/Graphics/3DRenderer.cpp b/Engine/Graphics/3DRenderer.cpp index 315a871..3718903 100644 --- a/Engine/Graphics/3DRenderer.cpp +++ b/Engine/Graphics/3DRenderer.cpp @@ -12,7 +12,7 @@ //#define DISABLE_AABB_CLIPPING //#define DISABLE_TRIANGLE_CLIPPING -//#define DISABLE_WIREFRAME_MODE +#define DISABLE_WIREFRAME_MODE // Rendering pipeline: diff --git a/Engine/Graphics/Camera.cpp b/Engine/Graphics/Camera.cpp index 6955127..39fb137 100644 --- a/Engine/Graphics/Camera.cpp +++ b/Engine/Graphics/Camera.cpp @@ -13,6 +13,14 @@ void Camera::SetFrustrum(float fov, float r, float zn, float zf) { frustrumUpdated = true; } +void Camera::SetFrustrumOrthographic(float w, float h, float zn, float zf) { + //if (!frameDirty) + this->fov = 90.f; + M3D_MATRIX pMat = M3D_TransformMatrixOrthographicLH(w, h, zn, zf); + M3D_V4StoreF4x4(&mProjMat, pMat); + frustrumUpdated = true; +} + void Camera::UpdateCamView() { M3D_VECTOR P = M3D_V4LoadF3(&mPos); M3D_VECTOR L = M3D_V4LoadF3(&mLook); diff --git a/Engine/Graphics/Camera.hpp b/Engine/Graphics/Camera.hpp index 72e800a..0145bfb 100644 --- a/Engine/Graphics/Camera.hpp +++ b/Engine/Graphics/Camera.hpp @@ -29,6 +29,7 @@ public: void SetPosition(const M3D_F3 v) { mPos = v; } void SetFrustrum(float fov, float r, float zn, float zf); + void SetFrustrumOrthographic(float w, float h, float zn, float zf); void UpdateCamView(); void LookAt(M3D_VECTOR pos, M3D_VECTOR target, M3D_VECTOR worldUp); void LookAt(const M3D_F3& pos, const M3D_F3& target, const M3D_F3& up); diff --git a/Engine/Graphics/InfoScreen.cpp b/Engine/Graphics/InfoScreen.cpp new file mode 100644 index 0000000..ca9ba01 --- /dev/null +++ b/Engine/Graphics/InfoScreen.cpp @@ -0,0 +1,100 @@ +#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(); + 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(); + 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 projVertices(vCount); + auto& oMesh = mTankHolo->GetObjectMesh(); + // Vertices homogeneous clip space (NDC) transformation + M3D_V3Transform( + projVertices.data(), sizeof(M3D_F4), + reinterpret_cast(oMesh.vertices.data()), sizeof(Vertex), + vCount, + mTankHolo->GetTransform() * viewProjMat + ); + + sf::Vertex drawPoints[4]; + for (auto& objPt : oMesh.parts) { + auto indicePtr = static_cast(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); + } + } + } +} \ No newline at end of file diff --git a/Engine/Graphics/InfoScreen.hpp b/Engine/Graphics/InfoScreen.hpp new file mode 100644 index 0000000..313203e --- /dev/null +++ b/Engine/Graphics/InfoScreen.hpp @@ -0,0 +1,34 @@ +#pragma once + +#include +#include + +#include "Camera.hpp" +#include "../World/Tank.hpp" + + +class InfoScreen final { +public: + InfoScreen(); + ~InfoScreen(); + + InfoScreen(InfoScreen&&) = default; + InfoScreen& operator= (InfoScreen&&) = default; + InfoScreen(InfoScreen const&) = delete; + InfoScreen& operator= (InfoScreen const&) = delete; + + const sf::Vector2f& GetRTSize() const noexcept { return mRTSize; } + void SetRTSize(unsigned int w, unsigned int h); + const sf::Vector2f& GetRTOffset() const noexcept { return mRTOffset; } + void SetRTOffset(unsigned int w, unsigned int h) { mRTOffset.x = w; mRTOffset.y = h; } + + void Draw(sf::RenderTexture& context); + +private: + std::unique_ptr mCamera; + sf::Vector2f mRTSize; + sf::Vector2f mRTOffset; + + std::unique_ptr mTankHolo; + +}; \ No newline at end of file diff --git a/Engine/Graphics/UI.cpp b/Engine/Graphics/UI.cpp index e6e04c9..5afd463 100644 --- a/Engine/Graphics/UI.cpp +++ b/Engine/Graphics/UI.cpp @@ -51,6 +51,9 @@ CockpitUI::CockpitUI(unsigned int w, unsigned int h) : UI(w, h) { mStaticCockpitTexture.setSrgb(true); if (!mStaticCockpitTexture.loadFromFile("cockpit_ui.png", sf::IntRect(0, 0, 1280, 780))) throw std::runtime_error("Unable to load texture datas"); + + if (mInfoScreen == nullptr) + mInfoScreen = std::make_unique(); } void CockpitUI::Update() { @@ -71,6 +74,9 @@ void CockpitUI::Draw(std::shared_ptr& context) { radar.setFillColor(SF_COLOR_4CHEX(0x666666FF)); mUIRender.draw(radar, sRS); + // Draw the player info screen + mInfoScreen->Draw(mUIRender); + // Draw the static board sf::Sprite staticBoardSprite(mStaticCockpitTexture); mUIRender.draw(staticBoardSprite, sRS); diff --git a/Engine/Graphics/UI.hpp b/Engine/Graphics/UI.hpp index 9fa9c9c..5fb0108 100644 --- a/Engine/Graphics/UI.hpp +++ b/Engine/Graphics/UI.hpp @@ -5,6 +5,7 @@ #include #include "3DRenderer.hpp" +#include "InfoScreen.hpp" class UI { @@ -48,6 +49,7 @@ public: private: sf::Texture mStaticCockpitTexture; + std::unique_ptr mInfoScreen; }; diff --git a/Engine/Utils/3DMaths.hpp b/Engine/Utils/3DMaths.hpp index 90fbd1c..1195d6f 100644 --- a/Engine/Utils/3DMaths.hpp +++ b/Engine/Utils/3DMaths.hpp @@ -586,6 +586,8 @@ M3D_MATRIX M3D_TransformMatrixCamLookToLH(M3D_VECTOR viewPos, M3D_VECTOR viewDir M3D_MATRIX M3D_TransformMatrixCamLookToRH(M3D_VECTOR viewPos, M3D_VECTOR viewDirection, M3D_VECTOR upDirection) noexcept; M3D_MATRIX M3D_TransformMatrixFrustrumFovLH(float fov, float ratio, float near, float far) noexcept; M3D_MATRIX M3D_TransformMatrixFrustrumFovRH(float fov, float ratio, float near, float far) noexcept; +M3D_MATRIX M3D_TransformMatrixOrthographicLH(float w, float h, float near, float far) noexcept; +M3D_MATRIX M3D_TransformMatrixOrthographicRH(float w, float h, float near, float far) noexcept; M3D_MATRIX M3D_TransformMatrixScale(float ScaleX, float ScaleY, float ScaleZ) noexcept; M3D_MATRIX M3D_TransformMatrixScale(M3D_VECTOR Scale) noexcept; M3D_MATRIX M3D_TransformMatrixTranslate(float OffsetX, float OffsetY, float OffsetZ) noexcept; diff --git a/Engine/Utils/3DMaths_mat.inl b/Engine/Utils/3DMaths_mat.inl index f22d9f6..d2e368b 100644 --- a/Engine/Utils/3DMaths_mat.inl +++ b/Engine/Utils/3DMaths_mat.inl @@ -1749,6 +1749,116 @@ INLINE_AVX_FIX M3D_MATRIX M3D_TransformMatrixFrustrumFovRH(float fov, float rati #endif } +INLINE_AVX_FIX M3D_MATRIX M3D_TransformMatrixOrthographicLH(float w, float h, float near, float far) noexcept { + float fRange = 1.0f / (far - near); + +#ifdef DISABLE_INTRINSICS + M3D_MATRIX ret; + ret.mat[0][0] = 2.0f / w; + ret.mat[0][1] = 0.0f; + ret.mat[0][2] = 0.0f; + ret.mat[0][3] = 0.0f; + + ret.mat[1][0] = 0.0f; + ret.mat[1][1] = 2.0f / h; + ret.mat[1][2] = 0.0f; + ret.mat[1][3] = 0.0f; + + ret.mat[2][0] = 0.0f; + ret.mat[2][1] = 0.0f; + ret.mat[2][2] = fRange; + ret.mat[2][3] = 0.0f; + + ret.mat[3][0] = 0.0f; + ret.mat[3][1] = 0.0f; + ret.mat[3][2] = -fRange * near; + ret.mat[3][3] = 1.0f; + return ret; +#else + M3D_VECTOR rMem = { + 2.0f / w, + 2.0f / h, + fRange, + -fRange * near + }; + + // Copy from memory to SSE register + M3D_VECTOR vValues = rMem; + + M3D_MATRIX ret; + M3D_VECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_move_ss(vTemp, vValues); + + ret.rows[0] = vTemp; // 2.0f / w, 0, 0, 0 + + vTemp = vValues; + vTemp = _mm_and_ps(vTemp, M3D_MMaskY); + ret.rows[1] = vTemp; // 0, 2.0f / h, 0, 0 + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues, M3D_MIdentityR3, _MM_SHUFFLE(3, 2, 3, 2)); + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(2, 0, 0, 0)); + ret.rows[2] = vTemp; // 0, 0, fRange, 0.f + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(3, 1, 0, 0)); + ret.rows[3] = vTemp; // 0, 0, -fRange * near, 1.0f + return ret; +#endif +} + +INLINE_AVX_FIX M3D_MATRIX M3D_TransformMatrixOrthographicRH(float w, float h, float near, float far) noexcept { + float fRange = 1.0f / (near - far); + +#ifdef DISABLE_INTRINSICS + M3D_MATRIX ret; + ret.mat[0][0] = 2.0f / w; + ret.mat[0][1] = 0.0f; + ret.mat[0][2] = 0.0f; + ret.mat[0][3] = 0.0f; + + ret.mat[1][0] = 0.0f; + ret.mat[1][1] = 2.0f / h; + ret.mat[1][2] = 0.0f; + ret.mat[1][3] = 0.0f; + + ret.mat[2][0] = 0.0f; + ret.mat[2][1] = 0.0f; + ret.mat[2][2] = fRange; + ret.mat[2][3] = 0.0f; + + ret.mat[3][0] = 0.0f; + ret.mat[3][1] = 0.0f; + ret.mat[3][2] = fRange * near; + ret.mat[3][3] = 1.0f; + return ret; +#else + M3D_VECTOR rMem = { + 2.0f / w, + 2.0f / h, + fRange, + fRange * near + }; + + // Copy from memory to SSE register + M3D_VECTOR vValues = rMem; + + M3D_MATRIX ret; + M3D_VECTOR vTemp = _mm_setzero_ps(); + vTemp = _mm_move_ss(vTemp, vValues); + + ret.rows[0] = vTemp; // 2.0f / w, 0, 0, 0 + + vTemp = vValues; + vTemp = _mm_and_ps(vTemp, M3D_MMaskY); + ret.rows[1] = vTemp; // 0, 2.0f / h, 0, 0 + vTemp = _mm_setzero_ps(); + vValues = _mm_shuffle_ps(vValues, M3D_MIdentityR3, _MM_SHUFFLE(3, 2, 3, 2)); + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(2, 0, 0, 0)); + ret.rows[2] = vTemp; // 0, 0, fRange, 0.f + vTemp = _mm_shuffle_ps(vTemp, vValues, _MM_SHUFFLE(3, 1, 0, 0)); + ret.rows[3] = vTemp; // 0, 0, fRange * near, 1.0f + return ret; +#endif +} + INLINE_AVX_FIX M3D_MATRIX M3D_TransformMatrixTranslate(M3D_VECTOR Offset) noexcept { #ifdef DISABLE_INTRINSICS M3D_MATRIX ret; diff --git a/README.md b/README.md index d379ae6..de376e0 100644 --- a/README.md +++ b/README.md @@ -18,6 +18,7 @@ This code has been written with experimentation and education in mind. It is sub I've used some libs for backend boilerplate like: - SFML (window management) +- fmt (logging) - tinyobjloader (OBJ file loading) - Tweaked DirectXMath (Heavy math duty) @@ -32,7 +33,7 @@ the question of the proprietary code issue was quickly answered! ## About -*Actually, 72 coffees have been used to produce this code.* +*Actually, 80 coffees have been used to produce this code.* Feel free to ask question about the code: jackcartersmith@jcsmith.fr diff --git a/srcs.list b/srcs.list index 009603b..2089c8a 100644 --- a/srcs.list +++ b/srcs.list @@ -34,6 +34,8 @@ set(GAME_SCRS set(GRAPHS_SCRS Engine/Graphics/3DRenderer.cpp Engine/Graphics/3DRenderer.hpp + Engine/Graphics/InfoScreen.cpp + Engine/Graphics/InfoScreen.hpp Engine/Graphics/Camera.cpp Engine/Graphics/Camera.hpp Engine/Graphics/UI.cpp