Browse Source

Merge branch 'feature-fboSource' into develop

master
Krisjanis Rijnieks 11 years ago
parent
commit
2be9468a5e
  1. 12
      example/example.xcodeproj/project.pbxproj
  2. 43
      example/src/CustomSource.cpp
  3. 17
      example/src/CustomSource.h
  4. 52
      example/src/ofApp.cpp
  5. 13
      example/src/ofApp.h
  6. 96
      src/MediaServer/MediaServer.cpp
  7. 37
      src/MediaServer/MediaServer.h
  8. 3
      src/Sources/BaseSource.h
  9. 81
      src/Sources/FboSource.cpp
  10. 49
      src/Sources/FboSource.h
  11. 7
      src/Sources/SourceType.h
  12. 19
      src/Surfaces/SurfaceManager.cpp
  13. 148
      src/UserInterface/SourcesEditor.cpp
  14. 19
      src/UserInterface/SourcesEditor.h
  15. 8
      src/ofxPiMapper.cpp
  16. 8
      src/ofxPiMapper.h

12
example/example.xcodeproj/project.pbxproj

@ -20,6 +20,8 @@
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 */; };
397EFC7F1A08FE720009286E /* FboSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 397EFC7D1A08FE720009286E /* FboSource.cpp */; };
397EFC821A09047C0009286E /* CustomSource.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 397EFC801A09047C0009286E /* CustomSource.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 */; };
@ -138,6 +140,10 @@
3933D5D219BB87BD000ACA55 /* ofxToggle.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxToggle.h; sourceTree = "<group>"; };
39366FD519BDA95E006E5BE6 /* ofxPiMapper.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ofxPiMapper.h; sourceTree = "<group>"; };
397EFC7B1A08E7680009286E /* ofxPiMapper.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = ofxPiMapper.cpp; sourceTree = "<group>"; };
397EFC7D1A08FE720009286E /* FboSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = FboSource.cpp; sourceTree = "<group>"; };
397EFC7E1A08FE720009286E /* FboSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = FboSource.h; sourceTree = "<group>"; };
397EFC801A09047C0009286E /* CustomSource.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CustomSource.cpp; sourceTree = "<group>"; };
397EFC811A09047C0009286E /* CustomSource.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = CustomSource.h; sourceTree = "<group>"; };
39C123E719EE9589005DF557 /* alphanum.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = alphanum.hpp; sourceTree = "<group>"; };
39C123EA19EE9589005DF557 /* lz4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lz4.c; sourceTree = "<group>"; };
39C123EB19EE9589005DF557 /* lz4.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lz4.h; sourceTree = "<group>"; };
@ -577,6 +583,8 @@
39C1245B19F08965005DF557 /* ImageSource.h */,
39C1245C19F08965005DF557 /* VideoSource.cpp */,
39C1245D19F08965005DF557 /* VideoSource.h */,
397EFC7D1A08FE720009286E /* FboSource.cpp */,
397EFC7E1A08FE720009286E /* FboSource.h */,
);
path = Sources;
sourceTree = "<group>";
@ -696,6 +704,8 @@
E4B69E1D0A3A1BDC003C02F2 /* main.cpp */,
E4B69E1E0A3A1BDC003C02F2 /* ofApp.cpp */,
E4B69E1F0A3A1BDC003C02F2 /* ofApp.h */,
397EFC801A09047C0009286E /* CustomSource.cpp */,
397EFC811A09047C0009286E /* CustomSource.h */,
);
path = src;
sourceTree = SOURCE_ROOT;
@ -810,6 +820,7 @@
39C1246A19F0AB96005DF557 /* QuadSurface.cpp in Sources */,
39C1247F19F187D5005DF557 /* RadioList.cpp in Sources */,
39C1243419EE9589005DF557 /* Base64Encoding.cpp in Sources */,
397EFC7F1A08FE720009286E /* FboSource.cpp in Sources */,
E4B69E200A3A1BDC003C02F2 /* main.cpp in Sources */,
39C1244719EE9589005DF557 /* RegexPathFilter.cpp in Sources */,
39C1247C19F187D5005DF557 /* BaseJoint.cpp in Sources */,
@ -850,6 +861,7 @@
39264842192224F90008A7F5 /* tinyxmlerror.cpp in Sources */,
3926483B192224DA0008A7F5 /* ofxXmlSettings.cpp in Sources */,
39C1245119EE95DD005DF557 /* DirectoryWatcher.cpp in Sources */,
397EFC821A09047C0009286E /* CustomSource.cpp in Sources */,
39C1243819EE9589005DF557 /* ByteBufferWriter.cpp in Sources */,
3933D5D519BB87BD000ACA55 /* ofxGuiGroup.cpp in Sources */,
);

43
example/src/CustomSource.cpp

@ -0,0 +1,43 @@
#include "CustomSource.h"
// Don't do any drawing here
void CustomSource::setup() {
// Give our source a decent name
name = "Custom FBO Source";
// Allocate our FBO source, decide how big it should be
allocate(500, 500);
// 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(),
ofRandom(20)));
rectSpeeds.push_back((1.0f + ofRandom(5)));
}
}
// Don't do any drawing here
void CustomSource::update() {
// Move rects
for (int i = 0; i < rects.size(); i++) {
rects[i].y += rectSpeeds[i];
if (rects[i].y > fbo->getHeight()) {
rects[i].y = -rects[i].getHeight();
}
}
}
// No need to take care of fbo.begin() and fbo.end() here.
// All within draw() is being rendered into fbo;
void CustomSource::draw() {
// Fill FBO with our rects
ofClear(0);
//ofBackground(0);
ofSetColor(255);
for (int i = 0; i < rects.size(); i++) {
ofRect(rects[i]);
}
}

17
example/src/CustomSource.h

@ -0,0 +1,17 @@
#pragma once
#include "ofMain.h"
#include "FboSource.h"
class CustomSource : public ofx::piMapper::FboSource {
public:
// These are overrides of FboSource virtual functions.
// FBO sources are not executing before they have been assigned to a surface.
void setup();
void update();
void draw(); // You don't have to care about fbo.begin() or fbo.end() here
private:
vector<ofRectangle> rects;
vector<float> rectSpeeds;
};

52
example/src/ofApp.cpp

@ -1,53 +1,19 @@
#include "ofApp.h"
void ofApp::setup() {
ofBackground(0);
// The ofxPiMapper is being set up automatically before the first
// ofApp setup call
piMapper.showInfo(); // The info layer is hidden by default, press <i> to toggle
// Create our custom FBO
fbo = new ofFbo();
fbo->allocate(500, 500);
fboSource = new ofx::piMapper::BaseSource(&fbo->getTextureReference());
// Assign the FBO's texture to one of the surfaces ofxPiMapper has created
piMapper.getSurfaceManager().getSurface(0)->setSource(fboSource);
// 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(),
ofRandom(20)));
rectSpeeds.push_back((1.0f + ofRandom(5)));
}
}
void ofApp::update() {
// Add our CustomSource to list of fbo sources of the piMapper
// FBO sources should be added before piMapper.setup() so the
// piMapper is able to load the source if it is assigned to
// a surface in XML settings.
piMapper.addFboSource(customSource);
piMapper.setup();
// Move rects
for (int i = 0; i < rects.size(); i++) {
rects[i].y += rectSpeeds[i];
if (rects[i].y > fbo->getHeight()) {
rects[i].y = -rects[i].getHeight();
}
}
// Fill FBO with our rects
fbo->begin();
ofClear(0);
ofBackground(0);
ofSetColor(255);
for (int i = 0; i < rects.size(); i++) {
ofRect(rects[i]);
}
fbo->end();
// The info layer is hidden by default, press <i> to toggle
piMapper.showInfo();
}
void ofApp::draw() {
piMapper.draw();
}
void ofApp::exit() {
delete fbo;
}

13
example/src/ofApp.h

@ -2,21 +2,16 @@
#include "ofMain.h"
#include "ofxPiMapper.h"
#include "BaseSource.h"
#include "CustomSource.h"
class ofApp : public ofBaseApp {
public:
void setup();
void update();
void draw();
void exit();
ofxPiMapper piMapper;
// Custom FBO surface variables
ofImage image;
ofFbo* fbo;
ofx::piMapper::BaseSource* fboSource;
vector<ofRectangle> rects;
vector<float> rectSpeeds;
// By using a custom source that is derived from FboSource
// you will be able to see the source listed in sources editor
CustomSource customSource;
};

96
src/MediaServer/MediaServer.cpp

@ -23,6 +23,7 @@ namespace piMapper {
int MediaServer::getNumImages() { return imageWatcher.getFilePaths().size(); }
int MediaServer::getNumVideos() { return videoWatcher.getFilePaths().size(); }
int MediaServer::getNumFboSources() { return fboSources.size(); }
std::vector<std::string>& MediaServer::getImagePaths() {
return imageWatcher.getFilePaths();
@ -40,6 +41,14 @@ namespace piMapper {
return imageNames;
}
std::vector<std::string> MediaServer::getFboSourceNames() {
std::vector<std::string> fboSourceNames;
for (int i = 0; i < fboSources.size(); i++) {
fboSourceNames.push_back(fboSources[i]->getName());
}
return fboSourceNames;
}
std::vector<std::string>& MediaServer::getVideoPaths() {
return videoWatcher.getFilePaths();
}
@ -56,14 +65,14 @@ namespace piMapper {
return videoNames;
}
BaseSource* MediaServer::loadMedia(string &path, int mediaType) {
// Chose load method depending on type
if (mediaType == SourceType::SOURCE_TYPE_IMAGE) {
return loadImage(path);
} else if (mediaType == SourceType::SOURCE_TYPE_VIDEO) {
return loadVideo(path);
} else if (mediaType == SourceType::SOURCE_TYPE_FBO) {
return loadFboSource(path);
} else {
std::stringstream ss;
ss << "Can not load media of unknown type: " << mediaType;
@ -214,16 +223,15 @@ namespace piMapper {
unloadImage(path);
} else if (mediaSource->getType() == SourceType::SOURCE_TYPE_VIDEO) {
unloadVideo(path);
} else if (mediaSource->getType() == SourceType::SOURCE_TYPE_FBO) {
unloadFboSource(path);
} else {
// Oh my god, what to do!? Relax and exit.
ofLogFatalError("MediaServer") << "Attempt to unload media of unknown type";
std::exit(EXIT_FAILURE);
}
} else {
std:stringstream ss;
ss << "Media with path " << path << " is not loaded and thus can't be unloaded";
ofLogFatalError("MediaServer") << ss.str();
std::exit(EXIT_FAILURE);
ofLogNotice("MediaServer") << "Nothing to unload";
}
}
@ -231,11 +239,15 @@ namespace piMapper {
void MediaServer::clear() {
typedef std::map<std::string, BaseSource*>::iterator it_type;
for (it_type i = loadedSources.begin(); i != loadedSources.end(); i++) {
delete i->second;
// Do not delete FBO source pointers as they are (and should be) initialized elsewhere
if (i->second->getType() != SourceType::SOURCE_TYPE_FBO) {
delete i->second;
}
}
loadedSources.clear();
}
// TODO: getLoadedSourceByPath
BaseSource* MediaServer::getSourceByPath(std::string& mediaPath) {
if (loadedSources.count(mediaPath)) {
return loadedSources[mediaPath];
@ -268,6 +280,76 @@ namespace piMapper {
}
}
void MediaServer::addFboSource(ofx::piMapper::FboSource &fboSource) {
ofLogNotice("MediaServer") << "Attempting to add FBO source with name " << fboSource.getName();
// FBO source has to be with unique name
for (int i = 0; i < fboSources.size(); i++) {
if (fboSources[i]->getName() == fboSource.getName()) {
ofLogWarning("MediaServer") << "Attempt to add FBO source with duplicate name";
ofExit(EXIT_FAILURE); // Here we definitely need to fail to avoid confusion
}
}
ofLogNotice("MediaServer") << "Source new, adding";
fboSources.push_back(&fboSource);
} // addFboSource
BaseSource* MediaServer::loadFboSource(std::string &fboSourceName) {
ofLogNotice("MediaServer") << "Attempting to load FBO source with name " << fboSourceName;
// Search for FBO source name in our storage
FboSource* source = NULL;
for (int i = 0; i < fboSources.size(); i++) {
if (fboSources[i]->getName() == fboSourceName) {
source = fboSources[i];
break;
}
}
// Panic if not in storage
if (source == NULL) {
ofLogError("MediaServer") << "Attempt to load non existing FBO source: " << fboSourceName;
ofExit(EXIT_FAILURE);
}
// Check if it is loaded/activated
if (loadedSources.count(fboSourceName)) {
// Is loaded, increase reference count and return existing
loadedSources[fboSourceName]->referenceCount++;
ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount;
return loadedSources[fboSourceName];
}
// else
// Not loaded, add to loaded sources and activate
// source var should be set by now
source->addAppListeners();
source->referenceCount = 1;
ofLogNotice("MediaServer") << "Current " << fboSourceName << " reference count: " << source->referenceCount;
loadedSources[fboSourceName] = source;
return loadedSources[fboSourceName];
} // loadFboSource
void MediaServer::unloadFboSource(std::string &fboSourceName) {
ofLogNotice("MediaServer") << "Attempt to unload FBO source " << fboSourceName;
// Check if loaded at all
if (!loadedSources.count(fboSourceName)) {
ofLogWarning("MediaServer") << "FBO source not loaded";
return;
}
// TODO: remove static cast, make the sources handle reference counting,
// enabling and disabling by themselves
FboSource* source = static_cast<FboSource*>(loadedSources[fboSourceName]);
// else decrease reference count
source->referenceCount--;
ofLogNotice("MediaServer") << "Current " << fboSourceName << "reference count: " << loadedSources[fboSourceName]->referenceCount;
// If no references left, disable
if (source->referenceCount <= 0) {
ofLogNotice("MediaServer") << fboSourceName << " reference count <= 0, removing from loaded sources";
source->referenceCount = 0;
source->removeAppListeners();
std::map<std::string, BaseSource*>::iterator it = loadedSources.find(fboSourceName);
loadedSources.erase(it);
ofLogNotice("MediaServer") << "Source count after FBO source removal: " << loadedSources.size() << endl;
ofNotifyEvent(onFboSourceUnloaded, fboSourceName, this);
}
} // unloadFboSource
void MediaServer::handleImageAdded(string& path) {
ofNotifyEvent(onImageAdded, path, this);
}

37
src/MediaServer/MediaServer.h

@ -6,6 +6,9 @@
//
//
// TODO: move reference counting, enabling and disabling of sources
// to source classes themselves
#pragma once
#include "ofMain.h"
@ -13,6 +16,7 @@
#include "BaseSource.h"
#include "ImageSource.h"
#include "VideoSource.h"
#include "FboSource.h"
#include "SourceType.h"
#define DEFAULT_IMAGES_DIR "sources/images/"
@ -28,10 +32,12 @@ class MediaServer {
int getNumVideos();
int getNumImages();
int getNumFboSources(); // new
std::vector<std::string>& getVideoPaths();
std::vector<std::string> getVideoNames();
std::vector<std::string>& getImagePaths();
std::vector<std::string> getImageNames();
std::vector<std::string> getFboSourceNames(); // new
BaseSource* loadMedia(string& path, int mediaType);
BaseSource* loadImage(string& path);
@ -45,15 +51,25 @@ class MediaServer {
std::string getDefaultVideoDir();
std::string getDefaultMediaDir(int sourceType);
// Custom events
ofEvent<string> onImageAdded;
ofEvent<string> onImageRemoved;
ofEvent<string> onVideoAdded;
ofEvent<string> onVideoRemoved;
ofEvent<string> onImageLoaded;
ofEvent<string> onImageUnloaded;
ofEvent<string> onVideoLoaded;
ofEvent<string> onVideoUnloaded;
// Do things with FBO sources
void addFboSource(FboSource& fboSource); // could be called also as register FBO source
BaseSource* loadFboSource(std::string& fboSourceName);
void unloadFboSource(std::string& fboSourceName);
// Custom events, add/remove
ofEvent<std::string> onImageAdded;
ofEvent<std::string> onImageRemoved;
ofEvent<std::string> onVideoAdded;
ofEvent<std::string> onVideoRemoved;
ofEvent<std::string> onFboSourceAdded;
ofEvent<std::string> onFboSourceRemoved;
// load/unload
ofEvent<std::string> onImageLoaded;
ofEvent<std::string> onImageUnloaded;
ofEvent<std::string> onVideoLoaded;
ofEvent<std::string> onVideoUnloaded;
ofEvent<std::string> onFboSourceLoaded;
ofEvent<std::string> onFboSourceUnloaded;
private:
// Directory Watchers
@ -86,6 +102,9 @@ class MediaServer {
// Remove event listeners to image and video watcher events
void removeWatcherListeners();
// FBO source storage before they go to loadedSources
std::vector<FboSource*> fboSources; // FBO source storage
};
} // namespace piMapper
} // namespace ofx

3
src/Sources/BaseSource.h

@ -18,6 +18,9 @@ namespace ofx {
int getType();
std::string& getPath();
virtual void clear() {};
// TODO: add virtual increaseReferenceCount and decreaseReferenceCount methods
// and make the variable protected
int referenceCount;
private:

81
src/Sources/FboSource.cpp

@ -0,0 +1,81 @@
#include "FboSource.h"
namespace ofx {
namespace piMapper {
FboSource::FboSource() : fbo(NULL) {
name = PIMAPPER_DEF_FBO_SOURCE_NAME;
loadable = false;
loaded = false;
type = SourceType::SOURCE_TYPE_FBO;
ofAddListener(ofEvents().setup, this, &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP);
}
FboSource::~FboSource() {
removeAppListeners();
clear();
}
void FboSource::addAppListeners() {
ofLogNotice("FboSource") << "Adding app listeners";
ofAddListener(ofEvents().update, this, &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP);
ofAddListener(ofEvents().draw, this, &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP);
ofAddListener(ofEvents().exit, this, &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP);
}
void FboSource::removeAppListeners() {
ofLogNotice("FboSource") << "Removing app listeners";
ofRemoveListener(ofEvents().update, this, &FboSource::onAppUpdate, OF_EVENT_ORDER_BEFORE_APP);
ofRemoveListener(ofEvents().draw, this, &FboSource::onAppDraw, OF_EVENT_ORDER_BEFORE_APP);
ofRemoveListener(ofEvents().exit, this, &FboSource::onAppExit, OF_EVENT_ORDER_AFTER_APP);
}
void FboSource::onAppSetup(ofEventArgs &args) {
ofRemoveListener(ofEvents().setup, this, &FboSource::onAppSetup, OF_EVENT_ORDER_BEFORE_APP);
setup();
}
void FboSource::onAppUpdate(ofEventArgs &args) {
if (fbo == NULL || !fbo->isAllocated()) {
ofLogWarning("FboSource") << "FBO not allocated";
return;
}
update();
}
void FboSource::onAppDraw(ofEventArgs &args) {
if (fbo == NULL || !fbo->isAllocated()) {
ofLogWarning("FboSource") << "FBO not allocated";
return;
}
fbo->begin();
draw();
fbo->end();
}
void FboSource::onAppExit(ofEventArgs &args) {
exit();
}
void FboSource::allocate(int width, int height) {
clear();
fbo = new ofFbo();
fbo->allocate(width, height);
// Clear FBO
fbo->begin();
ofClear(0);
fbo->end();
texture = &(fbo->getTextureReference());
}
void FboSource::clear() {
texture = NULL;
if (fbo != NULL) {
delete fbo;
fbo = NULL;
}
}
} // namespace piMapper
} // namespace ofx

49
src/Sources/FboSource.h

@ -0,0 +1,49 @@
/*
Use this as base class for your generative sources:
class YourGenerativeSource : public FboSource {
// Your code here
}
*/
#pragma once
#include "ofMain.h"
#include "BaseSource.h"
#define PIMAPPER_DEF_FBO_SOURCE_NAME "FBO Source"
namespace ofx {
namespace piMapper {
class FboSource : public BaseSource {
public:
FboSource();
~FboSource();
// Add/remove calls to update and draw
// App listeners are added once the source is assigned to at least one surface
// App listeners are removed once the source is not assigned anywhere
void addAppListeners();
void removeAppListeners();
// These are called on app events
void onAppSetup(ofEventArgs& args);
void onAppUpdate(ofEventArgs& args);
void onAppDraw(ofEventArgs& args);
void onAppExit(ofEventArgs& args);
// Override these in your custom FBO source
virtual void setup() {}; // Don't do any drawing here
virtual void update() {}; // Don't do any drawing here
// You don't need to take care of fbo.begin() and fbo.end() here;
virtual void draw() {}; // But this is the only place where you shoud do drawing
virtual void exit() {};
// Use these to set up FBo itself
void allocate(int width, int height);
void clear(); // The only method from BaseSource to be overriden
protected:
ofFbo* fbo;
};
} // namespace piMapper
} // namespace ofx

7
src/Sources/SourceType.h

@ -5,12 +5,13 @@
#define SOURCE_TYPE_NAME_NONE "none"
#define SOURCE_TYPE_NAME_IMAGE "image"
#define SOURCE_TYPE_NAME_VIDEO "video"
#define SOURCE_TYPE_NAME_FBO "fbo"
namespace ofx {
namespace piMapper {
class SourceType {
public:
enum { SOURCE_TYPE_NONE, SOURCE_TYPE_IMAGE, SOURCE_TYPE_VIDEO };
enum { SOURCE_TYPE_NONE, SOURCE_TYPE_IMAGE, SOURCE_TYPE_VIDEO, SOURCE_TYPE_FBO };
static std::string GetSourceTypeName(int sourceTypeEnum) {
if (sourceTypeEnum == SOURCE_TYPE_IMAGE) {
@ -19,6 +20,8 @@ namespace ofx {
return SOURCE_TYPE_NAME_VIDEO;
} else if (sourceTypeEnum == SOURCE_TYPE_NONE) {
return SOURCE_TYPE_NAME_NONE;
} else if (sourceTypeEnum == SOURCE_TYPE_FBO) {
return SOURCE_TYPE_NAME_FBO;
} else {
std::stringstream ss;
ss << "Invalid source type: " << sourceTypeEnum;
@ -34,6 +37,8 @@ namespace ofx {
return SOURCE_TYPE_VIDEO;
} else if (sourceTypeName == SOURCE_TYPE_NAME_NONE) {
return SOURCE_TYPE_NONE;
} else if (sourceTypeName == SOURCE_TYPE_NAME_FBO) {
return SOURCE_TYPE_FBO;
} else {
std::stringstream ss;
ss << "Invalid source type name: " << sourceTypeName;

19
src/Surfaces/SurfaceManager.cpp

@ -225,13 +225,18 @@ void SurfaceManager::loadXmlSettings(string fileName) {
if (sourceName != "" && sourceName != "none" && sourceType != "") {
// Load source depending on type
int typeEnum = SourceType::GetSourceTypeEnum(sourceType);
// Construct full path
string dir = mediaServer->getDefaultMediaDir(typeEnum);
std::stringstream pathss;
pathss << ofToDataPath(dir, true) << sourceName;
string sourcePath = pathss.str();
// Load media by using full path
source = mediaServer->loadMedia(sourcePath, typeEnum);
if (typeEnum == SourceType::SOURCE_TYPE_FBO) {
// Load FBO source using sourceName
source = mediaServer->loadMedia(sourceName, typeEnum);
} else {
// Construct full path
string dir = mediaServer->getDefaultMediaDir(typeEnum);
std::stringstream pathss;
pathss << ofToDataPath(dir, true) << sourceName;
string sourcePath = pathss.str();
// Load media by using full path
source = mediaServer->loadMedia(sourcePath, typeEnum);
}
}
xmlSettings.popTag(); // source
xmlSettings.pushTag("vertices");

148
src/UserInterface/SourcesEditor.cpp

@ -11,6 +11,12 @@ namespace piMapper {
addMediaServerListeners();
}
void SourcesEditor::init() {
mediaServer = NULL; // Pointers to NULL pointer so we can check later
isMediaServerExternal = false;
registerAppEvents();
}
SourcesEditor::SourcesEditor(MediaServer* externalMediaServer) {
init();
// Assign external MediaServer instance pointer
@ -23,6 +29,7 @@ namespace piMapper {
unregisterAppEvents();
delete imageSelector;
delete videoSelector;
delete fboSelector;
removeMediaServerListeners();
clearMediaServer();
}
@ -38,10 +45,12 @@ namespace piMapper {
void SourcesEditor::setup(ofEventArgs& args) {
imageSelector = new RadioList();
videoSelector = new RadioList();
fboSelector = new RadioList();
// Get media count
int numImages = mediaServer->getNumImages();
int numVideos = mediaServer->getNumVideos();
int numFbos = mediaServer->getNumFboSources();
// Depending on media count, decide what to load and initialize
if (numImages) {
@ -55,16 +64,25 @@ namespace piMapper {
videoSelector->setup("Videos", videoNames, mediaServer->getVideoPaths());
ofAddListener(videoSelector->onRadioSelected, this, &SourcesEditor::handleVideoSelected);
}
if (numFbos) {
std::vector<std::string> fboNames = mediaServer->getFboSourceNames();
fboSelector->setup("FBOs", fboNames, fboNames);
ofAddListener(fboSelector->onRadioSelected, this, &SourcesEditor::handleFboSelected);
}
// Align menus
int menuPosX = 20;
int distX = 230;
if (numImages) {
imageSelector->setPosition(20, 20);
if (numVideos) {
videoSelector->setPosition(250, 20);
}
} else {
if (numVideos) {
videoSelector->setPosition(20, 20);
}
imageSelector->setPosition(menuPosX, 20);
menuPosX += distX;
}
if (numVideos) {
videoSelector->setPosition(menuPosX, 20);
menuPosX += distX;
}
if (numFbos) {
fboSelector->setPosition(menuPosX, 20);
}
}
@ -81,6 +99,9 @@ namespace piMapper {
if (videoSelector->size()) {
videoSelector->draw();
}
if (fboSelector->size()) {
fboSelector->draw();
}
}
@ -91,6 +112,9 @@ namespace piMapper {
if (videoSelector->size()) {
videoSelector->disable();
}
if (fboSelector->size()) {
fboSelector->disable();
}
}
void SourcesEditor::enable() {
@ -105,6 +129,9 @@ namespace piMapper {
if (videoSelector->size()) {
videoSelector->enable();
}
if (fboSelector->size()) {
fboSelector->enable();
}
BaseSource* source = surfaceManager->getSelectedSurface()->getSource();
selectSourceRadioButton(source->getPath());
}
@ -137,18 +164,25 @@ namespace piMapper {
if (videoSelector->size()) {
videoSelector->unselectAll();
}
if (fboSelector->size()) {
fboSelector->unselectAll();
}
return;
} else {
// Check image selector first
bool imageRadioSelected = false;
bool videoRadioSelected = false;
bool fboRadioSelected = false;
if (imageSelector->size()) {
imageRadioSelected = imageSelector->selectItemByValue(sourcePath);
}
if (videoSelector->size()) {
videoRadioSelected = videoSelector->selectItemByValue(sourcePath);
}
if (imageRadioSelected || videoRadioSelected) {
if (fboSelector->size()) {
fboRadioSelected = fboSelector->selectItemByValue(sourcePath);
}
if (imageRadioSelected || videoRadioSelected || fboRadioSelected) {
return;
}
// Log warning if we are still here
@ -156,12 +190,6 @@ namespace piMapper {
}
}
void SourcesEditor::init() {
mediaServer = NULL; // Pointers to NULL pointer so we can check later
isMediaServerExternal = false;
registerAppEvents();
}
void SourcesEditor::addMediaServerListeners() {
// Check if the media server is valid
if (mediaServer == NULL) {
@ -176,6 +204,11 @@ namespace piMapper {
ofAddListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded);
ofAddListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded);
ofAddListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded);
ofAddListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved);
ofAddListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded);
ofAddListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded);
}
void SourcesEditor::removeMediaServerListeners() {
@ -191,42 +224,81 @@ namespace piMapper {
ofRemoveListener(mediaServer->onVideoRemoved, this, &SourcesEditor::handleVideoRemoved);
ofRemoveListener(mediaServer->onImageLoaded, this, &SourcesEditor::handleImageLoaded);
ofRemoveListener(mediaServer->onImageUnloaded, this, &SourcesEditor::handleImageUnloaded);
ofRemoveListener(mediaServer->onFboSourceAdded, this, &SourcesEditor::handleFboSourceAdded);
ofRemoveListener(mediaServer->onFboSourceRemoved, this, &SourcesEditor::handleFboSourceRemoved);
ofRemoveListener(mediaServer->onFboSourceLoaded, this, &SourcesEditor::handleFboSourceLoaded);
ofRemoveListener(mediaServer->onFboSourceUnloaded, this, &SourcesEditor::handleFboSourceUnloaded);
}
void SourcesEditor::handleImageSelected(string& imagePath) {
// Unselect video item if any selected
// Unselect selected items
videoSelector->unselectAll();
fboSelector->unselectAll();
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
ofLogNotice("SourcesEditor") << "No surface selected";
ofLogWarning("SourcesEditor") << "No surface selected";
return;
}
// Unload old media
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
} else {
mediaServer->unloadMedia(source->getName());
}
// Load new image
surface->setSource(mediaServer->loadImage(imagePath));
}
void SourcesEditor::handleVideoSelected(string& videoPath) {
// Unselect image item if any selected
// Unselect any selected items
fboSelector->unselectAll();
imageSelector->unselectAll();
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
ofLogNotice("SourcesEditor") << "No surface selected";
ofLogWarning("SourcesEditor") << "No surface selected";
return;
}
// Unload old media
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
} else {
mediaServer->unloadMedia(source->getName());
}
// Load new video
surface->setSource(mediaServer->loadVideo(videoPath));
}
void SourcesEditor::handleFboSelected(string &fboName) {
videoSelector->unselectAll();
imageSelector->unselectAll();
// Get selected surface
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
ofLogWarning("SourcesEditor") << "No surface selected";
return;
}
// Unload old media
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
} else {
mediaServer->unloadMedia(source->getName());
}
// Load new FBO
surface->setSource(mediaServer->loadFboSource(fboName));
}
void SourcesEditor::clearMediaServer() {
// If mediaServer is local, clear it
if (!isMediaServerExternal) {
@ -238,34 +310,16 @@ namespace piMapper {
}
}
void SourcesEditor::handleImageAdded(string& path) {
cout << "image added: " << path << endl;
}
void SourcesEditor::handleImageRemoved(string& path) {
cout << "image removed: " << path << endl;
}
void SourcesEditor::handleVideoAdded(string& path) {
cout << "video added: " << path << endl;
}
void SourcesEditor::handleVideoRemoved(string& path) {
cout << "video removed: " << path << endl;
}
void SourcesEditor::handleImageLoaded(string& path) {
cout << "Image loaded: " << path << endl;
// Test image unload
// mediaServer->unloadImage(path);
//BaseSource* source = mediaServer->getSourceByPath(path);
//surfaceManager->getSelectedSurface()->setSource(source);
}
void SourcesEditor::handleImageAdded(std::string& path) {}
void SourcesEditor::handleImageRemoved(std::string& path) {}
void SourcesEditor::handleVideoAdded(std::string& path) {}
void SourcesEditor::handleVideoRemoved(std::string& path) {}
void SourcesEditor::handleImageLoaded(std::string& path) {}
void SourcesEditor::handleImageUnloaded(std::string& path) {}
void SourcesEditor::handleFboSourceAdded(std::string& name) {}
void SourcesEditor::handleFboSourceRemoved(std::string& name) {}
void SourcesEditor::handleFboSourceLoaded(std::string& name) {}
void SourcesEditor::handleFboSourceUnloaded(std::string& name) {}
void SourcesEditor::handleImageUnloaded(string& path) {
cout << "Image unloaded: " << path << endl;
}
}
}

19
src/UserInterface/SourcesEditor.h

@ -41,6 +41,7 @@ class SourcesEditor {
SurfaceManager* surfaceManager;
RadioList* imageSelector;
RadioList* videoSelector;
RadioList* fboSelector;
// Is the media server pointer local or from somewhere else?
// We use this to determine if we are allowed to clear media server locally.
@ -56,18 +57,24 @@ class SourcesEditor {
// Handles GUI event, whenever someone has clicked on a radio button
void handleImageSelected(string& imagePath);
void handleVideoSelected(string& videoPath);
void handleFboSelected(string& fboName);
// Careful clearing of the media server,
// clears only if the media server has been initialized locally
void clearMediaServer();
// MediaServer event handlers
void handleImageAdded(string& path);
void handleImageRemoved(string& path);
void handleVideoAdded(string& path);
void handleVideoRemoved(string& path);
void handleImageLoaded(string& path);
void handleImageUnloaded(string& path);
void handleImageAdded(std::string& path);
void handleImageRemoved(std::string& path);
void handleVideoAdded(std::string& path);
void handleVideoRemoved(std::string& path);
void handleImageLoaded(std::string& path);
void handleImageUnloaded(std::string& path);
void handleFboSourceAdded(std::string& name);
void handleFboSourceRemoved(std::string& name);
void handleFboSourceLoaded(std::string& name);
void handleFboSourceUnloaded(std::string& name);
};
}
}

8
src/ofxPiMapper.cpp

@ -3,16 +3,14 @@
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) {
void ofxPiMapper::setup() {
ofLogNotice("ofxPiMapper") << "Setting up...";
// Assign media server to other pi mapper components
@ -105,6 +103,10 @@ void ofxPiMapper::keyPressed(ofKeyEventArgs &args) {
}
} // keyPressed
void ofxPiMapper::addFboSource(ofx::piMapper::FboSource &fboSource) {
mediaServer.addFboSource(fboSource);
} // addFboSource
void ofxPiMapper::addTriangleSurface() {
int surfaceType = ofx::piMapper::SurfaceType::TRIANGLE_SURFACE;

8
src/ofxPiMapper.h

@ -4,6 +4,7 @@
#include "SurfaceManager.h"
#include "SurfaceManagerGui.h"
#include "MediaServer.h"
#include "FboSource.h"
#define PIMAPPER_DEF_SURFACES_XML_FILE "defaultSurfaces.xml"
#define PIMAPPER_USER_SURFACES_XML_FILE "surfaces.xml"
@ -13,11 +14,14 @@ public:
ofxPiMapper();
~ofxPiMapper();
void setup(ofEventArgs& args);
void setup();
void draw(); // Called manually to make custom layering possible
void keyPressed(ofKeyEventArgs& args);
// TODO: Move these methods to SurfaceManager
// Use this to add custom FBO source
void addFboSource(ofx::piMapper::FboSource& fboSource);
// TODO: Copy/move these methods to SurfaceManager
void addTriangleSurface();
void addQuadSurface();

Loading…
Cancel
Save