diff --git a/olcPixelGameEngine.h b/olcPixelGameEngine.h index 4e9e599..948941f 100644 --- a/olcPixelGameEngine.h +++ b/olcPixelGameEngine.h @@ -2,7 +2,7 @@ olcPixelGameEngine.h +-------------------------------------------------------------+ - | OneLoneCoder Pixel Game Engine v2.04 | + | OneLoneCoder Pixel Game Engine v2.05 | | "What do you need? Pixels... Lots of Pixels..." - javidx9 | +-------------------------------------------------------------+ @@ -111,7 +111,7 @@ JackOJC, KrossX, Huhlig, Dragoneye, Appa, JustinRichardsMusic, SliceNDice Ralakus, Gorbit99, raoul, joshinils, benedani, Moros1138, SaladinAkara & MagetzUb for advice, ideas and testing, and I'd like to extend my appreciation to the - 135K YouTube followers, 60+ Patreons and 6K Discord server members who give me + 144K YouTube followers, 70+ Patreons and 6K Discord server members who give me the motivation to keep going with all this :D Significant Contributors: @MaGetzUb, @slavka, @Dragoneye & @Gorbit99 @@ -134,6 +134,7 @@ 2.02: Added Decal destructor, optimised Pixel constructor 2.03: Added FreeBSD flags, Added DrawStringDecal() 2.04: Windows Full-Screen bug fixed + 2.05: Added DrawPartialWarpedDecal(), Added DrawPartialRotatedDecal() */ ////////////////////////////////////////////////////////////////////////////////////////// @@ -201,7 +202,6 @@ int main() #include #include #include -#include #include #include #include @@ -656,6 +656,12 @@ namespace olc void DrawRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center = { 0.0f, 0.0f }, const olc::vf2d& scale = { 1.0f,1.0f }, const olc::Pixel& tint = olc::WHITE); void DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col = olc::WHITE, const olc::vf2d& scale = { 1.0f, 1.0f }); + void DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale = { 1.0f, 1.0f }, const olc::Pixel& tint = olc::WHITE); + + void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + void DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + void DrawPartialWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint = olc::WHITE); + // Draws a single line of text void DrawString(int32_t x, int32_t y, const std::string& sText, Pixel col = olc::WHITE, uint32_t scale = 1); @@ -1857,6 +1863,60 @@ namespace olc vLayers[nTargetLayer].vecDecalInstance.push_back(di); } + void PixelGameEngine::DrawPartialRotatedDecal(const olc::vf2d& pos, olc::Decal* decal, const float fAngle, const olc::vf2d& center, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::vf2d& scale, const olc::Pixel& tint) + { + DecalInstance di; + di.decal = decal; + di.tint = tint; + di.pos[0] = (olc::vf2d(0.0f, 0.0f) - center) * scale; + di.pos[1] = (olc::vf2d(0.0f, source_size.y) - center) * scale; + di.pos[2] = (olc::vf2d(source_size.x, source_size.y) - center) * scale; + di.pos[3] = (olc::vf2d(source_size.x, 0.0f) - center) * scale; + float c = cos(fAngle), s = sin(fAngle); + for (int i = 0; i < 4; i++) + { + di.pos[i] = pos + olc::vf2d(di.pos[i].x * c - di.pos[i].y * s, di.pos[i].x * s + di.pos[i].y * c); + di.pos[i] = di.pos[i] * vInvScreenSize * 2.0f - olc::vf2d(1.0f, 1.0f); + di.pos[i].y *= -1.0f; + } + + olc::vf2d uvtl = source_pos * decal->vUVScale; + olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale); + di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1] = { uvtl.x, uvbr.y }; + di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3] = { uvbr.x, uvtl.y }; + + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { + DecalInstance di; + di.decal = decal; + di.tint = tint; + olc::vf2d center; + float rd = ((pos[2].x - pos[0].x) * (pos[3].y - pos[1].y) - (pos[3].x - pos[1].x) * (pos[2].y - pos[0].y)); + if (rd != 0) + { + olc::vf2d uvtl = source_pos * decal->vUVScale; + olc::vf2d uvbr = uvtl + (source_size * decal->vUVScale); + di.uv[0] = { uvtl.x, uvtl.y }; di.uv[1] = { uvtl.x, uvbr.y }; + di.uv[2] = { uvbr.x, uvbr.y }; di.uv[3] = { uvbr.x, uvtl.y }; + + rd = 1.0f / rd; + float rn = ((pos[3].x - pos[1].x) * (pos[0].y - pos[1].y) - (pos[3].y - pos[1].y) * (pos[0].x - pos[1].x)) * rd; + float sn = ((pos[2].x - pos[0].x) * (pos[0].y - pos[1].y) - (pos[2].y - pos[0].y) * (pos[0].x - pos[1].x)) * rd; + if (!(rn < 0.f || rn > 1.f || sn < 0.f || sn > 1.f)) center = pos[0] + rn * (pos[2] - pos[0]); + float d[4]; for (int i = 0; i < 4; i++) d[i] = (pos[i] - center).mag(); + for (int i = 0; i < 4; i++) + { + float q = d[i] == 0.0f ? 1.0f : (d[i] + d[(i + 2) & 3]) / d[(i + 2) & 3]; + di.uv[i] *= q; di.w[i] *= q; + di.pos[i] = { (pos[i].x * vInvScreenSize.x) * 2.0f - 1.0f, ((pos[i].y * vInvScreenSize.y) * 2.0f - 1.0f) * -1.0f }; + } + vLayers[nTargetLayer].vecDecalInstance.push_back(di); + } + } + void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d* pos, const olc::Pixel& tint) { // Thanks Nathan Reed, a brilliant article explaining whats going on here @@ -1884,15 +1944,17 @@ namespace olc } void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::Pixel& tint) - { - DrawWarpedDecal(decal, pos.data(), tint); - } + { DrawWarpedDecal(decal, pos.data(), tint); } void PixelGameEngine::DrawWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::Pixel& tint) - { - DrawWarpedDecal(decal, &pos[0], tint); - } + { DrawWarpedDecal(decal, &pos[0], tint); } + + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const std::array& pos, const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { DrawPartialWarpedDecal(decal, pos.data(), source_pos, source_size, tint); } + void PixelGameEngine::DrawPartialWarpedDecal(olc::Decal* decal, const olc::vf2d(&pos)[4], const olc::vf2d& source_pos, const olc::vf2d& source_size, const olc::Pixel& tint) + { DrawPartialWarpedDecal(decal, &pos[0], source_pos, source_size, tint); } + void PixelGameEngine::DrawStringDecal(const olc::vf2d& pos, const std::string& sText, const Pixel col, const olc::vf2d& scale) { olc::vf2d spos = { 0.0f, 0.0f };