Browse Source

Massive restructure:

- Added source types
 - Adjusted surfaces to work with the types instead of plain textures
 - Improved media server to manage all of the source types
 - Added video source that works on Mac for now
 - A lot of small adjustments
master
Krisjanis Rijnieks 11 years ago
parent
commit
19c33ddd5f
  1. BIN
      example/bin/data/sources/videos/test.mov
  2. 0
      example/bin/data/sources/videos/test.mp4
  3. 15
      example/src/ofApp.cpp
  4. 5
      example/src/ofApp.h
  5. 4
      src/MediaServer/DirectoryWatcher.cpp
  6. 2
      src/MediaServer/DirectoryWatcher.h
  7. 235
      src/MediaServer/MediaServer.cpp
  8. 26
      src/MediaServer/MediaServer.h
  9. 9
      src/MediaServer/MediaType.h
  10. 57
      src/Sources/BaseSource.cpp
  11. 35
      src/Sources/BaseSource.h
  12. 41
      src/Sources/ImageSource.cpp
  13. 18
      src/Sources/ImageSource.h
  14. 46
      src/Sources/SourceType.h
  15. 66
      src/Sources/VideoSource.cpp
  16. 32
      src/Sources/VideoSource.h
  17. 32
      src/SourcesEditor.cpp
  18. 198
      src/SurfaceManager.cpp
  19. 17
      src/SurfaceManager.h
  20. 11
      src/SurfaceManagerGui.cpp
  21. 2
      src/SurfaceManagerGui.h
  22. 42
      src/Surfaces/BaseSurface.cpp
  23. 21
      src/Surfaces/BaseSurface.h
  24. 17
      src/Surfaces/QuadSurface.cpp
  25. 2
      src/Surfaces/QuadSurface.h
  26. 17
      src/Surfaces/TriangleSurface.cpp
  27. 2
      src/Surfaces/TriangleSurface.h
  28. 12
      src/TextureEditor.cpp

BIN
example/bin/data/sources/videos/test.mov

Binary file not shown.

0
example/bin/data/sources/videos/test.mp4

15
example/src/ofApp.cpp

@ -2,6 +2,12 @@
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
@ -17,7 +23,8 @@ void ofApp::setup() {
// Create FBO
fbo = new ofFbo();
fbo->allocate(500, 500);
setFboAsTexture();
fboSource = new ofx::piMapper::BaseSource(&fbo->getTextureReference());
setFboAsSource();
// Genereate rects
int numRects = 20; // change this to add more or less rects
@ -114,7 +121,7 @@ void ofApp::keyPressed(int key) {
surfaceManager.saveXmlSettings("surfaces.xml");
break;
case 'a':
setFboAsTexture();
setFboAsSource();
break;
case OF_KEY_BACKSPACE:
surfaceManager.removeSelectedSurface();
@ -178,6 +185,6 @@ void ofApp::addSurface() {
surfaceManager.selectSurface(surfaceManager.size() - 1);
}
void ofApp::setFboAsTexture() {
surfaceManager.getSurface(0)->setTexture(&fbo->getTextureReference());
void ofApp::setFboAsSource() {
surfaceManager.getSurface(0)->setSource(fboSource);
}

5
example/src/ofApp.h

@ -2,6 +2,7 @@
#include "ofMain.h"
#include "ofxPiMapper.h"
#include "BaseSource.h"
class ofApp : public ofBaseApp {
public:
@ -15,13 +16,15 @@ class ofApp : public ofBaseApp {
void addRandomSurface();
void addQuadSurface();
void addSurface();
void setFboAsTexture();
void setFboAsSource();
ofImage image;
ofx::piMapper::MediaServer mediaServer;
ofx::piMapper::SurfaceManager surfaceManager;
ofx::piMapper::SurfaceManagerGui gui;
bool bShowInfo;
ofFbo* fbo;
ofx::piMapper::BaseSource* fboSource;
vector<ofRectangle> rects;
vector<float> rectSpeeds;
};

4
src/MediaServer/DirectoryWatcher.cpp

@ -13,9 +13,9 @@ namespace ofx {
DirectoryWatcher::DirectoryWatcher(std::string path, int watcherMediaType) {
mediaType = watcherMediaType;
// Decide what filter we need depending on media type
if (mediaType == MediaType::MEDIA_TYPE_VIDEO) {
if (mediaType == SourceType::SOURCE_TYPE_VIDEO) {
filter = new VideoPathFilter();
} else if (mediaType == MediaType::MEDIA_TYPE_IMAGE) {
} else if (mediaType == SourceType::SOURCE_TYPE_IMAGE) {
filter = new ImagePathFilter();
} else {
ofLogFatalError("DirectoryWatcher::DirectoryWatcher", "Unkonwn media type");

2
src/MediaServer/DirectoryWatcher.h

@ -10,7 +10,7 @@
#include "ofMain.h"
#include "ofxIO.h"
#include "MediaType.h"
#include "SourceType.h"
namespace ofx {
namespace piMapper {

235
src/MediaServer/MediaServer.cpp

@ -12,12 +12,13 @@ namespace ofx {
namespace piMapper {
MediaServer::MediaServer():
videoWatcher(ofToDataPath(DEFAULT_VIDEOS_DIR, true), MediaType::MEDIA_TYPE_VIDEO),
imageWatcher(ofToDataPath(DEFAULT_IMAGES_DIR, true), MediaType::MEDIA_TYPE_IMAGE) {
videoWatcher(ofToDataPath(DEFAULT_VIDEOS_DIR, true), SourceType::SOURCE_TYPE_VIDEO),
imageWatcher(ofToDataPath(DEFAULT_IMAGES_DIR, true), SourceType::SOURCE_TYPE_IMAGE) {
addWatcherListeners();
}
MediaServer::~MediaServer() {
cout << "Media server is over" << endl;
removeWatcherListeners();
};
@ -43,67 +44,215 @@ namespace piMapper {
return imageNames;
}
void MediaServer::loadImage(string& path) {
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 {
std::stringstream ss;
ss << "Can not load media of unknown type: " << mediaType;
ofLogFatalError("MediaServer") << ss.str();
std::exit(EXIT_FAILURE);
}
return NULL;
}
BaseSource* MediaServer::loadImage(string& path) {
ImageSource* imageSource = NULL;
// Check if this image is already loaded
bool isImageLoaded = false;
for (int i = 0; i < loadedImagePaths.size(); i++) {
if (path == loadedImagePaths[i]) {
isImageLoaded = true;
break;
}
if (loadedSources.count(path)) {
imageSource = static_cast<ImageSource*>(loadedSources[path]);
isImageLoaded = true;
}
// If image is loaded
if (isImageLoaded) {
// Increase reference count of this source
//referenceCount[path]++;
imageSource->referenceCount++;
std::stringstream refss;
refss << "Current reference count for " << path << " = " << imageSource->referenceCount;
ofLogNotice("MediaServer") << refss.str();
// Notify objects registered to onImageLoaded event
std::stringstream ss;
ss << "Image " << path << " already loaded";
ofLogNotice("MediaServer") << ss.str();
ofNotifyEvent(onImageLoaded, path, this);
} else {
// Load image and add to vector if loading success
ofImage image;
if (image.loadImage(path)) {
loadedImages.push_back(image);
loadedImagePaths.push_back(path); // Save also path
// Notify objects registered to onImageLoaded event
ofNotifyEvent(onImageLoaded, path, this);
return imageSource;
}
// Else load fresh
imageSource = new ImageSource();
imageSource->loadImage(path);
loadedSources[path] = imageSource;
// Set reference count of this image path to 1
//referenceCount[path] = 1;
std::stringstream refss;
refss << "Initialized reference count of " << path << " to " << imageSource->referenceCount;
ofLogNotice("MediaServer") << refss.str();
// Notify objects registered to onImageLoaded event
ofNotifyEvent(onImageLoaded, path, this);
return imageSource;
}
void MediaServer::unloadImage(string& path) {
ImageSource* source = static_cast<ImageSource*>(getSourceByPath(path));
// Decrease reference count of the image
//referenceCount[path]--;
source->referenceCount--;
// Unload only if reference count is less or equal to 0
cout << "referenceCount: " << source->referenceCount << endl;
if (source->referenceCount > 0) {
ofLogNotice("MediaServer") << "Not unloading image as it is being referenced elsewhere";
return;
}
// Reference count 0 or less, unload image
std::stringstream ss;
ss << "Removing image " << path;
ofLogNotice("MediaServer") << ss.str();
// Destroy image source
if (loadedSources.count(path)) {
//loadedSources[path]->clear();
delete loadedSources[path];
loadedSources.erase(path);
ofNotifyEvent(onImageUnloaded, path, this);
return;
}
// Something wrong here, we should be out of the routine by now
std::stringstream failss;
failss << "Failed to remove image source: " << path;
ofLogFatalError("MediaServer") << failss.str();
std::exit(EXIT_FAILURE);
}
BaseSource* MediaServer::loadVideo(string& path) {
cout << "loading video: " << path << endl;
VideoSource* videoSource = NULL;
// Check if this video is already loaded
bool isVideoLoaded = false;
if (loadedSources.count(path)) {
videoSource = static_cast<VideoSource*>(loadedSources[path]);
isVideoLoaded = true;
}
// If is loaded
if (isVideoLoaded) {
// Increase reference count of this source
//referenceCount[path]++;
videoSource->referenceCount++;
std::stringstream refss;
refss << "Current reference count for " << path << " = " << videoSource->referenceCount;
ofLogNotice("MediaServer") << refss.str();
// Notify objects registered to onImageLoaded event
std::stringstream ss;
ss << "Video " << path << " already loaded";
ofLogNotice("MediaServer") << ss.str();
ofNotifyEvent(onVideoLoaded, path, this);
return videoSource;
}
// Else load fresh
videoSource = new VideoSource();
videoSource->loadVideo(path);
loadedSources[path] = videoSource;
// Set reference count of this image path to 1
//referenceCount[path] = 1;
std::stringstream refss;
refss << "Initialized reference count of " << path << " to " << videoSource->referenceCount;
ofLogNotice("MediaServer") << refss.str();
ofNotifyEvent(onVideoLoaded, path, this);
return videoSource;
}
void MediaServer::unloadVideo(string& path) {
VideoSource* videoSource = static_cast<VideoSource*>(getSourceByPath(path));
// Decrease reference count of the video
//referenceCount[path]--;
videoSource->referenceCount--;
// Unload only if reference count is less or equal to 0
if (videoSource->referenceCount > 0) {
ofLogNotice("MediaServer") << "Not unloading video as it is being referenced elsewhere";
return;
}
// Reference count 0 or less, let's unload the video
std::stringstream ss;
ss << "Removing video " << path;
ofLogNotice("MediaServer") << ss.str();
// Distroy video source
if (loadedSources.count(path)) {
loadedSources[path]->clear();
delete loadedSources[path];
loadedSources.erase(path);
ofNotifyEvent(onVideoUnloaded, path, this);
return;
}
// Something wrong here, we should be out of the routine by now
std::stringstream failss;
failss << "Failed to remove video source: " << path;
ofLogFatalError("MediaServer") << failss.str();
std::exit(EXIT_FAILURE);
}
void MediaServer::unloadMedia(string &path) {
if (loadedSources.count(path)) {
BaseSource* mediaSource = getSourceByPath(path);
if (mediaSource->getType() == SourceType::SOURCE_TYPE_IMAGE) {
unloadImage(path);
} else if (mediaSource->getType() == SourceType::SOURCE_TYPE_VIDEO) {
unloadVideo(path);
} else {
ofLogFatalError("MediaServer") << "Failed to load image";
// 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);
}
}
void MediaServer::unloadImage(string& path) {
// Search for given path in loaded image paths
for (int i = 0; i < loadedImagePaths.size(); i++) {
// If found
if (loadedImagePaths[i] == path) {
// Remove path and unload image as well as remove it from storage
loadedImagePaths.erase(loadedImagePaths.begin() + i);
loadedImages[i].clear();
loadedImages.erase(loadedImages.begin() + i);
ofNotifyEvent(onImageUnloaded, path, this);
break;
}
// Clear all loaded media
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;
}
loadedSources.clear();
}
ofTexture* MediaServer::getImageTexture(string &path) {
// Find image index by path
for (int i = 0; i < loadedImagePaths.size(); i++) {
if (path == loadedImagePaths[i]) {
if (loadedImages[i].isAllocated()) {
return &loadedImages[i].getTextureReference();
}
}
BaseSource* MediaServer::getSourceByPath(std::string& mediaPath) {
cout << "num loaded sources: " << loadedSources.size() << endl;
if (loadedSources.count(mediaPath)) {
return loadedSources[mediaPath];
}
// Source not found, exit with error
std::stringstream ss;
ss << "Could not find source by path: " << mediaPath;
ofLogFatalError("MediaServer") << ss.str();
std::exit(EXIT_FAILURE);
}
std::string MediaServer::getDefaultImageDir() {
return DEFAULT_IMAGES_DIR;
}
std::string MediaServer::getDefaultVideoDir() {
return DEFAULT_VIDEOS_DIR;
}
std::string MediaServer::getDefaultMediaDir(int sourceType) {
if (sourceType == SourceType::SOURCE_TYPE_IMAGE) {
return getDefaultImageDir();
} else if (sourceType == SourceType::SOURCE_TYPE_VIDEO) {
return getDefaultVideoDir();
} else {
std::stringstream ss;
ss << "Could not get default media dir. Unknown source type: " << sourceType;
ofLogFatalError("MediaServer") << ss.str();
std::exit(EXIT_FAILURE);
}
// If we havent returned yet, that means that there is no image
// and we need to sort this out somehow
ofLogError("MediaServer::getImageTexture", "Image not found");
return NULL;
}
void MediaServer::handleImageAdded(string& path) {

26
src/MediaServer/MediaServer.h

@ -10,7 +10,10 @@
#include "ofMain.h"
#include "DirectoryWatcher.h"
#include "MediaType.h"
#include "BaseSource.h"
#include "ImageSource.h"
#include "VideoSource.h"
#include "SourceType.h"
#define DEFAULT_IMAGES_DIR "sources/images/"
#define DEFAULT_VIDEOS_DIR "sources/videos/"
@ -29,10 +32,17 @@ class MediaServer {
std::vector<string>& getImagePaths();
std::vector<string> getImageNames();
// Image loading and handling
void loadImage(string& path);
BaseSource* loadMedia(string& path, int mediaType);
BaseSource* loadImage(string& path);
void unloadImage(string& path);
ofTexture* getImageTexture(string& path);
BaseSource* loadVideo(string& path);
void unloadVideo(string& path);
void unloadMedia(string& path);
void clear(); // Force all loaded source unload
BaseSource* getSourceByPath(std::string& mediaPath);
std::string getDefaultImageDir();
std::string getDefaultVideoDir();
std::string getDefaultMediaDir(int sourceType);
// Custom events
ofEvent<string> onImageAdded;
@ -41,16 +51,14 @@ class MediaServer {
ofEvent<string> onVideoRemoved;
ofEvent<string> onImageLoaded;
ofEvent<string> onImageUnloaded;
ofEvent<string> onVideoLoaded;
ofEvent<string> onVideoUnloaded;
private:
// Directory Watchers
ofx::piMapper::DirectoryWatcher videoWatcher;
ofx::piMapper::DirectoryWatcher imageWatcher;
// Loaded media
vector<ofImage> loadedImages;
vector<string> loadedImagePaths;
std::map<std::string, BaseSource*> loadedSources;
// imageWatcher event listeners
void handleImageAdded(string& path);
void handleImageRemoved(string& path);

9
src/MediaServer/MediaType.h

@ -1,9 +0,0 @@
#pragma once
namespace ofx {
namespace piMapper {
struct MediaType {
enum { MEDIA_TYPE_IMAGE, MEDIA_TYPE_VIDEO };
};
}
}

57
src/Sources/BaseSource.cpp

@ -0,0 +1,57 @@
#include "BaseSource.h"
namespace ofx {
namespace piMapper {
BaseSource::BaseSource() {
//cout << "BaseSource" << endl;
init();
}
BaseSource::BaseSource(ofTexture* newTexture) {
init();
texture = newTexture;
}
ofTexture* BaseSource::getTexture() {
return texture;
}
std::string& BaseSource::getName() {
return name;
}
bool BaseSource::isLoadable() {
return loadable;
}
bool BaseSource::isLoaded() {
return loaded;
}
int BaseSource::getType() {
return type;
}
std::string& BaseSource::getPath() {
return path;
}
void BaseSource::init() {
texture = NULL;
name = "";
path = "";
loadable = false;
loaded = false;
type = SourceType::SOURCE_TYPE_NONE;
referenceCount = 1; // We have one instance on init
}
void BaseSource::setNameFromPath(std::string& fullPath) {
std::vector<string> pathParts;
//cout << "fullPath: " << fullPath << endl;
pathParts = ofSplitString(fullPath, "/"); // Maybe on win "/" is "\", have to test
//cout << "lastPathPart: " << pathParts[pathParts.size() - 1] << endl;
name = pathParts[pathParts.size() - 1];
}
}
}

35
src/Sources/BaseSource.h

@ -0,0 +1,35 @@
#pragma once
#include "ofMain.h"
#include "SourceType.h"
namespace ofx {
namespace piMapper {
// Use this for adding generative sources to your surfaces
class BaseSource {
public:
BaseSource();
BaseSource(ofTexture* newTexture); // Only one clean way of passing the texture
ofTexture* getTexture();
std::string& getName();
bool isLoadable(); // Maybe the loading features shoud go to a derrived class
bool isLoaded(); // as BaseSourceLoadable
int getType();
std::string& getPath();
virtual void clear() {};
int referenceCount;
private:
void init();
protected:
void setNameFromPath(std::string& fullPath);
ofTexture* texture;
std::string name;
std::string path; // This is set only if loadable is true
bool loadable; // If the source can be loaded from disk like image and video
bool loaded; // Is the source loaded?
int type;
};
}
}

41
src/Sources/ImageSource.cpp

@ -0,0 +1,41 @@
#include "ImageSource.h"
namespace ofx {
namespace piMapper {
ImageSource::ImageSource() {
//cout << "ImageSource" << endl;
loadable = true;
loaded = false;
type = SourceType::SOURCE_TYPE_IMAGE;
}
ImageSource::~ImageSource() {
clear();
}
void ImageSource::loadImage(std::string& filePath) {
path = filePath;
cout << "loading image: " << filePath << endl;
setNameFromPath(filePath);
cout << "path: " << path << endl;
image = new ofImage();
if (!image->loadImage(filePath)) {
ofLogFatalError("ImageSource") << "Could not load image";
std::exit(EXIT_FAILURE);
}
texture = &image->getTextureReference();
loaded = true;
}
void ImageSource::clear() {
texture = NULL;
image->clear();
delete image;
image = NULL;
path = "";
name = "";
loaded = false;
}
}
}

18
src/Sources/ImageSource.h

@ -0,0 +1,18 @@
#pragma once
#include "BaseSource.h"
namespace ofx {
namespace piMapper {
class ImageSource : public BaseSource {
public:
ImageSource();
~ImageSource();
std::string& getPath();
void loadImage(std::string& filePath);
void clear();
private:
ofImage* image;
};
}
}

46
src/Sources/SourceType.h

@ -0,0 +1,46 @@
#pragma once
#import "ofLog.h"
#define SOURCE_TYPE_NAME_NONE "none"
#define SOURCE_TYPE_NAME_IMAGE "image"
#define SOURCE_TYPE_NAME_VIDEO "video"
namespace ofx {
namespace piMapper {
class SourceType {
public:
enum { SOURCE_TYPE_NONE, SOURCE_TYPE_IMAGE, SOURCE_TYPE_VIDEO };
static std::string GetSourceTypeName(int sourceTypeEnum) {
if (sourceTypeEnum == SOURCE_TYPE_IMAGE) {
return SOURCE_TYPE_NAME_IMAGE;
} else if (sourceTypeEnum == SOURCE_TYPE_VIDEO) {
return SOURCE_TYPE_NAME_VIDEO;
} else if (sourceTypeEnum == SOURCE_TYPE_NONE) {
return SOURCE_TYPE_NAME_NONE;
} else {
std::stringstream ss;
ss << "Invalid source type: " << sourceTypeEnum;
ofLogFatalError("SourceType") << ss.str();
std::exit(EXIT_FAILURE);
}
};
static int GetSourceTypeEnum(std::string sourceTypeName) {
if (sourceTypeName == SOURCE_TYPE_NAME_IMAGE) {
return SOURCE_TYPE_IMAGE;
} else if (sourceTypeName == SOURCE_TYPE_NAME_VIDEO) {
return SOURCE_TYPE_VIDEO;
} else if (sourceTypeName == SOURCE_TYPE_NAME_NONE) {
return SOURCE_TYPE_NONE;
} else {
std::stringstream ss;
ss << "Invalid source type name: " << sourceTypeName;
ofLogFatalError("SourceType") << ss.str();
std::exit(EXIT_FAILURE);
}
}
};
}
}

66
src/Sources/VideoSource.cpp

@ -0,0 +1,66 @@
#include "VideoSource.h"
namespace ofx {
namespace piMapper {
VideoSource::VideoSource() {
loadable = true;
loaded = false;
type = SourceType::SOURCE_TYPE_VIDEO;
}
VideoSource::~VideoSource() {
clear();
}
void VideoSource::loadVideo(std::string& filePath) {
path = filePath;
//cout << "loading video: " << filePath << endl;
setNameFromPath(filePath);
#ifdef TARGET_RASPBERRY_PI
// TODO: do omx player
//
//
//
#else
// regular ofVideoPlayer
videoPlayer = new ofVideoPlayer();
videoPlayer->loadMovie(filePath);
videoPlayer->setLoopState(OF_LOOP_NORMAL);
videoPlayer->play();
texture = &(videoPlayer->getTextureReference());
ofAddListener(ofEvents().update, this, &VideoSource::update);
#endif
loaded = true;
}
void VideoSource::clear() {
ofRemoveListener(ofEvents().update, this, &VideoSource::update);
texture = NULL;
#ifdef TARGET_RASPBERRY_PI
// TODO: do omx player
//
//
//
#else
videoPlayer->stop();
videoPlayer->close();
delete videoPlayer;
videoPlayer = NULL;
#endif
path = "";
name = "";
loaded = false;
}
void VideoSource::update(ofEventArgs &args) {
#ifdef TARGET_RASPBERRY_PI
// TODO: do omx player
//
// probably needs updating as well
//
#else
videoPlayer->update();
#endif
}
}
}

32
src/Sources/VideoSource.h

@ -0,0 +1,32 @@
#pragma once
#include "ofMain.h"
#include "BaseSource.h"
#ifdef TARGET_RASPBERRY_PI
#include "ofxOMXPlayer.h"
#endif
namespace ofx {
namespace piMapper {
class VideoSource : public BaseSource {
public:
VideoSource();
~VideoSource();
std::string& getPath();
void loadVideo(std::string& path);
void clear();
void update(ofEventArgs& args);
private:
#ifdef TARGET_RASPBERRY_PI
// TODO: implement ofxOMXPlayer
//
//
//
#else
// Go with ofVideoPlayer or
// TODO: High Performance Video player on newer Macs
ofVideoPlayer* videoPlayer;
#endif
};
}
}

32
src/SourcesEditor.cpp

@ -87,9 +87,7 @@ namespace piMapper {
void SourcesEditor::loadImage(string name, string path) {
images.push_back(new ofImage());
images.back()->loadImage(path);
imageNames.push_back(name);
ofSendMessage("imageLoaded");
}
@ -113,13 +111,15 @@ namespace piMapper {
// If the new media server is not valid
if (newMediaServer == NULL) {
// Log an error and return from the routine
ofLogError("SourcesEditor::setMediaServer", "New media server is NULL");
return;
ofLogFatalError("SourcesEditor") << "New media server is NULL";
std::exit(EXIT_FAILURE);
}
// Attempt to clear existing media server and assign new one
clearMediaServer();
cout << "old ms addr: " << mediaServer << endl;
cout << "new ms addr: " << newMediaServer << endl;
mediaServer = newMediaServer;
isMediaServerExternal = true;
}
void SourcesEditor::selectImageSourceRadioButton(string name) {
@ -188,22 +188,22 @@ namespace piMapper {
}
void SourcesEditor::handleRadioSelected(string& sourcePath) {
if (surfaceManager->getSelectedSurface() == NULL) {
BaseSurface* surface = surfaceManager->getSelectedSurface();
if (surface == NULL) {
return;
}
cout << "Attempt to load image: " << sourcePath << endl;
mediaServer->loadImage(sourcePath);
BaseSource* source = surface->getSource();
if (source->isLoadable()) {
mediaServer->unloadMedia(source->getPath());
}
surface->setSource(mediaServer->loadImage(sourcePath));
}
void SourcesEditor::clearMediaServer() {
// If mediaServer is local, clear it
if (isMediaServerExternal) {
if (!isMediaServerExternal) {
// Clear all loaded sources
//mediaServer->clear()
mediaServer->clear();
// Destroy the pointer and set it to NULL pointer
delete mediaServer;
mediaServer = NULL;
@ -232,8 +232,8 @@ namespace piMapper {
// Test image unload
// mediaServer->unloadImage(path);
ofTexture* texture = mediaServer->getImageTexture(path);
surfaceManager->getSelectedSurface()->setTexture(texture);
BaseSource* source = mediaServer->getSourceByPath(path);
surfaceManager->getSelectedSurface()->setSource(source);
}
void SourcesEditor::handleImageUnloaded(string& path) {

198
src/SurfaceManager.cpp

@ -2,7 +2,10 @@
namespace ofx {
namespace piMapper {
SurfaceManager::SurfaceManager() {}
SurfaceManager::SurfaceManager() {
// Init variables
mediaServer = NULL;
}
SurfaceManager::~SurfaceManager() { clear(); }
@ -18,19 +21,21 @@ void SurfaceManager::addSurface(int surfaceType) {
} else if (surfaceType == SurfaceType::QUAD_SURFACE) {
surfaces.push_back(new QuadSurface());
} else {
throw std::runtime_error("Attempt to add non-existing surface type.");
ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type";
std::exit(EXIT_FAILURE);
}
}
void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr) {
void SurfaceManager::addSurface(int surfaceType, BaseSource* newSource) {
if (surfaceType == SurfaceType::TRIANGLE_SURFACE) {
surfaces.push_back(new TriangleSurface());
surfaces.back()->setTexture(texturePtr);
surfaces.back()->setSource(newSource);
} else if (surfaceType == SurfaceType::QUAD_SURFACE) {
surfaces.push_back(new QuadSurface());
surfaces.back()->setTexture(texturePtr);
surfaces.back()->setSource(newSource);
} else {
throw std::runtime_error("Attempt to add non-existing surface type.");
ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type";
std::exit(EXIT_FAILURE);
}
}
@ -67,11 +72,12 @@ void SurfaceManager::addSurface(int surfaceType, vector<ofVec2f> vertices,
surfaces.back()->setTexCoord(i, texCoords[i]);
}
} else {
throw std::runtime_error("Attempt to add non-existing surface type.");
ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type";
std::exit(EXIT_FAILURE);
}
}
void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr,
void SurfaceManager::addSurface(int surfaceType, BaseSource* newSource,
vector<ofVec2f> vertices,
vector<ofVec2f> texCoords) {
if (surfaceType == SurfaceType::TRIANGLE_SURFACE) {
@ -84,7 +90,7 @@ void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr,
}
surfaces.push_back(new TriangleSurface());
surfaces.back()->setTexture(texturePtr);
surfaces.back()->setSource(newSource);
for (int i = 0; i < 3; i++) {
surfaces.back()->setVertex(i, vertices[i]);
@ -100,20 +106,22 @@ void SurfaceManager::addSurface(int surfaceType, ofTexture* texturePtr,
}
surfaces.push_back(new QuadSurface());
surfaces.back()->setTexture(texturePtr);
surfaces.back()->setSource(newSource);
for (int i = 0; i < 4; i++) {
surfaces.back()->setVertex(i, vertices[i]);
surfaces.back()->setTexCoord(i, texCoords[i]);
}
} else {
throw std::runtime_error("Attempt to add non-existing surface type.");
ofLogFatalError("SurfaceManager") << "Attempt to add non-existing surface type";
std::exit(EXIT_FAILURE);
}
}
void SurfaceManager::removeSelectedSurface() {
if (selectedSurface == NULL) return;
if (selectedSurface == NULL) {
return;
}
for (int i = 0; i < surfaces.size(); i++) {
if (surfaces[i] == selectedSurface) {
delete surfaces[i];
@ -124,61 +132,23 @@ void SurfaceManager::removeSelectedSurface() {
}
}
void SurfaceManager::manageMemory() {
// check if each of the sources is assigned to a surface or not
for (int i = 0; i < loadedImageSources.size(); i++) {
bool bAssigned = false;
for (int j = 0; j < surfaces.size(); j++) {
if (surfaces[j]->getTexture() ==
&loadedImageSources[i]->getTextureReference()) {
bAssigned = true;
break;
}
}
if (!bAssigned) {
// purge the image source from memory
delete loadedImageSources[i];
loadedImageSources.erase(loadedImageSources.begin() + i);
cout << "Deleting image source: " << loadedImageSourceNames[i] << endl;
loadedImageSourceNames.erase(loadedImageSourceNames.begin() + i);
i--;
}
}
}
void SurfaceManager::clear() {
// delete all extra allocations from the heap
while (surfaces.size()) {
delete surfaces.back();
surfaces.pop_back();
}
while (loadedImageSources.size()) {
delete loadedImageSources.back();
loadedImageSources.pop_back();
}
while (loadedImageSourceNames.size()) {
loadedImageSourceNames.pop_back();
}
}
// String getTypeString(SurfaceType e)
// {
// switch e
// {
// case TRINAGLE_SURFACE: return "TRINAGLE_SURFACE";
// case QUAD_SURFACE: return "QUAD_SURFACE";
// default: throw Exception("Bad MyEnum");
// }
// }
void SurfaceManager::saveXmlSettings(string fileName) {
// Exit if mediaServer not set
if (mediaServer == NULL) {
ofLogFatalError("SurfaceManager") << "Media server not set";
std::exit(EXIT_FAILURE);
}
// We need a fresh copy of the xml settings object
xmlSettings.clear();
// save surfaces
// Save surfaces
xmlSettings.addTag("surfaces");
xmlSettings.pushTag("surfaces");
for (int i = 0; i < surfaces.size(); i++) {
@ -214,37 +184,31 @@ void SurfaceManager::saveXmlSettings(string fileName) {
xmlSettings.popTag(); // texCoord
}
xmlSettings.popTag(); // texCoords
xmlSettings.addTag("source");
xmlSettings.pushTag("source");
xmlSettings.addValue("source-type", "image");
xmlSettings.addValue("source-name", getSurfaceSourceName(surface));
// xmlSettings.addValue("source-path", "/root/etc/image.jpg");
string sourceTypeName = SourceType::GetSourceTypeName(surface->getSource()->getType());
cout << "sourceTypeName: " << sourceTypeName << endl;
xmlSettings.addValue("source-type", sourceTypeName);
xmlSettings.addValue("source-name", surface->getSource()->getName());
xmlSettings.popTag(); // source
// xmlSettings.addTag("type");
// xmlSettings.pushTag("type");
// // surfaceType == SurfaceType::TRIANGLE_SURFACE
// SurfaceType surfaceType = &surface->getType();
// xmlSettings.addValue("surface-type", surfaceType);
// xmlSettings.popTag(); // type
xmlSettings.popTag(); // surface
}
xmlSettings.popTag(); // surfaces
xmlSettings.save(fileName);
}
void SurfaceManager::loadXmlSettings(string fileName) {
// Exit if there is no media server
if (mediaServer == NULL) {
ofLogFatalError("SurfaceManager") << "Media server not set";
std::exit(EXIT_FAILURE);
}
if (!xmlSettings.loadFile(fileName)) {
ofLog(OF_LOG_WARNING, "Could not load XML settings.");
ofLogWarning("SurfaceManager") << "Could not load XML settings";
return;
}
if (!xmlSettings.tagExists("surfaces")) {
ofLog(OF_LOG_WARNING, "XML settings is empty or has wrong markup.");
ofLogWarning("SurfaceManager") << "XML settings is empty or has wrong markup";
return;
}
@ -255,28 +219,24 @@ void SurfaceManager::loadXmlSettings(string fileName) {
xmlSettings.pushTag("surface", i);
// attempt to load surface source
xmlSettings.pushTag("source");
string sourceType = xmlSettings.getValue("source-type", "image");
string sourceName = xmlSettings.getValue("source-name", "none");
ofTexture* sourceTexture = NULL;
if (sourceName != "none") {
stringstream ss;
ss << "sources/images/" << sourceName; // TODO: reuse constants here
sourceTexture = loadImageSource(sourceName, ss.str());
string sourceType = xmlSettings.getValue("source-type", "");
string sourceName = xmlSettings.getValue("source-name", "");
BaseSource* source = NULL;
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);
}
xmlSettings.popTag(); // source
// // attempt to load surface type
// ofLog(OF_LOG_WARNING, "Attempt to load surface type.");
// xmlSettings.pushTag("type");
// string surfaceType = xmlSettings.getValue("surface-type",
// "TRIANGLE_SURFACE");
// xmlSettings.popTag(); // type
xmlSettings.pushTag("vertices");
vector<ofVec2f> vertices;
int vertexCount = xmlSettings.getNumTags("vertex");
// it's a triangle ?
if (vertexCount == 3) {
//ofLog(OF_LOG_NOTICE, "create Triangle");
@ -320,8 +280,8 @@ void SurfaceManager::loadXmlSettings(string fileName) {
// now we have variables sourceName and sourceTexture
// by checking those we can use one or another addSurface method
if (sourceName != "none" && sourceTexture != NULL) {
addSurface(SurfaceType::TRIANGLE_SURFACE, sourceTexture, vertices,
if (sourceName != "none" && source != NULL) {
addSurface(SurfaceType::TRIANGLE_SURFACE, source, vertices,
texCoords);
} else {
addSurface(SurfaceType::TRIANGLE_SURFACE, vertices, texCoords);
@ -381,8 +341,8 @@ void SurfaceManager::loadXmlSettings(string fileName) {
// now we have variables sourceName and sourceTexture
// by checking those we can use one or another addSurface method
if (sourceName != "none" && sourceTexture != NULL) {
addSurface(SurfaceType::QUAD_SURFACE, sourceTexture, vertices,
if (sourceName != "none" && source != NULL) {
addSurface(SurfaceType::QUAD_SURFACE, source, vertices,
texCoords);
} else {
addSurface(SurfaceType::QUAD_SURFACE, vertices, texCoords);
@ -394,6 +354,10 @@ void SurfaceManager::loadXmlSettings(string fileName) {
xmlSettings.popTag(); // surfaces
}
void SurfaceManager::setMediaServer(MediaServer* newMediaServer) {
mediaServer = newMediaServer;
}
BaseSurface* SurfaceManager::selectSurface(int index) {
if (index >= surfaces.size()) {
@ -406,46 +370,12 @@ BaseSurface* SurfaceManager::selectSurface(int index) {
ofSendMessage("surfaceSelected");
}
BaseSurface* SurfaceManager::getSelectedSurface() { return selectedSurface; }
void SurfaceManager::deselectSurface() { selectedSurface = NULL; }
ofTexture* SurfaceManager::loadImageSource(string name, string path) {
// check if it is loaded
for (int i = 0; i < loadedImageSourceNames.size(); i++) {
if (loadedImageSourceNames[i] == name) {
// this image is already loaded
return &loadedImageSources[i]->getTextureReference();
}
}
// not loaded - load
ofImage* image = new ofImage();
if (!image->loadImage(path)) {
return NULL;
}
loadedImageSources.push_back(image);
loadedImageSourceNames.push_back(name);
return &image->getTextureReference();
BaseSurface* SurfaceManager::getSelectedSurface() {
return selectedSurface;
}
string SurfaceManager::getSelectedSurfaceSourceName() {
if (selectedSurface == NULL) {
return "none";
}
return getSurfaceSourceName(selectedSurface);
}
string SurfaceManager::getSurfaceSourceName(BaseSurface* surface) {
ofTexture* tex = surface->getTexture();
for (int i = 0; i < loadedImageSources.size(); i++) {
if (tex == &loadedImageSources[i]->getTextureReference()) {
return loadedImageSourceNames[i];
}
}
return "none";
void SurfaceManager::deselectSurface() {
selectedSurface = NULL;
}
BaseSurface* SurfaceManager::getSurface(int index) {

17
src/SurfaceManager.h

@ -4,6 +4,9 @@
#include "TriangleSurface.h"
#include "QuadSurface.h"
#include "SurfaceType.h"
#include "MediaServer.h"
#include "BaseSource.h"
#include "SourceType.h"
#include "ofEvents.h"
#include "ofxXmlSettings.h"
@ -19,32 +22,28 @@ class SurfaceManager {
void draw();
void addSurface(int surfaceType);
void addSurface(int surfaceType, ofTexture* texturePtr);
void addSurface(int surfaceType, BaseSource* newSource);
void addSurface(int surfaceType, vector<ofVec2f> vertices,
vector<ofVec2f> texCoords);
void addSurface(int surfaceType, ofTexture* texturePtr,
void addSurface(int surfaceType, BaseSource* newSource,
vector<ofVec2f> vertices, vector<ofVec2f> texCoords);
void removeSelectedSurface();
void manageMemory(); // deletes unasigned sources
void clear();
void saveXmlSettings(string fileName);
void loadXmlSettings(string fileName);
void setMediaServer(MediaServer* newMediaServer);
BaseSurface* getSurface(int index);
int size();
BaseSurface* selectSurface(int index);
BaseSurface* getSelectedSurface();
void deselectSurface();
ofTexture* loadImageSource(string name, string path);
string getSelectedSurfaceSourceName();
string getSurfaceSourceName(BaseSurface* surface);
private:
vector<BaseSurface*> surfaces;
std::vector<BaseSurface*> surfaces;
BaseSurface* selectedSurface;
vector<string> loadedImageSourceNames;
vector<ofImage*> loadedImageSources;
ofxXmlSettings xmlSettings;
MediaServer* mediaServer;
};
}
}

11
src/SurfaceManagerGui.cpp

@ -174,6 +174,13 @@ void SurfaceManagerGui::setSurfaceManager(SurfaceManager* newSurfaceManager) {
sourcesEditor.setSurfaceManager(surfaceManager);
}
// Set external media server so we can access it from wherever we need
void SurfaceManagerGui::setMediaServer(MediaServer* newMediaServer) {
mediaServer = newMediaServer;
// Set the media server of the sources editor here
sourcesEditor.setMediaServer(mediaServer);
}
void SurfaceManagerGui::setMode(int newGuiMode) {
if (newGuiMode != GuiMode::NONE && newGuiMode != GuiMode::TEXTURE_MAPPING &&
newGuiMode != GuiMode::PROJECTION_MAPPING &&
@ -191,8 +198,8 @@ void SurfaceManagerGui::setMode(int newGuiMode) {
if (guiMode == GuiMode::SOURCE_SELECTION) {
sourcesEditor.enable();
string sourceName = surfaceManager->getSelectedSurfaceSourceName();
sourcesEditor.selectImageSourceRadioButton(sourceName);
//string sourceName = surfaceManager->getSelectedSurfaceSourceName();
//sourcesEditor.selectImageSourceRadioButton(sourceName);
} else {
sourcesEditor.disable();
}

2
src/SurfaceManagerGui.h

@ -27,6 +27,7 @@ class SurfaceManagerGui {
void mouseReleased(ofMouseEventArgs& args);
void mouseDragged(ofMouseEventArgs& args);
void setSurfaceManager(SurfaceManager* newSurfaceManager);
void setMediaServer(MediaServer* newMediaServer);
void setMode(int newGuiMode);
void drawSelectedSurfaceHighlight();
void drawSelectedSurfaceTextureHighlight();
@ -35,6 +36,7 @@ class SurfaceManagerGui {
private:
SurfaceManager* surfaceManager;
MediaServer* mediaServer;
TextureEditor textureEditor;
ProjectionEditor projectionEditor;
SourcesEditor sourcesEditor;

42
src/BaseSurface.cpp → src/Surfaces/BaseSurface.cpp

@ -7,6 +7,12 @@ BaseSurface::BaseSurface() {
ofEnableNormalizedTexCoords();
createDefaultTexture();
}
BaseSurface::~BaseSurface() {
delete defaultSource;
defaultSource = NULL;
defaultTexture.clear();
}
void BaseSurface::createDefaultTexture() {
ofPixels pixels;
@ -38,33 +44,47 @@ void BaseSurface::createDefaultTexture() {
// load pixels into texture
defaultTexture.loadData(pixels);
// Assign default texture to texture pointer
texture = &defaultTexture;
// Create new source to be the default
defaultSource = new BaseSource(&defaultTexture);
source = defaultSource;
}
void BaseSurface::drawTexture(ofVec2f position) {
if (source->getTexture() == NULL) {
ofLogWarning("BaseSurface") << "Source texture empty. Not drawing.";
return;
}
ofMesh texMesh;
texMesh.addVertex(position);
texMesh.addVertex(position + ofVec2f(texture->getWidth(), 0.0f));
texMesh.addVertex(position + ofVec2f(source->getTexture()->getWidth(), 0.0f));
texMesh.addVertex(position +
ofVec2f(texture->getWidth(), texture->getHeight()));
texMesh.addVertex(position + ofVec2f(0.0f, texture->getHeight()));
ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight()));
texMesh.addVertex(position + ofVec2f(0.0f, source->getTexture()->getHeight()));
texMesh.addTriangle(0, 2, 3);
texMesh.addTriangle(0, 1, 2);
texMesh.addTexCoord(ofVec2f(0.0f, 0.0f));
texMesh.addTexCoord(ofVec2f(1.0f, 0.0f));
texMesh.addTexCoord(ofVec2f(1.0f, 1.0f));
texMesh.addTexCoord(ofVec2f(0.0f, 1.0f));
texture->bind();
source->getTexture()->bind();
texMesh.draw();
texture->unbind();
source->getTexture()->unbind();
}
void BaseSurface::setTexture(ofTexture* texturePtr) { texture = texturePtr; }
//void BaseSurface::setTexture(ofTexture* texturePtr) { texture = texturePtr; }
void BaseSurface::setSource(BaseSource* newSource) {
source = newSource;
}
ofTexture* BaseSurface::getTexture() { return texture; }
//ofTexture* BaseSurface::getTexture() { return texture; }
BaseSource* BaseSurface::getSource() {
return source;
}
ofTexture* BaseSurface::getDefaultTexture() { return &defaultTexture; }
//ofTexture* BaseSurface::getDefaultTexture() { return &defaultTexture; }
BaseSource* BaseSurface::getDefaultSource() {
return defaultSource;
}
}
}

21
src/BaseSurface.h → src/Surfaces/BaseSurface.h

@ -2,6 +2,7 @@
#include "ofMain.h"
#include <string>
#include "BaseSource.h"
using namespace std;
@ -10,6 +11,7 @@ namespace piMapper {
class BaseSurface {
public:
BaseSurface();
~BaseSurface();
virtual void setup() {};
virtual void draw() {};
virtual void setVertex(int index, ofVec2f p) {};
@ -24,16 +26,21 @@ class BaseSurface {
// Draws a texture using ofMesh
void drawTexture(ofVec2f position);
void setTexture(ofTexture* texturePtr);
ofTexture* getTexture();
ofTexture* getDefaultTexture();
//void setTexture(ofTexture* texturePtr);
void setSource(BaseSource* newSource);
//ofTexture* getTexture();
//ofTexture* getDefaultTexture();
BaseSource* getSource();
BaseSource* getDefaultSource();
protected:
ofMesh mesh;
ofTexture* texture;
//ofTexture* texture;
ofTexture defaultTexture;
BaseSource* source;
BaseSource* defaultSource;
void createDefaultTexture();
};
}

17
src/QuadSurface.cpp → src/Surfaces/QuadSurface.cpp

@ -22,14 +22,14 @@ void QuadSurface::setup() {
ofVec2f t3 = ofVec2f(ofVec2f(1.0f, 1.0f));
ofVec2f t4 = ofVec2f(ofVec2f(0.0f, 1.0f));
setup(p1, p2, p3, p4, t1, t2, t3, t4, texture);
setup(p1, p2, p3, p4, t1, t2, t3, t4, source);
}
void QuadSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4,
ofVec2f t1, ofVec2f t2, ofVec2f t3, ofVec2f t4,
ofTexture* texturePtr) {
BaseSource* newSource) {
// Assign texture
texture = texturePtr;
source = newSource;
// Clear mesh
mesh.clear();
@ -68,6 +68,11 @@ void QuadSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4,
}
void QuadSurface::draw() {
if (source->getTexture() == NULL) {
ofLogWarning("QuadSurface") << "Source texture empty. Not drawing.";
return;
}
/*if(mesh.haveVertsChanged() || mesh.haveTexCoordsChanged()){
calculate4dTextureCoords();
}*/
@ -75,9 +80,9 @@ void QuadSurface::draw() {
glTexCoordPointer(4, GL_FLOAT, 0, quadTexCoordinates);
glVertexPointer(3, GL_FLOAT, 0, quadVertices);
texture->bind();
source->getTexture()->bind();
glDrawElements(GL_TRIANGLES, 6, GL_UNSIGNED_BYTE, quadIndices);
texture->unbind();
source->getTexture()->unbind();
}
void QuadSurface::setVertex(int index, ofVec2f p) {
@ -154,7 +159,7 @@ ofPolyline QuadSurface::getHitArea() {
ofPolyline QuadSurface::getTextureHitArea() {
ofPolyline line;
vector<ofVec2f>& texCoords = mesh.getTexCoords();
ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight());
ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight());
for (int i = 0; i < texCoords.size(); i++) {
line.addVertex(ofPoint(texCoords[i] * textureSize));
}

2
src/QuadSurface.h → src/Surfaces/QuadSurface.h

@ -14,7 +14,7 @@ class QuadSurface : public BaseSurface {
void setup();
void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f p4, ofVec2f t1,
ofVec2f t2, ofVec2f t3, ofVec2f t4, ofTexture* texturePtr);
ofVec2f t2, ofVec2f t3, ofVec2f t4, BaseSource* newSource);
void draw();
void setVertex(int index, ofVec2f p);

17
src/TriangleSurface.cpp → src/Surfaces/TriangleSurface.cpp

@ -19,13 +19,13 @@ void TriangleSurface::setup() {
ofVec2f t2 = ofVec2f(0, 1.0f);
ofVec2f t3 = ofVec2f(1, 1.0f);
setup(p1, p2, p3, t1, t2, t3, texture);
setup(p1, p2, p3, t1, t2, t3, source);
}
void TriangleSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1,
ofVec2f t2, ofVec2f t3, ofTexture* texturePtr) {
ofVec2f t2, ofVec2f t3, BaseSource* newSource) {
// Assign texture
texture = texturePtr;
source = newSource;
// Clear mesh
mesh.clear();
@ -42,9 +42,14 @@ void TriangleSurface::setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1,
}
void TriangleSurface::draw() {
texture->bind();
if (source->getTexture() == NULL) {
ofLogWarning("TriangleSurface") << "Source texture is empty. Not drawing.";
return;
}
source->getTexture()->bind();
mesh.draw();
texture->unbind();
source->getTexture()->unbind();
}
void TriangleSurface::setVertex(int index, ofVec2f p) {
@ -117,7 +122,7 @@ ofPolyline TriangleSurface::getHitArea() {
ofPolyline TriangleSurface::getTextureHitArea() {
ofPolyline line;
vector<ofVec2f>& texCoords = mesh.getTexCoords();
ofVec2f textureSize = ofVec2f(texture->getWidth(), texture->getHeight());
ofVec2f textureSize = ofVec2f(source->getTexture()->getWidth(), source->getTexture()->getHeight());
for (int i = 0; i < texCoords.size(); i++) {
line.addVertex(ofPoint(texCoords[i] * textureSize));
}

2
src/TriangleSurface.h → src/Surfaces/TriangleSurface.h

@ -13,7 +13,7 @@ class TriangleSurface : public BaseSurface {
void setup();
void setup(ofVec2f p1, ofVec2f p2, ofVec2f p3, ofVec2f t1, ofVec2f t2,
ofVec2f t3, ofTexture* texturePtr);
ofVec2f t3, BaseSource* newSource);
void draw();
void setVertex(int index, ofVec2f p);
void setTexCoord(int index, ofVec2f t);

12
src/TextureEditor.cpp

@ -45,8 +45,8 @@ void TextureEditor::update(ofEventArgs& args) {
if (surface == NULL) return;
// update surface if one of the joints is being dragged
ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(),
surface->getTexture()->getHeight());
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
// Get selected joint index
int selectedJointIndex = 0;
@ -138,8 +138,8 @@ void TextureEditor::createJoints() {
if (surface == NULL) return;
clearJoints();
vector<ofVec2f>& texCoords = surface->getTexCoords();
ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(),
surface->getTexture()->getHeight());
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
for (int i = 0; i < texCoords.size(); i++) {
joints.push_back(new CircleJoint());
@ -163,8 +163,8 @@ void TextureEditor::unselectAllJoints() {
void TextureEditor::moveTexCoords(ofVec2f by) {
if (surface == NULL) return;
vector<ofVec2f>& texCoords = surface->getTexCoords();
ofVec2f textureSize = ofVec2f(surface->getTexture()->getWidth(),
surface->getTexture()->getHeight());
ofVec2f textureSize = ofVec2f(surface->getSource()->getTexture()->getWidth(),
surface->getSource()->getTexture()->getHeight());
for (int i = 0; i < texCoords.size(); i++) {
joints[i]->position += by;
texCoords[i] = joints[i]->position / textureSize;

Loading…
Cancel
Save