]> git.mxchange.org Git - simgear.git/blob - simgear/scene/sky/CloudShaderGeometry.cxx
eaa9450fe9ea1f36f2345462e12605e0dffb4447
[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     osg::State& state = *renderInfo.getState();
38     osg::Matrix vm = state.getModelViewMatrix();
39     
40     //TODO: It isn't clear whether this is worth the perf hit ATM.
41     
42     // Do a single iteration of a bubble sort. We do this in reverse
43     // so that elements closest to the camera bubble to the front than
44     // the elements further away
45     for(int i = (_cloudsprites.size() -2); i >= 0; i--)
46     {
47         osg::Vec4f p = vm * osg::Vec4f(_cloudsprites[i]->position.osg(),   1.0f);
48         osg::Vec4f q = vm * osg::Vec4f(_cloudsprites[i+1]->position.osg(), 1.0f);
49         
50         if (p.z() > q.z())
51         {
52             CloudSprite c = *_cloudsprites[i];
53             *_cloudsprites[i] = *_cloudsprites[i+1];
54             *_cloudsprites[i+1] = c;
55         }
56     }
57     
58     const Extensions* extensions = getExtensions(state.getContextID(),true);
59
60     for(CloudSpriteList::const_iterator t = _cloudsprites.begin(); t != _cloudsprites.end(); ++t)
61     {
62         extensions->glVertexAttrib1f(TEXTURE_INDEX_X, (GLfloat) (*t)->texture_index_x/varieties_x);
63         extensions->glVertexAttrib1f(TEXTURE_INDEX_Y, (GLfloat) (*t)->texture_index_y/varieties_y);
64         extensions->glVertexAttrib1f(WIDTH, (GLfloat) (*t)->width);
65         extensions->glVertexAttrib1f(HEIGHT, (GLfloat) (*t)->height);
66         extensions->glVertexAttrib1f(SHADE, (GLfloat) (*t)->shade);
67         glColor4f((*t)->position.x(), (*t)->position.y(), (*t)->position.z(), 1.0);
68         _geometry->draw(renderInfo);
69     }
70 }
71
72 BoundingBox CloudShaderGeometry::computeBound() const
73 {
74     BoundingBox geom_box = _geometry->getBound();
75     BoundingBox bb;
76     for(CloudSpriteList::const_iterator itr = _cloudsprites.begin();
77         itr != _cloudsprites.end();
78         ++itr) {
79          bb.expandBy(geom_box.corner(0)*(*itr)->width +
80                  osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
81          bb.expandBy(geom_box.corner(7)*(*itr)->height +
82                  osg::Vec3( (*itr)->position.x(), (*itr)->position.y(), (*itr)->position.z() ));
83     }
84     return bb;
85 }
86
87 bool CloudShaderGeometry_readLocalData(Object& obj, Input& fr)
88 {
89     bool iteratorAdvanced = false;
90
91     CloudShaderGeometry& geom = static_cast<CloudShaderGeometry&>(obj);
92
93     if ((fr[0].matchWord("geometry"))) {
94         ++fr;
95         iteratorAdvanced = true;
96         osg::Drawable* drawable = fr.readDrawable();
97         if (drawable) {
98             geom._geometry = drawable;
99         }
100     }
101     if ((fr.matchSequence("instances %i"))) {
102         int entry = fr[0].getNoNestedBrackets();
103         int capacity;
104         fr[1].getInt(capacity);
105         geom._cloudsprites.reserve(capacity);
106         fr += 3;
107         iteratorAdvanced = true;
108         // skip {
109         while (!fr.eof() && fr[0].getNoNestedBrackets() > entry) {
110             SGVec3f v;
111             int tx, ty;
112             float w, h, s;
113             if (fr[0].getFloat(v.x()) && fr[1].getFloat(v.y())
114                 && fr[2].getFloat(v.z()) && fr[3].getInt(tx) && fr[3].getInt(ty) &&  
115                 fr[4].getFloat(w) && fr[4].getFloat(h)&& fr[4].getFloat(s)) {
116                     fr += 5;
117                     //SGVec3f* v = new SGVec3f(v.x(), v.y(), v.z());
118                     geom._cloudsprites.push_back(new CloudShaderGeometry::CloudSprite(v, tx, ty, w, h,s));
119             } else {
120                 ++fr;
121             }
122         }
123     }
124     return iteratorAdvanced;
125 }
126
127 bool CloudShaderGeometry_writeLocalData(const Object& obj, Output& fw)
128 {
129     const CloudShaderGeometry& geom = static_cast<const CloudShaderGeometry&>(obj);
130
131     fw.indent() << "geometry" << std::endl;
132     fw.writeObject(*geom._geometry);
133     fw.indent() << "instances " << geom._cloudsprites.size() << std::endl;
134     fw.indent() << "{" << std::endl;
135     fw.moveIn();
136     for (CloudShaderGeometry::CloudSpriteList::const_iterator itr
137              = geom._cloudsprites.begin();
138          itr != geom._cloudsprites.end();
139          ++itr) {
140              fw.indent() << (*itr)->position.x() << " " << (*itr)->position.y() << " " 
141                      << (*itr)->position.z() << " " << (*itr)->texture_index_x << " "
142                      << (*itr)->texture_index_y << " "  
143                      << (*itr)->width << " " << (*itr)->height << " " << (*itr)->shade << std::endl;
144     }
145     fw.moveOut();
146     fw.indent() << "}" << std::endl;
147     return true;
148 }
149
150
151 osgDB::RegisterDotOsgWrapperProxy cloudShaderGeometryProxy
152 (
153     new CloudShaderGeometry,
154     "CloudShaderGeometry",
155     "Object Drawable CloudShaderGeometry",
156     &CloudShaderGeometry_readLocalData,
157     &CloudShaderGeometry_writeLocalData
158     );
159 }