]> git.mxchange.org Git - flightgear.git/blob - src/Objects/material.cxx
Moving towards increased dependence on ssg.
[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 <Include/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 <XGL/xgl.h>
40
41 #include STL_STRING
42
43 #include <Debug/logstream.hxx>
44 #include <Misc/fgpath.hxx>
45 #include <Misc/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     emissive[0] = emissive[1] = emissive[2] = emissive[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 == "emissive" ) {
90             in >> token >> m.emissive[0] >> m.emissive[1]
91                >> m.emissive[2] >> m.emissive[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 void
110 FGMaterial::load_texture( const string& root )
111 {
112     GLubyte *texbuf;
113     int width, height;
114
115     FG_LOG( FG_TERRAIN, FG_INFO,
116             "  Loading texture for material " << texture_name );
117
118     // create the texture object and bind it
119 #ifdef GL_VERSION_1_1
120     xglGenTextures(1, &texture_id );
121     xglBindTexture(GL_TEXTURE_2D, texture_id );
122 #elif GL_EXT_texture_object
123     xglGenTexturesEXT(1, &texture_id );
124     xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
125 #else
126 #  error port me
127 #endif
128
129     // set the texture parameters back to the defaults for loading
130     // this texture
131     xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
132     xglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
133     xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
134     xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
135
136     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
137     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
138     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
139     xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, 
140                       /* GL_LINEAR */ 
141                       /* GL_NEAREST_MIPMAP_LINEAR */
142                       GL_LINEAR_MIPMAP_LINEAR ) ;
143
144     // load in the texture data
145     FGPath base_path( root );
146     base_path.append( "Textures" );
147     base_path.append( texture_name );
148
149     FGPath tpath = base_path;
150     tpath.concat( ".rgb" );
151
152     FGPath fg_tpath = tpath;
153     fg_tpath.concat( ".gz" );
154
155     FGPath fg_raw_tpath = base_path;
156     fg_raw_tpath.concat( ".raw" );
157
158     // create string names for msfs compatible textures
159     FGPath fg_r8_tpath = base_path;
160     fg_r8_tpath.concat( ".r8" );
161
162     FGPath fg_tex_tpath = base_path;
163     fg_tex_tpath.concat( ".txt" );
164
165     FGPath fg_pat_tpath = base_path;
166     fg_pat_tpath.concat( ".pat" );
167
168     FGPath fg_oav_tpath = base_path;
169     fg_oav_tpath.concat( ".oav" );
170
171     if ( alpha == 0 ) {
172         // load rgb texture
173
174         // Try uncompressed
175         if ( (texbuf = 
176               read_rgb_texture(tpath.c_str(), &width, &height)) != 
177              NULL )
178             ;
179         // Try compressed
180         else if ( (texbuf = 
181                    read_rgb_texture(fg_tpath.c_str(), &width, &height)) 
182                   != NULL )
183             ;
184         // Try raw
185         else if ( (texbuf = 
186                    read_raw_texture(fg_raw_tpath.c_str(), &width, &height)) 
187                   != NULL )
188             ;
189         // Try r8
190         else if ( (texbuf =
191                    read_r8_texture(fg_r8_tpath.c_str(), &width, &height)) 
192                   != NULL )
193             ;
194         // Try tex
195         else if ( (texbuf =
196                    read_r8_texture(fg_tex_tpath.c_str(), &width, &height)) 
197                   != NULL )
198             ;
199         // Try pat
200         else if ( (texbuf =
201                    read_r8_texture(fg_pat_tpath.c_str(), &width, &height)) 
202                   != NULL )
203             ;
204         // Try oav
205         else if ( (texbuf =
206                    read_r8_texture(fg_oav_tpath.c_str(), &width, &height)) 
207                   != NULL )
208             ;
209         else {
210             FG_LOG( FG_GENERAL, FG_ALERT, 
211                     "Error in loading texture " << tpath.str() );
212             exit(-1);
213         } 
214
215         if ( gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, 
216                                 GL_RGB, GL_UNSIGNED_BYTE, texbuf ) != 0 )
217         {
218             FG_LOG( FG_GENERAL, FG_ALERT, "Error building mipmaps");
219             exit(-1);
220         }
221     } else if ( alpha == 1 ) {
222         // load rgba (alpha) texture
223
224         // Try uncompressed
225         if ( (texbuf = 
226               read_alpha_texture(tpath.c_str(), &width, &height))
227              == NULL )
228         {
229             // Try compressed
230             if ((texbuf = 
231                  read_alpha_texture(fg_tpath.c_str(), &width, &height))
232                 == NULL )
233             {
234                 FG_LOG( FG_GENERAL, FG_ALERT, 
235                         "Error in loading texture " << tpath.str() );
236                 exit(-1);
237             } 
238         } 
239
240         xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
241                       GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
242     }
243
244     loaded = true;
245 }
246
247
248 // Destructor
249 FGMaterial::~FGMaterial ( void ) {
250 }