]> git.mxchange.org Git - flightgear.git/blob - src/Objects/material.cxx
Code reorganization.
[flightgear.git] / src / Objects / material.cxx
1 // material.cxx -- class to handle material properties
2 //
3 // Written by Curtis Olson, started May 1998.
4 //
5 // Copyright (C) 1998  Curtis L. Olson  - curt@me.umn.edu
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 FG_MATH_EXCEPTION_CLASH
31 #  include <math.h>
32 #endif
33
34 #ifdef HAVE_WINDOWS_H
35 #  include <windows.h>
36 #endif
37
38 #include <GL/glut.h>
39 #include <simgear/xgl.h>
40
41 #include STL_STRING
42
43 #include <simgear/logstream.hxx>
44 #include <simgear/fgpath.hxx>
45 #include <simgear/fgstream.hxx>
46
47 #include "material.hxx"
48 #include "texload.h"
49
50 FG_USING_STD(string);
51
52
53 // Constructor
54 FGMaterial::FGMaterial ( void )
55     : loaded(false),
56       texture_name(""),
57       alpha(0)
58     // , list_size(0)
59 {
60     ambient[0]  = ambient[1]  = ambient[2]  = ambient[3]  = 0.0;
61     diffuse[0]  = diffuse[1]  = diffuse[2]  = diffuse[3]  = 0.0;
62     specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
63     emission[0] = emission[1] = emission[2] = emission[3] = 0.0;
64 }
65
66
67 istream&
68 operator >> ( istream& in, FGMaterial& m )
69 {
70     string token;
71
72     for (;;) {
73         in >> token;
74         if ( token == "texture" ) {
75             in >> token >> m.texture_name;
76         } else if ( token == "xsize" ) {
77             in >> token >> m.xsize;
78         } else if ( token == "ysize" ) {
79             in >> token >> m.ysize;
80         } else if ( token == "ambient" ) {
81             in >> token >> m.ambient[0] >> m.ambient[1]
82                >> m.ambient[2] >> m.ambient[3];
83         } else if ( token == "diffuse" ) {
84             in >> token >> m.diffuse[0] >> m.diffuse[1]
85                >> m.diffuse[2] >> m.diffuse[3];
86         } else if ( token == "specular" ) {
87             in >> token >> m.specular[0] >> m.specular[1]
88                >> m.specular[2] >> m.specular[3];
89         } else if ( token == "emission" ) {
90             in >> token >> m.emission[0] >> m.emission[1]
91                >> m.emission[2] >> m.emission[3];
92         } else if ( token == "alpha" ) {
93             in >> token >> token;
94             if ( token == "yes" ) {
95                 m.alpha = 1;
96             } else if ( token == "no" ) {
97                 m.alpha = 0;
98             } else {
99                 FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
100             }
101         } else if ( token[0] == '}' ) {
102             break;
103         }
104     }
105
106     return in;
107 }
108
109
110 void
111 FGMaterial::load_texture( const string& root )
112 {
113     GLubyte *texbuf;
114     int width, height;
115
116     FG_LOG( FG_TERRAIN, FG_INFO,
117             "  Loading texture for material " << texture_name );
118
119     // create the texture object and bind it
120 #ifdef GL_VERSION_1_1
121     xglGenTextures(1, &texture_id );
122     xglBindTexture(GL_TEXTURE_2D, texture_id );
123 #elif GL_EXT_texture_object
124     xglGenTexturesEXT(1, &texture_id );
125     xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
126 #else
127 #  error port me
128 #endif
129
130     // set the texture parameters back to the defaults for loading
131     // this texture
132     xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
133     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
134     xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
135     xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
136
137     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
138     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
139     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
140     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
141                       /* GL_LINEAR */ 
142                       /* GL_NEAREST_MIPMAP_LINEAR */
143                       GL_LINEAR_MIPMAP_LINEAR ) ;
144
145     // load in the texture data
146     FGPath base_path( root );
147     base_path.append( "Textures" );
148     base_path.append( texture_name );
149
150     FGPath tpath = base_path;
151     tpath.concat( ".rgb" );
152
153     FGPath fg_tpath = tpath;
154     fg_tpath.concat( ".gz" );
155
156     FGPath fg_raw_tpath = base_path;
157     fg_raw_tpath.concat( ".raw" );
158
159     // create string names for msfs compatible textures
160     FGPath fg_r8_tpath = base_path;
161     fg_r8_tpath.concat( ".r8" );
162
163     FGPath fg_tex_tpath = base_path;
164     fg_tex_tpath.concat( ".txt" );
165
166     FGPath fg_pat_tpath = base_path;
167     fg_pat_tpath.concat( ".pat" );
168
169     FGPath fg_oav_tpath = base_path;
170     fg_oav_tpath.concat( ".oav" );
171
172     if ( alpha == 0 ) {
173         // load rgb texture
174
175         // Try uncompressed
176         if ( (texbuf = 
177               read_rgb_texture(tpath.c_str(), &width, &height)) != 
178              NULL )
179             ;
180         // Try compressed
181         else if ( (texbuf = 
182                    read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
183                   != NULL )
184             ;
185         // Try raw
186         else if ( (texbuf = 
187                    read_raw_texture(fg_raw_tpath.c_str(), &width, &height)) 
188                   != NULL )
189             ;
190         // Try r8
191         else if ( (texbuf =
192                    read_r8_texture(fg_r8_tpath.c_str(), &width, &height)) 
193                   != NULL )
194             ;
195         // Try tex
196         else if ( (texbuf =
197                    read_r8_texture(fg_tex_tpath.c_str(), &width, &height)) 
198                   != NULL )
199             ;
200         // Try pat
201         else if ( (texbuf =
202                    read_r8_texture(fg_pat_tpath.c_str(), &width, &height)) 
203                   != NULL )
204             ;
205         // Try oav
206         else if ( (texbuf =
207                    read_r8_texture(fg_oav_tpath.c_str(), &width, &height)) 
208                   != NULL )
209             ;
210         else {
211             FG_LOG( FG_GENERAL, FG_ALERT, 
212                     "Error in loading texture " << tpath.str() );
213             exit(-1);
214         } 
215
216         if ( gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, 
217                                 GL_RGB, GL_UNSIGNED_BYTE, texbuf ) != 0 )
218         {
219             FG_LOG( FG_GENERAL, FG_ALERT, "Error building mipmaps");
220             exit(-1);
221         }
222     } else if ( alpha == 1 ) {
223         // load rgba (alpha) texture
224
225         // Try uncompressed
226         if ( (texbuf = 
227               read_alpha_texture(tpath.c_str(), &width, &height))
228              == NULL )
229         {
230             // Try compressed
231             if ((texbuf = 
232                  read_alpha_texture(fg_tpath.c_str(), &width, &height))
233                 == NULL )
234             {
235                 FG_LOG( FG_GENERAL, FG_ALERT, 
236                         "Error in loading texture " << tpath.str() );
237                 exit(-1);
238             } 
239         } 
240
241         xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
242                       GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
243     }
244
245     loaded = true;
246 }
247
248
249 // Destructor
250 void FGMaterial::dump_info () {
251     FG_LOG( FG_TERRAIN, FG_INFO, "{" << endl << "  texture = " 
252             << texture_name );
253     FG_LOG( FG_TERRAIN, FG_INFO, "  xsize = " << xsize );
254     FG_LOG( FG_TERRAIN, FG_INFO, "  ysize = " << ysize );
255     FG_LOG( FG_TERRAIN, FG_INFO, "  ambient = " << ambient[0] << " "
256             << ambient[1] <<" "<< ambient[2] <<" "<< ambient[3] );
257     FG_LOG( FG_TERRAIN, FG_INFO, "  diffuse = " << diffuse[0] << " " 
258             << diffuse[1] << " " << diffuse[2] << " " << diffuse[3] );
259     FG_LOG( FG_TERRAIN, FG_INFO, "  specular = " << specular[0] << " " 
260             << specular[1] << " " << specular[2] << " " << specular[3]);
261     FG_LOG( FG_TERRAIN, FG_INFO, "  emission = " << emission[0] << " " 
262             << emission[1] << " " << emission[2] << " " << emission[3]);
263     FG_LOG( FG_TERRAIN, FG_INFO, "  alpha = " << alpha << endl <<"}" );
264             
265 }
266
267
268 // Destructor
269 FGMaterial::~FGMaterial ( void ) {
270 }