]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/mat.hxx
New effects from Till Busch: crops, water, landmass
[simgear.git] / simgear / scene / material / mat.hxx
1 // mat.hxx -- a material in the scene graph.
2 // TODO: this class needs to be renamed.
3 //
4 // Written by Curtis Olson, started May 1998.
5 // Overhauled by David Megginson, December 2001
6 //
7 // Copyright (C) 1998 - 2000  Curtis L. Olson  - http://www.flightgear.org/~curt
8 //
9 // This program is free software; you can redistribute it and/or
10 // modify it under the terms of the GNU General Public License as
11 // published by the Free Software Foundation; either version 2 of the
12 // License, or (at your option) any later version.
13 //
14 // This program is distributed in the hope that it will be useful, but
15 // WITHOUT ANY WARRANTY; without even the implied warranty of
16 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
17 // General Public License for more details.
18 //
19 // You should have received a copy of the GNU General Public License
20 // along with this program; if not, write to the Free Software
21 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
22 //
23 // $Id$
24
25
26 #ifndef _SG_MAT_HXX
27 #define _SG_MAT_HXX
28
29 #ifndef __cplusplus
30 # error This library requires C++
31 #endif
32
33 #include <simgear/compiler.h>
34
35 #include <string>      // Standard C++ string library
36 #include <vector>
37 #include <map>
38
39 #include <simgear/math/SGMath.hxx>
40
41 #include <osg/ref_ptr>
42 #include <osgDB/ReaderWriter>
43
44 namespace osg
45 {
46 class StateSet;
47 }
48
49 #include <simgear/props/props.hxx>
50 #include <simgear/structure/SGSharedPtr.hxx>
51 #include <simgear/scene/util/SGSceneFeatures.hxx>
52
53 #include "matmodel.hxx"
54
55 namespace simgear
56 {
57 class Effect;
58 void reload_shaders();
59 }
60
61 class SGMaterialGlyph;
62
63 /**
64  * A material in the scene graph.
65  *
66  * A material represents information about a single surface type
67  * in the 3D scene graph, including texture, colour, lighting,
68  * tiling, and so on; most of the materials in FlightGear are
69  * defined in the $FG_ROOT/materials.xml file, and can be changed
70  * at runtime.
71  */
72 class SGMaterial : public SGReferenced {
73
74 public:
75
76 \f
77   ////////////////////////////////////////////////////////////////////
78   // Public Constructors.
79   ////////////////////////////////////////////////////////////////////
80
81   /**
82    * Construct a material from a set of properties.
83    *
84    * @param props A property node containing subnodes with the
85    * state information for the material.  This node is usually
86    * loaded from the $FG_ROOT/materials.xml file.
87    */
88   SGMaterial( const osgDB::ReaderWriter::Options*, const SGPropertyNode *props);
89
90   /**
91    * Destructor.
92    */
93   ~SGMaterial( void );
94
95
96 \f
97   ////////////////////////////////////////////////////////////////////
98   // Public methods.
99   ////////////////////////////////////////////////////////////////////
100
101   /**
102    * Get the textured state.
103    */
104   simgear::Effect *get_effect(int n = -1);
105
106   /**
107    * Get the number of textures assigned to this material.
108    */
109   inline int get_num() const { return _status.size(); }
110
111
112   /**
113    * Get the xsize of the texture, in meters.
114    */
115   inline double get_xsize() const { return xsize; }
116
117
118   /**
119    * Get the ysize of the texture, in meters.
120    */
121   inline double get_ysize() const { return ysize; }
122
123
124   /**
125    * Get the light coverage.
126    *
127    * A smaller number means more generated night lighting.
128    *
129    * @return The area (m^2) covered by each light.
130    */
131   inline double get_light_coverage () const { return light_coverage; }
132
133   /**
134    * Get the forest coverage.
135    *
136    * A smaller number means more generated forest canopy.
137    *
138    * @return The area (m^2) covered by each canopy.
139    */
140   inline double get_tree_coverage () const { return tree_coverage; }
141
142   /**
143    * Get the forest height.
144    *
145    * @return The average height of the trees.
146    */
147   inline double get_tree_height () const { return tree_height; }
148
149   /**
150    * Get the forest width.
151    *
152    * @return The average width of the trees.
153    */
154   inline double get_tree_width () const { return tree_width; }
155
156   /**
157    * Get the forest LoD range.
158    *
159    * @return The LoD range for the trees.
160    */
161   inline double get_tree_range () const { return tree_range; }
162   
163   /**
164    * Get the number of tree varieties available
165    *
166    * @return the number of different trees defined in the texture strip
167    */
168   inline int get_tree_varieties () const { return tree_varieties; }
169   
170   /**
171    * Get the texture strip to use for trees
172    *
173    * @return the texture to use for trees.
174    */
175   inline std::string get_tree_texture () const { return  tree_texture; }
176
177   /**
178    * Return if the surface material is solid, if it is not solid, a fluid
179    * can be assumed, that is usually water.
180    */
181   bool get_solid () const { return solid; }
182
183   /**
184    * Get the friction factor for that material
185    */
186   double get_friction_factor () const { return friction_factor; }
187
188   /**
189    * Get the rolling friction for that material
190    */
191   double get_rolling_friction () const { return rolling_friction; }
192
193   /**
194    * Get the bumpines for that material
195    */
196   double get_bumpiness () const { return bumpiness; }
197
198   /**
199    * Get the load resistance
200    */
201   double get_load_resistance () const { return load_resistance; }
202
203   /**
204    * Get the list of names for this material
205    */
206   const std::vector<std::string>& get_names() const { return _names; }
207
208   /**
209    * add the given name to the list of names this material is known
210    */
211   void add_name(const std::string& name) { _names.push_back(name); }
212
213   /**
214    * Get the number of randomly-placed objects defined for this material.
215    */
216   int get_object_group_count () const { return object_groups.size(); }
217
218   /**
219    * Get a randomly-placed object for this material.
220    */
221   SGMatModelGroup * get_object_group (int index) const {
222     return object_groups[index];
223   }
224
225   /**
226    * Return pointer to glyph class, or 0 if it doesn't exist.
227    */
228   SGMaterialGlyph * get_glyph (const std::string& name) const;
229
230   void set_light_color(const SGVec4f& color)
231   { emission = color; }
232   const SGVec4f& get_light_color() const
233   { return emission; }
234
235   SGVec2f get_tex_coord_scale() const
236   {
237     float tex_width = get_xsize();
238     float tex_height = get_ysize();
239
240     return SGVec2f((0 < tex_width) ? 1000.0f/tex_width : 1.0f,
241                    (0 < tex_height) ? 1000.0f/tex_height : 1.0f);
242   }
243
244 protected:
245
246 \f
247   ////////////////////////////////////////////////////////////////////
248   // Protected methods.
249   ////////////////////////////////////////////////////////////////////
250
251   /**
252    * Initialization method, invoked by all public constructors.
253    */
254   void init();
255
256 protected:
257
258   struct _internal_state {
259       _internal_state(simgear::Effect *e, const std::string &t, bool l,
260                       const osgDB::ReaderWriter::Options *o);
261       osg::ref_ptr<simgear::Effect> effect;
262       std::string texture_path;
263       bool effect_realized;
264       osg::ref_ptr<const osgDB::ReaderWriter::Options> options;
265   };
266
267 private:
268
269 \f
270   ////////////////////////////////////////////////////////////////////
271   // Internal state.
272   ////////////////////////////////////////////////////////////////////
273
274   // texture status
275   std::vector<_internal_state> _status;
276
277   // Round-robin counter
278   mutable unsigned int _current_ptr;
279
280   // texture size
281   double xsize, ysize;
282
283   // wrap texture?
284   bool wrapu, wrapv;
285
286   // use mipmapping?
287   bool mipmap;
288
289   // coverage of night lighting.
290   double light_coverage;
291   
292   // coverage of trees
293   double tree_coverage;
294   
295   // Range at which trees become visible
296   double tree_range;
297
298   // Height of the tree
299   double tree_height;
300
301   // Width of the tree
302   double tree_width;
303
304   // Number of varieties of tree texture
305   int tree_varieties;
306
307   // True if the material is solid, false if it is a fluid
308   bool solid;
309
310   // the friction factor of that surface material
311   double friction_factor;
312
313   // the rolling friction of that surface material
314   double rolling_friction;
315
316   // the bumpiness of that surface material
317   double bumpiness;
318
319   // the load resistance of that surface material
320   double load_resistance;
321
322   // material properties
323   SGVec4f ambient, diffuse, specular, emission;
324   double shininess;
325
326   // effect for this material
327   std::string effect;
328
329   // the list of names for this material. May be empty.
330   std::vector<std::string> _names;
331
332   std::vector<SGSharedPtr<SGMatModelGroup> > object_groups;
333
334   // taxiway-/runway-sign texture elements
335   std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs;
336   
337   // Tree texture, typically a strip of applicable tree textures
338   std::string tree_texture;
339 \f
340   ////////////////////////////////////////////////////////////////////
341   // Internal constructors and methods.
342   ////////////////////////////////////////////////////////////////////
343
344   void read_properties(const osgDB::ReaderWriter::Options* options,
345                         const SGPropertyNode *props);
346   void buildEffectProperties(const osgDB::ReaderWriter::Options* options);
347 };
348
349
350 class SGMaterialGlyph : public SGReferenced {
351 public:
352   SGMaterialGlyph(SGPropertyNode *);
353   inline double get_left() const { return _left; }
354   inline double get_right() const { return _right; }
355   inline double get_width() const { return _right - _left; }
356
357 protected:
358   double _left;
359   double _right;
360 };
361
362 class SGMaterialUserData : public osg::Referenced {
363 public:
364   SGMaterialUserData(const SGMaterial* material) :
365     mMaterial(material)
366   {}
367   const SGMaterial* getMaterial() const
368   { return mMaterial; }
369 private:
370   // this cannot be an SGSharedPtr since that would create a cicrular reference
371   // making it impossible to ever free the space needed by SGMaterial
372   const SGMaterial* mMaterial;
373 };
374
375 void
376 SGSetTextureFilter( int max);
377
378 int
379 SGGetTextureFilter();
380
381 #endif // _SG_MAT_HXX