diff --git a/BUGS b/BUGS index 61ee0c5..cf14dbc 100644 --- a/BUGS +++ b/BUGS @@ -4,3 +4,8 @@ LibreMapping known bugs * cannot delete paints * cannot remove points in meshes +On OS X +------- +QObject: shared QObject was deleted directly. The program is malformed and may crash. +mapmap(299,0x7fff79da0310) malloc: *** error for object 0x102229ce0: pointer being freed was not allocated +*** set a breakpoint in malloc_error_break to debug diff --git a/DestinationGLCanvas.cpp b/DestinationGLCanvas.cpp index e2f7224..988e170 100644 --- a/DestinationGLCanvas.cpp +++ b/DestinationGLCanvas.cpp @@ -36,57 +36,13 @@ Shape* DestinationGLCanvas::getShapeFromMappingId(uid mappingId) void DestinationGLCanvas::doDraw(QPainter* painter) { -// // No sources = nothing to do. -// if (Common::nImages() == 0) -// return; -// -// // TODO: Ceci est un hack necessaire car tout est en fonction de la width/height de la texture. -// // Il faut changer ca. -// std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(Common::currentMapping); -// Q_CHECK_PTR(textureMapping); -// -// std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); -// Q_CHECK_PTR(texture); -// -// for (int i=0; i < Common::nImages(); i++) -// { -// std::tr1::shared_ptr tex = std::tr1::static_pointer_cast(Common::mappings[i]->getPaint()); -// Q_CHECK_PTR(tex); -// -// // FIXME: maybe the texture id is actually 0 and it's ok, no? -// // we should use a boolean is_texture_loaded, or so -// if (tex->getTextureId() == 0) -// { -// tex->loadTexture(); -// } -// } - - - if (getMainWindow() == NULL) - return; - glPushMatrix(); - MappingManager& mappingManager = getMainWindow()->getMappingManager(); - QVector mappings = mappingManager.getVisibleMappings(); + + // Draw the mappings. + QVector mappings = getMainWindow()->getMappingManager().getVisibleMappings(); for (QVector::const_iterator it = mappings.begin(); it != mappings.end(); ++it) { - Mapping::ptr mapping = (*it); - - // XXX: change : UGLY! - if (mapping->getType().endsWith("_texture")) - { - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(mapping); - Q_CHECK_PTR(textureMapping); - - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(textureMapping->getPaint()); - Q_CHECK_PTR(texture); - - if (texture->getTextureId() == 0) - texture->loadTexture(); - } - - // Draw the mappings. - getMainWindow()->getMapperByMappingId(mapping->getId())->draw(painter); + getMainWindow()->getMapperByMappingId((*it)->getId())->draw(painter); } // Draw the controls of current mapping. diff --git a/DestinationGLCanvas.h b/DestinationGLCanvas.h index 46cbc8c..cfd270a 100644 --- a/DestinationGLCanvas.h +++ b/DestinationGLCanvas.h @@ -36,8 +36,6 @@ public: virtual Shape* getShapeFromMappingId(uid mappingId); -// virtual Quad& getQuad(); - private: virtual void doDraw(QPainter* painter); }; diff --git a/HACKING b/HACKING index 3e57ddc..8b6c68e 100644 --- a/HACKING +++ b/HACKING @@ -65,3 +65,10 @@ Make a release * merge into develop. * keep developing. +XML file version number +----------------------- +* update its minor number when you introduce new features. +* update its major number when it's not backward-comptatible anymore with its previous versions +* generally, we should follow the MapMap version, when new changes are introduced. (no need to increment it otherwise) +* we will need to implement some fancy XML file version number checking in the future. + diff --git a/INSTALL b/INSTALL index b43053e..7dcf674 100644 --- a/INSTALL +++ b/INSTALL @@ -52,7 +52,7 @@ Build on Mac OS X * Install the Apple Developer Tools. You need to register with a credit card in the Apple Store in order to download it. * Install Qt5. You can get it from http://qt-project.org/downloads and choose the default location. -* Install the GStreamer SDK development files. +* Install the GStreamer SDK development files http://docs.gstreamer.com/display/GstSDK/Installing+on+Mac+OS+X Do this:: diff --git a/MainWindow.h b/MainWindow.h index 406ea5e..25c0f03 100644 --- a/MainWindow.h +++ b/MainWindow.h @@ -170,6 +170,8 @@ private: // Actions-related. bool okToContinue(); + +public: bool loadFile(const QString &fileName); bool saveFile(const QString &fileName); void setCurrentFile(const QString &fileName); @@ -184,6 +186,7 @@ private: // Returns a short version of filename. static QString strippedName(const QString &fullFileName); +private: // Connects/disconnects project-specific widgets (paints and mappings). void connectProjectWidgets(); void disconnectProjectWidgets(); diff --git a/Mapper.cpp b/Mapper.cpp index 9d682ea..7bcf2b8 100644 --- a/Mapper.cpp +++ b/Mapper.cpp @@ -299,7 +299,7 @@ void TextureMapper::draw(QPainter* painter) painter->beginNativePainting(); // Only works for similar shapes. - Q_ASSERT( outputShape->nVertices() == outputShape->nVertices()); + Q_ASSERT( inputShape->nVertices() == outputShape->nVertices()); // Project source texture and sent it to destination. texture->update(); @@ -333,6 +333,54 @@ void TextureMapper::draw(QPainter* painter) void TextureMapper::drawInput(QPainter* painter) { Q_UNUSED(painter); + painter->beginNativePainting(); + + // Only works for similar shapes. + Q_ASSERT( inputShape->nVertices() == outputShape->nVertices()); + + // Project source texture and sent it to destination. + texture->update(); + + glEnable (GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); + + // Copy bits to texture iff necessary. + if (texture->bitsHaveChanged()) + { + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, + texture->getWidth(), texture->getHeight(), 0, GL_RGBA, + GL_UNSIGNED_BYTE, texture->getBits()); + } + + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + + glColor4f(1.0f, 1.0f, 1.0f, 1.0f); + + // FIXME: Does this draw the quad counterclockwise? + glBegin (GL_QUADS); + { + Util::correctGlTexCoord(0, 0); + glVertex3f (texture->getX(), texture->getY(), 0); + + Util::correctGlTexCoord(1, 0); + glVertex3f (texture->getX()+texture->getWidth(), texture->getY(), 0); + + Util::correctGlTexCoord(1, 1); + glVertex3f (texture->getX()+texture->getWidth(), texture->getY() + texture->getHeight(), 0); + + Util::correctGlTexCoord(0, 1); + glVertex3f (texture->getX(), texture->getY() + texture->getHeight(), 0); + } + glEnd (); + + glDisable(GL_TEXTURE_2D); + + glPopMatrix(); + + painter->endNativePainting(); } void TextureMapper::drawControls(QPainter* painter) diff --git a/Mapper.h b/Mapper.h index f6a635d..227e473 100644 --- a/Mapper.h +++ b/Mapper.h @@ -72,9 +72,14 @@ protected: public: virtual QWidget* getPropertiesEditor(); + + virtual void draw(QPainter* painter) = 0; virtual void drawControls(QPainter* painter) = 0; + virtual void drawInput(QPainter* painter) { Q_UNUSED(painter); } + virtual void drawInputControls(QPainter* painter) { Q_UNUSED(painter); } + static void drawShapeContour(QPainter* painter, const Shape& shape, int lineWidth, const QColor& color); public slots: diff --git a/Mapping.h b/Mapping.h index 68db3e7..4421c1a 100644 --- a/Mapping.h +++ b/Mapping.h @@ -18,20 +18,17 @@ * along with this program. If not, see . */ - #ifndef MAPPING_H_ #define MAPPING_H_ #include #include - #include "Shape.h" #include "Paint.h" - #include "UidAllocator.h" /** - * Mapping is the central concept of Libremapping. + * Mapping is the central concept of this software. * * A Mapping represents a relationship between an input Paint and * and output Shape where the paint (possibly modified by some other @@ -85,6 +82,9 @@ public: Paint::ptr getPaint() const { return _paint; } Shape::ptr getShape() const { return _shape; } + virtual bool hasInputShape() const { return false; } + virtual Shape::ptr getInputShape() const { return Shape::ptr(); } + uid getId() const { return _id; } void setLocked(bool locked) { _isLocked = locked; } @@ -148,7 +148,8 @@ public: } public: - Shape::ptr getInputShape() const { return _inputShape; } + virtual bool hasInputShape() const { return true; } + virtual Shape::ptr getInputShape() const { return _inputShape; } }; #endif /* MAPPING_H_ */ diff --git a/MediaImpl.cpp b/MediaImpl.cpp index aaccde2..a1e8107 100644 --- a/MediaImpl.cpp +++ b/MediaImpl.cpp @@ -23,6 +23,7 @@ */ #include "MediaImpl.h" #include +#include // -------- private implementation of VideoImpl ------- @@ -430,6 +431,7 @@ bool MediaImpl::runVideo() { } _videoNewBufferCounter--; + //std::cout << "VideoImpl::runVideo: read frame #" << _videoNewBufferCounter << std::endl; } _postRun(); diff --git a/OscInterface.cpp b/OscInterface.cpp index 96955dc..fc742de 100644 --- a/OscInterface.cpp +++ b/OscInterface.cpp @@ -211,12 +211,11 @@ void OscInterface::applyOscCommand(MainWindow &main_window, QVariantList & comma std::string typetags = command.at(1).toString().toStdString(); // Handle all OSC messages here - if (path == "/texture/uri" && typetags == "is") + if (path == "/mapmap/paint/media/load" && typetags == "is") { int paint_id = command.at(2).toInt(); std::string image_uri = command.at(3).toString().toStdString(); - //std::cout << "TODO load /image/uri " << image_id << " " << image_uri << std::endl; - // TODO: + //std::cout << "load /mapmap/paint/media/load " << paint_id << " " << image_uri << std::endl; main_window.setTextureUri(paint_id, image_uri); } diff --git a/Paint.cpp b/Paint.cpp index b201781..3fe6eb0 100644 --- a/Paint.cpp +++ b/Paint.cpp @@ -76,8 +76,8 @@ int Media::getHeight() const } void Media::update() { - if (impl_->runVideo()) - bitsChanged = true; + //std::cout << "XXX Video::update()!" << std::endl; + impl_->runVideo(); } const uchar* Media::_getBits() const diff --git a/ProjectReader.cpp b/ProjectReader.cpp index 830f645..cd5d982 100644 --- a/ProjectReader.cpp +++ b/ProjectReader.cpp @@ -41,8 +41,10 @@ bool ProjectReader::readFile(QIODevice *device) } QDomElement root = doc.documentElement(); - if (root.tagName() != "project" || root.attribute("version") != "1.0") { - _xml.raiseError(QObject::tr("The file is not a mapmap version 1.0 file.")); + // The handling of the version number will get fancier as we go. + if (root.tagName() != "project" || root.attribute("version") != "0.1") + { + _xml.raiseError(QObject::tr("The file is not a mapmap version 0.1 file.")); return false; } diff --git a/ProjectWriter.cpp b/ProjectWriter.cpp index 7ea9b4a..5c4bd3d 100644 --- a/ProjectWriter.cpp +++ b/ProjectWriter.cpp @@ -33,7 +33,7 @@ bool ProjectWriter::writeFile(QIODevice *device) _xml.writeStartDocument(); _xml.writeDTD(""); _xml.writeStartElement("project"); - _xml.writeAttribute("version", "1.0"); + _xml.writeAttribute("version", "0.1"); // Similar to pkg-config version numbers. _xml.writeStartElement("paints"); for (int i = 0; i < _manager->nPaints(); i++) diff --git a/README b/README index 1431374..e7d36f7 100644 --- a/README +++ b/README @@ -26,18 +26,22 @@ Build and install ----------------- See the INSTALL file. +To use this software on Mac OS X: +* Install Qt5. You can get it from http://qt-project.org/downloads and choose the default location. +* Install the GStreamer SDK Runtime files from http://docs.gstreamer.com/display/GstSDK/Installing+on+Mac+OS+X + Authors ------- -* Sofian Audry, lead developer, project manager. -* Alexandre Quessy, release manager, developer, technical writer, project manager. +* Alexandre Quessy: release manager, developer, technical writer, project manager. +* Sofian Audry: lead developer, user interface designer, project manager. Contributors ------------ -* Mike Latona, user interface designer. -* Vasilis Liaskovitis, developer. -* Maxime Damecour, inspiration. -* Christian Ambaud, sponsor, inspiration. -* Louis Desjardins, project manager. -* Julien Keable, developer. -* Sylvain Cormier, developer. +* Mike Latona: user interface designer. +* Vasilis Liaskovitis: developer. +* Maxime Damecour: inspiration. +* Christian Ambaud: sponsor, inspiration. +* Louis Desjardins: project manager. +* Julien Keable: developer. +* Sylvain Cormier: developer. diff --git a/SourceGLCanvas.cpp b/SourceGLCanvas.cpp index ce2152d..db75cd4 100644 --- a/SourceGLCanvas.cpp +++ b/SourceGLCanvas.cpp @@ -36,149 +36,21 @@ Shape* SourceGLCanvas::getShapeFromMappingId(uid mappingId) else { Mapping::ptr mapping = getMainWindow()->getMappingManager().getMappingById(mappingId); - // TODO: this is real shit... : we should at the very least use some dynamic casting or (better) implement a correct - // class architecture to suit our needs - if (mapping->getType().endsWith("_texture")) - { - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(mapping); - Q_CHECK_PTR(textureMapping); - - return textureMapping->getInputShape().get(); - } - else - return NULL; + Q_CHECK_PTR(mapping); + return mapping->getInputShape().get(); } } -//Quad& SourceGLCanvas::getQuad() -//{ -// std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(Common::currentMapping); -// Q_CHECK_PTR(textureMapping); -// -// std::tr1::shared_ptr inputQuad = std::tr1::static_pointer_cast(textureMapping->getInputShape()); -// Q_CHECK_PTR(inputQuad); -// -// return (*inputQuad); -//} void SourceGLCanvas::doDraw(QPainter* painter) { - if (!getMainWindow()->hasCurrentPaint()) - return; - - uint paintId = getMainWindow()->getCurrentPaintId(); - - // Retrieve paint (as texture) and draw it. - Paint::ptr paint = getMainWindow()->getMappingManager().getPaintById(paintId); - Q_CHECK_PTR(paint); - - // Retrieve all mappings associated to paint. - QMap mappings = getMainWindow()->getMappingManager().getPaintMappingsById(paintId); - - if (paint->getType() == "color") - _drawColor(painter, paint, mappings); - else - _drawTexture(painter, paint, mappings); -} - -void SourceGLCanvas::_drawColor(QPainter* painter, Paint::ptr paint, QMap mappings) -{ - // Not doing anything for now. - Q_UNUSED(painter); - Q_UNUSED(paint); - Q_UNUSED(mappings); -} - -void SourceGLCanvas::_drawTexture(QPainter* painter, Paint::ptr paint, QMap mappings) -{ - Q_UNUSED(painter); - - std::tr1::shared_ptr texture = std::tr1::static_pointer_cast(paint); - Q_CHECK_PTR(texture); - - // Load texture if needed. - if (texture->getTextureId() == 0) { - texture->loadTexture(); - } - - // Draw the texture. - glPushMatrix(); - - // Enable blending mode (for alphas). - glEnable (GL_BLEND); - glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); - - glDisable (GL_LIGHTING); - glEnable (GL_TEXTURE_2D); - glBindTexture(GL_TEXTURE_2D, texture->getTextureId()); - - if (texture->bitsHaveChanged()) - { - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, texture->getWidth(), texture->getHeight(), 0, GL_RGBA, - GL_UNSIGNED_BYTE, texture->getBits()); - } - - //std::cout << texture->getX() << "x" << texture->getY() << " : " << texture->getWidth() << "x" << texture->getHeight() << " " << texture->getTextureId() << std::endl; - - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); - - // TODO: Exact projection of texture - // see http://stackoverflow.com/questions/15242507/perspective-correct-texturing-of-trapezoid-in-opengl-es-2-0 - - // Draw source texture (not moving) in the center of the area. - - // float centerX = (float) width() / 2.0f; - // float centerY = (float) height() / 2.0f; - // float textureHalfWidth = (float) texture->getWidth() / 2.0f; - // float textureHalfHeight = (float) texture->getHeight() / 2.0f; - - - glColor4f (1.0f, 1.0f, 1.0f, 1.0f); - // FIXME: Does this draw the quad counterclockwise? - glBegin (GL_QUADS); - { - Util::correctGlTexCoord(0, 0); - glVertex3f (texture->getX(), texture->getY(), 0); - - Util::correctGlTexCoord(1, 0); - glVertex3f (texture->getX()+texture->getWidth(), texture->getY(), 0); - - Util::correctGlTexCoord(1, 1); - glVertex3f (texture->getX()+texture->getWidth(), texture->getY() + texture->getHeight(), 0); - - Util::correctGlTexCoord(0, 1); - glVertex3f (texture->getX(), texture->getY() + texture->getHeight(), 0); - } - glEnd (); - - glDisable(GL_TEXTURE_2D); - - for (QMap::iterator it = mappings.begin(); it != mappings.end(); ++it) - { - // TODO: Ceci est un hack necessaire car tout est en fonction de la width/height de la texture. - // Il faut changer ca. - std::tr1::shared_ptr textureMapping = std::tr1::static_pointer_cast(it.value()); - Q_CHECK_PTR(textureMapping); - - std::tr1::shared_ptr inputShape = std::tr1::static_pointer_cast(textureMapping->getInputShape()); - Q_CHECK_PTR(inputShape); - - if (displayControls() && - it.key() == getMainWindow()->getCurrentMappingId()) - { - Mapper::ptr mapper = getMainWindow()->getMapperByMappingId(it.key()); - Q_CHECK_PTR(mapper); - - std::tr1::shared_ptr textureMapper = std::tr1::static_pointer_cast(mapper); - Q_CHECK_PTR(textureMapper); - - textureMapper->drawInputControls(painter); - } - } - - glPopMatrix(); + if (getMainWindow()->hasCurrentMapping()) + { + uint mappingId = getMainWindow()->getCurrentMappingId(); + Mapper::ptr mapper = getMainWindow()->getMapperByMappingId(mappingId); + mapper->drawInput(painter); + if (displayControls()) + mapper->drawInputControls(painter); + } } diff --git a/SourceGLCanvas.h b/SourceGLCanvas.h index f0ac43e..60161f1 100644 --- a/SourceGLCanvas.h +++ b/SourceGLCanvas.h @@ -36,13 +36,9 @@ public: // virtual ~SourceGLCanvas() {} virtual Shape* getShapeFromMappingId(uid mappingId); -// virtual Quad& getQuad(); private: virtual void doDraw(QPainter* painter); - - void _drawColor(QPainter* painter, Paint::ptr paint, QMap mappings); - void _drawTexture(QPainter* painter, Paint::ptr paint, QMap mappings); }; diff --git a/TODO b/TODO index 8393dee..bd139e0 100644 --- a/TODO +++ b/TODO @@ -49,3 +49,25 @@ Fonctionnalités cool à faire plus tard * animation de stroke par groupe * OSC pour controler les positions et l'alpha des quads +OSC INTERFACE ADDITIONAL CALLBACKS +---------------------------------- +Instead of using boolean values (true or false) we use numbers, where 0 means false, and any positive number means true. + +You should make sure to block all incoming messages on that port if you don't want to be hacked during a show. + +/mapmap/mapping/move/xy ,iff +/mapmap/mapping/vertex/source/xy ,iiff +/mapmap/mapping/vertex/destination/xy ,iiff +/mapmap/mapping/visible ,ii +/mapmap/mapping/highlight ,ii +/mapmap/mapping/vertex/highlight ,iii +/mapmap/project/load ,s +/mapmap/project/save ,s +/mapmap/paint/color/rgba ,iffff (each channel within [0,1]) +/mapmap/paint/media/load ,is +/mapmap/paint/media/speed ,if (1.0 means 100% speed) +/mapmap/paint/media/seek ,il