1
0
Fork 0

Cleaned up all the old fragment and material_mgr stuff which originated

from the pre-ssg / render everything ourselves days.  Replaced with a
material library manager that is much better suited for working in the
context of ssg.  This simplified and cleaned up a ton of old junk.
This commit is contained in:
curt 2000-06-23 00:30:04 +00:00
parent 276a1d5221
commit 39ae3864de
22 changed files with 70 additions and 2046 deletions

View file

@ -3,7 +3,6 @@ noinst_LIBRARIES = libAirports.a
noinst_PROGRAMS = buildsimple
libAirports_a_SOURCES = \
genapt.cxx genapt.hxx \
simple.cxx simple.hxx
buildsimple_SOURCES = buildsimple.cxx

View file

@ -1,296 +0,0 @@
//
// genapt.cxx -- generate airport scenery from the given definition file
//
// Written by Curtis Olson, started September 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include <simgear/compiler.h>
#include STL_STRING
#include <vector>
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <math.h>
#ifdef FG_HAVE_NATIVE_SGI_COMPILERS
# include <strings.h>
#endif
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include <plib/sg.h>
#include <simgear/debug/logstream.hxx>
#include <simgear/math/fg_geodesy.hxx>
#include <simgear/math/point3d.hxx>
#include <simgear/math/polar3d.hxx>
#include <simgear/misc/fgstream.hxx>
#include <Objects/materialmgr.hxx>
#include "genapt.hxx"
FG_USING_STD(string);
FG_USING_STD(vector);
typedef vector < Point3D > container;
typedef container::iterator iterator;
typedef container::const_iterator const_iterator;
#define FG_APT_BASE_TEX_CONSTANT 2000.0
// Calculate texture coordinates for a given point.
static Point3D calc_tex_coords(const Point3D& node, const Point3D& ref) {
Point3D cp;
Point3D pp;
cp = Point3D( node[0] + ref.x(), node[1] + ref.y(), node[2] + ref.z() );
pp = fgCartToPolar3d(cp);
pp.setx( fmod(FG_APT_BASE_TEX_CONSTANT * pp.x(), 10.0) );
pp.sety( fmod(FG_APT_BASE_TEX_CONSTANT * pp.y(), 10.0) );
if ( pp.x() < 0.0 ) {
pp.setx( pp.x() + 10.0 );
}
if ( pp.y() < 0.0 ) {
pp.sety( pp.y() + 10.0 );
}
return(pp);
}
// generate the actual base area for the airport
static void
gen_base( const Point3D& average, const container& perimeter, FGTileEntry *t)
{
GLint display_list;
Point3D cart, cart_trans, tex;
sgVec3 normal;
double dist, max_dist;
int center_num, i;
fgFRAGMENT fragment;
max_dist = 0.0;
FG_LOG( FG_TERRAIN, FG_INFO,
"generating airport base for size = " << perimeter.size() );
fragment.init();
fragment.tile_ptr = t;
// find airport base material in the properties list
if ( ! material_mgr.find( APT_BASE_MATERIAL, fragment.material_ptr )) {
FG_LOG( FG_TERRAIN, FG_ALERT,
"Ack! unknown material name = " << APT_BASE_MATERIAL
<< " in fgAptGenerat()" );
}
FG_LOG( FG_TERRAIN, FG_INFO,
" tile center = "
<< t->center.x() << " " << t->center.y() << " " << t->center.z() );
FG_LOG( FG_TERRAIN, FG_INFO,
" airport center = "
<< average.x() << " " << average.y() << " " << average.z() );
fragment.center = average;
sgSetVec3( normal, average.x(), average.y(), average.z() );
sgNormalizeVec3( normal );
display_list = xglGenLists(1);
xglNewList(display_list, GL_COMPILE);
xglBegin(GL_TRIANGLE_FAN);
// first point center of fan
cart_trans = average - t->center;
t->nodes[t->ncount][0] = cart_trans.x();
t->nodes[t->ncount][1] = cart_trans.y();
t->nodes[t->ncount][2] = cart_trans.z();
center_num = t->ncount;
t->ncount++;
tex = calc_tex_coords( t->nodes[t->ncount-1], t->center );
xglTexCoord2f(tex.x(), tex.y());
xglNormal3fv(normal);
xglVertex3d(t->nodes[t->ncount-1][0],
t->nodes[t->ncount-1][1],
t->nodes[t->ncount-1][2]);
// first point on perimeter
const_iterator current = perimeter.begin();
cart = fgGeodToCart( *current );
cart_trans = cart - t->center;
t->nodes[t->ncount][0] = cart_trans.x();
t->nodes[t->ncount][1] = cart_trans.y();
t->nodes[t->ncount][2] = cart_trans.z();
t->ncount++;
i = 1;
tex = calc_tex_coords( t->nodes[i], t->center );
dist = cart.distance3Dsquared(average);
if ( dist > max_dist ) {
max_dist = dist;
}
xglTexCoord2f(tex.x(), tex.y());
xglVertex3dv(t->nodes[i].get_n());
++current;
++i;
const_iterator last = perimeter.end();
for ( ; current != last; ++current ) {
cart = fgGeodToCart( *current );
cart_trans = cart - t->center;
t->nodes[t->ncount][0] = cart_trans.x();
t->nodes[t->ncount][1] = cart_trans.y();
t->nodes[t->ncount][2] = cart_trans.z();
t->ncount++;
fragment.add_face(center_num, i - 1, i);
tex = calc_tex_coords( t->nodes[i], t->center );
dist = cart.distance3Dsquared(average);
if ( dist > max_dist ) {
max_dist = dist;
}
xglTexCoord2f(tex.x(), tex.y());
xglVertex3dv(t->nodes[i].get_n());
i++;
}
// last point (first point in perimeter list)
current = perimeter.begin();
cart = fgGeodToCart( *current );
cart_trans = cart - t->center;
fragment.add_face(center_num, i - 1, 1);
tex = calc_tex_coords( t->nodes[1], t->center );
xglTexCoord2f(tex.x(), tex.y());
xglVertex3dv(t->nodes[1].get_n());
xglEnd();
xglEndList();
fragment.bounding_radius = sqrt(max_dist);
// fragment.display_list = display_list;
t->fragment_list.push_back(fragment);
}
// Load a .apt file and register the GL fragments with the
// corresponding tile
int
fgAptGenerate(const string& path, FGTileEntry *tile)
{
string token;
string apt_id, apt_name;
char c;
int i = 1;
// face list (this indexes into the master tile vertex list)
container perimeter;
Point3D p, average;
double avex = 0.0, avey = 0.0, avez = 0.0;
int size;
// gpc_vertex p_2d, list_2d[MAX_PERIMETER];
// gpc_vertex_list perimeter_2d;
fg_gzifstream in( path );
if ( !in.is_open() ) {
// return immediately assuming an airport file for this tile
// doesn't exist.
return 0;
}
apt_id = "";
// read in each line of the file
in >> skipcomment;
while ( ! in.eof() )
{
in >> token;
if ( token == "a" ) {
// airport info record (start of airport)
if ( apt_id.length() > 0 ) {
// we have just finished reading and airport record.
// process the info
gen_base(average, perimeter, tile);
}
FG_LOG( FG_TERRAIN, FG_INFO, "Reading airport record" );
in >> apt_id;
apt_name = "";
i = 1;
avex = avey = avez = 0.0;
perimeter.erase( perimeter.begin(), perimeter.end() );
// skip to end of line.
while ( in.get(c) && c != '\n' ) {
apt_name += c;
}
FG_LOG( FG_TERRAIN, FG_INFO,
"\tID = " << apt_id << " Name = " << apt_name );
} else if ( token == "p" ) {
// airport area bounding polygon coordinate. These
// specify a convex hull that should already have been cut
// out of the base terrain. The points are given in
// counter clockwise order and are specified in lon/lat
// degrees.
in >> p;
avex += tile->nodes[i][0];
avey += tile->nodes[i][1];
avez += tile->nodes[i][2];
perimeter.push_back(p);
++i;
} else if ( token == "r" ) {
// runway record
// skip for now
while ( in.get(c) && c != '\n' );
}
in >> skipcomment;
}
if ( apt_id.length() > 0 ) {
// we have just finished reading and airport record.
// process the info
size = perimeter.size();
average = Point3D( avex / (double)size + tile->center.x(),
avey / (double)size + tile->center.y(),
avez / (double)size + tile->center.z() );
gen_base(average, perimeter, tile);
}
return 1;
}

View file

@ -1,65 +0,0 @@
//
// getapt.hxx -- generate airport scenery from the given definition file
//
// Written by Curtis Olson, started September 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _GENAPT_HXX
#define _GENAPT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#include <simgear/compiler.h>
#include STL_STRING
#include <set>
#ifdef __BORLANDC__
# define exception c_exception
#endif
#include <Scenery/tileentry.hxx>
FG_USING_STD(string);
FG_USING_STD(set);
// maximum size of airport perimeter structure, even for complex
// airports such as KORD this number is typically not very big.
#define MAX_PERIMETER 20
// name of the material to use for the airport base
#define APT_BASE_MATERIAL "grass"
// Load a .apt file and register the GL fragments with the
// corresponding tile
int
fgAptGenerate(const string& path, FGTileEntry *tile);
#endif /* _AIRPORTS_HXX */

View file

@ -62,7 +62,6 @@ fgfs_LDADD = \
$(top_builddir)/src/Airports/libAirports.a \
$(NETWORK_LIBS) \
$(top_builddir)/src/Objects/libObjects.a \
$(top_builddir)/src/Clouds/libClouds.a \
$(top_builddir)/src/Time/libTime.a \
$(WEATHER_LIBS) \
$(top_builddir)/src/Sky/libSky.a \

View file

@ -70,6 +70,7 @@
#include <FDM/MagicCarpet.hxx>
#include <Include/general.hxx>
#include <Joystick/joystick.hxx>
#include <Objects/matlib.hxx>
#include <Navaids/fixlist.hxx>
#include <Navaids/ilslist.hxx>
#include <Navaids/navlist.hxx>
@ -273,9 +274,18 @@ bool fgInitSubsystems( void ) {
// set the initial position
fgInitPosition();
// Initialize the material property lib
FGPath mpath( current_options.get_fg_root() );
mpath.append( "materials" );
if ( material_lib.load( mpath.str() ) ) {
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error loading material lib!" );
exit(-1);
}
// Initialize the Scenery Management subsystem
if ( fgSceneryInit() ) {
// Scenery initialized ok.
// Material lib initialized ok.
} else {
FG_LOG( FG_GENERAL, FG_ALERT, "Error in Scenery initialization!" );
exit(-1);

View file

@ -55,7 +55,7 @@
#include <Cockpit/hud.hxx>
#include <GUI/gui.h>
#include <Scenery/tilemgr.hxx>
#include <Objects/materialmgr.hxx>
#include <Objects/matlib.hxx>
#include <Time/fg_time.hxx>
#include <Time/light.hxx>
@ -529,18 +529,13 @@ void GLUTspecialkey(int k, int x, int y) {
return;
case GLUT_KEY_F9: // F9 toggles textures on and off...
if ( material_mgr.loaded() ) {
if (current_options.get_textures()) {
current_options.set_textures(false);
material_mgr.set_step(1);
} else {
current_options.set_textures(true);
material_mgr.set_step(0);
}
FG_LOG( FG_INPUT, FG_INFO, "Toggling texture" );
FG_LOG( FG_INPUT, FG_INFO, "Toggling texture" );
if ( current_options.get_textures() ) {
current_options.set_textures( false );
material_lib.set_step( 1 );
} else {
FG_LOG( FG_INPUT, FG_INFO,
"No textures loaded, cannot toggle" );
current_options.set_textures( true );
material_lib.set_step( 0 );
}
return;
case GLUT_KEY_F10: // F10 toggles menu on and off...

View file

@ -87,7 +87,6 @@
#ifdef FG_NETWORK_OLK
#include <NetworkOLK/network.h>
#endif
#include <Objects/materialmgr.hxx>
#include <Scenery/scenery.hxx>
#include <Scenery/tilemgr.hxx>
#include <Sky/sky.hxx>

View file

@ -15,7 +15,6 @@ SUBDIRS = \
Aircraft \
Airports \
Autopilot \
Clouds \
Cockpit \
Controls \
Ephemeris \

View file

@ -1,9 +1,8 @@
noinst_LIBRARIES = libObjects.a
libObjects_a_SOURCES = \
fragment.cxx fragment.hxx \
material.cxx material.hxx \
materialmgr.cxx materialmgr.hxx \
newmat.cxx newmat.hxx \
matlib.cxx matlib.hxx \
obj.cxx obj.hxx \
texload.c texload.h colours.h

View file

@ -1,330 +0,0 @@
// fragment.cxx -- routines to handle "atomic" display objects
//
// Written by Curtis Olson, started August 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
#include <Scenery/tileentry.hxx>
#include "fragment.hxx"
template <class T>
inline const int FG_SIGN(const T& x) {
return x < T(0) ? -1 : 1;
}
template <class T>
inline const T& FG_MIN(const T& a, const T& b) {
return b < a ? b : a;
}
template <class T>
inline const T& FG_MAX(const T& a, const T& b) {
return a < b ? b : a;
}
// return the minimum of the three values
template <class T>
inline const T& fg_min3( const T& a, const T& b, const T& c)
{
return (a > b ? FG_MIN (b, c) : FG_MIN (a, c));
}
// return the maximum of the three values
template <class T>
inline const T& fg_max3 (const T& a, const T& b, const T& c)
{
return (a < b ? FG_MAX (b, c) : FG_MAX (a, c));
}
// Add a face to the face list
// Copy constructor
fgFRAGMENT::fgFRAGMENT ( const fgFRAGMENT & rhs ) :
center ( rhs.center ),
bounding_radius( rhs.bounding_radius ),
material_ptr ( rhs.material_ptr ),
tile_ptr ( rhs.tile_ptr ),
/* display_list ( rhs.display_list ), */
faces ( rhs.faces )
{
}
fgFRAGMENT & fgFRAGMENT::operator = ( const fgFRAGMENT & rhs )
{
if(!(this == &rhs )) {
center = rhs.center;
bounding_radius = rhs.bounding_radius;
material_ptr = rhs.material_ptr;
tile_ptr = rhs.tile_ptr;
// display_list = rhs.display_list;
faces = rhs.faces;
}
return *this;
}
// test if line intesects with this fragment. p0 and p1 are the two
// line end points of the line. If side_flag is true, check to see
// that end points are on opposite sides of face. Returns 1 if it
// intersection found, 0 otherwise. If it intesects, result is the
// point of intersection
int fgFRAGMENT::intersect( const Point3D& end0,
const Point3D& end1,
int side_flag,
Point3D& result) const
{
FGTileEntry *t;
sgVec3 v1, v2, n, center;
sgVec3 p1, p2, p3;
sgVec3 temp;
double x, y, z; // temporary holding spot for result
double a, b, c, d;
double x0, y0, z0, x1, y1, z1, a1, b1, c1;
double t1, t2, t3;
double xmin, xmax, ymin, ymax, zmin, zmax;
double dx, dy, dz, min_dim, x2, y2, x3, y3, rx, ry;
int side1, side2;
// find the associated tile
t = tile_ptr;
// printf("Intersecting\n");
// traverse the face list for this fragment
const_iterator last = faces.end();
for ( const_iterator current = faces.begin(); current != last; ++current )
{
// printf(".");
// get face vertex coordinates
sgSetVec3( center, t->center.x(), t->center.y(), t->center.z() );
sgSetVec3( temp, t->nodes[(*current).n1].x(),
t->nodes[(*current).n1].y(), t->nodes[(*current).n1].z() );
sgAddVec3( p1, temp, center );
sgSetVec3( temp, t->nodes[(*current).n2].x(),
t->nodes[(*current).n2].y(), t->nodes[(*current).n2].z() );
sgAddVec3( p2, temp, center );
sgSetVec3( temp, t->nodes[(*current).n3].x(),
t->nodes[(*current).n3].y(), t->nodes[(*current).n3].z() );
sgAddVec3( p3, temp, center );
// printf("point 1 = %.2f %.2f %.2f\n", p1[0], p1[1], p1[2]);
// printf("point 2 = %.2f %.2f %.2f\n", p2[0], p2[1], p2[2]);
// printf("point 3 = %.2f %.2f %.2f\n", p3[0], p3[1], p3[2]);
// calculate two edge vectors, and the face normal
sgSubVec3( v1, p2, p1 );
sgSubVec3( v2, p3, p1 );
sgVectorProductVec3( n, v1, v2 );
// calculate the plane coefficients for the plane defined by
// this face. If n is the normal vector, n = (a, b, c) and p1
// is a point on the plane, p1 = (x0, y0, z0), then the
// equation of the line is a(x-x0) + b(y-y0) + c(z-z0) = 0
a = n[0];
b = n[1];
c = n[2];
d = a * p1[0] + b * p1[1] + c * p1[2];
// printf("a, b, c, d = %.2f %.2f %.2f %.2f\n", a, b, c, d);
// printf("p1(d) = %.2f\n", a * p1[0] + b * p1[1] + c * p1[2]);
// printf("p2(d) = %.2f\n", a * p2[0] + b * p2[1] + c * p2[2]);
// printf("p3(d) = %.2f\n", a * p3[0] + b * p3[1] + c * p3[2]);
// calculate the line coefficients for the specified line
x0 = end0.x(); x1 = end1.x();
y0 = end0.y(); y1 = end1.y();
z0 = end0.z(); z1 = end1.z();
if ( fabs(x1 - x0) > FG_EPSILON ) {
a1 = 1.0 / (x1 - x0);
} else {
// we got a big divide by zero problem here
a1 = 0.0;
}
b1 = y1 - y0;
c1 = z1 - z0;
// intersect the specified line with this plane
t1 = b * b1 * a1;
t2 = c * c1 * a1;
// printf("a = %.2f t1 = %.2f t2 = %.2f\n", a, t1, t2);
if ( fabs(a + t1 + t2) > FG_EPSILON ) {
x = (t1*x0 - b*y0 + t2*x0 - c*z0 + d) / (a + t1 + t2);
t3 = a1 * (x - x0);
y = b1 * t3 + y0;
z = c1 * t3 + z0;
// printf("result(d) = %.2f\n", a * x + b * y + c * z);
} else {
// no intersection point
continue;
}
if ( side_flag ) {
// check to see if end0 and end1 are on opposite sides of
// plane
if ( (x - x0) > FG_EPSILON ) {
t1 = x;
t2 = x0;
t3 = x1;
} else if ( (y - y0) > FG_EPSILON ) {
t1 = y;
t2 = y0;
t3 = y1;
} else if ( (z - z0) > FG_EPSILON ) {
t1 = z;
t2 = z0;
t3 = z1;
} else {
// everything is too close together to tell the difference
// so the current intersection point should work as good
// as any
result = Point3D(x, y, z);
return(1);
}
side1 = FG_SIGN (t1 - t2);
side2 = FG_SIGN (t1 - t3);
if ( side1 == side2 ) {
// same side, punt
continue;
}
}
// check to see if intersection point is in the bounding
// cube of the face
#ifdef XTRA_DEBUG_STUFF
xmin = fg_min3 (p1[0], p2[0], p3[0]);
xmax = fg_max3 (p1[0], p2[0], p3[0]);
ymin = fg_min3 (p1[1], p2[1], p3[1]);
ymax = fg_max3 (p1[1], p2[1], p3[1]);
zmin = fg_min3 (p1[2], p2[2], p3[2]);
zmax = fg_max3 (p1[2], p2[2], p3[2]);
printf("bounding cube = %.2f,%.2f,%.2f %.2f,%.2f,%.2f\n",
xmin, ymin, zmin, xmax, ymax, zmax);
#endif
// punt if outside bouding cube
if ( x < (xmin = fg_min3 (p1[0], p2[0], p3[0])) ) {
continue;
} else if ( x > (xmax = fg_max3 (p1[0], p2[0], p3[0])) ) {
continue;
} else if ( y < (ymin = fg_min3 (p1[1], p2[1], p3[1])) ) {
continue;
} else if ( y > (ymax = fg_max3 (p1[1], p2[1], p3[1])) ) {
continue;
} else if ( z < (zmin = fg_min3 (p1[2], p2[2], p3[2])) ) {
continue;
} else if ( z > (zmax = fg_max3 (p1[2], p2[2], p3[2])) ) {
continue;
}
// (finally) check to see if the intersection point is
// actually inside this face
//first, drop the smallest dimension so we only have to work
//in 2d.
dx = xmax - xmin;
dy = ymax - ymin;
dz = zmax - zmin;
min_dim = fg_min3 (dx, dy, dz);
if ( fabs(min_dim - dx) <= FG_EPSILON ) {
// x is the smallest dimension
x1 = p1[1];
y1 = p1[2];
x2 = p2[1];
y2 = p2[2];
x3 = p3[1];
y3 = p3[2];
rx = y;
ry = z;
} else if ( fabs(min_dim - dy) <= FG_EPSILON ) {
// y is the smallest dimension
x1 = p1[0];
y1 = p1[2];
x2 = p2[0];
y2 = p2[2];
x3 = p3[0];
y3 = p3[2];
rx = x;
ry = z;
} else if ( fabs(min_dim - dz) <= FG_EPSILON ) {
// z is the smallest dimension
x1 = p1[0];
y1 = p1[1];
x2 = p2[0];
y2 = p2[1];
x3 = p3[0];
y3 = p3[1];
rx = x;
ry = y;
} else {
// all dimensions are really small so lets call it close
// enough and return a successful match
result = Point3D(x, y, z);
return 1;
}
// check if intersection point is on the same side of p1 <-> p2 as p3
t1 = (y1 - y2) / (x1 - x2);
side1 = FG_SIGN (t1 * ((x3) - x2) + y2 - (y3));
side2 = FG_SIGN (t1 * ((rx) - x2) + y2 - (ry));
if ( side1 != side2 ) {
// printf("failed side 1 check\n");
continue;
}
// check if intersection point is on correct side of p2 <-> p3 as p1
t1 = (y2 - y3) / (x2 - x3);
side1 = FG_SIGN (t1 * ((x1) - x3) + y3 - (y1));
side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
if ( side1 != side2 ) {
// printf("failed side 2 check\n");
continue;
}
// check if intersection point is on correct side of p1 <-> p3 as p2
t1 = (y1 - y3) / (x1 - x3);
side1 = FG_SIGN (t1 * ((x2) - x3) + y3 - (y2));
side2 = FG_SIGN (t1 * ((rx) - x3) + y3 - (ry));
if ( side1 != side2 ) {
// printf("failed side 3 check\n");
continue;
}
// printf( "intersection point = %.2f %.2f %.2f\n", x, y, z);
result = Point3D(x, y, z);
return 1;
}
// printf("\n");
return 0;
}

View file

@ -1,171 +0,0 @@
// fragment.hxx -- routines to handle "atomic" display objects
//
// Written by Curtis Olson, started August 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _FRAGMENT_HXX
#define _FRAGMENT_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include <simgear/compiler.h>
#include <vector>
#include <simgear/constants.h>
#include <simgear/math/point3d.hxx>
FG_USING_STD(vector);
struct fgFACE {
int n1, n2, n3;
fgFACE( int a = 0, int b =0, int c =0 )
: n1(a), n2(b), n3(c) {}
fgFACE( const fgFACE & image )
: n1(image.n1), n2(image.n2), n3(image.n3) {}
fgFACE& operator= ( const fgFACE & image ) {
n1 = image.n1; n2 = image.n2; n3 = image.n3; return *this;
}
~fgFACE() {}
};
inline bool
operator== ( const fgFACE& lhs, const fgFACE& rhs )
{
return (lhs.n1 == rhs.n1) && (lhs.n2 == rhs.n2) && (lhs.n3 == rhs.n3);
}
// Forward declarations
class FGTileEntry;
class FGMaterialSlot;
// Object fragment data class
class fgFRAGMENT {
private:
public:
// culling data for this object fragment (fine grain culling)
Point3D center;
double bounding_radius;
// variable offset data for this object fragment for this frame
// 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
FGMaterialSlot *material_ptr;
// tile pointer
FGTileEntry *tile_ptr;
// OpenGL display list for fragment data
// GLint display_list;
// face list (this indexes into the master tile vertex list)
typedef vector < fgFACE > container;
typedef container::iterator iterator;
typedef container::const_iterator const_iterator;
container faces;
public:
// number of faces in this fragment
int num_faces() {
return faces.size();
}
// Add a face to the face list
void add_face(int n1, int n2, int n3) {
faces.push_back( fgFACE(n1,n2,n3) );
}
// test if line intesects with this fragment. p0 and p1 are the
// two line end points of the line. If side_flag is true, check
// to see that end points are on opposite sides of face. Returns
// 1 if it intersection found, 0 otherwise. If it intesects,
// result is the point of intersection
int intersect( const Point3D& end0,
const Point3D& end1,
int side_flag,
Point3D& result) const;
// Constructors
fgFRAGMENT () { /*faces.reserve(512);*/}
fgFRAGMENT ( const fgFRAGMENT &image );
// Destructor
~fgFRAGMENT() { faces.erase( faces.begin(), faces.end() ); }
// operators
fgFRAGMENT & operator = ( const fgFRAGMENT & rhs );
bool operator < ( const fgFRAGMENT & rhs ) const {
// This is completely arbitrary. It satisfies RW's STL implementation
return bounding_radius < rhs.bounding_radius;
}
void init() {
faces.clear();
}
// int deleteDisplayList() {
// xglDeleteLists( display_list, 1 ); return 0;
// }
friend bool operator== ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs );
};
inline bool
operator == ( const fgFRAGMENT & lhs, const fgFRAGMENT & rhs ) {
return lhs.center == rhs.center;
}
#endif // _FRAGMENT_HXX

View file

@ -1,286 +0,0 @@
// material.cxx -- class to handle material properties
//
// Written by Curtis Olson, started May 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#include <simgear/compiler.h>
#ifdef FG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include STL_STRING
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/fgpath.hxx>
#include <simgear/misc/fgstream.hxx>
#include "material.hxx"
#include "texload.h"
FG_USING_STD(string);
// Constructor
FGMaterial::FGMaterial ( void )
: loaded(false),
texture_name(""),
alpha(0)
// , list_size(0)
{
ambient[0] = ambient[1] = ambient[2] = ambient[3] = 0.0;
diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 0.0;
specular[0] = specular[1] = specular[2] = specular[3] = 0.0;
emission[0] = emission[1] = emission[2] = emission[3] = 0.0;
}
// Constructor
FGMaterial::FGMaterial ( const string &name )
: loaded(false),
alpha(0)
// , list_size(0)
{
texture_name = name;
xsize = ysize = 0;
alpha = 0;
ambient[0] = ambient[1] = ambient[2] = ambient[3] = 1.0;
diffuse[0] = diffuse[1] = diffuse[2] = diffuse[3] = 1.0;
specular[0] = specular[1] = specular[2] = specular[3] = 1.0;
emission[0] = emission[1] = emission[2] = emission[3] = 1.0;
}
istream&
operator >> ( istream& in, FGMaterial& m )
{
string token;
for (;;) {
in >> token;
if ( token == "texture" ) {
in >> token >> m.texture_name;
} else if ( token == "xsize" ) {
in >> token >> m.xsize;
} else if ( token == "ysize" ) {
in >> token >> m.ysize;
} else if ( token == "ambient" ) {
in >> token >> m.ambient[0] >> m.ambient[1]
>> m.ambient[2] >> m.ambient[3];
} else if ( token == "diffuse" ) {
in >> token >> m.diffuse[0] >> m.diffuse[1]
>> m.diffuse[2] >> m.diffuse[3];
} else if ( token == "specular" ) {
in >> token >> m.specular[0] >> m.specular[1]
>> m.specular[2] >> m.specular[3];
} else if ( token == "emission" ) {
in >> token >> m.emission[0] >> m.emission[1]
>> m.emission[2] >> m.emission[3];
} else if ( token == "alpha" ) {
in >> token >> token;
if ( token == "yes" ) {
m.alpha = 1;
} else if ( token == "no" ) {
m.alpha = 0;
} else {
FG_LOG( FG_TERRAIN, FG_INFO, "Bad alpha value " << token );
}
} else if ( token[0] == '}' ) {
break;
}
}
return in;
}
void
FGMaterial::load_texture( const string& root )
{
GLubyte *texbuf;
int width, height;
FG_LOG( FG_TERRAIN, FG_INFO,
" Loading texture for material " << texture_name );
// create the texture object and bind it
#ifdef GL_VERSION_1_1
xglGenTextures(1, &texture_id );
xglBindTexture(GL_TEXTURE_2D, texture_id );
#elif GL_EXT_texture_object
xglGenTexturesEXT(1, &texture_id );
xglBindTextureEXT(GL_TEXTURE_2D, texture_id );
#else
# error port me
#endif
// set the texture parameters back to the defaults for loading
// this texture
xglPixelStorei(GL_UNPACK_ALIGNMENT, 4);
xglPixelStorei(GL_UNPACK_ROW_LENGTH, 0);
xglPixelStorei(GL_UNPACK_SKIP_PIXELS, 0);
xglPixelStorei(GL_UNPACK_SKIP_ROWS, 0);
xglTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT ) ;
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_NEAREST_MIPMAP_LINEAR */
GL_LINEAR_MIPMAP_LINEAR ) ;
// load in the texture data
FGPath base_path( root );
base_path.append( "Textures" );
base_path.append( texture_name );
FGPath tpath = base_path;
tpath.concat( ".rgb" );
FGPath fg_tpath = tpath;
fg_tpath.concat( ".gz" );
FGPath fg_raw_tpath = base_path;
fg_raw_tpath.concat( ".raw" );
// create string names for msfs compatible textures
FGPath fg_r8_tpath = base_path;
fg_r8_tpath.concat( ".r8" );
FGPath fg_tex_tpath = base_path;
fg_tex_tpath.concat( ".txt" );
FGPath fg_pat_tpath = base_path;
fg_pat_tpath.concat( ".pat" );
FGPath fg_oav_tpath = base_path;
fg_oav_tpath.concat( ".oav" );
if ( alpha == 0 ) {
// load rgb texture
// Try uncompressed
if ( (texbuf =
read_rgb_texture(tpath.c_str(), &width, &height)) !=
NULL )
;
// Try compressed
else if ( (texbuf =
read_rgb_texture(fg_tpath.c_str(), &width, &height))
!= NULL )
;
// Try raw
else if ( (texbuf =
read_raw_texture(fg_raw_tpath.c_str(), &width, &height))
!= NULL )
;
// Try r8
else if ( (texbuf =
read_r8_texture(fg_r8_tpath.c_str(), &width, &height))
!= NULL )
;
// Try tex
else if ( (texbuf =
read_r8_texture(fg_tex_tpath.c_str(), &width, &height))
!= NULL )
;
// Try pat
else if ( (texbuf =
read_r8_texture(fg_pat_tpath.c_str(), &width, &height))
!= NULL )
;
// Try oav
else if ( (texbuf =
read_r8_texture(fg_oav_tpath.c_str(), &width, &height))
!= NULL )
;
else {
FG_LOG( FG_GENERAL, FG_ALERT,
"Error in loading texture " << tpath.str() );
exit(-1);
}
if ( gluBuild2DMipmaps( GL_TEXTURE_2D, GL_RGB, width, height,
GL_RGB, GL_UNSIGNED_BYTE, texbuf ) != 0 )
{
FG_LOG( FG_GENERAL, FG_ALERT, "Error building mipmaps");
exit(-1);
}
} else if ( alpha == 1 ) {
// load rgba (alpha) texture
// Try uncompressed
if ( (texbuf =
read_alpha_texture(tpath.c_str(), &width, &height))
== NULL )
{
// Try compressed
if ((texbuf =
read_alpha_texture(fg_tpath.c_str(), &width, &height))
== NULL )
{
FG_LOG( FG_GENERAL, FG_ALERT,
"Error in loading texture " << tpath.str() );
exit(-1);
}
}
xglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0,
GL_RGBA, GL_UNSIGNED_BYTE, texbuf);
}
loaded = true;
}
// Destructor
void FGMaterial::dump_info () {
FG_LOG( FG_TERRAIN, FG_INFO, "{" << endl << " texture = "
<< texture_name );
FG_LOG( FG_TERRAIN, FG_INFO, " xsize = " << xsize );
FG_LOG( FG_TERRAIN, FG_INFO, " ysize = " << ysize );
FG_LOG( FG_TERRAIN, FG_INFO, " ambient = " << ambient[0] << " "
<< ambient[1] <<" "<< ambient[2] <<" "<< ambient[3] );
FG_LOG( FG_TERRAIN, FG_INFO, " diffuse = " << diffuse[0] << " "
<< diffuse[1] << " " << diffuse[2] << " " << diffuse[3] );
FG_LOG( FG_TERRAIN, FG_INFO, " specular = " << specular[0] << " "
<< specular[1] << " " << specular[2] << " " << specular[3]);
FG_LOG( FG_TERRAIN, FG_INFO, " emission = " << emission[0] << " "
<< emission[1] << " " << emission[2] << " " << emission[3]);
FG_LOG( FG_TERRAIN, FG_INFO, " alpha = " << alpha << endl <<"}" );
}
// Destructor
FGMaterial::~FGMaterial ( void ) {
}

View file

@ -1,106 +0,0 @@
// material.hxx -- class to handle material properties
//
// Written by Curtis Olson, started May 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _MATERIAL_HXX
#define _MATERIAL_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include STL_STRING // Standard C++ string library
FG_USING_STD(string);
// MSVC++ 6.0 kuldge - Need forward declaration of friends.
class FGMaterial;
istream& operator >> ( istream& in, FGMaterial& m );
// Material property class
class FGMaterial {
private:
// texture loaded
bool loaded;
// 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], emission[4];
GLint texture_ptr;
public:
// Constructor
FGMaterial ( void );
FGMaterial ( const string& name );
// Destructor
~FGMaterial ( void );
void load_texture( const string& root );
friend istream& operator >> ( istream& in, FGMaterial& m );
inline bool is_loaded() const { return loaded; }
inline GLuint get_texture_id() const { return texture_id; }
inline string get_texture_name() const { return texture_name; }
inline double get_xsize() const { return xsize; }
inline double get_ysize() const { return ysize; }
inline GLfloat *get_ambient() { return ambient; }
inline GLfloat *get_diffuse() { return diffuse; }
inline GLfloat *get_specular() { return specular; }
inline GLfloat *get_emission() { return emission; }
void dump_info();
};
#endif // _MATERIAL_HXX

View file

@ -1,418 +0,0 @@
// materialmgr.cxx -- class to handle material properties
//
// Written by Curtis Olson, started May 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef FG_MATH_EXCEPTION_CLASH
# include <math.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include <simgear/compiler.h>
#include <string.h>
#include STL_STRING
#include <simgear/debug/logstream.hxx>
#include <simgear/misc/fgpath.hxx>
#include <simgear/misc/fgstream.hxx>
#include <Main/options.hxx>
#include <Main/views.hxx>
#include <Scenery/tileentry.hxx>
#include "materialmgr.hxx"
#include "fragment.hxx"
FG_USING_STD(string);
// global material management class
fgMATERIAL_MGR material_mgr;
// Constructor
FGMaterialSlot::FGMaterialSlot ( void ) { }
// Destructor
FGMaterialSlot::~FGMaterialSlot ( void ) {
}
// Constructor
fgMATERIAL_MGR::fgMATERIAL_MGR ( void ) {
materials_loaded = false;
}
#if 0
void
FGMaterialSlot::render_fragments()
{
FG_LOG( FG_GENERAL, FG_ALERT,
"FGMaterialSlot::render_fragments() is depricated ... " <<
"we shouldn't be here!" );
int tris_rendered = current_view.get_tris_rendered();
// cout << "rendering " + texture_name + " = " << list_size << "\n";
if ( empty() ) {
return;
}
if ( current_options.get_textures() ) {
if ( !m.is_loaded() ) {
m.load_texture( current_options.get_fg_root() );
}
#ifdef GL_VERSION_1_1
xglBindTexture( GL_TEXTURE_2D, m.get_texture_id() );
#elif GL_EXT_texture_object
xglBindTextureEXT( GL_TEXTURE_2D, m.get_texture_id() );
#else
# error port me
#endif
} else {
xglMaterialfv (GL_FRONT, GL_AMBIENT, m.get_ambient() );
xglMaterialfv (GL_FRONT, GL_DIFFUSE, m.get_diffuse() );
}
FGTileEntry* last_tile_ptr = NULL;
frag_list_iterator current = list.begin();
frag_list_iterator last = list.end();
for ( ; current != last; ++current ) {
fgFRAGMENT* frag_ptr = *current;
tris_rendered += frag_ptr->num_faces();
if ( frag_ptr->tile_ptr != last_tile_ptr ) {
// new tile, new translate
last_tile_ptr = frag_ptr->tile_ptr;
xglLoadMatrixf( frag_ptr->tile_ptr->model_view );
}
// Woohoo!!! We finally get to draw something!
// printf(" display_list = %d\n", frag_ptr->display_list);
// xglCallList( frag_ptr->display_list );
}
current_view.set_tris_rendered( tris_rendered );
}
#endif
// Load a library of material properties
int
fgMATERIAL_MGR::load_lib ( void )
{
string material_name;
// build the path name to the material db
FGPath mpath( current_options.get_fg_root() );
mpath.append( "materials" );
fg_gzifstream in( mpath.str() );
if ( ! in.is_open() ) {
FG_LOG( FG_GENERAL, FG_ALERT, "Cannot open file: " << mpath.str() );
exit(-1);
}
#ifndef __MWERKS__
while ( ! in.eof() ) {
#else
char c = '\0';
while ( in.get(c) && c != '\0' ) {
in.putback(c);
#endif
// printf("%s", line);
// strip leading white space and comments
in >> skipcomment;
// set to zero to prevent its value accidently being '{'
// after a failed >> operation.
char token = 0;
in >> material_name >> token;
if ( token == '{' ) {
FGMaterial m;
in >> m;
FGMaterialSlot m_slot;
m_slot.set_m( m );
// build the ssgSimpleState
FGPath tex_file( current_options.get_fg_root() );
tex_file.append( "Textures" );
tex_file.append( m.get_texture_name() );
// tex_file.concat( ".rgb" );
FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
<< material_name << " (" << tex_file.c_str() << ")");
#if EXTRA_DEBUG
m.dump_info();
#endif
ssgStateSelector *state = new ssgStateSelector(2);
ssgSimpleState *textured = new ssgSimpleState();
ssgSimpleState *nontextured = new ssgSimpleState();
// Set up the textured state
textured->enable( GL_LIGHTING );
if ( current_options.get_shading() == 1 ) {
textured->setShadeModel( GL_SMOOTH );
} else {
textured->setShadeModel( GL_FLAT );
}
textured->enable ( GL_CULL_FACE ) ;
textured->enable( GL_TEXTURE_2D );
textured->disable( GL_BLEND );
textured->disable( GL_ALPHA_TEST );
textured->setTexture( (char *)tex_file.c_str() );
textured->enable( GL_COLOR_MATERIAL );
textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
textured->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
// Set up the coloured state
nontextured->enable( GL_LIGHTING );
if ( current_options.get_shading() == 1 ) {
nontextured->setShadeModel( GL_SMOOTH );
} else {
nontextured->setShadeModel( GL_FLAT );
}
nontextured->enable ( GL_CULL_FACE ) ;
nontextured->disable( GL_TEXTURE_2D );
nontextured->disable( GL_BLEND );
nontextured->disable( GL_ALPHA_TEST );
nontextured->disable( GL_COLOR_MATERIAL );
GLfloat *ambient, *diffuse, *specular, *emission;
ambient = m.get_ambient();
diffuse = m.get_diffuse();
specular = m.get_specular();
emission = m.get_emission();
/* cout << "ambient = " << ambient[0] << "," << ambient[1]
<< "," << ambient[2] << endl; */
nontextured->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
nontextured->setMaterial ( GL_DIFFUSE,
diffuse[0], diffuse[1],
diffuse[2], diffuse[3] ) ;
nontextured->setMaterial ( GL_SPECULAR,
specular[0], specular[1],
specular[2], specular[3] ) ;
nontextured->setMaterial ( GL_EMISSION,
emission[0], emission[1],
emission[2], emission[3] ) ;
state->setStep( 0, textured ); // textured
state->setStep( 1, nontextured ); // untextured
// Choose the appropriate starting state.
if ( current_options.get_textures() ) {
state->selectStep(0);
} else {
state->selectStep(1);
}
m_slot.set_state( state );
material_mgr.material_map[material_name] = m_slot;
}
}
materials_loaded = true;
return 1;
}
// Load a library of material properties
bool
fgMATERIAL_MGR::add_item ( const string &path )
{
string material_name = path;
int pos = path.rfind( "/" );
material_name = material_name.substr( pos + 1 );
FGMaterial m( material_name );
FGMaterialSlot m_slot;
m_slot.set_m( m );
// build the ssgSimpleState
FGPath tex_file( path );
FG_LOG( FG_TERRAIN, FG_INFO, " Loading material "
<< material_name << " (" << tex_file.c_str() << ")");
#if EXTRA_DEBUG
m.dump_info();
#endif
ssgStateSelector *state = new ssgStateSelector(2);
ssgSimpleState *textured = new ssgSimpleState();
ssgSimpleState *nontextured = new ssgSimpleState();
// Set up the textured state
textured->enable( GL_LIGHTING );
if ( current_options.get_shading() == 1 ) {
textured->setShadeModel( GL_SMOOTH );
} else {
textured->setShadeModel( GL_FLAT );
}
textured->enable ( GL_CULL_FACE ) ;
textured->enable( GL_TEXTURE_2D );
textured->disable( GL_BLEND );
textured->disable( GL_ALPHA_TEST );
textured->setTexture( (char *)tex_file.c_str() );
textured->enable( GL_COLOR_MATERIAL );
textured->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
textured->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
textured->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
// Set up the coloured state
nontextured->enable( GL_LIGHTING );
if ( current_options.get_shading() == 1 ) {
nontextured->setShadeModel( GL_SMOOTH );
} else {
nontextured->setShadeModel( GL_FLAT );
}
nontextured->enable ( GL_CULL_FACE ) ;
nontextured->disable( GL_TEXTURE_2D );
nontextured->disable( GL_BLEND );
nontextured->disable( GL_ALPHA_TEST );
nontextured->disable( GL_COLOR_MATERIAL );
GLfloat *ambient, *diffuse, *specular, *emission;
ambient = m.get_ambient();
diffuse = m.get_diffuse();
specular = m.get_specular();
emission = m.get_emission();
/* cout << "ambient = " << ambient[0] << "," << ambient[1]
<< "," << ambient[2] << endl; */
nontextured->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
nontextured->setMaterial ( GL_DIFFUSE,
diffuse[0], diffuse[1],
diffuse[2], diffuse[3] ) ;
nontextured->setMaterial ( GL_SPECULAR,
specular[0], specular[1],
specular[2], specular[3] ) ;
nontextured->setMaterial ( GL_EMISSION,
emission[0], emission[1],
emission[2], emission[3] ) ;
state->setStep( 0, textured ); // textured
state->setStep( 1, nontextured ); // untextured
// Choose the appropriate starting state.
if ( current_options.get_textures() ) {
state->selectStep(0);
} else {
state->selectStep(1);
}
m_slot.set_state( state );
material_mgr.material_map[material_name] = m_slot;
return 1;
}
// Initialize the transient list of fragments for each material property
void
fgMATERIAL_MGR::init_transient_material_lists( void )
{
iterator last = end();
for ( iterator it = begin(); it != last; ++it ) {
(*it).second.init_sort_list();
}
}
bool
fgMATERIAL_MGR::find( const string& material, FGMaterialSlot*& mtl_ptr )
{
iterator it = material_map.find( material );
if ( it != end() ) {
mtl_ptr = &((*it).second);
return true;
}
return false;
}
// Destructor
fgMATERIAL_MGR::~fgMATERIAL_MGR ( void ) {
}
// Set the step for all of the state selectors in the material slots
void
fgMATERIAL_MGR::set_step ( int step )
{
// container::iterator it = begin();
for (container::iterator it = begin(); it != end(); it++) {
const string &key = it->first;
FG_LOG( FG_GENERAL, FG_INFO,
"Updating material " << key << " to step " << step );
FGMaterialSlot &slot = it->second;
slot.get_state()->selectStep(step);
}
}
#if 0
void
fgMATERIAL_MGR::render_fragments()
{
current_view.set_tris_rendered( 0 );
iterator last = end();
for ( iterator current = begin(); current != last; ++current ) {
(*current).second.render_fragments();
}
}
#endif

View file

@ -1,181 +0,0 @@
// materialmgr.hxx -- class to handle material properties
//
// Written by Curtis Olson, started May 1998.
//
// Copyright (C) 1998 Curtis L. Olson - curt@me.umn.edu
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
// published by the Free Software Foundation; either version 2 of the
// License, or (at your option) any later version.
//
// This program is distributed in the hope that it will be useful, but
// WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
// General Public License for more details.
//
// You should have received a copy of the GNU General Public License
// along with this program; if not, write to the Free Software
// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
//
// $Id$
#ifndef _MATERIALMGR_HXX
#define _MATERIALMGR_HXX
#ifndef __cplusplus
# error This library requires C++
#endif
#ifdef HAVE_CONFIG_H
# include <config.h>
#endif
#ifdef HAVE_WINDOWS_H
# include <windows.h>
#endif
#include <simgear/compiler.h>
#include <GL/glut.h>
#include <simgear/xgl/xgl.h>
#include STL_STRING // Standard C++ string library
#include <map> // STL associative "array"
#include <vector> // STL "array"
#include <plib/ssg.h> // plib include
#include "material.hxx"
#include "fragment.hxx"
FG_USING_STD(string);
FG_USING_STD(map);
FG_USING_STD(vector);
FG_USING_STD(less);
// forward decl.
class fgFRAGMENT;
// convenience types
typedef vector < fgFRAGMENT * > frag_list_type;
typedef frag_list_type::iterator frag_list_iterator;
typedef frag_list_type::const_iterator frag_list_const_iterator;
// #define FG_MAX_MATERIAL_FRAGS 800
// MSVC++ 6.0 kuldge - Need forward declaration of friends.
// class FGMaterialSlot;
// istream& operator >> ( istream& in, FGMaterialSlot& m );
// Material property class
class FGMaterialSlot {
private:
FGMaterial m;
// 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
ssgStateSelector *state;
bool state_valid;
public:
// Constructor
FGMaterialSlot ( void );
int size() const { return list.size(); }
bool empty() const { return list.size() == 0; }
// Sorting routines
void init_sort_list( void ) {
list.erase( list.begin(), list.end() );
}
bool append_sort_list( fgFRAGMENT *object ) {
list.push_back( object );
return true;
}
// void render_fragments();
// Destructor
~FGMaterialSlot ( void );
// friend istream& operator >> ( istream& in, FGMaterialSlot& m );
inline FGMaterial get_m() const { return m; }
inline void set_m( FGMaterial new_m ) { m = new_m; }
// ssg state
inline ssgStateSelector *get_state() { return state; }
inline void set_state( ssgStateSelector *s ) { state = s; }
inline bool get_state_valid() const { return state_valid; }
inline void set_state_valid( bool flag ) { state_valid = flag; }
};
// Material management class
class fgMATERIAL_MGR {
public:
// associative array of materials
typedef map < string, FGMaterialSlot, less<string> > container;
typedef container::iterator iterator;
typedef container::const_iterator const_iterator;
iterator begin() { return material_map.begin(); }
const_iterator begin() const { return material_map.begin(); }
iterator end() { return material_map.end(); }
const_iterator end() const { return material_map.end(); }
// Constructor
fgMATERIAL_MGR ( void );
// Load a library of material properties
int load_lib ( void );
// Add the named texture with default properties
bool add_item( const string &name );
inline bool loaded() const { return materials_loaded; }
// Initialize the transient list of fragments for each material property
void init_transient_material_lists( void );
bool find( const string& material, FGMaterialSlot*& mtl_ptr );
// void render_fragments();
void set_step (int step);
// Destructor
~fgMATERIAL_MGR ( void );
private:
// Has the material properties lib been loaded
bool materials_loaded;
container material_map;
};
// global material management class
extern fgMATERIAL_MGR material_mgr;
#endif // _MATERIALMGR_HXX

View file

@ -57,7 +57,7 @@
#include <Main/options.hxx>
#include <Scenery/tileentry.hxx>
#include "materialmgr.hxx"
#include "matlib.hxx"
#include "obj.hxx"
FG_USING_STD(string);
@ -73,6 +73,7 @@ static double normals[FG_MAX_NODES][3];
static double tex_coords[FG_MAX_NODES*3][3];
#if 0
// given three points defining a triangle, calculate the normal
static void calc_normal(Point3D p1, Point3D p2,
Point3D p3, sgVec3 normal)
@ -88,6 +89,7 @@ static void calc_normal(Point3D p1, Point3D p2,
// fgPrintf( FG_TERRAIN, FG_DEBUG, " Normal = %.2f %.2f %.2f\n",
// normal[0], normal[1], normal[2]);
}
#endif
#define FG_TEX_CONSTANT 69.0
@ -130,31 +132,32 @@ static Point3D local_calc_tex_coords(const Point3D& node, const Point3D& ref) {
// Generate a generic ocean tile on the fly
ssgBranch *fgGenTile( const string& path, FGTileEntry *t) {
fgFRAGMENT fragment;
fragment.init();
fragment.tile_ptr = t;
FGNewMat *newmat;
ssgSimpleState *state = NULL;
ssgBranch *tile = new ssgBranch () ;
tile -> setName ( (char *)path.c_str() ) ;
double tex_width = 1000.0;
// double tex_height;
// find Ocean material in the properties list
if ( ! material_mgr.find( "Ocean", fragment.material_ptr )) {
newmat = material_lib.find( "Ocean" );
if ( newmat != NULL ) {
// set the texture width and height values for this
// material
tex_width = newmat->get_xsize();
// tex_height = newmat->get_ysize();
// set ssgState
state = newmat->get_state();
} else {
FG_LOG( FG_TERRAIN, FG_ALERT,
"Ack! unknown usemtl name = " << "Ocean"
<< " in " << path );
}
// set the texture width and height values for this
// material
FGMaterial m = fragment.material_ptr->get_m();
double tex_width = m.get_xsize();
// double tex_height = m.get_ysize();
// set ssgState
state = fragment.material_ptr->get_state();
// Calculate center point
FGBucket b = t->tile_bucket;
double clon = b.get_center_lon();
@ -164,7 +167,6 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) {
Point3D center = fgGeodToCart(Point3D(clon*DEG_TO_RAD,clat*DEG_TO_RAD,0.0));
t->center = center;
fragment.center = center;
// cout << "center = " << center << endl;;
// Caculate corner vertices
@ -194,7 +196,6 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) {
// Calculate bounding radius
t->bounding_radius = center.distance3D( cart[0] );
fragment.bounding_radius = t->bounding_radius;
// cout << "bounding radius = " << t->bounding_radius << endl;
// Calculate normals
@ -220,11 +221,6 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) {
point_list texs = calc_tex_coords( b, geod_nodes, rectangle,
1000.0 / tex_width );
// Build flight gear structure
fragment.add_face(0, 1, 2);
fragment.add_face(0, 2, 3);
t->fragment_list.push_back(fragment);
// Allocate ssg structure
ssgVertexArray *vl = new ssgVertexArray( 4 );
ssgNormalArray *nl = new ssgNormalArray( 4 );
@ -271,21 +267,21 @@ ssgBranch *fgGenTile( const string& path, FGTileEntry *t) {
}
// Load a .obj file and build the fragment list
// Load a .obj file
ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
fgFRAGMENT fragment;
FGNewMat *newmat;
Point3D pp;
sgVec3 approx_normal;
// sgVec3 approx_normal;
// double normal[3], scale = 0.0;
// double x, y, z, xmax, xmin, ymax, ymin, zmax, zmin;
// GLfloat sgenparams[] = { 1.0, 0.0, 0.0, 0.0 };
// GLint display_list = 0;
int shading;
bool in_fragment = false, in_faces = false;
bool in_faces = false;
int vncount, vtcount;
int n1 = 0, n2 = 0, n3 = 0, n4 = 0;
int n1 = 0, n2 = 0, n3 = 0;
int tex;
int last1 = 0, last2 = 0;
// int last1 = 0, last2 = 0;
bool odd = false;
point_list nodes;
Point3D node;
@ -315,7 +311,6 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
shading = current_options.get_shading();
in_fragment = false;
if ( is_base ) {
t->ncount = 0;
}
@ -375,11 +370,10 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
// << " radius = " << t->bounding_radius << endl;
} else if ( token == "bs" ) {
// reference point (center offset)
in >> fragment.center;
in >> fragment.bounding_radius;
// cout << "center = " << fragment.center
// << " radius = " << fragment.bounding_radius << endl;
// (skip past this)
Point3D junk1;
double junk2;
in >> junk1 >> junk2;
} else if ( token == "usemtl" ) {
// material property specification
@ -419,45 +413,19 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
}
}
// series of individual triangles
// if ( in_faces ) {
// xglEnd();
// }
// this also signals the start of a new fragment
if ( in_fragment ) {
// close out the previous structure and start the next
// xglEndList();
// printf("xglEnd(); xglEndList();\n");
// update fragment
// fragment.display_list = display_list;
// push this fragment onto the tile's object list
t->fragment_list.push_back(fragment);
} else {
in_fragment = true;
}
// printf("start of fragment (usemtl)\n");
// display_list = xglGenLists(1);
// xglNewList(display_list, GL_COMPILE);
// printf("xglGenLists(); xglNewList();\n");
in_faces = false;
// reset the existing face list
// printf("cleaning a fragment with %d faces\n",
// fragment.faces.size());
fragment.init();
// scan the material line
string material;
in >> material;
fragment.tile_ptr = t;
// find this material in the properties list
if ( ! material_mgr.find( material, fragment.material_ptr )) {
newmat = material_lib.find( material );
if ( newmat == NULL ) {
// see if this is an on the fly texture
string file = path;
int pos = file.rfind( "/" );
@ -466,38 +434,30 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
file += "/";
file += material;
cout << "current file = " << file << endl;
if ( ! material_mgr.add_item( file ) ) {
if ( ! material_lib.add_item( file ) ) {
FG_LOG( FG_TERRAIN, FG_ALERT,
"Ack! unknown usemtl name = " << material
<< " in " << path );
} else {
// locate our newly created material
if ( !material_mgr.find( material, fragment.material_ptr ) ) {
newmat = material_lib.find( material );
if ( newmat == NULL ) {
FG_LOG( FG_TERRAIN, FG_ALERT,
"Ack! bad on the fly materia create = "
<< material << " in " << path );
}
}
}
// set the texture width and height values for this
// material
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;
// initialize the fragment transformation matrix
/*
for ( i = 0; i < 16; i++ ) {
fragment.matrix[i] = 0.0;
}
fragment.matrix[0] = fragment.matrix[5] =
fragment.matrix[10] = fragment.matrix[15] = 1.0;
*/
if ( newmat != NULL ) {
// set the texture width and height values for this
// material
tex_width = newmat->get_xsize();
tex_height = newmat->get_ysize();
state = newmat->get_state();
// cout << "(w) = " << tex_width << " (h) = "
// << tex_width << endl;
}
} else {
// unknown comment, just gobble the input untill the
// end of line
@ -653,15 +613,9 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
if ( (token == "tf") || (token == "f") ) {
// triangle fan
fragment.add_face(n1, n2, n3);
n2 = n3;
} else {
// triangle strip
if ( odd ) {
fragment.add_face(n1, n2, n3);
} else {
fragment.add_face(n2, n1, n3);
}
odd = !odd;
n1 = n2;
n2 = n3;
@ -727,34 +681,6 @@ ssgBranch *fgObjLoad( const string& path, FGTileEntry *t, const bool is_base) {
}
}
if ( in_fragment ) {
// close out the previous structure and start the next
// xglEnd();
// xglEndList();
// printf("xglEnd(); xglEndList();\n");
// update fragment
// fragment.display_list = display_list;
// push this fragment onto the tile's object list
t->fragment_list.push_back(fragment);
}
#if 0
// Draw normal vectors (for visually verifying normals)
xglBegin(GL_LINES);
xglColor3f(0.0, 0.0, 0.0);
for ( i = 0; i < t->ncount; i++ ) {
xglVertex3d(nodes[i][0],
nodes[i][1] ,
nodes[i][2]);
xglVertex3d(nodes[i][0] + 500*normals[i][0],
nodes[i][1] + 500*normals[i][1],
nodes[i][2] + 500*normals[i][2]);
}
xglEnd();
#endif
if ( is_base ) {
t->nodes = nodes;
}

View file

@ -55,7 +55,7 @@ FG_USING_STD(string);
#define FG_MAX_NODES 2000
// Load a .obj file and build the fragment list
// Load a .obj file
ssgBranch *fgObjLoad(const string& path, FGTileEntry *tile, const bool is_base);

View file

@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started January 1998.
//
// Copyright (C) 1998, 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as
@ -39,8 +39,6 @@
#include <simgear/misc/fgstream.hxx>
#include <simgear/misc/fgpath.hxx>
#include <Airports/genapt.hxx>
#include <Clouds/cloudobj.hxx>
#include <Main/options.hxx>
#include <Main/views.hxx>
#include <Objects/obj.hxx>
@ -175,7 +173,7 @@ FGTileCache::fill_in( int index, const FGBucket& p )
tile_path.append( "Scenery" );
tile_path.append( p.gen_base_path() );
// Load the appropriate data file and build tile fragment list
// Load the appropriate data file
FGPath tile_base = tile_path;
tile_base.append( p.gen_index_str() );
ssgBranch *new_tile = fgObjLoad( tile_base.str(), &tile_cache[index],
@ -219,14 +217,6 @@ FGTileCache::fill_in( int index, const FGBucket& p )
}
}
// generate cloud layer
if ( current_options.get_clouds() ) {
ssgLeaf *cloud_layer = fgGenCloudLayer( &tile_cache[index],
current_options.get_clouds_asl() );
cloud_layer->clrTraversalMaskBits( SSGTRAV_HOT );
new_tile -> addKid( cloud_layer );
}
tile_cache[index].transform_ptr->addKid( tile_cache[index].range_ptr );
// calculate initial tile offset

View file

@ -2,7 +2,7 @@
//
// Written by Curtis Olson, started January 1998.
//
// Copyright (C) 1998, 1999 Curtis L. Olson - curt@flightgear.org
// Copyright (C) 1998 - 2000 Curtis L. Olson - curt@flightgear.org
//
// This program is free software; you can redistribute it and/or
// modify it under the terms of the GNU General Public License as

View file

@ -74,8 +74,7 @@ static void my_remove_branch( ssgBranch * branch ) {
}
// Step through the fragment list, deleting the display list, then the
// fragment, until the list is empty. Also delete the arrays used by
// Clean up the memory used by this tile and delete the arrays used by
// ssg as well as the whole ssg branch
void FGTileEntry::free_tile() {
int i;
@ -85,10 +84,6 @@ void FGTileEntry::free_tile() {
// mark tile unused
mark_unused();
// delete fragment list and node list
FG_LOG( FG_TERRAIN, FG_DEBUG,
" deleting " << fragment_list.size() << " fragments" );
fragment_list.clear();
FG_LOG( FG_TERRAIN, FG_DEBUG,
" deleting " << nodes.size() << " nodes" );
nodes.clear();

View file

@ -50,8 +50,6 @@
#include <simgear/bucket/newbucket.hxx>
#include <simgear/math/point3d.hxx>
#include <Objects/fragment.hxx>
#if defined( sgi )
#include <strings.h>
#endif
@ -81,16 +79,13 @@ private:
public:
typedef vector < fgFRAGMENT > container;
typedef container::iterator FragmentIterator;
typedef container::const_iterator FragmentConstIterator;
typedef vector < sgVec3 * > free_vec3_list;
typedef vector < sgVec2 * > free_vec2_list;
typedef vector < unsigned short * > free_index_list;
public:
// node list (the per fragment face lists reference this node list)
// node list
point_list nodes;
int ncount;
@ -105,13 +100,6 @@ public:
// 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;
// list of pointers to memory chunks that need to be freed when
// tile entry goes away
free_vec3_list vec3_ptrs;
@ -147,23 +135,7 @@ public:
// Destructor
~FGTileEntry ( void );
FragmentIterator begin() { return fragment_list.begin(); }
FragmentConstIterator begin() const { return fragment_list.begin(); }
FragmentIterator end() { return fragment_list.end(); }
FragmentConstIterator end() const { return fragment_list.end(); }
void add_fragment( fgFRAGMENT& frag ) {
frag.tile_ptr = this;
fragment_list.push_back( frag );
}
size_t num_fragments() const {
return fragment_list.size();
}
// Step through the fragment list, deleting the display list, then
// the fragment, until the list is empty. Also delete the arrays
// Clean up the memory used by this tile and delete the arrays
// used by ssg as well as the whole ssg branch
void free_tile();

View file

@ -42,7 +42,6 @@
#include <Aircraft/aircraft.hxx>
#include <Main/options.hxx>
#include <Main/views.hxx>
#include <Objects/materialmgr.hxx>
#include <Objects/obj.hxx>
#ifndef FG_OLD_WEATHER
@ -87,11 +86,6 @@ FGTileMgr::~FGTileMgr ( void ) {
int FGTileMgr::init( void ) {
FG_LOG( FG_TERRAIN, FG_INFO, "Initializing Tile Manager subsystem." );
// load default material library
if ( ! material_mgr.loaded() ) {
material_mgr.load_lib();
}
global_tile_cache.init();
hit_list.clear();