Skip to content
This repository has been archived by the owner on Oct 10, 2020. It is now read-only.

Commit

Permalink
Added gif image effect
Browse files Browse the repository at this point in the history
  • Loading branch information
Daandelange committed Jun 6, 2014
1 parent 58a9084 commit 762f907
Show file tree
Hide file tree
Showing 7 changed files with 297 additions and 200 deletions.
41 changes: 41 additions & 0 deletions karmaMapper.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,10 @@
859125171932569200FB75FD /* fft.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 859125131932569200FB75FD /* fft.cpp */; };
859125181932569200FB75FD /* fftOctaveAnalyzer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 859125151932569200FB75FD /* fftOctaveAnalyzer.cpp */; };
85A0B39F193E5BC80089EDAF /* videoEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85A0B39D193E5BC80089EDAF /* videoEffect.cpp */; };
85AC89011941F50A0019DA65 /* gifEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85AC88FF1941F50A0019DA65 /* gifEffect.cpp */; };
85AC89211941FCE00019DA65 /* ofxGifDecoder.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85AC89181941FCE00019DA65 /* ofxGifDecoder.cpp */; };
85AC89221941FCE00019DA65 /* ofxGifFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85AC891A1941FCE00019DA65 /* ofxGifFile.cpp */; };
85AC89231941FCE00019DA65 /* ofxGifFrame.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85AC891C1941FCE00019DA65 /* ofxGifFrame.cpp */; };
85E4A4EA1931235B00C1A046 /* ofxTrueTypeFontUC.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85E4A4E61931235B00C1A046 /* ofxTrueTypeFontUC.cpp */; };
85EE9E7118DE26ED0055FE86 /* basicEffect.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85EE9E6F18DE26ED0055FE86 /* basicEffect.cpp */; };
85EE9E7B18DE2A0F0055FE86 /* karmaMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 85EE9E7918DE2A0F0055FE86 /* karmaMapper.cpp */; };
Expand Down Expand Up @@ -136,6 +140,14 @@
859125161932569200FB75FD /* fftOctaveAnalyzer.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = fftOctaveAnalyzer.h; path = soundAnalysis/fftOctaveAnalyzer.h; sourceTree = "<group>"; };
85A0B39D193E5BC80089EDAF /* videoEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = videoEffect.cpp; path = effects/videoEffect.cpp; sourceTree = "<group>"; };
85A0B39E193E5BC80089EDAF /* videoEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = videoEffect.h; path = effects/videoEffect.h; sourceTree = "<group>"; };
85AC88FF1941F50A0019DA65 /* gifEffect.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = gifEffect.cpp; path = effects/gifEffect.cpp; sourceTree = "<group>"; };
85AC89001941F50A0019DA65 /* gifEffect.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = gifEffect.h; path = effects/gifEffect.h; sourceTree = "<group>"; };
85AC89181941FCE00019DA65 /* ofxGifDecoder.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxGifDecoder.cpp; sourceTree = "<group>"; };
85AC89191941FCE00019DA65 /* ofxGifDecoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxGifDecoder.h; sourceTree = "<group>"; };
85AC891A1941FCE00019DA65 /* ofxGifFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxGifFile.cpp; sourceTree = "<group>"; };
85AC891B1941FCE00019DA65 /* ofxGifFile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxGifFile.h; sourceTree = "<group>"; };
85AC891C1941FCE00019DA65 /* ofxGifFrame.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxGifFrame.cpp; sourceTree = "<group>"; };
85AC891D1941FCE00019DA65 /* ofxGifFrame.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxGifFrame.h; sourceTree = "<group>"; };
85D2F92218E9AD0F009EBB7B /* shapes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = shapes.h; path = src/shapes/shapes.h; sourceTree = SOURCE_ROOT; };
85E4A4D519311F2800C1A046 /* ofxTextBox.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxTextBox.h; sourceTree = "<group>"; };
85E4A4E61931235B00C1A046 /* ofxTrueTypeFontUC.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxTrueTypeFontUC.cpp; sourceTree = "<group>"; };
Expand Down Expand Up @@ -361,6 +373,8 @@
852D0CF3193920150090E770 /* effects.h */,
85EE9E6F18DE26ED0055FE86 /* basicEffect.cpp */,
85EE9E7018DE26ED0055FE86 /* basicEffect.h */,
85AC88FF1941F50A0019DA65 /* gifEffect.cpp */,
85AC89001941F50A0019DA65 /* gifEffect.h */,
852D0CF41939C7BF0090E770 /* shaderEffect.cpp */,
852D0CF51939C7BF0090E770 /* shaderEffect.h */,
85A0B39D193E5BC80089EDAF /* videoEffect.cpp */,
Expand All @@ -382,6 +396,28 @@
name = soundAnalysis;
sourceTree = "<group>";
};
85AC89021941FCE00019DA65 /* ofxGifDecoder */ = {
isa = PBXGroup;
children = (
85AC89171941FCE00019DA65 /* src */,
);
name = ofxGifDecoder;
path = ../../../addons/ofxGifDecoder;
sourceTree = "<group>";
};
85AC89171941FCE00019DA65 /* src */ = {
isa = PBXGroup;
children = (
85AC89181941FCE00019DA65 /* ofxGifDecoder.cpp */,
85AC89191941FCE00019DA65 /* ofxGifDecoder.h */,
85AC891A1941FCE00019DA65 /* ofxGifFile.cpp */,
85AC891B1941FCE00019DA65 /* ofxGifFile.h */,
85AC891C1941FCE00019DA65 /* ofxGifFrame.cpp */,
85AC891D1941FCE00019DA65 /* ofxGifFrame.h */,
);
path = src;
sourceTree = "<group>";
};
85E4A4C419311F2700C1A046 /* ofxTextBox */ = {
isa = PBXGroup;
children = (
Expand Down Expand Up @@ -466,6 +502,7 @@
8531421018D269E500165AE1 /* ofxFft */,
480A780D8D0308AE4A368801 /* ofxGui */,
1F4FB5C423662B96ADFDCC0B /* ofxXmlSettings */,
85AC89021941FCE00019DA65 /* ofxGifDecoder */,
734AC65571ADBB395C126C1A /* ofxMSAInteractiveObject */,
);
name = addons;
Expand Down Expand Up @@ -641,14 +678,17 @@
buildActionMask = 2147483647;
files = (
E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */,
85AC89011941F50A0019DA65 /* gifEffect.cpp in Sources */,
85EE9E8118DE2BEC0055FE86 /* bezierShape.cpp in Sources */,
85AC89211941FCE00019DA65 /* ofxGifDecoder.cpp in Sources */,
8531441018D269EA00165AE1 /* kiss_fftr.c in Sources */,
D1395DD979998DCFFA40ACAC /* ofxMSAInteractiveObject.cpp in Sources */,
8531440F18D269EA00165AE1 /* kiss_fft.c in Sources */,
852D0CF61939C7BF0090E770 /* shaderEffect.cpp in Sources */,
85EE9E8418DE2D440055FE86 /* basicShape.cpp in Sources */,
856AA354D08AB4B323081444 /* ofxBaseGui.cpp in Sources */,
5CBB2AB3A60F65431D7B555D /* ofxButton.cpp in Sources */,
85AC89231941FCE00019DA65 /* ofxGifFrame.cpp in Sources */,
B266578FC55D23BFEBC042E7 /* ofxGuiGroup.cpp in Sources */,
8531441118D269EA00165AE1 /* ofxEasyFft.cpp in Sources */,
483908258D00B98B4BE69F07 /* ofxLabel.cpp in Sources */,
Expand All @@ -661,6 +701,7 @@
B56FE57CC35806596D38118C /* ofxSliderGroup.cpp in Sources */,
8531441318D269EA00165AE1 /* ofxFftBasic.cpp in Sources */,
8531441218D269EA00165AE1 /* ofxFft.cpp in Sources */,
85AC89221941FCE00019DA65 /* ofxGifFile.cpp in Sources */,
85A0B39F193E5BC80089EDAF /* videoEffect.cpp in Sources */,
1CD33E884D9E3358252E82A1 /* ofxToggle.cpp in Sources */,
85EE9E8018DE2BEC0055FE86 /* movablePoint.cpp in Sources */,
Expand Down
1 change: 1 addition & 0 deletions src/effects/effects.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@
#include "basicEffect.h"
#include "shaderEffect.h"
#include "videoEffect.h"
#include "gifEffect.h"

#endif
199 changes: 199 additions & 0 deletions src/effects/gifEffect.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,199 @@
//
// gifEffect.cpp
// karmaMapper
//
// Created by Daan de Lange on 06/06/2014.
//
// - - - -
//
// Parent class for all effects.
// Implements some standard methods for overall usage.
//

#include "gifEffect.h"

gifEffect::gifEffect(){
basicEffect::basicEffect();

directory = "";
gifFiles.resize(0);
shader.load("./gifEffect/videoShader");
timePerFrame = 0.05;
loopCount = 0;
loopStartTime = ofGetElapsedTimef();
cachedGif = -1;
cachedFiles.resize(2);

numLoopsPerGif = 4;
for(int i=0;i<cachedFiles.size();i++) cachedFiles[i].setBackgroundColor( ofColor(0,0) );
}

gifEffect::~gifEffect(){
basicEffect::~basicEffect();
}

// spawns the effect @ the scene so it starts rendering (setup)
// overrule this function with your own.
void gifEffect::spawn(){
basicEffect::spawn();
}

// update --> animation
void gifEffect::render(){
// todo: what if gif contains only 1 frame ?
if( pShape==NULL || cachedGif<0 || cachedGif >= cachedFiles.size() || cachedFiles[cachedGif].getNumFrames() < 1 ) return;

//int currentFrame;

// looped ?
if(loopStartTime + timePerFrame*numLoopsPerGif*cachedFiles[cachedGif].getNumFrames() < ofGetElapsedTimef() ){
//cachedGif++;
//cachedGif = cachedGif%cachedFiles.size();

if( loadGif( (currentGif+1)%gifFiles.size() ) ){
loopStartTime = ofGetElapsedTimef();
}
// todo: skip gif if stuck/fail
else {

}
}

// calc current frame Nb
//timePerFrame = cachedFiles[cachedGif].getDuration() / cachedFiles[cachedGif].getNumFrames();
int currentFrame = (int) floor( (ofGetElapsedTimef() - loopStartTime) /(timePerFrame) ) % (int) cachedFiles[cachedGif].getNumFrames();


// load shader
shader.begin();
shader.setUniformTexture("tex0", *cachedFiles[cachedGif].getFrameAt(currentFrame)->getRawTexture() , 0);
shader.setUniform2f("resolution", pShape->boundingBox.width, pShape->boundingBox.height);
shader.setUniform2f("textureResolution", cachedFiles[cachedGif].getWidth(), cachedFiles[cachedGif].getHeight() );
shader.setUniform2f("shapeCenterOffset", pShape->getCenterOffsetFromBoundingBox().x, pShape->getCenterOffsetFromBoundingBox().y);
shader.setUniform1f("textureScale", 1);

// draw shape so GPU gets their vertex data
pShape->render();

// flush the pipeline! :D
shader.end();

}

void gifEffect::update(){
basicEffect::update();

//stream.update();

// tmp
if( ofGetKeyPressed('r') ){
shader.load("./gifEffect/videoShader");
cout << "Shader reloaded"<<endl;
}
}

// resets all values
// overrule this function with your own.
void gifEffect::reset(){
basicEffect::reset();
}

// called just before removal
void gifEffect::destroy(){
basicEffect::destroy();
}

bool gifEffect::setDirectory(string _dir){
// already set ?
if(_dir==directory) return true;

ofDirectory dir(_dir);


if( !dir.exists() || !dir.canRead() ){
ofLogNotice("gifEffect") << "Unable to load " << _dir << endl;
return false;
}
else{
// default video path
if(directory=="") directory="./gifEffect/gifs/";

dir.allowExt("gif");
dir.sort();
dir.listDir(_dir);


if(dir.size()==0){
if(!dir.exists()){
ofLogNotice("gifEffect") << "Folder «" << _dir << "» doesn't exist." << endl;
}
else if(!dir.canRead()){
ofLogNotice("gifEffect") << "Folder «" << _dir << "» is not readable." << endl;
}
else if(!dir.isDirectory()){
ofLogNotice("gifEffect") << "Folder «" << _dir << "» is not a directory." << endl;
}
else ofLogNotice("gifEffect") << "Folder «" << _dir << "» gif files." << endl;
}
else ofLogVerbose("gifEffect") << "Scanning «" << _dir << "» ... Found " << ofToString(dir.size()) << " file(s) (.gif) [readable=" << dir.canRead() << "] [isDirectory=" << ofToString(dir.isDirectory()) << "]" << endl;

// get videos
gifFiles.resize(0);
for(int i=0; i<dir.size(); i++){
// test videos before adding... HEAVY (remove this check for performence?)
//if(decoder.decode( dir.getPath(i) )){
gifFiles.push_back( dir.getName(i) );
//decoder.reset();
//}
//else {
// ofLogNotice("gifEffect") << "Could not add " << dir.getPath(i);
//}
}

directory = _dir;

//loadRandomGif();
loadGif(0);
}

return true;
}

bool gifEffect::loadRandomGif(){
return loadGif( (int)ofRandom(-.49, gifFiles.size()-.51) );
}

bool gifEffect::loadGif(int gifID){
if(gifID < 0 || gifID >= gifFiles.size() ) return false;

string tmp = ofToString(directory+"/"+gifFiles[gifID]);
if( decoder.decode( tmp ) ){
cachedGif = (cachedGif+1)%cachedFiles.size();
cachedFiles[ cachedGif ] = decoder.getFile();
pShape->hasError = false;
ofLogVerbose("gifEffect") << "Successfully loaded movie: " << gifFiles[gifID] << endl;
currentGif = gifID;

return true;
}
else{
ofLogNotice("gifEffect") << "Could not load "+ directory+"/"+gifFiles[gifID] << endl;;
pShape->hasError = true;
cachedGif = -1;
return false;
}
}

// not: string must exist in gifFiles
bool gifEffect::loadGif(string videoName){
int found = -1;

for(int i=0; i<gifFiles.size(); i++){
if(gifFiles[i]==videoName){
found=i;
break;
}
}

return (found<0)?false:loadGif(found);
}
45 changes: 45 additions & 0 deletions src/effects/gifEffect.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
//
// gifEffect.h
// karmaMapper
//
// Created by Daan de Lange on 06/06/2014.
//
//

#pragma once

#include "ofMain.h"
#include "basicEffect.h"
#include "ofxGifDecoder.h"

class gifEffect : public basicEffect {

public:
gifEffect();
~gifEffect();

virtual void spawn();
virtual void render();
virtual void update();
virtual void reset();
virtual void destroy();

bool setDirectory(string _dir);
bool loadRandomGif();
bool loadGif(int videoID);
bool loadGif(string videoName);

protected:
vector<string> gifFiles;
string directory;
ofShader shader;

unsigned int numLoopsPerGif;
unsigned int loopCount;
unsigned int currentGif;
float loopStartTime;
float timePerFrame;
ofxGifDecoder decoder;
vector<ofxGifFile> cachedFiles;
int cachedGif; // cachedFiles is for precaching... this tells which one is being used
};
15 changes: 11 additions & 4 deletions src/karmaMapper.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
#include "karmaMapper.h"

#define KARMA_DEBUG true;
//#define KARMA_DEBUG true;

// todo : pop effects handling out of this class and let an effectsControllerClass handle their renderings, transitions and so on.

Expand Down Expand Up @@ -34,20 +34,27 @@ void karmaMapper::setup(){
//ofSoundStreamSetup(0,2,this, 44100, BUFFER_SIZE, 4);

// populate effects with current setup
if( false && rwi.shapeExists(0) ){
if( rwi.shapeExists(0) ){
shaderEffect* tmpEffect = new shaderEffect();
tmpEffect->spawn();
tmpEffect->bindWithShape( rwi.getShape(0) );
tmpEffect->loadShader( "", "./shaders/menger_journey_ok.frag" );
effects.push_back( tmpEffect );
}
if( rwi.shapeExists(1) ){
if( false && rwi.shapeExists(0) ){
videoEffect* tmpEffect = new videoEffect();
tmpEffect->spawn();
tmpEffect->bindWithShape( rwi.getShape(1) );
tmpEffect->bindWithShape( rwi.getShape(0) );
tmpEffect->setDirectory("./videoEffect/videos");
effects.push_back( tmpEffect );
}
if( false && rwi.shapeExists(1) ){
gifEffect* tmpEffect = new gifEffect();
tmpEffect->spawn();
tmpEffect->bindWithShape( rwi.getShape(1) );
tmpEffect->setDirectory("./gifEffect/gifs");
effects.push_back( tmpEffect );
}

//shader.linkProgram();
//cout << "Link status:" << shader.linkProgram() << endl;
Expand Down
Loading

0 comments on commit 762f907

Please sign in to comment.