From 18489da2a4eb2e5e83b3877b77622e5dd8ae9321 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 18:40:13 +0200 Subject: [PATCH 01/88] Moved transformation functions to util --- src/renderer/renderer.cpp | 1 + src/util.cpp | 27 +++++++++++++++++++++++++++ src/util.h | 13 +++++++++++++ 3 files changed, 41 insertions(+) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 03fbc939b..93ef633ad 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -272,4 +272,5 @@ void BaseRenderer::DrawProcessedText_LBFont( if (maskedSheet) Flush(); } + } // namespace Impacto diff --git a/src/util.cpp b/src/util.cpp index 6b120f1d6..b15073bab 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2,6 +2,7 @@ #include "profile/game.h" #include +#include namespace Impacto { @@ -16,6 +17,32 @@ glm::mat2 Rotate2D(float angle) { return result; } +glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, + const glm::quat rotation, const glm::vec3 scaling) { + glm::mat4 matrix(1.0f); + matrix = glm::translate(matrix, -origin); + matrix = glm::scale(matrix, scaling); + matrix = glm::toMat4(rotation) * matrix; + matrix = glm::translate(matrix, origin + translation); + return matrix; +} + +glm::vec2 Transform2D(const glm::vec2 pos, const glm::vec2 translation, + const glm::vec2 origin, const float rotation, + const glm::vec2 scaling) { + return Transformation3D(glm::vec3(translation, 0.0f), glm::vec3(origin, 0.0f), + glm::quat(rotation, {0.0f, 0.0f, 1.0f}), + glm::vec3(scaling, 1.0f)) * + glm::vec4(pos, 0.0f, 0.0f); +} + +glm::vec3 Transform3D(const glm::vec3 pos, const glm::vec3 translation, + const glm::vec3 origin, const glm::quat rotation, + const glm::vec3 scaling) { + return Transformation3D(translation, origin, rotation, scaling) * + glm::vec4(pos, 0.0f); +} + glm::vec2 DesignToNDC(glm::vec2 xy) { glm::vec2 result; result.x = (xy.x / (Profile::DesignWidth * 0.5f)) - 1.0f; diff --git a/src/util.h b/src/util.h index 833b78e7b..46709669c 100644 --- a/src/util.h +++ b/src/util.h @@ -51,6 +51,19 @@ concept is_any_of = std::disjunction_v...>; glm::mat2 Rotate2D(float angle); +glm::mat4 Transformation3D(glm::vec3 translation, + glm::vec3 origin = glm::vec3(0.0f), + glm::quat rotation = glm::quat(), + glm::vec2 scaling = glm::vec2(1.0f)); + +glm::vec2 Transform2D(glm::vec2 pos, glm::vec2 translation, + glm::vec2 origin = glm::vec2(0.0f), float rotation = 0.0f, + glm::vec2 scaling = glm::vec2(1.0f)); +glm::vec3 Transform3D(glm::vec3 pos, glm::vec3 translation, + glm::vec3 origin = glm::vec3(0.0f), + glm::quat rotation = glm::quat(), + glm::vec2 scaling = glm::vec2(1.0f)); + struct Rect; struct RectF { From ad2d530fc01fe701e381c3d4e8cef7ff0ed3ce51 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 18:41:37 +0200 Subject: [PATCH 02/88] Added ScrWorkAngleToRad function to util --- profiles/common/scriptvars.lua | 4 ++++ src/background2d.cpp | 11 ++++++++--- src/background2d.h | 2 +- src/scriptvars.h | 4 ++++ src/util.h | 3 +++ 5 files changed, 20 insertions(+), 4 deletions(-) diff --git a/profiles/common/scriptvars.lua b/profiles/common/scriptvars.lua index c0032c6cf..1f0afd0e8 100644 --- a/profiles/common/scriptvars.lua +++ b/profiles/common/scriptvars.lua @@ -78,6 +78,8 @@ root.ScriptVars = { SW_BGEFF1_OFSY=2801, SW_BGEFF1_ALPHA_OFS=2806, SW_BGEFF1_SIZE_OFS=2802, + SW_BGEFF1_ROTX_OFS=2803, + SW_BGEFF1_ROTY_OFS=2804, SW_BGEFF1_ROTZ_OFS=2805, SW_BGEFF1_MASK_VERTEX1_OFSX=2809, SW_BGEFF1_MASK_VERTEX1_OFSY=2810, @@ -347,6 +349,8 @@ root.ScriptVars = { SW_BGEFF1_MASK_TYPE=6612, SW_BGEFF1_FADECT=6613, SW_BGEFF1_MODE=6614, + SW_BGEFF1_ROTX=6615, + SW_BGEFF1_ROTY=6616, SW_BGEFF1_ROTZ=6617, SW_BGEFF1_ALPHA=6618, SW_BGEFF1_MASKNO=6619, diff --git a/src/background2d.cpp b/src/background2d.cpp index 609c40fea..9801f34c0 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -169,9 +169,14 @@ void Background2D::RenderBgEff(int bgId, int layer) { FadeCount = ScrWork[SW_BGEFF1_FADECT + structOffset]; FadeRange = ScrWork[SW_BGEFF1_MASKFADERANGE + structOffset]; - Angle = (ScrWork[SW_BGEFF1_ROTZ + structOffset] + - ScrWork[SW_BGEFF1_ROTZ_OFS + structOfsOffset]) * - (float)(2.0f * M_PI / (float)(1 << 16)); + Angle = glm::vec3( + ScrWorkAngleToRad((float)(ScrWork[SW_BGEFF1_ROTX + structOffset] + + ScrWork[SW_BGEFF1_ROTX_OFS + structOfsOffset])), + ScrWorkAngleToRad((float)(ScrWork[SW_BGEFF1_ROTY + structOffset] + + ScrWork[SW_BGEFF1_ROTY_OFS + structOfsOffset])), + ScrWorkAngleToRad( + (float)(ScrWork[SW_BGEFF1_ROTZ + structOffset] + + ScrWork[SW_BGEFF1_ROTZ_OFS + structOfsOffset]))); Scale = glm::vec2((ScrWork[SW_BGEFF1_SIZE + structOffset] + ScrWork[SW_BGEFF1_SIZE_OFS + structOfsOffset]) / diff --git a/src/background2d.h b/src/background2d.h index 36b91894a..c0c6318bf 100644 --- a/src/background2d.h +++ b/src/background2d.h @@ -39,7 +39,7 @@ class Background2D : public Loadable { glm::vec2 DisplayCoords; glm::vec2 Origin = {0.0f, 0.0f}; glm::vec2 Scale = {1.0f, 1.0f}; - float Angle = 0.0f; + glm::vec3 Angle = glm::vec3(0.0f); glm::vec4 Tint = glm::vec4(1.0f); int MaskNumber; diff --git a/src/scriptvars.h b/src/scriptvars.h index 76c8de13a..4ae0b2106 100644 --- a/src/scriptvars.h +++ b/src/scriptvars.h @@ -82,6 +82,8 @@ V(SW_BGEFF1_OFSX) V(SW_BGEFF1_OFSY) V(SW_BGEFF1_ALPHA_OFS) V(SW_BGEFF1_SIZE_OFS) +V(SW_BGEFF1_ROTX_OFS) +V(SW_BGEFF1_ROTY_OFS) V(SW_BGEFF1_ROTZ_OFS) V(SW_BGEFF1_MASK_VERTEX1_OFSX) V(SW_BGEFF1_MASK_VERTEX1_OFSY) @@ -346,6 +348,8 @@ V(SW_BGEFF1_PRI) V(SW_BGEFF1_MASK_TYPE) V(SW_BGEFF1_FADECT) V(SW_BGEFF1_MODE) +V(SW_BGEFF1_ROTX) +V(SW_BGEFF1_ROTY) V(SW_BGEFF1_ROTZ) V(SW_BGEFF1_ALPHA) V(SW_BGEFF1_MASKNO) diff --git a/src/util.h b/src/util.h index 46709669c..0a1ab7ebd 100644 --- a/src/util.h +++ b/src/util.h @@ -299,6 +299,9 @@ inline float NormalizeRad(float rad) { if (rad < 0) rad += 2.0f * (float)M_PI; return rad - (float)M_PI; } +constexpr float ScrWorkAngleToRad(float angle) { + return angle * (float)(2.0f * M_PI / (float)(1 << 16)); +} inline bool StringEndsWith(std::string const& str, std::string const& ending) { if (str.length() < ending.length()) return false; From 8705e5393a647fdfccacfecbc95c7b8426e893ef Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 19:38:24 +0200 Subject: [PATCH 03/88] Moved renderer Quad methods to static base renderer methods --- src/renderer/dx9/renderer.cpp | 231 ++--------------------------- src/renderer/dx9/renderer.h | 17 --- src/renderer/opengl/renderer.cpp | 241 +++---------------------------- src/renderer/opengl/renderer.h | 17 --- src/renderer/renderer.cpp | 187 ++++++++++++++++++++++++ src/renderer/renderer.h | 27 ++++ src/renderer/vulkan/renderer.cpp | 218 ++-------------------------- src/renderer/vulkan/renderer.h | 14 -- 8 files changed, 261 insertions(+), 691 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index d9f7f0d9b..d571ff01a 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -298,7 +298,7 @@ void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -403,7 +403,7 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -440,7 +440,7 @@ void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPositionOffset(sprite.Bounds, topLeft, displayOffset, scale, angle, (uintptr_t)&vertices[0].Position, @@ -491,9 +491,9 @@ void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -548,9 +548,9 @@ void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, (uintptr_t)&vertices[0].Position, @@ -685,9 +685,9 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -746,9 +746,9 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -791,11 +791,11 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -804,209 +804,6 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, vertices[i].Tint = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); } -inline void Renderer::QuadSetUVFlipped(RectF const& spriteBounds, - float designWidth, float designHeight, - uintptr_t uvs, int stride) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - // top-left - *(glm::vec2*)(uvs + 0 * stride) = glm::vec2(leftUV, topUV); - // bottom-left - *(glm::vec2*)(uvs + 1 * stride) = glm::vec2(leftUV, bottomUV); - // bottom-right - *(glm::vec2*)(uvs + 2 * stride) = glm::vec2(rightUV, bottomUV); - // top-right - *(glm::vec2*)(uvs + 3 * stride) = glm::vec2(rightUV, topUV); -} - -inline void Renderer::QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - glm::vec2 bottomLeft(leftUV, bottomUV); - glm::vec2 topLeft(leftUV, topUV); - glm::vec2 topRight(rightUV, topUV); - glm::vec2 bottomRight(rightUV, bottomUV); - - if (angle != 0.0f) { - glm::vec2 center = (bottomLeft + topRight) * 0.5f; // Center of the quad - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(uvs + 0 * stride) = bottomLeft; - // top-left - *(glm::vec2*)(uvs + 1 * stride) = topLeft; - // top-right - *(glm::vec2*)(uvs + 2 * stride) = topRight; - // bottom-right - *(glm::vec2*)(uvs + 3 * stride) = bottomRight; -} - -inline void Renderer::QuadSetPositionOffset( - RectF const& spriteBounds, glm::vec2 displayXY, glm::vec2 displayOffset, - glm::vec2 scale, float angle, uintptr_t positions, int stride, bool toNDC) { - glm::vec2 topLeft = {0.0f, 0.0f}; - glm::vec2 bottomLeft = {0.0f, spriteBounds.Height}; - glm::vec2 topRight = {spriteBounds.Width, 0.0f}; - glm::vec2 bottomRight = {spriteBounds.Width, spriteBounds.Height}; - - // Translate to origin - topLeft -= displayOffset; - bottomLeft -= displayOffset; - topRight -= displayOffset; - bottomRight -= displayOffset; - - // Scale - bottomLeft *= scale; - topLeft *= scale; - topRight *= scale; - bottomRight *= scale; - - // Rotate - if (angle != 0.0f) { - const glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * bottomLeft; - topLeft = rot * topLeft; - topRight = rot * topRight; - bottomRight = rot * bottomRight; - } - - // Translate to the desired screen position - bottomLeft += displayOffset + displayXY; - topLeft += displayOffset + displayXY; - topRight += displayOffset + displayXY; - bottomRight += displayOffset + displayXY; - - if (toNDC) { - bottomLeft = DesignToNDC(bottomLeft); - topLeft = DesignToNDC(topLeft); - topRight = DesignToNDC(topRight); - bottomRight = DesignToNDC(bottomRight); - } - - // Store the transformed positions - *(glm::vec2*)(positions + 0 * stride) = bottomLeft; - *(glm::vec2*)(positions + 1 * stride) = topLeft; - *(glm::vec2*)(positions + 2 * stride) = topRight; - *(glm::vec2*)(positions + 3 * stride) = bottomRight; -} - -inline void Renderer::QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride) { - glm::vec2 bottomLeft = - glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); - glm::vec2 topLeft = glm::vec2(transformedQuad.X, transformedQuad.Y); - glm::vec2 topRight = - glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y); - glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, - transformedQuad.Y + transformedQuad.Height); - - if (angle != 0.0f) { - glm::vec2 center = transformedQuad.Center(); - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(bottomLeft); - // top-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(topLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(topRight); - // bottom-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(bottomRight); -} - -inline void Renderer::QuadSetPosition(CornersQuad destQuad, float angle, - uintptr_t positions, int stride) { - if (angle != 0.0f) { - glm::vec2 center = (destQuad.BottomLeft + destQuad.TopRight) * 0.5f; - glm::mat2 rot = Rotate2D(angle); - - destQuad.BottomLeft = rot * (destQuad.BottomLeft - center) + center; - destQuad.TopLeft = rot * (destQuad.TopLeft - center) + center; - destQuad.TopRight = rot * (destQuad.TopRight - center) + center; - destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.BottomLeft); - // top-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.TopLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.TopRight); - // bottom-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.BottomRight); -} - -void Renderer::QuadSetPosition3DRotated(RectF const& transformedQuad, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - uintptr_t positions, int stride) { - float widthNormalized = transformedQuad.Width / (Profile::DesignWidth * 0.5f); - float heightNormalized = - transformedQuad.Height / (Profile::DesignHeight * 0.5f); - - glm::vec4 corners[4]{ - // bottom-left - {glm::vec2(-widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}, - // top-left - {glm::vec2(-widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // top-right - {glm::vec2(widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // bottom-right - {glm::vec2(widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}}; - - glm::mat4 transform = - glm::translate(glm::mat4(1.0f), - glm::vec3(DesignToNDC(transformedQuad.Center()), 0)) * - glm::mat4_cast(rot); - - glm::vec4 vanishingPointNDC(DesignToNDC(vanishingPoint), 0, 0); - - for (int i = 0; i < 4; i++) { - corners[i] = transform * corners[i]; - } - - if (stayInScreen) { - float maxZ = 0.0f; - for (int i = 0; i < 4; i++) { - if (corners[i].z > maxZ) maxZ = corners[i].z; - } - for (int i = 0; i < 4; i++) { - corners[i].z -= maxZ; - } - } - - for (int i = 0; i < 4; i++) { - // perspective - corners[i] -= vanishingPointNDC; - corners[i].x *= (depth / (depth - corners[i].z)); - corners[i].y *= (depth / (depth - corners[i].z)); - corners[i] += vanishingPointNDC; - - *(glm::vec2*)(positions + i * stride) = corners[i]; - } -} - void Renderer::EnsureSpaceAvailable(int vertices, int vertexSize, int indices) { if (VertexBufferFill + vertices * vertexSize > VertexBufferSize || IndexBufferFill + indices > IndexBufferCount) { @@ -1116,7 +913,7 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, IndexBufferFill += 6; QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 9ca66074c..0fb23a71e 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -112,23 +112,6 @@ class Renderer : public BaseRenderer { void EnsureShader(Shader* shader, bool flush = true); void Flush(); - void QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle = 0.0f); - void QuadSetPositionOffset(RectF const& spriteBounds, glm::vec2 topLeftPos, - glm::vec2 displayOffset, glm::vec2 scale, - float angle, uintptr_t positions, int stride, - bool toNDC = true); - void QuadSetUVFlipped(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride); - void QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride); - void QuadSetPosition(CornersQuad destQuad, float angle, uintptr_t positions, - int stride); - void QuadSetPosition3DRotated(RectF const& transformedQuad, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, uintptr_t positions, int stride); - DirectX9Window* DXWindow; IDirect3D9* Interface; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 6f337489c..2e4a86540 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -296,7 +296,7 @@ void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -393,11 +393,11 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, if (sprite.Sheet.IsScreenCap) { QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } else { QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, @@ -517,11 +517,11 @@ void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, if (sprite.Sheet.IsScreenCap) { QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } else { QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } @@ -583,15 +583,15 @@ void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, if (sprite.Sheet.IsScreenCap) { QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } else { QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -657,15 +657,15 @@ void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, if (sprite.Sheet.IsScreenCap) { QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } else { QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, (uintptr_t)&vertices[0].Position, @@ -738,10 +738,10 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -794,15 +794,15 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, if (sprite.Sheet.IsScreenCap) { QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } else { QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -856,219 +856,16 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, (uintptr_t)&vertices[0].UV, + sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); } -inline void Renderer::QuadSetUVFlipped(RectF const& spriteBounds, - float designWidth, float designHeight, - uintptr_t uvs, int stride) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - // top-left - *(glm::vec2*)(uvs + 0 * stride) = glm::vec2(leftUV, topUV); - // bottom-left - *(glm::vec2*)(uvs + 1 * stride) = glm::vec2(leftUV, bottomUV); - // bottom-right - *(glm::vec2*)(uvs + 2 * stride) = glm::vec2(rightUV, bottomUV); - // top-right - *(glm::vec2*)(uvs + 3 * stride) = glm::vec2(rightUV, topUV); -} - -inline void Renderer::QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - glm::vec2 bottomLeft(leftUV, bottomUV); - glm::vec2 topLeft(leftUV, topUV); - glm::vec2 topRight(rightUV, topUV); - glm::vec2 bottomRight(rightUV, bottomUV); - - if (angle != 0.0f) { - glm::vec2 center = (bottomLeft + topRight) * 0.5f; // Center of the quad - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(uvs + 0 * stride) = bottomLeft; - // top-left - *(glm::vec2*)(uvs + 1 * stride) = topLeft; - // top-right - *(glm::vec2*)(uvs + 2 * stride) = topRight; - // bottom-right - *(glm::vec2*)(uvs + 3 * stride) = bottomRight; -} - -inline void Renderer::QuadSetPositionOffset( - RectF const& spriteBounds, glm::vec2 displayXY, glm::vec2 displayOffset, - glm::vec2 scale, float angle, uintptr_t positions, int stride, bool toNDC) { - glm::vec2 topLeft = {0.0f, 0.0f}; - glm::vec2 bottomLeft = {0.0f, spriteBounds.Height}; - glm::vec2 topRight = {spriteBounds.Width, 0.0f}; - glm::vec2 bottomRight = {spriteBounds.Width, spriteBounds.Height}; - - // Translate to origin - topLeft -= displayOffset; - bottomLeft -= displayOffset; - topRight -= displayOffset; - bottomRight -= displayOffset; - - // Scale - bottomLeft *= scale; - topLeft *= scale; - topRight *= scale; - bottomRight *= scale; - - // Rotate - if (angle != 0.0f) { - const glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * bottomLeft; - topLeft = rot * topLeft; - topRight = rot * topRight; - bottomRight = rot * bottomRight; - } - - // Translate to the desired screen position - bottomLeft += displayOffset + displayXY; - topLeft += displayOffset + displayXY; - topRight += displayOffset + displayXY; - bottomRight += displayOffset + displayXY; - - if (toNDC) { - bottomLeft = DesignToNDC(bottomLeft); - topLeft = DesignToNDC(topLeft); - topRight = DesignToNDC(topRight); - bottomRight = DesignToNDC(bottomRight); - } - - // Store the transformed positions - *(glm::vec2*)(positions + 0 * stride) = bottomLeft; - *(glm::vec2*)(positions + 1 * stride) = topLeft; - *(glm::vec2*)(positions + 2 * stride) = topRight; - *(glm::vec2*)(positions + 3 * stride) = bottomRight; -} - -inline void Renderer::QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride) { - glm::vec2 bottomLeft = - glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); - glm::vec2 topLeft = glm::vec2(transformedQuad.X, transformedQuad.Y); - glm::vec2 topRight = - glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y); - glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, - transformedQuad.Y + transformedQuad.Height); - - if (angle != 0.0f) { - glm::vec2 center = transformedQuad.Center(); - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(bottomLeft); - // top-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(topLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(topRight); - // bottom-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(bottomRight); -} - -inline void Renderer::QuadSetPosition(CornersQuad destQuad, float angle, - uintptr_t positions, int stride) { - if (angle != 0.0f) { - glm::vec2 center = (destQuad.BottomLeft + destQuad.TopRight) * 0.5f; - glm::mat2 rot = Rotate2D(angle); - - destQuad.BottomLeft = rot * (destQuad.BottomLeft - center) + center; - destQuad.TopLeft = rot * (destQuad.TopLeft - center) + center; - destQuad.TopRight = rot * (destQuad.TopRight - center) + center; - destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.BottomLeft); - // top-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.TopLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.TopRight); - // bottom-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.BottomRight); -} - -void Renderer::QuadSetPosition3DRotated(RectF const& transformedQuad, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - uintptr_t positions, int stride) { - float widthNormalized = transformedQuad.Width / (Profile::DesignWidth * 0.5f); - float heightNormalized = - transformedQuad.Height / (Profile::DesignHeight * 0.5f); - - glm::vec4 corners[4]{ - // bottom-left - {glm::vec2(-widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}, - // top-left - {glm::vec2(-widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // top-right - {glm::vec2(widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // bottom-right - {glm::vec2(widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}}; - - glm::mat4 transform = - glm::translate(glm::mat4(1.0f), - glm::vec3(DesignToNDC(transformedQuad.Center()), 0)) * - glm::mat4_cast(rot); - - glm::vec4 vanishingPointNDC(DesignToNDC(vanishingPoint), 0, 0); - - for (int i = 0; i < 4; i++) { - corners[i] = transform * corners[i]; - } - - if (stayInScreen) { - float maxZ = 0.0f; - for (int i = 0; i < 4; i++) { - if (corners[i].z > maxZ) maxZ = corners[i].z; - } - for (int i = 0; i < 4; i++) { - corners[i].z -= maxZ; - } - } - - for (int i = 0; i < 4; i++) { - // perspective - corners[i] -= vanishingPointNDC; - corners[i].x *= (depth / (depth - corners[i].z)); - corners[i].y *= (depth / (depth - corners[i].z)); - corners[i] += vanishingPointNDC; - - *(glm::vec2*)(positions + i * stride) = corners[i]; - } -} - void Renderer::EnsureSpaceAvailable(int vertices, int vertexSize, int indices) { if (VertexBufferFill + vertices * vertexSize > VertexBufferSize || IndexBufferFill + indices > IndexBufferCount) { @@ -1169,7 +966,7 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, IndexBufferFill += 6; QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 24fa88415..1c2ff1dd2 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -130,23 +130,6 @@ class Renderer : public BaseRenderer { void EnsureModeSprite(bool inverted); void Flush(); - void QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle = 0.0f); - void QuadSetPositionOffset(RectF const& spriteBounds, glm::vec2 displayXY, - glm::vec2 displayOffset, glm::vec2 scale, - float angle, uintptr_t positions, int stride, - bool toNDC = true); - void QuadSetUVFlipped(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride); - void QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride); - void QuadSetPosition(CornersQuad destQuad, float angle, uintptr_t positions, - int stride); - void QuadSetPosition3DRotated(RectF const& transformedQuad, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, uintptr_t positions, int stride); - GLWindow* OpenGLWindow; GLuint ShaderProgramSprite; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 93ef633ad..103ab8b74 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -273,4 +273,191 @@ void BaseRenderer::DrawProcessedText_LBFont( if (maskedSheet) Flush(); } +void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, float angle, + uintptr_t positions, int stride) { + glm::vec2 bottomLeft = + glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); + glm::vec2 topLeft = glm::vec2(transformedQuad.X, transformedQuad.Y); + glm::vec2 topRight = + glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y); + glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, + transformedQuad.Y + transformedQuad.Height); + + if (angle != 0.0f) { + glm::vec2 center = transformedQuad.Center(); + glm::mat2 rot = Rotate2D(angle); + + bottomLeft = rot * (bottomLeft - center) + center; + topLeft = rot * (topLeft - center) + center; + topRight = rot * (topRight - center) + center; + bottomRight = rot * (bottomRight - center) + center; + } + + // top-left + *(glm::vec2*)(positions + 0 * stride) = DesignToNDCNonFlipped(topLeft); + // bottom-left + *(glm::vec2*)(positions + 1 * stride) = DesignToNDCNonFlipped(bottomLeft); + // bottom-right + *(glm::vec2*)(positions + 2 * stride) = DesignToNDCNonFlipped(bottomRight); + // top-right + *(glm::vec2*)(positions + 3 * stride) = DesignToNDCNonFlipped(topRight); +} + +void BaseRenderer::QuadSetPosition(CornersQuad destQuad, float angle, + uintptr_t positions, int stride) { + if (angle != 0.0f) { + glm::vec2 center = (destQuad.BottomLeft + destQuad.TopRight) * 0.5f; + glm::mat2 rot = Rotate2D(angle); + + destQuad.BottomLeft = rot * (destQuad.BottomLeft - center) + center; + destQuad.TopLeft = rot * (destQuad.TopLeft - center) + center; + destQuad.TopRight = rot * (destQuad.TopRight - center) + center; + destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; + } + + // bottom-left + *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.BottomLeft); + // top-left + *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.TopLeft); + // top-right + *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.TopRight); + // bottom-right + *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.BottomRight); +} + +void BaseRenderer::QuadSetPositionOffset( + RectF const& spriteBounds, glm::vec2 displayXY, glm::vec2 displayOffset, + glm::vec2 scale, float angle, uintptr_t positions, int stride, bool toNDC) { + glm::vec2 topLeft = {0.0f, 0.0f}; + glm::vec2 bottomLeft = {0.0f, spriteBounds.Height}; + glm::vec2 topRight = {spriteBounds.Width, 0.0f}; + glm::vec2 bottomRight = {spriteBounds.Width, spriteBounds.Height}; + + // Translate to origin + topLeft -= displayOffset; + bottomLeft -= displayOffset; + topRight -= displayOffset; + bottomRight -= displayOffset; + + // Scale + bottomLeft *= scale; + topLeft *= scale; + topRight *= scale; + bottomRight *= scale; + + // Rotate + if (angle != 0.0f) { + const glm::mat2 rot = Rotate2D(angle); + + bottomLeft = rot * bottomLeft; + topLeft = rot * topLeft; + topRight = rot * topRight; + bottomRight = rot * bottomRight; + } + + // Translate to the desired screen position + bottomLeft += displayOffset + displayXY; + topLeft += displayOffset + displayXY; + topRight += displayOffset + displayXY; + bottomRight += displayOffset + displayXY; + + if (toNDC) { + topLeft = DesignToNDCNonFlipped(topLeft); + bottomLeft = DesignToNDCNonFlipped(bottomLeft); + bottomRight = DesignToNDCNonFlipped(bottomRight); + topRight = DesignToNDCNonFlipped(topRight); + } + + // Store the transformed positions + *(glm::vec2*)(positions + 0 * stride) = topLeft; + *(glm::vec2*)(positions + 1 * stride) = bottomLeft; + *(glm::vec2*)(positions + 2 * stride) = bottomRight; + *(glm::vec2*)(positions + 3 * stride) = topRight; +} + +void BaseRenderer::QuadSetPosition3DRotated(RectF const& transformedQuad, + float depth, + glm::vec2 vanishingPoint, + bool stayInScreen, glm::quat rot, + uintptr_t positions, int stride) { + float widthNormalized = transformedQuad.Width / (Profile::DesignWidth * 0.5f); + float heightNormalized = + transformedQuad.Height / (Profile::DesignHeight * 0.5f); + + glm::vec4 corners[4]{ + // top-left + {glm::vec2(-widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, + // top-right + {glm::vec2(widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, + // bottom-right + {glm::vec2(widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}, + // bottom-left + {glm::vec2(-widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}}; + + glm::mat4 transform = + glm::translate( + glm::mat4(1.0f), + glm::vec3(DesignToNDCNonFlipped(transformedQuad.Center()), 0)) * + glm::mat4_cast(rot); + + glm::vec4 vanishingPointNDC(DesignToNDCNonFlipped(vanishingPoint), 0, 0); + + for (int i = 0; i < 4; i++) { + corners[i] = transform * corners[i]; + } + + if (stayInScreen) { + float maxZ = 0.0f; + for (int i = 0; i < 4; i++) { + if (corners[i].z > maxZ) maxZ = corners[i].z; + } + for (int i = 0; i < 4; i++) { + corners[i].z -= maxZ; + } + } + + for (int i = 0; i < 4; i++) { + // perspective + corners[i] -= vanishingPointNDC; + corners[i].x *= (depth / (depth - corners[i].z)); + corners[i].y *= (depth / (depth - corners[i].z)); + corners[i] += vanishingPointNDC; + + *(glm::vec2*)(positions + i * stride) = corners[i]; + } +} + +void BaseRenderer::QuadSetUV(const RectF spriteBounds, const float designWidth, + const float designHeight, glm::vec2* const uvs, + const size_t stride, const float angle) { + float topUV = (spriteBounds.Y / designHeight); + float leftUV = (spriteBounds.X / designWidth); + float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); + float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); + + glm::vec2 bottomLeft(leftUV, bottomUV); + glm::vec2 topLeft(leftUV, topUV); + glm::vec2 topRight(rightUV, topUV); + glm::vec2 bottomRight(rightUV, bottomUV); + + if (angle != 0.0f) { + glm::vec2 center = (bottomLeft + topRight) * 0.5f; // Center of the quad + glm::mat2 rot = Rotate2D(angle); + + bottomLeft = rot * (bottomLeft - center) + center; + topLeft = rot * (topLeft - center) + center; + topRight = rot * (topRight - center) + center; + bottomRight = rot * (bottomRight - center) + center; + } + + // bottom-left + *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = bottomLeft; + // top-left + *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = topLeft; + // top-right + *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = topRight; + // bottom-right + *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = bottomRight; +} + } // namespace Impacto diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index ffd52a734..b5857e48f 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -183,6 +183,33 @@ class BaseRenderer { glm::vec4 Tint; glm::vec2 MaskUV; }; + + static void QuadSetUV(const RectF spriteBounds, float designWidth, + float designHeight, glm::vec2* uvs, size_t stride, + float angle = 0.0f); + + static void QuadSetUVFlipped(const RectF spriteBounds, float designWidth, + float designHeight, glm::vec2* uvs, + size_t stride) { + QuadSetUV({spriteBounds.X, spriteBounds.Y + spriteBounds.Height, + spriteBounds.Width, -spriteBounds.Height}, + designWidth, designHeight, uvs, stride); + } + + static void QuadSetPosition(RectF const& transformedQuad, float angle, + uintptr_t positions, int stride); + static void QuadSetPosition(CornersQuad destQuad, float angle, + uintptr_t positions, int stride); + + static void QuadSetPositionOffset(RectF const& spriteBounds, + glm::vec2 displayXY, + glm::vec2 displayOffset, glm::vec2 scale, + float angle, uintptr_t positions, + int stride, bool toNDC = true); + static void QuadSetPosition3DRotated(RectF const& transformedQuad, + float depth, glm::vec2 vanishingPoint, + bool stayInScreen, glm::quat rot, + uintptr_t positions, int stride); }; inline BaseRenderer* Renderer; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 32eb07f9b..87edc7780 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1166,7 +1166,7 @@ void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1299,7 +1299,7 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1336,7 +1336,7 @@ void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPositionOffset(sprite.Bounds, topLeft, centerSprite, scale, angle, (uintptr_t)&vertices[0].Position, @@ -1405,9 +1405,9 @@ void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1480,9 +1480,9 @@ void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, (uintptr_t)&vertices[0].Position, @@ -1650,9 +1650,9 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1748,9 +1748,9 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1812,9 +1812,9 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - (uintptr_t)&vertices[0].MaskUV, sizeof(VertexBufferSprites)); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); @@ -1841,196 +1841,6 @@ inline void Renderer::MakeQuad() { } } -inline void Renderer::QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - glm::vec2 bottomLeft(leftUV, bottomUV); - glm::vec2 topLeft(leftUV, topUV); - glm::vec2 topRight(rightUV, topUV); - glm::vec2 bottomRight(rightUV, bottomUV); - - if (angle != 0.0f) { - glm::vec2 center = (bottomLeft + topRight) * 0.5f; // Center of the quad - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // top-left - *(glm::vec2*)(uvs + 0 * stride) = topLeft; - // bottom-left - *(glm::vec2*)(uvs + 1 * stride) = bottomLeft; - // bottom-right - *(glm::vec2*)(uvs + 2 * stride) = bottomRight; - // top-right - *(glm::vec2*)(uvs + 3 * stride) = topRight; -} - -inline void Renderer::QuadSetPositionOffset( - RectF const& spriteBounds, glm::vec2 displayXY, glm::vec2 displayOffset, - glm::vec2 scale, float angle, uintptr_t positions, int stride, bool toNDC) { - glm::vec2 topLeft = {0.0f, 0.0f}; - glm::vec2 bottomLeft = {0.0f, spriteBounds.Height}; - glm::vec2 topRight = {spriteBounds.Width, 0.0f}; - glm::vec2 bottomRight = {spriteBounds.Width, spriteBounds.Height}; - - // Translate to origin - topLeft -= displayOffset; - bottomLeft -= displayOffset; - topRight -= displayOffset; - bottomRight -= displayOffset; - - // Scale - bottomLeft *= scale; - topLeft *= scale; - topRight *= scale; - bottomRight *= scale; - - // Rotate - if (angle != 0.0f) { - const glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * bottomLeft; - topLeft = rot * topLeft; - topRight = rot * topRight; - bottomRight = rot * bottomRight; - } - - // Translate to the desired screen position - bottomLeft += displayOffset + displayXY; - topLeft += displayOffset + displayXY; - topRight += displayOffset + displayXY; - bottomRight += displayOffset + displayXY; - - if (toNDC) { - topLeft = DesignToNDCNonFlipped(topLeft); - bottomLeft = DesignToNDCNonFlipped(bottomLeft); - bottomRight = DesignToNDCNonFlipped(bottomRight); - topRight = DesignToNDCNonFlipped(topRight); - } - - // Store the transformed positions - *(glm::vec2*)(positions + 0 * stride) = topLeft; - *(glm::vec2*)(positions + 1 * stride) = bottomLeft; - *(glm::vec2*)(positions + 2 * stride) = bottomRight; - *(glm::vec2*)(positions + 3 * stride) = topRight; -} - -inline void Renderer::QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride) { - glm::vec2 bottomLeft = - glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); - glm::vec2 topLeft = glm::vec2(transformedQuad.X, transformedQuad.Y); - glm::vec2 topRight = - glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y); - glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, - transformedQuad.Y + transformedQuad.Height); - - if (angle != 0.0f) { - glm::vec2 center = transformedQuad.Center(); - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - - // top-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDCNonFlipped(topLeft); - // bottom-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDCNonFlipped(bottomLeft); - // bottom-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDCNonFlipped(bottomRight); - // top-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDCNonFlipped(topRight); -} - -inline void Renderer::QuadSetPosition(CornersQuad destQuad, float angle, - uintptr_t positions, int stride) { - if (angle != 0.0f) { - glm::vec2 center = (destQuad.BottomLeft + destQuad.TopRight) * 0.5f; - glm::mat2 rot = Rotate2D(angle); - - destQuad.BottomLeft = rot * (destQuad.BottomLeft - center) + center; - destQuad.TopLeft = rot * (destQuad.TopLeft - center) + center; - destQuad.TopRight = rot * (destQuad.TopRight - center) + center; - destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; - } - - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = - DesignToNDCNonFlipped(destQuad.TopLeft); - // top-left - *(glm::vec2*)(positions + 1 * stride) = - DesignToNDCNonFlipped(destQuad.BottomLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = - DesignToNDCNonFlipped(destQuad.BottomRight); - // bottom-right - *(glm::vec2*)(positions + 3 * stride) = - DesignToNDCNonFlipped(destQuad.TopRight); -} - -void Renderer::QuadSetPosition3DRotated(RectF const& transformedQuad, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - uintptr_t positions, int stride) { - float widthNormalized = transformedQuad.Width / (Profile::DesignWidth * 0.5f); - float heightNormalized = - transformedQuad.Height / (Profile::DesignHeight * 0.5f); - - glm::vec4 corners[4]{ - // top-left - {glm::vec2(-widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // top-right - {glm::vec2(widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // bottom-right - {glm::vec2(widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}, - // bottom-left - {glm::vec2(-widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}}; - - glm::mat4 transform = - glm::translate( - glm::mat4(1.0f), - glm::vec3(DesignToNDCNonFlipped(transformedQuad.Center()), 0)) * - glm::mat4_cast(rot); - - glm::vec4 vanishingPointNDC(DesignToNDCNonFlipped(vanishingPoint), 0, 0); - - for (int i = 0; i < 4; i++) { - corners[i] = transform * corners[i]; - } - - if (stayInScreen) { - float maxZ = 0.0f; - for (int i = 0; i < 4; i++) { - if (corners[i].z > maxZ) maxZ = corners[i].z; - } - for (int i = 0; i < 4; i++) { - corners[i].z -= maxZ; - } - } - - for (int i = 0; i < 4; i++) { - // perspective - corners[i] -= vanishingPointNDC; - corners[i].x *= (depth / (depth - corners[i].z)); - corners[i].y *= (depth / (depth - corners[i].z)); - corners[i] += vanishingPointNDC; - - *(glm::vec2*)(positions + i * stride) = corners[i]; - } -} - void Renderer::EnsureTextureBound(unsigned int texture) { if (CurrentTexture != texture) { ImpLogSlow(LogLevel::Trace, LogChannel::Render, @@ -2149,7 +1959,7 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, VertexBufferFill += 4 * sizeof(VertexBufferSprites); QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - (uintptr_t)&vertices[0].UV, sizeof(VertexBufferSprites)); + &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index e6bcf0d8e..eaa2115b1 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -161,20 +161,6 @@ class Renderer : public BaseRenderer { void Flush(); void MakeQuad(); - void QuadSetUV(RectF const& spriteBounds, float designWidth, - float designHeight, uintptr_t uvs, int stride, - float angle = 0.0f); - void QuadSetPositionOffset(RectF const& spriteBounds, glm::vec2 topLeftPos, - glm::vec2 displayOffset, glm::vec2 scale, - float angle, uintptr_t positions, int stride, - bool toNDC = true); - void QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride); - void QuadSetPosition(CornersQuad destQuad, float angle, uintptr_t positions, - int stride); - void QuadSetPosition3DRotated(RectF const& transformedQuad, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, uintptr_t positions, int stride); bool Drawing = false; From 250accc576cb09f7c53a02da4701d20249005112 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 21:37:46 +0200 Subject: [PATCH 04/88] Added transformation DrawSprite methods to renderer --- src/background2d.cpp | 9 +++++ src/renderer/opengl/renderer.cpp | 69 ++++++++++++++++++++++++++++++++ src/renderer/opengl/renderer.h | 5 +++ src/renderer/renderer.cpp | 23 +++++++++++ src/renderer/renderer.h | 14 +++++++ src/util.cpp | 22 ++++++---- src/util.h | 8 +++- 7 files changed, 142 insertions(+), 8 deletions(-) diff --git a/src/background2d.cpp b/src/background2d.cpp index 9801f34c0..a75aabece 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -227,6 +227,15 @@ void Background2D::RenderBgEff(int bgId, int layer) { Origin = {0.0f, 0.0f}; for (const glm::vec2 vertex : vertices) Origin += vertex / (float)vertexCount; + // Transform vertices + const glm::mat4 transformation = + Transformation3D(glm::vec3(DisplayCoords, 0.0f), glm::vec3(Origin, 0.0f), + Rotation, glm::vec3(Scale, 1.0f)); + std::transform(vertices.begin(), vertices.end(), vertices.begin(), + [transformation](const glm::vec2 vertex) { + return transformation * glm::vec4(vertex, 0.0f, 1.0f); + }); + // Draw if (maskType == 0) { // Rectangle const glm::vec2 maskDimensions = vertices[3] - vertices[0]; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 2e4a86540..c3f3f7b01 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -599,6 +599,75 @@ void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } +void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const std::array& tints, + const bool isInverted, + const bool isSameTexture) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); + return; + } + + if (alpha < 0) alpha = 0; + if (alpha > fadeRange + 256) alpha = fadeRange + 256; + + float alphaRange = 256.0f / fadeRange; + float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + + // Do we have space for one more sprite quad? + EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); + + if (CurrentMode != R2D_Masked) { + Flush(); + CurrentMode = R2D_Masked; + } + + EnsureTextureBound(sprite.Sheet.Texture); + + glBindVertexArray(VAOSprites); + glUseProgram(ShaderProgramMaskedSprite); + glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); + glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), + alphaRange, constAlpha); + glUniform1i(MaskedIsInvertedLocation, isInverted); + glUniform1i(MaskedIsSameTextureLocation, isSameTexture); + + glActiveTexture(GL_TEXTURE0); + glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); + + glActiveTexture(GL_TEXTURE2); + glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); + glBindSampler(2, Sampler); + + // OK, all good, make quad + + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); + VertexBufferFill += 4 * sizeof(VertexBufferSprites); + + IndexBufferFill += 6; + + if (sprite.Sheet.IsScreenCap) { + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, + sprite.Sheet.DesignHeight, &vertices[0].UV, + sizeof(VertexBufferSprites)); + } else { + QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, + sprite.Sheet.DesignHeight, &vertices[0].UV, + sizeof(VertexBufferSprites)); + } + QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + + QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + sizeof(VertexBufferSprites)); + + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; +} + void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, const glm::vec2 pos, const glm::vec2 origin, int alpha, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 1c2ff1dd2..6bab77330 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -69,6 +69,11 @@ class Renderer : public BaseRenderer { int fadeRange, bool isInverted = false, bool isSameTexture = false) override; + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, int fadeRange, + const std::array& tints, bool isInverted, + bool isSameTexture) override; + void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 103ab8b74..fa0eba6fb 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -55,6 +55,29 @@ void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, DrawSprite(sprite, scaledDest, tint, angle, inverted); } +void BaseRenderer::DrawSprite(const Sprite& sprite, + const glm::mat4 transformation, + const glm::vec4 tint, const bool inverted) { + CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), + sprite.ScaledHeight())) + .Transform(transformation); + + DrawSprite(sprite, dest, std::array{tint}, inverted); +} + +void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const int alpha, const int fadeRange, + const glm::mat4 transformation, + const glm::vec4 tint, const bool isInverted, + const bool isSameTexture) { + CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), + sprite.ScaledHeight())) + .Transform(transformation); + + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, + std::array{tint}, isInverted, isSameTexture); +} + void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index b5857e48f..1d869ff72 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -54,6 +54,8 @@ class BaseRenderer { virtual void DrawSprite(Sprite const& sprite, CornersQuad const& dest, std::array const& tints, float angle = 0.0f, bool inverted = false) = 0; + void DrawSprite(const Sprite& sprite, glm::mat4 transformation, + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); virtual void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, glm::vec2 displayOffset, @@ -77,6 +79,18 @@ class BaseRenderer { int fadeRange, bool isInverted = false, bool isSameTexture = false) = 0; + virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, + const std::array& tints, + bool isInverted = false, + bool isSameTexture = false) {} + + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, + int fadeRange, glm::mat4 transformation, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false); + virtual void DrawMaskedSpriteOffset( const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), diff --git a/src/util.cpp b/src/util.cpp index b15073bab..a64b12b0f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -2,10 +2,18 @@ #include "profile/game.h" #include -#include namespace Impacto { +CornersQuad& CornersQuad::Transform(const glm::mat4 transformation) { + TopLeft = transformation * glm::vec4(TopLeft, 0.0f, 1.0f); + TopRight = transformation * glm::vec4(TopRight, 0.0f, 1.0f); + BottomRight = transformation * glm::vec4(BottomRight, 0.0f, 1.0f); + BottomLeft = transformation * glm::vec4(BottomLeft, 0.0f, 1.0f); + + return *this; +} + glm::mat2 Rotate2D(float angle) { glm::mat2 result; float cosa = cosf(angle); @@ -20,10 +28,10 @@ glm::mat2 Rotate2D(float angle) { glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, const glm::quat rotation, const glm::vec3 scaling) { glm::mat4 matrix(1.0f); - matrix = glm::translate(matrix, -origin); - matrix = glm::scale(matrix, scaling); - matrix = glm::toMat4(rotation) * matrix; - matrix = glm::translate(matrix, origin + translation); + matrix = glm::translate(glm::mat4(1.0f), -origin) * matrix; + matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; + matrix = glm::mat4_cast(rotation) * matrix; + matrix = glm::translate(glm::mat4(1.0f), origin + translation) * matrix; return matrix; } @@ -33,14 +41,14 @@ glm::vec2 Transform2D(const glm::vec2 pos, const glm::vec2 translation, return Transformation3D(glm::vec3(translation, 0.0f), glm::vec3(origin, 0.0f), glm::quat(rotation, {0.0f, 0.0f, 1.0f}), glm::vec3(scaling, 1.0f)) * - glm::vec4(pos, 0.0f, 0.0f); + glm::vec4(pos, 0.0f, 1.0f); } glm::vec3 Transform3D(const glm::vec3 pos, const glm::vec3 translation, const glm::vec3 origin, const glm::quat rotation, const glm::vec3 scaling) { return Transformation3D(translation, origin, rotation, scaling) * - glm::vec4(pos, 0.0f); + glm::vec4(pos, 1.0f); } glm::vec2 DesignToNDC(glm::vec2 xy) { diff --git a/src/util.h b/src/util.h index 0a1ab7ebd..b4d484bd0 100644 --- a/src/util.h +++ b/src/util.h @@ -54,7 +54,7 @@ glm::mat2 Rotate2D(float angle); glm::mat4 Transformation3D(glm::vec3 translation, glm::vec3 origin = glm::vec3(0.0f), glm::quat rotation = glm::quat(), - glm::vec2 scaling = glm::vec2(1.0f)); + glm::vec3 scaling = glm::vec3(1.0f)); glm::vec2 Transform2D(glm::vec2 pos, glm::vec2 translation, glm::vec2 origin = glm::vec2(0.0f), float rotation = 0.0f, @@ -199,8 +199,14 @@ struct CornersQuad { {(float)rect.X, (float)(rect.Y + rect.Height)}, {(float)(rect.X + rect.Width), (float)rect.Y}, {(float)(rect.X + rect.Width), (float)(rect.Y + rect.Height)}) {} + + CornersQuad& Transform(glm::mat4 transformation); }; +inline CornersQuad operator*(const glm::mat4 transformation, CornersQuad quad) { + return quad.Transform(transformation); +} + inline constexpr RectF::RectF(Rect const& rect) : RectF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height) {} From cefbc63a9a6ae1a73262b30cceaa390f6fce3c6f Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 21:50:51 +0200 Subject: [PATCH 05/88] Changed Background2D to use quaternions --- src/background2d.cpp | 56 +++++++++++++++++++++----------------------- src/background2d.h | 2 +- src/util.cpp | 5 ++++ src/util.h | 1 + 4 files changed, 34 insertions(+), 30 deletions(-) diff --git a/src/background2d.cpp b/src/background2d.cpp index a75aabece..11713d602 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -169,14 +169,13 @@ void Background2D::RenderBgEff(int bgId, int layer) { FadeCount = ScrWork[SW_BGEFF1_FADECT + structOffset]; FadeRange = ScrWork[SW_BGEFF1_MASKFADERANGE + structOffset]; - Angle = glm::vec3( - ScrWorkAngleToRad((float)(ScrWork[SW_BGEFF1_ROTX + structOffset] + - ScrWork[SW_BGEFF1_ROTX_OFS + structOfsOffset])), - ScrWorkAngleToRad((float)(ScrWork[SW_BGEFF1_ROTY + structOffset] + - ScrWork[SW_BGEFF1_ROTY_OFS + structOfsOffset])), - ScrWorkAngleToRad( - (float)(ScrWork[SW_BGEFF1_ROTZ + structOffset] + - ScrWork[SW_BGEFF1_ROTZ_OFS + structOfsOffset]))); + Rotation = ScrWorkAnglesToQuaternion( + ScrWork[SW_BGEFF1_ROTX + structOffset] + + ScrWork[SW_BGEFF1_ROTX_OFS + structOfsOffset], + ScrWork[SW_BGEFF1_ROTY + structOffset] + + ScrWork[SW_BGEFF1_ROTY_OFS + structOfsOffset], + ScrWork[SW_BGEFF1_ROTZ + structOffset] + + ScrWork[SW_BGEFF1_ROTZ_OFS + structOfsOffset]); Scale = glm::vec2((ScrWork[SW_BGEFF1_SIZE + structOffset] + ScrWork[SW_BGEFF1_SIZE_OFS + structOfsOffset]) / @@ -255,43 +254,42 @@ void Background2D::RenderBgEff(int bgId, int layer) { } void Background2D::RenderRegular() { - Renderer->DrawSpriteOffset(BgSprite, DisplayCoords, Origin, Tint, Scale, - Angle, false); + glm::mat4 transformation = Transformation3D( + {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + Renderer->DrawSprite(BgSprite, transformation, Tint, false); for (int i = 0; i < MaxLinkedBgBuffers; i++) { if (Links[i].Direction != LD_Off && Links[i].LinkedBuffer != NULL) { - Renderer->DrawSpriteOffset(Links[i].LinkedBuffer->BgSprite, - Links[i].DisplayCoords, Origin, Tint, Scale, - Angle, false); + glm::mat4 transformation = + Transformation3D({Links[i].DisplayCoords, 0.0f}, {Origin, 0.0f}, + Rotation, {Scale, 1.0f}); + Renderer->DrawSprite(Links[i].LinkedBuffer->BgSprite, transformation, + Tint, false); } } } void Background2D::RenderMasked() { - Renderer->DrawMaskedSpriteOffset(BgSprite, Masks2D[MaskNumber].MaskSprite, - DisplayCoords, Origin, FadeCount, FadeRange, - Tint, Scale, Angle, false, false, false); + const glm::mat4 transformation = Transformation3D( + {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + + Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, + FadeCount, FadeRange, transformation, Tint, false, + false); } void Background2D::RenderMaskedInverted() { - Renderer->DrawMaskedSpriteOffset(BgSprite, Masks2D[MaskNumber].MaskSprite, - DisplayCoords, Origin, FadeCount, FadeRange, - Tint, Scale, Angle, false, true, false); + const glm::mat4 transformation = Transformation3D( + {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, + FadeCount, FadeRange, transformation, Tint, true, + false); } void Background2D::RenderFade() { Tint.a *= FadeCount / 256.0f; - Renderer->DrawSpriteOffset(BgSprite, DisplayCoords, Origin, Tint, Scale, - Angle, false); - - for (int i = 0; i < MaxLinkedBgBuffers; i++) { - if (Links[i].Direction != LD_Off && Links[i].LinkedBuffer != NULL) { - Renderer->DrawSpriteOffset(Links[i].LinkedBuffer->BgSprite, - Links[i].DisplayCoords, Origin, Tint, Scale, - Angle, false); - } - } + RenderRegular(); } } // namespace Impacto \ No newline at end of file diff --git a/src/background2d.h b/src/background2d.h index c0c6318bf..4d595c2ef 100644 --- a/src/background2d.h +++ b/src/background2d.h @@ -39,7 +39,7 @@ class Background2D : public Loadable { glm::vec2 DisplayCoords; glm::vec2 Origin = {0.0f, 0.0f}; glm::vec2 Scale = {1.0f, 1.0f}; - glm::vec3 Angle = glm::vec3(0.0f); + glm::quat Rotation = glm::quat(); glm::vec4 Tint = glm::vec4(1.0f); int MaskNumber; diff --git a/src/util.cpp b/src/util.cpp index a64b12b0f..a707416be 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -160,4 +160,9 @@ RectF RectF::Coalesce(const RectF& first, const RectF& second) { return rect; } +glm::quat ScrWorkAnglesToQuaternion(const int x, const int y, const int z) { + return glm::quat( + {ScrWorkAngleToRad(x), ScrWorkAngleToRad(y), ScrWorkAngleToRad(z)}); +} + } // namespace Impacto \ No newline at end of file diff --git a/src/util.h b/src/util.h index b4d484bd0..af40088fc 100644 --- a/src/util.h +++ b/src/util.h @@ -308,6 +308,7 @@ inline float NormalizeRad(float rad) { constexpr float ScrWorkAngleToRad(float angle) { return angle * (float)(2.0f * M_PI / (float)(1 << 16)); } +glm::quat ScrWorkAnglesToQuaternion(int x, int y, int z); inline bool StringEndsWith(std::string const& str, std::string const& ending) { if (str.length() < ending.length()) return false; From 535c60542a6198528fc278a4c65575d008e792cc Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 26 Apr 2025 23:13:53 +0200 Subject: [PATCH 06/88] Fix rendering issues --- src/renderer/renderer.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index fa0eba6fb..48b5aadc1 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -62,7 +62,8 @@ void BaseRenderer::DrawSprite(const Sprite& sprite, sprite.ScaledHeight())) .Transform(transformation); - DrawSprite(sprite, dest, std::array{tint}, inverted); + DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, + inverted); } void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, @@ -75,7 +76,8 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, .Transform(transformation); DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, - std::array{tint}, isInverted, isSameTexture); + std::array{tint, tint, tint, tint}, isInverted, + isSameTexture); } void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, From fef6ee01524292237b5aa9b596923d81306f5a08 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 19:32:53 +0200 Subject: [PATCH 07/88] Fixed quad orientation --- src/renderer/renderer.cpp | 40 +++++++++++++++++++-------------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 48b5aadc1..d5b2e7482 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -319,13 +319,13 @@ void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, float angle, } // top-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDCNonFlipped(topLeft); + *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(topLeft); // bottom-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDCNonFlipped(bottomLeft); + *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(bottomLeft); // bottom-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDCNonFlipped(bottomRight); + *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(bottomRight); // top-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDCNonFlipped(topRight); + *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(topRight); } void BaseRenderer::QuadSetPosition(CornersQuad destQuad, float angle, @@ -340,14 +340,14 @@ void BaseRenderer::QuadSetPosition(CornersQuad destQuad, float angle, destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; } - // bottom-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.BottomLeft); // top-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.TopLeft); - // top-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.TopRight); + *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.TopLeft); + // bottom-left + *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.BottomLeft); // bottom-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.BottomRight); + *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.BottomRight); + // top-right + *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.TopRight); } void BaseRenderer::QuadSetPositionOffset( @@ -387,10 +387,10 @@ void BaseRenderer::QuadSetPositionOffset( bottomRight += displayOffset + displayXY; if (toNDC) { - topLeft = DesignToNDCNonFlipped(topLeft); - bottomLeft = DesignToNDCNonFlipped(bottomLeft); - bottomRight = DesignToNDCNonFlipped(bottomRight); - topRight = DesignToNDCNonFlipped(topRight); + topLeft = DesignToNDC(topLeft); + bottomLeft = DesignToNDC(bottomLeft); + bottomRight = DesignToNDC(bottomRight); + topRight = DesignToNDC(topRight); } // Store the transformed positions @@ -475,14 +475,14 @@ void BaseRenderer::QuadSetUV(const RectF spriteBounds, const float designWidth, bottomRight = rot * (bottomRight - center) + center; } - // bottom-left - *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = bottomLeft; // top-left - *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = topLeft; - // top-right - *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = topRight; + *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = topLeft; + // bottom-left + *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = bottomLeft; // bottom-right - *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = bottomRight; + *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = bottomRight; + // top-right + *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = topRight; } } // namespace Impacto From 9cd2ddf9833ebd307400686113c4739d856de8cc Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 19:39:11 +0200 Subject: [PATCH 08/88] Added TODO notes --- src/renderer/renderer.h | 31 +++++++++++++++++++++---------- 1 file changed, 21 insertions(+), 10 deletions(-) diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 1d869ff72..d763e1981 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -44,19 +44,23 @@ class BaseRenderer { virtual void FreeTexture(uint32_t id) = 0; virtual YUVFrame* CreateYUVFrame(float width, float height) = 0; + virtual void DrawSprite(Sprite const& sprite, CornersQuad const& dest, + std::array const& tints, + float angle = 0.0f, bool inverted = false) = 0; + void DrawSprite(const Sprite& sprite, glm::mat4 transformation, + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + + // TODO: Remove entirely void DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, bool inverted = false); + // TODO: Remove entirely void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0), glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, bool inverted = false); - virtual void DrawSprite(Sprite const& sprite, CornersQuad const& dest, - std::array const& tints, - float angle = 0.0f, bool inverted = false) = 0; - void DrawSprite(const Sprite& sprite, glm::mat4 transformation, - glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + // TODO: Remove entirely virtual void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, glm::vec2 displayOffset, glm::vec4 tint = glm::vec4(1.0), @@ -74,11 +78,6 @@ class BaseRenderer { virtual void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) = 0; - virtual void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false) = 0; - virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, @@ -86,11 +85,18 @@ class BaseRenderer { bool isInverted = false, bool isSameTexture = false) {} + // TODO: Remove entirely + virtual void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, + RectF const& dest, glm::vec4 tint, int alpha, + int fadeRange, bool isInverted = false, + bool isSameTexture = false) = 0; + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); + // TODO: Remove entirely virtual void DrawMaskedSpriteOffset( const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), @@ -121,16 +127,21 @@ class BaseRenderer { float angle = 0.0f, bool useMaskAlpha = true) = 0; + // TODO: Remove entirely virtual void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false) = 0; + + // TODO: Remove entirely void DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), glm::vec2 scale = glm::vec2(1.0f), bool inverted = false); + + // TODO: Remove entirely virtual void DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) = 0; From 2baebc452f073fb094599ed694ce970ca3f9f754 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 19:48:17 +0200 Subject: [PATCH 09/88] Added Transformation2D function --- src/util.cpp | 11 ++++++++--- src/util.h | 4 ++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index a707416be..a6950194f 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -25,6 +25,13 @@ glm::mat2 Rotate2D(float angle) { return result; } +glm::mat4 Transformation2D(const glm::vec2 translation, const glm::vec2 origin, + const float rotation, const glm::vec2 scaling) { + return Transformation3D({translation, 0.0f}, {origin, 0.0f}, + glm::quat(rotation, {0.0f, 0.0f, 1.0f}), + {scaling, 1.0f}); +} + glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, const glm::quat rotation, const glm::vec3 scaling) { glm::mat4 matrix(1.0f); @@ -38,9 +45,7 @@ glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, glm::vec2 Transform2D(const glm::vec2 pos, const glm::vec2 translation, const glm::vec2 origin, const float rotation, const glm::vec2 scaling) { - return Transformation3D(glm::vec3(translation, 0.0f), glm::vec3(origin, 0.0f), - glm::quat(rotation, {0.0f, 0.0f, 1.0f}), - glm::vec3(scaling, 1.0f)) * + return Transformation2D(translation, origin, rotation, scaling) * glm::vec4(pos, 0.0f, 1.0f); } diff --git a/src/util.h b/src/util.h index af40088fc..9cb4dca9a 100644 --- a/src/util.h +++ b/src/util.h @@ -51,6 +51,10 @@ concept is_any_of = std::disjunction_v...>; glm::mat2 Rotate2D(float angle); +glm::mat4 Transformation2D(glm::vec2 translation, + glm::vec2 origin = glm::vec2(0.0f), + float rotation = 0.0f, + glm::vec2 scaling = glm::vec2(1.0f)); glm::mat4 Transformation3D(glm::vec3 translation, glm::vec3 origin = glm::vec3(0.0f), glm::quat rotation = glm::quat(), From 0e04d1543e2aa14046696721f2601ceedee4764e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 21:12:13 +0200 Subject: [PATCH 10/88] Added AxisAnglesToQuaternion function --- src/util.cpp | 4 ++-- src/util.h | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index a6950194f..db5e5dc4a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -28,7 +28,7 @@ glm::mat2 Rotate2D(float angle) { glm::mat4 Transformation2D(const glm::vec2 translation, const glm::vec2 origin, const float rotation, const glm::vec2 scaling) { return Transformation3D({translation, 0.0f}, {origin, 0.0f}, - glm::quat(rotation, {0.0f, 0.0f, 1.0f}), + AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), {scaling, 1.0f}); } @@ -37,7 +37,7 @@ glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, glm::mat4 matrix(1.0f); matrix = glm::translate(glm::mat4(1.0f), -origin) * matrix; matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; - matrix = glm::mat4_cast(rotation) * matrix; + matrix = glm::mat4_cast(normalize(rotation)) * matrix; matrix = glm::translate(glm::mat4(1.0f), origin + translation) * matrix; return matrix; } diff --git a/src/util.h b/src/util.h index 9cb4dca9a..732e98274 100644 --- a/src/util.h +++ b/src/util.h @@ -312,7 +312,11 @@ inline float NormalizeRad(float rad) { constexpr float ScrWorkAngleToRad(float angle) { return angle * (float)(2.0f * M_PI / (float)(1 << 16)); } + glm::quat ScrWorkAnglesToQuaternion(int x, int y, int z); +inline glm::quat AxisAngleToQuaternion(glm::vec3 axis, float angle) { + return glm::quat(cos(angle / 2.0f), sin(angle / 2.0f) * axis); +} inline bool StringEndsWith(std::string const& str, std::string const& ending) { if (str.length() < ending.length()) return false; From c3bf7951ab7d4715a408a3e355c13379c16d2546 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 21:12:40 +0200 Subject: [PATCH 11/88] Refactored out DrawSpriteOffset --- src/renderer/dx9/renderer.cpp | 39 ----------------------------- src/renderer/dx9/renderer.h | 6 ----- src/renderer/opengl/renderer.cpp | 43 -------------------------------- src/renderer/opengl/renderer.h | 6 ----- src/renderer/renderer.cpp | 27 ++++++++++++++------ src/renderer/renderer.h | 10 ++++---- src/renderer/vulkan/renderer.cpp | 39 ----------------------------- src/renderer/vulkan/renderer.h | 6 ----- 8 files changed, 24 insertions(+), 152 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index d571ff01a..7aa0b3d8d 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -410,45 +410,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, glm::vec4 tint, - glm::vec2 scale, float angle, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite() called before BeginFrame()\n"); - return; - } - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - // Are we in sprite mode? - if (inverted) - EnsureShader(ShaderSpriteInverted); - else - EnsureShader(ShaderSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - - QuadSetPositionOffset(sprite.Bounds, topLeft, displayOffset, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, bool isInverted, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 0fb23a71e..f7cd44181 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -38,12 +38,6 @@ class Renderer : public BaseRenderer { const std::array& tints, float angle = 0.0f, bool inverted = false) override; - void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool inverted = false) override; - void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, int width, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index c3f3f7b01..d526a6b2c 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -489,49 +489,6 @@ void Renderer::DrawVertices(SpriteSheet const& sheet, GL_STATIC_DRAW); } -void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, glm::vec4 tint, - glm::vec2 scale, float angle, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite() called before BeginFrame()\n"); - return; - } - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - // Are we in sprite mode? - EnsureModeSprite(inverted); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - - QuadSetPositionOffset(sprite.Bounds, topLeft, displayOffset, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, bool isInverted, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 6bab77330..5aace53b5 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -49,12 +49,6 @@ class Renderer : public BaseRenderer { const std::array& tints, float angle = 0.0f, bool inverted = false) override; - void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool inverted = false) override; - void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, int width, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index d5b2e7482..9e376639a 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -40,6 +40,17 @@ void InitRenderer() { Renderer->Init(); } +void BaseRenderer::DrawSprite(const Sprite& sprite, + const glm::mat4 transformation, + const glm::vec4 tint, const bool inverted) { + CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), + sprite.ScaledHeight())) + .Transform(transformation); + + DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, + inverted); +} + void BaseRenderer::DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, float angle, bool inverted) { std::array tints = {tint, tint, tint, tint}; @@ -55,15 +66,15 @@ void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, DrawSprite(sprite, scaledDest, tint, angle, inverted); } -void BaseRenderer::DrawSprite(const Sprite& sprite, - const glm::mat4 transformation, - const glm::vec4 tint, const bool inverted) { - CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), - sprite.ScaledHeight())) - .Transform(transformation); +void BaseRenderer::DrawSpriteOffset(const Sprite& sprite, + const glm::vec2 topLeft, + const glm::vec2 displayOffset, + const glm::vec4 tint, const glm::vec2 scale, + const float angle, const bool inverted) { + const glm::mat4 transformation = + Transformation2D(topLeft, displayOffset, angle, scale); - DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, - inverted); + DrawSprite(sprite, transformation, tint, inverted); } void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index d763e1981..83308a196 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -61,11 +61,11 @@ class BaseRenderer { bool inverted = false); // TODO: Remove entirely - virtual void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), - float angle = 0.0f, bool inverted = false) = 0; + void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, + glm::vec2 displayOffset, + glm::vec4 tint = glm::vec4(1.0), + glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, + bool inverted = false); virtual void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 87edc7780..4162695c8 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1306,45 +1306,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 centerSprite, glm::vec4 tint, - glm::vec2 scale, float angle, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite() called before BeginFrame()\n"); - return; - } - - if (!sprite.Sheet.Texture) return; - if (Textures.count(sprite.Sheet.Texture) == 0) return; - - // Are we in sprite mode? - if (inverted) - EnsureMode(PipelineSpriteInverted); - else - EnsureMode(PipelineSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - MakeQuad(); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - - QuadSetPositionOffset(sprite.Bounds, topLeft, centerSprite, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, bool isInverted, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index eaa2115b1..0400853c9 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -66,12 +66,6 @@ class Renderer : public BaseRenderer { const std::array& tints, float angle = 0.0f, bool inverted = false) override; - void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool inverted = false) override; - void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, int width, From 71b5a040dc60553565ee147ce5d8bb0375b8300c Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 21:30:41 +0200 Subject: [PATCH 12/88] Refactored out DrawMaskedSprite overload --- src/renderer/dx9/renderer.cpp | 52 ------------------------ src/renderer/dx9/renderer.h | 5 --- src/renderer/opengl/renderer.cpp | 67 ------------------------------ src/renderer/opengl/renderer.h | 5 --- src/renderer/renderer.cpp | 10 +++++ src/renderer/renderer.h | 35 ++++++++-------- src/renderer/vulkan/renderer.cpp | 70 -------------------------------- src/renderer/vulkan/renderer.h | 5 --- 8 files changed, 27 insertions(+), 222 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 7aa0b3d8d..390fcfd3b 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -410,58 +410,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, - bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - Flush(); - EnsureShader(ShaderMaskedSprite); - - Device->SetTexture(0, Textures[sprite.Sheet.Texture]); - Device->SetTexture(1, Textures[mask.Sheet.Texture]); - - // This is cursed man, idk - float alphaRes[] = {alphaRange, constAlpha}; - BOOL isInvertedB = (BOOL)isInverted; - BOOL isSameTextureB = (BOOL)isSameTexture; - Device->SetPixelShaderConstantF(0, alphaRes, 1); - Device->SetPixelShaderConstantB(0, &isInvertedB, 1); - Device->SetPixelShaderConstantB(1, &isSameTextureB, 1); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, const glm::vec2 pos, const glm::vec2 origin, int alpha, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index f7cd44181..0e73def4d 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -47,11 +47,6 @@ class Renderer : public BaseRenderer { void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) override; - void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false) override; - void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index d526a6b2c..cfed52e76 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -489,73 +489,6 @@ void Renderer::DrawVertices(SpriteSheet const& sheet, GL_STATIC_DRAW); } -void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, - bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - if (CurrentMode != R2D_Masked) { - Flush(); - CurrentMode = R2D_Masked; - } - - EnsureTextureBound(sprite.Sheet.Texture); - - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramMaskedSprite); - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); - glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), - alphaRange, constAlpha); - glUniform1i(MaskedIsInvertedLocation, isInverted); - glUniform1i(MaskedIsSameTextureLocation, isSameTexture); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, const int fadeRange, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 5aace53b5..eab488c45 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -58,11 +58,6 @@ class Renderer : public BaseRenderer { void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) override; - void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false) override; - void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, const std::array& tints, bool isInverted, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 9e376639a..af423fce6 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -91,6 +91,16 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, isSameTexture); } +void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const RectF& dest, const glm::vec4 tint, + const int alpha, const int fadeRange, + const bool isInverted, + const bool isSameTexture) { + DrawMaskedSprite(sprite, mask, CornersQuad(dest), alpha, fadeRange, + std::array{tint, tint, tint, tint}, isInverted, + isSameTexture); +} + void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 83308a196..fb7972010 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -67,35 +67,23 @@ class BaseRenderer { glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, bool inverted = false); - virtual void DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, - glm::vec4 tint = glm::vec4(1.0), - bool inverted = false, - bool disableBlend = false) = 0; - - virtual void DrawRect(RectF const& dest, glm::vec4 color, - float angle = 0.0f) = 0; - virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, const std::array& tints, bool isInverted = false, bool isSameTexture = false) {} - - // TODO: Remove entirely - virtual void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false) = 0; - void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); + // TODO: Remove entirely + void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, + RectF const& dest, glm::vec4 tint, int alpha, + int fadeRange, bool isInverted = false, + bool isSameTexture = false); + // TODO: Remove entirely virtual void DrawMaskedSpriteOffset( const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, @@ -109,6 +97,17 @@ class BaseRenderer { alpha, fadeRange, maskInverted, isSameTexture); } + virtual void DrawVertices(SpriteSheet const& sheet, + std::span sheetPositions, + std::span displayPositions, + int width, int height, + glm::vec4 tint = glm::vec4(1.0), + bool inverted = false, + bool disableBlend = false) = 0; + + virtual void DrawRect(RectF const& dest, glm::vec4 color, + float angle = 0.0f) = 0; + void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 4162695c8..ce7822f81 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1306,76 +1306,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, - bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (Textures.count(sprite.Sheet.Texture) == 0 || - Textures.count(mask.Sheet.Texture) == 0) - return; - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - Flush(); - EnsureMode(PipelineMaskedSprite, false); - - VkDescriptorImageInfo imageBufferInfo[2]; - imageBufferInfo[0].sampler = Sampler; - imageBufferInfo[0].imageView = Textures[sprite.Sheet.Texture].ImageView; - imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imageBufferInfo[1].sampler = Sampler; - imageBufferInfo[1].imageView = Textures[mask.Sheet.Texture].ImageView; - imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = 0; - writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorCount = 2; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = imageBufferInfo; - - vkCmdPushDescriptorSetKHR( - CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, - PipelineMaskedSprite->PipelineLayout, 0, 1, &writeDescriptorSet); - - SpritePushConstants constants = {}; - constants.Alpha = glm::vec2(alphaRange, constAlpha); - constants.IsInverted = isInverted; - constants.IsSameTexture = isSameTexture; - vkCmdPushConstants( - CommandBuffers[CurrentFrameIndex], CurrentPipeline->PipelineLayout, - VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(SpritePushConstants), &constants); - - // OK, all good, make quad - MakeQuad(); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, const glm::vec2 pos, const glm::vec2 origin, int alpha, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 0400853c9..daf1e8c50 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -75,11 +75,6 @@ class Renderer : public BaseRenderer { void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) override; - void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false) override; - void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), From 7711e817a3034a52ae3b726c6c4eda23e76ea2e3 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 21:37:31 +0200 Subject: [PATCH 13/88] Removed DrawMaskedSpriteOffset --- src/renderer/dx9/renderer.cpp | 61 ------------------------ src/renderer/dx9/renderer.h | 8 ---- src/renderer/opengl/renderer.cpp | 78 ------------------------------- src/renderer/opengl/renderer.h | 8 ---- src/renderer/renderer.h | 13 ------ src/renderer/vulkan/renderer.cpp | 79 -------------------------------- src/renderer/vulkan/renderer.h | 8 ---- 7 files changed, 255 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 390fcfd3b..b53b3a547 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -410,67 +410,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - const glm::vec2 pos, - const glm::vec2 origin, int alpha, - const int fadeRange, const glm::vec4 tint, - const glm::vec2 scale, const float angle, - const bool spriteInverted, - const bool maskInverted, - const bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - Flush(); - // TODO: handle inverted sprites - EnsureShader(ShaderMaskedSprite); - - Device->SetTexture(0, Textures[sprite.Sheet.Texture]); - Device->SetTexture(1, Textures[mask.Sheet.Texture]); - - // This is cursed man, idk - float alphaRes[] = {alphaRange, constAlpha}; - BOOL isInvertedB = (BOOL)maskInverted; - BOOL isSameTextureB = (BOOL)isSameTexture; - Device->SetPixelShaderConstantF(0, alphaRes, 1); - Device->SetPixelShaderConstantB(0, &isInvertedB, 1); - Device->SetPixelShaderConstantB(1, &isSameTextureB, 1); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - QuadSetPositionOffset({0.0f, 0.0f, 1.0f, 1.0f}, pos, origin, scale, angle, - (uintptr_t)&vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 0e73def4d..92f7dd55d 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -47,14 +47,6 @@ class Renderer : public BaseRenderer { void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) override; - void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - glm::vec2 pos, glm::vec2 origin, int alpha, - int fadeRange, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0), - float angle = 0.0f, bool spriteInverted = false, - bool maskInverted = false, - bool isSameTexture = false) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index cfed52e76..87442541c 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -558,84 +558,6 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - const glm::vec2 pos, - const glm::vec2 origin, int alpha, - const int fadeRange, const glm::vec4 tint, - const glm::vec2 scale, const float angle, - const bool spriteInverted, - const bool maskInverted, - const bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - // Are we in sprite mode? - EnsureModeSprite(spriteInverted); - - if (CurrentMode != R2D_Masked) { - Flush(); - CurrentMode = R2D_Masked; - } - - EnsureTextureBound(sprite.Sheet.Texture); - - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramMaskedSprite); - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); - glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), - alphaRange, constAlpha); - glUniform1i(MaskedIsInvertedLocation, maskInverted); - glUniform1i(MaskedIsSameTextureLocation, isSameTexture); - - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - QuadSetPositionOffset({0.0f, 0.0f, 1.0f, 1.0f}, pos, origin, scale, angle, - (uintptr_t)&vertices[0].MaskUV, - sizeof(VertexBufferSprites), false); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index eab488c45..75a7c3dc4 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -63,14 +63,6 @@ class Renderer : public BaseRenderer { const std::array& tints, bool isInverted, bool isSameTexture) override; - void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - glm::vec2 pos, glm::vec2 origin, int alpha, - int fadeRange, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0), - float angle = 0.0f, bool spriteInverted = false, - bool maskInverted = false, - bool isSameTexture = false) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index fb7972010..6f9107d0f 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -84,19 +84,6 @@ class BaseRenderer { int fadeRange, bool isInverted = false, bool isSameTexture = false); - // TODO: Remove entirely - virtual void DrawMaskedSpriteOffset( - const Sprite& sprite, const Sprite& mask, glm::vec2 pos, glm::vec2 origin, - int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool spriteInverted = false, bool maskInverted = false, - bool isSameTexture = false) { - DrawMaskedSprite( - sprite, mask, - {pos.x, pos.y, sprite.ScaledWidth(), sprite.ScaledHeight()}, tint, - alpha, fadeRange, maskInverted, isSameTexture); - } - virtual void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index ce7822f81..7fbbd2b85 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1306,85 +1306,6 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - const glm::vec2 pos, - const glm::vec2 origin, int alpha, - const int fadeRange, const glm::vec4 tint, - const glm::vec2 scale, const float angle, - const bool spriteInverted, - const bool maskInverted, - const bool isSameTexture) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); - return; - } - - if (Textures.count(sprite.Sheet.Texture) == 0 || - Textures.count(mask.Sheet.Texture) == 0) - return; - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - Flush(); - // TODO: handle inverted sprites - EnsureMode(PipelineMaskedSprite, false); - - VkDescriptorImageInfo imageBufferInfo[2]; - imageBufferInfo[0].sampler = Sampler; - imageBufferInfo[0].imageView = Textures[sprite.Sheet.Texture].ImageView; - imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - imageBufferInfo[1].sampler = Sampler; - imageBufferInfo[1].imageView = Textures[mask.Sheet.Texture].ImageView; - imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = 0; - writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorCount = 2; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = imageBufferInfo; - - vkCmdPushDescriptorSetKHR( - CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, - PipelineMaskedSprite->PipelineLayout, 0, 1, &writeDescriptorSet); - - SpritePushConstants constants = {}; - constants.Alpha = glm::vec2(alphaRange, constAlpha); - constants.IsInverted = maskInverted; - constants.IsSameTexture = isSameTexture; - vkCmdPushConstants( - CommandBuffers[CurrentFrameIndex], CurrentPipeline->PipelineLayout, - VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(SpritePushConstants), &constants); - - // OK, all good, make quad - MakeQuad(); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - - QuadSetPositionOffset(sprite.Bounds, pos, origin, scale, angle, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - QuadSetPositionOffset({0.0f, 0.0f, 1.0f, 1.0f}, pos, origin, scale, angle, - (uintptr_t)&vertices[0].MaskUV, - sizeof(VertexBufferSprites), false); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index daf1e8c50..57e174a79 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -75,14 +75,6 @@ class Renderer : public BaseRenderer { void DrawRect(RectF const& dest, glm::vec4 color, float angle = 0.0f) override; - void DrawMaskedSpriteOffset(const Sprite& sprite, const Sprite& mask, - glm::vec2 pos, glm::vec2 origin, int alpha, - int fadeRange, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0), - float angle = 0.0f, bool spriteInverted = false, - bool maskInverted = false, - bool isSameTexture = false) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; From bbcbd54f9f78756bad83be8397f1cbb9726fda9b Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 23:31:38 +0200 Subject: [PATCH 14/88] Refactored out DrawSprite3DRotated --- src/renderer/dx9/renderer.cpp | 39 -------------------------------- src/renderer/dx9/renderer.h | 4 ---- src/renderer/opengl/renderer.cpp | 36 ----------------------------- src/renderer/opengl/renderer.h | 4 ---- src/renderer/renderer.cpp | 37 ++++++++++++++++++++++++++++++ src/renderer/renderer.h | 9 ++++---- src/renderer/vulkan/renderer.cpp | 38 ------------------------------- src/renderer/vulkan/renderer.h | 4 ---- 8 files changed, 41 insertions(+), 130 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index b53b3a547..37921edeb 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -267,45 +267,6 @@ void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { BaseRenderer::DrawSprite(RectSprite, dest, color, angle); } -void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - glm::vec4 tint, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite3DRotated() called before BeginFrame()\n"); - return; - } - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - // Are we in sprite mode? - if (inverted) - EnsureShader(ShaderSpriteInverted); - else - EnsureShader(ShaderSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 92f7dd55d..d7d262d95 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -59,10 +59,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false) override; void DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 87442541c..8fe1565ff 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -268,42 +268,6 @@ void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { BaseRenderer::DrawSprite(RectSprite, dest, color, angle); } -void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - glm::vec4 tint, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite3DRotated() called before BeginFrame()\n"); - return; - } - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - // Are we in sprite mode? - EnsureModeSprite(inverted); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 75a7c3dc4..29ecc5fdf 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -75,10 +75,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false) override; void DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index af423fce6..08787e495 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -111,6 +111,43 @@ void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, DrawCCMessageBox(sprite, mask, scaledDest, tint, alpha, fadeRange, effectCt); } +void BaseRenderer::DrawSprite3DRotated( + const Sprite& sprite, const RectF& dest, const float depth, + const glm::vec2 vanishingPoint, const bool stayInScreen, + const glm::quat rot, const glm::vec4 tint, const bool inverted) { + CornersQuad corners = dest; + std::array vertices = { + glm::vec4(corners.TopLeft, 0.0f, 1.0f), + glm::vec4(corners.TopRight, 0.0f, 1.0f), + glm::vec4(corners.BottomRight, 0.0f, 1.0f), + glm::vec4(corners.BottomLeft, 0.0f, 1.0f)}; + + const glm::mat4 transformation = + Transformation3D(glm::vec3(0.0f), {dest.Center(), 0.0f}, rot); + for (glm::vec4& vertex : vertices) vertex = transformation * vertex; + + if (stayInScreen) { + float maxZ = 0.0f; + for (const glm::vec4 vertex : vertices) maxZ = std::max(maxZ, vertex.z); + + for (glm::vec4& vertex : vertices) vertex.z -= maxZ; + } + + for (glm::vec4 vertex : vertices) { + vertex -= glm::vec4(vanishingPoint, 0.0f, 0.0f); + vertex *= depth / (depth - vertex.z); + vertex += glm::vec4(vanishingPoint, 0.0f, 0.0f); + } + + corners.TopLeft = glm::vec2(vertices[0]); + corners.TopRight = glm::vec2(vertices[1]); + corners.BottomRight = glm::vec2(vertices[2]); + corners.BottomLeft = glm::vec2(vertices[3]); + + DrawSprite(sprite, corners, std::array{tint, tint, tint, tint}, + 0.0f, inverted); +} + void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 6f9107d0f..6610d54ad 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -114,11 +114,10 @@ class BaseRenderer { bool useMaskAlpha = true) = 0; // TODO: Remove entirely - virtual void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false) = 0; + void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, + glm::vec2 vanishingPoint, bool stayInScreen, + glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), + bool inverted = false); // TODO: Remove entirely void DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 7fbbd2b85..e7669b82f 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1136,44 +1136,6 @@ void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { BaseRenderer::DrawSprite(RectSprite, dest, color, angle); } -void Renderer::DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - glm::vec4 tint, bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite3DRotated() called before BeginFrame()\n"); - return; - } - - if (Textures.count(sprite.Sheet.Texture) == 0) return; - - // Are we in sprite mode? - if (inverted) - EnsureMode(PipelineSpriteInverted); - else - EnsureMode(PipelineSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - // OK, all good, make quad - MakeQuad(); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition3DRotated(dest, depth, vanishingPoint, stayInScreen, rot, - (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 57e174a79..4ebc6b474 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -87,10 +87,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false) override; void DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) override; From 48cd1c94445fe2bc461b2b51b423a58ae864b43f Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 27 Apr 2025 23:52:23 +0200 Subject: [PATCH 15/88] Removed superfluous angle parameter from DrawSprite --- src/games/cclcc/mapsystem.cpp | 2 +- src/renderer/dx9/renderer.cpp | 8 ++++---- src/renderer/dx9/renderer.h | 6 +++--- src/renderer/opengl/renderer.cpp | 8 ++++---- src/renderer/opengl/renderer.h | 6 +++--- src/renderer/renderer.cpp | 8 +++++--- src/renderer/renderer.h | 6 +++--- src/renderer/vulkan/renderer.cpp | 8 ++++---- src/renderer/vulkan/renderer.h | 6 +++--- 9 files changed, 30 insertions(+), 28 deletions(-) diff --git a/src/games/cclcc/mapsystem.cpp b/src/games/cclcc/mapsystem.cpp index 508890f9b..442ce20f3 100644 --- a/src/games/cclcc/mapsystem.cpp +++ b/src/games/cclcc/mapsystem.cpp @@ -2007,7 +2007,7 @@ void MapSystemCCLCC::RenderButtonGuide() { glm::vec2{guideXWidth + 60, 988.0f}, // top right glm::vec2{guideXWidth + 60, 1042.0f}, // bottom right }; - Renderer->DrawSprite(MapButtonGuideSprite2, dest, tints, 0, false); + Renderer->DrawSprite(MapButtonGuideSprite2, dest, tints, false); } } } diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 37921edeb..d9ff6359b 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -334,9 +334,9 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, } } -void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, - const std::array& tints, float angle, - bool inverted) { +void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -365,7 +365,7 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index d7d262d95..16cee60aa 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -34,9 +34,9 @@ class Renderer : public BaseRenderer { void FreeTexture(uint32_t id) override; YUVFrame* CreateYUVFrame(float width, float height) override; - void DrawSprite(Sprite const& sprite, CornersQuad const& dest, - const std::array& tints, float angle = 0.0f, - bool inverted = false) override; + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 8fe1565ff..f4fda6883 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -325,9 +325,9 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, GL_STATIC_DRAW); } -void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, - const std::array& tints, float angle, - bool inverted) { +void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -364,7 +364,7 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 29ecc5fdf..1fe095ac8 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -45,9 +45,9 @@ class Renderer : public BaseRenderer { void FreeTexture(uint32_t id) override; YUVFrame* CreateYUVFrame(float width, float height) override; - void DrawSprite(Sprite const& sprite, CornersQuad const& dest, - const std::array& tints, float angle = 0.0f, - bool inverted = false) override; + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 08787e495..0ee9d5a77 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -53,8 +53,10 @@ void BaseRenderer::DrawSprite(const Sprite& sprite, void BaseRenderer::DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, float angle, bool inverted) { - std::array tints = {tint, tint, tint, tint}; - DrawSprite(sprite, CornersQuad(dest), tints, angle, inverted); + const glm::mat4 transformation = + Transformation2D({0.0f, 0.0f}, dest.Center(), angle); + DrawSprite(sprite, CornersQuad(dest).Transform(transformation), + std::array{tint, tint, tint, tint}, inverted); } void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, @@ -145,7 +147,7 @@ void BaseRenderer::DrawSprite3DRotated( corners.BottomLeft = glm::vec2(vertices[3]); DrawSprite(sprite, corners, std::array{tint, tint, tint, tint}, - 0.0f, inverted); + inverted); } void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 6610d54ad..82b7792ab 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -44,9 +44,9 @@ class BaseRenderer { virtual void FreeTexture(uint32_t id) = 0; virtual YUVFrame* CreateYUVFrame(float width, float height) = 0; - virtual void DrawSprite(Sprite const& sprite, CornersQuad const& dest, - std::array const& tints, - float angle = 0.0f, bool inverted = false) = 0; + virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + bool inverted = false) = 0; void DrawSprite(const Sprite& sprite, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index e7669b82f..b56131206 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1231,9 +1231,9 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, Flush(); } -void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, - std::array const& tints, float angle, - bool inverted) { +void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + std::array const& tints, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -1262,7 +1262,7 @@ void Renderer::DrawSprite(Sprite const& sprite, CornersQuad const& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 4ebc6b474..223ccc650 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -62,9 +62,9 @@ class Renderer : public BaseRenderer { void FreeTexture(uint32_t id) override; YUVFrame* CreateYUVFrame(float width, float height) override; - void DrawSprite(Sprite const& sprite, CornersQuad const& dest, - const std::array& tints, float angle = 0.0f, - bool inverted = false) override; + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const std::array& tints, + const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, From cd594e32163500c33a1adb2e75eb010b183654a8 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 00:01:40 +0200 Subject: [PATCH 16/88] Refactored out DrawRect --- src/renderer/dx9/renderer.cpp | 4 ---- src/renderer/dx9/renderer.h | 5 ----- src/renderer/opengl/renderer.cpp | 4 ---- src/renderer/opengl/renderer.h | 5 ----- src/renderer/renderer.cpp | 5 +++++ src/renderer/renderer.h | 5 +++-- src/renderer/vulkan/renderer.cpp | 4 ---- src/renderer/vulkan/renderer.h | 5 ----- 8 files changed, 8 insertions(+), 29 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index d9ff6359b..dbc0da744 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -263,10 +263,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { - BaseRenderer::DrawSprite(RectSprite, dest, color, angle); -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 16cee60aa..42163479f 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -44,9 +44,6 @@ class Renderer : public BaseRenderer { int height, glm::vec4 tint = glm::vec4(1.0), bool inverted = false, bool disableBlend = false) override; - void DrawRect(RectF const& dest, glm::vec4 color, - float angle = 0.0f) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; @@ -122,8 +119,6 @@ class Renderer : public BaseRenderer { IDirect3DIndexBuffer9* IndexBufferDevice; IDirect3DIndexBuffer9* IndexBufferMvl; int IndexBufferFill = 0; - - Sprite RectSprite; }; } // namespace DirectX9 diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index f4fda6883..eeed425b2 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -264,10 +264,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)frame; } -void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { - BaseRenderer::DrawSprite(RectSprite, dest, color, angle); -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 1fe095ac8..0c946eb21 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -55,9 +55,6 @@ class Renderer : public BaseRenderer { int height, glm::vec4 tint = glm::vec4(1.0), bool inverted = false, bool disableBlend = false) override; - void DrawRect(RectF const& dest, glm::vec4 color, - float angle = 0.0f) override; - void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, const std::array& tints, bool isInverted, @@ -148,8 +145,6 @@ class Renderer : public BaseRenderer { uint16_t IndexBuffer[IndexBufferCount]; int IndexBufferFill = 0; - Sprite RectSprite; - // ShaderCompiler compiler ShaderCompiler* Shaders; }; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 0ee9d5a77..2e73739f1 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -162,6 +162,11 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, rot, tint, inverted); } +void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, + const float angle) { + DrawSprite(RectSprite, dest, color, angle); +} + void BaseRenderer::DrawProcessedText(std::span text, Font* font, float opacity, RendererOutlineMode outlineMode, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 82b7792ab..9f123a1d8 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -92,8 +92,7 @@ class BaseRenderer { bool inverted = false, bool disableBlend = false) = 0; - virtual void DrawRect(RectF const& dest, glm::vec4 color, - float angle = 0.0f) = 0; + void DrawRect(const RectF& dest, glm::vec4 color, float angle = 0.0f); void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, @@ -220,6 +219,8 @@ class BaseRenderer { float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, uintptr_t positions, int stride); + + Sprite RectSprite; }; inline BaseRenderer* Renderer; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index b56131206..eb3f4ce66 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1132,10 +1132,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawRect(RectF const& dest, glm::vec4 color, float angle) { - BaseRenderer::DrawSprite(RectSprite, dest, color, angle); -} - void Renderer::DrawRect3DRotated(RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, glm::quat rot, glm::vec4 color) { diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 223ccc650..7806f9849 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -72,9 +72,6 @@ class Renderer : public BaseRenderer { int height, glm::vec4 tint = glm::vec4(1.0), bool inverted = false, bool disableBlend = false) override; - void DrawRect(RectF const& dest, glm::vec4 color, - float angle = 0.0f) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; @@ -210,8 +207,6 @@ class Renderer : public BaseRenderer { int IndexBufferFill = 0; int IndexBufferOffset = 0; - Sprite RectSprite; - RectF PreviousScissorRect; static VkVertexInputBindingDescription GetBindingDescription(); From 05b53c993c8a2be97213b8733a520d77e0372611 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 00:07:15 +0200 Subject: [PATCH 17/88] Refactored out DrawRect3DRotated --- src/renderer/dx9/renderer.cpp | 7 ------- src/renderer/dx9/renderer.h | 4 ---- src/renderer/opengl/renderer.cpp | 7 ------- src/renderer/opengl/renderer.h | 4 ---- src/renderer/renderer.cpp | 9 +++++++++ src/renderer/renderer.h | 6 +++--- src/renderer/vulkan/renderer.cpp | 7 ------- src/renderer/vulkan/renderer.h | 4 ---- 8 files changed, 12 insertions(+), 36 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index dbc0da744..33f9a9e47 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -263,13 +263,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) { - DrawSprite3DRotated(RectSprite, dest, depth, vanishingPoint, stayInScreen, - rot, color); -} - void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 42163479f..c0796a772 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -56,10 +56,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, bool inverted, glm::vec4 tint, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index eeed425b2..17448ac8c 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -264,13 +264,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)frame; } -void Renderer::DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) { - DrawSprite3DRotated(RectSprite, dest, depth, vanishingPoint, stayInScreen, - rot, color); -} - void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 0c946eb21..9165e8187 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -72,10 +72,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, bool inverted, glm::vec4 tint, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 2e73739f1..9650ba61d 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -167,6 +167,15 @@ void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, DrawSprite(RectSprite, dest, color, angle); } +void BaseRenderer::DrawRect3DRotated(const RectF& dest, const float depth, + const glm::vec2 vanishingPoint, + const bool stayInScreen, + const glm::quat rot, + const glm::vec4 color) { + DrawSprite3DRotated(RectSprite, dest, depth, vanishingPoint, stayInScreen, + rot, color); +} + void BaseRenderer::DrawProcessedText(std::span text, Font* font, float opacity, RendererOutlineMode outlineMode, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 9f123a1d8..5a536542c 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -126,9 +126,9 @@ class BaseRenderer { bool inverted = false); // TODO: Remove entirely - virtual void DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) = 0; + void DrawRect3DRotated(const RectF& dest, float depth, + glm::vec2 vanishingPoint, bool stayInScreen, + glm::quat rot, glm::vec4 color); void DrawProcessedText_BasicFont(std::span text, BasicFont* font, float opacity, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index eb3f4ce66..4038ecaad 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1132,13 +1132,6 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) { - DrawSprite3DRotated(RectSprite, dest, depth, vanishingPoint, stayInScreen, - rot, color); -} - void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 7806f9849..d812e1f1a 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -84,10 +84,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawRect3DRotated(RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, bool inverted, glm::vec4 tint, From d006f9859d1bb19a8c7d4364b40beacb04c74b64 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 19:35:30 +0200 Subject: [PATCH 18/88] Properly mark overridden methods --- src/renderer/dx9/renderer.h | 2 +- src/renderer/opengl/renderer.h | 4 ++-- src/renderer/vulkan/renderer.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index c0796a772..1cbd06bb7 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -80,7 +80,7 @@ class Renderer : public BaseRenderer { void EnsureSpaceAvailable(int vertices, int vertexSize, int indices); void EnsureTextureBound(uint32_t texture); void EnsureShader(Shader* shader, bool flush = true); - void Flush(); + void Flush() override; DirectX9Window* DXWindow; diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 9165e8187..08b8b3d45 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -67,7 +67,7 @@ class Renderer : public BaseRenderer { void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, bool isInverted, float angle, - bool useMaskAlpha); + bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; @@ -103,7 +103,7 @@ class Renderer : public BaseRenderer { void EnsureSpaceAvailable(int vertices, int vertexSize, int indices); void EnsureTextureBound(GLuint texture); void EnsureModeSprite(bool inverted); - void Flush(); + void Flush() override; GLWindow* OpenGLWindow; diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index d812e1f1a..27ed10c65 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -79,7 +79,7 @@ class Renderer : public BaseRenderer { void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, bool isInverted, float angle, - bool useMaskAlpha); + bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; @@ -128,7 +128,7 @@ class Renderer : public BaseRenderer { void EnsureTextureBound(unsigned int texture); void EnsureMode(Pipeline* pipeline, bool flush = true); - void Flush(); + void Flush() override; void MakeQuad(); From b7ff25267972b4b78cbe71e2f698d1a9446374aa Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 20:00:39 +0200 Subject: [PATCH 19/88] Changed pure virtual DrawMaskedSpriteOverlay to be more generic --- src/renderer/dx9/renderer.cpp | 13 ++++---- src/renderer/dx9/renderer.h | 6 ++-- src/renderer/opengl/renderer.cpp | 13 ++++---- src/renderer/opengl/renderer.h | 6 ++-- src/renderer/renderer.cpp | 21 +++++++++++++ src/renderer/renderer.h | 52 ++++++++++++++++++++------------ src/renderer/vulkan/renderer.cpp | 13 ++++---- src/renderer/vulkan/renderer.h | 6 ++-- src/spritesheet.h | 3 ++ 9 files changed, 86 insertions(+), 47 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 33f9a9e47..91cc39a89 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -493,11 +493,12 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } -void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, - int alpha, int fadeRange, - bool isInverted, float angle, - bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const glm::vec4 tint, + const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -546,7 +547,7 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 1cbd06bb7..c51059f5c 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -48,9 +48,9 @@ class Renderer : public BaseRenderer { RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, float angle, + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, glm::vec4 tint, bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 17448ac8c..549a7787e 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -511,11 +511,12 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, - int alpha, int fadeRange, - bool isInverted, float angle, - bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const glm::vec4 tint, + const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -575,7 +576,7 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 08b8b3d45..76ebc3363 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -64,9 +64,9 @@ class Renderer : public BaseRenderer { RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, float angle, + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, glm::vec4 tint, bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 9650ba61d..3cda5a22a 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -103,6 +103,27 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, isSameTexture); } +void BaseRenderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const int alpha, + const int fadeRange, const glm::mat4 transformation, const glm::vec4 tint, + const bool isInverted, const bool useMaskAlpha) { + const CornersQuad dest = + CornersQuad(sprite.ScaledBounds()).Transform(transformation); + DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, + isInverted, useMaskAlpha); +} + +void BaseRenderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const RectF& dest, + const glm::vec4 tint, const int alpha, const int fadeRange, + const bool isInverted, const float angle, const bool useMaskAlpha) { + const CornersQuad corners = CornersQuad(dest).Transform( + Transformation2D({0.0f, 0.0f}, dest.Center(), angle)); + + DrawMaskedSpriteOverlay(sprite, mask, corners, alpha, fadeRange, tint, + isInverted, useMaskAlpha); +} + void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 5a536542c..9fe37240d 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -67,6 +67,19 @@ class BaseRenderer { glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, bool inverted = false); + // TODO: Remove entirely + void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, + glm::vec2 vanishingPoint, bool stayInScreen, + glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), + bool inverted = false); + + // TODO: Remove entirely + void DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, + glm::vec2 vanishingPoint, bool stayInScreen, + glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), + glm::vec2 scale = glm::vec2(1.0f), + bool inverted = false); + virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, @@ -84,6 +97,25 @@ class BaseRenderer { int fadeRange, bool isInverted = false, bool isSameTexture = false); + virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true) = 0; + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + int alpha, int fadeRange, + glm::mat4 transformation, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true); + + // TODO: Remove entirely + void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, + RectF const& dest, glm::vec4 tint, int alpha, + int fadeRange, bool isInverted = false, + float angle = 0.0f, bool useMaskAlpha = true); + virtual void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, @@ -105,26 +137,6 @@ class BaseRenderer { virtual void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) = 0; - virtual void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, - int alpha, int fadeRange, - bool isInverted = false, - float angle = 0.0f, - bool useMaskAlpha = true) = 0; - - // TODO: Remove entirely - void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false); - - // TODO: Remove entirely - void DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0f), - bool inverted = false); - // TODO: Remove entirely void DrawRect3DRotated(const RectF& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 4038ecaad..7ab62bec0 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1423,11 +1423,12 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } -void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, - int alpha, int fadeRange, - bool isInverted, float angle, - bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const glm::vec4 tint, + const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -1513,7 +1514,7 @@ void Renderer::DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites), angle); + &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 27ed10c65..83b3430fb 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -76,9 +76,9 @@ class Renderer : public BaseRenderer { RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted, float angle, + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, glm::vec4 tint, bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, diff --git a/src/spritesheet.h b/src/spritesheet.h index 925c85fd8..e1df2e65d 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -36,6 +36,9 @@ struct Sprite { void SetScaledHeight(float scaledHeight) { Bounds.Height = scaledHeight / BaseScale.y; } + RectF ScaledBounds() const { + return Bounds.Scale(BaseScale, Bounds.GetPos()); + } }; } // namespace Impacto \ No newline at end of file From 6f8aabecef694b82259c4de1fc301d82d2b6b8e5 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 21:20:00 +0200 Subject: [PATCH 20/88] Changed pure virtual DrawCharacterMvl to be more generic --- src/renderer/dx9/renderer.cpp | 26 ++++++++++++-------------- src/renderer/dx9/renderer.h | 7 +++---- src/renderer/opengl/renderer.cpp | 32 +++++++++++++++----------------- src/renderer/opengl/renderer.h | 7 +++---- src/renderer/renderer.cpp | 31 +++++++++++++++++++++++++++++++ src/renderer/renderer.h | 23 +++++++++++++++++------ src/renderer/vulkan/renderer.cpp | 31 ++++++++++--------------------- src/renderer/vulkan/renderer.h | 7 +++---- 8 files changed, 94 insertions(+), 70 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 91cc39a89..7fdea6b24 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -263,11 +263,10 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, - int indicesCount, uint16_t* mvlIndices, - bool inverted, glm::vec4 tint, - glm::vec2 scale) { +void Renderer::DrawCharacterMvl(const Sprite& sprite, + const std::span mvlVertices, + const std::span mvlIndices, + const glm::vec4 tint, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); @@ -287,20 +286,19 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, // Do we have the texture assigned? EnsureTextureBound(sprite.Sheet.Texture); + const size_t vertexCount = mvlVertices.size() / 5; VertexBufferSprites* vertices = (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - IndexBufferFill += indicesCount; + IndexBufferFill += mvlIndices.size(); - memcpy(IndexBuffer, mvlIndices, indicesCount * sizeof(mvlIndices[0])); + std::copy(mvlIndices.begin(), mvlIndices.end(), IndexBuffer); - for (int i = 0; i < verticesCount; i++) { - glm::vec2 pos = glm::vec2(mvlVertices[i * 5], mvlVertices[i * 5 + 1]); - pos *= scale; - pos += topLeft; - vertices[i].Position = DesignToNDC(pos); - vertices[i].UV = glm::vec2(mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]); + for (int i = 0; i < vertexCount; i++) { + vertices[i].Position = + DesignToNDC({mvlVertices[i * 5], mvlVertices[i * 5 + 1]}); + vertices[i].UV = {mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]}; vertices[i].Tint = tint; } diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index c51059f5c..fd33fb4ac 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -56,10 +56,9 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, int indicesCount, - uint16_t* mvlIndices, bool inverted, glm::vec4 tint, - glm::vec2 scale) override; + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + std::span indices, glm::vec4 tint, + bool inverted) override; void DrawVideoTexture(YUVFrame* tex, RectF const& dest, glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 549a7787e..6575f0c9c 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -264,11 +264,10 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)frame; } -void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, - int indicesCount, uint16_t* mvlIndices, - bool inverted, glm::vec4 tint, - glm::vec2 scale) { +void Renderer::DrawCharacterMvl(const Sprite& sprite, + const std::span mvlVertices, + const std::span mvlIndices, + const glm::vec4 tint, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); @@ -280,8 +279,9 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, Flush(); // Do we have space for the whole character? - EnsureSpaceAvailable(verticesCount, sizeof(VertexBufferSprites), - indicesCount); + const size_t vertexCount = mvlVertices.size() / 5; + EnsureSpaceAvailable(vertexCount, sizeof(VertexBufferSprites), + mvlIndices.size()); // Are we in sprite mode? EnsureModeSprite(inverted); @@ -291,19 +291,17 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, VertexBufferSprites* vertices = (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - IndexBufferFill += indicesCount; + IndexBufferFill += mvlIndices.size(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indicesCount * sizeof(mvlIndices[0]), - mvlIndices, GL_STATIC_DRAW); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, mvlIndices.size() * sizeof(uint16_t), + mvlIndices.data(), GL_STATIC_DRAW); - for (int i = 0; i < verticesCount; i++) { - glm::vec2 pos = glm::vec2(mvlVertices[i * 5], mvlVertices[i * 5 + 1]); - pos *= scale; - pos += topLeft; - vertices[i].Position = DesignToNDC(pos); - vertices[i].UV = glm::vec2(mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]); + for (int i = 0; i < vertexCount; i++) { + vertices[i].Position = + DesignToNDC({mvlVertices[i * 5], mvlVertices[i * 5 + 1]}); + vertices[i].UV = {mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]}; vertices[i].Tint = tint; } diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 76ebc3363..c62e0cd92 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -72,10 +72,9 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, int indicesCount, - uint16_t* mvlIndices, bool inverted, glm::vec4 tint, - glm::vec2 scale) override; + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + std::span indices, glm::vec4 tint, + bool inverted) override; void DrawVideoTexture(YUVFrame* tex, RectF const& dest, glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 3cda5a22a..442ae4460 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -234,6 +234,37 @@ void BaseRenderer::DrawProcessedText(std::span text, } } +void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, + const std::span vertices, + const std::span indices, + glm::mat4 transformation, glm::vec4 tint, + bool inverted) { + const size_t vertexCount = vertices.size() / 5; + for (size_t i = 0; i < vertexCount; i++) { + const glm::vec2 pos = + transformation * + glm::vec4(vertices[i * 5], vertices[i * 5 + 1], 0.0f, 1.0f); + vertices[i * 5] = pos.x; + vertices[i * 5 + 1] = pos.y; + } + + DrawCharacterMvl(sprite, vertices, indices, tint, inverted); +} + +void BaseRenderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, + int verticesCount, float* mvlVertices, + int indicesCount, uint16_t* mvlIndices, + bool inverted, glm::vec4 tint, + glm::vec2 scale) { + const glm::mat4 transformation = + Transformation2D(topLeft, {0.0f, 0.0f}, 0.0f, scale); + + std::vector vertices(mvlVertices, mvlVertices + verticesCount * 5); + std::vector indices(mvlIndices, mvlIndices + indicesCount); + + DrawCharacterMvl(sprite, vertices, indices, transformation, tint, inverted); +} + void BaseRenderer::DrawVideoTexture(YUVFrame* tex, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle, bool alphaVideo) { diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 9fe37240d..5f8533a41 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -166,12 +166,23 @@ class BaseRenderer { RendererOutlineMode outlineMode = RendererOutlineMode::None, bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = 0); - virtual void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, - int indicesCount, uint16_t* mvlIndices, - bool inverted = false, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0f)) = 0; + virtual void DrawCharacterMvl(const Sprite& sprite, + std::span vertices, + std::span indices, + glm::vec4 tint = glm::vec4(1.0f), + bool inverted = false) = 0; + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + std::span indices, + glm::mat4 transformation, + glm::vec4 tint = glm::vec4(1.0f), + bool inverted = false); + + // TODO: Remove entirely + void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, + int verticesCount, float* mvlVertices, int indicesCount, + uint16_t* mvlIndices, bool inverted = false, + glm::vec4 tint = glm::vec4(1.0), + glm::vec2 scale = glm::vec2(1.0f)); virtual void DrawVideoTexture(YUVFrame* tex, RectF const& dest, glm::vec4 tint = glm::vec4(1.0), diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 7ab62bec0..76533909b 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1132,11 +1132,10 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, - int indicesCount, uint16_t* mvlIndices, - bool inverted, glm::vec4 tint, - glm::vec2 scale) { +void Renderer::DrawCharacterMvl(const Sprite& sprite, + const std::span mvlVertices, + const std::span mvlIndices, + const glm::vec4 tint, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); @@ -1158,20 +1157,19 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, // Do we have the texture assigned? EnsureTextureBound(sprite.Sheet.Texture); + const size_t vertexCount = mvlVertices.size() / 5; VertexBufferSprites* vertices = (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - IndexBufferFill += indicesCount; + IndexBufferFill += mvlIndices.size(); int indexBufferOffset = IndexBufferOffset / sizeof(uint16_t); - memcpy(IndexBuffer + indexBufferOffset, mvlIndices, - indicesCount * sizeof(mvlIndices[0])); + std::copy(mvlIndices.begin(), mvlIndices.end(), + IndexBuffer + indexBufferOffset); - for (int i = 0; i < verticesCount; i += 4) { - glm::vec2 pos = glm::vec2(mvlVertices[i * 5], mvlVertices[i * 5 + 1]); - (void)pos; // Currently unused + for (int i = 0; i < vertexCount; i += 4) { glm::vec2 bottomLeftV = glm::vec2(mvlVertices[i * 5], mvlVertices[i * 5 + 1]); glm::vec2 topLeftV = @@ -1190,15 +1188,6 @@ void Renderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, glm::vec2 bottomRightUV = glm::vec2(mvlVertices[(i + 3) * 5 + 3], mvlVertices[(i + 3) * 5 + 4]); - bottomLeftV *= scale; - bottomLeftV += topLeft; - topLeftV *= scale; - topLeftV += topLeft; - topRightV *= scale; - topRightV += topLeft; - bottomRightV *= scale; - bottomRightV += topLeft; - // top-left vertices[i].Position = DesignToNDCNonFlipped(topLeftV); vertices[i].UV = topLeftUV; diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 83b3430fb..1745a7c2a 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -84,10 +84,9 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, int indicesCount, - uint16_t* mvlIndices, bool inverted, glm::vec4 tint, - glm::vec2 scale) override; + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + std::span indices, glm::vec4 tint, + bool inverted) override; void DrawVideoTexture(YUVFrame* tex, RectF const& dest, glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, From 9ced0e9c6b5dfc3d9b3405184e2015d21cb1196e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 21:44:35 +0200 Subject: [PATCH 21/88] Changed DrawRect into more generic DrawQuad --- src/renderer/renderer.cpp | 8 +++++++- src/renderer/renderer.h | 13 ++++++++----- 2 files changed, 15 insertions(+), 6 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 442ae4460..41259c5b2 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -183,9 +183,15 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, rot, tint, inverted); } +void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { + DrawSprite(RectSprite, dest, {color, color, color, color}); +} + void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, const float angle) { - DrawSprite(RectSprite, dest, color, angle); + DrawQuad(CornersQuad(dest).Transform( + Transformation2D({0.0f, 0.0f}, dest.Center(), angle)), + color); } void BaseRenderer::DrawRect3DRotated(const RectF& dest, const float depth, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 5f8533a41..e9b0b28c3 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -124,8 +124,16 @@ class BaseRenderer { bool inverted = false, bool disableBlend = false) = 0; + void DrawQuad(const CornersQuad& dest, glm::vec4 color); + + // TODO: Remove entirely void DrawRect(const RectF& dest, glm::vec4 color, float angle = 0.0f); + // TODO: Remove entirely + void DrawRect3DRotated(const RectF& dest, float depth, + glm::vec2 vanishingPoint, bool stayInScreen, + glm::quat rot, glm::vec4 color); + void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, @@ -137,11 +145,6 @@ class BaseRenderer { virtual void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) = 0; - // TODO: Remove entirely - void DrawRect3DRotated(const RectF& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color); - void DrawProcessedText_BasicFont(std::span text, BasicFont* font, float opacity, RendererOutlineMode outlineMode, From b9d2069c9f60163188b8ba12e3902a7f5e92e458 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 22:17:39 +0200 Subject: [PATCH 22/88] Changed pure virtual DrawVideoTexture to be more generic --- src/renderer/dx9/renderer.cpp | 18 ++++++++-------- src/renderer/dx9/renderer.h | 5 ++--- src/renderer/opengl/renderer.cpp | 26 +++++++++++----------- src/renderer/opengl/renderer.h | 5 ++--- src/renderer/renderer.cpp | 37 ++++++++++---------------------- src/renderer/renderer.h | 16 +++++++------- src/renderer/vulkan/renderer.cpp | 18 ++++++++-------- src/renderer/vulkan/renderer.h | 5 ++--- src/util.h | 4 ++++ 9 files changed, 60 insertions(+), 74 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 7fdea6b24..dec8fa817 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -352,7 +352,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; @@ -485,7 +485,7 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -547,7 +547,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -594,7 +594,7 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) @@ -679,8 +679,8 @@ void Renderer::Flush() { CurrentTexture = -1; } -void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint, float angle, bool alphaVideo) { +void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVideoTexture() called before BeginFrame()\n"); @@ -709,9 +709,9 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, IndexBufferFill += 6; - QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, + frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index fd33fb4ac..afbf4989f 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -60,9 +60,8 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, - bool alphaVideo = false) override; + void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 6575f0c9c..33b983af0 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -351,7 +351,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; @@ -503,7 +503,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; @@ -576,7 +576,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -637,7 +637,7 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -695,7 +695,7 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); } @@ -755,8 +755,8 @@ void Renderer::Flush() { CurrentTexture = 0; } -void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint, float angle, bool alphaVideo) { +void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVideoTexture() called before BeginFrame()\n"); @@ -778,16 +778,16 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, // Luma glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, tex->LumaId); + glBindTexture(GL_TEXTURE_2D, frame.LumaId); // Cb glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, tex->CbId); + glBindTexture(GL_TEXTURE_2D, frame.CbId); glBindSampler(2, Sampler); // Cr glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, tex->CrId); + glBindTexture(GL_TEXTURE_2D, frame.CrId); glBindSampler(4, Sampler); // OK, all good, make quad @@ -798,9 +798,9 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, IndexBufferFill += 6; - QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, + frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index c62e0cd92..5662c51eb 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -76,9 +76,8 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, - bool alphaVideo = false) override; + void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 41259c5b2..777b1a705 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -274,9 +274,14 @@ void BaseRenderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, void BaseRenderer::DrawVideoTexture(YUVFrame* tex, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle, bool alphaVideo) { - RectF scaledDest(topLeft.x, topLeft.y, scale.x * tex->Width, - scale.y * tex->Height); - DrawVideoTexture(tex, scaledDest, tint, angle, alphaVideo); + CornersQuad corners = CornersQuad( + RectF(topLeft.x, topLeft.y, scale.x * tex->Width, scale.y * tex->Height)); + + const glm::mat4 transformation = + Transformation2D({0.0f, 0.0f}, corners.Center(), angle); + corners.Transform(transformation); + + DrawVideoTexture(*tex, corners, tint, alphaVideo); } void BaseRenderer::DrawProcessedText_BasicFont( @@ -430,7 +435,7 @@ void BaseRenderer::DrawProcessedText_LBFont( if (maskedSheet) Flush(); } -void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, float angle, +void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, uintptr_t positions, int stride) { glm::vec2 bottomLeft = glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); @@ -440,16 +445,6 @@ void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, float angle, glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y + transformedQuad.Height); - if (angle != 0.0f) { - glm::vec2 center = transformedQuad.Center(); - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } - // top-left *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(topLeft); // bottom-left @@ -460,18 +455,8 @@ void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, float angle, *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(topRight); } -void BaseRenderer::QuadSetPosition(CornersQuad destQuad, float angle, - uintptr_t positions, int stride) { - if (angle != 0.0f) { - glm::vec2 center = (destQuad.BottomLeft + destQuad.TopRight) * 0.5f; - glm::mat2 rot = Rotate2D(angle); - - destQuad.BottomLeft = rot * (destQuad.BottomLeft - center) + center; - destQuad.TopLeft = rot * (destQuad.TopLeft - center) + center; - destQuad.TopRight = rot * (destQuad.TopRight - center) + center; - destQuad.BottomRight = rot * (destQuad.BottomRight - center) + center; - } - +void BaseRenderer::QuadSetPosition(CornersQuad destQuad, uintptr_t positions, + int stride) { // top-left *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.TopLeft); // bottom-left diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index e9b0b28c3..cc88cfa56 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -187,10 +187,10 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0), glm::vec2 scale = glm::vec2(1.0f)); - virtual void DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint = glm::vec4(1.0), - float angle = 0.0f, - bool alphaVideo = false) = 0; + virtual void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + glm::vec4 tint, bool alphaVideo = false) = 0; + + // TODO: Remove entirely void DrawVideoTexture(YUVFrame* tex, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0), glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, @@ -231,10 +231,10 @@ class BaseRenderer { designWidth, designHeight, uvs, stride); } - static void QuadSetPosition(RectF const& transformedQuad, float angle, - uintptr_t positions, int stride); - static void QuadSetPosition(CornersQuad destQuad, float angle, - uintptr_t positions, int stride); + static void QuadSetPosition(RectF const& transformedQuad, uintptr_t positions, + int stride); + static void QuadSetPosition(CornersQuad destQuad, uintptr_t positions, + int stride); static void QuadSetPositionOffset(RectF const& spriteBounds, glm::vec2 displayXY, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 76533909b..be9458463 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1240,7 +1240,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; @@ -1406,7 +1406,7 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -1505,7 +1505,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; @@ -1569,7 +1569,7 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, 0.0f, (uintptr_t)&vertices[0].Position, + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); } @@ -1663,8 +1663,8 @@ void Renderer::Flush() { CurrentTexture = 0; } -void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint, float angle, bool alphaVideo) { +void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVideoTexture() called before BeginFrame()\n"); @@ -1711,9 +1711,9 @@ void Renderer::DrawVideoTexture(YUVFrame* tex, RectF const& dest, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(RectF(0.0f, 0.0f, tex->Width, tex->Height), tex->Width, tex->Height, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, angle, (uintptr_t)&vertices[0].Position, + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, + frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); + QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 1745a7c2a..6f8cf8e74 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -88,9 +88,8 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(YUVFrame* tex, RectF const& dest, - glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, - bool alphaVideo = false) override; + void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/util.h b/src/util.h index 732e98274..5c7cf8fde 100644 --- a/src/util.h +++ b/src/util.h @@ -204,6 +204,10 @@ struct CornersQuad { {(float)(rect.X + rect.Width), (float)rect.Y}, {(float)(rect.X + rect.Width), (float)(rect.Y + rect.Height)}) {} + constexpr glm::vec2 Center() const { + return (TopLeft + BottomLeft + TopRight + BottomRight) / 4.0f; + } + CornersQuad& Transform(glm::mat4 transformation); }; From e5a56ff373d0386f947b2ebd9114a82fbf314b27 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 22:33:24 +0200 Subject: [PATCH 23/88] Changed some arrays to spans --- src/renderer/dx9/renderer.cpp | 2 +- src/renderer/dx9/renderer.h | 2 +- src/renderer/opengl/renderer.cpp | 4 ++-- src/renderer/opengl/renderer.h | 4 ++-- src/renderer/renderer.cpp | 3 ++- src/renderer/renderer.h | 4 ++-- src/renderer/vulkan/renderer.cpp | 2 +- src/renderer/vulkan/renderer.h | 2 +- 8 files changed, 12 insertions(+), 11 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index dec8fa817..8875e80b2 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -322,7 +322,7 @@ void Renderer::DrawCharacterMvl(const Sprite& sprite, } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + const std::span tints, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index afbf4989f..0f9096e25 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -35,7 +35,7 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + std::span tints, const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 33b983af0..809e9ac8e 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -313,7 +313,7 @@ void Renderer::DrawCharacterMvl(const Sprite& sprite, } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + const std::span tints, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, @@ -443,7 +443,7 @@ void Renderer::DrawVertices(SpriteSheet const& sheet, void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, const int fadeRange, - const std::array& tints, + const std::span tints, const bool isInverted, const bool isSameTexture) { if (!Drawing) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 5662c51eb..ada0d0d9a 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -46,7 +46,7 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + std::span tints, const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, @@ -57,7 +57,7 @@ class Renderer : public BaseRenderer { void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, - const std::array& tints, bool isInverted, + std::span tints, bool isInverted, bool isSameTexture) override; void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 777b1a705..63f6f9f89 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -184,7 +184,8 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, } void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { - DrawSprite(RectSprite, dest, {color, color, color, color}); + DrawSprite(RectSprite, dest, + std::array{color, color, color, color}); } void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index cc88cfa56..0938f5381 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -45,7 +45,7 @@ class BaseRenderer { virtual YUVFrame* CreateYUVFrame(float width, float height) = 0; virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + std::span tints, bool inverted = false) = 0; void DrawSprite(const Sprite& sprite, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); @@ -83,7 +83,7 @@ class BaseRenderer { virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, - const std::array& tints, + std::span tints, bool isInverted = false, bool isSameTexture = false) {} void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index be9458463..869572cbe 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1210,7 +1210,7 @@ void Renderer::DrawCharacterMvl(const Sprite& sprite, } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::array const& tints, + const std::span tints, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 6f8cf8e74..2e267b08d 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -63,7 +63,7 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - const std::array& tints, + std::span tints, const bool inverted) override; void DrawVertices(SpriteSheet const& sheet, From fb0e8784308ad705ecafc6d726d93bdfb8fd0cf2 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 22:37:38 +0200 Subject: [PATCH 24/88] Removed superfluous angle parameter from QuadSetUV --- src/renderer/renderer.cpp | 33 +++++++++------------------------ src/renderer/renderer.h | 3 +-- 2 files changed, 10 insertions(+), 26 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 63f6f9f89..15176ce5e 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -572,35 +572,20 @@ void BaseRenderer::QuadSetPosition3DRotated(RectF const& transformedQuad, void BaseRenderer::QuadSetUV(const RectF spriteBounds, const float designWidth, const float designHeight, glm::vec2* const uvs, - const size_t stride, const float angle) { - float topUV = (spriteBounds.Y / designHeight); - float leftUV = (spriteBounds.X / designWidth); - float bottomUV = ((spriteBounds.Y + spriteBounds.Height) / designHeight); - float rightUV = ((spriteBounds.X + spriteBounds.Width) / designWidth); - - glm::vec2 bottomLeft(leftUV, bottomUV); - glm::vec2 topLeft(leftUV, topUV); - glm::vec2 topRight(rightUV, topUV); - glm::vec2 bottomRight(rightUV, bottomUV); - - if (angle != 0.0f) { - glm::vec2 center = (bottomLeft + topRight) * 0.5f; // Center of the quad - glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * (bottomLeft - center) + center; - topLeft = rot * (topLeft - center) + center; - topRight = rot * (topRight - center) + center; - bottomRight = rot * (bottomRight - center) + center; - } + const size_t stride) { + const float topUV = spriteBounds.Y / designHeight; + const float leftUV = spriteBounds.X / designWidth; + const float bottomUV = (spriteBounds.Y + spriteBounds.Height) / designHeight; + const float rightUV = (spriteBounds.X + spriteBounds.Width) / designWidth; // top-left - *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = topLeft; + *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = {leftUV, topUV}; // bottom-left - *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = bottomLeft; + *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = {leftUV, bottomUV}; // bottom-right - *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = bottomRight; + *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = {rightUV, bottomUV}; // top-right - *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = topRight; + *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = {rightUV, topUV}; } } // namespace Impacto diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 0938f5381..d180481a0 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -220,8 +220,7 @@ class BaseRenderer { }; static void QuadSetUV(const RectF spriteBounds, float designWidth, - float designHeight, glm::vec2* uvs, size_t stride, - float angle = 0.0f); + float designHeight, glm::vec2* uvs, size_t stride); static void QuadSetUVFlipped(const RectF spriteBounds, float designWidth, float designHeight, glm::vec2* uvs, From 5bac30b781e44db7a4d11117dda3e99239e9e7d4 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 22:40:50 +0200 Subject: [PATCH 25/88] Removed superfluous transformed QuadSetUV methods --- src/renderer/renderer.cpp | 122 -------------------------------------- src/renderer/renderer.h | 12 ---- 2 files changed, 134 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 15176ce5e..a6d535d8f 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -436,26 +436,6 @@ void BaseRenderer::DrawProcessedText_LBFont( if (maskedSheet) Flush(); } -void BaseRenderer::QuadSetPosition(RectF const& transformedQuad, - uintptr_t positions, int stride) { - glm::vec2 bottomLeft = - glm::vec2(transformedQuad.X, transformedQuad.Y + transformedQuad.Height); - glm::vec2 topLeft = glm::vec2(transformedQuad.X, transformedQuad.Y); - glm::vec2 topRight = - glm::vec2(transformedQuad.X + transformedQuad.Width, transformedQuad.Y); - glm::vec2 bottomRight = glm::vec2(transformedQuad.X + transformedQuad.Width, - transformedQuad.Y + transformedQuad.Height); - - // top-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(topLeft); - // bottom-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(bottomLeft); - // bottom-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(bottomRight); - // top-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(topRight); -} - void BaseRenderer::QuadSetPosition(CornersQuad destQuad, uintptr_t positions, int stride) { // top-left @@ -468,108 +448,6 @@ void BaseRenderer::QuadSetPosition(CornersQuad destQuad, uintptr_t positions, *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.TopRight); } -void BaseRenderer::QuadSetPositionOffset( - RectF const& spriteBounds, glm::vec2 displayXY, glm::vec2 displayOffset, - glm::vec2 scale, float angle, uintptr_t positions, int stride, bool toNDC) { - glm::vec2 topLeft = {0.0f, 0.0f}; - glm::vec2 bottomLeft = {0.0f, spriteBounds.Height}; - glm::vec2 topRight = {spriteBounds.Width, 0.0f}; - glm::vec2 bottomRight = {spriteBounds.Width, spriteBounds.Height}; - - // Translate to origin - topLeft -= displayOffset; - bottomLeft -= displayOffset; - topRight -= displayOffset; - bottomRight -= displayOffset; - - // Scale - bottomLeft *= scale; - topLeft *= scale; - topRight *= scale; - bottomRight *= scale; - - // Rotate - if (angle != 0.0f) { - const glm::mat2 rot = Rotate2D(angle); - - bottomLeft = rot * bottomLeft; - topLeft = rot * topLeft; - topRight = rot * topRight; - bottomRight = rot * bottomRight; - } - - // Translate to the desired screen position - bottomLeft += displayOffset + displayXY; - topLeft += displayOffset + displayXY; - topRight += displayOffset + displayXY; - bottomRight += displayOffset + displayXY; - - if (toNDC) { - topLeft = DesignToNDC(topLeft); - bottomLeft = DesignToNDC(bottomLeft); - bottomRight = DesignToNDC(bottomRight); - topRight = DesignToNDC(topRight); - } - - // Store the transformed positions - *(glm::vec2*)(positions + 0 * stride) = topLeft; - *(glm::vec2*)(positions + 1 * stride) = bottomLeft; - *(glm::vec2*)(positions + 2 * stride) = bottomRight; - *(glm::vec2*)(positions + 3 * stride) = topRight; -} - -void BaseRenderer::QuadSetPosition3DRotated(RectF const& transformedQuad, - float depth, - glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - uintptr_t positions, int stride) { - float widthNormalized = transformedQuad.Width / (Profile::DesignWidth * 0.5f); - float heightNormalized = - transformedQuad.Height / (Profile::DesignHeight * 0.5f); - - glm::vec4 corners[4]{ - // top-left - {glm::vec2(-widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // top-right - {glm::vec2(widthNormalized / 2.0f, heightNormalized / 2.0f), 0, 1}, - // bottom-right - {glm::vec2(widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}, - // bottom-left - {glm::vec2(-widthNormalized / 2.0f, -heightNormalized / 2.0f), 0, 1}}; - - glm::mat4 transform = - glm::translate( - glm::mat4(1.0f), - glm::vec3(DesignToNDCNonFlipped(transformedQuad.Center()), 0)) * - glm::mat4_cast(rot); - - glm::vec4 vanishingPointNDC(DesignToNDCNonFlipped(vanishingPoint), 0, 0); - - for (int i = 0; i < 4; i++) { - corners[i] = transform * corners[i]; - } - - if (stayInScreen) { - float maxZ = 0.0f; - for (int i = 0; i < 4; i++) { - if (corners[i].z > maxZ) maxZ = corners[i].z; - } - for (int i = 0; i < 4; i++) { - corners[i].z -= maxZ; - } - } - - for (int i = 0; i < 4; i++) { - // perspective - corners[i] -= vanishingPointNDC; - corners[i].x *= (depth / (depth - corners[i].z)); - corners[i].y *= (depth / (depth - corners[i].z)); - corners[i] += vanishingPointNDC; - - *(glm::vec2*)(positions + i * stride) = corners[i]; - } -} - void BaseRenderer::QuadSetUV(const RectF spriteBounds, const float designWidth, const float designHeight, glm::vec2* const uvs, const size_t stride) { diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index d180481a0..88474259c 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -230,21 +230,9 @@ class BaseRenderer { designWidth, designHeight, uvs, stride); } - static void QuadSetPosition(RectF const& transformedQuad, uintptr_t positions, - int stride); static void QuadSetPosition(CornersQuad destQuad, uintptr_t positions, int stride); - static void QuadSetPositionOffset(RectF const& spriteBounds, - glm::vec2 displayXY, - glm::vec2 displayOffset, glm::vec2 scale, - float angle, uintptr_t positions, - int stride, bool toNDC = true); - static void QuadSetPosition3DRotated(RectF const& transformedQuad, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - uintptr_t positions, int stride); - Sprite RectSprite; }; From 192119445137af0ef5b46902adede175a0af867e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 23:08:20 +0200 Subject: [PATCH 26/88] Improved QuadSet function definitions --- src/renderer/dx9/renderer.cpp | 47 ++++++++++----------- src/renderer/opengl/renderer.cpp | 70 +++++++++++++------------------- src/renderer/renderer.cpp | 35 +++++----------- src/renderer/renderer.h | 16 ++++---- src/renderer/vulkan/renderer.cpp | 48 ++++++++++------------ src/spritesheet.h | 2 + 6 files changed, 93 insertions(+), 125 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 8875e80b2..8ce6c3de8 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -350,10 +350,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, IndexBufferFill += 6; - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -480,13 +479,12 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -542,13 +540,12 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -587,15 +584,13 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = glm::vec4(1.0f, 1.0f, 1.0f, 1.0f); @@ -709,10 +704,10 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, IndexBufferFill += 6; - QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, - frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), + {frame.Width, frame.Height}, &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 809e9ac8e..62d58f3c4 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -343,16 +343,13 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, IndexBufferFill += 6; if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), + &vertices[0].UV, sizeof(VertexBufferSprites)); } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -492,19 +489,16 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), + &vertices[0].UV, sizeof(VertexBufferSprites)); } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetUV(sprite.Bounds, sprite.Bounds.Width, sprite.Bounds.Height, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Bounds.GetSize(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -570,14 +564,13 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -626,19 +619,16 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, IndexBufferFill += 6; if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, - sizeof(VertexBufferSprites)); + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), + &vertices[0].UV, sizeof(VertexBufferSprites)); } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -688,15 +678,13 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, IndexBufferFill += 6; - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.DesignWidth, - sprite.Sheet.DesignHeight, &vertices[0].UV, + QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); } void Renderer::EnsureSpaceAvailable(int vertices, int vertexSize, int indices) { @@ -798,10 +786,10 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, IndexBufferFill += 6; - QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, - frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), + {frame.Width, frame.Height}, &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index a6d535d8f..bdf81a695 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -436,34 +436,21 @@ void BaseRenderer::DrawProcessedText_LBFont( if (maskedSheet) Flush(); } -void BaseRenderer::QuadSetPosition(CornersQuad destQuad, uintptr_t positions, +void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, int stride) { - // top-left - *(glm::vec2*)(positions + 0 * stride) = DesignToNDC(destQuad.TopLeft); - // bottom-left - *(glm::vec2*)(positions + 1 * stride) = DesignToNDC(destQuad.BottomLeft); - // bottom-right - *(glm::vec2*)(positions + 2 * stride) = DesignToNDC(destQuad.BottomRight); - // top-right - *(glm::vec2*)(positions + 3 * stride) = DesignToNDC(destQuad.TopRight); + *(glm::vec2*)((uint8_t*)pos + 0 * stride) = DesignToNDC(quad.TopLeft); + *(glm::vec2*)((uint8_t*)pos + 1 * stride) = DesignToNDC(quad.BottomLeft); + *(glm::vec2*)((uint8_t*)pos + 2 * stride) = DesignToNDC(quad.BottomRight); + *(glm::vec2*)((uint8_t*)pos + 3 * stride) = DesignToNDC(quad.TopRight); } -void BaseRenderer::QuadSetUV(const RectF spriteBounds, const float designWidth, - const float designHeight, glm::vec2* const uvs, +void BaseRenderer::QuadSetUV(const CornersQuad bounds, + const glm::vec2 dimensions, glm::vec2* const uvs, const size_t stride) { - const float topUV = spriteBounds.Y / designHeight; - const float leftUV = spriteBounds.X / designWidth; - const float bottomUV = (spriteBounds.Y + spriteBounds.Height) / designHeight; - const float rightUV = (spriteBounds.X + spriteBounds.Width) / designWidth; - - // top-left - *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = {leftUV, topUV}; - // bottom-left - *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = {leftUV, bottomUV}; - // bottom-right - *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = {rightUV, bottomUV}; - // top-right - *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = {rightUV, topUV}; + *(glm::vec2*)((uint8_t*)uvs + 0 * stride) = bounds.TopLeft / dimensions; + *(glm::vec2*)((uint8_t*)uvs + 1 * stride) = bounds.BottomLeft / dimensions; + *(glm::vec2*)((uint8_t*)uvs + 2 * stride) = bounds.BottomRight / dimensions; + *(glm::vec2*)((uint8_t*)uvs + 3 * stride) = bounds.TopRight / dimensions; } } // namespace Impacto diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 88474259c..231a7fc39 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -219,18 +219,18 @@ class BaseRenderer { glm::vec2 MaskUV; }; - static void QuadSetUV(const RectF spriteBounds, float designWidth, - float designHeight, glm::vec2* uvs, size_t stride); + static void QuadSetUV(CornersQuad spriteBounds, glm::vec2 designDimensions, + glm::vec2* uvs, size_t stride); - static void QuadSetUVFlipped(const RectF spriteBounds, float designWidth, - float designHeight, glm::vec2* uvs, + static void QuadSetUVFlipped(CornersQuad spriteBounds, + glm::vec2 designDimensions, glm::vec2* uvs, size_t stride) { - QuadSetUV({spriteBounds.X, spriteBounds.Y + spriteBounds.Height, - spriteBounds.Width, -spriteBounds.Height}, - designWidth, designHeight, uvs, stride); + QuadSetUV({spriteBounds.BottomLeft, spriteBounds.TopLeft, + spriteBounds.BottomRight, spriteBounds.TopRight}, + designDimensions, uvs, stride); } - static void QuadSetPosition(CornersQuad destQuad, uintptr_t positions, + static void QuadSetPosition(CornersQuad destQuad, glm::vec2* positions, int stride); Sprite RectSprite; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 869572cbe..856fb09be 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1238,10 +1238,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -1401,13 +1400,12 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -1500,13 +1498,12 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } @@ -1564,13 +1561,12 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(sprite.Bounds, sprite.Sheet.DesignWidth, sprite.Sheet.DesignHeight, - &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.DesignWidth, mask.Sheet.DesignHeight, - &vertices[0].MaskUV, sizeof(VertexBufferSprites)); + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); } inline void Renderer::MakeQuad() { @@ -1711,10 +1707,10 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, VertexBufferFill); VertexBufferFill += 4 * sizeof(VertexBufferSprites); - QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), frame.Width, - frame.Height, &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, (uintptr_t)&vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), + {frame.Width, frame.Height}, &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } diff --git a/src/spritesheet.h b/src/spritesheet.h index e1df2e65d..b1035f0b3 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -12,6 +12,8 @@ struct SpriteSheet { float DesignWidth = 0; float DesignHeight = 0; + glm::vec2 GetDimensions() const { return {DesignWidth, DesignHeight}; } + uint32_t Texture = 0; bool IsScreenCap = false; }; From a4cfe407b9b1b021e561e6d759d60bcc738f7c16 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 28 Apr 2025 23:44:18 +0200 Subject: [PATCH 27/88] Implemented DrawMaskedSprite for DirectX9 and Vulkan --- src/renderer/dx9/renderer.cpp | 175 +++++++++++++------- src/renderer/dx9/renderer.h | 5 + src/renderer/opengl/renderer.cpp | 182 ++++++++++---------- src/renderer/renderer.h | 2 +- src/renderer/vulkan/renderer.cpp | 274 ++++++++++++++++++++----------- src/renderer/vulkan/renderer.h | 5 + 6 files changed, 390 insertions(+), 253 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 8ce6c3de8..3867b1896 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -357,6 +357,120 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } +void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const std::span tints, + const bool isInverted, + const bool isSameTexture) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); + return; + } + + if (sprite.Sheet.IsScreenCap) Flush(); + + alpha = std::clamp(alpha, 0, fadeRange + 256); + const float alphaRange = 256.0f / fadeRange; + const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + + // Do we have space for one more sprite quad? + EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); + + std::array alphaRes = {alphaRange, constAlpha}; + const BOOL isInvertedB = (BOOL)isInverted; + const BOOL isSameTextureB = (BOOL)isSameTexture; + + EnsureShader(ShaderMaskedSprite); + Device->SetTexture(0, Textures[sprite.Sheet.Texture]); + Device->SetTexture(1, Textures[mask.Sheet.Texture]); + + Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + Device->SetPixelShaderConstantF(0, alphaRes.data(), 1); + Device->SetPixelShaderConstantB(0, &isInvertedB, 1); + Device->SetPixelShaderConstantB(1, &isSameTextureB, 1); + + // OK, all good, make quad + + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); + VertexBufferFill += 4 * sizeof(VertexBufferSprites); + + IndexBufferFill += 6; + + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); + + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; +} + +void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const glm::vec4 tint, + const bool isInverted, + const bool useMaskAlpha) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); + return; + } + + if (sprite.Sheet.IsScreenCap) Flush(); + + if (alpha < 0) alpha = 0; + if (alpha > fadeRange + 256) alpha = fadeRange + 256; + + float alphaRange = 256.0f / fadeRange; + float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + + // Do we have space for one more sprite quad? + EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); + + std::array alphaRes = {alphaRange, constAlpha}; + BOOL isInvertedB = (BOOL)isInverted; + BOOL isSameTextureB = (BOOL) false; + BOOL useMaskAlphaB = (BOOL)useMaskAlpha; + + if (useMaskAlpha) { + EnsureShader(ShaderMaskedSprite); + Device->SetPixelShaderConstantB(1, &isSameTextureB, 1); + } else { + EnsureShader(ShaderMaskedSpriteNoAlpha); + } + + Device->SetTexture(0, Textures[sprite.Sheet.Texture]); + Device->SetTexture(1, Textures[mask.Sheet.Texture]); + + Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + Device->SetPixelShaderConstantF(0, alphaRes.data(), 1); + Device->SetPixelShaderConstantB(0, &isInvertedB, 1); + + // OK, all good, make quad + + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); + VertexBufferFill += 4 * sizeof(VertexBufferSprites); + + IndexBufferFill += 6; + + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); + + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + + for (int i = 0; i < 4; i++) vertices[i].Tint = tint; +} + void Renderer::DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, @@ -489,67 +603,6 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } -void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, - const int fadeRange, - const glm::vec4 tint, - const bool isInverted, - const bool useMaskAlpha) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); - return; - } - - if (sprite.Sheet.IsScreenCap) Flush(); - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - - float alphaRes[] = {alphaRange, constAlpha}; - BOOL isInvertedB = (BOOL)isInverted; - BOOL isSameTextureB = (BOOL) false; - BOOL useMaskAlphaB = (BOOL)useMaskAlpha; - - if (useMaskAlpha) { - EnsureShader(ShaderMaskedSprite); - Device->SetPixelShaderConstantB(1, &isSameTextureB, 1); - } else { - EnsureShader(ShaderMaskedSpriteNoAlpha); - } - - Device->SetTexture(0, Textures[sprite.Sheet.Texture]); - Device->SetTexture(1, Textures[mask.Sheet.Texture]); - - Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); - Device->SetPixelShaderConstantF(0, alphaRes, 1); - Device->SetPixelShaderConstantB(0, &isInvertedB, 1); - - // OK, all good, make quad - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) { if (!Drawing) { diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 0f9096e25..36bf64323 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -38,6 +38,11 @@ class Renderer : public BaseRenderer { std::span tints, const bool inverted) override; + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, int fadeRange, + std::span tints, bool isInverted, + bool isSameTexture); + void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, int width, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 62d58f3c4..79c2422a8 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -354,89 +354,6 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, glm::vec4 tint, - bool inverted, bool disableBlend) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawVertices() called before BeginFrame()\n"); - return; - } - - if (disableBlend) { - glDisable(GL_BLEND); - } - - const int verticesCount = sheetPositions.size(); - - if (verticesCount != displayPositions.size()) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawVertices() called with mismatched vertices count\n"); - return; - } - Flush(); - glBindSampler(2, Sampler); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); - - EnsureSpaceAvailable(verticesCount, sizeof(VertexBufferSprites), - verticesCount * 3); - EnsureModeSprite(inverted); - - EnsureTextureBound(sheet.Texture); - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); - std::vector indices; - indices.reserve((width - 1) * (height - 1) * 6); - // Generate indices for triangles - for (int y = 0; y < height - 1; y++) { - for (int x = 0; x < width - 1; x++) { - int v0 = y * width + x; - int v1 = y * width + (x + 1); - int v2 = (y + 1) * width + x; - int v3 = (y + 1) * width + (x + 1); - - // First triangle - for (auto v : {v1, v0, v2}) { - indices.push_back(v); - } - // Second triangle - for (auto v : {v3, v1, v2}) { - indices.push_back(v); - } - } - } - IndexBufferFill += indices.size(); - - glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferFill * sizeof(uint16_t), - indices.data(), GL_STATIC_DRAW); - - for (int i = 0; i < verticesCount; i++) { - vertices[i].Position = DesignToNDC(displayPositions[i]); - vertices[i].Tint = tint; - glm::vec2 uv = - sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); - if (sheet.IsScreenCap) { - uv.y = 1.0f - uv.y; - } - vertices[i].UV = uv; - } - - // Flush again and bind back our buffer - Flush(); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (disableBlend) { - glEnable(GL_BLEND); - } - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, - GL_STATIC_DRAW); -} - void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, const int fadeRange, @@ -449,11 +366,9 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, return; } - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + alpha = std::clamp(alpha, 0, fadeRange + 256); + const float alphaRange = 256.0f / fadeRange; + const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); @@ -515,11 +430,9 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, return; } - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + alpha = std::clamp(alpha, 0, fadeRange + 256); + const float alphaRange = 256.0f / fadeRange; + const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); @@ -575,6 +488,89 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } +void Renderer::DrawVertices(SpriteSheet const& sheet, + std::span sheetPositions, + std::span displayPositions, + int width, int height, glm::vec4 tint, + bool inverted, bool disableBlend) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawVertices() called before BeginFrame()\n"); + return; + } + + if (disableBlend) { + glDisable(GL_BLEND); + } + + const int verticesCount = sheetPositions.size(); + + if (verticesCount != displayPositions.size()) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawVertices() called with mismatched vertices count\n"); + return; + } + Flush(); + glBindSampler(2, Sampler); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + + EnsureSpaceAvailable(verticesCount, sizeof(VertexBufferSprites), + verticesCount * 3); + EnsureModeSprite(inverted); + + EnsureTextureBound(sheet.Texture); + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); + VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + std::vector indices; + indices.reserve((width - 1) * (height - 1) * 6); + // Generate indices for triangles + for (int y = 0; y < height - 1; y++) { + for (int x = 0; x < width - 1; x++) { + int v0 = y * width + x; + int v1 = y * width + (x + 1); + int v2 = (y + 1) * width + x; + int v3 = (y + 1) * width + (x + 1); + + // First triangle + for (auto v : {v1, v0, v2}) { + indices.push_back(v); + } + // Second triangle + for (auto v : {v3, v1, v2}) { + indices.push_back(v); + } + } + } + IndexBufferFill += indices.size(); + + glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferFill * sizeof(uint16_t), + indices.data(), GL_STATIC_DRAW); + + for (int i = 0; i < verticesCount; i++) { + vertices[i].Position = DesignToNDC(displayPositions[i]); + vertices[i].Tint = tint; + glm::vec2 uv = + sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); + if (sheet.IsScreenCap) { + uv.y = 1.0f - uv.y; + } + vertices[i].UV = uv; + } + + // Flush again and bind back our buffer + Flush(); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + if (disableBlend) { + glEnable(GL_BLEND); + } + glBufferData(GL_ELEMENT_ARRAY_BUFFER, + IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, + GL_STATIC_DRAW); +} + void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) { diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 231a7fc39..1e7ea550e 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -85,7 +85,7 @@ class BaseRenderer { int fadeRange, std::span tints, bool isInverted = false, - bool isSameTexture = false) {} + bool isSameTexture = false) = 0; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 856fb09be..79195f414 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1245,6 +1245,182 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } +void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const std::span tints, + const bool isInverted, + const bool isSameTexture) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); + return; + } + + if (sprite.Sheet.IsScreenCap) Flush(); + + if (Textures.count(sprite.Sheet.Texture) == 0 || + Textures.count(mask.Sheet.Texture) == 0) + return; + + alpha = std::clamp(alpha, 0, fadeRange + 256); + const float alphaRange = 256.0f / fadeRange; + const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.pNext = nullptr; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.anisotropyEnable = VK_TRUE; + samplerInfo.maxAnisotropy = 16; + + VkDescriptorImageInfo imageBufferInfo[2]; + imageBufferInfo[0].sampler = Sampler; + imageBufferInfo[0].imageView = Textures[sprite.Sheet.Texture].ImageView; + imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + vkCreateSampler(Device, &samplerInfo, nullptr, &imageBufferInfo[1].sampler); + imageBufferInfo[1].imageView = Textures[mask.Sheet.Texture].ImageView; + imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet writeDescriptorSet{}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = 0; + writeDescriptorSet.dstBinding = 0; + writeDescriptorSet.descriptorCount = 2; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = imageBufferInfo; + + EnsureMode(PipelineMaskedSprite, true); + vkCmdPushDescriptorSetKHR( + CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, + CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); + SpritePushConstants constants = {}; + constants.Alpha = glm::vec2(alphaRange, constAlpha); + constants.IsInverted = isInverted; + constants.IsSameTexture = isSameTexture; + vkCmdPushConstants( + CommandBuffers[CurrentFrameIndex], CurrentPipeline->PipelineLayout, + VK_SHADER_STAGE_FRAGMENT_BIT, 0, sizeof(SpritePushConstants), &constants); + + // OK, all good, make quad + MakeQuad(); + + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + + VertexBufferFill); + VertexBufferFill += 4 * sizeof(VertexBufferSprites); + + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); + + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; +} + +void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + const int fadeRange, + const glm::vec4 tint, + const bool isInverted, + const bool useMaskAlpha) { + if (!Drawing) { + ImpLog(LogLevel::Error, LogChannel::Render, + "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); + return; + } + + if (sprite.Sheet.IsScreenCap) Flush(); + + if (Textures.count(sprite.Sheet.Texture) == 0 || + Textures.count(mask.Sheet.Texture) == 0) + return; + + alpha = std::clamp(alpha, 0, fadeRange + 256); + const float alphaRange = 256.0f / fadeRange; + const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; + + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.pNext = nullptr; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.anisotropyEnable = VK_TRUE; + samplerInfo.maxAnisotropy = 16; + + VkDescriptorImageInfo imageBufferInfo[2]; + imageBufferInfo[0].sampler = Sampler; + imageBufferInfo[0].imageView = Textures[sprite.Sheet.Texture].ImageView; + imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + vkCreateSampler(Device, &samplerInfo, nullptr, &imageBufferInfo[1].sampler); + imageBufferInfo[1].imageView = Textures[mask.Sheet.Texture].ImageView; + imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet writeDescriptorSet{}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = 0; + writeDescriptorSet.dstBinding = 0; + writeDescriptorSet.descriptorCount = 2; + writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = imageBufferInfo; + + if (useMaskAlpha) { + EnsureMode(PipelineMaskedSprite, true); + vkCmdPushDescriptorSetKHR( + CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, + CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); + SpritePushConstants constants = {}; + constants.Alpha = glm::vec2(alphaRange, constAlpha); + constants.IsInverted = isInverted; + constants.IsSameTexture = false; + vkCmdPushConstants(CommandBuffers[CurrentFrameIndex], + CurrentPipeline->PipelineLayout, + VK_SHADER_STAGE_FRAGMENT_BIT, 0, + sizeof(SpritePushConstants), &constants); + + } else { + EnsureMode(PipelineMaskedSpriteNoAlpha, true); + vkCmdPushDescriptorSetKHR( + CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, + CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); + MaskedNoAlphaPushConstants constants = {}; + constants.Alpha = glm::vec2(alphaRange, constAlpha); + constants.IsInverted = isInverted; + vkCmdPushConstants(CommandBuffers[CurrentFrameIndex], + CurrentPipeline->PipelineLayout, + VK_SHADER_STAGE_FRAGMENT_BIT, 0, + sizeof(MaskedNoAlphaPushConstants), &constants); + } + + // OK, all good, make quad + MakeQuad(); + + VertexBufferSprites* vertices = + (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + + VertexBufferFill); + VertexBufferFill += 4 * sizeof(VertexBufferSprites); + + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, + sizeof(VertexBufferSprites)); + QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + sizeof(VertexBufferSprites)); + + QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + + for (int i = 0; i < 4; i++) vertices[i].Tint = tint; +} + void Renderer::DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, @@ -1410,104 +1586,6 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tint; } -void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, - const int fadeRange, - const glm::vec4 tint, - const bool isInverted, - const bool useMaskAlpha) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); - return; - } - - if (sprite.Sheet.IsScreenCap) Flush(); - - if (Textures.count(sprite.Sheet.Texture) == 0 || - Textures.count(mask.Sheet.Texture) == 0) - return; - - if (alpha < 0) alpha = 0; - if (alpha > fadeRange + 256) alpha = fadeRange + 256; - - float alphaRange = 256.0f / fadeRange; - float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - - VkSamplerCreateInfo samplerInfo = {}; - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.pNext = nullptr; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.anisotropyEnable = VK_TRUE; - samplerInfo.maxAnisotropy = 16; - - VkDescriptorImageInfo imageBufferInfo[2]; - imageBufferInfo[0].sampler = Sampler; - imageBufferInfo[0].imageView = Textures[sprite.Sheet.Texture].ImageView; - imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - vkCreateSampler(Device, &samplerInfo, nullptr, &imageBufferInfo[1].sampler); - imageBufferInfo[1].imageView = Textures[mask.Sheet.Texture].ImageView; - imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = 0; - writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorCount = 2; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = imageBufferInfo; - - if (useMaskAlpha) { - EnsureMode(PipelineMaskedSprite, true); - vkCmdPushDescriptorSetKHR( - CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, - CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); - SpritePushConstants constants = {}; - constants.Alpha = glm::vec2(alphaRange, constAlpha); - constants.IsInverted = isInverted; - constants.IsSameTexture = false; - vkCmdPushConstants(CommandBuffers[CurrentFrameIndex], - CurrentPipeline->PipelineLayout, - VK_SHADER_STAGE_FRAGMENT_BIT, 0, - sizeof(SpritePushConstants), &constants); - - } else { - EnsureMode(PipelineMaskedSpriteNoAlpha, true); - vkCmdPushDescriptorSetKHR( - CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, - CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); - MaskedNoAlphaPushConstants constants = {}; - constants.Alpha = glm::vec2(alphaRange, constAlpha); - constants.IsInverted = isInverted; - vkCmdPushConstants(CommandBuffers[CurrentFrameIndex], - CurrentPipeline->PipelineLayout, - VK_SHADER_STAGE_FRAGMENT_BIT, 0, - sizeof(MaskedNoAlphaPushConstants), &constants); - } - - // OK, all good, make quad - MakeQuad(); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; -} - void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) { if (!Drawing) { diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 2e267b08d..fde208a3b 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -66,6 +66,11 @@ class Renderer : public BaseRenderer { std::span tints, const bool inverted) override; + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, int fadeRange, + std::span tints, bool isInverted, + bool isSameTexture); + void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, int width, From 8455f088ca1608a0d8c0d33f86f253cd6ae57434 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 30 Apr 2025 02:24:01 +0200 Subject: [PATCH 28/88] Moved ScrWorkAnglesToQuaternion to inline header --- src/util.cpp | 5 ----- src/util.h | 6 +++++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index db5e5dc4a..c9073673a 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -165,9 +165,4 @@ RectF RectF::Coalesce(const RectF& first, const RectF& second) { return rect; } -glm::quat ScrWorkAnglesToQuaternion(const int x, const int y, const int z) { - return glm::quat( - {ScrWorkAngleToRad(x), ScrWorkAngleToRad(y), ScrWorkAngleToRad(z)}); -} - } // namespace Impacto \ No newline at end of file diff --git a/src/util.h b/src/util.h index 5c7cf8fde..83d3f41df 100644 --- a/src/util.h +++ b/src/util.h @@ -317,7 +317,11 @@ constexpr float ScrWorkAngleToRad(float angle) { return angle * (float)(2.0f * M_PI / (float)(1 << 16)); } -glm::quat ScrWorkAnglesToQuaternion(int x, int y, int z); +inline glm::quat ScrWorkAnglesToQuaternion(int x, int y, int z) { + return glm::quat( + {ScrWorkAngleToRad(x), ScrWorkAngleToRad(y), ScrWorkAngleToRad(z)}); +} + inline glm::quat AxisAngleToQuaternion(glm::vec3 axis, float angle) { return glm::quat(cos(angle / 2.0f), sin(angle / 2.0f) * axis); } From 8a1c8998fc45717fbf16296b2cbe07e7d9bc63e9 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 30 Apr 2025 03:10:27 +0200 Subject: [PATCH 29/88] Added monadic transformation methods to CornersQuad and RectF --- src/renderer/vulkan/renderer.h | 2 +- src/spritesheet.h | 2 +- src/util.cpp | 99 ++++++++++++++++++++++++++++++++-- src/util.h | 23 +++++--- 4 files changed, 113 insertions(+), 13 deletions(-) diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index fde208a3b..0e442738a 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -69,7 +69,7 @@ class Renderer : public BaseRenderer { void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, std::span tints, bool isInverted, - bool isSameTexture); + bool isSameTexture) override; void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, diff --git a/src/spritesheet.h b/src/spritesheet.h index b1035f0b3..a6fc61e1f 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -39,7 +39,7 @@ struct Sprite { Bounds.Height = scaledHeight / BaseScale.y; } RectF ScaledBounds() const { - return Bounds.Scale(BaseScale, Bounds.GetPos()); + return RectF(Bounds).Scale(BaseScale, Bounds.GetPos()); } }; diff --git a/src/util.cpp b/src/util.cpp index c9073673a..61101d43d 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -14,6 +14,88 @@ CornersQuad& CornersQuad::Transform(const glm::mat4 transformation) { return *this; } +CornersQuad& CornersQuad::Translate(const glm::vec2 offset) { + TopLeft += offset; + TopRight += offset; + BottomRight += offset; + BottomLeft += offset; + + return *this; +} + +CornersQuad& CornersQuad::Scale(const glm::vec2 scaling, + const glm::vec2 origin) { + Translate(-origin); + + TopLeft *= scaling; + TopRight *= scaling; + BottomRight *= scaling; + BottomLeft *= scaling; + + Translate(origin); + + return *this; +} + +CornersQuad& CornersQuad::Rotate(const float angle, const glm::vec2 origin) { + Translate(-origin); + + const glm::mat2 rotation = Rotate2D(angle); + TopLeft = rotation * TopLeft; + TopRight = rotation * TopRight; + BottomRight = rotation * BottomRight; + BottomLeft = rotation * BottomLeft; + + Translate(origin); + + return *this; +} + +CornersQuad& CornersQuad::Rotate(const glm::quat rotation, glm::vec3 origin) { + glm::vec3 topLeft = glm::vec3(TopLeft, 0.0f) - origin; + glm::vec3 topRight = glm::vec3(TopRight, 0.0f) - origin; + glm::vec3 bottomRight = glm::vec3(BottomRight, 0.0f) - origin; + glm::vec3 bottomLeft = glm::vec3(BottomLeft, 0.0f) - origin; + + const glm::mat3 rotationMatrix = glm::mat3_cast(rotation); + topLeft = rotationMatrix * topLeft; + topRight = rotationMatrix * topRight; + bottomRight = rotationMatrix * bottomRight; + topRight = rotationMatrix * topRight; + + TopLeft = topLeft + origin; + TopRight = topRight + origin; + BottomRight = bottomRight + origin; + BottomLeft = bottomLeft + origin; + + return *this; +} + +CornersQuad RectF::Transform(glm::mat4 transformation) const { + return CornersQuad(*this).Transform(transformation); +} + +RectF& RectF::Scale(const glm::vec2 scaling, const glm::vec2 origin) { + Translate(-origin); + + X *= scaling.x; + Y *= scaling.y; + Width *= scaling.x; + Height *= scaling.y; + + Translate(origin); + + return *this; +} + +CornersQuad RectF::Rotate(float angle, glm::vec2 origin) const { + return CornersQuad(*this).Rotate(angle, origin); +} + +CornersQuad RectF::Rotate(glm::quat rotation, glm::vec3 origin) const { + return CornersQuad(*this).Rotate(rotation, origin); +} + glm::mat2 Rotate2D(float angle) { glm::mat2 result; float cosa = cosf(angle); @@ -35,10 +117,19 @@ glm::mat4 Transformation2D(const glm::vec2 translation, const glm::vec2 origin, glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, const glm::quat rotation, const glm::vec3 scaling) { glm::mat4 matrix(1.0f); - matrix = glm::translate(glm::mat4(1.0f), -origin) * matrix; - matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; - matrix = glm::mat4_cast(normalize(rotation)) * matrix; - matrix = glm::translate(glm::mat4(1.0f), origin + translation) * matrix; + + if (origin != glm::vec3(0.0f)) + matrix = glm::translate(glm::mat4(1.0f), -origin) * matrix; + + if (scaling != glm::vec3(0.0f)) + matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; + + if (rotation != glm::quat()) + matrix = glm::mat4_cast(normalize(rotation)) * matrix; + + if (origin + translation != glm::vec3(0.0f)) + matrix = glm::translate(glm::mat4(1.0f), origin + translation) * matrix; + return matrix; } diff --git a/src/util.h b/src/util.h index 83d3f41df..ac9a6bdf3 100644 --- a/src/util.h +++ b/src/util.h @@ -69,6 +69,7 @@ glm::vec3 Transform3D(glm::vec3 pos, glm::vec3 translation, glm::vec2 scaling = glm::vec2(1.0f)); struct Rect; +struct CornersQuad; struct RectF { float X = 0; @@ -113,14 +114,18 @@ struct RectF { return RectF(X - movementVector.x, Y - movementVector.y, Width, Height); } - constexpr void operator+=(const glm::vec2 movementVector) { + constexpr RectF& operator+=(const glm::vec2 movementVector) { X += movementVector.x; Y += movementVector.y; + + return *this; } - constexpr void operator-=(const glm::vec2 movementVector) { + constexpr RectF& operator-=(const glm::vec2 movementVector) { X -= movementVector.x; Y -= movementVector.y; + + return *this; } constexpr bool operator==(RectF const& other) const { @@ -136,11 +141,11 @@ struct RectF { static RectF Coalesce(const RectF& first, const RectF& second); - constexpr RectF Scale(const glm::vec2 scalar, const glm::vec2 origin) const { - const float scaledX = (X - origin.x) * scalar.x + origin.x; - const float scaledY = (Y - origin.y) * scalar.y + origin.y; - return RectF(scaledX, scaledY, Width * scalar.x, Height * scalar.y); - } + CornersQuad Transform(glm::mat4 transformation) const; + RectF& Translate(glm::vec2 offset) { return *this += offset; } + RectF& Scale(glm::vec2 scaling, glm::vec2 origin); + CornersQuad Rotate(float angle, glm::vec2 origin) const; + CornersQuad Rotate(glm::quat rotation, glm::vec3 origin) const; }; struct Rect { @@ -209,6 +214,10 @@ struct CornersQuad { } CornersQuad& Transform(glm::mat4 transformation); + CornersQuad& Translate(glm::vec2 offset); + CornersQuad& Scale(glm::vec2 scaling, glm::vec2 origin); + CornersQuad& Rotate(float angle, glm::vec2 origin); + CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin); }; inline CornersQuad operator*(const glm::mat4 transformation, CornersQuad quad) { From 24817e1a8843a55650b0223e5b02744757f86c98 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 1 May 2025 22:15:39 +0200 Subject: [PATCH 30/88] Fixed ScrWork variable order in files --- profiles/common/scriptvars.lua | 2 +- src/scriptvars.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/profiles/common/scriptvars.lua b/profiles/common/scriptvars.lua index 1f0afd0e8..eaaab6b81 100644 --- a/profiles/common/scriptvars.lua +++ b/profiles/common/scriptvars.lua @@ -76,11 +76,11 @@ root.ScriptVars = { SW_MASK3ALPHA_OFS=2788, SW_BGEFF1_OFSX=2800, SW_BGEFF1_OFSY=2801, - SW_BGEFF1_ALPHA_OFS=2806, SW_BGEFF1_SIZE_OFS=2802, SW_BGEFF1_ROTX_OFS=2803, SW_BGEFF1_ROTY_OFS=2804, SW_BGEFF1_ROTZ_OFS=2805, + SW_BGEFF1_ALPHA_OFS=2806, SW_BGEFF1_MASK_VERTEX1_OFSX=2809, SW_BGEFF1_MASK_VERTEX1_OFSY=2810, SW_MAINTHDP=3304, diff --git a/src/scriptvars.h b/src/scriptvars.h index 4ae0b2106..0e67451b1 100644 --- a/src/scriptvars.h +++ b/src/scriptvars.h @@ -80,11 +80,11 @@ V(SW_MASK2ALPHA_OFS) V(SW_MASK3ALPHA_OFS) V(SW_BGEFF1_OFSX) V(SW_BGEFF1_OFSY) -V(SW_BGEFF1_ALPHA_OFS) V(SW_BGEFF1_SIZE_OFS) V(SW_BGEFF1_ROTX_OFS) V(SW_BGEFF1_ROTY_OFS) V(SW_BGEFF1_ROTZ_OFS) +V(SW_BGEFF1_ALPHA_OFS) V(SW_BGEFF1_MASK_VERTEX1_OFSX) V(SW_BGEFF1_MASK_VERTEX1_OFSY) V(SW_MAINTHDP) From 66767293d9bf410f1c1fc65da1fdb65a4822241b Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 1 May 2025 22:43:50 +0200 Subject: [PATCH 31/88] Added position overloads to renderer --- src/renderer/renderer.cpp | 92 ++++++++++++++++++++++++++------------- src/renderer/renderer.h | 15 +++++++ 2 files changed, 77 insertions(+), 30 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index bdf81a695..abce7bfaa 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -43,28 +43,34 @@ void InitRenderer() { void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::mat4 transformation, const glm::vec4 tint, const bool inverted) { - CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), - sprite.ScaledHeight())) - .Transform(transformation); + const CornersQuad dest = + RectF(0.0f, 0.0f, sprite.ScaledWidth(), sprite.ScaledHeight()) + .Transform(transformation); + + DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, + inverted); +} +void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, + const glm::vec4 tint, const bool inverted) { + const CornersQuad dest = + RectF(topLeft.x, topLeft.y, sprite.ScaledWidth(), sprite.ScaledHeight()); DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, inverted); } void BaseRenderer::DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, float angle, bool inverted) { - const glm::mat4 transformation = - Transformation2D({0.0f, 0.0f}, dest.Center(), angle); - DrawSprite(sprite, CornersQuad(dest).Transform(transformation), + DrawSprite(sprite, dest.Rotate(angle, dest.Center()), std::array{tint, tint, tint, tint}, inverted); } void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle, bool inverted) { - RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); + const RectF scaledDest(topLeft.x, topLeft.y, + scale.x * sprite.Bounds.Width * sprite.BaseScale.x, + scale.y * sprite.Bounds.Height * sprite.BaseScale.y); DrawSprite(sprite, scaledDest, tint, angle, inverted); } @@ -75,7 +81,6 @@ void BaseRenderer::DrawSpriteOffset(const Sprite& sprite, const float angle, const bool inverted) { const glm::mat4 transformation = Transformation2D(topLeft, displayOffset, angle, scale); - DrawSprite(sprite, transformation, tint, inverted); } @@ -84,10 +89,19 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const glm::mat4 transformation, const glm::vec4 tint, const bool isInverted, const bool isSameTexture) { - CornersQuad dest = CornersQuad(RectF(0.0f, 0.0f, sprite.ScaledWidth(), - sprite.ScaledHeight())) - .Transform(transformation); + const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, + std::array{tint, tint, tint, tint}, isInverted, + isSameTexture); +} +void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const int alpha, const int fadeRange, + const glm::vec2 topLeft, + const glm::vec4 tint, const bool isInverted, + const bool isSameTexture) { + const RectF dest = {topLeft.x, topLeft.y, sprite.ScaledWidth(), + sprite.ScaledHeight()}; DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, std::array{tint, tint, tint, tint}, isInverted, isSameTexture); @@ -98,7 +112,7 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const bool isInverted, const bool isSameTexture) { - DrawMaskedSprite(sprite, mask, CornersQuad(dest), alpha, fadeRange, + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, std::array{tint, tint, tint, tint}, isInverted, isSameTexture); } @@ -107,8 +121,17 @@ void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const glm::mat4 transformation, const glm::vec4 tint, const bool isInverted, const bool useMaskAlpha) { - const CornersQuad dest = - CornersQuad(sprite.ScaledBounds()).Transform(transformation); + const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); + DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, + isInverted, useMaskAlpha); +} + +void BaseRenderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const int alpha, + const int fadeRange, const glm::vec2 topLeft, const glm::vec4 tint, + const bool isInverted, const bool useMaskAlpha) { + const RectF dest = {topLeft.x, topLeft.y, sprite.ScaledWidth(), + sprite.ScaledHeight()}; DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, isInverted, useMaskAlpha); } @@ -117,20 +140,17 @@ void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const RectF& dest, const glm::vec4 tint, const int alpha, const int fadeRange, const bool isInverted, const float angle, const bool useMaskAlpha) { - const CornersQuad corners = CornersQuad(dest).Transform( - Transformation2D({0.0f, 0.0f}, dest.Center(), angle)); - - DrawMaskedSpriteOverlay(sprite, mask, corners, alpha, fadeRange, tint, - isInverted, useMaskAlpha); + DrawMaskedSpriteOverlay(sprite, mask, dest.Rotate(angle, dest.Center()), + alpha, fadeRange, tint, isInverted, useMaskAlpha); } void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, glm::vec2 scale) { - RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); + const RectF scaledDest(topLeft.x, topLeft.y, + scale.x * sprite.Bounds.Width * sprite.BaseScale.x, + scale.y * sprite.Bounds.Height * sprite.BaseScale.y); DrawCCMessageBox(sprite, mask, scaledDest, tint, alpha, fadeRange, effectCt); } @@ -176,9 +196,9 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, bool stayInScreen, glm::quat rot, glm::vec4 tint, glm::vec2 scale, bool inverted) { - RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); + const RectF scaledDest(topLeft.x, topLeft.y, + scale.x * sprite.Bounds.Width * sprite.BaseScale.x, + scale.y * sprite.Bounds.Height * sprite.BaseScale.y); DrawSprite3DRotated(sprite, scaledDest, depth, vanishingPoint, stayInScreen, rot, tint, inverted); } @@ -190,9 +210,7 @@ void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, const float angle) { - DrawQuad(CornersQuad(dest).Transform( - Transformation2D({0.0f, 0.0f}, dest.Center(), angle)), - color); + DrawQuad(dest.Rotate(angle, dest.Center()), color); } void BaseRenderer::DrawRect3DRotated(const RectF& dest, const float depth, @@ -258,6 +276,20 @@ void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, DrawCharacterMvl(sprite, vertices, indices, tint, inverted); } +void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, + std::span vertices, + std::span indices, + const glm::vec2 offset, + const glm::vec4 tint, const bool inverted) { + const size_t vertexCount = vertices.size() / 5; + for (size_t i = 0; i < vertexCount; i++) { + vertices[i * 5] += offset.x; + vertices[i * 5 + 1] += offset.y; + } + + DrawCharacterMvl(sprite, vertices, indices, tint, inverted); +} + void BaseRenderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, int verticesCount, float* mvlVertices, int indicesCount, uint16_t* mvlIndices, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 1e7ea550e..d3362b821 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -49,6 +49,8 @@ class BaseRenderer { bool inverted = false) = 0; void DrawSprite(const Sprite& sprite, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); // TODO: Remove entirely void DrawSprite(Sprite const& sprite, RectF const& dest, @@ -90,6 +92,10 @@ class BaseRenderer { int fadeRange, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, + int fadeRange, glm::vec2 topLeft, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false); // TODO: Remove entirely void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, @@ -109,6 +115,11 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true); + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + int alpha, int fadeRange, glm::vec2 topLeft, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true); // TODO: Remove entirely void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, @@ -179,6 +190,10 @@ class BaseRenderer { glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + std::span indices, glm::vec2 offset, + glm::vec4 tint = glm::vec4(1.0f), + bool inverted = false); // TODO: Remove entirely void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, From d43efd4b8af234f7ed6997d79e87c955e1914bb8 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 1 May 2025 23:00:17 +0200 Subject: [PATCH 32/88] Changed DrawVideoTexture to take a RectF instead of CornersQuad --- src/renderer/dx9/renderer.cpp | 2 +- src/renderer/dx9/renderer.h | 2 +- src/renderer/opengl/renderer.cpp | 2 +- src/renderer/opengl/renderer.h | 2 +- src/renderer/renderer.cpp | 13 ------------- src/renderer/renderer.h | 14 +++----------- src/renderer/vulkan/renderer.cpp | 2 +- src/renderer/vulkan/renderer.h | 2 +- src/video/ffmpegplayer.cpp | 11 ++++------- 9 files changed, 13 insertions(+), 37 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 3867b1896..14b82ba01 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -727,7 +727,7 @@ void Renderer::Flush() { CurrentTexture = -1; } -void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, +void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 36bf64323..8a9cb7f8d 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -65,7 +65,7 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 79c2422a8..adddad0e9 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -739,7 +739,7 @@ void Renderer::Flush() { CurrentTexture = 0; } -void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, +void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index ada0d0d9a..bd2cfcc5c 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -76,7 +76,7 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index abce7bfaa..51ca328cc 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -304,19 +304,6 @@ void BaseRenderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, DrawCharacterMvl(sprite, vertices, indices, transformation, tint, inverted); } -void BaseRenderer::DrawVideoTexture(YUVFrame* tex, glm::vec2 topLeft, - glm::vec4 tint, glm::vec2 scale, - float angle, bool alphaVideo) { - CornersQuad corners = CornersQuad( - RectF(topLeft.x, topLeft.y, scale.x * tex->Width, scale.y * tex->Height)); - - const glm::mat4 transformation = - Transformation2D({0.0f, 0.0f}, corners.Center(), angle); - corners.Transform(transformation); - - DrawVideoTexture(*tex, corners, tint, alphaVideo); -} - void BaseRenderer::DrawProcessedText_BasicFont( std::span text, BasicFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index d3362b821..09a88a4af 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -57,10 +57,8 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, bool inverted = false); // TODO: Remove entirely - void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool inverted = false); + void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, + glm::vec2 scale, float angle = 0.0f, bool inverted = false); // TODO: Remove entirely void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, @@ -202,15 +200,9 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0), glm::vec2 scale = glm::vec2(1.0f)); - virtual void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + virtual void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo = false) = 0; - // TODO: Remove entirely - void DrawVideoTexture(YUVFrame* tex, glm::vec2 topLeft, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool alphaVideo = false); - virtual void CaptureScreencap(Sprite& sprite) = 0; virtual void SetFramebuffer(size_t buffer) = 0; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 79195f414..c4b98e0d3 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1737,7 +1737,7 @@ void Renderer::Flush() { CurrentTexture = 0; } -void Renderer::DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, +void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, const glm::vec4 tint, const bool alphaVideo) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 0e442738a..64368ed35 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -93,7 +93,7 @@ class Renderer : public BaseRenderer { std::span indices, glm::vec4 tint, bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const CornersQuad& dest, + void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; void CaptureScreencap(Sprite& sprite) override; diff --git a/src/video/ffmpegplayer.cpp b/src/video/ffmpegplayer.cpp index 7056091f6..c5f21d791 100644 --- a/src/video/ffmpegplayer.cpp +++ b/src/video/ffmpegplayer.cpp @@ -476,13 +476,10 @@ void FFmpegPlayer::Update(float dt) { void FFmpegPlayer::Render(float videoAlpha) { if (IsPlaying && PlaybackStarted) { - float widthScale = Profile::DesignWidth / VideoTexture->Width; - float heightScale = Profile::DesignHeight / VideoTexture->Height; - glm::vec4 tint = glm::vec4(1.0f); - tint.a = videoAlpha; - Renderer->DrawVideoTexture(VideoTexture, glm::vec2(0.0f, 0.0f), tint, - glm::vec2(widthScale, heightScale), 0.0f, - IsAlpha); + const RectF dest = {0.0f, 0.0f, Profile::DesignWidth, + Profile::DesignHeight}; + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, videoAlpha}; + Renderer->DrawVideoTexture(*VideoTexture, dest, tint, IsAlpha); } } From 756d820524e960b70d79e757ba7236e91e1dc941 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 3 May 2025 19:50:51 +0200 Subject: [PATCH 33/88] Improved sprite rendering tint API --- src/games/cclcc/delusiontrigger.cpp | 2 +- src/games/cclcc/systemmenu.cpp | 7 +++--- src/renderer/dx9/renderer.cpp | 12 ++++------ src/renderer/dx9/renderer.h | 5 ++-- src/renderer/opengl/renderer.cpp | 12 ++++------ src/renderer/opengl/renderer.h | 5 ++-- src/renderer/renderer.cpp | 24 +++++++------------- src/renderer/renderer.h | 29 ++++++++++++++++++++---- src/renderer/vulkan/renderer.cpp | 12 ++++------ src/renderer/vulkan/renderer.h | 5 ++-- src/ui/widgets/cclcc/saveentrybutton.cpp | 4 ++-- 11 files changed, 64 insertions(+), 53 deletions(-) diff --git a/src/games/cclcc/delusiontrigger.cpp b/src/games/cclcc/delusiontrigger.cpp index 484d3416e..15ddd36d9 100644 --- a/src/games/cclcc/delusiontrigger.cpp +++ b/src/games/cclcc/delusiontrigger.cpp @@ -343,7 +343,7 @@ void DelusionTrigger::Render() { BgOverlaySprite, glm::vec2{0.0f, 0.0f}, glm::vec2{960.0f, 413.0f}, glm::vec4{1.0f, 1.0f, 1.0f, mtrgSelAlpha}, {scale, scale}); } else { - Renderer->DrawSprite(BgOverlaySprite, {0, 0, 1920, 1080}); + Renderer->DrawSprite(BgOverlaySprite, RectF{0, 0, 1920, 1080}); } float spinAngle = MtrgAng / 65535.0f * 2.0f * float(M_PI); diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index f897345f1..04cd2c9a4 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -291,9 +291,10 @@ void SystemMenu::Render() { DisplayGridVertices, 21, 11, glm::vec4{1}, false, true); } - Renderer->DrawSprite(SystemMenuMask, - {0, 0, Profile::DesignWidth, Profile::DesignHeight}, - glm::vec4{tint, alpha}); + Renderer->DrawSprite( + SystemMenuMask, + RectF{0, 0, Profile::DesignWidth, Profile::DesignHeight}, + glm::vec4{tint, alpha}); MainItems->Tint = glm::vec4(tint, glm::smoothstep(0.0f, 1.0f, ItemsFade.Progress)); diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 14b82ba01..cff776339 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -410,12 +410,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, - const int fadeRange, - const glm::vec4 tint, - const bool isInverted, - const bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, + int alpha, const int fadeRange, const std::span tints, + const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -468,7 +466,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } void Renderer::DrawVertices(SpriteSheet const& sheet, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 8a9cb7f8d..2ede03a4a 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -55,8 +55,9 @@ class Renderer : public BaseRenderer { void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, - int fadeRange, glm::vec4 tint, bool isInverted, - bool useMaskAlpha) override; + int fadeRange, + std::span tints, + bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index adddad0e9..8e1bcfd1e 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -418,12 +418,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, - const int fadeRange, - const glm::vec4 tint, - const bool isInverted, - const bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, + int alpha, const int fadeRange, const std::span tints, + const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -485,7 +483,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } void Renderer::DrawVertices(SpriteSheet const& sheet, diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index bd2cfcc5c..4e92eb6a5 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -66,8 +66,9 @@ class Renderer : public BaseRenderer { void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, - int fadeRange, glm::vec4 tint, bool isInverted, - bool useMaskAlpha) override; + int fadeRange, + std::span tints, + bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 51ca328cc..f9e1ed559 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -47,22 +47,19 @@ void BaseRenderer::DrawSprite(const Sprite& sprite, RectF(0.0f, 0.0f, sprite.ScaledWidth(), sprite.ScaledHeight()) .Transform(transformation); - DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, - inverted); + DrawSprite(sprite, dest, tint, inverted); } void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, const glm::vec4 tint, const bool inverted) { const CornersQuad dest = RectF(topLeft.x, topLeft.y, sprite.ScaledWidth(), sprite.ScaledHeight()); - DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, - inverted); + DrawSprite(sprite, dest, tint, inverted); } void BaseRenderer::DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, float angle, bool inverted) { - DrawSprite(sprite, dest.Rotate(angle, dest.Center()), - std::array{tint, tint, tint, tint}, inverted); + DrawSprite(sprite, dest.Rotate(angle, dest.Center()), tint, inverted); } void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, @@ -90,8 +87,7 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const glm::vec4 tint, const bool isInverted, const bool isSameTexture) { const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, - std::array{tint, tint, tint, tint}, isInverted, + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, isSameTexture); } @@ -102,8 +98,7 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const bool isSameTexture) { const RectF dest = {topLeft.x, topLeft.y, sprite.ScaledWidth(), sprite.ScaledHeight()}; - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, - std::array{tint, tint, tint, tint}, isInverted, + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, isSameTexture); } @@ -112,8 +107,7 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const bool isInverted, const bool isSameTexture) { - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, - std::array{tint, tint, tint, tint}, isInverted, + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, isSameTexture); } @@ -187,8 +181,7 @@ void BaseRenderer::DrawSprite3DRotated( corners.BottomRight = glm::vec2(vertices[2]); corners.BottomLeft = glm::vec2(vertices[3]); - DrawSprite(sprite, corners, std::array{tint, tint, tint, tint}, - inverted); + DrawSprite(sprite, corners, tint, inverted); } void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, @@ -204,8 +197,7 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, } void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { - DrawSprite(RectSprite, dest, - std::array{color, color, color, color}); + DrawSprite(RectSprite, dest, color); } void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 09a88a4af..1a944a3f7 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -47,15 +47,19 @@ class BaseRenderer { virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, std::span tints, bool inverted = false) = 0; + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false) { + DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, + inverted); + } void DrawSprite(const Sprite& sprite, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); // TODO: Remove entirely - void DrawSprite(Sprite const& sprite, RectF const& dest, - glm::vec4 tint = glm::vec4(1.0), float angle = 0.0f, - bool inverted = false); + void DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, + float angle, bool inverted = false); // TODO: Remove entirely void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle = 0.0f, bool inverted = false); @@ -86,6 +90,14 @@ class BaseRenderer { std::span tints, bool isInverted = false, bool isSameTexture = false) = 0; + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, int fadeRange, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, + std::array{tint, tint, tint, tint}, + isInverted, isSameTexture); + } void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), @@ -104,9 +116,18 @@ class BaseRenderer { virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, - glm::vec4 tint = glm::vec4(1.0f), + std::span tints, bool isInverted = false, bool useMaskAlpha = true) = 0; + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& dest, int alpha, + int fadeRange, glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, + std::array{tint, tint, tint, tint}, + isInverted, useMaskAlpha); + } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 transformation, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index c4b98e0d3..0ab824598 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1325,12 +1325,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, - const int fadeRange, - const glm::vec4 tint, - const bool isInverted, - const bool useMaskAlpha) { +void Renderer::DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, + int alpha, const int fadeRange, const std::span tints, + const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -1418,7 +1416,7 @@ void Renderer::DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; + for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } void Renderer::DrawVertices(SpriteSheet const& sheet, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 64368ed35..56ab0bbbf 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -83,8 +83,9 @@ class Renderer : public BaseRenderer { void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, - int fadeRange, glm::vec4 tint, bool isInverted, - bool useMaskAlpha) override; + int fadeRange, + std::span tints, + bool isInverted, bool useMaskAlpha) override; void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; diff --git a/src/ui/widgets/cclcc/saveentrybutton.cpp b/src/ui/widgets/cclcc/saveentrybutton.cpp index c4f31081d..d9a8428fd 100644 --- a/src/ui/widgets/cclcc/saveentrybutton.cpp +++ b/src/ui/widgets/cclcc/saveentrybutton.cpp @@ -85,8 +85,8 @@ void SaveEntryButton::Render() { } Renderer->DrawSprite( Thumbnail, - {Bounds.X + 20, Bounds.Y + 22, Thumbnail.Bounds.Width + 30, - Thumbnail.Bounds.Height + 17}, + RectF{Bounds.X + 20, Bounds.Y + 22, Thumbnail.Bounds.Width + 30, + Thumbnail.Bounds.Height + 17}, Tint); CharacterRouteLabel.Render(); SceneTitleLabel.Render(); From a03459bfb7565af912093bc44244aaff1f23ea6d Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 3 May 2025 23:34:39 +0200 Subject: [PATCH 34/88] Disabled Vulkan face culling --- src/renderer/vulkan/pipeline.cpp | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/renderer/vulkan/pipeline.cpp b/src/renderer/vulkan/pipeline.cpp index 9ad9f024f..696dcc68c 100644 --- a/src/renderer/vulkan/pipeline.cpp +++ b/src/renderer/vulkan/pipeline.cpp @@ -23,8 +23,7 @@ Pipeline::Pipeline(VkDevice device, VkRenderPass renderPass) { rasterizer.rasterizerDiscardEnable = VK_FALSE; rasterizer.polygonMode = VK_POLYGON_MODE_FILL; rasterizer.lineWidth = 1.0f; - rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; - rasterizer.frontFace = VK_FRONT_FACE_COUNTER_CLOCKWISE; + rasterizer.cullMode = VK_CULL_MODE_NONE; rasterizer.depthBiasEnable = VK_FALSE; RasterizerInfo = rasterizer; From 04bc7ba8828fded15f45d6ef94dbb3fe62ce700f Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 3 May 2025 23:58:00 +0200 Subject: [PATCH 35/88] Made DesignToNDC pure virtual --- src/renderer/dx9/renderer.cpp | 7 +++++++ src/renderer/dx9/renderer.h | 2 ++ src/renderer/opengl/renderer.cpp | 7 +++++++ src/renderer/opengl/renderer.h | 2 ++ src/renderer/renderer.h | 5 +++-- src/renderer/vulkan/renderer.cpp | 17 ++++++++++++----- src/renderer/vulkan/renderer.h | 2 ++ src/util.cpp | 24 ------------------------ src/util.h | 4 ---- 9 files changed, 35 insertions(+), 35 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index cff776339..8e1969fcc 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -821,5 +821,12 @@ void Renderer::DisableScissor() { Device->SetRenderState(D3DRS_SCISSORTESTENABLE, false); } +glm::vec2 Renderer::DesignToNDC(glm::vec2 designCoord) const { + glm::vec2 result; + result.x = (designCoord.x / (Profile::DesignWidth * 0.5f)) - 1.0f; + result.y = 1.0f - (designCoord.y / (Profile::DesignHeight * 0.5f)); + return result; +} + } // namespace DirectX9 } // namespace Impacto diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 2ede03a4a..9fe3970e1 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -86,6 +86,8 @@ class Renderer : public BaseRenderer { void EnsureShader(Shader* shader, bool flush = true); void Flush() override; + glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + DirectX9Window* DXWindow; IDirect3D9* Interface; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 8e1bcfd1e..369824712 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -828,5 +828,12 @@ void Renderer::DisableScissor() { glDisable(GL_SCISSOR_TEST); } +glm::vec2 Renderer::DesignToNDC(glm::vec2 designCoord) const { + glm::vec2 result; + result.x = (designCoord.x / (Profile::DesignWidth * 0.5f)) - 1.0f; + result.y = 1.0f - (designCoord.y / (Profile::DesignHeight * 0.5f)); + return result; +} + } // namespace OpenGL } // namespace Impacto diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 4e92eb6a5..f8d488852 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -104,6 +104,8 @@ class Renderer : public BaseRenderer { void EnsureModeSprite(bool inverted); void Flush() override; + glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + GLWindow* OpenGLWindow; GLuint ShaderProgramSprite; diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 1a944a3f7..549902ebf 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -258,8 +258,9 @@ class BaseRenderer { designDimensions, uvs, stride); } - static void QuadSetPosition(CornersQuad destQuad, glm::vec2* positions, - int stride); + void QuadSetPosition(CornersQuad destQuad, glm::vec2* positions, int stride); + + virtual glm::vec2 DesignToNDC(glm::vec2 designCoord) const = 0; Sprite RectSprite; }; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 0ab824598..331b2e4d2 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1189,19 +1189,19 @@ void Renderer::DrawCharacterMvl(const Sprite& sprite, glm::vec2(mvlVertices[(i + 3) * 5 + 3], mvlVertices[(i + 3) * 5 + 4]); // top-left - vertices[i].Position = DesignToNDCNonFlipped(topLeftV); + vertices[i].Position = DesignToNDC(topLeftV); vertices[i].UV = topLeftUV; vertices[i].Tint = tint; // bottom-left - vertices[i + 1].Position = DesignToNDCNonFlipped(bottomLeftV); + vertices[i + 1].Position = DesignToNDC(bottomLeftV); vertices[i + 1].UV = bottomLeftUV; vertices[i + 1].Tint = tint; // bottom-right - vertices[i + 2].Position = DesignToNDCNonFlipped(bottomRightV); + vertices[i + 2].Position = DesignToNDC(bottomRightV); vertices[i + 2].UV = bottomRightUV; vertices[i + 2].Tint = tint; // top-right - vertices[i + 3].Position = DesignToNDCNonFlipped(topRightV); + vertices[i + 3].Position = DesignToNDC(topRightV); vertices[i + 3].UV = topRightUV; vertices[i + 3].Tint = tint; } @@ -1510,7 +1510,7 @@ void Renderer::DrawVertices(SpriteSheet const& sheet, assert(IndexBufferFill == (width - 1) * (height - 1) * 6); for (int i = 0; i < verticesCount; i++) { - vertices[i].Position = DesignToNDCNonFlipped(displayPositions[i]); + vertices[i].Position = DesignToNDC(displayPositions[i]); vertices[i].Tint = tint; glm::vec2 uv = sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); @@ -1989,5 +1989,12 @@ void Renderer::DisableScissor() { } } +glm::vec2 Renderer::DesignToNDC(const glm::vec2 designCoord) const { + glm::vec2 result; + result.x = (designCoord.x / (Profile::DesignWidth * 0.5f)) - 1.0f; + result.y = (designCoord.y / (Profile::DesignHeight * 0.5f)) - 1.0f; + return result; +} + } // namespace Vulkan } // namespace Impacto diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 56ab0bbbf..3cd979326 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -136,6 +136,8 @@ class Renderer : public BaseRenderer { void MakeQuad(); + glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + bool Drawing = false; VulkanWindow* VkWindow; diff --git a/src/util.cpp b/src/util.cpp index 61101d43d..144e311ed 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -147,30 +147,6 @@ glm::vec3 Transform3D(const glm::vec3 pos, const glm::vec3 translation, glm::vec4(pos, 1.0f); } -glm::vec2 DesignToNDC(glm::vec2 xy) { - glm::vec2 result; - result.x = (xy.x / (Profile::DesignWidth * 0.5f)) - 1.0f; - result.y = 1.0f - (xy.y / (Profile::DesignHeight * 0.5f)); - return result; -} - -glm::vec2 DesignToNDCNonFlipped(glm::vec2 xy) { - glm::vec2 result; - result.x = (xy.x / (Profile::DesignWidth * 0.5f)) - 1.0f; - result.y = (xy.y / (Profile::DesignHeight * 0.5f)) - 1.0f; - return result; -} - -RectF DesignToNDC(RectF const& rect) { - RectF result; - glm::vec2 xy = DesignToNDC(glm::vec2(rect.X, rect.Y)); - result.X = xy.x; - result.Y = xy.y; - result.Width = rect.Width / (Profile::DesignWidth * 0.5f); - result.Height = rect.Height / (Profile::DesignHeight * 0.5f); - return result; -} - uint32_t GetHashCode(uint8_t* data, int length) { uint32_t hash = 2166136261; for (int i = 0; i < length; i++) { diff --git a/src/util.h b/src/util.h index ac9a6bdf3..211369ed7 100644 --- a/src/util.h +++ b/src/util.h @@ -228,10 +228,6 @@ inline constexpr RectF::RectF(Rect const& rect) : RectF((float)rect.X, (float)rect.Y, (float)rect.Width, (float)rect.Height) {} -glm::vec2 DesignToNDC(glm::vec2 xy); -glm::vec2 DesignToNDCNonFlipped(glm::vec2 xy); -RectF DesignToNDC(RectF const& rect); - constexpr glm::vec4 RgbIntToFloat(uint32_t rgb) { return glm::vec4{(float)((rgb >> 16) & 0xFF) / 255.0f, (float)((rgb >> 8) & 0xFF) / 255.0f, From 6f3acac4da578fea2a72dcd97d15ce954e937653 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 15:10:29 +0200 Subject: [PATCH 36/88] Removed superfluous DrawMaskedSprite overload --- src/games/mo6tw/titlemenu.cpp | 24 ++++++++++++------------ src/renderer/renderer.cpp | 9 --------- src/renderer/renderer.h | 6 ------ 3 files changed, 12 insertions(+), 27 deletions(-) diff --git a/src/games/mo6tw/titlemenu.cpp b/src/games/mo6tw/titlemenu.cpp index 54674e045..00b4913ba 100644 --- a/src/games/mo6tw/titlemenu.cpp +++ b/src/games/mo6tw/titlemenu.cpp @@ -368,14 +368,14 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), (ScrWork[SW_TITLECT] * 287) / 48, 32, false, + (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::vec4(1.0f), false, true); if (ScrWork[SW_TITLECT] > 48) { Renderer->DrawMaskedSprite( LogoSprite, Masks2D[17].MaskSprite, RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), LogoSprite.ScaledHeight()), - glm::vec4(1.0f), (ScrWork[SW_TITLECT] * 271 - 13008) / 32, 16); + (ScrWork[SW_TITLECT] * 271 - 13008) / 32, 16); } break; case 1: { // Press to start @@ -383,7 +383,7 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -397,7 +397,7 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -408,7 +408,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); MainItems->Render(); } break; case 5: // Secondary menu Extra story Fade In @@ -417,7 +417,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); ExtraStoryItems->Render(); MainItems->Render(); } break; @@ -427,7 +427,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); ContinueItems->Render(); MainItems->Render(); } break; @@ -437,7 +437,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); MemoriesItems->Render(); MainItems->Render(); } break; @@ -447,7 +447,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); SystemItems->Render(); MainItems->Render(); } break; @@ -457,19 +457,19 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 32, false, true); + 287, 32, glm::vec4(1.0f), false, true); Renderer->DrawMaskedSprite( LogoSprite, Masks2D[17].MaskSprite, RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), LogoSprite.ScaledHeight()), - glm::vec4(1.0f), 287, 16); + 287, 16); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); Renderer->DrawMaskedSprite( MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - glm::vec4(1.0f), (ScrWork[SW_TITLECT] * 287) / 48, 32, false, + (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::vec4(1.0f), false, true); } break; } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index f9e1ed559..d55af0c16 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -102,15 +102,6 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, isSameTexture); } -void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const RectF& dest, const glm::vec4 tint, - const int alpha, const int fadeRange, - const bool isInverted, - const bool isSameTexture) { - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, - isSameTexture); -} - void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const glm::mat4 transformation, const glm::vec4 tint, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 549902ebf..da1d87c0b 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -107,12 +107,6 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); - // TODO: Remove entirely - void DrawMaskedSprite(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - bool isSameTexture = false); - virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, From 6a00e479d9434229e3a5ca7490c29f0fc71699dc Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 16:20:10 +0200 Subject: [PATCH 37/88] Removed superfluous DrawSprite overload --- src/games/cclcc/mapsystem.cpp | 10 ++++--- src/games/cclcc/yesnotrigger.cpp | 11 +++++--- src/renderer/renderer.cpp | 45 ++++++++++++-------------------- src/renderer/renderer.h | 3 --- src/spritesheet.h | 4 ++- 5 files changed, 33 insertions(+), 40 deletions(-) diff --git a/src/games/cclcc/mapsystem.cpp b/src/games/cclcc/mapsystem.cpp index 442ce20f3..b89edda88 100644 --- a/src/games/cclcc/mapsystem.cpp +++ b/src/games/cclcc/mapsystem.cpp @@ -1832,10 +1832,13 @@ void MapSystemCCLCC::MapDispLine(int id, int partType) { RectF lineShadowRect(xPos * scaledFactor, yPosShadow * scaledFactor, lineWidth * scaledFactor, 10.0f * scaledFactor); - Renderer->DrawSprite(shortenedLine, lineShadowRect, shadowTint, -angle); + Renderer->DrawSprite(shortenedLine, + lineShadowRect.Rotate(-angle, lineShadowRect.Center()), + shadowTint); RectF lineRect(xPos * scaledFactor, yPos * scaledFactor, lineWidth * scaledFactor, 10.0f * scaledFactor); - Renderer->DrawSprite(shortenedLine, lineRect, color, -angle); + Renderer->DrawSprite(shortenedLine, + lineRect.Rotate(-angle, lineRect.Center()), color); } } @@ -2021,8 +2024,7 @@ void MapSystemCCLCC::Render() { MapBgSprite.Bounds = Rect(static_cast(MapPosX), static_cast(MapPosY), static_cast(MapBGWidth), static_cast(MapBGHeight)); - Renderer->DrawSprite(MapBgSprite, Rect(0, 0, 1920, 1080), glm::vec4{1.0f}, - 0.0f); + Renderer->DrawSprite(MapBgSprite, Rect(0, 0, 1920, 1080)); // Render map parts for (int i = 0; i < MapPartsMax; ++i) { diff --git a/src/games/cclcc/yesnotrigger.cpp b/src/games/cclcc/yesnotrigger.cpp index cef20583a..bacde95e3 100644 --- a/src/games/cclcc/yesnotrigger.cpp +++ b/src/games/cclcc/yesnotrigger.cpp @@ -249,7 +249,7 @@ void YesNoTrigger::Render() { static_cast(BgSpritePos.y + bgYOffset), static_cast(bgWidth), static_cast(bgHeight)); - Renderer->DrawSprite(ActiveBackground, Rect(0, 0, 1920, 1080), bgtint, 0.0f); + Renderer->DrawSprite(ActiveBackground, Rect(0, 0, 1920, 1080), bgtint); if (DispSel) { float chipYesX = @@ -298,8 +298,11 @@ void YesNoTrigger::Render() { float noChipWidthX = 0.5f * BgSpriteScale * ActiveNoChip->Bounds.Width; float noChipWidthY = 0.5f * BgSpriteScale * ActiveNoChip->Bounds.Height; if (Selection != YesNoSelect::NONE) { - Renderer->DrawSprite(StarChip, starPos, chipTint, {1.0, 1.0}, - StarAngle / 65536.0f); + const CornersQuad dest = + StarChip.ScaledBounds() + .Rotate(StarAngle / 65536.0f, StarChip.Center()) + .Translate(starPos); + Renderer->DrawSprite(StarChip, dest, chipTint); } Renderer->DrawSprite(*ActiveYesChip, Rect(chipYesX, chipYesY, yesChipWidthX, yesChipWidthY), @@ -309,7 +312,7 @@ void YesNoTrigger::Render() { chipTint); } glm::vec4 maskTint = glm::vec4(1.0f, 1.0f, 1.0f, 160 / 256.0f); - Renderer->DrawSprite(YesNoBgMask, Rect(0, 0, 1920, 1080), maskTint, 0.0f); + Renderer->DrawSprite(YesNoBgMask, Rect(0, 0, 1920, 1080), maskTint); } void YesNoTrigger::Start(int type, int bgBufId, int chipsBufId) { diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index d55af0c16..851726d83 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -43,32 +43,25 @@ void InitRenderer() { void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::mat4 transformation, const glm::vec4 tint, const bool inverted) { - const CornersQuad dest = - RectF(0.0f, 0.0f, sprite.ScaledWidth(), sprite.ScaledHeight()) - .Transform(transformation); - + const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); DrawSprite(sprite, dest, tint, inverted); } void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, const glm::vec4 tint, const bool inverted) { - const CornersQuad dest = - RectF(topLeft.x, topLeft.y, sprite.ScaledWidth(), sprite.ScaledHeight()); + const CornersQuad dest = sprite.ScaledBounds().Translate(topLeft); DrawSprite(sprite, dest, tint, inverted); } -void BaseRenderer::DrawSprite(Sprite const& sprite, RectF const& dest, - glm::vec4 tint, float angle, bool inverted) { - DrawSprite(sprite, dest.Rotate(angle, dest.Center()), tint, inverted); -} - void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle, bool inverted) { - const RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); - DrawSprite(sprite, scaledDest, tint, angle, inverted); + CornersQuad dest = sprite.ScaledBounds(); + dest.Scale(scale, {0.0f, 0.0f}) + .Rotate(angle, dest.Center()) + .Translate(topLeft); + + DrawSprite(sprite, dest, tint, inverted); } void BaseRenderer::DrawSpriteOffset(const Sprite& sprite, @@ -96,8 +89,7 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const glm::vec2 topLeft, const glm::vec4 tint, const bool isInverted, const bool isSameTexture) { - const RectF dest = {topLeft.x, topLeft.y, sprite.ScaledWidth(), - sprite.ScaledHeight()}; + const RectF dest = sprite.ScaledBounds().Translate(topLeft); DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, isSameTexture); } @@ -115,8 +107,7 @@ void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const glm::vec2 topLeft, const glm::vec4 tint, const bool isInverted, const bool useMaskAlpha) { - const RectF dest = {topLeft.x, topLeft.y, sprite.ScaledWidth(), - sprite.ScaledHeight()}; + const RectF dest = sprite.ScaledBounds().Translate(topLeft); DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, isInverted, useMaskAlpha); } @@ -133,10 +124,9 @@ void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, glm::vec2 scale) { - const RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); - DrawCCMessageBox(sprite, mask, scaledDest, tint, alpha, fadeRange, effectCt); + const RectF dest = + sprite.ScaledBounds().Scale(scale, {0.0f, 0.0f}).Translate(topLeft); + DrawCCMessageBox(sprite, mask, dest, tint, alpha, fadeRange, effectCt); } void BaseRenderer::DrawSprite3DRotated( @@ -180,11 +170,10 @@ void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, bool stayInScreen, glm::quat rot, glm::vec4 tint, glm::vec2 scale, bool inverted) { - const RectF scaledDest(topLeft.x, topLeft.y, - scale.x * sprite.Bounds.Width * sprite.BaseScale.x, - scale.y * sprite.Bounds.Height * sprite.BaseScale.y); - DrawSprite3DRotated(sprite, scaledDest, depth, vanishingPoint, stayInScreen, - rot, tint, inverted); + const RectF dest = + sprite.ScaledBounds().Scale(scale, {0.0f, 0.0f}).Translate(topLeft); + DrawSprite3DRotated(sprite, dest, depth, vanishingPoint, stayInScreen, rot, + tint, inverted); } void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index da1d87c0b..370309df0 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -58,9 +58,6 @@ class BaseRenderer { glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); // TODO: Remove entirely - void DrawSprite(Sprite const& sprite, RectF const& dest, glm::vec4 tint, - float angle, bool inverted = false); - // TODO: Remove entirely void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle = 0.0f, bool inverted = false); diff --git a/src/spritesheet.h b/src/spritesheet.h index a6fc61e1f..3b1ea7e13 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -39,8 +39,10 @@ struct Sprite { Bounds.Height = scaledHeight / BaseScale.y; } RectF ScaledBounds() const { - return RectF(Bounds).Scale(BaseScale, Bounds.GetPos()); + return {0.0f, 0.0f, ScaledWidth(), ScaledHeight()}; } + + glm::vec2 Center() const { return ScaledBounds().Center(); } }; } // namespace Impacto \ No newline at end of file From 46923badbece5cf87cb73ef09b5a1cc83fd9d05a Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 17:57:46 +0200 Subject: [PATCH 38/88] Removed superfluous DrawSpriteOffset method --- src/games/cclcc/delusiontrigger.cpp | 209 +++++++++++++++------------- src/games/cclcc/mapsystem.cpp | 122 ++++++++-------- src/renderer/renderer.cpp | 10 -- src/renderer/renderer.h | 7 - 4 files changed, 171 insertions(+), 177 deletions(-) diff --git a/src/games/cclcc/delusiontrigger.cpp b/src/games/cclcc/delusiontrigger.cpp index 15ddd36d9..c77c4dbbf 100644 --- a/src/games/cclcc/delusiontrigger.cpp +++ b/src/games/cclcc/delusiontrigger.cpp @@ -184,150 +184,164 @@ void DelusionTrigger::Update(float dt) { } void DelusionTrigger::RenderStartTransition(float spinAngle, int spinAlpha) { - float scale = (ScrWork[SW_DELUSION_SPIN_COUNTER] + 64) / 64.0f; - float transparency = - ((64 - ScrWork[SW_DELUSION_SPIN_COUNTER]) * spinAlpha >> 6) / 256.0f; + const glm::vec2 scale((ScrWork[SW_DELUSION_SPIN_COUNTER] + 64) / 64.0f); + const glm::vec4 tint = { + 1.0f, 1.0f, 1.0f, + ((64 - ScrWork[SW_DELUSION_SPIN_COUNTER]) * spinAlpha >> 6) / 256.0f}; + if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - glm::vec2 topLeft = {-800.0f, -109.0f}; - glm::vec2 offset = {600.0f, 557.0f}; - Renderer->DrawSpriteOffset(PositiveDelusionSprite, topLeft, offset, - {1.0f, 1.0f, 1.0f, transparency}, {scale, scale}, - spinAngle); + const glm::vec2 topLeft = {-800, -109}; + const glm::vec2 offset = {600, 557}; + const glm::mat4 transformation = + Transformation2D(topLeft, offset, spinAngle, scale); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } + if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - glm::vec2 topLeft = {1696.0f, -109.0f}; - glm::vec2 offset = {424.0f, 557.0f}; - Renderer->DrawSpriteOffset(NegativeDelusionSprite, topLeft, offset, - {1.0f, 1.0f, 1.0f, transparency}, {scale, scale}, - spinAngle); + const glm::vec2 topLeft = {1696, -109}; + const glm::vec2 offset = {424, 557}; + const glm::mat4 transformation = + Transformation2D(topLeft, offset, spinAngle, scale); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } void DelusionTrigger::RenderStable(float spinAngle, int spinAlpha) { + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + if (DelusionState == DS_Neutral) { if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, {-800, -109}, {600, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1.0, 1.0}, spinAngle); + const glm::mat4 transformation = + Transformation2D({-800, -109}, {600, 557}, spinAngle); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } + if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, {1696.0f, -109.0f}, {424, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1.0, 1.0}, spinAngle); + const glm::mat4 transformation = + Transformation2D({1696, -109}, {424, 557}, spinAngle); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } + } else if (DelusionState == DS_Positive) { - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{448, -109.0f}, glm::vec2{600, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1.8, 1.8}, spinAngle); + const glm::mat4 transformation = + Transformation2D({448, -109}, {600, 557}, spinAngle, {1.8f, 1.8f}); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); + } else if (DelusionState == DS_Negative) { - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{448, -109.0f}, glm::vec2{424, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1.8, 1.8}, spinAngle); + const glm::mat4 transformation = + Transformation2D({448, -109}, {424, 557}, spinAngle, {1.8f, 1.8f}); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } void DelusionTrigger::RenderNeutralToPositiveTransition(float spinAngle, int spinAlpha) { - float topLeftX = - 448.0f - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6); - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{topLeftX, -109.0f}, {600, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, - {1.8 - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8 / 64, - 1.8 - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8 / 64}, - spinAngle); + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + + const glm::vec2 topLeft = { + 448 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; + const glm::vec2 scale(1.8f - + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); + const glm::mat4 transformation = + Transformation2D(topLeft, {600, 557}, spinAngle, scale); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); + if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { - float centerX = - 2944.0f - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6); - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{centerX, -109.0f}, - glm::vec2{424.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 center = { + 2944 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; + const glm::mat4 negativeTransformation = + Transformation2D(center, {424, 557}, spinAngle); + Renderer->DrawSprite(NegativeDelusionSprite, negativeTransformation, tint); } } void DelusionTrigger::RenderNeutralToNegativeTransition(float spinAngle, int spinAlpha) { - float topLeftX = - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 448.0f; - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{topLeftX, -109.0f}, {424, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, - {1.8 - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8 / 64, - 1.8 - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8 / 64}, - spinAngle); + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + + const glm::vec2 topLeft = { + ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 448, -109}; + const glm::vec2 scale(1.8f - + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); + const glm::mat4 transformation = + Transformation2D(topLeft, {424, 557}, spinAngle, scale); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); + if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { - float topLeftX = - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 2048.0f; - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{topLeftX, -109.0f}, - glm::vec2{600.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 topLeftPositive = { + ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 2048, -109}; + const glm::mat4 transformationPositive = + Transformation2D(topLeftPositive, {600, 557}, spinAngle); + Renderer->DrawSprite(PositiveDelusionSprite, transformationPositive, tint); } } void DelusionTrigger::RenderPositiveToNeutralTransition(float spinAngle, int spinAlpha) { - float scale = 1.0f + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f; + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + + const glm::vec2 topLeft = { + ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 800, -109}; + const glm::vec2 scale(1.0f + + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); + const glm::mat4 transformation = + Transformation2D(topLeft, {600, 557}, spinAngle, scale); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); - float topLeftX = - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 800.0f; - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{topLeftX, -109.0f}, {600, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {scale, scale}, spinAngle); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { - float centerX = - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 1696.0f; - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{centerX, -109.0f}, - glm::vec2{424.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 center = { + ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 1696, -109}; + const glm::mat4 transformationNegative = + Transformation2D(center, {424, 557}, spinAngle); + Renderer->DrawSprite(NegativeDelusionSprite, transformationNegative, tint); } } void DelusionTrigger::RenderNegativeToNeutralTransition(float spinAngle, int spinAlpha) { - float scale = - 1.0f + (float)(ScrWork[SW_DELUSION_SPIN_COUNTER]) * 0.8f / 64.0f; - - float topLeftX = - 1696.0f - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6); - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{topLeftX, -109.0f}, {424, 557}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {scale, scale}, spinAngle); + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + + const glm::vec2 topLeft = { + 1696 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; + const glm::vec2 scale(1.0f + + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); + const glm::mat4 transformation = + Transformation2D(topLeft, {424, 557}, spinAngle, scale); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); + if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { - float centerX = - -800.0f - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6); - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{centerX, -109.0f}, - glm::vec2{600.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 center = { + -800 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; + const glm::mat4 transformationPositive = + Transformation2D(center, {600, 557}, spinAngle); + Renderer->DrawSprite(PositiveDelusionSprite, transformationPositive, tint); } } void DelusionTrigger::RenderEndNeutralTransition(float spinAngle, int spinAlpha) { + const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; + if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - float topLeftX = - (float)((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5) - 2048.0f; - Renderer->DrawSpriteOffset( - PositiveDelusionSprite, glm::vec2{topLeftX, -109.0f}, - glm::vec2{600.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 topLeft = { + ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5) - 2048, -109}; + const glm::mat4 transformation = + Transformation2D(topLeft, {600, 557}, spinAngle); + Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } + if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - float topLeftX = - 2944.0f - (float)((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 5); - Renderer->DrawSpriteOffset( - NegativeDelusionSprite, glm::vec2{topLeftX, -109.0f}, - glm::vec2{424.0f, 557.0f}, - {1.0f, 1.0f, 1.0f, (float)spinAlpha / 256.0f}, {1, 1}, spinAngle); + const glm::vec2 topLeft = { + 2944 - ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5), -109}; + const glm::mat4 transformation = + Transformation2D(topLeft, {424, 557}, spinAngle); + Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } @@ -335,13 +349,14 @@ void DelusionTrigger::Render() { if (ScrWork[SW_DELUSION_BG_COUNTER] == 0) { return; } - float mtrgSelAlpha = - ((ScrWork[SW_DELUSION_BG_COUNTER] * 8) & 0xffffff) / 256.0f; + const glm::vec4 mtrgSelTint = { + 1.0f, 1.0f, 1.0f, + ((ScrWork[SW_DELUSION_BG_COUNTER] * 8) & 0xffffff) / 256.0f}; if (ScrWork[SW_DELUSION_BG_COUNTER] < 32) { - float scale = 2.0f - (ScrWork[SW_DELUSION_BG_COUNTER] / 32.0f); - Renderer->DrawSpriteOffset( - BgOverlaySprite, glm::vec2{0.0f, 0.0f}, glm::vec2{960.0f, 413.0f}, - glm::vec4{1.0f, 1.0f, 1.0f, mtrgSelAlpha}, {scale, scale}); + const glm::vec2 scale(2.0f - (ScrWork[SW_DELUSION_BG_COUNTER] / 32.0f)); + const CornersQuad dest = + BgOverlaySprite.ScaledBounds().Scale(scale, {960, 413}); + Renderer->DrawSprite(BgOverlaySprite, dest, mtrgSelTint); } else { Renderer->DrawSprite(BgOverlaySprite, RectF{0, 0, 1920, 1080}); } diff --git a/src/games/cclcc/mapsystem.cpp b/src/games/cclcc/mapsystem.cpp index b89edda88..ce44373af 100644 --- a/src/games/cclcc/mapsystem.cpp +++ b/src/games/cclcc/mapsystem.cpp @@ -1419,18 +1419,19 @@ void MapSystemCCLCC::MapDispPhoto(int id, int photoGroupId) { float scaledPosOffsetY = (yOffset + 10) * scaledFactor; // Shadow - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2((xOffset + 82 + 3) * scaledFactor - 82, - (yOffset + 10 + 3) * scaledFactor - 10), - glm::vec2{82, 10}, glm::vec4{0.0f, 0.0f, 0.0f, (alpha / 2) / 256.0f}, - glm::vec2{shadowZoom, shadowZoom}, angle); + const glm::vec2 shadowPos = {(xOffset + 82 + 3) * scaledFactor - 82, + (yOffset + 10 + 3) * scaledFactor - 10}; + const glm::mat4 shadowTransformation = + Transformation2D(shadowPos, {82, 10}, angle, {shadowZoom, shadowZoom}); + Renderer->DrawSprite(displayedSprite, shadowTransformation, + {0.0f, 0.0f, 0.0f, (alpha / 2) / 256.0f}); + // Photo - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2(scaledPosOffsetX - 82, scaledPosOffsetY - 10), - glm::vec2{82, 10}, glm::vec4{1.0f, 1.0f, 1.0f, alpha / 256.0f}, - glm::vec2{zoomMulti, zoomMulti}, angle); + const glm::mat4 photoTransformation = + Transformation2D({scaledPosOffsetX - 82, scaledPosOffsetY - 10}, + {82, 10}, angle, {zoomMulti, zoomMulti}); + Renderer->DrawSprite(displayedSprite, photoTransformation, + {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } } @@ -1498,27 +1499,25 @@ void MapSystemCCLCC::MapPoolDispPhoto(int poolId) { (MapPoolCurCt[poolId] * 50.0f / 16.0f + 78.0f) * 2; // HoverTag Tag - Renderer->DrawSpriteOffset( - SelectedMapPoolTagSprite, - glm::vec2(scaledPosOffsetX - selectedTagXOffset, - scaledPosOffsetY - 18), - glm::vec2{selectedTagXOffset, 11}, - glm::vec4{1.0f, 1.0f, 1.0f, alpha / 256.0f}, - glm::vec2{zoomMulti / 2.0, zoomMulti / 2.0}, angle); + const glm::mat4 transformation = Transformation2D( + {scaledPosOffsetX - selectedTagXOffset, scaledPosOffsetY - 18}, + {selectedTagXOffset, 11}, angle, glm::vec2(zoomMulti / 2.0f)); + Renderer->DrawSprite(SelectedMapPoolTagSprite, transformation, + {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } // Shadow - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2((xOffset + 82 + 3) * scaledFactor - 82, - (yOffset + 10 + 3) * scaledFactor - 10), - glm::vec2{82, 10}, glm::vec4{0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}, - glm::vec2{shadowZoom, shadowZoom}, angle); + const glm::mat4 shadowTransformation = + Transformation2D({(xOffset + 82 + 3) * scaledFactor - 82, + (yOffset + 10 + 3) * scaledFactor - 10}, + {82, 10}, angle, glm::vec2(shadowZoom)); + Renderer->DrawSprite(displayedSprite, shadowTransformation, + {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); // Photo - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2(scaledPosOffsetX - 82, scaledPosOffsetY - 10), - glm::vec2{82, 10}, glm::vec4{1.0f, 1.0f, 1.0f, alpha / 256.0f}, - glm::vec2{zoomMulti, zoomMulti}, angle); + const glm::mat4 photoTransformation = + Transformation2D({scaledPosOffsetX - 82, scaledPosOffsetY - 10}, + {82, 10}, angle, glm::vec2(zoomMulti)); + Renderer->DrawSprite(displayedSprite, photoTransformation, + {1.0f, 1.0f, 1.0f, alpha / 256.0f}); if (!MapPool[poolId].button.Enabled) { MapPool[poolId].button.Enabled = true; MapPool[poolId].button.Id = poolId; @@ -1575,10 +1574,11 @@ void MapSystemCCLCC::MapPoolDispPin(int poolId) { glm::vec4 color = RgbIntToFloat(Tints[poolId]); color[3] = alpha / 256.0f; - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2(scaledPosOffsetX - 16.0f, scaledPosOffsetY - 29.0f), - glm::vec2{16.0f, 29.0f}, color, glm::vec2{zoomMulti, zoomMulti}, 0); + const RectF dest = + displayedSprite.ScaledBounds() + .Scale({zoomMulti, zoomMulti}, {16.0f, 29.0f}) + .Translate({scaledPosOffsetX - 16.0f, scaledPosOffsetY - 29.0f}); + Renderer->DrawSprite(displayedSprite, dest, color); } } @@ -1648,10 +1648,11 @@ void MapSystemCCLCC::MapDispPin(int id) { glm::vec4 color = RgbIntToFloat(Tints[mappedId + 27]); color[3] = alpha / 256.0f; - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2(scaledPosOffsetX - 16.0f, scaledPosOffsetY - 29.0f), - glm::vec2{16.0f, 29.0f}, color, glm::vec2{zoomMulti, zoomMulti}, 0); + const RectF dest = + displayedSprite.ScaledBounds() + .Scale({zoomMulti, zoomMulti}, {16, 29}) + .Translate({scaledPosOffsetX - 16.0f, scaledPosOffsetY - 29.0f}); + Renderer->DrawSprite(displayedSprite, dest, color); } } @@ -1696,20 +1697,16 @@ void MapSystemCCLCC::MapDispArticle(int id) { float displayPhotoY = scaledPosOffsetY - 16; // Shadow - Renderer->DrawSpriteOffset( - MapPartsArticleSprites[partId], - glm::vec2(displayShadowPhotoX, displayShadowPhotoY), glm::vec2{166, 16}, - glm::vec4{0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}, - glm::vec2{shadowZoom * 0.5 * scaledFactor, - shadowZoom * scaledFactor * 0.5}, - angle); + const glm::mat4 shadowTransformation = + Transformation2D({displayShadowPhotoX, displayShadowPhotoY}, {166, 16}, + angle, glm::vec2(shadowZoom * 0.5 * scaledFactor)); + Renderer->DrawSprite(MapPartsArticleSprites[partId], shadowTransformation, + {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); // Photo - Renderer->DrawSpriteOffset(MapPartsArticleSprites[partId], - glm::vec2(displayPhotoX, displayPhotoY), - glm::vec2{166, 16}, glm::vec4{1.0f}, - glm::vec2{zoomMulti * 0.5 * scaledFactor, - zoomMulti * 0.5 * scaledFactor}, - angle); + const glm::mat4 photoTransformation = + Transformation2D({displayPhotoX, displayPhotoY}, {166, 16}, angle, + glm::vec2(zoomMulti * 0.5 * scaledFactor)); + Renderer->DrawSprite(MapPartsArticleSprites[partId], photoTransformation); } } @@ -1753,21 +1750,20 @@ void MapSystemCCLCC::MapDispTag(int id) { float shadowScaledPosOffsetX = (xOffset + 2.0f + 46.0f) * scaledFactor; float shadowScaledPosOffsetY = (yOffset + 2.0f + 16.0f) * scaledFactor; // Shadow - Renderer->DrawSpriteOffset(displayedSprite, - glm::vec2(shadowScaledPosOffsetX - 46.0f, - shadowScaledPosOffsetY - 16.0f), - glm::vec2{46.0f, 16.0f}, - {0.0f, 0.0f, 0.0f, alpha / 2 / 256.0f}, - glm::vec2{shadowZoom, shadowZoom}, angle); - float scaledPosOffsetX = (xOffset + 46.0f) * scaledFactor; - float scaledPosOffsetY = (yOffset + 16.0f) * scaledFactor; + const glm::mat4 shadowTransformation = Transformation2D( + {shadowScaledPosOffsetX - 46.0f, shadowScaledPosOffsetY - 16.0f}, + {46, 16}, angle, glm::vec2(shadowZoom)); + Renderer->DrawSprite(displayedSprite, shadowTransformation, + {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); // Tag - Renderer->DrawSpriteOffset( - displayedSprite, - glm::vec2(scaledPosOffsetX - 46.0f, scaledPosOffsetY - 16.0f), - glm::vec2{46.0f, 16.0f}, {1.0f, 1.0f, 1.0f, alpha / 256.0f}, - glm::vec2{zoomMulti, zoomMulti}, angle); + const glm::vec2 scaledPosOffset = + glm::vec2(xOffset + 46.0f, yOffset + 16.0f) * scaledFactor; + const glm::mat4 tagTransformation = + Transformation2D(scaledPosOffset - glm::vec2(46.0f, 16.0f), {46, 16}, + angle, {zoomMulti, zoomMulti}); + Renderer->DrawSprite(displayedSprite, tagTransformation, + {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 851726d83..17490aeff 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -64,16 +64,6 @@ void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, DrawSprite(sprite, dest, tint, inverted); } -void BaseRenderer::DrawSpriteOffset(const Sprite& sprite, - const glm::vec2 topLeft, - const glm::vec2 displayOffset, - const glm::vec4 tint, const glm::vec2 scale, - const float angle, const bool inverted) { - const glm::mat4 transformation = - Transformation2D(topLeft, displayOffset, angle, scale); - DrawSprite(sprite, transformation, tint, inverted); -} - void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const glm::mat4 transformation, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 370309df0..23acf9fa8 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -61,13 +61,6 @@ class BaseRenderer { void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, glm::vec2 scale, float angle = 0.0f, bool inverted = false); - // TODO: Remove entirely - void DrawSpriteOffset(Sprite const& sprite, glm::vec2 topLeft, - glm::vec2 displayOffset, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0), float angle = 0.0f, - bool inverted = false); - // TODO: Remove entirely void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, From 73b5029c4fdaf7e58c0746ec8f3dba5ccaac444d Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 18:15:18 +0200 Subject: [PATCH 39/88] Removed superfluous DrawMaskedSpriteOverlay overload --- src/games/chlcc/delusiontrigger.cpp | 9 +++++---- src/renderer/renderer.cpp | 26 +++++++++----------------- src/renderer/renderer.h | 6 ------ src/ui/widgets/cc/backlogentry.cpp | 4 ++-- 4 files changed, 16 insertions(+), 29 deletions(-) diff --git a/src/games/chlcc/delusiontrigger.cpp b/src/games/chlcc/delusiontrigger.cpp index 5ccfe5cff..dadb6cc34 100644 --- a/src/games/chlcc/delusiontrigger.cpp +++ b/src/games/chlcc/delusiontrigger.cpp @@ -341,10 +341,11 @@ void DelusionTrigger::Render() { ScreenMask, RectF(0.0f, 0.0f, 1280.0f, 720.0f), glm::vec4(1.0f, 1.0f, 1.0f, (backgroundAlpha * 160) / 65536.0)); - Renderer->DrawMaskedSpriteOverlay( - BackgroundSprite, ScaledMask, RectF(0.0f, 0.0f, 1280.0f, 720.0f), - glm::vec4{1.0f}, (backgroundAlpha * 160) >> 8, 20, true, - spinAngle * 2 * (float)M_PI / 65536.0f); + CornersQuad dest = RectF(0.0f, 0.0f, 1280.0f, 720.0f) + .Rotate(ScrWorkAngleToRad(spinAngle), {640, 360}); + Renderer->DrawMaskedSpriteOverlay(BackgroundSprite, ScaledMask, dest, + (backgroundAlpha * 160) >> 8, 20, + glm::vec4(1.0f), true); } } // namespace CHLCC diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 17490aeff..018e41567 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -102,14 +102,6 @@ void BaseRenderer::DrawMaskedSpriteOverlay( isInverted, useMaskAlpha); } -void BaseRenderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const RectF& dest, - const glm::vec4 tint, const int alpha, const int fadeRange, - const bool isInverted, const float angle, const bool useMaskAlpha) { - DrawMaskedSpriteOverlay(sprite, mask, dest.Rotate(angle, dest.Center()), - alpha, fadeRange, tint, isInverted, useMaskAlpha); -} - void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, @@ -290,8 +282,8 @@ void BaseRenderer::DrawProcessedText_BasicFont( Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = dest; - DrawMaskedSpriteOverlay(glyph, mask, dest, color, color.a * 255, - 256, false, 0, i == 0); + DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, + color, false, i == 0); } else { DrawSprite(glyph, dest, color); } @@ -305,8 +297,8 @@ void BaseRenderer::DrawProcessedText_BasicFont( Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = dest; - DrawMaskedSpriteOverlay(glyph, mask, dest, color, color.a * 255, - 256, false, 0, i == 0); + DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, + color, false, i == 0); } else { DrawSprite(glyph, dest, color); } @@ -330,8 +322,8 @@ void BaseRenderer::DrawProcessedText_BasicFont( mask.Sheet = *maskedSheet; mask.Bounds = text[i].DestRect; DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, - text[i].DestRect, color, color.a * 255, 256, - false, 0, false); + text[i].DestRect, color.a * 255, 256, color, + false, false); } else { DrawSprite(font->Glyph(text[i].CharId), text[i].DestRect, color); } @@ -379,8 +371,8 @@ void BaseRenderer::DrawProcessedText_LBFont( mask.Sheet = *maskedSheet; mask.Bounds = outlineDest; DrawMaskedSpriteOverlay(font->OutlineGlyph(text[i].CharId), mask, - outlineDest, color, color.a * 255, 256, false, - 0, i == 0); + outlineDest, color.a * 255, 256, color, false, + i == 0); } else { DrawSprite(font->OutlineGlyph(text[i].CharId), outlineDest, color); } @@ -408,7 +400,7 @@ void BaseRenderer::DrawProcessedText_LBFont( mask.Sheet = *maskedSheet; mask.Bounds = foregroundDest; DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, foregroundDest, - color, color.a * 255, 256, false, 0, false); + color.a * 255, 256, color, false, false); } else { DrawSprite(font->Glyph(text[i].CharId), foregroundDest, color); } diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 23acf9fa8..2d70e36a1 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -124,12 +124,6 @@ class BaseRenderer { bool isInverted = false, bool useMaskAlpha = true); - // TODO: Remove entirely - void DrawMaskedSpriteOverlay(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, bool isInverted = false, - float angle = 0.0f, bool useMaskAlpha = true); - virtual void DrawVertices(SpriteSheet const& sheet, std::span sheetPositions, std::span displayPositions, diff --git a/src/ui/widgets/cc/backlogentry.cpp b/src/ui/widgets/cc/backlogentry.cpp index dbdff1dd6..671095e29 100644 --- a/src/ui/widgets/cc/backlogentry.cpp +++ b/src/ui/widgets/cc/backlogentry.cpp @@ -21,8 +21,8 @@ void BacklogEntry::Render() { mask.Sheet = BacklogMaskSheet; mask.Bounds = bounds; - Renderer->DrawMaskedSpriteOverlay(VoiceIcon, mask, bounds, Tint, - Tint.a * 255, 256, false, 0, false); + Renderer->DrawMaskedSpriteOverlay(VoiceIcon, mask, bounds, Tint.a * 255, + 256, Tint, false, false); } if (BacklogPage->HasName) { From 459f211375d2b6bf023b85ab2a03811d54324620 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 18:26:01 +0200 Subject: [PATCH 40/88] Removed superfluous DrawRect method --- src/game.cpp | 4 ++-- src/games/cc/dialoguebox.cpp | 2 +- src/games/cc/titlemenu.cpp | 2 +- src/games/cclcc/titlemenu.cpp | 6 +++--- src/games/chlcc/albummenu.cpp | 2 +- src/games/chlcc/clearlistmenu.cpp | 2 +- src/games/chlcc/delusiontrigger.cpp | 2 +- src/games/chlcc/dialoguebox.cpp | 2 +- src/games/chlcc/moviemenu.cpp | 2 +- src/games/chlcc/musicmenu.cpp | 2 +- src/games/chlcc/optionsmenu.cpp | 2 +- src/games/chlcc/savemenu.cpp | 2 +- src/games/chlcc/systemmenu.cpp | 2 +- src/games/chlcc/tipsmenu.cpp | 6 +++--- src/games/chlcc/titlemenu.cpp | 2 +- src/games/chlcc/trophymenu.cpp | 2 +- src/games/mo6tw/dialoguebox.cpp | 2 +- src/games/mo6tw/titlemenu.cpp | 2 +- src/games/mo8/titlemenu.cpp | 4 ++-- src/games/rne/sysmesbox.cpp | 2 +- src/hud/dialoguebox.cpp | 2 +- src/renderer/renderer.cpp | 5 ----- src/renderer/renderer.h | 3 --- src/ui/widgets/cclcc/optionsbinarybutton.cpp | 2 +- src/ui/widgets/cclcc/optionsentry.cpp | 4 ++-- src/ui/widgets/cclcc/optionsslider.cpp | 2 +- src/ui/widgets/cclcc/optionsvoiceslider.cpp | 6 +++--- src/ui/widgets/cgviewer.cpp | 2 +- 28 files changed, 35 insertions(+), 43 deletions(-) diff --git a/src/game.cpp b/src/game.cpp index 61b8f9b7f..26766b3f4 100644 --- a/src/game.cpp +++ b/src/game.cpp @@ -370,7 +370,7 @@ static void RenderMain() { } glm::vec4 col = ScrWorkGetColor(SW_MASK1COLOR); col.a = glm::min(maskAlpha / 255.0f, 1.0f); - Renderer->DrawRect(RectF(maskPosX, maskPosY, maskSizeX, maskSizeY), + Renderer->DrawQuad(RectF(maskPosX, maskPosY, maskSizeX, maskSizeY), col); } } @@ -522,7 +522,7 @@ void Render() { break; } case DrawComponentType::Mask: { - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), glm::vec4(0.0f, 0.0f, 0.0f, (ScrWork[SW_RESTARTMASK] / 256.0f))); break; diff --git a/src/games/cc/dialoguebox.cpp b/src/games/cc/dialoguebox.cpp index ada4931aa..1c3bac5c5 100644 --- a/src/games/cc/dialoguebox.cpp +++ b/src/games/cc/dialoguebox.cpp @@ -41,7 +41,7 @@ void DialogueBox::Render(DialoguePageMode mode, bool hasName, float nameWidth, } } else { glm::vec4 nvlBoxTint(0.0f, 0.0f, 0.0f, opacity * NVLBoxMaxOpacity); - Renderer->DrawRect(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), + Renderer->DrawQuad(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), nvlBoxTint); } } diff --git a/src/games/cc/titlemenu.cpp b/src/games/cc/titlemenu.cpp index 23d9b8c3c..c06edc590 100644 --- a/src/games/cc/titlemenu.cpp +++ b/src/games/cc/titlemenu.cpp @@ -252,7 +252,7 @@ void TitleMenu::Render() { OverlaySprite, RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight)); DrawSmoke(SmokeOpacityNormal); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), glm::vec4(1.0f, 1.0f, 1.0f, 1.0f - ScrWork[SW_TITLEDISPCT] / 60.0f)); diff --git a/src/games/cclcc/titlemenu.cpp b/src/games/cclcc/titlemenu.cpp index 3e655be9a..e1f09d73a 100644 --- a/src/games/cclcc/titlemenu.cpp +++ b/src/games/cclcc/titlemenu.cpp @@ -529,7 +529,7 @@ void TitleMenu::Render() { DrawSmoke(SmokeOpacityNormal); Renderer->DrawSprite(CopyrightTextSprite, glm::vec2(CopyrightTextX, CopyrightTextY)); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), glm::vec4(1.0f, 1.0f, 1.0f, 1.0f - ScrWork[SW_TITLEDISPCT] / 60.0f)); @@ -560,7 +560,7 @@ void TitleMenu::Render() { MainItems->Render(); ContinueItems->Render(); ExtraItems->Render(); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), {0.0f, 0.0f, 0.0f, ScrWork[SW_TITLEDISPCT] / 32.0f}); } break; @@ -590,7 +590,7 @@ void TitleMenu::Render() { int maskAlpha = ScrWork[SW_TITLEMASKALPHA]; glm::vec4 col = ScrWorkGetColor(SW_TITLEMASKCOLOR); col.a = glm::min(maskAlpha / 255.0f, 1.0f); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), col); } } diff --git a/src/games/chlcc/albummenu.cpp b/src/games/chlcc/albummenu.cpp index fb59285cb..5e88065b1 100644 --- a/src/games/chlcc/albummenu.cpp +++ b/src/games/chlcc/albummenu.cpp @@ -112,7 +112,7 @@ void AlbumMenu::Hide() { void AlbumMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/clearlistmenu.cpp b/src/games/chlcc/clearlistmenu.cpp index 755864815..08a9ca7f5 100644 --- a/src/games/chlcc/clearlistmenu.cpp +++ b/src/games/chlcc/clearlistmenu.cpp @@ -64,7 +64,7 @@ void ClearListMenu::Hide() { void ClearListMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/delusiontrigger.cpp b/src/games/chlcc/delusiontrigger.cpp index dadb6cc34..c94773559 100644 --- a/src/games/chlcc/delusiontrigger.cpp +++ b/src/games/chlcc/delusiontrigger.cpp @@ -334,7 +334,7 @@ void DelusionTrigger::Render() { ScaledMask.Bounds.Y = BackgroundSpriteMask.Bounds.Y - deltaHeight / 2.0f; TriggerOnTint[3] = TriggerOnTintAlpha * backgroundAlpha / 65536.0f; - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), TriggerOnTint); + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), TriggerOnTint); ScreenMask.Bounds.X = UnderlayerXOffset / 1000.0f; Renderer->DrawSprite( diff --git a/src/games/chlcc/dialoguebox.cpp b/src/games/chlcc/dialoguebox.cpp index 3473e97c2..63334364e 100644 --- a/src/games/chlcc/dialoguebox.cpp +++ b/src/games/chlcc/dialoguebox.cpp @@ -93,7 +93,7 @@ void DialogueBox::Render(DialoguePageMode mode, bool hasName, float nameWidth, if (mode == DPM_NVL) { glm::vec4 nvlBoxTint(0.0f, 0.0f, 0.0f, opacity * NVLBoxMaxOpacity); - Renderer->DrawRect(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), + Renderer->DrawQuad(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), nvlBoxTint); } } diff --git a/src/games/chlcc/moviemenu.cpp b/src/games/chlcc/moviemenu.cpp index a9d2c0204..fde0a0911 100644 --- a/src/games/chlcc/moviemenu.cpp +++ b/src/games/chlcc/moviemenu.cpp @@ -125,7 +125,7 @@ void MovieMenu::Hide() { void MovieMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/musicmenu.cpp b/src/games/chlcc/musicmenu.cpp index a1c42dea0..a23c59381 100644 --- a/src/games/chlcc/musicmenu.cpp +++ b/src/games/chlcc/musicmenu.cpp @@ -102,7 +102,7 @@ void MusicMenu::Hide() { void MusicMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/optionsmenu.cpp b/src/games/chlcc/optionsmenu.cpp index 46498178e..5b1b0eda3 100644 --- a/src/games/chlcc/optionsmenu.cpp +++ b/src/games/chlcc/optionsmenu.cpp @@ -44,7 +44,7 @@ OptionsMenu::OptionsMenu() : UI::OptionsMenu() { void OptionsMenu::Render() { if (State != Hidden) { if (FadeAnimation.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/savemenu.cpp b/src/games/chlcc/savemenu.cpp index 30c535b0c..300754242 100644 --- a/src/games/chlcc/savemenu.cpp +++ b/src/games/chlcc/savemenu.cpp @@ -357,7 +357,7 @@ void SaveMenu::Update(float dt) { void SaveMenu::Render() { if (State != Hidden && ScrWork[SW_FILEALPHA] != 0) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/systemmenu.cpp b/src/games/chlcc/systemmenu.cpp index 149a31ae4..b11305cdb 100644 --- a/src/games/chlcc/systemmenu.cpp +++ b/src/games/chlcc/systemmenu.cpp @@ -118,7 +118,7 @@ void SystemMenu::Update(float dt) { void SystemMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/chlcc/tipsmenu.cpp b/src/games/chlcc/tipsmenu.cpp index c4b17e6a7..484d206ac 100644 --- a/src/games/chlcc/tipsmenu.cpp +++ b/src/games/chlcc/tipsmenu.cpp @@ -70,7 +70,7 @@ void TipsMenu::Hide() { void TipsMenu::Render() { if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); @@ -214,12 +214,12 @@ inline void TipsMenu::DrawTipsTree(float yOffset) { currentTipBackgroundPosition); glm::vec2 gradientPosition(GradientPosition.x, GradientPosition.y + yOffset); Renderer->DrawSprite(TipsGradient, gradientPosition); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(GradientPosition.x, TipsGradient.Bounds.Height + yOffset, TipsGradient.Bounds.Width - 10.0f, 720.0f - TipsGradient.Bounds.Height - 86.0f), RgbIntToFloat(EndOfGradientColor)); - Renderer->DrawRect(RectF(GradientPosition.x, 634.0f + yOffset, + Renderer->DrawQuad(RectF(GradientPosition.x, 634.0f + yOffset, TipsGradient.Bounds.Width, 86.0f), RgbIntToFloat(EndOfGradientColor)); glm::vec2 treePosition(TreePosition.x, TreePosition.y + yOffset); diff --git a/src/games/chlcc/titlemenu.cpp b/src/games/chlcc/titlemenu.cpp index 76473cda7..12c580e07 100644 --- a/src/games/chlcc/titlemenu.cpp +++ b/src/games/chlcc/titlemenu.cpp @@ -439,7 +439,7 @@ void TitleMenu::Render() { int maskAlpha = ScrWork[SW_TITLEMASKALPHA]; glm::vec4 col = ScrWorkGetColor(SW_TITLEMASKCOLOR); col.a = glm::min(maskAlpha / 255.0f, 1.0f); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), col); } } diff --git a/src/games/chlcc/trophymenu.cpp b/src/games/chlcc/trophymenu.cpp index cb055f54c..b2a6666ae 100644 --- a/src/games/chlcc/trophymenu.cpp +++ b/src/games/chlcc/trophymenu.cpp @@ -92,7 +92,7 @@ void TrophyMenu::Render() { if (State == Hidden) return; if (State != Hidden) { if (MenuTransition.IsIn()) { - Renderer->DrawRect(RectF(0.0f, 0.0f, 1280.0f, 720.0f), + Renderer->DrawQuad(RectF(0.0f, 0.0f, 1280.0f, 720.0f), RgbIntToFloat(BackgroundColor)); } else { DrawCircles(); diff --git a/src/games/mo6tw/dialoguebox.cpp b/src/games/mo6tw/dialoguebox.cpp index 967577bfc..cd6327deb 100644 --- a/src/games/mo6tw/dialoguebox.cpp +++ b/src/games/mo6tw/dialoguebox.cpp @@ -25,7 +25,7 @@ void DialogueBox::Render(DialoguePageMode mode, bool hasName, float nameWidth, Renderer->DrawSprite(ADVBoxDecoration, ADVBoxDecorationPos, col); } else { glm::vec4 nvlBoxTint(0.0f, 0.0f, 0.0f, opacity * NVLBoxMaxOpacity); - Renderer->DrawRect(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), + Renderer->DrawQuad(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), nvlBoxTint); } diff --git a/src/games/mo6tw/titlemenu.cpp b/src/games/mo6tw/titlemenu.cpp index 00b4913ba..c6a0ddd2b 100644 --- a/src/games/mo6tw/titlemenu.cpp +++ b/src/games/mo6tw/titlemenu.cpp @@ -478,7 +478,7 @@ void TitleMenu::Render() { int maskAlpha = ScrWork[SW_TITLEMASKALPHA]; glm::vec4 col = ScrWorkGetColor(SW_TITLEMASKCOLOR); col.a = glm::min(maskAlpha / 255.0f, 1.0f); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), col); } } diff --git a/src/games/mo8/titlemenu.cpp b/src/games/mo8/titlemenu.cpp index c3cc3417b..2eeacf561 100644 --- a/src/games/mo8/titlemenu.cpp +++ b/src/games/mo8/titlemenu.cpp @@ -284,7 +284,7 @@ void TitleMenu::Render() { glm::vec2(PressToStartX, PressToStartY), col); glm::vec4 black = glm::vec4(0.0f); black.a = glm::smoothstep(0.0f, 1.0f, PrimaryFadeAnimation.Progress); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), black); } break; @@ -314,7 +314,7 @@ void TitleMenu::Render() { GalleryItems->Render(); glm::vec4 black = glm::vec4(0.0f); black.a = glm::smoothstep(0.0f, 1.0f, PrimaryFadeAnimation.Progress); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), black); } break; diff --git a/src/games/rne/sysmesbox.cpp b/src/games/rne/sysmesbox.cpp index 19a1c7cc3..850dc1359 100644 --- a/src/games/rne/sysmesbox.cpp +++ b/src/games/rne/sysmesbox.cpp @@ -221,7 +221,7 @@ void SysMesBox::Render() { glm::vec4 col(1.0f, 1.0f, 1.0f, 1.0f); if (BoxAnimCount > BoxDisplayStartCount) { - Renderer->DrawRect( + Renderer->DrawQuad( RectF(BoxDisplayX, BoxTopY - 1.0f, BoxWidth, BoxHeight + 2.0f), glm::vec4(1.0f, 1.0f, 1.0f, 0.75f)); Renderer->DrawSprite(BoxDecorationTop, diff --git a/src/hud/dialoguebox.cpp b/src/hud/dialoguebox.cpp index f139c46a0..e1460a657 100644 --- a/src/hud/dialoguebox.cpp +++ b/src/hud/dialoguebox.cpp @@ -59,7 +59,7 @@ void DialogueBox::Render(DialoguePageMode mode, bool hasName, float nameWidth, RenderControlButtons(col); } else { glm::vec4 nvlBoxTint(0.0f, 0.0f, 0.0f, opacity * NVLBoxMaxOpacity); - Renderer->DrawRect(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), + Renderer->DrawQuad(RectF(0, 0, Profile::DesignWidth, Profile::DesignHeight), nvlBoxTint); } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 018e41567..e25cf23c5 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -162,11 +162,6 @@ void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { DrawSprite(RectSprite, dest, color); } -void BaseRenderer::DrawRect(const RectF& dest, const glm::vec4 color, - const float angle) { - DrawQuad(dest.Rotate(angle, dest.Center()), color); -} - void BaseRenderer::DrawRect3DRotated(const RectF& dest, const float depth, const glm::vec2 vanishingPoint, const bool stayInScreen, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 2d70e36a1..2ef6ea577 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -134,9 +134,6 @@ class BaseRenderer { void DrawQuad(const CornersQuad& dest, glm::vec4 color); - // TODO: Remove entirely - void DrawRect(const RectF& dest, glm::vec4 color, float angle = 0.0f); - // TODO: Remove entirely void DrawRect3DRotated(const RectF& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, diff --git a/src/ui/widgets/cclcc/optionsbinarybutton.cpp b/src/ui/widgets/cclcc/optionsbinarybutton.cpp index 7f35fa978..e3f3a4b90 100644 --- a/src/ui/widgets/cclcc/optionsbinarybutton.cpp +++ b/src/ui/widgets/cclcc/optionsbinarybutton.cpp @@ -46,7 +46,7 @@ void OptionsBinaryButton::Render() { highlightBounds.X = highlightPos.x; highlightBounds.Y = highlightPos.y; - Renderer->DrawRect(highlightBounds, HighlightTint); + Renderer->DrawQuad(highlightBounds, HighlightTint); Renderer->DrawSprite(BoxSprite, TrueButton.Bounds.GetPos(), Tint); Renderer->DrawSprite(TrueSprite, TrueButton.Bounds.GetPos(), Tint, diff --git a/src/ui/widgets/cclcc/optionsentry.cpp b/src/ui/widgets/cclcc/optionsentry.cpp index 28c4f346a..3f6754fc1 100644 --- a/src/ui/widgets/cclcc/optionsentry.cpp +++ b/src/ui/widgets/cclcc/optionsentry.cpp @@ -35,8 +35,8 @@ void OptionsEntry::Render() { if (HasFocus) { RectF highlightBoundBox(Bounds.X, Bounds.Y, EntryDimensions.x, EntryDimensions.y); - Renderer->DrawRect(highlightBoundBox, HighlightTint); - Renderer->DrawRect( + Renderer->DrawQuad(highlightBoundBox, HighlightTint); + Renderer->DrawQuad( RectF(highlightBoundBox.X + 2.0f, highlightBoundBox.Y + 2.0f, highlightBoundBox.Width - 4.0f, highlightBoundBox.Height - 4.0f), glm::vec4(1.0f, 1.0f, 1.0f, Tint.a)); diff --git a/src/ui/widgets/cclcc/optionsslider.cpp b/src/ui/widgets/cclcc/optionsslider.cpp index 5276ac2f4..fa79d7230 100644 --- a/src/ui/widgets/cclcc/optionsslider.cpp +++ b/src/ui/widgets/cclcc/optionsslider.cpp @@ -46,7 +46,7 @@ void OptionsSlider::Render() { Bounds.Y + SliderTrackOffset.y, Slider.GetNormalizedValue() * BoxSprite.ScaledWidth(), BoxSprite.ScaledHeight()); - Renderer->DrawRect(highlightBounds, HighlightTint); + Renderer->DrawQuad(highlightBounds, HighlightTint); Renderer->DrawSprite(BoxSprite, Bounds.GetPos() + SliderTrackOffset, Tint); } diff --git a/src/ui/widgets/cclcc/optionsvoiceslider.cpp b/src/ui/widgets/cclcc/optionsvoiceslider.cpp index 3b426d170..a0e9ec52c 100644 --- a/src/ui/widgets/cclcc/optionsvoiceslider.cpp +++ b/src/ui/widgets/cclcc/optionsvoiceslider.cpp @@ -45,8 +45,8 @@ void OptionsVoiceSlider::Render() { if (HasFocus) { RectF highlightBoundBox(Bounds.X, Bounds.Y, VoiceEntryDimensions.x, VoiceEntryDimensions.y); - Renderer->DrawRect(highlightBoundBox, HighlightTint); - Renderer->DrawRect( + Renderer->DrawQuad(highlightBoundBox, HighlightTint); + Renderer->DrawQuad( RectF(highlightBoundBox.X + 2.0f, highlightBoundBox.Y + 2.0f, highlightBoundBox.Width - 4.0f, highlightBoundBox.Height - 4.0f), glm::vec4(1.0f, 1.0f, 1.0f, Tint.a)); @@ -61,7 +61,7 @@ void OptionsVoiceSlider::Render() { Bounds.Y + VoiceSliderOffset.y, Slider.GetNormalizedValue() * BoxSprite.ScaledWidth(), BoxSprite.ScaledHeight()); - Renderer->DrawRect(highlightBounds, HighlightTint); + Renderer->DrawQuad(highlightBounds, HighlightTint); Renderer->DrawSprite(BoxSprite, Bounds.GetPos() + VoiceSliderOffset, Tint); } diff --git a/src/ui/widgets/cgviewer.cpp b/src/ui/widgets/cgviewer.cpp index e1a5d71d5..4e0db85c8 100644 --- a/src/ui/widgets/cgviewer.cpp +++ b/src/ui/widgets/cgviewer.cpp @@ -111,7 +111,7 @@ void CgViewer::Update(float dt) { void CgViewer::Render() { glm::vec4 col(1.0f, 1.0f, 1.0f, glm::smoothstep(0.0f, 1.0f, FadeAnimation.Progress)); - Renderer->DrawRect( + Renderer->DrawQuad( RectF(0.0f, 0.0f, Profile::DesignWidth, Profile::DesignHeight), glm::vec4(0.0f, 0.0f, 0.0f, col.a)); glm::vec2 pos; From 3a73e849165446806b26eed7fa1ee94a13f32002 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 18:27:19 +0200 Subject: [PATCH 41/88] Removed superfluous DrawRect3DRotated method --- src/renderer/renderer.cpp | 9 --------- src/renderer/renderer.h | 5 ----- 2 files changed, 14 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index e25cf23c5..79ec5512f 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -162,15 +162,6 @@ void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { DrawSprite(RectSprite, dest, color); } -void BaseRenderer::DrawRect3DRotated(const RectF& dest, const float depth, - const glm::vec2 vanishingPoint, - const bool stayInScreen, - const glm::quat rot, - const glm::vec4 color) { - DrawSprite3DRotated(RectSprite, dest, depth, vanishingPoint, stayInScreen, - rot, color); -} - void BaseRenderer::DrawProcessedText(std::span text, Font* font, float opacity, RendererOutlineMode outlineMode, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 2ef6ea577..3258708fc 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -134,11 +134,6 @@ class BaseRenderer { void DrawQuad(const CornersQuad& dest, glm::vec4 color); - // TODO: Remove entirely - void DrawRect3DRotated(const RectF& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 color); - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, From fba916cd36239f141ea95be438a215d9acda1694 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 18:51:06 +0200 Subject: [PATCH 42/88] Removed superfluous DrawCharacterMvl overload --- src/character2d.cpp | 9 +++++---- src/renderer/renderer.cpp | 34 ++++++++++++---------------------- src/renderer/renderer.h | 11 ++--------- 3 files changed, 19 insertions(+), 35 deletions(-) diff --git a/src/character2d.cpp b/src/character2d.cpp index 826ce0a98..06ebd7657 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -202,10 +202,11 @@ void Character2D::Render(int layer) { if (Status != LS_Loaded || !OnLayer(layer) || !Show) return; if (Profile::CharaIsMvl) { - Renderer->DrawCharacterMvl(CharaSprite, glm::vec2(OffsetX, OffsetY), - MvlVerticesCount, MvlVertices.data(), - MvlIndicesCount, MvlIndices.data(), false, Tint, - glm::vec2(ScaleX, ScaleY)); + const glm::mat4 transformation = Transformation2D( + {OffsetX, OffsetY}, {0.0f, 0.0f}, 0.0f, {ScaleX, ScaleY}); + Renderer->DrawCharacterMvl(CharaSprite, MvlVertices, + std::span(MvlIndices.begin(), MvlIndicesCount), + transformation, Tint); } else { for (auto id : StatesToDraw) { if (auto stateItr = States.find(id); stateItr != States.end()) { diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 79ec5512f..40724aed7 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -200,48 +200,38 @@ void BaseRenderer::DrawProcessedText(std::span text, } void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, - const std::span vertices, + const std::span vertices, const std::span indices, glm::mat4 transformation, glm::vec4 tint, bool inverted) { + std::vector transformedVertices(vertices.begin(), vertices.end()); + const size_t vertexCount = vertices.size() / 5; for (size_t i = 0; i < vertexCount; i++) { const glm::vec2 pos = transformation * glm::vec4(vertices[i * 5], vertices[i * 5 + 1], 0.0f, 1.0f); - vertices[i * 5] = pos.x; - vertices[i * 5 + 1] = pos.y; + transformedVertices[i * 5] = pos.x; + transformedVertices[i * 5 + 1] = pos.y; } - DrawCharacterMvl(sprite, vertices, indices, tint, inverted); + DrawCharacterMvl(sprite, transformedVertices, indices, tint, inverted); } void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, - std::span vertices, + std::span vertices, std::span indices, const glm::vec2 offset, const glm::vec4 tint, const bool inverted) { + std::vector transformedVertices(vertices.begin(), vertices.end()); + const size_t vertexCount = vertices.size() / 5; for (size_t i = 0; i < vertexCount; i++) { - vertices[i * 5] += offset.x; - vertices[i * 5 + 1] += offset.y; + transformedVertices[i * 5] += offset.x; + transformedVertices[i * 5 + 1] += offset.y; } - DrawCharacterMvl(sprite, vertices, indices, tint, inverted); -} - -void BaseRenderer::DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, - int indicesCount, uint16_t* mvlIndices, - bool inverted, glm::vec4 tint, - glm::vec2 scale) { - const glm::mat4 transformation = - Transformation2D(topLeft, {0.0f, 0.0f}, 0.0f, scale); - - std::vector vertices(mvlVertices, mvlVertices + verticesCount * 5); - std::vector indices(mvlIndices, mvlIndices + indicesCount); - - DrawCharacterMvl(sprite, vertices, indices, transformation, tint, inverted); + DrawCharacterMvl(sprite, transformedVertices, indices, tint, inverted); } void BaseRenderer::DrawProcessedText_BasicFont( diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 3258708fc..743d2d225 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -174,23 +174,16 @@ class BaseRenderer { std::span indices, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false) = 0; - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, std::span indices, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, + void DrawCharacterMvl(const Sprite& sprite, std::span vertices, std::span indices, glm::vec2 offset, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); - // TODO: Remove entirely - void DrawCharacterMvl(Sprite const& sprite, glm::vec2 topLeft, - int verticesCount, float* mvlVertices, int indicesCount, - uint16_t* mvlIndices, bool inverted = false, - glm::vec4 tint = glm::vec4(1.0), - glm::vec2 scale = glm::vec2(1.0f)); - virtual void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo = false) = 0; From 74609eccec472fd3115e5df15d8c87b80a3f88b9 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 20:42:08 +0200 Subject: [PATCH 43/88] Removed another superfluous DrawSprite overload --- src/games/chlcc/albummenu.cpp | 8 +++- src/games/chlcc/clearlistmenu.cpp | 8 +++- src/games/chlcc/moviemenu.cpp | 9 ++++- src/games/chlcc/musicmenu.cpp | 8 +++- src/games/chlcc/optionsmenu.cpp | 8 +++- src/games/chlcc/savemenu.cpp | 8 +++- src/games/chlcc/tipsmenu.cpp | 8 +++- src/games/chlcc/titlemenu.cpp | 12 ++++-- src/games/chlcc/trophymenu.cpp | 9 ++++- src/games/rne/titlemenu.cpp | 9 +---- src/hud/autoicondisplay.cpp | 14 ++++--- src/hud/skipicondisplay.cpp | 10 +++-- src/hud/waiticondisplay.cpp | 15 +++++--- src/renderer/renderer.cpp | 11 ------ src/renderer/renderer.h | 4 -- src/ui/widgets/button.cpp | 10 +++-- src/ui/widgets/cclcc/optionsbinarybutton.cpp | 6 +-- src/ui/widgets/cclcc/saveentrybutton.cpp | 40 ++++++++++++++------ src/ui/widgets/cclcc/tipsentrybutton.cpp | 10 +++-- src/ui/widgets/mo6tw/tipsentrybutton.cpp | 10 +++-- 20 files changed, 132 insertions(+), 85 deletions(-) diff --git a/src/games/chlcc/albummenu.cpp b/src/games/chlcc/albummenu.cpp index 5e88065b1..2ef102096 100644 --- a/src/games/chlcc/albummenu.cpp +++ b/src/games/chlcc/albummenu.cpp @@ -123,8 +123,12 @@ void AlbumMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(AlbumMenuTitle, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), AlbumMenuTitleAngle); + + const CornersQuad titleDest = + AlbumMenuTitle.ScaledBounds() + .Rotate(AlbumMenuTitleAngle, AlbumMenuTitle.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(AlbumMenuTitle, titleDest); } Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); diff --git a/src/games/chlcc/clearlistmenu.cpp b/src/games/chlcc/clearlistmenu.cpp index 08a9ca7f5..bb0e97bd5 100644 --- a/src/games/chlcc/clearlistmenu.cpp +++ b/src/games/chlcc/clearlistmenu.cpp @@ -75,8 +75,12 @@ void ClearListMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleText, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleText.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleText, titleDest); } Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); diff --git a/src/games/chlcc/moviemenu.cpp b/src/games/chlcc/moviemenu.cpp index fde0a0911..c8f7ade3f 100644 --- a/src/games/chlcc/moviemenu.cpp +++ b/src/games/chlcc/moviemenu.cpp @@ -135,8 +135,13 @@ void MovieMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleText, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleText.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleText, titleDest); + Renderer->DrawSprite(MenuTitleText, LeftTitlePos); } diff --git a/src/games/chlcc/musicmenu.cpp b/src/games/chlcc/musicmenu.cpp index a23c59381..660214c3f 100644 --- a/src/games/chlcc/musicmenu.cpp +++ b/src/games/chlcc/musicmenu.cpp @@ -112,8 +112,12 @@ void MusicMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(SoundLibraryTitle, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), SoundLibraryTitleAngle); + + const CornersQuad titleDest = + SoundLibraryTitle.ScaledBounds() + .Rotate(SoundLibraryTitleAngle, SoundLibraryTitle.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(SoundLibraryTitle, titleDest); } Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); diff --git a/src/games/chlcc/optionsmenu.cpp b/src/games/chlcc/optionsmenu.cpp index 5b1b0eda3..0a7df4452 100644 --- a/src/games/chlcc/optionsmenu.cpp +++ b/src/games/chlcc/optionsmenu.cpp @@ -54,8 +54,12 @@ void OptionsMenu::Render() { } if (FadeAnimation.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleText, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleText.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleText, titleDest); } glm::vec3 tint = {1.0f, 1.0f, 1.0f}; diff --git a/src/games/chlcc/savemenu.cpp b/src/games/chlcc/savemenu.cpp index 300754242..9d0444f9f 100644 --- a/src/games/chlcc/savemenu.cpp +++ b/src/games/chlcc/savemenu.cpp @@ -367,8 +367,12 @@ void SaveMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleTextSprite, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleTextSprite.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleTextSprite.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleTextSprite, titleDest); } Renderer->CaptureScreencap(ShaderScreencapture.BgSprite); diff --git a/src/games/chlcc/tipsmenu.cpp b/src/games/chlcc/tipsmenu.cpp index 484d206ac..cca9b2d71 100644 --- a/src/games/chlcc/tipsmenu.cpp +++ b/src/games/chlcc/tipsmenu.cpp @@ -80,8 +80,12 @@ void TipsMenu::Render() { } if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleText, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleText.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleText, titleDest); } glm::vec3 tint = {1.0f, 1.0f, 1.0f}; diff --git a/src/games/chlcc/titlemenu.cpp b/src/games/chlcc/titlemenu.cpp index 12c580e07..c36730cd7 100644 --- a/src/games/chlcc/titlemenu.cpp +++ b/src/games/chlcc/titlemenu.cpp @@ -446,10 +446,14 @@ void TitleMenu::Render() { inline void TitleMenu::DrawTitleMenuBackGraphics() { Renderer->DrawSprite(BackgroundSprite, glm::vec2(0.0f)); - Renderer->DrawSprite(SpinningCircleSprite, - glm::vec2(SpinningCircleX, SpinningCircleY), - glm::vec4(1.0f), glm::vec2(2.0f), - -SpinningCircleAnimation.Progress * 2.0f * (float)M_PI); + + const CornersQuad spinningCircleDest = + SpinningCircleSprite.ScaledBounds() + .Rotate(-SpinningCircleAnimation.Progress * 2.0f * (float)M_PI, + SpinningCircleSprite.Center()) + .Translate({SpinningCircleX, SpinningCircleY}); + Renderer->DrawSprite(SpinningCircleSprite, spinningCircleDest); + Renderer->DrawSprite(DelusionADVUnderSprite, glm::vec2(DelusionADVUnderX, DelusionADVUnderY)); Renderer->DrawSprite(DelusionADVSprite, diff --git a/src/games/chlcc/trophymenu.cpp b/src/games/chlcc/trophymenu.cpp index b2a6666ae..f992c1712 100644 --- a/src/games/chlcc/trophymenu.cpp +++ b/src/games/chlcc/trophymenu.cpp @@ -102,8 +102,13 @@ void TrophyMenu::Render() { } if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - Renderer->DrawSprite(MenuTitleText, RightTitlePos, glm::vec4(1.0f), - glm::vec2(1.0f), MenuTitleTextAngle); + + const CornersQuad titleDest = + MenuTitleText.ScaledBounds() + .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) + .Translate(RightTitlePos); + Renderer->DrawSprite(MenuTitleText, titleDest); + Renderer->DrawSprite(MenuTitleText, LeftTitlePos); } diff --git a/src/games/rne/titlemenu.cpp b/src/games/rne/titlemenu.cpp index 493e52256..c25d14a01 100644 --- a/src/games/rne/titlemenu.cpp +++ b/src/games/rne/titlemenu.cpp @@ -91,13 +91,8 @@ void TitleMenu::Render() { glm::vec4(1.0f)); Renderer->DrawSprite(EliteSprite, glm::vec2(EliteX, EliteY), glm::vec4(1.0f)); - if (ScrWork[SW_TITLECGNO] == 542) { - Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY), - glm::vec4(1.0f), glm::vec2(1.0f), 0.0f, true); - } else { - Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY), - glm::vec4(1.0f)); - } + Renderer->DrawSprite(LogoSprite, {LogoX, LogoY}, glm::vec4(1.0f), + ScrWork[SW_TITLECGNO] == 542); } } } diff --git a/src/hud/autoicondisplay.cpp b/src/hud/autoicondisplay.cpp index a0dfa6fdd..33297c342 100644 --- a/src/hud/autoicondisplay.cpp +++ b/src/hud/autoicondisplay.cpp @@ -86,12 +86,14 @@ void Render(glm::vec4 opacityTint) { case AutoIconType::CHLCC: if (MesSkipMode & SkipModeFlags::Auto) { - Renderer->DrawSprite( - AutoSkipArrowsSprite, glm::vec2(AutoIconOffset.x, AutoIconOffset.y), - opacityTint, glm::vec2(1.0f), Progress * 2 * (float)M_PI); - Renderer->DrawSprite(AutoIconSprite, - glm::vec2(AutoIconOffset.x, AutoIconOffset.y), - opacityTint); + const CornersQuad arrowsDest = + AutoSkipArrowsSprite.ScaledBounds() + .Rotate(Progress * 2.0f * (float)M_PI, + AutoSkipArrowsSprite.Center()) + .Translate(AutoIconOffset); + Renderer->DrawSprite(AutoSkipArrowsSprite, arrowsDest, opacityTint); + + Renderer->DrawSprite(AutoIconSprite, AutoIconOffset, opacityTint); } break; } diff --git a/src/hud/skipicondisplay.cpp b/src/hud/skipicondisplay.cpp index 7992bf271..c45c2a4bc 100644 --- a/src/hud/skipicondisplay.cpp +++ b/src/hud/skipicondisplay.cpp @@ -88,9 +88,13 @@ void Render(glm::vec4 opacityTint) { case SkipIconType::CHLCC: if (MesSkipMode & (SkipModeFlags::SkipRead | SkipModeFlags::SkipAll)) { - Renderer->DrawSprite( - AutoSkipArrowsSprite, glm::vec2(SkipIconOffset.x, SkipIconOffset.y), - opacityTint, glm::vec2(1.0f), Progress * 2 * (float)M_PI); + const CornersQuad arrowsDest = + AutoSkipArrowsSprite.ScaledBounds() + .Rotate(Progress * 2.0f * (float)M_PI, + AutoSkipArrowsSprite.Center()) + .Translate(SkipIconOffset); + Renderer->DrawSprite(AutoSkipArrowsSprite, arrowsDest, opacityTint); + Renderer->DrawSprite(SkipIconSprite, glm::vec2(SkipIconOffset.x, SkipIconOffset.y), opacityTint); diff --git a/src/hud/waiticondisplay.cpp b/src/hud/waiticondisplay.cpp index ef21793cd..334c93f39 100644 --- a/src/hud/waiticondisplay.cpp +++ b/src/hud/waiticondisplay.cpp @@ -146,15 +146,18 @@ void Render(glm::vec2 pos, glm::vec4 opacityTint, DialoguePageMode mode) { RenderFixed(opacityTint); return; - default: + default: { if (!GetFlag(Profile::ScriptVars::SF_SHOWWAITICON)) return; - Renderer->DrawSprite( - WaitIconSprite, - glm::vec2(pos.x + WaitIconOffset.x, pos.y + WaitIconOffset.y), - opacityTint, glm::vec2(1.0f), - SimpleAnim.Progress * 2.0f * (float)M_PI); + const CornersQuad dest = + WaitIconSprite.ScaledBounds() + .Rotate(SimpleAnim.Progress * 2.0f * (float)M_PI, + WaitIconSprite.Center()) + .Translate(pos + WaitIconOffset); + Renderer->DrawSprite(WaitIconSprite, dest, opacityTint); + return; + } } } diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 40724aed7..ab4f7200a 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -53,17 +53,6 @@ void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, DrawSprite(sprite, dest, tint, inverted); } -void BaseRenderer::DrawSprite(Sprite const& sprite, glm::vec2 topLeft, - glm::vec4 tint, glm::vec2 scale, float angle, - bool inverted) { - CornersQuad dest = sprite.ScaledBounds(); - dest.Scale(scale, {0.0f, 0.0f}) - .Rotate(angle, dest.Center()) - .Translate(topLeft); - - DrawSprite(sprite, dest, tint, inverted); -} - void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, const glm::mat4 transformation, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 743d2d225..d424a2509 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -57,10 +57,6 @@ class BaseRenderer { void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); - // TODO: Remove entirely - void DrawSprite(Sprite const& sprite, glm::vec2 topLeft, glm::vec4 tint, - glm::vec2 scale, float angle = 0.0f, bool inverted = false); - // TODO: Remove entirely void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, glm::vec2 vanishingPoint, bool stayInScreen, diff --git a/src/ui/widgets/button.cpp b/src/ui/widgets/button.cpp index 5c5d2bbf9..0db60349e 100644 --- a/src/ui/widgets/button.cpp +++ b/src/ui/widgets/button.cpp @@ -47,10 +47,12 @@ void Button::UpdateInput() { void Button::Render() { if (HasFocus) { - Renderer->DrawSprite( - HighlightSprite, - glm::vec2(Bounds.X + HighlightOffset.x, Bounds.Y + HighlightOffset.y), - Tint, glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + const RectF dest = + HighlightSprite.ScaledBounds() + .Scale({Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f}, + {0.0f, 0.0f}) + .Translate(Bounds.GetPos() + HighlightOffset); + Renderer->DrawSprite(HighlightSprite, dest, Tint); } if (IsLocked) { diff --git a/src/ui/widgets/cclcc/optionsbinarybutton.cpp b/src/ui/widgets/cclcc/optionsbinarybutton.cpp index e3f3a4b90..1d0e28233 100644 --- a/src/ui/widgets/cclcc/optionsbinarybutton.cpp +++ b/src/ui/widgets/cclcc/optionsbinarybutton.cpp @@ -49,10 +49,8 @@ void OptionsBinaryButton::Render() { Renderer->DrawQuad(highlightBounds, HighlightTint); Renderer->DrawSprite(BoxSprite, TrueButton.Bounds.GetPos(), Tint); - Renderer->DrawSprite(TrueSprite, TrueButton.Bounds.GetPos(), Tint, - glm::vec2(1.0f), 0.0f, !State); - Renderer->DrawSprite(FalseSprite, FalseButton.Bounds.GetPos(), Tint, - glm::vec2(1.0f), 0.0f, State); + Renderer->DrawSprite(TrueSprite, TrueButton.Bounds.GetPos(), Tint, !State); + Renderer->DrawSprite(FalseSprite, FalseButton.Bounds.GetPos(), Tint, State); } void OptionsBinaryButton::Update(float dt) { diff --git a/src/ui/widgets/cclcc/saveentrybutton.cpp b/src/ui/widgets/cclcc/saveentrybutton.cpp index d9a8428fd..5fc2b1c68 100644 --- a/src/ui/widgets/cclcc/saveentrybutton.cpp +++ b/src/ui/widgets/cclcc/saveentrybutton.cpp @@ -57,42 +57,58 @@ SaveEntryButton::SaveEntryButton(int id, int index, Sprite const& focusedBox, } void SaveEntryButton::Render() { + const glm::vec2 scale = {Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f}; + NormalSpriteLabel.Render(); if (HasFocus) { FocusedSpriteLabel.Tint = FocusedAlpha; FocusedSpriteLabel.Render(); - Renderer->DrawSprite( - HighlightSprite, - glm::vec2(Bounds.X + HighlightOffset.x, Bounds.Y + HighlightOffset.y), - Tint, glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + + const RectF highlightDest = + HighlightSprite.ScaledBounds() + .Scale(scale, {0.0f, 0.0f}) + .Translate(Bounds.GetPos() + HighlightOffset); + Renderer->DrawSprite(HighlightSprite, highlightDest, Tint); } + + const RectF numberDigitDest = NumberDigitSprite[0][0] + .ScaledBounds() + .Scale(scale, {0.0f, 0.0f}) + .Translate(Bounds.GetPos()); Renderer->DrawSprite( NumberDigitSprite[ScrWork[SW_SAVEMENUMODE]][(Index + 1) / 10], - glm::vec2(Bounds.X + 720, Bounds.Y + 120), Tint, - glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + RectF(numberDigitDest).Translate({720, 120}), Tint); Renderer->DrawSprite( NumberDigitSprite[ScrWork[SW_SAVEMENUMODE]][(Index + 1) % 10], - glm::vec2(Bounds.X + 752, Bounds.Y + 120), Tint, - glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + RectF(numberDigitDest).Translate({752, 120}), Tint); + if (SaveStatus == 1) { - Renderer->DrawSprite( - SeparationLineSprite[ScrWork[SW_SAVEMENUMODE]], - glm::vec2(Bounds.X + 308, Bounds.Y + 112), Tint, - glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + const RectF separationLineDest = + SeparationLineSprite[0] + .ScaledBounds() + .Scale(scale, {0.0f, 0.0f}) + .Translate(Bounds.GetPos() + glm::vec2(308, 112)); + Renderer->DrawSprite(SeparationLineSprite[ScrWork[SW_SAVEMENUMODE]], + separationLineDest, Tint); + if (IsLocked) { SceneTitleLabel.Render(); LockedSymbol.Render(); } + Renderer->DrawSprite( Thumbnail, RectF{Bounds.X + 20, Bounds.Y + 22, Thumbnail.Bounds.Width + 30, Thumbnail.Bounds.Height + 17}, Tint); + CharacterRouteLabel.Render(); SceneTitleLabel.Render(); SaveDateLabel.Render(); + } else if (SaveStatus == 0) { NoDataSymbol.Render(); + } else { BrokenDataSymbol.Render(); } diff --git a/src/ui/widgets/cclcc/tipsentrybutton.cpp b/src/ui/widgets/cclcc/tipsentrybutton.cpp index a5486a6f5..b3b4b6939 100644 --- a/src/ui/widgets/cclcc/tipsentrybutton.cpp +++ b/src/ui/widgets/cclcc/tipsentrybutton.cpp @@ -79,10 +79,12 @@ void TipsEntryButton::UpdateInput() { void TipsEntryButton::Render() { if (HasFocus) { - Renderer->DrawSprite( - HighlightSprite, - glm::vec2(Bounds.X + HighlightOffset.x, Bounds.Y + HighlightOffset.y), - Tint, glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + const RectF dest = + HighlightSprite.ScaledBounds() + .Scale({Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f}, + {0.0f, 0.0f}) + .Translate(Bounds.GetPos() + HighlightOffset); + Renderer->DrawSprite(HighlightSprite, dest, Tint); } Renderer->DrawProcessedText(TipNumber, Profile::Dialogue::DialogueFont, diff --git a/src/ui/widgets/mo6tw/tipsentrybutton.cpp b/src/ui/widgets/mo6tw/tipsentrybutton.cpp index 9cc1d47e8..8f2c38c67 100644 --- a/src/ui/widgets/mo6tw/tipsentrybutton.cpp +++ b/src/ui/widgets/mo6tw/tipsentrybutton.cpp @@ -65,10 +65,12 @@ void TipsEntryButton::Update(float dt) { void TipsEntryButton::Render() { if (HasFocus) { - Renderer->DrawSprite( - HighlightSprite, - glm::vec2(Bounds.X + HighlightOffset.x, Bounds.Y + HighlightOffset.y), - Tint, glm::vec2(Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f)); + const RectF dest = + HighlightSprite.ScaledBounds() + .Scale({Bounds.Width / HighlightSprite.ScaledWidth(), 1.0f}, + {0.0f, 0.0f}) + .Translate(Bounds.GetPos() + HighlightOffset); + Renderer->DrawSprite(HighlightSprite, dest, Tint); } Renderer->DrawProcessedText(TipNumber, Profile::Dialogue::DialogueFont, From ae4492bed2a529d6f08585aaceb4accf7299d02b Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 4 May 2025 22:19:40 +0200 Subject: [PATCH 44/88] Removed superfluous DrawSprite3DRotated methods --- src/games/rne/tilebackground.cpp | 11 ++++---- src/hud/waiticondisplay.cpp | 14 ++++------ src/renderer/renderer.cpp | 47 -------------------------------- src/renderer/renderer.h | 13 --------- src/util.cpp | 44 ++++++++++++++++++++++++++++++ src/util.h | 4 +++ 6 files changed, 59 insertions(+), 74 deletions(-) diff --git a/src/games/rne/tilebackground.cpp b/src/games/rne/tilebackground.cpp index 1eb1c2b32..5421e9530 100644 --- a/src/games/rne/tilebackground.cpp +++ b/src/games/rne/tilebackground.cpp @@ -63,12 +63,11 @@ void TileBackground::Render() { tileSprite.Bounds.X = (float)x * tileSprite.Bounds.Width; tileSprite.Bounds.Y = (float)y * tileSprite.Bounds.Height; - Renderer->DrawSprite3DRotated( - tileSprite, - RectF((float)x * ColumnWidth, (float)y * RowHeight, ColumnWidth, - RowHeight), - 2.0f, vanishingPoint, false, quat, - glm::vec4(1.0f, 1.0f, 1.0f, smoothedTileProgress)); + CornersQuad dest = RectF((float)x * ColumnWidth, (float)y * RowHeight, + ColumnWidth, RowHeight); + dest.Rotate(quat, {dest.Center(), 0.0f}, 2.0f, vanishingPoint); + Renderer->DrawSprite(tileSprite, dest, + {1.0f, 1.0f, 1.0f, smoothedTileProgress}); } } } diff --git a/src/hud/waiticondisplay.cpp b/src/hud/waiticondisplay.cpp index 334c93f39..038e2bc1f 100644 --- a/src/hud/waiticondisplay.cpp +++ b/src/hud/waiticondisplay.cpp @@ -109,14 +109,12 @@ static void RenderRotateZ(glm::vec2 pos, glm::vec4 opacityTint) { glm::quat quat; eulerZYXToQuat(&euler, &quat); - glm::vec2 vanishingPoint( - (pos.x + WaitIconOffset.x) + (WaitIconSprite.ScaledWidth() / 2.0f), - (pos.y + WaitIconOffset.y) + (WaitIconSprite.ScaledHeight() / 2.0f)); - - Renderer->DrawSprite3DRotated( - WaitIconSprite, - glm::vec2(pos.x + WaitIconOffset.x, pos.y + WaitIconOffset.y), 1.0f, - vanishingPoint, true, quat, opacityTint); + glm::vec2 vanishingPoint = pos + WaitIconOffset + WaitIconSprite.Center(); + + CornersQuad dest = + WaitIconSprite.ScaledBounds().Translate(pos + WaitIconOffset); + dest.Rotate(quat, {dest.Center(), 0.0f}, 1.0f, vanishingPoint, true); + Renderer->DrawSprite(WaitIconSprite, dest, opacityTint); } static void RenderFixed(glm::vec4 opacityTint) { diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index ab4f7200a..66b0bd59f 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -100,53 +100,6 @@ void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, DrawCCMessageBox(sprite, mask, dest, tint, alpha, fadeRange, effectCt); } -void BaseRenderer::DrawSprite3DRotated( - const Sprite& sprite, const RectF& dest, const float depth, - const glm::vec2 vanishingPoint, const bool stayInScreen, - const glm::quat rot, const glm::vec4 tint, const bool inverted) { - CornersQuad corners = dest; - std::array vertices = { - glm::vec4(corners.TopLeft, 0.0f, 1.0f), - glm::vec4(corners.TopRight, 0.0f, 1.0f), - glm::vec4(corners.BottomRight, 0.0f, 1.0f), - glm::vec4(corners.BottomLeft, 0.0f, 1.0f)}; - - const glm::mat4 transformation = - Transformation3D(glm::vec3(0.0f), {dest.Center(), 0.0f}, rot); - for (glm::vec4& vertex : vertices) vertex = transformation * vertex; - - if (stayInScreen) { - float maxZ = 0.0f; - for (const glm::vec4 vertex : vertices) maxZ = std::max(maxZ, vertex.z); - - for (glm::vec4& vertex : vertices) vertex.z -= maxZ; - } - - for (glm::vec4 vertex : vertices) { - vertex -= glm::vec4(vanishingPoint, 0.0f, 0.0f); - vertex *= depth / (depth - vertex.z); - vertex += glm::vec4(vanishingPoint, 0.0f, 0.0f); - } - - corners.TopLeft = glm::vec2(vertices[0]); - corners.TopRight = glm::vec2(vertices[1]); - corners.BottomRight = glm::vec2(vertices[2]); - corners.BottomLeft = glm::vec2(vertices[3]); - - DrawSprite(sprite, corners, tint, inverted); -} - -void BaseRenderer::DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, - float depth, glm::vec2 vanishingPoint, - bool stayInScreen, glm::quat rot, - glm::vec4 tint, glm::vec2 scale, - bool inverted) { - const RectF dest = - sprite.ScaledBounds().Scale(scale, {0.0f, 0.0f}).Translate(topLeft); - DrawSprite3DRotated(sprite, dest, depth, vanishingPoint, stayInScreen, rot, - tint, inverted); -} - void BaseRenderer::DrawQuad(const CornersQuad& dest, const glm::vec4 color) { DrawSprite(RectSprite, dest, color); } diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index d424a2509..1deb022b5 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -57,19 +57,6 @@ class BaseRenderer { void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); - // TODO: Remove entirely - void DrawSprite3DRotated(Sprite const& sprite, RectF const& dest, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false); - - // TODO: Remove entirely - void DrawSprite3DRotated(Sprite const& sprite, glm::vec2 topLeft, float depth, - glm::vec2 vanishingPoint, bool stayInScreen, - glm::quat rot, glm::vec4 tint = glm::vec4(1.0f), - glm::vec2 scale = glm::vec2(1.0f), - bool inverted = false); - virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, diff --git a/src/util.cpp b/src/util.cpp index 144e311ed..3003dba31 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -71,6 +71,43 @@ CornersQuad& CornersQuad::Rotate(const glm::quat rotation, glm::vec3 origin) { return *this; } +CornersQuad& CornersQuad::Rotate(const glm::quat rotation, + const glm::vec3 origin, const float depth, + const glm::vec2 vanishingPoint, + const bool stayInScreen) { + std::array vertices = { + glm::vec4(TopLeft, 0.0f, 1.0f), glm::vec4(BottomLeft, 0.0f, 1.0f), + glm::vec4(TopRight, 0.0f, 1.0f), glm::vec4(BottomRight, 0.0f, 1.0f)}; + + // Rotate + const glm::mat4 rotationMatrix = glm::mat4_cast(rotation); + for (glm::vec4& vertex : vertices) { + vertex -= glm::vec4(origin, 0.0f); + vertex = rotationMatrix * vertex; + vertex += glm::vec4(origin, 0.0f); + } + + // Move into screen + if (stayInScreen) { + float maxZ = 0.0f; + for (const glm::vec4 vertex : vertices) maxZ = std::max(maxZ, vertex.z); + + for (glm::vec4& vertex : vertices) vertex.z -= maxZ; + } + + // Project + for (glm::vec4& vertex : vertices) { + vertex -= glm::vec4(vanishingPoint, 0.0f, 0.0f); + const float normalizedZ = vertex.z / glm::length(glm::vec3(vertex)); + vertex *= depth / (depth - normalizedZ); + vertex += glm::vec4(vanishingPoint, 0.0f, 0.0f); + } + + *this = {glm::vec2(vertices[0]), glm::vec2(vertices[1]), + glm::vec2(vertices[2]), glm::vec2(vertices[3])}; + return *this; +} + CornersQuad RectF::Transform(glm::mat4 transformation) const { return CornersQuad(*this).Transform(transformation); } @@ -96,6 +133,13 @@ CornersQuad RectF::Rotate(glm::quat rotation, glm::vec3 origin) const { return CornersQuad(*this).Rotate(rotation, origin); } +CornersQuad RectF::Rotate(const glm::quat rotation, const glm::vec3 origin, + const float depth, const glm::vec2 vanishingPoint, + const bool stayInScreen) const { + return CornersQuad(*this).Rotate(rotation, origin, depth, vanishingPoint, + stayInScreen); +} + glm::mat2 Rotate2D(float angle) { glm::mat2 result; float cosa = cosf(angle); diff --git a/src/util.h b/src/util.h index 211369ed7..a179399e4 100644 --- a/src/util.h +++ b/src/util.h @@ -146,6 +146,8 @@ struct RectF { RectF& Scale(glm::vec2 scaling, glm::vec2 origin); CornersQuad Rotate(float angle, glm::vec2 origin) const; CornersQuad Rotate(glm::quat rotation, glm::vec3 origin) const; + CornersQuad Rotate(glm::quat rotation, glm::vec3 origin, float depth, + glm::vec2 vanishingPoint, bool stayInScreen = false) const; }; struct Rect { @@ -218,6 +220,8 @@ struct CornersQuad { CornersQuad& Scale(glm::vec2 scaling, glm::vec2 origin); CornersQuad& Rotate(float angle, glm::vec2 origin); CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin); + CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin, float depth, + glm::vec2 vanishingPoint, bool stayInScreen = false); }; inline CornersQuad operator*(const glm::mat4 transformation, CornersQuad quad) { From c66ae291e9fafbee213c1322d8d96a5c011e83f8 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 6 May 2025 00:26:15 +0200 Subject: [PATCH 45/88] Added more transformation utilities --- src/background2d.cpp | 26 +++++----- src/character2d.cpp | 4 +- src/games/cclcc/delusiontrigger.cpp | 76 ++++++++++++++++------------- src/games/cclcc/mapsystem.cpp | 54 ++++++++++---------- src/games/cclcc/yesnotrigger.cpp | 7 ++- src/games/chlcc/albummenu.cpp | 7 ++- src/games/chlcc/clearlistmenu.cpp | 7 ++- src/games/chlcc/moviemenu.cpp | 7 ++- src/games/chlcc/musicmenu.cpp | 2 +- src/games/chlcc/optionsmenu.cpp | 7 ++- src/games/chlcc/savemenu.cpp | 7 ++- src/games/chlcc/tipsmenu.cpp | 7 ++- src/games/chlcc/titlemenu.cpp | 4 +- src/games/chlcc/trophymenu.cpp | 7 ++- src/hud/autoicondisplay.cpp | 3 +- src/hud/skipicondisplay.cpp | 3 +- src/hud/waiticondisplay.cpp | 3 +- src/util.cpp | 66 +++++++++++++++++-------- src/util.h | 49 +++++++++++++------ 19 files changed, 195 insertions(+), 151 deletions(-) diff --git a/src/background2d.cpp b/src/background2d.cpp index 11713d602..a268dedc1 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -228,8 +228,8 @@ void Background2D::RenderBgEff(int bgId, int layer) { // Transform vertices const glm::mat4 transformation = - Transformation3D(glm::vec3(DisplayCoords, 0.0f), glm::vec3(Origin, 0.0f), - Rotation, glm::vec3(Scale, 1.0f)); + TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, + Rotation, {DisplayCoords, 0.0f}); std::transform(vertices.begin(), vertices.end(), vertices.begin(), [transformation](const glm::vec2 vertex) { return transformation * glm::vec4(vertex, 0.0f, 1.0f); @@ -254,15 +254,17 @@ void Background2D::RenderBgEff(int bgId, int layer) { } void Background2D::RenderRegular() { - glm::mat4 transformation = Transformation3D( - {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + const glm::mat4 transformation = + TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, + Rotation, {DisplayCoords, 0.0f}); Renderer->DrawSprite(BgSprite, transformation, Tint, false); for (int i = 0; i < MaxLinkedBgBuffers; i++) { if (Links[i].Direction != LD_Off && Links[i].LinkedBuffer != NULL) { - glm::mat4 transformation = - Transformation3D({Links[i].DisplayCoords, 0.0f}, {Origin, 0.0f}, - Rotation, {Scale, 1.0f}); + const glm::mat4 linkTransformation = + transformation * + glm::translate(glm::mat4(1.0f), {Links[i].DisplayCoords, 0.0f}); + Renderer->DrawSprite(Links[i].LinkedBuffer->BgSprite, transformation, Tint, false); } @@ -270,8 +272,9 @@ void Background2D::RenderRegular() { } void Background2D::RenderMasked() { - const glm::mat4 transformation = Transformation3D( - {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + const glm::mat4 transformation = + TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, + Rotation, {DisplayCoords, 0.0f}); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, false, @@ -279,8 +282,9 @@ void Background2D::RenderMasked() { } void Background2D::RenderMaskedInverted() { - const glm::mat4 transformation = Transformation3D( - {DisplayCoords, 0.0f}, {Origin, 0.0f}, Rotation, {Scale, 1.0f}); + const glm::mat4 transformation = + TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, + Rotation, {DisplayCoords, 0.0f}); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, true, false); diff --git a/src/character2d.cpp b/src/character2d.cpp index 06ebd7657..2dc791865 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -202,8 +202,8 @@ void Character2D::Render(int layer) { if (Status != LS_Loaded || !OnLayer(layer) || !Show) return; if (Profile::CharaIsMvl) { - const glm::mat4 transformation = Transformation2D( - {OffsetX, OffsetY}, {0.0f, 0.0f}, 0.0f, {ScaleX, ScaleY}); + const glm::mat4 transformation = TransformationMatrix( + {0.0f, 0.0f}, {ScaleX, ScaleY}, {0.0f, 0.0f}, 0.0f, {OffsetX, OffsetY}); Renderer->DrawCharacterMvl(CharaSprite, MvlVertices, std::span(MvlIndices.begin(), MvlIndicesCount), transformation, Tint); diff --git a/src/games/cclcc/delusiontrigger.cpp b/src/games/cclcc/delusiontrigger.cpp index c77c4dbbf..83264c51a 100644 --- a/src/games/cclcc/delusiontrigger.cpp +++ b/src/games/cclcc/delusiontrigger.cpp @@ -194,7 +194,7 @@ void DelusionTrigger::RenderStartTransition(float spinAngle, int spinAlpha) { const glm::vec2 topLeft = {-800, -109}; const glm::vec2 offset = {600, 557}; const glm::mat4 transformation = - Transformation2D(topLeft, offset, spinAngle, scale); + TransformationMatrix(offset, scale, offset, spinAngle, topLeft); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } @@ -203,7 +203,7 @@ void DelusionTrigger::RenderStartTransition(float spinAngle, int spinAlpha) { const glm::vec2 topLeft = {1696, -109}; const glm::vec2 offset = {424, 557}; const glm::mat4 transformation = - Transformation2D(topLeft, offset, spinAngle, scale); + TransformationMatrix(offset, scale, offset, spinAngle, topLeft); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } @@ -214,26 +214,28 @@ void DelusionTrigger::RenderStable(float spinAngle, int spinAlpha) { if (DelusionState == DS_Neutral) { if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - const glm::mat4 transformation = - Transformation2D({-800, -109}, {600, 557}, spinAngle); - Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {600, 557}) + .Translate({-800, -109}); + Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - const glm::mat4 transformation = - Transformation2D({1696, -109}, {424, 557}, spinAngle); - Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {424, 557}) + .Translate({1696, -109}); + Renderer->DrawSprite(NegativeDelusionSprite, dest, tint); } } else if (DelusionState == DS_Positive) { - const glm::mat4 transformation = - Transformation2D({448, -109}, {600, 557}, spinAngle, {1.8f, 1.8f}); + const glm::mat4 transformation = TransformationMatrix( + {600, 557}, {1.8f, 1.8f}, {600, 557}, spinAngle, {448, -109}); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } else if (DelusionState == DS_Negative) { - const glm::mat4 transformation = - Transformation2D({448, -109}, {424, 557}, spinAngle, {1.8f, 1.8f}); + const glm::mat4 transformation = TransformationMatrix( + {424, 557}, {1.8f, 1.8f}, {424, 557}, spinAngle, {448, -109}); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } @@ -247,15 +249,16 @@ void DelusionTrigger::RenderNeutralToPositiveTransition(float spinAngle, const glm::vec2 scale(1.8f - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - Transformation2D(topLeft, {600, 557}, spinAngle, scale); + TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, topLeft); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { const glm::vec2 center = { 2944 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; - const glm::mat4 negativeTransformation = - Transformation2D(center, {424, 557}, spinAngle); - Renderer->DrawSprite(NegativeDelusionSprite, negativeTransformation, tint); + const CornersQuad dest = NegativeDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {424, 557}) + .Translate(center); + Renderer->DrawSprite(NegativeDelusionSprite, dest, tint); } } @@ -268,15 +271,16 @@ void DelusionTrigger::RenderNeutralToNegativeTransition(float spinAngle, const glm::vec2 scale(1.8f - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - Transformation2D(topLeft, {424, 557}, spinAngle, scale); + TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, topLeft); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { const glm::vec2 topLeftPositive = { ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 2048, -109}; - const glm::mat4 transformationPositive = - Transformation2D(topLeftPositive, {600, 557}, spinAngle); - Renderer->DrawSprite(PositiveDelusionSprite, transformationPositive, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {600, 557}) + .Translate(topLeftPositive); + Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } } @@ -289,15 +293,16 @@ void DelusionTrigger::RenderPositiveToNeutralTransition(float spinAngle, const glm::vec2 scale(1.0f + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - Transformation2D(topLeft, {600, 557}, spinAngle, scale); + TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, topLeft); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { const glm::vec2 center = { ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 1696, -109}; - const glm::mat4 transformationNegative = - Transformation2D(center, {424, 557}, spinAngle); - Renderer->DrawSprite(NegativeDelusionSprite, transformationNegative, tint); + const CornersQuad dest = NegativeDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {424, 557}) + .Translate(center); + Renderer->DrawSprite(NegativeDelusionSprite, dest, tint); } } @@ -310,15 +315,16 @@ void DelusionTrigger::RenderNegativeToNeutralTransition(float spinAngle, const glm::vec2 scale(1.0f + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - Transformation2D(topLeft, {424, 557}, spinAngle, scale); + TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, topLeft); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { const glm::vec2 center = { -800 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; - const glm::mat4 transformationPositive = - Transformation2D(center, {600, 557}, spinAngle); - Renderer->DrawSprite(PositiveDelusionSprite, transformationPositive, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {600, 557}) + .Translate(center); + Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } } @@ -330,18 +336,20 @@ void DelusionTrigger::RenderEndNeutralTransition(float spinAngle, (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { const glm::vec2 topLeft = { ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5) - 2048, -109}; - const glm::mat4 transformation = - Transformation2D(topLeft, {600, 557}, spinAngle); - Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {600, 557}) + .Translate(topLeft); + Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { const glm::vec2 topLeft = { 2944 - ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5), -109}; - const glm::mat4 transformation = - Transformation2D(topLeft, {424, 557}, spinAngle); - Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); + const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() + .Rotate(spinAngle, {424, 557}) + .Translate(topLeft); + Renderer->DrawSprite(NegativeDelusionSprite, dest, tint); } } diff --git a/src/games/cclcc/mapsystem.cpp b/src/games/cclcc/mapsystem.cpp index ce44373af..9aedab7f3 100644 --- a/src/games/cclcc/mapsystem.cpp +++ b/src/games/cclcc/mapsystem.cpp @@ -1421,15 +1421,15 @@ void MapSystemCCLCC::MapDispPhoto(int id, int photoGroupId) { // Shadow const glm::vec2 shadowPos = {(xOffset + 82 + 3) * scaledFactor - 82, (yOffset + 10 + 3) * scaledFactor - 10}; - const glm::mat4 shadowTransformation = - Transformation2D(shadowPos, {82, 10}, angle, {shadowZoom, shadowZoom}); + const glm::mat4 shadowTransformation = TransformationMatrix( + {82, 10}, {shadowZoom, shadowZoom}, {82, 10}, angle, shadowPos); Renderer->DrawSprite(displayedSprite, shadowTransformation, {0.0f, 0.0f, 0.0f, (alpha / 2) / 256.0f}); // Photo const glm::mat4 photoTransformation = - Transformation2D({scaledPosOffsetX - 82, scaledPosOffsetY - 10}, - {82, 10}, angle, {zoomMulti, zoomMulti}); + TransformationMatrix({82, 10}, {zoomMulti, zoomMulti}, {82, 10}, angle, + {scaledPosOffsetX - 82, scaledPosOffsetY - 10}); Renderer->DrawSprite(displayedSprite, photoTransformation, {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } @@ -1499,23 +1499,24 @@ void MapSystemCCLCC::MapPoolDispPhoto(int poolId) { (MapPoolCurCt[poolId] * 50.0f / 16.0f + 78.0f) * 2; // HoverTag Tag - const glm::mat4 transformation = Transformation2D( - {scaledPosOffsetX - selectedTagXOffset, scaledPosOffsetY - 18}, - {selectedTagXOffset, 11}, angle, glm::vec2(zoomMulti / 2.0f)); + const glm::vec2 origin = {selectedTagXOffset, 11}; + const glm::mat4 transformation = TransformationMatrix( + origin, glm::vec2(zoomMulti / 2.0f), origin, angle, + {scaledPosOffsetX - selectedTagXOffset, scaledPosOffsetY - 18}); Renderer->DrawSprite(SelectedMapPoolTagSprite, transformation, {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } // Shadow const glm::mat4 shadowTransformation = - Transformation2D({(xOffset + 82 + 3) * scaledFactor - 82, - (yOffset + 10 + 3) * scaledFactor - 10}, - {82, 10}, angle, glm::vec2(shadowZoom)); + TransformationMatrix({82, 10}, glm::vec2(shadowZoom), {82, 10}, angle, + {(xOffset + 82 + 3) * scaledFactor - 82, + (yOffset + 10 + 3) * scaledFactor - 10}); Renderer->DrawSprite(displayedSprite, shadowTransformation, {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); // Photo const glm::mat4 photoTransformation = - Transformation2D({scaledPosOffsetX - 82, scaledPosOffsetY - 10}, - {82, 10}, angle, glm::vec2(zoomMulti)); + TransformationMatrix({82, 10}, glm::vec2(zoomMulti), {82, 10}, angle, + {scaledPosOffsetX - 82, scaledPosOffsetY - 10}); Renderer->DrawSprite(displayedSprite, photoTransformation, {1.0f, 1.0f, 1.0f, alpha / 256.0f}); if (!MapPool[poolId].button.Enabled) { @@ -1697,15 +1698,15 @@ void MapSystemCCLCC::MapDispArticle(int id) { float displayPhotoY = scaledPosOffsetY - 16; // Shadow - const glm::mat4 shadowTransformation = - Transformation2D({displayShadowPhotoX, displayShadowPhotoY}, {166, 16}, - angle, glm::vec2(shadowZoom * 0.5 * scaledFactor)); + const glm::mat4 shadowTransformation = TransformationMatrix( + {166, 16}, glm::vec2(shadowZoom * 0.5 * scaledFactor), {166, 16}, angle, + {displayShadowPhotoX, displayShadowPhotoY}); Renderer->DrawSprite(MapPartsArticleSprites[partId], shadowTransformation, {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); // Photo - const glm::mat4 photoTransformation = - Transformation2D({displayPhotoX, displayPhotoY}, {166, 16}, angle, - glm::vec2(zoomMulti * 0.5 * scaledFactor)); + const glm::mat4 photoTransformation = TransformationMatrix( + {166, 16}, glm::vec2(zoomMulti * 0.5 * scaledFactor), {166, 16}, angle, + {displayPhotoX, displayPhotoY}); Renderer->DrawSprite(MapPartsArticleSprites[partId], photoTransformation); } } @@ -1750,9 +1751,9 @@ void MapSystemCCLCC::MapDispTag(int id) { float shadowScaledPosOffsetX = (xOffset + 2.0f + 46.0f) * scaledFactor; float shadowScaledPosOffsetY = (yOffset + 2.0f + 16.0f) * scaledFactor; // Shadow - const glm::mat4 shadowTransformation = Transformation2D( - {shadowScaledPosOffsetX - 46.0f, shadowScaledPosOffsetY - 16.0f}, - {46, 16}, angle, glm::vec2(shadowZoom)); + const glm::mat4 shadowTransformation = TransformationMatrix( + {46, 16}, glm::vec2(shadowZoom), {46, 16}, angle, + {shadowScaledPosOffsetX - 46.0f, shadowScaledPosOffsetY - 16.0f}); Renderer->DrawSprite(displayedSprite, shadowTransformation, {0.0f, 0.0f, 0.0f, (alpha >> 1) / 256.0f}); @@ -1760,8 +1761,8 @@ void MapSystemCCLCC::MapDispTag(int id) { const glm::vec2 scaledPosOffset = glm::vec2(xOffset + 46.0f, yOffset + 16.0f) * scaledFactor; const glm::mat4 tagTransformation = - Transformation2D(scaledPosOffset - glm::vec2(46.0f, 16.0f), {46, 16}, - angle, {zoomMulti, zoomMulti}); + TransformationMatrix({46, 16}, {zoomMulti, zoomMulti}, {46, 16}, angle, + scaledPosOffset - glm::vec2(46.0f, 16.0f)); Renderer->DrawSprite(displayedSprite, tagTransformation, {1.0f, 1.0f, 1.0f, alpha / 256.0f}); } @@ -1829,12 +1830,11 @@ void MapSystemCCLCC::MapDispLine(int id, int partType) { RectF lineShadowRect(xPos * scaledFactor, yPosShadow * scaledFactor, lineWidth * scaledFactor, 10.0f * scaledFactor); Renderer->DrawSprite(shortenedLine, - lineShadowRect.Rotate(-angle, lineShadowRect.Center()), - shadowTint); + lineShadowRect.RotateAroundCenter(-angle), shadowTint); RectF lineRect(xPos * scaledFactor, yPos * scaledFactor, lineWidth * scaledFactor, 10.0f * scaledFactor); - Renderer->DrawSprite(shortenedLine, - lineRect.Rotate(-angle, lineRect.Center()), color); + Renderer->DrawSprite(shortenedLine, lineRect.RotateAroundCenter(-angle), + color); } } diff --git a/src/games/cclcc/yesnotrigger.cpp b/src/games/cclcc/yesnotrigger.cpp index bacde95e3..980e85d2e 100644 --- a/src/games/cclcc/yesnotrigger.cpp +++ b/src/games/cclcc/yesnotrigger.cpp @@ -298,10 +298,9 @@ void YesNoTrigger::Render() { float noChipWidthX = 0.5f * BgSpriteScale * ActiveNoChip->Bounds.Width; float noChipWidthY = 0.5f * BgSpriteScale * ActiveNoChip->Bounds.Height; if (Selection != YesNoSelect::NONE) { - const CornersQuad dest = - StarChip.ScaledBounds() - .Rotate(StarAngle / 65536.0f, StarChip.Center()) - .Translate(starPos); + const CornersQuad dest = StarChip.ScaledBounds() + .RotateAroundCenter(StarAngle / 65536.0f) + .Translate(starPos); Renderer->DrawSprite(StarChip, dest, chipTint); } Renderer->DrawSprite(*ActiveYesChip, diff --git a/src/games/chlcc/albummenu.cpp b/src/games/chlcc/albummenu.cpp index 2ef102096..1e925f2c6 100644 --- a/src/games/chlcc/albummenu.cpp +++ b/src/games/chlcc/albummenu.cpp @@ -124,10 +124,9 @@ void AlbumMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - AlbumMenuTitle.ScaledBounds() - .Rotate(AlbumMenuTitleAngle, AlbumMenuTitle.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = AlbumMenuTitle.ScaledBounds() + .RotateAroundCenter(AlbumMenuTitleAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(AlbumMenuTitle, titleDest); } diff --git a/src/games/chlcc/clearlistmenu.cpp b/src/games/chlcc/clearlistmenu.cpp index bb0e97bd5..1baaa23bc 100644 --- a/src/games/chlcc/clearlistmenu.cpp +++ b/src/games/chlcc/clearlistmenu.cpp @@ -76,10 +76,9 @@ void ClearListMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleText.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleText.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleText, titleDest); } diff --git a/src/games/chlcc/moviemenu.cpp b/src/games/chlcc/moviemenu.cpp index c8f7ade3f..d1c9422f6 100644 --- a/src/games/chlcc/moviemenu.cpp +++ b/src/games/chlcc/moviemenu.cpp @@ -136,10 +136,9 @@ void MovieMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleText.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleText.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleText, titleDest); Renderer->DrawSprite(MenuTitleText, LeftTitlePos); diff --git a/src/games/chlcc/musicmenu.cpp b/src/games/chlcc/musicmenu.cpp index 660214c3f..6b7e6c8ad 100644 --- a/src/games/chlcc/musicmenu.cpp +++ b/src/games/chlcc/musicmenu.cpp @@ -115,7 +115,7 @@ void MusicMenu::Render() { const CornersQuad titleDest = SoundLibraryTitle.ScaledBounds() - .Rotate(SoundLibraryTitleAngle, SoundLibraryTitle.Center()) + .RotateAroundCenter(SoundLibraryTitleAngle) .Translate(RightTitlePos); Renderer->DrawSprite(SoundLibraryTitle, titleDest); } diff --git a/src/games/chlcc/optionsmenu.cpp b/src/games/chlcc/optionsmenu.cpp index 0a7df4452..d629c2238 100644 --- a/src/games/chlcc/optionsmenu.cpp +++ b/src/games/chlcc/optionsmenu.cpp @@ -55,10 +55,9 @@ void OptionsMenu::Render() { if (FadeAnimation.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleText.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleText.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleText, titleDest); } diff --git a/src/games/chlcc/savemenu.cpp b/src/games/chlcc/savemenu.cpp index 9d0444f9f..923c913cd 100644 --- a/src/games/chlcc/savemenu.cpp +++ b/src/games/chlcc/savemenu.cpp @@ -368,10 +368,9 @@ void SaveMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleTextSprite.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleTextSprite.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleTextSprite.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleTextSprite, titleDest); } diff --git a/src/games/chlcc/tipsmenu.cpp b/src/games/chlcc/tipsmenu.cpp index cca9b2d71..ff880ad74 100644 --- a/src/games/chlcc/tipsmenu.cpp +++ b/src/games/chlcc/tipsmenu.cpp @@ -81,10 +81,9 @@ void TipsMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleText.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleText.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleText, titleDest); } diff --git a/src/games/chlcc/titlemenu.cpp b/src/games/chlcc/titlemenu.cpp index c36730cd7..40e7e5931 100644 --- a/src/games/chlcc/titlemenu.cpp +++ b/src/games/chlcc/titlemenu.cpp @@ -449,8 +449,8 @@ inline void TitleMenu::DrawTitleMenuBackGraphics() { const CornersQuad spinningCircleDest = SpinningCircleSprite.ScaledBounds() - .Rotate(-SpinningCircleAnimation.Progress * 2.0f * (float)M_PI, - SpinningCircleSprite.Center()) + .RotateAroundCenter(-SpinningCircleAnimation.Progress * 2.0f * + (float)M_PI) .Translate({SpinningCircleX, SpinningCircleY}); Renderer->DrawSprite(SpinningCircleSprite, spinningCircleDest); diff --git a/src/games/chlcc/trophymenu.cpp b/src/games/chlcc/trophymenu.cpp index f992c1712..6d58cf7fc 100644 --- a/src/games/chlcc/trophymenu.cpp +++ b/src/games/chlcc/trophymenu.cpp @@ -103,10 +103,9 @@ void TrophyMenu::Render() { if (MenuTransition.Progress > 0.34f) { Renderer->DrawSprite(RedBarLabel, RedTitleLabelPos); - const CornersQuad titleDest = - MenuTitleText.ScaledBounds() - .Rotate(MenuTitleTextAngle, MenuTitleText.Center()) - .Translate(RightTitlePos); + const CornersQuad titleDest = MenuTitleText.ScaledBounds() + .RotateAroundCenter(MenuTitleTextAngle) + .Translate(RightTitlePos); Renderer->DrawSprite(MenuTitleText, titleDest); Renderer->DrawSprite(MenuTitleText, LeftTitlePos); diff --git a/src/hud/autoicondisplay.cpp b/src/hud/autoicondisplay.cpp index 33297c342..4938d68d8 100644 --- a/src/hud/autoicondisplay.cpp +++ b/src/hud/autoicondisplay.cpp @@ -88,8 +88,7 @@ void Render(glm::vec4 opacityTint) { if (MesSkipMode & SkipModeFlags::Auto) { const CornersQuad arrowsDest = AutoSkipArrowsSprite.ScaledBounds() - .Rotate(Progress * 2.0f * (float)M_PI, - AutoSkipArrowsSprite.Center()) + .RotateAroundCenter(Progress * 2.0f * (float)M_PI) .Translate(AutoIconOffset); Renderer->DrawSprite(AutoSkipArrowsSprite, arrowsDest, opacityTint); diff --git a/src/hud/skipicondisplay.cpp b/src/hud/skipicondisplay.cpp index c45c2a4bc..5c79628de 100644 --- a/src/hud/skipicondisplay.cpp +++ b/src/hud/skipicondisplay.cpp @@ -90,8 +90,7 @@ void Render(glm::vec4 opacityTint) { if (MesSkipMode & (SkipModeFlags::SkipRead | SkipModeFlags::SkipAll)) { const CornersQuad arrowsDest = AutoSkipArrowsSprite.ScaledBounds() - .Rotate(Progress * 2.0f * (float)M_PI, - AutoSkipArrowsSprite.Center()) + .RotateAroundCenter(Progress * 2.0f * (float)M_PI) .Translate(SkipIconOffset); Renderer->DrawSprite(AutoSkipArrowsSprite, arrowsDest, opacityTint); diff --git a/src/hud/waiticondisplay.cpp b/src/hud/waiticondisplay.cpp index 038e2bc1f..8ac810b19 100644 --- a/src/hud/waiticondisplay.cpp +++ b/src/hud/waiticondisplay.cpp @@ -149,8 +149,7 @@ void Render(glm::vec2 pos, glm::vec4 opacityTint, DialoguePageMode mode) { const CornersQuad dest = WaitIconSprite.ScaledBounds() - .Rotate(SimpleAnim.Progress * 2.0f * (float)M_PI, - WaitIconSprite.Center()) + .RotateAroundCenter(SimpleAnim.Progress * 2.0f * (float)M_PI) .Translate(pos + WaitIconOffset); Renderer->DrawSprite(WaitIconSprite, dest, opacityTint); diff --git a/src/util.cpp b/src/util.cpp index 3003dba31..6f778e97e 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -129,6 +129,10 @@ CornersQuad RectF::Rotate(float angle, glm::vec2 origin) const { return CornersQuad(*this).Rotate(angle, origin); } +CornersQuad RectF::RotateAroundCenter(float angle) const { + return Rotate(angle, Center()); +} + CornersQuad RectF::Rotate(glm::quat rotation, glm::vec3 origin) const { return CornersQuad(*this).Rotate(rotation, origin); } @@ -140,6 +144,10 @@ CornersQuad RectF::Rotate(const glm::quat rotation, const glm::vec3 origin, stayInScreen); } +inline CornersQuad operator*(const glm::mat4 transformation, RectF rect) { + return rect.Transform(transformation); +} + glm::mat2 Rotate2D(float angle) { glm::mat2 result; float cosa = cosf(angle); @@ -151,43 +159,61 @@ glm::mat2 Rotate2D(float angle) { return result; } -glm::mat4 Transformation2D(const glm::vec2 translation, const glm::vec2 origin, - const float rotation, const glm::vec2 scaling) { - return Transformation3D({translation, 0.0f}, {origin, 0.0f}, - AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), - {scaling, 1.0f}); +glm::mat4 TransformationMatrix(const glm::vec2 scalingOrigin, + const glm::vec2 scaling, + const glm::vec2 rotationOrigin, + const float rotation, + const glm::vec2 translation) { + return TransformationMatrix( + {scalingOrigin, 0.0f}, {scaling, 1.0f}, {rotationOrigin, 0.0f}, + AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), {translation, 0.0f}); } -glm::mat4 Transformation3D(const glm::vec3 translation, const glm::vec3 origin, - const glm::quat rotation, const glm::vec3 scaling) { +glm::mat4 TransformationMatrix(const glm::vec3 scalingOrigin, + const glm::vec3 scaling, + const glm::vec3 rotationOrigin, + const glm::quat rotation, + const glm::vec3 translation) { glm::mat4 matrix(1.0f); - if (origin != glm::vec3(0.0f)) - matrix = glm::translate(glm::mat4(1.0f), -origin) * matrix; + if (scalingOrigin != glm::vec3(0.0f)) + matrix = glm::translate(glm::mat4(1.0f), -scalingOrigin) * matrix; - if (scaling != glm::vec3(0.0f)) + if (scaling != glm::vec3(1.0f)) matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; + if (scalingOrigin - rotationOrigin != glm::vec3(0.0f)) { + matrix = glm::translate(glm::mat4(1.0f), scalingOrigin - rotationOrigin) * + matrix; + } + if (rotation != glm::quat()) matrix = glm::mat4_cast(normalize(rotation)) * matrix; - if (origin + translation != glm::vec3(0.0f)) - matrix = glm::translate(glm::mat4(1.0f), origin + translation) * matrix; + if (rotationOrigin + translation != glm::vec3(0.0f)) { + matrix = + glm::translate(glm::mat4(1.0f), rotationOrigin + translation) * matrix; + } return matrix; } -glm::vec2 Transform2D(const glm::vec2 pos, const glm::vec2 translation, - const glm::vec2 origin, const float rotation, - const glm::vec2 scaling) { - return Transformation2D(translation, origin, rotation, scaling) * +glm::vec4 TransformVector(const glm::vec2 pos, const glm::vec2 scalingOrigin, + const glm::vec2 scaling, + const glm::vec2 rotationOrigin, const float rotation, + const glm::vec2 translation) { + return TransformationMatrix(scalingOrigin, scaling, rotationOrigin, rotation, + translation) * glm::vec4(pos, 0.0f, 1.0f); } -glm::vec3 Transform3D(const glm::vec3 pos, const glm::vec3 translation, - const glm::vec3 origin, const glm::quat rotation, - const glm::vec3 scaling) { - return Transformation3D(translation, origin, rotation, scaling) * +glm::vec4 TransformVector(const glm::vec3 pos, const glm::vec3 scalingOrigin, + const glm::vec3 scaling, + const glm::vec3 rotationOrigin, + const glm::quat rotation, + const glm::vec3 translation) { + return TransformationMatrix(scalingOrigin, scaling, rotationOrigin, rotation, + translation) * glm::vec4(pos, 1.0f); } diff --git a/src/util.h b/src/util.h index a179399e4..080adc4f6 100644 --- a/src/util.h +++ b/src/util.h @@ -51,22 +51,25 @@ concept is_any_of = std::disjunction_v...>; glm::mat2 Rotate2D(float angle); -glm::mat4 Transformation2D(glm::vec2 translation, - glm::vec2 origin = glm::vec2(0.0f), - float rotation = 0.0f, - glm::vec2 scaling = glm::vec2(1.0f)); -glm::mat4 Transformation3D(glm::vec3 translation, - glm::vec3 origin = glm::vec3(0.0f), - glm::quat rotation = glm::quat(), - glm::vec3 scaling = glm::vec3(1.0f)); - -glm::vec2 Transform2D(glm::vec2 pos, glm::vec2 translation, - glm::vec2 origin = glm::vec2(0.0f), float rotation = 0.0f, - glm::vec2 scaling = glm::vec2(1.0f)); -glm::vec3 Transform3D(glm::vec3 pos, glm::vec3 translation, - glm::vec3 origin = glm::vec3(0.0f), - glm::quat rotation = glm::quat(), - glm::vec2 scaling = glm::vec2(1.0f)); +glm::mat4 TransformationMatrix(glm::vec2 scalingOrigin, glm::vec2 scaling, + glm::vec2 rotationOrigin = glm::vec2(0.0f), + float rotation = 0.0f, + glm::vec2 translation = glm::vec2(0.0f)); +glm::mat4 TransformationMatrix(glm::vec3 scalingOrigin, glm::vec3 scaling, + glm::vec3 rotationOrigin = glm::vec3(0.0f), + glm::quat rotation = glm::quat(), + glm::vec3 translation = glm::vec3(0.0f)); + +glm::vec4 TransformVector(glm::vec2 pos, glm::vec2 scalingOrigin, + glm::vec2 scaling, + glm::vec2 rotationOrigin = glm::vec2(0.0f), + float rotation = 0.0f, + glm::vec2 translation = glm::vec2(0.0f)); +glm::vec4 TransformVector(glm::vec3 pos, glm::vec3 scalingOrigin, + glm::vec3 scaling, + glm::vec3 rotationOrigin = glm::vec3(0.0f), + glm::quat rotation = glm::quat(), + glm::vec3 translation = glm::vec3(0.0f)); struct Rect; struct CornersQuad; @@ -142,14 +145,21 @@ struct RectF { static RectF Coalesce(const RectF& first, const RectF& second); CornersQuad Transform(glm::mat4 transformation) const; + RectF& Translate(glm::vec2 offset) { return *this += offset; } + RectF& Translate(float dx, float dy) { return Translate({dx, dy}); } + RectF& Scale(glm::vec2 scaling, glm::vec2 origin); + CornersQuad Rotate(float angle, glm::vec2 origin) const; + CornersQuad RotateAroundCenter(float angle) const; CornersQuad Rotate(glm::quat rotation, glm::vec3 origin) const; CornersQuad Rotate(glm::quat rotation, glm::vec3 origin, float depth, glm::vec2 vanishingPoint, bool stayInScreen = false) const; }; +inline CornersQuad operator*(const glm::mat4 transformation, RectF rect); + struct Rect { int X = 0; int Y = 0; @@ -216,9 +226,16 @@ struct CornersQuad { } CornersQuad& Transform(glm::mat4 transformation); + CornersQuad& Translate(glm::vec2 offset); + CornersQuad& Translate(float dx, float dy) { return Translate({dx, dy}); } + CornersQuad& Scale(glm::vec2 scaling, glm::vec2 origin); + CornersQuad& Rotate(float angle, glm::vec2 origin); + CornersQuad& RotateAroundCenter(float angle) { + return Rotate(angle, Center()); + } CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin); CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin, float depth, glm::vec2 vanishingPoint, bool stayInScreen = false); From 53f8cdd35b6a251171a7887481ca15cdaa18b880 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 6 May 2025 23:25:10 +0200 Subject: [PATCH 46/88] Marked DesignToNDC as overridden --- src/renderer/dx9/renderer.h | 2 +- src/renderer/opengl/renderer.h | 2 +- src/renderer/vulkan/renderer.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 9fe3970e1..8041e4124 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -86,7 +86,7 @@ class Renderer : public BaseRenderer { void EnsureShader(Shader* shader, bool flush = true); void Flush() override; - glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + glm::vec2 DesignToNDC(glm::vec2 designCoord) const override; DirectX9Window* DXWindow; diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index f8d488852..03daa993b 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -104,7 +104,7 @@ class Renderer : public BaseRenderer { void EnsureModeSprite(bool inverted); void Flush() override; - glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + glm::vec2 DesignToNDC(glm::vec2 designCoord) const override; GLWindow* OpenGLWindow; diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 3cd979326..f5ddfa7b1 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -136,7 +136,7 @@ class Renderer : public BaseRenderer { void MakeQuad(); - glm::vec2 DesignToNDC(glm::vec2 designCoord) const; + glm::vec2 DesignToNDC(glm::vec2 designCoord) const override; bool Drawing = false; From f5d20bf80ef14fb07a0bbb6d346fbf96a4ed657b Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 7 May 2025 22:34:24 +0200 Subject: [PATCH 47/88] Abstracted DrawCharacterMvl into DrawVertices --- src/character2d.cpp | 31 ++++-- src/character2d.h | 8 +- src/games/cclcc/systemmenu.cpp | 106 +++++++++--------- src/games/cclcc/systemmenu.h | 8 +- src/renderer/dx9/renderer.cpp | 130 ++++------------------- src/renderer/dx9/renderer.h | 16 +-- src/renderer/opengl/renderer.cpp | 143 +++++++------------------ src/renderer/opengl/renderer.h | 16 +-- src/renderer/renderer.cpp | 143 ++++++++++++++++++------- src/renderer/renderer.h | 72 +++++++------ src/renderer/vulkan/renderer.cpp | 177 ++++--------------------------- src/renderer/vulkan/renderer.h | 16 +-- 12 files changed, 319 insertions(+), 547 deletions(-) diff --git a/src/character2d.cpp b/src/character2d.cpp index 2dc791865..33ddc749c 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -37,7 +37,7 @@ bool Character2D::LoadSync(uint32_t charaId) { // Skip to state data stream->Seek(0x68, SEEK_CUR); - MvlVerticesCount = Io::ReadLE(stream); + int vertexCount = Io::ReadLE(stream); int vertexOffset = Io::ReadLE(stream); for (int i = 0; i < stateCount; i++) { @@ -79,8 +79,18 @@ bool Character2D::LoadSync(uint32_t charaId) { // They seem to use the whole vertex array in all states, so... read it once // and forget about it? stream->Seek(vertexOffset, SEEK_SET); - MvlVertices.resize(MvlVerticesCount * 5); - Io::ReadArrayLE(MvlVertices.data(), stream, MvlVerticesCount * 5); + std::vector mvlVertexInfo(vertexCount * 5); + Io::ReadArrayLE(mvlVertexInfo.data(), stream, vertexCount * 5); + + MvlVertices.resize(vertexCount); + for (size_t i = 0; i < vertexCount; i++) { + MvlVertices[i] = VertexBufferSprites{ + .Position = {mvlVertexInfo[i * 5], mvlVertexInfo[i * 5 + 1]}, + .UV = glm::vec2(mvlVertexInfo[i * 5 + 3], mvlVertexInfo[i * 5 + 4]), + .Tint = Tint, + }; + } + delete stream; } else { // LAY format @@ -146,7 +156,7 @@ void Character2D::UnloadSync() { Show = false; std::fill(Layers.begin(), Layers.end(), -1); MvlVertices.clear(); - MvlIndicesCount = 0; + MvlIndices.clear(); States.clear(); StatesToDraw.clear(); } @@ -165,7 +175,7 @@ void Character2D::MainThreadOnLoad() { void Character2D::Update(float dt) { if (Profile::CharaIsMvl) { - MvlIndicesCount = 0; + MvlIndices.clear(); StatesToDraw.clear(); StatesToDraw.push_back((Face & 0xFFFF0000) >> 16); // face StatesToDraw.push_back(0x40000000 | ((Face & 0xFFFF0000) >> 8) | @@ -178,9 +188,9 @@ void Character2D::Update(float dt) { Character2DState const& state = stateItr->second; auto& stateIndices = std::get_if(&state.Data)->Indices; - std::copy(stateIndices.get(), stateIndices.get() + state.Count, - MvlIndices.begin() + MvlIndicesCount); - MvlIndicesCount += state.Count; + MvlIndices.reserve(MvlIndices.size() + state.Count); + MvlIndices.insert(MvlIndices.end(), stateIndices.get(), + stateIndices.get() + state.Count); } } } else { @@ -204,9 +214,8 @@ void Character2D::Render(int layer) { if (Profile::CharaIsMvl) { const glm::mat4 transformation = TransformationMatrix( {0.0f, 0.0f}, {ScaleX, ScaleY}, {0.0f, 0.0f}, 0.0f, {OffsetX, OffsetY}); - Renderer->DrawCharacterMvl(CharaSprite, MvlVertices, - std::span(MvlIndices.begin(), MvlIndicesCount), - transformation, Tint); + Renderer->DrawVertices(CharaSpriteSheet, MvlVertices, MvlIndices, + transformation); } else { for (auto id : StatesToDraw) { if (auto stateItr = States.find(id); stateItr != States.end()) { diff --git a/src/character2d.h b/src/character2d.h index 7b18fd599..42ebe3540 100644 --- a/src/character2d.h +++ b/src/character2d.h @@ -45,8 +45,6 @@ struct Character2DState { } }; -int constexpr MaxMvlIndices = 128 * 1024; - class Character2D : public Loadable { friend class Loadable; @@ -86,10 +84,8 @@ class Character2D : public Loadable { ankerl::unordered_dense::map States; std::vector StatesToDraw; - int MvlVerticesCount; - std::vector MvlVertices; - std::array MvlIndices; - int MvlIndicesCount; + std::vector MvlVertices; + std::vector MvlIndices; }; int constexpr MaxCharacters2D = 16; diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 04cd2c9a4..de998ebf1 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -154,7 +154,7 @@ void SystemMenu::Update(float dt) { } } -auto GenerateMatrix(CornersQuad const& corners, glm::vec2 offset) { +auto GenerateMatrix(CornersQuad const& corners) { auto get2DIndex = [](int x, int y) { return x + (GridColCount + 1) * y; }; constexpr int xVerticesCount = GridColCount + 1; constexpr int yVerticesCount = GridRowCount + 1; @@ -192,35 +192,55 @@ auto GenerateMatrix(CornersQuad const& corners, glm::vec2 offset) { std::array matrix; for (int row = 0; row < yVerticesCount; row++) { for (int col = 0; col < xVerticesCount; col++) { - glm::vec2 pos = {topRowX[col] + xDeltas[col] * row - offset.x, - leftColY[row] + yDeltas[row] * col - offset.y}; + glm::vec2 pos = {topRowX[col] + xDeltas[col] * row, + leftColY[row] + yDeltas[row] * col}; matrix[get2DIndex(col, row)] = pos; } } return matrix; } +glm::vec2 TransformImageVertex(const glm::vec2 vertex, const glm::quat rotation, + const float scale, const glm::vec2 origin) { + glm::mat4 transformation = + TransformationMatrix({origin, 0.0f}, {scale, scale, 1.0f}, {origin, 0.0f}, + rotation, {-origin, 0.0f}); + + glm::vec4 transformedVertex = {vertex, 0.0f, 1.0f}; + transformedVertex = transformation * transformedVertex; + const float perspective = (transformedVertex.z / 2000.0f) + 1.0f; + transformedVertex *= perspective; + transformedVertex += glm::vec4(origin, 0.0f, 0.0f); + + return transformedVertex; +} + +void TransformImageCorners(CornersQuad& corners, const glm::quat rotation, + const float scale, const glm::vec2 origin) { + corners.BottomLeft = + TransformImageVertex(corners.BottomLeft, rotation, scale, origin); + corners.BottomRight = + TransformImageVertex(corners.BottomRight, rotation, scale, origin); + corners.TopLeft = + TransformImageVertex(corners.TopLeft, rotation, scale, origin); + corners.TopRight = + TransformImageVertex(corners.TopRight, rotation, scale, origin); +} + void TransformImage(CornersQuad const& sprCorners, - CornersQuad const& destCorners, float angleX, float angleY, - float angleZ, float scale, glm::vec2 dispOffset, - SystemMenu::GridVertices& outSpriteVertices, - SystemMenu::GridVertices& outDisplayVertices) { - glm::mat4 modelMatrix{1.0f}; - - modelMatrix = glm::rotate(modelMatrix, angleZ, glm::vec3(0.0f, 0.0f, 1.0f)); - modelMatrix = glm::rotate(modelMatrix, angleX, glm::vec3(1.0f, 0.0f, 0.0f)); - modelMatrix = glm::rotate(modelMatrix, angleY, glm::vec3(0.0f, 1.0f, 0.0f)); - - outSpriteVertices = GenerateMatrix(sprCorners, {0, 0}); - outDisplayVertices = GenerateMatrix(destCorners, dispOffset); - for (auto& dispVertex : outDisplayVertices) { - glm::vec4 destPos{dispVertex, 0, 1}; - destPos *= scale; - destPos = modelMatrix * destPos; - const float perspective = (destPos.z / 2000.0f) + 1.0f; - dispVertex = destPos; - dispVertex *= perspective; - dispVertex += dispOffset; + CornersQuad const& destCorners, glm::quat rotation, + float scale, glm::vec2 origin, glm::vec2 sheetBounds, + SystemMenu::GridVertices& vertices) { + auto spriteVertices = GenerateMatrix(sprCorners); + auto displayVertices = GenerateMatrix(destCorners); + + for (size_t i = 0; i < vertices.size(); i++) { + vertices[i] = VertexBufferSprites{ + .Position = + TransformImageVertex(displayVertices[i], rotation, scale, origin), + .UV = spriteVertices[i] / sheetBounds, + .Tint = glm::vec4(1.0f), + }; } } @@ -241,15 +261,10 @@ void SystemMenu::Render() { const float scale = (1000.0f - (ScrWork[SW_SYSMENUCT] * 400 / 32)) / 1000.0f; - const float angleX = glm::pi() * - (ScrWork[SW_SYSMENUCT] * AngleMultiplier.x) / - (2 << 14); - const float angleY = glm::pi() * - (ScrWork[SW_SYSMENUCT] * AngleMultiplier.y) / - (2 << 14); - const float angleZ = glm::pi() * - (ScrWork[SW_SYSMENUCT] * AngleMultiplier.z) / - (2 << 14); + const glm::quat rotation = + ScrWorkAnglesToQuaternion((ScrWork[SW_SYSMENUCT] * AngleMultiplier.x), + (ScrWork[SW_SYSMENUCT] * AngleMultiplier.y), + (ScrWork[SW_SYSMENUCT] * AngleMultiplier.z)); CornersQuad bgDisp = { BGDispOffsetTopLeft, @@ -257,12 +272,9 @@ void SystemMenu::Render() { BGDispOffsetTopRight, BGDispOffsetBottomRight, }; - - TransformImage(bgSpriteBounds, bgDisp, angleX, angleY, angleZ, scale, - BGTranslationOffset, SpriteGridVertices, - DisplayGridVertices); - Renderer->DrawVertices(SystemMenuBG.Sheet, SpriteGridVertices, - DisplayGridVertices, 21, 11); + TransformImage(bgSpriteBounds, bgDisp, rotation, scale, BGTranslationOffset, + SystemMenuBG.Sheet.GetDimensions(), Vertices); + Renderer->DrawVertices(SystemMenuBG.Sheet, Vertices, 21, 11); if (!GetFlag(SF_SYSTEMMENUDIRECT)) { CornersQuad frameDisp = { @@ -271,12 +283,8 @@ void SystemMenu::Render() { glm::vec2{bgOffset, 0} + FrameOffsetTopRight, glm::vec2{bgOffset, 0} + FrameOffsetBottomRight, }; - - TransformImage(SystemMenuFrame.Bounds, frameDisp, angleX, angleY, angleZ, - scale, BGTranslationOffset, SpriteGridVertices, - DisplayGridVertices); - Renderer->DrawVertices(SystemMenuFrame.Sheet, SpriteGridVertices, - DisplayGridVertices, 21, 11); + TransformImageCorners(frameDisp, rotation, scale, BGTranslationOffset); + Renderer->DrawSprite(SystemMenuFrame, frameDisp); CornersQuad screenCapDisp = { glm::vec2{bgOffset + 0, 0}, @@ -284,12 +292,10 @@ void SystemMenu::Render() { glm::vec2{bgOffset + Profile::DesignWidth, 0}, glm::vec2{bgOffset + Profile::DesignWidth, Profile::DesignHeight}, }; - TransformImage(ScreenCap.Bounds, screenCapDisp, angleX, angleY, angleZ, - scale, BGTranslationOffset, SpriteGridVertices, - DisplayGridVertices); - Renderer->DrawVertices(ScreenCap.Sheet, SpriteGridVertices, - DisplayGridVertices, 21, 11, glm::vec4{1}, false, - true); + TransformImageCorners(screenCapDisp, rotation, scale, + BGTranslationOffset); + Renderer->DrawSprite(ScreenCap, screenCapDisp, glm::vec4(1.0f), false, + true); } Renderer->DrawSprite( SystemMenuMask, diff --git a/src/games/cclcc/systemmenu.h b/src/games/cclcc/systemmenu.h index 91e71daa9..c318d6bdd 100644 --- a/src/games/cclcc/systemmenu.h +++ b/src/games/cclcc/systemmenu.h @@ -13,8 +13,9 @@ namespace CCLCC { class SystemMenu : public Menu { public: using GridVertices = - std::array; + std::array; SystemMenu(); @@ -35,8 +36,7 @@ class SystemMenu : public Menu { bool ItemsFadeComplete = false; glm::vec2 BGPosition{}; - GridVertices SpriteGridVertices; - GridVertices DisplayGridVertices; + GridVertices Vertices; }; } // namespace CCLCC diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 8e1969fcc..7e4d92610 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -263,67 +263,9 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawCharacterMvl(const Sprite& sprite, - const std::span mvlVertices, - const std::span mvlIndices, - const glm::vec4 tint, const bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); - return; - } - - // Draw just the character with this since we need to rebind the index buffer - // anyway... - Flush(); - - // Are we in sprite mode? - if (inverted) - EnsureShader(ShaderSpriteInverted); - else - EnsureShader(ShaderSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - const size_t vertexCount = mvlVertices.size() / 5; - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - - IndexBufferFill += mvlIndices.size(); - - std::copy(mvlIndices.begin(), mvlIndices.end(), IndexBuffer); - - for (int i = 0; i < vertexCount; i++) { - vertices[i].Position = - DesignToNDC({mvlVertices[i * 5], mvlVertices[i * 5 + 1]}); - vertices[i].UV = {mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]}; - vertices[i].Tint = tint; - } - - Flush(); - - // ReFill index buffer with quads - int index = 0; - int vertex = 0; - while (index + 6 <= IndexBufferCount) { - // bottom-left -> top-left -> top-right - IndexBuffer[index] = vertex + 0; - IndexBuffer[index + 1] = vertex + 1; - IndexBuffer[index + 2] = vertex + 2; - // bottom-left -> top-right -> bottom-right - IndexBuffer[index + 3] = vertex + 0; - IndexBuffer[index + 4] = vertex + 2; - IndexBuffer[index + 5] = vertex + 3; - index += 6; - vertex += 4; - } -} - void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const std::span tints, - const bool inverted) { + const bool inverted, const bool disableBlend) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -469,74 +411,44 @@ void Renderer::DrawMaskedSpriteOverlay( for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, glm::vec4 tint, - bool inverted, bool disableBlend) { +void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::span vertices, + const std::span indices, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawSprite() called before BeginFrame()\n"); - return; - } - const int verticesCount = sheetPositions.size(); - if (verticesCount != displayPositions.size()) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawVertices() called with mismatched vertices count\n"); + "Renderer->DrawVertices() called before BeginFrame()\n"); return; } - EnsureSpaceAvailable(verticesCount, sizeof(VertexBufferSprites), - verticesCount * 3); - + // The index buffer needs to be flushed Flush(); - // Are we in sprite mode? if (inverted) EnsureShader(ShaderSpriteInverted); else EnsureShader(ShaderSprite); EnsureTextureBound(sheet.Texture); - Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_WRAP); - Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_WRAP); - VertexBufferSprites* vertices = + // Push vertices + VertexBufferSprites* vertexBuffer = (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + VertexBufferFill += vertices.size_bytes(); - IndexBufferFill = 0; - // Generate indices for triangles - for (int y = 0; y < height - 1; y++) { - for (int x = 0; x < width - 1; x++) { - uint16_t v0 = y * width + x; - uint16_t v1 = y * width + (x + 1); - uint16_t v2 = (y + 1) * width + x; - uint16_t v3 = (y + 1) * width + (x + 1); - - // First triangle - for (auto v : {v1, v0, v2}) { - IndexBuffer[IndexBufferFill++] = v; - } - // Second triangle - for (auto v : {v3, v1, v2}) { - IndexBuffer[IndexBufferFill++] = v; - } - } - } - assert(IndexBufferFill == (height - 1) * (width - 1) * 6); - - for (int i = 0; i < verticesCount; i++) { - vertices[i].Position = DesignToNDC(displayPositions[i]); - vertices[i].Tint = tint; - glm::vec2 uv = - sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); - vertices[i].UV = uv; - } + const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { + info.Position = DesignToNDC(info.Position); + return info; + }; + std::transform(vertices.begin(), vertices.end(), vertexBuffer, + vertexInfoToNDC); + // Push indices + IndexBufferFill += indices.size(); + std::copy(indices.begin(), indices.end(), IndexBuffer); + + // Flush again and bind back our buffer Flush(); - Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); - Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); // ReFill index buffer with quads int index = 0; diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 8041e4124..89d6f9e96 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -35,19 +35,17 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, - const bool inverted) override; + std::span tints, bool inverted, + bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, std::span tints, bool isInverted, bool isSameTexture); - void DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, int width, - int height, glm::vec4 tint = glm::vec4(1.0), - bool inverted = false, bool disableBlend = false) override; + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, bool inverted) override; void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, @@ -62,10 +60,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, - std::span indices, glm::vec4 tint, - bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 369824712..fb2dcbf47 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -264,57 +264,9 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)frame; } -void Renderer::DrawCharacterMvl(const Sprite& sprite, - const std::span mvlVertices, - const std::span mvlIndices, - const glm::vec4 tint, const bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); - return; - } - - // Draw just the character with this since we need to rebind the index buffer - // anyway... - Flush(); - - // Do we have space for the whole character? - const size_t vertexCount = mvlVertices.size() / 5; - EnsureSpaceAvailable(vertexCount, sizeof(VertexBufferSprites), - mvlIndices.size()); - - // Are we in sprite mode? - EnsureModeSprite(inverted); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - - IndexBufferFill += mvlIndices.size(); - - glBufferData(GL_ELEMENT_ARRAY_BUFFER, mvlIndices.size() * sizeof(uint16_t), - mvlIndices.data(), GL_STATIC_DRAW); - - for (int i = 0; i < vertexCount; i++) { - vertices[i].Position = - DesignToNDC({mvlVertices[i * 5], mvlVertices[i * 5 + 1]}); - vertices[i].UV = {mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]}; - vertices[i].Tint = tint; - } - - // Flush again and bind back our buffer - Flush(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, - GL_STATIC_DRAW); -} - void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const std::span tints, - const bool inverted) { + const bool inverted, const bool disableBlend) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -334,6 +286,11 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, // Do we have the texture assigned? EnsureTextureBound(sprite.Sheet.Texture); + if (disableBlend) { + Flush(); + glDisable(GL_BLEND); + } + // OK, all good, make quad VertexBufferSprites* vertices = @@ -352,6 +309,11 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; + + if (disableBlend) { + Flush(); + glEnable(GL_BLEND); + } } void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, @@ -486,84 +448,51 @@ void Renderer::DrawMaskedSpriteOverlay( for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, glm::vec4 tint, - bool inverted, bool disableBlend) { +void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::span vertices, + const std::span indices, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVertices() called before BeginFrame()\n"); return; } - if (disableBlend) { - glDisable(GL_BLEND); - } + // The index buffer needs to be flushed + Flush(); - const int verticesCount = sheetPositions.size(); + EnsureSpaceAvailable(vertices.size(), sizeof(VertexBufferSprites), + indices.size()); + + EnsureModeSprite(inverted); + EnsureTextureBound(sheet.Texture); - if (verticesCount != displayPositions.size()) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawVertices() called with mismatched vertices count\n"); - return; - } - Flush(); glBindSampler(2, Sampler); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); - EnsureSpaceAvailable(verticesCount, sizeof(VertexBufferSprites), - verticesCount * 3); - EnsureModeSprite(inverted); - - EnsureTextureBound(sheet.Texture); - VertexBufferSprites* vertices = + // Push vertices + VertexBufferSprites* vertexBuffer = (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); - std::vector indices; - indices.reserve((width - 1) * (height - 1) * 6); - // Generate indices for triangles - for (int y = 0; y < height - 1; y++) { - for (int x = 0; x < width - 1; x++) { - int v0 = y * width + x; - int v1 = y * width + (x + 1); - int v2 = (y + 1) * width + x; - int v3 = (y + 1) * width + (x + 1); - - // First triangle - for (auto v : {v1, v0, v2}) { - indices.push_back(v); - } - // Second triangle - for (auto v : {v3, v1, v2}) { - indices.push_back(v); - } - } - } - IndexBufferFill += indices.size(); + VertexBufferFill += vertices.size_bytes(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferFill * sizeof(uint16_t), - indices.data(), GL_STATIC_DRAW); + const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { + info.Position = DesignToNDC(info.Position); + if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; + return info; + }; + std::transform(vertices.begin(), vertices.end(), vertexBuffer, + vertexInfoToNDC); - for (int i = 0; i < verticesCount; i++) { - vertices[i].Position = DesignToNDC(displayPositions[i]); - vertices[i].Tint = tint; - glm::vec2 uv = - sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); - if (sheet.IsScreenCap) { - uv.y = 1.0f - uv.y; - } - vertices[i].UV = uv; - } + // Push indices + IndexBufferFill += indices.size(); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size_bytes(), indices.data(), + GL_STATIC_DRAW); // Flush again and bind back our buffer Flush(); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - if (disableBlend) { - glEnable(GL_BLEND); - } glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, GL_STATIC_DRAW); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 03daa993b..8b3016e00 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -46,14 +46,12 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, - const bool inverted) override; + std::span tints, bool inverted, + bool disableBlend) override; - void DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, int width, - int height, glm::vec4 tint = glm::vec4(1.0), - bool inverted = false, bool disableBlend = false) override; + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, bool inverted) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, @@ -73,10 +71,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, - std::span indices, glm::vec4 tint, - bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 66b0bd59f..98a9abdcb 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -42,15 +42,17 @@ void InitRenderer() { void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::mat4 transformation, - const glm::vec4 tint, const bool inverted) { + const glm::vec4 tint, const bool inverted, + const bool disableBlend) { const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); - DrawSprite(sprite, dest, tint, inverted); + DrawSprite(sprite, dest, tint, inverted, disableBlend); } void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, - const glm::vec4 tint, const bool inverted) { + const glm::vec4 tint, const bool inverted, + const bool disableBlend) { const CornersQuad dest = sprite.ScaledBounds().Translate(topLeft); - DrawSprite(sprite, dest, tint, inverted); + DrawSprite(sprite, dest, tint, inverted, disableBlend); } void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, @@ -91,6 +93,104 @@ void BaseRenderer::DrawMaskedSpriteOverlay( isInverted, useMaskAlpha); } +void BaseRenderer::DrawVertices( + const SpriteSheet& sheet, + const std::span vertices, + const std::span indices, const glm::mat4 transformation, + const bool inverted) { + std::vector transformedVertices; + transformedVertices.resize(vertices.size()); + + const auto transform = [transformation](VertexBufferSprites info) { + info.Position = transformation * glm::vec4(info.Position, 0.0f, 1.0f); + return info; + }; + std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), + transform); + + DrawVertices(sheet, transformedVertices, indices, inverted); +} + +void BaseRenderer::DrawVertices( + const SpriteSheet& sheet, + const std::span vertices, + const std::span indices, const glm::vec2 offset, + const bool inverted) { + std::vector transformedVertices; + transformedVertices.resize(vertices.size()); + + const auto transform = [offset](VertexBufferSprites info) { + info.Position += offset; + return info; + }; + std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), + transform); + + DrawVertices(sheet, transformedVertices, indices, inverted); +} + +void BaseRenderer::DrawVertices( + const SpriteSheet& sheet, + const std::span vertices, const int width, + const int height, const bool inverted) { + // Generate indices for triangles + std::vector indices; + indices.reserve((width - 1) * (height - 1) * 6); + for (int y = 0; y < height - 1; y++) { + for (int x = 0; x < width - 1; x++) { + int v0 = y * width + x; + int v1 = y * width + (x + 1); + int v2 = (y + 1) * width + x; + int v3 = (y + 1) * width + (x + 1); + + // First triangle + for (auto v : {v1, v0, v2}) { + indices.push_back(v); + } + // Second triangle + for (auto v : {v3, v1, v2}) { + indices.push_back(v); + } + } + } + + DrawVertices(sheet, vertices, indices, inverted); +} + +void BaseRenderer::DrawVertices( + const SpriteSheet& sheet, + const std::span vertices, const int width, + const int height, const glm::mat4 transformation, const bool inverted) { + std::vector transformedVertices; + transformedVertices.resize(vertices.size()); + + const auto transform = [transformation](VertexBufferSprites info) { + info.Position = transformation * glm::vec4(info.Position, 0.0f, 1.0f); + return info; + }; + std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), + transform); + + DrawVertices(sheet, transformedVertices, width, height, inverted); +} + +void BaseRenderer::DrawVertices( + const SpriteSheet& sheet, + const std::span vertices, const int width, + const int height, const glm::vec2 offset, const bool inverted) { + std::vector transformedVertices; + transformedVertices.resize(vertices.size()); + + const auto transform = [offset](VertexBufferSprites info) { + info.Position += offset; + return info; + }; + std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), + transform); + + DrawVertices(sheet, transformedVertices, width, height, inverted); +} + void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, @@ -141,41 +241,6 @@ void BaseRenderer::DrawProcessedText(std::span text, } } -void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, - const std::span vertices, - const std::span indices, - glm::mat4 transformation, glm::vec4 tint, - bool inverted) { - std::vector transformedVertices(vertices.begin(), vertices.end()); - - const size_t vertexCount = vertices.size() / 5; - for (size_t i = 0; i < vertexCount; i++) { - const glm::vec2 pos = - transformation * - glm::vec4(vertices[i * 5], vertices[i * 5 + 1], 0.0f, 1.0f); - transformedVertices[i * 5] = pos.x; - transformedVertices[i * 5 + 1] = pos.y; - } - - DrawCharacterMvl(sprite, transformedVertices, indices, tint, inverted); -} - -void BaseRenderer::DrawCharacterMvl(const Sprite& sprite, - std::span vertices, - std::span indices, - const glm::vec2 offset, - const glm::vec4 tint, const bool inverted) { - std::vector transformedVertices(vertices.begin(), vertices.end()); - - const size_t vertexCount = vertices.size() / 5; - for (size_t i = 0; i < vertexCount; i++) { - transformedVertices[i * 5] += offset.x; - transformedVertices[i * 5 + 1] += offset.y; - } - - DrawCharacterMvl(sprite, transformedVertices, indices, tint, inverted); -} - void BaseRenderer::DrawProcessedText_BasicFont( std::span text, BasicFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 1deb022b5..89f555945 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -17,6 +17,13 @@ enum class RendererOutlineMode { None, BottomRight, Full }; constexpr inline int MaxFramebuffers = 10; +struct VertexBufferSprites { + glm::vec2 Position; + glm::vec2 UV; + glm::vec4 Tint; + glm::vec2 MaskUV; +}; + class BaseRenderer { public: virtual void Init() = 0; @@ -46,16 +53,19 @@ class BaseRenderer { virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, std::span tints, - bool inverted = false) = 0; + bool inverted = false, bool disableBlend = false) = 0; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - glm::vec4 tint = glm::vec4(1.0f), bool inverted = false) { + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, + bool disableBlend = false) { DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, - inverted); + inverted, disableBlend); } void DrawSprite(const Sprite& sprite, glm::mat4 transformation, - glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, + bool disableBlend = false); void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, - glm::vec4 tint = glm::vec4(1.0f), bool inverted = false); + glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, + bool disableBlend = false); virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, @@ -107,13 +117,29 @@ class BaseRenderer { bool isInverted = false, bool useMaskAlpha = true); - virtual void DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, - glm::vec4 tint = glm::vec4(1.0), - bool inverted = false, - bool disableBlend = false) = 0; + virtual void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, + bool inverted = false) = 0; + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, glm::mat4 transformation, + bool inverted = false); + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, glm::vec2 offset, + bool inverted = false); + + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, int width, + int height, bool inverted = false); + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, int width, + int height, glm::mat4 transformation, + bool inverted = false); + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, int width, + int height, glm::vec2 offset, bool inverted = false); void DrawQuad(const CornersQuad& dest, glm::vec4 color); @@ -152,21 +178,6 @@ class BaseRenderer { RendererOutlineMode outlineMode = RendererOutlineMode::None, bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = 0); - virtual void DrawCharacterMvl(const Sprite& sprite, - std::span vertices, - std::span indices, - glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false) = 0; - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, - std::span indices, - glm::mat4 transformation, - glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false); - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, - std::span indices, glm::vec2 offset, - glm::vec4 tint = glm::vec4(1.0f), - bool inverted = false); - virtual void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo = false) = 0; @@ -186,13 +197,6 @@ class BaseRenderer { protected: virtual void Flush() = 0; - struct VertexBufferSprites { - glm::vec2 Position; - glm::vec2 UV; - glm::vec4 Tint; - glm::vec2 MaskUV; - }; - static void QuadSetUV(CornersQuad spriteBounds, glm::vec2 designDimensions, glm::vec2* uvs, size_t stride); diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 331b2e4d2..9af587917 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -18,7 +18,7 @@ namespace Vulkan { VkVertexInputBindingDescription Renderer::GetBindingDescription() { VkVertexInputBindingDescription bindingDescription{}; bindingDescription.binding = 0; - bindingDescription.stride = sizeof(Renderer::VertexBufferSprites); + bindingDescription.stride = sizeof(VertexBufferSprites); bindingDescription.inputRate = VK_VERTEX_INPUT_RATE_VERTEX; return bindingDescription; @@ -1132,86 +1132,9 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)VideoFrameInternal; } -void Renderer::DrawCharacterMvl(const Sprite& sprite, - const std::span mvlVertices, - const std::span mvlIndices, - const glm::vec4 tint, const bool inverted) { - if (!Drawing) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawCharacterMvl() called before BeginFrame()\n"); - return; - } - - if (Textures.count(sprite.Sheet.Texture) == 0) return; - - // Draw just the character with this since we need to rebind the index buffer - // anyway... - Flush(); - - // Are we in sprite mode? - if (inverted) - EnsureMode(PipelineSpriteInverted); - else - EnsureMode(PipelineSprite); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - - const size_t vertexCount = mvlVertices.size() / 5; - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + - VertexBufferFill); - VertexBufferFill += vertexCount * sizeof(VertexBufferSprites); - - IndexBufferFill += mvlIndices.size(); - - int indexBufferOffset = IndexBufferOffset / sizeof(uint16_t); - std::copy(mvlIndices.begin(), mvlIndices.end(), - IndexBuffer + indexBufferOffset); - - for (int i = 0; i < vertexCount; i += 4) { - glm::vec2 bottomLeftV = - glm::vec2(mvlVertices[i * 5], mvlVertices[i * 5 + 1]); - glm::vec2 topLeftV = - glm::vec2(mvlVertices[(i + 1) * 5], mvlVertices[(i + 1) * 5 + 1]); - glm::vec2 topRightV = - glm::vec2(mvlVertices[(i + 2) * 5], mvlVertices[(i + 2) * 5 + 1]); - glm::vec2 bottomRightV = - glm::vec2(mvlVertices[(i + 3) * 5], mvlVertices[(i + 3) * 5 + 1]); - - glm::vec2 bottomLeftUV = - glm::vec2(mvlVertices[i * 5 + 3], mvlVertices[i * 5 + 4]); - glm::vec2 topLeftUV = - glm::vec2(mvlVertices[(i + 1) * 5 + 3], mvlVertices[(i + 1) * 5 + 4]); - glm::vec2 topRightUV = - glm::vec2(mvlVertices[(i + 2) * 5 + 3], mvlVertices[(i + 2) * 5 + 4]); - glm::vec2 bottomRightUV = - glm::vec2(mvlVertices[(i + 3) * 5 + 3], mvlVertices[(i + 3) * 5 + 4]); - - // top-left - vertices[i].Position = DesignToNDC(topLeftV); - vertices[i].UV = topLeftUV; - vertices[i].Tint = tint; - // bottom-left - vertices[i + 1].Position = DesignToNDC(bottomLeftV); - vertices[i + 1].UV = bottomLeftUV; - vertices[i + 1].Tint = tint; - // bottom-right - vertices[i + 2].Position = DesignToNDC(bottomRightV); - vertices[i + 2].UV = bottomRightUV; - vertices[i + 2].Tint = tint; - // top-right - vertices[i + 3].Position = DesignToNDC(topRightV); - vertices[i + 3].UV = topRightUV; - vertices[i + 3].Tint = tint; - } - - Flush(); -} - void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const std::span tints, - const bool inverted) { + const bool inverted, const bool disableBlend) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -1224,6 +1147,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, // Are we in sprite mode? if (inverted) EnsureMode(PipelineSpriteInverted); + else if (disableBlend) + EnsureMode(PipelineSpriteNoBlending); else EnsureMode(PipelineSprite); @@ -1419,11 +1344,10 @@ void Renderer::DrawMaskedSpriteOverlay( for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, - int width, int height, glm::vec4 tint, - bool inverted, bool disableBlend) { +void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::span vertices, + const std::span indices, + const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVertices() called before BeginFrame()\n"); @@ -1431,91 +1355,36 @@ void Renderer::DrawVertices(SpriteSheet const& sheet, } if (Textures.count(sheet.Texture) == 0) return; - const int verticesCount = sheetPositions.size(); - - if (verticesCount != displayPositions.size()) { - ImpLog(LogLevel::Error, LogChannel::Render, - "Renderer->DrawVertices() called with mismatched vertices count\n"); - return; - } + // The index buffer needs to be flushed Flush(); - VkSamplerCreateInfo samplerInfo = {}; - samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; - samplerInfo.pNext = nullptr; - samplerInfo.magFilter = VK_FILTER_LINEAR; - samplerInfo.minFilter = VK_FILTER_LINEAR; - samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; - samplerInfo.anisotropyEnable = VK_TRUE; - samplerInfo.maxAnisotropy = 16; - - VkDescriptorImageInfo imageBufferInfo[2]; - imageBufferInfo[0].sampler = Sampler; - imageBufferInfo[0].imageView = Textures[sheet.Texture].ImageView; - imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - vkCreateSampler(Device, &samplerInfo, nullptr, &imageBufferInfo[1].sampler); - imageBufferInfo[1].imageView = Textures[sheet.Texture].ImageView; - imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; - - VkWriteDescriptorSet writeDescriptorSet{}; - writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; - writeDescriptorSet.dstSet = 0; - writeDescriptorSet.dstBinding = 0; - writeDescriptorSet.descriptorCount = 2; - writeDescriptorSet.descriptorType = VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; - writeDescriptorSet.pImageInfo = imageBufferInfo; - - // Are we in sprite mode? if (inverted) EnsureMode(PipelineSpriteInverted); - else if (disableBlend) - EnsureMode(PipelineSpriteNoBlending); else EnsureMode(PipelineSprite); - vkCmdPushDescriptorSetKHR( - CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, - CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); + EnsureTextureBound(sheet.Texture); - VertexBufferSprites* vertices = + // Push vertices + VertexBufferSprites* vertexBuffer = (VertexBufferSprites*)(VertexBuffer + VertexBufferOffset + VertexBufferFill); + VertexBufferFill += vertices.size_bytes(); - VertexBufferFill += verticesCount * sizeof(VertexBufferSprites); + const auto vertexInfoToNDC = [this](VertexBufferSprites info) { + info.Position = DesignToNDC(info.Position); + return info; + }; + std::transform(vertices.begin(), vertices.end(), vertexBuffer, + vertexInfoToNDC); + // Push indices + IndexBufferFill += indices.size(); int indexBufferOffset = IndexBufferOffset / sizeof(uint16_t); + std::copy(indices.begin(), indices.end(), IndexBuffer + indexBufferOffset); - // Generate indices for triangles - for (int y = 0; y < height - 1; y++) { - for (int x = 0; x < width - 1; x++) { - uint16_t v0 = y * width + x; - uint16_t v1 = y * width + (x + 1); - uint16_t v2 = (y + 1) * width + x; - uint16_t v3 = (y + 1) * width + (x + 1); - - // First triangle - for (auto v : {v1, v0, v2}) { - IndexBuffer[indexBufferOffset + IndexBufferFill++] = v; - } - // Second triangle - for (auto v : {v3, v1, v2}) { - IndexBuffer[indexBufferOffset + IndexBufferFill++] = v; - } - } - } - assert(IndexBufferFill == (width - 1) * (height - 1) * 6); - - for (int i = 0; i < verticesCount; i++) { - vertices[i].Position = DesignToNDC(displayPositions[i]); - vertices[i].Tint = tint; - glm::vec2 uv = - sheetPositions[i] / glm::vec2(sheet.DesignWidth, sheet.DesignHeight); - vertices[i].UV = uv; - } + // Flush again and bind back our buffer Flush(); } diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index f5ddfa7b1..546b4f217 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -63,19 +63,17 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, - const bool inverted) override; + std::span tints, bool inverted, + bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, int alpha, int fadeRange, std::span tints, bool isInverted, bool isSameTexture) override; - void DrawVertices(SpriteSheet const& sheet, - std::span sheetPositions, - std::span displayPositions, int width, - int height, glm::vec4 tint = glm::vec4(1.0), - bool inverted = false, bool disableBlend = false) override; + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, bool inverted) override; void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, @@ -90,10 +88,6 @@ class Renderer : public BaseRenderer { void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; - void DrawCharacterMvl(const Sprite& sprite, std::span vertices, - std::span indices, glm::vec4 tint, - bool inverted) override; - void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo) override; From 420d1ae782aa135ea9875ea30f03aec21efe3d98 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 8 May 2025 00:13:44 +0200 Subject: [PATCH 48/88] Added scaling around center overloads --- src/util.h | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/util.h b/src/util.h index 080adc4f6..2f2331d86 100644 --- a/src/util.h +++ b/src/util.h @@ -150,6 +150,9 @@ struct RectF { RectF& Translate(float dx, float dy) { return Translate({dx, dy}); } RectF& Scale(glm::vec2 scaling, glm::vec2 origin); + RectF& ScaleAroundCenter(glm::vec2 scaling, glm::vec2 origin) { + return Scale(scaling, Center()); + } CornersQuad Rotate(float angle, glm::vec2 origin) const; CornersQuad RotateAroundCenter(float angle) const; @@ -231,6 +234,9 @@ struct CornersQuad { CornersQuad& Translate(float dx, float dy) { return Translate({dx, dy}); } CornersQuad& Scale(glm::vec2 scaling, glm::vec2 origin); + CornersQuad& ScaleAroundCenter(glm::vec2 scaling, glm::vec2 origin) { + return Scale(scaling, Center()); + } CornersQuad& Rotate(float angle, glm::vec2 origin); CornersQuad& RotateAroundCenter(float angle) { From 19366ba8f0fc8e786c6e6d6e3e4985decdbaaca8 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:17:25 +0200 Subject: [PATCH 49/88] Removed superfluous vector reserve --- src/character2d.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/src/character2d.cpp b/src/character2d.cpp index 33ddc749c..5acbcf621 100644 --- a/src/character2d.cpp +++ b/src/character2d.cpp @@ -188,7 +188,6 @@ void Character2D::Update(float dt) { Character2DState const& state = stateItr->second; auto& stateIndices = std::get_if(&state.Data)->Indices; - MvlIndices.reserve(MvlIndices.size() + state.Count); MvlIndices.insert(MvlIndices.end(), stateIndices.get(), stateIndices.get() + state.Count); } From 8c597c506ee8ea7ca01f436782c2cda7c65df910 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:20:46 +0200 Subject: [PATCH 50/88] Renamed cclcc delusion trigger topleft and offset to offset and origin --- src/games/cclcc/delusiontrigger.cpp | 40 ++++++++++++++--------------- 1 file changed, 20 insertions(+), 20 deletions(-) diff --git a/src/games/cclcc/delusiontrigger.cpp b/src/games/cclcc/delusiontrigger.cpp index 83264c51a..2bfcd522e 100644 --- a/src/games/cclcc/delusiontrigger.cpp +++ b/src/games/cclcc/delusiontrigger.cpp @@ -191,19 +191,19 @@ void DelusionTrigger::RenderStartTransition(float spinAngle, int spinAlpha) { if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - const glm::vec2 topLeft = {-800, -109}; - const glm::vec2 offset = {600, 557}; + const glm::vec2 offset = {-800, -109}; + const glm::vec2 origin = {600, 557}; const glm::mat4 transformation = - TransformationMatrix(offset, scale, offset, spinAngle, topLeft); + TransformationMatrix(origin, scale, origin, spinAngle, offset); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); } if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - const glm::vec2 topLeft = {1696, -109}; - const glm::vec2 offset = {424, 557}; + const glm::vec2 offset = {1696, -109}; + const glm::vec2 origin = {424, 557}; const glm::mat4 transformation = - TransformationMatrix(offset, scale, offset, spinAngle, topLeft); + TransformationMatrix(origin, scale, origin, spinAngle, offset); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); } } @@ -244,12 +244,12 @@ void DelusionTrigger::RenderNeutralToPositiveTransition(float spinAngle, int spinAlpha) { const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; - const glm::vec2 topLeft = { + const glm::vec2 offset = { 448 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; const glm::vec2 scale(1.8f - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, topLeft); + TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, offset); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { @@ -266,20 +266,20 @@ void DelusionTrigger::RenderNeutralToNegativeTransition(float spinAngle, int spinAlpha) { const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; - const glm::vec2 topLeft = { + const glm::vec2 offset = { ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) + 448, -109}; const glm::vec2 scale(1.8f - ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, topLeft); + TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, offset); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { - const glm::vec2 topLeftPositive = { + const glm::vec2 offsetPositive = { ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 2048, -109}; const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() .Rotate(spinAngle, {600, 557}) - .Translate(topLeftPositive); + .Translate(offsetPositive); Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } } @@ -288,12 +288,12 @@ void DelusionTrigger::RenderPositiveToNeutralTransition(float spinAngle, int spinAlpha) { const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; - const glm::vec2 topLeft = { + const glm::vec2 offset = { ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6) - 800, -109}; const glm::vec2 scale(1.0f + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, topLeft); + TransformationMatrix({600, 557}, scale, {600, 557}, spinAngle, offset); Renderer->DrawSprite(PositiveDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { @@ -310,12 +310,12 @@ void DelusionTrigger::RenderNegativeToNeutralTransition(float spinAngle, int spinAlpha) { const glm::vec4 tint = {1.0f, 1.0f, 1.0f, spinAlpha / 256.0f}; - const glm::vec2 topLeft = { + const glm::vec2 offset = { 1696 - ((ScrWork[SW_DELUSION_SPIN_COUNTER] * 1248) >> 6), -109}; const glm::vec2 scale(1.0f + ScrWork[SW_DELUSION_SPIN_COUNTER] * 0.8f / 64.0f); const glm::mat4 transformation = - TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, topLeft); + TransformationMatrix({424, 557}, scale, {424, 557}, spinAngle, offset); Renderer->DrawSprite(NegativeDelusionSprite, transformation, tint); if (ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) { @@ -334,21 +334,21 @@ void DelusionTrigger::RenderEndNeutralTransition(float spinAngle, if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_PosOnly)) { - const glm::vec2 topLeft = { + const glm::vec2 offset = { ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5) - 2048, -109}; const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() .Rotate(spinAngle, {600, 557}) - .Translate(topLeft); + .Translate(offset); Renderer->DrawSprite(PositiveDelusionSprite, dest, tint); } if ((ScrWork[SW_DELUSION_LIMIT] == Delusion_Both) || (ScrWork[SW_DELUSION_LIMIT] == Delusion_NegOnly)) { - const glm::vec2 topLeft = { + const glm::vec2 offset = { 2944 - ((ScrWork[SW_DELUSION_BG_COUNTER] * 1248) >> 5), -109}; const CornersQuad dest = PositiveDelusionSprite.ScaledBounds() .Rotate(spinAngle, {424, 557}) - .Translate(topLeft); + .Translate(offset); Renderer->DrawSprite(NegativeDelusionSprite, dest, tint); } } From e0c2fff8058a2f89558296e6ef2c282f029be31c Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:26:45 +0200 Subject: [PATCH 51/88] Explicitly emptied out unused floats in DX9 shader constant array --- src/renderer/dx9/renderer.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 7e4d92610..21f1585b4 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -320,7 +320,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - std::array alphaRes = {alphaRange, constAlpha}; + std::array alphaRes = {alphaRange, constAlpha, 0.0f, 0.0f}; const BOOL isInvertedB = (BOOL)isInverted; const BOOL isSameTextureB = (BOOL)isSameTexture; @@ -373,7 +373,7 @@ void Renderer::DrawMaskedSpriteOverlay( // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - std::array alphaRes = {alphaRange, constAlpha}; + std::array alphaRes = {alphaRange, constAlpha, 0.0f, 0.0f}; BOOL isInvertedB = (BOOL)isInverted; BOOL isSameTextureB = (BOOL) false; BOOL useMaskAlphaB = (BOOL)useMaskAlpha; From edf1dd34dce29b85cbad2618fba71a15bdb3bcf6 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:32:39 +0200 Subject: [PATCH 52/88] Re-added flush to DX9 and VK DrawMaskedSprite --- src/renderer/dx9/renderer.cpp | 2 ++ src/renderer/vulkan/renderer.cpp | 2 +- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 21f1585b4..c094db8e5 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -324,6 +324,8 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const BOOL isInvertedB = (BOOL)isInverted; const BOOL isSameTextureB = (BOOL)isSameTexture; + Flush(); + EnsureShader(ShaderMaskedSprite); Device->SetTexture(0, Textures[sprite.Sheet.Texture]); Device->SetTexture(1, Textures[mask.Sheet.Texture]); diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 9af587917..f3429b95e 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1182,7 +1182,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, return; } - if (sprite.Sheet.IsScreenCap) Flush(); + Flush(); if (Textures.count(sprite.Sheet.Texture) == 0 || Textures.count(mask.Sheet.Texture) == 0) From 3692b6a3d13dcc0726edc6ad034f020e3018d02b Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:39:28 +0200 Subject: [PATCH 53/88] Fixed DX9 and VK DrawMaskedSprite mask UVs --- src/renderer/dx9/renderer.cpp | 2 +- src/renderer/vulkan/renderer.cpp | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index c094db8e5..b2930401c 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -346,7 +346,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index f3429b95e..cac0ba94d 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1242,7 +1242,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); From a759996f427a619a7374bdd9ff62576cd83d47f9 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:49:35 +0200 Subject: [PATCH 54/88] Replaced maxZ for loop with std::max_element --- src/util.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 6f778e97e..2176decdc 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -89,8 +89,10 @@ CornersQuad& CornersQuad::Rotate(const glm::quat rotation, // Move into screen if (stayInScreen) { - float maxZ = 0.0f; - for (const glm::vec4 vertex : vertices) maxZ = std::max(maxZ, vertex.z); + float maxZ = + std::max_element(vertices.begin(), vertices.end(), + [](auto lhs, auto rhs) { return lhs.z < rhs.z; }) + ->z; for (glm::vec4& vertex : vertices) vertex.z -= maxZ; } From 6abce58e38b69b8218d96fdbb4497d15d2f6ed70 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 15:57:55 +0200 Subject: [PATCH 55/88] Added 2d-scaling 3d-rotation TransformationMatrix overload --- src/background2d.cpp | 20 ++++++++------------ src/games/cclcc/systemmenu.cpp | 5 ++--- src/util.cpp | 2 +- src/util.h | 17 +++++++++++++++++ 4 files changed, 28 insertions(+), 16 deletions(-) diff --git a/src/background2d.cpp b/src/background2d.cpp index a268dedc1..a0f3f2d3b 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -227,9 +227,8 @@ void Background2D::RenderBgEff(int bgId, int layer) { for (const glm::vec2 vertex : vertices) Origin += vertex / (float)vertexCount; // Transform vertices - const glm::mat4 transformation = - TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, - Rotation, {DisplayCoords, 0.0f}); + const glm::mat4 transformation = TransformationMatrix( + Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); std::transform(vertices.begin(), vertices.end(), vertices.begin(), [transformation](const glm::vec2 vertex) { return transformation * glm::vec4(vertex, 0.0f, 1.0f); @@ -254,9 +253,8 @@ void Background2D::RenderBgEff(int bgId, int layer) { } void Background2D::RenderRegular() { - const glm::mat4 transformation = - TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, - Rotation, {DisplayCoords, 0.0f}); + const glm::mat4 transformation = TransformationMatrix( + Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); Renderer->DrawSprite(BgSprite, transformation, Tint, false); for (int i = 0; i < MaxLinkedBgBuffers; i++) { @@ -272,9 +270,8 @@ void Background2D::RenderRegular() { } void Background2D::RenderMasked() { - const glm::mat4 transformation = - TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, - Rotation, {DisplayCoords, 0.0f}); + const glm::mat4 transformation = TransformationMatrix( + Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, false, @@ -282,9 +279,8 @@ void Background2D::RenderMasked() { } void Background2D::RenderMaskedInverted() { - const glm::mat4 transformation = - TransformationMatrix({Origin, 0.0f}, {Scale, 1.0f}, {Origin, 0.0f}, - Rotation, {DisplayCoords, 0.0f}); + const glm::mat4 transformation = TransformationMatrix( + Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, true, false); diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index de998ebf1..828ca4ce3 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -202,9 +202,8 @@ auto GenerateMatrix(CornersQuad const& corners) { glm::vec2 TransformImageVertex(const glm::vec2 vertex, const glm::quat rotation, const float scale, const glm::vec2 origin) { - glm::mat4 transformation = - TransformationMatrix({origin, 0.0f}, {scale, scale, 1.0f}, {origin, 0.0f}, - rotation, {-origin, 0.0f}); + glm::mat4 transformation = TransformationMatrix( + origin, {scale, scale}, {origin, 0.0f}, rotation, {-origin, 0.0f}); glm::vec4 transformedVertex = {vertex, 0.0f, 1.0f}; transformedVertex = transformation * transformedVertex; diff --git a/src/util.cpp b/src/util.cpp index 2176decdc..bd770b020 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -167,7 +167,7 @@ glm::mat4 TransformationMatrix(const glm::vec2 scalingOrigin, const float rotation, const glm::vec2 translation) { return TransformationMatrix( - {scalingOrigin, 0.0f}, {scaling, 1.0f}, {rotationOrigin, 0.0f}, + scalingOrigin, scaling, {rotationOrigin, 0.0f}, AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), {translation, 0.0f}); } diff --git a/src/util.h b/src/util.h index 2f2331d86..825e9c3ca 100644 --- a/src/util.h +++ b/src/util.h @@ -59,6 +59,15 @@ glm::mat4 TransformationMatrix(glm::vec3 scalingOrigin, glm::vec3 scaling, glm::vec3 rotationOrigin = glm::vec3(0.0f), glm::quat rotation = glm::quat(), glm::vec3 translation = glm::vec3(0.0f)); +inline glm::mat4 TransformationMatrix(glm::vec2 scalingOrigin, + glm::vec2 scaling, + glm::vec3 rotationOrigin, + glm::quat rotation, + glm::vec3 translation = glm::vec3(0.0f)) { + return TransformationMatrix(glm::vec3(scalingOrigin, 0.0f), + glm::vec3(scaling, 1.0f), rotationOrigin, + rotation, translation); +} glm::vec4 TransformVector(glm::vec2 pos, glm::vec2 scalingOrigin, glm::vec2 scaling, @@ -70,6 +79,14 @@ glm::vec4 TransformVector(glm::vec3 pos, glm::vec3 scalingOrigin, glm::vec3 rotationOrigin = glm::vec3(0.0f), glm::quat rotation = glm::quat(), glm::vec3 translation = glm::vec3(0.0f)); +inline glm::vec4 TransformVector(glm::vec3 pos, glm::vec2 scalingOrigin, + glm::vec2 scaling, glm::vec3 rotationOrigin, + glm::quat rotation, + glm::vec3 translation = glm::vec3(0.0f)) { + return TransformVector(pos, glm::vec3(scalingOrigin, 0.0f), + glm::vec3(scaling, 1.0f), rotationOrigin, rotation, + translation); +} struct Rect; struct CornersQuad; From db86be4131bd8a108e18d7446ffa4775e9c93e8e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 16:23:31 +0200 Subject: [PATCH 56/88] Added MaskedSpriteOverlay overloads for setting the sprite and mask transformations independently --- src/renderer/dx9/renderer.cpp | 12 +++++---- src/renderer/dx9/renderer.h | 3 ++- src/renderer/opengl/renderer.cpp | 12 +++++---- src/renderer/opengl/renderer.h | 3 ++- src/renderer/renderer.cpp | 24 +++++++++++------- src/renderer/renderer.h | 42 ++++++++++++++++++++++++++++---- src/renderer/vulkan/renderer.cpp | 12 +++++---- src/renderer/vulkan/renderer.h | 3 ++- 8 files changed, 79 insertions(+), 32 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index b2930401c..cca54fb2a 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -355,9 +355,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, } void Renderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, - int alpha, const int fadeRange, const std::span tints, - const bool isInverted, const bool useMaskAlpha) { + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + const std::span tints, const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -405,10 +406,11 @@ void Renderer::DrawMaskedSpriteOverlay( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 89d6f9e96..28cb72089 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -52,7 +52,8 @@ class Renderer : public BaseRenderer { int fadeRange, float effectCt) override; void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool useMaskAlpha) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index fb2dcbf47..5f9d8c733 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -381,9 +381,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, } void Renderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, - int alpha, const int fadeRange, const std::span tints, - const bool isInverted, const bool useMaskAlpha) { + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + const std::span tints, const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -440,10 +441,11 @@ void Renderer::DrawMaskedSpriteOverlay( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 8b3016e00..5bfbba0df 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -63,7 +63,8 @@ class Renderer : public BaseRenderer { int fadeRange, float effectCt) override; void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool useMaskAlpha) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 98a9abdcb..16f456267 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -77,20 +77,26 @@ void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const int alpha, - const int fadeRange, const glm::mat4 transformation, const glm::vec4 tint, + const int fadeRange, const glm::mat4 spriteTransformation, + const glm::mat4 maskTransformation, const glm::vec4 tint, const bool isInverted, const bool useMaskAlpha) { - const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); - DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, - isInverted, useMaskAlpha); + const CornersQuad spriteDest = + sprite.ScaledBounds().Transform(spriteTransformation); + const CornersQuad maskDest = + mask.ScaledBounds().Transform(maskTransformation); + DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, fadeRange, + tint, isInverted, useMaskAlpha); } void BaseRenderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const int alpha, - const int fadeRange, const glm::vec2 topLeft, const glm::vec4 tint, - const bool isInverted, const bool useMaskAlpha) { - const RectF dest = sprite.ScaledBounds().Translate(topLeft); - DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, tint, - isInverted, useMaskAlpha); + const int fadeRange, const glm::vec2 spriteTopLeft, + const glm::vec2 maskTopLeft, const glm::vec4 tint, const bool isInverted, + const bool useMaskAlpha) { + const RectF spriteDest = sprite.ScaledBounds().Translate(spriteTopLeft); + const RectF maskDest = mask.ScaledBounds().Translate(maskTopLeft); + DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, fadeRange, + tint, isInverted, useMaskAlpha); } void BaseRenderer::DrawVertices( diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 89f555945..780cd3ed7 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -91,31 +91,63 @@ class BaseRenderer { bool isInverted = false, bool isSameTexture = false); virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted = false, bool useMaskAlpha = true) = 0; void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true) { - DrawMaskedSpriteOverlay(sprite, mask, dest, alpha, fadeRange, + DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, + fadeRange, std::array{tint, tint, tint, tint}, isInverted, useMaskAlpha); } + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& spriteDest, int alpha, + int fadeRange, glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, spriteDest, mask.ScaledBounds(), + alpha, fadeRange, tint, isInverted, useMaskAlpha); + } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, - glm::mat4 transformation, + glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true); void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - int alpha, int fadeRange, glm::vec2 topLeft, + int alpha, int fadeRange, + glm::mat4 spriteTransformation, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, alpha, fadeRange, + spriteTransformation, glm::mat4(1.0f), tint, + isInverted, useMaskAlpha); + } + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + int alpha, int fadeRange, + glm::vec2 spriteTopLeft, glm::vec2 maskTopLeft, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true); + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + int alpha, int fadeRange, + glm::vec2 spriteTopLeft, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, alpha, fadeRange, spriteTopLeft, + {0.0f, 0.0f}, tint, isInverted, useMaskAlpha); + } virtual void DrawVertices(const SpriteSheet& sheet, std::span vertices, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index cac0ba94d..cafc83790 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1251,9 +1251,10 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, } void Renderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const CornersQuad& dest, - int alpha, const int fadeRange, const std::span tints, - const bool isInverted, const bool useMaskAlpha) { + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + const std::span tints, const bool isInverted, + const bool useMaskAlpha) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -1336,10 +1337,11 @@ void Renderer::DrawMaskedSpriteOverlay( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index 546b4f217..bc28df8fc 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -80,7 +80,8 @@ class Renderer : public BaseRenderer { int fadeRange, float effectCt) override; void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool useMaskAlpha) override; From a43597f87f7797b65dea48645b5d1581907a6447 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 16:26:08 +0200 Subject: [PATCH 57/88] fixed chlcc delusion trigger mask rotation --- src/games/chlcc/delusiontrigger.cpp | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/src/games/chlcc/delusiontrigger.cpp b/src/games/chlcc/delusiontrigger.cpp index c94773559..8e2d49eab 100644 --- a/src/games/chlcc/delusiontrigger.cpp +++ b/src/games/chlcc/delusiontrigger.cpp @@ -341,10 +341,11 @@ void DelusionTrigger::Render() { ScreenMask, RectF(0.0f, 0.0f, 1280.0f, 720.0f), glm::vec4(1.0f, 1.0f, 1.0f, (backgroundAlpha * 160) / 65536.0)); - CornersQuad dest = RectF(0.0f, 0.0f, 1280.0f, 720.0f) - .Rotate(ScrWorkAngleToRad(spinAngle), {640, 360}); - Renderer->DrawMaskedSpriteOverlay(BackgroundSprite, ScaledMask, dest, - (backgroundAlpha * 160) >> 8, 20, + const RectF spriteDest = {0.0f, 0.0f, 1280.0f, 720.0f}; + const CornersQuad maskDest = + ScaledMask.Bounds.RotateAroundCenter(ScrWorkAngleToRad(spinAngle)); + Renderer->DrawMaskedSpriteOverlay(BackgroundSprite, ScaledMask, spriteDest, + maskDest, (backgroundAlpha * 160) >> 8, 20, glm::vec4(1.0f), true); } From d7f51243532032bac940d3d1c784ac0fd0e47556 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 16:34:01 +0200 Subject: [PATCH 58/88] Added MaskedSprite overloads for setting the sprite and mask transformations independently --- src/renderer/dx9/renderer.cpp | 8 ++++--- src/renderer/dx9/renderer.h | 3 ++- src/renderer/opengl/renderer.cpp | 8 ++++--- src/renderer/opengl/renderer.h | 3 ++- src/renderer/renderer.cpp | 22 ++++++++++++------- src/renderer/renderer.h | 36 +++++++++++++++++++++++++++----- src/renderer/vulkan/renderer.cpp | 8 ++++--- src/renderer/vulkan/renderer.h | 3 ++- 8 files changed, 66 insertions(+), 25 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index cca54fb2a..2771ec088 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -300,7 +300,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, } void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, const std::span tints, const bool isInverted, @@ -346,10 +347,11 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(maskDest, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 28cb72089..0b2eb2320 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -39,7 +39,8 @@ class Renderer : public BaseRenderer { bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, int fadeRange, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool isSameTexture); diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 5f9d8c733..9b235d8b5 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -317,7 +317,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, } void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, const std::span tints, const bool isInverted, @@ -372,10 +373,11 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); } - QuadSetUV(sprite.Bounds, sprite.Bounds.GetSize(), &vertices[0].MaskUV, + QuadSetUV(maskDest, sprite.Bounds.GetSize(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 5bfbba0df..edbaef378 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -54,7 +54,8 @@ class Renderer : public BaseRenderer { std::span indices, bool inverted) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, int fadeRange, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool isSameTexture) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 16f456267..45ea9c0ae 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -57,22 +57,28 @@ void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, - const glm::mat4 transformation, + const glm::mat4 spriteTransformation, + const glm::mat4 maskTransformation, const glm::vec4 tint, const bool isInverted, const bool isSameTexture) { - const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, - isSameTexture); + const CornersQuad spriteDest = + sprite.ScaledBounds().Transform(spriteTransformation); + const CornersQuad maskDest = + sprite.ScaledBounds().Transform(maskTransformation); + DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, tint, + isInverted, isSameTexture); } void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const int alpha, const int fadeRange, - const glm::vec2 topLeft, + const glm::vec2 spriteTopLeft, + const glm::vec2 maskTopLeft, const glm::vec4 tint, const bool isInverted, const bool isSameTexture) { - const RectF dest = sprite.ScaledBounds().Translate(topLeft); - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, tint, isInverted, - isSameTexture); + const RectF spriteDest = sprite.ScaledBounds().Translate(spriteTopLeft); + const RectF maskDest = sprite.ScaledBounds().Translate(maskTopLeft); + DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, tint, + isInverted, isSameTexture); } void BaseRenderer::DrawMaskedSpriteOverlay( diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 780cd3ed7..3a3097834 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -68,27 +68,53 @@ class BaseRenderer { bool disableBlend = false); virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted = false, bool isSameTexture = false) = 0; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, int fadeRange, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false) { - DrawMaskedSprite(sprite, mask, dest, alpha, fadeRange, + DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, + std::array{tint, tint, tint, tint}, + isInverted, isSameTexture); + } + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, + const CornersQuad& spriteDest, int alpha, int fadeRange, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, spriteDest, sprite.ScaledBounds(), alpha, + fadeRange, std::array{tint, tint, tint, tint}, isInverted, isSameTexture); } void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, - int fadeRange, glm::mat4 transformation, + int fadeRange, glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, - int fadeRange, glm::vec2 topLeft, + int fadeRange, glm::mat4 spriteTransformation, glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, alpha, fadeRange, spriteTransformation, + glm::mat4(1.0f), tint, isInverted, isSameTexture); + } + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, + int fadeRange, glm::vec2 spriteTopLeft, + glm::vec2 maskTopLeft, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false); + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, + int fadeRange, glm::vec2 spriteTopLeft, + glm::vec4 tint = glm::vec4(1.0f), + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, alpha, fadeRange, spriteTopLeft, + {0.0f, 0.0f}, tint, isInverted, isSameTexture); + } virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index cafc83790..50de6eb41 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1171,7 +1171,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, } void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, const std::span tints, const bool isInverted, @@ -1242,10 +1243,11 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(maskDest, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(spriteDest, &vertices[0].Position, + sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index bc28df8fc..ca5da98cf 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -67,7 +67,8 @@ class Renderer : public BaseRenderer { bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& dest, int alpha, int fadeRange, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, std::span tints, bool isInverted, bool isSameTexture) override; From 2c7648e594b4e90e59ea0408b6e21cee6c100485 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 10 May 2025 16:50:53 +0200 Subject: [PATCH 59/88] Fixed chlcc titlemenu circle rendering --- src/games/chlcc/titlemenu.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/src/games/chlcc/titlemenu.cpp b/src/games/chlcc/titlemenu.cpp index 40e7e5931..d22404f8a 100644 --- a/src/games/chlcc/titlemenu.cpp +++ b/src/games/chlcc/titlemenu.cpp @@ -449,6 +449,7 @@ inline void TitleMenu::DrawTitleMenuBackGraphics() { const CornersQuad spinningCircleDest = SpinningCircleSprite.ScaledBounds() + .Scale({2.0f, 2.0f}, {0.0f, 0.0f}) .RotateAroundCenter(-SpinningCircleAnimation.Progress * 2.0f * (float)M_PI) .Translate({SpinningCircleX, SpinningCircleY}); From 6a6abf1d0a2a38ea04936ef829868265252b72b2 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 13 May 2025 00:37:26 +0200 Subject: [PATCH 60/88] Changed 2d TransformationMatrix with 3d rotation method to take in 2d translation as well --- src/background2d.cpp | 8 ++++---- src/games/cclcc/systemmenu.cpp | 2 +- src/util.cpp | 2 +- src/util.h | 12 ++++++------ 4 files changed, 12 insertions(+), 12 deletions(-) diff --git a/src/background2d.cpp b/src/background2d.cpp index a0f3f2d3b..8ae2c255e 100644 --- a/src/background2d.cpp +++ b/src/background2d.cpp @@ -228,7 +228,7 @@ void Background2D::RenderBgEff(int bgId, int layer) { // Transform vertices const glm::mat4 transformation = TransformationMatrix( - Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); + Origin, Scale, {Origin, 0.0f}, Rotation, DisplayCoords); std::transform(vertices.begin(), vertices.end(), vertices.begin(), [transformation](const glm::vec2 vertex) { return transformation * glm::vec4(vertex, 0.0f, 1.0f); @@ -254,7 +254,7 @@ void Background2D::RenderBgEff(int bgId, int layer) { void Background2D::RenderRegular() { const glm::mat4 transformation = TransformationMatrix( - Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); + Origin, Scale, {Origin, 0.0f}, Rotation, DisplayCoords); Renderer->DrawSprite(BgSprite, transformation, Tint, false); for (int i = 0; i < MaxLinkedBgBuffers; i++) { @@ -271,7 +271,7 @@ void Background2D::RenderRegular() { void Background2D::RenderMasked() { const glm::mat4 transformation = TransformationMatrix( - Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); + Origin, Scale, {Origin, 0.0f}, Rotation, DisplayCoords); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, false, @@ -280,7 +280,7 @@ void Background2D::RenderMasked() { void Background2D::RenderMaskedInverted() { const glm::mat4 transformation = TransformationMatrix( - Origin, Scale, {Origin, 0.0f}, Rotation, {DisplayCoords, 0.0f}); + Origin, Scale, {Origin, 0.0f}, Rotation, DisplayCoords); Renderer->DrawMaskedSprite(BgSprite, Masks2D[MaskNumber].MaskSprite, FadeCount, FadeRange, transformation, Tint, true, false); diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 828ca4ce3..5b20d9ed2 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -203,7 +203,7 @@ auto GenerateMatrix(CornersQuad const& corners) { glm::vec2 TransformImageVertex(const glm::vec2 vertex, const glm::quat rotation, const float scale, const glm::vec2 origin) { glm::mat4 transformation = TransformationMatrix( - origin, {scale, scale}, {origin, 0.0f}, rotation, {-origin, 0.0f}); + origin, {scale, scale}, {origin, 0.0f}, rotation, -origin); glm::vec4 transformedVertex = {vertex, 0.0f, 1.0f}; transformedVertex = transformation * transformedVertex; diff --git a/src/util.cpp b/src/util.cpp index bd770b020..375c62f70 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -168,7 +168,7 @@ glm::mat4 TransformationMatrix(const glm::vec2 scalingOrigin, const glm::vec2 translation) { return TransformationMatrix( scalingOrigin, scaling, {rotationOrigin, 0.0f}, - AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), {translation, 0.0f}); + AxisAngleToQuaternion({0.0f, 0.0f, 1.0f}, rotation), translation); } glm::mat4 TransformationMatrix(const glm::vec3 scalingOrigin, diff --git a/src/util.h b/src/util.h index 825e9c3ca..a531c9a2d 100644 --- a/src/util.h +++ b/src/util.h @@ -63,10 +63,10 @@ inline glm::mat4 TransformationMatrix(glm::vec2 scalingOrigin, glm::vec2 scaling, glm::vec3 rotationOrigin, glm::quat rotation, - glm::vec3 translation = glm::vec3(0.0f)) { + glm::vec2 translation = glm::vec2(0.0f)) { return TransformationMatrix(glm::vec3(scalingOrigin, 0.0f), glm::vec3(scaling, 1.0f), rotationOrigin, - rotation, translation); + rotation, glm::vec3(translation, 0.0f)); } glm::vec4 TransformVector(glm::vec2 pos, glm::vec2 scalingOrigin, @@ -79,13 +79,13 @@ glm::vec4 TransformVector(glm::vec3 pos, glm::vec3 scalingOrigin, glm::vec3 rotationOrigin = glm::vec3(0.0f), glm::quat rotation = glm::quat(), glm::vec3 translation = glm::vec3(0.0f)); -inline glm::vec4 TransformVector(glm::vec3 pos, glm::vec2 scalingOrigin, +inline glm::vec4 TransformVector(glm::vec2 pos, glm::vec2 scalingOrigin, glm::vec2 scaling, glm::vec3 rotationOrigin, glm::quat rotation, - glm::vec3 translation = glm::vec3(0.0f)) { - return TransformVector(pos, glm::vec3(scalingOrigin, 0.0f), + glm::vec2 translation = glm::vec2(0.0f)) { + return TransformVector({pos, 0.0f}, glm::vec3(scalingOrigin, 0.0f), glm::vec3(scaling, 1.0f), rotationOrigin, rotation, - translation); + {translation, 0.0f}); } struct Rect; From a3893fe428187f354ccfbe8bf56854f6aa92f966 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 15 May 2025 01:50:39 +0200 Subject: [PATCH 61/88] Moved vertex transformation to vertex shader --- src/games/cclcc/mapsystem.cpp | 3 +- src/games/chlcc/delusiontrigger.cpp | 2 +- src/games/mo6tw/titlemenu.cpp | 24 +-- src/renderer/dx9/renderer.cpp | 16 +- src/renderer/dx9/renderer.h | 24 ++- src/renderer/opengl/renderer.cpp | 93 +++++++--- src/renderer/opengl/renderer.h | 33 ++-- src/renderer/renderer.cpp | 175 +++--------------- src/renderer/renderer.h | 127 ++++++++----- src/renderer/vulkan/renderer.cpp | 16 +- src/renderer/vulkan/renderer.h | 24 ++- .../opengl/CCMessageBoxSprite_vert.glsl | 4 +- .../opengl/CHLCCMenuBackground_vert.glsl | 4 +- .../opengl/MaskedSpriteNoAlpha_vert.glsl | 8 +- src/shaders/opengl/MaskedSprite_vert.glsl | 8 +- src/shaders/opengl/Sprite_inverted_vert.glsl | 5 +- src/shaders/opengl/Sprite_vert.glsl | 5 +- src/shaders/opengl/YUVFrame_vert.glsl | 4 +- src/ui/widgets/cc/backlogentry.cpp | 2 +- 19 files changed, 291 insertions(+), 286 deletions(-) diff --git a/src/games/cclcc/mapsystem.cpp b/src/games/cclcc/mapsystem.cpp index 9aedab7f3..dcc880023 100644 --- a/src/games/cclcc/mapsystem.cpp +++ b/src/games/cclcc/mapsystem.cpp @@ -2006,7 +2006,8 @@ void MapSystemCCLCC::RenderButtonGuide() { glm::vec2{guideXWidth + 60, 988.0f}, // top right glm::vec2{guideXWidth + 60, 1042.0f}, // bottom right }; - Renderer->DrawSprite(MapButtonGuideSprite2, dest, tints, false); + Renderer->DrawSprite(MapButtonGuideSprite2, dest, glm::mat4(1.0f), + tints, false); } } } diff --git a/src/games/chlcc/delusiontrigger.cpp b/src/games/chlcc/delusiontrigger.cpp index 8e2d49eab..7c870fe36 100644 --- a/src/games/chlcc/delusiontrigger.cpp +++ b/src/games/chlcc/delusiontrigger.cpp @@ -346,7 +346,7 @@ void DelusionTrigger::Render() { ScaledMask.Bounds.RotateAroundCenter(ScrWorkAngleToRad(spinAngle)); Renderer->DrawMaskedSpriteOverlay(BackgroundSprite, ScaledMask, spriteDest, maskDest, (backgroundAlpha * 160) >> 8, 20, - glm::vec4(1.0f), true); + glm::mat4(1.0f), glm::vec4(1.0f), true); } } // namespace CHLCC diff --git a/src/games/mo6tw/titlemenu.cpp b/src/games/mo6tw/titlemenu.cpp index c6a0ddd2b..48b0e44df 100644 --- a/src/games/mo6tw/titlemenu.cpp +++ b/src/games/mo6tw/titlemenu.cpp @@ -368,8 +368,8 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::vec4(1.0f), false, - true); + (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::mat4(1.0f), + glm::vec4(1.0f), false, true); if (ScrWork[SW_TITLECT] > 48) { Renderer->DrawMaskedSprite( LogoSprite, Masks2D[17].MaskSprite, @@ -383,7 +383,7 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -397,7 +397,7 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); Renderer->DrawSprite(LogoSprite, glm::vec2(LogoX, LogoY)); Renderer->DrawSprite(CopyrightSprite, glm::vec2(CopyrightX, CopyrightY)); @@ -408,7 +408,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); MainItems->Render(); } break; case 5: // Secondary menu Extra story Fade In @@ -417,7 +417,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); ExtraStoryItems->Render(); MainItems->Render(); } break; @@ -427,7 +427,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); ContinueItems->Render(); MainItems->Render(); } break; @@ -437,7 +437,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); MemoriesItems->Render(); MainItems->Render(); } break; @@ -447,7 +447,7 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); SystemItems->Render(); MainItems->Render(); } break; @@ -457,7 +457,7 @@ void TitleMenu::Render() { BackgroundSprite, BackgroundSprite, RectF(0.0f, 0.0f, BackgroundSprite.ScaledWidth(), BackgroundSprite.ScaledHeight()), - 287, 32, glm::vec4(1.0f), false, true); + 287, 32, glm::mat4(1.0f), glm::vec4(1.0f), false, true); Renderer->DrawMaskedSprite( LogoSprite, Masks2D[17].MaskSprite, RectF(LogoX, LogoY, LogoSprite.ScaledWidth(), @@ -469,8 +469,8 @@ void TitleMenu::Render() { MenuBackgroundSprite, MenuBackgroundSprite, RectF(0.0f, 0.0f, MenuBackgroundSprite.ScaledWidth(), MenuBackgroundSprite.ScaledHeight()), - (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::vec4(1.0f), false, - true); + (ScrWork[SW_TITLECT] * 287) / 48, 32, glm::mat4(1.0f), + glm::vec4(1.0f), false, true); } break; } } diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 2771ec088..8605d4603 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -264,6 +264,7 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const glm::mat4 transformation, const std::span tints, const bool inverted, const bool disableBlend) { if (!Drawing) { @@ -299,13 +300,12 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - const int fadeRange, - const std::span tints, - const bool isInverted, - const bool isSameTexture) { +void Renderer::DrawMaskedSprite( + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + const glm::mat4 spriteTransformation, const glm::mat4 maskTransformation, + const std::span tints, const bool isInverted, + const bool isSameTexture) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -359,6 +359,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, void Renderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, const int fadeRange, + const glm::mat4 spriteTransformation, const glm::mat4 maskTransformation, const std::span tints, const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { @@ -420,6 +421,7 @@ void Renderer::DrawMaskedSpriteOverlay( void Renderer::DrawVertices(const SpriteSheet& sheet, const std::span vertices, const std::span indices, + const glm::mat4 transformation, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 0b2eb2320..baf788bad 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -35,30 +35,34 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, bool inverted, - bool disableBlend) override; + glm::mat4 transformation, std::span tints, + bool inverted, bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, int fadeRange, + glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, std::span tints, bool isInverted, bool isSameTexture); + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, + int fadeRange, glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, + std::span tints, + bool isInverted, bool useMaskAlpha) override; + void DrawVertices(const SpriteSheet& sheet, std::span vertices, - std::span indices, bool inverted) override; + std::span indices, glm::mat4 transformation, + bool inverted) override; void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - int fadeRange, - std::span tints, - bool isInverted, bool useMaskAlpha) override; - void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 9b235d8b5..8ffbfbe05 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -92,6 +92,9 @@ void Renderer::Init() { glUniform1i(glGetUniformLocation(ShaderProgramSprite, "ColorMap"), 0); ShaderProgramSpriteInverted = Shaders->Compile("Sprite_inverted"); glUniform1i(glGetUniformLocation(ShaderProgramSpriteInverted, "ColorMap"), 0); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramSpriteInverted, "Projection"), 1, + GL_FALSE, &Projection[0][0]); ShaderProgramMaskedSprite = Shaders->Compile("MaskedSprite"); glUseProgram(ShaderProgramMaskedSprite); @@ -100,6 +103,9 @@ void Renderer::Init() { glGetUniformLocation(ShaderProgramMaskedSprite, "IsInverted"); MaskedIsSameTextureLocation = glGetUniformLocation(ShaderProgramMaskedSprite, "IsSameTexture"); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramMaskedSprite, "Projection"), 1, + GL_FALSE, &Projection[0][0]); ShaderProgramMaskedSpriteNoAlpha = Shaders->Compile("MaskedSpriteNoAlpha"); glUseProgram(ShaderProgramMaskedSpriteNoAlpha); @@ -107,10 +113,15 @@ void Renderer::Init() { glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "ColorMap"), 0); MaskedNoAlphaIsInvertedLocation = glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "IsInverted"); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "Projection"), 1, + GL_FALSE, &Projection[0][0]); ShaderProgramYUVFrame = Shaders->Compile("YUVFrame"); glUseProgram(ShaderProgramYUVFrame); glUniform1i(glGetUniformLocation(ShaderProgramYUVFrame, "Luma"), 0); + glUniformMatrix4fv(glGetUniformLocation(ShaderProgramYUVFrame, "Projection"), + 1, GL_FALSE, &Projection[0][0]); YUVFrameCbLocation = glGetUniformLocation(ShaderProgramYUVFrame, "Cb"); YUVFrameCrLocation = glGetUniformLocation(ShaderProgramYUVFrame, "Cr"); YUVFrameIsAlphaLocation = @@ -119,7 +130,14 @@ void Renderer::Init() { ShaderProgramCCMessageBox = Shaders->Compile("CCMessageBoxSprite"); glUseProgram(ShaderProgramCCMessageBox); glUniform1i(glGetUniformLocation(ShaderProgramCCMessageBox, "ColorMap"), 0); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramCCMessageBox, "Projection"), 1, + GL_FALSE, &Projection[0][0]); + ShaderProgramCHLCCMenuBackground = Shaders->Compile("CHLCCMenuBackground"); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramCHLCCMenuBackground, "Projection"), 1, + GL_FALSE, &Projection[0][0]); // No-mipmapping sampler glGenSamplers(1, &Sampler); @@ -265,6 +283,7 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const glm::mat4 transformation, const std::span tints, const bool inverted, const bool disableBlend) { if (!Drawing) { @@ -283,6 +302,13 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, Flush(); } + // Set uniform variables + const GLuint shaderProgram = + inverted ? ShaderProgramSpriteInverted : ShaderProgramSprite; + + glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "Transformation"), 1, + GL_FALSE, &transformation[0][0]); + // Do we have the texture assigned? EnsureTextureBound(sprite.Sheet.Texture); @@ -316,13 +342,12 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, } } -void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - const int fadeRange, - const std::span tints, - const bool isInverted, - const bool isSameTexture) { +void Renderer::DrawMaskedSprite( + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + glm::mat4 spriteTransformation, glm::mat4 maskTransformation, + const std::span tints, const bool isInverted, + const bool isSameTexture) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSprite() called before BeginFrame()\n"); @@ -343,14 +368,24 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, EnsureTextureBound(sprite.Sheet.Texture); + // Set uniform variables glBindVertexArray(VAOSprites); glUseProgram(ShaderProgramMaskedSprite); + glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), alphaRange, constAlpha); + glUniform1i(MaskedIsInvertedLocation, isInverted); glUniform1i(MaskedIsSameTextureLocation, isSameTexture); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramMaskedSprite, "SpriteTransformation"), + 1, GL_FALSE, &spriteTransformation[0][0]); + glUniformMatrix4fv( + glGetUniformLocation(ShaderProgramMaskedSprite, "MaskTransformation"), 1, + GL_FALSE, &maskTransformation[0][0]); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -385,6 +420,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, void Renderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, const int fadeRange, + glm::mat4 spriteTransformation, glm::mat4 maskTransformation, const std::span tints, const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { @@ -401,30 +437,38 @@ void Renderer::DrawMaskedSpriteOverlay( EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); glBindVertexArray(VAOSprites); + GLuint shaderProgram; if (useMaskAlpha) { + shaderProgram = ShaderProgramMaskedSprite; + if (CurrentMode != R2D_Masked || sprite.Sheet.IsScreenCap) { Flush(); CurrentMode = R2D_Masked; } - glUseProgram(ShaderProgramMaskedSprite); - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); - glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), - alphaRange, constAlpha); + glUseProgram(shaderProgram); glUniform1i(MaskedIsInvertedLocation, isInverted); glUniform1i(MaskedIsSameTextureLocation, false); } else { + shaderProgram = ShaderProgramMaskedSpriteNoAlpha; + if (CurrentMode != R2D_MaskedNoAlpha || sprite.Sheet.IsScreenCap) { Flush(); CurrentMode = R2D_MaskedNoAlpha; } - glUseProgram(ShaderProgramMaskedSpriteNoAlpha); - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "Mask"), - 2); - glUniform2f(glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "Alpha"), - alphaRange, constAlpha); + glUseProgram(shaderProgram); glUniform1i(MaskedNoAlphaIsInvertedLocation, isInverted); } + glUniform1i(glGetUniformLocation(shaderProgram, "Mask"), 2); + glUniform2f(glGetUniformLocation(shaderProgram, "Alpha"), alphaRange, + constAlpha); + + glUniformMatrix4fv( + glGetUniformLocation(shaderProgram, "SpriteTransformation"), 1, GL_FALSE, + &spriteTransformation[0][0]); + glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MaskTransformation"), + 1, GL_FALSE, &maskTransformation[0][0]); + glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -455,7 +499,7 @@ void Renderer::DrawMaskedSpriteOverlay( void Renderer::DrawVertices(const SpriteSheet& sheet, const std::span vertices, const std::span indices, - const bool inverted) { + glm::mat4 transformation, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawVertices() called before BeginFrame()\n"); @@ -471,6 +515,13 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, EnsureModeSprite(inverted); EnsureTextureBound(sheet.Texture); + // Set uniform variables + const GLuint shaderProgram = + inverted ? ShaderProgramSpriteInverted : ShaderProgramSprite; + + glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "Transformation"), 1, + GL_FALSE, &transformation[0][0]); + glBindSampler(2, Sampler); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); @@ -481,7 +532,6 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, VertexBufferFill += vertices.size_bytes(); const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { - info.Position = DesignToNDC(info.Position); if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; return info; }; @@ -761,12 +811,5 @@ void Renderer::DisableScissor() { glDisable(GL_SCISSOR_TEST); } -glm::vec2 Renderer::DesignToNDC(glm::vec2 designCoord) const { - glm::vec2 result; - result.x = (designCoord.x / (Profile::DesignWidth * 0.5f)) - 1.0f; - result.y = 1.0f - (designCoord.y / (Profile::DesignHeight * 0.5f)); - return result; -} - } // namespace OpenGL } // namespace Impacto diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index edbaef378..3cb9dd000 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -8,6 +8,8 @@ #include "shader.h" #include "glc.h" +#include "../../profile/game.h" + namespace Impacto { namespace OpenGL { @@ -46,30 +48,34 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, bool inverted, - bool disableBlend) override; - - void DrawVertices(const SpriteSheet& sheet, - std::span vertices, - std::span indices, bool inverted) override; + glm::mat4 transformation, std::span tints, + bool inverted, bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, int fadeRange, + glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, std::span tints, bool isInverted, bool isSameTexture) override; - void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, - RectF const& dest, glm::vec4 tint, int alpha, - int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, - int fadeRange, + int fadeRange, glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, std::span tints, bool isInverted, bool useMaskAlpha) override; + void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, glm::mat4 transformation, + bool inverted) override; + + void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, + RectF const& dest, glm::vec4 tint, int alpha, + int fadeRange, float effectCt) override; + void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; @@ -100,8 +106,6 @@ class Renderer : public BaseRenderer { void EnsureModeSprite(bool inverted); void Flush() override; - glm::vec2 DesignToNDC(glm::vec2 designCoord) const override; - GLWindow* OpenGLWindow; GLuint ShaderProgramSprite; @@ -138,6 +142,9 @@ class Renderer : public BaseRenderer { uint16_t IndexBuffer[IndexBufferCount]; int IndexBufferFill = 0; + const glm::mat4 Projection = + glm::ortho(0.0f, Profile::DesignWidth, Profile::DesignHeight, 0.0f); + // ShaderCompiler compiler ShaderCompiler* Shaders; }; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 45ea9c0ae..1e83f89e3 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -40,111 +40,10 @@ void InitRenderer() { Renderer->Init(); } -void BaseRenderer::DrawSprite(const Sprite& sprite, - const glm::mat4 transformation, - const glm::vec4 tint, const bool inverted, - const bool disableBlend) { - const CornersQuad dest = sprite.ScaledBounds().Transform(transformation); - DrawSprite(sprite, dest, tint, inverted, disableBlend); -} - -void BaseRenderer::DrawSprite(const Sprite& sprite, const glm::vec2 topLeft, - const glm::vec4 tint, const bool inverted, - const bool disableBlend) { - const CornersQuad dest = sprite.ScaledBounds().Translate(topLeft); - DrawSprite(sprite, dest, tint, inverted, disableBlend); -} - -void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const int alpha, const int fadeRange, - const glm::mat4 spriteTransformation, - const glm::mat4 maskTransformation, - const glm::vec4 tint, const bool isInverted, - const bool isSameTexture) { - const CornersQuad spriteDest = - sprite.ScaledBounds().Transform(spriteTransformation); - const CornersQuad maskDest = - sprite.ScaledBounds().Transform(maskTransformation); - DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, tint, - isInverted, isSameTexture); -} - -void BaseRenderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const int alpha, const int fadeRange, - const glm::vec2 spriteTopLeft, - const glm::vec2 maskTopLeft, - const glm::vec4 tint, const bool isInverted, - const bool isSameTexture) { - const RectF spriteDest = sprite.ScaledBounds().Translate(spriteTopLeft); - const RectF maskDest = sprite.ScaledBounds().Translate(maskTopLeft); - DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, tint, - isInverted, isSameTexture); -} - -void BaseRenderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const int alpha, - const int fadeRange, const glm::mat4 spriteTransformation, - const glm::mat4 maskTransformation, const glm::vec4 tint, - const bool isInverted, const bool useMaskAlpha) { - const CornersQuad spriteDest = - sprite.ScaledBounds().Transform(spriteTransformation); - const CornersQuad maskDest = - mask.ScaledBounds().Transform(maskTransformation); - DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, fadeRange, - tint, isInverted, useMaskAlpha); -} - -void BaseRenderer::DrawMaskedSpriteOverlay( - const Sprite& sprite, const Sprite& mask, const int alpha, - const int fadeRange, const glm::vec2 spriteTopLeft, - const glm::vec2 maskTopLeft, const glm::vec4 tint, const bool isInverted, - const bool useMaskAlpha) { - const RectF spriteDest = sprite.ScaledBounds().Translate(spriteTopLeft); - const RectF maskDest = mask.ScaledBounds().Translate(maskTopLeft); - DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, fadeRange, - tint, isInverted, useMaskAlpha); -} - -void BaseRenderer::DrawVertices( - const SpriteSheet& sheet, - const std::span vertices, - const std::span indices, const glm::mat4 transformation, - const bool inverted) { - std::vector transformedVertices; - transformedVertices.resize(vertices.size()); - - const auto transform = [transformation](VertexBufferSprites info) { - info.Position = transformation * glm::vec4(info.Position, 0.0f, 1.0f); - return info; - }; - std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), - transform); - - DrawVertices(sheet, transformedVertices, indices, inverted); -} - -void BaseRenderer::DrawVertices( - const SpriteSheet& sheet, - const std::span vertices, - const std::span indices, const glm::vec2 offset, - const bool inverted) { - std::vector transformedVertices; - transformedVertices.resize(vertices.size()); - - const auto transform = [offset](VertexBufferSprites info) { - info.Position += offset; - return info; - }; - std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), - transform); - - DrawVertices(sheet, transformedVertices, indices, inverted); -} - void BaseRenderer::DrawVertices( const SpriteSheet& sheet, const std::span vertices, const int width, - const int height, const bool inverted) { + const int height, const glm::mat4 transformation, const bool inverted) { // Generate indices for triangles std::vector indices; indices.reserve((width - 1) * (height - 1) * 6); @@ -166,41 +65,7 @@ void BaseRenderer::DrawVertices( } } - DrawVertices(sheet, vertices, indices, inverted); -} - -void BaseRenderer::DrawVertices( - const SpriteSheet& sheet, - const std::span vertices, const int width, - const int height, const glm::mat4 transformation, const bool inverted) { - std::vector transformedVertices; - transformedVertices.resize(vertices.size()); - - const auto transform = [transformation](VertexBufferSprites info) { - info.Position = transformation * glm::vec4(info.Position, 0.0f, 1.0f); - return info; - }; - std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), - transform); - - DrawVertices(sheet, transformedVertices, width, height, inverted); -} - -void BaseRenderer::DrawVertices( - const SpriteSheet& sheet, - const std::span vertices, const int width, - const int height, const glm::vec2 offset, const bool inverted) { - std::vector transformedVertices; - transformedVertices.resize(vertices.size()); - - const auto transform = [offset](VertexBufferSprites info) { - info.Position += offset; - return info; - }; - std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), - transform); - - DrawVertices(sheet, transformedVertices, width, height, inverted); + DrawVertices(sheet, vertices, indices, transformation, inverted); } void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, @@ -268,37 +133,45 @@ void BaseRenderer::DrawProcessedText_BasicFont( color.a *= text[i].Opacity; } Sprite glyph = font->Glyph(text[i].CharId); + RectF dest = text[i].DestRect; switch (outlineMode) { case RendererOutlineMode::Full: dest.X--; dest.Y--; + if (maskedSheet) { Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = dest; DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, - color, false, i == 0); + glm::mat4(1.0f), color, false, i == 0); } else { DrawSprite(glyph, dest, color); } + dest.X++; dest.Y++; + [[fallthrough]]; case RendererOutlineMode::BottomRight: dest.X++; dest.Y++; + if (maskedSheet) { Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = dest; DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, - color, false, i == 0); + glm::mat4(1.0f), color, false, i == 0); } else { DrawSprite(glyph, dest, color); } break; + default: + ImpLogSlow(LogLevel::Warning, LogChannel::Render, + "Unexpected outline mode!"); break; } } @@ -307,18 +180,20 @@ void BaseRenderer::DrawProcessedText_BasicFont( for (int i = 0; i < text.size(); i++) { glm::vec4 color = RgbIntToFloat(text[i].Colors.TextColor); color.a = opacity; + if (smoothstepGlyphOpacity) { color.a *= glm::smoothstep(0.0f, 1.0f, text[i].Opacity); } else { color.a *= text[i].Opacity; } + if (maskedSheet) { Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = text[i].DestRect; DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, - text[i].DestRect, color.a * 255, 256, color, - false, false); + text[i].DestRect, color.a * 255, 256, + glm::mat4(1.0f), color, false, false); } else { DrawSprite(font->Glyph(text[i].CharId), text[i].DestRect, color); } @@ -359,15 +234,18 @@ void BaseRenderer::DrawProcessedText_LBFont( scaleY * (font->OutlineCellHeight + font->OutlineOffset.y / 2)); break; default: + ImpLogSlow(LogLevel::Warning, LogChannel::Render, + "Unexpected outline mode!"); break; } + if (maskedSheet) { Sprite mask; mask.Sheet = *maskedSheet; mask.Bounds = outlineDest; DrawMaskedSpriteOverlay(font->OutlineGlyph(text[i].CharId), mask, - outlineDest, color.a * 255, 256, color, false, - i == 0); + outlineDest, color.a * 255, 256, + glm::mat4(1.0f), color, false, i == 0); } else { DrawSprite(font->OutlineGlyph(text[i].CharId), outlineDest, color); } @@ -395,7 +273,8 @@ void BaseRenderer::DrawProcessedText_LBFont( mask.Sheet = *maskedSheet; mask.Bounds = foregroundDest; DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, foregroundDest, - color.a * 255, 256, color, false, false); + color.a * 255, 256, glm::mat4(1.0f), color, false, + false); } else { DrawSprite(font->Glyph(text[i].CharId), foregroundDest, color); } @@ -406,10 +285,10 @@ void BaseRenderer::DrawProcessedText_LBFont( void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, int stride) { - *(glm::vec2*)((uint8_t*)pos + 0 * stride) = DesignToNDC(quad.TopLeft); - *(glm::vec2*)((uint8_t*)pos + 1 * stride) = DesignToNDC(quad.BottomLeft); - *(glm::vec2*)((uint8_t*)pos + 2 * stride) = DesignToNDC(quad.BottomRight); - *(glm::vec2*)((uint8_t*)pos + 3 * stride) = DesignToNDC(quad.TopRight); + *(glm::vec2*)((uint8_t*)pos + 0 * stride) = quad.TopLeft; + *(glm::vec2*)((uint8_t*)pos + 1 * stride) = quad.BottomLeft; + *(glm::vec2*)((uint8_t*)pos + 2 * stride) = quad.BottomRight; + *(glm::vec2*)((uint8_t*)pos + 3 * stride) = quad.TopRight; } void BaseRenderer::QuadSetUV(const CornersQuad bounds, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 3a3097834..690c6a4c8 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -52,43 +52,51 @@ class BaseRenderer { virtual YUVFrame* CreateYUVFrame(float width, float height) = 0; virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + glm::mat4 transformation, std::span tints, bool inverted = false, bool disableBlend = false) = 0; + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, + glm::mat4 transformation = glm::mat4(1.0f), glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, bool disableBlend = false) { - DrawSprite(sprite, dest, std::array{tint, tint, tint, tint}, - inverted, disableBlend); + DrawSprite(sprite, dest, transformation, + std::array{tint, tint, tint, tint}, inverted, + disableBlend); + } + void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::vec4 tint, + bool inverted = false, bool disableBlend = false) { + DrawSprite(sprite, dest, glm::mat4(1.0f), tint, inverted, disableBlend); } void DrawSprite(const Sprite& sprite, glm::mat4 transformation, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, - bool disableBlend = false); + bool disableBlend = false) { + DrawSprite(sprite, sprite.ScaledBounds(), transformation, tint, inverted, + disableBlend); + } void DrawSprite(const Sprite& sprite, glm::vec2 topLeft, glm::vec4 tint = glm::vec4(1.0f), bool inverted = false, - bool disableBlend = false); + bool disableBlend = false) { + DrawSprite(sprite, sprite.ScaledBounds().Translate(topLeft), + glm::mat4(1.0f), tint, inverted, disableBlend); + } virtual void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, - int fadeRange, + int fadeRange, glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, std::span tints, bool isInverted = false, bool isSameTexture = false) = 0; - void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, int fadeRange, - glm::vec4 tint = glm::vec4(1.0f), - bool isInverted = false, bool isSameTexture = false) { - DrawMaskedSprite(sprite, mask, spriteDest, maskDest, alpha, fadeRange, - std::array{tint, tint, tint, tint}, - isInverted, isSameTexture); - } + void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, int alpha, int fadeRange, + glm::mat4 spriteTransformation = glm::mat4(1.0f), glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool isSameTexture = false) { DrawMaskedSprite(sprite, mask, spriteDest, sprite.ScaledBounds(), alpha, - fadeRange, + fadeRange, spriteTransformation, glm::mat4(1.0f), std::array{tint, tint, tint, tint}, isInverted, isSameTexture); } @@ -96,7 +104,12 @@ class BaseRenderer { int fadeRange, glm::mat4 spriteTransformation, glm::mat4 maskTransformation, glm::vec4 tint = glm::vec4(1.0f), - bool isInverted = false, bool isSameTexture = false); + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, sprite.ScaledBounds(), sprite.ScaledBounds(), + alpha, fadeRange, spriteTransformation, maskTransformation, + std::array{tint, tint, tint, tint}, + isInverted, isSameTexture); + } void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 spriteTransformation, glm::vec4 tint = glm::vec4(1.0f), @@ -107,7 +120,14 @@ class BaseRenderer { void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::vec2 spriteTopLeft, glm::vec2 maskTopLeft, glm::vec4 tint = glm::vec4(1.0f), - bool isInverted = false, bool isSameTexture = false); + bool isInverted = false, bool isSameTexture = false) { + DrawMaskedSprite(sprite, mask, + sprite.ScaledBounds().Translate(spriteTopLeft), + sprite.ScaledBounds().Translate(maskTopLeft), alpha, + fadeRange, glm::mat4(1.0f), glm::mat4(1.0f), + std::array{tint, tint, tint, tint}, + isInverted, isSameTexture); + } void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::vec2 spriteTopLeft, glm::vec4 tint = glm::vec4(1.0f), @@ -116,31 +136,37 @@ class BaseRenderer { {0.0f, 0.0f}, tint, isInverted, isSameTexture); } - virtual void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - int fadeRange, - std::span tints, - bool isInverted = false, - bool useMaskAlpha = true) = 0; + virtual void DrawMaskedSpriteOverlay( + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, int fadeRange, + glm::mat4 spriteTransformation, glm::mat4 maskTransformation, + std::span tints, bool isInverted = false, + bool useMaskAlpha = true) = 0; + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, - int fadeRange, glm::vec4 tint = glm::vec4(1.0f), + int fadeRange, glm::mat4 spriteTransformation, + glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true) { DrawMaskedSpriteOverlay(sprite, mask, spriteDest, maskDest, alpha, - fadeRange, + fadeRange, spriteTransformation, glm::mat4(1.0f), std::array{tint, tint, tint, tint}, isInverted, useMaskAlpha); } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, int alpha, - int fadeRange, glm::vec4 tint = glm::vec4(1.0f), + int fadeRange, + glm::mat4 spriteTransformation = glm::mat4(1.0f), + glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, bool useMaskAlpha = true) { DrawMaskedSpriteOverlay(sprite, mask, spriteDest, mask.ScaledBounds(), - alpha, fadeRange, tint, isInverted, useMaskAlpha); + alpha, fadeRange, spriteTransformation, + glm::mat4(1.0f), + std::array{tint, tint, tint, tint}, + isInverted, useMaskAlpha); } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, @@ -148,7 +174,13 @@ class BaseRenderer { glm::mat4 maskTransformation, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, - bool useMaskAlpha = true); + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, sprite.ScaledBounds(), + mask.ScaledBounds(), alpha, fadeRange, + spriteTransformation, maskTransformation, + std::array{tint, tint, tint, tint}, + isInverted, useMaskAlpha); + } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::mat4 spriteTransformation, @@ -164,7 +196,14 @@ class BaseRenderer { glm::vec2 spriteTopLeft, glm::vec2 maskTopLeft, glm::vec4 tint = glm::vec4(1.0f), bool isInverted = false, - bool useMaskAlpha = true); + bool useMaskAlpha = true) { + DrawMaskedSpriteOverlay(sprite, mask, + sprite.ScaledBounds().Translate(spriteTopLeft), + mask.ScaledBounds().Translate(maskTopLeft), alpha, + fadeRange, glm::mat4(1.0f), glm::mat4(1.0f), + std::array{tint, tint, tint, tint}, + isInverted, useMaskAlpha); + } void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, int alpha, int fadeRange, glm::vec2 spriteTopLeft, @@ -178,26 +217,28 @@ class BaseRenderer { virtual void DrawVertices(const SpriteSheet& sheet, std::span vertices, std::span indices, + glm::mat4 transformation = glm::mat4(1.0f), bool inverted = false) = 0; - void DrawVertices(const SpriteSheet& sheet, - std::span vertices, - std::span indices, glm::mat4 transformation, - bool inverted = false); + void DrawVertices(const SpriteSheet& sheet, std::span vertices, std::span indices, glm::vec2 offset, - bool inverted = false); - - void DrawVertices(const SpriteSheet& sheet, - std::span vertices, int width, - int height, bool inverted = false); + bool inverted = false) { + DrawVertices(sheet, vertices, indices, + glm::translate(glm::mat4(1.0f), glm::vec3(offset, 0.0f)), + inverted); + } void DrawVertices(const SpriteSheet& sheet, std::span vertices, int width, - int height, glm::mat4 transformation, + int height, glm::mat4 transformation = glm::mat4(1.0f), bool inverted = false); void DrawVertices(const SpriteSheet& sheet, std::span vertices, int width, - int height, glm::vec2 offset, bool inverted = false); + int height, glm::vec2 offset, bool inverted = false) { + DrawVertices(sheet, vertices, width, height, + glm::translate(glm::mat4(1.0f), glm::vec3(offset, 0.0f)), + inverted); + } void DrawQuad(const CornersQuad& dest, glm::vec4 color); @@ -268,7 +309,9 @@ class BaseRenderer { void QuadSetPosition(CornersQuad destQuad, glm::vec2* positions, int stride); - virtual glm::vec2 DesignToNDC(glm::vec2 designCoord) const = 0; + virtual glm::vec2 DesignToNDC(glm::vec2 designCoord) const { + return designCoord; + } Sprite RectSprite; }; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 50de6eb41..a1d52f5f1 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1133,6 +1133,7 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, + const glm::mat4 transformation, const std::span tints, const bool inverted, const bool disableBlend) { if (!Drawing) { @@ -1170,13 +1171,12 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } -void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - const int fadeRange, - const std::span tints, - const bool isInverted, - const bool isSameTexture) { +void Renderer::DrawMaskedSprite( + const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, const int fadeRange, + const glm::mat4 spriteTransformation, const glm::mat4 maskTransformation, + const std::span tints, const bool isInverted, + const bool isSameTexture) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawMaskedSpriteOverlay() called before BeginFrame()\n"); @@ -1255,6 +1255,7 @@ void Renderer::DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, void Renderer::DrawMaskedSpriteOverlay( const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, const int fadeRange, + const glm::mat4 spriteTransformation, const glm::mat4 maskTransformation, const std::span tints, const bool isInverted, const bool useMaskAlpha) { if (!Drawing) { @@ -1351,6 +1352,7 @@ void Renderer::DrawMaskedSpriteOverlay( void Renderer::DrawVertices(const SpriteSheet& sheet, const std::span vertices, const std::span indices, + const glm::mat4 transformation, const bool inverted) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index ca5da98cf..b0be4a9c4 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -63,30 +63,34 @@ class Renderer : public BaseRenderer { YUVFrame* CreateYUVFrame(float width, float height) override; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, - std::span tints, bool inverted, - bool disableBlend) override; + glm::mat4 transformation, std::span tints, + bool inverted, bool disableBlend) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, const CornersQuad& maskDest, int alpha, int fadeRange, + glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, std::span tints, bool isInverted, bool isSameTexture) override; + void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, + const CornersQuad& spriteDest, + const CornersQuad& maskDest, int alpha, + int fadeRange, glm::mat4 spriteTransformation, + glm::mat4 maskTransformation, + std::span tints, + bool isInverted, bool useMaskAlpha) override; + void DrawVertices(const SpriteSheet& sheet, std::span vertices, - std::span indices, bool inverted) override; + std::span indices, glm::mat4 transformation, + bool inverted) override; void DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, RectF const& dest, glm::vec4 tint, int alpha, int fadeRange, float effectCt) override; - void DrawMaskedSpriteOverlay(const Sprite& sprite, const Sprite& mask, - const CornersQuad& spriteDest, - const CornersQuad& maskDest, int alpha, - int fadeRange, - std::span tints, - bool isInverted, bool useMaskAlpha) override; - void DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, const RectF& dest, float alpha) override; diff --git a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl index 60eff8035..e65804731 100644 --- a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl +++ b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl @@ -7,8 +7,10 @@ out vec2 uv; out vec4 tint; out vec2 maskUV; +uniform mat4 Projection; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; maskUV = MaskUV; diff --git a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl index d8f3cc778..c5aef4068 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl @@ -5,8 +5,10 @@ layout (location = 3) in vec2 MaskUV; out vec2 uv; out vec2 maskUV; +uniform mat4 Projection; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * vec4(Position, 0.0, 1.0); uv = UV; maskUV = MaskUV; } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl index 60eff8035..d42ea4868 100644 --- a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl +++ b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl @@ -7,9 +7,13 @@ out vec2 uv; out vec4 tint; out vec2 maskUV; +uniform mat4 Projection; +uniform mat4 SpriteTransformation; +uniform mat4 MaskTransformation; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; - maskUV = MaskUV; + maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSprite_vert.glsl b/src/shaders/opengl/MaskedSprite_vert.glsl index 60eff8035..d42ea4868 100644 --- a/src/shaders/opengl/MaskedSprite_vert.glsl +++ b/src/shaders/opengl/MaskedSprite_vert.glsl @@ -7,9 +7,13 @@ out vec2 uv; out vec4 tint; out vec2 maskUV; +uniform mat4 Projection; +uniform mat4 SpriteTransformation; +uniform mat4 MaskTransformation; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; - maskUV = MaskUV; + maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_inverted_vert.glsl b/src/shaders/opengl/Sprite_inverted_vert.glsl index 3a11d26a8..0960a5292 100644 --- a/src/shaders/opengl/Sprite_inverted_vert.glsl +++ b/src/shaders/opengl/Sprite_inverted_vert.glsl @@ -5,8 +5,11 @@ layout(location = 2) in vec4 Tint; out vec2 uv; out vec4 tint; +uniform mat4 Projection; +uniform mat4 Transformation; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_vert.glsl b/src/shaders/opengl/Sprite_vert.glsl index 3a11d26a8..0960a5292 100644 --- a/src/shaders/opengl/Sprite_vert.glsl +++ b/src/shaders/opengl/Sprite_vert.glsl @@ -5,8 +5,11 @@ layout(location = 2) in vec4 Tint; out vec2 uv; out vec4 tint; +uniform mat4 Projection; +uniform mat4 Transformation; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/YUVFrame_vert.glsl b/src/shaders/opengl/YUVFrame_vert.glsl index 3a11d26a8..cdef1458d 100644 --- a/src/shaders/opengl/YUVFrame_vert.glsl +++ b/src/shaders/opengl/YUVFrame_vert.glsl @@ -5,8 +5,10 @@ layout(location = 2) in vec4 Tint; out vec2 uv; out vec4 tint; +uniform mat4 Projection; + void main() { - gl_Position = vec4(Position.x, Position.y, 0.0, 1.0); + gl_Position = Projection * vec4(Position, 0.0, 1.0); uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/ui/widgets/cc/backlogentry.cpp b/src/ui/widgets/cc/backlogentry.cpp index 671095e29..512d9cf2d 100644 --- a/src/ui/widgets/cc/backlogentry.cpp +++ b/src/ui/widgets/cc/backlogentry.cpp @@ -22,7 +22,7 @@ void BacklogEntry::Render() { mask.Bounds = bounds; Renderer->DrawMaskedSpriteOverlay(VoiceIcon, mask, bounds, Tint.a * 255, - 256, Tint, false, false); + 256, glm::mat4(1.0f), Tint, false, false); } if (BacklogPage->HasName) { From b95a41608b2ef7bfe52974c904d713e13305055d Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 20 May 2025 00:12:15 +0200 Subject: [PATCH 62/88] Updated DrawProcessedText to issue only one draw call --- src/renderer/renderer.cpp | 343 ++++++++++++++++++++++++-------------- 1 file changed, 214 insertions(+), 129 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 1e83f89e3..2550d828b 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -40,6 +40,53 @@ void InitRenderer() { Renderer->Init(); } +static void InsertQuad(std::vector& vertices, + const CornersQuad position, const CornersQuad uv, + const glm::vec4 tint, + const CornersQuad maskUV = RectF()) { + vertices.insert(vertices.end(), { + VertexBufferSprites{ + .Position = position.TopLeft, + .UV = uv.TopLeft, + .Tint = tint, + .MaskUV = maskUV.TopLeft, + }, + VertexBufferSprites{ + .Position = position.TopRight, + .UV = uv.TopRight, + .Tint = tint, + .MaskUV = maskUV.TopRight, + }, + VertexBufferSprites{ + .Position = position.BottomRight, + .UV = uv.BottomRight, + .Tint = tint, + .MaskUV = maskUV.BottomRight, + }, + VertexBufferSprites{ + .Position = position.BottomLeft, + .UV = uv.BottomLeft, + .Tint = tint, + .MaskUV = maskUV.BottomLeft, + }, + }); +} + +static void InsertQuad(std::vector& vertices, + std::vector& indices, uint16_t& maxIndex, + const CornersQuad position, const CornersQuad uv, + const glm::vec4 tint, + const CornersQuad maskUV = RectF()) { + InsertQuad(vertices, position, uv, tint, maskUV); + + const uint16_t tl = maxIndex; + const uint16_t tr = maxIndex + 1; + const uint16_t br = maxIndex + 2; + const uint16_t bl = maxIndex + 3; + indices.insert(indices.end(), {tl, tr, br, tl, br, bl}); + maxIndex += 4; +} + void BaseRenderer::DrawVertices( const SpriteSheet& sheet, const std::span vertices, const int width, @@ -122,165 +169,203 @@ void BaseRenderer::DrawProcessedText_BasicFont( std::span text, BasicFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, float outlineOpacity, SpriteSheet* maskedSheet) { - // cruddy mages outline - if (outlineMode != RendererOutlineMode::None) { - for (int i = 0; i < text.size(); i++) { - glm::vec4 color = RgbIntToFloat(text[i].Colors.OutlineColor); - color.a = outlineOpacity; - if (smoothstepGlyphOpacity) { - color.a *= glm::smoothstep(0.0f, 1.0f, text[i].Opacity); - } else { - color.a *= text[i].Opacity; - } - Sprite glyph = font->Glyph(text[i].CharId); + const size_t vertexCount = text.size() * 4; + const size_t indexCount = text.size() * 6; + std::vector vertices; + std::vector indices; + vertices.reserve(vertexCount); + indices.reserve(indexCount); + + uint16_t maxIndex = 0; + for (const ProcessedTextGlyph glyph : text) { + const CornersQuad dest = glyph.DestRect; + const CornersQuad destUV = CornersQuad(font->Glyph(glyph.CharId).Bounds) + .Scale({1.0f / font->Sheet.DesignWidth, + 1.0f / font->Sheet.DesignHeight}, + {0.0f, 0.0f}); + glm::vec4 color = RgbIntToFloat(glyph.Colors.TextColor); + color.a = opacity * (smoothstepGlyphOpacity + ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) + : glyph.Opacity); + + InsertQuad(vertices, indices, maxIndex, dest, destUV, color, dest); + } - RectF dest = text[i].DestRect; - switch (outlineMode) { - case RendererOutlineMode::Full: - dest.X--; - dest.Y--; - - if (maskedSheet) { - Sprite mask; - mask.Sheet = *maskedSheet; - mask.Bounds = dest; - DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, - glm::mat4(1.0f), color, false, i == 0); - } else { - DrawSprite(glyph, dest, color); - } - - dest.X++; - dest.Y++; - - [[fallthrough]]; - case RendererOutlineMode::BottomRight: - dest.X++; - dest.Y++; - - if (maskedSheet) { - Sprite mask; - mask.Sheet = *maskedSheet; - mask.Bounds = dest; - DrawMaskedSpriteOverlay(glyph, mask, dest, color.a * 255, 256, - glm::mat4(1.0f), color, false, i == 0); - } else { - DrawSprite(glyph, dest, color); - } - break; + if (outlineMode != RendererOutlineMode::None) { + // Add outline to the front of the buffers + vertices.reserve(vertexCount * 2); + vertices.insert(vertices.end(), vertices.begin(), vertices.end()); + + indices.resize(indexCount * 2); + std::transform(indices.begin(), indices.begin() + indexCount, + indices.begin() + indexCount, + [maxIndex](uint16_t index) { return index + maxIndex; }); + maxIndex += vertexCount; + + // Set the color of the outline + for (size_t i = 0; i < text.size(); i++) { + const ProcessedTextGlyph glyph = text[i]; + glm::vec4 color = RgbIntToFloat(glyph.Colors.OutlineColor); + color.a = + outlineOpacity * (smoothstepGlyphOpacity + ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) + : glyph.Opacity); + std::transform(vertices.begin() + i * 4, vertices.begin() + (i + 1) * 4, + vertices.begin() + i * 4, [color](auto vertex) { + vertex.Tint = color; + return vertex; + }); + } - default: - ImpLogSlow(LogLevel::Warning, LogChannel::Render, - "Unexpected outline mode!"); - break; + const auto translateVertex = [](VertexBufferSprites vertex, + const glm::vec2 offset) { + vertex.Position += offset; + return vertex; + }; + + switch (outlineMode) { + case RendererOutlineMode::Full: { + // Add bottom-right outline + vertices.reserve(vertexCount * 3); + vertices.insert(vertices.begin() + vertexCount, vertices.begin(), + vertices.begin() + vertexCount); + + indices.resize(indexCount * 3); + std::transform(indices.begin(), indices.begin() + indexCount, + indices.begin() + indexCount * 2, + [maxIndex](uint16_t index) { return index + maxIndex; }); + maxIndex += vertexCount; + + // Translate outlines + const auto glyphsBegin = vertices.begin() + vertexCount * 2; + const auto glyphsEnd = vertices.end(); + std::transform(glyphsBegin, glyphsEnd, vertices.begin(), + [translateVertex](auto vertex) { + return translateVertex(vertex, {-1.0f, -1.0f}); + }); + std::transform(glyphsBegin, glyphsEnd, vertices.begin() + vertexCount, + [translateVertex](auto vertex) { + return translateVertex(vertex, {1.0f, 1.0f}); + }); + + break; } - } - } - for (int i = 0; i < text.size(); i++) { - glm::vec4 color = RgbIntToFloat(text[i].Colors.TextColor); - color.a = opacity; + case RendererOutlineMode::BottomRight: { + std::transform(vertices.begin(), vertices.end(), vertices.begin(), + [translateVertex](auto vertex) { + return translateVertex(vertex, {-1.0f, -1.0f}); + }); - if (smoothstepGlyphOpacity) { - color.a *= glm::smoothstep(0.0f, 1.0f, text[i].Opacity); - } else { - color.a *= text[i].Opacity; - } + break; + } - if (maskedSheet) { - Sprite mask; - mask.Sheet = *maskedSheet; - mask.Bounds = text[i].DestRect; - DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, - text[i].DestRect, color.a * 255, 256, - glm::mat4(1.0f), color, false, false); - } else { - DrawSprite(font->Glyph(text[i].CharId), text[i].DestRect, color); + default: + ImpLogSlow(LogLevel::Warning, LogChannel::Render, + "Unexpected outline mode!"); + break; } } + + DrawVertices(font->Sheet, vertices, indices); } void BaseRenderer::DrawProcessedText_LBFont( std::span text, LBFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, float outlineOpacity, SpriteSheet* maskedSheet) { - if (outlineMode != RendererOutlineMode::None) { - for (int i = 0; i < text.size(); i++) { - glm::vec4 color = RgbIntToFloat(text[i].Colors.OutlineColor); - color.a = outlineOpacity; - if (smoothstepGlyphOpacity) { - color.a *= glm::smoothstep(0.0f, 1.0f, text[i].Opacity); - } else { - color.a *= text[i].Opacity; - } + const size_t vertexCount = text.size() * 4; + const size_t indexCount = text.size() * 6; + std::vector indices; + indices.reserve(indexCount); - float scaleX = text[i].DestRect.Height / font->BitmapEmWidth; - float scaleY = text[i].DestRect.Height / font->BitmapEmHeight; - RectF outlineDest; + for (size_t i = 0; i < text.size(); i++) { + const uint16_t tl = i * 4; + const uint16_t tr = tl + 1; + const uint16_t br = tl + 2; + const uint16_t bl = tl + 3; + + indices.insert(indices.end(), {tl, tr, br, tl, br, bl}); + } + if (outlineMode != RendererOutlineMode::None) { + std::vector outlineVertices; + outlineVertices.reserve(vertexCount); + + for (const ProcessedTextGlyph glyph : text) { + glm::vec4 color = RgbIntToFloat(glyph.Colors.OutlineColor); + color.a = + outlineOpacity * (smoothstepGlyphOpacity + ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) + : glyph.Opacity); + const CornersQuad destUV = + CornersQuad(font->OutlineGlyph(glyph.CharId).Bounds) + .Scale({1.0f / font->OutlineSheet.DesignWidth, + 1.0f / font->OutlineSheet.DesignHeight}, + {0.0f, 0.0f}); + + CornersQuad dest = RectF(); + const glm::vec2 scale = {glyph.DestRect.Height / font->BitmapEmWidth, + glyph.DestRect.Height / font->BitmapEmHeight}; switch (outlineMode) { - case RendererOutlineMode::Full: - outlineDest = - RectF(text[i].DestRect.X + scaleX * font->OutlineOffset.x, - text[i].DestRect.Y + scaleY * font->OutlineOffset.y, - scaleX * font->OutlineCellWidth, - scaleY * font->OutlineCellHeight); + case RendererOutlineMode::Full: { + dest = RectF(font->OutlineOffset.x, font->OutlineOffset.y, + font->OutlineCellWidth, font->OutlineCellHeight) + .Scale(scale, {0.0f, 0.0f}) + .Translate(glyph.DestRect.GetPos()); break; - case RendererOutlineMode::BottomRight: - outlineDest = RectF( - text[i].DestRect.X + scaleX * (font->OutlineOffset.x * 3 / 4), - text[i].DestRect.Y + scaleY * (font->OutlineOffset.y * 3 / 4), - scaleX * (font->OutlineCellWidth + font->OutlineOffset.x / 2), - scaleY * (font->OutlineCellHeight + font->OutlineOffset.y / 2)); + } + + case RendererOutlineMode::BottomRight: { + dest = RectF(font->OutlineOffset.x * 3 / 4, + font->OutlineOffset.y * 3 / 4, + font->OutlineCellWidth + font->OutlineOffset.x / 2, + font->OutlineCellHeight + font->OutlineOffset.y / 2) + .Scale(scale, {0.0f, 0.0f}) + .Translate(glyph.DestRect.GetPos()); break; + } + default: ImpLogSlow(LogLevel::Warning, LogChannel::Render, "Unexpected outline mode!"); break; } - if (maskedSheet) { - Sprite mask; - mask.Sheet = *maskedSheet; - mask.Bounds = outlineDest; - DrawMaskedSpriteOverlay(font->OutlineGlyph(text[i].CharId), mask, - outlineDest, color.a * 255, 256, - glm::mat4(1.0f), color, false, i == 0); - } else { - DrawSprite(font->OutlineGlyph(text[i].CharId), outlineDest, color); - } + InsertQuad(outlineVertices, dest, destUV, color, dest); } - } - for (int i = 0; i < text.size(); i++) { - glm::vec4 color = RgbIntToFloat(text[i].Colors.TextColor); - color.a = opacity; - if (smoothstepGlyphOpacity) { - color.a *= glm::smoothstep(0.0f, 1.0f, text[i].Opacity); - } else { - color.a *= text[i].Opacity; - } + DrawVertices(font->OutlineSheet, outlineVertices, indices); + } - float scaleX = text[i].DestRect.Height / font->BitmapEmWidth; - float scaleY = text[i].DestRect.Height / font->BitmapEmHeight; - - RectF foregroundDest = - RectF(text[i].DestRect.X + scaleX * font->ForegroundOffset.x, - text[i].DestRect.Y + scaleY * font->ForegroundOffset.y, - scaleX * font->CellWidth, scaleY * font->CellHeight); - if (maskedSheet) { - Sprite mask; - mask.Sheet = *maskedSheet; - mask.Bounds = foregroundDest; - DrawMaskedSpriteOverlay(font->Glyph(text[i].CharId), mask, foregroundDest, - color.a * 255, 256, glm::mat4(1.0f), color, false, - false); - } else { - DrawSprite(font->Glyph(text[i].CharId), foregroundDest, color); - } + std::vector vertices; + vertices.reserve(vertexCount); + + for (const ProcessedTextGlyph glyph : text) { + glm::vec2 scale = {glyph.DestRect.Height / font->BitmapEmWidth, + glyph.DestRect.Height / font->BitmapEmHeight}; + CornersQuad dest = RectF(font->ForegroundOffset.x, font->ForegroundOffset.y, + font->CellWidth, font->CellHeight) + .Scale(scale, {0.0f, 0.0f}) + .Translate(glyph.DestRect.GetPos()); + + const CornersQuad destUV = + CornersQuad(font->Glyph(glyph.CharId).Bounds) + .Scale({1.0f / font->OutlineSheet.DesignWidth, + 1.0f / font->OutlineSheet.DesignHeight}, + {0.0f, 0.0f}); + + glm::vec4 color = RgbIntToFloat(glyph.Colors.TextColor); + color.a = opacity * (smoothstepGlyphOpacity + ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) + : glyph.Opacity); + + InsertQuad(vertices, dest, destUV, color, dest); } - if (maskedSheet) Flush(); + DrawVertices(font->ForegroundSheet, vertices, indices); + + return; } void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, From 56c125e8b598f607dbb3fc9c6f81b8cb1fbf3b56 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 22 May 2025 02:19:36 +0200 Subject: [PATCH 63/88] Reduced cclcc system menu background rendering to single quad --- src/games/cclcc/systemmenu.cpp | 150 ++++++++----------------------- src/renderer/opengl/renderer.cpp | 10 +-- src/renderer/renderer.cpp | 28 ------ src/renderer/renderer.h | 11 --- src/util.cpp | 15 ++++ src/util.h | 4 + 6 files changed, 56 insertions(+), 162 deletions(-) diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 5b20d9ed2..146fc283c 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -154,95 +154,6 @@ void SystemMenu::Update(float dt) { } } -auto GenerateMatrix(CornersQuad const& corners) { - auto get2DIndex = [](int x, int y) { return x + (GridColCount + 1) * y; }; - constexpr int xVerticesCount = GridColCount + 1; - constexpr int yVerticesCount = GridRowCount + 1; - std::array topRowX; - std::array bottomRowX; - const float topRowWidthDelta = - (corners.TopRight.x - corners.TopLeft.x) / GridColCount; - const float bottomRowWidthDelta = - (corners.BottomRight.x - corners.BottomLeft.x) / GridColCount; - for (int i = 0; i < xVerticesCount; i++) { - topRowX[i] = corners.TopLeft.x + topRowWidthDelta * i; - bottomRowX[i] = corners.BottomLeft.x + bottomRowWidthDelta * i; - } - std::array leftColY; - std::array rightColY; - const float leftColHeightDelta = - (corners.BottomLeft.y - corners.TopLeft.y) / GridRowCount; - const float rightColHeightDelta = - (corners.BottomRight.y - corners.TopRight.y) / GridRowCount; - for (int i = 0; i < yVerticesCount; i++) { - leftColY[i] = corners.TopLeft.y + leftColHeightDelta * i; - rightColY[i] = corners.TopRight.y + rightColHeightDelta * i; - } - - std::array xDeltas; - for (int col = 0; col < xDeltas.size(); col++) { - xDeltas[col] = (bottomRowX[col] - topRowX[col]) / GridRowCount; - } - - std::array yDeltas; - for (int row = 0; row < yDeltas.size(); row++) { - yDeltas[row] = (rightColY[row] - leftColY[row]) / GridColCount; - } - - std::array matrix; - for (int row = 0; row < yVerticesCount; row++) { - for (int col = 0; col < xVerticesCount; col++) { - glm::vec2 pos = {topRowX[col] + xDeltas[col] * row, - leftColY[row] + yDeltas[row] * col}; - matrix[get2DIndex(col, row)] = pos; - } - } - return matrix; -} - -glm::vec2 TransformImageVertex(const glm::vec2 vertex, const glm::quat rotation, - const float scale, const glm::vec2 origin) { - glm::mat4 transformation = TransformationMatrix( - origin, {scale, scale}, {origin, 0.0f}, rotation, -origin); - - glm::vec4 transformedVertex = {vertex, 0.0f, 1.0f}; - transformedVertex = transformation * transformedVertex; - const float perspective = (transformedVertex.z / 2000.0f) + 1.0f; - transformedVertex *= perspective; - transformedVertex += glm::vec4(origin, 0.0f, 0.0f); - - return transformedVertex; -} - -void TransformImageCorners(CornersQuad& corners, const glm::quat rotation, - const float scale, const glm::vec2 origin) { - corners.BottomLeft = - TransformImageVertex(corners.BottomLeft, rotation, scale, origin); - corners.BottomRight = - TransformImageVertex(corners.BottomRight, rotation, scale, origin); - corners.TopLeft = - TransformImageVertex(corners.TopLeft, rotation, scale, origin); - corners.TopRight = - TransformImageVertex(corners.TopRight, rotation, scale, origin); -} - -void TransformImage(CornersQuad const& sprCorners, - CornersQuad const& destCorners, glm::quat rotation, - float scale, glm::vec2 origin, glm::vec2 sheetBounds, - SystemMenu::GridVertices& vertices) { - auto spriteVertices = GenerateMatrix(sprCorners); - auto displayVertices = GenerateMatrix(destCorners); - - for (size_t i = 0; i < vertices.size(); i++) { - vertices[i] = VertexBufferSprites{ - .Position = - TransformImageVertex(displayVertices[i], rotation, scale, origin), - .UV = spriteVertices[i] / sheetBounds, - .Tint = glm::vec4(1.0f), - }; - } -} - void SystemMenu::Render() { if (State != Hidden && !GetFlag(SF_TITLEMODE)) { if (MenuTransition.IsIn()) { @@ -253,10 +164,11 @@ void SystemMenu::Render() { // Renderer->DrawSprite(BackgroundFilter, RectF(0.0f, 0.0f, 1280.0f, // 720.0f), // glm::vec4(tint, alpha)); + float bgOffset = (ScrWork[SW_SYSSUBMENUCT] * 3000.0f * 0.03125f); - RectF bgSpriteBounds = SystemMenuBG.Bounds; - bgSpriteBounds.X += (BGPosition.x - 0.5f * bgOffset); - bgSpriteBounds.Y += BGPosition.y; + Sprite offsetSystemMenuBG(SystemMenuBG); + offsetSystemMenuBG.Bounds.Translate(BGPosition.x - 0.5f * bgOffset, + BGPosition.y); const float scale = (1000.0f - (ScrWork[SW_SYSMENUCT] * 400 / 32)) / 1000.0f; @@ -265,34 +177,42 @@ void SystemMenu::Render() { (ScrWork[SW_SYSMENUCT] * AngleMultiplier.y), (ScrWork[SW_SYSMENUCT] * AngleMultiplier.z)); - CornersQuad bgDisp = { - BGDispOffsetTopLeft, - BGDispOffsetBottomLeft, - BGDispOffsetTopRight, - BGDispOffsetBottomRight, + const auto transformation = [rotation, scale](glm::vec2 vertex) { + glm::mat4 transformation = TransformationMatrix( + BGTranslationOffset, {scale, scale}, {BGTranslationOffset, 0.0f}, + rotation, -BGTranslationOffset); + + glm::vec4 transformedVertex = {vertex, 0.0f, 1.0f}; + transformedVertex = transformation * transformedVertex; + const float perspective = (transformedVertex.z / 2000.0f) + 1.0f; + transformedVertex *= perspective; + transformedVertex += glm::vec4(BGTranslationOffset, 0.0f, 0.0f); + + return glm::vec2(transformedVertex); }; - TransformImage(bgSpriteBounds, bgDisp, rotation, scale, BGTranslationOffset, - SystemMenuBG.Sheet.GetDimensions(), Vertices); - Renderer->DrawVertices(SystemMenuBG.Sheet, Vertices, 21, 11); + + const CornersQuad bgDisp = + CornersQuad(BGDispOffsetTopLeft, BGDispOffsetBottomLeft, + BGDispOffsetTopRight, BGDispOffsetBottomRight) + .Transform(transformation); + Renderer->DrawSprite(offsetSystemMenuBG, bgDisp); if (!GetFlag(SF_SYSTEMMENUDIRECT)) { - CornersQuad frameDisp = { - glm::vec2{bgOffset, 0} + FrameOffsetTopLeft, - glm::vec2{bgOffset, 0} + FrameOffsetBottomLeft, - glm::vec2{bgOffset, 0} + FrameOffsetTopRight, - glm::vec2{bgOffset, 0} + FrameOffsetBottomRight, - }; - TransformImageCorners(frameDisp, rotation, scale, BGTranslationOffset); + const CornersQuad frameDisp = + CornersQuad(glm::vec2{bgOffset, 0} + FrameOffsetTopLeft, + glm::vec2{bgOffset, 0} + FrameOffsetBottomLeft, + glm::vec2{bgOffset, 0} + FrameOffsetTopRight, + glm::vec2{bgOffset, 0} + FrameOffsetBottomRight) + .Transform(transformation); Renderer->DrawSprite(SystemMenuFrame, frameDisp); - CornersQuad screenCapDisp = { - glm::vec2{bgOffset + 0, 0}, - glm::vec2{bgOffset + 0, Profile::DesignHeight}, - glm::vec2{bgOffset + Profile::DesignWidth, 0}, - glm::vec2{bgOffset + Profile::DesignWidth, Profile::DesignHeight}, - }; - TransformImageCorners(screenCapDisp, rotation, scale, - BGTranslationOffset); + const CornersQuad screenCapDisp = + CornersQuad( + glm::vec2{bgOffset + 0, 0}, + glm::vec2{bgOffset + 0, Profile::DesignHeight}, + glm::vec2{bgOffset + Profile::DesignWidth, 0}, + glm::vec2{bgOffset + Profile::DesignWidth, Profile::DesignHeight}) + .Transform(transformation); Renderer->DrawSprite(ScreenCap, screenCapDisp, glm::vec4(1.0f), false, true); } diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 8ffbfbe05..bea9b6a71 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -143,8 +143,8 @@ void Renderer::Init() { glGenSamplers(1, &Sampler); // Don't wrap textures - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); glSamplerParameteri(Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glSamplerParameteri(Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); @@ -522,10 +522,6 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "Transformation"), 1, GL_FALSE, &transformation[0][0]); - glBindSampler(2, Sampler); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); - // Push vertices VertexBufferSprites* vertexBuffer = (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); @@ -545,8 +541,6 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, // Flush again and bind back our buffer Flush(); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, GL_STATIC_DRAW); diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 2550d828b..f90239fdb 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -87,34 +87,6 @@ static void InsertQuad(std::vector& vertices, maxIndex += 4; } -void BaseRenderer::DrawVertices( - const SpriteSheet& sheet, - const std::span vertices, const int width, - const int height, const glm::mat4 transformation, const bool inverted) { - // Generate indices for triangles - std::vector indices; - indices.reserve((width - 1) * (height - 1) * 6); - for (int y = 0; y < height - 1; y++) { - for (int x = 0; x < width - 1; x++) { - int v0 = y * width + x; - int v1 = y * width + (x + 1); - int v2 = (y + 1) * width + x; - int v3 = (y + 1) * width + (x + 1); - - // First triangle - for (auto v : {v1, v0, v2}) { - indices.push_back(v); - } - // Second triangle - for (auto v : {v3, v1, v2}) { - indices.push_back(v); - } - } - } - - DrawVertices(sheet, vertices, indices, transformation, inverted); -} - void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, glm::vec2 topLeft, glm::vec4 tint, int alpha, int fadeRange, float effectCt, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 690c6a4c8..4aceb1bb9 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -228,17 +228,6 @@ class BaseRenderer { glm::translate(glm::mat4(1.0f), glm::vec3(offset, 0.0f)), inverted); } - void DrawVertices(const SpriteSheet& sheet, - std::span vertices, int width, - int height, glm::mat4 transformation = glm::mat4(1.0f), - bool inverted = false); - void DrawVertices(const SpriteSheet& sheet, - std::span vertices, int width, - int height, glm::vec2 offset, bool inverted = false) { - DrawVertices(sheet, vertices, width, height, - glm::translate(glm::mat4(1.0f), glm::vec3(offset, 0.0f)), - inverted); - } void DrawQuad(const CornersQuad& dest, glm::vec4 color); diff --git a/src/util.cpp b/src/util.cpp index 375c62f70..2f1aa6403 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -14,6 +14,16 @@ CornersQuad& CornersQuad::Transform(const glm::mat4 transformation) { return *this; } +CornersQuad& CornersQuad::Transform( + const std::function& transformation) { + TopLeft = transformation(TopLeft); + TopRight = transformation(TopRight); + BottomLeft = transformation(BottomLeft); + BottomRight = transformation(BottomRight); + + return *this; +} + CornersQuad& CornersQuad::Translate(const glm::vec2 offset) { TopLeft += offset; TopRight += offset; @@ -114,6 +124,11 @@ CornersQuad RectF::Transform(glm::mat4 transformation) const { return CornersQuad(*this).Transform(transformation); } +CornersQuad RectF::Transform( + const std::function& transformation) const { + return CornersQuad(*this).Transform(transformation); +} + RectF& RectF::Scale(const glm::vec2 scaling, const glm::vec2 origin) { Translate(-origin); diff --git a/src/util.h b/src/util.h index a531c9a2d..9a16544bd 100644 --- a/src/util.h +++ b/src/util.h @@ -162,6 +162,8 @@ struct RectF { static RectF Coalesce(const RectF& first, const RectF& second); CornersQuad Transform(glm::mat4 transformation) const; + CornersQuad Transform( + const std::function& transformation) const; RectF& Translate(glm::vec2 offset) { return *this += offset; } RectF& Translate(float dx, float dy) { return Translate({dx, dy}); } @@ -246,6 +248,8 @@ struct CornersQuad { } CornersQuad& Transform(glm::mat4 transformation); + CornersQuad& Transform( + const std::function& transformation); CornersQuad& Translate(glm::vec2 offset); CornersQuad& Translate(float dx, float dy) { return Translate({dx, dy}); } From ada6fa0c3c4d9018352cafe487111e1dea8e8546 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 5 Jun 2025 21:37:42 +0200 Subject: [PATCH 64/88] More optimized transformation generation --- src/util.cpp | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-) diff --git a/src/util.cpp b/src/util.cpp index 2f1aa6403..6e86025c0 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -193,23 +193,24 @@ glm::mat4 TransformationMatrix(const glm::vec3 scalingOrigin, const glm::vec3 translation) { glm::mat4 matrix(1.0f); - if (scalingOrigin != glm::vec3(0.0f)) - matrix = glm::translate(glm::mat4(1.0f), -scalingOrigin) * matrix; + if (rotationOrigin + translation != glm::vec3(0.0f)) { + matrix = glm::translate(matrix, rotationOrigin + translation); + } - if (scaling != glm::vec3(1.0f)) - matrix = glm::scale(glm::mat4(1.0f), scaling) * matrix; + if (rotation != glm::quat()) { + matrix *= glm::mat4_cast(normalize(rotation)); + } if (scalingOrigin - rotationOrigin != glm::vec3(0.0f)) { - matrix = glm::translate(glm::mat4(1.0f), scalingOrigin - rotationOrigin) * - matrix; + matrix = glm::translate(matrix, scalingOrigin - rotationOrigin); } - if (rotation != glm::quat()) - matrix = glm::mat4_cast(normalize(rotation)) * matrix; + if (scaling != glm::vec3(1.0f)) { + matrix = glm::scale(matrix, scaling); + } - if (rotationOrigin + translation != glm::vec3(0.0f)) { - matrix = - glm::translate(glm::mat4(1.0f), rotationOrigin + translation) * matrix; + if (scalingOrigin != glm::vec3(0.0f)) { + matrix = glm::translate(matrix, -scalingOrigin); } return matrix; From e6212ecb82a407593ac64181d3aa6169c589586f Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 3 Jun 2025 23:19:39 +0200 Subject: [PATCH 65/88] Severe rewrite of shader logic --- src/renderer/opengl/3d/renderable3d.cpp | 3 +- src/renderer/opengl/3d/renderable3d.h | 3 +- src/renderer/opengl/3d/scene.cpp | 7 +- src/renderer/opengl/3d/scene.h | 4 +- src/renderer/opengl/renderer.cpp | 270 ++++++++++-------------- src/renderer/opengl/renderer.h | 56 +++-- src/renderer/opengl/shader.cpp | 170 ++++++++++++++- src/renderer/opengl/shader.h | 219 +++++++++++++++++++ 8 files changed, 535 insertions(+), 197 deletions(-) diff --git a/src/renderer/opengl/3d/renderable3d.cpp b/src/renderer/opengl/3d/renderable3d.cpp index 844acb9df..bd3e0d2a3 100644 --- a/src/renderer/opengl/3d/renderable3d.cpp +++ b/src/renderer/opengl/3d/renderable3d.cpp @@ -61,7 +61,8 @@ static bool CurrentMaterialIsDepthWrite = false; static GLWindow* Window; -void Renderable3D::Init(GLWindow* window, ShaderCompiler* shaderCompiler) { +void Renderable3D::Init(GLWindow* window, + std::shared_ptr shaderCompiler) { assert(IsInit == false); ImpLog(LogLevel::Info, LogChannel::Renderable3D, "Initializing Renderable3D system\n"); diff --git a/src/renderer/opengl/3d/renderable3d.h b/src/renderer/opengl/3d/renderable3d.h index 3a51f9a44..e92be602f 100644 --- a/src/renderer/opengl/3d/renderable3d.h +++ b/src/renderer/opengl/3d/renderable3d.h @@ -12,7 +12,8 @@ enum RenderPass { RP_Outline = 0, RP_First = 1, RP_Second = 2, RP_Count }; class Renderable3D : public IRenderable3D { public: - static void Init(GLWindow* window, ShaderCompiler* shaderCompiler); + static void Init(GLWindow* window, + std::shared_ptr shaderCompiler); static void BeginFrame(IScene3D* scene, Camera* camera); void MakePlane() override; diff --git a/src/renderer/opengl/3d/scene.cpp b/src/renderer/opengl/3d/scene.cpp index 67190dcd1..aa1fa330f 100644 --- a/src/renderer/opengl/3d/scene.cpp +++ b/src/renderer/opengl/3d/scene.cpp @@ -11,10 +11,9 @@ namespace Impacto { namespace OpenGL { -Scene3D::Scene3D(GLWindow* window, ShaderCompiler* shaderCompiler) { - Window = window; - Shaders = shaderCompiler; -} +Scene3D::Scene3D(GLWindow* window, + std::shared_ptr shaderCompiler) + : Window(window), Shaders(shaderCompiler) {} void Scene3D::Init() { assert(IsInit == false); diff --git a/src/renderer/opengl/3d/scene.h b/src/renderer/opengl/3d/scene.h index d5fb2789a..acbd8ea7f 100644 --- a/src/renderer/opengl/3d/scene.h +++ b/src/renderer/opengl/3d/scene.h @@ -24,7 +24,7 @@ enum MSResolveMode { class Scene3D : public IScene3D { public: - Scene3D(GLWindow* window, ShaderCompiler* shaderCompiler); + Scene3D(GLWindow* window, std::shared_ptr shaderCompiler); void Init(); void Shutdown(); @@ -35,7 +35,7 @@ class Scene3D : public IScene3D { bool IsInit = false; GLWindow* Window; - ShaderCompiler* Shaders; + std::shared_ptr Shaders; void SetupFramebufferState(); void CleanFramebufferState(); diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index bea9b6a71..d740f5ac9 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -24,7 +24,7 @@ void Renderer::Init() { OpenGLWindow->Init(); Window = (BaseWindow*)OpenGLWindow; - Shaders = new ShaderCompiler(); + Shaders = std::make_shared(); if (Profile::GameFeatures & GameFeature::Scene3D) { Scene = new Scene3D(OpenGLWindow, Shaders); @@ -86,58 +86,23 @@ void Renderer::Init() { rectSheet.Texture = rectTexture.Submit(); RectSprite = Sprite(rectSheet, 0.0f, 0.0f, 1.0f, 1.0f); - // Set up sprite shader - ShaderProgramSprite = Shaders->Compile("Sprite"); - glUseProgram(ShaderProgramSprite); - glUniform1i(glGetUniformLocation(ShaderProgramSprite, "ColorMap"), 0); - ShaderProgramSpriteInverted = Shaders->Compile("Sprite_inverted"); - glUniform1i(glGetUniformLocation(ShaderProgramSpriteInverted, "ColorMap"), 0); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramSpriteInverted, "Projection"), 1, - GL_FALSE, &Projection[0][0]); - - ShaderProgramMaskedSprite = Shaders->Compile("MaskedSprite"); - glUseProgram(ShaderProgramMaskedSprite); - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "ColorMap"), 0); - MaskedIsInvertedLocation = - glGetUniformLocation(ShaderProgramMaskedSprite, "IsInverted"); - MaskedIsSameTextureLocation = - glGetUniformLocation(ShaderProgramMaskedSprite, "IsSameTexture"); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramMaskedSprite, "Projection"), 1, - GL_FALSE, &Projection[0][0]); - - ShaderProgramMaskedSpriteNoAlpha = Shaders->Compile("MaskedSpriteNoAlpha"); - glUseProgram(ShaderProgramMaskedSpriteNoAlpha); - glUniform1i( - glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "ColorMap"), 0); - MaskedNoAlphaIsInvertedLocation = - glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "IsInverted"); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramMaskedSpriteNoAlpha, "Projection"), 1, - GL_FALSE, &Projection[0][0]); - - ShaderProgramYUVFrame = Shaders->Compile("YUVFrame"); - glUseProgram(ShaderProgramYUVFrame); - glUniform1i(glGetUniformLocation(ShaderProgramYUVFrame, "Luma"), 0); - glUniformMatrix4fv(glGetUniformLocation(ShaderProgramYUVFrame, "Projection"), - 1, GL_FALSE, &Projection[0][0]); - YUVFrameCbLocation = glGetUniformLocation(ShaderProgramYUVFrame, "Cb"); - YUVFrameCrLocation = glGetUniformLocation(ShaderProgramYUVFrame, "Cr"); - YUVFrameIsAlphaLocation = - glGetUniformLocation(ShaderProgramYUVFrame, "IsAlpha"); - - ShaderProgramCCMessageBox = Shaders->Compile("CCMessageBoxSprite"); - glUseProgram(ShaderProgramCCMessageBox); - glUniform1i(glGetUniformLocation(ShaderProgramCCMessageBox, "ColorMap"), 0); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramCCMessageBox, "Projection"), 1, - GL_FALSE, &Projection[0][0]); - - ShaderProgramCHLCCMenuBackground = Shaders->Compile("CHLCCMenuBackground"); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramCHLCCMenuBackground, "Projection"), 1, - GL_FALSE, &Projection[0][0]); + // Set up shaders + SpriteShaderProgram = + std::make_unique(Shaders->Compile("Sprite")); + SpriteInvertedShaderProgram = std::make_unique( + Shaders->Compile("SpriteInverted")); + MaskedSpriteShaderProgram = + std::make_unique(Shaders->Compile("MaskedSprite")); + MaskedSpriteNoAlphaShaderProgram = + std::make_unique( + Shaders->Compile("MaskedSpriteNoAlpha")); + YUVFrameShaderProgram = + std::make_unique(Shaders->Compile("YUVFrame")); + CCMessageBoxShaderProgram = std::make_unique( + Shaders->Compile("CCMessageBoxSprite")); + CHLCCMenuBackgroundShaderProgram = + std::make_unique( + Shaders->Compile("CHLCCMenuBackground")); // No-mipmapping sampler glGenSamplers(1, &Sampler); @@ -187,7 +152,6 @@ void Renderer::BeginFrame2D() { Drawing = true; CurrentTexture = 0; - CurrentMode = R2D_None; VertexBufferFill = 0; IndexBufferFill = 0; @@ -295,19 +259,27 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - // Are we in sprite mode? - EnsureModeSprite(inverted); - - if (sprite.Sheet.IsScreenCap) { - Flush(); - } + if (sprite.Sheet.IsScreenCap) Flush(); // Set uniform variables - const GLuint shaderProgram = - inverted ? ShaderProgramSpriteInverted : ShaderProgramSprite; + if (inverted) { + SpriteInvertedUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .ColorMap = 0, + }; + + UseShader(SpriteInvertedShaderProgram, uniforms); + + } else { + SpriteUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .ColorMap = 0, + }; - glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "Transformation"), 1, - GL_FALSE, &transformation[0][0]); + UseShader(SpriteShaderProgram, uniforms); + } // Do we have the texture assigned? EnsureTextureBound(sprite.Sheet.Texture); @@ -361,30 +333,21 @@ void Renderer::DrawMaskedSprite( // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (CurrentMode != R2D_Masked) { - Flush(); - CurrentMode = R2D_Masked; - } - EnsureTextureBound(sprite.Sheet.Texture); // Set uniform variables - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramMaskedSprite); - - glUniform1i(glGetUniformLocation(ShaderProgramMaskedSprite, "Mask"), 2); - glUniform2f(glGetUniformLocation(ShaderProgramMaskedSprite, "Alpha"), - alphaRange, constAlpha); - - glUniform1i(MaskedIsInvertedLocation, isInverted); - glUniform1i(MaskedIsSameTextureLocation, isSameTexture); + MaskedSpriteUniforms uniforms{ + .Projection = Projection, + .SpriteTransformation = spriteTransformation, + .MaskTransformation = maskTransformation, + .ColorMap = 0, + .Mask = 2, + .Alpha = {alphaRange, constAlpha}, + .IsInverted = isInverted, + .IsSameTexture = isSameTexture, + }; - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramMaskedSprite, "SpriteTransformation"), - 1, GL_FALSE, &spriteTransformation[0][0]); - glUniformMatrix4fv( - glGetUniformLocation(ShaderProgramMaskedSprite, "MaskTransformation"), 1, - GL_FALSE, &maskTransformation[0][0]); + UseShader(MaskedSpriteShaderProgram, uniforms); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -436,39 +399,34 @@ void Renderer::DrawMaskedSpriteOverlay( // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - glBindVertexArray(VAOSprites); - GLuint shaderProgram; if (useMaskAlpha) { - shaderProgram = ShaderProgramMaskedSprite; + MaskedSpriteUniforms uniforms{ + .Projection = Projection, + .SpriteTransformation = spriteTransformation, + .MaskTransformation = maskTransformation, + .ColorMap = 0, + .Mask = 2, + .Alpha = {alphaRange, constAlpha}, + .IsInverted = isInverted, + .IsSameTexture = false, + }; + + UseShader(MaskedSpriteShaderProgram, uniforms); - if (CurrentMode != R2D_Masked || sprite.Sheet.IsScreenCap) { - Flush(); - CurrentMode = R2D_Masked; - } - glUseProgram(shaderProgram); - glUniform1i(MaskedIsInvertedLocation, isInverted); - glUniform1i(MaskedIsSameTextureLocation, false); } else { - shaderProgram = ShaderProgramMaskedSpriteNoAlpha; - - if (CurrentMode != R2D_MaskedNoAlpha || sprite.Sheet.IsScreenCap) { - Flush(); - CurrentMode = R2D_MaskedNoAlpha; - } - glUseProgram(shaderProgram); - glUniform1i(MaskedNoAlphaIsInvertedLocation, isInverted); + MaskedSpriteNoAlphaUniforms uniforms{ + .Projection = Projection, + .SpriteTransformation = spriteTransformation, + .MaskTransformation = maskTransformation, + .ColorMap = 0, + .Mask = 2, + .Alpha = {alphaRange, constAlpha}, + .IsInverted = isInverted, + }; + + UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); } - glUniform1i(glGetUniformLocation(shaderProgram, "Mask"), 2); - glUniform2f(glGetUniformLocation(shaderProgram, "Alpha"), alphaRange, - constAlpha); - - glUniformMatrix4fv( - glGetUniformLocation(shaderProgram, "SpriteTransformation"), 1, GL_FALSE, - &spriteTransformation[0][0]); - glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "MaskTransformation"), - 1, GL_FALSE, &maskTransformation[0][0]); - glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -512,15 +470,27 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, EnsureSpaceAvailable(vertices.size(), sizeof(VertexBufferSprites), indices.size()); - EnsureModeSprite(inverted); EnsureTextureBound(sheet.Texture); // Set uniform variables - const GLuint shaderProgram = - inverted ? ShaderProgramSpriteInverted : ShaderProgramSprite; + if (inverted) { + SpriteInvertedUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .ColorMap = 0, + }; - glUniformMatrix4fv(glGetUniformLocation(shaderProgram, "Transformation"), 1, - GL_FALSE, &transformation[0][0]); + UseShader(SpriteInvertedShaderProgram, uniforms); + + } else { + SpriteUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .ColorMap = 0, + }; + + UseShader(SpriteShaderProgram, uniforms); + } // Push vertices VertexBufferSprites* vertexBuffer = @@ -564,15 +534,14 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (CurrentMode != R2D_CCMessageBox) { - Flush(); - CurrentMode = R2D_CCMessageBox; - } - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramCCMessageBox); - glUniform1i(glGetUniformLocation(ShaderProgramCCMessageBox, "Mask"), 2); - glUniform4f(glGetUniformLocation(ShaderProgramCCMessageBox, "Alpha"), - alphaRange, constAlpha, effectCt, 0.0f); + CCMessageBoxUniforms uniforms{ + .Projection = Projection, + .ColorMap = 0, + .Mask = 2, + .Alpha = {alphaRange, constAlpha, effectCt, 0.0f}, + }; + + UseShader(CCMessageBoxShaderProgram, uniforms); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -620,17 +589,14 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (CurrentMode != R2D_CHLCCMenuBackground) { - Flush(); - CurrentMode = R2D_CHLCCMenuBackground; - } + CHLCCMenuBackgroundUniforms uniforms{ + .Projection = Projection, + .ColorMap = 0, + .Mask = 2, + .Alpha = alpha, + }; - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramCHLCCMenuBackground); - glUniform1i(glGetUniformLocation(ShaderProgramCCMessageBox, "ColorMap"), 0); - glUniform1i(glGetUniformLocation(ShaderProgramCCMessageBox, "Mask"), 2); - glUniform1f(glGetUniformLocation(ShaderProgramCHLCCMenuBackground, "Alpha"), - alpha); + UseShader(CHLCCMenuBackgroundShaderProgram, uniforms); glActiveTexture(GL_TEXTURE0); glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); @@ -683,20 +649,6 @@ void Renderer::EnsureTextureBound(GLuint texture) { } } -void Renderer::EnsureModeSprite(bool inverted) { - Renderer2DMode wantedMode = inverted ? R2D_SpriteInverted : R2D_Sprite; - if (CurrentMode != wantedMode) { - ImpLogSlow( - LogLevel::Trace, LogChannel::Render, - "Renderer2D flushing because mode {:d} is not R2D_Sprite/inverted\n", - to_underlying(CurrentMode)); - Flush(); - glBindVertexArray(VAOSprites); - glUseProgram(inverted ? ShaderProgramSpriteInverted : ShaderProgramSprite); - CurrentMode = wantedMode; - } -} - void Renderer::Flush() { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, @@ -725,15 +677,15 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, // Do we have space for one more sprite quad? EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (CurrentMode != R2D_YUVFrame) { - Flush(); - CurrentMode = R2D_YUVFrame; - } - glBindVertexArray(VAOSprites); - glUseProgram(ShaderProgramYUVFrame); - glUniform1i(YUVFrameCbLocation, 2); - glUniform1i(YUVFrameCrLocation, 4); - glUniform1i(YUVFrameIsAlphaLocation, alphaVideo); + YUVFrameUniforms uniforms{ + .Projection = Projection, + .Luma = 0, + .Cb = 2, + .Cr = 4, + .IsAlpha = alphaVideo, + }; + + UseShader(YUVFrameShaderProgram, uniforms); // Luma glActiveTexture(GL_TEXTURE0); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 3cb9dd000..2f3fa810e 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -16,17 +16,6 @@ namespace OpenGL { int constexpr NkMaxVertexMemory = 256 * 1024; int constexpr NkMaxElementMemory = 128 * 1024; -enum Renderer2DMode { - R2D_None, - R2D_Sprite, - R2D_SpriteInverted, - R2D_YUVFrame, - R2D_Masked, - R2D_MaskedNoAlpha, - R2D_CCMessageBox, - R2D_CHLCCMenuBackground, -}; - class Renderer : public BaseRenderer { public: void Init() override; @@ -101,28 +90,38 @@ class Renderer : public BaseRenderer { void DisableScissor() override; private: + std::unique_ptr SpriteShaderProgram; + std::unique_ptr SpriteInvertedShaderProgram; + std::unique_ptr MaskedSpriteShaderProgram; + std::unique_ptr MaskedSpriteNoAlphaShaderProgram; + std::unique_ptr YUVFrameShaderProgram; + std::unique_ptr CCMessageBoxShaderProgram; + std::unique_ptr CHLCCMenuBackgroundShaderProgram; + + const void* CurrentShaderProgram = nullptr; + + template + void UseShader(std::unique_ptr& shader, UniformsStruct uniforms) { + static_assert(std::is_base_of, ShaderType>()); + + if (CurrentShaderProgram != &shader) { + Flush(); + CurrentShaderProgram = &shader; + shader->Bind(); + } + + if (shader->GetUniforms() != uniforms) { + Flush(); + shader->UploadUniforms(uniforms); + } + } + void EnsureSpaceAvailable(int vertices, int vertexSize, int indices); void EnsureTextureBound(GLuint texture); - void EnsureModeSprite(bool inverted); void Flush() override; GLWindow* OpenGLWindow; - GLuint ShaderProgramSprite; - GLuint ShaderProgramSpriteInverted; - GLuint ShaderProgramMaskedSprite; - GLuint ShaderProgramMaskedSpriteNoAlpha; - GLuint ShaderProgramYUVFrame; - GLuint ShaderProgramCCMessageBox; - GLuint ShaderProgramCHLCCMenuBackground; - - GLuint YUVFrameCbLocation; - GLuint YUVFrameCrLocation; - GLuint YUVFrameIsAlphaLocation; - GLuint MaskedIsInvertedLocation; - GLuint MaskedIsSameTextureLocation; - GLuint MaskedNoAlphaIsInvertedLocation; - GLuint VBO; GLuint IBO; GLuint VAOSprites; @@ -136,7 +135,6 @@ class Renderer : public BaseRenderer { VertexBufferSize / (4 * sizeof(VertexBufferSprites)) * 6; GLuint CurrentTexture = 0; - Renderer2DMode CurrentMode = R2D_None; uint8_t VertexBuffer[VertexBufferSize]; int VertexBufferFill = 0; uint16_t IndexBuffer[IndexBufferCount]; @@ -146,7 +144,7 @@ class Renderer : public BaseRenderer { glm::ortho(0.0f, Profile::DesignWidth, Profile::DesignHeight, 0.0f); // ShaderCompiler compiler - ShaderCompiler* Shaders; + std::shared_ptr Shaders; }; } // namespace OpenGL diff --git a/src/renderer/opengl/shader.cpp b/src/renderer/opengl/shader.cpp index f66bea211..49c871861 100644 --- a/src/renderer/opengl/shader.cpp +++ b/src/renderer/opengl/shader.cpp @@ -238,5 +238,173 @@ GLuint ShaderCompiler::Compile(char const* name, ShaderParamMap const& params) { return program; } +SpriteShader::SpriteShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + TransformationLocation(glGetUniformLocation(programId, "Transformation")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.Transformation, TransformationLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); +} + +void SpriteShader::UploadUniforms(SpriteUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + UpdateVar(newUniforms.Transformation, Uniforms.Transformation, + TransformationLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); +} + +SpriteInvertedShader::SpriteInvertedShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + TransformationLocation(glGetUniformLocation(programId, "Transformation")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.Transformation, TransformationLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); +} + +void SpriteInvertedShader::UploadUniforms(SpriteInvertedUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + UpdateVar(newUniforms.Transformation, Uniforms.Transformation, + TransformationLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); +} + +YUVFrameShader::YUVFrameShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + LumaLocation(glGetUniformLocation(programId, "Luma")), + CbLocation(glGetUniformLocation(programId, "Cb")), + CrLocation(glGetUniformLocation(programId, "Cr")), + IsAlphaLocation(glGetUniformLocation(programId, "IsAlpha")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.Luma, LumaLocation); + UploadVar(Uniforms.Cb, CbLocation); + UploadVar(Uniforms.Cr, CrLocation); + UploadVar(Uniforms.IsAlpha, IsAlphaLocation); +} + +void YUVFrameShader::UploadUniforms(YUVFrameUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + + UpdateVar(newUniforms.Luma, Uniforms.Luma, LumaLocation); + UpdateVar(newUniforms.Cb, Uniforms.Cb, CbLocation); + UpdateVar(newUniforms.Cr, Uniforms.Cr, CrLocation); + UpdateVar(newUniforms.IsAlpha, Uniforms.IsAlpha, IsAlphaLocation); +} + +MaskedSpriteNoAlphaShader::MaskedSpriteNoAlphaShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + SpriteTransformationLocation( + glGetUniformLocation(programId, "SpriteTransformation")), + MaskTransformationLocation( + glGetUniformLocation(programId, "MaskTransformation")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")), + AlphaLocation(glGetUniformLocation(programId, "Alpha")), + IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); + UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Alpha, AlphaLocation); + UploadVar(Uniforms.IsInverted, IsInvertedLocation); +} + +void MaskedSpriteNoAlphaShader::UploadUniforms( + MaskedSpriteNoAlphaUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + UpdateVar(newUniforms.SpriteTransformation, Uniforms.SpriteTransformation, + SpriteTransformationLocation); + UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, + MaskTransformationLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); + UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); +} + +MaskedSpriteShader::MaskedSpriteShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + SpriteTransformationLocation( + glGetUniformLocation(programId, "SpriteTransformation")), + MaskTransformationLocation( + glGetUniformLocation(programId, "MaskTransformation")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")), + AlphaLocation(glGetUniformLocation(programId, "Alpha")), + IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")), + IsSameTextureLocation(glGetUniformLocation(programId, "IsSameTexture")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); + UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Alpha, AlphaLocation); + UploadVar(Uniforms.IsInverted, IsInvertedLocation); +} + +void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + UpdateVar(newUniforms.SpriteTransformation, Uniforms.SpriteTransformation, + SpriteTransformationLocation); + UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, + MaskTransformationLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); + UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); +} + +CCMessageBoxShader::CCMessageBoxShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")), + AlphaLocation(glGetUniformLocation(programId, "Alpha")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Alpha, AlphaLocation); +} + +void CCMessageBoxShader::UploadUniforms(CCMessageBoxUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); +} + +CHLCCMenuBackgroundShader::CHLCCMenuBackgroundShader(GLint programId) + : Shader(programId), + ProjectionLocation(glGetUniformLocation(programId, "Projection")), + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")), + AlphaLocation(glGetUniformLocation(programId, "Alpha")) { + UploadVar(Uniforms.Projection, ProjectionLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Alpha, AlphaLocation); +} + +void CHLCCMenuBackgroundShader::UploadUniforms( + CHLCCMenuBackgroundUniforms newUniforms) { + UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); + + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); +} + } // namespace OpenGL -} // namespace Impacto \ No newline at end of file +} // namespace Impacto diff --git a/src/renderer/opengl/shader.h b/src/renderer/opengl/shader.h index 360a99b76..eee64ea33 100644 --- a/src/renderer/opengl/shader.h +++ b/src/renderer/opengl/shader.h @@ -74,5 +74,224 @@ class ShaderCompiler { char const* params); }; +template +class Shader { + public: + Shader(GLuint programId) : ProgramId(programId) { Bind(); } + + ~Shader() { glDeleteProgram(ProgramId); } + + void Bind() { glUseProgram(ProgramId); } + + UniformsStruct GetUniforms() { return Uniforms; } + virtual void UploadUniforms(UniformsStruct uniforms) = 0; + + protected: + const GLuint ProgramId; + + UniformsStruct Uniforms; + + void UploadVar(bool value, GLint location) { glUniform1i(location, value); } + void UploadVar(int value, GLint location) { glUniform1i(location, value); } + void UploadVar(float value, GLint location) { glUniform1f(location, value); } + void UploadVar(glm::vec2 value, GLint location) { + glUniform2fv(location, 1, &value[0]); + } + void UploadVar(glm::vec4 value, GLint location) { + glUniform4fv(location, 1, &value[0]); + } + void UploadVar(glm::mat4 value, GLint location) { + glUniformMatrix4fv(location, 1, GL_FALSE, &value[0][0]); + } + + template + void UpdateVar(T newValue, T& oldValue, GLint location) { + if (newValue != oldValue) { + oldValue = newValue; + UploadVar(newValue, location); + } + } +}; + +struct SpriteUniforms { + bool operator==(const SpriteUniforms& other) const = default; + + glm::mat4 Projection; + glm::mat4 Transformation; + + int ColorMap; +}; + +class SpriteShader : public Shader { + public: + SpriteShader(GLint programId); + + void UploadUniforms(SpriteUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + const GLint TransformationLocation; + + const GLint ColorMapLocation; +}; + +struct SpriteInvertedUniforms { + bool operator==(const SpriteInvertedUniforms& other) const = default; + + glm::mat4 Projection; + glm::mat4 Transformation; + + int ColorMap; +}; + +class SpriteInvertedShader : public Shader { + public: + SpriteInvertedShader(GLint programId); + + void UploadUniforms(SpriteInvertedUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + const GLint TransformationLocation; + + const GLint ColorMapLocation; +}; + +struct YUVFrameUniforms { + bool operator==(const YUVFrameUniforms& other) const = default; + + glm::mat4 Projection; + + int Luma; + int Cb; + int Cr; + bool IsAlpha; +}; + +class YUVFrameShader : public Shader { + public: + YUVFrameShader(GLint programId); + + void UploadUniforms(YUVFrameUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + + const GLint LumaLocation; + const GLint CbLocation; + const GLint CrLocation; + const GLint IsAlphaLocation; +}; + +struct MaskedSpriteNoAlphaUniforms { + bool operator==(const MaskedSpriteNoAlphaUniforms& other) const = default; + + glm::mat4 Projection = glm::mat4(); + glm::mat4 SpriteTransformation = glm::mat4(); + glm::mat4 MaskTransformation = glm::mat4(); + + int ColorMap = 0; + int Mask = 2; + glm::vec2 Alpha = glm::vec2(); + bool IsInverted = false; +}; + +class MaskedSpriteNoAlphaShader : public Shader { + public: + MaskedSpriteNoAlphaShader(GLint programId); + + void UploadUniforms(MaskedSpriteNoAlphaUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + const GLint SpriteTransformationLocation; + const GLint MaskTransformationLocation; + + const GLint ColorMapLocation; + const GLint MaskLocation; + const GLint AlphaLocation; + const GLint IsInvertedLocation; +}; + +struct MaskedSpriteUniforms { + bool operator==(const MaskedSpriteUniforms& other) const = default; + + glm::mat4 Projection = glm::mat4(); + glm::mat4 SpriteTransformation = glm::mat4(); + glm::mat4 MaskTransformation = glm::mat4(); + + int ColorMap = 0; + int Mask = 2; + glm::vec2 Alpha = glm::vec2(); + bool IsInverted = false; + bool IsSameTexture = false; +}; + +class MaskedSpriteShader : public Shader { + public: + MaskedSpriteShader(GLint programId); + + void UploadUniforms(MaskedSpriteUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + const GLint SpriteTransformationLocation; + const GLint MaskTransformationLocation; + + const GLint ColorMapLocation; + const GLint MaskLocation; + const GLint AlphaLocation; + const GLint IsInvertedLocation; + const GLint IsSameTextureLocation; +}; + +struct CCMessageBoxUniforms { + bool operator==(const CCMessageBoxUniforms& other) const = default; + + glm::mat4 Projection = glm::mat4(); + + int ColorMap = 0; + int Mask = 2; + glm::vec4 Alpha = glm::vec4(); +}; + +class CCMessageBoxShader : public Shader { + public: + CCMessageBoxShader(GLint programId); + + void UploadUniforms(CCMessageBoxUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + + const GLint ColorMapLocation; + const GLint MaskLocation; + const GLint AlphaLocation; +}; + +struct CHLCCMenuBackgroundUniforms { + bool operator==(const CHLCCMenuBackgroundUniforms& other) const = default; + + glm::mat4 Projection = glm::mat4(); + + int ColorMap = 0; + int Mask = 0; + float Alpha = 0.0f; +}; + +class CHLCCMenuBackgroundShader : public Shader { + public: + CHLCCMenuBackgroundShader(GLint programId); + + void UploadUniforms(CHLCCMenuBackgroundUniforms uniforms) override; + + private: + const GLint ProjectionLocation; + + const GLint ColorMapLocation; + const GLint MaskLocation; + const GLint AlphaLocation; +}; + } // namespace OpenGL } // namespace Impacto \ No newline at end of file From c2db35430e818022f49254e4a1acea4eec67f16c Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Fri, 6 Jun 2025 19:47:09 +0200 Subject: [PATCH 66/88] Overhauled vertex and index buffers --- src/renderer/opengl/renderer.cpp | 288 +++++++++++-------------------- src/renderer/opengl/renderer.h | 31 +++- src/renderer/renderer.cpp | 151 ++++++++-------- src/spritesheet.h | 6 + src/util.cpp | 8 + src/util.h | 15 ++ 6 files changed, 226 insertions(+), 273 deletions(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index d740f5ac9..cd518e6e8 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -31,35 +31,11 @@ void Renderer::Init() { Scene->Init(); } - // Fill index buffer with quads - int index = 0; - int vertex = 0; - while (index + 6 <= IndexBufferCount) { - // bottom-left -> top-left -> top-right - IndexBuffer[index] = vertex + 0; - IndexBuffer[index + 1] = vertex + 1; - IndexBuffer[index + 2] = vertex + 2; - // bottom-left -> top-right -> bottom-right - IndexBuffer[index + 3] = vertex + 0; - IndexBuffer[index + 4] = vertex + 2; - IndexBuffer[index + 5] = vertex + 3; - index += 6; - vertex += 4; - } - // Generate buffers glGenBuffers(1, &VBO); glGenBuffers(1, &IBO); glGenVertexArrays(1, &VAOSprites); - glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, VertexBufferSize, NULL, GL_STREAM_DRAW); - - glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, - GL_STATIC_DRAW); - GLC::InitializeFramebuffers(); // Specify vertex layouts @@ -152,8 +128,10 @@ void Renderer::BeginFrame2D() { Drawing = true; CurrentTexture = 0; - VertexBufferFill = 0; - IndexBufferFill = 0; + + VertexCount = 0; + IndexCount = 0; + NextFreeIndex = 0; glDisable(GL_CULL_FACE); @@ -246,6 +224,63 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { return (YUVFrame*)frame; } +void Renderer::InsertVertices( + const std::span vertices, + const std::span indices) { + if (vertices.empty() || indices.empty()) return; + assert(indices.size() <= MaxIndexCount); + + if (IndexCount + indices.size() > MaxIndexCount) Flush(); + + const uint16_t maxIndex = *std::max_element(indices.begin(), indices.end()); + + std::copy(vertices.begin(), vertices.end(), + VertexBuffer.begin() + VertexCount); + VertexCount += vertices.size(); + + std::transform( + indices.begin(), indices.end(), IndexBuffer.begin() + IndexCount, + [this](uint16_t index) { return index + this->NextFreeIndex; }); + IndexCount += indices.size(); + + NextFreeIndex += maxIndex + 1; +} + +void Renderer::InsertVerticesQuad(const CornersQuad pos, const CornersQuad uv, + const std::span tints, + const CornersQuad maskUV) { + const std::array vertices = { + VertexBufferSprites{ + .Position = pos.BottomLeft, + .UV = uv.BottomLeft, + .Tint = tints[0], + .MaskUV = maskUV.BottomLeft, + }, + VertexBufferSprites{ + .Position = pos.TopLeft, + .UV = uv.TopLeft, + .Tint = tints[1], + .MaskUV = maskUV.TopLeft, + }, + VertexBufferSprites{ + .Position = pos.TopRight, + .UV = uv.TopRight, + .Tint = tints[2], + .MaskUV = maskUV.TopRight, + }, + VertexBufferSprites{ + .Position = pos.BottomRight, + .UV = uv.BottomRight, + .Tint = tints[3], + .MaskUV = maskUV.BottomRight, + }, + }; + + const std::array indices = {0, 1, 2, 0, 2, 3}; + + InsertVertices(vertices, indices); +} + void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const glm::mat4 transformation, const std::span tints, @@ -256,9 +291,6 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, return; } - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (sprite.Sheet.IsScreenCap) Flush(); // Set uniform variables @@ -291,22 +323,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), - &vertices[0].UV, sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; + CornersQuad uvDest = sprite.NormalizedBounds(); + if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); + InsertVerticesQuad(dest, uvDest, tints); if (disableBlend) { Flush(); @@ -330,9 +349,6 @@ void Renderer::DrawMaskedSprite( const float alphaRange = 256.0f / fadeRange; const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - EnsureTextureBound(sprite.Sheet.Texture); // Set uniform variables @@ -358,26 +374,11 @@ void Renderer::DrawMaskedSprite( // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), - &vertices[0].UV, sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - QuadSetUV(maskDest, sprite.Bounds.GetSize(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; + CornersQuad uvDest = sprite.NormalizedBounds(); + if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); + CornersQuad maskUVDest = CornersQuad(maskDest).Scale( + {1.0f / sprite.Bounds.Width, 1.0f / sprite.Bounds.Height}, {0.0f, 0.0f}); + InsertVerticesQuad(spriteDest, uvDest, tints, maskUVDest); } void Renderer::DrawMaskedSpriteOverlay( @@ -396,9 +397,6 @@ void Renderer::DrawMaskedSpriteOverlay( const float alphaRange = 256.0f / fadeRange; const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - if (useMaskAlpha) { MaskedSpriteUniforms uniforms{ .Projection = Projection, @@ -436,22 +434,8 @@ void Renderer::DrawMaskedSpriteOverlay( // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - - QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; + InsertVerticesQuad(spriteDest, sprite.NormalizedBounds(), tints, + mask.NormalizedBounds()); } void Renderer::DrawVertices(const SpriteSheet& sheet, @@ -464,12 +448,6 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, return; } - // The index buffer needs to be flushed - Flush(); - - EnsureSpaceAvailable(vertices.size(), sizeof(VertexBufferSprites), - indices.size()); - EnsureTextureBound(sheet.Texture); // Set uniform variables @@ -492,28 +470,21 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, UseShader(SpriteShaderProgram, uniforms); } - // Push vertices - VertexBufferSprites* vertexBuffer = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += vertices.size_bytes(); - - const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { - if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; - return info; - }; - std::transform(vertices.begin(), vertices.end(), vertexBuffer, - vertexInfoToNDC); + if (sheet.IsScreenCap) { + std::vector flippedVertices; + flippedVertices.reserve(vertices.size()); - // Push indices - IndexBufferFill += indices.size(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, indices.size_bytes(), indices.data(), - GL_STATIC_DRAW); + const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { + if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; + return info; + }; + std::transform(vertices.begin(), vertices.end(), flippedVertices.begin(), + vertexInfoToNDC); - // Flush again and bind back our buffer - Flush(); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, - IndexBufferCount * sizeof(IndexBuffer[0]), IndexBuffer, - GL_STATIC_DRAW); + InsertVertices(flippedVertices, indices); + } else { + InsertVertices(vertices, indices); + } } void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, @@ -531,9 +502,6 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, float alphaRange = 256.0f / fadeRange; float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - CCMessageBoxUniforms uniforms{ .Projection = Projection, .ColorMap = 0, @@ -552,25 +520,9 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - if (sprite.Sheet.IsScreenCap) { - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), - &vertices[0].UV, sizeof(VertexBufferSprites)); - } else { - QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - } - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; + CornersQuad uvDest = sprite.NormalizedBounds(); + if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); + InsertVerticesQuad(dest, uvDest, tint, mask.NormalizedBounds()); } void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, @@ -586,9 +538,6 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, else if (alpha > 1.0f) alpha = 1.0f; - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - CHLCCMenuBackgroundUniforms uniforms{ .Projection = Projection, .ColorMap = 0, @@ -609,31 +558,8 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUVFlipped(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, - sizeof(VertexBufferSprites)); - - QuadSetUV(mask.Bounds, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, - sizeof(VertexBufferSprites)); - - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); -} - -void Renderer::EnsureSpaceAvailable(int vertices, int vertexSize, int indices) { - if (VertexBufferFill + vertices * vertexSize > VertexBufferSize || - IndexBufferFill + indices > IndexBufferCount) { - ImpLogSlow( - LogLevel::Trace, LogChannel::Render, - "Renderer->EnsureSpaceAvailable flushing because buffers full at " - "VertexBufferFill=0x{:08x},IndexBufferFill=0x{:08x}\n", - VertexBufferFill, IndexBufferFill); - Flush(); - } + InsertVerticesQuad(dest, sprite.NormalizedBounds(), glm::vec4(1.0f), + mask.NormalizedBounds()); } void Renderer::EnsureTextureBound(GLuint texture) { @@ -655,14 +581,22 @@ void Renderer::Flush() { "Renderer->Flush() called before BeginFrame()\n"); return; } - if (VertexBufferFill > 0 && IndexBufferFill > 0) { + if (VertexCount != 0 && IndexCount != 0) { glBindBuffer(GL_ARRAY_BUFFER, VBO); - // TODO: better to specify the whole thing or just this? - glBufferSubData(GL_ARRAY_BUFFER, 0, VertexBufferFill, VertexBuffer); - glDrawElements(GL_TRIANGLES, IndexBufferFill, GL_UNSIGNED_SHORT, 0); + glBufferData(GL_ARRAY_BUFFER, VertexCount * sizeof(VertexBufferSprites), + VertexBuffer.data(), GL_DYNAMIC_DRAW); + + glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); + glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexCount * sizeof(uint16_t), + IndexBuffer.data(), GL_DYNAMIC_DRAW); + + glDrawElements(GL_TRIANGLES, IndexCount, GL_UNSIGNED_SHORT, 0); } - IndexBufferFill = 0; - VertexBufferFill = 0; + + VertexCount = 0; + IndexCount = 0; + NextFreeIndex = 0; + CurrentTexture = 0; } @@ -674,9 +608,6 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, return; } - // Do we have space for one more sprite quad? - EnsureSpaceAvailable(4, sizeof(VertexBufferSprites), 6); - YUVFrameUniforms uniforms{ .Projection = Projection, .Luma = 0, @@ -703,18 +634,7 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, // OK, all good, make quad - VertexBufferSprites* vertices = - (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); - VertexBufferFill += 4 * sizeof(VertexBufferSprites); - - IndexBufferFill += 6; - - QuadSetUV(RectF(0.0f, 0.0f, frame.Width, frame.Height), - {frame.Width, frame.Height}, &vertices[0].UV, - sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); - - for (int i = 0; i < 4; i++) vertices[i].Tint = tint; + InsertVerticesQuad(dest, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); } void Renderer::CaptureScreencap(Sprite& sprite) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 2f3fa810e..fca8c1a12 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -116,10 +116,19 @@ class Renderer : public BaseRenderer { } } - void EnsureSpaceAvailable(int vertices, int vertexSize, int indices); void EnsureTextureBound(GLuint texture); void Flush() override; + void InsertVertices(std::span vertices, + std::span indices); + void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, + std::span tints, + CornersQuad maskUV = RectF()); + void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, glm::vec4 tint, + CornersQuad maskUV = RectF()) { + InsertVerticesQuad(pos, uv, std::array{tint, tint, tint, tint}, maskUV); + } + GLWindow* OpenGLWindow; GLuint VBO; @@ -130,15 +139,19 @@ class Renderer : public BaseRenderer { bool Drawing = false; - static int constexpr VertexBufferSize = 1024 * 1024; - static int constexpr IndexBufferCount = - VertexBufferSize / (4 * sizeof(VertexBufferSprites)) * 6; - GLuint CurrentTexture = 0; - uint8_t VertexBuffer[VertexBufferSize]; - int VertexBufferFill = 0; - uint16_t IndexBuffer[IndexBufferCount]; - int IndexBufferFill = 0; + + static constexpr size_t MaxVertexCount = + 1024 * 1024 / sizeof(VertexBufferSprites); + static constexpr uint16_t MaxIndexCount = + std::numeric_limits::max(); + + std::array VertexBuffer; + std::array IndexBuffer; + + size_t VertexCount = 0; + size_t IndexCount = 0; + uint16_t NextFreeIndex = 0; const glm::mat4 Projection = glm::ortho(0.0f, Profile::DesignWidth, Profile::DesignHeight, 0.0f); diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index f90239fdb..30b5960b9 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -40,51 +40,34 @@ void InitRenderer() { Renderer->Init(); } -static void InsertQuad(std::vector& vertices, +static void InsertQuad(const std::span vertices, const CornersQuad position, const CornersQuad uv, const glm::vec4 tint, const CornersQuad maskUV = RectF()) { - vertices.insert(vertices.end(), { - VertexBufferSprites{ - .Position = position.TopLeft, - .UV = uv.TopLeft, - .Tint = tint, - .MaskUV = maskUV.TopLeft, - }, - VertexBufferSprites{ - .Position = position.TopRight, - .UV = uv.TopRight, - .Tint = tint, - .MaskUV = maskUV.TopRight, - }, - VertexBufferSprites{ - .Position = position.BottomRight, - .UV = uv.BottomRight, - .Tint = tint, - .MaskUV = maskUV.BottomRight, - }, - VertexBufferSprites{ - .Position = position.BottomLeft, - .UV = uv.BottomLeft, - .Tint = tint, - .MaskUV = maskUV.BottomLeft, - }, - }); -} - -static void InsertQuad(std::vector& vertices, - std::vector& indices, uint16_t& maxIndex, - const CornersQuad position, const CornersQuad uv, - const glm::vec4 tint, - const CornersQuad maskUV = RectF()) { - InsertQuad(vertices, position, uv, tint, maskUV); - - const uint16_t tl = maxIndex; - const uint16_t tr = maxIndex + 1; - const uint16_t br = maxIndex + 2; - const uint16_t bl = maxIndex + 3; - indices.insert(indices.end(), {tl, tr, br, tl, br, bl}); - maxIndex += 4; + vertices[0] = { + .Position = position.BottomLeft, + .UV = uv.BottomLeft, + .Tint = tint, + .MaskUV = maskUV.BottomLeft, + }; + vertices[1] = { + .Position = position.TopLeft, + .UV = uv.TopLeft, + .Tint = tint, + .MaskUV = maskUV.TopLeft, + }; + vertices[2] = { + .Position = position.TopRight, + .UV = uv.TopRight, + .Tint = tint, + .MaskUV = maskUV.TopRight, + }; + vertices[3] = { + .Position = position.BottomRight, + .UV = uv.BottomRight, + .Tint = tint, + .MaskUV = maskUV.BottomRight, + }; } void BaseRenderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, @@ -145,27 +128,40 @@ void BaseRenderer::DrawProcessedText_BasicFont( const size_t indexCount = text.size() * 6; std::vector vertices; std::vector indices; - vertices.reserve(vertexCount); - indices.reserve(indexCount); + vertices.resize(vertexCount); + indices.resize(indexCount); + + for (size_t i = 0; i < text.size(); i++) { + const uint16_t bl = i * 4; + const uint16_t tl = bl + 1; + const uint16_t tr = bl + 2; + const uint16_t br = bl + 3; + + indices[i * 6 + 0] = bl; + indices[i * 6 + 1] = tl; + indices[i * 6 + 2] = tr; + indices[i * 6 + 3] = bl; + indices[i * 6 + 4] = tr; + indices[i * 6 + 5] = br; + } uint16_t maxIndex = 0; - for (const ProcessedTextGlyph glyph : text) { + for (size_t i = 0; i < text.size(); i++) { + const ProcessedTextGlyph glyph = text[i]; + const CornersQuad dest = glyph.DestRect; - const CornersQuad destUV = CornersQuad(font->Glyph(glyph.CharId).Bounds) - .Scale({1.0f / font->Sheet.DesignWidth, - 1.0f / font->Sheet.DesignHeight}, - {0.0f, 0.0f}); + const CornersQuad destUV = font->Glyph(glyph.CharId).NormalizedBounds(); glm::vec4 color = RgbIntToFloat(glyph.Colors.TextColor); color.a = opacity * (smoothstepGlyphOpacity ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); - InsertQuad(vertices, indices, maxIndex, dest, destUV, color, dest); + InsertQuad(std::span(vertices.begin() + i * 4, 4), + dest, destUV, color, dest); } if (outlineMode != RendererOutlineMode::None) { // Add outline to the front of the buffers - vertices.reserve(vertexCount * 2); vertices.insert(vertices.end(), vertices.begin(), vertices.end()); indices.resize(indexCount * 2); @@ -198,7 +194,6 @@ void BaseRenderer::DrawProcessedText_BasicFont( switch (outlineMode) { case RendererOutlineMode::Full: { // Add bottom-right outline - vertices.reserve(vertexCount * 3); vertices.insert(vertices.begin() + vertexCount, vertices.begin(), vertices.begin() + vertexCount); @@ -248,33 +243,34 @@ void BaseRenderer::DrawProcessedText_LBFont( float outlineOpacity, SpriteSheet* maskedSheet) { const size_t vertexCount = text.size() * 4; const size_t indexCount = text.size() * 6; - std::vector indices; - indices.reserve(indexCount); + std::vector vertices(vertexCount); + std::vector indices(indexCount); for (size_t i = 0; i < text.size(); i++) { - const uint16_t tl = i * 4; - const uint16_t tr = tl + 1; - const uint16_t br = tl + 2; - const uint16_t bl = tl + 3; - - indices.insert(indices.end(), {tl, tr, br, tl, br, bl}); + const uint16_t bl = i * 4; + const uint16_t tl = bl + 1; + const uint16_t tr = bl + 2; + const uint16_t br = bl + 3; + + indices[i * 6 + 0] = bl; + indices[i * 6 + 1] = tl; + indices[i * 6 + 2] = tr; + indices[i * 6 + 3] = bl; + indices[i * 6 + 4] = tr; + indices[i * 6 + 5] = br; } if (outlineMode != RendererOutlineMode::None) { - std::vector outlineVertices; - outlineVertices.reserve(vertexCount); + for (size_t i = 0; i < text.size(); i++) { + const ProcessedTextGlyph glyph = text[i]; - for (const ProcessedTextGlyph glyph : text) { glm::vec4 color = RgbIntToFloat(glyph.Colors.OutlineColor); color.a = outlineOpacity * (smoothstepGlyphOpacity ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); const CornersQuad destUV = - CornersQuad(font->OutlineGlyph(glyph.CharId).Bounds) - .Scale({1.0f / font->OutlineSheet.DesignWidth, - 1.0f / font->OutlineSheet.DesignHeight}, - {0.0f, 0.0f}); + font->OutlineGlyph(glyph.CharId).NormalizedBounds(); CornersQuad dest = RectF(); const glm::vec2 scale = {glyph.DestRect.Height / font->BitmapEmWidth, @@ -304,16 +300,16 @@ void BaseRenderer::DrawProcessedText_LBFont( break; } - InsertQuad(outlineVertices, dest, destUV, color, dest); + InsertQuad(std::span(vertices.begin() + i * 4, 4), + dest, destUV, color, dest); } - DrawVertices(font->OutlineSheet, outlineVertices, indices); + DrawVertices(font->OutlineSheet, vertices, indices); } - std::vector vertices; - vertices.reserve(vertexCount); + for (size_t i = 0; i < text.size(); i++) { + const ProcessedTextGlyph glyph = text[i]; - for (const ProcessedTextGlyph glyph : text) { glm::vec2 scale = {glyph.DestRect.Height / font->BitmapEmWidth, glyph.DestRect.Height / font->BitmapEmHeight}; CornersQuad dest = RectF(font->ForegroundOffset.x, font->ForegroundOffset.y, @@ -321,23 +317,18 @@ void BaseRenderer::DrawProcessedText_LBFont( .Scale(scale, {0.0f, 0.0f}) .Translate(glyph.DestRect.GetPos()); - const CornersQuad destUV = - CornersQuad(font->Glyph(glyph.CharId).Bounds) - .Scale({1.0f / font->OutlineSheet.DesignWidth, - 1.0f / font->OutlineSheet.DesignHeight}, - {0.0f, 0.0f}); + const CornersQuad destUV = font->Glyph(glyph.CharId).NormalizedBounds(); glm::vec4 color = RgbIntToFloat(glyph.Colors.TextColor); color.a = opacity * (smoothstepGlyphOpacity ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); - InsertQuad(vertices, dest, destUV, color, dest); + InsertQuad(std::span(vertices.begin() + i * 4, 4), + dest, destUV, color, dest); } DrawVertices(font->ForegroundSheet, vertices, indices); - - return; } void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, diff --git a/src/spritesheet.h b/src/spritesheet.h index 3b1ea7e13..e7e976bf3 100644 --- a/src/spritesheet.h +++ b/src/spritesheet.h @@ -43,6 +43,12 @@ struct Sprite { } glm::vec2 Center() const { return ScaledBounds().Center(); } + + RectF NormalizedBounds() const { + return RectF(Bounds).Scale( + glm::vec2(1.0f / Sheet.DesignWidth, 1.0f / Sheet.DesignHeight), + {0.0f, 0.0f}); + } }; } // namespace Impacto \ No newline at end of file diff --git a/src/util.cpp b/src/util.cpp index 6e86025c0..ae6831571 100644 --- a/src/util.cpp +++ b/src/util.cpp @@ -161,6 +161,14 @@ CornersQuad RectF::Rotate(const glm::quat rotation, const glm::vec3 origin, stayInScreen); } +CornersQuad RectF::FlipVertical() const { + return CornersQuad(*this).FlipVertical(); +} + +CornersQuad RectF::FlipHorizontal() const { + return CornersQuad(*this).FlipHorizontal(); +} + inline CornersQuad operator*(const glm::mat4 transformation, RectF rect) { return rect.Transform(transformation); } diff --git a/src/util.h b/src/util.h index 9a16544bd..e485e1d02 100644 --- a/src/util.h +++ b/src/util.h @@ -178,6 +178,9 @@ struct RectF { CornersQuad Rotate(glm::quat rotation, glm::vec3 origin) const; CornersQuad Rotate(glm::quat rotation, glm::vec3 origin, float depth, glm::vec2 vanishingPoint, bool stayInScreen = false) const; + + CornersQuad FlipVertical() const; + CornersQuad FlipHorizontal() const; }; inline CornersQuad operator*(const glm::mat4 transformation, RectF rect); @@ -266,6 +269,18 @@ struct CornersQuad { CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin); CornersQuad& Rotate(glm::quat rotation, glm::vec3 origin, float depth, glm::vec2 vanishingPoint, bool stayInScreen = false); + + CornersQuad& FlipVertical() { + std::swap(TopLeft, BottomLeft); + std::swap(TopRight, BottomRight); + return *this; + } + + CornersQuad& FlipHorizontal() { + std::swap(TopLeft, TopRight); + std::swap(BottomLeft, BottomRight); + return *this; + } }; inline CornersQuad operator*(const glm::mat4 transformation, CornersQuad quad) { From 7add5c260e77b68cd6ef36789f7508720acd5fed Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sat, 7 Jun 2025 00:09:53 +0200 Subject: [PATCH 67/88] Batched textures --- src/renderer/opengl/renderer.cpp | 274 +++++++++++------- src/renderer/opengl/renderer.h | 25 +- src/renderer/opengl/shader.cpp | 58 ++-- src/renderer/opengl/shader.h | 44 ++- src/renderer/renderer.h | 2 + .../opengl/CCMessageBoxSprite_frag.glsl | 9 +- .../opengl/CCMessageBoxSprite_vert.glsl | 13 +- .../opengl/CHLCCMenuBackground_frag.glsl | 18 +- .../opengl/CHLCCMenuBackground_vert.glsl | 11 +- .../opengl/MaskedSpriteNoAlpha_frag.glsl | 9 +- .../opengl/MaskedSpriteNoAlpha_vert.glsl | 13 +- src/shaders/opengl/MaskedSprite_frag.glsl | 9 +- src/shaders/opengl/MaskedSprite_vert.glsl | 13 +- ...ted_frag.glsl => SpriteInverted_frag.glsl} | 5 +- ...ted_vert.glsl => SpriteInverted_vert.glsl} | 8 +- src/shaders/opengl/Sprite_frag.glsl | 5 +- src/shaders/opengl/Sprite_vert.glsl | 8 +- src/shaders/opengl/YUVFrame_vert.glsl | 4 +- 18 files changed, 308 insertions(+), 220 deletions(-) rename src/shaders/opengl/{Sprite_inverted_frag.glsl => SpriteInverted_frag.glsl} (53%) rename src/shaders/opengl/{Sprite_inverted_vert.glsl => SpriteInverted_vert.glsl} (60%) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index cd518e6e8..7a0d169ad 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -1,6 +1,7 @@ #include "renderer.h" #include +#include #include "shader.h" #include "../../profile/game.h" #include "../../game.h" @@ -44,16 +45,22 @@ void Renderer::Init() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, Position)); - glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, sizeof(VertexBufferSprites), + (void*)offsetof(VertexBufferSprites, ColorMap)); + glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, UV)); - glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, Tint)); - glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribIPointer(4, 1, GL_UNSIGNED_INT, sizeof(VertexBufferSprites), + (void*)offsetof(VertexBufferSprites, Mask)); + glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, MaskUV)); glEnableVertexAttribArray(0); glEnableVertexAttribArray(1); glEnableVertexAttribArray(2); glEnableVertexAttribArray(3); + glEnableVertexAttribArray(4); + glEnableVertexAttribArray(5); // Make 1x1 white pixel for colored rectangles Texture rectTexture; @@ -81,15 +88,23 @@ void Renderer::Init() { Shaders->Compile("CHLCCMenuBackground")); // No-mipmapping sampler - glGenSamplers(1, &Sampler); + glGenSamplers(MaxTextureCount, Samplers.data()); // Don't wrap textures - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + for (size_t i = 0; i < Samplers.size(); i++) { + const GLint sampler = Samplers[i]; - glSamplerParameteri(Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(Sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); + glBindSampler(i, sampler); + + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); + } + + glActiveTexture(GL_TEXTURE0 + MaxTextureCount); } void Renderer::Shutdown() { @@ -127,16 +142,12 @@ void Renderer::BeginFrame2D() { } Drawing = true; - CurrentTexture = 0; VertexCount = 0; IndexCount = 0; NextFreeIndex = 0; glDisable(GL_CULL_FACE); - - // TODO should we really be making this global? - glBindSampler(0, Sampler); } void Renderer::EndFrame() { @@ -246,32 +257,43 @@ void Renderer::InsertVertices( NextFreeIndex += maxIndex + 1; } -void Renderer::InsertVerticesQuad(const CornersQuad pos, const CornersQuad uv, +void Renderer::InsertVerticesQuad(const CornersQuad pos, + const GLuint textureLocation, + const CornersQuad uv, const std::span tints, + const GLuint maskLocation, const CornersQuad maskUV) { const std::array vertices = { VertexBufferSprites{ .Position = pos.BottomLeft, + .ColorMap = textureLocation, .UV = uv.BottomLeft, .Tint = tints[0], + .Mask = maskLocation, .MaskUV = maskUV.BottomLeft, }, VertexBufferSprites{ .Position = pos.TopLeft, + .ColorMap = textureLocation, .UV = uv.TopLeft, .Tint = tints[1], + .Mask = maskLocation, .MaskUV = maskUV.TopLeft, }, VertexBufferSprites{ .Position = pos.TopRight, + .ColorMap = textureLocation, .UV = uv.TopRight, .Tint = tints[2], + .Mask = maskLocation, .MaskUV = maskUV.TopRight, }, VertexBufferSprites{ .Position = pos.BottomRight, + .ColorMap = textureLocation, .UV = uv.BottomRight, .Tint = tints[3], + .Mask = maskLocation, .MaskUV = maskUV.BottomRight, }, }; @@ -281,6 +303,81 @@ void Renderer::InsertVerticesQuad(const CornersQuad pos, const CornersQuad uv, InsertVertices(vertices, indices); } +// Important to call as late as possible, +// as flushes may invalidate the given texture IDs! +std::vector Renderer::GetTextureLocations( + const std::span textureIds) { + std::vector allocatedLocations(textureIds.size()); + + size_t newTexturesNeeded = 0; + std::vector notFound; + for (size_t i = 0; i < textureIds.size(); i++) { + const auto locationsIt = std::find(TextureLocations.begin(), + TextureLocations.end(), textureIds[i]); + + if (locationsIt != TextureLocations.end()) { + allocatedLocations[i] = + std::distance(TextureLocations.begin(), locationsIt); + } else { + notFound.push_back(i); + + const auto textureIt = textureIds.begin() + i; + newTexturesNeeded += + std::find(textureIds.begin(), textureIt, textureIds[i]) == textureIt; + } + } + + // If all textures were found, immediately return their locations + if (notFound.empty()) return allocatedLocations; + + if (TextureLocations.size() + newTexturesNeeded <= MaxTextureCount) { + // If the needed textures still fit in the buffer, add them + TextureLocations.reserve(TextureLocations.size() + newTexturesNeeded); + + for (size_t i : notFound) { + const auto foundIt = std::find(TextureLocations.begin(), + TextureLocations.end(), textureIds[i]); + + if (foundIt != TextureLocations.end()) { + // Texture already added by prior entry in notFound + allocatedLocations[i] = + std::distance(TextureLocations.begin(), foundIt); + + } else { + // Add the texture + const size_t glTextureId = TextureLocations.size(); + glBindTextureUnit(glTextureId, textureIds[i]); + TextureLocations.push_back(textureIds[i]); + allocatedLocations[i] = glTextureId; + } + } + + return allocatedLocations; + } + + // If they do not fit in the buffer, flush and add them + Flush(); + + for (size_t i = 0; i < textureIds.size(); i++) { + const auto foundIt = std::find(TextureLocations.begin(), + TextureLocations.end(), textureIds[i]); + + if (foundIt != TextureLocations.end()) { + // Texture already added by prior entry in textureIds + allocatedLocations[i] = std::distance(TextureLocations.begin(), foundIt); + + } else { + // Add the texture + const size_t glTextureId = TextureLocations.size(); + glBindTextureUnit(glTextureId, textureIds[i]); + TextureLocations.push_back(textureIds[i]); + allocatedLocations[i] = glTextureId; + } + } + + return allocatedLocations; +} + void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const glm::mat4 transformation, const std::span tints, @@ -298,7 +395,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, SpriteInvertedUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .ColorMap = 0, + .Textures = Textures, }; UseShader(SpriteInvertedShaderProgram, uniforms); @@ -307,25 +404,25 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, SpriteUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .ColorMap = 0, + .Textures = Textures, }; UseShader(SpriteShaderProgram, uniforms); } - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); - if (disableBlend) { Flush(); glDisable(GL_BLEND); } + const std::vector textureLocations = + GetTextureLocations(std::array{sprite.Sheet.Texture}); + // OK, all good, make quad CornersQuad uvDest = sprite.NormalizedBounds(); if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); - InsertVerticesQuad(dest, uvDest, tints); + InsertVerticesQuad(dest, textureLocations[0], uvDest, tints); if (disableBlend) { Flush(); @@ -349,15 +446,12 @@ void Renderer::DrawMaskedSprite( const float alphaRange = 256.0f / fadeRange; const float constAlpha = ((255.0f - alpha) * alphaRange) / 255.0f; - EnsureTextureBound(sprite.Sheet.Texture); - // Set uniform variables MaskedSpriteUniforms uniforms{ .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .ColorMap = 0, - .Mask = 2, + .Textures = Textures, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, .IsSameTexture = isSameTexture, @@ -365,12 +459,8 @@ void Renderer::DrawMaskedSprite( UseShader(MaskedSpriteShaderProgram, uniforms); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); + const std::vector textureLocations = + GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad @@ -378,7 +468,8 @@ void Renderer::DrawMaskedSprite( if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); CornersQuad maskUVDest = CornersQuad(maskDest).Scale( {1.0f / sprite.Bounds.Width, 1.0f / sprite.Bounds.Height}, {0.0f, 0.0f}); - InsertVerticesQuad(spriteDest, uvDest, tints, maskUVDest); + InsertVerticesQuad(spriteDest, textureLocations[0], uvDest, tints, + textureLocations[1], maskUVDest); } void Renderer::DrawMaskedSpriteOverlay( @@ -402,8 +493,7 @@ void Renderer::DrawMaskedSpriteOverlay( .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .ColorMap = 0, - .Mask = 2, + .Textures = Textures, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, .IsSameTexture = false, @@ -416,8 +506,7 @@ void Renderer::DrawMaskedSpriteOverlay( .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .ColorMap = 0, - .Mask = 2, + .Textures = Textures, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, }; @@ -425,17 +514,13 @@ void Renderer::DrawMaskedSpriteOverlay( UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); } - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); + const std::vector textureLocations = + GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad - InsertVerticesQuad(spriteDest, sprite.NormalizedBounds(), tints, - mask.NormalizedBounds()); + InsertVerticesQuad(spriteDest, textureLocations[0], sprite.NormalizedBounds(), + tints, textureLocations[1], mask.NormalizedBounds()); } void Renderer::DrawVertices(const SpriteSheet& sheet, @@ -448,14 +533,12 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, return; } - EnsureTextureBound(sheet.Texture); - // Set uniform variables if (inverted) { SpriteInvertedUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .ColorMap = 0, + .Textures = Textures, }; UseShader(SpriteInvertedShaderProgram, uniforms); @@ -464,27 +547,28 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, SpriteUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .ColorMap = 0, + .Textures = Textures, }; UseShader(SpriteShaderProgram, uniforms); } - if (sheet.IsScreenCap) { - std::vector flippedVertices; - flippedVertices.reserve(vertices.size()); + const std::vector textureLocations = + GetTextureLocations(std::array{sheet.Texture}); - const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { - if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; - return info; - }; - std::transform(vertices.begin(), vertices.end(), flippedVertices.begin(), - vertexInfoToNDC); + std::vector transformedVertices; + transformedVertices.resize(vertices.size()); - InsertVertices(flippedVertices, indices); - } else { - InsertVertices(vertices, indices); - } + const auto transformVertex = [this, sheet, + &textureLocations](VertexBufferSprites info) { + if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; + info.ColorMap = textureLocations[0]; + return info; + }; + std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), + transformVertex); + + InsertVertices(transformedVertices, indices); } void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, @@ -504,25 +588,21 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, CCMessageBoxUniforms uniforms{ .Projection = Projection, - .ColorMap = 0, - .Mask = 2, + .Textures = Textures, .Alpha = {alphaRange, constAlpha, effectCt, 0.0f}, }; UseShader(CCMessageBoxShaderProgram, uniforms); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); + const std::vector textureLocations = + GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad CornersQuad uvDest = sprite.NormalizedBounds(); if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); - InsertVerticesQuad(dest, uvDest, tint, mask.NormalizedBounds()); + InsertVerticesQuad(dest, textureLocations[0], uvDest, tint, + textureLocations[1], mask.NormalizedBounds()); } void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, @@ -540,41 +620,22 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, CHLCCMenuBackgroundUniforms uniforms{ .Projection = Projection, - .ColorMap = 0, - .Mask = 2, + .Textures = Textures, .Alpha = alpha, }; UseShader(CHLCCMenuBackgroundShaderProgram, uniforms); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, sprite.Sheet.Texture); - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, mask.Sheet.Texture); - glBindSampler(2, Sampler); - - // Do we have the texture assigned? - EnsureTextureBound(sprite.Sheet.Texture); + const std::vector textureLocations = + GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad - InsertVerticesQuad(dest, sprite.NormalizedBounds(), glm::vec4(1.0f), + InsertVerticesQuad(dest, textureLocations[0], sprite.NormalizedBounds(), + glm::vec4(1.0f), textureLocations[1], mask.NormalizedBounds()); } -void Renderer::EnsureTextureBound(GLuint texture) { - if (CurrentTexture != texture) { - ImpLogSlow(LogLevel::Trace, LogChannel::Render, - "Renderer->EnsureTextureBound flushing because texture {:d} is " - "not {:d}\n", - CurrentTexture, texture); - Flush(); - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, texture); - CurrentTexture = texture; - } -} - void Renderer::Flush() { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, @@ -597,7 +658,7 @@ void Renderer::Flush() { IndexCount = 0; NextFreeIndex = 0; - CurrentTexture = 0; + TextureLocations.clear(); } void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, @@ -608,33 +669,22 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, return; } + const std::vector textureLocations = + GetTextureLocations(std::array{frame.LumaId, frame.CbId, frame.CrId}); + YUVFrameUniforms uniforms{ .Projection = Projection, - .Luma = 0, - .Cb = 2, - .Cr = 4, + .Luma = textureLocations[0], + .Cb = textureLocations[1], + .Cr = textureLocations[2], .IsAlpha = alphaVideo, }; UseShader(YUVFrameShaderProgram, uniforms); - // Luma - glActiveTexture(GL_TEXTURE0); - glBindTexture(GL_TEXTURE_2D, frame.LumaId); - - // Cb - glActiveTexture(GL_TEXTURE2); - glBindTexture(GL_TEXTURE_2D, frame.CbId); - glBindSampler(2, Sampler); - - // Cr - glActiveTexture(GL_TEXTURE4); - glBindTexture(GL_TEXTURE_2D, frame.CrId); - glBindSampler(4, Sampler); - // OK, all good, make quad - InsertVerticesQuad(dest, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); + InsertVerticesQuad(dest, 0, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); } void Renderer::CaptureScreencap(Sprite& sprite) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index fca8c1a12..deac57e91 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -116,17 +116,21 @@ class Renderer : public BaseRenderer { } } - void EnsureTextureBound(GLuint texture); void Flush() override; void InsertVertices(std::span vertices, std::span indices); - void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, - std::span tints, + void InsertVerticesQuad(CornersQuad pos, GLuint textureLocation, + CornersQuad uv, std::span tints, + GLuint maskLocation = 0, CornersQuad maskUV = RectF()); - void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, glm::vec4 tint, + void InsertVerticesQuad(CornersQuad pos, GLuint textureLocation, + CornersQuad uv, glm::vec4 tint = glm::vec4(1.0f), + GLuint maskLocation = 0, CornersQuad maskUV = RectF()) { - InsertVerticesQuad(pos, uv, std::array{tint, tint, tint, tint}, maskUV); + InsertVerticesQuad(pos, textureLocation, uv, + std::array{tint, tint, tint, tint}, maskLocation, + maskUV); } GLWindow* OpenGLWindow; @@ -135,11 +139,16 @@ class Renderer : public BaseRenderer { GLuint IBO; GLuint VAOSprites; - GLuint Sampler; - bool Drawing = false; - GLuint CurrentTexture = 0; + static constexpr size_t MaxTextureCount = 15; + static constexpr std::array Textures = { + 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; + std::vector TextureLocations; + + std::vector GetTextureLocations(std::span textureIds); + + std::array Samplers; static constexpr size_t MaxVertexCount = 1024 * 1024 / sizeof(VertexBufferSprites); diff --git a/src/renderer/opengl/shader.cpp b/src/renderer/opengl/shader.cpp index 49c871861..89bbd8853 100644 --- a/src/renderer/opengl/shader.cpp +++ b/src/renderer/opengl/shader.cpp @@ -242,36 +242,34 @@ SpriteShader::SpriteShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), TransformationLocation(glGetUniformLocation(programId, "Transformation")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.Transformation, TransformationLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Textures, TexturesLocation); } void SpriteShader::UploadUniforms(SpriteUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); UpdateVar(newUniforms.Transformation, Uniforms.Transformation, TransformationLocation); - - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); } SpriteInvertedShader::SpriteInvertedShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), TransformationLocation(glGetUniformLocation(programId, "Transformation")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.Transformation, TransformationLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Textures, TexturesLocation); } void SpriteInvertedShader::UploadUniforms(SpriteInvertedUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); UpdateVar(newUniforms.Transformation, Uniforms.Transformation, TransformationLocation); - - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); } YUVFrameShader::YUVFrameShader(GLint programId) @@ -304,15 +302,13 @@ MaskedSpriteNoAlphaShader::MaskedSpriteNoAlphaShader(GLint programId) glGetUniformLocation(programId, "SpriteTransformation")), MaskTransformationLocation( glGetUniformLocation(programId, "MaskTransformation")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), - MaskLocation(glGetUniformLocation(programId, "Mask")), AlphaLocation(glGetUniformLocation(programId, "Alpha")), - IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")) { + IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")), + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); - UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Textures, TexturesLocation); UploadVar(Uniforms.Alpha, AlphaLocation); UploadVar(Uniforms.IsInverted, IsInvertedLocation); } @@ -325,8 +321,7 @@ void MaskedSpriteNoAlphaShader::UploadUniforms( UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, MaskTransformationLocation); - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); - UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); } @@ -338,16 +333,14 @@ MaskedSpriteShader::MaskedSpriteShader(GLint programId) glGetUniformLocation(programId, "SpriteTransformation")), MaskTransformationLocation( glGetUniformLocation(programId, "MaskTransformation")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), - MaskLocation(glGetUniformLocation(programId, "Mask")), AlphaLocation(glGetUniformLocation(programId, "Alpha")), IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")), - IsSameTextureLocation(glGetUniformLocation(programId, "IsSameTexture")) { + IsSameTextureLocation(glGetUniformLocation(programId, "IsSameTexture")), + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); - UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Textures, TexturesLocation); UploadVar(Uniforms.Alpha, AlphaLocation); UploadVar(Uniforms.IsInverted, IsInvertedLocation); } @@ -359,8 +352,7 @@ void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, MaskTransformationLocation); - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); - UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); } @@ -368,32 +360,27 @@ void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { CCMessageBoxShader::CCMessageBoxShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), - MaskLocation(glGetUniformLocation(programId, "Mask")), - AlphaLocation(glGetUniformLocation(programId, "Alpha")) { + AlphaLocation(glGetUniformLocation(programId, "Alpha")), + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); - UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Textures, TexturesLocation); UploadVar(Uniforms.Alpha, AlphaLocation); } void CCMessageBoxShader::UploadUniforms(CCMessageBoxUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); - UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); } CHLCCMenuBackgroundShader::CHLCCMenuBackgroundShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), - ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), - MaskLocation(glGetUniformLocation(programId, "Mask")), - AlphaLocation(glGetUniformLocation(programId, "Alpha")) { + AlphaLocation(glGetUniformLocation(programId, "Alpha")), + TexturesLocation(glGetUniformLocation(programId, "Textures")) { UploadVar(Uniforms.Projection, ProjectionLocation); - UploadVar(Uniforms.ColorMap, ColorMapLocation); - UploadVar(Uniforms.Mask, MaskLocation); + UploadVar(Uniforms.Textures, TexturesLocation); UploadVar(Uniforms.Alpha, AlphaLocation); } @@ -401,8 +388,7 @@ void CHLCCMenuBackgroundShader::UploadUniforms( CHLCCMenuBackgroundUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); - UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); - UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); + UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); } diff --git a/src/renderer/opengl/shader.h b/src/renderer/opengl/shader.h index eee64ea33..2d189f365 100644 --- a/src/renderer/opengl/shader.h +++ b/src/renderer/opengl/shader.h @@ -93,6 +93,9 @@ class Shader { void UploadVar(bool value, GLint location) { glUniform1i(location, value); } void UploadVar(int value, GLint location) { glUniform1i(location, value); } + void UploadVar(GLuint value, GLint location) { + glUniform1ui(location, value); + } void UploadVar(float value, GLint location) { glUniform1f(location, value); } void UploadVar(glm::vec2 value, GLint location) { glUniform2fv(location, 1, &value[0]); @@ -103,6 +106,9 @@ class Shader { void UploadVar(glm::mat4 value, GLint location) { glUniformMatrix4fv(location, 1, GL_FALSE, &value[0][0]); } + void UploadVar(std::span value, GLint location) { + glUniform1iv(location, value.size(), value.data()); + } template void UpdateVar(T newValue, T& oldValue, GLint location) { @@ -119,7 +125,7 @@ struct SpriteUniforms { glm::mat4 Projection; glm::mat4 Transformation; - int ColorMap; + std::array Textures; }; class SpriteShader : public Shader { @@ -132,7 +138,7 @@ class SpriteShader : public Shader { const GLint ProjectionLocation; const GLint TransformationLocation; - const GLint ColorMapLocation; + const GLint TexturesLocation; }; struct SpriteInvertedUniforms { @@ -141,7 +147,7 @@ struct SpriteInvertedUniforms { glm::mat4 Projection; glm::mat4 Transformation; - int ColorMap; + std::array Textures; }; class SpriteInvertedShader : public Shader { @@ -154,7 +160,7 @@ class SpriteInvertedShader : public Shader { const GLint ProjectionLocation; const GLint TransformationLocation; - const GLint ColorMapLocation; + const GLint TexturesLocation; }; struct YUVFrameUniforms { @@ -162,9 +168,9 @@ struct YUVFrameUniforms { glm::mat4 Projection; - int Luma; - int Cb; - int Cr; + GLuint Luma; + GLuint Cb; + GLuint Cr; bool IsAlpha; }; @@ -190,8 +196,7 @@ struct MaskedSpriteNoAlphaUniforms { glm::mat4 SpriteTransformation = glm::mat4(); glm::mat4 MaskTransformation = glm::mat4(); - int ColorMap = 0; - int Mask = 2; + std::array Textures; glm::vec2 Alpha = glm::vec2(); bool IsInverted = false; }; @@ -207,8 +212,7 @@ class MaskedSpriteNoAlphaShader : public Shader { const GLint SpriteTransformationLocation; const GLint MaskTransformationLocation; - const GLint ColorMapLocation; - const GLint MaskLocation; + const GLint TexturesLocation; const GLint AlphaLocation; const GLint IsInvertedLocation; }; @@ -220,8 +224,7 @@ struct MaskedSpriteUniforms { glm::mat4 SpriteTransformation = glm::mat4(); glm::mat4 MaskTransformation = glm::mat4(); - int ColorMap = 0; - int Mask = 2; + std::array Textures; glm::vec2 Alpha = glm::vec2(); bool IsInverted = false; bool IsSameTexture = false; @@ -238,8 +241,7 @@ class MaskedSpriteShader : public Shader { const GLint SpriteTransformationLocation; const GLint MaskTransformationLocation; - const GLint ColorMapLocation; - const GLint MaskLocation; + const GLint TexturesLocation; const GLint AlphaLocation; const GLint IsInvertedLocation; const GLint IsSameTextureLocation; @@ -250,8 +252,7 @@ struct CCMessageBoxUniforms { glm::mat4 Projection = glm::mat4(); - int ColorMap = 0; - int Mask = 2; + std::array Textures; glm::vec4 Alpha = glm::vec4(); }; @@ -264,8 +265,7 @@ class CCMessageBoxShader : public Shader { private: const GLint ProjectionLocation; - const GLint ColorMapLocation; - const GLint MaskLocation; + const GLint TexturesLocation; const GLint AlphaLocation; }; @@ -274,8 +274,7 @@ struct CHLCCMenuBackgroundUniforms { glm::mat4 Projection = glm::mat4(); - int ColorMap = 0; - int Mask = 0; + std::array Textures; float Alpha = 0.0f; }; @@ -288,8 +287,7 @@ class CHLCCMenuBackgroundShader : public Shader { private: const GLint ProjectionLocation; - const GLint ColorMapLocation; - const GLint MaskLocation; + const GLint TexturesLocation; const GLint AlphaLocation; }; diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 4aceb1bb9..b3282b0eb 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -19,8 +19,10 @@ constexpr inline int MaxFramebuffers = 10; struct VertexBufferSprites { glm::vec2 Position; + GLuint ColorMap; glm::vec2 UV; glm::vec4 Tint; + GLuint Mask; glm::vec2 MaskUV; }; diff --git a/src/shaders/opengl/CCMessageBoxSprite_frag.glsl b/src/shaders/opengl/CCMessageBoxSprite_frag.glsl index 3d51cbafd..0539d1963 100644 --- a/src/shaders/opengl/CCMessageBoxSprite_frag.glsl +++ b/src/shaders/opengl/CCMessageBoxSprite_frag.glsl @@ -1,17 +1,18 @@ +flat in uint colorMap; in vec2 uv; in vec4 tint; +flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D ColorMap; -uniform sampler2D Mask; +uniform sampler2D[15] Textures; uniform vec4 Alpha; void main() { - color = texture(ColorMap, uv); + color = texture(Textures[colorMap], uv); color *= tint; - vec4 alp = texture(Mask, maskUV); + vec4 alp = texture(Textures[mask], maskUV); float ga = alp.r; float ea = 1.0 - alp.g; float fa = 1.0 - alp.b; diff --git a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl index e65804731..c7ae21d3d 100644 --- a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl +++ b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl @@ -1,17 +1,24 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; -layout(location = 3) in vec2 MaskUV; +layout(location = 1) in uint ColorMap; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; +layout(location = 4) in uint Mask; +layout(location = 5) in vec2 MaskUV; +flat out uint colorMap; out vec2 uv; out vec4 tint; +flat out uint mask; out vec2 maskUV; uniform mat4 Projection; void main() { gl_Position = Projection * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; tint = Tint; + mask = Mask; maskUV = MaskUV; } \ No newline at end of file diff --git a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl index 2f218865e..0b84d6cd2 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl @@ -1,12 +1,14 @@ -uniform sampler2D ColorMap; -uniform sampler2D Mask; uniform float Alpha; +flat in int ucolorMap; in vec2 uv; +flat in int umask; in vec2 maskUV; out vec4 outColor; +uniform sampler2D[15] Textures; + float remapMiddle(float value, float newMiddle) { if (value < 0.5) { return mix(0.0, newMiddle, 2.0 * value); @@ -16,12 +18,12 @@ float remapMiddle(float value, float newMiddle) { } void main() { - vec4 color = texture(ColorMap, uv); - vec4 mask = texture(Mask, maskUV); + vec4 color = texture(Textures[colorMap], uv); + vec4 maskColor = texture(Textures[mask], maskUV); outColor = vec4( - remapMiddle(color.r, mask.r), - remapMiddle(color.g, mask.g), - remapMiddle(color.b, mask.b), - mask.a * Alpha + remapMiddle(color.r, maskColor.r), + remapMiddle(color.g, maskColor.g), + remapMiddle(color.b, maskColor.b), + maskColor.a * Alpha ); } \ No newline at end of file diff --git a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl index c5aef4068..df374c03e 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl @@ -1,14 +1,21 @@ layout (location = 0) in vec2 Position; -layout (location = 1) in vec2 UV; -layout (location = 3) in vec2 MaskUV; +layout (location = 1) in uint ColorMap; +layout (location = 2) in vec2 UV; +layout (location = 4) in uint Mask; +layout (location = 5) in vec2 MaskUV; +flat out uint colorMap; out vec2 uv; +flat out uint mask; out vec2 maskUV; uniform mat4 Projection; void main() { gl_Position = Projection * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; + mask = Mask; maskUV = MaskUV; } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl b/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl index 51944bbe3..4e6a624cc 100644 --- a/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl +++ b/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl @@ -1,11 +1,12 @@ +flat in uint colorMap; in vec2 uv; in vec4 tint; +flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D ColorMap; -uniform sampler2D Mask; +uniform sampler2D[15] Textures; uniform vec2 Alpha; uniform bool IsInverted; @@ -17,8 +18,8 @@ float rgbToLightness(vec3 rgb) { } void main() { - color = texture(ColorMap, uv); - vec4 alp = texture(Mask, maskUV); + color = texture(Textures[colorMap], uv); + vec4 alp = texture(Textures[mask], maskUV); float maskAlpha = rgbToLightness(alp.rgb); if (IsInverted) maskAlpha = 1.0f - maskAlpha; diff --git a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl index d42ea4868..645921dce 100644 --- a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl +++ b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl @@ -1,10 +1,14 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; -layout(location = 3) in vec2 MaskUV; +layout(location = 1) in uint ColorMap; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; +layout(location = 4) in uint Mask; +layout(location = 5) in vec2 MaskUV; +flat out uint colorMap; out vec2 uv; out vec4 tint; +flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -13,7 +17,10 @@ uniform mat4 MaskTransformation; void main() { gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; tint = Tint; + mask = Mask; maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSprite_frag.glsl b/src/shaders/opengl/MaskedSprite_frag.glsl index d90f0d943..5b4b59c4d 100644 --- a/src/shaders/opengl/MaskedSprite_frag.glsl +++ b/src/shaders/opengl/MaskedSprite_frag.glsl @@ -1,18 +1,19 @@ +flat in uint colorMap; in vec2 uv; in vec4 tint; +flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D ColorMap; -uniform sampler2D Mask; +uniform sampler2D[15] Textures; uniform vec2 Alpha; uniform bool IsInverted; uniform bool IsSameTexture; void main() { - color = texture(ColorMap, uv); - vec4 alp = texture(Mask, maskUV); + color = texture(Textures[colorMap], uv); + vec4 alp = texture(Textures[mask], maskUV); if (IsInverted) alp.a = 1.0f - alp.a; alp.a *= Alpha.x; alp.a -= Alpha.y; diff --git a/src/shaders/opengl/MaskedSprite_vert.glsl b/src/shaders/opengl/MaskedSprite_vert.glsl index d42ea4868..645921dce 100644 --- a/src/shaders/opengl/MaskedSprite_vert.glsl +++ b/src/shaders/opengl/MaskedSprite_vert.glsl @@ -1,10 +1,14 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; -layout(location = 3) in vec2 MaskUV; +layout(location = 1) in uint ColorMap; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; +layout(location = 4) in uint Mask; +layout(location = 5) in vec2 MaskUV; +flat out uint colorMap; out vec2 uv; out vec4 tint; +flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -13,7 +17,10 @@ uniform mat4 MaskTransformation; void main() { gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; tint = Tint; + mask = Mask; maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_inverted_frag.glsl b/src/shaders/opengl/SpriteInverted_frag.glsl similarity index 53% rename from src/shaders/opengl/Sprite_inverted_frag.glsl rename to src/shaders/opengl/SpriteInverted_frag.glsl index fe7d6744f..9922a61b0 100644 --- a/src/shaders/opengl/Sprite_inverted_frag.glsl +++ b/src/shaders/opengl/SpriteInverted_frag.glsl @@ -1,12 +1,13 @@ +flat in uint colorMap; in vec2 uv; in vec4 tint; out vec4 color; -uniform sampler2D ColorMap; +uniform sampler2D[15] Textures; void main() { - color = texture(ColorMap, uv); + color = texture(Textures[colorMap], uv); color.rgb = vec3(1.0) - color.rgb; color *= tint; } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_inverted_vert.glsl b/src/shaders/opengl/SpriteInverted_vert.glsl similarity index 60% rename from src/shaders/opengl/Sprite_inverted_vert.glsl rename to src/shaders/opengl/SpriteInverted_vert.glsl index 0960a5292..1f8dfe764 100644 --- a/src/shaders/opengl/Sprite_inverted_vert.glsl +++ b/src/shaders/opengl/SpriteInverted_vert.glsl @@ -1,7 +1,9 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; +layout(location = 1) in uint ColorMap; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; +flat out uint colorMap; out vec2 uv; out vec4 tint; @@ -10,6 +12,8 @@ uniform mat4 Transformation; void main() { gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_frag.glsl b/src/shaders/opengl/Sprite_frag.glsl index 37416a70f..0b809f219 100644 --- a/src/shaders/opengl/Sprite_frag.glsl +++ b/src/shaders/opengl/Sprite_frag.glsl @@ -1,8 +1,9 @@ +flat in uint colorMap; in vec2 uv; in vec4 tint; out vec4 color; -uniform sampler2D ColorMap; +uniform sampler2D[15] Textures; -void main() { color = tint * texture(ColorMap, uv); } \ No newline at end of file +void main() { color = tint * texture(Textures[colorMap], uv); } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_vert.glsl b/src/shaders/opengl/Sprite_vert.glsl index 0960a5292..1f8dfe764 100644 --- a/src/shaders/opengl/Sprite_vert.glsl +++ b/src/shaders/opengl/Sprite_vert.glsl @@ -1,7 +1,9 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; +layout(location = 1) in uint ColorMap; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; +flat out uint colorMap; out vec2 uv; out vec4 tint; @@ -10,6 +12,8 @@ uniform mat4 Transformation; void main() { gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); + + colorMap = ColorMap; uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/YUVFrame_vert.glsl b/src/shaders/opengl/YUVFrame_vert.glsl index cdef1458d..d5f5a8173 100644 --- a/src/shaders/opengl/YUVFrame_vert.glsl +++ b/src/shaders/opengl/YUVFrame_vert.glsl @@ -1,6 +1,6 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in vec2 UV; -layout(location = 2) in vec4 Tint; +layout(location = 2) in vec2 UV; +layout(location = 3) in vec4 Tint; out vec2 uv; out vec4 tint; From 2f7b99b2540cccb145055a560cb2e3c2ac451663 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 9 Jun 2025 18:32:08 +0200 Subject: [PATCH 68/88] Added masked DrawVertices support --- src/renderer/dx9/renderer.cpp | 1 + src/renderer/dx9/renderer.h | 1 + src/renderer/opengl/renderer.cpp | 40 +++++++++++++++++++++++--------- src/renderer/opengl/renderer.h | 1 + src/renderer/renderer.cpp | 26 ++++++++++++++++----- src/renderer/renderer.h | 32 ++++++++++++++++++++----- src/renderer/vulkan/renderer.cpp | 1 + src/renderer/vulkan/renderer.h | 1 + 8 files changed, 80 insertions(+), 23 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 8605d4603..568327a6b 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -419,6 +419,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::optional mask, const std::span vertices, const std::span indices, const glm::mat4 transformation, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index baf788bad..57bca1720 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -55,6 +55,7 @@ class Renderer : public BaseRenderer { bool isInverted, bool useMaskAlpha) override; void DrawVertices(const SpriteSheet& sheet, + std::optional mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 7a0d169ad..dcbefede8 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -524,6 +524,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::optional mask, const std::span vertices, const std::span indices, glm::mat4 transformation, const bool inverted) { @@ -534,27 +535,43 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, } // Set uniform variables - if (inverted) { - SpriteInvertedUniforms uniforms{ + if (mask.has_value()) { + MaskedSpriteNoAlphaUniforms uniforms{ .Projection = Projection, - .Transformation = transformation, + .SpriteTransformation = transformation, + .MaskTransformation = glm::mat4(1.0f), .Textures = Textures, + .Alpha = {1.0f, 0.0f}, + .IsInverted = inverted, }; - UseShader(SpriteInvertedShaderProgram, uniforms); + UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); } else { - SpriteUniforms uniforms{ - .Projection = Projection, - .Transformation = transformation, - .Textures = Textures, - }; + if (inverted) { + SpriteInvertedUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .Textures = Textures, + }; - UseShader(SpriteShaderProgram, uniforms); + UseShader(SpriteInvertedShaderProgram, uniforms); + + } else { + SpriteUniforms uniforms{ + .Projection = Projection, + .Transformation = transformation, + .Textures = Textures, + }; + + UseShader(SpriteShaderProgram, uniforms); + } } const std::vector textureLocations = - GetTextureLocations(std::array{sheet.Texture}); + mask.has_value() ? GetTextureLocations(std::array{ + sheet.Texture, mask->Texture}) + : GetTextureLocations(std::array{sheet.Texture}); std::vector transformedVertices; transformedVertices.resize(vertices.size()); @@ -563,6 +580,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, &textureLocations](VertexBufferSprites info) { if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; info.ColorMap = textureLocations[0]; + if (textureLocations.size() >= 2) info.Mask = textureLocations[1]; return info; }; std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index deac57e91..467861ef8 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -57,6 +57,7 @@ class Renderer : public BaseRenderer { bool isInverted, bool useMaskAlpha) override; void DrawVertices(const SpriteSheet& sheet, + std::optional mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 30b5960b9..3c43b9cf3 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -151,13 +151,16 @@ void BaseRenderer::DrawProcessedText_BasicFont( const CornersQuad dest = glyph.DestRect; const CornersQuad destUV = font->Glyph(glyph.CharId).NormalizedBounds(); + const CornersQuad maskUV = CornersQuad(dest).Scale( + {1.0f / Window->WindowWidth, 1.0f / Window->WindowHeight}, + {0.0f, 0.0f}); glm::vec4 color = RgbIntToFloat(glyph.Colors.TextColor); color.a = opacity * (smoothstepGlyphOpacity ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); InsertQuad(std::span(vertices.begin() + i * 4, 4), - dest, destUV, color, dest); + dest, destUV, color, maskUV); } if (outlineMode != RendererOutlineMode::None) { @@ -234,13 +237,18 @@ void BaseRenderer::DrawProcessedText_BasicFont( } } - DrawVertices(font->Sheet, vertices, indices); + const std::optional mask = + maskedSheet ? std::optional(*maskedSheet) : std::nullopt; + DrawVertices(font->Sheet, mask, vertices, indices); } void BaseRenderer::DrawProcessedText_LBFont( std::span text, LBFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, float outlineOpacity, SpriteSheet* maskedSheet) { + const std::optional mask = + maskedSheet ? std::optional(*maskedSheet) : std::nullopt; + const size_t vertexCount = text.size() * 4; const size_t indexCount = text.size() * 6; std::vector vertices(vertexCount); @@ -300,11 +308,14 @@ void BaseRenderer::DrawProcessedText_LBFont( break; } + const CornersQuad maskUV = CornersQuad(dest).Scale( + {1.0f / Window->WindowWidth, 1.0f / Window->WindowHeight}, + {0.0f, 0.0f}); InsertQuad(std::span(vertices.begin() + i * 4, 4), - dest, destUV, color, dest); + dest, destUV, color, maskUV); } - DrawVertices(font->OutlineSheet, vertices, indices); + DrawVertices(font->OutlineSheet, mask, vertices, indices); } for (size_t i = 0; i < text.size(); i++) { @@ -324,11 +335,14 @@ void BaseRenderer::DrawProcessedText_LBFont( ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); + const CornersQuad maskUV = CornersQuad(dest).Scale( + {1.0f / Window->WindowWidth, 1.0f / Window->WindowHeight}, + {0.0f, 0.0f}); InsertQuad(std::span(vertices.begin() + i * 4, 4), - dest, destUV, color, dest); + dest, destUV, color, maskUV); } - DrawVertices(font->ForegroundSheet, vertices, indices); + DrawVertices(font->ForegroundSheet, mask, vertices, indices); } void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index b3282b0eb..6eccdfba7 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -18,12 +18,12 @@ enum class RendererOutlineMode { None, BottomRight, Full }; constexpr inline int MaxFramebuffers = 10; struct VertexBufferSprites { - glm::vec2 Position; - GLuint ColorMap; - glm::vec2 UV; - glm::vec4 Tint; - GLuint Mask; - glm::vec2 MaskUV; + glm::vec2 Position = {0.0f, 0.0f}; + GLuint ColorMap = 0; + glm::vec2 UV = {0.0f, 0.0f}; + glm::vec4 Tint = glm::vec4(1.0f); + GLuint Mask = 0; + glm::vec2 MaskUV = {0.0f, 0.0f}; }; class BaseRenderer { @@ -217,11 +217,31 @@ class BaseRenderer { } virtual void DrawVertices(const SpriteSheet& sheet, + std::optional mask, std::span vertices, std::span indices, glm::mat4 transformation = glm::mat4(1.0f), bool inverted = false) = 0; + virtual void DrawVertices(const SpriteSheet& sheet, + std::span vertices, + std::span indices, + glm::mat4 transformation = glm::mat4(1.0f), + bool inverted = false) { + DrawVertices(sheet, std::nullopt, vertices, indices, transformation, + inverted); + } + + void DrawVertices(const SpriteSheet& sheet, + std::optional mask, + std::span vertices, + std::span indices, glm::vec2 offset, + bool inverted = false) { + DrawVertices(sheet, mask, vertices, indices, + glm::translate(glm::mat4(1.0f), glm::vec3(offset, 0.0f)), + inverted); + } + void DrawVertices(const SpriteSheet& sheet, std::span vertices, std::span indices, glm::vec2 offset, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index a1d52f5f1..b6623ced7 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1350,6 +1350,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, + const std::optional mask, const std::span vertices, const std::span indices, const glm::mat4 transformation, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index b0be4a9c4..aad9ec18a 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -83,6 +83,7 @@ class Renderer : public BaseRenderer { bool isInverted, bool useMaskAlpha) override; void DrawVertices(const SpriteSheet& sheet, + std::optional mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; From a615aa1c9ed913528c840be00732863f80ab7a23 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 9 Jun 2025 19:23:03 +0200 Subject: [PATCH 69/88] Added cache check to opengl scissor state --- src/renderer/opengl/renderer.cpp | 8 ++++++++ src/renderer/opengl/renderer.h | 2 ++ 2 files changed, 10 insertions(+) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index dcbefede8..6d13ba5e5 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -722,11 +722,16 @@ void Renderer::CaptureScreencap(Sprite& sprite) { } void Renderer::EnableScissor() { + if (ScissorEnabled) return; + Flush(); glEnable(GL_SCISSOR_TEST); + ScissorEnabled = true; } void Renderer::SetScissorRect(RectF const& rect) { + if (!ScissorEnabled) return; + Rect viewport = Window->GetViewport(); float scale = fmin((float)Window->WindowWidth / Profile::DesignWidth, (float)Window->WindowHeight / Profile::DesignHeight); @@ -741,8 +746,11 @@ void Renderer::SetScissorRect(RectF const& rect) { } void Renderer::DisableScissor() { + if (!ScissorEnabled) return; + Flush(); glDisable(GL_SCISSOR_TEST); + ScissorEnabled = false; } } // namespace OpenGL diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 467861ef8..cdeb7cec4 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -168,6 +168,8 @@ class Renderer : public BaseRenderer { // ShaderCompiler compiler std::shared_ptr Shaders; + + bool ScissorEnabled = false; }; } // namespace OpenGL From e88cfaf13ee2713e6f97a1d7fbfe2a782da14c46 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 9 Jun 2025 20:14:30 +0200 Subject: [PATCH 70/88] Fix YUV frames --- src/renderer/opengl/renderer.cpp | 17 ++++++++++++++--- src/renderer/opengl/shader.h | 6 +++--- src/renderer/opengl/yuvframe.cpp | 5 +++++ 3 files changed, 22 insertions(+), 6 deletions(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 6d13ba5e5..4f39cab0e 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -692,14 +692,25 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, YUVFrameUniforms uniforms{ .Projection = Projection, - .Luma = textureLocations[0], - .Cb = textureLocations[1], - .Cr = textureLocations[2], + .Luma = (GLint)textureLocations[0], + .Cb = (GLint)textureLocations[1], + .Cr = (GLint)textureLocations[2], .IsAlpha = alphaVideo, }; UseShader(YUVFrameShaderProgram, uniforms); + // TODO: Remove hack and create new vertex layout + if (TextureLocations.empty()) { + GLuint maxIndex = + *std::max_element(textureLocations.begin(), textureLocations.end()); + TextureLocations.resize(maxIndex + 1); + + TextureLocations[textureLocations[0]] = frame.LumaId; + TextureLocations[textureLocations[1]] = frame.CbId; + TextureLocations[textureLocations[2]] = frame.CrId; + } + // OK, all good, make quad InsertVerticesQuad(dest, 0, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); diff --git a/src/renderer/opengl/shader.h b/src/renderer/opengl/shader.h index 2d189f365..a384447e3 100644 --- a/src/renderer/opengl/shader.h +++ b/src/renderer/opengl/shader.h @@ -168,9 +168,9 @@ struct YUVFrameUniforms { glm::mat4 Projection; - GLuint Luma; - GLuint Cb; - GLuint Cr; + GLint Luma = 0; + GLint Cb = 0; + GLint Cr = 0; bool IsAlpha; }; diff --git a/src/renderer/opengl/yuvframe.cpp b/src/renderer/opengl/yuvframe.cpp index 7c1f5efe3..564c4bdd1 100644 --- a/src/renderer/opengl/yuvframe.cpp +++ b/src/renderer/opengl/yuvframe.cpp @@ -21,12 +21,17 @@ void GLYUVFrame::Submit(const void* luma, const void* cb, const void* cr) { glBindTexture(GL_TEXTURE_2D, LumaId); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, (GLsizei)Width, (GLsizei)Height, 0, GL_RED, GL_UNSIGNED_BYTE, luma); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, CbId); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, (GLsizei)(Width / 2), (GLsizei)(Height / 2), 0, GL_RED, GL_UNSIGNED_BYTE, cb); + glGenerateMipmap(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, CrId); glTexImage2D(GL_TEXTURE_2D, 0, GL_R8, (GLsizei)(Width / 2), (GLsizei)(Height / 2), 0, GL_RED, GL_UNSIGNED_BYTE, cr); + glGenerateMipmap(GL_TEXTURE_2D); } void GLYUVFrame::Release() { From b235d238c7962c5782381561b444c64b9b79e612 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 10 Jun 2025 17:32:31 +0200 Subject: [PATCH 71/88] Turned texture units into managed objects --- CMakeLists.txt | 1 + src/renderer/opengl/renderer.cpp | 168 ++++++++++++++---------------- src/renderer/opengl/renderer.h | 12 +-- src/renderer/opengl/textureunit.h | 70 +++++++++++++ 4 files changed, 155 insertions(+), 96 deletions(-) create mode 100644 src/renderer/opengl/textureunit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index bdb96c5df..cdfee508a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1031,6 +1031,7 @@ if (NOT DEFINED IMPACTO_DISABLE_OPENGL) src/renderer/opengl/shader.h src/renderer/opengl/glc.h src/renderer/opengl/yuvframe.h + src/renderer/opengl/textureunit.h src/renderer/opengl/3d/renderable3d.h src/renderer/opengl/3d/scene.h ) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 4f39cab0e..ff4fc0873 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -87,24 +87,10 @@ void Renderer::Init() { std::make_unique( Shaders->Compile("CHLCCMenuBackground")); - // No-mipmapping sampler - glGenSamplers(MaxTextureCount, Samplers.data()); + for (size_t i = 0; i < TextureUnitCount; i++) + TextureUnits[i] = std::make_unique(i); - // Don't wrap textures - for (size_t i = 0; i < Samplers.size(); i++) { - const GLint sampler = Samplers[i]; - - glBindSampler(i, sampler); - - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); - - glSamplerParameteri(sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(sampler, GL_TEXTURE_MAX_ANISOTROPY_EXT, 16); - } - - glActiveTexture(GL_TEXTURE0 + MaxTextureCount); + glActiveTexture(GL_TEXTURE0 + TextureUnitCount); } void Renderer::Shutdown() { @@ -303,79 +289,89 @@ void Renderer::InsertVerticesQuad(const CornersQuad pos, InsertVertices(vertices, indices); } -// Important to call as late as possible, -// as flushes may invalidate the given texture IDs! -std::vector Renderer::GetTextureLocations( +std::vector Renderer::GetTextureLocations( const std::span textureIds) { - std::vector allocatedLocations(textureIds.size()); + std::vector allocatedLocations(textureIds.size()); + + std::vector returnVector; + returnVector.reserve(allocatedLocations.size()); size_t newTexturesNeeded = 0; std::vector notFound; for (size_t i = 0; i < textureIds.size(); i++) { - const auto locationsIt = std::find(TextureLocations.begin(), - TextureLocations.end(), textureIds[i]); + const uint32_t textureId = textureIds[i]; + + const auto sameTexture = + [this, textureId](const std::unique_ptr& unit) { + return unit->GetTexture() == textureId; + }; + const auto foundIt = + std::find_if(TextureUnits.begin(), TextureUnits.end(), sameTexture); + + if (foundIt != TextureUnits.end()) { + allocatedLocations[i] = std::distance(TextureUnits.begin(), foundIt); + + // TODO: Remove once textures are managed + // Currently needed because the texture under this ID may be deleted and + // then recreated, meaning the texture would need to be rebound + (*foundIt)->SetTexture(textureId); + + (*foundIt)->Reserve(); - if (locationsIt != TextureLocations.end()) { - allocatedLocations[i] = - std::distance(TextureLocations.begin(), locationsIt); } else { notFound.push_back(i); - const auto textureIt = textureIds.begin() + i; - newTexturesNeeded += - std::find(textureIds.begin(), textureIt, textureIds[i]) == textureIt; + // Check if the current new texture hasn't already been requested + const auto curTextureIt = textureIds.begin() + i; + newTexturesNeeded += std::find(textureIds.begin(), curTextureIt, + textureIds[i]) == curTextureIt; } } // If all textures were found, immediately return their locations - if (notFound.empty()) return allocatedLocations; - - if (TextureLocations.size() + newTexturesNeeded <= MaxTextureCount) { - // If the needed textures still fit in the buffer, add them - TextureLocations.reserve(TextureLocations.size() + newTexturesNeeded); - - for (size_t i : notFound) { - const auto foundIt = std::find(TextureLocations.begin(), - TextureLocations.end(), textureIds[i]); - - if (foundIt != TextureLocations.end()) { - // Texture already added by prior entry in notFound - allocatedLocations[i] = - std::distance(TextureLocations.begin(), foundIt); - - } else { - // Add the texture - const size_t glTextureId = TextureLocations.size(); - glBindTextureUnit(glTextureId, textureIds[i]); - TextureLocations.push_back(textureIds[i]); - allocatedLocations[i] = glTextureId; - } - } + if (notFound.empty()) { + for (size_t unit : allocatedLocations) + returnVector.emplace_back(*TextureUnits[unit]); - return allocatedLocations; + return returnVector; } - // If they do not fit in the buffer, flush and add them - Flush(); + const size_t freeSlots = + std::count_if(TextureUnits.begin(), TextureUnits.end(), + [](const auto& unit) { return !unit->IsLocked(); }); - for (size_t i = 0; i < textureIds.size(); i++) { - const auto foundIt = std::find(TextureLocations.begin(), - TextureLocations.end(), textureIds[i]); + // If the needed textures don't fit in the buffer, flush to make room + if (newTexturesNeeded > freeSlots) Flush(); + + for (size_t i : notFound) { + const uint32_t textureId = textureIds[i]; + const auto sameTexture = + [this, textureId](const std::unique_ptr& unit) { + return unit->GetTexture() == textureId; + }; + const auto foundIt = + std::find_if(TextureUnits.begin(), TextureUnits.end(), sameTexture); - if (foundIt != TextureLocations.end()) { - // Texture already added by prior entry in textureIds - allocatedLocations[i] = std::distance(TextureLocations.begin(), foundIt); + if (foundIt != TextureUnits.end()) { + // Texture already added by prior entry in notFound + allocatedLocations[i] = std::distance(TextureUnits.begin(), foundIt); } else { // Add the texture - const size_t glTextureId = TextureLocations.size(); - glBindTextureUnit(glTextureId, textureIds[i]); - TextureLocations.push_back(textureIds[i]); - allocatedLocations[i] = glTextureId; + const auto freeIt = + std::find_if(TextureUnits.begin(), TextureUnits.end(), + [](const auto& unit) { return !unit->IsLocked(); }); + + (*freeIt)->SetTexture(textureId); + (*freeIt)->Reserve(); + allocatedLocations[i] = std::distance(TextureUnits.begin(), freeIt); } } - return allocatedLocations; + for (size_t unit : allocatedLocations) + returnVector.emplace_back(*TextureUnits[unit]); + + return returnVector; } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, @@ -390,6 +386,11 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, if (sprite.Sheet.IsScreenCap) Flush(); + if (disableBlend) { + Flush(); + glDisable(GL_BLEND); + } + // Set uniform variables if (inverted) { SpriteInvertedUniforms uniforms{ @@ -410,12 +411,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, UseShader(SpriteShaderProgram, uniforms); } - if (disableBlend) { - Flush(); - glDisable(GL_BLEND); - } - - const std::vector textureLocations = + std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture}); // OK, all good, make quad @@ -424,6 +420,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); InsertVerticesQuad(dest, textureLocations[0], uvDest, tints); + // Free texture units for possible flush + textureLocations.clear(); + if (disableBlend) { Flush(); glEnable(GL_BLEND); @@ -459,7 +458,7 @@ void Renderer::DrawMaskedSprite( UseShader(MaskedSpriteShaderProgram, uniforms); - const std::vector textureLocations = + const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad @@ -514,7 +513,7 @@ void Renderer::DrawMaskedSpriteOverlay( UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); } - const std::vector textureLocations = + const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad @@ -568,7 +567,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, } } - const std::vector textureLocations = + const std::vector textureLocations = mask.has_value() ? GetTextureLocations(std::array{ sheet.Texture, mask->Texture}) : GetTextureLocations(std::array{sheet.Texture}); @@ -612,7 +611,7 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, UseShader(CCMessageBoxShaderProgram, uniforms); - const std::vector textureLocations = + const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad @@ -644,7 +643,7 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, UseShader(CHLCCMenuBackgroundShaderProgram, uniforms); - const std::vector textureLocations = + const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); // OK, all good, make quad @@ -676,7 +675,7 @@ void Renderer::Flush() { IndexCount = 0; NextFreeIndex = 0; - TextureLocations.clear(); + for (std::unique_ptr& unit : TextureUnits) unit->Flush(); } void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, @@ -687,7 +686,7 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, return; } - const std::vector textureLocations = + const std::vector textureLocations = GetTextureLocations(std::array{frame.LumaId, frame.CbId, frame.CrId}); YUVFrameUniforms uniforms{ @@ -700,17 +699,6 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, UseShader(YUVFrameShaderProgram, uniforms); - // TODO: Remove hack and create new vertex layout - if (TextureLocations.empty()) { - GLuint maxIndex = - *std::max_element(textureLocations.begin(), textureLocations.end()); - TextureLocations.resize(maxIndex + 1); - - TextureLocations[textureLocations[0]] = frame.LumaId; - TextureLocations[textureLocations[1]] = frame.CbId; - TextureLocations[textureLocations[2]] = frame.CrId; - } - // OK, all good, make quad InsertVerticesQuad(dest, 0, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index cdeb7cec4..0326b7cf9 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -7,6 +7,7 @@ #include "shader.h" #include "glc.h" +#include "textureunit.h" #include "../../profile/game.h" @@ -142,14 +143,13 @@ class Renderer : public BaseRenderer { bool Drawing = false; - static constexpr size_t MaxTextureCount = 15; - static constexpr std::array Textures = { + static constexpr size_t TextureUnitCount = 15; + static constexpr std::array Textures = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - std::vector TextureLocations; + std::array, TextureUnitCount> TextureUnits; - std::vector GetTextureLocations(std::span textureIds); - - std::array Samplers; + std::vector GetTextureLocations( + std::span textureIds); static constexpr size_t MaxVertexCount = 1024 * 1024 / sizeof(VertexBufferSprites); diff --git a/src/renderer/opengl/textureunit.h b/src/renderer/opengl/textureunit.h new file mode 100644 index 000000000..7190517d7 --- /dev/null +++ b/src/renderer/opengl/textureunit.h @@ -0,0 +1,70 @@ +#pragma once + +#include +#include + +namespace Impacto { +namespace OpenGL { + +struct TextureUnitInfo { + uint32_t TextureId = 0; + bool Flushed = true; +}; + +class TextureUnit { + public: + TextureUnit(GLuint unit) : Unit(unit) { + glGenSamplers(1, &Sampler); + glBindSampler(unit, Sampler); + + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glSamplerParameteri(Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glSamplerParameteri(Sampler, GL_TEXTURE_MAX_ANISOTROPY, 16); + } + + ~TextureUnit() { + if (Info.use_count() == 1) glDeleteSamplers(1, &Sampler); + } + + TextureUnit(const TextureUnit& other) + : Unit(other.Unit), Sampler(other.Sampler), Info(other.Info) { + Info->Flushed = false; + } + + TextureUnit(TextureUnit&& other) + : Unit(std::move(other.Unit)), + Sampler(std::move(other.Sampler)), + Info(std::move(other.Info)) {} + + GLuint GetUnit() const { return Unit; } + operator GLuint() const { return GetUnit(); } + + bool IsLocked() const { return Info.use_count() > 1 || !Info->Flushed; } + + uint32_t GetTexture() const { return Info->TextureId; } + bool SetTexture(uint32_t textureId) { + if (IsLocked()) return false; + + Info->TextureId = textureId; + glBindTextureUnit(Unit, textureId); + + return true; + } + + void Flush() { + if (Info.use_count() == 1) Info->Flushed = true; + } + void Reserve() { Info->Flushed = false; } + + private: + const GLuint Unit; + GLuint Sampler; + const std::shared_ptr Info = + std::make_shared(); +}; + +} // namespace OpenGL +} // namespace Impacto From 6dbd9c037ffb7692c9e01529b6daf238114328c6 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 10 Jun 2025 21:25:24 +0200 Subject: [PATCH 72/88] Fix disable blending option --- src/renderer/opengl/renderer.cpp | 2 ++ src/renderer/opengl/textureunit.h | 2 ++ 2 files changed, 4 insertions(+) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index ff4fc0873..52df91d37 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -134,6 +134,8 @@ void Renderer::BeginFrame2D() { NextFreeIndex = 0; glDisable(GL_CULL_FACE); + + glBindSampler(0, TextureUnits[0]->GetSampler()); } void Renderer::EndFrame() { diff --git a/src/renderer/opengl/textureunit.h b/src/renderer/opengl/textureunit.h index 7190517d7..3bb1d9108 100644 --- a/src/renderer/opengl/textureunit.h +++ b/src/renderer/opengl/textureunit.h @@ -54,6 +54,8 @@ class TextureUnit { return true; } + GLuint GetSampler() const { return Sampler; } + void Flush() { if (Info.use_count() == 1) Info->Flushed = true; } From 16885a588b3edccace5f4e59a4b1a67cd55257ac Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 10 Jun 2025 22:04:45 +0200 Subject: [PATCH 73/88] Fix basic font rendering --- src/renderer/renderer.cpp | 28 ++++++++++++++++------------ 1 file changed, 16 insertions(+), 12 deletions(-) diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 3c43b9cf3..08e8f9be1 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -145,7 +145,6 @@ void BaseRenderer::DrawProcessedText_BasicFont( indices[i * 6 + 5] = br; } - uint16_t maxIndex = 0; for (size_t i = 0; i < text.size(); i++) { const ProcessedTextGlyph glyph = text[i]; @@ -162,6 +161,7 @@ void BaseRenderer::DrawProcessedText_BasicFont( InsertQuad(std::span(vertices.begin() + i * 4, 4), dest, destUV, color, maskUV); } + uint16_t maxIndex = vertexCount; if (outlineMode != RendererOutlineMode::None) { // Add outline to the front of the buffers @@ -181,11 +181,12 @@ void BaseRenderer::DrawProcessedText_BasicFont( outlineOpacity * (smoothstepGlyphOpacity ? glm::smoothstep(0.0f, 1.0f, glyph.Opacity) : glyph.Opacity); - std::transform(vertices.begin() + i * 4, vertices.begin() + (i + 1) * 4, - vertices.begin() + i * 4, [color](auto vertex) { - vertex.Tint = color; - return vertex; - }); + const auto glyphStart = vertices.begin() + i * 4; + const auto glyphEnd = glyphStart + 4; + std::transform(glyphStart, glyphEnd, glyphStart, [color](auto vertex) { + vertex.Tint = color; + return vertex; + }); } const auto translateVertex = [](VertexBufferSprites vertex, @@ -207,13 +208,14 @@ void BaseRenderer::DrawProcessedText_BasicFont( maxIndex += vertexCount; // Translate outlines - const auto glyphsBegin = vertices.begin() + vertexCount * 2; - const auto glyphsEnd = vertices.end(); - std::transform(glyphsBegin, glyphsEnd, vertices.begin(), + const auto tlOutlineStart = vertices.begin(); + const auto brOutlineStart = tlOutlineStart + vertexCount; + const auto foregroundStart = brOutlineStart + vertexCount; + std::transform(tlOutlineStart, brOutlineStart, tlOutlineStart, [translateVertex](auto vertex) { return translateVertex(vertex, {-1.0f, -1.0f}); }); - std::transform(glyphsBegin, glyphsEnd, vertices.begin() + vertexCount, + std::transform(brOutlineStart, foregroundStart, brOutlineStart, [translateVertex](auto vertex) { return translateVertex(vertex, {1.0f, 1.0f}); }); @@ -222,9 +224,11 @@ void BaseRenderer::DrawProcessedText_BasicFont( } case RendererOutlineMode::BottomRight: { - std::transform(vertices.begin(), vertices.end(), vertices.begin(), + const auto brOutlineStart = vertices.begin(); + const auto foregroundStart = vertices.begin() + vertexCount; + std::transform(brOutlineStart, foregroundStart, brOutlineStart, [translateVertex](auto vertex) { - return translateVertex(vertex, {-1.0f, -1.0f}); + return translateVertex(vertex, {1.0f, 1.0f}); }); break; From 7575cfbd35dd0aa5833cbef5b151da927cc1eb06 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 10 Jun 2025 22:14:19 +0200 Subject: [PATCH 74/88] Fix chlcc menu background --- src/renderer/opengl/renderer.cpp | 7 ++++--- src/shaders/opengl/CHLCCMenuBackground_frag.glsl | 4 ++-- 2 files changed, 6 insertions(+), 5 deletions(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 52df91d37..280ef449a 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -650,9 +650,10 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, // OK, all good, make quad - InsertVerticesQuad(dest, textureLocations[0], sprite.NormalizedBounds(), - glm::vec4(1.0f), textureLocations[1], - mask.NormalizedBounds()); + CornersQuad uvDest = sprite.NormalizedBounds(); + if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); + InsertVerticesQuad(dest, textureLocations[0], uvDest, glm::vec4(1.0f), + textureLocations[1], mask.NormalizedBounds()); } void Renderer::Flush() { diff --git a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl index 0b84d6cd2..8d55e0f0c 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl @@ -1,8 +1,8 @@ uniform float Alpha; -flat in int ucolorMap; +flat in uint colorMap; in vec2 uv; -flat in int umask; +flat in uint mask; in vec2 maskUV; out vec4 outColor; From 60b73133f988d68288dea92ea6cf658b9d4df6e4 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Tue, 10 Jun 2025 22:43:04 +0200 Subject: [PATCH 75/88] Fixed MaskedSpriteShader's IsSameTexture uniform not being updated --- src/renderer/opengl/shader.cpp | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/renderer/opengl/shader.cpp b/src/renderer/opengl/shader.cpp index 89bbd8853..fa12d6115 100644 --- a/src/renderer/opengl/shader.cpp +++ b/src/renderer/opengl/shader.cpp @@ -343,6 +343,7 @@ MaskedSpriteShader::MaskedSpriteShader(GLint programId) UploadVar(Uniforms.Textures, TexturesLocation); UploadVar(Uniforms.Alpha, AlphaLocation); UploadVar(Uniforms.IsInverted, IsInvertedLocation); + UploadVar(Uniforms.IsSameTexture, IsSameTextureLocation); } void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { @@ -355,6 +356,8 @@ void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); + UpdateVar(newUniforms.IsSameTexture, Uniforms.IsSameTexture, + IsSameTextureLocation); } CCMessageBoxShader::CCMessageBoxShader(GLint programId) From 0a9662c8073bc3f3e5627b5d9126481e81b43f5a Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 11 Jun 2025 16:37:11 +0200 Subject: [PATCH 76/88] 'Fixed' DX9 and VK --- src/renderer/dx9/renderer.cpp | 23 ++++++++++++++--------- src/renderer/renderer.cpp | 8 ++++---- src/renderer/vulkan/renderer.cpp | 23 ++++++++++++++--------- 3 files changed, 32 insertions(+), 22 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 568327a6b..6e87f7fed 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -295,7 +295,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(dest).Transform(transformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -347,11 +348,12 @@ void Renderer::DrawMaskedSprite( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(maskDest, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(CornersQuad(maskDest).Transform(maskTransformation), + sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(spriteDest).Transform(spriteTransformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -409,11 +411,12 @@ void Renderer::DrawMaskedSpriteOverlay( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(CornersQuad(maskDest).Transform(maskTransformation), + mask.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(spriteDest).Transform(spriteTransformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -445,8 +448,10 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, (VertexBufferSprites*)(VertexBuffer + VertexBufferFill); VertexBufferFill += vertices.size_bytes(); - const auto vertexInfoToNDC = [this, sheet](VertexBufferSprites info) { - info.Position = DesignToNDC(info.Position); + const auto vertexInfoToNDC = [this, + transformation](VertexBufferSprites info) { + info.Position = DesignToNDC( + glm::vec2(transformation * glm::vec4(info.Position, 0.0f, 1.0f))); return info; }; std::transform(vertices.begin(), vertices.end(), vertexBuffer, diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index 08e8f9be1..d6f678ad1 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -351,10 +351,10 @@ void BaseRenderer::DrawProcessedText_LBFont( void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, int stride) { - *(glm::vec2*)((uint8_t*)pos + 0 * stride) = quad.TopLeft; - *(glm::vec2*)((uint8_t*)pos + 1 * stride) = quad.BottomLeft; - *(glm::vec2*)((uint8_t*)pos + 2 * stride) = quad.BottomRight; - *(glm::vec2*)((uint8_t*)pos + 3 * stride) = quad.TopRight; + *(glm::vec2*)((uint8_t*)pos + 0 * stride) = DesignToNDC(quad.TopLeft); + *(glm::vec2*)((uint8_t*)pos + 1 * stride) = DesignToNDC(quad.BottomLeft); + *(glm::vec2*)((uint8_t*)pos + 2 * stride) = DesignToNDC(quad.BottomRight); + *(glm::vec2*)((uint8_t*)pos + 3 * stride) = DesignToNDC(quad.TopRight); } void BaseRenderer::QuadSetUV(const CornersQuad bounds, diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index b6623ced7..a27f520a5 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1166,7 +1166,8 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetPosition(dest, &vertices[0].Position, sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(dest).Transform(transformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -1243,11 +1244,12 @@ void Renderer::DrawMaskedSprite( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(maskDest, sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(CornersQuad(maskDest).Transform(maskTransformation), + sprite.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(spriteDest).Transform(spriteTransformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -1340,11 +1342,12 @@ void Renderer::DrawMaskedSpriteOverlay( QuadSetUV(sprite.Bounds, sprite.Sheet.GetDimensions(), &vertices[0].UV, sizeof(VertexBufferSprites)); - QuadSetUV(maskDest, mask.Sheet.GetDimensions(), &vertices[0].MaskUV, + QuadSetUV(CornersQuad(maskDest).Transform(maskTransformation), + mask.Sheet.GetDimensions(), &vertices[0].MaskUV, sizeof(VertexBufferSprites)); - QuadSetPosition(spriteDest, &vertices[0].Position, - sizeof(VertexBufferSprites)); + QuadSetPosition(CornersQuad(spriteDest).Transform(spriteTransformation), + &vertices[0].Position, sizeof(VertexBufferSprites)); for (int i = 0; i < 4; i++) vertices[i].Tint = tints[i]; } @@ -1379,8 +1382,10 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, VertexBufferFill); VertexBufferFill += vertices.size_bytes(); - const auto vertexInfoToNDC = [this](VertexBufferSprites info) { - info.Position = DesignToNDC(info.Position); + const auto vertexInfoToNDC = [this, + transformation](VertexBufferSprites info) { + info.Position = DesignToNDC( + glm::vec2(transformation * glm::vec4(info.Position, 0.0f, 1.0f))); return info; }; std::transform(vertices.begin(), vertices.end(), vertexBuffer, From 44c14fff626715883711246436fc908280707e56 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 11 Jun 2025 17:28:31 +0200 Subject: [PATCH 77/88] Change vertex/index buffers to use vectors instead of arrays --- src/renderer/opengl/renderer.cpp | 28 ++++++++++++++-------------- src/renderer/opengl/renderer.h | 6 ++---- 2 files changed, 16 insertions(+), 18 deletions(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 280ef449a..82e3e89b2 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -129,8 +129,8 @@ void Renderer::BeginFrame2D() { Drawing = true; - VertexCount = 0; - IndexCount = 0; + VertexBuffer.clear(); + IndexBuffer.clear(); NextFreeIndex = 0; glDisable(GL_CULL_FACE); @@ -229,18 +229,17 @@ void Renderer::InsertVertices( if (vertices.empty() || indices.empty()) return; assert(indices.size() <= MaxIndexCount); - if (IndexCount + indices.size() > MaxIndexCount) Flush(); + if (IndexBuffer.size() + indices.size() > MaxIndexCount) Flush(); const uint16_t maxIndex = *std::max_element(indices.begin(), indices.end()); - std::copy(vertices.begin(), vertices.end(), - VertexBuffer.begin() + VertexCount); - VertexCount += vertices.size(); + VertexBuffer.insert(VertexBuffer.end(), vertices.begin(), vertices.end()); + const size_t indexOffset = IndexBuffer.size(); + IndexBuffer.resize(IndexBuffer.size() + indices.size()); std::transform( - indices.begin(), indices.end(), IndexBuffer.begin() + IndexCount, + indices.begin(), indices.end(), IndexBuffer.begin() + indexOffset, [this](uint16_t index) { return index + this->NextFreeIndex; }); - IndexCount += indices.size(); NextFreeIndex += maxIndex + 1; } @@ -662,20 +661,21 @@ void Renderer::Flush() { "Renderer->Flush() called before BeginFrame()\n"); return; } - if (VertexCount != 0 && IndexCount != 0) { + if (!VertexBuffer.empty() && !IndexBuffer.empty()) { glBindBuffer(GL_ARRAY_BUFFER, VBO); - glBufferData(GL_ARRAY_BUFFER, VertexCount * sizeof(VertexBufferSprites), + glBufferData(GL_ARRAY_BUFFER, + VertexBuffer.size() * sizeof(VertexBufferSprites), VertexBuffer.data(), GL_DYNAMIC_DRAW); glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); - glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexCount * sizeof(uint16_t), + glBufferData(GL_ELEMENT_ARRAY_BUFFER, IndexBuffer.size() * sizeof(uint16_t), IndexBuffer.data(), GL_DYNAMIC_DRAW); - glDrawElements(GL_TRIANGLES, IndexCount, GL_UNSIGNED_SHORT, 0); + glDrawElements(GL_TRIANGLES, IndexBuffer.size(), GL_UNSIGNED_SHORT, 0); } - VertexCount = 0; - IndexCount = 0; + VertexBuffer.clear(); + IndexBuffer.clear(); NextFreeIndex = 0; for (std::unique_ptr& unit : TextureUnits) unit->Flush(); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 0326b7cf9..9f3eef0d6 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -156,11 +156,9 @@ class Renderer : public BaseRenderer { static constexpr uint16_t MaxIndexCount = std::numeric_limits::max(); - std::array VertexBuffer; - std::array IndexBuffer; + std::vector VertexBuffer; + std::vector IndexBuffer; - size_t VertexCount = 0; - size_t IndexCount = 0; uint16_t NextFreeIndex = 0; const glm::mat4 Projection = From 74869557879d0ce37d70d52f6de53e9cde6d6807 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 11 Jun 2025 17:28:51 +0200 Subject: [PATCH 78/88] Added override for cclcc system menu --- src/games/cclcc/systemmenu.cpp | 5 ++++- src/renderer/dx9/renderer.cpp | 3 ++- src/renderer/dx9/renderer.h | 3 ++- src/renderer/opengl/renderer.cpp | 19 ++++++++++++++++++- src/renderer/opengl/renderer.h | 3 ++- src/renderer/renderer.h | 3 ++- src/renderer/vulkan/renderer.cpp | 3 ++- src/renderer/vulkan/renderer.h | 3 ++- 8 files changed, 34 insertions(+), 8 deletions(-) diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 146fc283c..0888b8431 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -195,7 +195,10 @@ void SystemMenu::Render() { CornersQuad(BGDispOffsetTopLeft, BGDispOffsetBottomLeft, BGDispOffsetTopRight, BGDispOffsetBottomRight) .Transform(transformation); - Renderer->DrawSprite(offsetSystemMenuBG, bgDisp); + Renderer->DrawSprite(offsetSystemMenuBG, bgDisp, glm::mat4(1.0f), + std::array{glm::vec4(1.0f), glm::vec4(1.0f), + glm::vec4(1.0f), glm::vec4(1.0f)}, + false, false, true); if (!GetFlag(SF_SYSTEMMENUDIRECT)) { const CornersQuad frameDisp = diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 6e87f7fed..1de36a227 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -266,7 +266,8 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const glm::mat4 transformation, const std::span tints, - const bool inverted, const bool disableBlend) { + const bool inverted, const bool disableBlend, + const bool textureWrapRepeat) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 57bca1720..354396862 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -36,7 +36,8 @@ class Renderer : public BaseRenderer { void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::mat4 transformation, std::span tints, - bool inverted, bool disableBlend) override; + bool inverted, bool disableBlend, + bool textureWrapRepeat) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 82e3e89b2..f1feecad8 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -378,7 +378,8 @@ std::vector Renderer::GetTextureLocations( void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const glm::mat4 transformation, const std::span tints, - const bool inverted, const bool disableBlend) { + const bool inverted, const bool disableBlend, + const bool textureWrapRepeat) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); @@ -387,6 +388,14 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, if (sprite.Sheet.IsScreenCap) Flush(); + if (textureWrapRepeat) { + Flush(); + const GLuint sampler = TextureUnits[0]->GetSampler(); + glBindSampler(0, sampler); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + } + if (disableBlend) { Flush(); glDisable(GL_BLEND); @@ -428,6 +437,14 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, Flush(); glEnable(GL_BLEND); } + + if (textureWrapRepeat) { + Flush(); + const GLuint sampler = TextureUnits[0]->GetSampler(); + glBindSampler(0, sampler); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + } } void Renderer::DrawMaskedSprite( diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 9f3eef0d6..5324a1f90 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -39,7 +39,8 @@ class Renderer : public BaseRenderer { void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::mat4 transformation, std::span tints, - bool inverted, bool disableBlend) override; + bool inverted, bool disableBlend, + bool textureWrapRepeat) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 6eccdfba7..892746cd6 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -56,7 +56,8 @@ class BaseRenderer { virtual void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::mat4 transformation, std::span tints, - bool inverted = false, bool disableBlend = false) = 0; + bool inverted = false, bool disableBlend = false, + bool textureWrapRepeat = false) = 0; void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::mat4 transformation = glm::mat4(1.0f), diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index a27f520a5..361df570e 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1135,7 +1135,8 @@ YUVFrame* Renderer::CreateYUVFrame(float width, float height) { void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, const glm::mat4 transformation, const std::span tints, - const bool inverted, const bool disableBlend) { + const bool inverted, const bool disableBlend, + const bool textureWrapRepeat) { if (!Drawing) { ImpLog(LogLevel::Error, LogChannel::Render, "Renderer->DrawSprite() called before BeginFrame()\n"); diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index aad9ec18a..f3b708c51 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -64,7 +64,8 @@ class Renderer : public BaseRenderer { void DrawSprite(const Sprite& sprite, const CornersQuad& dest, glm::mat4 transformation, std::span tints, - bool inverted, bool disableBlend) override; + bool inverted, bool disableBlend, + bool textureWrapRepeat) override; void DrawMaskedSprite(const Sprite& sprite, const Sprite& mask, const CornersQuad& spriteDest, From 6d18e543044b05f5e1ee072b68f8cd4b41a00c45 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Wed, 11 Jun 2025 17:23:22 +0200 Subject: [PATCH 79/88] Fix OpenGL DrawMaskedSpriteOverlay mask UVs --- src/renderer/opengl/renderer.cpp | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index f1feecad8..fc91c586b 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -536,8 +536,11 @@ void Renderer::DrawMaskedSpriteOverlay( // OK, all good, make quad + CornersQuad normalizedMaskDest = CornersQuad(maskDest).Scale( + {1.0f / mask.Sheet.DesignWidth, 1.0f / mask.Sheet.DesignHeight}, + {0.0f, 0.0f}); InsertVerticesQuad(spriteDest, textureLocations[0], sprite.NormalizedBounds(), - tints, textureLocations[1], mask.NormalizedBounds()); + tints, textureLocations[1], normalizedMaskDest); } void Renderer::DrawVertices(const SpriteSheet& sheet, From d817132574889e9b70dbd088dda2dcc4671a48e4 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 12 Jun 2025 12:53:53 +0200 Subject: [PATCH 80/88] Altered pointer use --- src/renderer/opengl/3d/renderable3d.cpp | 11 +++-- src/renderer/opengl/3d/renderable3d.h | 3 +- src/renderer/opengl/3d/scene.cpp | 5 +-- src/renderer/opengl/3d/scene.h | 4 +- src/renderer/opengl/renderer.cpp | 60 +++++++++++-------------- src/renderer/opengl/renderer.h | 26 +++++------ 6 files changed, 48 insertions(+), 61 deletions(-) diff --git a/src/renderer/opengl/3d/renderable3d.cpp b/src/renderer/opengl/3d/renderable3d.cpp index bd3e0d2a3..d86802588 100644 --- a/src/renderer/opengl/3d/renderable3d.cpp +++ b/src/renderer/opengl/3d/renderable3d.cpp @@ -61,8 +61,7 @@ static bool CurrentMaterialIsDepthWrite = false; static GLWindow* Window; -void Renderable3D::Init(GLWindow* window, - std::shared_ptr shaderCompiler) { +void Renderable3D::Init(GLWindow* window, ShaderCompiler& shaderCompiler) { assert(IsInit == false); ImpLog(LogLevel::Info, LogChannel::Renderable3D, "Initializing Renderable3D system\n"); @@ -76,13 +75,13 @@ void Renderable3D::Init(GLWindow* window, shaderParams["DASH"] = ShaderParameter(isDaSH, true); ShaderProgram = - shaderCompiler->Compile("Renderable3D_Character", shaderParams); + shaderCompiler.Compile("Renderable3D_Character", shaderParams); ShaderProgramOutline = - shaderCompiler->Compile("Renderable3D_Outline", shaderParams); - ShaderProgramEye = shaderCompiler->Compile("Renderable3D_Eye", shaderParams); + shaderCompiler.Compile("Renderable3D_Outline", shaderParams); + ShaderProgramEye = shaderCompiler.Compile("Renderable3D_Eye", shaderParams); ShaderProgramBackground = - shaderCompiler->Compile("Renderable3D_Background", shaderParams); + shaderCompiler.Compile("Renderable3D_Background", shaderParams); GLuint sceneUniformIndices[SU_Count]; glGetUniformIndices(ShaderProgram, SU_Count, SceneUniformNames, diff --git a/src/renderer/opengl/3d/renderable3d.h b/src/renderer/opengl/3d/renderable3d.h index e92be602f..2fff6ff85 100644 --- a/src/renderer/opengl/3d/renderable3d.h +++ b/src/renderer/opengl/3d/renderable3d.h @@ -12,8 +12,7 @@ enum RenderPass { RP_Outline = 0, RP_First = 1, RP_Second = 2, RP_Count }; class Renderable3D : public IRenderable3D { public: - static void Init(GLWindow* window, - std::shared_ptr shaderCompiler); + static void Init(GLWindow* window, ShaderCompiler& shaderCompiler); static void BeginFrame(IScene3D* scene, Camera* camera); void MakePlane() override; diff --git a/src/renderer/opengl/3d/scene.cpp b/src/renderer/opengl/3d/scene.cpp index aa1fa330f..a8ecd42ca 100644 --- a/src/renderer/opengl/3d/scene.cpp +++ b/src/renderer/opengl/3d/scene.cpp @@ -11,8 +11,7 @@ namespace Impacto { namespace OpenGL { -Scene3D::Scene3D(GLWindow* window, - std::shared_ptr shaderCompiler) +Scene3D::Scene3D(GLWindow* window, ShaderCompiler& shaderCompiler) : Window(window), Shaders(shaderCompiler) {} void Scene3D::Init() { @@ -210,7 +209,7 @@ void Scene3D::SetupFramebufferState() { glm::vec2(viewport.Width, viewport.Height); shaderParams["RenderScale"] = Window->RenderScale; - ShaderProgram = Shaders->Compile("SceneToRT", shaderParams); + ShaderProgram = Shaders.Compile("SceneToRT", shaderParams); glUseProgram(ShaderProgram); glUniform1i(glGetUniformLocation(ShaderProgram, "Framebuffer3D"), 0); diff --git a/src/renderer/opengl/3d/scene.h b/src/renderer/opengl/3d/scene.h index acbd8ea7f..cea8fe54e 100644 --- a/src/renderer/opengl/3d/scene.h +++ b/src/renderer/opengl/3d/scene.h @@ -24,7 +24,7 @@ enum MSResolveMode { class Scene3D : public IScene3D { public: - Scene3D(GLWindow* window, std::shared_ptr shaderCompiler); + Scene3D(GLWindow* window, ShaderCompiler& shaderCompiler); void Init(); void Shutdown(); @@ -35,7 +35,7 @@ class Scene3D : public IScene3D { bool IsInit = false; GLWindow* Window; - std::shared_ptr Shaders; + ShaderCompiler& Shaders; void SetupFramebufferState(); void CleanFramebufferState(); diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index fc91c586b..60f59c97b 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -25,8 +25,6 @@ void Renderer::Init() { OpenGLWindow->Init(); Window = (BaseWindow*)OpenGLWindow; - Shaders = std::make_shared(); - if (Profile::GameFeatures & GameFeature::Scene3D) { Scene = new Scene3D(OpenGLWindow, Shaders); Scene->Init(); @@ -70,25 +68,17 @@ void Renderer::Init() { RectSprite = Sprite(rectSheet, 0.0f, 0.0f, 1.0f, 1.0f); // Set up shaders - SpriteShaderProgram = - std::make_unique(Shaders->Compile("Sprite")); - SpriteInvertedShaderProgram = std::make_unique( - Shaders->Compile("SpriteInverted")); - MaskedSpriteShaderProgram = - std::make_unique(Shaders->Compile("MaskedSprite")); - MaskedSpriteNoAlphaShaderProgram = - std::make_unique( - Shaders->Compile("MaskedSpriteNoAlpha")); - YUVFrameShaderProgram = - std::make_unique(Shaders->Compile("YUVFrame")); - CCMessageBoxShaderProgram = std::make_unique( - Shaders->Compile("CCMessageBoxSprite")); - CHLCCMenuBackgroundShaderProgram = - std::make_unique( - Shaders->Compile("CHLCCMenuBackground")); - - for (size_t i = 0; i < TextureUnitCount; i++) - TextureUnits[i] = std::make_unique(i); + SpriteShaderProgram.emplace(Shaders.Compile("Sprite")); + SpriteInvertedShaderProgram.emplace(Shaders.Compile("SpriteInverted")); + MaskedSpriteShaderProgram.emplace(Shaders.Compile("MaskedSprite")); + MaskedSpriteNoAlphaShaderProgram.emplace( + Shaders.Compile("MaskedSpriteNoAlpha")); + YUVFrameShaderProgram.emplace(Shaders.Compile("YUVFrame")); + CCMessageBoxShaderProgram.emplace(Shaders.Compile("CCMessageBoxSprite")); + CHLCCMenuBackgroundShaderProgram.emplace( + Shaders.Compile("CHLCCMenuBackground")); + + for (size_t i = 0; i < TextureUnitCount; i++) TextureUnits[i].emplace(i); glActiveTexture(GL_TEXTURE0 + TextureUnitCount); } @@ -303,7 +293,7 @@ std::vector Renderer::GetTextureLocations( const uint32_t textureId = textureIds[i]; const auto sameTexture = - [this, textureId](const std::unique_ptr& unit) { + [this, textureId](const std::optional& unit) { return unit->GetTexture() == textureId; }; const auto foundIt = @@ -347,7 +337,7 @@ std::vector Renderer::GetTextureLocations( for (size_t i : notFound) { const uint32_t textureId = textureIds[i]; const auto sameTexture = - [this, textureId](const std::unique_ptr& unit) { + [this, textureId](const std::optional& unit) { return unit->GetTexture() == textureId; }; const auto foundIt = @@ -409,7 +399,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, .Textures = Textures, }; - UseShader(SpriteInvertedShaderProgram, uniforms); + UseShader(*SpriteInvertedShaderProgram, uniforms); } else { SpriteUniforms uniforms{ @@ -418,7 +408,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, .Textures = Textures, }; - UseShader(SpriteShaderProgram, uniforms); + UseShader(*SpriteShaderProgram, uniforms); } std::vector textureLocations = @@ -474,7 +464,7 @@ void Renderer::DrawMaskedSprite( .IsSameTexture = isSameTexture, }; - UseShader(MaskedSpriteShaderProgram, uniforms); + UseShader(*MaskedSpriteShaderProgram, uniforms); const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); @@ -516,7 +506,7 @@ void Renderer::DrawMaskedSpriteOverlay( .IsSameTexture = false, }; - UseShader(MaskedSpriteShaderProgram, uniforms); + UseShader(*MaskedSpriteShaderProgram, uniforms); } else { MaskedSpriteNoAlphaUniforms uniforms{ @@ -528,7 +518,7 @@ void Renderer::DrawMaskedSpriteOverlay( .IsInverted = isInverted, }; - UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); + UseShader(*MaskedSpriteNoAlphaShaderProgram, uniforms); } const std::vector textureLocations = @@ -565,7 +555,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, .IsInverted = inverted, }; - UseShader(MaskedSpriteNoAlphaShaderProgram, uniforms); + UseShader(*MaskedSpriteNoAlphaShaderProgram, uniforms); } else { if (inverted) { @@ -575,7 +565,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, .Textures = Textures, }; - UseShader(SpriteInvertedShaderProgram, uniforms); + UseShader(*SpriteInvertedShaderProgram, uniforms); } else { SpriteUniforms uniforms{ @@ -584,7 +574,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, .Textures = Textures, }; - UseShader(SpriteShaderProgram, uniforms); + UseShader(*SpriteShaderProgram, uniforms); } } @@ -630,7 +620,7 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, .Alpha = {alphaRange, constAlpha, effectCt, 0.0f}, }; - UseShader(CCMessageBoxShaderProgram, uniforms); + UseShader(*CCMessageBoxShaderProgram, uniforms); const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); @@ -662,7 +652,7 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, .Alpha = alpha, }; - UseShader(CHLCCMenuBackgroundShaderProgram, uniforms); + UseShader(*CHLCCMenuBackgroundShaderProgram, uniforms); const std::vector textureLocations = GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); @@ -698,7 +688,7 @@ void Renderer::Flush() { IndexBuffer.clear(); NextFreeIndex = 0; - for (std::unique_ptr& unit : TextureUnits) unit->Flush(); + for (std::optional& unit : TextureUnits) unit->Flush(); } void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, @@ -720,7 +710,7 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, .IsAlpha = alphaVideo, }; - UseShader(YUVFrameShaderProgram, uniforms); + UseShader(*YUVFrameShaderProgram, uniforms); // OK, all good, make quad diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 5324a1f90..420d95614 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -93,29 +93,29 @@ class Renderer : public BaseRenderer { void DisableScissor() override; private: - std::unique_ptr SpriteShaderProgram; - std::unique_ptr SpriteInvertedShaderProgram; - std::unique_ptr MaskedSpriteShaderProgram; - std::unique_ptr MaskedSpriteNoAlphaShaderProgram; - std::unique_ptr YUVFrameShaderProgram; - std::unique_ptr CCMessageBoxShaderProgram; - std::unique_ptr CHLCCMenuBackgroundShaderProgram; + std::optional SpriteShaderProgram; + std::optional SpriteInvertedShaderProgram; + std::optional MaskedSpriteShaderProgram; + std::optional MaskedSpriteNoAlphaShaderProgram; + std::optional YUVFrameShaderProgram; + std::optional CCMessageBoxShaderProgram; + std::optional CHLCCMenuBackgroundShaderProgram; const void* CurrentShaderProgram = nullptr; template - void UseShader(std::unique_ptr& shader, UniformsStruct uniforms) { + void UseShader(ShaderType& shader, UniformsStruct uniforms) { static_assert(std::is_base_of, ShaderType>()); if (CurrentShaderProgram != &shader) { Flush(); CurrentShaderProgram = &shader; - shader->Bind(); + shader.Bind(); } - if (shader->GetUniforms() != uniforms) { + if (shader.GetUniforms() != uniforms) { Flush(); - shader->UploadUniforms(uniforms); + shader.UploadUniforms(uniforms); } } @@ -147,7 +147,7 @@ class Renderer : public BaseRenderer { static constexpr size_t TextureUnitCount = 15; static constexpr std::array Textures = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - std::array, TextureUnitCount> TextureUnits; + std::array, TextureUnitCount> TextureUnits; std::vector GetTextureLocations( std::span textureIds); @@ -166,7 +166,7 @@ class Renderer : public BaseRenderer { glm::ortho(0.0f, Profile::DesignWidth, Profile::DesignHeight, 0.0f); // ShaderCompiler compiler - std::shared_ptr Shaders; + ShaderCompiler Shaders; bool ScissorEnabled = false; }; From b45a557597a5aa1f78b10399d4548aec2b2a89c4 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 12 Jun 2025 13:05:43 +0200 Subject: [PATCH 81/88] Changed some initializations to brace initializations --- src/games/cclcc/systemmenu.cpp | 21 ++++++++++----------- src/renderer/opengl/shader.h | 34 +++++++++++++++++----------------- 2 files changed, 27 insertions(+), 28 deletions(-) diff --git a/src/games/cclcc/systemmenu.cpp b/src/games/cclcc/systemmenu.cpp index 0888b8431..5e749b17c 100644 --- a/src/games/cclcc/systemmenu.cpp +++ b/src/games/cclcc/systemmenu.cpp @@ -192,8 +192,8 @@ void SystemMenu::Render() { }; const CornersQuad bgDisp = - CornersQuad(BGDispOffsetTopLeft, BGDispOffsetBottomLeft, - BGDispOffsetTopRight, BGDispOffsetBottomRight) + CornersQuad{BGDispOffsetTopLeft, BGDispOffsetBottomLeft, + BGDispOffsetTopRight, BGDispOffsetBottomRight} .Transform(transformation); Renderer->DrawSprite(offsetSystemMenuBG, bgDisp, glm::mat4(1.0f), std::array{glm::vec4(1.0f), glm::vec4(1.0f), @@ -202,20 +202,19 @@ void SystemMenu::Render() { if (!GetFlag(SF_SYSTEMMENUDIRECT)) { const CornersQuad frameDisp = - CornersQuad(glm::vec2{bgOffset, 0} + FrameOffsetTopLeft, + CornersQuad{glm::vec2{bgOffset, 0} + FrameOffsetTopLeft, glm::vec2{bgOffset, 0} + FrameOffsetBottomLeft, glm::vec2{bgOffset, 0} + FrameOffsetTopRight, - glm::vec2{bgOffset, 0} + FrameOffsetBottomRight) + glm::vec2{bgOffset, 0} + FrameOffsetBottomRight} .Transform(transformation); Renderer->DrawSprite(SystemMenuFrame, frameDisp); - const CornersQuad screenCapDisp = - CornersQuad( - glm::vec2{bgOffset + 0, 0}, - glm::vec2{bgOffset + 0, Profile::DesignHeight}, - glm::vec2{bgOffset + Profile::DesignWidth, 0}, - glm::vec2{bgOffset + Profile::DesignWidth, Profile::DesignHeight}) - .Transform(transformation); + const CornersQuad screenCapDisp = CornersQuad{ + glm::vec2{bgOffset + 0, 0}, + glm::vec2{bgOffset + 0, Profile::DesignHeight}, + glm::vec2{bgOffset + Profile::DesignWidth, 0}, + glm::vec2{bgOffset + Profile::DesignWidth, + Profile::DesignHeight}}.Transform(transformation); Renderer->DrawSprite(ScreenCap, screenCapDisp, glm::vec4(1.0f), false, true); } diff --git a/src/renderer/opengl/shader.h b/src/renderer/opengl/shader.h index a384447e3..923757756 100644 --- a/src/renderer/opengl/shader.h +++ b/src/renderer/opengl/shader.h @@ -89,7 +89,7 @@ class Shader { protected: const GLuint ProgramId; - UniformsStruct Uniforms; + UniformsStruct Uniforms{}; void UploadVar(bool value, GLint location) { glUniform1i(location, value); } void UploadVar(int value, GLint location) { glUniform1i(location, value); } @@ -122,8 +122,8 @@ class Shader { struct SpriteUniforms { bool operator==(const SpriteUniforms& other) const = default; - glm::mat4 Projection; - glm::mat4 Transformation; + glm::mat4 Projection{}; + glm::mat4 Transformation{}; std::array Textures; }; @@ -144,8 +144,8 @@ class SpriteShader : public Shader { struct SpriteInvertedUniforms { bool operator==(const SpriteInvertedUniforms& other) const = default; - glm::mat4 Projection; - glm::mat4 Transformation; + glm::mat4 Projection{}; + glm::mat4 Transformation{}; std::array Textures; }; @@ -171,7 +171,7 @@ struct YUVFrameUniforms { GLint Luma = 0; GLint Cb = 0; GLint Cr = 0; - bool IsAlpha; + bool IsAlpha = false; }; class YUVFrameShader : public Shader { @@ -192,12 +192,12 @@ class YUVFrameShader : public Shader { struct MaskedSpriteNoAlphaUniforms { bool operator==(const MaskedSpriteNoAlphaUniforms& other) const = default; - glm::mat4 Projection = glm::mat4(); - glm::mat4 SpriteTransformation = glm::mat4(); - glm::mat4 MaskTransformation = glm::mat4(); + glm::mat4 Projection{}; + glm::mat4 SpriteTransformation{}; + glm::mat4 MaskTransformation{}; std::array Textures; - glm::vec2 Alpha = glm::vec2(); + glm::vec2 Alpha{}; bool IsInverted = false; }; @@ -220,12 +220,12 @@ class MaskedSpriteNoAlphaShader : public Shader { struct MaskedSpriteUniforms { bool operator==(const MaskedSpriteUniforms& other) const = default; - glm::mat4 Projection = glm::mat4(); - glm::mat4 SpriteTransformation = glm::mat4(); - glm::mat4 MaskTransformation = glm::mat4(); + glm::mat4 Projection{}; + glm::mat4 SpriteTransformation{}; + glm::mat4 MaskTransformation{}; std::array Textures; - glm::vec2 Alpha = glm::vec2(); + glm::vec2 Alpha{}; bool IsInverted = false; bool IsSameTexture = false; }; @@ -250,10 +250,10 @@ class MaskedSpriteShader : public Shader { struct CCMessageBoxUniforms { bool operator==(const CCMessageBoxUniforms& other) const = default; - glm::mat4 Projection = glm::mat4(); + glm::mat4 Projection{}; std::array Textures; - glm::vec4 Alpha = glm::vec4(); + glm::vec4 Alpha{}; }; class CCMessageBoxShader : public Shader { @@ -272,7 +272,7 @@ class CCMessageBoxShader : public Shader { struct CHLCCMenuBackgroundUniforms { bool operator==(const CHLCCMenuBackgroundUniforms& other) const = default; - glm::mat4 Projection = glm::mat4(); + glm::mat4 Projection{}; std::array Textures; float Alpha = 0.0f; From cb19bc07cbd0c50f99dc7b678a0c155d6e89bec0 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 12 Jun 2025 13:14:00 +0200 Subject: [PATCH 82/88] Removed some resize calls in favor of back_inserter --- src/renderer/opengl/renderer.cpp | 4 ++-- src/renderer/renderer.cpp | 5 ++--- 2 files changed, 4 insertions(+), 5 deletions(-) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 60f59c97b..6cc478692 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -226,9 +226,9 @@ void Renderer::InsertVertices( VertexBuffer.insert(VertexBuffer.end(), vertices.begin(), vertices.end()); const size_t indexOffset = IndexBuffer.size(); - IndexBuffer.resize(IndexBuffer.size() + indices.size()); + IndexBuffer.reserve(IndexBuffer.size() + indices.size()); std::transform( - indices.begin(), indices.end(), IndexBuffer.begin() + indexOffset, + indices.begin(), indices.end(), std::back_inserter(IndexBuffer), [this](uint16_t index) { return index + this->NextFreeIndex; }); NextFreeIndex += maxIndex + 1; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index d6f678ad1..f84a74372 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -167,9 +167,8 @@ void BaseRenderer::DrawProcessedText_BasicFont( // Add outline to the front of the buffers vertices.insert(vertices.end(), vertices.begin(), vertices.end()); - indices.resize(indexCount * 2); - std::transform(indices.begin(), indices.begin() + indexCount, - indices.begin() + indexCount, + indices.reserve(indexCount * 2); + std::transform(indices.begin(), indices.end(), std::back_inserter(indices), [maxIndex](uint16_t index) { return index + maxIndex; }); maxIndex += vertexCount; From 7da1885e1cb8f7ebab2e11159540d918cc0411a4 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 12 Jun 2025 13:31:54 +0200 Subject: [PATCH 83/88] Added TextureUnit assignment operators --- src/renderer/opengl/textureunit.h | 25 ++++++++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/src/renderer/opengl/textureunit.h b/src/renderer/opengl/textureunit.h index 3bb1d9108..f690fdcf5 100644 --- a/src/renderer/opengl/textureunit.h +++ b/src/renderer/opengl/textureunit.h @@ -39,6 +39,26 @@ class TextureUnit { Sampler(std::move(other.Sampler)), Info(std::move(other.Info)) {} + TextureUnit& operator=(const TextureUnit& other) { + if (Info.use_count() == 1 && &other != this) glDeleteSamplers(1, &Sampler); + + Unit = other.Unit; + Sampler = other.Sampler; + Info = other.Info; + + return *this; + } + + TextureUnit& operator=(TextureUnit&& other) { + if (Info.use_count() == 1 && &other != this) glDeleteSamplers(1, &Sampler); + + Unit = std::move(other.Unit); + Sampler = std::move(other.Sampler); + Info = std::move(other.Info); + + return *this; + } + GLuint GetUnit() const { return Unit; } operator GLuint() const { return GetUnit(); } @@ -62,10 +82,9 @@ class TextureUnit { void Reserve() { Info->Flushed = false; } private: - const GLuint Unit; + GLuint Unit; GLuint Sampler; - const std::shared_ptr Info = - std::make_shared(); + std::shared_ptr Info = std::make_shared(); }; } // namespace OpenGL From f0dfb67aebdf513bdf400c57b506b4a71fc5a51e Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 12 Jun 2025 13:42:02 +0200 Subject: [PATCH 84/88] Changed DrawVertices to take in a nullable Sprite* for the mask --- src/renderer/dx9/renderer.cpp | 2 +- src/renderer/dx9/renderer.h | 3 +-- src/renderer/opengl/renderer.cpp | 10 +++++----- src/renderer/opengl/renderer.h | 3 +-- src/renderer/renderer.cpp | 11 +++-------- src/renderer/renderer.h | 13 +++++-------- src/renderer/vulkan/renderer.cpp | 2 +- src/renderer/vulkan/renderer.h | 3 +-- 8 files changed, 18 insertions(+), 29 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index 1de36a227..c790cf711 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -423,7 +423,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, - const std::optional mask, + const SpriteSheet* const mask, const std::span vertices, const std::span indices, const glm::mat4 transformation, diff --git a/src/renderer/dx9/renderer.h b/src/renderer/dx9/renderer.h index 354396862..aec51b9bd 100644 --- a/src/renderer/dx9/renderer.h +++ b/src/renderer/dx9/renderer.h @@ -55,8 +55,7 @@ class Renderer : public BaseRenderer { std::span tints, bool isInverted, bool useMaskAlpha) override; - void DrawVertices(const SpriteSheet& sheet, - std::optional mask, + void DrawVertices(const SpriteSheet& sheet, const SpriteSheet* mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 6cc478692..44d94ab22 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -534,7 +534,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, - const std::optional mask, + const SpriteSheet* const mask, const std::span vertices, const std::span indices, glm::mat4 transformation, const bool inverted) { @@ -545,7 +545,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, } // Set uniform variables - if (mask.has_value()) { + if (mask != nullptr) { MaskedSpriteNoAlphaUniforms uniforms{ .Projection = Projection, .SpriteTransformation = transformation, @@ -579,9 +579,9 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, } const std::vector textureLocations = - mask.has_value() ? GetTextureLocations(std::array{ - sheet.Texture, mask->Texture}) - : GetTextureLocations(std::array{sheet.Texture}); + mask ? GetTextureLocations( + std::array{sheet.Texture, mask->Texture}) + : GetTextureLocations(std::array{sheet.Texture}); std::vector transformedVertices; transformedVertices.resize(vertices.size()); diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 420d95614..925b92c5f 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -58,8 +58,7 @@ class Renderer : public BaseRenderer { std::span tints, bool isInverted, bool useMaskAlpha) override; - void DrawVertices(const SpriteSheet& sheet, - std::optional mask, + void DrawVertices(const SpriteSheet& sheet, const SpriteSheet* mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; diff --git a/src/renderer/renderer.cpp b/src/renderer/renderer.cpp index f84a74372..f3cb48bb5 100644 --- a/src/renderer/renderer.cpp +++ b/src/renderer/renderer.cpp @@ -240,18 +240,13 @@ void BaseRenderer::DrawProcessedText_BasicFont( } } - const std::optional mask = - maskedSheet ? std::optional(*maskedSheet) : std::nullopt; - DrawVertices(font->Sheet, mask, vertices, indices); + DrawVertices(font->Sheet, maskedSheet, vertices, indices); } void BaseRenderer::DrawProcessedText_LBFont( std::span text, LBFont* font, float opacity, RendererOutlineMode outlineMode, bool smoothstepGlyphOpacity, float outlineOpacity, SpriteSheet* maskedSheet) { - const std::optional mask = - maskedSheet ? std::optional(*maskedSheet) : std::nullopt; - const size_t vertexCount = text.size() * 4; const size_t indexCount = text.size() * 6; std::vector vertices(vertexCount); @@ -318,7 +313,7 @@ void BaseRenderer::DrawProcessedText_LBFont( dest, destUV, color, maskUV); } - DrawVertices(font->OutlineSheet, mask, vertices, indices); + DrawVertices(font->OutlineSheet, maskedSheet, vertices, indices); } for (size_t i = 0; i < text.size(); i++) { @@ -345,7 +340,7 @@ void BaseRenderer::DrawProcessedText_LBFont( dest, destUV, color, maskUV); } - DrawVertices(font->ForegroundSheet, mask, vertices, indices); + DrawVertices(font->ForegroundSheet, maskedSheet, vertices, indices); } void BaseRenderer::QuadSetPosition(CornersQuad quad, glm::vec2* const pos, diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 892746cd6..5b1bf3ce5 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -217,8 +217,7 @@ class BaseRenderer { {0.0f, 0.0f}, tint, isInverted, useMaskAlpha); } - virtual void DrawVertices(const SpriteSheet& sheet, - std::optional mask, + virtual void DrawVertices(const SpriteSheet& sheet, const SpriteSheet* mask, std::span vertices, std::span indices, glm::mat4 transformation = glm::mat4(1.0f), @@ -229,12 +228,10 @@ class BaseRenderer { std::span indices, glm::mat4 transformation = glm::mat4(1.0f), bool inverted = false) { - DrawVertices(sheet, std::nullopt, vertices, indices, transformation, - inverted); + DrawVertices(sheet, nullptr, vertices, indices, transformation, inverted); } - void DrawVertices(const SpriteSheet& sheet, - std::optional mask, + void DrawVertices(const SpriteSheet& sheet, const SpriteSheet* mask, std::span vertices, std::span indices, glm::vec2 offset, bool inverted = false) { @@ -281,13 +278,13 @@ class BaseRenderer { std::span text, Font* font, float opacity = 1.0f, RendererOutlineMode outlineMode = RendererOutlineMode::None, - bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = 0); + bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = nullptr); void DrawProcessedText( std::span text, Font* font, float opacity, float outlineOpacity, RendererOutlineMode outlineMode = RendererOutlineMode::None, - bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = 0); + bool smoothstepGlyphOpacity = true, SpriteSheet* maskedSheet = nullptr); virtual void DrawVideoTexture(const YUVFrame& frame, const RectF& dest, glm::vec4 tint, bool alphaVideo = false) = 0; diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index 361df570e..b25194341 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1354,7 +1354,7 @@ void Renderer::DrawMaskedSpriteOverlay( } void Renderer::DrawVertices(const SpriteSheet& sheet, - const std::optional mask, + const SpriteSheet* const mask, const std::span vertices, const std::span indices, const glm::mat4 transformation, diff --git a/src/renderer/vulkan/renderer.h b/src/renderer/vulkan/renderer.h index f3b708c51..7599e24ff 100644 --- a/src/renderer/vulkan/renderer.h +++ b/src/renderer/vulkan/renderer.h @@ -83,8 +83,7 @@ class Renderer : public BaseRenderer { std::span tints, bool isInverted, bool useMaskAlpha) override; - void DrawVertices(const SpriteSheet& sheet, - std::optional mask, + void DrawVertices(const SpriteSheet& sheet, const SpriteSheet* mask, std::span vertices, std::span indices, glm::mat4 transformation, bool inverted) override; From 9ae201651d6703ff6a494179db4e1ee2dcbe41fc Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 15 Jun 2025 16:45:17 +0200 Subject: [PATCH 85/88] Turn sampler2D[] back into sampler2D uniforms --- CMakeLists.txt | 1 - src/renderer/opengl/renderer.cpp | 260 +++++++----------- src/renderer/opengl/renderer.h | 36 ++- src/renderer/opengl/shader.cpp | 48 ++-- src/renderer/opengl/shader.h | 35 ++- src/renderer/opengl/textureunit.h | 91 ------ src/renderer/renderer.h | 2 - .../opengl/CCMessageBoxSprite_frag.glsl | 13 +- .../opengl/CCMessageBoxSprite_vert.glsl | 12 +- .../opengl/CHLCCMenuBackground_frag.glsl | 9 +- .../opengl/CHLCCMenuBackground_vert.glsl | 10 +- .../opengl/MaskedSpriteNoAlpha_frag.glsl | 9 +- .../opengl/MaskedSpriteNoAlpha_vert.glsl | 12 +- src/shaders/opengl/MaskedSprite_frag.glsl | 9 +- src/shaders/opengl/MaskedSprite_vert.glsl | 12 +- src/shaders/opengl/SpriteInverted_frag.glsl | 5 +- src/shaders/opengl/SpriteInverted_vert.glsl | 7 +- src/shaders/opengl/Sprite_frag.glsl | 5 +- src/shaders/opengl/Sprite_vert.glsl | 7 +- src/shaders/opengl/YUVFrame_vert.glsl | 4 +- 20 files changed, 210 insertions(+), 377 deletions(-) delete mode 100644 src/renderer/opengl/textureunit.h diff --git a/CMakeLists.txt b/CMakeLists.txt index cdfee508a..bdb96c5df 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -1031,7 +1031,6 @@ if (NOT DEFINED IMPACTO_DISABLE_OPENGL) src/renderer/opengl/shader.h src/renderer/opengl/glc.h src/renderer/opengl/yuvframe.h - src/renderer/opengl/textureunit.h src/renderer/opengl/3d/renderable3d.h src/renderer/opengl/3d/scene.h ) diff --git a/src/renderer/opengl/renderer.cpp b/src/renderer/opengl/renderer.cpp index 44d94ab22..495ab6d23 100644 --- a/src/renderer/opengl/renderer.cpp +++ b/src/renderer/opengl/renderer.cpp @@ -43,22 +43,13 @@ void Renderer::Init() { glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, IBO); glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, Position)); - glVertexAttribIPointer(1, 1, GL_UNSIGNED_INT, sizeof(VertexBufferSprites), - (void*)offsetof(VertexBufferSprites, ColorMap)); - glVertexAttribPointer(2, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, UV)); - glVertexAttribPointer(3, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribPointer(2, 4, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, Tint)); - glVertexAttribIPointer(4, 1, GL_UNSIGNED_INT, sizeof(VertexBufferSprites), - (void*)offsetof(VertexBufferSprites, Mask)); - glVertexAttribPointer(5, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), + glVertexAttribPointer(3, 2, GL_FLOAT, GL_FALSE, sizeof(VertexBufferSprites), (void*)offsetof(VertexBufferSprites, MaskUV)); - glEnableVertexAttribArray(0); - glEnableVertexAttribArray(1); - glEnableVertexAttribArray(2); - glEnableVertexAttribArray(3); - glEnableVertexAttribArray(4); - glEnableVertexAttribArray(5); + for (size_t i = 0; i < 4; i++) glEnableVertexAttribArray(i); // Make 1x1 white pixel for colored rectangles Texture rectTexture; @@ -78,9 +69,21 @@ void Renderer::Init() { CHLCCMenuBackgroundShaderProgram.emplace( Shaders.Compile("CHLCCMenuBackground")); - for (size_t i = 0; i < TextureUnitCount; i++) TextureUnits[i].emplace(i); + glGenSamplers(Samplers.size(), Samplers.data()); + for (size_t i = 0; i < TextureUnitCount; i++) { + glBindSampler(i, Samplers[i]); - glActiveTexture(GL_TEXTURE0 + TextureUnitCount); + glSamplerParameteri(Samplers[i], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(Samplers[i], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + + glSamplerParameteri(Samplers[i], GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glSamplerParameteri(Samplers[i], GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glSamplerParameteri(Samplers[i], GL_TEXTURE_MAX_ANISOTROPY, 16); + } + + glActiveTexture(GL_TEXTURE0); + glBindSampler(0, Samplers[0]); } void Renderer::Shutdown() { @@ -95,6 +98,8 @@ void Renderer::Shutdown() { glDeleteTextures(GLC::FramebufferTextures.size(), GLC::FramebufferTextures.data()); + glDeleteSamplers(Samplers.size(), Samplers.data()); + if (Profile::GameFeatures & GameFeature::Scene3D) { Scene->Shutdown(); } @@ -125,7 +130,7 @@ void Renderer::BeginFrame2D() { glDisable(GL_CULL_FACE); - glBindSampler(0, TextureUnits[0]->GetSampler()); + glBindSampler(0, Samplers[0]); } void Renderer::EndFrame() { @@ -234,43 +239,32 @@ void Renderer::InsertVertices( NextFreeIndex += maxIndex + 1; } -void Renderer::InsertVerticesQuad(const CornersQuad pos, - const GLuint textureLocation, - const CornersQuad uv, +void Renderer::InsertVerticesQuad(const CornersQuad pos, const CornersQuad uv, const std::span tints, - const GLuint maskLocation, const CornersQuad maskUV) { const std::array vertices = { VertexBufferSprites{ .Position = pos.BottomLeft, - .ColorMap = textureLocation, .UV = uv.BottomLeft, .Tint = tints[0], - .Mask = maskLocation, .MaskUV = maskUV.BottomLeft, }, VertexBufferSprites{ .Position = pos.TopLeft, - .ColorMap = textureLocation, .UV = uv.TopLeft, .Tint = tints[1], - .Mask = maskLocation, .MaskUV = maskUV.TopLeft, }, VertexBufferSprites{ .Position = pos.TopRight, - .ColorMap = textureLocation, .UV = uv.TopRight, .Tint = tints[2], - .Mask = maskLocation, .MaskUV = maskUV.TopRight, }, VertexBufferSprites{ .Position = pos.BottomRight, - .ColorMap = textureLocation, .UV = uv.BottomRight, .Tint = tints[3], - .Mask = maskLocation, .MaskUV = maskUV.BottomRight, }, }; @@ -280,89 +274,23 @@ void Renderer::InsertVerticesQuad(const CornersQuad pos, InsertVertices(vertices, indices); } -std::vector Renderer::GetTextureLocations( - const std::span textureIds) { - std::vector allocatedLocations(textureIds.size()); - - std::vector returnVector; - returnVector.reserve(allocatedLocations.size()); - - size_t newTexturesNeeded = 0; - std::vector notFound; - for (size_t i = 0; i < textureIds.size(); i++) { - const uint32_t textureId = textureIds[i]; - - const auto sameTexture = - [this, textureId](const std::optional& unit) { - return unit->GetTexture() == textureId; - }; - const auto foundIt = - std::find_if(TextureUnits.begin(), TextureUnits.end(), sameTexture); - - if (foundIt != TextureUnits.end()) { - allocatedLocations[i] = std::distance(TextureUnits.begin(), foundIt); - - // TODO: Remove once textures are managed - // Currently needed because the texture under this ID may be deleted and - // then recreated, meaning the texture would need to be rebound - (*foundIt)->SetTexture(textureId); - - (*foundIt)->Reserve(); - - } else { - notFound.push_back(i); - - // Check if the current new texture hasn't already been requested - const auto curTextureIt = textureIds.begin() + i; - newTexturesNeeded += std::find(textureIds.begin(), curTextureIt, - textureIds[i]) == curTextureIt; +void Renderer::UseTextures( + const std::span> textureUnitPairs) { + for (const auto [textureId, unitIndex] : textureUnitPairs) { + if (TextureUnits[unitIndex].TextureId != textureId && + TextureUnits[unitIndex].InUse) { + Flush(); } } - // If all textures were found, immediately return their locations - if (notFound.empty()) { - for (size_t unit : allocatedLocations) - returnVector.emplace_back(*TextureUnits[unit]); - - return returnVector; - } - - const size_t freeSlots = - std::count_if(TextureUnits.begin(), TextureUnits.end(), - [](const auto& unit) { return !unit->IsLocked(); }); + for (const auto [textureId, unitIndex] : textureUnitPairs) { + TextureUnit& textureUnit = TextureUnits[unitIndex]; - // If the needed textures don't fit in the buffer, flush to make room - if (newTexturesNeeded > freeSlots) Flush(); + glBindTextureUnit(unitIndex, textureId); - for (size_t i : notFound) { - const uint32_t textureId = textureIds[i]; - const auto sameTexture = - [this, textureId](const std::optional& unit) { - return unit->GetTexture() == textureId; - }; - const auto foundIt = - std::find_if(TextureUnits.begin(), TextureUnits.end(), sameTexture); - - if (foundIt != TextureUnits.end()) { - // Texture already added by prior entry in notFound - allocatedLocations[i] = std::distance(TextureUnits.begin(), foundIt); - - } else { - // Add the texture - const auto freeIt = - std::find_if(TextureUnits.begin(), TextureUnits.end(), - [](const auto& unit) { return !unit->IsLocked(); }); - - (*freeIt)->SetTexture(textureId); - (*freeIt)->Reserve(); - allocatedLocations[i] = std::distance(TextureUnits.begin(), freeIt); - } + textureUnit.TextureId = textureId; + textureUnit.InUse = true; } - - for (size_t unit : allocatedLocations) - returnVector.emplace_back(*TextureUnits[unit]); - - return returnVector; } void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, @@ -380,10 +308,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, if (textureWrapRepeat) { Flush(); - const GLuint sampler = TextureUnits[0]->GetSampler(); - glBindSampler(0, sampler); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_REPEAT); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_REPEAT); + glBindSampler(0, Samplers[0]); + glSamplerParameteri(Samplers[0], GL_TEXTURE_WRAP_S, GL_REPEAT); + glSamplerParameteri(Samplers[0], GL_TEXTURE_WRAP_T, GL_REPEAT); } if (disableBlend) { @@ -396,7 +323,7 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, SpriteInvertedUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .Textures = Textures, + .ColorMap = 0, }; UseShader(*SpriteInvertedShaderProgram, uniforms); @@ -405,23 +332,20 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, SpriteUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .Textures = Textures, + .ColorMap = 0, }; UseShader(*SpriteShaderProgram, uniforms); } - std::vector textureLocations = - GetTextureLocations(std::array{sprite.Sheet.Texture}); + UseTextures(std::array, 1>{ + std::pair{sprite.Sheet.Texture, 0}}); // OK, all good, make quad CornersQuad uvDest = sprite.NormalizedBounds(); if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); - InsertVerticesQuad(dest, textureLocations[0], uvDest, tints); - - // Free texture units for possible flush - textureLocations.clear(); + InsertVerticesQuad(dest, uvDest, tints); if (disableBlend) { Flush(); @@ -430,10 +354,9 @@ void Renderer::DrawSprite(const Sprite& sprite, const CornersQuad& dest, if (textureWrapRepeat) { Flush(); - const GLuint sampler = TextureUnits[0]->GetSampler(); - glBindSampler(0, sampler); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glBindSampler(0, Samplers[0]); + glSamplerParameteri(Samplers[0], GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glSamplerParameteri(Samplers[0], GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); } } @@ -458,7 +381,8 @@ void Renderer::DrawMaskedSprite( .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, .IsSameTexture = isSameTexture, @@ -466,8 +390,10 @@ void Renderer::DrawMaskedSprite( UseShader(*MaskedSpriteShaderProgram, uniforms); - const std::vector textureLocations = - GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); + UseTextures(std::array, 2>{ + std::pair{sprite.Sheet.Texture, 0}, + std::pair{mask.Sheet.Texture, 2}, + }); // OK, all good, make quad @@ -475,8 +401,7 @@ void Renderer::DrawMaskedSprite( if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); CornersQuad maskUVDest = CornersQuad(maskDest).Scale( {1.0f / sprite.Bounds.Width, 1.0f / sprite.Bounds.Height}, {0.0f, 0.0f}); - InsertVerticesQuad(spriteDest, textureLocations[0], uvDest, tints, - textureLocations[1], maskUVDest); + InsertVerticesQuad(spriteDest, uvDest, tints, maskUVDest); } void Renderer::DrawMaskedSpriteOverlay( @@ -500,7 +425,8 @@ void Renderer::DrawMaskedSpriteOverlay( .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, .IsSameTexture = false, @@ -513,7 +439,8 @@ void Renderer::DrawMaskedSpriteOverlay( .Projection = Projection, .SpriteTransformation = spriteTransformation, .MaskTransformation = maskTransformation, - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = {alphaRange, constAlpha}, .IsInverted = isInverted, }; @@ -521,16 +448,18 @@ void Renderer::DrawMaskedSpriteOverlay( UseShader(*MaskedSpriteNoAlphaShaderProgram, uniforms); } - const std::vector textureLocations = - GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); + UseTextures(std::array, 2>{ + std::pair{sprite.Sheet.Texture, 0}, + std::pair{mask.Sheet.Texture, 2}, + }); // OK, all good, make quad CornersQuad normalizedMaskDest = CornersQuad(maskDest).Scale( {1.0f / mask.Sheet.DesignWidth, 1.0f / mask.Sheet.DesignHeight}, {0.0f, 0.0f}); - InsertVerticesQuad(spriteDest, textureLocations[0], sprite.NormalizedBounds(), - tints, textureLocations[1], normalizedMaskDest); + InsertVerticesQuad(spriteDest, sprite.NormalizedBounds(), tints, + normalizedMaskDest); } void Renderer::DrawVertices(const SpriteSheet& sheet, @@ -550,7 +479,8 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, .Projection = Projection, .SpriteTransformation = transformation, .MaskTransformation = glm::mat4(1.0f), - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = {1.0f, 0.0f}, .IsInverted = inverted, }; @@ -562,7 +492,7 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, SpriteInvertedUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .Textures = Textures, + .ColorMap = 0, }; UseShader(*SpriteInvertedShaderProgram, uniforms); @@ -571,26 +501,29 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, SpriteUniforms uniforms{ .Projection = Projection, .Transformation = transformation, - .Textures = Textures, + .ColorMap = 0, }; UseShader(*SpriteShaderProgram, uniforms); } } - const std::vector textureLocations = - mask ? GetTextureLocations( - std::array{sheet.Texture, mask->Texture}) - : GetTextureLocations(std::array{sheet.Texture}); + if (mask == nullptr) { + UseTextures(std::array, 1>{ + std::pair{sheet.Texture, 0}, + }); + } else { + UseTextures(std::array, 2>{ + std::pair{sheet.Texture, 0}, + std::pair{mask->Texture, 2}, + }); + } std::vector transformedVertices; transformedVertices.resize(vertices.size()); - const auto transformVertex = [this, sheet, - &textureLocations](VertexBufferSprites info) { + const auto transformVertex = [this, sheet](VertexBufferSprites info) { if (sheet.IsScreenCap) info.UV.y = 1.0f - info.UV.y; - info.ColorMap = textureLocations[0]; - if (textureLocations.size() >= 2) info.Mask = textureLocations[1]; return info; }; std::transform(vertices.begin(), vertices.end(), transformedVertices.begin(), @@ -616,21 +549,23 @@ void Renderer::DrawCCMessageBox(Sprite const& sprite, Sprite const& mask, CCMessageBoxUniforms uniforms{ .Projection = Projection, - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = {alphaRange, constAlpha, effectCt, 0.0f}, }; UseShader(*CCMessageBoxShaderProgram, uniforms); - const std::vector textureLocations = - GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); + UseTextures(std::array, 2>{ + std::pair{sprite.Sheet.Texture, 0}, + std::pair{mask.Sheet.Texture, 2}, + }); // OK, all good, make quad CornersQuad uvDest = sprite.NormalizedBounds(); if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); - InsertVerticesQuad(dest, textureLocations[0], uvDest, tint, - textureLocations[1], mask.NormalizedBounds()); + InsertVerticesQuad(dest, uvDest, tint, mask.NormalizedBounds()); } void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, @@ -648,21 +583,23 @@ void Renderer::DrawCHLCCMenuBackground(const Sprite& sprite, const Sprite& mask, CHLCCMenuBackgroundUniforms uniforms{ .Projection = Projection, - .Textures = Textures, + .ColorMap = 0, + .Mask = 2, .Alpha = alpha, }; UseShader(*CHLCCMenuBackgroundShaderProgram, uniforms); - const std::vector textureLocations = - GetTextureLocations(std::array{sprite.Sheet.Texture, mask.Sheet.Texture}); + UseTextures(std::array, 2>{ + std::pair{sprite.Sheet.Texture, 0}, + std::pair{mask.Sheet.Texture, 2}, + }); // OK, all good, make quad CornersQuad uvDest = sprite.NormalizedBounds(); if (sprite.Sheet.IsScreenCap) uvDest.FlipVertical(); - InsertVerticesQuad(dest, textureLocations[0], uvDest, glm::vec4(1.0f), - textureLocations[1], mask.NormalizedBounds()); + InsertVerticesQuad(dest, uvDest, glm::vec4(1.0f), mask.NormalizedBounds()); } void Renderer::Flush() { @@ -688,7 +625,7 @@ void Renderer::Flush() { IndexBuffer.clear(); NextFreeIndex = 0; - for (std::optional& unit : TextureUnits) unit->Flush(); + FlushTextures(); } void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, @@ -699,14 +636,17 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, return; } - const std::vector textureLocations = - GetTextureLocations(std::array{frame.LumaId, frame.CbId, frame.CrId}); + UseTextures(std::array, 3>{ + std::pair{frame.LumaId, 0}, + std::pair{frame.CbId, 1}, + std::pair{frame.CrId, 2}, + }); YUVFrameUniforms uniforms{ .Projection = Projection, - .Luma = (GLint)textureLocations[0], - .Cb = (GLint)textureLocations[1], - .Cr = (GLint)textureLocations[2], + .Luma = 0, + .Cb = 1, + .Cr = 2, .IsAlpha = alphaVideo, }; @@ -714,7 +654,7 @@ void Renderer::DrawVideoTexture(const YUVFrame& frame, const RectF& dest, // OK, all good, make quad - InsertVerticesQuad(dest, 0, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); + InsertVerticesQuad(dest, RectF(0.0f, 0.0f, 1.0f, 1.0f), tint); } void Renderer::CaptureScreencap(Sprite& sprite) { diff --git a/src/renderer/opengl/renderer.h b/src/renderer/opengl/renderer.h index 925b92c5f..3738be291 100644 --- a/src/renderer/opengl/renderer.h +++ b/src/renderer/opengl/renderer.h @@ -7,7 +7,6 @@ #include "shader.h" #include "glc.h" -#include "textureunit.h" #include "../../profile/game.h" @@ -122,17 +121,13 @@ class Renderer : public BaseRenderer { void InsertVertices(std::span vertices, std::span indices); - void InsertVerticesQuad(CornersQuad pos, GLuint textureLocation, - CornersQuad uv, std::span tints, - GLuint maskLocation = 0, + void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, + std::span tints, CornersQuad maskUV = RectF()); - void InsertVerticesQuad(CornersQuad pos, GLuint textureLocation, - CornersQuad uv, glm::vec4 tint = glm::vec4(1.0f), - GLuint maskLocation = 0, + void InsertVerticesQuad(CornersQuad pos, CornersQuad uv, + glm::vec4 tint = glm::vec4(1.0f), CornersQuad maskUV = RectF()) { - InsertVerticesQuad(pos, textureLocation, uv, - std::array{tint, tint, tint, tint}, maskLocation, - maskUV); + InsertVerticesQuad(pos, uv, std::array{tint, tint, tint, tint}, maskUV); } GLWindow* OpenGLWindow; @@ -143,13 +138,24 @@ class Renderer : public BaseRenderer { bool Drawing = false; + struct TextureUnit { + uint32_t TextureId = 0; + bool InUse = false; + }; static constexpr size_t TextureUnitCount = 15; - static constexpr std::array Textures = { - 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}; - std::array, TextureUnitCount> TextureUnits; + std::array TextureUnits; + + void UseTextures( + std::span> textureUnitPairs); + void FlushTextures() { + std::transform(TextureUnits.begin(), TextureUnits.end(), + TextureUnits.begin(), [](TextureUnit unit) { + unit.InUse = false; + return unit; + }); + } - std::vector GetTextureLocations( - std::span textureIds); + std::array Samplers; static constexpr size_t MaxVertexCount = 1024 * 1024 / sizeof(VertexBufferSprites); diff --git a/src/renderer/opengl/shader.cpp b/src/renderer/opengl/shader.cpp index fa12d6115..bce28fe56 100644 --- a/src/renderer/opengl/shader.cpp +++ b/src/renderer/opengl/shader.cpp @@ -242,34 +242,34 @@ SpriteShader::SpriteShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), TransformationLocation(glGetUniformLocation(programId, "Transformation")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.Transformation, TransformationLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); } void SpriteShader::UploadUniforms(SpriteUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); UpdateVar(newUniforms.Transformation, Uniforms.Transformation, TransformationLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); } SpriteInvertedShader::SpriteInvertedShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), TransformationLocation(glGetUniformLocation(programId, "Transformation")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.Transformation, TransformationLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); } void SpriteInvertedShader::UploadUniforms(SpriteInvertedUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); UpdateVar(newUniforms.Transformation, Uniforms.Transformation, TransformationLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); } YUVFrameShader::YUVFrameShader(GLint programId) @@ -304,11 +304,13 @@ MaskedSpriteNoAlphaShader::MaskedSpriteNoAlphaShader(GLint programId) glGetUniformLocation(programId, "MaskTransformation")), AlphaLocation(glGetUniformLocation(programId, "Alpha")), IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); UploadVar(Uniforms.Alpha, AlphaLocation); UploadVar(Uniforms.IsInverted, IsInvertedLocation); } @@ -321,7 +323,8 @@ void MaskedSpriteNoAlphaShader::UploadUniforms( UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, MaskTransformationLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); } @@ -336,11 +339,13 @@ MaskedSpriteShader::MaskedSpriteShader(GLint programId) AlphaLocation(glGetUniformLocation(programId, "Alpha")), IsInvertedLocation(glGetUniformLocation(programId, "IsInverted")), IsSameTextureLocation(glGetUniformLocation(programId, "IsSameTexture")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")) { UploadVar(Uniforms.Projection, ProjectionLocation); UploadVar(Uniforms.SpriteTransformation, SpriteTransformationLocation); UploadVar(Uniforms.MaskTransformation, MaskTransformationLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); UploadVar(Uniforms.Alpha, AlphaLocation); UploadVar(Uniforms.IsInverted, IsInvertedLocation); UploadVar(Uniforms.IsSameTexture, IsSameTextureLocation); @@ -353,7 +358,8 @@ void MaskedSpriteShader::UploadUniforms(MaskedSpriteUniforms newUniforms) { UpdateVar(newUniforms.MaskTransformation, Uniforms.MaskTransformation, MaskTransformationLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); UpdateVar(newUniforms.IsInverted, Uniforms.IsInverted, IsInvertedLocation); UpdateVar(newUniforms.IsSameTexture, Uniforms.IsSameTexture, @@ -364,16 +370,19 @@ CCMessageBoxShader::CCMessageBoxShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), AlphaLocation(glGetUniformLocation(programId, "Alpha")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")) { UploadVar(Uniforms.Projection, ProjectionLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); UploadVar(Uniforms.Alpha, AlphaLocation); } void CCMessageBoxShader::UploadUniforms(CCMessageBoxUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); } @@ -381,9 +390,11 @@ CHLCCMenuBackgroundShader::CHLCCMenuBackgroundShader(GLint programId) : Shader(programId), ProjectionLocation(glGetUniformLocation(programId, "Projection")), AlphaLocation(glGetUniformLocation(programId, "Alpha")), - TexturesLocation(glGetUniformLocation(programId, "Textures")) { + ColorMapLocation(glGetUniformLocation(programId, "ColorMap")), + MaskLocation(glGetUniformLocation(programId, "Mask")) { UploadVar(Uniforms.Projection, ProjectionLocation); - UploadVar(Uniforms.Textures, TexturesLocation); + UploadVar(Uniforms.ColorMap, ColorMapLocation); + UploadVar(Uniforms.Mask, MaskLocation); UploadVar(Uniforms.Alpha, AlphaLocation); } @@ -391,7 +402,8 @@ void CHLCCMenuBackgroundShader::UploadUniforms( CHLCCMenuBackgroundUniforms newUniforms) { UpdateVar(newUniforms.Projection, Uniforms.Projection, ProjectionLocation); - UpdateVar(newUniforms.Textures, Uniforms.Textures, TexturesLocation); + UpdateVar(newUniforms.ColorMap, Uniforms.ColorMap, ColorMapLocation); + UpdateVar(newUniforms.Mask, Uniforms.Mask, MaskLocation); UpdateVar(newUniforms.Alpha, Uniforms.Alpha, AlphaLocation); } diff --git a/src/renderer/opengl/shader.h b/src/renderer/opengl/shader.h index 923757756..8fffb16b3 100644 --- a/src/renderer/opengl/shader.h +++ b/src/renderer/opengl/shader.h @@ -106,9 +106,6 @@ class Shader { void UploadVar(glm::mat4 value, GLint location) { glUniformMatrix4fv(location, 1, GL_FALSE, &value[0][0]); } - void UploadVar(std::span value, GLint location) { - glUniform1iv(location, value.size(), value.data()); - } template void UpdateVar(T newValue, T& oldValue, GLint location) { @@ -125,7 +122,7 @@ struct SpriteUniforms { glm::mat4 Projection{}; glm::mat4 Transformation{}; - std::array Textures; + GLint ColorMap = 0; }; class SpriteShader : public Shader { @@ -138,7 +135,7 @@ class SpriteShader : public Shader { const GLint ProjectionLocation; const GLint TransformationLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; }; struct SpriteInvertedUniforms { @@ -147,7 +144,7 @@ struct SpriteInvertedUniforms { glm::mat4 Projection{}; glm::mat4 Transformation{}; - std::array Textures; + GLint ColorMap = 0; }; class SpriteInvertedShader : public Shader { @@ -160,7 +157,7 @@ class SpriteInvertedShader : public Shader { const GLint ProjectionLocation; const GLint TransformationLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; }; struct YUVFrameUniforms { @@ -196,7 +193,8 @@ struct MaskedSpriteNoAlphaUniforms { glm::mat4 SpriteTransformation{}; glm::mat4 MaskTransformation{}; - std::array Textures; + GLint ColorMap = 0; + GLint Mask = 0; glm::vec2 Alpha{}; bool IsInverted = false; }; @@ -212,7 +210,8 @@ class MaskedSpriteNoAlphaShader : public Shader { const GLint SpriteTransformationLocation; const GLint MaskTransformationLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; + const GLint MaskLocation; const GLint AlphaLocation; const GLint IsInvertedLocation; }; @@ -224,7 +223,8 @@ struct MaskedSpriteUniforms { glm::mat4 SpriteTransformation{}; glm::mat4 MaskTransformation{}; - std::array Textures; + GLint ColorMap; + GLint Mask; glm::vec2 Alpha{}; bool IsInverted = false; bool IsSameTexture = false; @@ -241,7 +241,8 @@ class MaskedSpriteShader : public Shader { const GLint SpriteTransformationLocation; const GLint MaskTransformationLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; + const GLint MaskLocation; const GLint AlphaLocation; const GLint IsInvertedLocation; const GLint IsSameTextureLocation; @@ -252,7 +253,8 @@ struct CCMessageBoxUniforms { glm::mat4 Projection{}; - std::array Textures; + GLint ColorMap; + GLint Mask; glm::vec4 Alpha{}; }; @@ -265,7 +267,8 @@ class CCMessageBoxShader : public Shader { private: const GLint ProjectionLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; + const GLint MaskLocation; const GLint AlphaLocation; }; @@ -274,7 +277,8 @@ struct CHLCCMenuBackgroundUniforms { glm::mat4 Projection{}; - std::array Textures; + GLint ColorMap; + GLint Mask; float Alpha = 0.0f; }; @@ -287,7 +291,8 @@ class CHLCCMenuBackgroundShader : public Shader { private: const GLint ProjectionLocation; - const GLint TexturesLocation; + const GLint ColorMapLocation; + const GLint MaskLocation; const GLint AlphaLocation; }; diff --git a/src/renderer/opengl/textureunit.h b/src/renderer/opengl/textureunit.h deleted file mode 100644 index f690fdcf5..000000000 --- a/src/renderer/opengl/textureunit.h +++ /dev/null @@ -1,91 +0,0 @@ -#pragma once - -#include -#include - -namespace Impacto { -namespace OpenGL { - -struct TextureUnitInfo { - uint32_t TextureId = 0; - bool Flushed = true; -}; - -class TextureUnit { - public: - TextureUnit(GLuint unit) : Unit(unit) { - glGenSamplers(1, &Sampler); - glBindSampler(unit, Sampler); - - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); - glSamplerParameteri(Sampler, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); - - glSamplerParameteri(Sampler, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - glSamplerParameteri(Sampler, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - glSamplerParameteri(Sampler, GL_TEXTURE_MAX_ANISOTROPY, 16); - } - - ~TextureUnit() { - if (Info.use_count() == 1) glDeleteSamplers(1, &Sampler); - } - - TextureUnit(const TextureUnit& other) - : Unit(other.Unit), Sampler(other.Sampler), Info(other.Info) { - Info->Flushed = false; - } - - TextureUnit(TextureUnit&& other) - : Unit(std::move(other.Unit)), - Sampler(std::move(other.Sampler)), - Info(std::move(other.Info)) {} - - TextureUnit& operator=(const TextureUnit& other) { - if (Info.use_count() == 1 && &other != this) glDeleteSamplers(1, &Sampler); - - Unit = other.Unit; - Sampler = other.Sampler; - Info = other.Info; - - return *this; - } - - TextureUnit& operator=(TextureUnit&& other) { - if (Info.use_count() == 1 && &other != this) glDeleteSamplers(1, &Sampler); - - Unit = std::move(other.Unit); - Sampler = std::move(other.Sampler); - Info = std::move(other.Info); - - return *this; - } - - GLuint GetUnit() const { return Unit; } - operator GLuint() const { return GetUnit(); } - - bool IsLocked() const { return Info.use_count() > 1 || !Info->Flushed; } - - uint32_t GetTexture() const { return Info->TextureId; } - bool SetTexture(uint32_t textureId) { - if (IsLocked()) return false; - - Info->TextureId = textureId; - glBindTextureUnit(Unit, textureId); - - return true; - } - - GLuint GetSampler() const { return Sampler; } - - void Flush() { - if (Info.use_count() == 1) Info->Flushed = true; - } - void Reserve() { Info->Flushed = false; } - - private: - GLuint Unit; - GLuint Sampler; - std::shared_ptr Info = std::make_shared(); -}; - -} // namespace OpenGL -} // namespace Impacto diff --git a/src/renderer/renderer.h b/src/renderer/renderer.h index 5b1bf3ce5..5ff790643 100644 --- a/src/renderer/renderer.h +++ b/src/renderer/renderer.h @@ -19,10 +19,8 @@ constexpr inline int MaxFramebuffers = 10; struct VertexBufferSprites { glm::vec2 Position = {0.0f, 0.0f}; - GLuint ColorMap = 0; glm::vec2 UV = {0.0f, 0.0f}; glm::vec4 Tint = glm::vec4(1.0f); - GLuint Mask = 0; glm::vec2 MaskUV = {0.0f, 0.0f}; }; diff --git a/src/shaders/opengl/CCMessageBoxSprite_frag.glsl b/src/shaders/opengl/CCMessageBoxSprite_frag.glsl index 0539d1963..516f5fbdb 100644 --- a/src/shaders/opengl/CCMessageBoxSprite_frag.glsl +++ b/src/shaders/opengl/CCMessageBoxSprite_frag.glsl @@ -1,24 +1,23 @@ -flat in uint colorMap; in vec2 uv; in vec4 tint; -flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; +uniform sampler2D Mask; uniform vec4 Alpha; void main() { - color = texture(Textures[colorMap], uv); + color = texture(ColorMap, uv); color *= tint; - vec4 alp = texture(Textures[mask], maskUV); + vec4 alp = texture(Mask, maskUV); float ga = alp.r; float ea = 1.0 - alp.g; float fa = 1.0 - alp.b; fa *= Alpha.r; fa -= Alpha.g; - fa = clamp(fa,0.0,1.0); + fa = clamp(fa, 0.0, 1.0); color.a *= fa; ea += Alpha.b; @@ -29,5 +28,5 @@ void main() { ga *= ea; ga = clamp(ga, 0.0, 1.0); color.a -= ga; - color.a = clamp(color.a,0.0,1.0); + color.a = clamp(color.a, 0.0, 1.0); } \ No newline at end of file diff --git a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl index c7ae21d3d..30f694da7 100644 --- a/src/shaders/opengl/CCMessageBoxSprite_vert.glsl +++ b/src/shaders/opengl/CCMessageBoxSprite_vert.glsl @@ -1,14 +1,10 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in uint ColorMap; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; -layout(location = 4) in uint Mask; -layout(location = 5) in vec2 MaskUV; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; +layout(location = 3) in vec2 MaskUV; -flat out uint colorMap; out vec2 uv; out vec4 tint; -flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -16,9 +12,7 @@ uniform mat4 Projection; void main() { gl_Position = Projection * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; tint = Tint; - mask = Mask; maskUV = MaskUV; } \ No newline at end of file diff --git a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl index 8d55e0f0c..a66108d1d 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_frag.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_frag.glsl @@ -1,13 +1,12 @@ uniform float Alpha; -flat in uint colorMap; in vec2 uv; -flat in uint mask; in vec2 maskUV; out vec4 outColor; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; +uniform sampler2D Mask; float remapMiddle(float value, float newMiddle) { if (value < 0.5) { @@ -18,8 +17,8 @@ float remapMiddle(float value, float newMiddle) { } void main() { - vec4 color = texture(Textures[colorMap], uv); - vec4 maskColor = texture(Textures[mask], maskUV); + vec4 color = texture(ColorMap, uv); + vec4 maskColor = texture(Mask, maskUV); outColor = vec4( remapMiddle(color.r, maskColor.r), remapMiddle(color.g, maskColor.g), diff --git a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl index df374c03e..7ab5baa3a 100644 --- a/src/shaders/opengl/CHLCCMenuBackground_vert.glsl +++ b/src/shaders/opengl/CHLCCMenuBackground_vert.glsl @@ -1,12 +1,8 @@ layout (location = 0) in vec2 Position; -layout (location = 1) in uint ColorMap; -layout (location = 2) in vec2 UV; -layout (location = 4) in uint Mask; -layout (location = 5) in vec2 MaskUV; +layout (location = 1) in vec2 UV; +layout (location = 3) in vec2 MaskUV; -flat out uint colorMap; out vec2 uv; -flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -14,8 +10,6 @@ uniform mat4 Projection; void main() { gl_Position = Projection * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; - mask = Mask; maskUV = MaskUV; } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl b/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl index 4e6a624cc..51944bbe3 100644 --- a/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl +++ b/src/shaders/opengl/MaskedSpriteNoAlpha_frag.glsl @@ -1,12 +1,11 @@ -flat in uint colorMap; in vec2 uv; in vec4 tint; -flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; +uniform sampler2D Mask; uniform vec2 Alpha; uniform bool IsInverted; @@ -18,8 +17,8 @@ float rgbToLightness(vec3 rgb) { } void main() { - color = texture(Textures[colorMap], uv); - vec4 alp = texture(Textures[mask], maskUV); + color = texture(ColorMap, uv); + vec4 alp = texture(Mask, maskUV); float maskAlpha = rgbToLightness(alp.rgb); if (IsInverted) maskAlpha = 1.0f - maskAlpha; diff --git a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl index 645921dce..f474ceefa 100644 --- a/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl +++ b/src/shaders/opengl/MaskedSpriteNoAlpha_vert.glsl @@ -1,14 +1,10 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in uint ColorMap; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; -layout(location = 4) in uint Mask; -layout(location = 5) in vec2 MaskUV; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; +layout(location = 3) in vec2 MaskUV; -flat out uint colorMap; out vec2 uv; out vec4 tint; -flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -18,9 +14,7 @@ uniform mat4 MaskTransformation; void main() { gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; tint = Tint; - mask = Mask; maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/MaskedSprite_frag.glsl b/src/shaders/opengl/MaskedSprite_frag.glsl index 5b4b59c4d..d90f0d943 100644 --- a/src/shaders/opengl/MaskedSprite_frag.glsl +++ b/src/shaders/opengl/MaskedSprite_frag.glsl @@ -1,19 +1,18 @@ -flat in uint colorMap; in vec2 uv; in vec4 tint; -flat in uint mask; in vec2 maskUV; out vec4 color; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; +uniform sampler2D Mask; uniform vec2 Alpha; uniform bool IsInverted; uniform bool IsSameTexture; void main() { - color = texture(Textures[colorMap], uv); - vec4 alp = texture(Textures[mask], maskUV); + color = texture(ColorMap, uv); + vec4 alp = texture(Mask, maskUV); if (IsInverted) alp.a = 1.0f - alp.a; alp.a *= Alpha.x; alp.a -= Alpha.y; diff --git a/src/shaders/opengl/MaskedSprite_vert.glsl b/src/shaders/opengl/MaskedSprite_vert.glsl index 645921dce..f474ceefa 100644 --- a/src/shaders/opengl/MaskedSprite_vert.glsl +++ b/src/shaders/opengl/MaskedSprite_vert.glsl @@ -1,14 +1,10 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in uint ColorMap; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; -layout(location = 4) in uint Mask; -layout(location = 5) in vec2 MaskUV; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; +layout(location = 3) in vec2 MaskUV; -flat out uint colorMap; out vec2 uv; out vec4 tint; -flat out uint mask; out vec2 maskUV; uniform mat4 Projection; @@ -18,9 +14,7 @@ uniform mat4 MaskTransformation; void main() { gl_Position = Projection * SpriteTransformation * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; tint = Tint; - mask = Mask; maskUV = vec2(MaskTransformation * vec4(MaskUV, 0.0, 1.0)); } \ No newline at end of file diff --git a/src/shaders/opengl/SpriteInverted_frag.glsl b/src/shaders/opengl/SpriteInverted_frag.glsl index 9922a61b0..fe7d6744f 100644 --- a/src/shaders/opengl/SpriteInverted_frag.glsl +++ b/src/shaders/opengl/SpriteInverted_frag.glsl @@ -1,13 +1,12 @@ -flat in uint colorMap; in vec2 uv; in vec4 tint; out vec4 color; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; void main() { - color = texture(Textures[colorMap], uv); + color = texture(ColorMap, uv); color.rgb = vec3(1.0) - color.rgb; color *= tint; } \ No newline at end of file diff --git a/src/shaders/opengl/SpriteInverted_vert.glsl b/src/shaders/opengl/SpriteInverted_vert.glsl index 1f8dfe764..4908c6f70 100644 --- a/src/shaders/opengl/SpriteInverted_vert.glsl +++ b/src/shaders/opengl/SpriteInverted_vert.glsl @@ -1,9 +1,7 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in uint ColorMap; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; -flat out uint colorMap; out vec2 uv; out vec4 tint; @@ -13,7 +11,6 @@ uniform mat4 Transformation; void main() { gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_frag.glsl b/src/shaders/opengl/Sprite_frag.glsl index 0b809f219..37416a70f 100644 --- a/src/shaders/opengl/Sprite_frag.glsl +++ b/src/shaders/opengl/Sprite_frag.glsl @@ -1,9 +1,8 @@ -flat in uint colorMap; in vec2 uv; in vec4 tint; out vec4 color; -uniform sampler2D[15] Textures; +uniform sampler2D ColorMap; -void main() { color = tint * texture(Textures[colorMap], uv); } \ No newline at end of file +void main() { color = tint * texture(ColorMap, uv); } \ No newline at end of file diff --git a/src/shaders/opengl/Sprite_vert.glsl b/src/shaders/opengl/Sprite_vert.glsl index 1f8dfe764..4908c6f70 100644 --- a/src/shaders/opengl/Sprite_vert.glsl +++ b/src/shaders/opengl/Sprite_vert.glsl @@ -1,9 +1,7 @@ layout(location = 0) in vec2 Position; -layout(location = 1) in uint ColorMap; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; -flat out uint colorMap; out vec2 uv; out vec4 tint; @@ -13,7 +11,6 @@ uniform mat4 Transformation; void main() { gl_Position = Projection * Transformation * vec4(Position, 0.0, 1.0); - colorMap = ColorMap; uv = UV; tint = Tint; } \ No newline at end of file diff --git a/src/shaders/opengl/YUVFrame_vert.glsl b/src/shaders/opengl/YUVFrame_vert.glsl index d5f5a8173..cdef1458d 100644 --- a/src/shaders/opengl/YUVFrame_vert.glsl +++ b/src/shaders/opengl/YUVFrame_vert.glsl @@ -1,6 +1,6 @@ layout(location = 0) in vec2 Position; -layout(location = 2) in vec2 UV; -layout(location = 3) in vec4 Tint; +layout(location = 1) in vec2 UV; +layout(location = 2) in vec4 Tint; out vec2 uv; out vec4 tint; From 6db5d1142bbf42f2ce58a4d6dcee785819f1d374 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Thu, 19 Jun 2025 22:56:09 +0200 Subject: [PATCH 86/88] Fix scrollbar not rendering track when it doesn't have one --- src/ui/widgets/scrollbar.cpp | 29 ++++++++++++++--------------- src/ui/widgets/scrollbar.h | 6 ++---- 2 files changed, 16 insertions(+), 19 deletions(-) diff --git a/src/ui/widgets/scrollbar.cpp b/src/ui/widgets/scrollbar.cpp index 05f5a1019..965624183 100644 --- a/src/ui/widgets/scrollbar.cpp +++ b/src/ui/widgets/scrollbar.cpp @@ -22,8 +22,7 @@ Scrollbar::Scrollbar(int id, glm::vec2 pos, float start, float end, Step((end - start) * 0.01f), Length(dir == SBDIR_VERTICAL ? trackBounds.y : trackBounds.x), ThumbBounds(0.0f, 0.0f, 0.0f, 0.0f), - ThumbLength(0.0f), - HasTrack(false) { + ThumbLength(0.0f) { UpdatePosition(); } @@ -64,11 +63,10 @@ Scrollbar::Scrollbar(int id, glm::vec2 pos, float start, float end, TrackBounds(pos.x, pos.y, track.ScaledWidth(), track.ScaledHeight()), ScrollWheelBounds(wheelBounds == RectF() ? TrackBounds : wheelBounds), WheelSpeedMultiplier(wheelSpeedMultiplier), - Step((EndValue - StartValue) * 0.01f), - HasTrack(true) { + Step((EndValue - StartValue) * 0.01f) { Enabled = true; - Length = Direction == SBDIR_VERTICAL ? TrackSprite.Bounds.Height - : TrackSprite.Bounds.Width; + Length = Direction == SBDIR_VERTICAL ? TrackSprite->Bounds.Height + : TrackSprite->Bounds.Width; ThumbBounds = RectF(0.0f, 0.0f, ThumbSprite.ScaledWidth(), ThumbSprite.ScaledHeight()); if (Direction == SBDIR_VERTICAL) { @@ -91,7 +89,6 @@ Scrollbar::Scrollbar(int id, glm::vec2 pos, float start, float end, : Scrollbar(id, pos, start, end, value, dir, track, thumb, thumbOffset, thumbLength, wheelBounds, wheelSpeedMultiplier) { FillSprite = fill; - HasFill = true; UpdatePosition(); } @@ -156,15 +153,15 @@ void Scrollbar::UpdateInput() { } void Scrollbar::Render() { - if (HasFill && FillBeforeTrack) { - Renderer->DrawSprite(FillSprite, glm::vec2(TrackBounds.X, TrackBounds.Y), + if (FillSprite.has_value() && FillBeforeTrack) { + Renderer->DrawSprite(*FillSprite, glm::vec2(TrackBounds.X, TrackBounds.Y), Tint); } - if (HasTrack) { - Renderer->DrawSprite(TrackSprite, TrackBounds, Tint); + if (TrackSprite.has_value()) { + Renderer->DrawSprite(*TrackSprite, TrackBounds, Tint); } - if (HasFill && !FillBeforeTrack) { - Renderer->DrawSprite(FillSprite, glm::vec2(TrackBounds.X, TrackBounds.Y), + if (FillSprite.has_value() && !FillBeforeTrack) { + Renderer->DrawSprite(*FillSprite, glm::vec2(TrackBounds.X, TrackBounds.Y), Tint); } Renderer->DrawSprite(ThumbSprite, glm::vec2(ThumbBounds.X, ThumbBounds.Y), @@ -209,14 +206,16 @@ void Scrollbar::UpdatePosition() { ThumbBounds.Y = (TrackBounds.Y + ThumbLength / 2.0f + thumbNormalizedProgress) - (ThumbSprite.ScaledHeight() / 2.0f); - FillSprite.Bounds.Height = TrackProgress; + + if (FillSprite) FillSprite->Bounds.Height = TrackProgress; } else if (Direction == SBDIR_HORIZONTAL) { ThumbBounds.X = (TrackBounds.X + ThumbLength / 2.0f + thumbNormalizedProgress) - (ThumbSprite.ScaledWidth() / 2.0f); ThumbBounds.Y = (TrackBounds.Y + (TrackBounds.Height / 2.0f)) - (ThumbSprite.ScaledHeight() / 2.0f); - FillSprite.Bounds.Width = TrackProgress; + + if (FillSprite) FillSprite->Bounds.Width = TrackProgress; } ThumbBounds.X += ThumbSpriteOffset.x; diff --git a/src/ui/widgets/scrollbar.h b/src/ui/widgets/scrollbar.h index 3ef457320..54dc95719 100644 --- a/src/ui/widgets/scrollbar.h +++ b/src/ui/widgets/scrollbar.h @@ -41,9 +41,9 @@ class Scrollbar : public Widget { int Id; ScrollbarDirection Direction; - Sprite TrackSprite; Sprite ThumbSprite; - Sprite FillSprite; + std::optional TrackSprite; + std::optional FillSprite; float Length; float StartValue; float EndValue; @@ -62,8 +62,6 @@ class Scrollbar : public Widget { RectF ScrollWheelBounds; float ThumbLength; bool ScrollHeld = false; - bool HasFill = false; - bool HasTrack = true; int LastScrollPos = 0; float WheelSpeedMultiplier = 1.0f; void UpdatePosition(); From a43da760045dab4c9e915594f3ac86144344e621 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Sun, 22 Jun 2025 23:56:23 +0200 Subject: [PATCH 87/88] Added masked DrawVertices support for Vulkan --- src/renderer/vulkan/renderer.cpp | 53 +++++++++++++++++++++++++++++--- 1 file changed, 48 insertions(+), 5 deletions(-) diff --git a/src/renderer/vulkan/renderer.cpp b/src/renderer/vulkan/renderer.cpp index b25194341..7dd730b02 100644 --- a/src/renderer/vulkan/renderer.cpp +++ b/src/renderer/vulkan/renderer.cpp @@ -1370,12 +1370,55 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, // The index buffer needs to be flushed Flush(); - if (inverted) - EnsureMode(PipelineSpriteInverted); - else - EnsureMode(PipelineSprite); + if (mask != nullptr) { + VkSamplerCreateInfo samplerInfo = {}; + samplerInfo.sType = VK_STRUCTURE_TYPE_SAMPLER_CREATE_INFO; + samplerInfo.pNext = nullptr; + samplerInfo.magFilter = VK_FILTER_LINEAR; + samplerInfo.minFilter = VK_FILTER_LINEAR; + samplerInfo.addressModeU = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeV = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.addressModeW = VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + samplerInfo.anisotropyEnable = VK_TRUE; + samplerInfo.maxAnisotropy = 16; + + VkDescriptorImageInfo imageBufferInfo[2]; + imageBufferInfo[0].sampler = Sampler; + imageBufferInfo[0].imageView = Textures[sheet.Texture].ImageView; + imageBufferInfo[0].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + vkCreateSampler(Device, &samplerInfo, nullptr, &imageBufferInfo[1].sampler); + imageBufferInfo[1].imageView = Textures[mask->Texture].ImageView; + imageBufferInfo[1].imageLayout = VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL; + + VkWriteDescriptorSet writeDescriptorSet{}; + writeDescriptorSet.sType = VK_STRUCTURE_TYPE_WRITE_DESCRIPTOR_SET; + writeDescriptorSet.dstSet = 0; + writeDescriptorSet.dstBinding = 0; + writeDescriptorSet.descriptorCount = 2; + writeDescriptorSet.descriptorType = + VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER; + writeDescriptorSet.pImageInfo = imageBufferInfo; - EnsureTextureBound(sheet.Texture); + EnsureMode(PipelineMaskedSpriteNoAlpha); + vkCmdPushDescriptorSetKHR( + CommandBuffers[CurrentFrameIndex], VK_PIPELINE_BIND_POINT_GRAPHICS, + CurrentPipeline->PipelineLayout, 0, 1, &writeDescriptorSet); + MaskedNoAlphaPushConstants constants = {}; + constants.Alpha = glm::vec2(1.0f, 0.0f); + constants.IsInverted = inverted; + vkCmdPushConstants(CommandBuffers[CurrentFrameIndex], + CurrentPipeline->PipelineLayout, + VK_SHADER_STAGE_FRAGMENT_BIT, 0, + sizeof(MaskedNoAlphaPushConstants), &constants); + } else { + if (inverted) + EnsureMode(PipelineSpriteInverted); + else + EnsureMode(PipelineSprite); + + EnsureTextureBound(sheet.Texture); + } // Push vertices VertexBufferSprites* vertexBuffer = From 27e9e6272ff9e5652f2bd52af56e8fda325edc12 Mon Sep 17 00:00:00 2001 From: PringlesGang Date: Mon, 23 Jun 2025 00:01:15 +0200 Subject: [PATCH 88/88] Added masked DrawVertices support for DirectX9 --- src/renderer/dx9/renderer.cpp | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-) diff --git a/src/renderer/dx9/renderer.cpp b/src/renderer/dx9/renderer.cpp index c790cf711..813a00b51 100644 --- a/src/renderer/dx9/renderer.cpp +++ b/src/renderer/dx9/renderer.cpp @@ -437,12 +437,28 @@ void Renderer::DrawVertices(const SpriteSheet& sheet, // The index buffer needs to be flushed Flush(); - if (inverted) - EnsureShader(ShaderSpriteInverted); - else - EnsureShader(ShaderSprite); + if (mask != nullptr) { + std::array alphaRes = {1.0f, 0.0f, 0.0f, 0.0f}; + BOOL isInvertedB = (BOOL)inverted; + + EnsureShader(ShaderMaskedSpriteNoAlpha); - EnsureTextureBound(sheet.Texture); + Device->SetTexture(0, Textures[sheet.Texture]); + Device->SetTexture(1, Textures[mask->Texture]); + + Device->SetSamplerState(1, D3DSAMP_ADDRESSU, D3DTADDRESS_CLAMP); + Device->SetSamplerState(1, D3DSAMP_ADDRESSV, D3DTADDRESS_CLAMP); + Device->SetPixelShaderConstantF(0, alphaRes.data(), 1); + Device->SetPixelShaderConstantB(0, &isInvertedB, 1); + + } else { + if (inverted) + EnsureShader(ShaderSpriteInverted); + else + EnsureShader(ShaderSprite); + + EnsureTextureBound(sheet.Texture); + } // Push vertices VertexBufferSprites* vertexBuffer =