- update Sky code

git-svn-id: https://svn.code.sf.net/p/speed-dreams/code/trunk@4742 30fe4595-0a0c-4342-8851-515496e4dcbd

Former-commit-id: fe58d84e135161de3b80a22013c0307429b9ae19
Former-commit-id: ee48d81ed9ad6bb73e6c4b4d204e41d072a29b12
This commit is contained in:
torcs-ng 2012-06-10 21:51:14 +00:00
parent 2e14c32862
commit 03550e9138
6 changed files with 839 additions and 277 deletions

View file

@ -5,7 +5,8 @@ SET(SSGGRAPH_SOURCES CarSoundData.cpp CarSoundData.h
SoundInterface.cpp SoundInterface.h
PlibSoundInterface.cpp PlibSoundInterface.h
OpenalSoundInterface.cpp OpenalSoundInterface.h
grCelestialBody.cpp grCloudLayer.cpp grSky.cpp grSky.h
#grCelestialBody.cpp
grMoon.cpp grSun.cpp grCloudLayer.cpp grSky.cpp grSky.h
grSkyDome.cpp grSphere.cpp grSphere.h grStars.cpp
grboard.cpp grboard.h grcam.cpp grcam.h grcar.cpp grcar.h
grcarlight.cpp grcarlight.h grmain.cpp grmain.h

View file

@ -0,0 +1,147 @@
/***************************************************************************
file : grMoon.cpp
copyright : (C) 2009 by Xavier Bertaux (based on ssgasky plib code)
web : http://www.speed-dreams.org
version : $Id: grSky.cpp 3162 2010-12-05 13:11:22Z pouillot $
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include "grSky.h"
#include "grSphere.h"
static int grMoonOrbPreDraw( ssgEntity *e )
{
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE );
return true;
}
static int grMoonOrbPostDraw( ssgEntity *e )
{
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
glPopAttrib();
return true;
}
// Constructor
cGrMoon::cGrMoon( void ) :
prev_moon_angle(-1)
{
}
// Destructor
cGrMoon::~cGrMoon( void )
{
}
// build the moon object
ssgBranch * cGrMoon::build( const char *moon_path, double moon_size )
{
orb_state = new ssgSimpleState();
orb_state->setTexture( moon_path );
orb_state->setShadeModel( GL_SMOOTH );
orb_state->enable( GL_LIGHTING );
orb_state->enable( GL_CULL_FACE );
orb_state->enable( GL_TEXTURE_2D );
orb_state->enable( GL_COLOR_MATERIAL );
orb_state->setColourMaterial( GL_DIFFUSE );
orb_state->setMaterial( GL_AMBIENT, 0, 0, 0, 1.0 );
orb_state->setMaterial( GL_EMISSION, 0.0, 0.0, 0.0, 1 );
orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
orb_state->enable( GL_BLEND );
orb_state->enable( GL_ALPHA_TEST );
orb_state->setAlphaClamp( 0.01 );
cl = new ssgColourArray( 1 );
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
cl->add( color );
ssgBranch *orb = grMakeSphere( orb_state, cl, moon_size, 15, 15,
grMoonOrbPreDraw, grMoonOrbPostDraw );
repaint( 0.0 );
moon_transform = new ssgTransform;
moon_transform->addKid( orb );
return moon_transform;
}
bool cGrMoon::repaint( double moon_angle )
{
if (prev_moon_angle != moon_angle)
{
prev_moon_angle = moon_angle;
float moon_factor = 4*cos(moon_angle);
if (moon_factor > 1) moon_factor = 1.0;
if (moon_factor < -1) moon_factor = -1.0;
moon_factor = moon_factor/2 + 0.5;
sgVec4 color;
color[1] = sqrt(moon_factor);
color[0] = sqrt(color[1]);
color[2] = moon_factor * moon_factor;
color[2] *= color[2];
color[3] = 1.0;
grGammaCorrectRGB( color );
float *ptr;
ptr = cl->get( 0 );
sgCopyVec4( ptr, color );
}
return true;
}
bool cGrMoon::reposition( sgVec3 p, double angle, double rightAscension, double declination, double moon_dist )
{
sgMat4 T1, T2, GST, RA, DEC;
sgVec3 axis;
sgVec3 v;
sgMakeTransMat4( T1, p );
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, (float)angle, axis );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, ((float)rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, (float)declination * SGD_RADIANS_TO_DEGREES, axis );
sgSetVec3( v, 0.0, moon_dist, 0.0 );
sgMakeTransMat4( T2, v );
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, GST );
sgPreMultMat4( TRANSFORM, RA );
sgPreMultMat4( TRANSFORM, DEC );
sgPreMultMat4( TRANSFORM, T2 );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
moon_transform->setTransform( &skypos );
return true;
}

View file

@ -22,36 +22,39 @@
// Used for rise/set effects (flat earth - no rotation of skydome considered here )
void calc_celestial_angles( const sgVec3 body, const sgVec3 view, double& angle, double& rotation )
{
sgVec3 pos;
sgSubVec3(pos, body, view);
angle = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[2], sqrt(pos[0]*pos[0] + pos[1]*pos[1]));
rotation = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[0], pos[1]);
sgVec3 pos;
sgSubVec3(pos, body, view);
angle = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[2], sqrt(pos[0]*pos[0] + pos[1]*pos[1]));
rotation = (90*SGD_DEGREES_TO_RADIANS) - atan2(pos[0], pos[1]);
}
cGrSky::cGrSky( void )
{
dome = 0;
planets = 0;
stars = 0;
sol_ref = 0;
pre_root = 0;
post_root = 0;
dome = 0;
sun = 0;
moon = 0;
planets = 0;
stars = 0;
pre_root = 0;
post_root = 0;
effective_visibility = visibility = 10000.0;
effective_visibility = visibility = 10000.0;
// near cloud visibility state variables
in_puff = false;
puff_length = 0;
puff_progression = 0;
ramp_up = 0.15;
ramp_down = 0.15;
// near cloud visibility state variables
in_puff = false;
puff_length = 0;
puff_progression = 0;
ramp_up = 0.15;
ramp_down = 0.15;
}
cGrSky::~cGrSky( void )
{
delete dome;
delete sun;
delete moon;
delete planets;
delete stars;
delete pre_root;
@ -60,15 +63,18 @@ cGrSky::~cGrSky( void )
void cGrSky::build( double h_radius, double v_radius,
const char *sun_path, const char *ihalo_path, const char *ohalo_path,
float sun_size, const char *moon_path, float moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data )
int nstars, sgdVec3 *star_data, float humidity, float visibility )
{
delete dome;
delete sun;
delete moon;
delete planets;
delete stars;
delete pre_root;
delete post_root;
bodies.removeAll();
clouds.removeAll();
// build new
@ -81,19 +87,27 @@ void cGrSky::build( double h_radius, double v_radius,
pre_transform = new ssgTransform;
post_transform = new ssgTransform;
bodies_transform = new ssgTransform;
sun_transform = new ssgTransform;
moon_transform = new ssgTransform;
stars_transform = new ssgTransform;
dome = new cGrSkyDome;
pre_transform -> addKid( dome->build( h_radius, v_radius ) );
sun = new cGrSun;
sun_transform -> addKid( sun->build( sun_path, ihalo_path, ohalo_path, sun_size, humidity, visibility));
moon = new cGrMoon;
moon_transform -> addKid( moon->build( moon_path, moon_size ));
planets = new cGrStars;
stars_transform -> addKid( planets->build( nplanets, planet_data, h_radius ) );
stars = new cGrStars;
stars_transform -> addKid( stars->build( nstars, star_data, h_radius ) );
pre_transform -> addKid( bodies_transform );
pre_transform -> addKid( sun_transform );
pre_transform -> addKid( moon_transform );
pre_transform -> addKid( stars_transform );
pre_selector->addKid( pre_transform );
@ -107,7 +121,7 @@ void cGrSky::build( double h_radius, double v_radius,
}
cGrCelestialBody*
/*cGrCelestialBody*
cGrSky::addBody( const char *body_tex_path, const char *ihalo_tex_path, const char *ohalo_tex_path, double size, double dist, bool sol )
{
cGrCelestialBody* body = new cGrCelestialBody;
@ -136,7 +150,7 @@ cGrSky::addBody( ssgSimpleState *orb_state, ssgSimpleState *ihalo_state, ssgSimp
sol_ref = body;
return body;
}
}*/
cGrCloudLayer*
@ -161,41 +175,39 @@ cGrSky::addCloud( ssgSimpleState *cloud_state, float span, float elevation, floa
bool cGrSky::repositionFlat( sgVec3 view_pos, double spin, double dt )
{
int i;
double angle;
double rotation;
sgCoord pos;
int i;
double angle;
double rotation;
sgCoord pos;
for ( i = 0; i < bodies.getNum (); i++ )
{
cGrCelestialBody *body = bodies.get(i);
body->reposition( view_pos, 0 );
sun->reposition( view_pos, 0 );
moon->reposition( view_pos, 0 );
// Calc angles for rise/set effects
body->getPosition ( & pos );
sun->getPosition ( & pos );
calc_celestial_angles( pos.xyz, view_pos, angle, rotation );
body->setAngle( angle );
body->setRotation( rotation );
}
sun->setAngle( angle );
sun->setRotation( rotation );
for ( i = 0; i < clouds.getNum (); i++ )
{
clouds.get(i)->repositionFlat( view_pos, dt );
}
planets->reposition( view_pos, 0 );
stars->reposition( view_pos, 0 );
for ( i = 0; i < clouds.getNum (); i++ )
{
clouds.get(i)->repositionFlat( view_pos, dt );
}
if ( sol_ref )
{
dome->repositionFlat( view_pos, sol_ref->getRotation() );
}
else
{
dome->repositionFlat( view_pos, spin );
}
planets->reposition( view_pos, 0 );
stars->reposition( view_pos, 0 );
return true;
/*if ( sol_ref )
{
dome->repositionFlat( view_pos, sol_ref->getRotation() );
}
else
{*/
dome->repositionFlat( view_pos, spin );
//}
return true;
}
@ -207,12 +219,11 @@ bool cGrSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, doub
dome->reposition( zero_elev, lon, lat, spin );
for ( i = 0; i < bodies.getNum (); i++ )
bodies.get(i)->reposition( view_pos, angle );
for ( i = 0; i < clouds.getNum (); i++ )
clouds.get(i)->reposition( zero_elev, view_up, lon, lat, alt, dt );
sun->reposition( view_pos, angle);
moon->reposition(view_pos, angle);
planets->reposition( view_pos, angle );
stars->reposition( view_pos, angle );
@ -233,12 +244,11 @@ bool cGrSky::repaint( sgVec4 sky_color, sgVec4 fog_color, sgVec4 cloud_color, do
dome->repaint( sky_color, fog_color, sol_angle, effective_visibility );
for ( i = 0; i < bodies.getNum (); i++ )
bodies.get(i)->repaint();
for ( i = 0; i < clouds.getNum (); i++ )
clouds.get(i)->repaint( cloud_color );
sun->repaint( sol_angle, effective_visibility );
moon->repaint( sol_angle );
planets->repaint( sol_angle, nplanets, planet_data );
stars->repaint( sol_angle, nstars, star_data );
}

View file

@ -22,15 +22,199 @@
#include "plib/ssg.h"
class cGrCelestialBody;
class cGrCelestialBodyList;
//class cGrCelestialBody;
//class cGrCelestialBodyList;
class cGrSun;
class cGrMoon;
class cGrCloudLayer;
class cGrCloudLayerList;
class cGrStars;
class cGrSkyDome;
class cGrSky;
class cGrCelestialBody
class cGrMoon
{
ssgTransform *moon_transform;
ssgSimpleState *orb_state;
ssgSimpleState *halo_state;
ssgColourArray *cl;
ssgVertexArray *halo_vl;
ssgTexCoordArray *halo_tl;
double prev_moon_angle;
double moon_angle;
double moon_size;
double moon_dist;
double moonAscension;
double moondeclination;
public:
// Constructor
cGrMoon( void );
// Destructor
~cGrMoon( void );
// build the moon object
ssgBranch *build( const char* moon_path, double moon_size );
// repaint the moon colors based on current value of moon_anglein
// degrees relative to verticle
// 0 degrees = high noon
// 90 degrees = moon rise/set
// 180 degrees = darkest midnight
//bool repaint(double moon_angle);
/*bool reposition( sgVec3 p, double angle,
double rightAscension, double declination,
double moon_dist );*/
bool reposition(sgVec3 p, double moon_angle)
{
return reposition (p, moon_angle, moonAscension, moondeclination, moon_dist);
}
bool reposition(sgVec3 p, double moon_angle, double moonAscension, double moondeclination, double moon_dist);
bool repaint(double moon_angle);
void setmoonRightAscension ( double ra ) { moonAscension = ra; }
double getRightAscension () { return moonAscension; }
void setmoonDeclination ( double decl ) { moondeclination = decl; }
double getmoonDeclination () { return moondeclination; }
};
class cGrSun
{
ssgTransform *sun_transform;
ssgSimpleState *sun_state;
ssgSimpleState *ihalo_state;
ssgSimpleState *ohalo_state;
ssgColourArray *sun_cl;
ssgColourArray *ihalo_cl;
ssgColourArray *ohalo_cl;
ssgVertexArray *sun_vl;
ssgVertexArray *ihalo_vl;
ssgVertexArray *ohalo_vl;
ssgTexCoordArray *sun_tl;
ssgTexCoordArray *ihalo_tl;
ssgTexCoordArray *ohalo_tl;
GLuint sun_texid;
GLubyte *sun_texbuf;
double visibility;
double prev_sun_angle;
double sun_angle;
double sun_rotation;
// used by reposition
double sun_right_ascension;
double sun_declination;
double sun_dist;
double path_distance;
public:
// Constructor
cGrSun( void );
// Destructor
~cGrSun( void );
// return the sun object
ssgBranch *build( const char* sun_path, const char *ihalo_path, const char* ohalo_path, float sun_size, float humidity, float visibility );
// repaint the sun colors based on current value of sun_anglein
// degrees relative to verticle
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( double sun_angle, double new_visibility );
// reposition the sun at the specified right ascension and
// declination, offset by our current position (p) so that it
// appears fixed at a great distance from the viewer. Also add in
// an optional rotation (i.e. for the current time of day.)
/*bool reposition( sgVec3 p, double angle,
double rightAscension, double declination,
double sun_dist, double lat, double alt_asl, double sun_angle );*/
bool reposition( sgVec3 p, double sun_angle )
{
return reposition ( p, sun_angle, sun_right_ascension, sun_declination, sun_dist );
}
bool reposition( sgVec3 p, double sun_angle, double rightAscension, double declination, double dist );
void getPosition (sgCoord* p)
{
sgMat4 Xform;
sun_transform->getTransform(Xform);
sgSetCoord(p, Xform);
}
void setAngle (double angle)
{
sun_angle = angle;
}
double getAngle ()
{
return sun_angle;
}
void setRotation (double rotation)
{
sun_rotation = rotation;
}
double getRotation ()
{
return sun_rotation;
}
void setRightAscension (double ra)
{
sun_right_ascension = ra;
}
double getRightAscension ()
{
return sun_right_ascension;
}
void setDeclination ( double decl )
{
sun_declination = decl;
}
double getDeclination ()
{
return sun_declination;
}
void setDist ( double dist )
{
sun_dist = dist;
}
double getDist ()
{
return sun_dist;
}
// retrun the current color of the sun
inline float *get_color() { return ohalo_cl->get( 0 ); }
double effective_visibility;
};
/*class cGrCelestialBody
{
private:
@ -117,7 +301,7 @@ public:
delete get (i) ;
ssgSimpleList::removeAll () ;
}
} ;
} ;*/
class cGrCloudLayer
@ -273,8 +457,8 @@ private:
// components of the sky
cGrSkyDome *dome;
cGrCelestialBody* sol_ref;
cGrCelestialBodyList bodies;
cGrSun *sun;
cGrMoon *moon;
cGrCloudLayerList clouds;
cGrStars *planets;
cGrStars *stars;
@ -283,7 +467,7 @@ private:
ssgSelector *pre_selector, *post_selector;
ssgTransform *pre_transform, *post_transform;
ssgTransform *bodies_transform, *stars_transform;
ssgTransform *sun_transform, *moon_transform, *stars_transform;
// visibility
float visibility;
@ -302,13 +486,11 @@ public:
~cGrSky( void );
void build( double h_radius, double v_radius,
const char *sun_path, const char *ihalo_path,
const char *ohalo_path, float sun_size,
const char *moon_path, float moon_size,
int nplanets, sgdVec3 *planet_data,
int nstars, sgdVec3 *star_data);
cGrCelestialBody* addBody( const char *body_tex_path, const char *ihalo_path, const char* ohalo_path, double size, double dist, bool sol = false );
cGrCelestialBody* addBody( ssgSimpleState *orb_state, ssgSimpleState *ihalo_state, ssgSimpleState *ohalo_state, double size, double dist, bool sol = false );
cGrCelestialBody* getBody(int i) { return bodies.get(i); }
int getBodyCount() { return bodies.getNum(); }
int nstars, sgdVec3 *star_data, float humidity, float visibility);
cGrCloudLayer* addCloud( const char *cloud_tex_path, float span, float elevation, float thickness, float transition );
cGrCloudLayer* addCloud( ssgSimpleState *cloud_state, float span, float elevation, float thickness, float transition );
@ -391,190 +573,4 @@ inline void grGammaRestoreC(float *color, float reff = 2.5, float system = syste
*color = (float)pow(*color, system/reff);
};
#if O
class cGrMoon
{
ssgTransform *moon_transform;
ssgSimpleState *orb_state;
ssgSimpleState *halo_state;
ssgColourArray *cl;
ssgVertexArray *halo_vl;
ssgTexCoordArray *halo_tl;
double prev_moon_angle;
double moon_angle;
double moon_rotation;
// used by reposition
double moon_right_ascension;
double moon_declination;
double moon_dist;
public:
// Constructor
cGrMoon( void );
// Destructor
~cGrMoon( void );
// build the moon object
ssgBranch *build( const char* body_tex_path, double moon_size );
// repaint the moon colors based on current value of moon_anglein
// degrees relative to verticle
// 0 degrees = high noon
// 90 degrees = moon rise/set
// 180 degrees = darkest midnight
//bool repaint(double moon_angle);
/*bool reposition( sgVec3 p, double angle,
double rightAscension, double declination,
double moon_dist );*/
/*bool reposition(sgVec3 p, double moon_angle)
{
return reposition (p, moon_angle, rightAscension, declination, moon_dist);
}*/
bool reposition(sgVec3 p, double moon_angle, double rightAscension, double declination, double moon_dist);
/*bool repaint()
{
return repaint (moon_angle);
}*/
bool repaint(double moon_angle);
void getPosition (sgCoord* p)
{
sgMat4 Xform;
moon_transform->getTransform(Xform);
sgSetCoord(p, Xform);
}
void setAngle (double angle)
{
moon_angle = angle;
}
double getAngle ()
{
return moon_angle;
}
void setRotation (double rotation)
{
moon_rotation = rotation;
}
double getRotation ()
{
return moon_rotation;
}
void setRightAscension (double ra)
{
moon_right_ascension = ra;
}
double getRightAscension ()
{
return moon_right_ascension;
}
void setDeclination ( double decl )
{
moon_declination = decl;
}
double getDeclination ()
{
return moon_declination;
}
void setDist ( double dist )
{
moon_dist = dist;
}
double getDist ()
{
return moon_dist;
}
inline float *getColor()
{
return cl->get( 0 );
}
};
// Not used.
class cGrSun
{
ssgTransform *sun_transform;
ssgSimpleState *sun_state;
ssgSimpleState *ihalo_state;
ssgSimpleState *ohalo_state;
ssgColourArray *sun_cl;
ssgColourArray *ihalo_cl;
ssgColourArray *ohalo_cl;
ssgVertexArray *sun_vl;
ssgVertexArray *ihalo_vl;
ssgVertexArray *ohalo_vl;
ssgTexCoordArray *sun_tl;
ssgTexCoordArray *ihalo_tl;
ssgTexCoordArray *ohalo_tl;
GLuint sun_texid;
GLubyte *sun_texbuf;
double visibility;
double prev_sun_angle;
// distance of light traveling through the atmosphere
double path_distance;
public:
// Constructor
cGrSun( void );
// Destructor
~cGrSun( void );
// return the sun object
ssgBranch *build( const char* body_tex_path, const char* halo_tex_path, double sun_size);
// repaint the sun colors based on current value of sun_anglein
// degrees relative to verticle
// 0 degrees = high noon
// 90 degrees = sun rise/set
// 180 degrees = darkest midnight
bool repaint( double sun_angle, double new_visibility );
// reposition the sun at the specified right ascension and
// declination, offset by our current position (p) so that it
// appears fixed at a great distance from the viewer. Also add in
// an optional rotation (i.e. for the current time of day.)
/*bool reposition( sgVec3 p, double angle,
double rightAscension, double declination,
double sun_dist, double lat, double alt_asl, double sun_angle );*/
bool reposition( sgVec3 p, double sun_angle )
{
return reposition ( p, angle, sun_right_ascension, sun_declination, sun_body_dist );
}
bool reposition( sgVec3 p, double sun_angle, double rightAscension, double declination, double dist );
// retrun the current color of the sun
inline float *get_color() { return ohalo_cl->get( 0 ); }
// return the texture id of the sun halo texture
inline GLuint get_texture_id() { return ohalo_state->getTextureHandle(); }
};
#endif
#endif

View file

@ -0,0 +1,409 @@
/***************************************************************************
file : grSun.cpp
copyright : (C) 2009 by Xavier Bertaux (based on ssgasky plib code)
web : http://www.speed-dreams.org
version : $Id: grSky.cpp 3162 2010-12-05 13:11:22Z pouillot $
***************************************************************************/
/***************************************************************************
* *
* 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. *
* *
***************************************************************************/
#include <plib/sg.h>
#include <plib/ssg.h>
#include "grSky.h"
#include "grSphere.h"
static float sun_exp2_punch_through;
// Set up sun rendering call backs
static int grSunPreDraw( ssgEntity *e )
{
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply() ;
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
glDisable( GL_DEPTH_TEST );
glDisable( GL_FOG );
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int grSunPostDraw( ssgEntity *e )
{
glPopAttrib();
return true;
}
static int grSunHaloPreDraw( ssgEntity *e )
{
ssgLeaf *f = (ssgLeaf *)e;
if ( f -> hasState () ) f->getState()->apply();
glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
glDisable( GL_DEPTH_TEST );
glFogf (GL_FOG_DENSITY, sun_exp2_punch_through);
glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
return true;
}
static int grSunHaloPostDraw( ssgEntity *e )
{
glPopAttrib();
return true;
}
// Constructor
cGrSun::cGrSun( void )
{
prev_sun_angle = -9999.0;
visibility = -9999.0;
}
// Destructor
cGrSun::~cGrSun( void )
{
}
ssgBranch * cGrSun::build( const char *sun_path, const char *ihalo_path, const char *ohalo_path, float sun_size, float humidity, float visibility )
{
sgVec4 color;
sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
sun_cl = new ssgColourArray( 1 );
sun_cl->add( color );
ihalo_cl = new ssgColourArray( 1 );
ihalo_cl->add( color );
ohalo_cl = new ssgColourArray( 1 );
ohalo_cl->add( color );
//repaint( 0.0, 1.0 );
// set up the sun-state
sun_state = new ssgSimpleState();
sun_state->setShadeModel( GL_SMOOTH );
sun_state->disable( GL_LIGHTING );
sun_state->disable( GL_CULL_FACE );
sun_state->setTexture( sun_path);
sun_state->enable( GL_TEXTURE_2D );
sun_state->enable( GL_COLOR_MATERIAL );
sun_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
sun_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
sun_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
sun_state->enable( GL_BLEND );
sun_state->setAlphaClamp( 0.01 );
sun_state->enable( GL_ALPHA_TEST );
// Build ssg structure
sgVec3 va;
sun_vl = new ssgVertexArray;
sgSetVec3( va, -sun_size, 0.0, -sun_size );
sun_vl->add( va );
sgSetVec3( va, sun_size, 0.0, -sun_size );
sun_vl->add( va );
sgSetVec3( va, -sun_size, 0.0, sun_size );
sun_vl->add( va );
sgSetVec3( va, sun_size, 0.0, sun_size );
sun_vl->add( va );
sgVec2 vb;
sun_tl = new ssgTexCoordArray;
sgSetVec2( vb, 0.0f, 0.0f );
sun_tl->add( vb );
sgSetVec2( vb, 1.0, 0.0 );
sun_tl->add( vb );
sgSetVec2( vb, 0.0, 1.0 );
sun_tl->add( vb );
sgSetVec2( vb, 1.0, 1.0 );
sun_tl->add( vb );
ssgBranch *sun = grMakeSphere( sun_state, sun_cl, sun_size, 15, 15,
grSunPreDraw, grSunPostDraw );
repaint( 0.0, 1.0 );
ihalo_state = new ssgSimpleState();
ihalo_state->setTexture( ihalo_path );
ihalo_state->enable( GL_TEXTURE_2D );
ihalo_state->disable( GL_LIGHTING );
ihalo_state->setShadeModel( GL_SMOOTH );
ihalo_state->disable( GL_CULL_FACE );
ihalo_state->enable( GL_COLOR_MATERIAL );
ihalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
ihalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
ihalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
ihalo_state->enable( GL_ALPHA_TEST );
ihalo_state->setAlphaClamp(0.01);
ihalo_state->enable ( GL_BLEND ) ;
float ihalo_size = sun_size * 2.0;
sgVec3 vc;
ihalo_vl = new ssgVertexArray;
sgSetVec3( vc, -ihalo_size, 0.0, -ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, ihalo_size, 0.0, -ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, -ihalo_size, 0.0, ihalo_size );
ihalo_vl->add( vc );
sgSetVec3( vc, ihalo_size, 0.0, ihalo_size );
ihalo_vl->add( vc );
sgVec2 vd;
ihalo_tl = new ssgTexCoordArray;
sgSetVec2( vd, 0.0f, 0.0f );
ihalo_tl->add( vd );
sgSetVec2( vd, 1.0, 0.0 );
ihalo_tl->add( vd );
sgSetVec2( vd, 0.0, 1.0 );
ihalo_tl->add( vd );
sgSetVec2( vd, 1.0, 1.0 );
ihalo_tl->add( vd );
ssgLeaf *ihalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ihalo_vl, NULL, ihalo_tl, ihalo_cl );
ihalo->setState( ihalo_state );
ohalo_state = new ssgSimpleState();
ohalo_state->setTexture( ohalo_path );
ohalo_state->enable( GL_TEXTURE_2D );
ohalo_state->disable( GL_LIGHTING );
ohalo_state->setShadeModel( GL_SMOOTH );
ohalo_state->disable( GL_CULL_FACE );
ohalo_state->enable( GL_COLOR_MATERIAL );
ohalo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
ohalo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
ohalo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
ohalo_state->enable( GL_ALPHA_TEST );
ohalo_state->setAlphaClamp(0.01);
ohalo_state->enable ( GL_BLEND ) ;
float ohalo_size = (float)sun_size * 7.0;
sgVec3 ve;
ohalo_vl = new ssgVertexArray;
sgSetVec3( ve, -ohalo_size, 0.0, -ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, ohalo_size, 0.0, -ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, -ohalo_size, 0.0, ohalo_size );
ohalo_vl->add( ve );
sgSetVec3( ve, ohalo_size, 0.0, ohalo_size );
ohalo_vl->add( ve );
sgVec2 vf;
ohalo_tl = new ssgTexCoordArray;
sgSetVec2( vf, 0.0f, 0.0f );
ohalo_tl->add( vf );
sgSetVec2( vf, 1.0, 0.0 );
ohalo_tl->add( vf );
sgSetVec2( vf, 0.0, 1.0 );
ohalo_tl->add( vf );
sgSetVec2( vf, 1.0, 1.0 );
ohalo_tl->add( vf );
ssgLeaf *ohalo = new ssgVtxTable ( GL_TRIANGLE_STRIP, ohalo_vl, NULL, ohalo_tl, ohalo_cl );
ohalo->setState( ohalo_state );
sun_transform = new ssgTransform;
ihalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw );
ihalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw );
ohalo->setCallback( SSG_CALLBACK_PREDRAW, grSunHaloPreDraw );
ohalo->setCallback( SSG_CALLBACK_POSTDRAW, grSunHaloPostDraw );
sun_transform->addKid( ohalo );
sun_transform->addKid( ihalo );
sun_transform->addKid( sun );
return sun_transform;
}
bool cGrSun::repaint( double sun_angle, double new_visibility )
{
if ( visibility != new_visibility )
{
visibility = new_visibility;
static const float sqrt_m_log01 = sqrt( -log( 0.01 ) );
sun_exp2_punch_through = sqrt_m_log01 / ( visibility * 15 );
}
if ( prev_sun_angle != sun_angle )
{
prev_sun_angle = sun_angle;
float aerosol_factor;
if ( visibility < 100 )
{
aerosol_factor = 8000;
}
else
{
aerosol_factor = 80.5 / log( visibility / 100 );
}
float rel_humidity, density_avg;
/*if ( !env_node )
{*/
rel_humidity = 0.5;
density_avg = 0.7;
/*}
else
{
//rel_humidity = env_node->getFloatValue( "relative-humidity" );
//density_avg = env_node->getFloatValue( "atmosphere/density-tropo-avg" );
}*/
sgVec4 i_halo_color, o_halo_color, sun_color;
float red_scat_f = ( aerosol_factor * path_distance * density_avg ) / 5E+07;
sun_color[0] = 1 - red_scat_f;
i_halo_color[0] = 1 - ( 1.1 * red_scat_f );
o_halo_color[0] = 1 - ( 1.4 * red_scat_f );
// Green - 546.1 nm
float green_scat_f = ( aerosol_factor * path_distance * density_avg ) / 8.8938E+06;
sun_color[1] = 1 - green_scat_f;
i_halo_color[1] = 1 - ( 1.1 * green_scat_f );
o_halo_color[1] = 1 - ( 1.4 * green_scat_f );
// Blue - 435.8 nm
float blue_scat_f = ( aerosol_factor * path_distance * density_avg ) / 3.607E+06;
sun_color[2] = 1 - blue_scat_f;
i_halo_color[2] = 1 - ( 1.1 * blue_scat_f );
o_halo_color[2] = 1 - ( 1.4 * blue_scat_f );
// Alpha
sun_color[3] = 1;
i_halo_color[3] = 1;
o_halo_color[3] = blue_scat_f;
if ( ( new_visibility < 10000 ) && ( blue_scat_f > 1 ))
{
o_halo_color[3] = 2 - blue_scat_f;
}
float saturation = 1 - ( rel_humidity / 200 );
sun_color[1] += (( 1 - saturation ) * ( 1 - sun_color[1] ));
sun_color[2] += (( 1 - saturation ) * ( 1 - sun_color[2] ));
i_halo_color[1] += (( 1 - saturation ) * ( 1 - i_halo_color[1] ));
i_halo_color[2] += (( 1 - saturation ) * ( 1 - i_halo_color[2] ));
o_halo_color[1] += (( 1 - saturation ) * ( 1 - o_halo_color[1] ));
o_halo_color[2] += (( 1 - saturation ) * ( 1 - o_halo_color[2] ));
// just to make sure we're in the limits
if ( sun_color[0] < 0 ) sun_color[0] = 0;
else if ( sun_color[0] > 1) sun_color[0] = 1;
if ( i_halo_color[0] < 0 ) i_halo_color[0] = 0;
else if ( i_halo_color[0] > 1) i_halo_color[0] = 1;
if ( o_halo_color[0] < 0 ) o_halo_color[0] = 0;
else if ( o_halo_color[0] > 1) o_halo_color[0] = 1;
if ( sun_color[1] < 0 ) sun_color[1] = 0;
else if ( sun_color[1] > 1) sun_color[1] = 1;
if ( i_halo_color[1] < 0 ) i_halo_color[1] = 0;
else if ( i_halo_color[1] > 1) i_halo_color[1] = 1;
if ( o_halo_color[1] < 0 ) o_halo_color[1] = 0;
else if ( o_halo_color[1] > 1) o_halo_color[1] = 1;
if ( sun_color[2] < 0 ) sun_color[2] = 0;
else if ( sun_color[2] > 1) sun_color[2] = 1;
if ( i_halo_color[2] < 0 ) i_halo_color[2] = 0;
else if ( i_halo_color[2] > 1) i_halo_color[2] = 1;
if ( o_halo_color[2] < 0 ) o_halo_color[2] = 0;
else if ( o_halo_color[2] > 1) o_halo_color[2] = 1;
if ( o_halo_color[3] < 0 ) o_halo_color[2] = 0;
else if ( o_halo_color[3] > 1) o_halo_color[3] = 1;
grGammaCorrectRGB( i_halo_color );
grGammaCorrectRGB( o_halo_color );
grGammaCorrectRGB( sun_color );
float *ptr;
ptr = sun_cl->get( 0 );
sgCopyVec4( ptr, sun_color );
ptr = ihalo_cl->get( 0 );
sgCopyVec4( ptr, i_halo_color );
ptr = ohalo_cl->get( 0 );
sgCopyVec4( ptr, o_halo_color );
}
return true;
}
bool cGrSun::reposition( sgVec3 p, double angle, double rightAscension, double declination, double sun_dist )
{
sgMat4 T1, T2, GST, RA, DEC;
sgVec3 axis;
sgVec3 v;
sgMakeTransMat4( T1, p );
sgSetVec3( axis, 0.0, 0.0, -1.0 );
sgMakeRotMat4( GST, (float)angle, axis );
sgSetVec3( axis, 0.0, 0.0, 1.0 );
sgMakeRotMat4( RA, ((float)rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis );
sgSetVec3( axis, 1.0, 0.0, 0.0 );
sgMakeRotMat4( DEC, (float)declination * SGD_RADIANS_TO_DEGREES, axis );
sgSetVec3( v, 0.0, sun_dist, 0.0 );
sgMakeTransMat4( T2, v );
sgMat4 TRANSFORM;
sgCopyMat4( TRANSFORM, T1 );
sgPreMultMat4( TRANSFORM, GST );
sgPreMultMat4( TRANSFORM, RA );
sgPreMultMat4( TRANSFORM, DEC );
sgPreMultMat4( TRANSFORM, T2 );
sgCoord skypos;
sgSetCoord( &skypos, TRANSFORM );
sun_transform->setTransform( &skypos );
if ( prev_sun_angle != sun_angle )
{
if ( sun_angle == 0 ) sun_angle = 0.1;
const double r_earth_pole = 6356752.314;
const double r_tropo_pole = 6356752.314 + 8000;
const double epsilon_earth2 = 6.694380066E-3;
const double epsilon_tropo2 = 9.170014946E-3;
double r_tropo = r_tropo_pole / sqrt ( 1 - ( epsilon_tropo2 * pow ( cos( 0.0 ), 2 )));
double r_earth = r_earth_pole / sqrt ( 1 - ( epsilon_earth2 * pow ( cos( 0.0 ), 2 )));
double position_radius = r_earth;
double gamma = SG_PI - sun_angle;
double sin_beta = ( position_radius * sin ( gamma ) ) / r_tropo;
double alpha = SG_PI - gamma - asin( sin_beta );
path_distance = sqrt( pow( position_radius, 2 ) + pow( r_tropo, 2 )
- ( 2 * position_radius * r_tropo * cos( alpha ) ));
double alt_half = sqrt( pow ( r_tropo, 2 ) + pow( path_distance / 2, 2 ) - r_tropo * path_distance * cos( asin( sin_beta )) ) - r_earth;
if ( alt_half < 0.0 ) alt_half = 0.0;
/*if ( env_node )
{
//env_node->setDoubleValue( "atmosphere/altitude-troposphere-top", r_tropo - r_earth );
//env_node->setDoubleValue( "atmosphere/altitude-half-to-sun", alt_half );
}*/
}
return true;
}

View file

@ -50,8 +50,6 @@ static const int NMaxStars = 1000;
static const int NMaxPlanets = 0; //No planets displayed for the moment
static const int NMaxCloudLayers = 3;
enum {eCBSun = 0, eCBMoon, NMaxCelestianBodies}; // Celestial bodies in the sky.
static const sgVec4 Black = { 0.0f, 0.0f, 0.0f, 1.0f } ;
static const sgVec4 White = { 1.0f, 1.0f, 1.0f, 1.0f } ;
static const sgVec4 TranslucentWhite = { 1.0f, 1.0f, 1.0f, 0.8f } ;
@ -96,8 +94,10 @@ static ssgBranch *SunAnchor = NULL;
static ssgRoot *TheBackground = NULL;
static ssgTransform *TheSun = NULL;
static cGrCelestialBody *TheCelestBodies[NMaxCelestianBodies] = { NULL, NULL };
//static cGrCelestialBody *TheCelestBodies[NMaxCelestianBodies] = { NULL, NULL };
static cGrSky *TheSky = NULL;
static cGrSun *Sun = NULL;
static cGrMoon *Moon = NULL;
static sgdVec3 *AStarsData = NULL;
static sgdVec3 *APlanetsData = NULL;
@ -218,17 +218,18 @@ grInitBackground()
//Build the sky
TheSky = new cGrSky;
TheSky->build(grSkyDomeDistance, grSkyDomeDistance, NPlanets, APlanetsData, NStars, AStarsData);
//Add the Sun itself
const double domeSizeRatio = grSkyDomeDistance / 80000.0;
TheCelestBodies[eCBSun] = TheSky->addBody(NULL, "data/textures/halo.rgba", "data/textures/outer_halo.rgba",
2500 * domeSizeRatio, grSkyDomeDistance, /*isSun=*/true);
TheSky->build(grSkyDomeDistance, grSkyDomeDistance, "data/textures/halo.rgba", "data/textures/halo.rgba", "data/textures/outer_halo.rgba",
2500 * domeSizeRatio, "data/textures/moon.rgba", 2000 * domeSizeRatio, NPlanets, APlanetsData, NStars, AStarsData, 0.5f, visibility);
//Add the Sun itself
GLfloat sunAscension = grTrack->local.sunascension;
grSunDeclination = (float)(15 * (double)timeOfDay / 3600 - 90.0);
TheCelestBodies[eCBSun]->setDeclination ( DEG2RAD(grSunDeclination));
TheCelestBodies[eCBSun]->setRightAscension ( sunAscension );
Sun->setDeclination ( DEG2RAD(grSunDeclination));
Sun->setRightAscension ( sunAscension );
GfLogInfo(" Sun : time of day = %02d:%02d:%02d (declination = %.1f deg), "
"ascension = %.1f deg\n",
@ -236,8 +237,6 @@ grInitBackground()
grSunDeclination, RAD2DEG(sunAscension));
// Add the Moon (TODO: Find a better solution than this random positioning !)
TheCelestBodies[eCBMoon] = TheSky->addBody ( "data/textures/moon.rgba",NULL, NULL,
2000 * domeSizeRatio, grSkyDomeDistance);
if ( grSunDeclination > 180 )
grMoonDeclination = 3.0 + (rand() % 40);
else
@ -245,8 +244,8 @@ grInitBackground()
const float moonAscension = (float)(rand() % 360);
TheCelestBodies[eCBMoon]->setDeclination ( DEG2RAD(grMoonDeclination) );
TheCelestBodies[eCBMoon]->setRightAscension ( DEG2RAD(moonAscension) );
Moon->setmoonDeclination ( DEG2RAD(grMoonDeclination) );
Moon->setmoonRightAscension ( DEG2RAD(moonAscension) );
GfLogInfo(" Moon : declination = %.1f deg, ascension = %.1f deg\n",
grMoonDeclination, moonAscension);
@ -335,7 +334,7 @@ grInitBackground()
// Set up the light source to the Sun position.
sgCoord sunPosition;
TheCelestBodies[eCBSun]->getPosition(&sunPosition);
Sun->getPosition(&sunPosition);
light->setPosition(sunPosition.xyz);
// Initialize the whole sky dome.
@ -378,7 +377,7 @@ grInitBackground()
const GLfloat fog_exp2_density = sqrt_m_log01 / visibility;
//Setup overall light level according to rain if any
const float sol_angle = (float)TheCelestBodies[eCBSun]->getAngle();
const float sol_angle = (float)Sun->getAngle();
const float sky_brightness = (float)(1.0 + cos(sol_angle)) / 2.0f;
float scene_brightness = (float)pow(sky_brightness, 0.5f);
@ -413,7 +412,7 @@ grInitBackground()
NPlanets, APlanetsData, NStars, AStarsData);
sgCoord solpos;
TheCelestBodies[eCBSun]->getPosition(&solpos);
Sun->getPosition(&solpos);
light->setPosition(solpos.xyz);
SceneAmbiant[0] = BaseAmbiant[0] * scene_brightness;
@ -1020,19 +1019,19 @@ grUpdateSky(double currentTime, double accelTime)
if (grSunDeclination >= 360.0f)
grSunDeclination -= 360.0f;
TheCelestBodies[eCBSun]->setDeclination ( DEG2RAD(grSunDeclination) );
Sun->setDeclination ( DEG2RAD(grSunDeclination) );
// 2) Update moon position
grMoonDeclination += deltaDecl;
if (grMoonDeclination >= 360.0f)
grMoonDeclination -= 360.0f;
TheCelestBodies[eCBMoon]->setDeclination ( DEG2RAD(grMoonDeclination) );
Moon->setmoonDeclination ( DEG2RAD(grMoonDeclination) );
lastTimeLowSpeed = nextTimeLowSpeed;
}
// 3) Update scene color and light
const float sol_angle = (float)TheCelestBodies[eCBSun]->getAngle();
const float sol_angle = (float)Sun->getAngle();
const float sky_brightness = (float)(1.0 + cos(sol_angle)) / 2.0f;
float scene_brightness = (float)pow(sky_brightness, 0.5f);
@ -1070,7 +1069,7 @@ grUpdateSky(double currentTime, double accelTime)
// 3c) update the main light position (it's at the sun position !)
sgCoord solpos;
TheCelestBodies[eCBSun]-> getPosition(&solpos);
Sun-> getPosition(&solpos);
ssgGetLight(0)-> setPosition(solpos.xyz);
// 3c) update scene colors.