1999-05-13 02:34:49 +00:00
|
|
|
// material.cxx -- class to handle material properties
|
|
|
|
//
|
|
|
|
// Written by Curtis Olson, started May 1998.
|
|
|
|
//
|
|
|
|
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
|
|
|
|
//
|
|
|
|
// This program is free software; you can redistribute it and/or
|
|
|
|
// modify it under the terms of the GNU General Public License as
|
|
|
|
// published by the Free Software Foundation; either version 2 of the
|
|
|
|
// License, or (at your option) any later version.
|
|
|
|
//
|
|
|
|
// This program is distributed in the hope that it will be useful, but
|
|
|
|
// WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
|
|
// General Public License for more details.
|
|
|
|
//
|
|
|
|
// You should have received a copy of the GNU General Public License
|
|
|
|
// along with this program; if not, write to the Free Software
|
|
|
|
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
|
|
|
//
|
|
|
|
// $Id$
|
|
|
|
|
|
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
|
|
# include <config.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <Include/compiler.h>
|
|
|
|
|
|
|
|
#ifdef FG_MATH_EXCEPTION_CLASH
|
|
|
|
# include <math.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <GL/glut.h>
|
|
|
|
#include <XGL/xgl.h>
|
|
|
|
|
|
|
|
#include STL_STRING
|
|
|
|
|
|
|
|
#include <Debug/logstream.hxx>
|
|
|
|
#include <Misc/fgpath.hxx>
|
|
|
|
#include <Misc/fgstream.hxx>
|
|
|
|
|
|
|
|
#include "material.hxx"
|
|
|
|
#include "texload.h"
|
|
|
|
|
|
|
|
FG_USING_STD(string);
|
|
|
|
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
FGMaterial::FGMaterial ( void )
|
|
|
|
: loaded(false),
|
|
|
|
texture_name(""),
|
|
|
|
alpha(0)
|
|
|
|
// , list_size(0)
|
|
|
|
{
|
|
|
|
ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
|
|
|
|
diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
|
|
|
|
specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
|
|
|
|
emissive[0] = emissive[1] = emissive[2] = emissive[3] = 0.0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
istream&
|
|
|
|
operator >> ( istream& in, FGMaterial& m )
|
|
|
|
{
|
|
|
|
string token;
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
in >> token;
|
|
|
|
if ( token == "texture" ) {
|
|
|
|
in >> token >> m.texture_name;
|
|
|
|
} else if ( token == "xsize" ) {
|
|
|
|
in >> token >> m.xsize;
|
|
|
|
} else if ( token == "ysize" ) {
|
|
|
|
in >> token >> m.ysize;
|
|
|
|
} else if ( token == "ambient" ) {
|
|
|
|
in >> token >> m.ambient[0] >> m.ambient[1]
|
|
|
|
>> m.ambient[2] >> m.ambient[3];
|
|
|
|
} else if ( token == "diffuse" ) {
|
|
|
|
in >> token >> m.diffuse[0] >> m.diffuse[1]
|
|
|
|
>> m.diffuse[2] >> m.diffuse[3];
|
|
|
|
} else if ( token == "specular" ) {
|
|
|
|
in >> token >> m.specular[0] >> m.specular[1]
|
|
|
|
>> m.specular[2] >> m.specular[3];
|
|
|
|
} else if ( token == "emissive" ) {
|
|
|
|
in >> token >> m.emissive[0] >> m.emissive[1]
|
|
|
|
>> m.emissive[2] >> m.emissive[3];
|
|
|
|
} else if ( token == "alpha" ) {
|
|
|
|
in >> token >> token;
|
|
|
|
if ( token == "yes" ) {
|
|
|
|
m.alpha = 1;
|
|
|
|
} else if ( token == "no" ) {
|
|
|
|
m.alpha = 0;
|
|
|
|
} else {
|
|
|
|
FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
|
|
|
|
}
|
|
|
|
} else if ( token[0] == '}' ) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return in;
|
|
|
|
}
|
|
|
|
|
|
|
|
void
|
|
|
|
FGMaterial::load_texture( const string& root )
|
|
|
|
{
|
|
|
|
GLubyte *texbuf;
|
|
|
|
int width, height;
|
|
|
|
|
|
|
|
FG_LOG( FG_TERRAIN, FG_INFO,
|
|
|
|
" Loading texture for material " << texture_name );
|
|
|
|
|
|
|
|
// create the texture object and bind it
|
|
|
|
#ifdef GL_VERSION_1_1
|
|
|
|
xglGenTextures(1, &texture_id );
|
|
|
|
xglBindTexture(GL_TEXTURE_2D, texture_id );
|
|
|
|
#elif GL_EXT_texture_object
|
|
|
|
xglGenTexturesEXT(1, &texture_id );
|
|
|
|
xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
|
|
|
|
#else
|
|
|
|
# error port me
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// set the texture parameters for this texture
|
1999-05-13 19:01:29 +00:00
|
|
|
xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
|
1999-05-13 02:34:49 +00:00
|
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
|
|
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
|
1999-05-13 19:01:29 +00:00
|
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
|
1999-05-13 02:34:49 +00:00
|
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
|
|
/* GL_LINEAR */
|
|
|
|
/* GL_NEAREST_MIPMAP_LINEAR */
|
|
|
|
GL_LINEAR_MIPMAP_LINEAR ) ;
|
|
|
|
|
|
|
|
// load in the texture data
|
|
|
|
FGPath base_path( root );
|
|
|
|
base_path.append( "Textures" );
|
|
|
|
base_path.append( texture_name );
|
|
|
|
|
|
|
|
FGPath tpath = base_path;
|
|
|
|
tpath.concat( ".rgb" );
|
|
|
|
|
|
|
|
FGPath fg_tpath = tpath;
|
|
|
|
fg_tpath.concat( ".gz" );
|
|
|
|
|
|
|
|
FGPath fg_raw_tpath = base_path;
|
|
|
|
fg_raw_tpath.concat( ".raw" );
|
|
|
|
|
|
|
|
// create string names for msfs compatible textures
|
|
|
|
FGPath fg_r8_tpath = base_path;
|
|
|
|
fg_r8_tpath.concat( ".r8" );
|
|
|
|
|
|
|
|
FGPath fg_tex_tpath = base_path;
|
|
|
|
fg_tex_tpath.concat( ".txt" );
|
|
|
|
|
|
|
|
FGPath fg_pat_tpath = base_path;
|
|
|
|
fg_pat_tpath.concat( ".pat" );
|
|
|
|
|
|
|
|
FGPath fg_oav_tpath = base_path;
|
|
|
|
fg_oav_tpath.concat( ".oav" );
|
|
|
|
|
|
|
|
if ( alpha == 0 ) {
|
|
|
|
// load rgb texture
|
|
|
|
|
|
|
|
// Try uncompressed
|
|
|
|
if ( (texbuf =
|
|
|
|
read_rgb_texture(tpath.c_str(), &width, &height)) !=
|
|
|
|
NULL )
|
|
|
|
;
|
|
|
|
// Try compressed
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_rgb_texture(fg_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
|
|
|
// Try raw
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_raw_texture(fg_raw_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
|
|
|
// Try r8
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_r8_texture(fg_r8_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
|
|
|
// Try tex
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_r8_texture(fg_tex_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
|
|
|
// Try pat
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_r8_texture(fg_pat_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
|
|
|
// Try oav
|
|
|
|
else if ( (texbuf =
|
|
|
|
read_r8_texture(fg_oav_tpath.c_str(), &width, &height))
|
|
|
|
!= NULL )
|
|
|
|
;
|
1999-05-13 19:01:29 +00:00
|
|
|
else {
|
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
|
|
"Error in loading texture " << tpath.str() );
|
|
|
|
exit(-1);
|
|
|
|
}
|
1999-05-13 02:34:49 +00:00
|
|
|
|
1999-05-13 19:01:29 +00:00
|
|
|
if ( gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
|
|
|
|
GL_RGB, GL_UNSIGNED_BYTE, texbuf ) != 0 )
|
1999-05-13 19:08:10 +00:00
|
|
|
{
|
1999-05-13 19:01:29 +00:00
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Error building mipmaps");
|
|
|
|
exit(-1);
|
|
|
|
}
|
1999-05-13 02:34:49 +00:00
|
|
|
} else if ( alpha == 1 ) {
|
|
|
|
// load rgba (alpha) texture
|
|
|
|
|
|
|
|
// Try uncompressed
|
|
|
|
if ( (texbuf =
|
|
|
|
read_alpha_texture(tpath.c_str(), &width, &height))
|
|
|
|
== NULL )
|
|
|
|
{
|
|
|
|
// Try compressed
|
|
|
|
if ((texbuf =
|
|
|
|
read_alpha_texture(fg_tpath.c_str(), &width, &height))
|
|
|
|
== NULL )
|
|
|
|
{
|
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
|
|
"Error in loading texture " << tpath.str() );
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
|
|
|
GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
|
|
|
|
}
|
|
|
|
|
|
|
|
loaded = true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Destructor
|
|
|
|
FGMaterial::~FGMaterial ( void ) {
|
|
|
|
}
|