terrain.
// ssg variables
ssgRoot *scene = NULL;
+ssgBranch *terrain = NULL;
ssgTransform *penguin = NULL;
xglMatrixMode(GL_PROJECTION);
xglLoadIdentity();
ssgSetFOV(60.0f, 0.0f);
- ssgSetNearFar(1.0f, 700.0f);
+ ssgSetNearFar(1.0f, 14000.0f);
sgMat4 sgTRANS;
sgMakeTransMat4( sgTRANS,
sgMultMat4( sgVIEW, current_view.sgVIEW, sgTRANS );
ssgSetCamera( sgVIEW );
// ssgSetCamera( current_view.sgVIEW );
- // ssgCullAndDraw( scene );
+ ssgCullAndDraw( scene );
}
// distribution) specifically from the ssg tux example
//
- // ssgModelPath( "/stage/pinky01/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
- // ssgTexturePath( "/stage/pinky01/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
- ssgModelPath( "/h/curt/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
- ssgTexturePath( "/h/curt/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
+ ssgModelPath( "/stage/pinky01/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
+ ssgTexturePath( "/stage/pinky01/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
+ // ssgModelPath( "/h/curt/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
+ // ssgTexturePath( "/h/curt/src/Libs/plib-1.0.12/examples/ssg/tux/data/" );
scene = new ssgRoot;
+ terrain = new ssgBranch;
+ terrain->setName( "Terrain" );
penguin = new ssgTransform;
ssgEntity *tux_obj = ssgLoadAC( "tuxedo.ac" );
ssgFlatten( tux_obj );
ssgStripify( penguin );
+ scene->addKid( terrain );
scene->addKid( penguin );
// pass control off to the master GLUT event handler
# include <windows.h>
#endif
-#include "Include/compiler.h"
+#include <Include/compiler.h>
#include <GL/glut.h>
#include <XGL/xgl.h>
inline GLfloat *get_diffuse() { return diffuse; }
inline GLfloat *get_specular() { return specular; }
inline GLfloat *get_emissive() { return emissive; }
-
};
// Constructor
fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
- textures_loaded = false;
+ materials_loaded = false;
}
// cout << "rendering " + texture_name + " = " << list_size << "\n";
- if ( empty() )
+ if ( empty() ) {
return;
+ }
if ( current_options.get_textures() ) {
if ( !m.is_loaded() ) {
m.load_texture( current_options.get_fg_root() );
+
+ // build the ssgSimpleState
+ GLuint tex_id = m.get_texture_id();
+ state.setTexture( tex_id );
+ state.enable( GL_TEXTURE_2D );
+ state.enable( GL_LIGHTING );
+ state.setShadeModel( GL_SMOOTH );
+ state.enable ( GL_CULL_FACE ) ;
+ state.setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ;
}
#ifdef GL_VERSION_1_1
}
if ( current_options.get_textures() ) {
- textures_loaded = true;
+ materials_loaded = true;
}
return(1);
#include <GL/glut.h>
#include <XGL/xgl.h>
-#include STL_STRING // Standard C++ string library
-#include <map> // STL associative "array"
-#include <vector> // STL "array"
+#include STL_STRING // Standard C++ string library
+#include <map> // STL associative "array"
+#include <vector> // STL "array"
+
+#include <ssg.h> // plib include
#include "material.hxx"
private:
FGMaterial m;
- // OpenGL texture name
- // GLuint texture_id;
-
- // file name of texture
- // string texture_name;
-
- // alpha texture?
- // int alpha;
-
- // texture size
- // double xsize, ysize;
-
- // material properties
- // GLfloat ambient[4], diffuse[4], specular[4], emissive[4];
- // GLint texture_ptr;
-
// transient list of objects with this material type (used for sorting
// by material to reduce GL state changes when rendering the scene
frag_list_type list;
// size_t list_size;
+ // ssg stage structure
+ ssgSimpleState state;
+ bool state_valid;
+
public:
// Constructor
void render_fragments();
- // void load_texture();
-
// Destructor
~FGMaterialSlot ( void );
inline FGMaterial get_m() const { return m; }
inline void set_m( FGMaterial new_m ) { m = new_m; }
+
+ // ssg state
+ inline ssgSimpleState *get_state() { return &state; }
+ inline void set_state( ssgSimpleState s ) { state = s; }
+ inline bool get_state_valid() const { return state_valid; }
+ inline void set_state_valid( bool flag ) { state_valid = flag; }
};
// Load a library of material properties
int load_lib ( void );
- inline bool loaded() const { return textures_loaded; }
+ inline bool loaded() const { return materials_loaded; }
// Initialize the transient list of fragments for each material property
void init_transient_material_lists( void );
private:
- // Have textures been loaded
- bool textures_loaded;
+ // Has the material properties lib been loaded
+ bool materials_loaded;
container material_map;
#include <Include/compiler.h>
#include STL_STRING
-#include <map> // STL
-#include <ctype.h> // isdigit()
+#include <map> // STL
+#include <vector> // STL
+#include <ctype.h> // isdigit()
#include <Debug/logstream.hxx>
#include <Misc/fgstream.hxx>
#include "obj.hxx"
FG_USING_STD(string);
+FG_USING_STD(vector);
+
+
+typedef vector < int > int_list;
+typedef int_list::iterator int_list_iterator;
+typedef int_list::const_iterator int_point_list_iterator;
static double normals[FG_MAX_NODES][3];
// Load a .obj file and build the GL fragment list
-int fgObjLoad( const string& path, FGTileEntry *t) {
+ssgBranch *fgObjLoad( const string& path, FGTileEntry *t) {
fgFRAGMENT fragment;
Point3D pp;
double approx_normal[3], normal[3] /*, scale = 0.0 */;
// GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
GLint display_list = 0;
int shading;
- int in_fragment = 0, in_faces = 0, vncount, vtcount;
+ bool in_fragment = false, in_faces = false;
+ int vncount, vtcount;
int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
int tex;
int last1 = 0, last2 = 0, odd = 0;
Point3D node;
Point3D center;
double tex_width = 1000.0, tex_height = 1000.0;
+ bool shared_done = false;
+ int_list fan_vertices;
+ int_list fan_tex_coords;
+ int i;
+ ssgSimpleState *state = NULL;
// printf("loading %s\n", path.c_str() );
shading = current_options.get_shading();
- in_fragment = 0;
+ in_fragment = false;
t->ncount = 0;
vncount = 0;
vtcount = 0;
StopWatch stopwatch;
stopwatch.start();
+ ssgBranch *tile = new ssgBranch () ;
+ tile -> setName ( path.c_str() ) ;
+
// ignore initial comments and blank lines. (priming the pump)
// in >> skipcomment;
string line;
} else if ( token == "usemtl" ) {
// material property specification
+ // if first usemtl with shared_done = false, then set
+ // shared_done true and build the ssg shared lists
+ if ( ! shared_done ) {
+ shared_done = true;
+
+ t->vtlist = new sgVec3 [ nodes.size() ];
+ t->vnlist = new sgVec3 [ vncount ];
+ t->tclist = new sgVec2 [ vtcount ];
+
+ for ( i = 0; i < (int)nodes.size(); ++i ) {
+ sgSetVec3( t->vtlist[i],
+ nodes[i][0], nodes[i][1], nodes[i][2] );
+ }
+ for ( i = 0; i < vncount; ++i ) {
+ sgSetVec3( t->vnlist[i],
+ normals[i][0],
+ normals[i][1],
+ normals[i][2] );
+ }
+ for ( i = 0; i < vtcount; ++i ) {
+ sgSetVec2( t->tclist[i],
+ tex_coords[i][0], tex_coords[i][1] );
+ }
+ }
+
// series of individual triangles
if ( in_faces ) {
xglEnd();
// push this fragment onto the tile's object list
t->fragment_list.push_back(fragment);
} else {
- in_fragment = 1;
+ in_fragment = true;
}
// printf("start of fragment (usemtl)\n");
display_list = xglGenLists(1);
xglNewList(display_list, GL_COMPILE);
// printf("xglGenLists(); xglNewList();\n");
- in_faces = 0;
+ in_faces = false;
// reset the existing face list
// printf("cleaning a fragment with %d faces\n",
FGMaterial m = fragment.material_ptr->get_m();
tex_width = m.get_xsize();
tex_height = m.get_ysize();
+ state = fragment.material_ptr->get_state();
// cout << "(w) = " << tex_width << " (h) = "
// << tex_width << endl;
// triangle fan
// fgPrintf( FG_TERRAIN, FG_DEBUG, "new fan");
+ fan_vertices.clear();
+ fan_tex_coords.clear();
+
xglBegin(GL_TRIANGLE_FAN);
in >> n1;
+ fan_vertices.push_back( n1 );
xglNormal3dv(normals[n1]);
if ( in.get( c ) && c == '/' ) {
in >> tex;
+ fan_tex_coords.push_back( tex );
pp.setx( tex_coords[tex][0] * (1000.0 / tex_width) );
pp.sety( tex_coords[tex][1] * (1000.0 / tex_height) );
} else {
xglVertex3dv(nodes[n1].get_n());
in >> n2;
+ fan_vertices.push_back( n2 );
xglNormal3dv(normals[n2]);
if ( in.get( c ) && c == '/' ) {
in >> tex;
+ fan_tex_coords.push_back( tex );
pp.setx( tex_coords[tex][0] * (1000.0 / tex_width) );
pp.sety( tex_coords[tex][1] * (1000.0 / tex_height) );
} else {
}
in >> n3;
+ fan_vertices.push_back( n3 );
// cout << " triangle = "
// << n1 << "," << n2 << "," << n3
// << endl;
xglNormal3dv(normals[n3]);
if ( in.get( c ) && c == '/' ) {
in >> tex;
+ fan_tex_coords.push_back( tex );
pp.setx( tex_coords[tex][0] * (1000.0 / tex_width) );
pp.sety( tex_coords[tex][1] * (1000.0 / tex_height) );
} else {
}
xglEnd();
+
+ // build the ssg entity
+ unsigned short *vindex =
+ new unsigned short [ fan_vertices.size() ];
+ unsigned short *tindex =
+ new unsigned short [ fan_tex_coords.size() ];
+ for ( i = 0; i < (int)fan_vertices.size(); ++i ) {
+ vindex[i] = fan_vertices[i];
+ }
+ for ( i = 0; i < (int)fan_tex_coords.size(); ++i ) {
+ tindex[i] = fan_tex_coords[i];
+ }
+ ssgLeaf *leaf =
+ new ssgVTable ( GL_TRIANGLE_FAN,
+ fan_vertices.size(), vindex, t->vtlist,
+ fan_vertices.size(), vindex, t->vnlist,
+ fan_tex_coords.size(), tindex, t->tclist,
+ 0, NULL, NULL ) ;
+ leaf->setState( state );
+
+ tile->addKid( leaf );
+
} else if ( token == "f" ) {
// unoptimized face
if ( !in_faces ) {
xglBegin(GL_TRIANGLES);
// printf("xglBegin(triangles)\n");
- in_faces = 1;
+ in_faces = true;
}
// fgPrintf( FG_TERRAIN, FG_DEBUG, "new triangle = %s", line);*/
"Loaded " << path << " in "
<< stopwatch.elapsedSeconds() << " seconds" );
- return 1;
+ return tile;
}
# include <config.h>
#endif
+#include <Include/compiler.h>
+
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glut.h>
-#include <string>
+#include STL_STRING
+
+#include <ssg.h> // plib include
#include <Scenery/tileentry.hxx>
+FG_USING_STD(string);
+
// Load a .obj file and build the GL fragment list
-int fgObjLoad(const string& path, FGTileEntry *tile);
+ssgBranch *fgObjLoad(const string& path, FGTileEntry *tile);
#endif // _OBJ_HXX
#include <GL/glut.h>
#include <XGL/xgl.h>
+#include <ssg.h> // plib include
+
#include <Debug/logstream.hxx>
#include <Airports/genapt.hxx>
#include <Bucket/newbucket.hxx>
#include "tileentry.hxx"
+// a cheesy hack (to be fixed later)
+extern ssgBranch *terrain;
+extern ssgEntity *penguin;
+
+
// the tile cache
FGTileCache global_tile_cache;
tile_cache[index].mark_loaded();
tile_cache[index].tile_bucket = p;
- fgObjLoad( tile_path.str(), &tile_cache[index] );
-// tile_cache[ index ].ObjLoad( tile_path, p );
+ ssgBranch *new_tile = fgObjLoad( tile_path.str(), &tile_cache[index] );
+ tile_cache[index].branch_ptr = new ssgTransform;
+ tile_cache[index].branch_ptr->addKid( new_tile );
+ tile_cache[index].branch_ptr->addKid( penguin );
+ terrain->addKid( tile_cache[index].branch_ptr );
// cout << " ncount before = " << tile_cache[index].ncount << "\n";
// cout << " fragments before = " << tile_cache[index].fragment_list.size()
#include <vector>
#include STL_STRING
-#include <sg.h> // plib includes
+#include <ssg.h> // plib includes
#include <Bucket/newbucket.hxx>
#include <Math/mat3.h>
// this tile's official location in the world
FGBucket tile_bucket;
- // the tile cache will mark here if the tile is being used
+ // the tile cache will keep track here if the tile is being used
tile_state state;
container fragment_list;
+ // ssg related structures
+ sgVec3 *vtlist;
+ sgVec3 *vnlist;
+ sgVec2 *tclist;
+
+ // pointer to ssg branch;
+ ssgTransform *branch_ptr;
+
public:
// Constructor
// calculate tile offset
t->SetOffset( scenery.center );
+ // calculate ssg transform
+ sgCoord sgcoord;
+ sgSetCoord( &sgcoord,
+ t->offset.x(), t->offset.y(), t->offset.z(),
+ 0.0, 0.0, 0.0 );
+ t->branch_ptr->setTransform( &sgcoord );
+
// Course (tile based) culling
if ( viewable(t->offset, t->bounding_radius) ) {
// at least a portion of this tile could be viewable
// traverse the transient per-material fragment lists and render
// out all fragments for each material property.
xglPushMatrix();
- material_mgr.render_fragments();
+ // material_mgr.render_fragments();
xglPopMatrix();
}