diff --git a/example/example.xcodeproj/project.pbxproj b/example/example.xcodeproj/project.pbxproj index f1df4b8..f83a8eb 100644 --- a/example/example.xcodeproj/project.pbxproj +++ b/example/example.xcodeproj/project.pbxproj @@ -19,6 +19,7 @@ 3933D5D819BB87BD000ACA55 /* ofxSlider.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3933D5CD19BB87BD000ACA55 /* ofxSlider.cpp */; }; 3933D5D919BB87BD000ACA55 /* ofxSliderGroup.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3933D5CF19BB87BD000ACA55 /* ofxSliderGroup.cpp */; }; 3933D5DA19BB87BD000ACA55 /* ofxToggle.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 3933D5D119BB87BD000ACA55 /* ofxToggle.cpp */; }; + 397EFC7C1A08E7680009286E /* ofxPiMapper.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 397EFC7B1A08E7680009286E /* ofxPiMapper.cpp */; }; 39C1243319EE9589005DF557 /* lz4.c in Sources */ = {isa = PBXBuildFile; fileRef = 39C123EA19EE9589005DF557 /* lz4.c */; }; 39C1243419EE9589005DF557 /* Base64Encoding.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39C1241219EE9589005DF557 /* Base64Encoding.cpp */; }; 39C1243519EE9589005DF557 /* ByteBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 39C1241319EE9589005DF557 /* ByteBuffer.cpp */; }; @@ -136,6 +137,7 @@ 3933D5D119BB87BD000ACA55 /* ofxToggle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxToggle.cpp; sourceTree = ""; }; 3933D5D219BB87BD000ACA55 /* ofxToggle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxToggle.h; sourceTree = ""; }; 39366FD519BDA95E006E5BE6 /* ofxPiMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxPiMapper.h; sourceTree = ""; }; + 397EFC7B1A08E7680009286E /* ofxPiMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxPiMapper.cpp; sourceTree = ""; }; 39C123E719EE9589005DF557 /* alphanum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = alphanum.hpp; sourceTree = ""; }; 39C123EA19EE9589005DF557 /* lz4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4.c; sourceTree = ""; }; 39C123EB19EE9589005DF557 /* lz4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4.h; sourceTree = ""; }; @@ -361,6 +363,7 @@ 39C1245619F086A9005DF557 /* Sources */, 39C1244C19EE95DD005DF557 /* MediaServer */, 39366FD519BDA95E006E5BE6 /* ofxPiMapper.h */, + 397EFC7B1A08E7680009286E /* ofxPiMapper.cpp */, ); name = src; path = ../src; @@ -828,6 +831,7 @@ 39C1244A19EE9589005DF557 /* snappy-stubs-internal.cc in Sources */, 39C1245F19F08965005DF557 /* VideoSource.cpp in Sources */, 39C1244119EE9589005DF557 /* HexBinaryEncoding.cpp in Sources */, + 397EFC7C1A08E7680009286E /* ofxPiMapper.cpp in Sources */, 39C1244219EE9589005DF557 /* HiddenFileFilter.cpp in Sources */, 39C1244819EE9589005DF557 /* SearchPath.cpp in Sources */, 39C1248019F187D5005DF557 /* SourcesEditor.cpp in Sources */, diff --git a/example/src/ofApp.cpp b/example/src/ofApp.cpp index 101e14e..bacbe47 100755 --- a/example/src/ofApp.cpp +++ b/example/src/ofApp.cpp @@ -1,32 +1,20 @@ #include "ofApp.h" void ofApp::setup() { - bShowInfo = false; - // Pass pointers to our media server instance to both: - // surface manager and it's gui, only then we will be able to - // load surface data from xml settings files - surfaceManager.setMediaServer(&mediaServer); - gui.setMediaServer(&mediaServer); - - // check if the surfaces.xml file is there - // if not - load defaultSurfaces.xml - if (ofFile::doesFileExist("surfaces.xml")) { - surfaceManager.loadXmlSettings("surfaces.xml"); - } else { - surfaceManager.loadXmlSettings("defaultSurfaces.xml"); - } - - // Pass the surface manager to the mapper graphical user interface - gui.setSurfaceManager(&surfaceManager); - - // Create FBO + // The ofxPiMapper is being set up automatically before the first + // ofApp setup call + piMapper.showInfo(); // The info layer is hidden by default, press to toggle + + // Create our custom FBO fbo = new ofFbo(); fbo->allocate(500, 500); fboSource = new ofx::piMapper::BaseSource(&fbo->getTextureReference()); - setFboAsSource(); + + // Assign the FBO's texture to one of the surfaces ofxPiMapper has created + piMapper.getSurfaceManager().getSurface(0)->setSource(fboSource); - // Genereate rects + // Genereate rects to be rendered into the FBO int numRects = 20; // change this to add more or less rects for (int i = 0; i < numRects; i++) { rects.push_back(ofRectangle(0, ofRandom(fbo->getHeight()), fbo->getWidth(), @@ -36,6 +24,7 @@ void ofApp::setup() { } void ofApp::update() { + // Move rects for (int i = 0; i < rects.size(); i++) { rects[i].y += rectSpeeds[i]; @@ -44,7 +33,7 @@ void ofApp::update() { } } - // Fill FBO + // Fill FBO with our rects fbo->begin(); ofClear(0); ofBackground(0); @@ -56,135 +45,9 @@ void ofApp::update() { } void ofApp::draw() { - // Draw the piMapper GUI - gui.draw(); - - if (bShowInfo) { - // Draw instructions - stringstream ss; - ss << "There are 4 modes:\n\n"; - ss << " 1. Presentation mode\n"; - ss << " 2. Texture mapping mode\n"; - ss << " 3. Projection mapping mode\n"; - ss << " 4. Source selection mode\n\n"; - ss << "You can switch between the modes by using <1>, <2>, <3> and <4> " - "keys on the keyboard.\n\n"; - ss << "Press or to add random or normal surface.\n"; - ss << "Press to add a new quad surface.\n"; - ss << "Press to save the composition.\n"; - ss << "Press to toggle fullscreen.\n"; - ss << "Press to reassign the fbo texture to the first surface\n"; - ss << "Hit to hide this message."; - - ofDrawBitmapStringHighlight(ss.str(), 10, 20, ofColor(0, 0, 0, 100), - ofColor(255, 255, 255, 200)); - } + piMapper.draw(); } void ofApp::exit() { - // Clear FBO from mem delete fbo; -} - -void ofApp::keyPressed(int key) { - cout << "Key pressed: " << static_cast(key) << endl; - - switch (key) { - case '1': - gui.setMode(ofx::piMapper::GuiMode::NONE); - break; - case '2': - gui.setMode(ofx::piMapper::GuiMode::TEXTURE_MAPPING); - break; - case '3': - gui.setMode(ofx::piMapper::GuiMode::PROJECTION_MAPPING); - break; - case '4': - gui.setMode(ofx::piMapper::GuiMode::SOURCE_SELECTION); - break; - case 'i': - bShowInfo = !bShowInfo; - break; - case 'r': - addRandomSurface(); - break; - case 'q': - addQuadSurface(); - break; - case 'n': - addSurface(); - break; - case 'f': - ofToggleFullscreen(); - break; - case 's': - surfaceManager.saveXmlSettings("surfaces.xml"); - break; - case 'a': - setFboAsSource(); - break; - case OF_KEY_BACKSPACE: - surfaceManager.removeSelectedSurface(); - break; - default: - break; - } -} - -void ofApp::addRandomSurface() { - int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; - vector vertices; - vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); - vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); - vertices.push_back(ofVec2f(ofRandomWidth(), ofRandomHeight())); - vector texCoords; - texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); - texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); - texCoords.push_back(ofVec2f(ofRandomuf(), ofRandomuf())); - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size() - 1); -} - -void ofApp::addQuadSurface() { - int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; - vector vertices; - - int border = 50; - vertices.push_back(ofVec2f(border, border)); - vertices.push_back(ofVec2f(ofGetWidth() - border, border)); - vertices.push_back(ofVec2f(ofGetWidth() - border, ofGetHeight() - border)); - vertices.push_back(ofVec2f(border, ofGetHeight() - border)); - - vector texCoords; - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); - texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); - texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); - - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size() - 1); -} - -void ofApp::addSurface() { - int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; - vector vertices; - vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, 0.0f)); - vertices.push_back(ofVec2f((float)ofGetWidth(), (float)ofGetHeight())); - vertices.push_back(ofVec2f(0.0f, (float)ofGetHeight())); - vector texCoords; - texCoords.push_back(ofVec2f(0.5f, 0.0f)); - texCoords.push_back(ofVec2f(1.0f, 1.0f)); - texCoords.push_back(ofVec2f(0.0f, 1.0f)); - surfaceManager.addSurface(surfaceType, vertices, texCoords); - - // select this surface right away - surfaceManager.selectSurface(surfaceManager.size() - 1); -} - -void ofApp::setFboAsSource() { - surfaceManager.getSurface(0)->setSource(fboSource); } \ No newline at end of file diff --git a/example/src/ofApp.h b/example/src/ofApp.h index b3455a3..e6cb415 100755 --- a/example/src/ofApp.h +++ b/example/src/ofApp.h @@ -5,24 +5,16 @@ #include "BaseSource.h" class ofApp : public ofBaseApp { - public: +public: void setup(); void update(); void draw(); void exit(); - void keyPressed(int key); - - void addRandomSurface(); - void addQuadSurface(); - void addSurface(); - void setFboAsSource(); - + ofxPiMapper piMapper; + + // Custom FBO surface variables ofImage image; - ofx::piMapper::MediaServer mediaServer; - ofx::piMapper::SurfaceManager surfaceManager; - ofx::piMapper::SurfaceManagerGui gui; - bool bShowInfo; ofFbo* fbo; ofx::piMapper::BaseSource* fboSource; vector rects; diff --git a/src/ofxPiMapper.cpp b/src/ofxPiMapper.cpp new file mode 100644 index 0000000..1e8bce9 --- /dev/null +++ b/src/ofxPiMapper.cpp @@ -0,0 +1,158 @@ +#include "ofxPiMapper.h" + +ofxPiMapper::ofxPiMapper(): +bShowInfo(false), +isSetUp(false){ + ofAddListener(ofEvents().setup, this, &ofxPiMapper::setup, OF_EVENT_ORDER_BEFORE_APP); + ofAddListener(ofEvents().keyPressed, this, &ofxPiMapper::keyPressed); +} + +ofxPiMapper::~ofxPiMapper() { + ofRemoveListener(ofEvents().setup, this, &ofxPiMapper::setup, OF_EVENT_ORDER_BEFORE_APP); + ofRemoveListener(ofEvents().keyPressed, this, &ofxPiMapper::keyPressed); +} + +void ofxPiMapper::setup(ofEventArgs& args) { + ofLogNotice("ofxPiMapper") << "Setting up..."; + + // Assign media server to other pi mapper components + surfaceManager.setMediaServer(&mediaServer); + gui.setMediaServer(&mediaServer); + + // Check if we have user surfaces defined, if not - load default + if (ofFile::doesFileExist(PIMAPPER_USER_SURFACES_XML_FILE)) { + ofLogNotice("ofxPiMapper") << "Loading user surfaces from " << PIMAPPER_USER_SURFACES_XML_FILE; + surfaceManager.loadXmlSettings(PIMAPPER_USER_SURFACES_XML_FILE); + } else { + ofLogNotice("ofxPiMapper") << "Loading default surfaces from " << PIMAPPER_DEF_SURFACES_XML_FILE; + surfaceManager.loadXmlSettings(PIMAPPER_DEF_SURFACES_XML_FILE); + } + + // The GUI needs something to interface with + gui.setSurfaceManager(&surfaceManager); + + isSetUp = true; + + ofLogNotice("ofxPiMapper") << "Done setting up"; +} + +void ofxPiMapper::draw() { + if (!isSetUp) { + return; + } + + // Draw the piMapper GUI + gui.draw(); + + if (bShowInfo) { + // Draw instructions + stringstream ss; + ss << "There are 4 modes:\n\n"; + ss << " 1. Presentation mode\n"; + ss << " 2. Texture mapping mode\n"; + ss << " 3. Projection mapping mode\n"; + ss << " 4. Source selection mode\n\n"; + ss << "You can switch between the modes by using <1>, <2>, <3> and <4> " + "keys on the keyboard.\n\n"; + ss << "Press to add new triangle surface\n"; + ss << "Press to add new quad surface\n"; + ss << "Press to save the composition\n"; + ss << "Press to toggle fullscreen\n"; + ss << "Press to hide this message"; + + ofDrawBitmapStringHighlight(ss.str(), 10, 20, ofColor(0, 0, 0, 100), + ofColor(255, 255, 255, 200)); + } + +} // draw + +void ofxPiMapper::keyPressed(ofKeyEventArgs &args) { + ofLogNotice("ofxPiMapper") << "Key pressed: " << static_cast(args.key); + + switch (args.key) { + case '1': + gui.setMode(ofx::piMapper::GuiMode::NONE); + break; + case '2': + gui.setMode(ofx::piMapper::GuiMode::TEXTURE_MAPPING); + break; + case '3': + gui.setMode(ofx::piMapper::GuiMode::PROJECTION_MAPPING); + break; + case '4': + gui.setMode(ofx::piMapper::GuiMode::SOURCE_SELECTION); + break; + case 'i': + bShowInfo = !bShowInfo; + break; + case 'q': + addQuadSurface(); + break; + case 't': + addTriangleSurface(); + break; + case 'f': + ofToggleFullscreen(); + break; + case 's': + surfaceManager.saveXmlSettings(PIMAPPER_USER_SURFACES_XML_FILE); + break; + case OF_KEY_BACKSPACE: + surfaceManager.removeSelectedSurface(); + break; + default: + break; + } +} // keyPressed + +void ofxPiMapper::addTriangleSurface() { + int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f((float)ofGetWidth() / 2.0f, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(0.5f, 0.0f)); + texCoords.push_back(ofVec2f(1.0f, 1.0f)); + texCoords.push_back(ofVec2f(0.0f, 1.0f)); + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // Select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); + +} // addTriangleSurface + +void ofxPiMapper::addQuadSurface() { + + int surfaceType = ofx::piMapper::SurfaceType::QUAD_SURFACE; + + vector vertices; + float margin = 50.0f; + vertices.push_back(ofVec2f(margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, margin)); + vertices.push_back(ofVec2f((float)ofGetWidth() - margin, (float)ofGetHeight() - margin)); + vertices.push_back(ofVec2f(margin, (float)ofGetHeight() - margin)); + + vector texCoords; + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 0.0f))); + texCoords.push_back(ofVec2f(ofVec2f(1.0f, 1.0f))); + texCoords.push_back(ofVec2f(ofVec2f(0.0f, 1.0f))); + + surfaceManager.addSurface(surfaceType, vertices, texCoords); + + // select this surface right away + surfaceManager.selectSurface(surfaceManager.size() - 1); + +} // addQuadSurface + +ofx::piMapper::MediaServer& ofxPiMapper::getMediaServer() { + return mediaServer; +} + +ofx::piMapper::SurfaceManager& ofxPiMapper::getSurfaceManager() { + return surfaceManager; +} \ No newline at end of file diff --git a/src/ofxPiMapper.h b/src/ofxPiMapper.h index 975b9f6..ff93ab7 100644 --- a/src/ofxPiMapper.h +++ b/src/ofxPiMapper.h @@ -1,6 +1,38 @@ #pragma once +#include "ofMain.h" #include "SurfaceManager.h" #include "SurfaceManagerGui.h" +#include "MediaServer.h" -#include "MediaServer.h" \ No newline at end of file +#define PIMAPPER_DEF_SURFACES_XML_FILE "defaultSurfaces.xml" +#define PIMAPPER_USER_SURFACES_XML_FILE "surfaces.xml" + +class ofxPiMapper { +public: + ofxPiMapper(); + ~ofxPiMapper(); + + void setup(ofEventArgs& args); + void draw(); // Called manually to make custom layering possible + void keyPressed(ofKeyEventArgs& args); + + // TODO: Move these methods to SurfaceManager + void addTriangleSurface(); + void addQuadSurface(); + + // Toggle help / info + void showInfo() { bShowInfo = true; }; + void hideInfo() { bShowInfo = false; }; + + // Getters + ofx::piMapper::MediaServer& getMediaServer(); + ofx::piMapper::SurfaceManager& getSurfaceManager(); + +private: + bool isSetUp; + bool bShowInfo; + ofx::piMapper::MediaServer mediaServer; + ofx::piMapper::SurfaceManager surfaceManager; + ofx::piMapper::SurfaceManagerGui gui; +}; \ No newline at end of file