diff --git a/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj b/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj index d809d4dc..0b979b34 100644 --- a/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj +++ b/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj @@ -43,11 +43,12 @@ true true + true true - false - false + true + true true diff --git a/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj.filters b/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj.filters index 6ebcfc8f..236e8825 100644 --- a/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj.filters +++ b/dev/msvc/olcPGE3_BuildSH/olcPGE3_BuildSH.vcxproj.filters @@ -93,6 +93,9 @@ Source Files + + Source Files + diff --git a/dev/src/api_macos.cpp b/dev/src/api_macos.cpp index 40188d23..d0cbcccc 100644 --- a/dev/src/api_macos.cpp +++ b/dev/src/api_macos.cpp @@ -18,7 +18,7 @@ static constexpr const char* kCustomOpenGLViewClass = "CustomOpenGLV static constexpr const char* kGeneralWindowDelegateClass = "GeneralWindowDelegate"; // Application Screen management selectors -static constexpr const char* kNSScreenClass = "NSScreen"; +//static constexpr const char* kNSScreenClass = "NSScreen"; // Temp remove unused variable warning static constexpr const char* kScreenSel = "screen"; static constexpr const char* kNSCursorClass = "NSCursor"; static constexpr const char* kUnhideSel = "unhide"; @@ -139,7 +139,7 @@ static constexpr const char* kLocaleIdentifierSel = "localeIdentif static constexpr const char* kWindowTitle = "C macOS OpenGL Framework"; static constexpr double kDefaultWindowWidth = 800.0; static constexpr double kDefaultWindowHeight = 600.0; -static constexpr int kBitsPerByte = 8; +// static constexpr int kBitsPerByte = 8; // Temp remove unused variable warning static constexpr int kMinValidDimension = 0; static constexpr int kRGBABytesPerPixel = 4; static constexpr int kFullyOpaque = 255; @@ -149,7 +149,7 @@ static constexpr int kZeroWidth = 0; static constexpr int kZeroHeight = 0; static constexpr int kFlippedOffset = 1; static constexpr int kNoButton = -1; -static constexpr int kDefaultScreenNumber = 1; +// static constexpr int kDefaultScreenNumber = 1; // Temp remove unused variable warning bool bAllowHideCursor = true; bool bHideCursor = false; @@ -280,8 +280,8 @@ namespace ObjectiveCSEL { // NSLocale selectors static SEL currentLocaleSel = nullptr; static SEL localeIdentifierSel = nullptr; - static SEL currentInputContextSel = nullptr; - static SEL localizedNameSel = nullptr; + // static SEL currentInputContextSel = nullptr; // Temp remove unused variable warning + // static SEL localizedNameSel = nullptr; // Temp remove unused variable warning // Initialize all selectors - called once at startup void initializeSelectors() { @@ -508,7 +508,7 @@ static constexpr int NSOpenGLPFAOpenGLProfile = static_cast(NSOpenGLPixelFo static constexpr int NSOpenGLPFASampleBuffers = static_cast(NSOpenGLPixelFormatAttribute::SampleBuffers); static constexpr int NSOpenGLPFAMultisample = static_cast(NSOpenGLPixelFormatAttribute::Multisample); static constexpr int NSOpenGLAllowOfflineRenderers = static_cast(NSOpenGLPixelFormatAttribute::AllowOfflineRenderers); -static constexpr int NSOpenGLPFAAcceleratedCompute = static_cast(NSOpenGLPixelFormatAttribute::AcceleratedCompute); +// static constexpr int NSOpenGLPFAAcceleratedCompute = static_cast(NSOpenGLPixelFormatAttribute::AcceleratedCompute); // Temp remove unused variable warning // enum for OpenGL profile versions enum class NSOpenGLProfile : int { @@ -517,6 +517,14 @@ enum class NSOpenGLProfile : int { Version4_1Core = 0x4100, // OpenGL 4.1 Core Profile }; +// enum for OpenGL context parameters +enum NSOpenGLContextParameter : int { + NSOpenGLContextParameterSwapInterval = 222, + NSOpenGLContextParameterSurfaceOrder = 235, + NSOpenGLContextParameterSurfaceOpacity = 236, + NSOpenGLContextParameterSurfaceBackingSize = 237 +}; + // Backward compatibility //static constexpr int NSOpenGLProfileVersion3_2Core = static_cast(NSOpenGLProfile::Version3_2Core); static constexpr int NSOpenGLProfileVersion4_1Core = static_cast(NSOpenGLProfile::Version4_1Core); @@ -538,10 +546,10 @@ enum class NSWindowStyleMask : uint16_t { }; // Backward compatibility -static constexpr int NSWindowStyleMaskTitled = static_cast(NSWindowStyleMask::Titled); -static constexpr int NSWindowStyleMaskClosable = static_cast(NSWindowStyleMask::Closable); -static constexpr int NSWindowStyleMaskMiniaturizable = static_cast(NSWindowStyleMask::Miniaturizable); -static constexpr int NSWindowStyleMaskResizable = static_cast(NSWindowStyleMask::Resizable); +// static constexpr int NSWindowStyleMaskTitled = static_cast(NSWindowStyleMask::Titled); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskClosable = static_cast(NSWindowStyleMask::Closable); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskMiniaturizable = static_cast(NSWindowStyleMask::Miniaturizable); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskResizable = static_cast(NSWindowStyleMask::Resizable); // Temp remove unused variable warning static constexpr int NSWindowStyleMaskFullScreen = static_cast(NSWindowStyleMask::FullScreen); // enum for backing store types @@ -1846,7 +1854,7 @@ extern "C" { GLint swapInterval = enabled ? 1 : 0; // Use NSOpenGLContext setValues:forParameter: to set swap interval - const GLint parameter = 222; // NSOpenGLContextParameterSwapInterval + const GLint parameter = NSOpenGLContextParameterSwapInterval; ((void(*)(id, SEL, const GLint*, GLint))objc_msgSend)(self->glContext, ObjectiveCSEL::setValuesSel, &swapInterval, parameter); } @@ -1897,13 +1905,13 @@ extern "C" { CGDataProviderRef provider = CGImageGetDataProvider(image); CFDataRef rawData = CGDataProviderCopyData(provider); - CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(image); - CGImageAlphaInfo alphaInfo = (CGImageAlphaInfo)(bitmapInfo & kCGBitmapAlphaInfoMask); - CGBitmapInfo byteOrder = bitmapInfo & kCGBitmapByteOrderMask; + //CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(image); // Temp remove unused variable warning + //CGImageAlphaInfo alphaInfo = (CGImageAlphaInfo)(bitmapInfo & kCGBitmapAlphaInfoMask); // Temp remove unused variable warning + //CGBitmapInfo byteOrder = bitmapInfo & kCGBitmapByteOrderMask; // Temp remove unused variable warning - self->width = CGImageGetWidth(image); - self->height = CGImageGetHeight(image); - self->bytesPerPixel = 4; + self->width = (int)CGImageGetWidth(image); + self->height = (int)CGImageGetHeight(image); + self->bytesPerPixel = kRGBABytesPerPixel; // 4 bytes for RGBA self->bytesPerRow = self->width * self->bytesPerPixel; self->hasAlpha = YES; diff --git a/dev/src/api_opengl.cpp b/dev/src/api_opengl.cpp index 4923ef82..578a8473 100644 --- a/dev/src/api_opengl.cpp +++ b/dev/src/api_opengl.cpp @@ -265,6 +265,8 @@ namespace olc::apis::opengl { #if OLC_HOST == OLC_HOST_WINDOWS _wglSwapIntervalEXT(n); +#else + olc_IgnoreUnused(n); #endif } diff --git a/dev/src/config.h b/dev/src/config.h index b193a529..b974500b 100644 --- a/dev/src/config.h +++ b/dev/src/config.h @@ -152,11 +152,20 @@ #define LICENCE_DEFAULT "OneLoneCoder.com - Pixel Game Engine 3 - " +#if OLC_HOST == OLC_HOST_MACOS +// De-Noise in clang (C++20) MacOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" // Allow unknown pragmas for compatibility with different compilers +#pragma clang diagnostic ignored "-Wgnu-anonymous-struct" // Allow anonymous structs in unions + +#endif + // De-Noise in MSVC (C++20) /Wall #pragma warning(disable:4820) // Disable Padding Warnings #pragma warning(disable:5045) // Disable Spectre Mitigation Warnings #pragma warning(disable:4514) // Disable Unreferenced Inline Function Warnings + template inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {} @@ -188,4 +197,4 @@ inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {} #define OLC_FRIENDLY_HOST Host_Android #endif -//! END CONFIGURATION \ No newline at end of file +//! END CONFIGURATION diff --git a/dev/src/core.cpp b/dev/src/core.cpp index 7ac6568a..612d3d68 100644 --- a/dev/src/core.cpp +++ b/dev/src/core.cpp @@ -201,6 +201,8 @@ namespace olc // Present final composite pRenderer->SetViewport(vViewPos, vViewSize); pRenderer->ClearViewport(config.colClear, true, true); + draw.SetBlendMode(olc::BlendMode::Alpha); + draw.SetCullMode(olc::CullMode::None); draw.ImageRect(GetScreen().flipV(), { 0.0,0.0 }, vViewSize); draw.ProcessGPUTasks(); @@ -514,6 +516,8 @@ namespace olc draw.ProcessGPUTasks(); // Set to known default state + draw.SetBlendMode(olc::BlendMode::Alpha); + draw.SetCullMode(olc::CullMode::None); draw.SetTarget(GetScreen()); draw.WorldReset(); gpu->ApplyDefaultShader(); diff --git a/dev/src/draw.cpp b/dev/src/draw.cpp index a239b244..388f00ea 100644 --- a/dev/src/draw.cpp +++ b/dev/src/draw.cpp @@ -3,6 +3,10 @@ #include "gpu_iface.h" //! START IMPLEMENTATION +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpessimizing-move" // Suppress clang C++20 warning about moves preventing copy elision on macOS +#endif using namespace olc; // Some local pools to reduce allocations @@ -266,6 +270,7 @@ GPUTask olc::Draw::TaskDrawLine(const std::vector& vPoints, const std task.vertexBuffer[i*2+0] = { {vPoints[i].x, vPoints[i].y, 1.0f, 1.0f}, vColours[i], {0, 0}, {0, 0}, {0, 0}, {0, 0} }; task.vertexBuffer[i*2+1] = { {vPoints[i + 1].x, vPoints[i + 1].y, 1.0f, 1.0f}, vColours[i + 1], {0, 0}, {0, 0}, {0, 0}, {0, 0} }; } + task.blendmode = blendMode; task.tint = tint; return task; } @@ -278,6 +283,7 @@ GPUTask olc::Draw::TaskDrawPolygon(olc::Structure structure, const std::vector(os_win_id[1]); if (*bSkipFrame) return true; CGLContextObj cglContext = static_cast(os_win_id[0]); diff --git a/dev/src/gputask.h b/dev/src/gputask.h index 251230de..d2549def 100644 --- a/dev/src/gputask.h +++ b/dev/src/gputask.h @@ -37,6 +37,29 @@ namespace olc // Vertex buffer is a series of discrete triangles List, }; + + // Define blend modes for drawing operations + enum class BlendMode : uint8_t + { + // Alpha blend source and destination pixels based on source alpha + Alpha = 0, + // Additively blend source and destination pixels together + Additive, + // Multiplicatively blend source and destination pixels together + Multiplicative, + // No blending, just overwrite pixels with source colour + None, + }; + + enum class CullMode : uint8_t + { + // No + None = 0, + // Cull if vertices are listed in clockwise order + ClockWise, + // Cull if vertices are listed in anticlockwise order + CounterClockWise + }; // This is the default "packet" of work that is sent to // a GPU for drawing. Various drawing operations throughout @@ -85,21 +108,17 @@ namespace olc // Overall biasing colour (great for blends) olc::Pixel tint = olc::Colour::WHITE; + // Texture to be used for drawing (if any) (in slot #0) olc::Image* pImage = nullptr; // Define super structure to be drawn Structure structure = Structure::Fan; // Define if GPU should face cull based on winding order - enum class CullMode : uint8_t - { - // No - None = 0, - // Cull if vertices are listed in clockwise order - ClockWise, - // Cull if vertices are listed in anticlockwise order - CounterClockWise - } cullmode = CullMode::None; + CullMode cullmode = CullMode::None; + + // Define blend mode for drawing + BlendMode blendmode = BlendMode::Alpha; }; } #define PGE_GPUTASK_DECLARED 1 diff --git a/dev/src/host_apple_macos.cpp b/dev/src/host_apple_macos.cpp index f2bde38c..5130bb62 100644 --- a/dev/src/host_apple_macos.cpp +++ b/dev/src/host_apple_macos.cpp @@ -9,15 +9,15 @@ namespace olc::host { // NSEventModifierFlags values - constexpr unsigned int NSEventModifierNoFlags = 1 << 8; // 0x100 - constexpr unsigned int NSEventModifierFlagCapsLock = 1 << 16; // 0x10000 + // constexpr unsigned int NSEventModifierNoFlags = 1 << 8; // 0x100 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagCapsLock = 1 << 16; // 0x10000 // Temp remove unused variable warning constexpr unsigned int NSEventModifierFlagShift = 1 << 17; // 0x20000 constexpr unsigned int NSEventModifierFlagControl = 1 << 18; // 0x40000 - constexpr unsigned int NSEventModifierFlagOption = 1 << 19; // 0x80000 + // constexpr unsigned int NSEventModifierFlagOption = 1 << 19; // 0x80000 // Temp remove unused variable warning constexpr unsigned int NSEventModifierFlagCommand = 1 << 20; // 0x100000 - constexpr unsigned int NSEventModifierFlagNumericPad = 1 << 21; // 0x200000 - constexpr unsigned int NSEventModifierFlagHelp = 1 << 22; // 0x400000 - constexpr unsigned int NSEventModifierFlagFunction = 1 << 23; // 0x800000 + // constexpr unsigned int NSEventModifierFlagNumericPad = 1 << 21; // 0x200000 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagHelp = 1 << 22; // 0x400000 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagFunction = 1 << 23; // 0x800000 // Temp remove unused variable warning // enum for window appearance and behavior bit flags enum class NSWindowStyleMask : uint16_t { @@ -154,6 +154,7 @@ namespace olc::host { bool Host_Apple_MacOS::AddWindowFrame(olc::Window* pWindow, const olc::vi2d& vWindowPos, const olc::vi2d& vWindowSize, const bool bFullScreen){ + olc_IgnoreUnused(bFullScreen); pPGEwindow = pWindow; pPGEwindow->SetWindowPosition(vWindowPos); pPGEwindow->SetWindowSize(vWindowSize); @@ -181,7 +182,7 @@ namespace olc::host { } std::vector Host_Apple_MacOS::GetHostWindowDescriptor(olc::Window* pWindow){ - + olc_IgnoreUnused(pWindow); // Ensure OpenGL renderer is created if(pMacOSOpenGLRenderer == nullptr) CreateCGLContextObj(); @@ -210,6 +211,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetMousePosition(olc::Window* pWindow, const olc::vi2d& vPos) { + olc_IgnoreUnused(pWindow); dispatch_sync(dispatch_get_main_queue(), ^{ pMacOSWindow->setCursorPosition(vPos.x, vPos.y); }); @@ -218,6 +220,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetMouseVisible(olc::Window* pWindow, const bool bVisible) { + olc_IgnoreUnused(pWindow); dispatch_sync(dispatch_get_main_queue(), ^{ pMacOSWindow->setCursorVisibility(bVisible); }); @@ -226,6 +229,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetFullScreen(olc::Window* pWindow, const bool bFullScreen) { + olc_IgnoreUnused(pWindow); // if we're already in the specified state, return early if(pMacOSWindow->isFullScreen() == bFullScreen) return true; diff --git a/dev/src/imload_macos.cpp b/dev/src/imload_macos.cpp index 94734e6e..3136bc73 100644 --- a/dev/src/imload_macos.cpp +++ b/dev/src/imload_macos.cpp @@ -94,11 +94,13 @@ namespace olc::imload bool ImageLoader_MacOS::WriteImageToFile(const olc::Image& image, const std::string& sFileName) { + olc_IgnoreUnused(image, sFileName); return false; } bool ImageLoader_MacOS::WriteImageToMemoryFile(olc::Image& image, const std::vector& data) { + olc_IgnoreUnused(image, data); return false; } } diff --git a/dev/src/pixel.h b/dev/src/pixel.h index 54d7b154..95bb5de5 100644 --- a/dev/src/pixel.h +++ b/dev/src/pixel.h @@ -17,6 +17,10 @@ //! START DECLARATION #if !defined(PGE_PIXEL_DECLARED) +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" // Silence warnings about implicitly generated copy constructor for Pixel +#endif namespace olc { class Pixel @@ -324,6 +328,10 @@ namespace olc } } +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic pop +#endif + #define PGE_PIXEL_DECLARED 1 #endif //! END DECLARATION \ No newline at end of file diff --git a/dev/src/transform2d.h b/dev/src/transform2d.h index c4cec130..68b92edb 100644 --- a/dev/src/transform2d.h +++ b/dev/src/transform2d.h @@ -17,6 +17,10 @@ //! START DECLARATION #if !defined(PGE_TRANSFORM2D_DECLARED) +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-qualifiers" // Silence warnings about ignored qualifiers in olc::t_2d +#endif namespace olc { namespace internal @@ -259,6 +263,9 @@ namespace olc typedef t_2d tf2d; typedef t_2d td2d; } +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic pop +#endif #define PGE_TRANSFORM2D_DECLARED 1 #endif -//! END DECLARATION \ No newline at end of file +//! END DECLARATION diff --git a/dev/tests/test_mh.cpp b/dev/tests/test_mh.cpp index b2fb1a3b..4fefc1f3 100644 --- a/dev/tests/test_mh.cpp +++ b/dev/tests/test_mh.cpp @@ -364,8 +364,8 @@ class Example : public olc::PixelGameEngine - // Draw 3 triangle points - for (int i = 0; i < vecTestPoints.size(); i++) + // Draw 3 triangle points (change to size_t to remove warning -Wsign-compare) + for (size_t i = 0; i < vecTestPoints.size(); i++) { //draw.Rect(vecTestPoints[i] - (vTestPointSize * 0.5f), vTestPointSize, olc::Colour::MAGENTA); @@ -398,8 +398,8 @@ class Example : public olc::PixelGameEngine t2.translate(0.0f, 6.0f, 0.0f); t3.translate(7.0f, 0.0f, 0.0f); - olc::vf4d v1 = { 1,0,0,1 }; - olc::vf4d v2 = t3 * t2 * t1 * v1; + //olc::vf4d v1 = { 1,0,0,1 }; // Temp remove unused variable warning + //olc::vf4d v2 = t3 * t2 * t1 * v1; // Temp remove unused variable warning olc::mf4d matProj; @@ -452,7 +452,8 @@ class Example : public olc::PixelGameEngine if (mouse.GetButton(0).bPressed) { nSelectedPoint = -1; - for (int i = 0; i < vecTestPoints.size(); i++) + // change to size_t to remove warning -Wsign-compare + for (int i = 0; i < (int)vecTestPoints.size(); i++) { if ((mouse.GetPosition() - vecTestPoints[i]).mag2() < 9) { diff --git a/examples/olcPGE3_BlendingModes.cpp b/examples/olcPGE3_BlendingModes.cpp new file mode 100644 index 00000000..e3b6d0b7 --- /dev/null +++ b/examples/olcPGE3_BlendingModes.cpp @@ -0,0 +1,172 @@ +/* + olc::PixelGameEngine3 Example - Blending Modes + + Draws a few lines using different styles and techniques + + Licenced under the OLC-3 License +*/ + + +// Define OLC_PGE3_APPLICATION to include the implementation of +// the Pixel Game Engine as part of this translation unit +#define OLC_PGE3_APPLICATION +#include "../olcPixelGameEngine3.h" + +// Example application demonstrating various blend modes. This class +// overrides the olc::PixelGameEngine base class by implementing +// the OnUserCreate() and OnUserUpdate() functions +class Example_BlendingModes : public olc::PixelGameEngine +{ +public: + Example_BlendingModes() + { + sAppName = "Example - Blending Modes"; + } + + struct sGel + { + olc::vf2d vPos; + olc::Pixel col; + }; + + std::vector vecGels; + olc::vf2d vGelSize = { 32.0f, 32.0f }; + sGel* pSelectedGel = nullptr; + olc::BlendMode currentBlendMode = olc::BlendMode::Alpha; + olc::Image imgTest; + +public: + // Called once at the start, so create things here + bool OnUserCreate() override + { + // Create "gels" - these are just coloured rectangles that we + // will draw with different blend modes + vecGels.push_back({ { 98.0f, 74.0f }, olc::Colour::RED }); + vecGels.push_back({ { 114.0f, 57.0f }, olc::Colour::GREEN }); + vecGels.push_back({ { 118.0f, 80.0f }, olc::Colour::BLUE }); + vecGels.push_back({ { 145.0f, 178.0f }, olc::Colour::WHITE }); + vecGels.push_back({ { 113.0f, 135.0f }, olc::Colour::BLACK }); + vecGels.push_back({ { 77.0f, 176.0f }, olc::Pixel(128, 128, 128) }); + vecGels.push_back({ { 47.0f, 128.0f }, olc::Pixel(255, 255, 255, 64) }); + + // Last gel uses an image for complexity + vecGels.push_back({ { 18.0f, 169.0f }, olc::Pixel(255,255,255,64)}); + CreateImageFromFile(imgTest, "./assets/minsanity_texture.png"); + + return true; + } + + // Called every frame, so update things here + bool OnUserUpdate(float fElapsedTime) override + { + // Draw Colour Bars + draw.FilledRect({ 0.0f, 0.0f }, { 32.0f, 240.0f }, + olc::Colour::VERY_DARK_RED, olc::Colour::VERY_DARK_RED, + olc::Colour::RED, olc::Colour::RED); + draw.FilledRect({ 32.0f, 0.0f }, { 32.0f, 240.0f }, + olc::Colour::VERY_DARK_GREEN, olc::Colour::VERY_DARK_GREEN, + olc::Colour::GREEN, olc::Colour::GREEN); + draw.FilledRect({ 64.0f, 0.0f }, { 32.0f, 240.0f }, + olc::Colour::VERY_DARK_BLUE, olc::Colour::VERY_DARK_BLUE, + olc::Colour::BLUE, olc::Colour::BLUE); + draw.FilledRect({ 96.0f, 0.0f }, { 32.0f, 240.0f }, + olc::Colour::BLACK); + draw.FilledRect({ 128.0f, 0.0f }, { 128.0f, 240.0f }, + olc::Colour::WHITE, olc::Colour::WHITE, + olc::Colour::BLACK, olc::Colour::BLACK); + + // TADA!! Setting the Blend Mode changes how the GPU draws pixels to the screen. + // This is a global state, so all drawing operations will be affected by this + // setting until it is changed again + draw.SetBlendMode(currentBlendMode); + + // Note drawing happens as normal, the GPU has been instructed to + // use the current blend mode when drawing pixels + + // Draw Gels with appropriate mode + int gelCount = 0; + for (auto& gel : vecGels) + { + if (gelCount == vecGels.size() - 1) + { + // Gel is a texture + draw.ImageRect(imgTest, gel.vPos, vGelSize); + } + else // Gel is just a coloured rectangle + draw.FilledRect(gel.vPos, vGelSize, gel.col); + + gelCount++; + } + + + + // Switch back to alpha mode (aka Normal) for UI + draw.SetBlendMode(olc::BlendMode::Alpha); + + // Hilioght frame of gel and detect if mouse is over it + for (auto& gel : vecGels) + { + draw.Rect(gel.vPos, vGelSize, olc::Colour::WHITE); + + if (mouse.GetPosition().x >= gel.vPos.x && mouse.GetPosition().x < gel.vPos.x + vGelSize.x && + mouse.GetPosition().y >= gel.vPos.y && mouse.GetPosition().y < gel.vPos.y + vGelSize.y) + { + if (mouse.GetButton(0).bPressed) + { + pSelectedGel = ⋛ + } + } + } + + // Handle mouse + if(pSelectedGel && mouse.GetButton(0).bHeld) + { + pSelectedGel->vPos = mouse.GetPosition() - vGelSize / 2.0f; + } + + if (mouse.GetButton(0).bReleased) + { + pSelectedGel = nullptr; + } + + + // Change blend mode with number keys + if (keyboard.GetKey(olc::Key::K1).bPressed) + currentBlendMode = olc::BlendMode::Alpha; + if (keyboard.GetKey(olc::Key::K2).bPressed) + currentBlendMode = olc::BlendMode::Multiplicative; + if (keyboard.GetKey(olc::Key::K3).bPressed) + currentBlendMode = olc::BlendMode::Additive; + + + // Draw UI + draw.String({ 10.0f, 2.0f }, "1: Alpha Blend", + currentBlendMode == olc::BlendMode::Alpha ? olc::Colour::YELLOW : olc::Colour::WHITE); + draw.String({ 10.0f, 12.0f }, "2: Multiplicative Blend", + currentBlendMode == olc::BlendMode::Multiplicative ? olc::Colour::YELLOW : olc::Colour::WHITE); + draw.String({ 10.0f, 22.0f }, "3: Additive Blend", + currentBlendMode == olc::BlendMode::Additive ? olc::Colour::YELLOW : olc::Colour::WHITE); + draw.String({ 10.0f, 32.0f }, "Mouse to drag gels", olc::Colour::WHITE); + + // Successful frame + return true; + } +}; + + +// Main entry point for the application +int main() +{ + // Construct demo application + Example_BlendingModes demo; + + // Create "screen" of 256x240 "pixels" + // with a pixel size of 4x4 actual screen pixels + if (demo.Construct({ 256, 240 }, { 4, 4 })) + { + // Start the application + demo.Start(); + } + + return 0; +} \ No newline at end of file diff --git a/examples/olcPGE3_Extensions.cpp b/examples/olcPGE3_Extensions.cpp index 582e5633..b6a36757 100644 --- a/examples/olcPGE3_Extensions.cpp +++ b/examples/olcPGE3_Extensions.cpp @@ -24,7 +24,7 @@ class ExamplePGEX : public olc::PGEWindowExtension { // Called when extension is installed, usually in PGEWindow Constructor // Return true to continue application - virtual bool OnInstall([[maybe_unused]] olc::PGEWindow* pge) + virtual bool OnInstall([[maybe_unused]] olc::PGEWindow* pge) override { return true; } @@ -98,6 +98,8 @@ class Example_Extensions : public olc::PixelGameEngine // We need to create an instance of our extension class, and then install it in the PGE constructor ExamplePGEX pgex; + float fTotalTime = 0.0f; + public: // Called once at the start, so create things here bool OnUserCreate() override @@ -115,7 +117,7 @@ class Example_Extensions : public olc::PixelGameEngine draw.String({ 10.0f, 10.0f }, "This text is drawn from the\nmain application!\n\nMouse Move in X To Warp Time", olc::Colour::WHITE); // Draw a clocking line to illustrate the passage of time... - float fTotalTime = TotalTimeElapsed(); + fTotalTime += fElapsedTime; draw.Line(GetScreen().Size() / 2, olc::vf2d(cos(fTotalTime), sin(fTotalTime)) * 50.0f + GetScreen().Size() / 2, olc::Colour::GREEN); // Successful frame @@ -139,4 +141,4 @@ int main() } return 0; -} \ No newline at end of file +} diff --git a/olcPixelGameEngine3.h b/olcPixelGameEngine3.h index 37104252..48bd405a 100644 --- a/olcPixelGameEngine3.h +++ b/olcPixelGameEngine3.h @@ -290,11 +290,20 @@ #define LICENCE_DEFAULT "OneLoneCoder.com - Pixel Game Engine 3 - " +#if OLC_HOST == OLC_HOST_MACOS +// De-Noise in clang (C++20) MacOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wunknown-pragmas" // Allow unknown pragmas for compatibility with different compilers +#pragma clang diagnostic ignored "-Wgnu-anonymous-struct" // Allow anonymous structs in unions + +#endif + // De-Noise in MSVC (C++20) /Wall #pragma warning(disable:4820) // Disable Padding Warnings #pragma warning(disable:5045) // Disable Spectre Mitigation Warnings #pragma warning(disable:4514) // Disable Unreferenced Inline Function Warnings + template inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {} @@ -328,6 +337,10 @@ inline constexpr void olc_IgnoreUnused(Args&&...) noexcept {} #if !defined(PGE_PIXEL_DECLARED) +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wdeprecated-copy-with-user-provided-copy" // Silence warnings about implicitly generated copy constructor for Pixel +#endif namespace olc { class Pixel @@ -635,6 +648,10 @@ namespace olc } } +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic pop +#endif + #define PGE_PIXEL_DECLARED 1 #endif @@ -1965,6 +1982,10 @@ namespace olc #endif #if !defined(PGE_TRANSFORM2D_DECLARED) +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wignored-qualifiers" // Silence warnings about ignored qualifiers in olc::t_2d +#endif namespace olc { namespace internal @@ -2207,6 +2228,9 @@ namespace olc typedef t_2d tf2d; typedef t_2d td2d; } +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic pop +#endif #define PGE_TRANSFORM2D_DECLARED 1 #endif @@ -2479,6 +2503,29 @@ namespace olc // Vertex buffer is a series of discrete triangles List, }; + + // Define blend modes for drawing operations + enum class BlendMode : uint8_t + { + // Alpha blend source and destination pixels based on source alpha + Alpha = 0, + // Additively blend source and destination pixels together + Additive, + // Multiplicatively blend source and destination pixels together + Multiplicative, + // No blending, just overwrite pixels with source colour + None, + }; + + enum class CullMode : uint8_t + { + // No + None = 0, + // Cull if vertices are listed in clockwise order + ClockWise, + // Cull if vertices are listed in anticlockwise order + CounterClockWise + }; // This is the default "packet" of work that is sent to // a GPU for drawing. Various drawing operations throughout @@ -2527,21 +2574,17 @@ namespace olc // Overall biasing colour (great for blends) olc::Pixel tint = olc::Colour::WHITE; + // Texture to be used for drawing (if any) (in slot #0) olc::Image* pImage = nullptr; // Define super structure to be drawn Structure structure = Structure::Fan; // Define if GPU should face cull based on winding order - enum class CullMode : uint8_t - { - // No - None = 0, - // Cull if vertices are listed in clockwise order - ClockWise, - // Cull if vertices are listed in anticlockwise order - CounterClockWise - } cullmode = CullMode::None; + CullMode cullmode = CullMode::None; + + // Define blend mode for drawing + BlendMode blendmode = BlendMode::Alpha; }; } #define PGE_GPUTASK_DECLARED 1 @@ -3349,7 +3392,8 @@ namespace olc const olc::Pixel tint = olc::Colour::WHITE); public: // Applied Rendering Modes - void SetCullMode(const olc::GPUTask::CullMode mode); + void SetCullMode(const olc::CullMode mode); + void SetBlendMode(const olc::BlendMode mode); void EnableDepth(const bool bEnable); void SetViewport(const olc::vi2d& pos, const olc::vi2d& size); @@ -3549,7 +3593,8 @@ namespace olc olc::vi2d vViewportSize = { 0, 0 }; - olc::GPUTask::CullMode cullMode = olc::GPUTask::CullMode::None; + olc::CullMode cullMode = olc::CullMode::None; + olc::BlendMode blendMode = olc::BlendMode::Alpha; bool bDepth = true; @@ -7906,15 +7951,15 @@ namespace olc::host { // NSEventModifierFlags values - constexpr unsigned int NSEventModifierNoFlags = 1 << 8; // 0x100 - constexpr unsigned int NSEventModifierFlagCapsLock = 1 << 16; // 0x10000 + // constexpr unsigned int NSEventModifierNoFlags = 1 << 8; // 0x100 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagCapsLock = 1 << 16; // 0x10000 // Temp remove unused variable warning constexpr unsigned int NSEventModifierFlagShift = 1 << 17; // 0x20000 constexpr unsigned int NSEventModifierFlagControl = 1 << 18; // 0x40000 - constexpr unsigned int NSEventModifierFlagOption = 1 << 19; // 0x80000 + // constexpr unsigned int NSEventModifierFlagOption = 1 << 19; // 0x80000 // Temp remove unused variable warning constexpr unsigned int NSEventModifierFlagCommand = 1 << 20; // 0x100000 - constexpr unsigned int NSEventModifierFlagNumericPad = 1 << 21; // 0x200000 - constexpr unsigned int NSEventModifierFlagHelp = 1 << 22; // 0x400000 - constexpr unsigned int NSEventModifierFlagFunction = 1 << 23; // 0x800000 + // constexpr unsigned int NSEventModifierFlagNumericPad = 1 << 21; // 0x200000 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagHelp = 1 << 22; // 0x400000 // Temp remove unused variable warning + // constexpr unsigned int NSEventModifierFlagFunction = 1 << 23; // 0x800000 // Temp remove unused variable warning // enum for window appearance and behavior bit flags enum class NSWindowStyleMask : uint16_t { @@ -8051,6 +8096,7 @@ namespace olc::host { bool Host_Apple_MacOS::AddWindowFrame(olc::Window* pWindow, const olc::vi2d& vWindowPos, const olc::vi2d& vWindowSize, const bool bFullScreen){ + olc_IgnoreUnused(bFullScreen); pPGEwindow = pWindow; pPGEwindow->SetWindowPosition(vWindowPos); pPGEwindow->SetWindowSize(vWindowSize); @@ -8078,7 +8124,7 @@ namespace olc::host { } std::vector Host_Apple_MacOS::GetHostWindowDescriptor(olc::Window* pWindow){ - + olc_IgnoreUnused(pWindow); // Ensure OpenGL renderer is created if(pMacOSOpenGLRenderer == nullptr) CreateCGLContextObj(); @@ -8107,6 +8153,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetMousePosition(olc::Window* pWindow, const olc::vi2d& vPos) { + olc_IgnoreUnused(pWindow); dispatch_sync(dispatch_get_main_queue(), ^{ pMacOSWindow->setCursorPosition(vPos.x, vPos.y); }); @@ -8115,6 +8162,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetMouseVisible(olc::Window* pWindow, const bool bVisible) { + olc_IgnoreUnused(pWindow); dispatch_sync(dispatch_get_main_queue(), ^{ pMacOSWindow->setCursorVisibility(bVisible); }); @@ -8123,6 +8171,7 @@ namespace olc::host { bool Host_Apple_MacOS::SetFullScreen(olc::Window* pWindow, const bool bFullScreen) { + olc_IgnoreUnused(pWindow); // if we're already in the specified state, return early if(pMacOSWindow->isFullScreen() == bFullScreen) return true; @@ -8669,7 +8718,7 @@ static constexpr const char* kCustomOpenGLViewClass = "CustomOpenGLV static constexpr const char* kGeneralWindowDelegateClass = "GeneralWindowDelegate"; // Application Screen management selectors -static constexpr const char* kNSScreenClass = "NSScreen"; +//static constexpr const char* kNSScreenClass = "NSScreen"; // Temp remove unused variable warning static constexpr const char* kScreenSel = "screen"; static constexpr const char* kNSCursorClass = "NSCursor"; static constexpr const char* kUnhideSel = "unhide"; @@ -8790,7 +8839,7 @@ static constexpr const char* kLocaleIdentifierSel = "localeIdentif static constexpr const char* kWindowTitle = "C macOS OpenGL Framework"; static constexpr double kDefaultWindowWidth = 800.0; static constexpr double kDefaultWindowHeight = 600.0; -static constexpr int kBitsPerByte = 8; +// static constexpr int kBitsPerByte = 8; // Temp remove unused variable warning static constexpr int kMinValidDimension = 0; static constexpr int kRGBABytesPerPixel = 4; static constexpr int kFullyOpaque = 255; @@ -8800,7 +8849,7 @@ static constexpr int kZeroWidth = 0; static constexpr int kZeroHeight = 0; static constexpr int kFlippedOffset = 1; static constexpr int kNoButton = -1; -static constexpr int kDefaultScreenNumber = 1; +// static constexpr int kDefaultScreenNumber = 1; // Temp remove unused variable warning bool bAllowHideCursor = true; bool bHideCursor = false; @@ -8931,8 +8980,8 @@ namespace ObjectiveCSEL { // NSLocale selectors static SEL currentLocaleSel = nullptr; static SEL localeIdentifierSel = nullptr; - static SEL currentInputContextSel = nullptr; - static SEL localizedNameSel = nullptr; + // static SEL currentInputContextSel = nullptr; // Temp remove unused variable warning + // static SEL localizedNameSel = nullptr; // Temp remove unused variable warning // Initialize all selectors - called once at startup void initializeSelectors() { @@ -9159,7 +9208,7 @@ static constexpr int NSOpenGLPFAOpenGLProfile = static_cast(NSOpenGLPixelFo static constexpr int NSOpenGLPFASampleBuffers = static_cast(NSOpenGLPixelFormatAttribute::SampleBuffers); static constexpr int NSOpenGLPFAMultisample = static_cast(NSOpenGLPixelFormatAttribute::Multisample); static constexpr int NSOpenGLAllowOfflineRenderers = static_cast(NSOpenGLPixelFormatAttribute::AllowOfflineRenderers); -static constexpr int NSOpenGLPFAAcceleratedCompute = static_cast(NSOpenGLPixelFormatAttribute::AcceleratedCompute); +// static constexpr int NSOpenGLPFAAcceleratedCompute = static_cast(NSOpenGLPixelFormatAttribute::AcceleratedCompute); // Temp remove unused variable warning // enum for OpenGL profile versions enum class NSOpenGLProfile : int { @@ -9168,6 +9217,14 @@ enum class NSOpenGLProfile : int { Version4_1Core = 0x4100, // OpenGL 4.1 Core Profile }; +// enum for OpenGL context parameters +enum NSOpenGLContextParameter : int { + NSOpenGLContextParameterSwapInterval = 222, + NSOpenGLContextParameterSurfaceOrder = 235, + NSOpenGLContextParameterSurfaceOpacity = 236, + NSOpenGLContextParameterSurfaceBackingSize = 237 +}; + // Backward compatibility //static constexpr int NSOpenGLProfileVersion3_2Core = static_cast(NSOpenGLProfile::Version3_2Core); static constexpr int NSOpenGLProfileVersion4_1Core = static_cast(NSOpenGLProfile::Version4_1Core); @@ -9189,10 +9246,10 @@ enum class NSWindowStyleMask : uint16_t { }; // Backward compatibility -static constexpr int NSWindowStyleMaskTitled = static_cast(NSWindowStyleMask::Titled); -static constexpr int NSWindowStyleMaskClosable = static_cast(NSWindowStyleMask::Closable); -static constexpr int NSWindowStyleMaskMiniaturizable = static_cast(NSWindowStyleMask::Miniaturizable); -static constexpr int NSWindowStyleMaskResizable = static_cast(NSWindowStyleMask::Resizable); +// static constexpr int NSWindowStyleMaskTitled = static_cast(NSWindowStyleMask::Titled); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskClosable = static_cast(NSWindowStyleMask::Closable); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskMiniaturizable = static_cast(NSWindowStyleMask::Miniaturizable); // Temp remove unused variable warning +// static constexpr int NSWindowStyleMaskResizable = static_cast(NSWindowStyleMask::Resizable); // Temp remove unused variable warning static constexpr int NSWindowStyleMaskFullScreen = static_cast(NSWindowStyleMask::FullScreen); // enum for backing store types @@ -10497,7 +10554,7 @@ extern "C" { GLint swapInterval = enabled ? 1 : 0; // Use NSOpenGLContext setValues:forParameter: to set swap interval - const GLint parameter = 222; // NSOpenGLContextParameterSwapInterval + const GLint parameter = NSOpenGLContextParameterSwapInterval; ((void(*)(id, SEL, const GLint*, GLint))objc_msgSend)(self->glContext, ObjectiveCSEL::setValuesSel, &swapInterval, parameter); } @@ -10548,13 +10605,13 @@ extern "C" { CGDataProviderRef provider = CGImageGetDataProvider(image); CFDataRef rawData = CGDataProviderCopyData(provider); - CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(image); - CGImageAlphaInfo alphaInfo = (CGImageAlphaInfo)(bitmapInfo & kCGBitmapAlphaInfoMask); - CGBitmapInfo byteOrder = bitmapInfo & kCGBitmapByteOrderMask; + //CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(image); // Temp remove unused variable warning + //CGImageAlphaInfo alphaInfo = (CGImageAlphaInfo)(bitmapInfo & kCGBitmapAlphaInfoMask); // Temp remove unused variable warning + //CGBitmapInfo byteOrder = bitmapInfo & kCGBitmapByteOrderMask; // Temp remove unused variable warning - self->width = CGImageGetWidth(image); - self->height = CGImageGetHeight(image); - self->bytesPerPixel = 4; + self->width = (int)CGImageGetWidth(image); + self->height = (int)CGImageGetHeight(image); + self->bytesPerPixel = kRGBABytesPerPixel; // 4 bytes for RGBA self->bytesPerRow = self->width * self->bytesPerPixel; self->hasAlpha = YES; @@ -14441,6 +14498,8 @@ namespace olc::apis::opengl { #if OLC_HOST == OLC_HOST_WINDOWS _wglSwapIntervalEXT(n); +#else + olc_IgnoreUnused(n); #endif } @@ -15823,31 +15882,51 @@ void main() // Apply Culling modes - if (task.cullmode == GPUTask::CullMode::None) + if (task.cullmode == olc::CullMode::None) { gl.glDisable(GL_CULL_FACE); } - else if (task.cullmode == GPUTask::CullMode::ClockWise) + else if (task.cullmode == olc::CullMode::ClockWise) { gl.glCullFace(GL_FRONT); gl.glEnable(GL_CULL_FACE); } - else if (task.cullmode == GPUTask::CullMode::CounterClockWise) + else if (task.cullmode == olc::CullMode::CounterClockWise) { gl.glCullFace(GL_BACK); gl.glEnable(GL_CULL_FACE); } - //// Apply Depth Testing (if required) + // Apply Depth Testing (if required) if (task.bDepth) + { gl.glEnable(GL_DEPTH_TEST); + gl.glDepthFunc(GL_LESS); + } + - glDepthFunc(GL_LESS); + // Apply Blending Mode + if (task.blendmode == olc::BlendMode::Alpha) + { + gl.glEnable(GL_BLEND); + gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + } + else if(task.blendmode == olc::BlendMode::Additive) + { + gl.glEnable(GL_BLEND); + gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE); + } + else if(task.blendmode == olc::BlendMode::Multiplicative) + { + gl.glEnable(GL_BLEND); + gl.glBlendFunc(GL_DST_COLOR, GL_ONE_MINUS_SRC_ALPHA); + } - gl.glEnable(GL_BLEND); + //gl.glEnable(GL_BLEND); //gl.glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - gl.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + //gl.glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA); + // Apply Rendering Mode if (task.bWireframe) gl.glPolygonMode(GL_FRONT_AND_BACK, GL_LINE); @@ -15941,6 +16020,7 @@ void main() #if OLC_HOST == OLC_HOST_MACOS // The pointer value in os_win_id[1] will be set to true, when the OS requests to skip the frame swap + olc_IgnoreUnused(bVerticalSyncNow); const bool* bSkipFrame = static_cast(os_win_id[1]); if (*bSkipFrame) return true; CGLContextObj cglContext = static_cast(os_win_id[0]); @@ -16019,6 +16099,10 @@ void main() #endif #if defined(OLC_PGE3_APPLICATION) && !defined(PGE_DRAW_IMPLEMENTED) +#if OLC_HOST == OLC_HOST_MACOS +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wpessimizing-move" // Suppress clang C++20 warning about moves preventing copy elision on macOS +#endif using namespace olc; // Some local pools to reduce allocations @@ -16282,6 +16366,7 @@ GPUTask olc::Draw::TaskDrawLine(const std::vector& vPoints, const std task.vertexBuffer[i*2+0] = { {vPoints[i].x, vPoints[i].y, 1.0f, 1.0f}, vColours[i], {0, 0}, {0, 0}, {0, 0}, {0, 0} }; task.vertexBuffer[i*2+1] = { {vPoints[i + 1].x, vPoints[i + 1].y, 1.0f, 1.0f}, vColours[i + 1], {0, 0}, {0, 0}, {0, 0}, {0, 0} }; } + task.blendmode = blendMode; task.tint = tint; return task; } @@ -16294,6 +16379,7 @@ GPUTask olc::Draw::TaskDrawPolygon(olc::Structure structure, const std::vectorSetViewport(vViewPos, vViewSize); pRenderer->ClearViewport(config.colClear, true, true); + draw.SetBlendMode(olc::BlendMode::Alpha); + draw.SetCullMode(olc::CullMode::None); draw.ImageRect(GetScreen().flipV(), { 0.0,0.0 }, vViewSize); draw.ProcessGPUTasks(); @@ -18257,6 +18363,8 @@ namespace olc draw.ProcessGPUTasks(); // Set to known default state + draw.SetBlendMode(olc::BlendMode::Alpha); + draw.SetCullMode(olc::CullMode::None); draw.SetTarget(GetScreen()); draw.WorldReset(); gpu->ApplyDefaultShader(); @@ -18629,7 +18737,8 @@ namespace olc fontClassicPGE.glyphs.push_back(glyph); } else - fontClassicPGE.glyphs.push_back(FontGlyph{ fontClassicPGE.imgFont.region({0,0}, {8,8}) , 8.0f, {8.0f, 8.0f} }); + // Added missing vMonoSize for non-printable characters, which was causing -Wmissing-field-initializers + fontClassicPGE.glyphs.push_back(FontGlyph{ fontClassicPGE.imgFont.region({0,0}, {8,8}) , 8.0f, {8.0f, 8.0f}, { 0.0f, 0.0f } }); } fontClassicPGE.fLineHeight = 8.0f; @@ -19303,11 +19412,13 @@ namespace olc::imload bool ImageLoader_MacOS::WriteImageToFile(const olc::Image& image, const std::string& sFileName) { + olc_IgnoreUnused(image, sFileName); return false; } bool ImageLoader_MacOS::WriteImageToMemoryFile(olc::Image& image, const std::vector& data) { + olc_IgnoreUnused(image, data); return false; } }