Commit 4be92526 authored by Geequette's avatar Geequette

Fire in part_005

parent 1ebf6c2f
/*!
* \file main.cpp
* \brief apply a heat shader to a sprite (http://www.lucidarme.me/?p=6127)
* \author Philippe Lucidarme (from https://github.com/SFML/SFML/wiki/Source:-HeatHazeShader)
* \version 1.0
* \date 12/19/2016
*/
// SFML libraries
#include <SFML/Graphics.hpp>
#include <iostream>
#include <math.h>
// Sprite speed (high values = high speed)
#define SPRITE_SPEED 5
int main()
{
// _____________________
// ::: Create window :::
// Create a window with the same pixel depth as the desktop
sf::VideoMode desktopMode = sf::VideoMode::getDesktopMode();
sf::RenderWindow window(sf::VideoMode( desktopMode.width,
desktopMode.height,
desktopMode.bitsPerPixel),
"SFML part 5",
sf::Style::Fullscreen);
// Enable vertical sync. (vsync)
window.setVerticalSyncEnabled (true);
// ____________________
// ::: Load texture :::
// Create texture from PNG file
sf::Texture texture;
if (!texture.loadFromFile("../../img/sfml-icon-small.png"))
{
std::cerr << "Error while loading texture" << std::endl;
return -1;
}
// Enable the smooth filter. The texture appears smoother so that pixels are less noticeable.
texture.setSmooth(true);
// _______________________________________
// ::: Create sprite and apply texture :::
// Create the sprite and apply the texture
sf::Sprite sprite;
sprite.setTexture(texture);
sf::FloatRect spriteSize=sprite.getGlobalBounds();
// Set origin in the middle of the sprite
sprite.setOrigin(spriteSize.width/2.,spriteSize.height/2.);
int main() {
const float winW = 800;
const float winH = 600;
sf::RenderWindow window(sf::VideoMode(winW, winH), "SFML Shader Example");
window.setMouseCursorVisible(false); // hide the cursor
// Create a texture and a sprite for the shader
sf::Texture tex;
tex.create(winW, winH);
sf::Sprite spr(tex);
// _______________
// ::: Shaders :::
// Check if shaders are available
if (!sf::Shader::isAvailable())
{
std::cerr << "Shader are not available" << std::endl;
return -1;
}
// Load shaders
sf::Shader shader;
if (!shader.loadFromFile("../../shaders/example_001.vert", "../../shaders/example_001.frag"))
{
std::cerr << "Error while shaders" << std::endl;
return -1;
}
shader.loadFromFile("../../shaders/example_001.frag", sf::Shader::Fragment); // load the shader
if (!shader.isAvailable()) {
std::cout << "The shader is not available\n";
}
// Set the resolution parameter (the resoltion is divided to make the fire smaller)
shader.setParameter("resolution", sf::Vector2f(winW / 2, winH / 2));
// _________________
// ::: Main loop :::
// Use a timer to obtain the time elapsed
sf::Clock clk;
clk.restart(); // start the timer
sf::Clock timer;
while (window.isOpen())
{
// Process events
while (window.isOpen()) {
// Event handling
sf::Event event;
while (window.pollEvent(event))
{
// Close the window if a key is pressed or if requested
if (event.type == sf::Event::Closed) window.close();
// If a key is pressed
while (window.pollEvent(event)) {
// Exit the app when a key is pressed
if (event.type == sf::Event::KeyPressed)
{
switch (event.key.code)
{
// If escape is pressed, close the application
case sf::Keyboard::Escape : window.close(); break;
default : break;
}
}
window.close();
}
// Set the others parameters who need to be updated every frames
shader.setParameter("time", 3*clk.getElapsedTime().asSeconds());
shader.setParameter("time", timer.getElapsedTime().asSeconds());
// Clear the window and apply grey background
window.clear( sf::Color(127,127,127));
// Draw the sprite and apply shader
sprite.setPosition(window.getSize().x/2.,window.getSize().y/2.);
window.draw(sprite,&shader);
sf::Vector2i mousePos = sf::Mouse::getPosition(window);
shader.setParameter("mouse", sf::Vector2f(mousePos.x, mousePos.y - winH/2));
// Update display and wait for vsync
// Draw the sprite with the shader on it
window.clear();
window.draw(spr, &shader);
window.display();
}
return 0;
}
#version 130
#ifdef GL_ES
precision mediump float;
#endif
uniform sampler2D currentTexture; // Our render texture
uniform sampler2D distortionMapTexture; // Our heat distortion map texture
uniform float time;
uniform vec2 mouse;
uniform vec2 resolution;
uniform float time; // Time used to scroll the distortion map
uniform float distortionFactor; // Factor used to control severity of the effect
uniform float riseFactor; // Factor used to control how fast air rises
void main()
float snoise(vec3 uv, float res)
{
vec2 distortionMapCoordinate = gl_TexCoord[0].st;
const vec3 s = vec3(1e0, 1e2, 1e3);
uv *= res;
vec3 uv0 = floor(mod(uv, res))*s;
vec3 uv1 = floor(mod(uv+vec3(1.), res))*s;
vec3 f = fract(uv); f = f*f*(3.0-2.0*f);
vec4 v = vec4(uv0.x+uv0.y+uv0.z, uv1.x+uv0.y+uv0.z,
uv0.x+uv1.y+uv0.z, uv1.x+uv1.y+uv0.z);
vec4 r = fract(sin(v*1e-1)*1e3);
float r0 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
r = fract(sin((v + uv1.z - uv0.z)*1e-1)*1e3);
float r1 = mix(mix(r.x, r.y, f.x), mix(r.z, r.w, f.x), f.y);
return mix(r0, r1, f.z)*2.-1.;
}
// We use the time value to scroll our distortion texture upwards
// Since we enabled texture repeating, OpenGL takes care of
// coordinates that lie outside of [0, 1] by discarding
// the integer part and keeping the fractional part
// Basically performing a "floating point modulo 1"
// 1.1 = 0.1, 2.4 = 0.4, 10.3 = 0.3 etc.
distortionMapCoordinate.t -= time * riseFactor;
vec4 distortionMapValue = texture2D(distortionMapTexture, distortionMapCoordinate);
void main( void ) {
vec2 p = gl_FragCoord.xy / resolution.xy;
p.x = p.x - mouse.x / resolution.x;
p.y = p.y + mouse.y / resolution.y;
p.y = p.y - 1.0;
// The values are normalized by OpenGL to lie in the range [0, 1]
// We want negative offsets too, so we subtract 0.5 and multiply by 2
// We end up with values in the range [-1, 1]
vec2 distortionPositionOffset = distortionMapValue.xy;
distortionPositionOffset -= vec2(0.5f, 0.5f);
distortionPositionOffset *= 2.f;
p.x*=resolution.x/resolution.y;
// The factor scales the offset and thus controls the severity
distortionPositionOffset *= distortionFactor;
float color = 3.0 - (6.*length(p));
// The latter 2 channels of the texture are unused... be creative
vec2 distortionUnused = distortionMapValue.zw;
vec3 coord = vec3(atan(p.x,p.y)/6.2832, length(p)*0.4, .5);
// Since we all know that hot air rises and cools,
// the effect loses its severity the higher up we get
// We use the t (a.k.a. y) texture coordinate of the original texture
// to tell us how "high up" we are and damp accordingly
// Remember, OpenGL 0 is at the bottom
distortionPositionOffset *= (1.f - gl_TexCoord[0].t);
for(int i = 1; i <= 7; i++){
float power = pow(2.0, float(i));
color += (1.5 / power) * snoise(coord + vec3(0.,-time*.05, time*.01), power*16.);
}
vec2 distortedTextureCoordinate = gl_TexCoord[0].st + distortionPositionOffset;
gl_FragColor = vec4( color, pow(max(color,0.),2.)*0.4, pow(max(color,0.),3.)*0.15 , 1.0);
gl_FragColor = gl_Color * texture2D(currentTexture, distortedTextureCoordinate);
}
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment