Skip to content

Instantly share code, notes, and snippets.

@axjxwright
Created November 4, 2016 07:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save axjxwright/bbbe96bd0b17420b193322e09f1e0c8a to your computer and use it in GitHub Desktop.
Save axjxwright/bbbe96bd0b17420b193322e09f1e0c8a to your computer and use it in GitHub Desktop.
#include "cinder/app/App.h"
#include "cinder/app/RendererGl.h"
#include "cinder/gl/gl.h"
#include "cinder/Timeline.h"
#include "cinder/Rand.h"
using namespace ci;
using namespace ci::app;
using namespace std;
class GLSLIOApp : public App
{
public:
void setup ( ) override;
void mouseDown ( MouseEvent event ) override;
void update ( ) override;
void draw ( ) override;
void loadImages ( );
void loadShader ( );
ci::gl::Texture2dRef _fromImage;
ci::gl::Texture2dRef _toImage;
ci::gl::GlslProgRef _shader;
ci::Anim<float> _time{0.0f};
};
void GLSLIOApp::setup()
{
gl::enableAlphaBlending();
gl::enableDepth(false);
loadImages(); // Needs internet
loadShader();
app::timeline().apply ( &_time, 1.0f, randFloat(0.1, 4.0f), EaseInOutQuint() );
}
void GLSLIOApp::mouseDown( MouseEvent event )
{
if ( _time() > 0.5f )
{
app::timeline().apply ( &_time, 0.0f, 4.0f, EaseInOutQuint() );
}else
{
app::timeline().apply ( &_time, 1.0f, 4.0f, EaseInOutQuint() );
}
}
void GLSLIOApp::loadImages ( )
{
auto fmt = gl::Texture::Format().wrap(GL_REPEAT);
_fromImage = gl::Texture::create( loadImage ( loadUrl ( "http://transitions.glsl.io/assets/images/512x400/barley.jpg" ) ) );
_toImage = gl::Texture::create( loadImage ( loadUrl ( "http://transitions.glsl.io/assets/images/512x400/ic1dX3kBQjGNaPQb8Xel_1920x1280.jpg" ) ) );
}
void GLSLIOApp::loadShader ( )
{
auto vertex = CI_GLSL(150,
uniform mat4 ciModelViewProjection;
in vec4 ciPosition;
in vec2 ciTexCoord0;
out vec2 UV;
out vec2 Position;
void main ( )
{
gl_Position = ciModelViewProjection * vec4 ( ciPosition.xy, 0, 1 );
Position = ciPosition.xy;
UV = ciTexCoord0;
}
);
auto fragment = CI_GLSL(150,
in vec2 UV;
in vec2 Position;
out vec4 FinalColor;
uniform sampler2D from;
uniform sampler2D to;
uniform float progress;
uniform vec2 resolution;
const vec2 tileSize = vec2(128, 128);
const float checkerDistance = 0.015;
const bool flipX = true;
const bool flipY = false;
const bool preTileSingleColor = false;
const bool postTileSingleColor = false;
vec2 tile2Global(vec2 tex, vec2 tileNum, bool tileSingleColor)
{
vec2 perTile = tileSize / resolution.xy;
vec2 uv = tileNum * perTile + (tileSingleColor ? vec2(0) : tex*perTile);;
return vec2(uv.x, 1.0 - uv.y);
}
void main(void)
{
vec2 uv = gl_FragCoord.xy / resolution.xy;
uv = vec2(uv.x, 1.0 - uv.y);
FinalColor = vec4(1, 1, 0, 1);
vec2 posInTile = mod(Position, tileSize);
vec2 tileNum = floor(Position / tileSize);
int num = int(tileNum.x);
vec2 totalTiles = ceil(resolution.xy / tileSize);
float countTiles = totalTiles.x * totalTiles.y;
vec2 perTile = ceil(tileSize / resolution.xy);
float offset = 0.0;
offset = (tileNum.x + tileNum.y * totalTiles.x) / countTiles;
float timeOffset = (progress - offset) * countTiles;
timeOffset = clamp(timeOffset, 0.0, 0.5);
float sinTime = 1.0 - abs(cos(fract(timeOffset) * 3.1415926));
FinalColor.rg = uv;
FinalColor.b = sinTime;
vec2 texC = posInTile / tileSize;
if (sinTime <= 0.5)
{
if (flipX) {
if ((texC.x < sinTime) || (texC.x > 1.0 - sinTime)){
discard;
}
if (texC.x < 0.5) {
texC.x = (texC.x - sinTime) * 0.5 / (0.5 - sinTime);
} else {
texC.x = (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;
}
}
if (flipY) {
if ((texC.y < sinTime) || (texC.y > 1.0 - sinTime)){
discard;
}
if (texC.y < 0.5) {
texC.y = (texC.y - sinTime) * 0.5 / (0.5 - sinTime);
} else {
texC.y = (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;
}
}
FinalColor = texture(from, tile2Global(texC, tileNum, preTileSingleColor));
} else {
if (flipX) {
if ((texC.x > sinTime) || (texC.x < 1.0 - sinTime)){
discard;
}
if (texC.x < 0.5) {
texC.x = (texC.x - sinTime) * 0.5 / (0.5 - sinTime);
} else {
texC.x = (texC.x - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;
}
texC.x = 1.0 - texC.x;
}
if (flipY) {
if ((texC.y > sinTime) || (texC.y < 1.0 - sinTime)){
discard;
}
if (texC.y < 0.5) {
texC.y = (texC.y - sinTime) * 0.5 / (0.5 - sinTime);
} else {
texC.y = (texC.y - 0.5) * 0.5 / (0.5 - sinTime) + 0.5;
}
texC.y = 1.0 - texC.y;
}
FinalColor.rgb = texture(to, tile2Global(texC, tileNum, postTileSingleColor)).rgb;
}
} );
_shader = gl::GlslProg::create( vertex, fragment );
_shader->uniform( "from", 0 );
_shader->uniform( "to", 1 );
}
void GLSLIOApp::update()
{
_shader->uniform( "progress", _time() );
_shader->uniform( "resolution", vec2(getWindowSize()) );
}
void GLSLIOApp::draw()
{
gl::clear ( Colorf::black() );
gl::ScopedGlslProg shader ( _shader );
gl::ScopedTextureBind tex0 ( _fromImage, 0 );
gl::ScopedTextureBind tex1 ( _toImage, 1 );
gl::drawSolidRect ( getWindowBounds() );
}
CINDER_APP( GLSLIOApp, RendererGl )
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment