From 858f17b323a3c553dfa70195449fae594bff3e53 Mon Sep 17 00:00:00 2001 From: curt Date: Mon, 28 Jun 1999 00:02:52 +0000 Subject: [PATCH] Changes to begin incorporating plib support for managing and rendering the terrain. --- src/Main/main.cxx | 16 ++++--- src/Objects/material.hxx | 3 +- src/Objects/materialmgr.cxx | 16 +++++-- src/Objects/materialmgr.hxx | 42 ++++++++--------- src/Objects/obj.cxx | 91 +++++++++++++++++++++++++++++++++---- src/Objects/obj.hxx | 10 +++- src/Scenery/tilecache.cxx | 14 +++++- src/Scenery/tileentry.hxx | 12 ++++- src/Scenery/tilemgr.cxx | 9 +++- 9 files changed, 162 insertions(+), 51 deletions(-) diff --git a/src/Main/main.cxx b/src/Main/main.cxx index 9ed503240..830abc001 100644 --- a/src/Main/main.cxx +++ b/src/Main/main.cxx @@ -130,6 +130,7 @@ slSample *s2; // ssg variables ssgRoot *scene = NULL; +ssgBranch *terrain = NULL; ssgTransform *penguin = NULL; @@ -399,7 +400,7 @@ static void fgRenderFrame( void ) { xglMatrixMode(GL_PROJECTION); xglLoadIdentity(); ssgSetFOV(60.0f, 0.0f); - ssgSetNearFar(1.0f, 700.0f); + ssgSetNearFar(1.0f, 14000.0f); sgMat4 sgTRANS; sgMakeTransMat4( sgTRANS, @@ -427,7 +428,7 @@ static void fgRenderFrame( void ) { sgMultMat4( sgVIEW, current_view.sgVIEW, sgTRANS ); ssgSetCamera( sgVIEW ); // ssgSetCamera( current_view.sgVIEW ); - // ssgCullAndDraw( scene ); + ssgCullAndDraw( scene ); } @@ -1066,12 +1067,14 @@ int main( int argc, char **argv ) { // 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" ); @@ -1079,6 +1082,7 @@ int main( int argc, char **argv ) { ssgFlatten( tux_obj ); ssgStripify( penguin ); + scene->addKid( terrain ); scene->addKid( penguin ); // pass control off to the master GLUT event handler diff --git a/src/Objects/material.hxx b/src/Objects/material.hxx index d5399dbc8..fff6695e1 100644 --- a/src/Objects/material.hxx +++ b/src/Objects/material.hxx @@ -37,7 +37,7 @@ # include #endif -#include "Include/compiler.h" +#include #include #include @@ -94,7 +94,6 @@ public: inline GLfloat *get_diffuse() { return diffuse; } inline GLfloat *get_specular() { return specular; } inline GLfloat *get_emissive() { return emissive; } - }; diff --git a/src/Objects/materialmgr.cxx b/src/Objects/materialmgr.cxx index 182235a6b..790b2b273 100644 --- a/src/Objects/materialmgr.cxx +++ b/src/Objects/materialmgr.cxx @@ -69,7 +69,7 @@ FGMaterialSlot::~FGMaterialSlot ( void ) { // Constructor fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) { - textures_loaded = false; + materials_loaded = false; } @@ -80,13 +80,23 @@ FGMaterialSlot::render_fragments() // 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 @@ -168,7 +178,7 @@ fgMATERIAL_MGR::load_lib ( void ) } if ( current_options.get_textures() ) { - textures_loaded = true; + materials_loaded = true; } return(1); diff --git a/src/Objects/materialmgr.hxx b/src/Objects/materialmgr.hxx index a5fefa561..299608dbf 100644 --- a/src/Objects/materialmgr.hxx +++ b/src/Objects/materialmgr.hxx @@ -42,9 +42,11 @@ #include #include -#include STL_STRING // Standard C++ string library -#include // STL associative "array" -#include // STL "array" +#include STL_STRING // Standard C++ string library +#include // STL associative "array" +#include // STL "array" + +#include // plib include #include "material.hxx" @@ -75,27 +77,15 @@ class FGMaterialSlot { 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 @@ -116,8 +106,6 @@ public: void render_fragments(); - // void load_texture(); - // Destructor ~FGMaterialSlot ( void ); @@ -125,6 +113,12 @@ public: 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; } }; @@ -150,7 +144,7 @@ public: // 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 ); @@ -164,8 +158,8 @@ public: private: - // Have textures been loaded - bool textures_loaded; + // Has the material properties lib been loaded + bool materials_loaded; container material_map; diff --git a/src/Objects/obj.cxx b/src/Objects/obj.cxx index b890d7dec..4b41122f4 100644 --- a/src/Objects/obj.cxx +++ b/src/Objects/obj.cxx @@ -46,8 +46,9 @@ #include #include STL_STRING -#include // STL -#include // isdigit() +#include // STL +#include // STL +#include // isdigit() #include #include @@ -64,6 +65,12 @@ #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]; @@ -128,7 +135,7 @@ static Point3D calc_tex_coords(const Point3D& node, const Point3D& ref) { // 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 */; @@ -136,7 +143,8 @@ int fgObjLoad( const string& path, FGTileEntry *t) { // 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; @@ -144,6 +152,11 @@ int fgObjLoad( const string& path, FGTileEntry *t) { 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() ); @@ -156,7 +169,7 @@ int fgObjLoad( const string& path, FGTileEntry *t) { shading = current_options.get_shading(); - in_fragment = 0; + in_fragment = false; t->ncount = 0; vncount = 0; vtcount = 0; @@ -166,6 +179,9 @@ int fgObjLoad( const string& path, FGTileEntry *t) { 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; @@ -204,6 +220,31 @@ int fgObjLoad( const string& path, FGTileEntry *t) { } 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(); @@ -221,7 +262,7 @@ int fgObjLoad( const string& path, FGTileEntry *t) { // 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"); @@ -229,7 +270,7 @@ int fgObjLoad( const string& path, FGTileEntry *t) { 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", @@ -253,6 +294,7 @@ int fgObjLoad( const string& path, FGTileEntry *t) { 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; @@ -426,12 +468,17 @@ int fgObjLoad( const string& path, FGTileEntry *t) { // 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 { @@ -442,9 +489,11 @@ int fgObjLoad( const string& path, FGTileEntry *t) { 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 { @@ -470,12 +519,14 @@ int fgObjLoad( const string& path, FGTileEntry *t) { } 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 { @@ -490,13 +541,35 @@ int fgObjLoad( const string& path, FGTileEntry *t) { } 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);*/ @@ -657,7 +730,7 @@ int fgObjLoad( const string& path, FGTileEntry *t) { "Loaded " << path << " in " << stopwatch.elapsedSeconds() << " seconds" ); - return 1; + return tile; } diff --git a/src/Objects/obj.hxx b/src/Objects/obj.hxx index bed0908ed..586df9062 100644 --- a/src/Objects/obj.hxx +++ b/src/Objects/obj.hxx @@ -34,19 +34,25 @@ # include #endif +#include + #ifdef HAVE_WINDOWS_H # include #endif #include -#include +#include STL_STRING + +#include // plib include #include +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 diff --git a/src/Scenery/tilecache.cxx b/src/Scenery/tilecache.cxx index 67ef6deec..c81a47cfc 100644 --- a/src/Scenery/tilecache.cxx +++ b/src/Scenery/tilecache.cxx @@ -32,6 +32,8 @@ #include #include +#include // plib include + #include #include #include @@ -44,6 +46,11 @@ #include "tileentry.hxx" +// a cheesy hack (to be fixed later) +extern ssgBranch *terrain; +extern ssgEntity *penguin; + + // the tile cache FGTileCache global_tile_cache; @@ -130,8 +137,11 @@ FGTileCache::fill_in( int index, const FGBucket& p ) 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() diff --git a/src/Scenery/tileentry.hxx b/src/Scenery/tileentry.hxx index 21fd2fac9..719536110 100644 --- a/src/Scenery/tileentry.hxx +++ b/src/Scenery/tileentry.hxx @@ -45,7 +45,7 @@ #include #include STL_STRING -#include // plib includes +#include // plib includes #include #include @@ -99,11 +99,19 @@ public: // 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 diff --git a/src/Scenery/tilemgr.cxx b/src/Scenery/tilemgr.cxx index 86ebc4470..3b9b2854f 100644 --- a/src/Scenery/tilemgr.cxx +++ b/src/Scenery/tilemgr.cxx @@ -775,6 +775,13 @@ void FGTileMgr::render( void ) { // 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 @@ -847,6 +854,6 @@ void FGTileMgr::render( void ) { // 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(); } -- 2.39.5