Created
November 4, 2016 07:22
-
-
Save axjxwright/bbbe96bd0b17420b193322e09f1e0c8a 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
#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