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

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

Adding first version of osgVisual!!

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