Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: sf::BlendMode::apply() function  (Read 2443 times)

0 Members and 1 Guest are viewing this topic.

Jamin Grey

  • Newbie
  • *
  • Posts: 25
    • View Profile
    • Of Stranger Flames
sf::BlendMode::apply() function
« on: December 17, 2014, 05:15:55 am »
Hi! I love the new sf::BlendMode. I was planning to work around it with my own butchered hacks when SFML added it (I was specifically wanting Multiply2, or as PaintShopPro calls it, 'Overlay'). Thank you, gents!

Anyway, many of SFML's classes can be used directly with OpenGL, instead of going through SFML's 2D graphics API.

For example, sf::Shader and sf::Texture both have a bind() function.

Currently, if I want to use sf::BlendMode with OpenGL directly, I basically have to replicate the code in void sf::RenderTarget::applyBlendMode(const BlendMode& mode); (RenderTarget.cpp, line 421 in the current master)

Why not extract that exact same code into a new sf::BlendMode function (possibly called 'apply()' or maybe 'bind()')?

It'd look like this:
void BlendMode::apply() const
{
    // Apply the blend mode, falling back to the non-separate versions if necessary
    if (GLEXT_blend_func_separate)
    {
        glCheck(GLEXT_glBlendFuncSeparate(
            factorToGlConstant(colorSrcFactor), factorToGlConstant(colorDstFactor),
            factorToGlConstant(alphaSrcFactor), factorToGlConstant(alphaDstFactor)));
    }
    else
    {
        glCheck(glBlendFunc(
            factorToGlConstant(colorSrcFactor),
            factorToGlConstant(colorDstFactor)));
    }

    if (GLEXT_blend_equation_separate)
    {
        glCheck(GLEXT_glBlendEquationSeparate(
            equationToGlConstant(colorEquation),
            equationToGlConstant(alphaEquation)));
    }
    else
    {
        glCheck(GLEXT_glBlendEquation(equationToGlConstant(colorEquation)));
    }
}
(The only change is instead of taking 'mode' as a parameter, the class is directly using its own members)

And then RenderTarget::applyBlendMode() would be changed to this:
void RenderTarget::applyBlendMode(const BlendMode& mode)
{
     mode.apply();
     m_cache.lastBlendMode = mode;
}

Perfectly backwards compatible with prior SFML versions, cleans up RenderTarget of some of its responsibilities, and also makes sf::BlendMode more flexible and usable for general OpenGL users.

(Sorry for not contributing it directly to the GitHub. I don't currently have a GitHub account, and don't use git for my source control)
« Last Edit: December 17, 2014, 05:21:59 am by Jamin Grey »
Of Stranger Flames - My work-in-progress para-historical (and classically-inspired) 2D rpg.

thomas9459

  • Newbie
  • *
  • Posts: 49
    • View Profile
    • Email
Re: sf::BlendMode::apply() function
« Reply #1 on: December 23, 2014, 06:17:02 am »
Back when the new system was being implemented, Laurent had suggested that we keep all the OpenGL calls in sf::RenderTarget.

Moreover, apply() should not be there. Let's keep all implementation details in RenderTarget.cpp and the BlendMode structure clean. People who use direct OpenGL calls will not use sf::BlendMode anyway, so I don't see any reason to leave a public apply() function, other than possibly breaking the implementation / state cache / whatever.

However, having a public apply() function would be rather useful, and with proper usage, it will not invalidate the cache, so maybe we should consider adding it back in. Anyone from the core team care to comment?