#include <osg/RenderInfo>
#include <osg/Vec3>
#include <osg/Vec4>
+#include <osg/buffered_value>
#include <simgear/math/SGMath.hxx>
#include <simgear/math/sg_random.h>
{
public:
- const static unsigned int CLOUD_HEIGHT = 10;
- 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;
+ const static unsigned int USR_ATTR_3 = 12;
+
CloudShaderGeometry()
{
setUseDisplayList(false);
- skip_info = new SkipInfo();
}
- CloudShaderGeometry(int vx, int vy, float width, float height) :
- varieties_x(vx), varieties_y(vy)
+ CloudShaderGeometry(int vx, int vy, float width, float height, float ts, float ms, float bs, float shade, float ch, float zsc) :
+ varieties_x(vx), varieties_y(vy), top_factor(ts), middle_factor(ms), bottom_factor(bs), shade_factor(shade), cloud_height(ch), zscale(zsc)
{
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) :
- position(p), texture_index_x(tx), texture_index_y(ty), width(w), height(h), shade(s), cloud_height(ch)
+ CloudSprite(const SGVec3f& p, int tx, int ty, float w, float h) :
+ position(p), texture_index_x(tx), texture_index_y(ty), width(w), height(h)
{ }
SGVec3f position;
int texture_index_y;
float width;
float height;
- float shade;
- 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)); }
+ void insert(SGVec3f& p, int tx, int ty, float w, float h)
+ { insert(CloudSprite(p, tx, ty, w, h)); }
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 cull);
+
osg::ref_ptr<osg::Drawable> _geometry;
int varieties_x;
int varieties_y;
-
+ float top_factor;
+ float middle_factor;
+ float bottom_factor;
+ float shade_factor;
+ float cloud_height;
+ float zscale;
+
// 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 (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;
+ }
};
}