From: curt Date: Sat, 7 Sep 2002 02:58:19 +0000 (+0000) Subject: Initial revision X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=6d79582890ff5b8d0c74a4a7372084493e0cc83e;p=simgear.git Initial revision --- diff --git a/TODO b/TODO new file mode 100644 index 00000000..af525dba --- /dev/null +++ b/TODO @@ -0,0 +1 @@ +03/25/2001 - Resolve location of Sky dome implimentation documentation. diff --git a/mksymlinks.sh b/mksymlinks.sh deleted file mode 100755 index 311f8a9f..00000000 --- a/mksymlinks.sh +++ /dev/null @@ -1,42 +0,0 @@ -#! /bin/sh - -echo "" -echo "running $0 to rebuild simgear include links" - -# toast the old directory -rm -rf src/simgear -mkdir src/simgear -mkdir src/simgear/bucket -mkdir src/simgear/debug -mkdir src/simgear/math -mkdir src/simgear/misc -mkdir src/simgear/screen -mkdir src/simgear/serial -mkdir src/simgear/xgl -mkdir src/simgear/zlib - -# build new links -ln -s ../include/compiler.h src/simgear/compiler.h -ln -s ../include/constants.h src/simgear/constants.h -ln -s ../include/fg_traits.hxx src/simgear/fg_traits.hxx -ln -s ../include/fg_zlib.h src/simgear/fg_zlib.h -ln -s ../include/version.h src/simgear/version.h - -ln -s ../../bucket/newbucket.hxx src/simgear/bucket/newbucket.hxx - -ln -s ../../debug/debug_types.h src/simgear/debug/debug_types.h -ln -s ../../debug/logstream.hxx src/simgear/debug/logstream.hxx - -ln -s ../../math/fg_memory.h src/simgear/math/fg_memory.h -ln -s ../../math/fg_types.hxx src/simgear/math/fg_types.hxx -ln -s ../../math/point3d.hxx src/simgear/math/point3d.hxx -ln -s ../../math/polar3d.hxx src/simgear/math/polar3d.hxx - -ln -s ../../misc/fgpath.hxx src/simgear/misc/fgpath.hxx -ln -s ../../misc/fgstream.hxx src/simgear/misc/fgstream.hxx -ln -s ../../misc/zfstream.hxx src/simgear/misc/zfstream.hxx - -ln -s ../../xgl/xgl.h src/simgear/xgl/xgl.h - -ln -s ../../zlib/zlib.h src/simgear/zlib/zlib.h -ln -s ../../zlib/zconf.h src/simgear/zlib/zconf.h diff --git a/simgear/scene/sky/.cvsignore b/simgear/scene/sky/.cvsignore new file mode 100644 index 00000000..e9955884 --- /dev/null +++ b/simgear/scene/sky/.cvsignore @@ -0,0 +1,3 @@ +.deps +Makefile +Makefile.in diff --git a/simgear/scene/sky/Makefile.am b/simgear/scene/sky/Makefile.am new file mode 100644 index 00000000..36695897 --- /dev/null +++ b/simgear/scene/sky/Makefile.am @@ -0,0 +1,23 @@ +includedir = @includedir@/sky + +lib_LIBRARIES = libsgsky.a + +include_HEADERS = \ + cloud.hxx \ + dome.hxx \ + moon.hxx \ + oursun.hxx \ + sky.hxx \ + sphere.hxx \ + stars.hxx + +libsgsky_a_SOURCES = \ + cloud.cxx \ + dome.cxx \ + moon.cxx \ + oursun.cxx \ + sky.cxx \ + sphere.cxx \ + stars.cxx + +INCLUDES = -I$(top_srcdir) diff --git a/simgear/scene/sky/cloud.cxx b/simgear/scene/sky/cloud.cxx new file mode 100644 index 00000000..687f8d64 --- /dev/null +++ b/simgear/scene/sky/cloud.cxx @@ -0,0 +1,372 @@ +// cloud.cxx -- model a single cloud layer +// +// Written by Curtis Olson, started June 2000. +// +// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org +// +// 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 + +#include +#include STL_IOSTREAM + +#include +#include + +#include +#include +#include +#include +#include + +#include "cloud.hxx" + +ssgSimpleState * +SGCloudLayer::layer_states[SGCloudLayer::SG_MAX_CLOUD_TYPES]; + + +// Constructor +SGCloudLayer::SGCloudLayer( const string &tex_path ) + : layer_root(new ssgRoot), + layer_transform(new ssgTransform), + layer(0), + texture_path(tex_path), + layer_span(0), + layer_asl(0), + layer_thickness(0), + layer_transition(0), + layer_type(SG_CLOUD_CLEAR) +{ + layer_root->addKid(layer_transform); + rebuild(); +} + +// Destructor +SGCloudLayer::~SGCloudLayer() +{ + delete layer_root; // deletes layer_transform and layer as well +} + +float +SGCloudLayer::getSpan_m () const +{ + return layer_span; +} + +void +SGCloudLayer::setSpan_m (float span_m) +{ + if (span_m != layer_span) { + layer_span = span_m; + rebuild(); + } +} + +float +SGCloudLayer::getElevation_m () const +{ + return layer_asl; +} + +void +SGCloudLayer::setElevation_m (float elevation_m) +{ + layer_asl = elevation_m; +} + +float +SGCloudLayer::getThickness_m () const +{ + return layer_thickness; +} + +void +SGCloudLayer::setThickness_m (float thickness_m) +{ + layer_thickness = thickness_m; +} + +float +SGCloudLayer::getTransition_m () const +{ + return layer_transition; +} + +void +SGCloudLayer::setTransition_m (float transition_m) +{ + layer_transition = transition_m; +} + +SGCloudLayer::Type +SGCloudLayer::getType () const +{ + return layer_type; +} + +void +SGCloudLayer::setType (Type type) +{ + if (type != layer_type) { + layer_type = type; + rebuild(); + } +} + + +// build the cloud object +void +SGCloudLayer::rebuild() +{ + // Initialize states and sizes if necessary. + if (layer_states[0] == 0) { + SGPath cloud_path; + + cloud_path.set(texture_path.str()); + cloud_path.append("overcast.rgb"); + layer_states[SG_CLOUD_OVERCAST] = SGCloudMakeState(cloud_path.str()); + + cloud_path.set(texture_path.str()); + cloud_path.append("mostlycloudy.rgba"); + layer_states[SG_CLOUD_MOSTLY_CLOUDY] = + SGCloudMakeState(cloud_path.str()); + + cloud_path.set(texture_path.str()); + cloud_path.append("mostlysunny.rgba"); + layer_states[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState(cloud_path.str()); + + cloud_path.set(texture_path.str()); + cloud_path.append("cirrus.rgba"); + layer_states[SG_CLOUD_CIRRUS] = SGCloudMakeState(cloud_path.str()); + + layer_states[SG_CLOUD_CLEAR] = 0; + } + + scale = 4000.0; + + last_lon = last_lat = -999.0f; + + cl = new ssgColourArray( 4 ); + vl = new ssgVertexArray( 4 ); + tl = new ssgTexCoordArray( 4 ); + + // build the cloud layer + sgVec4 color; + sgVec3 vertex; + sgVec2 tc; + sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f ); + + sgSetVec3( vertex, -layer_span, -layer_span, 0.0f ); + sgVec2 base; + sgSetVec2( base, sg_random(), sg_random() ); + sgSetVec2( tc, base[0], base[1] ); + cl->add( color ); + vl->add( vertex ); + tl->add( tc ); + + sgSetVec3( vertex, layer_span, -layer_span, 0.0f ); + sgSetVec2( tc, base[0] + layer_span / scale, base[1] ); + cl->add( color ); + vl->add( vertex ); + tl->add( tc ); + + sgSetVec3( vertex, -layer_span, layer_span, 0.0f ); + sgSetVec2( tc, base[0], base[1] + layer_span / scale ); + cl->add( color ); + vl->add( vertex ); + tl->add( tc ); + + sgSetVec3( vertex, layer_span, layer_span, 0.0f ); + sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale ); + cl->add( color ); + vl->add( vertex ); + tl->add( tc ); + + if (layer != 0) + layer_transform->removeKid(layer); // automatic delete + layer = new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl ); + if (layer_states[layer_type] != 0) + layer->setState( layer_states[layer_type] ); + + // force a repaint of the moon colors with arbitrary defaults + repaint( color ); + + // moon_transform->addKid( halo ); + layer_transform->addKid( layer ); +} + + +// repaint the cloud layer colors +bool SGCloudLayer::repaint( sgVec3 fog_color ) { + float *color; + + for ( int i = 0; i < 4; ++i ) { + color = cl->get( i ); + sgCopyVec4( color, fog_color ); + } + + return true; +} + + +// reposition the cloud layer at the specified origin and orientation +// lon specifies a rotation about the Z axis +// lat specifies a rotation about the new Y axis +// spin specifies a rotation about the new Z axis (and orients the +// sunrise/set effects +bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat, + double alt ) +{ + sgMat4 T1, LON, LAT; + sgVec3 axis; + + // combine p and asl (meters) to get translation offset + sgVec3 asl_offset; + sgCopyVec3( asl_offset, up ); + sgNormalizeVec3( asl_offset ); + if ( alt <= layer_asl ) { + sgScaleVec3( asl_offset, layer_asl ); + } else { + sgScaleVec3( asl_offset, layer_asl + layer_thickness ); + } + // cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1] + // << "," << asl_offset[2] << endl; + sgAddVec3( asl_offset, p ); + // cout << " asl_offset = " << asl_offset[0] << "," << asl_offset[1] + // << "," << asl_offset[2] << endl; + + // Translate to zero elevation + // Point3D zero_elev = current_view.get_cur_zero_elev(); + // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() ); + sgMakeTransMat4( T1, asl_offset ); + + // printf(" Translated to %.2f %.2f %.2f\n", + // zero_elev.x, zero_elev.y, zero_elev.z ); + + // Rotate to proper orientation + // printf(" lon = %.2f lat = %.2f\n", + // lon * SGD_RADIANS_TO_DEGREES, + // lat * SGD_RADIANS_TO_DEGREES); + // xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis ); + + // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES, + // 0.0, 1.0, 0.0 ); + sgSetVec3( axis, 0.0, 1.0, 0.0 ); + sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis ); + + sgMat4 TRANSFORM; + + sgCopyMat4( TRANSFORM, T1 ); + sgPreMultMat4( TRANSFORM, LON ); + sgPreMultMat4( TRANSFORM, LAT ); + + sgCoord layerpos; + sgSetCoord( &layerpos, TRANSFORM ); + + layer_transform->setTransform( &layerpos ); + + // now calculate update texture coordinates + if ( last_lon < -900 ) { + last_lon = lon; + last_lat = lat; + } + + if ( lon != last_lon || lat != last_lat ) { + Point3D start( last_lon, last_lat, 0.0 ); + Point3D dest( lon, lat, 0.0 ); + double course, dist; + calc_gc_course_dist( dest, start, &course, &dist ); + // cout << "course = " << course << ", dist = " << dist << endl; + + double xoff = cos( course ) * dist / (2 * scale); + double yoff = sin( course ) * dist / (2 * scale); + + // cout << "xoff = " << xoff << ", yoff = " << yoff << endl; + + float *base, *tc; + base = tl->get( 0 ); + + base[0] += xoff; + + // the while loops can lead to *long* pauses if base[0] comes + // with a bogus value. + // while ( base[0] > 1.0 ) { base[0] -= 1.0; } + // while ( base[0] < 0.0 ) { base[0] += 1.0; } + if ( base[0] > -10.0 && base[0] < 10.0 ) { + base[0] -= (int)base[0]; + } else { + base[0] = 0.0; + SG_LOG(SG_ASTRO, SG_DEBUG, + "Error: base = " << base[0] << "," << base[1]); + } + + base[1] += yoff; + // the while loops can lead to *long* pauses if base[0] comes + // with a bogus value. + // while ( base[1] > 1.0 ) { base[1] -= 1.0; } + // while ( base[1] < 0.0 ) { base[1] += 1.0; } + if ( base[1] > -10.0 && base[1] < 10.0 ) { + base[1] -= (int)base[1]; + } else { + base[1] = 0.0; + SG_LOG(SG_ASTRO, SG_ALERT, + "Error: base = " << base[0] << "," << base[1]); + } + + // cout << "base = " << base[0] << "," << base[1] << endl; + + tc = tl->get( 1 ); + sgSetVec2( tc, base[0] + layer_span / scale, base[1] ); + + tc = tl->get( 2 ); + sgSetVec2( tc, base[0], base[1] + layer_span / scale ); + + tc = tl->get( 3 ); + sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale ); + + last_lon = lon; + last_lat = lat; + } + + return true; +} + + +void SGCloudLayer::draw() { + if (layer_type != SG_CLOUD_CLEAR) + ssgCullAndDraw( layer_root ); +} + + +// make an ssgSimpleState for a cloud layer given the named texture +ssgSimpleState *SGCloudMakeState( const string &path ) { + ssgSimpleState *state = new ssgSimpleState(); + + state->setTexture( (char *)path.c_str() ); + state->setShadeModel( GL_SMOOTH ); + state->disable( GL_LIGHTING ); + state->disable( GL_CULL_FACE ); + state->enable( GL_TEXTURE_2D ); + state->enable( GL_COLOR_MATERIAL ); + state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + state->enable( GL_BLEND ); + state->enable( GL_ALPHA_TEST ); + state->setAlphaClamp( 0.01 ); + + return state; +} diff --git a/simgear/scene/sky/cloud.hxx b/simgear/scene/sky/cloud.hxx new file mode 100644 index 00000000..36746d88 --- /dev/null +++ b/simgear/scene/sky/cloud.hxx @@ -0,0 +1,128 @@ +// cloud.hxx -- model a single cloud layer +// +// Written by Curtis Olson, started June 2000. +// +// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SG_CLOUD_HXX_ +#define _SG_CLOUD_HXX_ + +#include + +#include + +#include STL_STRING +SG_USING_STD(string); + + +class SGCloudLayer { + +public: + + enum Type { + SG_CLOUD_OVERCAST = 0, + SG_CLOUD_MOSTLY_CLOUDY, + SG_CLOUD_MOSTLY_SUNNY, + SG_CLOUD_CIRRUS, + SG_CLOUD_CLEAR, + SG_MAX_CLOUD_TYPES + }; + + // Constructors + SGCloudLayer( const string &tex_path ); + + // Destructor + ~SGCloudLayer( void ); + + float getSpan_m () const; + void setSpan_m (float span_m); + + float getElevation_m () const; + void setElevation_m (float elevation_m); + + float getThickness_m () const; + void setThickness_m (float thickness_m); + + float getTransition_m () const; + void setTransition_m (float transition_m); + + Type getType () const; + void setType (Type type); + + // build the cloud object + void rebuild(); + + // repaint the cloud colors based on current value of sun_angle, + // sky, and fog colors. This updates the color arrays for + // ssgVtxTable. + // sun angle in degrees relative to verticle + // 0 degrees = high noon + // 90 degrees = sun rise/set + // 180 degrees = darkest midnight + bool repaint( sgVec3 fog_color ); + + // reposition the cloud layer at the specified origin and + // orientation + // lon specifies a rotation about the Z axis + // lat specifies a rotation about the new Y axis + // spin specifies a rotation about the new Z axis (and orients the + // sunrise/set effects + bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt ); + + // draw the cloud layer + void draw(); + +private: + + static ssgSimpleState *layer_states[SG_MAX_CLOUD_TYPES]; + static int layer_sizes[SG_MAX_CLOUD_TYPES]; + + ssgRoot *layer_root; + ssgTransform *layer_transform; + ssgLeaf * layer; + + ssgColourArray *cl; + ssgVertexArray *vl; + ssgTexCoordArray *tl; + + // height above sea level (meters) + SGPath texture_path; + float layer_span; + float layer_asl; + float layer_thickness; + float layer_transition; + Type layer_type; + float scale; + + // for handling texture coordinates to simulate cloud movement + // from winds, and to simulate the clouds being tied to ground + // position, not view position + // double xoff, yoff; + double last_lon, last_lat; + +}; + + +// make an ssgSimpleState for a cloud layer given the named texture +ssgSimpleState *SGCloudMakeState( const string &path ); + + +#endif // _SG_CLOUD_HXX_ diff --git a/simgear/scene/sky/dome.cxx b/simgear/scene/sky/dome.cxx new file mode 100644 index 00000000..f7e2ddc8 --- /dev/null +++ b/simgear/scene/sky/dome.cxx @@ -0,0 +1,546 @@ +// dome.cxx -- model sky with an upside down "bowl" +// +// Written by Curtis Olson, started December 1997. +// SSG-ified by Curtis Olson, February 2000. +// +// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include + +#include +#include + +#include + +#include + +#include "dome.hxx" + + +#ifdef __MWERKS__ +# pragma global_optimizer off +#endif + + +// in meters of course +static const float center_elev = 0.3125; + +static const float upper_radius = 0.6250; +static const float upper_elev = 0.2500; + +static const float middle_radius = 0.8750; +static const float middle_elev = 0.1000; + +static const float lower_radius = 0.8750; +static const float lower_elev = 0.0000; + +static const float bottom_radius = 0.6250; +static const float bottom_elev = -0.0250; + + +// Set up dome rendering callbacks +static int sgSkyDomePreDraw( ssgEntity *e ) { + /* cout << endl << "Dome Pre Draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); + // cout << "push error = " << glGetError() << endl; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + + return true; +} + +static int sgSkyDomePostDraw( ssgEntity *e ) { + /* cout << endl << "Dome Post Draw" << endl << "----------------" + << endl << endl; */ + + glPopAttrib(); + // cout << "pop error = " << glGetError() << endl; + + return true; +} + + +// Constructor +SGSkyDome::SGSkyDome( void ) { +} + + +// Destructor +SGSkyDome::~SGSkyDome( void ) { +} + + +// initialize the sky object and connect it into our scene graph +ssgBranch * SGSkyDome::build( double hscale, double vscale ) { + sgVec4 color; + + float theta; + int i; + + // set up the state + dome_state = new ssgSimpleState(); + dome_state->setShadeModel( GL_SMOOTH ); + dome_state->disable( GL_LIGHTING ); + dome_state->disable( GL_CULL_FACE ); + dome_state->disable( GL_TEXTURE_2D ); + dome_state->enable( GL_COLOR_MATERIAL ); + dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + dome_state->disable( GL_BLEND ); + dome_state->disable( GL_ALPHA_TEST ); + + // initialize arrays + center_disk_vl = new ssgVertexArray( 14 ); + center_disk_cl = new ssgColourArray( 14 ); + + upper_ring_vl = new ssgVertexArray( 26 ); + upper_ring_cl = new ssgColourArray( 26 ); + + middle_ring_vl = new ssgVertexArray( 26 ); + middle_ring_cl = new ssgColourArray( 26 ); + + lower_ring_vl = new ssgVertexArray( 26 ); + lower_ring_cl = new ssgColourArray( 26 ); + + // initially seed to all blue + sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 ); + + // generate the raw vertex data + sgVec3 center_vertex; + sgVec3 upper_vertex[12]; + sgVec3 middle_vertex[12]; + sgVec3 lower_vertex[12]; + sgVec3 bottom_vertex[12]; + + sgSetVec3( center_vertex, 0.0, 0.0, center_elev * vscale ); + + for ( i = 0; i < 12; i++ ) { + theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS; + + sgSetVec3( upper_vertex[i], + cos(theta) * upper_radius * hscale, + sin(theta) * upper_radius * hscale, + upper_elev * vscale ); + + sgSetVec3( middle_vertex[i], + cos((double)theta) * middle_radius * hscale, + sin((double)theta) * middle_radius * hscale, + middle_elev * vscale ); + + sgSetVec3( lower_vertex[i], + cos((double)theta) * lower_radius * hscale, + sin((double)theta) * lower_radius * hscale, + lower_elev * vscale ); + + sgSetVec3( bottom_vertex[i], + cos((double)theta) * bottom_radius * hscale, + sin((double)theta) * bottom_radius * hscale, + bottom_elev * vscale ); + } + + // generate the center disk vertex/color arrays + center_disk_vl->add( center_vertex ); + center_disk_cl->add( color ); + for ( i = 11; i >= 0; i-- ) { + center_disk_vl->add( upper_vertex[i] ); + center_disk_cl->add( color ); + } + center_disk_vl->add( upper_vertex[11] ); + center_disk_cl->add( color ); + + // generate the upper ring + for ( i = 0; i < 12; i++ ) { + upper_ring_vl->add( middle_vertex[i] ); + upper_ring_cl->add( color ); + + upper_ring_vl->add( upper_vertex[i] ); + upper_ring_cl->add( color ); + } + upper_ring_vl->add( middle_vertex[0] ); + upper_ring_cl->add( color ); + + upper_ring_vl->add( upper_vertex[0] ); + upper_ring_cl->add( color ); + + // generate middle ring + for ( i = 0; i < 12; i++ ) { + middle_ring_vl->add( lower_vertex[i] ); + middle_ring_cl->add( color ); + + middle_ring_vl->add( middle_vertex[i] ); + middle_ring_cl->add( color ); + } + middle_ring_vl->add( lower_vertex[0] ); + middle_ring_cl->add( color ); + + middle_ring_vl->add( middle_vertex[0] ); + middle_ring_cl->add( color ); + + // generate lower ring + for ( i = 0; i < 12; i++ ) { + lower_ring_vl->add( bottom_vertex[i] ); + lower_ring_cl->add( color ); + + lower_ring_vl->add( lower_vertex[i] ); + lower_ring_cl->add( color ); + } + lower_ring_vl->add( bottom_vertex[0] ); + lower_ring_cl->add( color ); + + lower_ring_vl->add( lower_vertex[0] ); + lower_ring_cl->add( color ); + + // force a repaint of the sky colors with ugly defaults + sgVec4 fog_color; + sgSetVec4( fog_color, 1.0, 1.0, 1.0, 1.0 ); + repaint( color, fog_color, 0.0, 5000.0 ); + + // build the ssg scene graph sub tree for the sky and connected + // into the provide scene graph branch + ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring; + + center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, + center_disk_vl, NULL, NULL, center_disk_cl ); + + upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, + upper_ring_vl, NULL, NULL, upper_ring_cl ); + + middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, + middle_ring_vl, NULL, NULL, middle_ring_cl ); + + lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, + lower_ring_vl, NULL, NULL, lower_ring_cl ); + + center_disk->setState( dome_state ); + upper_ring->setState( dome_state ); + middle_ring->setState( dome_state ); + lower_ring->setState( dome_state ); + + dome_transform = new ssgTransform; + dome_transform->addKid( center_disk ); + dome_transform->addKid( upper_ring ); + dome_transform->addKid( middle_ring ); + dome_transform->addKid( lower_ring ); + + // not entirely satisfying. We are depending here that the first + // thing we add to a parent is the first drawn + center_disk->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); + center_disk->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); + + upper_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); + upper_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); + + middle_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); + middle_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); + + lower_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); + lower_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); + + return dome_transform; +} + + +// repaint the sky colors based on current value of sun_angle, sky, +// and fog colors. This updates the color arrays for ssgVtxTable. +// sun angle in degrees relative to verticle +// 0 degrees = high noon +// 90 degrees = sun rise/set +// 180 degrees = darkest midnight +bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, + double vis ) +{ + double diff; + sgVec3 outer_param, outer_amt, outer_diff; + sgVec3 middle_param, middle_amt, middle_diff; + int i, j; + + // Check for sunrise/sunset condition + if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) { + // 0.0 - 0.4 + sgSetVec3( outer_param, + (10.0 - fabs(90.0 - sun_angle)) / 20.0, + (10.0 - fabs(90.0 - sun_angle)) / 40.0, + -(10.0 - fabs(90.0 - sun_angle)) / 30.0 ); + + sgSetVec3( middle_param, + (10.0 - fabs(90.0 - sun_angle)) / 40.0, + (10.0 - fabs(90.0 - sun_angle)) / 80.0, + 0.0 ); + + sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 ); + + sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 ); + } else { + sgSetVec3( outer_param, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_param, 0.0, 0.0, 0.0 ); + + sgSetVec3( outer_diff, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_diff, 0.0, 0.0, 0.0 ); + } + // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n", + // outer_red_param, outer_red_diff); + + // calculate transition colors between sky and fog + sgCopyVec3( outer_amt, outer_param ); + sgCopyVec3( middle_amt, middle_param ); + + // + // First, recalulate the basic colors + // + + sgVec4 center_color; + sgVec4 upper_color[12]; + sgVec4 middle_color[12]; + sgVec4 lower_color[12]; + sgVec4 bottom_color[12]; + + double vis_factor; + + if ( vis < 3000.0 ) { + vis_factor = (vis - 1000.0) / 2000.0; + if ( vis_factor < 0.0 ) { + vis_factor = 0.0; + } + } else { + vis_factor = 1.0; + } + + for ( j = 0; j < 3; j++ ) { + diff = sky_color[j] - fog_color[j]; + center_color[j] = sky_color[j] - diff * ( 1.0 - vis_factor ); + } + center_color[3] = 1.0; + + for ( i = 0; i < 6; i++ ) { + for ( j = 0; j < 3; j++ ) { + diff = sky_color[j] - fog_color[j]; + + // printf("sky = %.2f fog = %.2f diff = %.2f\n", + // l->sky_color[j], l->fog_color[j], diff); + + upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7); + middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1) + + middle_amt[j]; + lower_color[i][j] = fog_color[j] + outer_amt[j]; + + if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } + if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } + if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } + if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } + if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } + if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } + } + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; + + for ( j = 0; j < 3; j++ ) { + outer_amt[j] -= outer_diff[j]; + middle_amt[j] -= middle_diff[j]; + } + + /* + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); + printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, + middle_color[i][0], middle_color[i][1], middle_color[i][2], + middle_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); + */ + } + + sgSetVec3( outer_amt, 0.0, 0.0, 0.0 ); + sgSetVec3( middle_amt, 0.0, 0.0, 0.0 ); + + for ( i = 6; i < 12; i++ ) { + for ( j = 0; j < 3; j++ ) { + diff = sky_color[j] - fog_color[j]; + + // printf("sky = %.2f fog = %.2f diff = %.2f\n", + // sky_color[j], fog_color[j], diff); + + upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7); + middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1) + + middle_amt[j]; + lower_color[i][j] = fog_color[j] + outer_amt[j]; + + if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } + if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } + if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } + if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } + if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } + if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } + } + upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; + + for ( j = 0; j < 3; j++ ) { + outer_amt[j] += outer_diff[j]; + middle_amt[j] += middle_diff[j]; + } + + /* + printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], + upper_color[i][1], upper_color[i][2], upper_color[i][3]); + printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, + middle_color[i][0], middle_color[i][1], middle_color[i][2], + middle_color[i][3]); + printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, + lower_color[i][0], lower_color[i][1], lower_color[i][2], + lower_color[i][3]); + */ + } + + for ( i = 0; i < 12; i++ ) { + sgCopyVec4( bottom_color[i], fog_color ); + } + + // + // Second, assign the basic colors to the object color arrays + // + + float *slot; + int counter; + + // update the center disk color arrays + counter = 0; + slot = center_disk_cl->get( counter++ ); + // sgVec4 red; + // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 ); + sgCopyVec4( slot, center_color ); + for ( i = 11; i >= 0; i-- ) { + slot = center_disk_cl->get( counter++ ); + sgCopyVec4( slot, upper_color[i] ); + } + slot = center_disk_cl->get( counter++ ); + sgCopyVec4( slot, upper_color[11] ); + + // generate the upper ring + counter = 0; + for ( i = 0; i < 12; i++ ) { + slot = upper_ring_cl->get( counter++ ); + sgCopyVec4( slot, middle_color[i] ); + + slot = upper_ring_cl->get( counter++ ); + sgCopyVec4( slot, upper_color[i] ); + } + slot = upper_ring_cl->get( counter++ ); + sgCopyVec4( slot, middle_color[0] ); + + slot = upper_ring_cl->get( counter++ ); + sgCopyVec4( slot, upper_color[0] ); + + // generate middle ring + counter = 0; + for ( i = 0; i < 12; i++ ) { + slot = middle_ring_cl->get( counter++ ); + sgCopyVec4( slot, lower_color[i] ); + + slot = middle_ring_cl->get( counter++ ); + sgCopyVec4( slot, middle_color[i] ); + } + slot = middle_ring_cl->get( counter++ ); + sgCopyVec4( slot, lower_color[0] ); + + slot = middle_ring_cl->get( counter++ ); + sgCopyVec4( slot, middle_color[0] ); + + // generate lower ring + counter = 0; + for ( i = 0; i < 12; i++ ) { + slot = lower_ring_cl->get( counter++ ); + sgCopyVec4( slot, bottom_color[i] ); + + slot = lower_ring_cl->get( counter++ ); + sgCopyVec4( slot, lower_color[i] ); + } + slot = lower_ring_cl->get( counter++ ); + sgCopyVec4( slot, bottom_color[0] ); + + slot = lower_ring_cl->get( counter++ ); + sgCopyVec4( slot, lower_color[0] ); + + return true; +} + + +// reposition the sky at the specified origin and orientation +// lon specifies a rotation about the Z axis +// lat specifies a rotation about the new Y axis +// spin specifies a rotation about the new Z axis (and orients the +// sunrise/set effects +bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) { + sgMat4 T, LON, LAT, SPIN; + sgVec3 axis; + + // Translate to view position + // Point3D zero_elev = current_view.get_cur_zero_elev(); + // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() ); + sgMakeTransMat4( T, p ); + + // printf(" Translated to %.2f %.2f %.2f\n", + // zero_elev.x, zero_elev.y, zero_elev.z ); + + // Rotate to proper orientation + // printf(" lon = %.2f lat = %.2f\n", + // lon * SGD_RADIANS_TO_DEGREES, + // lat * SGD_RADIANS_TO_DEGREES); + // xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis ); + + // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES, + // 0.0, 1.0, 0.0 ); + sgSetVec3( axis, 0.0, 1.0, 0.0 ); + sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis ); + + // xglRotatef( l->sun_rotation * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( SPIN, spin * SGD_RADIANS_TO_DEGREES, axis ); + + sgMat4 TRANSFORM; + + sgCopyMat4( TRANSFORM, T ); + sgPreMultMat4( TRANSFORM, LON ); + sgPreMultMat4( TRANSFORM, LAT ); + sgPreMultMat4( TRANSFORM, SPIN ); + + sgCoord skypos; + sgSetCoord( &skypos, TRANSFORM ); + + dome_transform->setTransform( &skypos ); + + return true; +} diff --git a/simgear/scene/sky/dome.hxx b/simgear/scene/sky/dome.hxx new file mode 100644 index 00000000..cb81a543 --- /dev/null +++ b/simgear/scene/sky/dome.hxx @@ -0,0 +1,85 @@ +// dome.hxx -- model sky with an upside down "bowl" +// +// Written by Curtis Olson, started December 1997. +// SSG-ified by Curtis Olson, February 2000. +// +// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SKYDOME_HXX +#define _SKYDOME_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + + +#include // plib include + + +class SGSkyDome { + ssgTransform *dome_transform; + ssgSimpleState *dome_state; + + ssgVertexArray *center_disk_vl; + ssgColourArray *center_disk_cl; + + ssgVertexArray *upper_ring_vl; + ssgColourArray *upper_ring_cl; + + ssgVertexArray *middle_ring_vl; + ssgColourArray *middle_ring_cl; + + ssgVertexArray *lower_ring_vl; + ssgColourArray *lower_ring_cl; + +public: + + // Constructor + SGSkyDome( void ); + + // Destructor + ~SGSkyDome( void ); + + // initialize the sky object and connect it into our scene graph + // root + ssgBranch *build( double hscale = 80000.0, double vscale = 80000.0 ); + + // repaint the sky colors based on current value of sun_angle, + // sky, and fog colors. This updates the color arrays for + // ssgVtxTable. + // sun angle in degrees relative to verticle + // 0 degrees = high noon + // 90 degrees = sun rise/set + // 180 degrees = darkest midnight + bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle, + double vis ); + + // reposition the sky at the specified origin and orientation + // lon specifies a rotation about the Z axis + // lat specifies a rotation about the new Y axis + // spin specifies a rotation about the new Z axis (and orients the + // sunrise/set effects + bool reposition( sgVec3 p, double lon, double lat, double spin ); +}; + + +#endif // _SKYDOME_HXX diff --git a/simgear/scene/sky/moon.cxx b/simgear/scene/sky/moon.cxx new file mode 100644 index 00000000..f5c81b3b --- /dev/null +++ b/simgear/scene/sky/moon.cxx @@ -0,0 +1,314 @@ +// moon.hxx -- model earth's moon +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#include + +#include +#include STL_IOSTREAM + +#include +#include + +#include + +#include "sphere.hxx" +#include "moon.hxx" + + +// Set up moon rendering call backs +static int sgMoonOrbPreDraw( ssgEntity *e ) { + /* cout << endl << "Moon orb pre draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT ); + // cout << "push error = " << glGetError() << endl; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ; + + return true; +} + + +static int sgMoonOrbPostDraw( ssgEntity *e ) { + /* cout << endl << "Moon orb post draw" << endl << "----------------" + << endl << endl; */ + // glEnable( GL_DEPTH_TEST ); + // glEnable( GL_FOG ); + + // Some drivers don't properly reset glBendFunc with a + // glPopAttrib() so we reset it to the 'default' here. + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + glPopAttrib(); + // cout << "pop error = " << glGetError() << endl; + + /* test + glDisable( GL_LIGHTING ); + glDisable( GL_CULL_FACE ); + glEnable( GL_COLOR_MATERIAL ); + glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); + glEnable( GL_CULL_FACE ); + glEnable( GL_LIGHTING ); */ + + return true; +} + + +#if 0 +static int sgMoonHaloPreDraw( ssgEntity *e ) { + /* cout << endl << "Moon halo pre draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT); + // cout << "push error = " << glGetError() << endl; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + return true; +} + +static int sgMoonHaloPostDraw( ssgEntity *e ) { + /* cout << endl << "Moon halo post draw" << endl << "----------------" + << endl << endl; */ + // glEnable( GL_DEPTH_TEST ); + // glEnable( GL_FOG ); + // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + glPopAttrib(); + // cout << "pop error = " << glGetError() << endl; + + return true; +} +#endif + + +// Constructor +SGMoon::SGMoon( void ) { +} + + +// Destructor +SGMoon::~SGMoon( void ) { +} + + +// build the moon object +ssgBranch * SGMoon::build( SGPath path, double moon_size ) { + + // set up the orb state + path.append( "moon.rgba" ); + orb_state = new ssgSimpleState(); + orb_state->setTexture( (char *)path.c_str() ); + 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, 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 = ssgMakeSphere( orb_state, cl, moon_size, 15, 15, + sgMoonOrbPreDraw, sgMoonOrbPostDraw ); + + // force a repaint of the moon colors with arbitrary defaults + repaint( 0.0 ); + + // build the halo + // moon_texbuf = new GLubyte[64*64*3]; + // moon_texid = makeHalo( moon_texbuf, 64 ); + // my_glWritePPMFile("moonhalo.ppm", moon_texbuf, 64, 64, RGB); + +#if 0 + // set up the halo state + halo_state = new ssgSimpleState(); + halo_state->setTexture( "halo.rgb" ); + // halo_state->setTexture( moon_texid ); + halo_state->enable( GL_TEXTURE_2D ); + halo_state->disable( GL_LIGHTING ); + halo_state->setShadeModel( GL_SMOOTH ); + halo_state->disable( GL_CULL_FACE ); + + halo_state->disable( GL_COLOR_MATERIAL ); + halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + halo_state->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ; + halo_state->setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ; + halo_state->setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ; + // halo_state -> setShininess ( 0 ) ; + halo_state->enable( GL_ALPHA_TEST ); + halo_state->setAlphaClamp(0.01); + halo_state->enable ( GL_BLEND ) ; + + + // Build ssg structure + double size = moon_size * 10.0; + sgVec3 v3; + halo_vl = new ssgVertexArray; + sgSetVec3( v3, -size, 0.0, -size ); + halo_vl->add( v3 ); + sgSetVec3( v3, size, 0.0, -size ); + halo_vl->add( v3 ); + sgSetVec3( v3, -size, 0.0, size ); + halo_vl->add( v3 ); + sgSetVec3( v3, size, 0.0, size ); + halo_vl->add( v3 ); + + sgVec2 v2; + halo_tl = new ssgTexCoordArray; + sgSetVec2( v2, 0.0f, 0.0f ); + halo_tl->add( v2 ); + sgSetVec2( v2, 1.0, 0.0 ); + halo_tl->add( v2 ); + sgSetVec2( v2, 0.0, 1.0 ); + halo_tl->add( v2 ); + sgSetVec2( v2, 1.0, 1.0 ); + halo_tl->add( v2 ); + + ssgLeaf *halo = + new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl ); + halo->setState( halo_state ); +#endif + + // build the ssg scene graph sub tree for the sky and connected + // into the provide scene graph branch + moon_transform = new ssgTransform; + + // moon_transform->addKid( halo ); + moon_transform->addKid( orb ); + + return moon_transform; +} + + +// repaint the moon colors based on current value of moon_angle in +// degrees relative to verticle +// 0 degrees = high noon +// 90 degrees = moon rise/set +// 180 degrees = darkest midnight +bool SGMoon::repaint( double moon_angle ) { + if ( moon_angle * SGD_RADIANS_TO_DEGREES < 100 ) { + // else moon is well below horizon (so no point in repainting it) + + // x_10 = moon_angle^10 + double x_10 = moon_angle * moon_angle * moon_angle * moon_angle + * moon_angle * moon_angle * moon_angle * moon_angle * moon_angle + * moon_angle; + + float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0)); + if (ambient < 0.3) { ambient = 0.3; } + if (ambient > 1.0) { ambient = 1.0; } + + sgVec4 color; + sgSetVec4( color, + (ambient * 6.0) - 1.0, // minimum value = 0.8 + (ambient * 11.0) - 3.0, // minimum value = 0.3 + (ambient * 12.0) - 3.6, // minimum value = 0.0 + 0.5 ); + + // temp test, forces the color to always be white + // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + + if (color[0] > 1.0) color[0] = 1.0; + if (color[1] > 1.0) color[1] = 1.0; + if (color[2] > 1.0) color[2] = 1.0; + + // cout << "color = " << color[0] << " " << color[1] << " " + // << color[2] << endl; + + float *ptr; + ptr = cl->get( 0 ); + sgCopyVec4( ptr, color ); + } + + return true; +} + + +// reposition the moon 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 SGMoon::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, angle, axis ); + + // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), + // 0.0, 0.0, 1.0); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); + + // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); + sgSetVec3( axis, 1.0, 0.0, 0.0 ); + sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis ); + + // xglTranslatef(0,moon_dist); + 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; +} + diff --git a/simgear/scene/sky/moon.hxx b/simgear/scene/sky/moon.hxx new file mode 100644 index 00000000..7fc8f808 --- /dev/null +++ b/simgear/scene/sky/moon.hxx @@ -0,0 +1,77 @@ +// moon.hxx -- model earth's moon +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SG_MOON_HXX_ +#define _SG_MOON_HXX_ + + +#include + +#include + + +class SGMoon { + + ssgTransform *moon_transform; + ssgSimpleState *orb_state; + ssgSimpleState *halo_state; + + ssgColourArray *cl; + + ssgVertexArray *halo_vl; + ssgTexCoordArray *halo_tl; + +public: + + // Constructor + SGMoon( void ); + + // Destructor + ~SGMoon( void ); + + // build the moon object + ssgBranch *build( SGPath 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 ); + + // reposition the moon 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 moon_dist ); +}; + + +#endif // _SG_MOON_HXX_ diff --git a/simgear/scene/sky/oursun.cxx b/simgear/scene/sky/oursun.cxx new file mode 100644 index 00000000..3ffd6538 --- /dev/null +++ b/simgear/scene/sky/oursun.cxx @@ -0,0 +1,415 @@ +// oursun.hxx -- model earth's sun +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#include + +#include +#include STL_IOSTREAM + +#include +#include + +// define the following to enable a cheesy lens flare effect for the sun +// #define FG_TEST_CHEESY_LENS_FLARE + +#ifdef FG_TEST_CHEESY_LENS_FLARE +# include +#endif + +#include "sphere.hxx" +#include "oursun.hxx" + + +// Set up sun rendering call backs +static int sgSunOrbPreDraw( ssgEntity *e ) { + /* cout << endl << "Sun orb pre draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); + // cout << "push error = " << glGetError() << endl; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + + return true; +} + +static int sgSunOrbPostDraw( ssgEntity *e ) { + /* cout << endl << "Sun orb post draw" << endl << "----------------" + << endl << endl; */ + + glPopAttrib(); + // cout << "pop error = " << glGetError() << endl; + + // glEnable( GL_DEPTH_TEST ); + // glEnable( GL_FOG ); + + return true; +} + +static int sgSunHaloPreDraw( ssgEntity *e ) { + /* cout << endl << "Sun halo pre draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); + // cout << "push error = " << glGetError() << endl; + + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + return true; +} + +static int sgSunHaloPostDraw( ssgEntity *e ) { + /* cout << endl << "Sun halo post draw" << endl << "----------------" + << endl << endl; */ + + glPopAttrib(); + // cout << "pop error = " << glGetError() << endl; + + // glEnable( GL_DEPTH_TEST ); + // glEnable( GL_FOG ); + + return true; +} + + +// Constructor +SGSun::SGSun( void ) { +} + + +// Destructor +SGSun::~SGSun( void ) { +} + + +#if 0 +// this might be nice to keep, just as an example of how to generate a +// texture on the fly ... +static GLuint makeHalo( GLubyte *sun_texbuf, int width ) { + int texSize; + GLuint texid; + GLubyte *p; + int i,j; + double radius; + + // create a texture id +#ifdef GL_VERSION_1_1 + glGenTextures(1, &texid); + glBindTexture(GL_TEXTURE_2D, texid); +#elif GL_EXT_texture_object + glGenTexturesEXT(1, &texid); + glBindTextureEXT(GL_TEXTURE_2D, texid); +#else +# error port me +#endif + + glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; + + // create the actual texture contents + texSize = width * width; + + if ( !sun_texbuf ) { + cout << "ouch ..." << endl; + exit(-1); // Ugly! + } + + p = sun_texbuf; + + radius = (double)(width / 2); + + GLubyte value; + double x, y, d; + for ( i = 0; i < width; i++ ) { + for ( j = 0; j < width; j++ ) { + x = fabs((double)(i - (width / 2))); + y = fabs((double)(j - (width / 2))); + d = sqrt((x * x) + (y * y)); + if (d < radius) { + // t is 1.0 at center, 0.0 at edge + double t = 1.0 - (d / radius); + + // inverse square looks nice + value = (int)((double) 0xff * (t*t)); + } else { + value = 0x00; + } + *p = value; + *(p+1) = value; + *(p+2) = value; + // *(p+3) = value; + + p += 3; + } + } + + /* glTexImage2D( GL_TEXTURE_2D, + 0, + GL_RGBA, + width, width, + 0, + GL_RGBA, GL_UNSIGNED_BYTE, + sun_texbuf ); */ + + return texid; +} + + +#define RGB 3 // 3 bytes of color info per pixel +#define RGBA 4 // 4 bytes of color+alpha info +void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode) +{ + int i, j, k, q; + unsigned char *ibuffer; + FILE *fp; + int pixelSize = mode==GL_RGBA?4:3; + + ibuffer = (unsigned char *) malloc(win_width*win_height*RGB); + + fp = fopen(filename, "wb"); + fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n", + win_width, win_height, UCHAR_MAX); + q = 0; + for (i = 0; i < win_height; i++) { + for (j = 0; j < win_width; j++) { + for (k = 0; k < RGB; k++) { + ibuffer[q++] = (unsigned char) + *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); + } + } + } + + // *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); + + fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp); + fclose(fp); + free(ibuffer); + + printf("wrote file (%d x %d pixels, %d bytes)\n", + win_width, win_height, RGB*win_width*win_height); +} +#endif + + +// initialize the sun object and connect it into our scene graph root +ssgBranch * SGSun::build( SGPath path, double sun_size ) { + + // set up the orb state + orb_state = new ssgSimpleState(); + orb_state->setShadeModel( GL_SMOOTH ); + orb_state->disable( GL_LIGHTING ); + // orb_state->enable( GL_LIGHTING ); + orb_state->disable( GL_CULL_FACE ); + orb_state->disable( GL_TEXTURE_2D ); + orb_state->enable( GL_COLOR_MATERIAL ); + orb_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + orb_state->disable( GL_BLEND ); + orb_state->disable( GL_ALPHA_TEST ); + + cl = new ssgColourArray( 1 ); + sgVec4 color; + sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + cl->add( color ); + + ssgBranch *orb = ssgMakeSphere( orb_state, cl, sun_size, 10, 10, + sgSunOrbPreDraw, sgSunOrbPostDraw ); + + // force a repaint of the sun colors with arbitrary defaults + repaint( 0.0 ); + + // build the halo + // sun_texbuf = new GLubyte[64*64*3]; + // sun_texid = makeHalo( sun_texbuf, 64 ); + // my_glWritePPMFile("sunhalo.ppm", sun_texbuf, 64, 64, RGB); + + // set up the halo state + path.append( "halo.rgba" ); + halo_state = new ssgSimpleState(); + halo_state->setTexture( (char *)path.c_str() ); + halo_state->enable( GL_TEXTURE_2D ); + halo_state->disable( GL_LIGHTING ); + // halo_state->enable( GL_LIGHTING ); + halo_state->setShadeModel( GL_SMOOTH ); + halo_state->disable( GL_CULL_FACE ); + halo_state->enable( GL_COLOR_MATERIAL ); + halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + halo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + halo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + halo_state->enable( GL_ALPHA_TEST ); + halo_state->setAlphaClamp(0.01); + halo_state->enable ( GL_BLEND ) ; + + // Build ssg structure + double size = sun_size * 10.0; + sgVec3 v3; + halo_vl = new ssgVertexArray; + sgSetVec3( v3, -size, 0.0, -size ); + halo_vl->add( v3 ); + sgSetVec3( v3, size, 0.0, -size ); + halo_vl->add( v3 ); + sgSetVec3( v3, -size, 0.0, size ); + halo_vl->add( v3 ); + sgSetVec3( v3, size, 0.0, size ); + halo_vl->add( v3 ); + + sgVec2 v2; + halo_tl = new ssgTexCoordArray; + sgSetVec2( v2, 0.0f, 0.0f ); + halo_tl->add( v2 ); + sgSetVec2( v2, 1.0, 0.0 ); + halo_tl->add( v2 ); + sgSetVec2( v2, 0.0, 1.0 ); + halo_tl->add( v2 ); + sgSetVec2( v2, 1.0, 1.0 ); + halo_tl->add( v2 ); + + ssgLeaf *halo = + new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl ); + halo->setState( halo_state ); + + // build the ssg scene graph sub tree for the sky and connected + // into the provide scene graph branch + sun_transform = new ssgTransform; + + halo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw ); + halo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw ); + sun_transform->addKid( halo ); + sun_transform->addKid( orb ); + +#ifdef FG_TEST_CHEESY_LENS_FLARE + // cheesy lens flair + sun_transform->addKid( new ssgaLensFlare ); +#endif + + return sun_transform; +} + + +// repaint the sun colors based on current value of sun_angle in +// degrees relative to verticle +// 0 degrees = high noon +// 90 degrees = sun rise/set +// 180 degrees = darkest midnight +bool SGSun::repaint( double sun_angle ) { + if ( sun_angle * SGD_RADIANS_TO_DEGREES < 100 ) { + // else sun is well below horizon (so no point in repainting it) + + // x_10 = sun_angle^10 + double x_10 = sun_angle * sun_angle * sun_angle * sun_angle * sun_angle + * sun_angle * sun_angle * sun_angle * sun_angle * sun_angle; + + float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0)); + if (ambient < 0.3) { ambient = 0.3; } + if (ambient > 1.0) { ambient = 1.0; } + + sgVec4 color; + sgSetVec4( color, + (ambient * 6.0) - 1.0, // minimum value = 0.8 + (ambient * 11.0) - 3.0, // minimum value = 0.3 + (ambient * 12.0) - 3.6, // minimum value = 0.0 + 1.0 ); + + // temp test, forces the color to always be white + // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + + if (color[0] > 1.0) color[0] = 1.0; + if (color[1] > 1.0) color[1] = 1.0; + if (color[2] > 1.0) color[2] = 1.0; + + // cout << "color = " << color[0] << " " << color[1] << " " + // << color[2] << endl; + + float *ptr; + ptr = cl->get( 0 ); + sgCopyVec4( ptr, color ); + } + + return true; +} + + +// 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 SGSun::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, angle, axis ); + + // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), + // 0.0, 0.0, 1.0); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); + + // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); + sgSetVec3( axis, 1.0, 0.0, 0.0 ); + sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis ); + + // xglTranslatef(0,sun_dist); + 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 ); + + return true; +} diff --git a/simgear/scene/sky/oursun.hxx b/simgear/scene/sky/oursun.hxx new file mode 100644 index 00000000..2ee90040 --- /dev/null +++ b/simgear/scene/sky/oursun.hxx @@ -0,0 +1,80 @@ +// oursun.hxx -- model earth's sun +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SG_SUN_HXX_ +#define _SG_SUN_HXX_ + + +#include + +#include + + +class SGSun { + + ssgTransform *sun_transform; + ssgSimpleState *orb_state; + ssgSimpleState *halo_state; + + ssgColourArray *cl; + + ssgVertexArray *halo_vl; + ssgTexCoordArray *halo_tl; + + GLuint sun_texid; + GLubyte *sun_texbuf; + +public: + + // Constructor + SGSun( void ); + + // Destructor + ~SGSun( void ); + + // return the sun object + ssgBranch *build( SGPath 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 ); + + // 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 ); +}; + + +#endif // _SG_SUN_HXX_ diff --git a/simgear/scene/sky/sky.cxx b/simgear/scene/sky/sky.cxx new file mode 100644 index 00000000..5ce06fe2 --- /dev/null +++ b/simgear/scene/sky/sky.cxx @@ -0,0 +1,354 @@ +// sky.cxx -- ssg based sky model +// +// Written by Curtis Olson, started December 1997. +// SSG-ified by Curtis Olson, February 2000. +// +// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#include +#include + +#include + +#include "sky.hxx" + + +// Constructor +SGSky::SGSky( void ) { + 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; + // ramp_up = 4.0; + // ramp_down = 4.0; +} + + +// Destructor +SGSky::~SGSky( void ) +{ + for (unsigned int i = 0; i < cloud_layers.size(); i++) + delete cloud_layers[i]; +} + + +// initialize the sky and connect the components to the scene graph at +// the provided branch +void SGSky::build( double sun_size, double moon_size, + int nplanets, sgdVec3 *planet_data, + double planet_dist, + int nstars, sgdVec3 *star_data, double star_dist ) +{ + pre_root = new ssgRoot; + post_root = new ssgRoot; + + pre_selector = new ssgSelector; + post_selector = new ssgSelector; + + pre_transform = new ssgTransform; + post_transform = new ssgTransform; + + dome = new SGSkyDome; + pre_transform -> addKid( dome->build() ); + + planets = new SGStars; + pre_transform -> addKid( planets->build(nplanets, planet_data, + planet_dist) + ); + + stars = new SGStars; + pre_transform -> addKid( stars->build(nstars, star_data, star_dist) ); + + moon = new SGMoon; + pre_transform -> addKid( moon->build(tex_path, moon_size) ); + + oursun = new SGSun; + pre_transform -> addKid( oursun->build(tex_path, sun_size) ); + + pre_selector->addKid( pre_transform ); + pre_selector->clrTraversalMaskBits( SSGTRAV_HOT ); + + post_selector->addKid( post_transform ); + post_selector->clrTraversalMaskBits( SSGTRAV_HOT ); + + pre_root->addKid( pre_selector ); + post_root->addKid( post_selector ); +} + + +// repaint the sky components based on current value of sun_angle, +// sky, and fog colors. +// +// sun angle in degrees relative to verticle +// 0 degrees = high noon +// 90 degrees = sun rise/set +// 180 degrees = darkest midnight +bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color, + double sun_angle, double moon_angle, + int nplanets, sgdVec3 *planet_data, + int nstars, sgdVec3 *star_data ) +{ + if ( effective_visibility > 1000.0 ) { + enable(); + dome->repaint( sky_color, fog_color, sun_angle, effective_visibility ); + oursun->repaint( sun_angle ); + moon->repaint( moon_angle ); + planets->repaint( sun_angle, nplanets, planet_data ); + stars->repaint( sun_angle, nstars, star_data ); + + for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { + cloud_layers[i]->repaint( fog_color ); + } + } else { + // turn off sky + disable(); + } + + return true; +} + + +// reposition the sky at the specified origin and orientation +// +// lon specifies a rotation about the Z axis +// lat specifies a rotation about the new Y axis +// spin specifies a rotation about the new Z axis (this allows +// additional orientation for the sunrise/set effects and is used by +// the skydome and perhaps clouds. +bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, + double lon, double lat, double alt, double spin, + double gst, + double sun_ra, double sun_dec, double sun_dist, + double moon_ra, double moon_dec, double moon_dist ) +{ + double angle = gst * 15; // degrees + dome->reposition( zero_elev, lon, lat, spin ); + oursun->reposition( view_pos, angle, sun_ra, sun_dec, sun_dist ); + moon->reposition( view_pos, angle, moon_ra, moon_dec, moon_dist ); + planets->reposition( view_pos, angle ); + stars->reposition( view_pos, angle ); + + for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { + cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt ); + } + + return true; +} + + +// draw background portions of the sky ... do this before you draw the +// rest of your scene. +void SGSky::preDraw() { + ssgCullAndDraw( pre_root ); +} + + +// draw translucent clouds ... do this after you've drawn all the +// oapaque elements of your scene. +void SGSky::postDraw( float alt ) { + float slop = 5.0; // if we are closer than this to a cloud layer, + // don't draw clouds + + int in_cloud = -1; // cloud we are in + + int i; + + // check where we are relative to the cloud layers + for ( i = 0; i < (int)cloud_layers.size(); ++i ) { + float asl = cloud_layers[i]->getElevation_m(); + float thickness = cloud_layers[i]->getThickness_m(); + + if ( alt < asl - slop ) { + // below cloud layer + } else if ( alt < asl + thickness + slop ) { + // in cloud layer + + // bail now and don't draw any clouds + in_cloud = i; + } else { + // above cloud layer + } + } + + // determine rendering order + int pos = 0; + while ( pos < (int)cloud_layers.size() && + alt > cloud_layers[pos]->getElevation_m()) + { + ++pos; + } + + if ( pos == 0 ) { + // we are below all the cloud layers, draw top to bottom + for ( i = cloud_layers.size() - 1; i >= 0; --i ) { + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } + } + } else if ( pos >= (int)cloud_layers.size() ) { + // we are above all the cloud layers, draw bottom to top + for ( i = 0; i < (int)cloud_layers.size(); ++i ) { + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } + } + } else { + // we are between cloud layers, draw lower layers bottom to + // top and upper layers top to bottom + for ( i = 0; i < pos; ++i ) { + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } + } + for ( i = cloud_layers.size() - 1; i >= pos; --i ) { + if ( i != in_cloud ) { + cloud_layers[i]->draw(); + } + } + } +} + +void +SGSky::add_cloud_layer( SGCloudLayer * layer ) +{ + cloud_layers.push_back(layer); +} + +const SGCloudLayer * +SGSky::get_cloud_layer (int i) const +{ + return cloud_layers[i]; +} + +SGCloudLayer * +SGSky::get_cloud_layer (int i) +{ + return cloud_layers[i]; +} + +int +SGSky::get_cloud_layer_count () const +{ + return cloud_layers.size(); +} + +// modify the current visibility based on cloud layers, thickness, +// transition range, and simulated "puffs". +void SGSky::modify_vis( float alt, float time_factor ) { + float effvis = visibility; + + for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { + float asl = cloud_layers[i]->getElevation_m(); + float thickness = cloud_layers[i]->getThickness_m(); + float transition = cloud_layers[i]->getTransition_m(); + + double ratio = 1.0; + + if ( alt < asl - transition ) { + // below cloud layer + ratio = 1.0; + } else if ( alt < asl ) { + // in lower transition + ratio = (asl - alt) / transition; + } else if ( alt < asl + thickness ) { + // in cloud layer + ratio = 0.0; + } else if ( alt < asl + thickness + transition ) { + // in upper transition + ratio = (alt - (asl + thickness)) / transition; + } else { + // above cloud layer + ratio = 1.0; + } + + // accumulate effects from multiple cloud layers + effvis *= ratio; + + if ( ratio < 1.0 ) { + if ( ! in_puff ) { + // calc chance of entering cloud puff + double rnd = sg_random(); + double chance = rnd * rnd * rnd; + if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) { + in_puff = true; + puff_length = sg_random() * 2.0; // up to 2 seconds + puff_progression = 0.0; + } + } + + if ( in_puff ) { + // modify actual_visibility based on puff envelope + + if ( puff_progression <= ramp_up ) { + double x = 0.5 * SGD_PI * puff_progression / ramp_up; + double factor = 1.0 - sin( x ); + // cout << "ramp up = " << puff_progression + // << " factor = " << factor << endl; + effvis = effvis * factor; + } else if ( puff_progression >= ramp_up + puff_length ) { + double x = 0.5 * SGD_PI * + (puff_progression - (ramp_up + puff_length)) / + ramp_down; + double factor = sin( x ); + // cout << "ramp down = " + // << puff_progression - (ramp_up + puff_length) + // << " factor = " << factor << endl; + effvis = effvis * factor; + } else { + effvis = 0.0; + } + + /* cout << "len = " << puff_length + << " x = " << x + << " factor = " << factor + << " actual_visibility = " << actual_visibility + << endl; */ + + // time_factor = ( global_multi_loop * + // current_options.get_speed_up() ) / + // (double)current_options.get_model_hz(); + + puff_progression += time_factor; + // cout << "time factor = " << time_factor << endl; + + /* cout << "gml = " << global_multi_loop + << " speed up = " << current_options.get_speed_up() + << " hz = " << current_options.get_model_hz() << endl; + */ + + if ( puff_progression > puff_length + ramp_up + ramp_down) { + in_puff = false; + } + } + + // never let visibility drop below 25 meters + if ( effvis <= 25.0 ) { + effvis = 25.0; + } + } + } // for + + effective_visibility = effvis; +} diff --git a/simgear/scene/sky/sky.hxx b/simgear/scene/sky/sky.hxx new file mode 100644 index 00000000..95b5ecba --- /dev/null +++ b/simgear/scene/sky/sky.hxx @@ -0,0 +1,403 @@ +/** + * \file sky.hxx + * Provides a class to model a realistic (time/date/position) based sky. + */ + +// Written by Curtis Olson, started December 1997. +// SSG-ified by Curtis Olson, February 2000. +// +// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SG_SKY_HXX +#define _SG_SKY_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + + +#include // plib include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +SG_USING_STD(vector); + + +typedef vector < SGCloudLayer* > layer_list_type; +typedef layer_list_type::iterator layer_list_iterator; +typedef layer_list_type::const_iterator layer_list_const_iterator; + +/** + * A class to model a realistic (time/date/position) based sky. + * + * Introduction + * + * The SGSky class models a blended sky dome, a haloed sun, a textured + * moon with phase that properly matches the date, stars and planets, + * and cloud layers. SGSky is designed to be dropped into existing + * plib based applications and depends heavily on plib's scene graph + * library, ssg. The sky implements various time of day lighting + * effects, it plays well with fog and visibility effects, and + * implements scudded cloud fly-through effects. Additionally, you can + * wire in the output of the SGEphemeris class to accurately position + * all the objects in the sky. + * + * Building the sky + * + + * Once you have created an instance of SGSky you must call the + * build() method. Building the sky requires several textures. So, + * you must specify the path/directory where these textures reside + * before building the sky. You do this first by calling the + * texture_path() method. + + * The arguments you pass to the build() method allow you to specify + * the size of your sun sphere and moon sphere, a number of planets, + * and a multitude of stars. For the planets and stars you pass in an + * array of right ascensions, declinations, magnitudes, and the + * distance from the view point. + + * Cloud Layers + + * Cloud layers can be added, changed, or removed individually. To add + * a cloud layer use the add_cloud_layer() method. The arguments + * allow you to specify base height above sea level, layer thickness, + * a transition zone for entering/leaving the cloud layer, the size of + * the cloud object, and the type of cloud texture. All distances are + * in meters. There are additional forms of this method that allow you + * to specify your own ssgSimpleState or texture name for drawing the + * cloud layer. + + * Repainting the Sky + + * As the sun circles the globe, you can call the repaint() method to + * recolor the sky objects to simulate sunrise and sunset effects, + * visibility, and other lighting changes. The arguments allow you to + * specify a base sky color (for the top of the dome), a fog color + * (for the horizon), the sun angle with the horizon (for + * sunrise/sunset effects), the moon angle (so we can make it more + * yellow at the horizon), and new star and planet data so that we can + * optionally change the magnitude of these (for day / night + * transitions.) + + * Positioning Sky Objects + + * As time progresses and as you move across the surface of the earth, + * the apparent position of the objects and the various lighting + * effects can change. the reposition() method allows you to specify + * the positions of all the sky objects as well as your view position. + * The arguments allow you to specify your view position in world + * Cartesian coordinates, the zero elevation position in world + * Cartesian coordinates (your longitude, your latitude, sea level), + * the ``up'' vector in world Cartesian coordinates, current + * longitude, latitude, and altitude. A ``spin'' angle can be + * specified for orienting the sky with the sun position so sunset and + * sunrise effects look correct. You must specify GMT side real time, + * the sun right ascension, sun declination, and sun distance from + * view point (to keep it inside your view volume.) You also must + * specify moon right ascension, moon declination, and moon distance + * from view point. + + * Rendering the Sky + + * The sky is designed to be rendered in two stages. The first stage + * renders the parts that form your back drop - the sky dome, the + * stars and planets, the sun, and the moon. These should be rendered + * before the rest of your scene by calling the preDraw() method. The + * second stage renders the clouds which are likely to be translucent + * (depending on type) and should be drawn after your scene has been + * rendered. Use the postDraw() method to draw the second stage of + * the sky. + + * A typical application might do the following: + + *
  • thesky->preDraw(); + *
  • ssgCullAndDraw ( myscene ) ; + *
  • thesky->postDraw( my_altitude ); + + * The current altitude in meters is passed to the postDraw() method + * so the clouds layers can be rendered correction from most distant + * to closest. + + * Visibility Effects + + * Visibility and fog is important for correctly rendering the + * sky. You can inform SGSky of the current visibility by calling the + * set_visibility() method. + + * When transitioning through clouds, it is nice to pull in the fog as + * you get close to the cloud layer to hide the fact that the clouds + * are drawn as a flat polygon. As you get nearer to the cloud layer + * it is also nice to temporarily pull in the visibility to simulate + * the effects of flying in and out of the puffy edge of the + * cloud. These effects can all be accomplished by calling the + * modify_vis() method. The arguments allow you to specify your + * current altitude (which is then compared to the altitudes of the + * various cloud layers.) You can also specify a time factor which + * should be the length in seconds since the last time you called + * modify_vis(). The time_factor value allows the puffy cloud effect + * to be calculated correctly. + + * The modify_vis() method alters the SGSky's internal idea of + * visibility, so you should subsequently call get_visibility() to get + * the actual modified visibility. You should then make the + * appropriate glFog() calls to setup fog properly for your scene. + + * Accessor Methods + + * Once an instance of SGSky has been successfully initialized, there + * are a couple accessor methods you can use such as get_num_layers() + * to return the number of cloud layers, get_cloud_layer(i) to return + * cloud layer number i, get_visibility() to return the actual + * visibility as modified by the sky/cloud model. + + */ + +class SGSky { + +private: + + // components of the sky + SGSkyDome *dome; + SGSun *oursun; + SGMoon *moon; + SGStars *planets; + SGStars *stars; + layer_list_type cloud_layers; + + ssgRoot *pre_root, *post_root; + + ssgSelector *pre_selector, *post_selector; + ssgTransform *pre_transform, *post_transform; + + SGPath tex_path; + + // visibility + float visibility; + float effective_visibility; + + // near cloud visibility state variables + bool in_puff; + double puff_length; // in seconds + double puff_progression; // in seconds + double ramp_up; // in seconds + double ramp_down; // in seconds + +public: + + /** Constructor */ + SGSky( void ); + + /** Destructor */ + ~SGSky( void ); + + /** + * Initialize the sky and connect the components to the scene + * graph at the provided branch. See discussion in detailed class + * description. + * @param sun_size size of sun + * @param moon_size size of moon + * @param nplanets number of planets + * @param planet_data an array of planet right ascensions, declinations, + * and magnitudes + * @param planet_dist distance from viewer to put the planets + * @param nstars number of stars + * @param star_data an array of star right ascensions, declinations, + * and magnitudes + * @param star_dist distance from viewer to put the stars */ + void build( double sun_size, double moon_size, + int nplanets, sgdVec3 *planet_data, double planet_dist, + int nstars, sgdVec3 *star_data, double star_dist ); + + /** + * Repaint the sky components based on current value of sun_angle, + * sky, and fog colors. You can also specify new star and planet + * data so that we can optionally change the magnitude of these + * (for day/night transitions.) See discussion in detailed + * class description. + * + * Sun and moon angles are specified in degrees relative to local up + *
  • 0 degrees = high noon + *
  • 90 degrees = sun rise/set + *
  • 180 degrees = darkest midnight + * @param sky_color the base sky color (for the top of the dome) + * @param fog_color the fog color (for the horizon) + * @param sun_angle the sun angle with the horizon (for sunrise/sunset + * effects) + * @param moon_angle the moon angle (so we can make it more yellow + * at the horizon) + * @param nplanets number of planets + * @param planet_data an array of planet right ascensions, declinations, + * and magnitudes + * @param nstars number of stars + * @param star_data an array of star right ascensions, declinations, + * and magnitudes + */ + bool repaint( sgVec4 sky_color, sgVec4 fog_color, + double sun_angle, double moon_angle, + int nplanets, sgdVec3 *planet_data, + int nstars, sgdVec3 *star_data ); + + /** + * Reposition the sky at the specified origin and orientation + * + * lon specifies a rotation about the Z axis + * lat specifies a rotation about the new Y axis + * spin specifies a rotation about the new Z axis (this allows + * additional orientation for the sunrise/set effects and is used + * by the skydome and perhaps clouds. See discussion in detailed + * class description. + * @param view_pos specify your view position in world Cartesian + * coordinates + * @param zero_elev the zero elevation position in world Cartesian + * coordinates + * @param view_up the up vector in world Cartesian coordinates + * @param lon current longitude + * @param lat current latitude + * @param alt current altitude + * @param spin an offset angle for orienting the sky effects with the + * sun position so sunset and sunrise effects look correct. + * @param gst GMT side real time + * @param sun_ra the sun's current right ascension + * @param sun_dec the sun's current declination + * @param sun_dist the sun's distance from the current view point + * (to keep it inside your view volume.) + * @param moon_ra the moon's current right ascension + * @param moon_dec the moon's current declination + * @param moon_dist the moon's distance from the current view point. + */ + bool reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, + double lon, double lat, double alt, double spin, + double gst, + double sun_ra, double sun_dec, double sun_dist, + double moon_ra, double moon_dec, double moon_dist ); + + /** + * Modify the given visibility based on cloud layers, thickness, + * transition range, and simulated "puffs". See discussion in detailed + * class description. + * @param alt current altitude + * @param time_factor amount of time since modify_vis() last called so + * we can scale effect rates properly despite variable frame rates. + */ + void modify_vis( float alt, float time_factor ); + + /** + * Draw background portions of the sky ... do this before you draw + * the rest of your scene. See discussion in detailed + * class description. + */ + void preDraw(); + + /** + * Draw translucent clouds ... do this after you've drawn all the + * oapaque elements of your scene. See discussion in detailed + * class description. + * @param alt current altitude + */ + void postDraw( float alt ); + + /** + * Specify the texture path (optional, defaults to current directory) + * @param path base path to texture locations + */ + inline void texture_path( const string& path ) { + tex_path = SGPath( path ); + } + + /** Enable drawing of the sky. */ + inline void enable() { + pre_selector->select( 1 ); + post_selector->select( 1 ); + } + + /** + * Disable drawing of the sky in the scene graph. The leaf node is still + * there, how ever it won't be traversed on by ssgCullandRender() + */ + inline void disable() { + pre_selector->select( 0 ); + post_selector->select( 0 ); + } + + /** + * Add a cloud layer. + * + * Transfer pointer ownership to this object. + * + * @param layer The new cloud layer to add. + */ + void add_cloud_layer (SGCloudLayer * layer); + + + /** + * Get a cloud layer (const). + * + * Pointer ownership remains with this object. + * + * @param i The index of the cloud layer, zero-based. + * @return A const pointer to the cloud layer. + */ + const SGCloudLayer * get_cloud_layer (int i) const; + + + /** + * Get a cloud layer (non-const). + * + * Pointer ownership remains with this object. + * + * @param i The index of the cloud layer, zero-based. + * @return A non-const pointer to the cloud layer. + */ + SGCloudLayer * get_cloud_layer (int i); + + + /** + * Return the number of cloud layers currently available. + * + * @return The cloud layer count. + */ + int get_cloud_layer_count () const; + + + /** @return current effective visibility */ + inline float get_visibility() const { return effective_visibility; } + + /** Set desired clear air visibility. + * @param v visibility in meters + */ + inline void set_visibility( float v ) { + effective_visibility = visibility = v; + } +}; + + +#endif // _SG_SKY_HXX diff --git a/simgear/scene/sky/sphere.cxx b/simgear/scene/sky/sphere.cxx new file mode 100644 index 00000000..428d966b --- /dev/null +++ b/simgear/scene/sky/sphere.cxx @@ -0,0 +1,134 @@ +// sphere.cxx -- build an ssg sphere object +// +// Pulled straight out of MesaGLU/quadratic.c +// +// Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and +// licensed under the GPL +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#include + +#include STL_IOSTREAM + +#include +#include + +#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS) +SG_USING_STD(cout); +SG_USING_STD(endl); +#endif + + +// return a sphere object as an ssgBranch +ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl, + double radius, int slices, int stacks, + ssgCallback predraw, ssgCallback postdraw ) +{ + float rho, drho, theta, dtheta; + float x, y, z; + float s, t, ds, dt; + int i, j, imin, imax; + float nsign = 1.0; + ssgBranch *sphere = new ssgBranch; + sgVec2 vec2; + sgVec3 vec3; + + drho = SGD_PI / (float) stacks; + dtheta = 2.0 * SGD_PI / (float) slices; + + /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y + axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along + longitudes) cannot use triangle fan on texturing (s coord. at + top/bottom tip varies) */ + + ds = 1.0 / slices; + dt = 1.0 / stacks; + t = 1.0; /* because loop now runs from 0 */ + imin = 0; + imax = stacks; + + /* build slices as quad strips */ + for ( i = imin; i < imax; i++ ) { + ssgVertexArray *vl = new ssgVertexArray(); + ssgNormalArray *nl = new ssgNormalArray(); + ssgTexCoordArray *tl = new ssgTexCoordArray(); + + rho = i * drho; + s = 0.0; + for ( j = 0; j <= slices; j++ ) { + theta = (j == slices) ? 0.0 : j * dtheta; + x = -sin(theta) * sin(rho); + y = cos(theta) * sin(rho); + z = nsign * cos(rho); + + // glNormal3f( x*nsign, y*nsign, z*nsign ); + sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); + sgNormalizeVec3( vec3 ); + nl->add( vec3 ); + + // glTexCoord2f(s,t); + sgSetVec2( vec2, s, t ); + tl->add( vec2 ); + + // glVertex3f( x*radius, y*radius, z*radius ); + sgSetVec3( vec3, x*radius, y*radius, z*radius ); + vl->add( vec3 ); + + x = -sin(theta) * sin(rho+drho); + y = cos(theta) * sin(rho+drho); + z = nsign * cos(rho+drho); + + // glNormal3f( x*nsign, y*nsign, z*nsign ); + sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); + sgNormalizeVec3( vec3 ); + nl->add( vec3 ); + + // glTexCoord2f(s,t-dt); + sgSetVec2( vec2, s, t-dt ); + tl->add( vec2 ); + s += ds; + + // glVertex3f( x*radius, y*radius, z*radius ); + sgSetVec3( vec3, x*radius, y*radius, z*radius ); + vl->add( vec3 ); + } + + ssgLeaf *slice = + new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl ); + + if ( vl->getNum() != nl->getNum() ) { + cout << "bad sphere1" << endl; + exit(-1); + } + if ( vl->getNum() != tl->getNum() ) { + cout << "bad sphere2" << endl; + exit(-1); + } + slice->setState( state ); + slice->setCallback( SSG_CALLBACK_PREDRAW, predraw ); + slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw ); + + sphere->addKid( slice ); + + t -= dt; + } + + return sphere; +} diff --git a/simgear/scene/sky/sphere.hxx b/simgear/scene/sky/sphere.hxx new file mode 100644 index 00000000..e7896e38 --- /dev/null +++ b/simgear/scene/sky/sphere.hxx @@ -0,0 +1,35 @@ +// sphere.hxx -- build an ssg sphere object +// +// Pulled straight out of MesaGLU/quadratic.c +// +// Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and +// licensed under the GPL +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#include + + +// return a sphere object as an ssgBranch (and connect in the +// specified ssgSimpleState +ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl, + double radius, int slices, int stacks, + ssgCallback predraw, ssgCallback postdraw ); + + diff --git a/simgear/scene/sky/stars.cxx b/simgear/scene/sky/stars.cxx new file mode 100644 index 00000000..0ca2efb4 --- /dev/null +++ b/simgear/scene/sky/stars.cxx @@ -0,0 +1,265 @@ +// stars.cxx -- model the stars +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#include + +#include +#include STL_IOSTREAM + +#include +#include + +#include "stars.hxx" + +#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS) +SG_USING_STD(cout); +SG_USING_STD(endl); +#endif + + +// Set up star rendering call backs +static int sgStarPreDraw( ssgEntity *e ) { + /* cout << endl << "Star pre draw" << endl << "----------------" + << endl << endl; */ + + ssgLeaf *f = (ssgLeaf *)e; + if ( f -> hasState () ) f->getState()->apply() ; + + glPushAttrib( 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 sgStarPostDraw( ssgEntity *e ) { + /* cout << endl << "Star post draw" << endl << "----------------" + << endl << endl; */ + + glPopAttrib(); + + // glEnable( GL_DEPTH_TEST ); + // glEnable( GL_FOG ); + + return true; +} + + +// Constructor +SGStars::SGStars( void ) : +old_phase(-1) +{ +} + + +// Destructor +SGStars::~SGStars( void ) { +} + + +// initialize the stars object and connect it into our scene graph root +ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) { + sgVec4 color; + + if ( star_data == NULL ) { + cout << "WARNING: null star data passed to SGStars::build()" << endl; + } + + // set up the orb state + state = new ssgSimpleState(); + state->disable( GL_LIGHTING ); + state->disable( GL_CULL_FACE ); + state->disable( GL_TEXTURE_2D ); + state->enable( GL_COLOR_MATERIAL ); + state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); + state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); + state->enable( GL_BLEND ); + state->disable( GL_ALPHA_TEST ); + + vl = new ssgVertexArray( num ); + cl = new ssgColourArray( num ); + // cl = new ssgColourArray( 1 ); + // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + // cl->add( color ); + + // Build ssg structure + sgVec3 p; + for ( int i = 0; i < num; ++i ) { + // position seeded to arbitrary values + sgSetVec3( p, + star_dist * cos( star_data[i][0] ) + * cos( star_data[i][1] ), + star_dist * sin( star_data[i][0] ) + * cos( star_data[i][1] ), + star_dist * sin( star_data[i][1] ) + ); + vl->add( p ); + + // color (magnitude) + sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); + cl->add( color ); + } + + ssgLeaf *stars_obj = + new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl ); + stars_obj->setState( state ); + stars_obj->setCallback( SSG_CALLBACK_PREDRAW, sgStarPreDraw ); + stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, sgStarPostDraw ); + + // build the ssg scene graph sub tree for the sky and connected + // into the provide scene graph branch + stars_transform = new ssgTransform; + + stars_transform->addKid( stars_obj ); + + cout << "stars = " << stars_transform << endl; + + return stars_transform; +} + + +// repaint the sun colors based on current value of sun_angle in +// degrees relative to verticle +// 0 degrees = high noon +// 90 degrees = sun rise/set +// 180 degrees = darkest midnight +bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) { + // cout << "repainting stars" << endl; + // double min = 100; + // double max = -100; + double mag, nmag, alpha, factor, cutoff; + float *color; + + int phase; + + // determine which star structure to draw + if ( sun_angle > (0.5 * SGD_PI + 10.0 * SGD_DEGREES_TO_RADIANS ) ) { + // deep night + factor = 1.0; + cutoff = 4.5; + phase = 0; + } else if ( sun_angle > (0.5 * SGD_PI + 8.8 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 1.0; + cutoff = 3.8; + phase = 1; + } else if ( sun_angle > (0.5 * SGD_PI + 7.5 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 0.95; + cutoff = 3.1; + phase = 2; + } else if ( sun_angle > (0.5 * SGD_PI + 7.0 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 0.9; + cutoff = 2.4; + phase = 3; + } else if ( sun_angle > (0.5 * SGD_PI + 6.5 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 0.85; + cutoff = 1.8; + phase = 4; + } else if ( sun_angle > (0.5 * SGD_PI + 6.0 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 0.8; + cutoff = 1.2; + phase = 5; + } else if ( sun_angle > (0.5 * SGD_PI + 5.5 * SGD_DEGREES_TO_RADIANS ) ) { + factor = 0.75; + cutoff = 0.6; + phase = 6; + } else { + // early dusk or late dawn + factor = 0.7; + cutoff = 0.0; + phase = 7; + } + + if( phase != old_phase ) { + // cout << " phase change, repainting stars, num = " << num << endl; + old_phase = phase; + for ( int i = 0; i < num; ++i ) { + // if ( star_data[i][2] < min ) { min = star_data[i][2]; } + // if ( star_data[i][2] > max ) { max = star_data[i][2]; } + + // magnitude ranges from -1 (bright) to 4 (dim). The + // range of star and planet magnitudes can actually go + // outside of this, but for our purpose, if it is brighter + // that -1, we'll color it full white/alpha anyway and 4 + // is a convenient cutoff point which keeps the number of + // stars drawn at about 500. + + // color (magnitude) + mag = star_data[i][2]; + if ( mag < cutoff ) { + nmag = ( 4.5 - mag ) / 5.5; // translate to 0 ... 1.0 scale + // alpha = nmag * 0.7 + 0.3; // translate to a 0.3 ... 1.0 scale + alpha = nmag * 0.85 + 0.15; // translate to a 0.15 ... 1.0 scale + alpha *= factor; // dim when the sun is brighter + } else { + alpha = 0.0; + } + + if (alpha > 1.0) { alpha = 1.0; } + if (alpha < 0.0) { alpha = 0.0; } + + color = cl->get( i ); + sgSetVec4( color, 1.0, 1.0, 1.0, alpha ); + // cout << "alpha[" << i << "] = " << alpha << endl; + } + } else { + // cout << " no phase change, skipping" << endl; + } + + // cout << "min = " << min << " max = " << max << " count = " << num + // << endl; + + return true; +} + + +// reposition the stars for the specified time (GST rotation), +// offset by our current position (p) so that it appears fixed at a +// great distance from the viewer. +bool SGStars::reposition( sgVec3 p, double angle ) +{ + sgMat4 T1, GST; + sgVec3 axis; + + sgMakeTransMat4( T1, p ); + + sgSetVec3( axis, 0.0, 0.0, -1.0 ); + sgMakeRotMat4( GST, angle, axis ); + + sgMat4 TRANSFORM; + sgCopyMat4( TRANSFORM, T1 ); + sgPreMultMat4( TRANSFORM, GST ); + + sgCoord skypos; + sgSetCoord( &skypos, TRANSFORM ); + + stars_transform->setTransform( &skypos ); + + return true; +} diff --git a/simgear/scene/sky/stars.hxx b/simgear/scene/sky/stars.hxx new file mode 100644 index 00000000..4260aad4 --- /dev/null +++ b/simgear/scene/sky/stars.hxx @@ -0,0 +1,72 @@ +// stars.hxx -- model the stars +// +// Written by Durk Talsma. Originally started October 1997, for distribution +// with the FlightGear project. Version 2 was written in August and +// September 1998. This code is based upon algorithms and data kindly +// provided by Mr. Paul Schlyter. (pausch@saaf.se). +// +// Separated out rendering pieces and converted to ssg by Curt Olson, +// March 2000 +// +// This library is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// This library 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 +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with this library; if not, write to the +// Free Software Foundation, Inc., 59 Temple Place - Suite 330, +// Boston, MA 02111-1307, USA. +// +// $Id$ + + +#ifndef _SG_STARS_HXX_ +#define _SG_STARS_HXX_ + + +#include + + +class SGStars { + + ssgTransform *stars_transform; + ssgSimpleState *state; + + ssgColourArray *cl; + ssgVertexArray *vl; + + int old_phase; // data for optimization + +public: + + // Constructor + SGStars( void ); + + // Destructor + ~SGStars( void ); + + // initialize the stars structure + ssgBranch *build( int num, sgdVec3 *star_data, double star_dist ); + + // repaint the planet magnitudes based on current value of + // sun_angle in degrees relative to verticle (so we can make them + // relatively dimmer during dawn and dusk + // 0 degrees = high noon + // 90 degrees = sun rise/set + // 180 degrees = darkest midnight + bool repaint( double sun_angle, int num, sgdVec3 *star_data ); + + // reposition the stars for the specified time (GST rotation), + // offset by our current position (p) so that it appears fixed at + // a great distance from the viewer. + bool reposition( sgVec3 p, double angle ); +}; + + +#endif // _SG_STARS_HXX_ diff --git a/simgear/screen/GLBitmaps.h b/simgear/screen/GLBitmaps.h old mode 100755 new mode 100644 diff --git a/simgear/screen/tr.cxx b/simgear/screen/tr.cxx index cba85767..393213b4 100644 --- a/simgear/screen/tr.cxx +++ b/simgear/screen/tr.cxx @@ -2,6 +2,9 @@ /* * $Log$ + * Revision 1.1 2002/09/07 02:58:19 curt + * Initial revision + * * Revision 1.3 2001/07/30 20:34:21 curt * Various MSVC fixes. * diff --git a/simgear/screen/tr.h b/simgear/screen/tr.h index e57b008d..5224786b 100644 --- a/simgear/screen/tr.h +++ b/simgear/screen/tr.h @@ -2,6 +2,9 @@ /* * $Log$ + * Revision 1.1 2002/09/07 02:58:19 curt + * Initial revision + * * Revision 1.1 2001/06/26 15:19:39 curt * Added tr.cxx / tr.h, Brian Paul's LGPL'd tiled rendering support libs for * rendering ultra high res "tiled" screen shots. diff --git a/simgear/sky/.cvsignore b/simgear/sky/.cvsignore deleted file mode 100644 index e9955884..00000000 --- a/simgear/sky/.cvsignore +++ /dev/null @@ -1,3 +0,0 @@ -.deps -Makefile -Makefile.in diff --git a/simgear/sky/Makefile.am b/simgear/sky/Makefile.am deleted file mode 100644 index 36695897..00000000 --- a/simgear/sky/Makefile.am +++ /dev/null @@ -1,23 +0,0 @@ -includedir = @includedir@/sky - -lib_LIBRARIES = libsgsky.a - -include_HEADERS = \ - cloud.hxx \ - dome.hxx \ - moon.hxx \ - oursun.hxx \ - sky.hxx \ - sphere.hxx \ - stars.hxx - -libsgsky_a_SOURCES = \ - cloud.cxx \ - dome.cxx \ - moon.cxx \ - oursun.cxx \ - sky.cxx \ - sphere.cxx \ - stars.cxx - -INCLUDES = -I$(top_srcdir) diff --git a/simgear/sky/cloud.cxx b/simgear/sky/cloud.cxx deleted file mode 100644 index 687f8d64..00000000 --- a/simgear/sky/cloud.cxx +++ /dev/null @@ -1,372 +0,0 @@ -// cloud.cxx -- model a single cloud layer -// -// Written by Curtis Olson, started June 2000. -// -// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org -// -// 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 - -#include -#include STL_IOSTREAM - -#include -#include - -#include -#include -#include -#include -#include - -#include "cloud.hxx" - -ssgSimpleState * -SGCloudLayer::layer_states[SGCloudLayer::SG_MAX_CLOUD_TYPES]; - - -// Constructor -SGCloudLayer::SGCloudLayer( const string &tex_path ) - : layer_root(new ssgRoot), - layer_transform(new ssgTransform), - layer(0), - texture_path(tex_path), - layer_span(0), - layer_asl(0), - layer_thickness(0), - layer_transition(0), - layer_type(SG_CLOUD_CLEAR) -{ - layer_root->addKid(layer_transform); - rebuild(); -} - -// Destructor -SGCloudLayer::~SGCloudLayer() -{ - delete layer_root; // deletes layer_transform and layer as well -} - -float -SGCloudLayer::getSpan_m () const -{ - return layer_span; -} - -void -SGCloudLayer::setSpan_m (float span_m) -{ - if (span_m != layer_span) { - layer_span = span_m; - rebuild(); - } -} - -float -SGCloudLayer::getElevation_m () const -{ - return layer_asl; -} - -void -SGCloudLayer::setElevation_m (float elevation_m) -{ - layer_asl = elevation_m; -} - -float -SGCloudLayer::getThickness_m () const -{ - return layer_thickness; -} - -void -SGCloudLayer::setThickness_m (float thickness_m) -{ - layer_thickness = thickness_m; -} - -float -SGCloudLayer::getTransition_m () const -{ - return layer_transition; -} - -void -SGCloudLayer::setTransition_m (float transition_m) -{ - layer_transition = transition_m; -} - -SGCloudLayer::Type -SGCloudLayer::getType () const -{ - return layer_type; -} - -void -SGCloudLayer::setType (Type type) -{ - if (type != layer_type) { - layer_type = type; - rebuild(); - } -} - - -// build the cloud object -void -SGCloudLayer::rebuild() -{ - // Initialize states and sizes if necessary. - if (layer_states[0] == 0) { - SGPath cloud_path; - - cloud_path.set(texture_path.str()); - cloud_path.append("overcast.rgb"); - layer_states[SG_CLOUD_OVERCAST] = SGCloudMakeState(cloud_path.str()); - - cloud_path.set(texture_path.str()); - cloud_path.append("mostlycloudy.rgba"); - layer_states[SG_CLOUD_MOSTLY_CLOUDY] = - SGCloudMakeState(cloud_path.str()); - - cloud_path.set(texture_path.str()); - cloud_path.append("mostlysunny.rgba"); - layer_states[SG_CLOUD_MOSTLY_SUNNY] = SGCloudMakeState(cloud_path.str()); - - cloud_path.set(texture_path.str()); - cloud_path.append("cirrus.rgba"); - layer_states[SG_CLOUD_CIRRUS] = SGCloudMakeState(cloud_path.str()); - - layer_states[SG_CLOUD_CLEAR] = 0; - } - - scale = 4000.0; - - last_lon = last_lat = -999.0f; - - cl = new ssgColourArray( 4 ); - vl = new ssgVertexArray( 4 ); - tl = new ssgTexCoordArray( 4 ); - - // build the cloud layer - sgVec4 color; - sgVec3 vertex; - sgVec2 tc; - sgSetVec4( color, 1.0f, 1.0f, 1.0f, 1.0f ); - - sgSetVec3( vertex, -layer_span, -layer_span, 0.0f ); - sgVec2 base; - sgSetVec2( base, sg_random(), sg_random() ); - sgSetVec2( tc, base[0], base[1] ); - cl->add( color ); - vl->add( vertex ); - tl->add( tc ); - - sgSetVec3( vertex, layer_span, -layer_span, 0.0f ); - sgSetVec2( tc, base[0] + layer_span / scale, base[1] ); - cl->add( color ); - vl->add( vertex ); - tl->add( tc ); - - sgSetVec3( vertex, -layer_span, layer_span, 0.0f ); - sgSetVec2( tc, base[0], base[1] + layer_span / scale ); - cl->add( color ); - vl->add( vertex ); - tl->add( tc ); - - sgSetVec3( vertex, layer_span, layer_span, 0.0f ); - sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale ); - cl->add( color ); - vl->add( vertex ); - tl->add( tc ); - - if (layer != 0) - layer_transform->removeKid(layer); // automatic delete - layer = new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, NULL, tl, cl ); - if (layer_states[layer_type] != 0) - layer->setState( layer_states[layer_type] ); - - // force a repaint of the moon colors with arbitrary defaults - repaint( color ); - - // moon_transform->addKid( halo ); - layer_transform->addKid( layer ); -} - - -// repaint the cloud layer colors -bool SGCloudLayer::repaint( sgVec3 fog_color ) { - float *color; - - for ( int i = 0; i < 4; ++i ) { - color = cl->get( i ); - sgCopyVec4( color, fog_color ); - } - - return true; -} - - -// reposition the cloud layer at the specified origin and orientation -// lon specifies a rotation about the Z axis -// lat specifies a rotation about the new Y axis -// spin specifies a rotation about the new Z axis (and orients the -// sunrise/set effects -bool SGCloudLayer::reposition( sgVec3 p, sgVec3 up, double lon, double lat, - double alt ) -{ - sgMat4 T1, LON, LAT; - sgVec3 axis; - - // combine p and asl (meters) to get translation offset - sgVec3 asl_offset; - sgCopyVec3( asl_offset, up ); - sgNormalizeVec3( asl_offset ); - if ( alt <= layer_asl ) { - sgScaleVec3( asl_offset, layer_asl ); - } else { - sgScaleVec3( asl_offset, layer_asl + layer_thickness ); - } - // cout << "asl_offset = " << asl_offset[0] << "," << asl_offset[1] - // << "," << asl_offset[2] << endl; - sgAddVec3( asl_offset, p ); - // cout << " asl_offset = " << asl_offset[0] << "," << asl_offset[1] - // << "," << asl_offset[2] << endl; - - // Translate to zero elevation - // Point3D zero_elev = current_view.get_cur_zero_elev(); - // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() ); - sgMakeTransMat4( T1, asl_offset ); - - // printf(" Translated to %.2f %.2f %.2f\n", - // zero_elev.x, zero_elev.y, zero_elev.z ); - - // Rotate to proper orientation - // printf(" lon = %.2f lat = %.2f\n", - // lon * SGD_RADIANS_TO_DEGREES, - // lat * SGD_RADIANS_TO_DEGREES); - // xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis ); - - // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES, - // 0.0, 1.0, 0.0 ); - sgSetVec3( axis, 0.0, 1.0, 0.0 ); - sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis ); - - sgMat4 TRANSFORM; - - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, LON ); - sgPreMultMat4( TRANSFORM, LAT ); - - sgCoord layerpos; - sgSetCoord( &layerpos, TRANSFORM ); - - layer_transform->setTransform( &layerpos ); - - // now calculate update texture coordinates - if ( last_lon < -900 ) { - last_lon = lon; - last_lat = lat; - } - - if ( lon != last_lon || lat != last_lat ) { - Point3D start( last_lon, last_lat, 0.0 ); - Point3D dest( lon, lat, 0.0 ); - double course, dist; - calc_gc_course_dist( dest, start, &course, &dist ); - // cout << "course = " << course << ", dist = " << dist << endl; - - double xoff = cos( course ) * dist / (2 * scale); - double yoff = sin( course ) * dist / (2 * scale); - - // cout << "xoff = " << xoff << ", yoff = " << yoff << endl; - - float *base, *tc; - base = tl->get( 0 ); - - base[0] += xoff; - - // the while loops can lead to *long* pauses if base[0] comes - // with a bogus value. - // while ( base[0] > 1.0 ) { base[0] -= 1.0; } - // while ( base[0] < 0.0 ) { base[0] += 1.0; } - if ( base[0] > -10.0 && base[0] < 10.0 ) { - base[0] -= (int)base[0]; - } else { - base[0] = 0.0; - SG_LOG(SG_ASTRO, SG_DEBUG, - "Error: base = " << base[0] << "," << base[1]); - } - - base[1] += yoff; - // the while loops can lead to *long* pauses if base[0] comes - // with a bogus value. - // while ( base[1] > 1.0 ) { base[1] -= 1.0; } - // while ( base[1] < 0.0 ) { base[1] += 1.0; } - if ( base[1] > -10.0 && base[1] < 10.0 ) { - base[1] -= (int)base[1]; - } else { - base[1] = 0.0; - SG_LOG(SG_ASTRO, SG_ALERT, - "Error: base = " << base[0] << "," << base[1]); - } - - // cout << "base = " << base[0] << "," << base[1] << endl; - - tc = tl->get( 1 ); - sgSetVec2( tc, base[0] + layer_span / scale, base[1] ); - - tc = tl->get( 2 ); - sgSetVec2( tc, base[0], base[1] + layer_span / scale ); - - tc = tl->get( 3 ); - sgSetVec2( tc, base[0] + layer_span / scale, base[1] + layer_span / scale ); - - last_lon = lon; - last_lat = lat; - } - - return true; -} - - -void SGCloudLayer::draw() { - if (layer_type != SG_CLOUD_CLEAR) - ssgCullAndDraw( layer_root ); -} - - -// make an ssgSimpleState for a cloud layer given the named texture -ssgSimpleState *SGCloudMakeState( const string &path ) { - ssgSimpleState *state = new ssgSimpleState(); - - state->setTexture( (char *)path.c_str() ); - state->setShadeModel( GL_SMOOTH ); - state->disable( GL_LIGHTING ); - state->disable( GL_CULL_FACE ); - state->enable( GL_TEXTURE_2D ); - state->enable( GL_COLOR_MATERIAL ); - state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - state->enable( GL_BLEND ); - state->enable( GL_ALPHA_TEST ); - state->setAlphaClamp( 0.01 ); - - return state; -} diff --git a/simgear/sky/cloud.hxx b/simgear/sky/cloud.hxx deleted file mode 100644 index 36746d88..00000000 --- a/simgear/sky/cloud.hxx +++ /dev/null @@ -1,128 +0,0 @@ -// cloud.hxx -- model a single cloud layer -// -// Written by Curtis Olson, started June 2000. -// -// Copyright (C) 2000 Curtis L. Olson - curt@flightgear.org -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SG_CLOUD_HXX_ -#define _SG_CLOUD_HXX_ - -#include - -#include - -#include STL_STRING -SG_USING_STD(string); - - -class SGCloudLayer { - -public: - - enum Type { - SG_CLOUD_OVERCAST = 0, - SG_CLOUD_MOSTLY_CLOUDY, - SG_CLOUD_MOSTLY_SUNNY, - SG_CLOUD_CIRRUS, - SG_CLOUD_CLEAR, - SG_MAX_CLOUD_TYPES - }; - - // Constructors - SGCloudLayer( const string &tex_path ); - - // Destructor - ~SGCloudLayer( void ); - - float getSpan_m () const; - void setSpan_m (float span_m); - - float getElevation_m () const; - void setElevation_m (float elevation_m); - - float getThickness_m () const; - void setThickness_m (float thickness_m); - - float getTransition_m () const; - void setTransition_m (float transition_m); - - Type getType () const; - void setType (Type type); - - // build the cloud object - void rebuild(); - - // repaint the cloud colors based on current value of sun_angle, - // sky, and fog colors. This updates the color arrays for - // ssgVtxTable. - // sun angle in degrees relative to verticle - // 0 degrees = high noon - // 90 degrees = sun rise/set - // 180 degrees = darkest midnight - bool repaint( sgVec3 fog_color ); - - // reposition the cloud layer at the specified origin and - // orientation - // lon specifies a rotation about the Z axis - // lat specifies a rotation about the new Y axis - // spin specifies a rotation about the new Z axis (and orients the - // sunrise/set effects - bool reposition( sgVec3 p, sgVec3 up, double lon, double lat, double alt ); - - // draw the cloud layer - void draw(); - -private: - - static ssgSimpleState *layer_states[SG_MAX_CLOUD_TYPES]; - static int layer_sizes[SG_MAX_CLOUD_TYPES]; - - ssgRoot *layer_root; - ssgTransform *layer_transform; - ssgLeaf * layer; - - ssgColourArray *cl; - ssgVertexArray *vl; - ssgTexCoordArray *tl; - - // height above sea level (meters) - SGPath texture_path; - float layer_span; - float layer_asl; - float layer_thickness; - float layer_transition; - Type layer_type; - float scale; - - // for handling texture coordinates to simulate cloud movement - // from winds, and to simulate the clouds being tied to ground - // position, not view position - // double xoff, yoff; - double last_lon, last_lat; - -}; - - -// make an ssgSimpleState for a cloud layer given the named texture -ssgSimpleState *SGCloudMakeState( const string &path ); - - -#endif // _SG_CLOUD_HXX_ diff --git a/simgear/sky/dome.cxx b/simgear/sky/dome.cxx deleted file mode 100644 index f7e2ddc8..00000000 --- a/simgear/sky/dome.cxx +++ /dev/null @@ -1,546 +0,0 @@ -// dome.cxx -- model sky with an upside down "bowl" -// -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_WINDOWS_H -# include -#endif - -#include - -#include -#include - -#include - -#include - -#include "dome.hxx" - - -#ifdef __MWERKS__ -# pragma global_optimizer off -#endif - - -// in meters of course -static const float center_elev = 0.3125; - -static const float upper_radius = 0.6250; -static const float upper_elev = 0.2500; - -static const float middle_radius = 0.8750; -static const float middle_elev = 0.1000; - -static const float lower_radius = 0.8750; -static const float lower_elev = 0.0000; - -static const float bottom_radius = 0.6250; -static const float bottom_elev = -0.0250; - - -// Set up dome rendering callbacks -static int sgSkyDomePreDraw( ssgEntity *e ) { - /* cout << endl << "Dome Pre Draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); - // cout << "push error = " << glGetError() << endl; - - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - - return true; -} - -static int sgSkyDomePostDraw( ssgEntity *e ) { - /* cout << endl << "Dome Post Draw" << endl << "----------------" - << endl << endl; */ - - glPopAttrib(); - // cout << "pop error = " << glGetError() << endl; - - return true; -} - - -// Constructor -SGSkyDome::SGSkyDome( void ) { -} - - -// Destructor -SGSkyDome::~SGSkyDome( void ) { -} - - -// initialize the sky object and connect it into our scene graph -ssgBranch * SGSkyDome::build( double hscale, double vscale ) { - sgVec4 color; - - float theta; - int i; - - // set up the state - dome_state = new ssgSimpleState(); - dome_state->setShadeModel( GL_SMOOTH ); - dome_state->disable( GL_LIGHTING ); - dome_state->disable( GL_CULL_FACE ); - dome_state->disable( GL_TEXTURE_2D ); - dome_state->enable( GL_COLOR_MATERIAL ); - dome_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - dome_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - dome_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - dome_state->disable( GL_BLEND ); - dome_state->disable( GL_ALPHA_TEST ); - - // initialize arrays - center_disk_vl = new ssgVertexArray( 14 ); - center_disk_cl = new ssgColourArray( 14 ); - - upper_ring_vl = new ssgVertexArray( 26 ); - upper_ring_cl = new ssgColourArray( 26 ); - - middle_ring_vl = new ssgVertexArray( 26 ); - middle_ring_cl = new ssgColourArray( 26 ); - - lower_ring_vl = new ssgVertexArray( 26 ); - lower_ring_cl = new ssgColourArray( 26 ); - - // initially seed to all blue - sgSetVec4( color, 0.0, 0.0, 1.0, 1.0 ); - - // generate the raw vertex data - sgVec3 center_vertex; - sgVec3 upper_vertex[12]; - sgVec3 middle_vertex[12]; - sgVec3 lower_vertex[12]; - sgVec3 bottom_vertex[12]; - - sgSetVec3( center_vertex, 0.0, 0.0, center_elev * vscale ); - - for ( i = 0; i < 12; i++ ) { - theta = (i * 30.0) * SGD_DEGREES_TO_RADIANS; - - sgSetVec3( upper_vertex[i], - cos(theta) * upper_radius * hscale, - sin(theta) * upper_radius * hscale, - upper_elev * vscale ); - - sgSetVec3( middle_vertex[i], - cos((double)theta) * middle_radius * hscale, - sin((double)theta) * middle_radius * hscale, - middle_elev * vscale ); - - sgSetVec3( lower_vertex[i], - cos((double)theta) * lower_radius * hscale, - sin((double)theta) * lower_radius * hscale, - lower_elev * vscale ); - - sgSetVec3( bottom_vertex[i], - cos((double)theta) * bottom_radius * hscale, - sin((double)theta) * bottom_radius * hscale, - bottom_elev * vscale ); - } - - // generate the center disk vertex/color arrays - center_disk_vl->add( center_vertex ); - center_disk_cl->add( color ); - for ( i = 11; i >= 0; i-- ) { - center_disk_vl->add( upper_vertex[i] ); - center_disk_cl->add( color ); - } - center_disk_vl->add( upper_vertex[11] ); - center_disk_cl->add( color ); - - // generate the upper ring - for ( i = 0; i < 12; i++ ) { - upper_ring_vl->add( middle_vertex[i] ); - upper_ring_cl->add( color ); - - upper_ring_vl->add( upper_vertex[i] ); - upper_ring_cl->add( color ); - } - upper_ring_vl->add( middle_vertex[0] ); - upper_ring_cl->add( color ); - - upper_ring_vl->add( upper_vertex[0] ); - upper_ring_cl->add( color ); - - // generate middle ring - for ( i = 0; i < 12; i++ ) { - middle_ring_vl->add( lower_vertex[i] ); - middle_ring_cl->add( color ); - - middle_ring_vl->add( middle_vertex[i] ); - middle_ring_cl->add( color ); - } - middle_ring_vl->add( lower_vertex[0] ); - middle_ring_cl->add( color ); - - middle_ring_vl->add( middle_vertex[0] ); - middle_ring_cl->add( color ); - - // generate lower ring - for ( i = 0; i < 12; i++ ) { - lower_ring_vl->add( bottom_vertex[i] ); - lower_ring_cl->add( color ); - - lower_ring_vl->add( lower_vertex[i] ); - lower_ring_cl->add( color ); - } - lower_ring_vl->add( bottom_vertex[0] ); - lower_ring_cl->add( color ); - - lower_ring_vl->add( lower_vertex[0] ); - lower_ring_cl->add( color ); - - // force a repaint of the sky colors with ugly defaults - sgVec4 fog_color; - sgSetVec4( fog_color, 1.0, 1.0, 1.0, 1.0 ); - repaint( color, fog_color, 0.0, 5000.0 ); - - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - ssgVtxTable *center_disk, *upper_ring, *middle_ring, *lower_ring; - - center_disk = new ssgVtxTable( GL_TRIANGLE_FAN, - center_disk_vl, NULL, NULL, center_disk_cl ); - - upper_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - upper_ring_vl, NULL, NULL, upper_ring_cl ); - - middle_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - middle_ring_vl, NULL, NULL, middle_ring_cl ); - - lower_ring = new ssgVtxTable( GL_TRIANGLE_STRIP, - lower_ring_vl, NULL, NULL, lower_ring_cl ); - - center_disk->setState( dome_state ); - upper_ring->setState( dome_state ); - middle_ring->setState( dome_state ); - lower_ring->setState( dome_state ); - - dome_transform = new ssgTransform; - dome_transform->addKid( center_disk ); - dome_transform->addKid( upper_ring ); - dome_transform->addKid( middle_ring ); - dome_transform->addKid( lower_ring ); - - // not entirely satisfying. We are depending here that the first - // thing we add to a parent is the first drawn - center_disk->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); - center_disk->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); - - upper_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); - upper_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); - - middle_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); - middle_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); - - lower_ring->setCallback( SSG_CALLBACK_PREDRAW, sgSkyDomePreDraw ); - lower_ring->setCallback( SSG_CALLBACK_POSTDRAW, sgSkyDomePostDraw ); - - return dome_transform; -} - - -// repaint the sky colors based on current value of sun_angle, sky, -// and fog colors. This updates the color arrays for ssgVtxTable. -// sun angle in degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = sun rise/set -// 180 degrees = darkest midnight -bool SGSkyDome::repaint( sgVec4 sky_color, sgVec4 fog_color, double sun_angle, - double vis ) -{ - double diff; - sgVec3 outer_param, outer_amt, outer_diff; - sgVec3 middle_param, middle_amt, middle_diff; - int i, j; - - // Check for sunrise/sunset condition - if ( (sun_angle > 80.0) && (sun_angle < 100.0) ) { - // 0.0 - 0.4 - sgSetVec3( outer_param, - (10.0 - fabs(90.0 - sun_angle)) / 20.0, - (10.0 - fabs(90.0 - sun_angle)) / 40.0, - -(10.0 - fabs(90.0 - sun_angle)) / 30.0 ); - - sgSetVec3( middle_param, - (10.0 - fabs(90.0 - sun_angle)) / 40.0, - (10.0 - fabs(90.0 - sun_angle)) / 80.0, - 0.0 ); - - sgScaleVec3( outer_diff, outer_param, 1.0 / 6.0 ); - - sgScaleVec3( middle_diff, middle_param, 1.0 / 6.0 ); - } else { - sgSetVec3( outer_param, 0.0, 0.0, 0.0 ); - sgSetVec3( middle_param, 0.0, 0.0, 0.0 ); - - sgSetVec3( outer_diff, 0.0, 0.0, 0.0 ); - sgSetVec3( middle_diff, 0.0, 0.0, 0.0 ); - } - // printf(" outer_red_param = %.2f outer_red_diff = %.2f\n", - // outer_red_param, outer_red_diff); - - // calculate transition colors between sky and fog - sgCopyVec3( outer_amt, outer_param ); - sgCopyVec3( middle_amt, middle_param ); - - // - // First, recalulate the basic colors - // - - sgVec4 center_color; - sgVec4 upper_color[12]; - sgVec4 middle_color[12]; - sgVec4 lower_color[12]; - sgVec4 bottom_color[12]; - - double vis_factor; - - if ( vis < 3000.0 ) { - vis_factor = (vis - 1000.0) / 2000.0; - if ( vis_factor < 0.0 ) { - vis_factor = 0.0; - } - } else { - vis_factor = 1.0; - } - - for ( j = 0; j < 3; j++ ) { - diff = sky_color[j] - fog_color[j]; - center_color[j] = sky_color[j] - diff * ( 1.0 - vis_factor ); - } - center_color[3] = 1.0; - - for ( i = 0; i < 6; i++ ) { - for ( j = 0; j < 3; j++ ) { - diff = sky_color[j] - fog_color[j]; - - // printf("sky = %.2f fog = %.2f diff = %.2f\n", - // l->sky_color[j], l->fog_color[j], diff); - - upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7); - middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1) - + middle_amt[j]; - lower_color[i][j] = fog_color[j] + outer_amt[j]; - - if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } - if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } - if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } - if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } - if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } - if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } - } - upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; - - for ( j = 0; j < 3; j++ ) { - outer_amt[j] -= outer_diff[j]; - middle_amt[j] -= middle_diff[j]; - } - - /* - printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], - upper_color[i][1], upper_color[i][2], upper_color[i][3]); - printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, - middle_color[i][0], middle_color[i][1], middle_color[i][2], - middle_color[i][3]); - printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, - lower_color[i][0], lower_color[i][1], lower_color[i][2], - lower_color[i][3]); - */ - } - - sgSetVec3( outer_amt, 0.0, 0.0, 0.0 ); - sgSetVec3( middle_amt, 0.0, 0.0, 0.0 ); - - for ( i = 6; i < 12; i++ ) { - for ( j = 0; j < 3; j++ ) { - diff = sky_color[j] - fog_color[j]; - - // printf("sky = %.2f fog = %.2f diff = %.2f\n", - // sky_color[j], fog_color[j], diff); - - upper_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.7); - middle_color[i][j] = sky_color[j] - diff * ( 1.0 - vis_factor * 0.1) - + middle_amt[j]; - lower_color[i][j] = fog_color[j] + outer_amt[j]; - - if ( upper_color[i][j] > 1.0 ) { upper_color[i][j] = 1.0; } - if ( upper_color[i][j] < 0.0 ) { upper_color[i][j] = 0.0; } - if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } - if ( middle_color[i][j] < 0.0 ) { middle_color[i][j] = 0.0; } - if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } - if ( lower_color[i][j] < 0.0 ) { lower_color[i][j] = 0.0; } - } - upper_color[i][3] = middle_color[i][3] = lower_color[i][3] = 1.0; - - for ( j = 0; j < 3; j++ ) { - outer_amt[j] += outer_diff[j]; - middle_amt[j] += middle_diff[j]; - } - - /* - printf("upper_color[%d] = %.2f %.2f %.2f %.2f\n", i, upper_color[i][0], - upper_color[i][1], upper_color[i][2], upper_color[i][3]); - printf("middle_color[%d] = %.2f %.2f %.2f %.2f\n", i, - middle_color[i][0], middle_color[i][1], middle_color[i][2], - middle_color[i][3]); - printf("lower_color[%d] = %.2f %.2f %.2f %.2f\n", i, - lower_color[i][0], lower_color[i][1], lower_color[i][2], - lower_color[i][3]); - */ - } - - for ( i = 0; i < 12; i++ ) { - sgCopyVec4( bottom_color[i], fog_color ); - } - - // - // Second, assign the basic colors to the object color arrays - // - - float *slot; - int counter; - - // update the center disk color arrays - counter = 0; - slot = center_disk_cl->get( counter++ ); - // sgVec4 red; - // sgSetVec4( red, 1.0, 0.0, 0.0, 1.0 ); - sgCopyVec4( slot, center_color ); - for ( i = 11; i >= 0; i-- ) { - slot = center_disk_cl->get( counter++ ); - sgCopyVec4( slot, upper_color[i] ); - } - slot = center_disk_cl->get( counter++ ); - sgCopyVec4( slot, upper_color[11] ); - - // generate the upper ring - counter = 0; - for ( i = 0; i < 12; i++ ) { - slot = upper_ring_cl->get( counter++ ); - sgCopyVec4( slot, middle_color[i] ); - - slot = upper_ring_cl->get( counter++ ); - sgCopyVec4( slot, upper_color[i] ); - } - slot = upper_ring_cl->get( counter++ ); - sgCopyVec4( slot, middle_color[0] ); - - slot = upper_ring_cl->get( counter++ ); - sgCopyVec4( slot, upper_color[0] ); - - // generate middle ring - counter = 0; - for ( i = 0; i < 12; i++ ) { - slot = middle_ring_cl->get( counter++ ); - sgCopyVec4( slot, lower_color[i] ); - - slot = middle_ring_cl->get( counter++ ); - sgCopyVec4( slot, middle_color[i] ); - } - slot = middle_ring_cl->get( counter++ ); - sgCopyVec4( slot, lower_color[0] ); - - slot = middle_ring_cl->get( counter++ ); - sgCopyVec4( slot, middle_color[0] ); - - // generate lower ring - counter = 0; - for ( i = 0; i < 12; i++ ) { - slot = lower_ring_cl->get( counter++ ); - sgCopyVec4( slot, bottom_color[i] ); - - slot = lower_ring_cl->get( counter++ ); - sgCopyVec4( slot, lower_color[i] ); - } - slot = lower_ring_cl->get( counter++ ); - sgCopyVec4( slot, bottom_color[0] ); - - slot = lower_ring_cl->get( counter++ ); - sgCopyVec4( slot, lower_color[0] ); - - return true; -} - - -// reposition the sky at the specified origin and orientation -// lon specifies a rotation about the Z axis -// lat specifies a rotation about the new Y axis -// spin specifies a rotation about the new Z axis (and orients the -// sunrise/set effects -bool SGSkyDome::reposition( sgVec3 p, double lon, double lat, double spin ) { - sgMat4 T, LON, LAT, SPIN; - sgVec3 axis; - - // Translate to view position - // Point3D zero_elev = current_view.get_cur_zero_elev(); - // xglTranslatef( zero_elev.x(), zero_elev.y(), zero_elev.z() ); - sgMakeTransMat4( T, p ); - - // printf(" Translated to %.2f %.2f %.2f\n", - // zero_elev.x, zero_elev.y, zero_elev.z ); - - // Rotate to proper orientation - // printf(" lon = %.2f lat = %.2f\n", - // lon * SGD_RADIANS_TO_DEGREES, - // lat * SGD_RADIANS_TO_DEGREES); - // xglRotatef( lon * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( LON, lon * SGD_RADIANS_TO_DEGREES, axis ); - - // xglRotatef( 90.0 - f->get_Latitude() * SGD_RADIANS_TO_DEGREES, - // 0.0, 1.0, 0.0 ); - sgSetVec3( axis, 0.0, 1.0, 0.0 ); - sgMakeRotMat4( LAT, 90.0 - lat * SGD_RADIANS_TO_DEGREES, axis ); - - // xglRotatef( l->sun_rotation * SGD_RADIANS_TO_DEGREES, 0.0, 0.0, 1.0 ); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( SPIN, spin * SGD_RADIANS_TO_DEGREES, axis ); - - sgMat4 TRANSFORM; - - sgCopyMat4( TRANSFORM, T ); - sgPreMultMat4( TRANSFORM, LON ); - sgPreMultMat4( TRANSFORM, LAT ); - sgPreMultMat4( TRANSFORM, SPIN ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); - - dome_transform->setTransform( &skypos ); - - return true; -} diff --git a/simgear/sky/dome.hxx b/simgear/sky/dome.hxx deleted file mode 100644 index cb81a543..00000000 --- a/simgear/sky/dome.hxx +++ /dev/null @@ -1,85 +0,0 @@ -// dome.hxx -- model sky with an upside down "bowl" -// -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SKYDOME_HXX -#define _SKYDOME_HXX - - -#ifndef __cplusplus -# error This library requires C++ -#endif - - -#include // plib include - - -class SGSkyDome { - ssgTransform *dome_transform; - ssgSimpleState *dome_state; - - ssgVertexArray *center_disk_vl; - ssgColourArray *center_disk_cl; - - ssgVertexArray *upper_ring_vl; - ssgColourArray *upper_ring_cl; - - ssgVertexArray *middle_ring_vl; - ssgColourArray *middle_ring_cl; - - ssgVertexArray *lower_ring_vl; - ssgColourArray *lower_ring_cl; - -public: - - // Constructor - SGSkyDome( void ); - - // Destructor - ~SGSkyDome( void ); - - // initialize the sky object and connect it into our scene graph - // root - ssgBranch *build( double hscale = 80000.0, double vscale = 80000.0 ); - - // repaint the sky colors based on current value of sun_angle, - // sky, and fog colors. This updates the color arrays for - // ssgVtxTable. - // sun angle in degrees relative to verticle - // 0 degrees = high noon - // 90 degrees = sun rise/set - // 180 degrees = darkest midnight - bool repaint( sgVec3 sky_color, sgVec3 fog_color, double sun_angle, - double vis ); - - // reposition the sky at the specified origin and orientation - // lon specifies a rotation about the Z axis - // lat specifies a rotation about the new Y axis - // spin specifies a rotation about the new Z axis (and orients the - // sunrise/set effects - bool reposition( sgVec3 p, double lon, double lat, double spin ); -}; - - -#endif // _SKYDOME_HXX diff --git a/simgear/sky/moon.cxx b/simgear/sky/moon.cxx deleted file mode 100644 index f5c81b3b..00000000 --- a/simgear/sky/moon.cxx +++ /dev/null @@ -1,314 +0,0 @@ -// moon.hxx -- model earth's moon -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#include - -#include -#include STL_IOSTREAM - -#include -#include - -#include - -#include "sphere.hxx" -#include "moon.hxx" - - -// Set up moon rendering call backs -static int sgMoonOrbPreDraw( ssgEntity *e ) { - /* cout << endl << "Moon orb pre draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_COLOR_BUFFER_BIT | GL_ENABLE_BIT ); - // cout << "push error = " << glGetError() << endl; - - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ; - - return true; -} - - -static int sgMoonOrbPostDraw( ssgEntity *e ) { - /* cout << endl << "Moon orb post draw" << endl << "----------------" - << endl << endl; */ - // glEnable( GL_DEPTH_TEST ); - // glEnable( GL_FOG ); - - // Some drivers don't properly reset glBendFunc with a - // glPopAttrib() so we reset it to the 'default' here. - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - - glPopAttrib(); - // cout << "pop error = " << glGetError() << endl; - - /* test - glDisable( GL_LIGHTING ); - glDisable( GL_CULL_FACE ); - glEnable( GL_COLOR_MATERIAL ); - glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); - glEnable( GL_CULL_FACE ); - glEnable( GL_LIGHTING ); */ - - return true; -} - - -#if 0 -static int sgMoonHaloPreDraw( ssgEntity *e ) { - /* cout << endl << "Moon halo pre draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT | GL_COLOR_BUFFER_BIT); - // cout << "push error = " << glGetError() << endl; - - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - - return true; -} - -static int sgMoonHaloPostDraw( ssgEntity *e ) { - /* cout << endl << "Moon halo post draw" << endl << "----------------" - << endl << endl; */ - // glEnable( GL_DEPTH_TEST ); - // glEnable( GL_FOG ); - // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - - glPopAttrib(); - // cout << "pop error = " << glGetError() << endl; - - return true; -} -#endif - - -// Constructor -SGMoon::SGMoon( void ) { -} - - -// Destructor -SGMoon::~SGMoon( void ) { -} - - -// build the moon object -ssgBranch * SGMoon::build( SGPath path, double moon_size ) { - - // set up the orb state - path.append( "moon.rgba" ); - orb_state = new ssgSimpleState(); - orb_state->setTexture( (char *)path.c_str() ); - 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, 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 = ssgMakeSphere( orb_state, cl, moon_size, 15, 15, - sgMoonOrbPreDraw, sgMoonOrbPostDraw ); - - // force a repaint of the moon colors with arbitrary defaults - repaint( 0.0 ); - - // build the halo - // moon_texbuf = new GLubyte[64*64*3]; - // moon_texid = makeHalo( moon_texbuf, 64 ); - // my_glWritePPMFile("moonhalo.ppm", moon_texbuf, 64, 64, RGB); - -#if 0 - // set up the halo state - halo_state = new ssgSimpleState(); - halo_state->setTexture( "halo.rgb" ); - // halo_state->setTexture( moon_texid ); - halo_state->enable( GL_TEXTURE_2D ); - halo_state->disable( GL_LIGHTING ); - halo_state->setShadeModel( GL_SMOOTH ); - halo_state->disable( GL_CULL_FACE ); - - halo_state->disable( GL_COLOR_MATERIAL ); - halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - halo_state->setMaterial ( GL_AMBIENT_AND_DIFFUSE, 1, 1, 1, 1 ) ; - halo_state->setMaterial ( GL_EMISSION, 0, 0, 0, 1 ) ; - halo_state->setMaterial ( GL_SPECULAR, 0, 0, 0, 1 ) ; - // halo_state -> setShininess ( 0 ) ; - halo_state->enable( GL_ALPHA_TEST ); - halo_state->setAlphaClamp(0.01); - halo_state->enable ( GL_BLEND ) ; - - - // Build ssg structure - double size = moon_size * 10.0; - sgVec3 v3; - halo_vl = new ssgVertexArray; - sgSetVec3( v3, -size, 0.0, -size ); - halo_vl->add( v3 ); - sgSetVec3( v3, size, 0.0, -size ); - halo_vl->add( v3 ); - sgSetVec3( v3, -size, 0.0, size ); - halo_vl->add( v3 ); - sgSetVec3( v3, size, 0.0, size ); - halo_vl->add( v3 ); - - sgVec2 v2; - halo_tl = new ssgTexCoordArray; - sgSetVec2( v2, 0.0f, 0.0f ); - halo_tl->add( v2 ); - sgSetVec2( v2, 1.0, 0.0 ); - halo_tl->add( v2 ); - sgSetVec2( v2, 0.0, 1.0 ); - halo_tl->add( v2 ); - sgSetVec2( v2, 1.0, 1.0 ); - halo_tl->add( v2 ); - - ssgLeaf *halo = - new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl ); - halo->setState( halo_state ); -#endif - - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - moon_transform = new ssgTransform; - - // moon_transform->addKid( halo ); - moon_transform->addKid( orb ); - - return moon_transform; -} - - -// repaint the moon colors based on current value of moon_angle in -// degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = moon rise/set -// 180 degrees = darkest midnight -bool SGMoon::repaint( double moon_angle ) { - if ( moon_angle * SGD_RADIANS_TO_DEGREES < 100 ) { - // else moon is well below horizon (so no point in repainting it) - - // x_10 = moon_angle^10 - double x_10 = moon_angle * moon_angle * moon_angle * moon_angle - * moon_angle * moon_angle * moon_angle * moon_angle * moon_angle - * moon_angle; - - float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0)); - if (ambient < 0.3) { ambient = 0.3; } - if (ambient > 1.0) { ambient = 1.0; } - - sgVec4 color; - sgSetVec4( color, - (ambient * 6.0) - 1.0, // minimum value = 0.8 - (ambient * 11.0) - 3.0, // minimum value = 0.3 - (ambient * 12.0) - 3.6, // minimum value = 0.0 - 0.5 ); - - // temp test, forces the color to always be white - // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - - if (color[0] > 1.0) color[0] = 1.0; - if (color[1] > 1.0) color[1] = 1.0; - if (color[2] > 1.0) color[2] = 1.0; - - // cout << "color = " << color[0] << " " << color[1] << " " - // << color[2] << endl; - - float *ptr; - ptr = cl->get( 0 ); - sgCopyVec4( ptr, color ); - } - - return true; -} - - -// reposition the moon 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 SGMoon::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, angle, axis ); - - // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), - // 0.0, 0.0, 1.0); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); - - // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); - sgSetVec3( axis, 1.0, 0.0, 0.0 ); - sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis ); - - // xglTranslatef(0,moon_dist); - 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; -} - diff --git a/simgear/sky/moon.hxx b/simgear/sky/moon.hxx deleted file mode 100644 index 7fc8f808..00000000 --- a/simgear/sky/moon.hxx +++ /dev/null @@ -1,77 +0,0 @@ -// moon.hxx -- model earth's moon -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SG_MOON_HXX_ -#define _SG_MOON_HXX_ - - -#include - -#include - - -class SGMoon { - - ssgTransform *moon_transform; - ssgSimpleState *orb_state; - ssgSimpleState *halo_state; - - ssgColourArray *cl; - - ssgVertexArray *halo_vl; - ssgTexCoordArray *halo_tl; - -public: - - // Constructor - SGMoon( void ); - - // Destructor - ~SGMoon( void ); - - // build the moon object - ssgBranch *build( SGPath 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 ); - - // reposition the moon 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 moon_dist ); -}; - - -#endif // _SG_MOON_HXX_ diff --git a/simgear/sky/oursun.cxx b/simgear/sky/oursun.cxx deleted file mode 100644 index 3ffd6538..00000000 --- a/simgear/sky/oursun.cxx +++ /dev/null @@ -1,415 +0,0 @@ -// oursun.hxx -- model earth's sun -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifdef HAVE_CONFIG_H -# include -#endif - -#include - -#include -#include STL_IOSTREAM - -#include -#include - -// define the following to enable a cheesy lens flare effect for the sun -// #define FG_TEST_CHEESY_LENS_FLARE - -#ifdef FG_TEST_CHEESY_LENS_FLARE -# include -#endif - -#include "sphere.hxx" -#include "oursun.hxx" - - -// Set up sun rendering call backs -static int sgSunOrbPreDraw( ssgEntity *e ) { - /* cout << endl << "Sun orb pre draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); - // cout << "push error = " << glGetError() << endl; - - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - - return true; -} - -static int sgSunOrbPostDraw( ssgEntity *e ) { - /* cout << endl << "Sun orb post draw" << endl << "----------------" - << endl << endl; */ - - glPopAttrib(); - // cout << "pop error = " << glGetError() << endl; - - // glEnable( GL_DEPTH_TEST ); - // glEnable( GL_FOG ); - - return true; -} - -static int sgSunHaloPreDraw( ssgEntity *e ) { - /* cout << endl << "Sun halo pre draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_FOG_BIT ); - // cout << "push error = " << glGetError() << endl; - - glDisable( GL_DEPTH_TEST ); - glDisable( GL_FOG ); - glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; - - return true; -} - -static int sgSunHaloPostDraw( ssgEntity *e ) { - /* cout << endl << "Sun halo post draw" << endl << "----------------" - << endl << endl; */ - - glPopAttrib(); - // cout << "pop error = " << glGetError() << endl; - - // glEnable( GL_DEPTH_TEST ); - // glEnable( GL_FOG ); - - return true; -} - - -// Constructor -SGSun::SGSun( void ) { -} - - -// Destructor -SGSun::~SGSun( void ) { -} - - -#if 0 -// this might be nice to keep, just as an example of how to generate a -// texture on the fly ... -static GLuint makeHalo( GLubyte *sun_texbuf, int width ) { - int texSize; - GLuint texid; - GLubyte *p; - int i,j; - double radius; - - // create a texture id -#ifdef GL_VERSION_1_1 - glGenTextures(1, &texid); - glBindTexture(GL_TEXTURE_2D, texid); -#elif GL_EXT_texture_object - glGenTexturesEXT(1, &texid); - glBindTextureEXT(GL_TEXTURE_2D, texid); -#else -# error port me -#endif - - glPixelStorei( GL_UNPACK_ALIGNMENT, 4 ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); - glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); - glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE ) ; - - // create the actual texture contents - texSize = width * width; - - if ( !sun_texbuf ) { - cout << "ouch ..." << endl; - exit(-1); // Ugly! - } - - p = sun_texbuf; - - radius = (double)(width / 2); - - GLubyte value; - double x, y, d; - for ( i = 0; i < width; i++ ) { - for ( j = 0; j < width; j++ ) { - x = fabs((double)(i - (width / 2))); - y = fabs((double)(j - (width / 2))); - d = sqrt((x * x) + (y * y)); - if (d < radius) { - // t is 1.0 at center, 0.0 at edge - double t = 1.0 - (d / radius); - - // inverse square looks nice - value = (int)((double) 0xff * (t*t)); - } else { - value = 0x00; - } - *p = value; - *(p+1) = value; - *(p+2) = value; - // *(p+3) = value; - - p += 3; - } - } - - /* glTexImage2D( GL_TEXTURE_2D, - 0, - GL_RGBA, - width, width, - 0, - GL_RGBA, GL_UNSIGNED_BYTE, - sun_texbuf ); */ - - return texid; -} - - -#define RGB 3 // 3 bytes of color info per pixel -#define RGBA 4 // 4 bytes of color+alpha info -void my_glWritePPMFile(const char *filename, GLubyte *buffer, int win_width, int win_height, int mode) -{ - int i, j, k, q; - unsigned char *ibuffer; - FILE *fp; - int pixelSize = mode==GL_RGBA?4:3; - - ibuffer = (unsigned char *) malloc(win_width*win_height*RGB); - - fp = fopen(filename, "wb"); - fprintf(fp, "P6\n# CREATOR: glReadPixel()\n%d %d\n%d\n", - win_width, win_height, UCHAR_MAX); - q = 0; - for (i = 0; i < win_height; i++) { - for (j = 0; j < win_width; j++) { - for (k = 0; k < RGB; k++) { - ibuffer[q++] = (unsigned char) - *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); - } - } - } - - // *(buffer + (pixelSize*((win_height-1-i)*win_width+j)+k)); - - fwrite(ibuffer, sizeof(unsigned char), RGB*win_width*win_height, fp); - fclose(fp); - free(ibuffer); - - printf("wrote file (%d x %d pixels, %d bytes)\n", - win_width, win_height, RGB*win_width*win_height); -} -#endif - - -// initialize the sun object and connect it into our scene graph root -ssgBranch * SGSun::build( SGPath path, double sun_size ) { - - // set up the orb state - orb_state = new ssgSimpleState(); - orb_state->setShadeModel( GL_SMOOTH ); - orb_state->disable( GL_LIGHTING ); - // orb_state->enable( GL_LIGHTING ); - orb_state->disable( GL_CULL_FACE ); - orb_state->disable( GL_TEXTURE_2D ); - orb_state->enable( GL_COLOR_MATERIAL ); - orb_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - orb_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - orb_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - orb_state->disable( GL_BLEND ); - orb_state->disable( GL_ALPHA_TEST ); - - cl = new ssgColourArray( 1 ); - sgVec4 color; - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - - ssgBranch *orb = ssgMakeSphere( orb_state, cl, sun_size, 10, 10, - sgSunOrbPreDraw, sgSunOrbPostDraw ); - - // force a repaint of the sun colors with arbitrary defaults - repaint( 0.0 ); - - // build the halo - // sun_texbuf = new GLubyte[64*64*3]; - // sun_texid = makeHalo( sun_texbuf, 64 ); - // my_glWritePPMFile("sunhalo.ppm", sun_texbuf, 64, 64, RGB); - - // set up the halo state - path.append( "halo.rgba" ); - halo_state = new ssgSimpleState(); - halo_state->setTexture( (char *)path.c_str() ); - halo_state->enable( GL_TEXTURE_2D ); - halo_state->disable( GL_LIGHTING ); - // halo_state->enable( GL_LIGHTING ); - halo_state->setShadeModel( GL_SMOOTH ); - halo_state->disable( GL_CULL_FACE ); - halo_state->enable( GL_COLOR_MATERIAL ); - halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - halo_state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - halo_state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - halo_state->enable( GL_ALPHA_TEST ); - halo_state->setAlphaClamp(0.01); - halo_state->enable ( GL_BLEND ) ; - - // Build ssg structure - double size = sun_size * 10.0; - sgVec3 v3; - halo_vl = new ssgVertexArray; - sgSetVec3( v3, -size, 0.0, -size ); - halo_vl->add( v3 ); - sgSetVec3( v3, size, 0.0, -size ); - halo_vl->add( v3 ); - sgSetVec3( v3, -size, 0.0, size ); - halo_vl->add( v3 ); - sgSetVec3( v3, size, 0.0, size ); - halo_vl->add( v3 ); - - sgVec2 v2; - halo_tl = new ssgTexCoordArray; - sgSetVec2( v2, 0.0f, 0.0f ); - halo_tl->add( v2 ); - sgSetVec2( v2, 1.0, 0.0 ); - halo_tl->add( v2 ); - sgSetVec2( v2, 0.0, 1.0 ); - halo_tl->add( v2 ); - sgSetVec2( v2, 1.0, 1.0 ); - halo_tl->add( v2 ); - - ssgLeaf *halo = - new ssgVtxTable ( GL_TRIANGLE_STRIP, halo_vl, NULL, halo_tl, cl ); - halo->setState( halo_state ); - - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - sun_transform = new ssgTransform; - - halo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw ); - halo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw ); - sun_transform->addKid( halo ); - sun_transform->addKid( orb ); - -#ifdef FG_TEST_CHEESY_LENS_FLARE - // cheesy lens flair - sun_transform->addKid( new ssgaLensFlare ); -#endif - - return sun_transform; -} - - -// repaint the sun colors based on current value of sun_angle in -// degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = sun rise/set -// 180 degrees = darkest midnight -bool SGSun::repaint( double sun_angle ) { - if ( sun_angle * SGD_RADIANS_TO_DEGREES < 100 ) { - // else sun is well below horizon (so no point in repainting it) - - // x_10 = sun_angle^10 - double x_10 = sun_angle * sun_angle * sun_angle * sun_angle * sun_angle - * sun_angle * sun_angle * sun_angle * sun_angle * sun_angle; - - float ambient = (float)(0.4 * pow (1.1, - x_10 / 30.0)); - if (ambient < 0.3) { ambient = 0.3; } - if (ambient > 1.0) { ambient = 1.0; } - - sgVec4 color; - sgSetVec4( color, - (ambient * 6.0) - 1.0, // minimum value = 0.8 - (ambient * 11.0) - 3.0, // minimum value = 0.3 - (ambient * 12.0) - 3.6, // minimum value = 0.0 - 1.0 ); - - // temp test, forces the color to always be white - // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - - if (color[0] > 1.0) color[0] = 1.0; - if (color[1] > 1.0) color[1] = 1.0; - if (color[2] > 1.0) color[2] = 1.0; - - // cout << "color = " << color[0] << " " << color[1] << " " - // << color[2] << endl; - - float *ptr; - ptr = cl->get( 0 ); - sgCopyVec4( ptr, color ); - } - - return true; -} - - -// 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 SGSun::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, angle, axis ); - - // xglRotatef( ((SGD_RADIANS_TO_DEGREES * rightAscension)- 90.0), - // 0.0, 0.0, 1.0); - sgSetVec3( axis, 0.0, 0.0, 1.0 ); - sgMakeRotMat4( RA, (rightAscension * SGD_RADIANS_TO_DEGREES) - 90.0, axis ); - - // xglRotatef((SGD_RADIANS_TO_DEGREES * declination), 1.0, 0.0, 0.0); - sgSetVec3( axis, 1.0, 0.0, 0.0 ); - sgMakeRotMat4( DEC, declination * SGD_RADIANS_TO_DEGREES, axis ); - - // xglTranslatef(0,sun_dist); - 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 ); - - return true; -} diff --git a/simgear/sky/oursun.hxx b/simgear/sky/oursun.hxx deleted file mode 100644 index 2ee90040..00000000 --- a/simgear/sky/oursun.hxx +++ /dev/null @@ -1,80 +0,0 @@ -// oursun.hxx -- model earth's sun -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SG_SUN_HXX_ -#define _SG_SUN_HXX_ - - -#include - -#include - - -class SGSun { - - ssgTransform *sun_transform; - ssgSimpleState *orb_state; - ssgSimpleState *halo_state; - - ssgColourArray *cl; - - ssgVertexArray *halo_vl; - ssgTexCoordArray *halo_tl; - - GLuint sun_texid; - GLubyte *sun_texbuf; - -public: - - // Constructor - SGSun( void ); - - // Destructor - ~SGSun( void ); - - // return the sun object - ssgBranch *build( SGPath 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 ); - - // 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 ); -}; - - -#endif // _SG_SUN_HXX_ diff --git a/simgear/sky/sky.cxx b/simgear/sky/sky.cxx deleted file mode 100644 index 5ce06fe2..00000000 --- a/simgear/sky/sky.cxx +++ /dev/null @@ -1,354 +0,0 @@ -// sky.cxx -- ssg based sky model -// -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#include -#include - -#include - -#include "sky.hxx" - - -// Constructor -SGSky::SGSky( void ) { - 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; - // ramp_up = 4.0; - // ramp_down = 4.0; -} - - -// Destructor -SGSky::~SGSky( void ) -{ - for (unsigned int i = 0; i < cloud_layers.size(); i++) - delete cloud_layers[i]; -} - - -// initialize the sky and connect the components to the scene graph at -// the provided branch -void SGSky::build( double sun_size, double moon_size, - int nplanets, sgdVec3 *planet_data, - double planet_dist, - int nstars, sgdVec3 *star_data, double star_dist ) -{ - pre_root = new ssgRoot; - post_root = new ssgRoot; - - pre_selector = new ssgSelector; - post_selector = new ssgSelector; - - pre_transform = new ssgTransform; - post_transform = new ssgTransform; - - dome = new SGSkyDome; - pre_transform -> addKid( dome->build() ); - - planets = new SGStars; - pre_transform -> addKid( planets->build(nplanets, planet_data, - planet_dist) - ); - - stars = new SGStars; - pre_transform -> addKid( stars->build(nstars, star_data, star_dist) ); - - moon = new SGMoon; - pre_transform -> addKid( moon->build(tex_path, moon_size) ); - - oursun = new SGSun; - pre_transform -> addKid( oursun->build(tex_path, sun_size) ); - - pre_selector->addKid( pre_transform ); - pre_selector->clrTraversalMaskBits( SSGTRAV_HOT ); - - post_selector->addKid( post_transform ); - post_selector->clrTraversalMaskBits( SSGTRAV_HOT ); - - pre_root->addKid( pre_selector ); - post_root->addKid( post_selector ); -} - - -// repaint the sky components based on current value of sun_angle, -// sky, and fog colors. -// -// sun angle in degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = sun rise/set -// 180 degrees = darkest midnight -bool SGSky::repaint( sgVec4 sky_color, sgVec4 fog_color, - double sun_angle, double moon_angle, - int nplanets, sgdVec3 *planet_data, - int nstars, sgdVec3 *star_data ) -{ - if ( effective_visibility > 1000.0 ) { - enable(); - dome->repaint( sky_color, fog_color, sun_angle, effective_visibility ); - oursun->repaint( sun_angle ); - moon->repaint( moon_angle ); - planets->repaint( sun_angle, nplanets, planet_data ); - stars->repaint( sun_angle, nstars, star_data ); - - for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { - cloud_layers[i]->repaint( fog_color ); - } - } else { - // turn off sky - disable(); - } - - return true; -} - - -// reposition the sky at the specified origin and orientation -// -// lon specifies a rotation about the Z axis -// lat specifies a rotation about the new Y axis -// spin specifies a rotation about the new Z axis (this allows -// additional orientation for the sunrise/set effects and is used by -// the skydome and perhaps clouds. -bool SGSky::reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, - double lon, double lat, double alt, double spin, - double gst, - double sun_ra, double sun_dec, double sun_dist, - double moon_ra, double moon_dec, double moon_dist ) -{ - double angle = gst * 15; // degrees - dome->reposition( zero_elev, lon, lat, spin ); - oursun->reposition( view_pos, angle, sun_ra, sun_dec, sun_dist ); - moon->reposition( view_pos, angle, moon_ra, moon_dec, moon_dist ); - planets->reposition( view_pos, angle ); - stars->reposition( view_pos, angle ); - - for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { - cloud_layers[i]->reposition( zero_elev, view_up, lon, lat, alt ); - } - - return true; -} - - -// draw background portions of the sky ... do this before you draw the -// rest of your scene. -void SGSky::preDraw() { - ssgCullAndDraw( pre_root ); -} - - -// draw translucent clouds ... do this after you've drawn all the -// oapaque elements of your scene. -void SGSky::postDraw( float alt ) { - float slop = 5.0; // if we are closer than this to a cloud layer, - // don't draw clouds - - int in_cloud = -1; // cloud we are in - - int i; - - // check where we are relative to the cloud layers - for ( i = 0; i < (int)cloud_layers.size(); ++i ) { - float asl = cloud_layers[i]->getElevation_m(); - float thickness = cloud_layers[i]->getThickness_m(); - - if ( alt < asl - slop ) { - // below cloud layer - } else if ( alt < asl + thickness + slop ) { - // in cloud layer - - // bail now and don't draw any clouds - in_cloud = i; - } else { - // above cloud layer - } - } - - // determine rendering order - int pos = 0; - while ( pos < (int)cloud_layers.size() && - alt > cloud_layers[pos]->getElevation_m()) - { - ++pos; - } - - if ( pos == 0 ) { - // we are below all the cloud layers, draw top to bottom - for ( i = cloud_layers.size() - 1; i >= 0; --i ) { - if ( i != in_cloud ) { - cloud_layers[i]->draw(); - } - } - } else if ( pos >= (int)cloud_layers.size() ) { - // we are above all the cloud layers, draw bottom to top - for ( i = 0; i < (int)cloud_layers.size(); ++i ) { - if ( i != in_cloud ) { - cloud_layers[i]->draw(); - } - } - } else { - // we are between cloud layers, draw lower layers bottom to - // top and upper layers top to bottom - for ( i = 0; i < pos; ++i ) { - if ( i != in_cloud ) { - cloud_layers[i]->draw(); - } - } - for ( i = cloud_layers.size() - 1; i >= pos; --i ) { - if ( i != in_cloud ) { - cloud_layers[i]->draw(); - } - } - } -} - -void -SGSky::add_cloud_layer( SGCloudLayer * layer ) -{ - cloud_layers.push_back(layer); -} - -const SGCloudLayer * -SGSky::get_cloud_layer (int i) const -{ - return cloud_layers[i]; -} - -SGCloudLayer * -SGSky::get_cloud_layer (int i) -{ - return cloud_layers[i]; -} - -int -SGSky::get_cloud_layer_count () const -{ - return cloud_layers.size(); -} - -// modify the current visibility based on cloud layers, thickness, -// transition range, and simulated "puffs". -void SGSky::modify_vis( float alt, float time_factor ) { - float effvis = visibility; - - for ( int i = 0; i < (int)cloud_layers.size(); ++i ) { - float asl = cloud_layers[i]->getElevation_m(); - float thickness = cloud_layers[i]->getThickness_m(); - float transition = cloud_layers[i]->getTransition_m(); - - double ratio = 1.0; - - if ( alt < asl - transition ) { - // below cloud layer - ratio = 1.0; - } else if ( alt < asl ) { - // in lower transition - ratio = (asl - alt) / transition; - } else if ( alt < asl + thickness ) { - // in cloud layer - ratio = 0.0; - } else if ( alt < asl + thickness + transition ) { - // in upper transition - ratio = (alt - (asl + thickness)) / transition; - } else { - // above cloud layer - ratio = 1.0; - } - - // accumulate effects from multiple cloud layers - effvis *= ratio; - - if ( ratio < 1.0 ) { - if ( ! in_puff ) { - // calc chance of entering cloud puff - double rnd = sg_random(); - double chance = rnd * rnd * rnd; - if ( chance > 0.95 /* * (diff - 25) / 50.0 */ ) { - in_puff = true; - puff_length = sg_random() * 2.0; // up to 2 seconds - puff_progression = 0.0; - } - } - - if ( in_puff ) { - // modify actual_visibility based on puff envelope - - if ( puff_progression <= ramp_up ) { - double x = 0.5 * SGD_PI * puff_progression / ramp_up; - double factor = 1.0 - sin( x ); - // cout << "ramp up = " << puff_progression - // << " factor = " << factor << endl; - effvis = effvis * factor; - } else if ( puff_progression >= ramp_up + puff_length ) { - double x = 0.5 * SGD_PI * - (puff_progression - (ramp_up + puff_length)) / - ramp_down; - double factor = sin( x ); - // cout << "ramp down = " - // << puff_progression - (ramp_up + puff_length) - // << " factor = " << factor << endl; - effvis = effvis * factor; - } else { - effvis = 0.0; - } - - /* cout << "len = " << puff_length - << " x = " << x - << " factor = " << factor - << " actual_visibility = " << actual_visibility - << endl; */ - - // time_factor = ( global_multi_loop * - // current_options.get_speed_up() ) / - // (double)current_options.get_model_hz(); - - puff_progression += time_factor; - // cout << "time factor = " << time_factor << endl; - - /* cout << "gml = " << global_multi_loop - << " speed up = " << current_options.get_speed_up() - << " hz = " << current_options.get_model_hz() << endl; - */ - - if ( puff_progression > puff_length + ramp_up + ramp_down) { - in_puff = false; - } - } - - // never let visibility drop below 25 meters - if ( effvis <= 25.0 ) { - effvis = 25.0; - } - } - } // for - - effective_visibility = effvis; -} diff --git a/simgear/sky/sky.hxx b/simgear/sky/sky.hxx deleted file mode 100644 index 95b5ecba..00000000 --- a/simgear/sky/sky.hxx +++ /dev/null @@ -1,403 +0,0 @@ -/** - * \file sky.hxx - * Provides a class to model a realistic (time/date/position) based sky. - */ - -// Written by Curtis Olson, started December 1997. -// SSG-ified by Curtis Olson, February 2000. -// -// Copyright (C) 1997-2000 Curtis L. Olson - curt@flightgear.org -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SG_SKY_HXX -#define _SG_SKY_HXX - - -#ifndef __cplusplus -# error This library requires C++ -#endif - - -#include // plib include - -#include -#include - -#include - -#include -#include -#include -#include -#include - -SG_USING_STD(vector); - - -typedef vector < SGCloudLayer* > layer_list_type; -typedef layer_list_type::iterator layer_list_iterator; -typedef layer_list_type::const_iterator layer_list_const_iterator; - -/** - * A class to model a realistic (time/date/position) based sky. - * - * Introduction - * - * The SGSky class models a blended sky dome, a haloed sun, a textured - * moon with phase that properly matches the date, stars and planets, - * and cloud layers. SGSky is designed to be dropped into existing - * plib based applications and depends heavily on plib's scene graph - * library, ssg. The sky implements various time of day lighting - * effects, it plays well with fog and visibility effects, and - * implements scudded cloud fly-through effects. Additionally, you can - * wire in the output of the SGEphemeris class to accurately position - * all the objects in the sky. - * - * Building the sky - * - - * Once you have created an instance of SGSky you must call the - * build() method. Building the sky requires several textures. So, - * you must specify the path/directory where these textures reside - * before building the sky. You do this first by calling the - * texture_path() method. - - * The arguments you pass to the build() method allow you to specify - * the size of your sun sphere and moon sphere, a number of planets, - * and a multitude of stars. For the planets and stars you pass in an - * array of right ascensions, declinations, magnitudes, and the - * distance from the view point. - - * Cloud Layers - - * Cloud layers can be added, changed, or removed individually. To add - * a cloud layer use the add_cloud_layer() method. The arguments - * allow you to specify base height above sea level, layer thickness, - * a transition zone for entering/leaving the cloud layer, the size of - * the cloud object, and the type of cloud texture. All distances are - * in meters. There are additional forms of this method that allow you - * to specify your own ssgSimpleState or texture name for drawing the - * cloud layer. - - * Repainting the Sky - - * As the sun circles the globe, you can call the repaint() method to - * recolor the sky objects to simulate sunrise and sunset effects, - * visibility, and other lighting changes. The arguments allow you to - * specify a base sky color (for the top of the dome), a fog color - * (for the horizon), the sun angle with the horizon (for - * sunrise/sunset effects), the moon angle (so we can make it more - * yellow at the horizon), and new star and planet data so that we can - * optionally change the magnitude of these (for day / night - * transitions.) - - * Positioning Sky Objects - - * As time progresses and as you move across the surface of the earth, - * the apparent position of the objects and the various lighting - * effects can change. the reposition() method allows you to specify - * the positions of all the sky objects as well as your view position. - * The arguments allow you to specify your view position in world - * Cartesian coordinates, the zero elevation position in world - * Cartesian coordinates (your longitude, your latitude, sea level), - * the ``up'' vector in world Cartesian coordinates, current - * longitude, latitude, and altitude. A ``spin'' angle can be - * specified for orienting the sky with the sun position so sunset and - * sunrise effects look correct. You must specify GMT side real time, - * the sun right ascension, sun declination, and sun distance from - * view point (to keep it inside your view volume.) You also must - * specify moon right ascension, moon declination, and moon distance - * from view point. - - * Rendering the Sky - - * The sky is designed to be rendered in two stages. The first stage - * renders the parts that form your back drop - the sky dome, the - * stars and planets, the sun, and the moon. These should be rendered - * before the rest of your scene by calling the preDraw() method. The - * second stage renders the clouds which are likely to be translucent - * (depending on type) and should be drawn after your scene has been - * rendered. Use the postDraw() method to draw the second stage of - * the sky. - - * A typical application might do the following: - - *
  • thesky->preDraw(); - *
  • ssgCullAndDraw ( myscene ) ; - *
  • thesky->postDraw( my_altitude ); - - * The current altitude in meters is passed to the postDraw() method - * so the clouds layers can be rendered correction from most distant - * to closest. - - * Visibility Effects - - * Visibility and fog is important for correctly rendering the - * sky. You can inform SGSky of the current visibility by calling the - * set_visibility() method. - - * When transitioning through clouds, it is nice to pull in the fog as - * you get close to the cloud layer to hide the fact that the clouds - * are drawn as a flat polygon. As you get nearer to the cloud layer - * it is also nice to temporarily pull in the visibility to simulate - * the effects of flying in and out of the puffy edge of the - * cloud. These effects can all be accomplished by calling the - * modify_vis() method. The arguments allow you to specify your - * current altitude (which is then compared to the altitudes of the - * various cloud layers.) You can also specify a time factor which - * should be the length in seconds since the last time you called - * modify_vis(). The time_factor value allows the puffy cloud effect - * to be calculated correctly. - - * The modify_vis() method alters the SGSky's internal idea of - * visibility, so you should subsequently call get_visibility() to get - * the actual modified visibility. You should then make the - * appropriate glFog() calls to setup fog properly for your scene. - - * Accessor Methods - - * Once an instance of SGSky has been successfully initialized, there - * are a couple accessor methods you can use such as get_num_layers() - * to return the number of cloud layers, get_cloud_layer(i) to return - * cloud layer number i, get_visibility() to return the actual - * visibility as modified by the sky/cloud model. - - */ - -class SGSky { - -private: - - // components of the sky - SGSkyDome *dome; - SGSun *oursun; - SGMoon *moon; - SGStars *planets; - SGStars *stars; - layer_list_type cloud_layers; - - ssgRoot *pre_root, *post_root; - - ssgSelector *pre_selector, *post_selector; - ssgTransform *pre_transform, *post_transform; - - SGPath tex_path; - - // visibility - float visibility; - float effective_visibility; - - // near cloud visibility state variables - bool in_puff; - double puff_length; // in seconds - double puff_progression; // in seconds - double ramp_up; // in seconds - double ramp_down; // in seconds - -public: - - /** Constructor */ - SGSky( void ); - - /** Destructor */ - ~SGSky( void ); - - /** - * Initialize the sky and connect the components to the scene - * graph at the provided branch. See discussion in detailed class - * description. - * @param sun_size size of sun - * @param moon_size size of moon - * @param nplanets number of planets - * @param planet_data an array of planet right ascensions, declinations, - * and magnitudes - * @param planet_dist distance from viewer to put the planets - * @param nstars number of stars - * @param star_data an array of star right ascensions, declinations, - * and magnitudes - * @param star_dist distance from viewer to put the stars */ - void build( double sun_size, double moon_size, - int nplanets, sgdVec3 *planet_data, double planet_dist, - int nstars, sgdVec3 *star_data, double star_dist ); - - /** - * Repaint the sky components based on current value of sun_angle, - * sky, and fog colors. You can also specify new star and planet - * data so that we can optionally change the magnitude of these - * (for day/night transitions.) See discussion in detailed - * class description. - * - * Sun and moon angles are specified in degrees relative to local up - *
  • 0 degrees = high noon - *
  • 90 degrees = sun rise/set - *
  • 180 degrees = darkest midnight - * @param sky_color the base sky color (for the top of the dome) - * @param fog_color the fog color (for the horizon) - * @param sun_angle the sun angle with the horizon (for sunrise/sunset - * effects) - * @param moon_angle the moon angle (so we can make it more yellow - * at the horizon) - * @param nplanets number of planets - * @param planet_data an array of planet right ascensions, declinations, - * and magnitudes - * @param nstars number of stars - * @param star_data an array of star right ascensions, declinations, - * and magnitudes - */ - bool repaint( sgVec4 sky_color, sgVec4 fog_color, - double sun_angle, double moon_angle, - int nplanets, sgdVec3 *planet_data, - int nstars, sgdVec3 *star_data ); - - /** - * Reposition the sky at the specified origin and orientation - * - * lon specifies a rotation about the Z axis - * lat specifies a rotation about the new Y axis - * spin specifies a rotation about the new Z axis (this allows - * additional orientation for the sunrise/set effects and is used - * by the skydome and perhaps clouds. See discussion in detailed - * class description. - * @param view_pos specify your view position in world Cartesian - * coordinates - * @param zero_elev the zero elevation position in world Cartesian - * coordinates - * @param view_up the up vector in world Cartesian coordinates - * @param lon current longitude - * @param lat current latitude - * @param alt current altitude - * @param spin an offset angle for orienting the sky effects with the - * sun position so sunset and sunrise effects look correct. - * @param gst GMT side real time - * @param sun_ra the sun's current right ascension - * @param sun_dec the sun's current declination - * @param sun_dist the sun's distance from the current view point - * (to keep it inside your view volume.) - * @param moon_ra the moon's current right ascension - * @param moon_dec the moon's current declination - * @param moon_dist the moon's distance from the current view point. - */ - bool reposition( sgVec3 view_pos, sgVec3 zero_elev, sgVec3 view_up, - double lon, double lat, double alt, double spin, - double gst, - double sun_ra, double sun_dec, double sun_dist, - double moon_ra, double moon_dec, double moon_dist ); - - /** - * Modify the given visibility based on cloud layers, thickness, - * transition range, and simulated "puffs". See discussion in detailed - * class description. - * @param alt current altitude - * @param time_factor amount of time since modify_vis() last called so - * we can scale effect rates properly despite variable frame rates. - */ - void modify_vis( float alt, float time_factor ); - - /** - * Draw background portions of the sky ... do this before you draw - * the rest of your scene. See discussion in detailed - * class description. - */ - void preDraw(); - - /** - * Draw translucent clouds ... do this after you've drawn all the - * oapaque elements of your scene. See discussion in detailed - * class description. - * @param alt current altitude - */ - void postDraw( float alt ); - - /** - * Specify the texture path (optional, defaults to current directory) - * @param path base path to texture locations - */ - inline void texture_path( const string& path ) { - tex_path = SGPath( path ); - } - - /** Enable drawing of the sky. */ - inline void enable() { - pre_selector->select( 1 ); - post_selector->select( 1 ); - } - - /** - * Disable drawing of the sky in the scene graph. The leaf node is still - * there, how ever it won't be traversed on by ssgCullandRender() - */ - inline void disable() { - pre_selector->select( 0 ); - post_selector->select( 0 ); - } - - /** - * Add a cloud layer. - * - * Transfer pointer ownership to this object. - * - * @param layer The new cloud layer to add. - */ - void add_cloud_layer (SGCloudLayer * layer); - - - /** - * Get a cloud layer (const). - * - * Pointer ownership remains with this object. - * - * @param i The index of the cloud layer, zero-based. - * @return A const pointer to the cloud layer. - */ - const SGCloudLayer * get_cloud_layer (int i) const; - - - /** - * Get a cloud layer (non-const). - * - * Pointer ownership remains with this object. - * - * @param i The index of the cloud layer, zero-based. - * @return A non-const pointer to the cloud layer. - */ - SGCloudLayer * get_cloud_layer (int i); - - - /** - * Return the number of cloud layers currently available. - * - * @return The cloud layer count. - */ - int get_cloud_layer_count () const; - - - /** @return current effective visibility */ - inline float get_visibility() const { return effective_visibility; } - - /** Set desired clear air visibility. - * @param v visibility in meters - */ - inline void set_visibility( float v ) { - effective_visibility = visibility = v; - } -}; - - -#endif // _SG_SKY_HXX diff --git a/simgear/sky/sphere.cxx b/simgear/sky/sphere.cxx deleted file mode 100644 index 428d966b..00000000 --- a/simgear/sky/sphere.cxx +++ /dev/null @@ -1,134 +0,0 @@ -// sphere.cxx -- build an ssg sphere object -// -// Pulled straight out of MesaGLU/quadratic.c -// -// Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and -// licensed under the GPL -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#include - -#include STL_IOSTREAM - -#include -#include - -#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS) -SG_USING_STD(cout); -SG_USING_STD(endl); -#endif - - -// return a sphere object as an ssgBranch -ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl, - double radius, int slices, int stacks, - ssgCallback predraw, ssgCallback postdraw ) -{ - float rho, drho, theta, dtheta; - float x, y, z; - float s, t, ds, dt; - int i, j, imin, imax; - float nsign = 1.0; - ssgBranch *sphere = new ssgBranch; - sgVec2 vec2; - sgVec3 vec3; - - drho = SGD_PI / (float) stacks; - dtheta = 2.0 * SGD_PI / (float) slices; - - /* texturing: s goes from 0.0/0.25/0.5/0.75/1.0 at +y/+x/-y/-x/+y - axis t goes from -1.0/+1.0 at z = -radius/+radius (linear along - longitudes) cannot use triangle fan on texturing (s coord. at - top/bottom tip varies) */ - - ds = 1.0 / slices; - dt = 1.0 / stacks; - t = 1.0; /* because loop now runs from 0 */ - imin = 0; - imax = stacks; - - /* build slices as quad strips */ - for ( i = imin; i < imax; i++ ) { - ssgVertexArray *vl = new ssgVertexArray(); - ssgNormalArray *nl = new ssgNormalArray(); - ssgTexCoordArray *tl = new ssgTexCoordArray(); - - rho = i * drho; - s = 0.0; - for ( j = 0; j <= slices; j++ ) { - theta = (j == slices) ? 0.0 : j * dtheta; - x = -sin(theta) * sin(rho); - y = cos(theta) * sin(rho); - z = nsign * cos(rho); - - // glNormal3f( x*nsign, y*nsign, z*nsign ); - sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); - sgNormalizeVec3( vec3 ); - nl->add( vec3 ); - - // glTexCoord2f(s,t); - sgSetVec2( vec2, s, t ); - tl->add( vec2 ); - - // glVertex3f( x*radius, y*radius, z*radius ); - sgSetVec3( vec3, x*radius, y*radius, z*radius ); - vl->add( vec3 ); - - x = -sin(theta) * sin(rho+drho); - y = cos(theta) * sin(rho+drho); - z = nsign * cos(rho+drho); - - // glNormal3f( x*nsign, y*nsign, z*nsign ); - sgSetVec3( vec3, x*nsign, y*nsign, z*nsign ); - sgNormalizeVec3( vec3 ); - nl->add( vec3 ); - - // glTexCoord2f(s,t-dt); - sgSetVec2( vec2, s, t-dt ); - tl->add( vec2 ); - s += ds; - - // glVertex3f( x*radius, y*radius, z*radius ); - sgSetVec3( vec3, x*radius, y*radius, z*radius ); - vl->add( vec3 ); - } - - ssgLeaf *slice = - new ssgVtxTable ( GL_TRIANGLE_STRIP, vl, nl, tl, cl ); - - if ( vl->getNum() != nl->getNum() ) { - cout << "bad sphere1" << endl; - exit(-1); - } - if ( vl->getNum() != tl->getNum() ) { - cout << "bad sphere2" << endl; - exit(-1); - } - slice->setState( state ); - slice->setCallback( SSG_CALLBACK_PREDRAW, predraw ); - slice->setCallback( SSG_CALLBACK_POSTDRAW, postdraw ); - - sphere->addKid( slice ); - - t -= dt; - } - - return sphere; -} diff --git a/simgear/sky/sphere.hxx b/simgear/sky/sphere.hxx deleted file mode 100644 index e7896e38..00000000 --- a/simgear/sky/sphere.hxx +++ /dev/null @@ -1,35 +0,0 @@ -// sphere.hxx -- build an ssg sphere object -// -// Pulled straight out of MesaGLU/quadratic.c -// -// Original gluSphere code is Copyright (C) 1999-2000 Brian Paul and -// licensed under the GPL -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#include - - -// return a sphere object as an ssgBranch (and connect in the -// specified ssgSimpleState -ssgBranch *ssgMakeSphere( ssgSimpleState *state, ssgColourArray *cl, - double radius, int slices, int stacks, - ssgCallback predraw, ssgCallback postdraw ); - - diff --git a/simgear/sky/stars.cxx b/simgear/sky/stars.cxx deleted file mode 100644 index 0ca2efb4..00000000 --- a/simgear/sky/stars.cxx +++ /dev/null @@ -1,265 +0,0 @@ -// stars.cxx -- model the stars -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#include - -#include -#include STL_IOSTREAM - -#include -#include - -#include "stars.hxx" - -#if !defined (SG_HAVE_NATIVE_SGI_COMPILERS) -SG_USING_STD(cout); -SG_USING_STD(endl); -#endif - - -// Set up star rendering call backs -static int sgStarPreDraw( ssgEntity *e ) { - /* cout << endl << "Star pre draw" << endl << "----------------" - << endl << endl; */ - - ssgLeaf *f = (ssgLeaf *)e; - if ( f -> hasState () ) f->getState()->apply() ; - - glPushAttrib( 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 sgStarPostDraw( ssgEntity *e ) { - /* cout << endl << "Star post draw" << endl << "----------------" - << endl << endl; */ - - glPopAttrib(); - - // glEnable( GL_DEPTH_TEST ); - // glEnable( GL_FOG ); - - return true; -} - - -// Constructor -SGStars::SGStars( void ) : -old_phase(-1) -{ -} - - -// Destructor -SGStars::~SGStars( void ) { -} - - -// initialize the stars object and connect it into our scene graph root -ssgBranch * SGStars::build( int num, sgdVec3 *star_data, double star_dist ) { - sgVec4 color; - - if ( star_data == NULL ) { - cout << "WARNING: null star data passed to SGStars::build()" << endl; - } - - // set up the orb state - state = new ssgSimpleState(); - state->disable( GL_LIGHTING ); - state->disable( GL_CULL_FACE ); - state->disable( GL_TEXTURE_2D ); - state->enable( GL_COLOR_MATERIAL ); - state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); - state->setMaterial( GL_EMISSION, 0, 0, 0, 1 ); - state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 ); - state->enable( GL_BLEND ); - state->disable( GL_ALPHA_TEST ); - - vl = new ssgVertexArray( num ); - cl = new ssgColourArray( num ); - // cl = new ssgColourArray( 1 ); - // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - // cl->add( color ); - - // Build ssg structure - sgVec3 p; - for ( int i = 0; i < num; ++i ) { - // position seeded to arbitrary values - sgSetVec3( p, - star_dist * cos( star_data[i][0] ) - * cos( star_data[i][1] ), - star_dist * sin( star_data[i][0] ) - * cos( star_data[i][1] ), - star_dist * sin( star_data[i][1] ) - ); - vl->add( p ); - - // color (magnitude) - sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 ); - cl->add( color ); - } - - ssgLeaf *stars_obj = - new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl ); - stars_obj->setState( state ); - stars_obj->setCallback( SSG_CALLBACK_PREDRAW, sgStarPreDraw ); - stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, sgStarPostDraw ); - - // build the ssg scene graph sub tree for the sky and connected - // into the provide scene graph branch - stars_transform = new ssgTransform; - - stars_transform->addKid( stars_obj ); - - cout << "stars = " << stars_transform << endl; - - return stars_transform; -} - - -// repaint the sun colors based on current value of sun_angle in -// degrees relative to verticle -// 0 degrees = high noon -// 90 degrees = sun rise/set -// 180 degrees = darkest midnight -bool SGStars::repaint( double sun_angle, int num, sgdVec3 *star_data ) { - // cout << "repainting stars" << endl; - // double min = 100; - // double max = -100; - double mag, nmag, alpha, factor, cutoff; - float *color; - - int phase; - - // determine which star structure to draw - if ( sun_angle > (0.5 * SGD_PI + 10.0 * SGD_DEGREES_TO_RADIANS ) ) { - // deep night - factor = 1.0; - cutoff = 4.5; - phase = 0; - } else if ( sun_angle > (0.5 * SGD_PI + 8.8 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 1.0; - cutoff = 3.8; - phase = 1; - } else if ( sun_angle > (0.5 * SGD_PI + 7.5 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 0.95; - cutoff = 3.1; - phase = 2; - } else if ( sun_angle > (0.5 * SGD_PI + 7.0 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 0.9; - cutoff = 2.4; - phase = 3; - } else if ( sun_angle > (0.5 * SGD_PI + 6.5 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 0.85; - cutoff = 1.8; - phase = 4; - } else if ( sun_angle > (0.5 * SGD_PI + 6.0 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 0.8; - cutoff = 1.2; - phase = 5; - } else if ( sun_angle > (0.5 * SGD_PI + 5.5 * SGD_DEGREES_TO_RADIANS ) ) { - factor = 0.75; - cutoff = 0.6; - phase = 6; - } else { - // early dusk or late dawn - factor = 0.7; - cutoff = 0.0; - phase = 7; - } - - if( phase != old_phase ) { - // cout << " phase change, repainting stars, num = " << num << endl; - old_phase = phase; - for ( int i = 0; i < num; ++i ) { - // if ( star_data[i][2] < min ) { min = star_data[i][2]; } - // if ( star_data[i][2] > max ) { max = star_data[i][2]; } - - // magnitude ranges from -1 (bright) to 4 (dim). The - // range of star and planet magnitudes can actually go - // outside of this, but for our purpose, if it is brighter - // that -1, we'll color it full white/alpha anyway and 4 - // is a convenient cutoff point which keeps the number of - // stars drawn at about 500. - - // color (magnitude) - mag = star_data[i][2]; - if ( mag < cutoff ) { - nmag = ( 4.5 - mag ) / 5.5; // translate to 0 ... 1.0 scale - // alpha = nmag * 0.7 + 0.3; // translate to a 0.3 ... 1.0 scale - alpha = nmag * 0.85 + 0.15; // translate to a 0.15 ... 1.0 scale - alpha *= factor; // dim when the sun is brighter - } else { - alpha = 0.0; - } - - if (alpha > 1.0) { alpha = 1.0; } - if (alpha < 0.0) { alpha = 0.0; } - - color = cl->get( i ); - sgSetVec4( color, 1.0, 1.0, 1.0, alpha ); - // cout << "alpha[" << i << "] = " << alpha << endl; - } - } else { - // cout << " no phase change, skipping" << endl; - } - - // cout << "min = " << min << " max = " << max << " count = " << num - // << endl; - - return true; -} - - -// reposition the stars for the specified time (GST rotation), -// offset by our current position (p) so that it appears fixed at a -// great distance from the viewer. -bool SGStars::reposition( sgVec3 p, double angle ) -{ - sgMat4 T1, GST; - sgVec3 axis; - - sgMakeTransMat4( T1, p ); - - sgSetVec3( axis, 0.0, 0.0, -1.0 ); - sgMakeRotMat4( GST, angle, axis ); - - sgMat4 TRANSFORM; - sgCopyMat4( TRANSFORM, T1 ); - sgPreMultMat4( TRANSFORM, GST ); - - sgCoord skypos; - sgSetCoord( &skypos, TRANSFORM ); - - stars_transform->setTransform( &skypos ); - - return true; -} diff --git a/simgear/sky/stars.hxx b/simgear/sky/stars.hxx deleted file mode 100644 index 4260aad4..00000000 --- a/simgear/sky/stars.hxx +++ /dev/null @@ -1,72 +0,0 @@ -// stars.hxx -- model the stars -// -// Written by Durk Talsma. Originally started October 1997, for distribution -// with the FlightGear project. Version 2 was written in August and -// September 1998. This code is based upon algorithms and data kindly -// provided by Mr. Paul Schlyter. (pausch@saaf.se). -// -// Separated out rendering pieces and converted to ssg by Curt Olson, -// March 2000 -// -// This library is free software; you can redistribute it and/or -// modify it under the terms of the GNU Library General Public -// License as published by the Free Software Foundation; either -// version 2 of the License, or (at your option) any later version. -// -// This library 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 -// Library General Public License for more details. -// -// You should have received a copy of the GNU Library General Public -// License along with this library; if not, write to the -// Free Software Foundation, Inc., 59 Temple Place - Suite 330, -// Boston, MA 02111-1307, USA. -// -// $Id$ - - -#ifndef _SG_STARS_HXX_ -#define _SG_STARS_HXX_ - - -#include - - -class SGStars { - - ssgTransform *stars_transform; - ssgSimpleState *state; - - ssgColourArray *cl; - ssgVertexArray *vl; - - int old_phase; // data for optimization - -public: - - // Constructor - SGStars( void ); - - // Destructor - ~SGStars( void ); - - // initialize the stars structure - ssgBranch *build( int num, sgdVec3 *star_data, double star_dist ); - - // repaint the planet magnitudes based on current value of - // sun_angle in degrees relative to verticle (so we can make them - // relatively dimmer during dawn and dusk - // 0 degrees = high noon - // 90 degrees = sun rise/set - // 180 degrees = darkest midnight - bool repaint( double sun_angle, int num, sgdVec3 *star_data ); - - // reposition the stars for the specified time (GST rotation), - // offset by our current position (p) so that it appears fixed at - // a great distance from the viewer. - bool reposition( sgVec3 p, double angle ); -}; - - -#endif // _SG_STARS_HXX_