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:
parent
f0b7744fd5
commit
c162577340
12 changed files with 395 additions and 172 deletions
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
159
src/Objects/pt_lights.cxx
Normal 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;
|
||||
}
|
|
@ -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
|
|
@ -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" );
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -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; }
|
||||
};
|
||||
|
||||
|
||||
|
|
|
@ -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 );
|
||||
|
|
|
@ -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 "
|
||||
}
|
||||
|
||||
|
|
Loading…
Add table
Reference in a new issue