Skip to content
Snippets Groups Projects
Select Git revision
  • 0233c3e3cc1eab6e6c68cf18f2f1e2f044992126
  • master default protected
  • Francois
  • Baptiste
  • Maxime
  • Sacha
  • Paul
7 results

Case.java

Blame
  • Reveal.cpp 21.59 KiB
    /***************************************************************************
     *	Reveal.cpp
     *	Part of Revil
     *	2015-  Florent Berthaut
     *	hitmuri.net
     ****************************************************************************/
    /*
     *	This program is free software; you can redistribute it and/or modify
     *	it under the terms of the GNU General Public License as published by
     *	the Free Software Foundation; either version 2 of the License, or
     *	(at your option) any later version.
     *
     *	This program is distributed in the hope that it will be useful,
     *	but WITHOUT ANY WARRANTY; without even the implied warranty of
     *	MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
     *	GNU General Public License for more details.
     *
     *	You should have received a copy of the GNU General Public License
     *	along with this program; if not, write to the Free Software
     *	Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
     */
    
    
    #include "Reveal.hpp" 
    
    #include <iostream>
    #include <unistd.h>
    #include <FL/filename.H>
    
    #include <OpenNI.h>
    
    #include "geoms/BoxGeometry.hpp"
    #include "geoms/CamGeometry.hpp"
    #include "geoms/QuadGeometry.hpp"
    #include "geoms/SphereGeometry.hpp"
    #include "geoms/TubeGeometry.hpp"
    #include "geoms/ConeGeometry.hpp"
    #include "geoms/FrameGeometry.hpp"
    
    #include "modules/RevealedShapeModule.hpp"
    #include "modules/RevealedPathModule.hpp"
    #include "modules/RevealedTextModule.hpp"
    #include "modules/RevealedCutModule.hpp"
    #include "modules/RevealedArrowModule.hpp"
    #include "modules/RevealedGridModule.hpp"
    #include "modules/RevealedModelModule.hpp"
    #include "modules/GroupModule.hpp"
    #include "modules/SpaceModule.hpp"
    #include "modules/PreviewModule.hpp"
    #include "modules/ProjectorModule.hpp"
    #include "modules/DepthCamModule.hpp"
    #include "modules/DepthShapeModule.hpp"
    #include "modules/DepthMeshModule.hpp"
    #include "modules/DepthGroupModule.hpp"
    #include "modules/RootSceneGroupModule.hpp"
    #include "modules/SceneGroupModule.hpp"
    #include "modules/OutputManagerModule.hpp"
    #include "gui/MainWindow.hpp"
    #include "gui/GuiListener.hpp"
    #include "osc/OscManager.hpp"
    #include "osc/OscListener.hpp"
    #include "audio/AudioManager.hpp"
    
    
    using namespace std;
    
    Reveal* Reveal::getInstance() {
        static Reveal rev;
        return &rev;
    }
    
    Reveal::~Reveal(){}
    
    Reveal::Reveal() : GroupModule() {
        m_type="Rivill";
        m_name="rivill";
        addAttribute(new Attribute("open", 
                    Attribute::FILE_OPEN_ATTRIBUTE, 
                    openCallback, this, Attribute::LOCAL, 
                    false));
        addAttribute(new Attribute("save", 
                    Attribute::FILE_SAVE_ATTRIBUTE, 
                    saveCallback, this, Attribute::LOCAL, 
                    false));
        addAttribute(new Attribute("quit", 
                    Attribute::ACTION_ATTRIBUTE, 
                    quitCallback, this, Attribute::LOCAL, 
                    false));
    
        addAttribute(new Attribute("audio_output", 
                    Attribute::BOOL_ATTRIBUTE, 
                    audioOutputCallback,this,1,Attribute::GLOBAL));
        m_audioOut=false;
    
        /*
           addAttribute(new Attribute("ressources_folder", 
           Attribute::FOLDER_OPEN_ATTRIBUTE, 
           ressourcesCallback, this, Attribute::LOCAL, 
           false));
           addAttribute(new Attribute("ressource_upload", 
           Attribute::ACTION_STRING_ATTRIBUTE, 
           uploadCallback,this,2,Attribute::GLOBAL,false));
           */
        addAttribute(new Attribute("debug_osc_input", 
                    Attribute::BOOL_ATTRIBUTE, 
                    debugOscCallback,this,1,Attribute::GLOBAL));
        m_debugOSC=false;
    }
    
    void idleFunc(void* data) {
        Reveal::getInstance()->update();
        usleep(1000);
    }
    
    void Reveal::init() {
        m_openPlanned=0;
    
        //initialize osc input 
        OscManager::getInstance()->init();
    
        //initialize depth cameras
        openni::OpenNI::initialize();
        openni::OpenNI::setLogConsoleOutput(false);
        cout<<"Initialized OpenNI "<<openni::OpenNI::getExtendedError()<<endl;
    
        //initialize observers counter
        m_upObsIdCounter=0;
    
        //create all scene geometries 
        m_geomsMap[GEOM_BOX] = new BoxGeometry();
        m_geomsMap[GEOM_QUAD] = new QuadGeometry();
        m_geomsMap[GEOM_SPHERE] = new SphereGeometry();
        m_geomsMap[GEOM_TUBE] = new TubeGeometry();
        m_geomsMap[GEOM_CONE] = new ConeGeometry();
        m_geomsMap[GEOM_FRAME] = new FrameGeometry();
        map<GEOM_ID, Geometry*>::iterator itGeom = m_geomsMap.begin();
        for(; itGeom!=m_geomsMap.end(); ++itGeom) {
            itGeom->second->setGeomID(itGeom->first);
            m_geoms.push_back(itGeom->second);
        }
    
        m_contextHandlersCounter=0;
    
        m_maxNbRevealed=502;
        m_maxNbDepthCams=10;
    
        //add the outputs module
        m_output = new OutputManagerModule();
        addChild(m_output);
    
        //add spaces module 
        m_spaces = new SpacesModule();
        addChild(m_spaces);
    
        //create scene module
        m_scene = new RootSceneGroupModule();
        m_scene->addGroupAttributes();
        addChild(m_scene);
    
        //Initialize main window
        fl_register_images();
        MainWindow::getInstance()->init();
        Fl::add_idle(idleFunc, MainWindow::getInstance());
    
        //Initialize glfw for preview and projector windows
        glewExperimental = GL_TRUE;
        if(!glfwInit()) {
            exit(EXIT_FAILURE);
        }
        glfwWindowHint(GLFW_TRANSPARENT_FRAMEBUFFER, GLFW_TRUE); //FIXME GLFW 3.3
        glfwWindowHint(GLFW_RESIZABLE, GL_TRUE);
        glfwWindowHint(GLFW_AUTO_ICONIFY, GL_FALSE);
    #ifdef GL43
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 3);
    #else 
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    #endif
    #ifdef OSX
        glfwWindowHint(GLFW_OPENGL_PROFILE, GLFW_OPENGL_CORE_PROFILE);
        glfwWindowHint(GLFW_OPENGL_FORWARD_COMPAT, GL_TRUE);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MAJOR, 4);
        glfwWindowHint(GLFW_CONTEXT_VERSION_MINOR, 1);
    #endif
    
        //add preview module
        m_preview = new PreviewModule();
        m_spaces->addChild(m_preview);
    
        refreshModules();
    
        //Show main window
        MainWindow::getInstance()->show();
    
        //start timer
        gettimeofday(&m_prevTime, NULL);
    }
    
    GLFWwindow* Reveal::getPreviewWindow() {
        return m_preview->getWindow();
    }
    
    void Reveal::setAudioOutput(const bool& aud) {
        if(aud) {
            AudioManager::getInstance()->init();
        }
    }
    
    void Reveal::planOpen(std::string opSt) {
        //FIXME find better strategy for delaying text
        m_openPlanned=10;
        m_openPlannedName=opSt;
    }
    
    void Reveal::update() {
        //delete listeners, attributes and modules
        testDelete();
    
        //update osc manager
        OscManager::getInstance()->update();
    
        //FIXME distinguish between anim and update (cam)
        //update observers every 50ms 
        timeval curTime, timeDiff;
        gettimeofday(&curTime,NULL);
        timersub(&curTime, &m_prevTime, &timeDiff);
        int timeDiffMs = timeDiff.tv_sec*1000.0+timeDiff.tv_usec/1000.0;
        m_prevTime=curTime;
        vector<Module*>::iterator itUp = m_updateObservers.begin();
        for(; itUp!=m_updateObservers.end(); ++itUp) {
            (*itUp)->update(timeDiffMs);
        }
    
        //draw all spaces
        m_spaces->draw();
    
        //delayed open to fix text rendering issues ...
        if(m_openPlanned>0) {
            m_openPlanned--;
            if(m_openPlanned==0) {
                open(m_openPlannedName);
            }
        }
    
        glfwPollEvents();
    }
    
    int Reveal::run() {
        return Fl::run();
    }
    
    void Reveal::askQuit() {
        MainWindow::getInstance()->cbQuit();
    }
    
    void Reveal::quit() {
        glfwTerminate();
        exit(0);
    }
    
    void Reveal::open(const std::string& fileName) {
        cout<<"Opening "<<fileName<<endl;
        bool open=true;
        xmlDocPtr doc = xmlReadFile(fileName.c_str(), NULL, 0);
        xmlNodePtr rootNode = xmlDocGetRootElement(doc);
        if(doc==NULL || rootNode==NULL) {
            DEBUG("Could not open file "<<fileName);
            open=false;
        }
        else if(xmlStrcmp(rootNode->name, (const xmlChar*)"Rivill")) {
            xmlFreeDoc(doc);
            DEBUG("Could not open file "<<fileName);
            open=false;
        }
        if(open) { //if the file is valid
            m_currentFile=fileName;
            //clear the scene and spaces
            m_scene->deleteChildren();
            m_spaces->removeChild(m_preview);
            m_spaces->deleteChildren();
            m_spaces->addChild(m_preview);
            m_revealedMap.clear();
            m_registeredOutputRevealed.clear();
            m_registeredOutputDepthCams.clear();
            m_upObsIdCounter=0;
            m_updateObservers.clear();
            //and load
            load(rootNode);
            m_attributesMap["save"]->initFile(m_currentFile);
            MainWindow::getInstance()->refreshModules();
            DEBUG("Opened file "<<fileName);
        }
    }
    
    void Reveal::save(const std::string& fileName) {
        cout<<"Saving to "<<fileName<<endl;
        m_currentFile=fileName;
        xmlDocPtr doc = xmlNewDoc(BAD_CAST "1.0");
        xmlNodePtr rootNode = GroupModule::save(NULL);
        xmlDocSetRootElement(doc, rootNode);
        xmlSaveFormatFileEnc(fileName.c_str(), doc, "UTF-8", 1);
        xmlFreeDoc(doc);
        xmlCleanupParser();
    }
    
    void Reveal::setRessourcesFolder(const std::string& f) {
    
    }
    
    void Reveal::uploadRessource(const std::vector<std::string>& vf) {
    
    }
    
    void Reveal::load(xmlNodePtr node) {
        Module::load(node);
        xmlNodePtr modsNode;
        for(modsNode=node->children; modsNode; modsNode=modsNode->next){
            if(modsNode->type == XML_ELEMENT_NODE &&
                    !xmlStrcmp(modsNode->name, (const xmlChar *) "Modules")) {
                xmlNodePtr modNode;
                for(modNode=modsNode->children; modNode; modNode=modNode->next){
                    if(modNode->type == XML_ELEMENT_NODE) {
                        if(!xmlStrcmp(modNode->name,(const xmlChar *)"Scene")) {
                            m_scene->load(modNode);
                        }
                        else if(!xmlStrcmp(modNode->name,(const xmlChar*)"Spaces")){
                            m_spaces->load(modNode);
                        }
                    }
                }
            }
        }
    }
    
    Module* Reveal::createModule(const std::string& typeStr) {
        Module* mod=NULL;
        if(typeStr.compare("Projector")==0) {
            mod=new ProjectorModule();
        }
        else if(typeStr.compare("Space")==0) {
            mod=new SpaceModule();
        }
        else if(typeStr.compare("DepthGroup")==0) {
            mod=new DepthGroupModule();
        }
        else if(typeStr.compare("DepthCam")==0) {
            mod=new DepthCamModule();
        }
        else if(typeStr.compare("DepthShape")==0) {
            mod=new DepthShapeModule();
        }
        else if(typeStr.compare("DepthMesh")==0) {
            mod=new DepthMeshModule();
        }
        else if(typeStr.compare("SceneGroup")==0) {
            mod=new SceneGroupModule();
        }
        else if(typeStr.compare("Shape")==0) {
            mod=new RevealedShapeModule();
        }
        else if(typeStr.compare("Model")==0) {
            mod=new RevealedModelModule();
        }
        else if(typeStr.compare("Path")==0) {
            mod=new RevealedPathModule();
        }
        else if(typeStr.compare("Text")==0) {
            mod=new RevealedTextModule();
        }
        else if(typeStr.compare("Cut")==0) {
            mod=new RevealedCutModule();
        }
        else if(typeStr.compare("Arrow")==0) {
            mod=new RevealedArrowModule();
        }
        else if(typeStr.compare("Grid")==0) {
            mod=new RevealedGridModule();
        }
        return mod;
    }
    
    Listener* Reveal::createListener(const std::string& typeStr) {
        Listener* lis=NULL;
        if(typeStr.compare("OscListener")==0) {
            lis=new OscListener();
        }
        return lis;
    }
    
    int Reveal::getVisibilityMask(const std::string& visibleFrom) {
        int res=0;
        map<string, int>::iterator itVis = m_visibleFromMap.find(visibleFrom);
        if(itVis!=m_visibleFromMap.end()) {
            res=itVis->second;
        }
        return res;
    }
    
    void Reveal::addUpdateObserver(Module* upObs) {
        m_updateObservers.push_back(upObs);
        upObs->setUpID(m_upObsIdCounter);
        m_upObsIdCounter++;
    }
    
    void Reveal::removeUpdateObserver(Module* upObs) {
        vector<Module*>::iterator itObs = m_updateObservers.begin();
        for(; itObs!=m_updateObservers.end(); ) {
            if((*itObs)->getUpID()==upObs->getUpID()) {
                itObs = m_updateObservers.erase(itObs);
            }
            else {
                itObs++;
            }
        }
    }
    
    void Reveal::addModuleListObserver(ModuleListObserver* obs) {
        unsigned int obsID=0;
        while(m_moduleListObservers.find(obsID)!=m_moduleListObservers.end()) {
            obsID++;
        }
        m_moduleListObservers[obsID]=obs;
        obs->setModuleListObsID(obsID);
    }
    
    void Reveal::removeModuleListObserver(ModuleListObserver* obs) {
        m_moduleListObservers.erase(obs->getModuleListObsID());
    }
    
    void Reveal::addContextHandler(ContextHandler* cont) {
        m_contextHandlers[m_contextHandlersCounter]=cont;
        cont->setContextHandlerID(m_contextHandlersCounter);
        m_contextHandlersCounter++;
    }
    
    void Reveal::removeContextHandler(ContextHandler* cont) {
        m_contextHandlers.erase(cont->getContextHandlerID());
    }
    
    void Reveal::registerGeom(Geometry* geom) {
        GEOM_ID newID = GEOM_MODEL;
        while(m_geomsMap.find(newID)!=m_geomsMap.end()) {
            newID = GEOM_ID(int(newID)+1);
        }
        geom->setGeomID(newID);
        m_geomsMap[newID]=geom;
        m_geoms.push_back(geom);
    }
    
    void Reveal::unregisterGeom(Geometry* geom) {
        m_geomsMap.erase(geom->getGeomID());
        vector<Geometry*>::iterator itGeom = m_geoms.begin();
        for(; itGeom!=m_geoms.end(); ) {
            if((*itGeom)->getGeomID()==geom->getGeomID()) {
                itGeom = m_geoms.erase(itGeom);
            }
            else {
                ++itGeom;
            }
        }
    }
    
    void Reveal::registerRevealed(RevealedModule* rev) {
        m_revealedVec.push_back(rev);
        updateRevealed();
    }
    
    void Reveal::unregisterRevealed(RevealedModule* rev) {
        vector<RevealedModule*>::iterator itRev=m_revealedVec.begin();
        for(; itRev!=m_revealedVec.end();) {
            if((*itRev)->getRevID()==rev->getRevID()) {
                itRev=m_revealedVec.erase(itRev);
            }
            else {
                ++itRev;
            }
        }
        updateRevealed();
        unregisterOutputRevealed(rev);
    }
    
    void Reveal::updateRevealed() {
        m_revealedMap.clear();
        vector<RevealedModule*>::iterator itRev=m_revealedVec.begin();
        unsigned int id=1;
        for(; itRev!=m_revealedVec.end(); ++itRev, ++id) {
            (*itRev)->setRevID(id);
            m_revealedMap[id]=*itRev;
        }
    }
    
    void Reveal::refreshModules() {
        //recreate map of modules and attributes
        m_modulesMap.clear();
        m_fullAttributesMap.clear();
        GroupModule::listModulesAndAttributes("", m_modulesMap, 
                m_fullAttributesMap);
    
        //inform observers of the new module list
        map<unsigned int, ModuleListObserver*>::iterator itObs 
            = m_moduleListObservers.begin(); 
        for(; itObs!=m_moduleListObservers.end(); ++itObs) {
            itObs->second->updateModulesList(m_modulesMap);
        }
    
        //refresh space/projectors list
        m_visibleFromVec.clear();
        m_visibleFromMap.clear();
        m_visibleFromVec.push_back("none");
        m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_NONE;
        m_visibleFromVec.push_back("all");
        m_visibleFromMap[m_visibleFromVec.back()]=VISIBLE_FROM_ALL;
        m_spaces->getVisibleFromList(m_visibleFromVec, m_visibleFromMap);
    
        map<unsigned int, RevealedModule*>::iterator itMod
            = m_revealedMap.begin(); 
        for(; itMod!=m_revealedMap.end(); ++itMod) {
            itMod->second->setVisibleFromList(m_visibleFromVec);
        }
    
        //refresh display
        MainWindow::getInstance()->refreshModules();
    
        /*
        //TEMP list all attributes of all modules 
        map<string, Attribute*>::iterator itAtt = m_attributesMap.begin();
        for(;itAtt!=m_attributesMap.end(); ++itAtt) {
        cout<<itAtt->first<<endl;
        }
        */
    }
    
    Attribute* Reveal::findAttribute(const std::string& fullName) {
        map<string,Attribute*>::iterator itAtt = m_fullAttributesMap.find(fullName);
        if(itAtt!=m_fullAttributesMap.end()) {
            return itAtt->second;
        }
        return NULL;
    }
    
    Module* Reveal::findModule(const std::string& fullName) {
        map<string, Module*>::iterator itMod = m_modulesMap.find(fullName);
        if(itMod!=m_modulesMap.end()) {
            return itMod->second;
        }
        return NULL;
    }
    
    void Reveal::registerOutputRevealed(RevealedModule* rev) {
        bool found=false;
        vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
        for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) {
            if((*itSh)->getRevID()==rev->getRevID()) {
                found=true;
            }
        }
        if(!found) {
            m_registeredOutputRevealed.push_back(rev);
        }
        updateOutputRevealed();
    }
    
    void Reveal::unregisterOutputRevealed(RevealedModule* rev) {
    
        //remove it from list
        vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
        for(; itSh!=m_registeredOutputRevealed.end(); ) {
            if((*itSh)->getRevID()==rev->getRevID()) {
                itSh=m_registeredOutputRevealed.erase(itSh);
            }
            else {
                ++itSh;
            }
        }
    
        //reset offsets 
        updateOutputRevealed();
    }
    
    void Reveal::updateOutputRevealed() {
        vector<RevealedModule*>::iterator itSh=m_registeredOutputRevealed.begin();
        unsigned int offset=0;
        for(; itSh!=m_registeredOutputRevealed.end(); ++itSh) {
            (*itSh)->updateRevOffset(offset);
        }
    }
    
    void Reveal::registerOutputDepthCam(DepthCamModule* cam) {
        bool found=false;
        vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin();
        for(; itCa!=m_registeredOutputDepthCams.end(); ++itCa) {
            if((*itCa)->getDepthID()==cam->getDepthID()) {
                found=true;
            }
        }
        if(!found) {
            m_registeredOutputDepthCams.push_back(cam);
        }
    }
    
    void Reveal::unregisterOutputDepthCam(DepthCamModule* cam) {
        vector<DepthCamModule*>::iterator itCa=m_registeredOutputDepthCams.begin();
        for(; itCa!=m_registeredOutputDepthCams.end(); ) {
            if((*itCa)->getDepthID()==cam->getDepthID()) {
                itCa=m_registeredOutputDepthCams.erase(itCa);
            }
            else {
                ++itCa;
            }
        }
    }
    
    void Reveal::deleteListener(Listener* lis) {
        m_listenersDeleteVec.push_back(lis);
    }
    
    void Reveal::deleteModule(Module* mod) {
        m_modulesDeleteVec.push_back(mod);
        refreshModules();
    }
    
    void Reveal::testDelete() {
        bool erasedListeners=false;
        vector<Listener*>::iterator itLis = m_listenersDeleteVec.begin();
        for(; itLis!=m_listenersDeleteVec.end(); ++itLis) {
            delete (*itLis);
            erasedListeners=true;
        }
        m_listenersDeleteVec.clear();
    
    
        if(m_modulesDeleteVec.size()>0) {
            MainWindow::getInstance()->refreshModules(true, erasedListeners);
        }
        vector<Module*>::iterator itMod = m_modulesDeleteVec.begin();
        for(; itMod!=m_modulesDeleteVec.end(); ++itMod) {
            delete (*itMod);
        }
        m_modulesDeleteVec.clear();
    }
    
    GLuint Reveal::createProgram(const char* vertSource, const char* fragSource) {
        GLint compile_ok = GL_FALSE, link_ok = GL_FALSE;
        GLuint vertexShader, fragmentShader;
        vertexShader = glCreateShader(GL_VERTEX_SHADER);
        glShaderSource(vertexShader, 1, &vertSource, NULL);
        glCompileShader(vertexShader);
        glGetShaderiv(vertexShader, GL_COMPILE_STATUS, &compile_ok);
        if(!compile_ok) {
            cout << "Error in vertex shader" << endl;
            GLint maxLength = 0;
            glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &maxLength);
            std::vector<GLchar> errorLog(maxLength);
            glGetShaderInfoLog(vertexShader,maxLength,&maxLength, &errorLog[0]);
            vector<GLchar>::iterator itC=errorLog.begin();
            for(; itC!=errorLog.end(); ++itC) {
                cout<<*itC;
            }
            cout<<endl;
        } 
        fragmentShader = glCreateShader(GL_FRAGMENT_SHADER);
        glShaderSource(fragmentShader, 1, &fragSource, NULL);
        glCompileShader(fragmentShader);
        glGetShaderiv(fragmentShader, GL_COMPILE_STATUS, &compile_ok);
        if(!compile_ok) {
            cout << "Error in fragment shader" << endl;
            GLint maxLength = 0;
            glGetShaderiv(fragmentShader, GL_INFO_LOG_LENGTH, &maxLength);
            std::vector<GLchar> errorLog(maxLength);
            glGetShaderInfoLog(fragmentShader,maxLength,&maxLength, &errorLog[0]);
            vector<GLchar>::iterator itC=errorLog.begin();
            for(; itC!=errorLog.end(); ++itC) {
                cout<<*itC;
            }
            cout<<endl;
        }
        GLuint program = glCreateProgram();
        glAttachShader(program, vertexShader);
        glAttachShader(program, fragmentShader);
        glLinkProgram(program);
        glGetProgramiv(program, GL_LINK_STATUS, &link_ok);
        if(!link_ok) {
            cout<<"Error linking glsl program "<<program<<" "<<endl;
            GLint maxLength = 0;
            glGetProgramiv(program, GL_INFO_LOG_LENGTH, &maxLength);
            std::vector<GLchar> errorLog(maxLength);
            glGetProgramInfoLog(program,maxLength,&maxLength, &errorLog[0]);
            vector<GLchar>::iterator itC=errorLog.begin();
            for(; itC!=errorLog.end(); ++itC) {
                cout<<*itC;
            }
            cout<<endl;
        }
        return program;
    }
    
    void Reveal::measureStart() {
        gettimeofday(&m_measureTime, NULL);
        m_measuring=true;
    }
    
    void Reveal::measureStore(const int& nbPixels) {
        if(m_measuring) {
            timeval curTime, timeDiff;
            gettimeofday(&curTime, NULL);
            timersub(&curTime, &m_measureTime, &timeDiff);
            int timeDiffMs=int(timeDiff.tv_sec)*1000000 
                + int(timeDiff.tv_usec);
            if(m_measurePixelNb.find(nbPixels)==m_measurePixelNb.end()) {
                m_measurePixelTimes[nbPixels]=0;
                m_measurePixelNb[nbPixels]=0;
            }
            m_measurePixelNb[nbPixels]++;
            m_measurePixelTimes[nbPixels]+=timeDiffMs;
            cout<<nbPixels<<" "
                <<float(m_measurePixelTimes[nbPixels])
                / float(m_measurePixelNb[nbPixels])<<endl;
    
            m_measuring=false;
        }
    }
    
    //MAIN 
    int main( int argc, char **argv ) {
        Reveal::getInstance()->init();
        if(argc>1) {
            char* abs = new char[200];
            fl_filename_absolute(abs, 200, argv[1]);
            Reveal::getInstance()->planOpen(string(abs));	 
        }
        return Reveal::getInstance()->run();
    }