Last active
August 2, 2020 13:24
-
-
Save rubenwardy/9b29e9b12766fca9a5b72410b813d8b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
uniform sampler2D source; | |
uniform vec4 mask; | |
uniform vec2 direction; | |
void main() { | |
vec2 textureCoordinates = gl_TexCoord[0].xy; | |
vec4 color = vec4(0.0); | |
color += texture2D(source, textureCoordinates - 4.0 * direction) * 0.0162162162; | |
color += texture2D(source, textureCoordinates - 3.0 * direction) * 0.0540540541; | |
color += texture2D(source, textureCoordinates - 2.0 * direction) * 0.1216216216; | |
color += texture2D(source, textureCoordinates - direction) * 0.1945945946; | |
color += texture2D(source, textureCoordinates) * 0.2270270270; | |
color += texture2D(source, textureCoordinates + direction) * 0.1945945946; | |
color += texture2D(source, textureCoordinates + 2.0 * direction) * 0.1216216216; | |
color += texture2D(source, textureCoordinates + 3.0 * direction) * 0.0540540541; | |
color += texture2D(source, textureCoordinates + 4.0 * direction) * 0.0162162162; | |
color = mask * vec4(100.0, 100.0, 100.0, color[3]) / 100.0; | |
gl_FragColor = color; | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include "DropShadow.hpp" | |
#include <cassert> | |
#include <cmath> | |
#include <memory> | |
using namespace sfext; | |
namespace { | |
std::unique_ptr<sf::Shader> shadowShader; | |
sf::Glsl::Vec4 convert255to100(const sf::Color &color) { | |
return sf::Glsl::Vec4((float)color.r * 100.f / 255.f, | |
(float)color.g * 100.f / 255.f, (float)color.b * 100.f / 255.f, | |
(float)color.a * 100.f / 255.f); | |
} | |
} // namespace | |
bool DropShadow::load(const std::string &shadowPath) { | |
shadowShader = std::make_unique<sf::Shader>(); | |
return shadowShader->loadFromFile(shadowPath, sf::Shader::Fragment); | |
} | |
void DropShadow::draw( | |
sf::RenderTarget &target, sf::RenderStates baseStates) const { | |
auto transformable = dynamic_cast<const sf::Transformable *>(&drawable); | |
// Draw shadow | |
{ | |
sf::Vector2f pos = transformable->getPosition() - | |
transformable->getOrigin() + offset - | |
sf::Vector2f(10, 10); | |
pos = {std::round(pos.x), std::round(pos.y)}; | |
sf::RenderStates states = baseStates; | |
sf::Sprite sprite(texture.getTexture()); | |
shadowShader->setUniform("mask", convert255to100(color)); | |
shadowShader->setUniform("direction", sf::Vector2f(0.f, pixelSize.y)); | |
states.shader = shadowShader.get(); | |
states.transform.translate(pos); | |
target.draw(sprite, states); | |
} | |
// Draw drawable | |
{ | |
sf::Vector2f pos = | |
transformable->getPosition() - transformable->getOrigin(); | |
pos = {std::round(pos.x), std::round(pos.y)}; | |
target.draw(drawable, baseStates); | |
} | |
} | |
void DropShadow::regenerate() { | |
auto transformable = dynamic_cast<const sf::Transformable *>(&drawable); | |
SanityCheck(transformable); | |
sf::Vector2i textureSize = {size.x + 20, size.y + 20}; | |
pixelSize = {1.f / float(textureSize.x), 1.f / float(textureSize.y)}; | |
// Render font to a single texture | |
sf::RenderTexture tmpTexture; | |
{ | |
SanityCheck(tmpTexture.create(textureSize.x, textureSize.y)); | |
tmpTexture.clear(sf::Color::Transparent); | |
sf::RenderStates states = sf::RenderStates::Default; | |
states.transform = transformable->getInverseTransform(); | |
states.transform.translate({10, 10}); | |
tmpTexture.draw(drawable, states); | |
tmpTexture.display(); | |
} | |
// Render horizontal blur | |
{ | |
SanityCheck(texture.create(textureSize.x, textureSize.y)); | |
texture.clear(sf::Color::Transparent); | |
sf::Sprite sprite(tmpTexture.getTexture()); | |
sf::RenderStates states = sf::RenderStates::Default; | |
shadowShader->setUniform("mask", sf::Glsl::Vec4(100, 100, 100, 100)); | |
shadowShader->setUniform("direction", sf::Vector2f(pixelSize.x, 0.f)); | |
states.shader = shadowShader.get(); | |
texture.draw(sprite, states); | |
texture.display(); | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SFML/Graphics.hpp> | |
#include <string> | |
namespace sfext { | |
class DropShadow : public sf::Drawable { | |
const sf::Drawable &drawable; | |
const sf::Vector2f size; | |
const sf::Vector2f offset; | |
const sf::Color color; | |
sf::RenderTexture texture; | |
sf::Vector2f pixelSize; | |
public: | |
DropShadow(const sf::Drawable &drawable, sf::Vector2f size, | |
sf::Vector2f offset, sf::Color color) | |
: drawable(drawable), size(size), offset(offset), color(color) { | |
regenerate(); | |
} | |
[[nodiscard]] static bool load(const std::string &shadowPath); | |
private: | |
virtual void draw( | |
sf::RenderTarget &target, sf::RenderStates states) const override; | |
void regenerate(); | |
}; | |
} // namespace sfext |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
sf::Text rawlabel = sf::Text("RVWP", font, 17); | |
rawlabel.setFillColor(sf::Color::White); | |
sfext::DropShadow label(static_cast<const sf::Drawable&>(rawlabel), | |
rawlabel.getLocalBounds(), sf::Vector2f(1.f, 2.f), sf::Color(0x0000007f)); | |
const auto size = rwindow->getSize(); | |
label.setPosition(sf::Vector2f(size.x / 2, size.y * 0.1f)); | |
sf::FloatRect textRect = rawlabel.getLocalBounds(); | |
label.setOrigin(textRect.left + textRect.width / 2.0f, | |
textRect.top + textRect.height / 2.0f); | |
rwindow->draw(label); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment