]> git.mxchange.org Git - flightgear.git/blob - src/Objects/newmat.cxx
Removed unused alpha variable; more code cleanups and documentation.
[flightgear.git] / src / Objects / newmat.cxx
1 // newmat.cxx -- class to handle material properties
2 //
3 // Written by Curtis Olson, started May 1998.
4 //
5 // Copyright (C) 1998 - 2000  Curtis L. Olson  - curt@flightgear.org
6 //
7 // This program is free software; you can redistribute it and/or
8 // modify it under the terms of the GNU General Public License as
9 // published by the Free Software Foundation; either version 2 of the
10 // License, or (at your option) any later version.
11 //
12 // This program is distributed in the hope that it will be useful, but
13 // WITHOUT ANY WARRANTY; without even the implied warranty of
14 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15 // General Public License for more details.
16 //
17 // You should have received a copy of the GNU General Public License
18 // along with this program; if not, write to the Free Software
19 // Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 //
21 // $Id$
22
23
24 #ifdef HAVE_CONFIG_H
25 #  include <config.h>
26 #endif
27
28 #include <simgear/compiler.h>
29
30 #ifdef SG_MATH_EXCEPTION_CLASH
31 #  include <math.h>
32 #endif
33
34 #include <simgear/debug/logstream.hxx>
35 #include <simgear/misc/sg_path.hxx>
36 #include <simgear/misc/sgstream.hxx>
37
38 #include <Main/globals.hxx>
39 #include <Main/fg_props.hxx>
40
41 #include "newmat.hxx"
42
43
44 \f
45 ////////////////////////////////////////////////////////////////////////
46 // Local static functions.
47 ////////////////////////////////////////////////////////////////////////
48
49 /**
50  * Internal method to test whether a file exists.
51  *
52  * TODO: this should be moved to a SimGear library of local file
53  * functions.
54  */
55 static inline bool
56 local_file_exists( const string& path ) {
57     sg_gzifstream in( path );
58     if ( ! in.is_open() ) {
59         return false;
60     } else {
61         return true;
62     }
63 }
64
65
66 \f
67 ////////////////////////////////////////////////////////////////////////
68 // Constructors and destructor.
69 ////////////////////////////////////////////////////////////////////////
70
71
72 FGNewMat::FGNewMat (const SGPropertyNode * props)
73 {
74     init();
75     read_properties(props);
76     build_ssg_state(false);
77 }
78
79 FGNewMat::FGNewMat (const string &texture_path)
80 {
81     init();
82     build_ssg_state(true);
83 }
84
85 FGNewMat::FGNewMat (ssgSimpleState * s)
86 {
87     init();
88     set_ssg_state(s);
89 }
90
91 FGNewMat::~FGNewMat (void)
92 {
93 }
94
95
96 \f
97 ////////////////////////////////////////////////////////////////////////
98 // Public methods.
99 ////////////////////////////////////////////////////////////////////////
100
101 void
102 FGNewMat::read_properties (const SGPropertyNode * props)
103 {
104                                 // Get the path to the texture
105   string tname = props->getStringValue("texture", "unknown.rgb");
106   SGPath tpath(globals->get_fg_root());
107   tpath.append("Textures.high");
108   tpath.append(tname);
109   if (!local_file_exists(tpath.str())) {
110     tpath = SGPath(globals->get_fg_root());
111     tpath.append("Textures");
112     tpath.append(tname);
113   }
114   texture_path = tpath.str();
115
116   xsize = props->getDoubleValue("xsize", 0.0);
117   ysize = props->getDoubleValue("ysize", 0.0);
118   wrapu = props->getBoolValue("wrapu", true);
119   wrapv = props->getBoolValue("wrapv", true);
120   mipmap = props->getBoolValue("mipmap", true);
121   light_coverage = props->getDoubleValue("light-coverage");
122
123   ambient[0] = props->getDoubleValue("ambient/r", 0.0);
124   ambient[1] = props->getDoubleValue("ambient/g", 0.0);
125   ambient[2] = props->getDoubleValue("ambient/b", 0.0);
126   ambient[3] = props->getDoubleValue("ambient/a", 0.0);
127
128   diffuse[0] = props->getDoubleValue("diffuse/r", 0.0);
129   diffuse[1] = props->getDoubleValue("diffuse/g", 0.0);
130   diffuse[2] = props->getDoubleValue("diffuse/b", 0.0);
131   diffuse[3] = props->getDoubleValue("diffuse/a", 0.0);
132
133   specular[0] = props->getDoubleValue("specular/r", 0.0);
134   specular[1] = props->getDoubleValue("specular/g", 0.0);
135   specular[2] = props->getDoubleValue("specular/b", 0.0);
136   specular[3] = props->getDoubleValue("specular/a", 0.0);
137
138   emission[0] = props->getDoubleValue("emissive/r", 0.0);
139   emission[1] = props->getDoubleValue("emissive/g", 0.0);
140   emission[2] = props->getDoubleValue("emissive/b", 0.0);
141   emission[3] = props->getDoubleValue("emissive/a", 0.0);
142 }
143
144
145 \f
146 ////////////////////////////////////////////////////////////////////////
147 // Private methods.
148 ////////////////////////////////////////////////////////////////////////
149
150 void 
151 FGNewMat::init ()
152 {
153   texture_path = "";
154   state = 0;
155   textured = 0;
156   nontextured = 0;
157   xsize = 0;
158   ysize = 0;
159   wrapu = true;
160   wrapv = true;
161   mipmap = true;
162   texture_loaded = false;
163   refcount = 0;
164   for (int i = 0; i < 4; i++)
165     ambient[i] = diffuse[i] = specular[i] = emission[i] = 0.0;
166 }
167
168 bool
169 FGNewMat::load_texture ()
170 {
171   if (texture_loaded) {
172     return false;
173   } else {
174     SG_LOG( SG_GENERAL, SG_INFO, "Loading deferred texture " << texture_path );
175 #ifdef PLIB_1_2_X
176     textured->setTexture((char *)texture_path.c_str(), wrapu, wrapv );
177 #else
178     textured->setTexture((char *)texture_path.c_str(), wrapu, wrapv, mipmap );
179 #endif
180     texture_loaded = true;
181     return true;
182   }
183 }
184
185
186 void 
187 FGNewMat::build_ssg_state (bool defer_tex_load)
188 {
189     GLenum shade_model =
190       (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
191     bool texture_default = fgGetBool("/sim/rendering/textures");
192
193     state = new ssgStateSelector(2);
194     state->ref();
195
196     textured = new ssgSimpleState();
197     textured->ref();
198
199     nontextured = new ssgSimpleState();
200     nontextured->ref();
201
202     // Set up the textured state
203     textured->setShadeModel( shade_model );
204     textured->enable( GL_LIGHTING );
205     textured->enable ( GL_CULL_FACE ) ;
206     textured->enable( GL_TEXTURE_2D );
207     textured->disable( GL_BLEND );
208     textured->disable( GL_ALPHA_TEST );
209     if ( !defer_tex_load ) {
210         textured->setTexture( (char *)texture_path.c_str(), wrapu, wrapv );
211         texture_loaded = true;
212     } else {
213         texture_loaded = false;
214     }
215     textured->enable( GL_COLOR_MATERIAL );
216     textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
217     textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
218     textured->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
219
220     // Set up the coloured state
221     nontextured->enable( GL_LIGHTING );
222     nontextured->setShadeModel( shade_model );
223     nontextured->enable ( GL_CULL_FACE      ) ;
224     nontextured->disable( GL_TEXTURE_2D );
225     nontextured->disable( GL_BLEND );
226     nontextured->disable( GL_ALPHA_TEST );
227     nontextured->disable( GL_COLOR_MATERIAL );
228
229     nontextured->setMaterial ( GL_AMBIENT, 
230                                ambient[0], ambient[1], 
231                                ambient[2], ambient[3] ) ;
232     nontextured->setMaterial ( GL_DIFFUSE, 
233                                diffuse[0], diffuse[1], 
234                                diffuse[2], diffuse[3] ) ;
235     nontextured->setMaterial ( GL_SPECULAR, 
236                                specular[0], specular[1], 
237                                specular[2], specular[3] ) ;
238     nontextured->setMaterial ( GL_EMISSION, 
239                                emission[0], emission[1], 
240                                emission[2], emission[3] ) ;
241
242     state->setStep( 0, textured );    // textured
243     state->setStep( 1, nontextured ); // untextured
244
245     // Choose the appropriate starting state.
246     if ( texture_default ) {
247         state->selectStep(0);
248     } else {
249         state->selectStep(1);
250     }
251 }
252
253
254 void FGNewMat::set_ssg_state( ssgSimpleState *s )
255 {
256     state = new ssgStateSelector(2);
257     state->ref();
258
259     textured = s;
260
261     nontextured = new ssgSimpleState();
262     nontextured->ref();
263
264     // Set up the coloured state
265     nontextured->enable( GL_LIGHTING );
266     nontextured->setShadeModel( GL_FLAT );
267     nontextured->enable ( GL_CULL_FACE      ) ;
268     nontextured->disable( GL_TEXTURE_2D );
269     nontextured->disable( GL_BLEND );
270     nontextured->disable( GL_ALPHA_TEST );
271     nontextured->disable( GL_COLOR_MATERIAL );
272
273     /* cout << "ambient = " << ambient[0] << "," << ambient[1] 
274        << "," << ambient[2] << endl; */
275     nontextured->setMaterial ( GL_AMBIENT, 
276                                ambient[0], ambient[1], 
277                                ambient[2], ambient[3] ) ;
278     nontextured->setMaterial ( GL_DIFFUSE, 
279                                diffuse[0], diffuse[1], 
280                                diffuse[2], diffuse[3] ) ;
281     nontextured->setMaterial ( GL_SPECULAR, 
282                                specular[0], specular[1], 
283                                specular[2], specular[3] ) ;
284     nontextured->setMaterial ( GL_EMISSION, 
285                                emission[0], emission[1], 
286                                emission[2], emission[3] ) ;
287
288     state->setStep( 0, textured );    // textured
289     state->setStep( 1, nontextured ); // untextured
290
291     // Choose the appropriate starting state.
292     state->selectStep(0);
293 }
294
295 // end of newmat.cxx