]> git.mxchange.org Git - simgear.git/blobdiff - simgear/scene/sky/CloudShaderGeometry.hxx
Merge branch 'ehofman/sound'
[simgear.git] / simgear / scene / sky / CloudShaderGeometry.hxx
index 1f0dd10d413b27aae12356b6a78e6084db43c11e..cd00da8de7139c8c252563b66e67cd00e83b3f7a 100755 (executable)
 #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
@@ -42,21 +44,22 @@ class CloudShaderGeometry : public osg::Drawable
 {
     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.*/
@@ -66,8 +69,9 @@ class CloudShaderGeometry : public osg::Drawable
         META_Object(flightgear, CloudShaderGeometry);
         
         struct CloudSprite {
-            CloudSprite(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;
@@ -76,58 +80,68 @@ class CloudShaderGeometry : public osg::Drawable
                     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)
-        { insert(new 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(); }
-        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)
+        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));
+            _geometry = geometry;
         }
         
+    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;
+    }
 };
 
 }