#include "material.hxx"
+// global material management class
+fgMATERIAL_MGR material_mgr;
+
+
// Constructor
fgMATERIAL::fgMATERIAL ( void ) {
}
// Load a library of material properties
int fgMATERIAL_MGR::load_lib ( void ) {
+ fgMATERIAL m;
fgOPTIONS *o;
+ char material_name[256];
char path[256], fgpath[256];
+ char line[256], *line_ptr;
fgFile f;
o = ¤t_options;
}
}
+ while ( fggets(f, line, 250) != NULL ) {
+ // printf("%s", line);
+
+ // strip leading white space
+ line_ptr = line;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+
+ }
+
+ if ( line_ptr[0] == '#' ) {
+ // ignore lines that start with '#'
+ } else if ( line_ptr[0] == '\n' ) {
+ // ignore blank lines
+ } else if ( strstr(line_ptr, "{") ) {
+ // start of record
+ m.ambient[0] = m.ambient[1] = m.ambient[2] = m.ambient[3] = 0.0;
+ m.diffuse[0] = m.diffuse[1] = m.diffuse[2] = m.diffuse[3] = 0.0;
+ m.specular[0] = m.specular[1] = m.specular[2] = m.specular[3] = 0.0;
+ m.emissive[0] = m.emissive[1] = m.emissive[2] = m.emissive[3] = 0.0;
+
+ material_name[0] = '\0';
+ sscanf(line_ptr, "%s", material_name);
+ if ( ! strlen(material_name) ) {
+ fgPrintf( FG_TERRAIN, FG_INFO, "Bad material name in '%s'\n",
+ line );
+ }
+ printf(" Loading material = %s\n", material_name);
+ } else if ( strncmp(line_ptr, "texture", 7) == 0 ) {
+ line_ptr += 7;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
+ (line_ptr[0] == '=') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+ }
+ // printf("texture name = %s\n", line_ptr);
+ sscanf(line_ptr, "%s\n", m.texture_name);
+ } else if ( strncmp(line_ptr, "ambient", 7) == 0 ) {
+ line_ptr += 7;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
+ (line_ptr[0] == '=') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+ }
+ sscanf( line_ptr, "%f %f %f %f",
+ &m.ambient[0], &m.ambient[1], &m.ambient[2], &m.ambient[3]);
+ } else if ( strncmp(line_ptr, "diffuse", 7) == 0 ) {
+ line_ptr += 7;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
+ (line_ptr[0] == '=') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+ }
+ sscanf( line_ptr, "%f %f %f %f",
+ &m.diffuse[0], &m.diffuse[1], &m.diffuse[2], &m.diffuse[3]);
+ } else if ( strncmp(line_ptr, "specular", 8) == 0 ) {
+ line_ptr += 8;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
+ (line_ptr[0] == '=') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+ }
+ sscanf( line_ptr, "%f %f %f %f",
+ &m.specular[0], &m.specular[1],
+ &m.specular[2], &m.specular[3]);
+ } else if ( strncmp(line_ptr, "emissive", 8) == 0 ) {
+ line_ptr += 8;
+ while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') ||
+ (line_ptr[0] == '=') ) &&
+ (line_ptr[0] != '\n') ) {
+ line_ptr++;
+ }
+ sscanf( line_ptr, "%f %f %f %f",
+ &m.emissive[0], &m.emissive[1],
+ &m.emissive[2], &m.emissive[3]);
+ } else if ( line_ptr[0] == '}' ) {
+ // end of record, lets add this one to the list
+ material_mgr.material_map[material_name] = m;
+ } else {
+ fgPrintf(FG_TERRAIN, FG_INFO,
+ "Unknown line in material properties file\n");
+ }
+ }
+
fgclose(f);
return(1);
}
+// Initialize the transient list of fragments for each material property
+void fgMATERIAL_MGR::init_transient_material_lists( void ) {
+ map < string, fgMATERIAL, less<string> > :: iterator mapcurrent =
+ material_mgr.material_map.begin();
+ map < string, fgMATERIAL, less<string> > :: iterator maplast =
+ material_mgr.material_map.end();
+
+ while ( mapcurrent != maplast ) {
+ // (char *)key = (*mapcurrent).first;
+ // (fgMATERIAL)value = (*mapcurrent).second;
+ (*mapcurrent).second.list_size = 0;
+
+ *mapcurrent++;
+ }
+}
+
+
// Destructor
fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
}
// $Log$
+// 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.
class fgMATERIAL {
public:
+ // file name of texture
+ char texture_name[256];
// material properties
- GLfloat ambient[4], diffuse[4], specular[4];
+ GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
GLint texture_ptr;
// transient list of objects with this material type (used for sorting
public:
// associative array of materials
- map < string, fgMATERIAL, less<string> > materials;
+ map < string, fgMATERIAL, less<string> > material_map;
// Constructor
fgMATERIAL_MGR ( void );
// Load a library of material properties
int load_lib ( void );
+ // Initialize the transient list of fragments for each material property
+ void init_transient_material_lists( void );
+
// Destructor
~fgMATERIAL_MGR ( void );
};
+// global material management class
+extern fgMATERIAL_MGR material_mgr;
+
+
#endif // _MATERIAL_HXX
// $Log$
+// Revision 1.4 1998/06/05 22:39:53 curt
+// Working on sorting by, and rendering by material properties.
+//
// Revision 1.3 1998/06/03 00:47:50 curt
// No .h for STL includes.
// Minor view culling optimizations.
#include <GL/glut.h>
#include <XGL/xgl.h>
+#include <map> // STL
+#include <string> // Standard C++ library
+
#include <Debug/fg_debug.h>
#include <Include/fg_constants.h>
#include <Include/fg_zlib.h>
#include <Math/fg_random.h>
#include <Math/polar3d.h>
+#include "material.hxx"
#include "obj.hxx"
#include "scenery.hxx"
#include "tile.hxx"
sscanf(line, "bs %lf %lf %lf %lf\n",
&fragment.center.x, &fragment.center.y, &fragment.center.z,
&fragment.bounding_radius);
+ fragment.tile_center = tile->center;
} else if ( strncmp(line, "v ", 2) == 0 ) {
// node (vertex)
if ( ncount < MAXNODES ) {
// scan the material line
sscanf(line, "usemtl %s\n", material);
+
+ // find this material in the properties list
+ map < string, fgMATERIAL, less<string> > :: iterator myfind =
+ material_mgr.material_map.find(material);
+ if ( myfind == material_mgr.material_map.end() ) {
+ fgPrintf( FG_TERRAIN, FG_ALERT,
+ "Ack! unknown usemtl name = %s in %s\n",
+ material, path);
+ } else {
+ (fgMATERIAL *)fragment.material_ptr = &(*myfind).second;
+ }
+
} else if ( line[0] == 't' ) {
// start a new triangle strip
// $Log$
+// Revision 1.9 1998/06/05 22:39:54 curt
+// Working on sorting by, and rendering by material properties.
+//
// Revision 1.8 1998/06/05 18:19:18 curt
// Recognize file, file.gz, and file.obj as scenery object files.
//
class fgFRAGMENT {
public:
+ // positional data for this object fragment
+ fgCartesianPoint3d tile_center;
// culling data for this object fragment (fine grain culling)
fgCartesianPoint3d center;
double bounding_radius;
// material property pointer
- int material_ptr;
+ void *material_ptr;
// OpenGL display list for fragment data
GLint display_list;
// $Log$
+// Revision 1.3 1998/06/05 22:39:54 curt
+// Working on sorting by, and rendering by material properties.
+//
// Revision 1.2 1998/06/03 00:47:50 curt
// No .h for STL includes.
// Minor view culling optimizations.
#include <Aircraft/aircraft.h>
-#include <Scenery/obj.hxx>
-#include <Scenery/scenery.hxx>
-#include <Scenery/tilecache.hxx>
-
#include <Bucket/bucketutils.h>
#include <Debug/fg_debug.h>
#include <Include/fg_constants.h>
#include <Main/views.hxx>
#include <Math/mat3.h>
+#include "material.hxx"
+#include "obj.hxx"
+#include "scenery.hxx"
+#include "tilecache.hxx"
+
#define FG_LOCAL_X_Y 81 // max(o->tile_diameter) ** 2
// Initialize the Tile Manager subsystem
int fgTileMgrInit( void ) {
fgPrintf( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem.\n");
+
+ // load default material library
+ material_mgr.load_lib();
+
return 1;
}
fgTILE *t;
fgVIEW *v;
struct fgBUCKET p;
- fgCartesianPoint3d offset;
- fgFRAGMENT fragment;
+ fgCartesianPoint3d offset, last_center;
+ fgFRAGMENT fragment, *frag_ptr;
+ fgMATERIAL *mtl_ptr;
list < fgFRAGMENT > :: iterator current;
list < fgFRAGMENT > :: iterator last;
- int i;
+ int i, size;
int index;
int culled = 0;
int drawn = 0;
FG_Longitude * RAD_TO_DEG, FG_Latitude * RAD_TO_DEG,
p.lon, p.lat, p.x, p.y, fgBucketGenIndex(&p) );
+ // initialize the transient per-material fragment lists
+ material_mgr.init_transient_material_lists();
+
+ // traverse the potentially viewable tile list
for ( i = 0; i < (o->tile_diameter * o->tile_diameter); i++ ) {
index = tiles[i];
// fgPrintf( FG_TERRAIN, FG_DEBUG, "Index = %d\n", index);
offset.z = fragment.center.z - scenery.center.z;
if ( viewable(&offset, fragment.bounding_radius * 2) ) {
+ // add to transient per-material property fragment list
+ mtl_ptr = (fgMATERIAL *)(fragment.material_ptr);
+ // printf(" lookup = %s\n", mtl_ptr->texture_name);
+ if ( mtl_ptr->list_size < FG_MAX_MATERIAL_FRAGS ) {
+ mtl_ptr->list[mtl_ptr->list_size] = &fragment;
+ (mtl_ptr->list_size)++;
+ }
+
xglCallList(fragment.display_list);
drawn++;
} else {
}
// printf("drawn = %d culled = %d saved = %.2f\n", drawn, culled,
// v->vfc_ratio);
+
+ // traverse the transient per-material fragment lists and render
+ // out all fragments for each material property.
+ map < string, fgMATERIAL, less<string> > :: iterator mapcurrent =
+ material_mgr.material_map.begin();
+ map < string, fgMATERIAL, less<string> > :: iterator maplast =
+ material_mgr.material_map.end();
+
+ while ( mapcurrent != maplast ) {
+ // (char *)key = (*mapcurrent).first;
+ // (fgMATERIAL)value = (*mapcurrent).second;
+ size = (*mapcurrent).second.list_size;
+ for ( i = 0; i < size; i++ ) {
+ // frag_ptr = &(*mapcurrent).second.list[i];
+ // frag_ptr->tile_center
+ }
+
+ *mapcurrent++;
+ }
+
}
// $Log$
+// Revision 1.16 1998/06/05 22:39:55 curt
+// Working on sorting by, and rendering by material properties.
+//
// Revision 1.15 1998/06/03 00:47:51 curt
// No .h for STL includes.
// Minor view culling optimizations.