1 // material.cxx -- class to handle material properties
3 // Written by Curtis Olson, started May 1998.
5 // Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
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.
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.
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.
28 #include <Include/compiler.h>
30 #ifdef FG_MATH_EXCEPTION_CLASH
43 #include <Debug/logstream.hxx>
44 #include <Misc/fgpath.hxx>
45 #include <Misc/fgstream.hxx>
47 #include "material.hxx"
54 FGMaterial::FGMaterial ( void )
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;
68 operator >> ( istream& in, FGMaterial& m )
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" ) {
94 if ( token == "yes" ) {
96 } else if ( token == "no" ) {
99 FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
101 } else if ( token[0] == '}' ) {
111 FGMaterial::load_texture( const string& root )
116 FG_LOG( FG_TERRAIN, FG_INFO,
117 " Loading texture for material " << texture_name );
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 );
130 // set the texture parameters back to the defaults for loading
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);
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,
142 /* GL_NEAREST_MIPMAP_LINEAR */
143 GL_LINEAR_MIPMAP_LINEAR ) ;
145 // load in the texture data
146 FGPath base_path( root );
147 base_path.append( "Textures" );
148 base_path.append( texture_name );
150 FGPath tpath = base_path;
151 tpath.concat( ".rgb" );
153 FGPath fg_tpath = tpath;
154 fg_tpath.concat( ".gz" );
156 FGPath fg_raw_tpath = base_path;
157 fg_raw_tpath.concat( ".raw" );
159 // create string names for msfs compatible textures
160 FGPath fg_r8_tpath = base_path;
161 fg_r8_tpath.concat( ".r8" );
163 FGPath fg_tex_tpath = base_path;
164 fg_tex_tpath.concat( ".txt" );
166 FGPath fg_pat_tpath = base_path;
167 fg_pat_tpath.concat( ".pat" );
169 FGPath fg_oav_tpath = base_path;
170 fg_oav_tpath.concat( ".oav" );
177 read_rgb_texture(tpath.c_str(), &width, &height)) !=
182 read_rgb_texture(fg_tpath.c_str(), &width, &height))
187 read_raw_texture(fg_raw_tpath.c_str(), &width, &height))
192 read_r8_texture(fg_r8_tpath.c_str(), &width, &height))
197 read_r8_texture(fg_tex_tpath.c_str(), &width, &height))
202 read_r8_texture(fg_pat_tpath.c_str(), &width, &height))
207 read_r8_texture(fg_oav_tpath.c_str(), &width, &height))
211 FG_LOG( FG_GENERAL, FG_ALERT,
212 "Error in loading texture " << tpath.str() );
216 if ( gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
217 GL_RGB, GL_UNSIGNED_BYTE, texbuf ) != 0 )
219 FG_LOG( FG_GENERAL, FG_ALERT, "Error building mipmaps");
222 } else if ( alpha == 1 ) {
223 // load rgba (alpha) texture
227 read_alpha_texture(tpath.c_str(), &width, &height))
232 read_alpha_texture(fg_tpath.c_str(), &width, &height))
235 FG_LOG( FG_GENERAL, FG_ALERT,
236 "Error in loading texture " << tpath.str() );
241 xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
242 GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
250 void FGMaterial::dump_info () {
251 FG_LOG( FG_TERRAIN, FG_INFO, "{" << endl << " texture = "
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 <<"}" );
269 FGMaterial::~FGMaterial ( void ) {