source: osgVisual/src/sky_Silverlining/skySilverLining_skyDrawable.cpp @ 53

Last change on this file since 53 was 53, checked in by Torben Dannhauer, 14 years ago

Update to use osg for sky fog instead OpenGL.

this way the osg fog feature "radialFog" can be used.

File size: 10.7 KB
Line 
1/* -*-c++-*- osgVisual - Copyright (C) 2009-2010 Torben Dannhauer
2 *
3 * This library is based on OpenSceneGraph, open source and may be redistributed and/or modified under
4 * the terms of the OpenSceneGraph Public License (OSGPL) version 0.0 or
5 * (at your option) any later version.  The full license is in LICENSE file
6 * included with this distribution, and on the openscenegraph.org website.
7 *
8 * osgVisual requires for some proprietary modules a license from the correspondig manufacturer.
9 * You have to aquire licenses for all used proprietary modules.
10 *
11 * This library is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 * OpenSceneGraph Public License for more details.
15 *
16 * This file is based on the OSG example of the Silverlining SDK:
17 * Copyright (c) 2008 Sundog Software, LLC. All rights reserved worldwide.
18*/
19
20#include <skySilverLining_skyDrawable.h>
21#include <SilverLining.h>
22#include <skySilverLining_AtmosphereReference.h>
23
24#include <GL/gl.h>
25#include <GL/glu.h>
26#include <assert.h>
27
28
29
30using namespace SilverLining;
31using namespace osgVisual;
32
33skySilverLining_skyDrawable::skySilverLining_skyDrawable()
34        : osg::Drawable()
35                , _view(0)
36                , _skyboxSize(0)
37{
38    setDataVariance(osg::Object::DYNAMIC);
39    setUseVertexBufferObjects(false);
40    setUseDisplayList(false);
41        cloudLayerSlots.clear();
42        newCloudLayersToAdd = false;
43}
44
45skySilverLining_skyDrawable::skySilverLining_skyDrawable(osgViewer::Viewer* view,  osg::CoordinateSystemNode* csn_)
46        : osg::Drawable()
47        , _view(view)
48                , _skyboxSize(0)
49{
50    setDataVariance(osg::Object::DYNAMIC);
51    setUseVertexBufferObjects(false);
52    setUseDisplayList(false);
53        cloudLayerSlots.clear();
54        newCloudLayersToAdd = false;
55        sceneRoot = csn_;
56}
57
58void skySilverLining_skyDrawable::setLighting(SilverLining::Atmosphere *atmosphere) const
59{
60    osg::Light *light = _view->getLight();
61    osg::Vec4 ambient, diffuse;
62    osg::Vec3 direction;
63
64    if (atmosphere && light)
65    {
66        float ra, ga, ba, rd, gd, bd, x, y, z;
67        atmosphere->GetAmbientColor(&ra, &ga, &ba);
68        atmosphere->GetSunOrMoonColor(&rd, &gd, &bd);
69        atmosphere->GetSunOrMoonPosition(&x, &y, &z);
70
71        direction = osg::Vec3(x, y, z);
72        ambient = osg::Vec4(ra, ga, ba, 1.0);
73        diffuse = osg::Vec4(rd, gd, bd, 1.0);
74
75        // xform the light direction into camera coordinates
76        osg::Quat view = _view->getCamera()->getViewMatrix().getRotate();
77        //direction = view * direction;
78        direction.normalize();
79
80        light->setAmbient(ambient);
81        light->setDiffuse(diffuse);
82        light->setSpecular(osg::Vec4(0,0,0,1));
83        light->setPosition(osg::Vec4(direction.x(), direction.y(), direction.z(), 0));
84    }
85}
86
87void skySilverLining_skyDrawable::setSceneFog(SilverLining::Atmosphere *atmosphere) const
88{   
89        //glEnable(GL_FOG);
90 //   glFogi(GL_FOG_MODE, GL_EXP);
91
92        ////float hazeR, hazeG, hazeB;
93        ////double hazeDepth, hazeDensity;
94        ////atmosphere->GetHaze(hazeR, hazeG, hazeB, hazeDepth, hazeDensity);
95
96 //   //hazeDensity = 1.0 / 40000;
97        ////hazeDensity = 0;
98        //float hazeDensity = 1.0 / atmosphere->GetConditions()->GetVisibility();
99
100 //   // Decrease fog density with altitude, to avoid fog effects through the vacuum of space.
101 //   static const double H = 8435.0; // Pressure scale height of Earth's atmosphere
102 //   double isothermalEffect = exp(-(atmosphere->GetConditions()->GetLocation().GetAltitude() / H));     
103 //   if (isothermalEffect <= 0) isothermalEffect = 1E-9;
104 //   if (isothermalEffect > 1.0) isothermalEffect = 1.0;
105 //   hazeDensity *= isothermalEffect;
106
107 //   bool silverLiningHandledTheFog = false;
108
109 //   if (atmosphere->GetFogEnabled())
110 //   {
111 //           float density, r, g, b;
112 //           // Note, the fog color returned is already lit
113 //           atmosphere->GetFogSettings(&density, &r, &g, &b);
114
115 //           if (density > hazeDensity)
116 //           {
117 //                   glFogf(GL_FOG_DENSITY, density);
118
119 //                   GLfloat fogColor[4] = {r, g, b, 1.0};
120 //                   glFogfv(GL_FOG_COLOR, fogColor);
121
122 //                   silverLiningHandledTheFog = true;
123 //           }
124 //   }
125 //   
126 //   if (!silverLiningHandledTheFog)
127 //   {
128 //           GLfloat fogColor[4];
129 //           //atmosphere->GetHorizonColor(yaw, &fogColor[0], &fogColor[1], &fogColor[2]);     // New version of this call: SL_1.94 /** \todo transmit the yaw value of the center channel to all slaves for consistent fog color. */
130        //              atmosphere->GetHorizonColor( 0, &fogColor[0], &fogColor[1], &fogColor[2]);
131 //           glFogfv(GL_FOG_COLOR, fogColor);
132
133 //           glFogf(GL_FOG_DENSITY, hazeDensity);
134 //   }
135
136
137
138
139
140       
141        osg::ref_ptr<osg::Fog> fog = new osg::Fog;
142    fog->setMode(osg::Fog::EXP);
143        //fog->setUseRadialFog( true );
144
145        //_objectsNode  = erde oder object, das mit nebel bedacht werden soll   
146        sceneRoot->getOrCreateStateSet()->setAttributeAndModes(fog.get());
147
148        //float hazeR, hazeG, hazeB;
149        //double hazeDepth, hazeDensity;
150        //atmosphere->GetHaze(hazeR, hazeG, hazeB, hazeDepth, hazeDensity);
151
152    //hazeDensity = 1.0 / 40000;
153        //hazeDensity = 0;
154        float hazeDensity = 1.0 / atmosphere->GetConditions()->GetVisibility();
155
156    // Decrease fog density with altitude, to avoid fog effects through the vacuum of space.
157    static const double H = 8435.0; // Pressure scale height of Earth's atmosphere
158    double isothermalEffect = exp(-(atmosphere->GetConditions()->GetLocation().GetAltitude() / H));     
159    if (isothermalEffect <= 0) isothermalEffect = 1E-9;
160    if (isothermalEffect > 1.0) isothermalEffect = 1.0;
161    hazeDensity *= isothermalEffect;
162
163    bool silverLiningHandledTheFog = false;
164
165    if (atmosphere->GetFogEnabled())
166    {
167            float density, r, g, b;
168            // Note, the fog color returned is already lit
169            atmosphere->GetFogSettings(&density, &r, &g, &b);
170
171            if (density > hazeDensity)
172            {
173                                fog->setDensity(density);
174                                fog->setColor(osg::Vec4(r, g, b, 1.0));
175
176                                silverLiningHandledTheFog = true;
177            }
178    }
179   
180    if (!silverLiningHandledTheFog)
181    {
182                float r, g, b;
183                atmosphere->GetHorizonColor(0, &r, &g, &b);// New version of this call: since SL_1.94 /** \todo transmit the yaw value of the center channel to all slaves for consistent fog color. */
184
185                fog->setDensity(hazeDensity);
186                fog->setColor(osg::Vec4(r, g, b, 1.0));
187    }
188
189}
190
191void skySilverLining_skyDrawable::initializeSilverLining(skySilverLining_atmosphereReference *ar)
192{
193    if (ar && !ar->atmosphereInitialized)
194    {
195        ar->atmosphereInitialized = true; // only try once.
196                SilverLining::Atmosphere *atmosphere = ar->atmosphere;
197
198                if (atmosphere)
199        {
200                        srand(1234); // constant random seed to ensure consistent clouds across windows
201
202            // Update the path below to where you installed SilverLining's resources folder.
203            //int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "C:\\Program Files\\SilverLining SDK\\resources\\", true, 0);
204                        int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "../resources/sky_silverlining/", true, 0);
205            if (ret != SilverLining::Atmosphere::E_NOERROR)
206            {
207                printf("SilverLining failed to initialize; error code %d.\n", ret);
208                printf("Check that the path to the SilverLining installation directory is set properly ");
209                printf("in skySilverLining_skyDrawable.cpp (in SkyDrawable::initializeSilverLining)\n");
210                exit(0);
211            }
212
213            // Let SilverLining know which way is up. OSG usually has Z going up.
214            //atmosphere->SetUpVector(0, 0, 1);
215            //atmosphere->SetRightVector(1, 0, 0);
216                        atmosphere->SetUpVector(0.662994, 0.136169, 0.736136);
217                        atmosphere->SetRightVector(-0.201185, 0.979553, 0.0);
218
219            // Set our location (change this to your own latitude and longitude)
220            SilverLining::Location loc;
221            loc.SetAltitude(0);
222            loc.SetLatitude(47);
223            loc.SetLongitude(11);
224            atmosphere->GetConditions()->SetLocation(loc);
225
226            // Set the sstem time in PST
227            SilverLining::LocalTime t;
228            t.SetFromSystemTime();
229                        t.SetTimeZone(CET);
230            atmosphere->GetConditions()->SetTime(t);
231
232                        // Setting Up Visibility
233                        atmosphere->GetConditions()->SetVisibility(40000);
234
235                        // Setting Up Haze
236                        atmosphere->GetConditions()->SetTurbidity(2.2);
237
238                        atmosphere->GetConditions()->EnableTimePassage( true, 5000 );
239                       
240                }       // if atmosphere ENDE
241
242    }   // If atmosphere not initialized ENDE
243}
244
245void skySilverLining_skyDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
246{
247        skySilverLining_atmosphereReference *ar = dynamic_cast<skySilverLining_atmosphereReference *>(renderInfo.getCurrentCamera()->getUserData());
248        SilverLining::Atmosphere *atmosphere = 0;
249
250        if (ar) atmosphere = ar->atmosphere;
251
252        renderInfo.getState()->disableAllVertexArrays();
253
254    if (atmosphere)
255    {
256        initializeSilverLining(ar);
257                const_cast<skySilverLining_skyDrawable*>(this)->seedAndAddCloudLayers(atmosphere);
258
259
260        atmosphere->BeginFrame(true, true, _skyboxSize);
261        setLighting(atmosphere);
262                setSceneFog(atmosphere);
263    }
264
265        renderInfo.getState()->dirtyAllVertexArrays();
266}
267
268void skySilverLining_skyDrawable::addCloudLayer(cloudLayerSlot *cloudLayerSlot_)
269{
270        OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
271        cloudLayerSlots.push_back( cloudLayerSlot_ );
272        newCloudLayersToAdd = true;
273}
274
275
276
277void skySilverLining_skyDrawable::seedAndAddCloudLayers(SilverLining::Atmosphere *atmosphere)
278{
279        // Only try to add if anything to do..
280        if ( newCloudLayersToAdd )
281        {
282                OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
283                for ( unsigned int i=0; cloudLayerSlots.size() > 0; i++)
284                {
285                        // Seed cloudLayer
286                        cloudLayerSlots.back()->cloudLayerPointer->SeedClouds(*atmosphere);
287
288                        //cloudLayerSlots.back()->cloudLayerPointer->SetEnabled( false );       // Todo: testing, please remove
289                        //cloudLayerSlots.back()->cloudLayerPointer->SetEnabled( true, 30000);  // Todo: testing, please remove
290
291                        // add cloudLayer to atmosphere
292                        cloudLayerSlots.back()->cloudLayerHandle = atmosphere->GetConditions()->AddCloudLayer( cloudLayerSlots.back()->cloudLayerPointer );
293
294                        // Delete this cloudLayer from the ToDo list.
295                        cloudLayerSlots.pop_back();
296                }
297
298                // Note nothing to do.
299                newCloudLayersToAdd = false;
300        }
301}
302
303void skySilverLining_skyDrawable::shutdown()
304{
305        sceneRoot = NULL;
306}
Note: See TracBrowser for help on using the repository browser.