├── resources ├── CinderApp.icns ├── images │ ├── pizza.jpg │ └── svvim-logo-white.png ├── pass.vert ├── project.vert ├── hblur.frag ├── vblur.frag └── project.frag ├── include └── Resources.h ├── xcode ├── SvvimGram.xcodeproj │ ├── project.xcworkspace │ │ └── contents.xcworkspacedata │ └── project.pbxproj ├── SvvimGram_Prefix.pch ├── Info.plist ├── InstagramStream.h ├── AsynchMovieWriter.h └── InstagramStream.cpp ├── README.md ├── src ├── SodaCan.h ├── svvim.h ├── SvvimScene.h ├── SvvimPost.h ├── InstagramStream.h ├── AsynchMovieWriter.h ├── ProjectionScene.h ├── SvvimGramApp.cpp ├── InstagramStream.cpp └── InstagramProjectionScene.h └── .gitignore /resources/CinderApp.icns: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatever/SvvimGram/master/resources/CinderApp.icns -------------------------------------------------------------------------------- /resources/images/pizza.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatever/SvvimGram/master/resources/images/pizza.jpg -------------------------------------------------------------------------------- /resources/images/svvim-logo-white.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/whatever/SvvimGram/master/resources/images/svvim-logo-white.png -------------------------------------------------------------------------------- /include/Resources.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cinder/CinderResources.h" 3 | 4 | //#define RES_MY_RES CINDER_RESOURCE( ../resources/, image_name.png, 128, IMAGE ) 5 | 6 | 7 | 8 | 9 | -------------------------------------------------------------------------------- /xcode/SvvimGram.xcodeproj/project.xcworkspace/contents.xcworkspacedata: -------------------------------------------------------------------------------- 1 | 2 | 4 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /resources/pass.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | void main () { 4 | gl_TexCoord[0] = gl_MultiTexCoord0; 5 | gl_Position = gl_ProjectionMatrix * gl_ModelViewMatrix * gl_Vertex;; 6 | gl_FrontColor = gl_Color; 7 | gl_BackColor = vec4(0.f, 0.f, 0.f, 1.f); 8 | } -------------------------------------------------------------------------------- /xcode/SvvimGram_Prefix.pch: -------------------------------------------------------------------------------- 1 | #ifdef __OBJC__ 2 | #import 3 | #endif 4 | 5 | #if defined( __cplusplus ) 6 | #include "cinder/Cinder.h" 7 | 8 | #include "cinder/app/AppBasic.h" 9 | 10 | #include "cinder/gl/gl.h" 11 | 12 | #include "cinder/CinderMath.h" 13 | #include "cinder/Matrix.h" 14 | #include "cinder/Vector.h" 15 | #include "cinder/Quaternion.h" 16 | #endif 17 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SvvimGram 2 | 3 | Instagram -> Cocoa App -> GIF/Mpeg-4/Tumblr 4 | 5 | # About 6 | 7 | SvvimGram is an art piece coded in Cocoa, err, C++/OpenGL via Cinder. It navigates Instagram streams and projects realtime video on rotating 3D objects. 8 | 9 | # License 10 | 11 | No one use this. It's just for show. 12 | 13 | # Author 14 | 15 | (@mattvvhatever)[https://twitter.com/mattvvhatever] 16 | -------------------------------------------------------------------------------- /src/SodaCan.h: -------------------------------------------------------------------------------- 1 | // 2 | // SodaCan.h 3 | // SvvimGram 4 | // 5 | // Created by Matthew Owen on 1/7/14. 6 | // 7 | // 8 | 9 | #ifndef SvvimGram_SodaCan_h 10 | #define SvvimGram_SodaCan_h 11 | 12 | namespace svvim { 13 | struct SodaCan { 14 | gl::VboMeshRef mesh; 15 | Vec3f position; 16 | Vec3f r0; 17 | Vec3f r1; 18 | }; 19 | 20 | void drawSodaCan(const SodaCan & obj, float t = 0.f) { 21 | Vec3f rotation = obj.r0 + 360 * t * Vec3f(1, -1, 1); 22 | gl::pushMatrices(); 23 | gl::translate(obj.position); 24 | gl::rotate(rotation); 25 | gl::draw(obj.mesh); 26 | gl::popMatrices(); 27 | } 28 | }; 29 | 30 | 31 | #endif 32 | -------------------------------------------------------------------------------- /resources/project.vert: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform int count = 4; 4 | 5 | varying vec4 ecPosition; 6 | varying vec3 ecPosition3; 7 | varying vec3 normal; 8 | varying vec4 ambientGlobal; 9 | varying vec4 projCoord; 10 | const int xxx = 3; 11 | uniform mat4 shadowMatrices[xxx]; 12 | 13 | varying vec4 projCoors[3]; 14 | 15 | void main() 16 | { 17 | ecPosition = gl_ModelViewMatrix * gl_Vertex; 18 | ecPosition3 = ecPosition.xyz/ecPosition.w; 19 | 20 | projCoord = shadowMatrices[0] * ecPosition; 21 | 22 | normal = gl_NormalMatrix * gl_Normal; 23 | gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex; 24 | 25 | ambientGlobal = gl_LightModel.ambient * gl_FrontMaterial.ambient; 26 | } -------------------------------------------------------------------------------- /resources/hblur.frag: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform sampler2D texture; 4 | uniform float size = 1/1024.f; 5 | 6 | const float offset[3] = float[] (0.0, 1.3846153846, 3.2307692308); 7 | const float weight[3] = float[] (0.2270270270, 0.3162162162, 0.0702702703); 8 | 9 | float luminance (vec4 color) { 10 | return dot(vec3(.17f, .51f, .32f), color.rgb); 11 | } 12 | 13 | void main () { 14 | vec2 coord = gl_TexCoord[0].xy; 15 | 16 | vec4 color = texture2D(texture, coord) * weight[0]; 17 | float s = 4.f * size; 18 | color += texture2D(texture, coord + vec2(offset[1], 0)*s) * weight[1]; 19 | color += texture2D(texture, coord - vec2(offset[1], 0)*s) * weight[1]; 20 | color += texture2D(texture, coord + vec2(offset[2], 0)*s) * weight[2]; 21 | color += texture2D(texture, coord - vec2(offset[2], 0)*s) * weight[2]; 22 | 23 | gl_FragColor = color; 24 | } -------------------------------------------------------------------------------- /resources/vblur.frag: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | uniform sampler2D texture; 4 | uniform float size = 1/1024.f; 5 | 6 | const float offset[3] = float[] (0.0, 1.3846153846, 3.2307692308); 7 | const float weight[3] = float[] (0.2270270270, 0.3162162162, 0.0702702703); 8 | 9 | float luminance (vec4 color) { 10 | return dot(vec3(.17f, .51f, .32f), color.rgb); 11 | } 12 | 13 | void main () { 14 | vec2 coord = gl_TexCoord[0].xy; 15 | 16 | vec4 color = texture2D(texture, coord) * weight[0]; 17 | float s = 4.f * size; 18 | color += texture2D(texture, coord + vec2(0, offset[1])*s) * weight[1]; 19 | color += texture2D(texture, coord - vec2(0, offset[1])*s) * weight[1]; 20 | color += texture2D(texture, coord + vec2(0, offset[2])*s) * weight[2]; 21 | color += texture2D(texture, coord - vec2(0, offset[2])*s) * weight[2]; 22 | 23 | gl_FragColor = color; 24 | } -------------------------------------------------------------------------------- /xcode/Info.plist: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | CFBundleDevelopmentRegion 6 | en 7 | CFBundleExecutable 8 | ${EXECUTABLE_NAME} 9 | CFBundleIconFile 10 | CinderApp.icns 11 | CFBundleIdentifier 12 | org.libcinder.${PRODUCT_NAME:rfc1034identifier} 13 | CFBundleInfoDictionaryVersion 14 | 6.0 15 | CFBundleName 16 | ${PRODUCT_NAME} 17 | CFBundlePackageType 18 | APPL 19 | CFBundleShortVersionString 20 | 1.0 21 | CFBundleSignature 22 | ???? 23 | CFBundleVersion 24 | 1 25 | LSMinimumSystemVersion 26 | ${MACOSX_DEPLOYMENT_TARGET} 27 | NSHumanReadableCopyright 28 | Copyright © 2013 __MyCompanyName__. All rights reserved. 29 | NSMainNibFile 30 | MainMenu 31 | NSPrincipalClass 32 | NSApplication 33 | 34 | 35 | -------------------------------------------------------------------------------- /src/svvim.h: -------------------------------------------------------------------------------- 1 | // 2 | // svvim.h 3 | // SvvimGram 4 | // 5 | // Created by Matthew Owen on 1/6/14. 6 | // 7 | // 8 | 9 | #ifndef SvvimGram_svvim_h 10 | #define SvvimGram_svvim_h 11 | 12 | namespace svvim { 13 | 14 | 15 | /** 16 | * Random Uniform Float on [a , b] 17 | * @param {float} a the lower bound on the random uniform float 18 | * @param {float} b the upper bound on the random uniform float 19 | * @return {float} a random float x, s.t. a <= x <= b 20 | */ 21 | float random (float a, float b) { 22 | float x = rand() / (float) RAND_MAX; 23 | return a + (b-a) * x; 24 | } 25 | 26 | 27 | class TimeCounter { 28 | public: 29 | TimeCounter() { 30 | mStart = clock(); 31 | mSinceTime = clock(); 32 | } 33 | float getElapsedSeconds () { 34 | mLast = mNow; 35 | mNow = clock(); 36 | mSince = mNow - mLast; 37 | return (float) (mNow - mStart) / CLOCKS_PER_SEC; 38 | } 39 | float since () { 40 | clock_t now = clock(); 41 | mNow = now; 42 | mSince = now - mSinceTime; 43 | mSinceTime = now; 44 | return mSince; 45 | } 46 | private: 47 | clock_t mStart; 48 | clock_t mLast; 49 | clock_t mNow; 50 | float mSince; 51 | float mSinceTime; 52 | }; 53 | 54 | 55 | 56 | namespace cinder { 57 | 58 | // 1 59 | 60 | namespace ci = cinder; 61 | } 62 | } 63 | 64 | namespace svv = svvim; 65 | 66 | #endif -------------------------------------------------------------------------------- /src/SvvimScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // SvvimScene.h 3 | // SvvimCommercial 4 | // 5 | // Created by Matthew Owen on 8/6/13. 6 | // 7 | // 8 | 9 | #pragma once 10 | #ifndef _SvvimScene_h 11 | #define _SvvimScene_h 12 | 13 | #include "cinder/app/AppNative.h" 14 | #include "cinder/gl/gl.h" 15 | #include "cinder/gl/GlslProg.h" 16 | #include "cinder/gl/Texture.h" 17 | #include "cinder/gl/Fbo.h" 18 | #include "cinder/qtime/QuickTime.h" 19 | 20 | using namespace ci; 21 | using namespace ci::app; 22 | using namespace std; 23 | 24 | class SvvimScene { 25 | public: 26 | // Constructors 27 | SvvimScene() {} 28 | 29 | // 30 | // The usual collection 31 | virtual void setup() {} 32 | virtual void update() {} 33 | virtual void draw() {} 34 | 35 | // Access State 36 | virtual bool isLoaded() { return true; }; 37 | virtual bool isDone() { return false; }; 38 | 39 | 40 | 41 | // RENDER 42 | gl::Texture & render() { 43 | mRenderFbo.bindFramebuffer(); 44 | gl::clear(Color(1, 1, 1)); 45 | draw(); 46 | mRenderFbo.unbindFramebuffer(); 47 | return mRenderFbo.getTexture(); 48 | } 49 | 50 | 51 | // Set Parameters 52 | void set(std::string key, float val) { 53 | mParams[key] = val; 54 | } 55 | 56 | float getElapsedSeconds() { 57 | if (mAppRef) { 58 | return mAppRef->getElapsedSeconds() - mStartTime; 59 | } 60 | return -1.f; 61 | } 62 | protected: 63 | gl::Fbo mRenderFbo; 64 | 65 | App * mAppRef; 66 | bool mIsLoaded, mIsDone; 67 | float mAlpha, mBeta, mGamma; 68 | std::map mParams; 69 | 70 | float mStartTime; 71 | 72 | gl::GlslProg mShader; 73 | }; 74 | 75 | #endif 76 | -------------------------------------------------------------------------------- /src/SvvimPost.h: -------------------------------------------------------------------------------- 1 | // 2 | // SvvimPost.h 3 | // SvvimGram 4 | // 5 | // Created by Matthew Owen on 1/6/14. 6 | // 7 | // 8 | 9 | #ifndef SvvimGram_SvvimPost_h 10 | #define SvvimGram_SvvimPost_h 11 | 12 | #include "cinder/app/App.h" 13 | #include "cinder/gl/gl.h" 14 | #include "cinder/gl/Texture.h" 15 | #include "cinder/gl/GlslProg.h" 16 | #include "cinder/gl/Fbo.h" 17 | 18 | using namespace cinder; 19 | using namespace cinder::gl; 20 | using namespace ci::app; 21 | using namespace std; 22 | 23 | class SvvimPost { 24 | public: 25 | 26 | 27 | SvvimPost() { 28 | 29 | } 30 | 31 | void setup () { 32 | mFirstPassFbo = Fbo(500, 500); 33 | mSecondPassFbo = Fbo(500, 500); 34 | HBLUR = GlslProg(loadResource("pass.vert"), loadResource("hblur.frag")); 35 | VBLUR = GlslProg(loadResource("pass.vert"), loadResource("vblur.frag")); 36 | } 37 | 38 | gl::Texture applyBlur( const gl::Texture &texture, const float amount); 39 | 40 | 41 | private: 42 | GlslProg CRUSH; 43 | GlslProg HBLUR; 44 | GlslProg VBLUR; 45 | 46 | Fbo mFirstPassFbo, mSecondPassFbo; 47 | }; 48 | 49 | gl::Texture SvvimPost::applyBlur(const gl::Texture &texture, const float amount) { 50 | gl::pushMatrices(); 51 | 52 | float a = amount/getWindowWidth(); 53 | 54 | // Apply vertical blur shader 55 | { 56 | glClearColor(.2, .2, .2, 1); 57 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 58 | SvvimPost::HBLUR.bind(); 59 | SvvimPost::HBLUR.uniform("texture", 0); 60 | SvvimPost::HBLUR.uniform("size", (float) a); 61 | mFirstPassFbo.bindFramebuffer(); 62 | texture.bind(0); 63 | gl::setMatricesWindow(getWindowWidth(), getWindowHeight()); 64 | gl::clear(ColorA(0, 0, 0, 0)); 65 | gl::color(1, 1, 1); 66 | gl::drawSolidRect(mFirstPassFbo.getBounds()); 67 | texture.unbind(0); 68 | mFirstPassFbo.unbindFramebuffer(); 69 | VBLUR.unbind(); 70 | } 71 | 72 | // Apply horizontal blur shader 73 | { 74 | glClearColor(.2, .2, .2, 1); 75 | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); 76 | VBLUR.bind(); 77 | VBLUR.uniform("texture", 0); 78 | VBLUR.uniform("size", (float) a); 79 | mSecondPassFbo.bindFramebuffer(); 80 | mFirstPassFbo.bindTexture(0); 81 | gl::setMatricesWindow(getWindowWidth(), getWindowHeight()); 82 | gl::clear(ColorA(0, 0, 0, 0)); 83 | gl::color(1, 1, 1); 84 | gl::drawSolidRect(mSecondPassFbo.getBounds()); 85 | mFirstPassFbo.unbindTexture(); 86 | mSecondPassFbo.unbindFramebuffer(); 87 | VBLUR.unbind(); 88 | } 89 | 90 | gl::popMatrices(); 91 | return mSecondPassFbo.getTexture(); 92 | } 93 | 94 | #endif 95 | -------------------------------------------------------------------------------- /src/InstagramStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstagramStream.h 3 | // InstagramTest 4 | // 5 | // Created by Greg Kepler on 6/9/12. 6 | // Copyright (c) 2012 The Barbarian Group. All rights reserved. 7 | // 8 | 9 | 10 | #pragma once 11 | 12 | #include "cinder/app/AppBasic.h" 13 | #include "cinder/Surface.h" 14 | #include "cinder/ConcurrentCircularBuffer.h" 15 | #include "cinder/Thread.h" 16 | #include "cinder/Url.h" 17 | #include 18 | 19 | // Hacking on InstagramVideo 20 | #include "cinder/qtime/QuickTime.h" 21 | 22 | class Instagram { 23 | public: 24 | Instagram() {} 25 | Instagram( const std::string &user, const std::string &imageUrl, const ci::Surface &image ) : 26 | mUser( user ), 27 | mImageUrl( imageUrl ), 28 | mImage (image) { 29 | } 30 | 31 | Instagram( const std::string &user, const std::string &videoUrl, const ci::qtime::MovieLoader & movieLoader ) : 32 | mUser(user), 33 | mVideoUrl(videoUrl) 34 | { 35 | cinder::Url url = cinder::Url(videoUrl); 36 | mMovieLoader = mMovieLoader; 37 | } 38 | 39 | const std::string& getUser() const { return mUser; } 40 | 41 | 42 | const bool hasVideoUrl() const { return !mVideoUrl.empty(); } 43 | const std::string& getVideoUrl() const { return mVideoUrl; } 44 | 45 | const bool hasImageUrl() const { return !mImageUrl.empty(); } 46 | const std::string& getImageUrl() const { return mImageUrl; } 47 | const ci::Surface& getImage() const { return mImage; } 48 | 49 | bool isNull() const { return mImageUrl.empty(); } 50 | 51 | private: 52 | cinder::qtime::MovieLoader mMovieLoader; 53 | std::string mUser, mImageUrl, mVideoUrl; 54 | ci::Surface mImage; 55 | }; 56 | 57 | 58 | 59 | class InstagramStream { 60 | public: 61 | // popular images 62 | InstagramStream( const std::string &clientId ); 63 | 64 | // images with a specific tag 65 | InstagramStream( const std::string &searchPhrase, const std::string &clientId ); 66 | InstagramStream( const std::string &searchPhrase, const int &minId, const int &maxId, const std::string &clientId ); 67 | 68 | // Search for media in a given area. 69 | InstagramStream( ci::Vec2f loc, float dist, int minTs, int maxTs, std::string clientId); 70 | InstagramStream( ci::Vec2f loc, float dist, std::string clientId); 71 | InstagramStream( ci::Vec2f loc, std::string clientId); 72 | 73 | ~InstagramStream(); 74 | 75 | bool hasInstagramAvailable(); 76 | Instagram getNextInstagram(); 77 | bool isConnected(); 78 | 79 | protected: 80 | void startThread( std::string url ); 81 | void serviceGrams( std::string url ); 82 | 83 | std::string mSearchPhrase; 84 | std::shared_ptr mThread; 85 | ci::ConcurrentCircularBuffer mBuffer; 86 | bool mCanceled; 87 | bool mIsConnected; 88 | std::string mClientId; 89 | }; -------------------------------------------------------------------------------- /xcode/InstagramStream.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstagramStream.h 3 | // InstagramTest 4 | // 5 | // Created by Greg Kepler on 6/9/12. 6 | // Copyright (c) 2012 The Barbarian Group. All rights reserved. 7 | // 8 | 9 | 10 | #pragma once 11 | 12 | #include "cinder/app/AppBasic.h" 13 | #include "cinder/Surface.h" 14 | #include "cinder/ConcurrentCircularBuffer.h" 15 | #include "cinder/Thread.h" 16 | #include "cinder/Url.h" 17 | #include 18 | 19 | // Hacking on InstagramVideo 20 | #include "cinder/qtime/QuickTime.h" 21 | 22 | class Instagram { 23 | public: 24 | Instagram() {} 25 | Instagram( const std::string &user, const std::string &imageUrl, const ci::Surface &image ) : 26 | mUser( user ), 27 | mImageUrl( imageUrl ), 28 | mImage (image) { 29 | } 30 | 31 | Instagram( const std::string &user, const std::string &videoUrl, const ci::qtime::MovieLoader & movieLoader ) : 32 | mUser(user), 33 | mVideoUrl(videoUrl) 34 | { 35 | cinder::Url url = cinder::Url(videoUrl); 36 | mMovieLoader = mMovieLoader; 37 | } 38 | 39 | const std::string& getUser() const { return mUser; } 40 | 41 | 42 | const bool hasVideoUrl() const { return !mVideoUrl.empty(); } 43 | const std::string& getVideoUrl() const { return mVideoUrl; } 44 | 45 | const bool hasImageUrl() const { return !mImageUrl.empty(); } 46 | const std::string& getImageUrl() const { return mImageUrl; } 47 | const ci::Surface& getImage() const { return mImage; } 48 | 49 | bool isNull() const { return mImageUrl.empty(); } 50 | 51 | private: 52 | cinder::qtime::MovieLoader mMovieLoader; 53 | std::string mUser, mImageUrl, mVideoUrl; 54 | ci::Surface mImage; 55 | }; 56 | 57 | 58 | 59 | class InstagramStream { 60 | public: 61 | // popular images 62 | InstagramStream( const std::string &clientId ); 63 | 64 | // images with a specific tag 65 | InstagramStream( const std::string &searchPhrase, const std::string &clientId ); 66 | InstagramStream( const std::string &searchPhrase, const int &minId, const int &maxId, const std::string &clientId ); 67 | 68 | // Search for media in a given area. 69 | InstagramStream( ci::Vec2f loc, float dist, int minTs, int maxTs, std::string clientId); 70 | InstagramStream( ci::Vec2f loc, float dist, std::string clientId); 71 | InstagramStream( ci::Vec2f loc, std::string clientId); 72 | 73 | ~InstagramStream(); 74 | 75 | bool hasInstagramAvailable(); 76 | Instagram getNextInstagram(); 77 | bool isConnected(); 78 | 79 | protected: 80 | void startThread( std::string url ); 81 | void serviceGrams( std::string url ); 82 | 83 | std::string mSearchPhrase; 84 | std::shared_ptr mThread; 85 | ci::ConcurrentCircularBuffer mBuffer; 86 | bool mCanceled; 87 | bool mIsConnected; 88 | std::string mClientId; 89 | }; -------------------------------------------------------------------------------- /src/AsynchMovieWriter.h: -------------------------------------------------------------------------------- 1 | // 2 | // AsynchMovieWriter.h 3 | // Projected 4 | // 5 | // Created by Matthew Owen on 1/6/14. 6 | // 7 | // 8 | 9 | #pragma once 10 | 11 | #include "cinder/qtime/MovieWriter.h" 12 | #include "cinder/ImageIo.h" 13 | #include "cinder/Thread.h" 14 | #include "cinder/gl/Texture.h" 15 | 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | using namespace ci; 21 | using namespace ci::app; 22 | 23 | using namespace cinder; 24 | using namespace cinder::qtime; 25 | 26 | class AsynchMovieWriter { 27 | public: 28 | 29 | // Useless constructor 30 | AsynchMovieWriter() : mClosing(true) { 31 | app::console() << "WARNING: Using bad default constructor\n"; 32 | } 33 | 34 | // Useful constructor 35 | AsynchMovieWriter (const fs::path &path, int32_t width, int32_t height, const qtime::MovieWriter::Format & format = qtime::MovieWriter::Format()) { 36 | mClosing = false; 37 | mPath = path; 38 | mFormat = format; 39 | // MovieWriter 40 | mMovieWriter = qtime::MovieWriter::create(mPath, width, height, mFormat); 41 | // Thread 42 | mThread = make_shared( bind(&AsynchMovieWriter::processFrames, this) ); 43 | } 44 | 45 | // Destructor 46 | ~AsynchMovieWriter () { 47 | mClosing = true; 48 | mThread->join(); 49 | } 50 | 51 | // Addframe 52 | void addFrame (const ImageSourceRef &imageSource, float duration = -1.0f) { 53 | Frame frame; 54 | frame.image = imageSource; 55 | frame.duration = duration; 56 | // Accessing mFrames requires a lock 57 | mLatch.lock(); 58 | mFrames.push(frame); 59 | mLatch.unlock(); 60 | } 61 | 62 | 63 | private: 64 | 65 | // Ongoing loop that only dies at end 66 | void processFrames () { 67 | while (!mClosing) { 68 | while (mFrames.size() > 0) { 69 | Frame frame = mFrames.front(); 70 | // Ensure that multiple frames aren't being written and that 71 | // mFrames access doesn't happen simultaneously 72 | mLatch.lock(); 73 | mMovieWriter->addFrame(frame.image, frame.duration); 74 | mFrames.pop(); 75 | mLatch.unlock(); 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * FRAME STRUCT 82 | * image : an image reference to be used with 83 | * duration : duration of the frame 84 | */ 85 | struct Frame { 86 | ImageSourceRef image; 87 | float duration; 88 | }; 89 | 90 | // Queue of frame objects 91 | std::queue mFrames; 92 | // Thread stuff 93 | bool mClosing; 94 | std::mutex mLatch; 95 | std::shared_ptr mThread; 96 | // Recorded variables 97 | fs::path mPath; 98 | qtime::MovieWriter::Format mFormat; 99 | qtime::MovieWriterRef mMovieWriter; 100 | }; -------------------------------------------------------------------------------- /xcode/AsynchMovieWriter.h: -------------------------------------------------------------------------------- 1 | // 2 | // AsynchMovieWriter.h 3 | // Projected 4 | // 5 | // Created by Matthew Owen on 1/6/14. 6 | // 7 | // 8 | 9 | #pragma once 10 | 11 | #include "cinder/qtime/MovieWriter.h" 12 | #include "cinder/ImageIo.h" 13 | #include "cinder/Thread.h" 14 | #include "cinder/gl/Texture.h" 15 | 16 | #include 17 | #include 18 | 19 | using namespace std; 20 | using namespace ci; 21 | using namespace ci::app; 22 | 23 | using namespace cinder; 24 | using namespace cinder::qtime; 25 | 26 | class AsynchMovieWriter { 27 | public: 28 | 29 | // Useless constructor 30 | AsynchMovieWriter() : mClosing(true) { 31 | app::console() << "WARNING: Using bad default constructor\n"; 32 | } 33 | 34 | // Useful constructor 35 | AsynchMovieWriter (const fs::path &path, int32_t width, int32_t height, const qtime::MovieWriter::Format & format = qtime::MovieWriter::Format()) { 36 | mClosing = false; 37 | mPath = path; 38 | mFormat = format; 39 | // MovieWriter 40 | // mMovieWriter = qtime::MovieWriter::create(mPath, width, height, mFormat); 41 | // Thread 42 | mThread = make_shared( bind(&AsynchMovieWriter::processFrames, this) ); 43 | } 44 | 45 | // Destructor 46 | ~AsynchMovieWriter () { 47 | mClosing = true; 48 | mThread->join(); 49 | } 50 | 51 | // Addframe 52 | void addFrame (const ImageSourceRef &imageSource, float duration = -1.0f) { 53 | Frame frame; 54 | frame.image = imageSource; 55 | frame.duration = duration; 56 | // Accessing mFrames requires a lock 57 | mLatch.lock(); 58 | mFrames.push(frame); 59 | mLatch.unlock(); 60 | } 61 | 62 | 63 | private: 64 | 65 | // Ongoing loop that only dies at end 66 | void processFrames () { 67 | while (!mClosing || mFrames.size() > 0)) { 68 | while (mFrames.size() > 0) { 69 | Frame frame = mFrames.front(); 70 | // Ensure that multiple frames aren't being written and that 71 | // mFrames access doesn't happen simultaneously 72 | mLatch.lock(); 73 | mMovieWriter->addFrame(frame.image, frame.duration); 74 | mFrames.pop(); 75 | mLatch.unlock(); 76 | } 77 | } 78 | } 79 | 80 | /** 81 | * FRAME STRUCT 82 | * image : an image reference to be used with 83 | * duration : duration of the frame 84 | */ 85 | struct Frame { 86 | ImageSourceRef image; 87 | float duration; 88 | }; 89 | 90 | // Queue of frame objects 91 | std::queue mFrames; 92 | // Thread stuff 93 | bool mClosing; 94 | std::mutex mLatch; 95 | std::shared_ptr mThread; 96 | // Recorded variables 97 | fs::path mPath; 98 | qtime::MovieWriter::Format mFormat; 99 | qtime::MovieWriterRef mMovieWriter; 100 | }; -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ######################### 2 | # .gitignore file for Xcode4 / OS X Source projects 3 | # 4 | # Version 2.0 5 | # For latest version, see: http://stackoverflow.com/questions/49478/git-ignore-file-for-xcode-projects 6 | # 7 | # 2013 updates: 8 | # - fixed the broken "save personal Schemes" 9 | # 10 | # NB: if you are storing "built" products, this WILL NOT WORK, 11 | # and you should use a different .gitignore (or none at all) 12 | # This file is for SOURCE projects, where there are many extra 13 | # files that we want to exclude 14 | # 15 | ######################### 16 | 17 | ##### 18 | # OS X temporary files that should never be committed 19 | 20 | .DS_Store 21 | *.swp 22 | *.lock 23 | profile 24 | 25 | 26 | #### 27 | # Xcode temporary files that should never be committed 28 | # 29 | # NB: NIB/XIB files still exist even on Storyboard projects, so we want this... 30 | 31 | *~.nib 32 | 33 | 34 | #### 35 | # Xcode build files - 36 | # 37 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "DerivedData" 38 | 39 | DerivedData/ 40 | 41 | # NB: slash on the end, so we only remove the FOLDER, not any files that were badly named "build" 42 | 43 | build/ 44 | 45 | 46 | ##### 47 | # Xcode private settings (window sizes, bookmarks, breakpoints, custom executables, smart groups) 48 | # 49 | # This is complicated: 50 | # 51 | # SOMETIMES you need to put this file in version control. 52 | # Apple designed it poorly - if you use "custom executables", they are 53 | # saved in this file. 54 | # 99% of projects do NOT use those, so they do NOT want to version control this file. 55 | # ..but if you're in the 1%, comment out the line "*.pbxuser" 56 | 57 | *.pbxuser 58 | *.mode1v3 59 | *.mode2v3 60 | *.perspectivev3 61 | # NB: also, whitelist the default ones, some projects need to use these 62 | !default.pbxuser 63 | !default.mode1v3 64 | !default.mode2v3 65 | !default.perspectivev3 66 | 67 | 68 | #### 69 | # Xcode 4 - semi-personal settings 70 | # 71 | # 72 | # OPTION 1: --------------------------------- 73 | # throw away ALL personal settings (including custom schemes! 74 | # - unless they are "shared") 75 | # 76 | # NB: this is exclusive with OPTION 2 below 77 | xcuserdata 78 | 79 | # OPTION 2: --------------------------------- 80 | # get rid of ALL personal settings, but KEEP SOME OF THEM 81 | # - NB: you must manually uncomment the bits you want to keep 82 | # 83 | # NB: this is exclusive with OPTION 1 above 84 | # 85 | #xcuserdata/**/* 86 | 87 | # (requires option 2 above): Personal Schemes 88 | # 89 | #!xcuserdata/**/xcschemes/* 90 | 91 | #### 92 | # XCode 4 workspaces - more detailed 93 | # 94 | # Workspaces are important! They are a core feature of Xcode - don't exclude them :) 95 | # 96 | # Workspace layout is quite spammy. For reference: 97 | # 98 | # /(root)/ 99 | # /(project-name).xcodeproj/ 100 | # project.pbxproj 101 | # /project.xcworkspace/ 102 | # contents.xcworkspacedata 103 | # /xcuserdata/ 104 | # /(your name)/xcuserdatad/ 105 | # UserInterfaceState.xcuserstate 106 | # /xcsshareddata/ 107 | # /xcschemes/ 108 | # (shared scheme name).xcscheme 109 | # /xcuserdata/ 110 | # /(your name)/xcuserdatad/ 111 | # (private scheme).xcscheme 112 | # xcschememanagement.plist 113 | # 114 | # 115 | 116 | #### 117 | # Xcode 4 - Deprecated classes 118 | # 119 | # Allegedly, if you manually "deprecate" your classes, they get moved here. 120 | # 121 | # We're using source-control, so this is a "feature" that we do not want! 122 | 123 | *.moved-aside 124 | 125 | 126 | #### 127 | # UNKNOWN: recommended by others, but I can't discover what these files are 128 | # 129 | # ...none. Everything is now explained. -------------------------------------------------------------------------------- /resources/project.frag: -------------------------------------------------------------------------------- 1 | #version 120 2 | 3 | 4 | varying vec3 normal; 5 | varying vec3 ecPosition3; 6 | varying vec4 ecPosition; 7 | varying vec4 ambientGlobal; 8 | varying vec4 projCoord; 9 | 10 | uniform sampler2D proj; 11 | uniform float scale = 3.f; 12 | 13 | void main (void) 14 | { 15 | vec3 N = normal; 16 | vec3 v = ecPosition3; 17 | 18 | vec3 L = normalize(gl_LightSource[0].position.xyz - v); 19 | vec3 E = normalize(-v); // we are in Eye Coordinates, so EyePos is (0,0,0) 20 | vec3 R = normalize(-reflect(L,N)); 21 | //calculate Ambient Term: 22 | vec4 Iamb = gl_FrontLightProduct[0].ambient; 23 | 24 | //calculate Diffuse Term: 25 | vec4 Idiff = gl_FrontLightProduct[0].diffuse * max(dot(N,L), 0.0); 26 | Idiff = clamp(Idiff, 0.0, 1.0); 27 | 28 | vec4 Ispec = gl_FrontLightProduct[0].specular * pow(max(dot(R,E),0.0),0.3*gl_FrontMaterial.shininess); 29 | Ispec = clamp(Ispec, 0.0, 1.0); 30 | 31 | vec3 coord = 0.5 * (projCoord.xyz / projCoord.w + 1.0); 32 | 33 | vec3 eee = v; 34 | vec3 nnn = R; 35 | float angle = dot(eee, nnn); 36 | 37 | if (coord.x >= 0.f && coord.x <= 1.f && coord.y >= 0.f && coord.y <= 1.f && angle < 0.0) { 38 | gl_FragColor = texture2DProj(proj, coord/scale); 39 | } 40 | else { 41 | gl_FragColor = vec4(vec3(0.f), 1.f); 42 | } 43 | 44 | /* 45 | else if (coord.x >= 0.f && coord.x <= 1.f && coord.y >= 0.f && coord.y <= 1.f) { 46 | gl_FragColor = max(dot(N, L) , 0.0) * texture2DProj(proj, coord/scale); 47 | gl_FragColor.a = 1.f; 48 | } 49 | else if (coord.x >= 0.f && coord.x <= 1.f && coord.y >= 0.f && coord.y <= 1.f) { 50 | gl_FragColor = gl_FrontLightModelProduct.sceneColor + Iamb + Idiff + Ispec; 51 | gl_FragColor = max(dot(N,L), 0.0) * texture2DProj(proj, coord/scale); 52 | gl_FragColor.rgb = vec3(0.f); 53 | gl_FragColor.a = 1.f; 54 | } 55 | else 56 | gl_FragColor = Iamb + Idiff; 57 | */ 58 | 59 | } 60 | 61 | /* 62 | varying vec3 normal; 63 | varying vec3 ecPosition3; 64 | varying vec4 ecPosition; 65 | varying vec4 ambientGlobal; 66 | varying vec4 projCoord; 67 | 68 | uniform sampler2D proj; 69 | uniform float scale = 3.f; 70 | float distCoord (vec3, vec3, vec3); 71 | 72 | void main () { 73 | // Eye-coordinates 74 | vec3 eye = -(ecPosition3); 75 | vec3 neye = -normalize(eye); 76 | 77 | // Clear the light intensity accumulators 78 | vec4 amb = vec4(0.f); 79 | vec4 diff = vec4(0.f); 80 | vec4 spec = vec4(0.f); 81 | 82 | // Compute ambient color 83 | amb = ambientGlobal + gl_LightSource[0].ambient; 84 | 85 | // Compute diffuse 86 | vec3 VP = -vec3(gl_LightSource[0].position); 87 | vec3 halfVector = normalize(VP + neye); 88 | float d = length(VP); 89 | VP = normalize(VP); 90 | 91 | float nDotVP = max(dot(normal, VP), 0.f); 92 | float nDotHV = max(dot(normal, gl_LightSource[0].halfVector.xyz), 0.f); 93 | float ndotl = max(dot(normal, VP + neye), 0.f); 94 | 95 | if (dot(gl_LightSource[0].position.xyz, normal) > 0.0) { 96 | spec += diff * ndotl; 97 | halfVector = normalize(halfVector); 98 | nDotHV = max(dot(normal, halfVector), 0.0); 99 | spec += gl_FrontMaterial.specular * gl_LightSource[0].specular * pow(nDotHV, 1.f/gl_FrontMaterial.shininess); 100 | } 101 | 102 | diff = nDotVP * gl_LightSource[0].diffuse; 103 | 104 | gl_FragColor = amb + diff + spec; 105 | 106 | float dist = distCoord(ecPosition.xyz, eye, gl_LightSource[0].position.xyz); 107 | gl_FragColor.a = 0.f; 108 | 109 | vec3 e, n; 110 | e = gl_LightSource[0].position.xyz; 111 | n = normal; 112 | vec3 coord = 0.5 * (projCoord.xyz / projCoord.w + 1.0); 113 | 114 | if (coord.x >= 0.f && coord.x <= 1.f && coord.y >= 0.f && coord.y <= 1.f && dot(e, n) > 0.3) { 115 | gl_FragColor = texture2DProj(proj, coord/scale); 116 | } 117 | else 118 | gl_FragColor = amb + diff; 119 | 120 | } 121 | 122 | float distCoord (vec3 pos, vec3 eye, vec3 light) { 123 | eye = eye - pos; 124 | light = light - pos; 125 | float d = length(light); 126 | if (dot (eye, light) > 0.f) 127 | return d/9.f; 128 | return 0.f; 129 | } 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | */ -------------------------------------------------------------------------------- /src/ProjectionScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // ProjectionScene.h 3 | // SvvimGram 4 | // 5 | // Created by Matthew Owen on 1/6/14. 6 | // 7 | // 8 | 9 | #ifndef SvvimGram_ProjectionScene_h 10 | #define SvvimGram_ProjectionScene_h 11 | 12 | #include "cinder/ObjLoader.h" 13 | #include "cinder/Camera.h" 14 | #include "cinder/gl/gl.h" 15 | #include "cinder/gl/Vbo.h" 16 | #include "cinder/gl/Texture.h" 17 | #include "cinder/gl/GlslProg.h" 18 | #include "cinder/gl/Light.h" 19 | 20 | #include "svvim.h" 21 | #include "SvvimScene.h" 22 | #include "SodaCan.h" 23 | #include 24 | 25 | class ProjectionScene : public SvvimScene { 26 | public: 27 | 28 | // ... 29 | ProjectionScene () { 30 | mParams["t"] = 0.f; 31 | } 32 | 33 | // ... 34 | void setup () { 35 | mProjector = make_shared(gl::Light::DIRECTIONAL, 0); 36 | 37 | ObjLoader loader((DataSourceRef)loadResource("Soda-Can.obj")); 38 | loader.load(&mMesh); 39 | mVbo = gl::VboMesh(mMesh); 40 | 41 | mCam.eye = Vec3f(10, 0, 0); 42 | mCam.dest = Vec3f(0, 0, 0); 43 | mCam.up = Vec3f(0, 1, 0); 44 | 45 | try { 46 | mProjShader = gl::GlslProg(loadResource("project.vert"), loadResource("project.frag")); 47 | } 48 | catch (const std::exception & e) { 49 | app::console() << e.what() << "\n"; 50 | } 51 | 52 | // Texture 53 | mTexture = loadImage(loadResource("pizza.jpg")); 54 | 55 | setupCans(); 56 | } 57 | 58 | // ... 59 | void update () { 60 | mProjector->setAmbient( Color(.8, .8, .8) ); 61 | mProjector->setDiffuse( Color(.1, .1, .1) ); 62 | mProjector->setSpecular( Color(.7, .7, .7) ); 63 | 64 | updateCans(); 65 | } 66 | 67 | // ... 68 | void draw () { 69 | gl::pushMatrices(); 70 | { 71 | float t = mParams.count("t") ? mParams["t"] : 0.f; 72 | t = 2.f * M_PI * fmod(t, 1.f); 73 | float x = 13.f * sin(t); 74 | float z = 13.1f * cos(t); 75 | 76 | mCam.point.lookAt( Vec3f(x, 0, z), mCam.dest, mCam.up); 77 | mProjector->lookAt( Vec3f(17, 0, 3), Vec3f(0, 0, 0)); 78 | mProjector->update(mCam.point); 79 | 80 | glEnable(GL_LIGHTING); 81 | glEnable(GL_DEPTH_TEST); 82 | 83 | gl::enableDepthWrite(); 84 | gl::enableDepthRead(); 85 | 86 | gl::clear(Color(1, 1, 1)); 87 | 88 | gl::setMatrices(mCam.point); 89 | 90 | if (mProjShader) { 91 | Matrix44f shadows[2]; 92 | shadows[0] = mProjector->getShadowTransformationMatrix(mCam.point); 93 | shadows[1] = mProjector->getShadowTransformationMatrix(mCam.point); 94 | 95 | mTexture.bind(0); 96 | mProjShader.bind(); 97 | mProjShader.uniform("proj", 0); 98 | mProjShader.uniform("shadowMatrices", shadows, 2); 99 | 100 | float no_mat[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 101 | float mat_diffuse[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; 102 | float mat_specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; 103 | glMaterialfv( GL_FRONT, GL_AMBIENT, no_mat); 104 | glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse); 105 | glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular); 106 | glMaterialf ( GL_FRONT, GL_SHININESS, 4.f); 107 | glMaterialfv( GL_FRONT, GL_EMISSION, no_mat); 108 | drawCans(); 109 | mProjShader.unbind(); 110 | } 111 | 112 | gl::color(1, 0, 1); 113 | // gl::drawFrustum(mProjector->getShadowCamera()); 114 | } 115 | 116 | gl::popMatrices(); 117 | } 118 | 119 | private: 120 | 121 | // Can updating 122 | void updateCans(); 123 | void setupCans(); 124 | void drawCans(); 125 | 126 | // The rest 127 | TriMesh mMesh; 128 | gl::VboMesh mVbo; 129 | gl::GlslProg mProjShader; 130 | shared_ptr mProjector; 131 | 132 | struct { 133 | CameraPersp point; 134 | Vec3f eye; 135 | Vec3f dest; 136 | Vec3f up; 137 | } mCam; 138 | 139 | std::vector mObjectList; 140 | 141 | gl::Texture mTexture; 142 | 143 | svvim::TimeCounter mTimer; 144 | }; 145 | 146 | /** 147 | 148 | IMPLEMENTATION! 149 | 150 | */ 151 | 152 | #define CAN_COUNT 200 153 | void ProjectionScene::setupCans() { 154 | mObjectList.resize(CAN_COUNT); 155 | for (int i = 0; i < CAN_COUNT; ++i) { 156 | svvim::SodaCan object; 157 | object.mesh = gl::VboMesh::create(mMesh); 158 | object.position = Vec3f(svv::random(-7, 7), svv::random(-7, 7), svv::random(-4, 4)); 159 | object.r0 = Vec3f(svv::random(-80, 80), svv::random(-80, 80), svv::random(-80, 80)); 160 | object.r1 = Vec3f(svv::random(-80, 80), svv::random(-80, 80), svv::random(-80, 80)); 161 | mObjectList[i] = object; 162 | } 163 | } 164 | 165 | void ProjectionScene::updateCans() { 166 | /* 167 | for (int i = 0; i < mObjectList.size(); ++i) { 168 | mObjectList[i].r1.x += 1.f; 169 | mObjectList[i].r1.y += 0.f; 170 | mObjectList[i].r1.z += 0.f; 171 | } */ 172 | } 173 | 174 | void ProjectionScene::drawCans() { 175 | float t = mParams.count("t") ? mParams["t"] : 0.f; 176 | t = fmod(t, 1.f); 177 | for (int i = 0; i < mObjectList.size(); ++i) { 178 | drawSodaCan(mObjectList[i], t); 179 | } 180 | } 181 | 182 | 183 | #endif 184 | -------------------------------------------------------------------------------- /src/SvvimGramApp.cpp: -------------------------------------------------------------------------------- 1 | // Needed for any kinda GL work 2 | #include "cinder/app/AppNative.h" 3 | #include "cinder/gl/gl.h" 4 | #include "cinder/qtime/QuickTime.h" 5 | 6 | // TODO: Write an AudioFftClass... preferably using FMOD though 7 | #include "cinder/audio/Io.h" 8 | #include "cinder/audio/Input.h" 9 | #include "cinder/audio/FftProcessor.h" 10 | #include "cinder/audio/PcmBuffer.h" 11 | 12 | // CUSTOME CODE SO SICK 13 | #include "SvvimPost.h" 14 | #include "AsynchMovieWriter.h" 15 | #include "ProjectionScene.h" 16 | #include "InstagramProjectionScene.h" 17 | 18 | using namespace ci; 19 | using namespace ci::app; 20 | using namespace std; 21 | 22 | Rectf getCoveringRect(gl::Texture texture, Area containerArea) { 23 | float scale; 24 | Rectf bounds = texture.getBounds(); 25 | bounds = bounds.getCenteredFit(containerArea, true); 26 | 27 | int container_h = containerArea.getHeight(), 28 | container_w = containerArea.getWidth(), 29 | texture_h = bounds.getHeight(), 30 | texture_w = bounds.getWidth(); 31 | 32 | if (abs(container_h - texture_h) > abs(container_w - texture_w)) 33 | scale = (float) container_h/texture_h; 34 | else 35 | scale = (float) container_w/texture_w; 36 | 37 | bounds.scaleCentered(scale + .05); 38 | 39 | return bounds; 40 | } 41 | 42 | class SvvimGramApp : public AppNative { 43 | public: 44 | void prepareSettings(Settings *settings); 45 | void setup(); 46 | void update(); 47 | 48 | void draw(); 49 | void drawLogo(); 50 | gl::Texture mSvvimLogo; 51 | 52 | private: 53 | shared_ptr mWriter; 54 | 55 | struct { 56 | shared_ptr projection; 57 | } mScenes; 58 | 59 | // Audio 60 | struct { 61 | audio::Input input; 62 | std::shared_ptr fft; 63 | audio::PcmBuffer32fRef pcmBuffer; 64 | } mAudio; 65 | void updateAudio(); 66 | 67 | // Parameters 68 | struct { 69 | float a, b, c; 70 | float gray; 71 | } m___; 72 | 73 | int mStep; 74 | 75 | SvvimPost mPost; 76 | }; 77 | 78 | void SvvimGramApp::prepareSettings(Settings *settings) { 79 | settings->setWindowSize(700, 700); 80 | // settings->setFullScreen(); 81 | } 82 | 83 | void SvvimGramApp::setup() { 84 | 85 | mSvvimLogo = loadImage(loadResource("svvim-logo-white.png")); 86 | 87 | m___.a = m___.b = m___.c = 1.f; 88 | 89 | mPost.setup(); 90 | mAudio.input = audio::Input(); 91 | mAudio.input.start(); 92 | 93 | mStep = 0; 94 | 95 | // Random Number Seed 96 | srand(time(NULL)); 97 | 98 | // Movie safe-file path 99 | fs::path path = fs::path("./what.mp4"); 100 | if( path.empty() ) 101 | return; 102 | 103 | // Write screen to movie asynchornously 104 | qtime::MovieWriter::Format format; 105 | format.setCodec(qtime::MovieWriter::CODEC_RAW); 106 | 107 | // format.setCodec(qtime::MovieWriter::..Format::) 108 | // mWriter = make_shared (path, 800, 800, format); 109 | 110 | // Initialize scenes 111 | mScenes.projection = make_shared (); 112 | mScenes.projection->setup(); 113 | } 114 | 115 | void SvvimGramApp::update() { 116 | 117 | updateAudio(); 118 | 119 | mStep += 1; 120 | mScenes.projection->update(); 121 | m___.a *= 1; 122 | m___.b *= 1; 123 | m___.c *= 1; 124 | 125 | if (m___.a < .075) 126 | m___.a = 0.f; 127 | 128 | } 129 | 130 | void SvvimGramApp::updateAudio() { 131 | mAudio.pcmBuffer = mAudio.input.getPcmBuffer(); 132 | 133 | if (mAudio.pcmBuffer) 134 | mAudio.fft = audio::calculateFft(mAudio.pcmBuffer->getChannelData( audio::CHANNEL_FRONT_LEFT ), 512); 135 | else 136 | return; 137 | 138 | uint16_t bandCount = 512; 139 | std::shared_ptr fftRef = audio::calculateFft(mAudio.pcmBuffer->getChannelData(audio::CHANNEL_FRONT_LEFT), bandCount); 140 | 141 | if (!fftRef) 142 | return; 143 | 144 | float * fftBuffer = fftRef.get(); 145 | 146 | int maxBand = bandCount / 5; 147 | 148 | for( int i = 0; i < maxBand; i++ ) 149 | m___.a += fftBuffer[i] * pow(2, -2.) / maxBand; 150 | 151 | m___.a /= 1.07f; 152 | m___.a = max(m___.a, 0.f); 153 | m___.a = min(m___.a, 1.9f) / 1.75f; 154 | } 155 | 156 | #define TOTAL_FRAMES 70 157 | void SvvimGramApp::draw() { 158 | // DRAW!! 159 | 160 | // float t = (mStep % TOTAL_FRAMES) / (float) TOTAL_FRAMES / 15.f; 161 | 162 | //if (mStep >= TOTAL_FRAMES) 163 | // quit(); 164 | 165 | mScenes.projection->set("t", getElapsedSeconds()); 166 | 167 | gl::clear(Color(1, 1, 1)); 168 | 169 | 170 | gl::enableAlphaBlending(); 171 | gl::disableDepthRead(); 172 | gl::disableDepthWrite(); 173 | 174 | gl::Texture texture, blurred; 175 | 176 | texture = mScenes.projection->render(); 177 | blurred = mPost.applyBlur(texture, 0.33f); 178 | 179 | gl::enableAdditiveBlending(); 180 | glEnable(GL_BLEND); 181 | glBlendFunc(GL_SRC_ALPHA, GL_ONE); 182 | 183 | gl::setMatricesWindow(getWindowWidth(), getWindowHeight()); 184 | glDisable(GL_LIGHTING); 185 | glDisable(GL_DEPTH_TEST); 186 | 187 | gl::color(ColorA(1, 1, 1, .5)); 188 | gl::draw(texture, getWindowBounds()); 189 | 190 | gl::color(ColorA(1, .9, .6, .6)); 191 | gl::draw(blurred, getWindowBounds()); 192 | 193 | // drawLogo(); 194 | 195 | //texture = mPost.applyBlur(texture, 3); 196 | 197 | //gl::color(Color(1, 1, 1)); 198 | // gl::draw(texture, getWindowBounds()); 199 | 200 | char path[256]; 201 | sprintf(path, "%03d.png", mStep % 100); 202 | // app::console() << path << "\n"; 203 | 204 | writeImage(path, copyWindowSurface()); 205 | } 206 | void SvvimGramApp::drawLogo() { 207 | if (mSvvimLogo) { 208 | gl::pushMatrices(); 209 | gl::setMatricesWindow(getWindowSize()); 210 | 211 | float w = 850; 212 | float h = w/mSvvimLogo.getAspectRatio(); 213 | float x = (getWindowWidth() - w)/2.f; 214 | float y = (getWindowHeight() - h)/2.f; 215 | gl::color(1, 1, 1, .4f); 216 | gl::draw(mSvvimLogo, Rectf(x, y, x + w, y + h)); 217 | 218 | gl::popMatrices(); 219 | } 220 | } 221 | 222 | 223 | 224 | CINDER_APP_NATIVE( SvvimGramApp, RendererGl ) 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | -------------------------------------------------------------------------------- /src/InstagramStream.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // InstagramStream.cpp 3 | // InstaScope 4 | // 5 | // Created by Greg Kepler on 6/9/12. 6 | // Copyright (c) 2012 The Barbarian Group. All rights reserved. 7 | // 8 | 9 | #include "cinder/app/AppBasic.h" 10 | #include "cinder/Rand.h" 11 | #include "cinder/Thread.h" 12 | #include "cinder/Function.h" 13 | #include "cinder/Json.h" 14 | #include "cinder/ImageIo.h" 15 | #include "cinder/Surface.h" 16 | #include "cinder/qtime/QuickTime.h" 17 | #include "cinder/Url.h" 18 | 19 | #include "InstagramStream.h" 20 | 21 | static const int BUFFER_SIZE = 10; 22 | 23 | using namespace std; 24 | using namespace ci; 25 | using namespace ci::app; 26 | 27 | static const string INSTAGRAM_API_URL = "https://api.instagram.com/v1"; 28 | 29 | JsonTree queryInstagram( const std::string &query ); 30 | 31 | 32 | InstagramStream::InstagramStream(const string &clientId ) 33 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 34 | mCanceled( false ), 35 | mClientId( clientId ) 36 | { 37 | startThread(INSTAGRAM_API_URL + "/media/popular?client_id="+ mClientId); 38 | } 39 | 40 | InstagramStream::InstagramStream( const std::string &searchPhrase, const string &clientId ) 41 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 42 | mCanceled( false ), 43 | mSearchPhrase( searchPhrase ), 44 | mClientId( clientId ) 45 | { 46 | startThread(INSTAGRAM_API_URL + "/tags/" + Url::encode( mSearchPhrase ) + "/media/recent?client_id="+ mClientId); 47 | } 48 | 49 | InstagramStream::InstagramStream(const std::string &searchPhrase, const int &minId, const int &maxId, const std::string &clientId ) 50 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 51 | mCanceled( false ), 52 | mSearchPhrase( searchPhrase ), 53 | mClientId( clientId ) 54 | { 55 | startThread(INSTAGRAM_API_URL + "/tags/" + Url::encode( mSearchPhrase ) + "/media/recent?client_id="+ mClientId + "&min_id=" + toString(minId) + "&max_id=" + toString(maxId)); 56 | } 57 | 58 | 59 | InstagramStream::InstagramStream(ci::Vec2f loc, float dist, int minTs, int maxTs, std::string clientId ) 60 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 61 | mCanceled( false ), 62 | mClientId( clientId ) 63 | { 64 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&distance=" + toString(dist) + "&min_timestamp=" + toString(minTs) + "&max_timestamp=" + toString(maxTs) + "&client_id="+ mClientId); 65 | } 66 | 67 | InstagramStream::InstagramStream(ci::Vec2f loc, float dist, std::string clientId ) 68 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 69 | mCanceled( false ), 70 | mClientId( clientId ) 71 | { 72 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&distance=" + toString(dist) + "&client_id="+ mClientId); 73 | } 74 | 75 | InstagramStream::InstagramStream(ci::Vec2f loc, std::string clientId ) 76 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 77 | mCanceled( false ), 78 | mClientId( clientId ) 79 | { 80 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&client_id="+ mClientId); 81 | } 82 | 83 | void InstagramStream::startThread(string url){ 84 | mThread = make_shared( bind( &InstagramStream::serviceGrams, this, url ) ); 85 | } 86 | 87 | InstagramStream::~InstagramStream() 88 | { 89 | mCanceled = true; 90 | mBuffer.cancel(); 91 | mThread->join(); 92 | } 93 | 94 | // Non-autenticated queries 95 | // X search for recent images of a certain tag 96 | // X get popular images 97 | // _ search for users with by user id https://api.instagram.com/v1/users/search?q=userId&client_id=xxx 98 | // _ get info about a user https://api.instagram.com/v1/users/1574083/?client_id=xxx 99 | // _ see who a user follows https://api.instagram.com/v1/users/1574083/follows?client_id=xxx 100 | // _ see who a user follows https://api.instagram.com/v1/users/1574083/followed-by?client_id=xxx 101 | // _ Get information about a media object. https://api.instagram.com/v1/media/3/?client_id=xxx 102 | // X Search for media in a given area. https://api.instagram.com/v1/media/search?lat=48.858844&lng=2.294351&client_id=xxx 103 | // _ Get comments of a speficic media https://api.instagram.com/v1/media/555/comments?client_id=xxx 104 | // _ Get likes of a speficic media https://api.instagram.com/v1/media/555/likes?client_id=xxx 105 | // _ Get information about a tag object. https://api.instagram.com/v1/tags/nofilter?client_id=xxx 106 | // _ Get information about a location https://api.instagram.com/v1/locations/1?client_id=xxx 107 | // _ Get a list of recent media objects from a given location. https://api.instagram.com/v1/tags/snow/media/recent?client_id=xxx 108 | // _ Search for a location by geographic coordinate. https://api.instagram.com/v1/locations/search?lat=48.858844&lng=2.294351&client_id=xxx 109 | 110 | 111 | // Function the background thread lives in 112 | void InstagramStream::serviceGrams(string url) 113 | { 114 | ThreadSetup threadSetup; 115 | std::string nextQueryString = url; 116 | 117 | JsonTree searchResults; 118 | JsonTree::ConstIter resultIt = searchResults.end(); 119 | 120 | // This function loops until the app quits. Each iteration a pulls out the next result from the Twitter API query. 121 | // When it reaches the last result of the current query it issues a new one, based on the "refresh_url" property 122 | // of the current query. 123 | // The loop doesn't spin (max out the processor) because ConcurrentCircularBuffer.pushFront() non-busy-waits for a new 124 | // slot in the circular buffer to become available. 125 | JsonTree queryResult; 126 | while( ! mCanceled ) { 127 | if( resultIt == searchResults.end() ) { // are we at the end of the results of this JSON query? 128 | // issue a new query 129 | try { 130 | queryResult = queryInstagram( nextQueryString ); 131 | // the next query will be the "refresh_url" of this one. 132 | 133 | try { 134 | nextQueryString = queryResult["pagination"].getChild("next_url").getValue(); 135 | } 136 | catch(...) { 137 | 138 | } 139 | 140 | searchResults = queryResult.getChild("data"); 141 | resultIt = searchResults.begin(); 142 | mIsConnected = true; 143 | } 144 | catch( ... ) { 145 | 146 | console() << "something broke" << endl; 147 | console() << queryResult << endl; 148 | console() << nextQueryString << endl; 149 | 150 | // check if it's a 420 error 151 | if(queryResult.getChild("meta").getChild("code").getValue() == "420"){ 152 | console() << "420 error" << endl; 153 | mIsConnected = false; 154 | } 155 | 156 | ci::sleep( 1000 ); // try again in 1 second 157 | } 158 | } 159 | if( resultIt != searchResults.end() ) { 160 | try { 161 | Surface image; 162 | string userName = (*resultIt)["user"]["username"].getValue(); 163 | 164 | JsonTree::ConstIter xo = (resultIt); 165 | 166 | 167 | string url = ""; 168 | 169 | if (xo->hasChild("videos.standard_resolution.url")) { 170 | url = xo->getChild("videos.standard_resolution.url").getValue(); 171 | cinder::qtime::MovieLoader movieLoader = cinder::qtime::MovieLoader(); 172 | mBuffer.pushFront( Instagram( userName, url, movieLoader ) ); 173 | } 174 | else if (xo->hasChild("images.standard_resolution.url")) { 175 | url = xo->getChild("images.standard_resolution.url").getValue(); 176 | image = loadImage( loadUrl( url ) ); 177 | // mBuffer.pushFront( Instagram( userName, url, image ) ); 178 | } 179 | 180 | // get the URL and load this instagram image 181 | 182 | 183 | // string imageUrl = "http://distilleryimage5.s3.amazonaws.com/1dd174cca14611e1af7612313813f8e8_7.jpg"; // Test image 184 | 185 | } 186 | catch( ... ) { // just ignore any errors 187 | //console() << "ERRORS FOUND" << endl; 188 | } 189 | ++resultIt; 190 | } 191 | } 192 | } 193 | 194 | JsonTree queryInstagram( const std::string &searchUrl ) 195 | { 196 | Url url(searchUrl , true ); 197 | return JsonTree( loadUrl( url ) ); 198 | } 199 | 200 | bool InstagramStream::hasInstagramAvailable() 201 | { 202 | return mBuffer.isNotEmpty(); 203 | } 204 | 205 | Instagram InstagramStream::getNextInstagram() 206 | { 207 | Instagram result; 208 | mBuffer.popBack( &result ); 209 | return result; 210 | } 211 | 212 | bool InstagramStream::isConnected() 213 | { 214 | return mIsConnected; 215 | } -------------------------------------------------------------------------------- /xcode/InstagramStream.cpp: -------------------------------------------------------------------------------- 1 | // 2 | // InstagramStream.cpp 3 | // InstaScope 4 | // 5 | // Created by Greg Kepler on 6/9/12. 6 | // Copyright (c) 2012 The Barbarian Group. All rights reserved. 7 | // 8 | 9 | #include "cinder/app/AppBasic.h" 10 | #include "cinder/Rand.h" 11 | #include "cinder/Thread.h" 12 | #include "cinder/Function.h" 13 | #include "cinder/Json.h" 14 | #include "cinder/ImageIo.h" 15 | #include "cinder/Surface.h" 16 | #include "cinder/qtime/QuickTime.h" 17 | #include "cinder/Url.h" 18 | 19 | #include "InstagramStream.h" 20 | 21 | static const int BUFFER_SIZE = 10; 22 | 23 | using namespace std; 24 | using namespace ci; 25 | using namespace ci::app; 26 | 27 | static const string INSTAGRAM_API_URL = "https://api.instagram.com/v1"; 28 | 29 | JsonTree queryInstagram( const std::string &query ); 30 | 31 | 32 | InstagramStream::InstagramStream(const string &clientId ) 33 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 34 | mCanceled( false ), 35 | mClientId( clientId ) 36 | { 37 | startThread(INSTAGRAM_API_URL + "/media/popular?client_id="+ mClientId); 38 | } 39 | 40 | InstagramStream::InstagramStream( const std::string &searchPhrase, const string &clientId ) 41 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 42 | mCanceled( false ), 43 | mSearchPhrase( searchPhrase ), 44 | mClientId( clientId ) 45 | { 46 | startThread(INSTAGRAM_API_URL + "/tags/" + Url::encode( mSearchPhrase ) + "/media/recent?client_id="+ mClientId); 47 | } 48 | 49 | InstagramStream::InstagramStream(const std::string &searchPhrase, const int &minId, const int &maxId, const std::string &clientId ) 50 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 51 | mCanceled( false ), 52 | mSearchPhrase( searchPhrase ), 53 | mClientId( clientId ) 54 | { 55 | startThread(INSTAGRAM_API_URL + "/tags/" + Url::encode( mSearchPhrase ) + "/media/recent?client_id="+ mClientId + "&min_id=" + toString(minId) + "&max_id=" + toString(maxId)); 56 | } 57 | 58 | 59 | InstagramStream::InstagramStream(ci::Vec2f loc, float dist, int minTs, int maxTs, std::string clientId ) 60 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 61 | mCanceled( false ), 62 | mClientId( clientId ) 63 | { 64 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&distance=" + toString(dist) + "&min_timestamp=" + toString(minTs) + "&max_timestamp=" + toString(maxTs) + "&client_id="+ mClientId); 65 | } 66 | 67 | InstagramStream::InstagramStream(ci::Vec2f loc, float dist, std::string clientId ) 68 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 69 | mCanceled( false ), 70 | mClientId( clientId ) 71 | { 72 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&distance=" + toString(dist) + "&client_id="+ mClientId); 73 | } 74 | 75 | InstagramStream::InstagramStream(ci::Vec2f loc, std::string clientId ) 76 | : mBuffer( BUFFER_SIZE ), // our buffer of instagrams can hold up to 10 77 | mCanceled( false ), 78 | mClientId( clientId ) 79 | { 80 | startThread(INSTAGRAM_API_URL + "/media/search?lat=" + toString(loc.x) + "&lng=" + toString(loc.y) + "&client_id="+ mClientId); 81 | } 82 | 83 | void InstagramStream::startThread(string url){ 84 | mThread = make_shared( bind( &InstagramStream::serviceGrams, this, url ) ); 85 | } 86 | 87 | InstagramStream::~InstagramStream() 88 | { 89 | mCanceled = true; 90 | mBuffer.cancel(); 91 | mThread->join(); 92 | } 93 | 94 | // Non-autenticated queries 95 | // X search for recent images of a certain tag 96 | // X get popular images 97 | // _ search for users with by user id https://api.instagram.com/v1/users/search?q=userId&client_id=xxx 98 | // _ get info about a user https://api.instagram.com/v1/users/1574083/?client_id=xxx 99 | // _ see who a user follows https://api.instagram.com/v1/users/1574083/follows?client_id=xxx 100 | // _ see who a user follows https://api.instagram.com/v1/users/1574083/followed-by?client_id=xxx 101 | // _ Get information about a media object. https://api.instagram.com/v1/media/3/?client_id=xxx 102 | // X Search for media in a given area. https://api.instagram.com/v1/media/search?lat=48.858844&lng=2.294351&client_id=xxx 103 | // _ Get comments of a speficic media https://api.instagram.com/v1/media/555/comments?client_id=xxx 104 | // _ Get likes of a speficic media https://api.instagram.com/v1/media/555/likes?client_id=xxx 105 | // _ Get information about a tag object. https://api.instagram.com/v1/tags/nofilter?client_id=xxx 106 | // _ Get information about a location https://api.instagram.com/v1/locations/1?client_id=xxx 107 | // _ Get a list of recent media objects from a given location. https://api.instagram.com/v1/tags/snow/media/recent?client_id=xxx 108 | // _ Search for a location by geographic coordinate. https://api.instagram.com/v1/locations/search?lat=48.858844&lng=2.294351&client_id=xxx 109 | 110 | 111 | // Function the background thread lives in 112 | void InstagramStream::serviceGrams(string url) 113 | { 114 | ThreadSetup threadSetup; 115 | std::string nextQueryString = url; 116 | 117 | JsonTree searchResults; 118 | JsonTree::ConstIter resultIt = searchResults.end(); 119 | 120 | // This function loops until the app quits. Each iteration a pulls out the next result from the Twitter API query. 121 | // When it reaches the last result of the current query it issues a new one, based on the "refresh_url" property 122 | // of the current query. 123 | // The loop doesn't spin (max out the processor) because ConcurrentCircularBuffer.pushFront() non-busy-waits for a new 124 | // slot in the circular buffer to become available. 125 | JsonTree queryResult; 126 | while( ! mCanceled ) { 127 | if( resultIt == searchResults.end() ) { // are we at the end of the results of this JSON query? 128 | // issue a new query 129 | try { 130 | queryResult = queryInstagram( nextQueryString ); 131 | // the next query will be the "refresh_url" of this one. 132 | 133 | try { 134 | nextQueryString = queryResult["pagination"].getChild("next_url").getValue(); 135 | } 136 | catch(...) { 137 | 138 | } 139 | 140 | searchResults = queryResult.getChild("data"); 141 | resultIt = searchResults.begin(); 142 | mIsConnected = true; 143 | } 144 | catch( ... ) { 145 | 146 | console() << "something broke" << endl; 147 | console() << queryResult << endl; 148 | console() << nextQueryString << endl; 149 | 150 | // check if it's a 420 error 151 | if(queryResult.getChild("meta").getChild("code").getValue() == "420"){ 152 | console() << "420 error" << endl; 153 | mIsConnected = false; 154 | } 155 | 156 | ci::sleep( 1000 ); // try again in 1 second 157 | } 158 | } 159 | if( resultIt != searchResults.end() ) { 160 | try { 161 | Surface image; 162 | string userName = (*resultIt)["user"]["username"].getValue(); 163 | 164 | JsonTree::ConstIter xo = (resultIt); 165 | 166 | 167 | string url = ""; 168 | 169 | if (xo->hasChild("videos.standard_resolution.url")) { 170 | url = xo->getChild("videos.standard_resolution.url").getValue(); 171 | cinder::qtime::MovieLoader movieLoader = cinder::qtime::MovieLoader(); 172 | mBuffer.pushFront( Instagram( userName, url, movieLoader ) ); 173 | } 174 | else if (xo->hasChild("images.standard_resolution.url")) { 175 | url = xo->getChild("images.standard_resolution.url").getValue(); 176 | image = loadImage( loadUrl( url ) ); 177 | // mBuffer.pushFront( Instagram( userName, url, image ) ); 178 | } 179 | 180 | // get the URL and load this instagram image 181 | 182 | 183 | // string imageUrl = "http://distilleryimage5.s3.amazonaws.com/1dd174cca14611e1af7612313813f8e8_7.jpg"; // Test image 184 | 185 | } 186 | catch( ... ) { // just ignore any errors 187 | //console() << "ERRORS FOUND" << endl; 188 | } 189 | ++resultIt; 190 | } 191 | } 192 | } 193 | 194 | JsonTree queryInstagram( const std::string &searchUrl ) 195 | { 196 | Url url(searchUrl , true ); 197 | return JsonTree( loadUrl( url ) ); 198 | } 199 | 200 | bool InstagramStream::hasInstagramAvailable() 201 | { 202 | return mBuffer.isNotEmpty(); 203 | } 204 | 205 | Instagram InstagramStream::getNextInstagram() 206 | { 207 | Instagram result; 208 | mBuffer.popBack( &result ); 209 | return result; 210 | } 211 | 212 | bool InstagramStream::isConnected() 213 | { 214 | return mIsConnected; 215 | } -------------------------------------------------------------------------------- /src/InstagramProjectionScene.h: -------------------------------------------------------------------------------- 1 | // 2 | // InstagramProjectionScene.h 3 | // SvvimGram 4 | // 5 | // Created by Matthew Owen on 1/7/14. 6 | // Based on ProjectionScene 7 | // 8 | 9 | #ifndef SvvimGram_InstagramProjectionScene_h 10 | #define SvvimGram_InstagramProjectionScene_h 11 | 12 | #include "cinder/ObjLoader.h" 13 | #include "cinder/Camera.h" 14 | #include "cinder/gl/gl.h" 15 | #include "cinder/gl/Vbo.h" 16 | #include "cinder/gl/Texture.h" 17 | #include "cinder/gl/GlslProg.h" 18 | #include "cinder/gl/Light.h" 19 | 20 | #include "cinder/qtime/MovieWriter.h" 21 | 22 | #include "svvim.h" 23 | #include "SvvimScene.h" 24 | #include "SodaCan.h" 25 | #include "InstagramStream.h" 26 | 27 | class InstagramProjectionScene : public SvvimScene { 28 | public: 29 | 30 | // ... 31 | InstagramProjectionScene () { 32 | mParams["t"] = 0.f; 33 | } 34 | 35 | // ... 36 | void setup () { 37 | gl::Fbo::Format format; 38 | mRenderFbo = gl::Fbo(700, 700, format); 39 | 40 | mLastUpdateTime = 0.f;; 41 | 42 | mProjector = make_shared(gl::Light::DIRECTIONAL, 0); 43 | 44 | ObjLoader loader((DataSourceRef)loadResource("Soda-Can.obj")); 45 | loader.load(&mMesh); 46 | mVbo = gl::VboMesh(mMesh); 47 | 48 | mCam.eye = Vec3f(10, 0, 0); 49 | mCam.dest = Vec3f(0, 0, 0); 50 | mCam.up = Vec3f(0, 1, 0); 51 | 52 | try { 53 | mProjShader = gl::GlslProg(loadResource("project.vert"), loadResource("project.frag")); 54 | } 55 | catch (const std::exception & e) { 56 | app::console() << e.what() << "\n"; 57 | } 58 | 59 | // Texture 60 | mTexture = loadImage(loadResource("pizza.jpg")); 61 | mCurTexture = mTexture; 62 | 63 | setupCans(); 64 | setupInstaStream(); 65 | } 66 | 67 | // ... 68 | void update () { 69 | mProjector->setAmbient( Color(0, 0, 0) ); 70 | mProjector->setDiffuse( Color(.1, .1, .1) ); 71 | mProjector->setSpecular( Color(.7, .7, .7) ); 72 | 73 | updateCans(); 74 | updateInstaStream(); 75 | } 76 | 77 | // RENDER 78 | gl::Texture render() { 79 | mRenderFbo.bindFramebuffer(); 80 | gl::clear(Color(.8, .8, .8)); 81 | draw(); 82 | mRenderFbo.unbindFramebuffer(); 83 | return mRenderFbo.getTexture(); 84 | } 85 | 86 | // ... 87 | void draw () { 88 | gl::pushMatrices(); 89 | { 90 | float t = mParams["t"] / 12.f; 91 | float t1 = t; 92 | float t2 = t + M_PI; 93 | 94 | Vec3d proj = Vec3f( 11.f * cos(t1), 3, 5.f * sin(t1) ); 95 | Vec3f eye = Vec3f( 13.f * cos(t2), 3, 13.f * sin(t2) ); 96 | 97 | mCam.point.lookAt( eye, mCam.dest, mCam.up); 98 | mProjector->lookAt( proj, mCam.dest); 99 | mProjector->update(mCam.point); 100 | 101 | glEnable(GL_LIGHTING); 102 | glEnable(GL_DEPTH_TEST); 103 | 104 | gl::enableDepthWrite(); 105 | gl::enableDepthRead(); 106 | 107 | gl::clear(Color(1, 1, 1)); 108 | 109 | gl::setMatrices(mCam.point); 110 | 111 | if (mProjShader && mCurTexture) { 112 | Matrix44f shadows[2]; 113 | shadows[0] = mProjector->getShadowTransformationMatrix(mCam.point); 114 | shadows[1] = mProjector->getShadowTransformationMatrix(mCam.point); 115 | 116 | mCurTexture.bind(0); 117 | mProjShader.bind(); 118 | mProjShader.uniform("proj", 0); 119 | mProjShader.uniform("shadowMatrices", shadows, 2); 120 | 121 | float no_mat[4] = { 0.0f, 0.0f, 0.0f, 1.0f }; 122 | float mat_diffuse[4] = { 0.5f, 0.5f, 0.5f, 1.0f }; 123 | float mat_specular[4] = { 1.0f, 1.0f, 1.0f, 1.0f }; 124 | glMaterialfv( GL_FRONT, GL_AMBIENT, no_mat); 125 | glMaterialfv( GL_FRONT, GL_DIFFUSE, mat_diffuse); 126 | glMaterialfv( GL_FRONT, GL_SPECULAR, mat_specular); 127 | glMaterialf ( GL_FRONT, GL_SHININESS, 4.f); 128 | glMaterialfv( GL_FRONT, GL_EMISSION, no_mat); 129 | 130 | drawCans(); 131 | mProjShader.unbind(); 132 | } 133 | 134 | // gl::color(1, 0, 1); 135 | // gl::drawFrustum(mProjector->getShadowCamera()); 136 | } 137 | 138 | gl::popMatrices(); 139 | } 140 | 141 | private: 142 | 143 | // Can updating 144 | void setupCans(); 145 | void updateCans(); 146 | void drawCans(); 147 | 148 | // InstaStream 149 | void setupInstaStream(); 150 | void updateInstaStream(); 151 | 152 | // ... 153 | void loadNew () { 154 | 155 | if (mSvvimStream && mSvvimStream->isConnected() && mSvvimStream->hasInstagramAvailable()) { 156 | mResInstagram = mSvvimStream->getNextInstagram(); 157 | 158 | if (mResInstagram.hasVideoUrl()) { 159 | mInstaMovieLoader = qtime::MovieLoader(Url(mResInstagram.getVideoUrl())); 160 | 161 | app::console() << "Loading: " << mResInstagram.getVideoUrl() << "\n"; 162 | } 163 | } 164 | 165 | else if (mInstaStream && mInstaStream->isConnected() && mInstaStream->hasInstagramAvailable()) { 166 | mResInstagram = mInstaStream->getNextInstagram(); 167 | 168 | if (mResInstagram.hasVideoUrl()) { 169 | mInstaMovieLoader = qtime::MovieLoader(Url(mResInstagram.getVideoUrl())); 170 | 171 | app::console() << "Loading: " << mResInstagram.getVideoUrl() << "\n"; 172 | } 173 | 174 | } 175 | else { 176 | app::console() << "No content available...\n"; 177 | app::console() << "No content available...\n"; 178 | app::console() << "No content available...\n"; 179 | app::console() << "No content available...\n"; 180 | app::console() << "No content available...\n"; 181 | app::console() << "No content available...\n"; 182 | app::console() << "No content available...\n"; 183 | app::console() << "No content available...\n"; 184 | } 185 | } 186 | 187 | 188 | bool isReady () { 189 | float t = mParams["t"]; 190 | 191 | if (t - mLastUpdateTime > 10.f) { 192 | 193 | mLastUpdateTime = t; 194 | return true; 195 | } 196 | 197 | return false; 198 | } 199 | 200 | Url mVideoUrl; 201 | qtime::MovieSurface mCurMovieSurface; 202 | ci::gl::Texture mCurTexture; 203 | Instagram mResInstagram; 204 | shared_ptr mInstaStream; 205 | shared_ptr mSvvimStream; 206 | qtime::MovieLoader mInstaMovieLoader; 207 | 208 | float mLastUpdateTime; 209 | 210 | // ------------------------------ 211 | 212 | // The rest 213 | TriMesh mMesh; 214 | gl::VboMesh mVbo; 215 | gl::GlslProg mProjShader; 216 | shared_ptr mProjector; 217 | 218 | struct { 219 | CameraPersp point; 220 | Vec3f eye; 221 | Vec3f dest; 222 | Vec3f up; 223 | } mCam; 224 | 225 | std::vector mObjectList; 226 | 227 | gl::Texture mTexture; 228 | 229 | svvim::TimeCounter mTimer; 230 | }; 231 | 232 | /** 233 | 234 | IMPLEMENTATION! 235 | 236 | */ 237 | 238 | void InstagramProjectionScene::setupInstaStream () { 239 | mSvvimStream = make_shared("video", "f7aa3779f33741b182e33cc28b40c474"); 240 | mInstaStream = make_shared("video", "f7aa3779f33741b182e33cc28b40c474"); 241 | } 242 | 243 | #define CAN_COUNT 250 244 | void InstagramProjectionScene::setupCans() { 245 | mObjectList.resize(CAN_COUNT); 246 | for (int i = 0; i < CAN_COUNT; ++i) { 247 | svvim::SodaCan object; 248 | object.mesh = gl::VboMesh::create(mMesh); 249 | float w = 5.; 250 | object.position = Vec3f(svv::random(-w, w), svv::random(-w, w), svv::random(-w, w)); 251 | object.r0 = Vec3f(svv::random(-80, 80), svv::random(-80, 80), svv::random(-80, 80)); 252 | object.r1 = Vec3f(svv::random(-80, 80), svv::random(-80, 80), svv::random(-80, 80)); 253 | mObjectList[i] = object; 254 | } 255 | } 256 | 257 | void InstagramProjectionScene::updateCans() { 258 | /* 259 | for (int i = 0; i < mObjectList.size(); ++i) { 260 | mObjectList[i].r1.x += 1.f; 261 | mObjectList[i].r1.y += 0.f; 262 | mObjectList[i].r1.z += 0.f; 263 | } */ 264 | } 265 | 266 | void InstagramProjectionScene::updateInstaStream () { 267 | Surface surface; 268 | 269 | if (mCurMovieSurface) { 270 | Surface surf = mCurMovieSurface.getSurface(); 271 | 272 | if (surf) { 273 | mCurTexture = gl::Texture(surf); 274 | } 275 | 276 | } 277 | 278 | if (mInstaMovieLoader && mInstaMovieLoader && mInstaMovieLoader.checkPlaythroughOk()) { 279 | mCurMovieSurface = ci::qtime::MovieSurface(mInstaMovieLoader); 280 | mCurMovieSurface.play(); 281 | mCurMovieSurface.setVolume(0.f); 282 | mCurMovieSurface.setLoop(); 283 | mInstaMovieLoader.reset(); 284 | } 285 | 286 | if (isReady()) { 287 | loadNew(); 288 | } 289 | } 290 | 291 | void InstagramProjectionScene::drawCans() { 292 | float t = mParams.count("t") ? mParams["t"] / 15.f : 0.f; 293 | // t = fmod(t, 1.f); 294 | for (int i = 0; i < mObjectList.size(); ++i) { 295 | drawSodaCan(mObjectList[i], t/4.f); 296 | } 297 | } 298 | 299 | #endif 300 | -------------------------------------------------------------------------------- /xcode/SvvimGram.xcodeproj/project.pbxproj: -------------------------------------------------------------------------------- 1 | // !$*UTF8*$! 2 | { 3 | archiveVersion = 1; 4 | classes = { 5 | }; 6 | objectVersion = 46; 7 | objects = { 8 | 9 | /* Begin PBXBuildFile section */ 10 | 0091D8F90E81B9330029341E /* OpenGL.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0091D8F80E81B9330029341E /* OpenGL.framework */; }; 11 | 00B784B30FF439BC000DE1D7 /* Accelerate.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784AF0FF439BC000DE1D7 /* Accelerate.framework */; }; 12 | 00B784B40FF439BC000DE1D7 /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784B00FF439BC000DE1D7 /* AudioToolbox.framework */; }; 13 | 00B784B50FF439BC000DE1D7 /* AudioUnit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784B10FF439BC000DE1D7 /* AudioUnit.framework */; }; 14 | 00B784B60FF439BC000DE1D7 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 00B784B20FF439BC000DE1D7 /* CoreAudio.framework */; }; 15 | 5323E6B20EAFCA74003A9687 /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5323E6B10EAFCA74003A9687 /* CoreVideo.framework */; }; 16 | 5323E6B60EAFCA7E003A9687 /* QTKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 5323E6B50EAFCA7E003A9687 /* QTKit.framework */; }; 17 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */; }; 18 | AC40C3579BB64EA3A2083669 /* QuickTime.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 25676F373D3E48A392E4BC25 /* QuickTime.framework */; }; 19 | C9213389187BCF4600828C98 /* Soda-Can.obj in Resources */ = {isa = PBXBuildFile; fileRef = C9213388187BCF4600828C98 /* Soda-Can.obj */; }; 20 | C921338F187BCF8A00828C98 /* pizza.jpg in Resources */ = {isa = PBXBuildFile; fileRef = C921338E187BCF8A00828C98 /* pizza.jpg */; }; 21 | C9213390187BD1E000828C98 /* project.frag in Resources */ = {isa = PBXBuildFile; fileRef = C921338A187BCF7A00828C98 /* project.frag */; }; 22 | C9213391187BD1E000828C98 /* project.vert in Resources */ = {isa = PBXBuildFile; fileRef = C921338B187BCF7A00828C98 /* project.vert */; }; 23 | C97455EFA2384A53986F304D /* CinderApp.icns in Resources */ = {isa = PBXBuildFile; fileRef = 03D18A33B65D46F8B558BE8A /* CinderApp.icns */; }; 24 | C97478D5187BB73E003DECA4 /* InstagramStream.cpp in Sources */ = {isa = PBXBuildFile; fileRef = C97478D3187BB73E003DECA4 /* InstagramStream.cpp */; }; 25 | C9FA6F60187CAE1900CD71AC /* hblur.frag in Resources */ = {isa = PBXBuildFile; fileRef = C9FA6F5A187CAABD00CD71AC /* hblur.frag */; }; 26 | C9FA6F61187CAE1900CD71AC /* pass.vert in Resources */ = {isa = PBXBuildFile; fileRef = C9FA6F5B187CAABD00CD71AC /* pass.vert */; }; 27 | C9FA6F62187CAE1900CD71AC /* vblur.frag in Resources */ = {isa = PBXBuildFile; fileRef = C9FA6F5C187CAABD00CD71AC /* vblur.frag */; }; 28 | C9FA6F6D187CDFE700CD71AC /* svvim-logo-white.png in Resources */ = {isa = PBXBuildFile; fileRef = C9FA6F6C187CDFE700CD71AC /* svvim-logo-white.png */; }; 29 | E6ABCBC128DF4EAEAED0B8D9 /* SvvimGramApp.cpp in Sources */ = {isa = PBXBuildFile; fileRef = B9E5F1A8CCA84F27BFE1A297 /* SvvimGramApp.cpp */; }; 30 | /* End PBXBuildFile section */ 31 | 32 | /* Begin PBXFileReference section */ 33 | 0091D8F80E81B9330029341E /* OpenGL.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGL.framework; path = /System/Library/Frameworks/OpenGL.framework; sourceTree = ""; }; 34 | 00B784AF0FF439BC000DE1D7 /* Accelerate.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Accelerate.framework; path = System/Library/Frameworks/Accelerate.framework; sourceTree = SDKROOT; }; 35 | 00B784B00FF439BC000DE1D7 /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; }; 36 | 00B784B10FF439BC000DE1D7 /* AudioUnit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioUnit.framework; path = System/Library/Frameworks/AudioUnit.framework; sourceTree = SDKROOT; }; 37 | 00B784B20FF439BC000DE1D7 /* CoreAudio.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreAudio.framework; path = System/Library/Frameworks/CoreAudio.framework; sourceTree = SDKROOT; }; 38 | 03D18A33B65D46F8B558BE8A /* CinderApp.icns */ = {isa = PBXFileReference; lastKnownFileType = image.icns; name = CinderApp.icns; path = ../resources/CinderApp.icns; sourceTree = ""; }; 39 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = /System/Library/Frameworks/Cocoa.framework; sourceTree = ""; }; 40 | 1A9E6A8454034E9096E913DB /* SvvimGram_Prefix.pch */ = {isa = PBXFileReference; lastKnownFileType = "\"\""; path = SvvimGram_Prefix.pch; sourceTree = ""; }; 41 | 25676F373D3E48A392E4BC25 /* QuickTime.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuickTime.framework; path = System/Library/Frameworks/QuickTime.framework; sourceTree = SDKROOT; }; 42 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AppKit.framework; path = /System/Library/Frameworks/AppKit.framework; sourceTree = ""; }; 43 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Foundation.framework; path = /System/Library/Frameworks/Foundation.framework; sourceTree = ""; }; 44 | 4397C570128C461C86383165 /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = ""; }; 45 | 5323E6B10EAFCA74003A9687 /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = /System/Library/Frameworks/CoreVideo.framework; sourceTree = ""; }; 46 | 5323E6B50EAFCA7E003A9687 /* QTKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QTKit.framework; path = /System/Library/Frameworks/QTKit.framework; sourceTree = ""; }; 47 | 8D1107320486CEB800E47090 /* SvvimGram.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = SvvimGram.app; sourceTree = BUILT_PRODUCTS_DIR; }; 48 | B2FEF269AE2F4CAB8761F3FA /* Resources.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = Resources.h; path = ../include/Resources.h; sourceTree = ""; }; 49 | B9E5F1A8CCA84F27BFE1A297 /* SvvimGramApp.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.cpp; name = SvvimGramApp.cpp; path = ../src/SvvimGramApp.cpp; sourceTree = ""; }; 50 | C9213388187BCF4600828C98 /* Soda-Can.obj */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text; name = "Soda-Can.obj"; path = "../resources/obj/Soda-Can.obj"; sourceTree = ""; }; 51 | C921338A187BCF7A00828C98 /* project.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = project.frag; path = ../resources/project.frag; sourceTree = ""; }; 52 | C921338B187BCF7A00828C98 /* project.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = project.vert; path = ../resources/project.vert; sourceTree = ""; }; 53 | C921338E187BCF8A00828C98 /* pizza.jpg */ = {isa = PBXFileReference; lastKnownFileType = image.jpeg; name = pizza.jpg; path = ../resources/images/pizza.jpg; sourceTree = ""; }; 54 | C9520287187BF36C00D4131A /* SvvimScene.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = SvvimScene.h; path = ../src/SvvimScene.h; sourceTree = ""; }; 55 | C97478D2187BB660003DECA4 /* AsynchMovieWriter.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = AsynchMovieWriter.h; sourceTree = ""; }; 56 | C97478D3187BB73E003DECA4 /* InstagramStream.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = InstagramStream.cpp; sourceTree = ""; }; 57 | C97478D4187BB73E003DECA4 /* InstagramStream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = InstagramStream.h; sourceTree = ""; }; 58 | C97478D7187BBC1B003DECA4 /* svvim.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; name = svvim.h; path = ../src/svvim.h; sourceTree = ""; }; 59 | C97478D8187BBC87003DECA4 /* SvvimPost.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SvvimPost.h; path = ../src/SvvimPost.h; sourceTree = ""; }; 60 | C97478D9187BBFBB003DECA4 /* ProjectionScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = ProjectionScene.h; path = ../src/ProjectionScene.h; sourceTree = ""; }; 61 | C9FA6F52187C020B00CD71AC /* InstagramProjectionScene.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = InstagramProjectionScene.h; path = ../src/InstagramProjectionScene.h; sourceTree = ""; }; 62 | C9FA6F53187C143500CD71AC /* SodaCan.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SodaCan.h; path = ../src/SodaCan.h; sourceTree = ""; }; 63 | C9FA6F5A187CAABD00CD71AC /* hblur.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = hblur.frag; path = ../resources/hblur.frag; sourceTree = ""; }; 64 | C9FA6F5B187CAABD00CD71AC /* pass.vert */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = pass.vert; path = ../resources/pass.vert; sourceTree = ""; }; 65 | C9FA6F5C187CAABD00CD71AC /* vblur.frag */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.glsl; name = vblur.frag; path = ../resources/vblur.frag; sourceTree = ""; }; 66 | C9FA6F6C187CDFE700CD71AC /* svvim-logo-white.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = "svvim-logo-white.png"; path = "../resources/images/svvim-logo-white.png"; sourceTree = ""; }; 67 | /* End PBXFileReference section */ 68 | 69 | /* Begin PBXFrameworksBuildPhase section */ 70 | 8D11072E0486CEB800E47090 /* Frameworks */ = { 71 | isa = PBXFrameworksBuildPhase; 72 | buildActionMask = 2147483647; 73 | files = ( 74 | 8D11072F0486CEB800E47090 /* Cocoa.framework in Frameworks */, 75 | 0091D8F90E81B9330029341E /* OpenGL.framework in Frameworks */, 76 | 5323E6B20EAFCA74003A9687 /* CoreVideo.framework in Frameworks */, 77 | 5323E6B60EAFCA7E003A9687 /* QTKit.framework in Frameworks */, 78 | 00B784B30FF439BC000DE1D7 /* Accelerate.framework in Frameworks */, 79 | 00B784B40FF439BC000DE1D7 /* AudioToolbox.framework in Frameworks */, 80 | 00B784B50FF439BC000DE1D7 /* AudioUnit.framework in Frameworks */, 81 | 00B784B60FF439BC000DE1D7 /* CoreAudio.framework in Frameworks */, 82 | AC40C3579BB64EA3A2083669 /* QuickTime.framework in Frameworks */, 83 | ); 84 | runOnlyForDeploymentPostprocessing = 0; 85 | }; 86 | /* End PBXFrameworksBuildPhase section */ 87 | 88 | /* Begin PBXGroup section */ 89 | 01B97315FEAEA392516A2CEA /* Blocks */ = { 90 | isa = PBXGroup; 91 | children = ( 92 | ); 93 | name = Blocks; 94 | sourceTree = ""; 95 | }; 96 | 080E96DDFE201D6D7F000001 /* Source */ = { 97 | isa = PBXGroup; 98 | children = ( 99 | B9E5F1A8CCA84F27BFE1A297 /* SvvimGramApp.cpp */, 100 | C97478D3187BB73E003DECA4 /* InstagramStream.cpp */, 101 | ); 102 | name = Source; 103 | sourceTree = ""; 104 | }; 105 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */ = { 106 | isa = PBXGroup; 107 | children = ( 108 | 00B784AF0FF439BC000DE1D7 /* Accelerate.framework */, 109 | 00B784B00FF439BC000DE1D7 /* AudioToolbox.framework */, 110 | 00B784B10FF439BC000DE1D7 /* AudioUnit.framework */, 111 | 00B784B20FF439BC000DE1D7 /* CoreAudio.framework */, 112 | 5323E6B50EAFCA7E003A9687 /* QTKit.framework */, 113 | 5323E6B10EAFCA74003A9687 /* CoreVideo.framework */, 114 | 0091D8F80E81B9330029341E /* OpenGL.framework */, 115 | 1058C7A1FEA54F0111CA2CBB /* Cocoa.framework */, 116 | ); 117 | name = "Linked Frameworks"; 118 | sourceTree = ""; 119 | }; 120 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */ = { 121 | isa = PBXGroup; 122 | children = ( 123 | 29B97324FDCFA39411CA2CEA /* AppKit.framework */, 124 | 29B97325FDCFA39411CA2CEA /* Foundation.framework */, 125 | ); 126 | name = "Other Frameworks"; 127 | sourceTree = ""; 128 | }; 129 | 19C28FACFE9D520D11CA2CBB /* Products */ = { 130 | isa = PBXGroup; 131 | children = ( 132 | 8D1107320486CEB800E47090 /* SvvimGram.app */, 133 | ); 134 | name = Products; 135 | sourceTree = ""; 136 | }; 137 | 29B97314FDCFA39411CA2CEA /* SvvimGram */ = { 138 | isa = PBXGroup; 139 | children = ( 140 | 01B97315FEAEA392516A2CEA /* Blocks */, 141 | 29B97315FDCFA39411CA2CEA /* Headers */, 142 | 080E96DDFE201D6D7F000001 /* Source */, 143 | 29B97317FDCFA39411CA2CEA /* Resources */, 144 | 29B97323FDCFA39411CA2CEA /* Frameworks */, 145 | 19C28FACFE9D520D11CA2CBB /* Products */, 146 | ); 147 | name = SvvimGram; 148 | sourceTree = ""; 149 | }; 150 | 29B97315FDCFA39411CA2CEA /* Headers */ = { 151 | isa = PBXGroup; 152 | children = ( 153 | B2FEF269AE2F4CAB8761F3FA /* Resources.h */, 154 | 1A9E6A8454034E9096E913DB /* SvvimGram_Prefix.pch */, 155 | C97478D7187BBC1B003DECA4 /* svvim.h */, 156 | C97478D8187BBC87003DECA4 /* SvvimPost.h */, 157 | C97478DB187BC3DC003DECA4 /* Dependencies */, 158 | C97478DA187BC3CC003DECA4 /* Scenes */, 159 | ); 160 | name = Headers; 161 | sourceTree = ""; 162 | }; 163 | 29B97317FDCFA39411CA2CEA /* Resources */ = { 164 | isa = PBXGroup; 165 | children = ( 166 | C9FA6F6C187CDFE700CD71AC /* svvim-logo-white.png */, 167 | C921338E187BCF8A00828C98 /* pizza.jpg */, 168 | C9213388187BCF4600828C98 /* Soda-Can.obj */, 169 | C97478E0187BCD22003DECA4 /* glsl */, 170 | 03D18A33B65D46F8B558BE8A /* CinderApp.icns */, 171 | 4397C570128C461C86383165 /* Info.plist */, 172 | ); 173 | name = Resources; 174 | sourceTree = ""; 175 | }; 176 | 29B97323FDCFA39411CA2CEA /* Frameworks */ = { 177 | isa = PBXGroup; 178 | children = ( 179 | 1058C7A0FEA54F0111CA2CBB /* Linked Frameworks */, 180 | 1058C7A2FEA54F0111CA2CBB /* Other Frameworks */, 181 | 25676F373D3E48A392E4BC25 /* QuickTime.framework */, 182 | ); 183 | name = Frameworks; 184 | sourceTree = ""; 185 | }; 186 | C97478DA187BC3CC003DECA4 /* Scenes */ = { 187 | isa = PBXGroup; 188 | children = ( 189 | C97478D9187BBFBB003DECA4 /* ProjectionScene.h */, 190 | C9FA6F52187C020B00CD71AC /* InstagramProjectionScene.h */, 191 | ); 192 | name = Scenes; 193 | sourceTree = ""; 194 | }; 195 | C97478DB187BC3DC003DECA4 /* Dependencies */ = { 196 | isa = PBXGroup; 197 | children = ( 198 | C9FA6F53187C143500CD71AC /* SodaCan.h */, 199 | C9520287187BF36C00D4131A /* SvvimScene.h */, 200 | C97478D2187BB660003DECA4 /* AsynchMovieWriter.h */, 201 | C97478D4187BB73E003DECA4 /* InstagramStream.h */, 202 | ); 203 | name = Dependencies; 204 | sourceTree = ""; 205 | }; 206 | C97478E0187BCD22003DECA4 /* glsl */ = { 207 | isa = PBXGroup; 208 | children = ( 209 | C9FA6F5A187CAABD00CD71AC /* hblur.frag */, 210 | C9FA6F5B187CAABD00CD71AC /* pass.vert */, 211 | C9FA6F5C187CAABD00CD71AC /* vblur.frag */, 212 | C921338A187BCF7A00828C98 /* project.frag */, 213 | C921338B187BCF7A00828C98 /* project.vert */, 214 | ); 215 | name = glsl; 216 | sourceTree = ""; 217 | }; 218 | /* End PBXGroup section */ 219 | 220 | /* Begin PBXNativeTarget section */ 221 | 8D1107260486CEB800E47090 /* SvvimGram */ = { 222 | isa = PBXNativeTarget; 223 | buildConfigurationList = C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "SvvimGram" */; 224 | buildPhases = ( 225 | 8D1107290486CEB800E47090 /* Resources */, 226 | 8D11072C0486CEB800E47090 /* Sources */, 227 | 8D11072E0486CEB800E47090 /* Frameworks */, 228 | ); 229 | buildRules = ( 230 | ); 231 | dependencies = ( 232 | ); 233 | name = SvvimGram; 234 | productInstallPath = "$(HOME)/Applications"; 235 | productName = SvvimGram; 236 | productReference = 8D1107320486CEB800E47090 /* SvvimGram.app */; 237 | productType = "com.apple.product-type.application"; 238 | }; 239 | /* End PBXNativeTarget section */ 240 | 241 | /* Begin PBXProject section */ 242 | 29B97313FDCFA39411CA2CEA /* Project object */ = { 243 | isa = PBXProject; 244 | attributes = { 245 | }; 246 | buildConfigurationList = C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SvvimGram" */; 247 | compatibilityVersion = "Xcode 3.2"; 248 | developmentRegion = English; 249 | hasScannedForEncodings = 1; 250 | knownRegions = ( 251 | English, 252 | Japanese, 253 | French, 254 | German, 255 | ); 256 | mainGroup = 29B97314FDCFA39411CA2CEA /* SvvimGram */; 257 | projectDirPath = ""; 258 | projectRoot = ""; 259 | targets = ( 260 | 8D1107260486CEB800E47090 /* SvvimGram */, 261 | ); 262 | }; 263 | /* End PBXProject section */ 264 | 265 | /* Begin PBXResourcesBuildPhase section */ 266 | 8D1107290486CEB800E47090 /* Resources */ = { 267 | isa = PBXResourcesBuildPhase; 268 | buildActionMask = 2147483647; 269 | files = ( 270 | C9FA6F6D187CDFE700CD71AC /* svvim-logo-white.png in Resources */, 271 | C9FA6F60187CAE1900CD71AC /* hblur.frag in Resources */, 272 | C9FA6F61187CAE1900CD71AC /* pass.vert in Resources */, 273 | C9FA6F62187CAE1900CD71AC /* vblur.frag in Resources */, 274 | C9213390187BD1E000828C98 /* project.frag in Resources */, 275 | C9213391187BD1E000828C98 /* project.vert in Resources */, 276 | C97455EFA2384A53986F304D /* CinderApp.icns in Resources */, 277 | C9213389187BCF4600828C98 /* Soda-Can.obj in Resources */, 278 | C921338F187BCF8A00828C98 /* pizza.jpg in Resources */, 279 | ); 280 | runOnlyForDeploymentPostprocessing = 0; 281 | }; 282 | /* End PBXResourcesBuildPhase section */ 283 | 284 | /* Begin PBXSourcesBuildPhase section */ 285 | 8D11072C0486CEB800E47090 /* Sources */ = { 286 | isa = PBXSourcesBuildPhase; 287 | buildActionMask = 2147483647; 288 | files = ( 289 | C97478D5187BB73E003DECA4 /* InstagramStream.cpp in Sources */, 290 | E6ABCBC128DF4EAEAED0B8D9 /* SvvimGramApp.cpp in Sources */, 291 | ); 292 | runOnlyForDeploymentPostprocessing = 0; 293 | }; 294 | /* End PBXSourcesBuildPhase section */ 295 | 296 | /* Begin XCBuildConfiguration section */ 297 | C01FCF4B08A954540054247B /* Debug */ = { 298 | isa = XCBuildConfiguration; 299 | buildSettings = { 300 | COMBINE_HIDPI_IMAGES = YES; 301 | COPY_PHASE_STRIP = NO; 302 | DEAD_CODE_STRIPPING = YES; 303 | GCC_DYNAMIC_NO_PIC = NO; 304 | GCC_INLINES_ARE_PRIVATE_EXTERN = YES; 305 | GCC_OPTIMIZATION_LEVEL = 0; 306 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 307 | GCC_PREFIX_HEADER = SvvimGram_Prefix.pch; 308 | GCC_PREPROCESSOR_DEFINITIONS = ( 309 | "DEBUG=1", 310 | "$(inherited)", 311 | ); 312 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 313 | INFOPLIST_FILE = Info.plist; 314 | INSTALL_PATH = "$(HOME)/Applications"; 315 | OTHER_LDFLAGS = "\"$(CINDER_PATH)/lib/libcinder_d.a\""; 316 | PRODUCT_NAME = SvvimGram; 317 | SYMROOT = ./build; 318 | WRAPPER_EXTENSION = app; 319 | }; 320 | name = Debug; 321 | }; 322 | C01FCF4C08A954540054247B /* Release */ = { 323 | isa = XCBuildConfiguration; 324 | buildSettings = { 325 | COMBINE_HIDPI_IMAGES = YES; 326 | DEAD_CODE_STRIPPING = YES; 327 | DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym"; 328 | GCC_FAST_MATH = YES; 329 | GCC_GENERATE_DEBUGGING_SYMBOLS = NO; 330 | GCC_INLINES_ARE_PRIVATE_EXTERN = YES; 331 | GCC_OPTIMIZATION_LEVEL = 3; 332 | GCC_PRECOMPILE_PREFIX_HEADER = YES; 333 | GCC_PREFIX_HEADER = SvvimGram_Prefix.pch; 334 | GCC_SYMBOLS_PRIVATE_EXTERN = NO; 335 | INFOPLIST_FILE = Info.plist; 336 | INSTALL_PATH = "$(HOME)/Applications"; 337 | OTHER_LDFLAGS = "\"$(CINDER_PATH)/lib/libcinder.a\""; 338 | PRODUCT_NAME = SvvimGram; 339 | STRIP_INSTALLED_PRODUCT = YES; 340 | SYMROOT = ./build; 341 | WRAPPER_EXTENSION = app; 342 | }; 343 | name = Release; 344 | }; 345 | C01FCF4F08A954540054247B /* Debug */ = { 346 | isa = XCBuildConfiguration; 347 | buildSettings = { 348 | ALWAYS_SEARCH_USER_PATHS = NO; 349 | ARCHS = i386; 350 | CINDER_PATH = ../../../../libs/cinder_0.8.5_mac; 351 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 352 | CLANG_CXX_LIBRARY = "libc++"; 353 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 354 | GCC_WARN_UNUSED_VARIABLE = YES; 355 | HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\""; 356 | MACOSX_DEPLOYMENT_TARGET = 10.7; 357 | SDKROOT = macosx; 358 | USER_HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/include\" ../include ../blocks/QuickTime/include"; 359 | }; 360 | name = Debug; 361 | }; 362 | C01FCF5008A954540054247B /* Release */ = { 363 | isa = XCBuildConfiguration; 364 | buildSettings = { 365 | ALWAYS_SEARCH_USER_PATHS = NO; 366 | ARCHS = i386; 367 | CINDER_PATH = ../../../../libs/cinder_0.8.5_mac; 368 | CLANG_CXX_LANGUAGE_STANDARD = "c++0x"; 369 | CLANG_CXX_LIBRARY = "libc++"; 370 | GCC_WARN_ABOUT_RETURN_TYPE = YES; 371 | GCC_WARN_UNUSED_VARIABLE = YES; 372 | HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/boost\""; 373 | MACOSX_DEPLOYMENT_TARGET = 10.7; 374 | SDKROOT = macosx; 375 | USER_HEADER_SEARCH_PATHS = "\"$(CINDER_PATH)/include\" ../include ../blocks/QuickTime/include"; 376 | }; 377 | name = Release; 378 | }; 379 | /* End XCBuildConfiguration section */ 380 | 381 | /* Begin XCConfigurationList section */ 382 | C01FCF4A08A954540054247B /* Build configuration list for PBXNativeTarget "SvvimGram" */ = { 383 | isa = XCConfigurationList; 384 | buildConfigurations = ( 385 | C01FCF4B08A954540054247B /* Debug */, 386 | C01FCF4C08A954540054247B /* Release */, 387 | ); 388 | defaultConfigurationIsVisible = 0; 389 | defaultConfigurationName = Release; 390 | }; 391 | C01FCF4E08A954540054247B /* Build configuration list for PBXProject "SvvimGram" */ = { 392 | isa = XCConfigurationList; 393 | buildConfigurations = ( 394 | C01FCF4F08A954540054247B /* Debug */, 395 | C01FCF5008A954540054247B /* Release */, 396 | ); 397 | defaultConfigurationIsVisible = 0; 398 | defaultConfigurationName = Release; 399 | }; 400 | /* End XCConfigurationList section */ 401 | }; 402 | rootObject = 29B97313FDCFA39411CA2CEA /* Project object */; 403 | } 404 | --------------------------------------------------------------------------------