]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/CloudShaderGeometry.cxx
87905434ec31489760dc55211330f2a4e60f10c3
[simgear.git] / simgear / scene / sky / CloudShaderGeometry.cxx
1 /* -*-c++-*-
2  *
3  * Copyright (C) 2008 Stuart Buchanan
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License as
7  * published by the Free Software Foundation; either version 2 of the
8  * License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful, but
11  * WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston,
18  * MA 02110-1301, USA.
19  *
20  */
21
22 #include <osgDB/Registry>
23 #include <osgDB/Input>
24 #include <osgDB/ParameterOutput>
25
26 #include "CloudShaderGeometry.hxx"
27
28 #include <simgear/props/props.hxx>
29
30 using namespace osg;
31 using namespace osgDB;
32
33 namespace simgear
34 {
35 void CloudShaderGeometry::drawImplementation(RenderInfo& renderInfo) const
36 {
37     if (!_cloudsprites.size()) return;
38     
39     osg::State& state = *renderInfo.getState();
40     osg::Matrix vm = state.getModelViewMatrix();
41     
42     //TODO: It isn't clear whether this is worth the perf hit ATM.
43     
44     // Transform the viewing direction, represented by the eye space vector (0,0,-1, 0), into model-space
45     // (here we simply take the opposite direction and reverse the ordering when sorting)
46     osg::Vec3f view_dir(vm(0, 2), vm(1, 2), vm(2, 2));      // Caveat: OpenSceneGraph matrices are transposed!
47
48     float p = view_dir*_cloudsprites[0]->position.osg();
49     // Do a single iteration of a bubble sort, sorting
50     // back to front.
51     for(int i = 0; i < _cloudsprites.size() - 1; i++)
52     {
53         float q = view_dir*_cloudsprites[i+1]->position.osg();
54         if (p > q) {  
55             CloudSprite c = *_cloudsprites[i];
56             *_cloudsprites[i] = *_cloudsprites[i+1];
57             *_cloudsprites[i+1] = c;
58         }
59         else
60             p = q;
61     }
62
63     const Extensions* extensions = getExtensions(state.getContextID(),true);
64
65     for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t)
66     {
67         extensions->glVertexAttrib1f(TEXTURE_INDEX_X, (GLfloat) (*t)->texture_index_x/varieties_x);
68         extensions->glVertexAttrib1f(TEXTURE_INDEX_Y, (GLfloat) (*t)->texture_index_y/varieties_y);
69         extensions->glVertexAttrib1f(WIDTH, (GLfloat) (*t)->width);
70         extensions->glVertexAttrib1f(HEIGHT, (GLfloat) (*t)->height);
71         extensions->glVertexAttrib1f(SHADE, (GLfloat) (*t)->shade);
72         extensions->glVertexAttrib1f(CLOUD_HEIGHT, (GLfloat) (*t)->cloud_height);
73         glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0);
74         _geometry->draw(renderInfo);
75     }
76 }
77
78 BoundingBox CloudShaderGeometry::computeBound() const
79 {
80     BoundingBox geom_box = _geometry->getBound();
81     BoundingBox bb;
82     for(CloudSpriteList::const_iterator itr = _cloudsprites.begin();
83         itr != _cloudsprites.end();
84         ++itr) {
85          bb.expandBy(geom_box.corner(0)*(*itr)->width +
86                  osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
87          bb.expandBy(geom_box.corner(7)*(*itr)->height +
88                  osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
89     }
90     return bb;
91 }
92
93 bool CloudShaderGeometry_readLocalData(Object& obj, Input& fr)
94 {
95     bool iteratorAdvanced = false;
96
97     CloudShaderGeometry& geom = static_cast<CloudShaderGeometry&>(obj);
98
99     if ((fr[0].matchWord("geometry"))) {
100         ++fr;
101         iteratorAdvanced = true;
102         osg::Drawable* drawable = fr.readDrawable();
103         if (drawable) {
104             geom._geometry = drawable;
105         }
106     }
107     if ((fr.matchSequence("instances %i"))) {
108         int entry = fr[0].getNoNestedBrackets();
109         int capacity;
110         fr[1].getInt(capacity);
111         geom._cloudsprites.reserve(capacity);
112         fr += 3;
113         iteratorAdvanced = true;
114         // skip {
115         while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
116             SGVec3f v;
117             int tx, ty;
118             float w, h, s, ch;
119             if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())
120                 && fr[2].getFloat(v.z()) && fr[3].getInt(tx) && fr[4].getInt(ty) &&  
121                 fr[5].getFloat(w) && fr[6].getFloat(h)&& fr[7].getFloat(s) && fr[8].getFloat(ch)) {
122                     fr += 5;
123                     //SGVec3f* v = new SGVec3f(v.x(), v.y(), v.z());
124                     geom._cloudsprites.push_back(new CloudShaderGeometry::CloudSprite(v, tx, ty, w, h,s,ch));
125             } else {
126                 ++fr;
127             }
128         }
129     }
130     return iteratorAdvanced;
131 }
132
133 bool CloudShaderGeometry_writeLocalData(const Object& obj, Output& fw)
134 {
135     const CloudShaderGeometry& geom = static_cast<const CloudShaderGeometry&>(obj);
136
137     fw.indent() << "geometry" << std::endl;
138     fw.writeObject(*geom._geometry);
139     fw.indent() << "instances " << geom._cloudsprites.size() << std::endl;
140     fw.indent() << "{" << std::endl;
141     fw.moveIn();
142     for (CloudShaderGeometry::CloudSpriteList::const_iterator itr
143              = geom._cloudsprites.begin();
144          itr != geom._cloudsprites.end();
145          ++itr) {
146              fw.indent() << (*itr)->position.x() << " " << (*itr)->position.y() << " " 
147                      << (*itr)->position.z() << " " << (*itr)->texture_index_x << " "
148                      << (*itr)->texture_index_y << " "  << (*itr)->width << " " 
149                      << (*itr)->height << " " << (*itr)->shade 
150                      << (*itr)->cloud_height << " "<< std::endl;
151     }
152     fw.moveOut();
153     fw.indent() << "}" << std::endl;
154     return true;
155 }
156
157
158 osgDB::RegisterDotOsgWrapperProxy cloudShaderGeometryProxy
159 (
160     new CloudShaderGeometry,
161     "CloudShaderGeometry",
162     "Object Drawable CloudShaderGeometry",
163     &CloudShaderGeometry_readLocalData,
164     &CloudShaderGeometry_writeLocalData
165     );
166 }