From de9af5d6bd85c0af46519969214534db2812bb52 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 12 Mar 2004 20:23:55 +0000 Subject: [PATCH] Cleaned up osgmovie example so it no longer depends upon LibMpeg3, just using readImageFile instead. --- Make/makedirdefs | 5 +- examples/osgmovie/GNUmakefile | 3 +- examples/osgmovie/GNUmakefile.inst | 3 +- examples/osgmovie/MpegImageStream.cpp | 289 -------------------------- examples/osgmovie/MpegImageStream.h | 128 ------------ examples/osgmovie/osgmovie.cpp | 150 ++++--------- 6 files changed, 43 insertions(+), 535 deletions(-) delete mode 100644 examples/osgmovie/MpegImageStream.cpp delete mode 100644 examples/osgmovie/MpegImageStream.h diff --git a/Make/makedirdefs b/Make/makedirdefs index 3bfd4d620..94946a39d 100644 --- a/Make/makedirdefs +++ b/Make/makedirdefs @@ -153,6 +153,7 @@ EXAMPLE_DIRS = \ osglight\ osglightpoint\ osglogo\ + osgmovie\ osgmultitexture\ osgoccluder\ osgpagedlod\ @@ -194,10 +195,6 @@ ifeq ($(GDAL_INSTALLED),yes) EXAMPLE_DIRS += osgbluemarble endif -ifeq ($(LIBMPEG3_INSTALLED),yes) - EXAMPLE_DIRS += osgmovie -endif - ifeq ($(DEMETER_INSTALLED),yes) EXAMPLE_DIRS += osgdemeter endif diff --git a/examples/osgmovie/GNUmakefile b/examples/osgmovie/GNUmakefile index 4881e5453..f007381f3 100644 --- a/examples/osgmovie/GNUmakefile +++ b/examples/osgmovie/GNUmakefile @@ -2,9 +2,8 @@ TOPDIR = ../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ - osgmovie.cpp MpegImageStream.cpp\ + osgmovie.cpp\ -OTHER_LIBS += -lmpeg3 -lpthread LIBS += -losgProducer -lProducer -losgText -losgGA -losgDB -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) INSTFILES = \ diff --git a/examples/osgmovie/GNUmakefile.inst b/examples/osgmovie/GNUmakefile.inst index e2202afc8..c3baf0c16 100644 --- a/examples/osgmovie/GNUmakefile.inst +++ b/examples/osgmovie/GNUmakefile.inst @@ -2,9 +2,8 @@ TOPDIR = ../.. include $(TOPDIR)/Make/makedefs CXXFILES =\ - osgmovie.cpp MpegImageStream.cpp\ + osgmovie.cpp\ -OTHER_LIBS += -lmpeg3 -lpthread LIBS += -losgProducer -lProducer -losgDB -losgText -losgUtil -losg $(GL_LIBS) $(X_LIBS) $(OTHER_LIBS) EXEC = osgmovie diff --git a/examples/osgmovie/MpegImageStream.cpp b/examples/osgmovie/MpegImageStream.cpp deleted file mode 100644 index 8428243bc..000000000 --- a/examples/osgmovie/MpegImageStream.cpp +++ /dev/null @@ -1,289 +0,0 @@ -// -*-c++-*- - -/* - * Copyright (C) 2001 Ulrich Hertlein - * - * Uses libmpeg3 by Adam Williams - * See http://www.heroinewarrior.com - * - * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for - * real-time rendering of large 3D photo-realistic models. - * The OSG homepage is http://www.openscenegraph.org/ - * - * This software 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 software 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 "MpegImageStream.h" -#include -#include - -#include -#include -#include - -#include "libmpeg3/libmpeg3.h" - -using namespace osg; - -#define IDLE_TIMEOUT 150000L - - -// Constructor: setup and start thread -MpegImageStream::MpegImageStream(const char* fileName) : ImageStream() -{ - _useMMX = false; - _fps = 0.0f; - _frames = 0; - _len = 0; - _mpg = 0; - - for (int i = 0; i < NUM_CMD_INDEX; i++) - _cmd[i] = THREAD_IDLE; - _wrIndex = _rdIndex = 0; - - load(fileName); - - ::pthread_mutex_init(&_mutex, NULL); - ::pthread_create(&_id, NULL, MpegImageStream::s_decode, this); - - if (fileName) - setFileName(fileName); - - -} - - -// Deconstructor: stop and terminate thread -MpegImageStream::~MpegImageStream() -{ - stop(); - setCmd(THREAD_QUIT); - ::pthread_join(_id, NULL); - ::pthread_mutex_destroy(&_mutex); - - mpeg3_t* mpg = (mpeg3_t*)_mpg; - if (mpg) { - mpeg3_close(mpg); - mpg = NULL; - } - if (_rows) { - ::free(_rows); - _rows = NULL; - } - -} - - -// Set command -void MpegImageStream::setCmd(ThreadCommand cmd) -{ - lock(); - _cmd[_wrIndex] = cmd; - _wrIndex = (_wrIndex + 1) % NUM_CMD_INDEX; - unlock(); -} - - -// Get command -MpegImageStream::ThreadCommand MpegImageStream::getCmd() -{ - ThreadCommand cmd = THREAD_IDLE; - lock(); - if (_rdIndex != _wrIndex) { - cmd = _cmd[_rdIndex]; - _rdIndex = (_rdIndex + 1) % NUM_CMD_INDEX; - } - unlock(); - return cmd; -} - - -/* - * Decoder thread - */ -void* MpegImageStream::s_decode(void* vp) -{ - return ((MpegImageStream*) vp)->decode(vp); -} - -void MpegImageStream::load(const char* fileName) -{ - mpeg3_t* mpg = mpeg3_open((char*) fileName); - if (!mpg) { - osg::notify(WARN) << "Unable to open " << fileName << std::endl; - return; - } - - if (!mpeg3_has_video(mpg)) { - osg::notify(WARN) << "No video streams in" << fileName << std::endl; - return; - } - if (mpeg3_has_audio(mpg)) { - osg::notify(NOTICE) << "Stream has audio" << std::endl; - } - - _mpg = (void*)mpg; - - mpeg3_set_cpus(mpg, 1); - mpeg3_set_mmx(mpg, _useMMX); - - int str = 0; //mpeg3_total_vstreams(mpg) - 1; - - _fps = mpeg3_frame_rate(mpg, str); - _frames = mpeg3_video_frames(mpg, str); - _len = (float) _frames / _fps; - - - int s = mpeg3_video_width(mpg, str); - int t = mpeg3_video_height(mpg, str); - - // Calculate texture size - // these are also calculated and stored within osg::Texture but - // too late (on the first apply) to be of any use... - int texWidth = 1; - for (; texWidth < s; texWidth <<= 1) - ; - int texHeight = 1; - for (; texHeight < t; texHeight <<= 1) - ; - - - // Allocate image data - // maybe use BGR888 and save some conversion somewhere? - unsigned char* data = (unsigned char*) ::malloc(s * t * 3); - - - setImage(s, t, 0, - GL_RGB, - GL_RGB, GL_UNSIGNED_BYTE, data, - osg::Image::USE_MALLOC_FREE); - - // Allocate decoder rows - // documentation says we need add'l bytes at the end of each - // row for MMX but this is more efficient and works so far. - _rows = (unsigned char**) ::malloc(t * sizeof(unsigned char*)); - unsigned char* dp = data; - for (int i = 0; i < t; i++) { - _rows[t-i-1] = dp; - dp += (s * 3); - } - - // - // #if 0 - // // Setup texture matrix - // Matrix mat; - // mat.makeScale((float) s / (float) texWidth, - // ((float) t / (float) texHeight) * -1.0f, 1.0f); - // mat = mat * Matrix::translate(0.0f, (float) t / (float) texHeight, 0.0f); - // _texMat->setMatrix(mat); - // #else - // _texMat->setMatrix(osg::Matrix::scale(s,-t,1.0f)*osg::Matrix::translate(0.0f,t,0.0f)); - // #endif - // XXX - osg::notify(NOTICE) << _frames << " @ " << _fps << " " << _len << "s" << std::endl; - osg::notify(NOTICE) << "img " << s << "x" << t << std::endl; - osg::notify(NOTICE) << "tex " << texWidth << "x" << texHeight << std::endl; -} - - -void* MpegImageStream::decode(void*) -{ - bool playing = false; - mpeg3_t* mpg = (mpeg3_t*)_mpg; - int str = 0; - float t0 = 0.0f; - unsigned long delay = (unsigned long) ((1.0f / _fps) * 1000.0f); - - bool done = false; - - const osg::Timer* timer = osg::Timer::instance(); - osg::Timer_t start_tick = timer->tick(); - osg::Timer_t last_frame_tick = start_tick; - double timePerFrame = 1.0f/_fps; - double frameNumber = 0.0; - - while (!done) { - - // Handle commands - ThreadCommand cmd = getCmd(); - if (cmd != THREAD_IDLE) { - switch (cmd) { - case THREAD_START: // Start or continue stream - playing = true; - break; - case THREAD_STOP: // XXX - osg::notify(NOTICE) << "stop at " << t0 << std::endl; - playing = false; - break; - case THREAD_REWIND: // XXX - t0 = 0.0; - mpeg3_seek_percentage(mpg, 0.0); - start_tick = timer->tick(); - frameNumber = 0; - break; - case THREAD_CLOSE: // Stop and close - playing = false; - if (mpg) { - mpeg3_close(mpg); - mpg = NULL; - } - break; - case THREAD_QUIT: // XXX - osg::notify(NOTICE) << "quit" << std::endl; - done = true; - break; - default: - osg::notify(osg::WARN) << "Unknown command " << cmd << std::endl; - break; - } - } - - if (playing) { - - - last_frame_tick = timer->tick(); - - // XXX needs more work to be real-time - mpeg3_read_frame(mpg, _rows, - 0, 0, _s, _t, - _s, _t, - MPEG3_RGB888, str); - dirty(); //Image(); - - ++frameNumber; - - if (frameNumber>=_frames) - { - - rewind(); - //stop(); - } - else - { - while (timePerFrame*(frameNumber+1)>timer->delta_s(start_tick,timer->tick())) - { - ::usleep(delay); - } - } - } - else { - ::usleep(IDLE_TIMEOUT); - } - } - - // Cleanup decoder - - return NULL; -} diff --git a/examples/osgmovie/MpegImageStream.h b/examples/osgmovie/MpegImageStream.h deleted file mode 100644 index 233aac51e..000000000 --- a/examples/osgmovie/MpegImageStream.h +++ /dev/null @@ -1,128 +0,0 @@ -// -*-c++-*- - -/* - * Copyright (C) 2001 Ulrich Hertlein - * - * Uses libmpeg3 by Adam Williams - * See http://www.heroinewarrior.com - * - * The Open Scene Graph (OSG) is a cross platform C++/OpenGL library for - * real-time rendering of large 3D photo-realistic models. - * The OSG homepage is http://www.openscenegraph.org/ - * - * This software 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 software 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 - */ - -#ifndef _MPEGIMAGESTREAM_H_ -#define _MPEGIMAGESTREAM_H_ - -#include -//#include "ImageStream.h" - -#include - -#define NUM_CMD_INDEX 4 - -namespace osg { - - /** - * MPEG1/2 Image Stream class. - */ - class SG_EXPORT MpegImageStream : public osg::ImageStream - { - public: - MpegImageStream(const char* fileName = NULL); - - virtual Object* clone() const { return new MpegImageStream; } - virtual bool isSameKindAs(const Object* obj) const { - return dynamic_cast(obj) != NULL; - } - virtual const char* className() const { return "MpegImageStream"; } - - /// Start or continue stream. - virtual inline void start() { setCmd(THREAD_START); } - - /// Stop stream at current position. - virtual inline void stop() { setCmd(THREAD_STOP); } - - /// Rewind stream to beginning. - virtual inline void rewind() { setCmd(THREAD_REWIND); } - - /// Enable/disable MMX. - inline void enableMMX(bool b) { _useMMX = b; } - - /** - * Set frame rate in fps. - * This is overwritten by the actual frame rate of the stream when - * it is opened. - */ - inline void setFrameRate(float fps) { _fps = (fps < 0.0f ? 0.0f : fps); } - - /// Get frame rate in fps. - inline float getFrameRate() const { return _fps; } - - /// Get number of frames. - inline long getNumFrames() const { return _frames; } - - /// Get total length in seconds. - inline float getLength() const { return _len; } - - void load(const char* fileName); - - protected: - virtual ~MpegImageStream(); - - private: - bool _useMMX; - float _fps; - long _frames; - float _len; - - enum ThreadCommand { - THREAD_IDLE = 0, - THREAD_START, - THREAD_STOP, - THREAD_REWIND, - THREAD_CLOSE, - THREAD_QUIT - }; - ThreadCommand _cmd[NUM_CMD_INDEX]; - int _wrIndex, _rdIndex; - - pthread_mutex_t _mutex; - pthread_t _id; - - // Lock/unlock object. - inline void lock() { ::pthread_mutex_lock(&_mutex); } - inline void unlock() { ::pthread_mutex_unlock(&_mutex); } - - /// Set command. - void setCmd(ThreadCommand cmd); - - /// Get command. - ThreadCommand getCmd(); - - /// Decoder hook. - static void* s_decode(void*); - void* decode(void*); - - void* _mpg; - unsigned char** _rows; - - }; - -} // namespace - -#endif diff --git a/examples/osgmovie/osgmovie.cpp b/examples/osgmovie/osgmovie.cpp index 4452f9e09..a9e2ac871 100644 --- a/examples/osgmovie/osgmovie.cpp +++ b/examples/osgmovie/osgmovie.cpp @@ -15,120 +15,39 @@ #include -#include - -#include "MpegImageStream.h" - - -/* - * Create morphed textured geometry - */ -osg::Geode* morphGeom(osg::Vec3Array* coords, - osg::Vec3Array* normals, - osg::Vec2Array* texCoords, - osg::Image* image, - osg::TexMat* texMat) +osg::Geometry* createTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image) { - /* - * GeoSet - */ - osg::Geometry* gset = new osg::Geometry(); - - gset->addPrimitiveSet(new osg::DrawArrays(osg::PrimitiveSet::POLYGON,0,4)); - - gset->setVertexArray(coords); - - gset->setNormalArray(normals); - gset->setNormalBinding(osg::Geometry::BIND_OVERALL); - - gset->setTexCoordArray(0,texCoords); - - /* - * StateSet - */ - osg::StateSet* state = new osg::StateSet; - - osg::Material* mtl = new osg::Material(); - osg::Vec4 white( 1.0f, 1.0f, 1.0f, 1.0f ); - mtl->setEmission( osg::Material::FRONT_AND_BACK, white ); - mtl->setAmbient( osg::Material::FRONT_AND_BACK, white ); - mtl->setDiffuse( osg::Material::FRONT_AND_BACK, white ); - mtl->setSpecular( osg::Material::FRONT_AND_BACK, white ); - state->setAttribute(mtl); - - //osg::Texture2D* tex = new osg::Texture2D; - osg::TextureRectangle* tex = new osg::TextureRectangle; - if (!image) { - image = osgDB::readImageFile("lz.rgb"); + bool useTextureRectangle = true; + if (useTextureRectangle) + { + osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos, + osg::Vec3(width,0.0f,0.0f), + osg::Vec3(0.0f,0.0f,height), + image->s(),image->t()); + + pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0, + new osg::TextureRectangle(image), + osg::StateAttribute::ON); + + return pictureQuad; } - tex->setImage(image); - tex->setFilter(osg::Texture::MIN_FILTER, osg::Texture::NEAREST); - tex->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP); - tex->setWrap(osg::Texture::WRAP_T, osg::Texture::CLAMP); - state->setTextureAttributeAndModes(0, tex, osg::StateAttribute::ON); + else + { + osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos, + osg::Vec3(width,0.0f,0.0f), + osg::Vec3(0.0f,0.0f,height), + 1.0f,1.0f); + + pictureQuad->getOrCreateStateSet()->setTextureAttributeAndModes(0, + new osg::Texture2D(image), + osg::StateAttribute::ON); - if (texMat) - state->setTextureAttributeAndModes(0, texMat, osg::StateAttribute::ON); - - // don't cull faces - osg::CullFace* cull = new osg::CullFace; - state->setAttributeAndModes(cull, osg::StateAttribute::OFF); - - /* - * Geode - */ - osg::Geode* geode = new osg::Geode; - geode->setStateSet( state ); - geode->addDrawable( gset ); - - return geode; + return pictureQuad; + } } - -/* - * Main - */ int main(int argc, char** argv) { - // coordinates - osg::Vec3Array* coords = new osg::Vec3Array(4); - (*coords)[0].set( -1.0f, 0.0f, -1.0f ); - (*coords)[1].set( 1.0f, 0.0f, -1.0f ); - (*coords)[2].set( 1.0f, 0.0f, 1.0f ); - (*coords)[3].set( -1.0f, 0.0f, 1.0f ); - - - // normals - osg::Vec3Array* normals = new osg::Vec3Array(1); - (*normals)[0].set( 0.0f, 1.0f, 0.0f ); - - // texture coordinates - osg::Vec2Array* texCoords = new osg::Vec2Array(4); - (*texCoords)[0].set(0.0f, 0.0f); - (*texCoords)[1].set(1.0f, 0.0f); - (*texCoords)[2].set(1.0f, 1.0f); - (*texCoords)[3].set(0.0f, 1.0f); - - - // open MpegImageStream - osg::MpegImageStream* mpeg = NULL; - if (argc > 1) { - mpeg = new osg::MpegImageStream(argv[1]); - mpeg->start(); - } - - osg::TexMat* texMat = new osg::TexMat; - texMat->setMatrix(osg::Matrix::scale(mpeg->s(),mpeg->t(),1.0f)); - - - // Create morphed geometry - osg::Geode* geode = morphGeom(coords, - normals, texCoords, mpeg, texMat); - //coordMorph.addGeode(geode); - - - - // use an ArgumentParser object to manage the program arguments. osg::ArgumentParser arguments(&argc,argv); @@ -155,6 +74,20 @@ int main(int argc, char** argv) return 1; } + osg::Geode* geode = new osg::Geode; + osg::Vec3 pos(0.0f,0.0f,0.0f); + + for(int i=1;iaddDrawable(createTexturedQuadGeometry(pos,image->s(),image->t(),image)); + } + + } + + // report any errors if they have occured when parsing the program aguments. if (arguments.errors()) { @@ -189,9 +122,6 @@ int main(int argc, char** argv) // wait for all cull and draw threads to complete. viewer.sync(); - // update the geoemtry - //coordMorph.update(viewer.getFrameStamp()->getReferenceTime()); - // update the scene by traversing it with the the update visitor which will // call all node update callbacks and animations. viewer.update();