#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 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;
CloudShaderGeometry()
{
setUseDisplayList(false);
- skip_info = new SkipInfo();
}
- CloudShaderGeometry(int vx, int vy) :
+ 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);
+ _bbox.expandBy(x, x, z);
}
/** Copy constructor using CopyOp to manage deep vs shallow copy.*/
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)
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]; }
- CloudSpriteList _cloudsprites;
-
- typedef std::vector<osg::Vec4> PositionSizeList;
virtual void drawImplementation(osg::RenderInfo& renderInfo) const;
- virtual osg::BoundingBox computeBound() const;
-
-
- void setGeometry(osg::Drawable* geometry)
+ virtual osg::BoundingBox computeBound() const
{
- _geometry = geometry;
+ return _bbox;
}
- void addSprite(SGVec3f& p, int tx, int ty, float w, float h, float s, float cull, float cloud_height)
+ void setGeometry(osg::Drawable* geometry)
{
- // 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));
+ _geometry = geometry;
}
+ void addSprite(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:
+ // 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() {
- 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;
+ }
};
}