Created
July 18, 2016 08:47
-
-
Save MarioLiebisch/fff9fb605295504eb29fc49c50d35321 to your computer and use it in GitHub Desktop.
Drawing a parallax background using a fragment shader.
This file contains hidden or 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> | |
int main() | |
{ | |
sf::RenderWindow window(sf::VideoMode(1024, 768), "Parallax Example", | |
sf::Style::Titlebar | sf::Style::Close | sf::Style::Fullscreen); | |
window.setVerticalSyncEnabled(true); | |
sf::Texture texture; | |
// This is a texture 1024x1024 with three backgrounds stacked one over the other from front to back | |
if (!texture.loadFromFile("resources/cave.png")) | |
return EXIT_FAILURE; | |
texture.setRepeated(true); | |
sf::VertexArray sprite(sf::TriangleFan); | |
sprite.append(sf::Vertex(sf::Vector2f(0,0), sf::Vector2f(0,0))); | |
sprite.append(sf::Vertex(sf::Vector2f(1024, 0), sf::Vector2f(1024, 0))); | |
sprite.append(sf::Vertex(sf::Vector2f(1024, 768), sf::Vector2f(1024, 1024))); | |
sprite.append(sf::Vertex(sf::Vector2f(0, 768), sf::Vector2f(0, 1024))); | |
sf::Shader parallaxShader; | |
parallaxShader.loadFromMemory( | |
"uniform sampler2D texture;" | |
"uniform float offset;" | |
// This shader is just for demonstration purposes. There's most likely a better way to do it. :) | |
"void main() {" | |
" vec2 p3 = gl_TexCoord[0].xy; p3.y = p3.y / 3.;" | |
" vec2 p2 = p3; p2.y = p2.y + .33; p2.x = p2.x + offset / 10;" | |
" vec2 p1 = p3; p1.y = p1.y + .67; p1.x = p1.x + offset / 100;" | |
" p3.x = p3.x + offset;" | |
" vec4 bg1 = texture2D(texture, p1);" | |
" vec4 bg2 = texture2D(texture, p2);" | |
" vec4 bg3 = texture2D(texture, p3);" | |
" bg1 = bg1 * (1 - bg2.a) + bg2 * bg2.a;" | |
" gl_FragColor = bg1 * (1 - bg3.a) + bg3 * bg3.a;" | |
"}" | |
, sf::Shader::Fragment); | |
float offset = 0.f; | |
sf::RenderStates state; | |
state.blendMode = sf::BlendAlpha; | |
state.shader = ¶llaxShader; | |
state.texture = &texture; | |
sf::Clock clock; | |
while (window.isOpen()) | |
{ | |
sf::Event event; | |
while (window.pollEvent(event)) | |
{ | |
switch (event.type) { | |
case sf::Event::Closed: | |
window.close(); | |
break; | |
} | |
} | |
// I set an arbitrary value as the offset, you'd calculate this based on camera position | |
parallaxShader.setUniform("offset", offset += clock.restart().asSeconds() / 2); | |
window.clear(); | |
window.draw(sprite, state); | |
window.display(); | |
} | |
return EXIT_SUCCESS; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment