The topic of adding more blend modes has come up several times before, and there is even an open issue in the tracker for it (
https://github.com/SFML/SFML/issues/298). Unfortunately, there does not seem to be any progress for over a year on the topic. I recently could have used such a feature myself for creating special effects and believe that this feature would benefit many others as well. I would be more than willing to implement the code if Laurent approves a design.
Here is my design proposal:
- Change sf::BlendMode to a class with the following public members: sourceFactor, destFactor, and equation.
- Change the current enumerators of sf::BlendMode to static members of sf::BlendMode of type sf::BlendMode (similar to sf::Transform::Identitiy).
- Overload the == operator in sf::BlendMode to test if the modes are the same (useful for the cache when drawing).
- Rewrite RenderTarget::applyBlendMode(BlendMode mode) to simply set the OpenGL blend functions to sourceFactor and destFactor.
Issues:
- Because this proposal changes the type of sf::BlendMode, should it wait until SFML 3.0 to be implemented?
- Should the OpenGL constants (GL_ZERO, GL_ONE, GL_SRC_ALPHA, etc.) be used, or should similar constants be defined in the sf namespace?
- How, if at all, should the separate blending function for alpha be handled?
These changes should (if I understand correctly) keep the following code valid,
void Laser::draw(sf::RenderTarget &target, sf::RenderStates states) const {
states.blendMode = sf::BlendMode::BlendAdd;
target.draw(m_sprite, states);
}
while allowing the following as well.
void Laser::draw(sf::RenderTarget &target, sf::RenderStates states) const {
states.blendMode = sf::BlendMode::BlendAdd;
// The texture uses premultiplied alpha
states.blendMode.srcFactor = GL_ONE; // or sf::BlendFactor::One
target.draw(m_sprite, states);
}
What do you guys think? Any suggestions and/or improvements?