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

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

Introductes VS 2008 Memory Leak Debugging.
Todo: Compile on Linux and compare with Valgrind, VS 2008 seems to be awkward in leak debugging

File size: 8.9 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        #include <leakDetection.h>
39       
40    setDataVariance(osg::Object::DYNAMIC);
41    setUseVertexBufferObjects(false);
42    setUseDisplayList(false);
43        cloudLayerSlots.clear();
44        newCloudLayersToAdd = false;
45}
46
47skySilverLining_skyDrawable::skySilverLining_skyDrawable(osgViewer::Viewer* view,  osg::CoordinateSystemNode* csn_)
48        : osg::Drawable()
49        , _view(view)
50                , _skyboxSize(0)
51{
52    setDataVariance(osg::Object::DYNAMIC);
53    setUseVertexBufferObjects(false);
54    setUseDisplayList(false);
55        cloudLayerSlots.clear();
56        newCloudLayersToAdd = false;
57        sceneRoot = csn_;
58}
59
60void skySilverLining_skyDrawable::setLighting(SilverLining::Atmosphere *atmosphere) const
61{
62    osg::Light *light = _view->getLight();
63    osg::Vec4 ambient, diffuse;
64    osg::Vec3 direction;
65
66    if (atmosphere && light)
67    {
68        float ra, ga, ba, rd, gd, bd, x, y, z;
69        atmosphere->GetAmbientColor(&ra, &ga, &ba);
70        atmosphere->GetSunOrMoonColor(&rd, &gd, &bd);
71        atmosphere->GetSunOrMoonPosition(&x, &y, &z);
72
73        direction = osg::Vec3(x, y, z);
74        ambient = osg::Vec4(ra, ga, ba, 1.0);
75        diffuse = osg::Vec4(rd, gd, bd, 1.0);
76
77        // xform the light direction into camera coordinates
78        osg::Quat view = _view->getCamera()->getViewMatrix().getRotate();
79        //direction = view * direction;
80        direction.normalize();
81
82        light->setAmbient(ambient);
83        light->setDiffuse(diffuse);
84        light->setSpecular(osg::Vec4(0,0,0,1));
85        light->setPosition(osg::Vec4(direction.x(), direction.y(), direction.z(), 0));
86    }
87}
88
89void skySilverLining_skyDrawable::setSceneFog(SilverLining::Atmosphere *atmosphere) const
90{   
91        osg::ref_ptr<osg::Fog> fog = new osg::Fog;
92    fog->setMode(osg::Fog::EXP);
93        //fog->setUseRadialFog( true );
94
95        //_objectsNode  = erde oder object, das mit nebel bedacht werden soll   
96        sceneRoot->getOrCreateStateSet()->setAttributeAndModes(fog.get());
97
98        //float hazeR, hazeG, hazeB;
99        //double hazeDepth, hazeDensity;
100        //atmosphere->GetHaze(hazeR, hazeG, hazeB, hazeDepth, hazeDensity);
101
102    //hazeDensity = 1.0 / 40000;
103        //hazeDensity = 0;
104        float hazeDensity = 1.0 / atmosphere->GetConditions()->GetVisibility();
105
106    // Decrease fog density with altitude, to avoid fog effects through the vacuum of space.
107    static const double H = 8435.0; // Pressure scale height of Earth's atmosphere
108    double isothermalEffect = exp(-(atmosphere->GetConditions()->GetLocation().GetAltitude() / H));     
109    if (isothermalEffect <= 0) isothermalEffect = 1E-9;
110    if (isothermalEffect > 1.0) isothermalEffect = 1.0;
111    hazeDensity *= isothermalEffect;
112
113    bool silverLiningHandledTheFog = false;
114
115    if (atmosphere->GetFogEnabled())
116    {
117            float density, r, g, b;
118            // Note, the fog color returned is already lit
119            atmosphere->GetFogSettings(&density, &r, &g, &b);
120
121            if (density > hazeDensity)
122            {
123                                fog->setDensity(density);
124                                fog->setColor(osg::Vec4(r, g, b, 1.0));
125
126                                silverLiningHandledTheFog = true;
127            }
128    }
129   
130    if (!silverLiningHandledTheFog)
131    {
132                float r, g, b;
133                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. */
134
135                fog->setDensity(hazeDensity);
136                fog->setColor(osg::Vec4(r, g, b, 1.0));
137    }
138
139}
140
141void skySilverLining_skyDrawable::initializeSilverLining(skySilverLining_atmosphereReference *ar)
142{
143    if (ar && !ar->atmosphereInitialized)
144    {
145        ar->atmosphereInitialized = true; // only try once.
146                SilverLining::Atmosphere *atmosphere = ar->atmosphere;
147
148                if (atmosphere)
149        {
150                        srand(1234); // constant random seed to ensure consistent clouds across windows
151
152            // Update the path below to where you installed SilverLining's resources folder.
153            //int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "C:\\Program Files\\SilverLining SDK\\resources\\", true, 0);
154                        int ret = atmosphere->Initialize(SilverLining::Atmosphere::OPENGL, "../resources/sky_silverlining/", true, 0);
155            if (ret != SilverLining::Atmosphere::E_NOERROR)
156            {
157                printf("SilverLining failed to initialize; error code %d.\n", ret);
158                printf("Check that the path to the SilverLining installation directory is set properly ");
159                printf("in skySilverLining_skyDrawable.cpp (in SkyDrawable::initializeSilverLining)\n");
160                exit(0);
161            }
162
163            // Let SilverLining know which way is up. OSG usually has Z going up.
164            //atmosphere->SetUpVector(0, 0, 1);
165            //atmosphere->SetRightVector(1, 0, 0);
166                        atmosphere->SetUpVector(0.662994, 0.136169, 0.736136);
167                        atmosphere->SetRightVector(-0.201185, 0.979553, 0.0);
168
169            // Set our location (change this to your own latitude and longitude)
170            SilverLining::Location loc;
171            loc.SetAltitude(0);
172            loc.SetLatitude(47);
173            loc.SetLongitude(11);
174            atmosphere->GetConditions()->SetLocation(loc);
175
176            // Set the sstem time in PST
177            SilverLining::LocalTime t;
178            t.SetFromSystemTime();
179                        t.SetTimeZone(CET);
180            atmosphere->GetConditions()->SetTime(t);
181
182                        // Setting Up Visibility
183                        atmosphere->GetConditions()->SetVisibility(40000);
184
185                        // Setting Up Haze
186                        atmosphere->GetConditions()->SetTurbidity(2.2);
187
188                        atmosphere->GetConditions()->EnableTimePassage( true, 5000 );
189                       
190                }       // if atmosphere ENDE
191
192    }   // If atmosphere not initialized ENDE
193}
194
195void skySilverLining_skyDrawable::drawImplementation(osg::RenderInfo& renderInfo) const
196{
197        skySilverLining_atmosphereReference *ar = dynamic_cast<skySilverLining_atmosphereReference *>(renderInfo.getCurrentCamera()->getUserData());
198        SilverLining::Atmosphere *atmosphere = 0;
199
200        if (ar) atmosphere = ar->atmosphere;
201
202        renderInfo.getState()->disableAllVertexArrays();
203
204    if (atmosphere)
205    {
206        initializeSilverLining(ar);
207                const_cast<skySilverLining_skyDrawable*>(this)->seedAndAddCloudLayers(atmosphere);
208
209
210        atmosphere->BeginFrame(true, true, _skyboxSize);
211        setLighting(atmosphere);
212                setSceneFog(atmosphere);
213    }
214
215        renderInfo.getState()->dirtyAllVertexArrays();
216}
217
218void skySilverLining_skyDrawable::addCloudLayer(cloudLayerSlot *cloudLayerSlot_)
219{
220        OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
221        cloudLayerSlots.push_back( cloudLayerSlot_ );
222        newCloudLayersToAdd = true;
223}
224
225
226
227void skySilverLining_skyDrawable::seedAndAddCloudLayers(SilverLining::Atmosphere *atmosphere)
228{
229        // Only try to add if anything to do..
230        if ( newCloudLayersToAdd )
231        {
232                OpenThreads::ScopedLock<OpenThreads::Mutex> sLock(cloudLayersToAddMutex); 
233                for ( unsigned int i=0; cloudLayerSlots.size() > 0; i++)
234                {
235                        // Seed cloudLayer
236                        cloudLayerSlots.back()->cloudLayerPointer->SeedClouds(*atmosphere);
237
238                        //cloudLayerSlots.back()->cloudLayerPointer->SetEnabled( false );       // Todo: testing, please remove
239                        //cloudLayerSlots.back()->cloudLayerPointer->SetEnabled( true, 30000);  // Todo: testing, please remove
240
241                        // add cloudLayer to atmosphere
242                        cloudLayerSlots.back()->cloudLayerHandle = atmosphere->GetConditions()->AddCloudLayer( cloudLayerSlots.back()->cloudLayerPointer );
243
244                        // Delete this cloudLayer from the ToDo list.
245                        cloudLayerSlots.pop_back();
246                }
247
248                // Note nothing to do.
249                newCloudLayersToAdd = false;
250        }
251}
252
253void skySilverLining_skyDrawable::shutdown()
254{
255        sceneRoot = NULL;
256}
Note: See TracBrowser for help on using the repository browser.