#include <osg/RenderInfo>
#include <osg/Vec3>
#include <osg/Vec4>
+#include <osg/buffered_value>
#include <simgear/math/SGMath.hxx>
+#include <simgear/math/sg_random.h>
namespace simgear
{
public:
- const static unsigned int TEXTURE_INDEX_X = 11;
- const static unsigned int TEXTURE_INDEX_Y = 12;
- const static unsigned int WIDTH = 13;
- const static unsigned int HEIGHT = 14;
- const static unsigned int SHADE = 15;
+ const static unsigned int USR_ATTR_1 = 10;
+ const static unsigned int USR_ATTR_2 = 11;
CloudShaderGeometry()
{
setUseDisplayList(false);
}
- CloudShaderGeometry(int vx, int vy) :
+ CloudShaderGeometry(int vx, int vy, float width, float height) :
varieties_x(vx), varieties_y(vy)
{
setUseDisplayList(false);
+ float x = width/2.0f;
+ float z = height/2.0f;
+ _bbox.expandBy(-x, -x, -z);
+ _bbox.expandBy(x, x, z);
}
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
META_Object(flightgear, CloudShaderGeometry);
struct CloudSprite {
- CloudSprite(const SGVec3f& p, int tx, int ty, float w, float h, float s) :
- position(p), texture_index_x(tx), texture_index_y(ty), width(w), height(h), shade(s)
+ CloudSprite(const SGVec3f& p, int tx, int ty, float w, float h,
+ float s, float ch) :
+ position(p), texture_index_x(tx), texture_index_y(ty), width(w), height(h), shade(s), cloud_height(ch)
{ }
SGVec3f position;
float width;
float height;
float shade;
+ float cloud_height;
};
typedef std::vector<CloudSprite> CloudSpriteList;
+ CloudSpriteList _cloudsprites;
void insert(const CloudSprite& t)
{ _cloudsprites.push_back(t); }
- void insert(const SGVec3f& p, int tx, int ty, float w, float h, float s)
- { insert(CloudSprite(p, tx, ty, w, h, s)); }
+ void insert(SGVec3f& p, int tx, int ty, float w, float h, float s, float ch)
+ { insert(CloudSprite(p, tx, ty, w, h, s, ch)); }
unsigned getNumCloudSprite() const
{ return _cloudsprites.size(); }
- const CloudSprite& getCloudSprite(unsigned i) const
+ CloudSprite& getCloudSprite(unsigned i)
{ return _cloudsprites[i]; }
- CloudSpriteList _cloudsprites;
-
- typedef std::vector<osg::Vec4> PositionSizeList;
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
- virtual osg::BoundingBox computeBound() const;
-
+ virtual osg::BoundingBox computeBound() const
+ {
+ return _bbox;
+ }
void setGeometry(osg::Drawable* geometry)
{
_geometry = geometry;
}
- void addSprite(const SGVec3f& p, int tx, int ty, float w, float h, float s, float cull)
- {
- // Only add the sprite if it is further than the cull distance to all other sprites
- for (CloudShaderGeometry::CloudSpriteList::const_iterator iter = _cloudsprites.begin();
- iter != _cloudsprites.end();
- ++iter)
- {
- if (distSqr(iter->position, p) < cull)
- {
- // Too close - cull it
- return;
- }
- }
-
- _cloudsprites.push_back(CloudSprite(p, tx, ty, w, h, s));
- }
-
+ void addSprite(const SGVec3f& p, int tx, int ty, float w, float h,
+ float s, float cull, float cloud_height);
+
osg::ref_ptr<osg::Drawable> _geometry;
int varieties_x;
int varieties_y;
-
- protected:
-
- virtual ~CloudShaderGeometry() {}
+ // Bounding box extents.
+ osg::BoundingBox _bbox;
+
+ struct SortData
+ {
+ struct SortItem
+ {
+ SortItem(size_t idx_, float depth_) : idx(idx_), depth(depth_) {}
+ SortItem() : idx(0), depth(0.0f) {}
+ size_t idx;
+ float depth;
+ };
+ SortData() : frameSorted(0), skip_limit(1), spriteIdx(0) {}
+ int frameSorted;
+ int skip_limit;
+ // This will be sorted by Z distance
+ typedef std::vector<SortItem> SortItemList;
+ SortItemList* spriteIdx;
+ };
+protected:
+ mutable osg::buffered_object<SortData> _sortData;
+
+ virtual ~CloudShaderGeometry()
+ {
+ for (unsigned int i = 0; i < _sortData.size(); ++i)
+ delete _sortData[i].spriteIdx;
+ }
};
}