mirror of
https://github.com/SFML/SFML.git
synced 2024-11-25 04:41:05 +08:00
More Shader.cpp
example simplifications
This commit is contained in:
parent
dae09a912c
commit
e7d67cfa2a
@ -18,7 +18,6 @@ namespace
|
|||||||
{
|
{
|
||||||
std::random_device rd;
|
std::random_device rd;
|
||||||
std::mt19937 rng(rd());
|
std::mt19937 rng(rd());
|
||||||
} // namespace
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
@ -36,20 +35,6 @@ struct Effect : sf::Drawable
|
|||||||
class Pixelate : public Effect
|
class Pixelate : public Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::optional<Pixelate> tryLoad()
|
|
||||||
{
|
|
||||||
auto texture = sf::Texture::loadFromFile("resources/background.jpg");
|
|
||||||
if (!texture.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
auto shader = sf::Shader::loadFromFile("resources/pixelate.frag", sf::Shader::Type::Fragment);
|
|
||||||
if (!shader.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return Pixelate{std::move(*texture), std::move(*shader)};
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Pixelate(sf::Texture&& texture, sf::Shader&& shader) :
|
explicit Pixelate(sf::Texture&& texture, sf::Shader&& shader) :
|
||||||
m_texture(std::move(texture)),
|
m_texture(std::move(texture)),
|
||||||
m_shader(std::move(shader))
|
m_shader(std::move(shader))
|
||||||
@ -68,6 +53,7 @@ private:
|
|||||||
target.draw(sf::Sprite{m_texture}, states);
|
target.draw(sf::Sprite{m_texture}, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
sf::Texture m_texture;
|
sf::Texture m_texture;
|
||||||
sf::Shader m_shader;
|
sf::Shader m_shader;
|
||||||
};
|
};
|
||||||
@ -79,15 +65,6 @@ private:
|
|||||||
class WaveBlur : public Effect
|
class WaveBlur : public Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::optional<WaveBlur> tryLoad(const sf::Font& font)
|
|
||||||
{
|
|
||||||
auto shader = sf::Shader::loadFromFile("resources/wave.vert", "resources/blur.frag");
|
|
||||||
if (!shader.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return WaveBlur{font, std::move(*shader)};
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float time, float x, float y) override
|
void update(float time, float x, float y) override
|
||||||
{
|
{
|
||||||
m_shader.setUniform("wave_phase", time);
|
m_shader.setUniform("wave_phase", time);
|
||||||
@ -101,7 +78,6 @@ public:
|
|||||||
target.draw(m_text, states);
|
target.draw(m_text, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
explicit WaveBlur(const sf::Font& font, sf::Shader&& shader) :
|
explicit WaveBlur(const sf::Font& font, sf::Shader&& shader) :
|
||||||
m_text(font,
|
m_text(font,
|
||||||
"Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.\n"
|
"Praesent suscipit augue in velit pulvinar hendrerit varius purus aliquam.\n"
|
||||||
@ -128,6 +104,7 @@ private:
|
|||||||
m_text.setPosition({30.f, 20.f});
|
m_text.setPosition({30.f, 20.f});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
sf::Text m_text;
|
sf::Text m_text;
|
||||||
sf::Shader m_shader;
|
sf::Shader m_shader;
|
||||||
};
|
};
|
||||||
@ -139,15 +116,6 @@ private:
|
|||||||
class StormBlink : public Effect
|
class StormBlink : public Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::optional<StormBlink> tryLoad()
|
|
||||||
{
|
|
||||||
auto shader = sf::Shader::loadFromFile("resources/storm.vert", "resources/blink.frag");
|
|
||||||
if (!shader.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
return StormBlink{std::move(*shader)};
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float time, float x, float y) override
|
void update(float time, float x, float y) override
|
||||||
{
|
{
|
||||||
const float radius = 200 + std::cos(time) * 150;
|
const float radius = 200 + std::cos(time) * 150;
|
||||||
@ -164,7 +132,6 @@ public:
|
|||||||
target.draw(m_points, states);
|
target.draw(m_points, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
explicit StormBlink(sf::Shader&& shader) : m_shader(std::move(shader))
|
explicit StormBlink(sf::Shader&& shader) : m_shader(std::move(shader))
|
||||||
{
|
{
|
||||||
std::uniform_real_distribution<float> xDistribution(0, 800);
|
std::uniform_real_distribution<float> xDistribution(0, 800);
|
||||||
@ -187,6 +154,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
sf::VertexArray m_points;
|
sf::VertexArray m_points;
|
||||||
sf::Shader m_shader;
|
sf::Shader m_shader;
|
||||||
};
|
};
|
||||||
@ -198,39 +166,6 @@ private:
|
|||||||
class Edge : public Effect
|
class Edge : public Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::optional<Edge> tryLoad()
|
|
||||||
{
|
|
||||||
// Create the off-screen surface
|
|
||||||
auto surface = sf::RenderTexture::create({800, 600});
|
|
||||||
if (!surface.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
surface->setSmooth(true);
|
|
||||||
|
|
||||||
// Load the background texture
|
|
||||||
auto backgroundTexture = sf::Texture::loadFromFile("resources/sfml.png");
|
|
||||||
if (!backgroundTexture.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
backgroundTexture->setSmooth(true);
|
|
||||||
|
|
||||||
// Load the entity texture
|
|
||||||
auto entityTexture = sf::Texture::loadFromFile("resources/devices.png");
|
|
||||||
if (!entityTexture.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
entityTexture->setSmooth(true);
|
|
||||||
|
|
||||||
// Load the shader
|
|
||||||
auto shader = sf::Shader::loadFromFile("resources/edge.frag", sf::Shader::Type::Fragment);
|
|
||||||
if (!shader.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
shader->setUniform("texture", sf::Shader::CurrentTexture);
|
|
||||||
|
|
||||||
return Edge{std::move(*surface), std::move(*backgroundTexture), std::move(*entityTexture), std::move(*shader)};
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float time, float x, float y) override
|
void update(float time, float x, float y) override
|
||||||
{
|
{
|
||||||
m_shader.setUniform("edge_threshold", 1 - (x + y) / 2);
|
m_shader.setUniform("edge_threshold", 1 - (x + y) / 2);
|
||||||
@ -265,7 +200,6 @@ public:
|
|||||||
target.draw(sf::Sprite{m_surface.getTexture()}, states);
|
target.draw(sf::Sprite{m_surface.getTexture()}, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Edge(sf::RenderTexture&& surface, sf::Texture&& backgroundTexture, sf::Texture&& entityTexture, sf::Shader&& shader) :
|
explicit Edge(sf::RenderTexture&& surface, sf::Texture&& backgroundTexture, sf::Texture&& entityTexture, sf::Shader&& shader) :
|
||||||
m_surface(std::move(surface)),
|
m_surface(std::move(surface)),
|
||||||
m_backgroundTexture(std::move(backgroundTexture)),
|
m_backgroundTexture(std::move(backgroundTexture)),
|
||||||
@ -274,6 +208,7 @@ private:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
sf::RenderTexture m_surface;
|
sf::RenderTexture m_surface;
|
||||||
sf::Texture m_backgroundTexture;
|
sf::Texture m_backgroundTexture;
|
||||||
sf::Texture m_entityTexture;
|
sf::Texture m_entityTexture;
|
||||||
@ -287,34 +222,6 @@ private:
|
|||||||
class Geometry : public Effect
|
class Geometry : public Effect
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::optional<Geometry> tryLoad()
|
|
||||||
{
|
|
||||||
// Check if geometry shaders are supported
|
|
||||||
if (!sf::Shader::isGeometryAvailable())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
// Load the logo texture
|
|
||||||
auto logoTexture = sf::Texture::loadFromFile("resources/logo.png");
|
|
||||||
if (!logoTexture.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
logoTexture->setSmooth(true);
|
|
||||||
|
|
||||||
// Load the shader
|
|
||||||
auto shader = sf::Shader::loadFromFile("resources/billboard.vert",
|
|
||||||
"resources/billboard.geom",
|
|
||||||
"resources/billboard.frag");
|
|
||||||
if (!shader.has_value())
|
|
||||||
return std::nullopt;
|
|
||||||
|
|
||||||
shader->setUniform("texture", sf::Shader::CurrentTexture);
|
|
||||||
|
|
||||||
// Set the render resolution (used for proper scaling)
|
|
||||||
shader->setUniform("resolution", sf::Vector2f(800, 600));
|
|
||||||
|
|
||||||
return Geometry{std::move(*logoTexture), std::move(*shader)};
|
|
||||||
}
|
|
||||||
|
|
||||||
void update(float /* time */, float x, float y) override
|
void update(float /* time */, float x, float y) override
|
||||||
{
|
{
|
||||||
// Reset our transformation matrix
|
// Reset our transformation matrix
|
||||||
@ -344,7 +251,6 @@ public:
|
|||||||
target.draw(m_pointCloud, states);
|
target.draw(m_pointCloud, states);
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
|
||||||
explicit Geometry(sf::Texture&& logoTexture, sf::Shader&& shader) :
|
explicit Geometry(sf::Texture&& logoTexture, sf::Shader&& shader) :
|
||||||
m_logoTexture(std::move(logoTexture)),
|
m_logoTexture(std::move(logoTexture)),
|
||||||
m_shader(std::move(shader)),
|
m_shader(std::move(shader)),
|
||||||
@ -359,6 +265,7 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
sf::Texture m_logoTexture;
|
sf::Texture m_logoTexture;
|
||||||
sf::Transform m_transform;
|
sf::Transform m_transform;
|
||||||
sf::Shader m_shader;
|
sf::Shader m_shader;
|
||||||
@ -366,6 +273,107 @@ private:
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
// Effect loading factory functions
|
||||||
|
////////////////////////////////////////////////////////////
|
||||||
|
std::optional<Pixelate> tryLoadPixelate()
|
||||||
|
{
|
||||||
|
auto texture = sf::Texture::loadFromFile("resources/background.jpg");
|
||||||
|
if (!texture.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
auto shader = sf::Shader::loadFromFile("resources/pixelate.frag", sf::Shader::Type::Fragment);
|
||||||
|
if (!shader.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return std::make_optional<Pixelate>(std::move(*texture), std::move(*shader));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<WaveBlur> tryLoadWaveBlur(const sf::Font& font)
|
||||||
|
{
|
||||||
|
auto shader = sf::Shader::loadFromFile("resources/wave.vert", "resources/blur.frag");
|
||||||
|
if (!shader.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return std::make_optional<WaveBlur>(font, std::move(*shader));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<StormBlink> tryLoadStormBlink()
|
||||||
|
{
|
||||||
|
auto shader = sf::Shader::loadFromFile("resources/storm.vert", "resources/blink.frag");
|
||||||
|
if (!shader.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
return std::make_optional<StormBlink>(std::move(*shader));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Edge> tryLoadEdge()
|
||||||
|
{
|
||||||
|
// Create the off-screen surface
|
||||||
|
auto surface = sf::RenderTexture::create({800, 600});
|
||||||
|
if (!surface.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
surface->setSmooth(true);
|
||||||
|
|
||||||
|
// Load the background texture
|
||||||
|
auto backgroundTexture = sf::Texture::loadFromFile("resources/sfml.png");
|
||||||
|
if (!backgroundTexture.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
backgroundTexture->setSmooth(true);
|
||||||
|
|
||||||
|
// Load the entity texture
|
||||||
|
auto entityTexture = sf::Texture::loadFromFile("resources/devices.png");
|
||||||
|
if (!entityTexture.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
entityTexture->setSmooth(true);
|
||||||
|
|
||||||
|
// Load the shader
|
||||||
|
auto shader = sf::Shader::loadFromFile("resources/edge.frag", sf::Shader::Type::Fragment);
|
||||||
|
if (!shader.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
shader->setUniform("texture", sf::Shader::CurrentTexture);
|
||||||
|
|
||||||
|
return std::make_optional<Edge>(std::move(*surface),
|
||||||
|
std::move(*backgroundTexture),
|
||||||
|
std::move(*entityTexture),
|
||||||
|
std::move(*shader));
|
||||||
|
}
|
||||||
|
|
||||||
|
std::optional<Geometry> tryLoadGeometry()
|
||||||
|
{
|
||||||
|
// Check if geometry shaders are supported
|
||||||
|
if (!sf::Shader::isGeometryAvailable())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
// Load the logo texture
|
||||||
|
auto logoTexture = sf::Texture::loadFromFile("resources/logo.png");
|
||||||
|
if (!logoTexture.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
logoTexture->setSmooth(true);
|
||||||
|
|
||||||
|
// Load the shader
|
||||||
|
auto shader = sf::Shader::loadFromFile("resources/billboard.vert",
|
||||||
|
"resources/billboard.geom",
|
||||||
|
"resources/billboard.frag");
|
||||||
|
if (!shader.has_value())
|
||||||
|
return std::nullopt;
|
||||||
|
|
||||||
|
shader->setUniform("texture", sf::Shader::CurrentTexture);
|
||||||
|
|
||||||
|
// Set the render resolution (used for proper scaling)
|
||||||
|
shader->setUniform("resolution", sf::Vector2f(800, 600));
|
||||||
|
|
||||||
|
return std::make_optional<Geometry>(std::move(*logoTexture), std::move(*shader));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////
|
||||||
/// Entry point of application
|
/// Entry point of application
|
||||||
///
|
///
|
||||||
@ -389,11 +397,11 @@ int main()
|
|||||||
const auto font = sf::Font::loadFromFile("resources/tuffy.ttf").value();
|
const auto font = sf::Font::loadFromFile("resources/tuffy.ttf").value();
|
||||||
|
|
||||||
// Create the effects
|
// Create the effects
|
||||||
std::optional pixelateEffect = Pixelate::tryLoad();
|
std::optional pixelateEffect = tryLoadPixelate();
|
||||||
std::optional waveBlurEffect = WaveBlur::tryLoad(font);
|
std::optional waveBlurEffect = tryLoadWaveBlur(font);
|
||||||
std::optional stormBlinkEffect = StormBlink::tryLoad();
|
std::optional stormBlinkEffect = tryLoadStormBlink();
|
||||||
std::optional edgeEffect = Edge::tryLoad();
|
std::optional edgeEffect = tryLoadEdge();
|
||||||
std::optional geometryEffect = Geometry::tryLoad();
|
std::optional geometryEffect = tryLoadGeometry();
|
||||||
|
|
||||||
const auto optionalToPtr = [&](auto& effect) -> Effect* { return effect.has_value() ? &*effect : nullptr; };
|
const auto optionalToPtr = [&](auto& effect) -> Effect* { return effect.has_value() ? &*effect : nullptr; };
|
||||||
|
|
||||||
@ -481,26 +489,25 @@ int main()
|
|||||||
}
|
}
|
||||||
|
|
||||||
// If the current example was loaded successfully...
|
// If the current example was loaded successfully...
|
||||||
if (effects[current] != nullptr)
|
if (Effect* currentEffect = effects[current])
|
||||||
{
|
{
|
||||||
// Update the current example
|
// Update the current example
|
||||||
const auto [x, y] = sf::Vector2f(sf::Mouse::getPosition(window)).cwiseDiv(sf::Vector2f(window.getSize()));
|
const auto [x, y] = sf::Vector2f(sf::Mouse::getPosition(window)).cwiseDiv(sf::Vector2f(window.getSize()));
|
||||||
effects[current]->update(clock.getElapsedTime().asSeconds(), x, y);
|
currentEffect->update(clock.getElapsedTime().asSeconds(), x, y);
|
||||||
|
|
||||||
// Clear the window
|
// Clear the window
|
||||||
window.clear(effectNames[current] == "Edge Post-effect" ? sf::Color::White : sf::Color(50, 50, 50));
|
window.clear(currentEffect == &*edgeEffect ? sf::Color::White : sf::Color(50, 50, 50));
|
||||||
|
|
||||||
// Draw the current example
|
// Draw the current example
|
||||||
window.draw(*effects[current]);
|
window.draw(*currentEffect);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
// Clear the window to grey to make sure the text is always readable
|
// Clear the window to grey to make sure the text is always readable
|
||||||
window.clear(sf::Color(50, 50, 50));
|
window.clear(sf::Color(50, 50, 50));
|
||||||
|
|
||||||
sf::Text error(font, "Shader not\nsupported");
|
sf::Text error(font, "Shader not\nsupported", 36);
|
||||||
error.setPosition({320.f, 200.f});
|
error.setPosition({320.f, 200.f});
|
||||||
error.setCharacterSize(36);
|
|
||||||
|
|
||||||
window.draw(error);
|
window.draw(error);
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user