]> git.mxchange.org Git - simgear.git/commitdiff
Harald Johnson:
authorehofman <ehofman>
Tue, 26 Apr 2005 08:30:38 +0000 (08:30 +0000)
committerehofman <ehofman>
Tue, 26 Apr 2005 08:30:38 +0000 (08:30 +0000)
Changes
=======

- corrected some strange behavior when playing with the render dialog options
- the density slider is now working : if you are fps limited and still want to see clouds in
  the distance you should play with that
- added the choice for texture resolution, its more comprehensible now (before it was
  wrongly allways choosing 64x64 textures)
- changed the initial texture size : you now have 64 texture of 64x64, this uses 1Mo of
  texture memory (before it was 20 texture of  256x256, that took more memory and there was
  not enought impostors)
- sun vector is now right so the lighting is a bit better
- removed useless sort and light computations for impostors, this should save a lot of cpu
- blending of distant cloud is more accurate now
- clouds are now positioned correctly, they don't try to escape you anymore
- no more red/white boxes around cloud
- textures are now filtered (no more big pixels)

known bugs
==========

- distant objects are seen in front of clouds

simgear/environment/visual_enviro.cxx
simgear/environment/visual_enviro.hxx
simgear/scene/sky/bbcache.cxx
simgear/scene/sky/cloudfield.cxx
simgear/scene/sky/cloudfield.hxx
simgear/scene/sky/newcloud.cxx

index 0fdeae26fbea2dede1f580295ac0aa395b8d5cb5..ebe8f85549c625ac4d09822d7fd4d22a33ba0ccd 100644 (file)
 
 SGEnviro sgEnviro;
 
-SGEnviro::SGEnviro(void) {
+SGEnviro::SGEnviro(void) :
+       view_in_cloud(false),
+       precipitation_enable_state(false),
+       precipitation_density(100.0)
+
+{
 }
 
 SGEnviro::~SGEnviro(void) {
 }
 
+void SGEnviro::startOfFrame(void) {
+       view_in_cloud = false;
+       if(SGNewCloud::cldCache)
+               SGNewCloud::cldCache->startNewFrame();
+}
+
+void SGEnviro::endOfFrame(void) {
+}
+
+// this can be queried to add some turbulence for example
+bool SGEnviro::is_view_in_cloud(void) const {
+       return view_in_cloud;
+}
+void SGEnviro::set_view_in_cloud(bool incloud) {
+       view_in_cloud = incloud;
+}
+
+int SGEnviro::get_CacheResolution(void) const {
+       return SGCloudField::get_CacheResolution();
+}
+
 int SGEnviro::get_clouds_CacheSize(void) const {
        return SGCloudField::get_CacheSize();
 }
@@ -45,6 +71,10 @@ bool SGEnviro::get_clouds_enable_state(void) const {
        return SGCloudField::get_enable3dClouds();
 }
 
+void SGEnviro::set_CacheResolution(int resolutionPixels) {
+       SGCloudField::set_CacheResolution(resolutionPixels);
+}
+
 void SGEnviro::set_clouds_CacheSize(int sizeKb) {
        SGCloudField::set_CacheSize(sizeKb);
 }
@@ -60,15 +90,17 @@ void SGEnviro::set_clouds_enable_state(bool enable) {
 
 // rain/snow
 float SGEnviro::get_precipitation_density(void) const {
-       return 0.0;
+       return precipitation_density;
 }
 bool SGEnviro::get_precipitation_enable_state(void) const {
-       return false;
+       return precipitation_enable_state;
 }
 
 void SGEnviro::set_precipitation_density(float density) {
+       precipitation_density = density;
 }
 void SGEnviro::set_precipitation_enable_state(bool enable) {
+       precipitation_enable_state = enable;
 }
 
 // others
index cc2a65d544bd879efd2bda94858fea2935b5cc53..f8a7e6c0e9fdb0f171cdf6ce1a8ea21a137869b2 100644 (file)
 
 class SGEnviro {
 
+private:
+       bool view_in_cloud;
+       bool precipitation_enable_state;
+       float precipitation_density;
+
 public:
        SGEnviro();
        ~SGEnviro();
 
+       void startOfFrame(void);
+       void endOfFrame(void);
+
+       // this can be queried to add some turbulence for example
+       bool is_view_in_cloud(void) const;
+       void set_view_in_cloud(bool incloud);
+
        // Clouds
        // return the size of the memory pool used by texture impostors
        int get_clouds_CacheSize(void) const;
+       int get_CacheResolution(void) const;
        float get_clouds_visibility(void) const;
        float get_clouds_density(void) const;
        bool get_clouds_enable_state(void) const;
 
        void set_clouds_CacheSize(int sizeKb);
+       void set_CacheResolution(int resolutionPixels);
        void set_clouds_visibility(float distance);
        void set_clouds_density(float density);
        void set_clouds_enable_state(bool enable);
@@ -54,5 +68,4 @@ public:
 
 extern SGEnviro sgEnviro;
 
-#endif // _VISUAL_ENVIRO_HXX
-
+#endif // _VISUAL_ENVIRO_HXX
\ No newline at end of file
index a05ce7c8477d881ac760688d192cf3cd0cf444ef..64bb7c6363a89670f1afe36a97b5df7800875795 100644 (file)
@@ -71,8 +71,8 @@ bool SGBbCache::allocTextureMemory(int cacheCount, int textureDimension) {
 
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
         glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
-        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
+        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        }
     glBindTexture(GL_TEXTURE_2D, 0);
        cacheSizeKb = (textureDimension * textureDimension * 4);
@@ -94,7 +94,7 @@ SGBbCache::SGBbCache(void) :
        rt(0),
        rtAvailable(false),
        frameNumber(0),
-       maxImpostorRegenFrame(10)
+       maxImpostorRegenFrame(20)
 {
 }
 
@@ -139,11 +139,11 @@ void SGBbCache::init(int cacheCount) {
                }
        }
        if( cacheCount )
-               allocTextureMemory( cacheCount, 256 );
+               allocTextureMemory( cacheCount, 64 );
 
 }
 
-// TODO:not callable atm, texture size not handled correctly
+
 bool SGBbCache::setCacheSize(int count, int textureDimension) {
        if( count < 0 || count > 500)
                return false;
@@ -172,7 +172,7 @@ bool SGBbCache::setCacheSize(int count, int textureDimension) {
        return allocTextureMemory( count, textureDimension);
 }
 
-// TODO:not callable atm, texture size not handled correctly
+
 bool SGBbCache::setCacheSize(int sizeKb) {
        if( sizeKb < 0 || sizeKb > 256*1024)
                return false;
@@ -181,10 +181,10 @@ bool SGBbCache::setCacheSize(int sizeKb) {
                return true;
        int count = 1;
        int textureDimension = 256;
-       if( cacheSizeKb >= 8*1024 ) {
+       if( sizeKb >= 8*1024 ) {
                // more than 32 256x256 textures
                textureDimension = 256;
-       } else  if( cacheSizeKb >= 2*1024 ) {
+       } else  if( sizeKb >= 2*1024 ) {
                // more than 32 128x128 textures
                textureDimension = 128;
        } else  {
@@ -305,10 +305,10 @@ bool SGBbCache::isBbValid( int cldId, int bbId, float angleY, float angleX) {
        if( builtBBframe >= maxImpostorRegenFrame )
                return true;
 
-    if( fabs(angleY - bbList[bbId].angleY) >= 5.0 )
+    if( fabs(angleY - bbList[bbId].angleY) >= 4.0 )
         return false;
 
-    if( fabs(angleX - bbList[bbId].angleX) >= 5.0 )
+    if( fabs(angleX - bbList[bbId].angleX) >= 4.0 )
         return false;
 
        bbList[bbId].frameUsed = frameNumber;
index 83f941d61027d15b58b03939a89a0e026f883965..8555af202d541dd513f43320249e81632a024523 100644 (file)
 #include <plib/sg.h>
 #include <plib/ssg.h>
 #include <simgear/math/sg_geodesy.hxx>
+#include <simgear/math/polar3d.hxx>
 
 #include STL_ALGORITHM
 #include <vector>
 
 SG_USING_STD(vector);
 
+#include <simgear/environment/visual_enviro.hxx>
 #include "newcloud.hxx"
 #include "cloudfield.hxx"
 
@@ -45,9 +47,26 @@ float SGCloudField::CloudVis = 25000.0f;
 bool SGCloudField::enable3D = true;
 // fieldSize must be > CloudVis or we can destroy the impostor cache
 // a cloud must only be seen once or the impostor will be generated for each of his positions
-double SGCloudField::fieldSize = 30000.0;
+double SGCloudField::fieldSize = 27000.0;
 float SGCloudField::density = 100.0;
-static int last_cache_size = 4*1024;
+static int last_cache_size = 1*1024;
+static int cacheResolution = 64;
+
+int SGCloudField::get_CacheResolution(void) {
+       return cacheResolution;
+}
+
+void SGCloudField::set_CacheResolution(int resolutionPixels) {
+       if(cacheResolution == resolutionPixels)
+               return;
+       cacheResolution = resolutionPixels;
+       if(enable3D) {
+               int count = last_cache_size * 1024 / (cacheResolution * cacheResolution * 4);
+               if(count == 0)
+                       count = 1;
+               SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
+       }
+}
 
 int SGCloudField::get_CacheSize(void) { 
        return SGNewCloud::cldCache->queryCacheSize(); 
@@ -61,10 +80,17 @@ void SGCloudField::set_CacheSize(int sizeKb) {
                return;
        if(sizeKb)
                last_cache_size = sizeKb;
-       SGNewCloud::cldCache->setCacheSize(sizeKb);
+       if(enable3D) {
+               int count = last_cache_size * 1024 / (cacheResolution * cacheResolution * 4);
+               if(count == 0)
+                       count = 1;
+//             SGNewCloud::cldCache->setCacheSize(sizeKb);
+               SGNewCloud::cldCache->setCacheSize(count, cacheResolution);
+       }
 }
 void SGCloudField::set_CloudVis(float distance) {
-       SGCloudField::CloudVis = distance;
+       if( distance <= fieldSize )
+               SGCloudField::CloudVis = distance;
 }
 void SGCloudField::set_density(float density) {
        SGCloudField::density = density;
@@ -104,15 +130,7 @@ void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, doub
 
        sgMakeCoordMat4( transform, &layerpos );
 
-       // TODO:use a simple sphere earth
-       double az1, az2, s;
-       geo_inverse_wgs_84( 0.0, 0.0, 0.0, lat*SG_RADIANS_TO_DEGREES , lon*SG_RADIANS_TO_DEGREES, &az1, &az2, &s);
-       az1 = az1 * SG_DEGREES_TO_RADIANS;
-       // compute the view position on a 'flat' earth
-       deltay = -cos(SG_PI/2+az1) * s;
-       deltax = -sin(SG_PI/2+az1) * s;
-//     deltax = cos(0.0) * s;
-//     deltay = sin(0.0) * s;
+
        this->alt = alt;
 
        // simulate clouds movement from wind
@@ -126,13 +144,51 @@ void SGCloudField::reposition( sgVec3 p, sgVec3 up, double lon, double lat, doub
                relative_position[SG_Y] += by;
     }
 
+    if ( lon != last_lon || lat != last_lat || sp_dist != 0 ) {
+        Point3D start( last_lon, last_lat, 0.0 );
+        Point3D dest( lon, lat, 0.0 );
+        double course = 0.0, dist = 0.0;
+
+        calc_gc_course_dist( dest, start, &course, &dist );
+        // if start and dest are too close together,
+        // calc_gc_course_dist() can return a course of "nan".  If
+        // this happens, lets just use the last known good course.
+        // This is a hack, and it would probably be better to make
+        // calc_gc_course_dist() more robust.
+        if ( isnan(course) ) {
+            course = last_course;
+        } else {
+            last_course = course;
+        }
+
+        // calculate cloud movement due to external forces
+        double ax = 0.0, ay = 0.0;
+
+        if (dist > 0.0) {
+            ax = cos(course) * dist;
+            ay = sin(course) * dist;
+        }
+
+               deltax += ax;
+               deltay += ay;
+
+        last_lon = lon;
+        last_lat = lat;
+    }
+
+
        // correct the frustum with the right far plane
        ssgContext *context = ssgGetCurrentContext();
        frustum = *context->getFrustum();
        frustum.setNearFar(1.0, CloudVis);
 }
 
-SGCloudField::SGCloudField() {
+SGCloudField::SGCloudField() :
+       last_density(0.0),
+       deltax(0.0),
+       deltay(0.0),
+       last_course(0.0)
+{
        sgSetVec3( relative_position, 0,0,0);
        theField.reserve(200);
        inViewClouds.reserve(200);
@@ -147,11 +203,43 @@ SGCloudField::~SGCloudField() {
 }
 
 
+// use a table or else we see poping when moving the slider...
+static int densTable[][10] = {
+       {0,0,0,0,0,0,0,0,0,0},
+       {1,0,0,0,0,0,0,0,0,0},
+       {1,0,0,0,1,0,0,0,0,0},
+       {1,0,0,0,1,0,0,1,0,0}, // 30%
+       {1,0,1,0,1,0,0,1,0,0},
+       {1,0,1,0,1,0,1,1,0,0}, // 50%
+       {1,0,1,0,1,0,1,1,0,1},
+       {1,0,1,1,1,0,1,1,0,1}, // 70%
+       {1,1,1,1,1,0,1,1,0,1},
+       {1,1,1,1,1,0,1,1,1,1}, // 90%
+       {1,1,1,1,1,1,1,1,1,1}
+};
+
+// set the visible flag depending on density
+void SGCloudField::applyDensity(void) {
+       int row = (int) (density / 10.0);
+       int col = 0;
+       list_of_Cloud::iterator iCloud;
+       for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
+               if(++col > 9)
+                       col = 0;
+               if( densTable[row][col] ) {
+                       iCloud->visible = true;
+               } else
+                       iCloud->visible = false;
+       }
+       last_density = density;
+}
+
 // add one cloud, data is not copied, ownership given
 void SGCloudField::addCloud( sgVec3 pos, SGNewCloud *cloud) {
        Cloud cl;
        sgCopyVec3( cl.pos, pos );
        cl.aCloud = cloud;
+       cl.visible = true;
        cloud->SetPos( pos );
        theField.push_back( cl );
 }
@@ -165,7 +253,7 @@ static float Rnd(float n) {
 // build a field of cloud of size 25x25 km, its a grid of 11x11 clouds
 void SGCloudField::buildTestLayer(void) {
 
-       const float s = 2200.0f;
+       const float s = 2250.0f;
 
        for( int z = -5 ; z <= 5 ; z++) {
                for( int x = -5 ; x <= 5 ; x++ ) {
@@ -175,21 +263,23 @@ void SGCloudField::buildTestLayer(void) {
             addCloud(pos, cloud);
                }
        }
-
+       applyDensity();
 }
 
 // cull all clouds of a tiled field
 void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
        list_of_Cloud::iterator iCloud;
-//     const float distVisCompare = CloudVis * CloudVis;
 
        // TODO:cull the field before culling the clouds in the field (should eliminate 3 fields)
        for( iCloud = theField.begin() ; iCloud != theField.end() ; iCloud++ ) {
                sgVec3 dist;
                sgSphere sphere;
+               if( ! iCloud->visible )
+                       continue;
                sgSubVec3( dist, iCloud->pos, eyePos );
                sphere.setCenter(dist[0], dist[2], dist[1]);
-               sphere.setRadius(iCloud->aCloud->getRadius());
+               float radius = iCloud->aCloud->getRadius();
+               sphere.setRadius(radius);
                sphere.orthoXform(mat);
                if( frustum.contains( & sphere ) != SG_OUTSIDE ) {
                        float squareDist = dist[0]*dist[0] + dist[1]*dist[1] + dist[2]*dist[2];
@@ -199,16 +289,13 @@ void SGCloudField::cullClouds(sgVec3 eyePos, sgMat4 mat) {
                        // save distance for later sort, opposite distance because we want back to front
                        tmp.dist   =  - squareDist;
                        inViewClouds.push_back(tmp);
+                       if( squareDist - radius*radius < 100*100 )
+                               sgEnviro.set_view_in_cloud(true);
                }
        }
 
 }
 
-static inline void myswap(float &a, float &b) {
-       float tmp = a;
-       a = b;
-       b = tmp;
-}
 
 // Render a cloud field
 // because no field can have an infinite size (and we don't want to reach his border)
@@ -221,30 +308,29 @@ void SGCloudField::Render(void) {
        if( ! enable3D )
                return;
 
+       if( last_density != density ) {
+               last_density = density;
+               applyDensity();
+       }
+
        // ask the impostor cache to do some cleanup
        // TODO:don't do that for every field
        SGNewCloud::cldCache->startNewFrame();
 
        inViewClouds.clear();
 
-       // cloud fields are tiled on the flat earth
-       // compute the position in the tile
-       relx = -fmod( deltax + relative_position[SG_X], fieldSize );
-       rely = -fmod( deltay + relative_position[SG_Y], fieldSize );
  
        glPushMatrix();
  
        sgMat4 modelview, tmp, invtrans;
 
-       // try to find the sun position (buggy)
+       // try to find the sun position
        sgTransposeNegateMat4( invtrans, transform );
     sgVec3 lightVec;
     ssgGetLight( 0 )->getPosition( lightVec );
-    sgNegateVec3( lightVec );
     sgXformVec3( lightVec, invtrans );
-       sgNormaliseVec3( lightVec );
        sgCopyVec3( SGNewCloud::modelSunDir, lightVec );
-
+       sgSetVec3(  SGNewCloud::modelSunDir, lightVec[0], lightVec[2], lightVec[1]);
        // try to find the lighting data (buggy)
        sgVec4 diffuse, ambient;
        ssgGetLight( 0 )->getColour( GL_DIFFUSE, diffuse );
@@ -257,11 +343,12 @@ void SGCloudField::Render(void) {
        sgCopyMat4( tmp, transform );
     sgPostMultMat4( tmp, modelview );
 
-       sgSetVec3( eyePos, -relx, -tmp[3][2], -rely);
-       sgSetVec3( eyePos, -relx, 0, -rely);
+       // cloud fields are tiled on the flat earth
+       // compute the position in the tile
+       relx = -fmod( deltax + relative_position[SG_X] + tmp[3][0], fieldSize );
+       rely = -fmod( deltay + relative_position[SG_Y] + tmp[3][1], fieldSize );
+
        sgSetVec3( eyePos, -relx, alt, -rely);
-//     sgSetVec3( eyePos, 0, - tmp[3][2], 0);
-//     sgSetVec3( eyePos, 20000, - tmp[3][2], 20000);
 
        tmp[3][2] = 0;
        tmp[3][0] = 0;
@@ -296,12 +383,10 @@ void SGCloudField::Render(void) {
     glEnable(GL_ALPHA_TEST);
     glAlphaFunc(GL_GREATER, 0.0f);
        glDisable(GL_CULL_FACE);
-//     glDisable(GL_DEPTH_TEST);
        glEnable(GL_DEPTH_TEST);
        glEnable(GL_SMOOTH);
     glEnable(GL_BLEND);
        glBlendFunc( GL_DST_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
-//     glEnable( GL_COLOR_MATERIAL ); 
        glEnable( GL_TEXTURE_2D );
        glDisable( GL_FOG );
     glDisable(GL_LIGHTING);
@@ -316,11 +401,13 @@ void SGCloudField::Render(void) {
 
        glBindTexture(GL_TEXTURE_2D, 0);
     glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
+       glEnable( GL_FOG );
+       glEnable(GL_CULL_FACE);
+       glEnable(GL_DEPTH_TEST);
 
        ssgLoadModelviewMatrix( modelview );
 
        glPopMatrix();
-//     glEnable(GL_DEPTH_TEST);
 
 }
 
index 39b0e00118455af317b80c694fe83d3c86f82dae..2a547eb61497cac658f1bc2e11c70da2132b2747 100644 (file)
@@ -38,7 +38,7 @@ public:
        sgVec3          eyePos;
        float           dist;
        bool operator<(const culledCloud &b) const {
-               return (this->dist < b.dist);
+               return this->dist < b.dist;
        }
 };
 typedef vector<culledCloud> list_of_culledCloud;
@@ -50,6 +50,7 @@ private:
        public:
                SGNewCloud      *aCloud;
                sgVec3          pos;
+               bool            visible;
 //             float           dist;
 //             bool            culled;
 
@@ -64,6 +65,8 @@ private:
        // cull all clouds of a tiled field
        void cullClouds(sgVec3 eyePos, sgMat4 mat);
 
+       void applyDensity(void);
+
        list_of_Cloud theField;
        // this is a relative position only, with that we can move all clouds at once
        sgVec3 relative_position;
@@ -73,6 +76,9 @@ private:
 
        sgMat4 transform;
        double deltax, deltay, alt;
+    double last_lon, last_lat, last_course;
+
+       float   last_density;
 
 public:
 
@@ -101,11 +107,13 @@ public:
 
        // return the size of the memory pool used by texture impostors
        static int get_CacheSize(void);
+       static int get_CacheResolution(void);
        static float get_CloudVis(void) { return CloudVis; }
        static float get_density(void) { return density; }
        static bool get_enable3dClouds(void) { return enable3D; }
 
        static void set_CacheSize(int sizeKb);
+       static void set_CacheResolution(int resolutionPixels);
        static void set_CloudVis(float distance);
        static void set_density(float density);
        static void set_enable3dClouds(bool enable);
index e0bcfce76ef82389b3120d1abec103d2bef22056..6ceb9dbb18832e62c1a56a4b5664d10f8c08c69d 100644 (file)
@@ -33,6 +33,7 @@
 #include STL_ALGORITHM
 #include SG_GLU_H
 
+#include "cloudfield.hxx"
 #include "newcloud.hxx"
 
 
@@ -45,7 +46,7 @@ static ssgTexture *cloudTextures[SGNewCloud::CLTexture_max];
 bool SGNewCloud::useAnisotropic = true;
 SGBbCache *SGNewCloud::cldCache = 0;
 static bool texturesLoaded = false;
-float SGNewCloud::nearRadius = 2500.0f;
+float SGNewCloud::nearRadius = 3500.0f;
 bool SGNewCloud::lowQuality = false;
 sgVec3 SGNewCloud::sunlight = {0.5f, 0.5f, 0.5f};
 sgVec3 SGNewCloud::ambLight = {0.5f, 0.5f, 0.5f};
@@ -67,7 +68,7 @@ SGNewCloud::SGNewCloud() :
 //     if( ! texturesLoaded ) {}
        if( cldCache == 0 ) {
                cldCache = new SGBbCache;
-               cldCache->init( 20 );
+               cldCache->init( 64 );
        }
 }
 
@@ -309,7 +310,7 @@ void SGNewCloud::genSprites( void ) {
 
 // definition of a cu cloud, only for testing
 void SGNewCloud::new_cu(void) {
-       float s = 150.0f;
+       float s = 250.0f;
        float r = Rnd(1.0) + 0.5;
        if( r < 0.5f ) {
                addContainer(0.0f, 0.0f, 0.0f, s, CLbox_cumulus);
@@ -332,7 +333,7 @@ void SGNewCloud::new_cu(void) {
 
        } else {
                // cb
-               s = 475.0f;
+               s = 675.0f;
                addContainer(0, 0, 0, s, CLbox_cumulus);
                addContainer(0, 0, s, s, CLbox_cumulus);
                addContainer(s, 0, s, s, CLbox_cumulus);
@@ -368,43 +369,12 @@ void SGNewCloud::SetPos(sgVec3 newPos) {
 
 
 
-/*
-Public Sub drawContainers()
-    Dim N As Integer, i As Integer
-    N = UBound(tbSpriteCont())
-
-    Call glPolygonMode(faceFrontAndBack, pgmLine)
-
-    Call glColor3f(0.9, 0.9, 0.9)
-
-    For i = 0 To N - 1
-        With tbSpriteCont(i)
-            Call glPushMatrix
-            Call glTranslatef(.x * c_scale + cloudpos(0), .y * c_scale + cloudpos(1), .z * c_scale + cloudpos(2))
-            Call gCtl.Shapes.box(.r * c_scale, .r * c_scale, .r * c_scale)
-            Call glPopMatrix
-        End With
-    Next i
-If 0 Then
-    Call glPushMatrix
-        Call glTranslatef(ccenter(0), ccenter(1), ccenter(2))
-        Call gCtl.Shapes.Sphere(cradius, 8, 8)
-    Call glPopMatrix
-End If
-End Sub
-*/
 void SGNewCloud::drawContainers() {
 
 
 }
 
 
-/*
-*/
-
-//bool SGNewCloud::compareSpriteFunction(const spriteDef &a, const spriteDef &b) {
-//     return (a.dist > b.dist);
-//}
 
 // sort on distance to eye because of transparency
 void SGNewCloud::sortSprite( sgVec3 eye ) {
@@ -424,7 +394,12 @@ void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos,
 
 /*    int clrank                = fadingrank / 10;
        int clfadeinrank = fadingrank - clrank * 10;*/
+       float CloudVisFade = 1.0 / (1.5 * SGCloudField::get_CloudVis());
+
+    computeSimpleLight( FakeEyePos );
 
+    // view point sort, we sort because of transparency
+       sortSprite( FakeEyePos );
 
        GLint previousTexture = -1, thisTexture;
        list_of_spriteDef::iterator iSprite;
@@ -491,8 +466,7 @@ void SGNewCloud::Render3Dcloud( bool drawBB, sgVec3 FakeEyePos, sgVec3 deltaPos,
                        sgCopyVec4 ( l3, iSprite->l3 );
                        if( ! drawBB ) {
                                // blend clouds with sky based on distance to limit the contrast of distant cloud
-                               // TODO:use cloudfield vis, not hardcoded value
-                               float t = 1.0f - dist_center / (15000.0f * 2.0 );
+                               float t = 1.0f - dist_center * CloudVisFade;
                                if ( t < 0.0f ) 
                                        t = 0.0f;       // no, it should have been culled
                                // now clouds at the far plane are half blended
@@ -591,8 +565,9 @@ void SGNewCloud::RenderBB(sgVec3 deltaPos, float angleY, float angleX, float dis
         glRotatef(angleX, 1.0f, 0.0f, 0.0f);
  
                // blend clouds with sky based on distance to limit the contrast of distant cloud
-               // TODO:use cloudfield vis, not hardcoded value
-               float t = 1.0f - dist_center / (15000.0f * 2.0 );
+               float CloudVisFade = (1.5 * SGCloudField::get_CloudVis());
+
+               float t = 1.0f - dist_center / CloudVisFade;
                // err the alpha value is not good for impostor, debug that
                t *= 1.65;
                if ( t < 0.0f ) 
@@ -611,7 +586,7 @@ void SGNewCloud::RenderBB(sgVec3 deltaPos, float angleY, float angleX, float dis
                        glVertex2f(-r, -r);
                glEnd();
 
-#if 1  // debug only
+#if 0  // debug only
                int age = cldCache->queryImpostorAge(bbId);
                // draw a red border for the newly generated BBs else draw a white border
         if( age < 200 )
@@ -646,36 +621,21 @@ bool SGNewCloud::isBillboardable(float dist) {
         // near clouds we don't want to use BB
         return false;
        }
-//     return false;
        return true;
 }
 
 
 
 // render the cloud, fakepos is a relative position inside the cloud field
-void SGNewCloud::Render(sgVec3 fakepos) {
-       sgVec3 eyePos, FakeEyePos;
+void SGNewCloud::Render(sgVec3 FakeEyePos) {
        sgVec3 dist;
 
 
-       glColor3f(1.0f, 1.0f, 1.0f);
-
-       // obsolete code
-       sgCopyVec3( eyePos, fakepos );
-
-    sgCopyVec3( FakeEyePos, fakepos);
        sgVec3 deltaPos;
-//    sgSubVec3( deltaPos, eyePos, FakeEyePos);
        sgCopyVec3( deltaPos, FakeEyePos);
     sgSubVec3( dist, center, FakeEyePos);
     float dist_center = sgLengthVec3(dist);
 
-       // eeeek don't do that so early, perhaps we will use an impostor
-    computeSimpleLight( FakeEyePos );
-
-    // view point sort, we sort because of transparency
-       // eeeek don't do that so early, perhaps we will use an impostor
-       sortSprite( FakeEyePos );
 
 
        if( !isBillboardable(dist_center) ) {