2000-06-23 02:59:03 +00:00
|
|
|
// materialmgr.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
|
|
|
|
|
|
|
|
#ifdef FG_MATH_EXCEPTION_CLASH
|
|
|
|
# include <math.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef HAVE_WINDOWS_H
|
|
|
|
# include <windows.h>
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include <GL/glut.h>
|
|
|
|
#include <simgear/xgl/xgl.h>
|
|
|
|
|
|
|
|
#include <simgear/compiler.h>
|
|
|
|
|
|
|
|
#include <string.h>
|
|
|
|
#include STL_STRING
|
|
|
|
|
|
|
|
#include <simgear/debug/logstream.hxx>
|
|
|
|
#include <simgear/misc/fgpath.hxx>
|
|
|
|
#include <simgear/misc/fgstream.hxx>
|
|
|
|
|
David Megginson writes:
I have a scrollable panel working (it didn't take long in the end). A
panel can now be much wider or higher than the available area, and the
user can scroll around using [Shift]F5, [Shift]F6, [Shift]F7, and
[Shift]F8. The user can also scroll the panel down to get a bigger
external view. Mouse clicks seem still to be working correctly.
To set the panel's (virtual) height and width, use the panel file's /w
and /h properties in a panel XML file; to set the initial x- and y-
offsets (untested), use the panel file's /x-offset and /y-offset
properties; to set the initial height of the external view (untested
and optional), use the panel file's /view-height property. Note that
none of these show up in the regular FGFS property manager.
Unfortunately, these patches will not affect your initialization
problems with the property manager -- I'm having a hard time tracking
them down because I cannot reproduce them.
I have also made some patches to main.cxx and views.cxx to do two
things:
1. Expand or shrink the external view as the panel moves up and down.
2. Set the window ratio correctly, so that we don't get an oval sun
and flat clouds when the panel is visible (the problem before was
integer division, so I added casts).
Unfortunately, the window ratio is not set properly at start-up --
there are too many dependencies, and I haven't figured that part out
yet. As soon as you hide and redisplay the panel or move it
vertically (i.e. force fgReshape to be called), you'll see the correct
ratio.
2000-10-06 21:16:01 +00:00
|
|
|
#include <Include/general.hxx>
|
2000-10-19 21:24:43 +00:00
|
|
|
#include <Main/globals.hxx>
|
2000-06-23 02:59:03 +00:00
|
|
|
#include <Scenery/tileentry.hxx>
|
|
|
|
|
|
|
|
#include "matlib.hxx"
|
|
|
|
|
|
|
|
FG_USING_STD(string);
|
|
|
|
|
|
|
|
|
|
|
|
// global material management class
|
|
|
|
FGMaterialLib material_lib;
|
|
|
|
|
|
|
|
|
|
|
|
// Constructor
|
|
|
|
FGMaterialLib::FGMaterialLib ( void ) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-10-04 20:51:57 +00:00
|
|
|
static bool local_file_exists( const string& path ) {
|
|
|
|
fg_gzifstream in( path );
|
|
|
|
if ( ! in.is_open() ) {
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
#if 0
|
|
|
|
cout << path << " ";
|
|
|
|
FILE *fp = fopen( path.c_str(), "r" );
|
|
|
|
if ( fp == NULL ) {
|
|
|
|
cout << " doesn't exist\n";
|
|
|
|
return false;
|
|
|
|
} else {
|
|
|
|
cout << " exists\n";
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
#endif
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2000-06-23 02:59:03 +00:00
|
|
|
// Load a library of material properties
|
|
|
|
bool FGMaterialLib::load( const string& mpath ) {
|
|
|
|
string material_name;
|
|
|
|
|
|
|
|
fg_gzifstream in( mpath );
|
|
|
|
if ( ! in.is_open() ) {
|
|
|
|
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath );
|
|
|
|
exit(-1);
|
|
|
|
}
|
|
|
|
|
|
|
|
#ifndef __MWERKS__
|
|
|
|
while ( ! in.eof() ) {
|
|
|
|
#else
|
|
|
|
char c = '\0';
|
|
|
|
while ( in.get(c) && c != '\0' ) {
|
|
|
|
in.putback(c);
|
|
|
|
#endif
|
|
|
|
// 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;
|
|
|
|
|
2000-11-03 20:21:43 +00:00
|
|
|
in >> material_name;
|
|
|
|
|
|
|
|
if ( material_name == "alias" ) {
|
|
|
|
string src_mat, dst_mat;
|
|
|
|
in >> dst_mat >> src_mat;
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO, " Material alias: " << dst_mat <<
|
|
|
|
" mapped to " << src_mat );
|
|
|
|
FGNewMat m = matlib[src_mat];
|
|
|
|
matlib[dst_mat] = m;
|
|
|
|
} else {
|
|
|
|
in >> token;
|
|
|
|
|
|
|
|
if ( token == '{' ) {
|
|
|
|
FGNewMat m;
|
|
|
|
in >> m;
|
|
|
|
|
|
|
|
// build the ssgSimpleState
|
|
|
|
FGPath tex_path( globals->get_options()->get_fg_root() );
|
|
|
|
tex_path.append( "Textures.high" );
|
|
|
|
|
|
|
|
FGPath tmp_path = tex_path;
|
|
|
|
tmp_path.append( m.get_texture_name() );
|
|
|
|
if ( ! local_file_exists(tmp_path.str())
|
|
|
|
|| general.get_glMaxTexSize() < 512 ) {
|
|
|
|
tex_path = FGPath( globals->get_options()->get_fg_root() );
|
|
|
|
tex_path.append( "Textures" );
|
|
|
|
}
|
2000-10-04 20:51:57 +00:00
|
|
|
|
2000-11-03 20:21:43 +00:00
|
|
|
FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
|
|
|
|
<< material_name << " (" << tex_path.c_str() << ")");
|
2000-06-23 02:59:03 +00:00
|
|
|
|
2000-11-03 20:21:43 +00:00
|
|
|
GLenum shade_model = GL_SMOOTH;
|
|
|
|
if ( globals->get_options()->get_shading() == 1 ) {
|
|
|
|
shade_model = GL_SMOOTH;
|
|
|
|
} else {
|
|
|
|
shade_model = GL_FLAT;
|
|
|
|
}
|
|
|
|
|
|
|
|
m.build_ssg_state( tex_path.str(), shade_model,
|
|
|
|
globals->get_options()->get_textures() );
|
2000-06-23 02:59:03 +00:00
|
|
|
|
|
|
|
#if EXTRA_DEBUG
|
2000-11-03 20:21:43 +00:00
|
|
|
m.dump_info();
|
2000-06-23 02:59:03 +00:00
|
|
|
#endif
|
|
|
|
|
2000-11-03 20:21:43 +00:00
|
|
|
matlib[material_name] = m;
|
|
|
|
}
|
2000-06-23 02:59:03 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2000-12-04 05:23:06 +00:00
|
|
|
// hard coded light state
|
|
|
|
ssgSimpleState *lights = new ssgSimpleState;
|
|
|
|
lights->ref();
|
|
|
|
lights->disable( GL_TEXTURE_2D );
|
|
|
|
lights->enable( GL_CULL_FACE );
|
|
|
|
lights->enable( GL_COLOR_MATERIAL );
|
|
|
|
lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
|
|
|
|
lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
|
|
|
|
lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
|
|
|
|
lights->disable( GL_BLEND );
|
|
|
|
lights->disable( GL_ALPHA_TEST );
|
|
|
|
lights->disable( GL_LIGHTING );
|
|
|
|
|
|
|
|
FGNewMat m;
|
|
|
|
m.set_ssg_state( lights );
|
|
|
|
matlib["LIGHTS"] = m;
|
|
|
|
|
2000-06-23 02:59:03 +00:00
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Load a library of material properties
|
2000-06-23 04:55:55 +00:00
|
|
|
bool FGMaterialLib::add_item ( const string &tex_path )
|
2000-06-23 02:59:03 +00:00
|
|
|
{
|
2000-06-23 04:55:55 +00:00
|
|
|
string material_name = tex_path;
|
|
|
|
int pos = tex_path.rfind( "/" );
|
2000-06-23 02:59:03 +00:00
|
|
|
material_name = material_name.substr( pos + 1 );
|
|
|
|
|
2000-06-23 04:55:55 +00:00
|
|
|
return add_item( material_name, tex_path );
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Load a library of material properties
|
|
|
|
bool FGMaterialLib::add_item ( const string &mat_name, const string &full_path )
|
|
|
|
{
|
|
|
|
int pos = full_path.rfind( "/" );
|
|
|
|
string tex_name = full_path.substr( pos + 1 );
|
|
|
|
string tex_path = full_path.substr( 0, pos );
|
2000-06-23 02:59:03 +00:00
|
|
|
|
2000-06-23 04:55:55 +00:00
|
|
|
FGNewMat m( mat_name, tex_name );
|
2000-06-23 02:59:03 +00:00
|
|
|
|
|
|
|
FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
|
2000-06-23 04:55:55 +00:00
|
|
|
<< mat_name << " (" << tex_path << ")");
|
2000-06-23 02:59:03 +00:00
|
|
|
|
|
|
|
#if EXTRA_DEBUG
|
|
|
|
m.dump_info();
|
|
|
|
#endif
|
|
|
|
|
|
|
|
GLenum shade_model = GL_SMOOTH;
|
2000-10-19 21:24:43 +00:00
|
|
|
if ( globals->get_options()->get_shading() == 1 ) {
|
2000-06-23 02:59:03 +00:00
|
|
|
shade_model = GL_SMOOTH;
|
|
|
|
} else {
|
|
|
|
shade_model = GL_FLAT;
|
|
|
|
}
|
|
|
|
|
2000-10-19 21:24:43 +00:00
|
|
|
m.build_ssg_state( tex_path, shade_model,
|
|
|
|
globals->get_options()->get_textures() );
|
2000-06-23 04:55:55 +00:00
|
|
|
|
|
|
|
material_lib.matlib[mat_name] = m;
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Load a library of material properties
|
|
|
|
bool FGMaterialLib::add_item ( const string &mat_name, ssgSimpleState *state )
|
|
|
|
{
|
|
|
|
FGNewMat m( mat_name );
|
|
|
|
m.set_ssg_state( state );
|
|
|
|
|
|
|
|
FG_LOG( FG_TERRAIN, FG_INFO, " Loading material given a premade "
|
|
|
|
<< "ssgSimpleState = " << mat_name );
|
|
|
|
|
|
|
|
#if EXTRA_DEBUG
|
|
|
|
m.dump_info();
|
|
|
|
#endif
|
2000-06-23 02:59:03 +00:00
|
|
|
|
2000-06-23 04:55:55 +00:00
|
|
|
material_lib.matlib[mat_name] = m;
|
2000-06-23 02:59:03 +00:00
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// find a material record by material name
|
|
|
|
FGNewMat *FGMaterialLib::find( const string& material ) {
|
|
|
|
FGNewMat *result = NULL;
|
|
|
|
material_map_iterator it = matlib.find( material );
|
|
|
|
if ( it != end() ) {
|
|
|
|
result = &((*it).second);
|
|
|
|
return result;
|
|
|
|
}
|
|
|
|
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Destructor
|
|
|
|
FGMaterialLib::~FGMaterialLib ( void ) {
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
// Set the step for all of the state selectors in the material slots
|
|
|
|
void FGMaterialLib::set_step ( int step )
|
|
|
|
{
|
|
|
|
// container::iterator it = begin();
|
|
|
|
for ( material_map_iterator it = begin(); it != end(); it++ ) {
|
|
|
|
const string &key = it->first;
|
|
|
|
FG_LOG( FG_GENERAL, FG_INFO,
|
|
|
|
"Updating material " << key << " to step " << step );
|
|
|
|
FGNewMat &slot = it->second;
|
|
|
|
slot.get_state()->selectStep(step);
|
|
|
|
}
|
|
|
|
}
|
2000-12-04 05:23:06 +00:00
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|