// draw the lights
glFogf (GL_FOG_DENSITY, fog_exp2_punch_through);
ssgSetNearFar( scene_nearplane, scene_farplane );
- ssgCullAndDraw( globals->get_scenery()->get_lighting() );
+ ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
+ ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
if (fgGetBool("/environment/clouds/status"))
thesky->postDraw( cur_fdm_state->get_Altitude() * SG_FEET_TO_METER );
#endif
ssgSetNearFar( scene_nearplane, scene_farplane );
- ssgCullAndDraw( globals->get_scenery()->get_lighting() );
+ ssgCullAndDraw( globals->get_scenery()->get_gnd_lights_root() );
+
+ glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_SPHERE_MAP);
+ glEnable(GL_TEXTURE_GEN_S);
+ glEnable(GL_TEXTURE_GEN_T);
+ glPolygonMode(GL_FRONT, GL_POINT);
+ ssgCullAndDraw( globals->get_scenery()->get_rwy_lights_root() );
+ glPolygonMode(GL_FRONT, GL_FILL);
+ glDisable(GL_TEXTURE_GEN_S);
+ glDisable(GL_TEXTURE_GEN_T);
//static int _frame_count = 0;
//if (_frame_count % 30 == 0) {
//SG_LOG(SG_FLIGHT,SG_INFO, "Updating time dep calcs()");
fgLIGHT *l = &cur_light_params;
- int i;
-
- long multi_loop = 1;
// Initialize the FDM here if it hasn't been and if we have a
// scenery elevation hit.
//dummy_tile->lightmaps_sequence->setTraversalMaskBits( SSGTRAV_HOT );
lightpoints_transform->addKid( dummy_tile->lightmaps_sequence );
lightpoints_transform->ref();
- globals->get_scenery()->get_gnd_lights_branch()->addKid( lightpoints_transform );
+ globals->get_scenery()->get_gnd_lights_root()->addKid( lightpoints_transform );
}
} //if in1
} //if objc
libObjects_a_SOURCES = \
apt_signs.cxx apt_signs.hxx \
- dir_lights.cxx dir_lights.hxx \
newmat.cxx newmat.hxx \
matlib.cxx matlib.hxx \
obj.cxx obj.hxx \
+ pt_lights.cxx pt_lights.hxx \
texload.c texload.h colours.h
INCLUDES = -I$(top_srcdir) -I$(top_srcdir)/src
+++ /dev/null
-// dir_lights.cxx -- build a 'directional' light on the fly
-//
-// Written by Curtis Olson, started March 2002.
-//
-// Copyright (C) 2002 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
-// 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 "dir_lights.hxx"
-
-
-// Generate a directional light
-ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir ) {
-return NULL;
-}
+++ /dev/null
-// dir_lights.hxx -- build a 'directional' light on the fly
-//
-// Written by Curtis Olson, started March 2002.
-//
-// Copyright (C) 2002 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
-// 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 _DIR_LIGHTS_HXX
-#define _DIR_LIGHTS_HXX
-
-
-#ifndef __cplusplus
-# error This library requires C++
-#endif
-
-
-#ifdef HAVE_CONFIG_H
-# include <config.h>
-#endif
-
-#include <simgear/compiler.h>
-
-#include <vector> // STL
-#include STL_STRING
-
-#include <plib/ssg.h> // plib include
-
-SG_USING_STD(string);
-SG_USING_STD(vector);
-
-
-typedef vector < int > int_list;
-typedef int_list::iterator int_list_iterator;
-typedef int_list::const_iterator int_point_list_iterator;
-
-
-// Define the various supported light types
-enum {
- FG_RWYLIGHT_TAXI = 0,
- FG_RWYLIGHT_VASI,
- FG_RWYLIGHT_EDGE,
- FG_RWYLIGHT_TOUCHDOWN,
- FG_RWYLIGHT_THRESHOLD,
- FG_RWYLIGHT_WHITE,
- FG_RWYLIGHT_RED,
- FG_RWYLIGHT_GREEN,
- FG_RWYLIGHT_YELLOW
-} fgRunwayLightType;
-
-
-// Generate a directional light. This routines creates a
-// 'directional' light that can only be viewed from within 90 degrees
-// of the specified dir vector.
-
-// To accomplish this, he routine creates a triangle with the 1st
-// point coincident with the specified pt and the 2nd and 3rd points
-// extending upward. The 1st point is created with an 'alpha' value
-// of 1 while the 2nd and 3rd points are created with an 'alpha' of
-// 0.0.
-
-// If the triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT) mode,
-// then two important things happen:
-
-// 1) Only the 3 vertex points are drawn, the 2nd two with an alpha of
-// 0 so actually only the desired point is rendered.
-
-// 2) since we are drawing a triangle, back face culling takes care of
-// eliminating this poing when the view angle relative to dir is
-// greater than 90 degrees.
-
-// The final piece of this puzzle is that if we now use environment
-// mapping on this point, via an appropriate texture we can then
-// control the intensity and color of the point based on the view
-// angle relative to 'dir' the optimal view direction of the light
-// (i.e. the direction the light is pointing.)
-
-// Yes this get's to be long and convoluted. If you can suggest a
-// simpler way, please do! :-)
-
-ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir );
-
-
-/* ssgLeaf *gen_directional_lights( const point_list &nodes,
- const point_list &normals,
- const int_list &pnt_i,
- const int_list &nml_i );
-*/
-
-#endif // _DIR_LIGHTS_HXX
#include <GL/gl.h>
#include <simgear/compiler.h>
+#include <simgear/constants.h>
#include <simgear/misc/exception.hxx>
#include <string.h>
}
+static int gen_test_light_map() {
+ static const int env_tex_res = 32;
+ int half_res = env_tex_res / 2;
+ unsigned char env_map[env_tex_res][env_tex_res][4];
+ GLuint tex_name;
+
+ for ( int i = 0; i < env_tex_res; ++i ) {
+ for ( int j = 0; j < env_tex_res; ++j ) {
+ double x = (i - half_res) / (double)half_res;
+ double y = (j - half_res) / (double)half_res;
+ double dist = sqrt(x*x + y*y);
+ if ( dist > 1.0 ) { dist = 1.0; }
+
+ // cout << x << "," << y << " " << (int)(dist * 255) << ","
+ // << (int)((1.0 - dist) * 255) << endl;
+ env_map[i][j][0] = (int)(dist * 255);
+ env_map[i][j][1] = (int)((1.0 - dist) * 255);
+ env_map[i][j][2] = 0;
+ env_map[i][j][3] = 255;
+ }
+ }
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glGenTextures( 1, &tex_name );
+ glBindTexture( GL_TEXTURE_2D, tex_name );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, env_map);
+
+ return tex_name;
+}
+
+
+static int gen_light_map() {
+ static const int env_tex_res = 32;
+ int half_res = env_tex_res / 2;
+ unsigned char env_map[env_tex_res][env_tex_res][4];
+ GLuint tex_name;
+
+ for ( int i = 0; i < env_tex_res; ++i ) {
+ for ( int j = 0; j < env_tex_res; ++j ) {
+ double x = (i - half_res) / (double)half_res;
+ double y = (j - half_res) / (double)half_res;
+ double dist = sqrt(x*x + y*y);
+ if ( dist > 1.0 ) { dist = 1.0; }
+ double bright = cos( dist * SGD_PI_2 );
+ if ( bright < 0.3 ) { bright = 0.3; }
+ env_map[i][j][0] = 255;
+ env_map[i][j][1] = 255;
+ env_map[i][j][2] = 255;
+ env_map[i][j][3] = (int)(bright * 255);
+ }
+ }
+
+ glPixelStorei( GL_UNPACK_ALIGNMENT, 1 );
+ glGenTextures( 1, &tex_name );
+ glBindTexture( GL_TEXTURE_2D, tex_name );
+
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
+ glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
+ glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, env_tex_res, env_tex_res, 0,
+ GL_RGBA, GL_UNSIGNED_BYTE, env_map);
+
+ return tex_name;
+}
+
+
// Load a library of material properties
bool FGMaterialLib::load( const string& mpath ) {
- SGPropertyNode materials;
-
- SG_LOG(SG_INPUT, SG_INFO, "Reading materials from " << mpath);
- try {
- readProperties(mpath, &materials);
- } catch (const sg_exception &ex) {
- SG_LOG(SG_INPUT, SG_ALERT, "Error reading materials: " << ex.getMessage());
- throw ex;
- }
-
- int nMaterials = materials.nChildren();
- for (int i = 0; i < nMaterials; i++) {
- const SGPropertyNode * node = materials.getChild(i);
- if (!strcmp(node->getName(), "material")) {
- FGNewMat * m = new FGNewMat(node);
-
- vector<SGPropertyNode_ptr>names = node->getChildren("name");
- for (unsigned int j = 0; j < names.size(); j++) {
- string name = names[j]->getStringValue();
- m->ref();
- // cerr << "Material " << name << endl;
- matlib[name] = m;
- SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
- << names[j]->getStringValue());
- }
- } else {
- SG_LOG(SG_INPUT, SG_ALERT,
- "Skipping bad material entry " << node->getName());
+ SGPropertyNode materials;
+
+ SG_LOG( SG_INPUT, SG_INFO, "Reading materials from " << mpath );
+ try {
+ readProperties( mpath, &materials );
+ } catch (const sg_exception &ex) {
+ SG_LOG( SG_INPUT, SG_ALERT, "Error reading materials: "
+ << ex.getMessage() );
+ throw ex;
}
- }
-
- // hard coded light state
- ssgSimpleState *lights = new ssgSimpleState;
- lights->ref();
- lights->disable( GL_TEXTURE_2D );
- lights->enable( GL_CULL_FACE );
- lights->enable( GL_COLOR_MATERIAL );
- lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
- lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
- lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
- lights->enable( GL_BLEND );
- lights->disable( GL_ALPHA_TEST );
- lights->disable( GL_LIGHTING );
-
- matlib["LIGHTS"] = new FGNewMat(lights);
+
+ int nMaterials = materials.nChildren();
+ for (int i = 0; i < nMaterials; i++) {
+ const SGPropertyNode * node = materials.getChild(i);
+ if (!strcmp(node->getName(), "material")) {
+ FGNewMat * m = new FGNewMat(node);
+
+ vector<SGPropertyNode_ptr>names = node->getChildren("name");
+ for ( unsigned int j = 0; j < names.size(); j++ ) {
+ string name = names[j]->getStringValue();
+ m->ref();
+ // cerr << "Material " << name << endl;
+ matlib[name] = m;
+ SG_LOG( SG_TERRAIN, SG_INFO, " Loading material "
+ << names[j]->getStringValue() );
+ }
+ } else {
+ SG_LOG(SG_INPUT, SG_ALERT,
+ "Skipping bad material entry " << node->getName());
+ }
+ }
+
+ // hard coded ground light state
+ ssgSimpleState *gnd_lights = new ssgSimpleState;
+ gnd_lights->ref();
+ gnd_lights->disable( GL_TEXTURE_2D );
+ gnd_lights->enable( GL_CULL_FACE );
+ gnd_lights->enable( GL_COLOR_MATERIAL );
+ gnd_lights->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
+ gnd_lights->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
+ gnd_lights->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
+ gnd_lights->enable( GL_BLEND );
+ gnd_lights->disable( GL_ALPHA_TEST );
+ gnd_lights->disable( GL_LIGHTING );
+ matlib["GROUND_LIGHTS"] = new FGNewMat(gnd_lights);
+
+ // hard coded runway light state
+ ssgSimpleState *rwy_lights = new ssgSimpleState();
+ rwy_lights->ref();
+
+ rwy_lights->disable( GL_LIGHTING );
+ rwy_lights->enable ( GL_CULL_FACE ) ;
+ rwy_lights->enable( GL_TEXTURE_2D );
+ rwy_lights->enable( GL_BLEND );
+ rwy_lights->enable( GL_ALPHA_TEST );
+ rwy_lights->enable( GL_COLOR_MATERIAL );
+ rwy_lights->setMaterial ( GL_AMBIENT, 1.0, 1.0, 1.0, 1.0 );
+ rwy_lights->setMaterial ( GL_DIFFUSE, 1.0, 1.0, 1.0, 1.0 );
+ rwy_lights->setMaterial ( GL_SPECULAR, 0.0, 0.0, 0.0, 0.0 );
+ rwy_lights->setMaterial ( GL_EMISSION, 0.0, 0.0, 0.0, 0.0 );
+
+ rwy_lights->setTexture( gen_light_map() );
+ matlib["RUNWAY_LIGHTS"] = new FGNewMat(rwy_lights);
return true;
}
{
// Load model only on demand
if (!_models_loaded) {
- for (int i = 0; i < _paths.size(); i++) {
+ for (unsigned int i = 0; i < _paths.size(); i++) {
ssgEntity * entity = globals->get_model_loader()->load_model(_paths[i]);
if (entity != 0) {
// FIXME: this stuff can be handled
build_ssg_state(true);
}
-FGNewMat::FGNewMat (ssgSimpleState * s)
+FGNewMat::FGNewMat (ssgSimpleState *s)
{
init();
set_ssg_state(s);
FGNewMat::build_ssg_state (bool defer_tex_load)
{
GLenum shade_model =
- (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
+ (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
bool texture_default = fgGetBool("/sim/rendering/textures");
-
+
state = new ssgStateSelector(2);
state->ref();
textured->enable( GL_TEXTURE_2D );
textured->disable( GL_BLEND );
textured->disable( GL_ALPHA_TEST );
-#if 0
-# ifdef GL_EXT_texture_filter_anisotropic
- float max_anisotropy;
- glGetFloatv( GL_MAX_TEXTURE_MAX_ANISOTROPY_EXT, &max_anisotropy );
- glTexParameterf( GL_TEXTURE_2D, GL_TEXTURE_MAX_ANISOTROPY_EXT,
- max_anisotropy );
- cout << "Max anisotropy = " << max_anisotropy << endl;
-# endif
-#endif
if ( !defer_tex_load ) {
textured->setTexture( (char *)texture_path.c_str(), wrapu, wrapv );
texture_loaded = true;
void FGNewMat::set_ssg_state( ssgSimpleState *s )
{
+ GLenum shade_model =
+ (fgGetBool("/sim/rendering/shading") ? GL_SMOOTH : GL_FLAT);
+ bool texture_default = fgGetBool("/sim/rendering/textures");
+
state = new ssgStateSelector(2);
state->ref();
textured = s;
+ texture_loaded = true;
nontextured = new ssgSimpleState();
nontextured->ref();
+ // Set up the textured state
+ textured->setShadeModel( shade_model );
+
// Set up the coloured state
nontextured->enable( GL_LIGHTING );
- nontextured->setShadeModel( GL_FLAT );
+ nontextured->setShadeModel( shade_model );
nontextured->enable ( GL_CULL_FACE ) ;
nontextured->disable( GL_TEXTURE_2D );
nontextured->disable( GL_BLEND );
nontextured->disable( GL_ALPHA_TEST );
nontextured->disable( GL_COLOR_MATERIAL );
- /* cout << "ambient = " << ambient[0] << "," << ambient[1]
- << "," << ambient[2] << endl; */
nontextured->setMaterial ( GL_AMBIENT,
ambient[0], ambient[1],
ambient[2], ambient[3] ) ;
state->setStep( 1, nontextured ); // untextured
// Choose the appropriate starting state.
- state->selectStep(0);
+ if ( texture_default ) {
+ state->selectStep(0);
+ } else {
+ state->selectStep(1);
+ }
}
// end of newmat.cxx
#include "newmat.hxx"
#include "matlib.hxx"
+#include "pt_lights.hxx"
#include "obj.hxx"
SG_USING_STD(string);
geometry->setName( (char *)path.c_str() );
- if ( is_base ) {
- // reference point (center offset/bounding sphere)
- *center = obj.get_gbs_center();
- *bounding_radius = obj.get_gbs_radius();
-
- }
+ // reference point (center offset/bounding sphere)
+ *center = obj.get_gbs_center();
+ *bounding_radius = obj.get_gbs_radius();
point_list const& nodes = obj.get_wgs84_nodes();
point_list const& colors = obj.get_colors();
for ( i = 0; i < pts_v.size(); ++i ) {
// cout << "pts_v.size() = " << pts_v.size() << endl;
if ( pt_materials[i].substr(0, 3) == "RWY" ) {
- material = "LIGHTS";
+ material = "GROUND_LIGHTS";
is_lighting = true;
- } else {
+ sgVec3 up;
+ sgSetVec3( up, center->x(), center->y(), center->z() );
+ ssgBranch *branch = gen_directional_lights( nodes, normals,
+ pts_v[i], pts_n[i],
+ up );
+ float ranges[] = { 0, 12000 };
+ // branch->setCallback( SSG_CALLBACK_PREDRAW, runway_lights_predraw );
+ ssgRangeSelector * lod = new ssgRangeSelector;
+ lod->setRanges( ranges, 2 );
+ lod->addKid( branch );
+ rwy_lights->addKid( lod );
+ } else {
material = pt_materials[i];
- }
- tex_index.clear();
- ssgLeaf *leaf = gen_leaf( path, GL_POINTS, material,
- nodes, normals, texcoords,
- pts_v[i], pts_n[i], tex_index,
- false, ground_lights );
+ tex_index.clear();
+ ssgLeaf *leaf = gen_leaf( path, GL_POINTS, material,
+ nodes, normals, texcoords,
+ pts_v[i], pts_n[i], tex_index,
+ false, ground_lights );
+ geometry->addKid( leaf );
+ }
if ( is_lighting ) {
- float ranges[] = {
- 0,
- 12000
- };
- leaf->setCallback(SSG_CALLBACK_PREDRAW, runway_lights_predraw);
- ssgRangeSelector * lod = new ssgRangeSelector;
- lod->setRanges(ranges, 2);
- lod->addKid(leaf);
- rwy_lights->addKid(lod);
- } else {
- geometry->addKid( leaf );
}
}
--- /dev/null
+// pt_lights.cxx -- build a 'directional' light on the fly
+//
+// Written by Curtis Olson, started March 2002.
+//
+// Copyright (C) 2002 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
+// 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 <plib/sg.h>
+
+#include "newmat.hxx"
+#include "matlib.hxx"
+
+#include "pt_lights.hxx"
+
+
+// Generate a directional light
+ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir, sgVec3 up ) {
+
+ // calculate a vector perpendicular to dir and up
+ sgVec3 perp;
+ sgVectorProductVec3( perp, dir, up );
+
+ ssgVertexArray *vl = new ssgVertexArray( 3 );
+ ssgNormalArray *nl = new ssgNormalArray( 1 );
+ ssgColourArray *cl = new ssgColourArray( 1 );
+
+ // front face
+ sgVec3 tmp3;
+ sgCopyVec3( tmp3, pt );
+ vl->add( tmp3 );
+ sgAddVec3( tmp3, up );
+ vl->add( tmp3 );
+ sgSubVec3( tmp3, perp );
+ vl->add( tmp3 );
+
+ nl->add( dir );
+ nl->add( dir );
+ nl->add( dir );
+
+ sgVec4 color;
+ sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
+ cl->add( color );
+ sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
+ cl->add( color );
+ cl->add( color );
+
+ // temporarily do back face
+ sgCopyVec3( tmp3, pt );
+ vl->add( tmp3 );
+ sgAddVec3( tmp3, up );
+ vl->add( tmp3 );
+ sgAddVec3( tmp3, perp );
+ vl->add( tmp3 );
+
+ sgNegateVec3( dir );
+ nl->add( dir );
+ nl->add( dir );
+ nl->add( dir );
+
+ sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
+ cl->add( color );
+ sgSetVec4( color, 1.0, 1.0, 1.0, 0.0 );
+ cl->add( color );
+ cl->add( color );
+
+ /* ssgTexCoordArray *tl = new ssgTexCoordArray( 4 );
+ sgVec2 tmp2;
+ sgSetVec2( tmp2, 0.0, 0.0 );
+ tl->add( tmp2 );
+ sgSetVec2( tmp2, 1.0, 0.0 );
+ tl->add( tmp2 );
+ sgSetVec2( tmp2, 1.0, 1.0 );
+ tl->add( tmp2 );
+ sgSetVec2( tmp2, 0.0, 1.0 );
+ tl->add( tmp2 );
+ */
+
+ ssgLeaf *leaf =
+ new ssgVtxTable ( GL_TRIANGLES, vl, nl, NULL, cl );
+
+ FGNewMat *newmat = material_lib.find( "RUNWAY_LIGHTS" );
+ // FGNewMat *newmat = material_lib.find( "IrrCropPastureCover" );
+ leaf->setState( newmat->get_state() );
+
+ return leaf;
+}
+
+
+// Generate a directional light
+ssgLeaf *gen_normal_line( sgVec3 pt, sgVec3 dir, sgVec3 up ) {
+
+ ssgVertexArray *vl = new ssgVertexArray( 3 );
+ ssgNormalArray *nl = new ssgNormalArray( 1 );
+ ssgColourArray *cl = new ssgColourArray( 1 );
+
+ sgVec3 tmp3;
+ sgCopyVec3( tmp3, pt );
+ vl->add( tmp3 );
+ sgAddVec3( tmp3, dir );
+ vl->add( tmp3 );
+
+ sgVec4 color;
+ sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
+ cl->add( color );
+ cl->add( color );
+
+ ssgLeaf *leaf =
+ new ssgVtxTable ( GL_LINES, vl, NULL, NULL, cl );
+
+ FGNewMat *newmat = material_lib.find( "GROUND_LIGHTS" );
+ // FGNewMat *newmat = material_lib.find( "IrrCropPastureCover" );
+ leaf->setState( newmat->get_state() );
+
+ return leaf;
+}
+
+
+ssgBranch *gen_directional_lights( const point_list &nodes,
+ const point_list &normals,
+ const int_list &pnt_i,
+ const int_list &nml_i,
+ sgVec3 up )
+{
+ ssgBranch *result = new ssgBranch;
+
+ sgVec3 nup;
+ sgNormalizeVec3( nup, up );
+
+ unsigned int i;
+ sgVec3 pt, normal;
+ for ( i = 0; i < pnt_i.size(); ++i ) {
+ sgSetVec3( pt, nodes[pnt_i[i]][0], nodes[pnt_i[i]][1],
+ nodes[pnt_i[i]][2] );
+ sgSetVec3( normal, normals[nml_i[i]][0], normals[nml_i[i]][1],
+ normals[nml_i[i]][2] );
+ ssgLeaf *light = gen_directional_light( pt, normal, nup );
+ result->addKid( light );
+ // light = gen_normal_line( pt, normal, nup );
+ // result->addKid( light );
+ }
+
+ return result;
+}
--- /dev/null
+// pt_lights.hxx -- build a 'directional' light on the fly
+//
+// Written by Curtis Olson, started March 2002.
+//
+// Copyright (C) 2002 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
+// 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 _PT_LIGHTS_HXX
+#define _PT_LIGHTS_HXX
+
+
+#ifndef __cplusplus
+# error This library requires C++
+#endif
+
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <simgear/compiler.h>
+
+#include <vector> // STL
+#include STL_STRING
+
+#include <plib/sg.h>
+#include <plib/ssg.h> // plib include
+
+#include <simgear/math/sg_types.hxx>
+
+SG_USING_STD(string);
+SG_USING_STD(vector);
+
+
+typedef vector < int > int_list;
+typedef int_list::iterator int_list_iterator;
+typedef int_list::const_iterator int_point_list_iterator;
+
+
+// Define the various supported light types
+typedef enum {
+ FG_RWYLIGHT_TAXI = 0,
+ FG_RWYLIGHT_VASI,
+ FG_RWYLIGHT_EDGE,
+ FG_RWYLIGHT_TOUCHDOWN,
+ FG_RWYLIGHT_THRESHOLD,
+ FG_RWYLIGHT_WHITE,
+ FG_RWYLIGHT_RED,
+ FG_RWYLIGHT_GREEN,
+ FG_RWYLIGHT_YELLOW
+} fgRunwayLightType;
+
+
+// Generate a directional light. This routines creates a
+// 'directional' light that can only be viewed from within 90 degrees
+// of the specified dir vector.
+
+// To accomplish this, he routine creates a triangle with the 1st
+// point coincident with the specified pt and the 2nd and 3rd points
+// extending upward. The 1st point is created with an 'alpha' value
+// of 1 while the 2nd and 3rd points are created with an 'alpha' of
+// 0.0.
+
+// If the triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT) mode,
+// then two important things happen:
+
+// 1) Only the 3 vertex points are drawn, the 2nd two with an alpha of
+// 0 so actually only the desired point is rendered.
+
+// 2) since we are drawing a triangle, back face culling takes care of
+// eliminating this poing when the view angle relative to dir is
+// greater than 90 degrees.
+
+// The final piece of this puzzle is that if we now use environment
+// mapping on this point, via an appropriate texture we can then
+// control the intensity and color of the point based on the view
+// angle relative to 'dir' the optimal view direction of the light
+// (i.e. the direction the light is pointing.)
+
+// Yes this get's to be long and convoluted. If you can suggest a
+// simpler way, please do! :-)
+
+ssgLeaf *gen_directional_light( sgVec3 pt, sgVec3 dir, sgVec3 up );
+
+
+ssgBranch *gen_directional_lights( const point_list &nodes,
+ const point_list &normals,
+ const int_list &pnt_i,
+ const int_list &nml_i,
+ sgVec3 up );
+
+
+#endif // _PT_LIGHTS_HXX
scene_graph = new ssgRoot;
scene_graph->setName( "Scene" );
- lighting = new ssgRoot;
- lighting->setName( "Lighting" );
-
// Terrain branch
terrain_branch = new ssgBranch;
terrain_branch->setName( "Terrain" );
scene_graph->addKid( aircraft_branch );
// Lighting
- gnd_lights_branch = new ssgBranch;
- gnd_lights_branch->setName( "Ground Lighting" );
- lighting->addKid( gnd_lights_branch );
+ gnd_lights_root = new ssgRoot;
+ gnd_lights_root->setName( "Ground Lighting Root" );
- rwy_lights_branch = new ssgBranch;
- rwy_lights_branch->setName( "Runway Lighting" );
- lighting->addKid( rwy_lights_branch );
+ rwy_lights_root = new ssgRoot;
+ rwy_lights_root->setName( "Runway Lighting Root" );
}
sgdVec3 cur_normal;
// SSG scene graph
- ssgRoot * scene_graph;
- ssgBranch * terrain_branch;
- ssgBranch * gnd_lights_branch;
- ssgBranch * rwy_lights_branch;
- ssgBranch * models_branch;
- ssgBranch * aircraft_branch;
-
- ssgRoot *lighting;
+ ssgRoot *scene_graph;
+ ssgBranch *terrain_branch;
+ ssgRoot *gnd_lights_root;
+ ssgRoot *rwy_lights_root;
+ ssgBranch *models_branch;
+ ssgBranch *aircraft_branch;
public:
inline void set_cur_radius( double r ) { cur_radius = r; }
inline void set_cur_normal( sgdVec3 n ) { sgdCopyVec3( cur_normal, n ); }
- inline ssgRoot * get_scene_graph () const { return scene_graph; }
+ inline ssgRoot *get_scene_graph () const { return scene_graph; }
inline void set_scene_graph (ssgRoot * s) { scene_graph = s; }
- inline ssgBranch * get_terrain_branch () const { return terrain_branch; }
+ inline ssgBranch *get_terrain_branch () const { return terrain_branch; }
inline void set_terrain_branch (ssgBranch * t) { terrain_branch = t; }
- inline ssgBranch * get_gnd_lights_branch () const {
- return gnd_lights_branch;
+ inline ssgRoot *get_gnd_lights_root () const {
+ return gnd_lights_root;
}
- inline void set_gnd_lights_branch (ssgBranch * t) {
- gnd_lights_branch = t;
+ inline void set_gnd_lights_root (ssgRoot *r) {
+ gnd_lights_root = r;
}
- inline ssgBranch * get_rwy_lights_branch () const {
- return rwy_lights_branch;
+ inline ssgRoot *get_rwy_lights_root () const {
+ return rwy_lights_root;
}
- inline void set_rwy_lights_branch (ssgBranch * t) {
- rwy_lights_branch = t;
+ inline void set_rwy_lights_root (ssgRoot *r) {
+ rwy_lights_root = r;
}
- inline ssgBranch * get_models_branch () const {
- return models_branch;
+ inline ssgBranch *get_models_branch () const {
+ return models_branch;
}
- inline void set_models_branch (ssgBranch * t) {
- models_branch = t;
+ inline void set_models_branch (ssgBranch *t) {
+ models_branch = t;
}
- inline ssgBranch * get_aircraft_branch () const {
- return aircraft_branch;
+ inline ssgBranch *get_aircraft_branch () const {
+ return aircraft_branch;
}
- inline void set_aircraft_branch (ssgBranch * t) {
- aircraft_branch = t;
+ inline void set_aircraft_branch (ssgBranch *t) {
+ aircraft_branch = t;
}
-
- inline ssgRoot * get_lighting () const { return lighting; }
- inline void set_lighting (ssgRoot *l) { lighting = l; }
};
new ssgVtxTable ( GL_POINTS, vl, nl, tl, cl );
// assign state
- FGNewMat *newmat = material_lib.find( "LIGHTS" );
+ FGNewMat *newmat = material_lib.find( "GROUND_LIGHTS" );
leaf->setState( newmat->get_state() );
leaf->setCallback( SSG_CALLBACK_PREDRAW, fgLightsPredraw );
leaf->setCallback( SSG_CALLBACK_POSTDRAW, fgLightsPostdraw );
attach_queue.pop();
#endif
e->add_ssg_nodes( globals->get_scenery()->get_terrain_branch(),
- globals->get_scenery()->get_gnd_lights_branch(),
- globals->get_scenery()->get_rwy_lights_branch() );
+ globals->get_scenery()->get_gnd_lights_root(),
+ globals->get_scenery()->get_rwy_lights_root() );
// cout << "Adding ssg nodes for "
}