├── 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 |
--------------------------------------------------------------------------------