Consolidate some internal graphics state definitions into a new renderstate file.

--HG--
branch : minor
This commit is contained in:
Alex Szpakowski
2019-12-26 23:07:51 -05:00
parent f3b52f66fe
commit efa2bd7837
16 changed files with 577 additions and 385 deletions
+2 -55
View File
@@ -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<std::string> 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<std::string> 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<std::string> Graphics::getConstants(BlendAlpha)
{
return blendAlphaModes.getNames();
}
bool Graphics::getConstant(const char *in, LineStyle &out)
{
return lineStyles.find(in, out);
@@ -1890,29 +1860,6 @@ StringMap<Graphics::ArcMode, Graphics::ARC_MAX_ENUM>::Entry Graphics::arcModeEnt
StringMap<Graphics::ArcMode, Graphics::ARC_MAX_ENUM> Graphics::arcModes(Graphics::arcModeEntries, sizeof(Graphics::arcModeEntries));
StringMap<Graphics::BlendMode, Graphics::BLEND_MAX_ENUM>::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::BlendMode, Graphics::BLEND_MAX_ENUM> Graphics::blendModes(Graphics::blendModeEntries, sizeof(Graphics::blendModeEntries));
StringMap<Graphics::BlendAlpha, Graphics::BLENDALPHA_MAX_ENUM>::Entry Graphics::blendAlphaEntries[] =
{
{ "alphamultiply", BLENDALPHA_MULTIPLY },
{ "premultiplied", BLENDALPHA_PREMULTIPLIED },
};
StringMap<Graphics::BlendAlpha, Graphics::BLENDALPHA_MAX_ENUM> Graphics::blendAlphaModes(Graphics::blendAlphaEntries, sizeof(Graphics::blendAlphaEntries));
StringMap<Graphics::LineStyle, Graphics::LINE_MAX_ENUM>::Entry Graphics::lineStyleEntries[] =
{
{ "smooth", LINE_SMOOTH },
+4 -62
View File
@@ -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<std::string> getConstants(ArcMode);
static bool getConstant(const char *in, BlendMode &out);
static bool getConstant(BlendMode in, const char *&out);
static std::vector<std::string> getConstants(BlendMode);
static bool getConstant(const char *in, BlendAlpha &out);
static bool getConstant(BlendAlpha in, const char *&out);
static std::vector<std::string> getConstants(BlendAlpha);
static bool getConstant(const char *in, LineStyle &out);
static bool getConstant(LineStyle in, const char *&out);
static std::vector<std::string> 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<ArcMode, ARC_MAX_ENUM>::Entry arcModeEntries[];
static StringMap<ArcMode, ARC_MAX_ENUM> arcModes;
static StringMap<BlendMode, BLEND_MAX_ENUM>::Entry blendModeEntries[];
static StringMap<BlendMode, BLEND_MAX_ENUM> blendModes;
static StringMap<BlendAlpha, BLENDALPHA_MAX_ENUM>::Entry blendAlphaEntries[];
static StringMap<BlendAlpha, BLENDALPHA_MAX_ENUM> blendAlphaModes;
static StringMap<LineStyle, LINE_MAX_ENUM>::Entry lineStyleEntries[];
static StringMap<LineStyle, LINE_MAX_ENUM> lineStyles;
+1 -1
View File
@@ -31,7 +31,7 @@
#include "Drawable.h"
#include "Quad.h"
#include "vertex.h"
#include "depthstencil.h"
#include "renderstate.h"
#include "Resource.h"
// C
-103
View File
@@ -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<StencilAction, STENCIL_MAX_ENUM>::Entry stencilActionEntries[] =
{
{ "replace", STENCIL_REPLACE },
{ "increment", STENCIL_INCREMENT },
{ "decrement", STENCIL_DECREMENT },
{ "incrementwrap", STENCIL_INCREMENT_WRAP },
{ "decrementwrap", STENCIL_DECREMENT_WRAP },
{ "invert", STENCIL_INVERT },
};
static StringMap<StencilAction, STENCIL_MAX_ENUM> stencilActions(stencilActionEntries, sizeof(stencilActionEntries));
static StringMap<CompareMode, COMPARE_MAX_ENUM>::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<CompareMode, COMPARE_MAX_ENUM> 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<std::string> 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<std::string> getConstants(CompareMode)
{
return compareModes.getNames();
}
} // graphics
} // love
-74
View File
@@ -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 <vector>
#include <string>
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<std::string> getConstants(StencilAction);
bool getConstant(const char *in, CompareMode &out);
bool getConstant(CompareMode in, const char *&out);
std::vector<std::string> getConstants(CompareMode);
} // graphics
} // love
+1 -1
View File
@@ -407,7 +407,7 @@ void Canvas::setDepthSampleMode(Optional<CompareMode> 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);
+44 -47
View File
@@ -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;
+1 -1
View File
@@ -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;
+1 -1
View File
@@ -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
+261
View File
@@ -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<BlendMode, BLEND_MAX_ENUM>::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<BlendMode, BLEND_MAX_ENUM> blendModes(blendModeEntries, sizeof(blendModeEntries));
static StringMap<BlendAlpha, BLENDALPHA_MAX_ENUM>::Entry blendAlphaEntries[] =
{
{ "alphamultiply", BLENDALPHA_MULTIPLY },
{ "premultiplied", BLENDALPHA_PREMULTIPLIED },
};
static StringMap<BlendAlpha, BLENDALPHA_MAX_ENUM> blendAlphaModes(blendAlphaEntries, sizeof(blendAlphaEntries));
static StringMap<BlendFactor, BLENDFACTOR_MAX_ENUM>::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<BlendFactor, BLENDFACTOR_MAX_ENUM> blendFactors(blendFactorEntries, sizeof(blendFactorEntries));
static StringMap<BlendOperation, BLENDOP_MAX_ENUM>::Entry blendOperationEntries[] =
{
{ "add", BLENDOP_ADD },
{ "subtract", BLENDOP_SUBTRACT },
{ "reversesubtract", BLENDOP_REVERSE_SUBTRACT },
{ "min", BLENDOP_MIN },
{ "max", BLENDOP_MAX },
};
static StringMap<BlendOperation, BLENDOP_MAX_ENUM> blendOperations(blendOperationEntries, sizeof(blendOperationEntries));
static StringMap<StencilAction, STENCIL_MAX_ENUM>::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<StencilAction, STENCIL_MAX_ENUM> stencilActions(stencilActionEntries, sizeof(stencilActionEntries));
static StringMap<CompareMode, COMPARE_MAX_ENUM>::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<CompareMode, COMPARE_MAX_ENUM> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> 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<std::string> getConstants(CompareMode)
{
return compareModes.getNames();
}
} // graphics
} // love
+216
View File
@@ -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 <vector>
#include <string>
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<std::string> getConstants(BlendMode);
bool getConstant(const char *in, BlendAlpha &out);
bool getConstant(BlendAlpha in, const char *&out);
std::vector<std::string> getConstants(BlendAlpha);
bool getConstant(const char *in, BlendFactor &out);
bool getConstant(BlendFactor in, const char *&out);
std::vector<std::string> getConstants(BlendFactor);
bool getConstant(const char *in, BlendOperation &out);
bool getConstant(BlendOperation in, const char *&out);
std::vector<std::string> getConstants(BlendOperation);
bool getConstant(const char *in, StencilAction &out);
bool getConstant(StencilAction in, const char *&out);
std::vector<std::string> getConstants(StencilAction);
bool getConstant(const char *in, CompareMode &out);
bool getConstant(CompareMode in, const char *&out);
std::vector<std::string> getConstants(CompareMode);
} // graphics
} // love
+12 -12
View File
@@ -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);