]> git.mxchange.org Git - simgear.git/blob - simgear/scene/material/mat.hxx
Use Effects in materials library, and therefore in scenery
[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
43 namespace osg
44 {
45 class StateSet;
46 }
47
48 #include <simgear/props/props.hxx>
49 #include <simgear/structure/SGSharedPtr.hxx>
50 #include <simgear/scene/util/SGSceneFeatures.hxx>
51
52 #include "matmodel.hxx"
53
54 namespace simgear
55 {
56 class Effect;
57 }
58
59 class SGMaterialGlyph;
60
61 /**
62  * A material in the scene graph.
63  *
64  * A material represents information about a single surface type
65  * in the 3D scene graph, including texture, colour, lighting,
66  * tiling, and so on; most of the materials in FlightGear are
67  * defined in the $FG_ROOT/materials.xml file, and can be changed
68  * at runtime.
69  */
70 class SGMaterial : public SGReferenced {
71
72 public:
73
74 \f
75   ////////////////////////////////////////////////////////////////////
76   // Public Constructors.
77   ////////////////////////////////////////////////////////////////////
78
79   /**
80    * Construct a material from a set of properties.
81    *
82    * @param props A property node containing subnodes with the
83    * state information for the material.  This node is usually
84    * loaded from the $FG_ROOT/materials.xml file.
85    */
86   SGMaterial( const std::string &fg_root, const SGPropertyNode *props);
87
88
89   /**
90    * Construct a material from an absolute texture path.
91    *
92    * @param texture_path A string containing an absolute path
93    * to a texture file (usually RGB).
94    */
95   SGMaterial( const std::string &texpath );
96
97
98   /**
99    * Construct a material around an existing state.
100    *
101    * This constructor allows the application to create a custom,
102    * low-level state for the scene graph and wrap a material around
103    * it.  Note: the pointer ownership is transferred to the material.
104    *
105    * @param s The state for this material.
106    */
107   SGMaterial( osg::StateSet *s );
108
109   /**
110    * Destructor.
111    */
112   ~SGMaterial( void );
113
114
115 \f
116   ////////////////////////////////////////////////////////////////////
117   // Public methods.
118   ////////////////////////////////////////////////////////////////////
119
120   /**
121    * Get the textured state.
122    */
123   osg::StateSet *get_state (int n = -1);
124   simgear::Effect *get_effect(int n = -1);
125
126   /**
127    * Get the number of textures assigned to this material.
128    */
129   inline int get_num() const { return _status.size(); }
130
131
132   /**
133    * Get the xsize of the texture, in meters.
134    */
135   inline double get_xsize() const { return xsize; }
136
137
138   /**
139    * Get the ysize of the texture, in meters.
140    */
141   inline double get_ysize() const { return ysize; }
142
143
144   /**
145    * Get the light coverage.
146    *
147    * A smaller number means more generated night lighting.
148    *
149    * @return The area (m^2) covered by each light.
150    */
151   inline double get_light_coverage () const { return light_coverage; }
152
153   /**
154    * Get the forest coverage.
155    *
156    * A smaller number means more generated forest canopy.
157    *
158    * @return The area (m^2) covered by each canopy.
159    */
160   inline double get_tree_coverage () const { return tree_coverage; }
161
162   /**
163    * Get the forest height.
164    *
165    * @return The average height of the trees.
166    */
167   inline double get_tree_height () const { return tree_height; }
168
169   /**
170    * Get the forest width.
171    *
172    * @return The average width of the trees.
173    */
174   inline double get_tree_width () const { return tree_width; }
175
176   /**
177    * Get the forest LoD range.
178    *
179    * @return The LoD range for the trees.
180    */
181   inline double get_tree_range () const { return tree_range; }
182   
183   /**
184    * Get the number of tree varieties available
185    *
186    * @return the number of different trees defined in the texture strip
187    */
188   inline int get_tree_varieties () const { return tree_varieties; }
189   
190   /**
191    * Get the texture strip to use for trees
192    *
193    * @return the texture to use for trees.
194    */
195   inline std::string get_tree_texture () const { return  tree_texture; }
196
197   /**
198    * Return if the surface material is solid, if it is not solid, a fluid
199    * can be assumed, that is usually water.
200    */
201   bool get_solid () const { return solid; }
202
203   /**
204    * Get the friction factor for that material
205    */
206   double get_friction_factor () const { return friction_factor; }
207
208   /**
209    * Get the rolling friction for that material
210    */
211   double get_rolling_friction () const { return rolling_friction; }
212
213   /**
214    * Get the bumpines for that material
215    */
216   double get_bumpiness () const { return bumpiness; }
217
218   /**
219    * Get the load resistance
220    */
221   double get_load_resistance () const { return load_resistance; }
222
223   /**
224    * Get the list of names for this material
225    */
226   const std::vector<std::string>& get_names() const { return _names; }
227
228   /**
229    * add the given name to the list of names this material is known
230    */
231   void add_name(const std::string& name) { _names.push_back(name); }
232
233   /**
234    * Get the number of randomly-placed objects defined for this material.
235    */
236   int get_object_group_count () const { return object_groups.size(); }
237
238   /**
239    * Get a randomly-placed object for this material.
240    */
241   SGMatModelGroup * get_object_group (int index) const {
242     return object_groups[index];
243   }
244
245   /**
246    * Return pointer to glyph class, or 0 if it doesn't exist.
247    */
248   SGMaterialGlyph * get_glyph (const std::string& name) const;
249
250   void set_light_color(const SGVec4f& color)
251   { emission = color; }
252   const SGVec4f& get_light_color() const
253   { return emission; }
254
255   SGVec2f get_tex_coord_scale() const
256   {
257     float tex_width = get_xsize();
258     float tex_height = get_ysize();
259
260     return SGVec2f((0 < tex_width) ? 1000.0f/tex_width : 1.0f,
261                    (0 < tex_height) ? 1000.0f/tex_height : 1.0f);
262   }
263
264 protected:
265
266 \f
267   ////////////////////////////////////////////////////////////////////
268   // Protected methods.
269   ////////////////////////////////////////////////////////////////////
270
271   /**
272    * Initialization method, invoked by all public constructors.
273    */
274   void init();
275
276 protected:
277
278   struct _internal_state {
279       _internal_state( osg::StateSet *s, const std::string &t, bool l );
280       osg::ref_ptr<osg::StateSet> state;
281       osg::ref_ptr<simgear::Effect> effect;
282       std::string texture_path;
283       bool texture_loaded;
284   };
285
286 private:
287
288 \f
289   ////////////////////////////////////////////////////////////////////
290   // Internal state.
291   ////////////////////////////////////////////////////////////////////
292
293   // texture status
294   std::vector<_internal_state> _status;
295
296   // Round-robin counter
297   mutable unsigned int _current_ptr;
298
299   // texture size
300   double xsize, ysize;
301
302   // wrap texture?
303   bool wrapu, wrapv;
304
305   // use mipmapping?
306   bool mipmap;
307
308   // coverage of night lighting.
309   double light_coverage;
310   
311   // coverage of trees
312   double tree_coverage;
313   
314   // Range at which trees become visible
315   double tree_range;
316
317   // Height of the tree
318   double tree_height;
319
320   // Width of the tree
321   double tree_width;
322
323   // Number of varieties of tree texture
324   int tree_varieties;
325
326   // True if the material is solid, false if it is a fluid
327   bool solid;
328
329   // the friction factor of that surface material
330   double friction_factor;
331
332   // the rolling friction of that surface material
333   double rolling_friction;
334
335   // the bumpiness of that surface material
336   double bumpiness;
337
338   // the load resistance of that surface material
339   double load_resistance;
340
341   // material properties
342   SGVec4f ambient, diffuse, specular, emission;
343   double shininess;
344
345   // the list of names for this material. May be empty.
346   std::vector<std::string> _names;
347
348   std::vector<SGSharedPtr<SGMatModelGroup> > object_groups;
349
350   // taxiway-/runway-sign texture elements
351   std::map<std::string, SGSharedPtr<SGMaterialGlyph> > glyphs;
352   
353   // Tree texture, typically a strip of applicable tree textures
354   std::string tree_texture;
355 \f
356   ////////////////////////////////////////////////////////////////////
357   // Internal constructors and methods.
358   ////////////////////////////////////////////////////////////////////
359
360   SGMaterial( const std::string &fg_root, const SGMaterial &mat ); // unimplemented
361
362   void read_properties( const std::string &fg_root, const SGPropertyNode *props );
363   void build_state( bool defer_tex_load );
364   void set_state( osg::StateSet *s );
365
366   void assignTexture( osg::StateSet *state, const std::string &fname, bool _wrapu = true, bool _wrapv = true, bool _mipmap = true );
367
368 };
369
370
371 class SGMaterialGlyph : public SGReferenced {
372 public:
373   SGMaterialGlyph(SGPropertyNode *);
374   inline double get_left() const { return _left; }
375   inline double get_right() const { return _right; }
376   inline double get_width() const { return _right - _left; }
377
378 protected:
379   double _left;
380   double _right;
381 };
382
383 class SGMaterialUserData : public osg::Referenced {
384 public:
385   SGMaterialUserData(const SGMaterial* material) :
386     mMaterial(material)
387   {}
388   const SGMaterial* getMaterial() const
389   { return mMaterial; }
390 private:
391   // this cannot be an SGSharedPtr since that would create a cicrular reference
392   // making it impossible to ever free the space needed by SGMaterial
393   const SGMaterial* mMaterial;
394 };
395
396 void
397 SGSetTextureFilter( int max);
398
399 int
400 SGGetTextureFilter();
401
402 #endif // _SG_MAT_HXX