1
0
Fork 0

Begin work on rendering runway lights using environment maps. The basics

are now working.  A runway light is defined by a point and a direction.  The
point and direction are combined with the local up vector to create a small
triangle orthogonal to the direction.  The two ficticous corners of the
triangle are given an alpha value of zero, the orignal corner is given an
alpha of one.  The triangle is drawn in glPolygonMode(GL_FRONT, GL_POINT)
mode which means only the corner points are drawn, and since two have alpha=0
only the original point is drawn.  This is a long way to go to draw a point,
but it ensures that the point is only visible within 90 degrees of the light
direction, behind the light it is not visible.  This is still a long way
to get to drawing a point, but we use an environement map, with the direction
vector as the normal to mimic a light that is brightest when viewed head
on and dimmest when viewed perpendicularly or disappears when viewed from
behind.

- warning, there is a bug in how the current runway light direction vector
  is calculated which will adversely effect runway lighting.  The airports
  should be regenerated in order to fix this problem.
This commit is contained in:
curt 2002-10-06 03:53:19 +00:00
parent f0b7744fd5
commit c162577340
12 changed files with 395 additions and 172 deletions

View file

@ -397,7 +397,8 @@ void trRenderFrame( void ) {
// 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 );
@ -749,7 +750,17 @@ void fgRenderFrame() {
#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) {
@ -855,9 +866,6 @@ void fgUpdateTimeDepCalcs() {
//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.
@ -2069,7 +2077,7 @@ void fgLoadDCS(void) {
//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

View file

@ -2,10 +2,10 @@ noinst_LIBRARIES = libObjects.a
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

View file

@ -1,30 +0,0 @@
// 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;
}

View file

@ -37,6 +37,7 @@
#include <GL/gl.h>
#include <simgear/compiler.h>
#include <simgear/constants.h>
#include <simgear/misc/exception.hxx>
#include <string.h>
@ -68,54 +69,145 @@ FGMaterialLib::FGMaterialLib ( void ) {
}
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;
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());
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 );
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);
matlib["LIGHTS"] = new FGNewMat(lights);
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;
}

View file

@ -131,7 +131,7 @@ FGNewMat::Object::load_models () const
{
// 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
@ -256,7 +256,7 @@ FGNewMat::FGNewMat (const string &texpath)
build_ssg_state(true);
}
FGNewMat::FGNewMat (ssgSimpleState * s)
FGNewMat::FGNewMat (ssgSimpleState *s)
{
init();
set_ssg_state(s);
@ -370,9 +370,9 @@ void
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();
@ -389,15 +389,6 @@ FGNewMat::build_ssg_state (bool defer_tex_load)
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;
@ -462,25 +453,31 @@ FGNewMat::build_ssg_state (bool defer_tex_load)
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] ) ;
@ -499,7 +496,11 @@ void FGNewMat::set_ssg_state( ssgSimpleState *s )
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

View file

@ -59,6 +59,7 @@
#include "newmat.hxx"
#include "matlib.hxx"
#include "pt_lights.hxx"
#include "obj.hxx"
SG_USING_STD(string);
@ -1376,12 +1377,9 @@ bool fgBinObjLoad( const string& path, const bool is_base,
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();
@ -1401,29 +1399,30 @@ bool fgBinObjLoad( const string& path, const bool is_base,
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 );
}
}

159
src/Objects/pt_lights.cxx Normal file
View file

@ -0,0 +1,159 @@
// 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;
}

View file

@ -1,4 +1,4 @@
// dir_lights.hxx -- build a 'directional' light on the fly
// pt_lights.hxx -- build a 'directional' light on the fly
//
// Written by Curtis Olson, started March 2002.
//
@ -21,8 +21,8 @@
// $Id$
#ifndef _DIR_LIGHTS_HXX
#define _DIR_LIGHTS_HXX
#ifndef _PT_LIGHTS_HXX
#define _PT_LIGHTS_HXX
#ifndef __cplusplus
@ -39,8 +39,11 @@
#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);
@ -51,7 +54,7 @@ typedef int_list::const_iterator int_point_list_iterator;
// Define the various supported light types
enum {
typedef enum {
FG_RWYLIGHT_TAXI = 0,
FG_RWYLIGHT_VASI,
FG_RWYLIGHT_EDGE,
@ -93,13 +96,14 @@ enum {
// 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_light( sgVec3 pt, sgVec3 dir, sgVec3 up );
/* ssgLeaf *gen_directional_lights( const point_list &nodes,
const point_list &normals,
const int_list &pnt_i,
const int_list &nml_i );
*/
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 // _DIR_LIGHTS_HXX
#endif // _PT_LIGHTS_HXX

View file

@ -61,9 +61,6 @@ void FGScenery::init() {
scene_graph = new ssgRoot;
scene_graph->setName( "Scene" );
lighting = new ssgRoot;
lighting->setName( "Lighting" );
// Terrain branch
terrain_branch = new ssgBranch;
terrain_branch->setName( "Terrain" );
@ -78,13 +75,11 @@ void FGScenery::init() {
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" );
}

View file

@ -61,14 +61,12 @@ class FGScenery : public FGSubsystem {
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:
@ -93,42 +91,39 @@ 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; }
};

View file

@ -1061,7 +1061,7 @@ ssgLeaf* FGTileEntry::gen_lights( ssgVertexArray *lights, int inc, float bright
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 );

View file

@ -370,8 +370,8 @@ int FGTileMgr::update( double lon, double lat, double visibility_meters,
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 "
}