#include <osg/RenderInfo>
#include <osg/Vec3>
#include <osg/Vec4>
+#include <osg/buffered_value>
#include <simgear/math/SGMath.hxx>
#include <simgear/math/sg_random.h>
CloudShaderGeometry()
{
setUseDisplayList(false);
- skip_info = new SkipInfo();
}
CloudShaderGeometry(int vx, int vy, float width, float height) :
varieties_x(vx), varieties_y(vy)
{
setUseDisplayList(false);
- skip_info = new SkipInfo();
float x = width/2.0f;
float z = height/2.0f;
_bbox.expandBy(-x, -x, -z);
META_Object(flightgear, CloudShaderGeometry);
- struct SkipInfo {
- SkipInfo() : skip_count(0), skip_limit(1) {}
- int skip_count;
- int skip_limit;
- };
-
- SkipInfo* skip_info;
-
struct CloudSprite {
- CloudSprite(SGVec3f& p, int tx, int ty, float w, float h, float s, float ch) :
+ 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)
{ }
float cloud_height;
};
- typedef std::vector<CloudSprite*> CloudSpriteList;
+ typedef std::vector<CloudSprite> CloudSpriteList;
CloudSpriteList _cloudsprites;
- void insert(CloudSprite* t)
+ void insert(const CloudSprite& t)
{ _cloudsprites.push_back(t); }
void insert(SGVec3f& p, int tx, int ty, float w, float h, float s, float ch)
- { insert(new CloudSprite(p, tx, ty, w, h, s, ch)); }
+ { insert(CloudSprite(p, tx, ty, w, h, s, ch)); }
unsigned getNumCloudSprite() const
{ return _cloudsprites.size(); }
- CloudSprite* getCloudSprite(unsigned i) const
+ CloudSprite& getCloudSprite(unsigned i)
{ return _cloudsprites[i]; }
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
_geometry = geometry;
}
- void addSprite(SGVec3f& p, int tx, int ty, float w, float h, float s, float cull, float cloud_height)
- {
- // Only add the sprite if it is further than the cull distance to all other sprites
- for (CloudShaderGeometry::CloudSpriteList::iterator iter = _cloudsprites.begin();
- iter != _cloudsprites.end();
- ++iter)
- {
- if (distSqr((*iter)->position, p) < cull)
- {
- // Too close - cull it
- return;
- }
- }
-
- _cloudsprites.push_back(new CloudSprite(p, tx, ty, w, h, s, cloud_height));
- }
-
+ 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;
// Bounding box extents.
osg::BoundingBox _bbox;
- protected:
+ 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() {
- delete skip_info;
- for (unsigned int i = 0; i < _cloudsprites.size(); i++)
- {
- delete _cloudsprites[i];
- }
- }
+ virtual ~CloudShaderGeometry()
+ {
+ for (unsigned int i = 0; i < _sortData.size(); ++i)
+ delete _sortData[i].spriteIdx;
+ }
};
}