From efa2bd7837ed0aec38e51ebc9b46caf153112f4f Mon Sep 17 00:00:00 2001 From: Alex Szpakowski Date: Thu, 26 Dec 2019 23:07:51 -0500 Subject: [PATCH] Consolidate some internal graphics state definitions into a new renderstate file. --HG-- branch : minor --- CMakeLists.txt | 4 +- .../xcode/liblove.xcodeproj/project.pbxproj | 18 +- src/common/pixelformat.cpp | 17 +- src/common/pixelformat.h | 23 +- src/modules/graphics/Graphics.cpp | 57 +--- src/modules/graphics/Graphics.h | 66 +---- src/modules/graphics/Texture.h | 2 +- src/modules/graphics/depthstencil.cpp | 103 ------- src/modules/graphics/depthstencil.h | 74 ----- src/modules/graphics/opengl/Canvas.cpp | 2 +- src/modules/graphics/opengl/Graphics.cpp | 91 +++--- src/modules/graphics/opengl/Graphics.h | 2 +- src/modules/graphics/opengl/OpenGL.h | 2 +- src/modules/graphics/renderstate.cpp | 261 ++++++++++++++++++ src/modules/graphics/renderstate.h | 216 +++++++++++++++ src/modules/graphics/wrap_Graphics.cpp | 24 +- 16 files changed, 577 insertions(+), 385 deletions(-) delete mode 100644 src/modules/graphics/depthstencil.cpp delete mode 100644 src/modules/graphics/depthstencil.h create mode 100644 src/modules/graphics/renderstate.cpp create mode 100644 src/modules/graphics/renderstate.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 8611a6acb..ef39444b7 100755 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -520,8 +520,6 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/Buffer.h src/modules/graphics/Canvas.cpp src/modules/graphics/Canvas.h - src/modules/graphics/depthstencil.cpp - src/modules/graphics/depthstencil.h src/modules/graphics/Deprecations.cpp src/modules/graphics/Deprecations.h src/modules/graphics/Drawable.cpp @@ -540,6 +538,8 @@ set(LOVE_SRC_MODULE_GRAPHICS_ROOT src/modules/graphics/Polyline.h src/modules/graphics/Quad.cpp src/modules/graphics/Quad.h + src/modules/graphics/renderstate.cpp + src/modules/graphics/renderstate.h src/modules/graphics/Resource.h src/modules/graphics/Shader.cpp src/modules/graphics/Shader.h diff --git a/platform/xcode/liblove.xcodeproj/project.pbxproj b/platform/xcode/liblove.xcodeproj/project.pbxproj index dfb3d04d2..149d415b2 100644 --- a/platform/xcode/liblove.xcodeproj/project.pbxproj +++ b/platform/xcode/liblove.xcodeproj/project.pbxproj @@ -975,6 +975,9 @@ FAB2D5AA1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AB1AABDD8A008224A4 /* TrueTypeRasterizer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */; }; FAB2D5AC1AABDD8A008224A4 /* TrueTypeRasterizer.h in Headers */ = {isa = PBXBuildFile; fileRef = FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */; }; + FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC271E323B5B5B400C200D3 /* renderstate.h */; }; + FAC271E623B5B5B400C200D3 /* renderstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC271E423B5B5B400C200D3 /* renderstate.cpp */; }; + FAC271E723B5B5B400C200D3 /* renderstate.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC271E423B5B5B400C200D3 /* renderstate.cpp */; }; FAC756F51E4F99B400B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F31E4F99B400B91289 /* Effect.cpp */; }; FAC756F61E4F99B400B91289 /* Effect.h in Headers */ = {isa = PBXBuildFile; fileRef = FAC756F41E4F99B400B91289 /* Effect.h */; }; FAC756F71E4F99BC00B91289 /* Effect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAC756F31E4F99B400B91289 /* Effect.cpp */; }; @@ -1204,8 +1207,6 @@ FAF140DB1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; }; FAF140DC1E20934C00F898D2 /* InitializeDll.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */; }; FAF140DD1E20934C00F898D2 /* InitializeDll.h in Headers */ = {isa = PBXBuildFile; fileRef = FAF1403C1E20934C00F898D2 /* InitializeDll.h */; }; - FAF1889F1E9DBC4B008C1479 /* depthstencil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */; }; - FAF188A01E9DBC4B008C1479 /* depthstencil.cpp in Sources */ = {isa = PBXBuildFile; fileRef = FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */; }; /* End PBXBuildFile section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -1904,6 +1905,8 @@ FAB17BF41ABFC4B100F9BA27 /* lz4hc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4hc.h; sourceTree = ""; }; FAB2D5A81AABDD8A008224A4 /* TrueTypeRasterizer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = TrueTypeRasterizer.cpp; sourceTree = ""; }; FAB2D5A91AABDD8A008224A4 /* TrueTypeRasterizer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = TrueTypeRasterizer.h; sourceTree = ""; }; + FAC271E323B5B5B400C200D3 /* renderstate.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = renderstate.h; sourceTree = ""; }; + FAC271E423B5B5B400C200D3 /* renderstate.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = renderstate.cpp; sourceTree = ""; }; FAC734C11B2E021A00AB460A /* wrap_SoundData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_SoundData.lua; sourceTree = ""; }; FAC734C21B2E628700AB460A /* wrap_ImageData.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_ImageData.lua; sourceTree = ""; }; FAC756F31E4F99B400B91289 /* Effect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Effect.cpp; sourceTree = ""; }; @@ -2057,8 +2060,6 @@ FAF1403B1E20934C00F898D2 /* InitializeDll.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InitializeDll.cpp; sourceTree = ""; }; FAF1403C1E20934C00F898D2 /* InitializeDll.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InitializeDll.h; sourceTree = ""; }; FAF1889C1E9DA834008C1479 /* Optional.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = Optional.h; sourceTree = ""; }; - FAF1889D1E9DBBC8008C1479 /* depthstencil.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = depthstencil.h; sourceTree = ""; }; - FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = depthstencil.cpp; sourceTree = ""; }; FAF949FD21DEE8B7001CD27E /* wrap_Event.lua */ = {isa = PBXFileReference; lastKnownFileType = text; path = wrap_Event.lua; sourceTree = ""; }; /* End PBXFileReference section */ @@ -2781,8 +2782,6 @@ FA1BA0A61E16F20600AA2803 /* Canvas.h */, FA9D53AA1F5307E900125C6B /* Deprecations.cpp */, FA9D53AB1F5307E900125C6B /* Deprecations.h */, - FAF1889E1E9DBC4B008C1479 /* depthstencil.cpp */, - FAF1889D1E9DBBC8008C1479 /* depthstencil.h */, FA9D8DDC1DEF842A002CD881 /* Drawable.cpp */, FA0B7B891A95902C000E1D17 /* Drawable.h */, FA1BA09B1E16CFCE00AA2803 /* Font.cpp */, @@ -2800,6 +2799,8 @@ FA0B7B9C1A95902C000E1D17 /* Polyline.h */, FA0B7BBC1A95902C000E1D17 /* Quad.cpp */, FA0B7BBD1A95902C000E1D17 /* Quad.h */, + FAC271E423B5B5B400C200D3 /* renderstate.cpp */, + FAC271E323B5B5B400C200D3 /* renderstate.h */, FA10DD7B1F9EC24E00E1FE3D /* Resource.h */, FA1BA0AF1E16FD0800AA2803 /* Shader.cpp */, FA1BA0B01E16FD0800AA2803 /* Shader.h */, @@ -3724,6 +3725,7 @@ FA0B7CCF1A95902C000E1D17 /* Audio.h in Headers */, FA0B7EC01A95902C000E1D17 /* Thread.h in Headers */, FA0B7E9C1A95902C000E1D17 /* VorbisDecoder.h in Headers */, + FAC271E523B5B5B400C200D3 /* renderstate.h in Headers */, FAC756FB1E4F99D200B91289 /* Effect.h in Headers */, FAC7CD901FE35E95006A60C7 /* physfs_miniz.h in Headers */, FA0B791D1A958E3B000E1D17 /* b64.h in Headers */, @@ -4300,6 +4302,7 @@ FA0B7E0D1A95902C000E1D17 /* Fixture.cpp in Sources */, FADF53FE1E3D74F200012CC0 /* Text.cpp in Sources */, FA0B7D191A95902C000E1D17 /* TrueTypeRasterizer.cpp in Sources */, + FAC271E723B5B5B400C200D3 /* renderstate.cpp in Sources */, FA0B7CFB1A95902C000E1D17 /* Filesystem.cpp in Sources */, FA0B7D3D1A95902C000E1D17 /* Image.cpp in Sources */, FA0B7B351A958EA3000E1D17 /* wuff_convert.c in Sources */, @@ -4402,7 +4405,6 @@ FA0B7A2A1A958EA3000E1D17 /* b2BroadPhase.cpp in Sources */, FA0A3A6123366CE9001C269E /* floattypes.cpp in Sources */, FA0B7A811A958EA3000E1D17 /* b2EdgeAndCircleContact.cpp in Sources */, - FAF188A01E9DBC4B008C1479 /* depthstencil.cpp in Sources */, FA0B7D071A95902C000E1D17 /* wrap_File.cpp in Sources */, FA6A2B751F60B6710074C308 /* ByteData.cpp in Sources */, FAD19A181DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, @@ -4623,6 +4625,7 @@ FA0B7ECB1A95902C000E1D17 /* wrap_Channel.cpp in Sources */, FACA02F21F5E396B0084B28F /* HashFunction.cpp in Sources */, FAF140A71E20934C00F898D2 /* ShaderLang.cpp in Sources */, + FAC271E623B5B5B400C200D3 /* renderstate.cpp in Sources */, FA1BA09D1E16CFCE00AA2803 /* Font.cpp in Sources */, FA0B7E6C1A95902C000E1D17 /* wrap_RevoluteJoint.cpp in Sources */, FA0B7A5E1A958EA3000E1D17 /* b2Body.cpp in Sources */, @@ -4797,7 +4800,6 @@ FA0B7DDC1A95902C000E1D17 /* wrap_BezierCurve.cpp in Sources */, FA0B7A951A958EA3000E1D17 /* b2Joint.cpp in Sources */, FA0B7D061A95902C000E1D17 /* wrap_File.cpp in Sources */, - FAF1889F1E9DBC4B008C1479 /* depthstencil.cpp in Sources */, FAC7CD871FE35E95006A60C7 /* physfs_archiver_vdf.c in Sources */, FA0B7A4E1A958EA3000E1D17 /* b2Draw.cpp in Sources */, FAD19A171DFF8CA200D5398A /* ImageDataBase.cpp in Sources */, diff --git a/src/common/pixelformat.cpp b/src/common/pixelformat.cpp index 2fedae672..97175191f 100644 --- a/src/common/pixelformat.cpp +++ b/src/common/pixelformat.cpp @@ -32,21 +32,22 @@ static StringMap::Entry formatEntries[] = { "hdr", PIXELFORMAT_HDR }, { "r8", PIXELFORMAT_R8_UNORM }, + { "r16", PIXELFORMAT_R16_UNORM }, + { "r16f", PIXELFORMAT_R16_FLOAT }, + { "r32f", PIXELFORMAT_R32_FLOAT }, + { "rg8", PIXELFORMAT_RG8_UNORM }, + { "la8", PIXELFORMAT_LA8_UNORM }, + { "rg16", PIXELFORMAT_RG16_UNORM }, + { "rg16f", PIXELFORMAT_RG16_FLOAT }, + { "rg32f", PIXELFORMAT_RG32_FLOAT }, + { "rgba8", PIXELFORMAT_RGBA8_UNORM }, { "srgba8", PIXELFORMAT_sRGBA8_UNORM }, - { "r16", PIXELFORMAT_R16_UNORM }, - { "rg16", PIXELFORMAT_RG16_UNORM }, { "rgba16", PIXELFORMAT_RGBA16_UNORM }, - { "r16f", PIXELFORMAT_R16_FLOAT }, - { "rg16f", PIXELFORMAT_RG16_FLOAT }, { "rgba16f", PIXELFORMAT_RGBA16_FLOAT }, - { "r32f", PIXELFORMAT_R32_FLOAT }, - { "rg32f", PIXELFORMAT_RG32_FLOAT }, { "rgba32f", PIXELFORMAT_RGBA32_FLOAT }, - { "la8", PIXELFORMAT_LA8_UNORM }, - { "rgba4", PIXELFORMAT_RGBA4_UNORM }, { "rgb5a1", PIXELFORMAT_RGB5A1_UNORM }, { "rgb565", PIXELFORMAT_RGB565_UNORM }, diff --git a/src/common/pixelformat.h b/src/common/pixelformat.h index 0f922c7aa..fd49c1aa4 100644 --- a/src/common/pixelformat.h +++ b/src/common/pixelformat.h @@ -33,29 +33,32 @@ enum PixelFormat PIXELFORMAT_NORMAL, PIXELFORMAT_HDR, - // "regular" formats + // 1-channel normal formats PIXELFORMAT_R8_UNORM, + PIXELFORMAT_R16_UNORM, + PIXELFORMAT_R16_FLOAT, + PIXELFORMAT_R32_FLOAT, + + // 2-channel normal formats PIXELFORMAT_RG8_UNORM, + PIXELFORMAT_LA8_UNORM, // Same as RG8, but accessed as (L, L, L, A) + PIXELFORMAT_RG16_UNORM, + PIXELFORMAT_RG16_FLOAT, + PIXELFORMAT_RG32_FLOAT, + + // 4-channel normal formats PIXELFORMAT_RGBA8_UNORM, PIXELFORMAT_sRGBA8_UNORM, - PIXELFORMAT_R16_UNORM, - PIXELFORMAT_RG16_UNORM, PIXELFORMAT_RGBA16_UNORM, - PIXELFORMAT_R16_FLOAT, - PIXELFORMAT_RG16_FLOAT, PIXELFORMAT_RGBA16_FLOAT, - PIXELFORMAT_R32_FLOAT, - PIXELFORMAT_RG32_FLOAT, PIXELFORMAT_RGBA32_FLOAT, - PIXELFORMAT_LA8_UNORM, // Same as RG8, but accessed as (L, L, L, A) - // packed formats PIXELFORMAT_RGBA4_UNORM, // LSB->MSB: [a, b, g, r] PIXELFORMAT_RGB5A1_UNORM, // LSB->MSB: [a, b, g, r] PIXELFORMAT_RGB565_UNORM, // LSB->MSB: [b, g, r] PIXELFORMAT_RGB10A2_UNORM, // LSB->MSB: [r, g, b, a] - PIXELFORMAT_RG11B10_FLOAT, // LSB->MSB: [r, g, b] + PIXELFORMAT_RG11B10_FLOAT, // LSB->MSB: [r, g, b] // depth/stencil formats PIXELFORMAT_STENCIL8, diff --git a/src/modules/graphics/Graphics.cpp b/src/modules/graphics/Graphics.cpp index 84a10ece4..ed8463388 100644 --- a/src/modules/graphics/Graphics.cpp +++ b/src/modules/graphics/Graphics.cpp @@ -896,12 +896,12 @@ vertex::Winding Graphics::getFrontFaceWinding() const return states.back().winding; } -Graphics::ColorMask Graphics::getColorMask() const +ColorChannelMask Graphics::getColorMask() const { return states.back().colorMask; } -Graphics::BlendMode Graphics::getBlendMode(BlendAlpha &alphamode) const +BlendMode Graphics::getBlendMode(BlendAlpha &alphamode) const { alphamode = states.back().blendAlphaMode; return states.back().blendMode; @@ -1778,36 +1778,6 @@ std::vector Graphics::getConstants(ArcMode) return arcModes.getNames(); } -bool Graphics::getConstant(const char *in, BlendMode &out) -{ - return blendModes.find(in, out); -} - -bool Graphics::getConstant(BlendMode in, const char *&out) -{ - return blendModes.find(in, out); -} - -std::vector Graphics::getConstants(BlendMode) -{ - return blendModes.getNames(); -} - -bool Graphics::getConstant(const char *in, BlendAlpha &out) -{ - return blendAlphaModes.find(in, out); -} - -bool Graphics::getConstant(BlendAlpha in, const char *&out) -{ - return blendAlphaModes.find(in, out); -} - -std::vector Graphics::getConstants(BlendAlpha) -{ - return blendAlphaModes.getNames(); -} - bool Graphics::getConstant(const char *in, LineStyle &out) { return lineStyles.find(in, out); @@ -1890,29 +1860,6 @@ StringMap::Entry Graphics::arcModeEnt StringMap Graphics::arcModes(Graphics::arcModeEntries, sizeof(Graphics::arcModeEntries)); -StringMap::Entry Graphics::blendModeEntries[] = -{ - { "alpha", BLEND_ALPHA }, - { "add", BLEND_ADD }, - { "subtract", BLEND_SUBTRACT }, - { "multiply", BLEND_MULTIPLY }, - { "lighten", BLEND_LIGHTEN }, - { "darken", BLEND_DARKEN }, - { "screen", BLEND_SCREEN }, - { "replace", BLEND_REPLACE }, - { "none", BLEND_NONE }, -}; - -StringMap Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries)); - -StringMap::Entry Graphics::blendAlphaEntries[] = -{ - { "alphamultiply", BLENDALPHA_MULTIPLY }, - { "premultiplied", BLENDALPHA_PREMULTIPLIED }, -}; - -StringMap Graphics::blendAlphaModes(Graphics::blendAlphaEntries, sizeof(Graphics::blendAlphaEntries)); - StringMap::Entry Graphics::lineStyleEntries[] = { { "smooth", LINE_SMOOTH }, diff --git a/src/modules/graphics/Graphics.h b/src/modules/graphics/Graphics.h index b43d30ad7..80befd39d 100644 --- a/src/modules/graphics/Graphics.h +++ b/src/modules/graphics/Graphics.h @@ -40,7 +40,7 @@ #include "Mesh.h" #include "Image.h" #include "Deprecations.h" -#include "depthstencil.h" +#include "renderstate.h" #include "math/Transform.h" #include "font/Rasterizer.h" #include "font/Font.h" @@ -118,27 +118,6 @@ public: ARC_MAX_ENUM }; - enum BlendMode - { - BLEND_ALPHA, - BLEND_ADD, - BLEND_SUBTRACT, - BLEND_MULTIPLY, - BLEND_LIGHTEN, - BLEND_DARKEN, - BLEND_SCREEN, - BLEND_REPLACE, - BLEND_NONE, - BLEND_MAX_ENUM - }; - - enum BlendAlpha - { - BLENDALPHA_MULTIPLY, - BLENDALPHA_PREMULTIPLIED, - BLENDALPHA_MAX_ENUM - }; - enum LineStyle { LINE_ROUGH, @@ -228,29 +207,6 @@ public: int64 textureMemory; }; - struct ColorMask - { - bool r, g, b, a; - - ColorMask() - : r(true), g(true), b(true), a(true) - {} - - ColorMask(bool _r, bool _g, bool _b, bool _a) - : r(_r), g(_g), b(_b), a(_a) - {} - - bool operator == (const ColorMask &m) const - { - return r == m.r && g == m.g && b == m.b && a == m.a; - } - - bool operator != (const ColorMask &m) const - { - return !(operator == (m)); - } - }; - struct DrawCommand { PrimitiveType primitiveType = PRIMITIVE_TRIANGLES; @@ -643,12 +599,12 @@ public: /** * Sets the enabled color components when rendering. **/ - virtual void setColorMask(ColorMask mask) = 0; + virtual void setColorMask(ColorChannelMask mask) = 0; /** * Gets the current color mask. **/ - ColorMask getColorMask() const; + ColorChannelMask getColorMask() const; /** * Sets the current blend mode. @@ -902,14 +858,6 @@ public: static bool getConstant(ArcMode in, const char *&out); static std::vector getConstants(ArcMode); - static bool getConstant(const char *in, BlendMode &out); - static bool getConstant(BlendMode in, const char *&out); - static std::vector getConstants(BlendMode); - - static bool getConstant(const char *in, BlendAlpha &out); - static bool getConstant(BlendAlpha in, const char *&out); - static std::vector getConstants(BlendAlpha); - static bool getConstant(const char *in, LineStyle &out); static bool getConstant(LineStyle in, const char *&out); static std::vector getConstants(LineStyle); @@ -964,7 +912,7 @@ protected: RenderTargetsStrongRef renderTargets; - ColorMask colorMask = ColorMask(true, true, true, true); + ColorChannelMask colorMask; bool wireframe = false; @@ -1082,12 +1030,6 @@ private: static StringMap::Entry arcModeEntries[]; static StringMap arcModes; - static StringMap::Entry blendModeEntries[]; - static StringMap blendModes; - - static StringMap::Entry blendAlphaEntries[]; - static StringMap blendAlphaModes; - static StringMap::Entry lineStyleEntries[]; static StringMap lineStyles; diff --git a/src/modules/graphics/Texture.h b/src/modules/graphics/Texture.h index 34606bca9..74162d59e 100644 --- a/src/modules/graphics/Texture.h +++ b/src/modules/graphics/Texture.h @@ -31,7 +31,7 @@ #include "Drawable.h" #include "Quad.h" #include "vertex.h" -#include "depthstencil.h" +#include "renderstate.h" #include "Resource.h" // C diff --git a/src/modules/graphics/depthstencil.cpp b/src/modules/graphics/depthstencil.cpp deleted file mode 100644 index 27fde28f9..000000000 --- a/src/modules/graphics/depthstencil.cpp +++ /dev/null @@ -1,103 +0,0 @@ -/** - * Copyright (c) 2006-2019 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#include "depthstencil.h" -#include "common/StringMap.h" - -namespace love -{ -namespace graphics -{ - -CompareMode getReversedCompareMode(CompareMode mode) -{ - switch (mode) - { - case COMPARE_LESS: - return COMPARE_GREATER; - case COMPARE_LEQUAL: - return COMPARE_GEQUAL; - case COMPARE_GEQUAL: - return COMPARE_LEQUAL; - case COMPARE_GREATER: - return COMPARE_LESS; - default: - return mode; - } -} - -static StringMap::Entry stencilActionEntries[] = -{ - { "replace", STENCIL_REPLACE }, - { "increment", STENCIL_INCREMENT }, - { "decrement", STENCIL_DECREMENT }, - { "incrementwrap", STENCIL_INCREMENT_WRAP }, - { "decrementwrap", STENCIL_DECREMENT_WRAP }, - { "invert", STENCIL_INVERT }, -}; - -static StringMap stencilActions(stencilActionEntries, sizeof(stencilActionEntries)); - -static StringMap::Entry compareModeEntries[] = -{ - { "less", COMPARE_LESS }, - { "lequal", COMPARE_LEQUAL }, - { "equal", COMPARE_EQUAL }, - { "gequal", COMPARE_GEQUAL }, - { "greater", COMPARE_GREATER }, - { "notequal", COMPARE_NOTEQUAL }, - { "always", COMPARE_ALWAYS }, - { "never", COMPARE_NEVER }, -}; - -static StringMap compareModes(compareModeEntries, sizeof(compareModeEntries)); - -bool getConstant(const char *in, StencilAction &out) -{ - return stencilActions.find(in, out); -} - -bool getConstant(StencilAction in, const char *&out) -{ - return stencilActions.find(in, out); -} - -std::vector getConstants(StencilAction) -{ - return stencilActions.getNames(); -} - -bool getConstant(const char *in, CompareMode &out) -{ - return compareModes.find(in, out); -} - -bool getConstant(CompareMode in, const char *&out) -{ - return compareModes.find(in, out); -} - -std::vector getConstants(CompareMode) -{ - return compareModes.getNames(); -} - -} // graphics -} // love diff --git a/src/modules/graphics/depthstencil.h b/src/modules/graphics/depthstencil.h deleted file mode 100644 index 66b18738a..000000000 --- a/src/modules/graphics/depthstencil.h +++ /dev/null @@ -1,74 +0,0 @@ -/** - * Copyright (c) 2006-2019 LOVE Development Team - * - * This software is provided 'as-is', without any express or implied - * warranty. In no event will the authors be held liable for any damages - * arising from the use of this software. - * - * Permission is granted to anyone to use this software for any purpose, - * including commercial applications, and to alter it and redistribute it - * freely, subject to the following restrictions: - * - * 1. The origin of this software must not be misrepresented; you must not - * claim that you wrote the original software. If you use this software - * in a product, an acknowledgment in the product documentation would be - * appreciated but is not required. - * 2. Altered source versions must be plainly marked as such, and must not be - * misrepresented as being the original software. - * 3. This notice may not be removed or altered from any source distribution. - **/ - -#pragma once - -#include -#include - -namespace love -{ -namespace graphics -{ - -enum StencilAction -{ - STENCIL_REPLACE, - STENCIL_INCREMENT, - STENCIL_DECREMENT, - STENCIL_INCREMENT_WRAP, - STENCIL_DECREMENT_WRAP, - STENCIL_INVERT, - STENCIL_MAX_ENUM -}; - -enum CompareMode -{ - COMPARE_LESS, - COMPARE_LEQUAL, - COMPARE_EQUAL, - COMPARE_GEQUAL, - COMPARE_GREATER, - COMPARE_NOTEQUAL, - COMPARE_ALWAYS, - COMPARE_NEVER, - COMPARE_MAX_ENUM -}; - -/** - * GPU APIs do the comparison in the opposite way of what makes sense for some - * of love's APIs. For example in OpenGL if the compare function is GL_GREATER, - * then the stencil test will pass if the reference value is greater than the - * value in the stencil buffer. With our stencil API it's more intuitive to - * assume that setStencilTest(COMPARE_GREATER, 4) will make it pass if the - * stencil buffer has a value greater than 4. - **/ -CompareMode getReversedCompareMode(CompareMode mode); - -bool getConstant(const char *in, StencilAction &out); -bool getConstant(StencilAction in, const char *&out); -std::vector getConstants(StencilAction); - -bool getConstant(const char *in, CompareMode &out); -bool getConstant(CompareMode in, const char *&out); -std::vector getConstants(CompareMode); - -} // graphics -} // love diff --git a/src/modules/graphics/opengl/Canvas.cpp b/src/modules/graphics/opengl/Canvas.cpp index e0501784f..81d379bb2 100644 --- a/src/modules/graphics/opengl/Canvas.cpp +++ b/src/modules/graphics/opengl/Canvas.cpp @@ -407,7 +407,7 @@ void Canvas::setDepthSampleMode(Optional mode) gl.bindTextureToUnit(texType, texture, 0, false); GLenum gltextype = OpenGL::getGLTextureType(texType); - // See the comment in depthstencil.h + // See the comment in renderstate.h GLenum glmode = OpenGL::getGLCompareMode(getReversedCompareMode(mode.value)); glTexParameteri(gltextype, GL_TEXTURE_COMPARE_MODE, GL_COMPARE_REF_TO_TEXTURE); diff --git a/src/modules/graphics/opengl/Graphics.cpp b/src/modules/graphics/opengl/Graphics.cpp index ca12c815a..afe98f460 100644 --- a/src/modules/graphics/opengl/Graphics.cpp +++ b/src/modules/graphics/opengl/Graphics.cpp @@ -54,6 +54,40 @@ namespace graphics namespace opengl { +static GLenum getGLBlendOperation(BlendOperation op) +{ + switch (op) + { + case BLENDOP_ADD: return GL_FUNC_ADD; + case BLENDOP_SUBTRACT: return GL_FUNC_SUBTRACT; + case BLENDOP_REVERSE_SUBTRACT: return GL_FUNC_REVERSE_SUBTRACT; + case BLENDOP_MIN: return GL_MIN; + case BLENDOP_MAX: return GL_MAX; + case BLENDOP_MAX_ENUM: return 0; + } + return 0; +} + +static GLenum getGLBlendFactor(BlendFactor factor) +{ + switch (factor) + { + case BLENDFACTOR_ZERO: return GL_ZERO; + case BLENDFACTOR_ONE: return GL_ONE; + case BLENDFACTOR_SRC_COLOR: return GL_SRC_COLOR; + case BLENDFACTOR_ONE_MINUS_SRC_COLOR: return GL_ONE_MINUS_SRC_COLOR; + case BLENDFACTOR_SRC_ALPHA: return GL_SRC_ALPHA; + case BLENDFACTOR_ONE_MINUS_SRC_ALPHA: return GL_ONE_MINUS_SRC_ALPHA; + case BLENDFACTOR_DST_COLOR: return GL_DST_COLOR; + case BLENDFACTOR_ONE_MINUS_DST_COLOR: return GL_ONE_MINUS_DST_COLOR; + case BLENDFACTOR_DST_ALPHA: return GL_DST_ALPHA; + case BLENDFACTOR_ONE_MINUS_DST_ALPHA: return GL_ONE_MINUS_DST_ALPHA; + case BLENDFACTOR_SRC_ALPHA_SATURATED: return GL_SRC_ALPHA_SATURATE; + case BLENDFACTOR_MAX_ENUM: return 0; + } + return 0; +} + Graphics::Graphics() : windowHasStencil(false) , mainVAO(0) @@ -1226,7 +1260,7 @@ void Graphics::setColor(Colorf c) states.back().color = c; } -void Graphics::setColorMask(ColorMask mask) +void Graphics::setColorMask(ColorChannelMask mask) { flushStreamDraws(); @@ -1253,7 +1287,7 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode) case BLEND_LIGHTEN: case BLEND_DARKEN: case BLEND_MULTIPLY: - getConstant(mode, modestr); + love::graphics::getConstant(mode, modestr); throw love::Exception("The '%s' blend mode must be used with premultiplied alpha.", modestr); break; default: @@ -1261,52 +1295,15 @@ void Graphics::setBlendMode(BlendMode mode, BlendAlpha alphamode) } } - GLenum func = GL_FUNC_ADD; - GLenum srcRGB = GL_ONE; - GLenum srcA = GL_ONE; - GLenum dstRGB = GL_ZERO; - GLenum dstA = GL_ZERO; + BlendState state = getBlendState(mode, alphamode); + GLenum opRGB = getGLBlendOperation(state.operationRGB); + GLenum opA = getGLBlendOperation(state.operationA); + GLenum srcRGB = getGLBlendFactor(state.srcFactorRGB); + GLenum srcA = getGLBlendFactor(state.srcFactorA); + GLenum dstRGB = getGLBlendFactor(state.dstFactorRGB); + GLenum dstA = getGLBlendFactor(state.dstFactorA); - switch (mode) - { - case BLEND_ALPHA: - srcRGB = srcA = GL_ONE; - dstRGB = dstA = GL_ONE_MINUS_SRC_ALPHA; - break; - case BLEND_MULTIPLY: - srcRGB = srcA = GL_DST_COLOR; - dstRGB = dstA = GL_ZERO; - break; - case BLEND_SUBTRACT: - func = GL_FUNC_REVERSE_SUBTRACT; - case BLEND_ADD: - srcRGB = GL_ONE; - srcA = GL_ZERO; - dstRGB = dstA = GL_ONE; - break; - case BLEND_LIGHTEN: - func = GL_MAX; - break; - case BLEND_DARKEN: - func = GL_MIN; - break; - case BLEND_SCREEN: - srcRGB = srcA = GL_ONE; - dstRGB = dstA = GL_ONE_MINUS_SRC_COLOR; - break; - case BLEND_REPLACE: - case BLEND_NONE: - default: - srcRGB = srcA = GL_ONE; - dstRGB = dstA = GL_ZERO; - break; - } - - // We can only do alpha-multiplication when srcRGB would have been unmodified. - if (srcRGB == GL_ONE && alphamode == BLENDALPHA_MULTIPLY && mode != BLEND_NONE) - srcRGB = GL_SRC_ALPHA; - - glBlendEquation(func); + glBlendEquationSeparate(opRGB, opA); glBlendFuncSeparate(srcRGB, dstRGB, srcA, dstA); states.back().blendMode = mode; diff --git a/src/modules/graphics/opengl/Graphics.h b/src/modules/graphics/opengl/Graphics.h index 272dd5219..1bbf182ff 100644 --- a/src/modules/graphics/opengl/Graphics.h +++ b/src/modules/graphics/opengl/Graphics.h @@ -96,7 +96,7 @@ public: void setFrontFaceWinding(vertex::Winding winding) override; - void setColorMask(ColorMask mask) override; + void setColorMask(ColorChannelMask mask) override; void setBlendMode(BlendMode mode, BlendAlpha alphamode) override; diff --git a/src/modules/graphics/opengl/OpenGL.h b/src/modules/graphics/opengl/OpenGL.h index 7b99bc99b..1037dd9e7 100644 --- a/src/modules/graphics/opengl/OpenGL.h +++ b/src/modules/graphics/opengl/OpenGL.h @@ -28,7 +28,7 @@ #include "common/Color.h" #include "graphics/Texture.h" #include "graphics/vertex.h" -#include "graphics/depthstencil.h" +#include "graphics/renderstate.h" #include "common/Matrix.h" // GLAD diff --git a/src/modules/graphics/renderstate.cpp b/src/modules/graphics/renderstate.cpp new file mode 100644 index 000000000..989c285d0 --- /dev/null +++ b/src/modules/graphics/renderstate.cpp @@ -0,0 +1,261 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#include "renderstate.h" +#include "common/StringMap.h" + +namespace love +{ +namespace graphics +{ + +BlendState getBlendState(BlendMode mode, BlendAlpha alphamode) +{ + BlendState s; + + s.enable = mode != BLEND_NONE; + s.operationRGB = BLENDOP_ADD; + s.operationA = BLENDOP_ADD; + + switch (mode) + { + case BLEND_ALPHA: + s.srcFactorRGB = s.srcFactorA = BLENDFACTOR_ONE; + s.dstFactorRGB = s.dstFactorA = BLENDFACTOR_ONE_MINUS_SRC_ALPHA; + break; + case BLEND_MULTIPLY: + s.srcFactorRGB = s.srcFactorA = BLENDFACTOR_DST_COLOR; + s.dstFactorRGB = s.dstFactorA = BLENDFACTOR_ZERO; + break; + case BLEND_SUBTRACT: + s.operationRGB = s.operationA = BLENDOP_REVERSE_SUBTRACT; + case BLEND_ADD: + s.srcFactorRGB = BLENDFACTOR_ONE; + s.srcFactorA = BLENDFACTOR_ZERO; + s.dstFactorRGB = s.dstFactorA = BLENDFACTOR_ONE; + break; + case BLEND_LIGHTEN: + s.operationRGB = s.operationA = BLENDOP_MAX; + break; + case BLEND_DARKEN: + s.operationRGB = s.operationA = BLENDOP_MIN; + break; + case BLEND_SCREEN: + s.srcFactorRGB = s.srcFactorA = BLENDFACTOR_ONE; + s.dstFactorRGB = s.dstFactorA = BLENDFACTOR_ONE_MINUS_SRC_COLOR; + break; + case BLEND_REPLACE: + case BLEND_NONE: + default: + s.srcFactorRGB = s.srcFactorA = BLENDFACTOR_ONE; + s.dstFactorRGB = s.dstFactorA = BLENDFACTOR_ZERO; + break; + } + + // We can only do alpha-multiplication when srcRGB would have been unmodified. + if (s.srcFactorRGB == BLENDFACTOR_ONE && alphamode == BLENDALPHA_MULTIPLY && mode != BLEND_NONE) + s.srcFactorRGB = BLENDFACTOR_SRC_ALPHA; + + return s; +} + +CompareMode getReversedCompareMode(CompareMode mode) +{ + switch (mode) + { + case COMPARE_LESS: return COMPARE_GREATER; + case COMPARE_LEQUAL: return COMPARE_GEQUAL; + case COMPARE_GEQUAL: return COMPARE_LEQUAL; + case COMPARE_GREATER: return COMPARE_LESS; + default: return mode; + } +} + +static StringMap::Entry blendModeEntries[] = +{ + { "alpha", BLEND_ALPHA }, + { "add", BLEND_ADD }, + { "subtract", BLEND_SUBTRACT }, + { "multiply", BLEND_MULTIPLY }, + { "lighten", BLEND_LIGHTEN }, + { "darken", BLEND_DARKEN }, + { "screen", BLEND_SCREEN }, + { "replace", BLEND_REPLACE }, + { "none", BLEND_NONE }, +}; + +static StringMap blendModes(blendModeEntries, sizeof(blendModeEntries)); + +static StringMap::Entry blendAlphaEntries[] = +{ + { "alphamultiply", BLENDALPHA_MULTIPLY }, + { "premultiplied", BLENDALPHA_PREMULTIPLIED }, +}; + +static StringMap blendAlphaModes(blendAlphaEntries, sizeof(blendAlphaEntries)); + +static StringMap::Entry blendFactorEntries[] = +{ + { "zero", BLENDFACTOR_ZERO }, + { "one", BLENDFACTOR_ONE }, + { "srccolor", BLENDFACTOR_SRC_COLOR }, + { "oneminussrccolor", BLENDFACTOR_ONE_MINUS_SRC_COLOR }, + { "srcalpha", BLENDFACTOR_SRC_ALPHA }, + { "oneminussrcalpha", BLENDFACTOR_ONE_MINUS_SRC_ALPHA }, + { "dstcolor", BLENDFACTOR_DST_COLOR }, + { "oneminusdstcolor", BLENDFACTOR_ONE_MINUS_DST_COLOR }, + { "dstalpha", BLENDFACTOR_DST_ALPHA }, + { "oneminusdstalpha", BLENDFACTOR_ONE_MINUS_DST_ALPHA }, + { "srcalphasaturated", BLENDFACTOR_SRC_ALPHA_SATURATED }, +}; + +static StringMap blendFactors(blendFactorEntries, sizeof(blendFactorEntries)); + +static StringMap::Entry blendOperationEntries[] = +{ + { "add", BLENDOP_ADD }, + { "subtract", BLENDOP_SUBTRACT }, + { "reversesubtract", BLENDOP_REVERSE_SUBTRACT }, + { "min", BLENDOP_MIN }, + { "max", BLENDOP_MAX }, +}; + +static StringMap blendOperations(blendOperationEntries, sizeof(blendOperationEntries)); + +static StringMap::Entry stencilActionEntries[] = +{ + { "keep", STENCIL_KEEP }, + { "zero", STENCIL_ZERO }, + { "replace", STENCIL_REPLACE }, + { "increment", STENCIL_INCREMENT }, + { "decrement", STENCIL_DECREMENT }, + { "incrementwrap", STENCIL_INCREMENT_WRAP }, + { "decrementwrap", STENCIL_DECREMENT_WRAP }, + { "invert", STENCIL_INVERT }, +}; + +static StringMap stencilActions(stencilActionEntries, sizeof(stencilActionEntries)); + +static StringMap::Entry compareModeEntries[] = +{ + { "less", COMPARE_LESS }, + { "lequal", COMPARE_LEQUAL }, + { "equal", COMPARE_EQUAL }, + { "gequal", COMPARE_GEQUAL }, + { "greater", COMPARE_GREATER }, + { "notequal", COMPARE_NOTEQUAL }, + { "always", COMPARE_ALWAYS }, + { "never", COMPARE_NEVER }, +}; + +static StringMap compareModes(compareModeEntries, sizeof(compareModeEntries)); + +bool getConstant(const char *in, BlendMode &out) +{ + return blendModes.find(in, out); +} + +bool getConstant(BlendMode in, const char *&out) +{ + return blendModes.find(in, out); +} + +std::vector getConstants(BlendMode) +{ + return blendModes.getNames(); +} + +bool getConstant(const char *in, BlendAlpha &out) +{ + return blendAlphaModes.find(in, out); +} + +bool getConstant(BlendAlpha in, const char *&out) +{ + return blendAlphaModes.find(in, out); +} + +std::vector getConstants(BlendAlpha) +{ + return blendAlphaModes.getNames(); +} + +bool getConstant(const char *in, BlendFactor &out) +{ + return blendFactors.find(in, out); +} + +bool getConstant(BlendFactor in, const char *&out) +{ + return blendFactors.find(in, out); +} + +std::vector getConstants(BlendFactor) +{ + return blendFactors.getNames(); +} + +bool getConstant(const char *in, BlendOperation &out) +{ + return blendOperations.find(in, out); +} + +bool getConstant(BlendOperation in, const char *&out) +{ + return blendOperations.find(in, out); +} + +std::vector getConstants(BlendOperation) +{ + return blendOperations.getNames(); +} + +bool getConstant(const char *in, StencilAction &out) +{ + return stencilActions.find(in, out); +} + +bool getConstant(StencilAction in, const char *&out) +{ + return stencilActions.find(in, out); +} + +std::vector getConstants(StencilAction) +{ + return stencilActions.getNames(); +} + +bool getConstant(const char *in, CompareMode &out) +{ + return compareModes.find(in, out); +} + +bool getConstant(CompareMode in, const char *&out) +{ + return compareModes.find(in, out); +} + +std::vector getConstants(CompareMode) +{ + return compareModes.getNames(); +} + +} // graphics +} // love diff --git a/src/modules/graphics/renderstate.h b/src/modules/graphics/renderstate.h new file mode 100644 index 000000000..b5898ce2b --- /dev/null +++ b/src/modules/graphics/renderstate.h @@ -0,0 +1,216 @@ +/** + * Copyright (c) 2006-2019 LOVE Development Team + * + * This software is provided 'as-is', without any express or implied + * warranty. In no event will the authors be held liable for any damages + * arising from the use of this software. + * + * Permission is granted to anyone to use this software for any purpose, + * including commercial applications, and to alter it and redistribute it + * freely, subject to the following restrictions: + * + * 1. The origin of this software must not be misrepresented; you must not + * claim that you wrote the original software. If you use this software + * in a product, an acknowledgment in the product documentation would be + * appreciated but is not required. + * 2. Altered source versions must be plainly marked as such, and must not be + * misrepresented as being the original software. + * 3. This notice may not be removed or altered from any source distribution. + **/ + +#pragma once + +#include "common/int.h" +#include "common/math.h" +#include "vertex.h" + +#include +#include + +namespace love +{ +namespace graphics +{ + +class Shader; + +enum BlendMode // High level wrappers +{ + BLEND_ALPHA, + BLEND_ADD, + BLEND_SUBTRACT, + BLEND_MULTIPLY, + BLEND_LIGHTEN, + BLEND_DARKEN, + BLEND_SCREEN, + BLEND_REPLACE, + BLEND_NONE, + BLEND_MAX_ENUM +}; + +enum BlendAlpha // High level wrappers +{ + BLENDALPHA_MULTIPLY, + BLENDALPHA_PREMULTIPLIED, + BLENDALPHA_MAX_ENUM +}; + +enum BlendFactor +{ + BLENDFACTOR_ZERO, + BLENDFACTOR_ONE, + BLENDFACTOR_SRC_COLOR, + BLENDFACTOR_ONE_MINUS_SRC_COLOR, + BLENDFACTOR_SRC_ALPHA, + BLENDFACTOR_ONE_MINUS_SRC_ALPHA, + BLENDFACTOR_DST_COLOR, + BLENDFACTOR_ONE_MINUS_DST_COLOR, + BLENDFACTOR_DST_ALPHA, + BLENDFACTOR_ONE_MINUS_DST_ALPHA, + BLENDFACTOR_SRC_ALPHA_SATURATED, + BLENDFACTOR_MAX_ENUM +}; + +enum BlendOperation +{ + BLENDOP_ADD, + BLENDOP_SUBTRACT, + BLENDOP_REVERSE_SUBTRACT, + BLENDOP_MIN, + BLENDOP_MAX, + BLENDOP_MAX_ENUM +}; + +enum StencilAction +{ + STENCIL_KEEP, + STENCIL_ZERO, + STENCIL_REPLACE, + STENCIL_INCREMENT, + STENCIL_DECREMENT, + STENCIL_INCREMENT_WRAP, + STENCIL_DECREMENT_WRAP, + STENCIL_INVERT, + STENCIL_MAX_ENUM +}; + +enum CompareMode +{ + COMPARE_LESS, + COMPARE_LEQUAL, + COMPARE_EQUAL, + COMPARE_GEQUAL, + COMPARE_GREATER, + COMPARE_NOTEQUAL, + COMPARE_ALWAYS, + COMPARE_NEVER, + COMPARE_MAX_ENUM +}; + +struct BlendState +{ + bool enable = false; + BlendOperation operationRGB = BLENDOP_ADD; + BlendOperation operationA = BLENDOP_ADD; + BlendFactor srcFactorRGB = BLENDFACTOR_ONE; + BlendFactor srcFactorA = BLENDFACTOR_ONE; + BlendFactor dstFactorRGB = BLENDFACTOR_ZERO; + BlendFactor dstFactorA = BLENDFACTOR_ZERO; + + bool operator == (const BlendState &b) const + { + return enable == b.enable + && operationRGB == b.operationRGB && operationA == b.operationA + && srcFactorRGB == b.srcFactorRGB && srcFactorA == b.srcFactorA + && dstFactorRGB == b.dstFactorRGB && dstFactorA == b.dstFactorA; + } +}; + +struct DepthState +{ + CompareMode compare = COMPARE_ALWAYS; + bool write = false; + + bool operator == (const DepthState &d) const + { + return compare == d.compare && write == d.write; + } +}; + +struct StencilState +{ + CompareMode compare = COMPARE_ALWAYS; + StencilAction action = STENCIL_KEEP; + int value = 0; + uint32 readMask = 0xFFFFFFFF; + uint32 writeMask = 0xFFFFFFFF; + + bool operator == (const StencilState &s) const + { + return compare == s.compare && action == s.action && value == s.value + && readMask == s.readMask && writeMask == s.writeMask; + } +}; + +struct ColorChannelMask +{ + bool r = true; + bool g = true; + bool b = true; + bool a = true; + + bool operator == (ColorChannelMask c) const + { + return r == c.r && g == c.g && b == c.b && a == c.a; + } + + bool operator != (ColorChannelMask c) const + { + return !(operator==(c)); + } +}; + +struct ScissorState +{ + Rect rect = {0, 0, 0, 0}; + bool enable = false; +}; + +BlendState getBlendState(BlendMode mode, BlendAlpha alphamode); + +/** + * GPU APIs do the comparison in the opposite way of what makes sense for some + * of love's APIs. For example in OpenGL if the compare function is GL_GREATER, + * then the stencil test will pass if the reference value is greater than the + * value in the stencil buffer. With our stencil API it's more intuitive to + * assume that setStencilTest(COMPARE_GREATER, 4) will make it pass if the + * stencil buffer has a value greater than 4. + **/ +CompareMode getReversedCompareMode(CompareMode mode); + +bool getConstant(const char *in, BlendMode &out); +bool getConstant(BlendMode in, const char *&out); +std::vector getConstants(BlendMode); + +bool getConstant(const char *in, BlendAlpha &out); +bool getConstant(BlendAlpha in, const char *&out); +std::vector getConstants(BlendAlpha); + +bool getConstant(const char *in, BlendFactor &out); +bool getConstant(BlendFactor in, const char *&out); +std::vector getConstants(BlendFactor); + +bool getConstant(const char *in, BlendOperation &out); +bool getConstant(BlendOperation in, const char *&out); +std::vector getConstants(BlendOperation); + +bool getConstant(const char *in, StencilAction &out); +bool getConstant(StencilAction in, const char *&out); +std::vector getConstants(StencilAction); + +bool getConstant(const char *in, CompareMode &out); +bool getConstant(CompareMode in, const char *&out); +std::vector getConstants(CompareMode); + +} // graphics +} // love diff --git a/src/modules/graphics/wrap_Graphics.cpp b/src/modules/graphics/wrap_Graphics.cpp index ab0a6d186..1e192efda 100644 --- a/src/modules/graphics/wrap_Graphics.cpp +++ b/src/modules/graphics/wrap_Graphics.cpp @@ -1777,7 +1777,7 @@ int w_getFont(lua_State *L) int w_setColorMask(lua_State *L) { - Graphics::ColorMask mask; + ColorChannelMask mask; if (lua_gettop(L) <= 1 && lua_isnoneornil(L, 1)) { @@ -1799,7 +1799,7 @@ int w_setColorMask(lua_State *L) int w_getColorMask(lua_State *L) { - Graphics::ColorMask mask = instance()->getColorMask(); + ColorChannelMask mask = instance()->getColorMask(); luax_pushboolean(L, mask.r); luax_pushboolean(L, mask.g); @@ -1811,17 +1811,17 @@ int w_getColorMask(lua_State *L) int w_setBlendMode(lua_State *L) { - Graphics::BlendMode mode; + BlendMode mode; const char *str = luaL_checkstring(L, 1); - if (!Graphics::getConstant(str, mode)) - return luax_enumerror(L, "blend mode", Graphics::getConstants(mode), str); + if (!getConstant(str, mode)) + return luax_enumerror(L, "blend mode", getConstants(mode), str); - Graphics::BlendAlpha alphamode = Graphics::BLENDALPHA_MULTIPLY; + BlendAlpha alphamode = BLENDALPHA_MULTIPLY; if (!lua_isnoneornil(L, 2)) { const char *alphastr = luaL_checkstring(L, 2); - if (!Graphics::getConstant(alphastr, alphamode)) - return luax_enumerror(L, "blend alpha mode", Graphics::getConstants(alphamode), alphastr); + if (!getConstant(alphastr, alphamode)) + return luax_enumerror(L, "blend alpha mode", getConstants(alphamode), alphastr); } luax_catchexcept(L, [&](){ instance()->setBlendMode(mode, alphamode); }); @@ -1833,13 +1833,13 @@ int w_getBlendMode(lua_State *L) const char *str; const char *alphastr; - Graphics::BlendAlpha alphamode; - Graphics::BlendMode mode = instance()->getBlendMode(alphamode); + BlendAlpha alphamode; + BlendMode mode = instance()->getBlendMode(alphamode); - if (!Graphics::getConstant(mode, str)) + if (!getConstant(mode, str)) return luaL_error(L, "Unknown blend mode"); - if (!Graphics::getConstant(alphamode, alphastr)) + if (!getConstant(alphamode, alphastr)) return luaL_error(L, "Unknown blend alpha mode"); lua_pushstring(L, str);