559 lines
15 KiB
C++
559 lines
15 KiB
C++
// 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$
|
|
// (Log is kept at end of this file)
|
|
|
|
|
|
#ifdef HAVE_CONFIG_H
|
|
# include <config.h>
|
|
#endif
|
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
# include <windows.h>
|
|
#endif
|
|
|
|
#include <GL/glut.h>
|
|
#include <XGL/xgl.h>
|
|
|
|
#include <Include/compiler.h>
|
|
|
|
#include <string.h>
|
|
#include STL_STRING
|
|
|
|
#include <Debug/logstream.hxx>
|
|
#include <Misc/fgstream.hxx>
|
|
#include <Main/options.hxx>
|
|
#include <Main/views.hxx>
|
|
#include <Scenery/tile.hxx>
|
|
|
|
#include "material.hxx"
|
|
#include "fragment.hxx"
|
|
#include "texload.h"
|
|
|
|
FG_USING_STD(string);
|
|
|
|
|
|
// global material management class
|
|
fgMATERIAL_MGR material_mgr;
|
|
|
|
|
|
// Constructor
|
|
fgMATERIAL::fgMATERIAL ( void )
|
|
: 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;
|
|
}
|
|
|
|
/*
|
|
int
|
|
fgMATERIAL::append_sort_list( fgFRAGMENT *object )
|
|
{
|
|
if ( list_size < FG_MAX_MATERIAL_FRAGS ) {
|
|
list[ list_size++ ] = object;
|
|
return 1;
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
*/
|
|
|
|
istream&
|
|
operator >> ( istream& in, fgMATERIAL& m )
|
|
{
|
|
string token;
|
|
|
|
for (;;) {
|
|
in >> token;
|
|
if ( token == "texture" )
|
|
{
|
|
in >> token >> m.texture_name;
|
|
}
|
|
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()
|
|
{
|
|
GLubyte *texbuf;
|
|
int width, height;
|
|
|
|
// 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
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ;
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
GL_LINEAR );
|
|
// xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
|
|
// GL_NEAREST_MIPMAP_NEAREST );
|
|
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
|
|
/* GL_LINEAR */
|
|
/* GL_NEAREST_MIPMAP_LINEAR */
|
|
GL_LINEAR_MIPMAP_LINEAR ) ;
|
|
|
|
/* load in the texture data */
|
|
string tpath = current_options.get_fg_root() + "/Textures/" +
|
|
texture_name + ".rgb";
|
|
string fg_tpath = tpath + ".gz";
|
|
|
|
if ( alpha == 0 ) {
|
|
// load rgb texture
|
|
|
|
// Try uncompressed
|
|
if ( (texbuf =
|
|
read_rgb_texture(tpath.c_str(), &width, &height)) ==
|
|
NULL )
|
|
{
|
|
// Try compressed
|
|
if ( (texbuf =
|
|
read_rgb_texture(fg_tpath.c_str(), &width, &height))
|
|
== NULL )
|
|
{
|
|
FG_LOG( FG_GENERAL, FG_ALERT,
|
|
"Error in loading texture " << tpath );
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
/* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0,
|
|
GL_RGB, GL_UNSIGNED_BYTE, texbuf); */
|
|
|
|
gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
|
|
GL_RGB, GL_UNSIGNED_BYTE, texbuf );
|
|
} 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 );
|
|
exit(-1);
|
|
}
|
|
}
|
|
|
|
xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
|
|
GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
|
|
}
|
|
}
|
|
|
|
|
|
// Destructor
|
|
fgMATERIAL::~fgMATERIAL ( void ) {
|
|
}
|
|
|
|
|
|
// Constructor
|
|
fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
|
|
textures_loaded = false;
|
|
}
|
|
|
|
|
|
void
|
|
fgMATERIAL::render_fragments()
|
|
{
|
|
int tris_rendered = current_view.get_tris_rendered();
|
|
|
|
// cout << "rendering " + texture_name + " = " << list_size << "\n";
|
|
|
|
if ( empty() )
|
|
return;
|
|
|
|
if ( current_options.get_textures() )
|
|
{
|
|
#ifdef GL_VERSION_1_1
|
|
xglBindTexture(GL_TEXTURE_2D, texture_id);
|
|
#elif GL_EXT_texture_object
|
|
xglBindTextureEXT(GL_TEXTURE_2D, texture_id);
|
|
#else
|
|
# error port me
|
|
#endif
|
|
} else {
|
|
xglMaterialfv (GL_FRONT, GL_AMBIENT, ambient);
|
|
xglMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse);
|
|
}
|
|
|
|
fgTILE* last_tile_ptr = NULL;
|
|
frag_list_iterator current = list.begin();
|
|
frag_list_iterator last = list.end();
|
|
|
|
for ( ; current != last; ++current ) {
|
|
fgFRAGMENT* frag_ptr = *current;
|
|
tris_rendered += frag_ptr->num_faces();
|
|
if ( frag_ptr->tile_ptr != last_tile_ptr )
|
|
{
|
|
// new tile, new translate
|
|
last_tile_ptr = frag_ptr->tile_ptr;
|
|
xglLoadMatrixd( frag_ptr->tile_ptr->model_view );
|
|
}
|
|
|
|
// Woohoo!!! We finally get to draw something!
|
|
// printf(" display_list = %d\n", frag_ptr->display_list);
|
|
xglCallList( frag_ptr->display_list );
|
|
}
|
|
|
|
current_view.set_tris_rendered( tris_rendered );
|
|
}
|
|
|
|
|
|
// Load a library of material properties
|
|
int
|
|
fgMATERIAL_MGR::load_lib ( void )
|
|
{
|
|
string material_name;
|
|
|
|
// build the path name to the material db
|
|
string mpath = current_options.get_fg_root() + "/materials";
|
|
fg_gzifstream in( mpath );
|
|
if ( ! in ) {
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
|
|
exit(-1);
|
|
}
|
|
|
|
while ( ! in.eof() ) {
|
|
// printf("%s", line);
|
|
|
|
// strip leading white space and comments
|
|
in >> skipcomment;
|
|
|
|
// set to zero to prevent its value accidently being '{'
|
|
// after a failed >> operation.
|
|
char token = 0;
|
|
|
|
in >> material_name >> token;
|
|
|
|
if ( token == '{' ) {
|
|
FG_LOG( FG_TERRAIN, FG_INFO,
|
|
" Loading material " << material_name );
|
|
fgMATERIAL m;
|
|
in >> m;
|
|
|
|
if ( current_options.get_textures() ) {
|
|
m.load_texture();
|
|
}
|
|
|
|
material_mgr.material_map[material_name] = m;
|
|
}
|
|
}
|
|
|
|
if ( current_options.get_textures() ) {
|
|
textures_loaded = true;
|
|
}
|
|
|
|
return(1);
|
|
}
|
|
|
|
|
|
// Initialize the transient list of fragments for each material property
|
|
void
|
|
fgMATERIAL_MGR::init_transient_material_lists( void )
|
|
{
|
|
iterator last = end();
|
|
for ( iterator it = begin(); it != last; ++it )
|
|
{
|
|
(*it).second.init_sort_list();
|
|
}
|
|
}
|
|
|
|
|
|
bool
|
|
fgMATERIAL_MGR::find( const string& material, fgMATERIAL*& mtl_ptr )
|
|
{
|
|
iterator it = material_map.find( material );
|
|
if ( it != end() )
|
|
{
|
|
mtl_ptr = &((*it).second);
|
|
return true;
|
|
}
|
|
|
|
return false;
|
|
}
|
|
|
|
|
|
// Destructor
|
|
fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
|
|
}
|
|
|
|
|
|
void
|
|
fgMATERIAL_MGR::render_fragments()
|
|
{
|
|
current_view.set_tris_rendered( 0 );
|
|
|
|
iterator last = end();
|
|
for ( iterator current = begin(); current != last; ++current )
|
|
(*current).second.render_fragments();
|
|
}
|
|
|
|
|
|
// $Log$
|
|
// Revision 1.14 1999/03/02 01:03:24 curt
|
|
// Tweaks for building with native SGI compilers.
|
|
//
|
|
// Revision 1.13 1999/02/26 22:09:58 curt
|
|
// Added initial support for native SGI compilers.
|
|
//
|
|
// Revision 1.12 1998/12/09 18:50:30 curt
|
|
// Converted "class fgVIEW" to "class FGView" and updated to make data
|
|
// members private and make required accessor functions.
|
|
//
|
|
// Revision 1.11 1998/11/07 19:07:12 curt
|
|
// Enable release builds using the --without-logging option to the configure
|
|
// script. Also a couple log message cleanups, plus some C to C++ comment
|
|
// conversion.
|
|
//
|
|
// Revision 1.10 1998/11/06 21:18:17 curt
|
|
// Converted to new logstream debugging facility. This allows release
|
|
// builds with no messages at all (and no performance impact) by using
|
|
// the -DFG_NDEBUG flag.
|
|
//
|
|
// Revision 1.9 1998/11/06 14:47:05 curt
|
|
// Changes to track Bernie's updates to fgstream.
|
|
//
|
|
// Revision 1.8 1998/10/12 23:49:17 curt
|
|
// Changes from NHV to make the code more dynamic with fewer hard coded limits.
|
|
//
|
|
// Revision 1.7 1998/09/17 18:35:52 curt
|
|
// Tweaks and optimizations by Norman Vine.
|
|
//
|
|
// Revision 1.6 1998/09/15 01:35:05 curt
|
|
// cleaned up my fragment.num_faces hack :-) to use the STL (no need in
|
|
// duplicating work.)
|
|
// Tweaked fgTileMgrRender() do not calc tile matrix unless necessary.
|
|
// removed some unneeded stuff from fgTileMgrCurElev()
|
|
//
|
|
// Revision 1.5 1998/09/10 19:07:11 curt
|
|
// /Simulator/Objects/fragment.hxx
|
|
// Nested fgFACE inside fgFRAGMENT since its not used anywhere else.
|
|
//
|
|
// ./Simulator/Objects/material.cxx
|
|
// ./Simulator/Objects/material.hxx
|
|
// Made fgMATERIAL and fgMATERIAL_MGR bona fide classes with private
|
|
// data members - that should keep the rabble happy :)
|
|
//
|
|
// ./Simulator/Scenery/tilemgr.cxx
|
|
// In viewable() delay evaluation of eye[0] and eye[1] in until they're
|
|
// actually needed.
|
|
// Change to fgTileMgrRender() to call fgMATERIAL_MGR::render_fragments()
|
|
// method.
|
|
//
|
|
// ./Include/fg_stl_config.h
|
|
// ./Include/auto_ptr.hxx
|
|
// Added support for g++ 2.7.
|
|
// Further changes to other files are forthcoming.
|
|
//
|
|
// Brief summary of changes required for g++ 2.7.
|
|
// operator->() not supported by iterators: use (*i).x instead of i->x
|
|
// default template arguments not supported,
|
|
// <functional> doesn't have mem_fun_ref() needed by callbacks.
|
|
// some std include files have different names.
|
|
// template member functions not supported.
|
|
//
|
|
// Revision 1.4 1998/09/01 19:03:08 curt
|
|
// Changes contributed by Bernie Bright <bbright@c031.aone.net.au>
|
|
// - The new classes in libmisc.tgz define a stream interface into zlib.
|
|
// I've put these in a new directory, Lib/Misc. Feel free to rename it
|
|
// to something more appropriate. However you'll have to change the
|
|
// include directives in all the other files. Additionally you'll have
|
|
// add the library to Lib/Makefile.am and Simulator/Main/Makefile.am.
|
|
//
|
|
// The StopWatch class in Lib/Misc requires a HAVE_GETRUSAGE autoconf
|
|
// test so I've included the required changes in config.tgz.
|
|
//
|
|
// There are a fair few changes to Simulator/Objects as I've moved
|
|
// things around. Loading tiles is quicker but thats not where the delay
|
|
// is. Tile loading takes a few tenths of a second per file on a P200
|
|
// but it seems to be the post-processing that leads to a noticeable
|
|
// blip in framerate. I suppose its time to start profiling to see where
|
|
// the delays are.
|
|
//
|
|
// I've included a brief description of each archives contents.
|
|
//
|
|
// Lib/Misc/
|
|
// zfstream.cxx
|
|
// zfstream.hxx
|
|
// C++ stream interface into zlib.
|
|
// Taken from zlib-1.1.3/contrib/iostream/.
|
|
// Minor mods for STL compatibility.
|
|
// There's no copyright associated with these so I assume they're
|
|
// covered by zlib's.
|
|
//
|
|
// fgstream.cxx
|
|
// fgstream.hxx
|
|
// FlightGear input stream using gz_ifstream. Tries to open the
|
|
// given filename. If that fails then filename is examined and a
|
|
// ".gz" suffix is removed or appended and that file is opened.
|
|
//
|
|
// stopwatch.hxx
|
|
// A simple timer for benchmarking. Not used in production code.
|
|
// Taken from the Blitz++ project. Covered by GPL.
|
|
//
|
|
// strutils.cxx
|
|
// strutils.hxx
|
|
// Some simple string manipulation routines.
|
|
//
|
|
// Simulator/Airports/
|
|
// Load airports database using fgstream.
|
|
// Changed fgAIRPORTS to use set<> instead of map<>.
|
|
// Added bool fgAIRPORTS::search() as a neater way doing the lookup.
|
|
// Returns true if found.
|
|
//
|
|
// Simulator/Astro/
|
|
// Modified fgStarsInit() to load stars database using fgstream.
|
|
//
|
|
// Simulator/Objects/
|
|
// Modified fgObjLoad() to use fgstream.
|
|
// Modified fgMATERIAL_MGR::load_lib() to use fgstream.
|
|
// Many changes to fgMATERIAL.
|
|
// Some changes to fgFRAGMENT but I forget what!
|
|
//
|
|
// Revision 1.3 1998/08/27 17:02:09 curt
|
|
// Contributions from Bernie Bright <bbright@c031.aone.net.au>
|
|
// - use strings for fg_root and airport_id and added methods to return
|
|
// them as strings,
|
|
// - inlined all access methods,
|
|
// - made the parsing functions private methods,
|
|
// - deleted some unused functions.
|
|
// - propogated some of these changes out a bit further.
|
|
//
|
|
// Revision 1.2 1998/08/25 20:53:33 curt
|
|
// Shuffled $FG_ROOT file layout.
|
|
//
|
|
// Revision 1.1 1998/08/25 16:51:24 curt
|
|
// Moved from ../Scenery
|
|
//
|
|
// Revision 1.13 1998/08/24 20:11:39 curt
|
|
// Tweaks ...
|
|
//
|
|
// Revision 1.12 1998/08/12 21:41:27 curt
|
|
// Need to negate the test for textures so that textures aren't loaded when
|
|
// they are disabled rather than visa versa ... :-)
|
|
//
|
|
// Revision 1.11 1998/08/12 21:13:03 curt
|
|
// material.cxx: don't load textures if they are disabled
|
|
// obj.cxx: optimizations from Norman Vine
|
|
// tile.cxx: minor tweaks
|
|
// tile.hxx: addition of num_faces
|
|
// tilemgr.cxx: minor tweaks
|
|
//
|
|
// Revision 1.10 1998/07/24 21:42:06 curt
|
|
// material.cxx: whups, double method declaration with no definition.
|
|
// obj.cxx: tweaks to avoid errors in SGI's CC.
|
|
// tile.cxx: optimizations by Norman Vine.
|
|
// tilemgr.cxx: optimizations by Norman Vine.
|
|
//
|
|
// Revision 1.9 1998/07/13 21:01:57 curt
|
|
// Wrote access functions for current fgOPTIONS.
|
|
//
|
|
// Revision 1.8 1998/07/08 14:47:20 curt
|
|
// Fix GL_MODULATE vs. GL_DECAL problem introduced by splash screen.
|
|
// polare3d.h renamed to polar3d.hxx
|
|
// fg{Cartesian,Polar}Point3d consolodated.
|
|
// Added some initial support for calculating local current ground elevation.
|
|
//
|
|
// Revision 1.7 1998/07/04 00:54:28 curt
|
|
// Added automatic mipmap generation.
|
|
//
|
|
// When rendering fragments, use saved model view matrix from associated tile
|
|
// rather than recalculating it with push() translate() pop().
|
|
//
|
|
// Revision 1.6 1998/06/27 16:54:59 curt
|
|
// Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use
|
|
// "EXT" versions of texture management routines.
|
|
//
|
|
// Revision 1.5 1998/06/17 21:36:39 curt
|
|
// Load and manage multiple textures defined in the Materials library.
|
|
// Boost max material fagments for each material property to 800.
|
|
// Multiple texture support when rendering.
|
|
//
|
|
// Revision 1.4 1998/06/12 00:58:04 curt
|
|
// Build only static libraries.
|
|
// Declare memmove/memset for Sloaris.
|
|
//
|
|
// Revision 1.3 1998/06/05 22:39:53 curt
|
|
// Working on sorting by, and rendering by material properties.
|
|
//
|
|
// Revision 1.2 1998/06/01 17:56:20 curt
|
|
// Incremental additions to material.cxx (not fully functional)
|
|
// Tweaked vfc_ratio math to avoid divide by zero.
|
|
//
|
|
// Revision 1.1 1998/05/30 01:56:45 curt
|
|
// Added material.cxx material.hxx
|
|
//
|