diff --git a/examples/osgmovie/osgmovie.cpp b/examples/osgmovie/osgmovie.cpp index 0b6f78f7e..0b0de6c9d 100644 --- a/examples/osgmovie/osgmovie.cpp +++ b/examples/osgmovie/osgmovie.cpp @@ -268,12 +268,13 @@ void MovieEventHandler::getUsage(osg::ApplicationUsage& usage) const osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,float height, osg::Image* image, bool useTextureRectangle) { + bool flip = image->getOrigin()==osg::Image::TOP_LEFT; if (useTextureRectangle) { osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos, osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,0.0f,height), - 0.0f,image->t(), image->s(),0.0f); + 0.0f, flip ? image->t() : 0.0, image->s(), flip ? 0.0 : image->t()); osg::TextureRectangle* texture = new osg::TextureRectangle(image); texture->setWrap(osg::Texture::WRAP_S, osg::Texture::CLAMP_TO_EDGE); @@ -291,7 +292,7 @@ osg::Geometry* myCreateTexturedQuadGeometry(const osg::Vec3& pos,float width,flo osg::Geometry* pictureQuad = osg::createTexturedQuadGeometry(pos, osg::Vec3(width,0.0f,0.0f), osg::Vec3(0.0f,0.0f,height), - 0.0f,1.0f, 1.0f,0.0f); + 0.0f, flip ? 1.0f : 0.0f , 1.0f, flip ? 0.0f : 1.0f); osg::Texture2D* texture = new osg::Texture2D(image); texture->setFilter(osg::Texture::MIN_FILTER,osg::Texture::LINEAR); diff --git a/include/osg/Image b/include/osg/Image index fd4ab48db..55a14495f 100644 --- a/include/osg/Image +++ b/include/osg/Image @@ -127,6 +127,24 @@ class OSG_EXPORT Image : public Object */ void copySubImage(int s_offset,int t_offset,int r_offset,osg::Image* source); + + enum Origin + { + BOTTOM_LEFT, + TOP_LEFT + }; + + /** Set the origin of the image. + * The default value is BOTTOM_LEFT and is consistent with OpenGL. + * TOP_LEFT is used for imagery that follows standard Imagery convention, such as movies, + * and hasn't been flipped yet. For such images one much flip the t axis of the tex coords. + * to handle this origin position. */ + void setOrigin(Origin origin) { _origin = origin; } + + /** Get the origin of the image.*/ + Origin getOrigin() const { return _origin; } + + /** Width of image. */ inline int s() const { return _s; } @@ -271,6 +289,8 @@ class OSG_EXPORT Image : public Object std::string _fileName; + Origin _origin; + int _s, _t, _r; GLint _internalTextureFormat; GLenum _pixelFormat; diff --git a/src/osg/Image.cpp b/src/osg/Image.cpp index 9916de898..104a08335 100644 --- a/src/osg/Image.cpp +++ b/src/osg/Image.cpp @@ -32,6 +32,7 @@ Image::Image() setDataVariance(STATIC); _fileName = ""; + _origin = BOTTOM_LEFT; _s = _t = _r = 0; _internalTextureFormat = 0; _pixelFormat = (unsigned int)0; @@ -47,6 +48,7 @@ Image::Image() Image::Image(const Image& image,const CopyOp& copyop): Object(image,copyop), _fileName(image._fileName), + _origin(image._origin), _s(image._s), _t(image._t), _r(image._r), _internalTextureFormat(image._internalTextureFormat), _pixelFormat(image._pixelFormat), diff --git a/src/osgPlugins/quicktime/QuicktimeImageStream.cpp b/src/osgPlugins/quicktime/QuicktimeImageStream.cpp index 25578a0c7..ca6485d0c 100644 --- a/src/osgPlugins/quicktime/QuicktimeImageStream.cpp +++ b/src/osgPlugins/quicktime/QuicktimeImageStream.cpp @@ -42,6 +42,8 @@ int QuicktimeImageStream::_qtInstanceCount = 0; // Constructor: setup and start thread QuicktimeImageStream::QuicktimeImageStream(std::string fileName) : ImageStream() { + setOrigin(osg::Image::TOP_LEFT); + _len = 0; _movieData = new MovieData(); diff --git a/src/osgPlugins/xine/ReaderWriterXine.cpp b/src/osgPlugins/xine/ReaderWriterXine.cpp index 1475d6668..5216b7ab3 100644 --- a/src/osgPlugins/xine/ReaderWriterXine.cpp +++ b/src/osgPlugins/xine/ReaderWriterXine.cpp @@ -30,7 +30,10 @@ class XineImageStream : public osg::ImageStream _visual(0), _stream(0), _event_queue(0), - _ready(false) {} + _ready(false) + { + setOrigin(osg::Image::TOP_LEFT); + } /** Copy constructor using CopyOp to manage deep vs shallow copy. */ XineImageStream(const XineImageStream& image,const osg::CopyOp& copyop=osg::CopyOp::SHALLOW_COPY):