Working on sorting by, and rendering by material properties.
This commit is contained in:
parent
22dd9999a8
commit
5c10725624
5 changed files with 200 additions and 10 deletions
|
@ -40,6 +40,10 @@
|
|||
#include "material.hxx"
|
||||
|
||||
|
||||
// global material management class
|
||||
fgMATERIAL_MGR material_mgr;
|
||||
|
||||
|
||||
// Constructor
|
||||
fgMATERIAL::fgMATERIAL ( void ) {
|
||||
}
|
||||
|
@ -64,8 +68,11 @@ fgMATERIAL_MGR::fgMATERIAL_MGR ( 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;
|
||||
|
@ -86,18 +93,123 @@ int fgMATERIAL_MGR::load_lib ( void ) {
|
|||
}
|
||||
}
|
||||
|
||||
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.
|
||||
|
|
|
@ -54,9 +54,11 @@
|
|||
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
|
||||
|
@ -82,7 +84,7 @@ class fgMATERIAL_MGR {
|
|||
public:
|
||||
|
||||
// associative array of materials
|
||||
map < string, fgMATERIAL, less<string> > materials;
|
||||
map < string, fgMATERIAL, less<string> > material_map;
|
||||
|
||||
// Constructor
|
||||
fgMATERIAL_MGR ( void );
|
||||
|
@ -90,15 +92,25 @@ public:
|
|||
// 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.
|
||||
|
|
|
@ -35,6 +35,9 @@
|
|||
#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>
|
||||
|
@ -43,6 +46,7 @@
|
|||
#include <Math/fg_random.h>
|
||||
#include <Math/polar3d.h>
|
||||
|
||||
#include "material.hxx"
|
||||
#include "obj.hxx"
|
||||
#include "scenery.hxx"
|
||||
#include "tile.hxx"
|
||||
|
@ -147,6 +151,7 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
|||
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 ) {
|
||||
|
@ -196,6 +201,18 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
|||
|
||||
// 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
|
||||
|
||||
|
@ -406,6 +423,9 @@ int fgObjLoad(char *path, fgTILE *tile) {
|
|||
|
||||
|
||||
// $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.
|
||||
//
|
||||
|
|
|
@ -51,13 +51,15 @@
|
|||
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;
|
||||
|
@ -99,6 +101,9 @@ public:
|
|||
|
||||
|
||||
// $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.
|
||||
|
|
|
@ -35,10 +35,6 @@
|
|||
|
||||
#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>
|
||||
|
@ -47,6 +43,11 @@
|
|||
#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
|
||||
|
||||
|
@ -59,6 +60,10 @@ int tiles[FG_LOCAL_X_Y];
|
|||
// 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;
|
||||
}
|
||||
|
||||
|
@ -295,11 +300,12 @@ void fgTileMgrRender( void ) {
|
|||
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;
|
||||
|
@ -319,6 +325,10 @@ void fgTileMgrRender( void ) {
|
|||
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);
|
||||
|
@ -350,6 +360,14 @@ void fgTileMgrRender( void ) {
|
|||
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 {
|
||||
|
@ -374,10 +392,33 @@ void fgTileMgrRender( void ) {
|
|||
}
|
||||
// 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.
|
||||
|
|
Loading…
Reference in a new issue