From: curt Date: Sat, 4 Jul 1998 00:54:28 +0000 (+0000) Subject: Added automatic mipmap generation. X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=6d48ba08a0c078dce1a98c0ccd5e2356ba9e099c;p=flightgear.git Added automatic mipmap generation. When rendering fragments, use saved model view matrix from associated tile rather than recalculating it with push() translate() pop(). --- diff --git a/Scenery/material.cxx b/Scenery/material.cxx index a4a02e2cb..8b27b037b 100644 --- a/Scenery/material.cxx +++ b/Scenery/material.cxx @@ -74,10 +74,11 @@ int fgMATERIAL_MGR::load_lib ( void ) { fgOPTIONS *o; char material_name[256]; char mpath[256], fg_mpath[256], tpath[256], fg_tpath[256]; - char line[256], *line_ptr; + char line[256], *line_ptr, value[256]; GLubyte *texbuf; fgFile f; int width, height; + int alpha; o = ¤t_options; @@ -114,6 +115,7 @@ int fgMATERIAL_MGR::load_lib ( void ) { // ignore blank lines } else if ( strstr(line_ptr, "{") ) { // start of record + alpha = 0; 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; @@ -126,6 +128,21 @@ int fgMATERIAL_MGR::load_lib ( void ) { line ); } printf(" Loading material = %s\n", material_name); + } else if ( strncmp(line_ptr, "alpha", 5) == 0 ) { + line_ptr += 5; + while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') || + (line_ptr[0] == '=') ) && + (line_ptr[0] != '\n') ) { + line_ptr++; + } + sscanf(line_ptr, "%s\n", value); + if ( strcmp(value, "no") == 0 ) { + alpha = 0; + } else if ( strcmp(value, "yes") == 0 ) { + alpha = 1; + } else { + fgPrintf( FG_TERRAIN, FG_INFO, "Bad alpha value '%s'\n", line ); + } } else if ( strncmp(line_ptr, "texture", 7) == 0 ) { line_ptr += 7; while ( ( (line_ptr[0] == ' ') || (line_ptr[0] == '\t') || @@ -152,7 +169,9 @@ int fgMATERIAL_MGR::load_lib ( void ) { xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT ) ; xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, - GL_LINEAR /* GL_LINEAR_MIPMAP_LINEAR */ ) ; + /* GL_LINEAR */ + /* GL_NEAREST_MIPMAP_LINEAR */ + GL_LINEAR_MIPMAP_LINEAR ) ; xglTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; xglHint( GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST ) ; @@ -163,21 +182,48 @@ int fgMATERIAL_MGR::load_lib ( void ) { strcat(tpath, m.texture_name); strcat(tpath, ".rgb"); - // Try uncompressed - if ( (texbuf = read_rgb_texture(tpath, &width, &height)) == NULL ) { - // Try compressed - strcpy(fg_tpath, tpath); - strcat(fg_tpath, ".gz"); - if ( (texbuf = read_rgb_texture(fg_tpath, &width, &height)) + if ( alpha == 0 ) { + // load rgb texture + + // Try uncompressed + if ( (texbuf = read_rgb_texture(tpath, &width, &height)) == NULL ) { - fgPrintf( FG_GENERAL, FG_EXIT, - "Error loading texture %s\n", tpath ); - return(0); + // Try compressed + strcpy(fg_tpath, tpath); + strcat(fg_tpath, ".gz"); + if ( (texbuf = read_rgb_texture(fg_tpath, &width, &height)) + == NULL ) { + fgPrintf( FG_GENERAL, FG_EXIT, + "Error in loading texture %s\n", tpath ); + return(0); + } } - } - xglTexImage2D(GL_TEXTURE_2D, 0, 3, width, height, 0, - GL_RGB, GL_UNSIGNED_BYTE, texbuf); + /* xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, width, height, 0, + GL_RGB, GL_UNSIGNED_BYTE, texbuf); */ + + gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height, + GL_RGB, GL_UNSIGNED_BYTE, texbuf ); + } else if ( alpha == 1 ) { + // load rgba (alpha) texture + + // Try uncompressed + if ( (texbuf = read_alpha_texture(tpath, &width, &height)) + == NULL ) { + // Try compressed + strcpy(fg_tpath, tpath); + strcat(fg_tpath, ".gz"); + if ((texbuf = read_alpha_texture(fg_tpath, &width, &height)) + == NULL ) { + fgPrintf( FG_GENERAL, FG_EXIT, + "Error in loading texture %s\n", tpath ); + return(0); + } + } + + xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, + GL_RGBA, GL_UNSIGNED_BYTE, texbuf); + } } else if ( strncmp(line_ptr, "ambient", 7) == 0 ) { line_ptr += 7; @@ -255,6 +301,12 @@ fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) { // $Log$ +// Revision 1.7 1998/07/04 00:54:28 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.6 1998/06/27 16:54:59 curt // Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use // "EXT" versions of texture management routines. diff --git a/Scenery/obj.cxx b/Scenery/obj.cxx index 5db17f004..66b8509b3 100644 --- a/Scenery/obj.cxx +++ b/Scenery/obj.cxx @@ -206,6 +206,9 @@ int fgObjLoad(char *path, fgTILE *tile) { // scan the material line sscanf(line, "usemtl %s\n", material); + // give the fragment a pointer back to the tile + (fgTILE *)fragment.tile_ptr = tile; + // find this material in the properties list map < string, fgMATERIAL, less > :: iterator myfind = material_mgr.material_map.find(material); @@ -435,6 +438,12 @@ int fgObjLoad(char *path, fgTILE *tile) { // $Log$ +// Revision 1.15 1998/07/04 00:54:28 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.14 1998/06/17 21:36:40 curt // Load and manage multiple textures defined in the Materials library. // Boost max material fagments for each material property to 800. diff --git a/Scenery/texload.c b/Scenery/texload.c index b03e9bff9..034c1f3ff 100644 --- a/Scenery/texload.c +++ b/Scenery/texload.c @@ -187,6 +187,9 @@ read_alpha_texture(char *name, int *width, int *height) (*width)=image->xsize; (*height)=image->ysize; + + printf("image->zsize = %d\n", image->zsize); + if (image->zsize != 1) { ImageClose(image); return NULL; diff --git a/Scenery/tile.hxx b/Scenery/tile.hxx index 295117936..8eafb627a 100644 --- a/Scenery/tile.hxx +++ b/Scenery/tile.hxx @@ -61,14 +61,21 @@ public: double bounding_radius; // variable offset data for this object fragment for this frame - fgCartesianPoint3d tile_offset; + // fgCartesianPoint3d tile_offset; // saved transformation matrix for this fragment (used by renderer) // GLfloat matrix[16]; + + // tile_ptr & material_ptr are set so that when we traverse the + // list of fragments we can quickly reference back the tile or + // material property this fragment is assigned to. // material property pointer void *material_ptr; + // tile pointer + void *tile_ptr; + // OpenGL display list for fragment data GLint display_list; @@ -89,9 +96,10 @@ public: fgCartesianPoint3d center; double bounding_radius; fgCartesianPoint3d offset; + GLdouble model_view[16]; // this tile's official location in the world - struct fgBUCKET tile_bucket; + fgBUCKET tile_bucket; // the tile cache will mark here if the tile is being used int used; @@ -110,6 +118,12 @@ public: // $Log$ +// Revision 1.8 1998/07/04 00:54:30 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.7 1998/06/12 00:58:05 curt // Build only static libraries. // Declare memmove/memset for Sloaris. diff --git a/Scenery/tilecache.cxx b/Scenery/tilecache.cxx index 4b4fdb8ba..cf7e361f9 100644 --- a/Scenery/tilecache.cxx +++ b/Scenery/tilecache.cxx @@ -64,7 +64,7 @@ void fgTILECACHE::Init( void ) { // Search for the specified "bucket" in the cache -int fgTILECACHE::Exists( struct fgBUCKET *p ) { +int fgTILECACHE::Exists( fgBUCKET *p ) { int i; for ( i = 0; i < FG_TILE_CACHE_SIZE; i++ ) { @@ -86,7 +86,7 @@ int fgTILECACHE::Exists( struct fgBUCKET *p ) { // Fill in a tile cache entry with real data for the specified bucket -void fgTILECACHE::EntryFillIn( int index, struct fgBUCKET *p ) { +void fgTILECACHE::EntryFillIn( int index, fgBUCKET *p ) { fgOPTIONS *o; char base_path[256]; char file_name[256]; @@ -209,6 +209,12 @@ fgTILECACHE::~fgTILECACHE( void ) { // $Log$ +// Revision 1.11 1998/07/04 00:54:30 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.10 1998/05/23 14:09:22 curt // Added tile.cxx and tile.hxx. // Working on rewriting the tile management system so a tile is just a list diff --git a/Scenery/tilecache.hxx b/Scenery/tilecache.hxx index 547dc3ef9..41cf4764c 100644 --- a/Scenery/tilecache.hxx +++ b/Scenery/tilecache.hxx @@ -57,7 +57,7 @@ /* // Tile cache record typedef struct { - struct fgBUCKET tile_bucket; + fgBUCKET tile_bucket; GLint display_list; fgCartesianPoint3d local_ref; double bounding_radius; @@ -81,7 +81,7 @@ public: void Init( void ); // Search for the specified "bucket" in the cache - int Exists( struct fgBUCKET *p ); + int Exists( fgBUCKET *p ); // Return index of next available slot in tile cache int NextAvail( void ); @@ -90,7 +90,7 @@ public: void EntryFree( int index ); // Fill in a tile cache entry with real data for the specified bucket - void EntryFillIn( int index, struct fgBUCKET *p ); + void EntryFillIn( int index, fgBUCKET *p ); // Return a pointer to the specified tile cache entry fgTILE *GetTile( int index ); @@ -108,6 +108,12 @@ extern fgTILECACHE global_tile_cache; // $Log$ +// Revision 1.10 1998/07/04 00:54:31 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.9 1998/05/23 14:09:22 curt // Added tile.cxx and tile.hxx. // Working on rewriting the tile management system so a tile is just a list diff --git a/Scenery/tilemgr.cxx b/Scenery/tilemgr.cxx index 92bc3d91e..fa7e16c10 100644 --- a/Scenery/tilemgr.cxx +++ b/Scenery/tilemgr.cxx @@ -69,7 +69,7 @@ int fgTileMgrInit( void ) { // load a tile -void fgTileMgrLoadTile( struct fgBUCKET *p, int *index) { +void fgTileMgrLoadTile( fgBUCKET *p, int *index) { fgTILECACHE *c; c = &global_tile_cache; @@ -93,8 +93,8 @@ int fgTileMgrUpdate( void ) { fgTILECACHE *c; fgFLIGHT *f; fgOPTIONS *o; - struct fgBUCKET p1, p2; - static struct fgBUCKET p_last = {-1000, 0, 0, 0}; + fgBUCKET p1, p2; + static fgBUCKET p_last = {-1000, 0, 0, 0}; int i, j, dw, dh; c = &global_tile_cache; @@ -299,13 +299,16 @@ void fgTileMgrRender( void ) { fgOPTIONS *o; fgTILE *t; fgVIEW *v; - struct fgBUCKET p; - fgCartesianPoint3d frag_offset, last_offset; + fgBUCKET p; + fgCartesianPoint3d frag_offset; fgFRAGMENT *frag_ptr; fgMATERIAL *mtl_ptr; + fgTILE *last_tile_ptr; + GLdouble *m; + double x, y, z; list < fgFRAGMENT > :: iterator current; list < fgFRAGMENT > :: iterator last; - int i, size; + int i, j, size; int index; int culled = 0; int drawn = 0; @@ -336,13 +339,24 @@ void fgTileMgrRender( void ) { t = c->GetTile(index); // calculate tile offset - t->offset.x = t->center.x - scenery.center.x; - t->offset.y = t->center.y - scenery.center.y; - t->offset.z = t->center.z - scenery.center.z; + x = t->offset.x = t->center.x - scenery.center.x; + y = t->offset.y = t->center.y - scenery.center.y; + z = t->offset.z = t->center.z - scenery.center.z; + + m = t->model_view; + for ( j = 0; j < 16; j++ ) { + m[j] = v->MODEL_VIEW[j]; + } + + // Calculate the model_view transformation matrix for this tile + m[12] = m[0] * x + m[4] * y + m[8] * z + m[12]; + m[13] = m[1] * x + m[5] * y + m[9] * z + m[13]; + m[14] = m[2] * x + m[6] * y + m[10] * z + m[14]; + m[15] = m[3] * x + m[7] * y + m[11] * z + m[15]; // Course (tile based) culling if ( viewable(&(t->offset), t->bounding_radius) ) { - // at least a portion of this tile is viewable + // at least a portion of this tile could be viewable // xglPushMatrix(); // xglTranslatef(t->offset.x, t->offset.y, t->offset.z); @@ -363,20 +377,9 @@ void fgTileMgrRender( void ) { if ( viewable(&frag_offset, frag_ptr->bounding_radius*2) ) { // add to transient per-material property fragment list - frag_ptr->tile_offset.x = t->offset.x; - frag_ptr->tile_offset.y = t->offset.y; - frag_ptr->tile_offset.z = t->offset.z; - - /* - frag_ptr->matrix[12] = t->offset.x; - frag_ptr->matrix[13] = t->offset.y; - frag_ptr->matrix[14] = t->offset.z; - - xglGetFloatv(GL_MODELVIEW_MATRIX, frag_ptr->matrix); - for ( j = 1; j < 16; j++ ) { - printf(" a%d = %f\n", j, frag_ptr->matrix[j]); - } - */ + // frag_ptr->tile_offset.x = t->offset.x; + // frag_ptr->tile_offset.y = t->offset.y; + // frag_ptr->tile_offset.z = t->offset.z; mtl_ptr = (fgMATERIAL *)(frag_ptr->material_ptr); // printf(" lookup = %s\n", mtl_ptr->texture_name); @@ -428,7 +431,7 @@ void fgTileMgrRender( void ) { // (fgMATERIAL)value = (*mapcurrent).second; mtl_ptr = &(*mapcurrent).second; - last_offset.x = last_offset.y = last_offset.z = -99999999.0; + last_tile_ptr = NULL; size = mtl_ptr->list_size; if ( size > 0 ) { @@ -450,36 +453,37 @@ void fgTileMgrRender( void ) { for ( i = 0; i < size; i++ ) { frag_ptr = mtl_ptr->list[i]; - if ( (frag_ptr->tile_offset.x == last_offset.x) && - (frag_ptr->tile_offset.y == last_offset.y) && - (frag_ptr->tile_offset.z == last_offset.z) ) { + if ( frag_ptr->tile_ptr == last_tile_ptr ) { // same tile as last time, no transform necessary } else { // new tile, new translate // xglLoadMatrixf( frag_ptr->matrix ); - xglPopMatrix(); - xglPushMatrix(); - xglTranslatef( frag_ptr->tile_offset.x, - frag_ptr->tile_offset.y, - frag_ptr->tile_offset.z ); + t = (fgTILE *)(frag_ptr->tile_ptr); + xglLoadMatrixd(t->model_view ); } // Woohoo!!! We finally get to draw something! // printf(" display_list = %d\n", frag_ptr->display_list); xglCallList(frag_ptr->display_list); - last_offset = frag_ptr->tile_offset; + last_tile_ptr = (fgTILE *)(frag_ptr->tile_ptr); } } - xglPopMatrix(); - *mapcurrent++; } + + xglPopMatrix(); } // $Log$ +// Revision 1.22 1998/07/04 00:54:31 curt +// Added automatic mipmap generation. +// +// When rendering fragments, use saved model view matrix from associated tile +// rather than recalculating it with push() translate() pop(). +// // Revision 1.21 1998/06/27 16:54:59 curt // Check for GL_VERSION_1_1 or GL_EXT_texture_object to decide whether to use // "EXT" versions of texture management routines.