DYT/Tool/OpenSceneGraph-3.6.5/include/osgEarth/ImageLayer

347 lines
12 KiB
Plaintext
Raw Normal View History

2024-12-24 23:49:36 +00:00
/* -*-c++-*- */
/* osgEarth - Geospatial SDK for OpenSceneGraph
* Copyright 2020 Pelican Mapping
* http://osgearth.org
*
* osgEarth is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program 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 Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program. If not, see <http://www.gnu.org/licenses/>
*/
#pragma once
#include <osgEarth/Common>
#include <osgEarth/Config>
#include <osgEarth/ColorFilter>
#include <osgEarth/TileLayer>
#include <osgEarth/URI>
#include <osgEarth/Threading>
#include <osg/Texture2D>
namespace osgEarth
{
class Profile;
}
namespace osgEarth
{
/**
* Texture paired with a scale/bias matrix defining a sub-window.
*/
class OSGEARTH_EXPORT TextureWindow
{
public:
//! Empty/invalid texture window
TextureWindow() : _texture(0L) { }
//! Construct a texture window
TextureWindow(osg::Texture* tex, const osg::Matrix& scalebias) : _texture(tex), _matrix(scalebias) { }
//! Texture
osg::Texture* getTexture() const { return _texture.get(); }
//! Scale bias matrix defining subwindow
const osg::Matrixf& getMatrix() const { return _matrix; }
//! Is it valid?
bool valid() const { return _texture.valid(); }
protected:
osg::ref_ptr<osg::Texture> _texture;
osg::Matrixf _matrix;
};
/**
* A map terrain layer containing bitmap image data.
*/
class OSGEARTH_EXPORT ImageLayer : public TileLayer
{
public: // Serialization
class OSGEARTH_EXPORT Options : public TileLayer::Options {
public:
META_LayerOptions(osgEarth, Options, TileLayer::Options);
OE_OPTION(URI, noDataImageFilename);
OE_OPTION(osg::Vec4ub, transparentColor, osg::Vec4ub(0, 0, 0, 0));
OE_OPTION(ColorFilterChain, colorFilters);
OE_OPTION(osg::Texture::FilterMode, minFilter, osg::Texture::LINEAR_MIPMAP_LINEAR);
OE_OPTION(osg::Texture::FilterMode, magFilter, osg::Texture::LINEAR);
OE_OPTION(std::string, textureCompression);
OE_OPTION(double, edgeBufferRatio, 0.0);
OE_OPTION(unsigned, reprojectedTileSize, 256u);
OE_OPTION(Distance, altitude);
OE_OPTION(bool, coverage, false);
OE_OPTION(bool, acceptDraping, false);
OE_OPTION(bool, async, false);
OE_OPTION(bool, shared, false);
OE_OPTION(std::string, shareTexUniformName);
OE_OPTION(std::string, shareTexMatUniformName);
virtual Config getConfig() const;
private:
void fromConfig(const Config& conf);
};
public:
META_Layer_Abstract(osgEarth, ImageLayer, Options, TileLayer);
//! Layer callbacks
class OSGEARTH_EXPORT Callback : public osg::Referenced
{
public:
//! Called when a new data is created. This callback fires
//! before the data is cached, and does NOT fire if the data
//! was read from a cache.
//! NOTE: This may be invoked from a worker thread. Use caution.
virtual void onCreate(const TileKey&, GeoImage&) { }
};
public:
//! Convenience function to create an ImageLayer from a ConfigOptions.
static ImageLayer* create(const ConfigOptions& conf);
//! @deprecated
//! Adds a color filter to the filter chain.
void addColorFilter(ColorFilter* filter);
//! @deprecated
//! Removes a color filter from the filter chain
void removeColorFilter(ColorFilter* filter);
//! @deprecated
//! Accesses the color filter chain
const ColorFilterChain& getColorFilters() const;
//! Sets the altitude
void setAltitude(const Distance& value);
const Distance& getAltitude() const;
//! Sets whether this layer should allow draped overlays
//! to render on it. This is most applicable to layers with a
//! non-zero altitude (setAltitude). Default is true.
void setAcceptDraping(bool value);
bool getAcceptDraping() const;
//! Marks this layer for asynchronous loading.
//! Usually all layers participating in a tile must load before the
//! tile is displayed. This flag defers the current layer so it can
//! load asynchronously and display when it is available. This can
//! help keep a slow-loading layer from blocking the rest of the tile
//! from displaying. The trade-off is possible visual artifacts
//! (flashing, no mipmaps/compression) when the new data appears.
void setAsyncLoading(bool value);
bool getAsyncLoading() const;
//! Whether this layer is marked for render sharing.
//! Only set this before opening the layer or adding it to a map.
void setShared(bool value);
bool getShared() const;
bool isShared() const { return getShared(); }
//! Whether this layer represents coverage data that should not be subject
//! to color-space filtering, interpolation, or compression.
//! Only set this before opening the layer or adding it to a map.
void setCoverage(bool value);
bool getCoverage() const;
bool isCoverage() const { return getCoverage(); }
//! When isShared() == true, this will return the name of the uniform holding the
//! image's texture.
void setSharedTextureUniformName(const std::string& value);
const std::string& getSharedTextureUniformName() const;
//! When isShared() == true, this will return the name of the uniform holding the
//! image's texture matrix.
void setSharedTextureMatrixUniformName(const std::string& value);
const std::string& getSharedTextureMatrixUniformName() const;
//! When isShared() == true, the engine will call this function to bind the
//! shared layer to a texture image unit.
optional<int>& sharedImageUnit() { return _shareImageUnit; }
const optional<int>& sharedImageUnit() const { return _shareImageUnit; }
osg::Image* getEmptyImage() const { return _emptyImage.get(); }
public: // methods
//! Creates an image for the given tile key.
//! @param key TileKey for which to create an image
//! @param progress Optional progress/cancelation callback
GeoImage createImage(const TileKey& key);
//! Creates an image for the given tile key.
//! @param key TileKey for which to create an image
//! @param progress Optional progress/cancelation callback
GeoImage createImage(const TileKey& key, ProgressCallback* progress);
//! Stores an image in this layer (if writing is enabled).
//! Returns a status value indicating whether the store succeeded.
Status writeImage(const TileKey& key, const osg::Image* image, ProgressCallback* progress = 0L);
//! Returns the compression method prefered by this layer
//! that you can pass to ImageUtils::compressImage.
const std::string getCompressionMethod() const;
//! Install a user callback
void addCallback(Callback* callback);
//! Remove a user callback
void removeCallback(Callback* callback);
//! Add a post-processing layer
void addPostLayer(Layer* layer);
public: // Texture support
//! Whether to use createTexture to create data for this layer
//! instead of createImage and a TileSource driver
bool useCreateTexture() const { return _useCreateTexture; }
//! Override this method to create the texture when useCreateTexture is true
virtual TextureWindow createTexture(const TileKey& key, ProgressCallback* progress) const
{
return TextureWindow();
}
//! Subclass overrides this to generate image data for the key.
//! The key will always be in the same profile as the layer.
virtual GeoImage createImageImplementation(const TileKey&, ProgressCallback* progress) const
{
return GeoImage::INVALID;
}
protected:
//! Subclass can override this to write data for a tile key.
virtual Status writeImageImplementation(const TileKey&, const osg::Image*, ProgressCallback*) const;
//! Modify the bbox if an altitude is set (for culling)
virtual void modifyTileBoundingBox(const TileKey& key, osg::BoundingBox& box) const;
//! Post processing image creation entry points
GeoImage createImage(
const GeoImage& canvas,
const TileKey& key,
ProgressCallback* progress);
//! Override to write an image over top of an existing image
virtual GeoImage createImageImplementation(
const GeoImage& canvas,
const TileKey& key,
ProgressCallback* progress) const {
return canvas;
}
//! Override to do something to an image before returning
//! it from createImage (including a GeoImage read from the cache)
virtual void postCreateImageImplementation(
GeoImage& createdImage,
const TileKey& key,
ProgressCallback* progress) const { }
protected: // Layer
virtual void init() override;
//! Open the layer for reading.
virtual Status openImplementation() override;
/** dtor */
virtual ~ImageLayer() { }
//! Configure the layer to create textures via createTexture instead of
//! using a createImage driver
void setUseCreateTexture();
//! Apply a post-processing layers to the image
virtual GeoImage applyPostLayer(
const GeoImage& image,
const TileKey& key,
Layer* postLayer,
ProgressCallback* progress) const;
osg::ref_ptr<osg::Image> _emptyImage;
private:
// Creates an image that's in the same profile as the provided key.
GeoImage createImageInKeyProfile(
const TileKey& key,
ProgressCallback* progress);
// Fetches multiple images from the TileSource; mosaics/reprojects/crops as necessary, and
// returns a single tile. This is called by createImageFromTileSource() if the key profile
// doesn't match the layer profile.
GeoImage assembleImage(
const TileKey& key,
ProgressCallback* progress);
// Creates an image that enhances the previous LOD's image
// using a fractal algorithm.
GeoImage createFractalUpsampledImage(
const TileKey& key,
ProgressCallback* p);
optional<int> _shareImageUnit;
bool _useCreateTexture;
void invoke_onCreate(const TileKey&, GeoImage&);
typedef std::vector< osg::ref_ptr<Callback> > Callbacks;
Threading::Mutexed<Callbacks> _callbacks;
Mutexed<std::vector<osg::ref_ptr<Layer>>> _postLayers;
Gate<TileKey> _sentry;
osg::ref_ptr<osg::Image> _nodataImage;
};
typedef std::vector< osg::ref_ptr<ImageLayer> > ImageLayerVector;
/**
* Texture that loads its data asynchronously
*/
class OSGEARTH_EXPORT FutureTexture
{
public:
virtual bool doneLoading() { update(); return _resolved; }
virtual bool succeeded() { update(); return _resolved && !_failed; }
virtual bool failed() { update(); return _resolved && _failed; }
protected:
FutureTexture() : _resolved(false), _failed(false) { }
bool _resolved, _failed;
virtual void update() = 0;
};
class OSGEARTH_EXPORT FutureTexture2D :
public osg::Texture2D,
public FutureTexture
{
public:
FutureTexture2D(
ImageLayer* layer,
const TileKey& key);
protected:
virtual ~FutureTexture2D() { }
void update() override;
private:
TileKey _key;
osg::ref_ptr<ImageLayer> _layer;
mutable Future<GeoImage> _result;
void dispatch() const;
};
} // namespace osgEarth
OSGEARTH_SPECIALIZE_CONFIG(osgEarth::ImageLayer::Options);