Thanks JS, fix now merged and submitted to svn/trunk.

On Thu, Jan 7, 2010 at 7:27 PM, Jean-Sébastien Guay
<[email protected]> wrote:
> Hi Robert,
>
> I was testing an osgWidget-based test app I have and noticed that I couldn't
> move the windows/frames around on the screen anymore. Turns out that the
> virtual methods' interface changed in the EventInterface base class, the
> third argument to mouseDrag() is now const, but it was not changed in the
> derived classes, so it still compiled but the derived-class version was not
> being called because its arguments differed.
>
> Here are the changes that fix it.
>
> J-S
> --
> ______________________________________________________
> Jean-Sebastien Guay    [email protected]
>                               http://www.cm-labs.com/
>                        http://whitestar02.webhop.org/
>
> /* -*-c++-*- OpenSceneGraph - Copyright (C) 1998-2008 Robert Osfield
>  *
>  * This library is open source and may be redistributed and/or modified
> under
>  * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
>  * (at your option) any later version.  The full license is in LICENSE file
>  * included with this distribution, and on the openscenegraph.org website.
>  *
>  * This library 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
>  * OpenSceneGraph Public License for more details.
> */
>
> // Code by: Jeremy Moles (cubicool) 2007-2008
>
> #ifndef OSGWIDGET_FRAME
> #define OSGWIDGET_FRAME
>
> #include <osgWidget/Table>
>
> namespace osgWidget {
>
> /*
> Lets take a moment and explain how Frame texturing works. When you create a
> Frame, you use
> a specially designed texture that is "chopped" up horizontally by the Frame
> code into 8 equal
> regions. Each region is then textured to a corresponding portion of the
> Frame, in the
> following order:
>
>        +---+---+---+---+---+---+---+---+
>        | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
>        +---+---+---+---+---+---+---+---+
>
>        1. Upper-Left corner.
>        2. Top border (rotated 90 degrees CCW).
>        3. Upper-Right corner.
>        4. Left border.
>        5. Right border.
>        6. Bottom-Left corner.
>        7. Bottom border (rotated 90 degrees CCW).
>        8. Bottom-Right corner.
>
> Now, these should be pretty self-explanatory if you visualize a frame as a
> 3x3 "table"
> (which is exactly what it is), but note how regions 2 and 7 are rotated
> counter-clockwise.
> We do this for a VERY important reason: we want to enable texture repeat on
> the border
> regions, so that when the frame is resized the borders cleanly paint the
> texture over
> the entire are (and don't stretch it). However, it is impossible in OpenGL
> to repeat a
> sub-region of a texture without including either the vertical or horizontal
> bounds, so the
> artist is required to rotate the region during their rendering so that our
> code can properly
> rotate it back internally and have it repeat in the desired way.
>
> This method of texturing a Frame object is inspired by World of Warcraft
> "edge files", and it
> is both efficient and easy-to-use--once you understand the basics. If you're
> still confused,
> take a look at this URL, or any of the example themes:
>
>        http://www.wowwiki.com/EdgeFiles
> */
>
> class OSGWIDGET_EXPORT Frame: public Table
> {
>    public:
>
>        enum CornerType
>        {
>            CORNER_LOWER_LEFT,
>            CORNER_LOWER_RIGHT,
>            CORNER_UPPER_LEFT,
>            CORNER_UPPER_RIGHT
>        };
>
>        enum BorderType
>        {
>            BORDER_LEFT,
>            BORDER_RIGHT,
>            BORDER_TOP,
>            BORDER_BOTTOM
>        };
>
>        enum FrameOptions
>        {
>            FRAME_RESIZE  = 1,
>            FRAME_MOVE    = 2,
>            FRAME_TEXTURE = 4,
>            FRAME_ALL     = FRAME_RESIZE | FRAME_MOVE | FRAME_TEXTURE
>        };
>
>        static std::string cornerTypeToString (CornerType);
>        static std::string borderTypeToString (BorderType);
>
>        class OSGWIDGET_EXPORT Corner: public Widget
>        {
>        public:
>            META_Object(osgWidget, Corner);
>
>            Corner (CornerType = CORNER_LOWER_LEFT, point_type = 0.0f,
> point_type = 0.0f);
>            Corner (const Corner&, const osg::CopyOp&);
>
>            virtual void parented  (Window*);
>            virtual bool mouseDrag (double, double, const WindowManager*);
>
>            CornerType getCornerType() const
>            {
>                return _corner;
>            }
>
>            void setCornerType(CornerType corner)
>            {
>                _corner = corner;
>            }
>
>            void setCornerTypeAndName(CornerType corner)
>            {
>                _corner = corner;
>                _name   = cornerTypeToString(corner);
>            }
>
>        protected:
>
>            CornerType _corner;
>        };
>
>        class OSGWIDGET_EXPORT Border: public Widget
>        {
>        public:
>            META_Object(osgWidget, Border);
>
>            Border (BorderType = BORDER_LEFT, point_type = 0.0f, point_type =
> 0.0f);
>            Border (const Border&, const osg::CopyOp&);
>
>            virtual void parented   (Window*);
>            virtual void positioned ();
>            virtual bool mouseDrag  (double, double, const WindowManager*);
>
>            BorderType getBorderType() const
>            {
>                return _border;
>            }
>
>            void setBorderType(BorderType border)
>            {
>                _border = border;
>            }
>
>            void setBorderTypeAndName(BorderType border)
>            {
>                _border = border;
>                _name   = borderTypeToString(border);
>            }
>
>        protected:
>
>            BorderType _border;
>        };
>
>        META_Object(osgWidget, Frame);
>
>        Frame (const std::string& = "", unsigned int = 0);
>        Frame (const Frame&, const osg::CopyOp&);
>
>        static Frame* createSimpleFrame(
>            const std::string&,
>            point_type,
>            point_type,
>            point_type,
>            point_type,
>            unsigned int = 0,
>            Frame*       = 0
>        );
>
>        static Frame* createSimpleFrameWithSingleTexture(
>            const std::string&,
>            osg::Image*,
>            point_type,
>            point_type,
>            unsigned int = 0,
>            Frame*       = 0
>        );
>
>        static Frame* createSimpleFrameFromTheme(
>            const std::string&,
>            osg::Image*,
>            point_type,
>            point_type,
>            unsigned int = 0,
>            Frame*       = 0
>        );
>
>        void createSimpleFrame(point_type cw, point_type ch, point_type w,
> point_type h)
>        {
>            createSimpleFrame(_name, cw, ch, w, h, 0, this);
>        }
>
>        void createSimpleFrameWithSingleTexture(
>            osg::Image* image,
>            point_type  w,
>            point_type  h
>        )
>        {
>            createSimpleFrameWithSingleTexture(_name, image, w, h, 0, this);
>        }
>
>        bool setWindow(Window*);
>
>        EmbeddedWindow* getEmbeddedWindow() { return
> dynamic_cast<EmbeddedWindow*>(getByRowCol(1, 1)); }
>
>        const EmbeddedWindow* getEmbeddedWindow() const { return
> dynamic_cast<const EmbeddedWindow*>(getByRowCol(1, 1)); }
>
>        Corner* getCorner(CornerType c) { return
> dynamic_cast<Corner*>(_getCorner(c)); }
>
>        const Corner* getCorner(CornerType c) const { return
> dynamic_cast<const Corner*>(_getCorner(c)); }
>
>        Border* getBorder(BorderType b) { return
> dynamic_cast<Border*>(_getBorder(b)); }
>
>        const Border* getBorder(BorderType b) const { return
> dynamic_cast<const Border*>(_getBorder(b)); }
>
>        // This method resizes the internal EmbeddedWindow object and then
> properly resizes
>        // the reset of the Frame based on the sizes of the Corners, Borders,
> etc.
>        bool resizeFrame(point_type, point_type);
>
>        unsigned int getFlags() const
>        {
>            return _flags;
>        }
>
>        void setFlags(unsigned int flags)
>        {
>            _flags = flags;
>        }
>
>        bool canResize() const
>        {
>            return (_flags & FRAME_RESIZE) != 0;
>        }
>
>        bool canMove() const
>        {
>            return (_flags & FRAME_MOVE) != 0;
>        }
>
>        bool canTexture() const
>        {
>            return (_flags & FRAME_TEXTURE) != 0;
>        }
>
>    protected:
>
>        Widget* _getCorner (CornerType) const;
>        Widget* _getBorder (BorderType) const;
>
>        unsigned int _flags;
> };
>
> }
>
> #endif
>
> // -*-c++-*- osgWidget - Code by: Jeremy Moles (cubicool) 2007-2008
>
> #include <osg/io_utils>
> #include <osgDB/ReadFile>
> #include <osgWidget/WindowManager>
> #include <osgWidget/Frame>
> #include <cassert>
>
> namespace osgWidget {
>
> std::string Frame::cornerTypeToString(CornerType c)
> {
>    if(c == CORNER_LOWER_LEFT) return "CornerLowerLeft";
>
>    else if(c == CORNER_LOWER_RIGHT) return "CornerLowerRight";
>
>    else if(c == CORNER_UPPER_RIGHT) return "CornerUpperRight";
>
>    else return "CornerUpperLeft";
> }
>
> std::string Frame::borderTypeToString(BorderType b)
> {
>    if(b == BORDER_LEFT) return "BorderLeft";
>
>    else if(b == BORDER_RIGHT) return "BorderRight";
>
>    else if(b == BORDER_TOP) return "BorderTop";
>
>    else return "BorderBottom";
> }
>
> Frame::Corner::Corner(CornerType corner, point_type width, point_type
> height):
> Widget  (cornerTypeToString(corner), width, height),
> _corner (corner)
> {
> }
>
> Frame::Corner::Corner(const Corner& corner, const osg::CopyOp& co):
> Widget  (corner, co),
> _corner (corner._corner)
> {
> }
>
> void Frame::Corner::parented(Window* window) {
>    Frame* parent = dynamic_cast<Frame*>(getParent());
>
>    if(!parent) return;
>
>    if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG);
> }
>
> bool Frame::Corner::mouseDrag(double x, double y, const WindowManager* wm)
> {
>    Frame* parent = dynamic_cast<Frame*>(getParent());
>
>    if(!parent || !parent->canResize()) return false;
>
>    if(_corner == CORNER_UPPER_LEFT) {
>        if(parent->resizeAdd(-x, y)) parent->addX(x);
>    }
>
>    else if(_corner == CORNER_UPPER_RIGHT) parent->resizeAdd(x, y);
>
>    else if(_corner == CORNER_LOWER_RIGHT) {
>        if(parent->resizeAdd(x, -y)) parent->addY(y);
>    }
>
>    else {
>        if(parent->resizeAdd(-x, -y)) parent->addOrigin(x, y);
>    }
>
>    parent->update();
>
>    return true;
> }
>
> Frame::Border::Border(BorderType border, point_type width, point_type
> height):
> Widget  (borderTypeToString(border), width, height),
> _border (border)
> {
>    setCanFill(true);
> }
>
> Frame::Border::Border(const Border& border, const osg::CopyOp& co):
> Widget  (border, co),
> _border (border._border)
> {
> }
>
> void Frame::Border::parented(Window* window) {
>    Frame* parent = dynamic_cast<Frame*>(getParent());
>
>    if(!parent) return;
>
>    if(parent->canResize()) setEventMask(EVENT_MASK_MOUSE_DRAG);
> }
>
> void Frame::Border::positioned()
> {
>    osg::Image* image = _image();
>
>    if(!image) return;
>
>    Frame* parent = dynamic_cast<Frame*>(getParent());
>
>    if(!parent || !parent->canTexture()) return;
>
>    point_type w = image->s() / 8.0f;
>    point_type h = getHeight();
>
>    if(_border == BORDER_LEFT) setTexCoordRegion(w * 3, 0.0f, w, h);
>
>    else if(_border == BORDER_RIGHT) setTexCoordRegion(w * 4, 0.0f, w, h);
>
>    else if(_border == BORDER_TOP) {
>        // TODO: Temporary; fix this.
>        point_type tx1 = (w * 2) / image->s();
>        point_type tx2 = w / image->s();
>        point_type tx3 = getWidth() / w;
>
>        setTexCoord(tx1, tx3,  LL);
>        setTexCoord(tx1, 0.0f, LR);
>        setTexCoord(tx2, 0.0f, UR);
>        setTexCoord(tx2, tx3,  UL);
>    }
>
>    else {
>        point_type tx1 = (w * 7) / image->s();
>        point_type tx2 = (w * 6) / image->s();
>        point_type tx3 = getWidth() / w;
>
>        setTexCoord(tx1, tx3,  LL);
>        setTexCoord(tx1, 0.0f, LR);
>        setTexCoord(tx2, 0.0f, UR);
>        setTexCoord(tx2, tx3,  UL);
>    }
> }
>
> bool Frame::Border::mouseDrag(double x, double y, const WindowManager* wm)
> {
>    Frame* parent = dynamic_cast<Frame*>(getParent());
>
>    if(!parent) return false;
>
>    if(_border == BORDER_TOP && parent->canMove()) parent->addOrigin(x, y);
>
>    else {
>        if(!parent->canResize()) return false;
>
>        if(_border == BORDER_LEFT) {
>            if(parent->resizeAdd(-x, 0.0f)) parent->addX(x);
>        }
>
>        else if(_border == BORDER_RIGHT) parent->resizeAdd(x, 0.0f);
>
>        else {
>            if(parent->resizeAdd(0.0f, -y)) parent->addY(y);
>        }
>    }
>
>    parent->update();
>
>    return true;
> }
>
> Frame::Frame(const std::string& name, unsigned int flags):
> Table  (name, 3, 3),
> _flags (flags)
> {
> }
>
> Frame::Frame(const Frame& frame, const osg::CopyOp& co):
> Table(frame, co)
> {
> }
>
> Widget* Frame::_getCorner(CornerType c) const
> {
>    return const_cast<Widget*>(getByName(cornerTypeToString(c)));
> }
>
> Widget* Frame::_getBorder(BorderType b) const
> {
>    return const_cast<Widget*>(getByName(borderTypeToString(b)));
> }
>
> bool Frame::setWindow(Window* window)
> {
>    if(!window) return false;
>
>    EmbeddedWindow* ew = getEmbeddedWindow();
>
>    // If it's the first time setting the Window...
>    // if(!ew || !ew->getWindow()) return addWidget(window->embed(), 1, 1);
>    if(!ew) return addWidget(window->embed(), 1, 1);
>
>    else return ew->setWindow(window);
> }
>
> Frame* Frame::createSimpleFrame(
>    const std::string& name,
>    point_type         cw,
>    point_type         ch,
>    point_type         w,
>    point_type         h,
>    unsigned int       flags,
>    Frame*             exFrame
> ) {
>    Frame* frame = 0;
>
>    // Use an "existing frame" if we have it (for example, if you've in
> inherited from
>    // Frame and want to use this stuff.
>    if(!exFrame) frame = new Frame(name, flags);
>
>    else frame = exFrame;
>
>    frame->addWidget(new Corner(CORNER_LOWER_LEFT,  cw, ch), 0, 0);
>    frame->addWidget(new Border(BORDER_BOTTOM,      w,  ch), 0, 1);
>    frame->addWidget(new Corner(CORNER_LOWER_RIGHT, cw, ch), 0, 2);
>    frame->addWidget(new Border(BORDER_LEFT,        cw, h),  1, 0);
>    frame->addWidget(new Border(BORDER_RIGHT,       cw, h),  1, 2);
>    frame->addWidget(new Corner(CORNER_UPPER_LEFT,  cw, ch), 2, 0);
>    frame->addWidget(new Border(BORDER_TOP,         w,  ch), 2, 1);
>    frame->addWidget(new Corner(CORNER_UPPER_RIGHT, cw, ch), 2, 2);
>
>    EmbeddedWindow* ew = new EmbeddedWindow(name, w, h);
>
>    ew->setCanFill(true);
>
>    frame->addWidget(ew, 1, 1);
>
>    return frame;
> }
>
> /*
> Frame* Frame::createSimpleFrameWithSingleTexture(
>    const std::string& name,
>    const std::string& texture,
>    point_type         tw,
>    point_type         th,
>    point_type         cw,
>    point_type         ch,
>    point_type         w,
>    point_type         h,
>    Frame*             exFrame
> ) {
>    Frame* frame = 0;
>
>    // The same as above...
>    if(!exFrame) frame = createSimpleFrame(name, cw, ch, w, h);
>
>    else frame = createSimpleFrame(name, cw, ch, w, h, exFrame);
>
>    for(unsigned int i = 0; i < 9; i++)
> frame->getObjects()[i]->setImage(texture);
>
>    frame->getByRowCol(0, 0)->setTexCoordRegion(0.0f, th - ch, cw, ch);
>    frame->getByRowCol(0, 1)->setTexCoordRegion(cw, th - ch, tw - (cw *
> 2.0f), ch);
>    frame->getByRowCol(0, 2)->setTexCoordRegion(tw - cw, th - ch, cw, ch);
>    frame->getByRowCol(1, 0)->setTexCoordRegion(0.0f, ch, cw, th - (ch *
> 2.0f));
>    frame->getByRowCol(1, 2)->setTexCoordRegion(tw - cw, ch, cw, th - (ch *
> 2.0f));
>    frame->getByRowCol(2, 0)->setTexCoordRegion(0.0f, 0.0f, cw, ch);
>    frame->getByRowCol(2, 1)->setTexCoordRegion(cw, 0.0f, tw - (cw * 2.0f),
> ch);
>    frame->getByRowCol(2, 2)->setTexCoordRegion(tw - cw, 0.0f, cw, ch);
>
>    frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw * 2.0f),
> th - (ch * 2.0f));
>
>    return frame;
> }
> */
>
> // Inspired by: http://www.wowwiki.com/EdgeFiles
> Frame* Frame::createSimpleFrameWithSingleTexture(
>    const std::string& name,
>    osg::Image*        image,
>    point_type         width,
>    point_type         height,
>    unsigned int       flags,
>    Frame*             exFrame
> ) {
>    Frame* frame = 0;
>
>    double w = width;
>    double h = height;
>
>    if (image)
>    {
>        w = image->s() / 8.0f;
>        h = image->t();
>    }
>
>    // The same as above...
>    if(!exFrame) frame = createSimpleFrame(name, w, h, width, height, flags);
>
>    else frame = createSimpleFrame(name, w, h, width, height, 0, exFrame);
>
>    if (image)
>    {
>
>        for(unsigned int i = 0; i < 9; i++)
> frame->getObjects()[i]->setImage(image);
>
>        XYCoord twh(w, h);
>
>        frame->getCorner(CORNER_UPPER_LEFT )->setTexCoordRegion(0.0f,  0.0f,
> twh);
>        frame->getBorder(BORDER_TOP        )->setTexCoordRegion(w,     0.0f,
> twh);
>        frame->getCorner(CORNER_UPPER_RIGHT)->setTexCoordRegion(w * 2, 0.0f,
> twh);
>        frame->getBorder(BORDER_LEFT       )->setTexCoordRegion(w * 3, 0.0f,
> twh);
>        frame->getBorder(BORDER_RIGHT      )->setTexCoordRegion(w * 4, 0.0f,
> twh);
>        frame->getCorner(CORNER_LOWER_LEFT )->setTexCoordRegion(w * 5, 0.0f,
> twh);
>        frame->getBorder(BORDER_BOTTOM     )->setTexCoordRegion(w * 6, 0.0f,
> twh);
>        frame->getCorner(CORNER_LOWER_RIGHT)->setTexCoordRegion(w * 7, 0.0f,
> twh);
>
>        // We set all of these to wrap vertically, but the REAL texture
> coordinates will
>        // be generated properly in the positioned() method.
>        frame->getByRowCol(0, 1)->setTexCoordWrapVertical();
>        frame->getByRowCol(1, 0)->setTexCoordWrapVertical();
>        frame->getByRowCol(1, 2)->setTexCoordWrapVertical();
>        frame->getByRowCol(2, 1)->setTexCoordWrapVertical();
>
>        // frame->getEmbeddedWindow()->setTexCoordRegion(cw, ch, tw - (cw *
> 2.0f), th - (ch * 2.0f));
>    }
>    else
>    {
>        osg::notify(osg::WARN) << "createSimpleFrameWithSingleTexture with a
> null image, the frame " << name << " will be use texture" << std::endl;
>    }
>
>    return frame;
> }
>
> bool Frame::resizeFrame(point_type w, point_type h) {
>    Border* left   = getBorder(BORDER_LEFT);
>    Border* right  = getBorder(BORDER_RIGHT);
>    Border* top    = getBorder(BORDER_TOP);
>    Border* bottom = getBorder(BORDER_BOTTOM);
>
>    if(!left || !right || !top || !bottom) return false;
>
>    return resize(
>        left->getWidth() + right->getWidth() + w,
>        top->getHeight() + bottom->getHeight() + h
>    );
> }
>
>
> osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme);
>
> Frame* Frame::createSimpleFrameFromTheme(
>    const std::string& name,
>    osg::Image*        image,
>    point_type         width,
>    point_type         height,
>    unsigned int       flags,
>    Frame*             exFrame
> ) {
>
>    osg::ref_ptr<osg::Image> natifImage =
> createNatifEdgeImageFromTheme(image);
>    Frame* frame;
>
>    frame = createSimpleFrameWithSingleTexture(name, natifImage.get(), width,
> height, flags, exFrame);
>
>    if (frame && image && natifImage.valid())
>    {
>        const unsigned int bpps = image->getPixelSizeInBits() / 8;
>        const unsigned int one_third_s = image->s()/3;
>        unsigned char* srcdata = (unsigned char*)image->data();
>        osg::Vec4 color(0,0,0,1);
>        for (unsigned int d = 0; d < bpps; d++)
>        {
>            color[d] = srcdata[one_third_s * image->s() * bpps +
> (one_third_s) * bpps + d] * 1.0/255.0;
>        }
>        frame->getEmbeddedWindow()->setColor(color);
>    }
>    return frame;
> }
>
>
>
>
>
>
>
> // (c) 2006-2008   Jean-Sébastien Guay
> // adapted by Cedric Pinson
>
> /** Implementation of copyImage. */
> template<typename T>
> void copyDataImpl(const osg::Image* source,
>                  const unsigned int x1, const unsigned int y1,
>                  const unsigned int x2, const unsigned int y2,
>                  osg::Image* destination,
>                  const unsigned int xd = 0, const unsigned int yd = 0)
> {
>    if ((unsigned int)destination->s() >= xd + (x2 - x1) &&
>        (unsigned int)destination->t() >= yd + (y2 - y1))
>    {
>        const unsigned int bpps =      source->getPixelSizeInBits() / (8 *
> sizeof(T));
>
>        T* srcdata = (T*)source->data();
>        T* dstdata = (T*)destination->data();
>
>        for (unsigned int y = 0; y < y2 - y1; ++y)
>        {
>            for (unsigned int x = 0; x < x2 - x1; ++x)
>            {
>                for (unsigned int d = 0; d < bpps; d++)
>                {
>                    T v = srcdata[(y + y1) * source->s() * bpps + (x + x1) *
> bpps + d];
>                    dstdata[(yd + y) * destination->s() * bpps + (xd + x) *
> bpps + d] = v;
>                }
>            }
>        }
>    }
>    else
>        assert(false && "copyDataImpl: Incorrect image dimensions.");
> }
>
> /** Copies a rectangle of corners (x1, y1), (x2, y2) from an image into
>    another image starting at position (xd, yd). No scaling is done, the
>    pixels are just copied, so the destination image must be at least
>    (xd + (x2 - x1)) by (yd + (y2 - y1)) pixels. */
> void copyData(const osg::Image* source,
>              const unsigned int x1, const unsigned int y1,
>              const unsigned int x2, const unsigned int y2,
>              osg::Image* destination,
>              const unsigned int xd, const unsigned int yd)
> {
>    if (source->getDataType() == destination->getDataType())
>    {
>        if (source->getDataType() == GL_UNSIGNED_BYTE)
>        {
>            copyDataImpl<unsigned char>(source, x1, y1, x2, y2,
>                                        destination, xd, yd);
>        }
>        else
>        {
>            assert(false && "copyData not implemented for this data type");
>        }
>    }
>    else
>    {
>        assert(false && "source and destination images must be of the same
> type.");
>        return;
>    }
> }
>
>
> /** Implementation of rotateImage. */
> template<typename T>
> osg::Image* rotateImageImpl(osg::Image* image)
> {
>    if (image->s() == image->t())
>    {
>        const unsigned int s = image->s();
>        const unsigned int bpp = image->getPixelSizeInBits() / (8 *
> sizeof(T));
>
>        osg::ref_ptr<osg::Image> destination  = new osg::Image;
>        destination->allocateImage(s, s, 1,
>                                   image->getPixelFormat(),
> image->getDataType(),
>                                   image->getPacking());
>
>  destination->setInternalTextureFormat(image->getInternalTextureFormat());
>
>        T* srcdata = (T*)image->data();
>        T* dstdata = (T*)destination->data();
>
>        for (unsigned int y = 0; y < s; ++y)
>        {
>            for (unsigned int x = 0; x < s; ++x)
>            {
>                for (unsigned int p = 0; p < bpp; p++)
>                    dstdata[y * s * bpp + x * bpp + p] = srcdata[x * s * bpp
> + y * bpp + p];
>            }
>        }
>
>        return destination.release();
>    }
>    else
>    {
>        assert(false && "rotateImageImpl: Image must be square.");
>        return 0;
>    }
> }
>
> /** Rotates an osg::Image by 90 degrees. Returns a new osg::Image, be sure
> to
>    store it in a ref_ptr so it will be freed correctly. */
> osg::Image* rotateImage(osg::Image* image)
> {
>    if (image->getDataType() == GL_UNSIGNED_BYTE)
>    {
>        return rotateImageImpl<unsigned char>(image);
>    }
>    else
>    {
>        assert(false && "rotateImage not implemented for this data type");
>        return 0;
>    }
> }
>
>
>
> // SOURCE
> //          +---+---+---+
> //          | 1 | 2 | 3 |
> //          +---+---+---+
> //          | 4 |   | 5 |
> //          +---+---+---+
> //          | 6 | 7 | 8 |
> //          +---+---+---+
>
>
> // FINAL
> //         +---+---+---+---+---+---+---+---+
> //         | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 |
> //         +---+---+---+---+---+---+---+---+
>
> //         1. Upper-Left corner.
> //         2. Top border (rotated 90 degrees CCW).
> //         3. Upper-Right corner.
> //         4. Left border.
> //         5. Right border.
> //         6. Bottom-Left corner.
> //         7. Bottom border (rotated 90 degrees CCW).
> //         8. Bottom-Right corner.
>
> osg::Image* createNatifEdgeImageFromTheme(osg::Image* theme)
> {
>    if (!theme) {
>        osg::notify(osg::WARN) << "can't create a natif edge image from null
> image theme as argument" << std::endl;
>        return 0;
>    }
>    osg::ref_ptr<osg::Image> final = new osg::Image;
>    const int s = theme->s();
>    const int t = theme->t();
>    const GLenum pixelFormat   = theme->getPixelFormat();
>    const GLenum dataType      = theme->getDataType();
>    const GLint internalFormat = theme->getInternalTextureFormat();
>    unsigned int packing       = theme->getPacking();
>
>    if (s != t)
>    {
>        osg::notify(osg::WARN) << "width and height are different, bad format
> theme image " << theme->getFileName() << std::endl;
>        return 0;
>    }
>
>    // check size
>    int ceilvalue = static_cast<int>(ceil(s * 1.0 / 3));
>    int intvalue = s/3;
>    if (intvalue != ceilvalue)
>    {
>        osg::notify(osg::WARN) << "the size of theme file " <<
> theme->getFileName() << " can not be divided by 3, check the documentation
> about theme format" << std::endl;
>        return 0;
>    }
>
>    const unsigned int one_third_s = s/3;
>    const unsigned int one_third_t = t/3;
>
>    final->allocateImage(8 * one_third_s , one_third_t, 1, pixelFormat,
> dataType, packing);
>    final->setInternalTextureFormat(internalFormat);
>
>    // copy 1 (6 in source)
>    copyData(theme, 0, 2 * one_third_s, one_third_s, 3 * one_third_s,
> final.get(), 0, 0);
>
>    // rotate and copy 2
>    osg::ref_ptr<osg::Image> rotateandcopy2  = new osg::Image;
>    rotateandcopy2->allocateImage(one_third_s , one_third_t, 1, pixelFormat,
> dataType, packing);
>    rotateandcopy2->setInternalTextureFormat(internalFormat);
>    copyData(theme, one_third_s, 0, 2 * one_third_s , one_third_s,
> rotateandcopy2.get(), 0, 0);
>    rotateandcopy2 = rotateImage(rotateandcopy2.get());
>    rotateandcopy2->flipHorizontal();
>    copyData(rotateandcopy2.get(), 0, 0, one_third_s , one_third_s,
> final.get(), 6*one_third_s, 0);
>
>    // copy 3 (8 in source)
>    copyData(theme, 2*one_third_s , 2 *one_third_s, 3*one_third_s , 3 *
> one_third_s, final.get(), 2 * one_third_s, 0);
>
>    // copy 4
>    copyData(theme, 0, one_third_s, one_third_s , 2 * one_third_s,
> final.get(), 3 * one_third_s, 0);
>
>    // copy 5
>    copyData(theme, 2*one_third_s , one_third_s, 3 * one_third_s , 2 *
> one_third_s, final.get(), 4 * one_third_s, 0);
>
>    // copy 6 (1 in source)
>    copyData(theme, 0 , 0, one_third_s, one_third_s, final.get(), 5 *
> one_third_s, 0);
>
>    // rotate and copy 7
>    osg::ref_ptr<osg::Image> rotateandcopy7  = new osg::Image;
>    rotateandcopy7->allocateImage(one_third_s , one_third_t, 1, pixelFormat,
> dataType, packing);
>    rotateandcopy7->setInternalTextureFormat(internalFormat);
>    copyData(theme, one_third_s, 2*one_third_s, 2 * one_third_s , 3 *
> one_third_s, rotateandcopy7.get(), 0, 0);
>    rotateandcopy7 = rotateImage(rotateandcopy7.get());
>    rotateandcopy7->flipHorizontal();
>    copyData(rotateandcopy7.get(), 0, 0, one_third_s , one_third_s,
> final.get(), one_third_s, 0);
>
>    // copy 8 (3 in source)
>    copyData(theme, 2 * one_third_s, 0, 3 * one_third_s , one_third_s ,
> final.get(), 7 * one_third_s, 0);
>
>    return final.release();
> }
>
> }
>
> _______________________________________________
> osg-submissions mailing list
> [email protected]
> http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org
>
>
_______________________________________________
osg-submissions mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-submissions-openscenegraph.org

Reply via email to