CanvasImage: support for http protocol.
- Download and display images.
This commit is contained in:
@@ -23,6 +23,7 @@
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
namespace HTTP { class Client; }
|
||||
namespace canvas
|
||||
{
|
||||
|
||||
@@ -35,6 +36,7 @@ namespace canvas
|
||||
virtual void addCamera(osg::Camera* camera) const = 0;
|
||||
virtual void removeCamera(osg::Camera* camera) const = 0;
|
||||
virtual osg::Image* getImage(const std::string& path) const = 0;
|
||||
virtual HTTP::Client* getHTTPClient() const = 0;
|
||||
};
|
||||
|
||||
} // namespace canvas
|
||||
|
||||
@@ -25,12 +25,12 @@
|
||||
#include <simgear/scene/util/OsgMath.hxx>
|
||||
#include <simgear/scene/util/parse_color.hxx>
|
||||
#include <simgear/misc/sg_path.hxx>
|
||||
#include <simgear/io/HTTPClient.hxx>
|
||||
|
||||
#include <osg/Array>
|
||||
#include <osg/Geometry>
|
||||
#include <osg/PrimitiveSet>
|
||||
|
||||
#include <boost/algorithm/string/predicate.hpp>
|
||||
#include <osgDB/Registry>
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
@@ -522,18 +522,29 @@ namespace canvas
|
||||
}
|
||||
else if( name == "file" )
|
||||
{
|
||||
static const std::string CANVAS_PROTOCOL = "canvas://";
|
||||
const std::string& path = child->getStringValue();
|
||||
static const std::string PROTOCOL_SEP = "://";
|
||||
|
||||
CanvasPtr canvas = _canvas.lock();
|
||||
if( !canvas )
|
||||
std::string url = child->getStringValue(),
|
||||
protocol, path;
|
||||
|
||||
size_t sep_pos = url.find(PROTOCOL_SEP);
|
||||
if( sep_pos != std::string::npos )
|
||||
{
|
||||
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No canvas available");
|
||||
return;
|
||||
protocol = url.substr(0, sep_pos);
|
||||
path = url.substr(sep_pos + PROTOCOL_SEP.length());
|
||||
}
|
||||
else
|
||||
path = url;
|
||||
|
||||
if( boost::starts_with(path, CANVAS_PROTOCOL) )
|
||||
if( protocol == "canvas" )
|
||||
{
|
||||
CanvasPtr canvas = _canvas.lock();
|
||||
if( !canvas )
|
||||
{
|
||||
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No canvas available");
|
||||
return;
|
||||
}
|
||||
|
||||
CanvasMgr* canvas_mgr = canvas->getCanvasMgr();
|
||||
if( !canvas_mgr )
|
||||
{
|
||||
@@ -544,7 +555,7 @@ namespace canvas
|
||||
const SGPropertyNode* canvas_node =
|
||||
canvas_mgr->getPropertyRoot()
|
||||
->getParent()
|
||||
->getNode( path.substr(CANVAS_PROTOCOL.size()) );
|
||||
->getNode( path );
|
||||
if( !canvas_node )
|
||||
{
|
||||
SG_LOG(SG_GL, SG_ALERT, "canvas::Image: No such canvas: " << path);
|
||||
@@ -562,6 +573,14 @@ namespace canvas
|
||||
|
||||
setSrcCanvas(src_canvas);
|
||||
}
|
||||
else if( protocol == "http" || protocol == "https" )
|
||||
// TODO check https
|
||||
{
|
||||
Canvas::getSystemAdapter()
|
||||
->getHTTPClient()
|
||||
->load(url)
|
||||
->done(this, &Image::handleImageLoadDone);
|
||||
}
|
||||
else
|
||||
{
|
||||
setImage( Canvas::getSystemAdapter()->getImage(path) );
|
||||
@@ -637,5 +656,37 @@ namespace canvas
|
||||
(*_texCoords)[i + 3].set(tl.x(), br.y());
|
||||
}
|
||||
|
||||
//----------------------------------------------------------------------------
|
||||
void Image::handleImageLoadDone(HTTP::Request* req)
|
||||
{
|
||||
if( req->responseCode() != 200 )
|
||||
{
|
||||
SG_LOG( SG_GL,
|
||||
SG_WARN,
|
||||
"canvas::Image: failed to download '" << req->url() << "': "
|
||||
<< req->responseReason() );
|
||||
return;
|
||||
}
|
||||
|
||||
std::string ext = SGPath(req->path()).extension();
|
||||
SG_LOG(SG_GL, SG_INFO, "canvas::Image: received " << req->url());
|
||||
|
||||
osgDB::ReaderWriter* rw =
|
||||
osgDB::Registry::instance()->getReaderWriterForExtension(ext);
|
||||
|
||||
std::istringstream img_data(
|
||||
static_cast<HTTP::MemoryRequest*>(req)->responseBody()
|
||||
);
|
||||
|
||||
osgDB::ReaderWriter::ReadResult result = rw->readImage(img_data);
|
||||
if( result.success() )
|
||||
setImage( result.takeImage() );
|
||||
else
|
||||
SG_LOG( SG_GL,
|
||||
SG_WARN,
|
||||
"canvas::Image: failed to read image '" << req->url() << "': "
|
||||
<< result.message() );
|
||||
}
|
||||
|
||||
} // namespace canvas
|
||||
} // namespace simgear
|
||||
|
||||
@@ -27,6 +27,7 @@
|
||||
|
||||
namespace simgear
|
||||
{
|
||||
namespace HTTP { class Request; }
|
||||
namespace canvas
|
||||
{
|
||||
|
||||
@@ -103,6 +104,8 @@ namespace canvas
|
||||
void setQuad(size_t index, const SGVec2f& tl, const SGVec2f& br);
|
||||
void setQuadUV(size_t index, const SGVec2f& tl, const SGVec2f& br);
|
||||
|
||||
void handleImageLoadDone(HTTP::Request*);
|
||||
|
||||
osg::ref_ptr<osg::Texture2D> _texture;
|
||||
// TODO optionally forward events to canvas
|
||||
CanvasWeakPtr _src_canvas;
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
#include <simgear/structure/SGSharedPtr.hxx>
|
||||
#include <simgear/math/sg_types.hxx>
|
||||
|
||||
#include <boost/bind.hpp>
|
||||
#include <boost/function.hpp>
|
||||
|
||||
class SGPropertyNode;
|
||||
@@ -53,6 +54,12 @@ public:
|
||||
*/
|
||||
Request* done(const Callback& cb);
|
||||
|
||||
template<class C>
|
||||
Request* done(C* instance, void (C::*mem_func)(Request*))
|
||||
{
|
||||
return done(boost::bind(mem_func, instance, _1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the handler to be called when the request completes or aborts with an
|
||||
* error.
|
||||
@@ -62,6 +69,12 @@ public:
|
||||
*/
|
||||
Request* fail(const Callback& cb);
|
||||
|
||||
template<class C>
|
||||
Request* fail(C* instance, void (C::*mem_func)(Request*))
|
||||
{
|
||||
return fail(boost::bind(mem_func, instance, _1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the handler to be called when the request either successfully
|
||||
* completes or fails.
|
||||
@@ -71,6 +84,12 @@ public:
|
||||
*/
|
||||
Request* always(const Callback& cb);
|
||||
|
||||
template<class C>
|
||||
Request* always(C* instance, void (C::*mem_func)(Request*))
|
||||
{
|
||||
return always(boost::bind(mem_func, instance, _1));
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the data for the body of the request. The request is automatically
|
||||
* send using the POST method.
|
||||
|
||||
Reference in New Issue
Block a user