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

Reply via email to