From: curt Date: Thu, 16 Mar 2000 03:17:04 +0000 (+0000) Subject: Complete overhaul of the sky/sun/moon/stars/planets. It is now an ssg X-Git-Url: https://git.mxchange.org/?a=commitdiff_plain;h=427f309aeab8afc80c3ced99ea03233033a1ea9e;p=simgear.git Complete overhaul of the sky/sun/moon/stars/planets. It is now an ssg model that get's inserted into the scene graph. --- diff --git a/simgear/sky/Makefile.am b/simgear/sky/Makefile.am index fe5d1b12..d71c6201 100644 --- a/simgear/sky/Makefile.am +++ b/simgear/sky/Makefile.am @@ -1,9 +1,11 @@ noinst_LIBRARIES = libSky.a libSky_a_SOURCES = \ - skydome.cxx skydome.hxx \ - skymoon.cxx skymoon.hxx \ - skysun.cxx skysun.hxx \ - sphere.cxx sphere.hxx + dome.cxx dome.hxx \ + moon.cxx moon.hxx \ + oursun.cxx oursun.hxx \ + sky.cxx sky.hxx \ + sphere.cxx sphere.hxx \ + stars.cxx stars.hxx INCLUDES += -I$(top_builddir) -I$(top_builddir)/src diff --git a/simgear/sky/dome.cxx b/simgear/sky/dome.cxx new file mode 100644 index 00000000..6f2a2c59 --- /dev/null +++ b/simgear/sky/dome.cxx @@ -0,0 +1,512 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifdef HAVE_CONFIG_H +# include +#endif + +#ifdef HAVE_WINDOWS_H +# include +#endif + +#include + +#include +#include + +#include +#include +#include + +#include "dome.hxx" + + +#ifdef __MWERKS__ +# pragma global_optimizer off +#endif + + +// in meters of course +#define CENTER_ELEV 25000.0 + +#define UPPER_RADIUS 50000.0 +#define UPPER_ELEV 20000.0 + +#define MIDDLE_RADIUS 70000.0 +#define MIDDLE_ELEV 8000.0 + +#define LOWER_RADIUS 80000.0 +#define LOWER_ELEV 0.0 + +#define BOTTOM_RADIUS 50000.0 +#define BOTTOM_ELEV -2000.0 + + +// Set up dome rendering callbacks +static int sgSkyDomePreDraw( ssgEntity *e ) { + /* cout << endl << "Dome Pre Draw" << endl << "----------------" + << endl << endl; */ + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + + return true; +} + +static int sgSkyDomePostDraw( ssgEntity *e ) { + /* cout << endl << "Dome Post Draw" << endl << "----------------" + << endl << endl; */ + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + + return true; +} + + +// Constructor +SGSkyDome::SGSkyDome( void ) { +} + + +// Destructor +SGSkyDome::~SGSkyDome( void ) { +} + + +// initialize the sky object and connect it into our scene graph +ssgBranch * SGSkyDome::build( ) { + 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->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 ); + + for ( i = 0; i < 12; i++ ) { + theta = (i * 30.0) * DEG_TO_RAD; + + sgSetVec3( upper_vertex[i], + cos(theta) * UPPER_RADIUS, + sin(theta) * UPPER_RADIUS, + UPPER_ELEV ); + + sgSetVec3( middle_vertex[i], + cos((double)theta) * MIDDLE_RADIUS, + sin((double)theta) * MIDDLE_RADIUS, + MIDDLE_ELEV ); + + sgSetVec3( lower_vertex[i], + cos((double)theta) * LOWER_RADIUS, + sin((double)theta) * LOWER_RADIUS, + LOWER_ELEV ); + + sgSetVec3( bottom_vertex[i], + cos((double)theta) * BOTTOM_RADIUS, + sin((double)theta) * BOTTOM_RADIUS, + BOTTOM_ELEV ); + } + + // 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 + sgVec3 fog_color; + sgSetVec3( fog_color, 1.0, 1.0, 1.0 ); + repaint( color, fog_color, 0.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 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 upper_color[12]; + sgVec4 middle_color[12]; + sgVec4 lower_color[12]; + sgVec4 bottom_color[12]; + + 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 * 0.3; + middle_color[i][j] = sky_color[j] - diff * 0.9 + 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.1 ) { upper_color[i][j] = 0.1; } + if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } + if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; } + if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } + if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; } + } + 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 * 0.3; + middle_color[i][j] = sky_color[j] - diff * 0.9 + 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.1 ) { upper_color[i][j] = 0.1; } + if ( middle_color[i][j] > 1.0 ) { middle_color[i][j] = 1.0; } + if ( middle_color[i][j] < 0.1 ) { middle_color[i][j] = 0.1; } + if ( lower_color[i][j] > 1.0 ) { lower_color[i][j] = 1.0; } + if ( lower_color[i][j] < 0.1 ) { lower_color[i][j] = 0.1; } + } + 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, sky_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", FG_Longitude * RAD_TO_DEG, + // FG_Latitude * RAD_TO_DEG); + // xglRotatef( f->get_Longitude() * RAD_TO_DEG, 0.0, 0.0, 1.0 ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( LON, lon * RAD_TO_DEG, axis ); + + // xglRotatef( 90.0 - f->get_Latitude() * RAD_TO_DEG, 0.0, 1.0, 0.0 ); + sgSetVec3( axis, 0.0, 1.0, 0.0 ); + sgMakeRotMat4( LAT, 90.0 - lat * RAD_TO_DEG, axis ); + + // xglRotatef( l->sun_rotation * RAD_TO_DEG, 0.0, 0.0, 1.0 ); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( SPIN, spin * RAD_TO_DEG, 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 new file mode 100644 index 00000000..e90f8976 --- /dev/null +++ b/simgear/sky/dome.hxx @@ -0,0 +1,83 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _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(); + + // 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 ); + + // 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 new file mode 100644 index 00000000..d4e8883c --- /dev/null +++ b/simgear/sky/moon.cxx @@ -0,0 +1,272 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#include +#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; */ + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE ) ; + // sgVec4 color; + // sgSetVec4( color, 0.0, 0.0, 0.0, 1.0 ); + // glMaterialfv ( GL_FRONT_AND_BACK, GL_AMBIENT, color ) ; + + return true; +} + +static int sgMoonOrbPostDraw( ssgEntity *e ) { + /* cout << endl << "Moon orb post draw" << endl << "----------------" + << endl << endl; */ + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ; + + return true; +} + +static int sgMoonHaloPreDraw( ssgEntity *e ) { + /* cout << endl << "Moon halo pre draw" << endl << "----------------" + << endl << 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 ) ; + + return true; +} + + +// Constructor +SGMoon::SGMoon( void ) { +} + + +// Destructor +SGMoon::~SGMoon( void ) { +} + + +// build the moon object +ssgBranch * SGMoon::build( FGPath 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.0, 0.0, 1.0 ); + orb_state->setMaterial( GL_SPECULAR, 0.0, 0.0, 0.0, 1.0 ); + 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 * RAD_TO_DEG < 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 ); + + 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(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( RA, (rightAscension * RAD_TO_DEG) - 90.0, axis ); + + // xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0); + sgSetVec3( axis, 1.0, 0.0, 0.0 ); + sgMakeRotMat4( DEC, declination * RAD_TO_DEG, axis ); + + // xglTranslatef(0,60000,0); + sgSetVec3( v, 0.0, 60000.0, 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 new file mode 100644 index 00000000..4c705bd0 --- /dev/null +++ b/simgear/sky/moon.hxx @@ -0,0 +1,76 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _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( FGPath 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 new file mode 100644 index 00000000..80d12c07 --- /dev/null +++ b/simgear/sky/oursun.cxx @@ -0,0 +1,364 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#include +#include + +#include + +#include + +#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; */ + glDisable( GL_DEPTH_TEST ); + glDisable( GL_FOG ); + + return true; +} + +static int sgSunOrbPostDraw( ssgEntity *e ) { + /* cout << endl << "Sun orb post draw" << endl << "----------------" + << endl << endl; */ + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + + return true; +} + +static int sgSunHaloPreDraw( ssgEntity *e ) { + /* cout << endl << "Sun halo pre draw" << endl << "----------------" + << endl << 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; */ + glEnable( GL_DEPTH_TEST ); + glEnable( GL_FOG ); + + return true; +} + + +// Constructor +SGSun::SGSun( void ) { +} + + +// Destructor +SGSun::~SGSun( void ) { +} + + +#if 0 +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( FGPath 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->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->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->setTexture( sun_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->enable( GL_COLOR_MATERIAL ); + halo_state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE ); + 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; + + sun_transform->addKid( halo ); + halo->setCallback( SSG_CALLBACK_PREDRAW, sgSunHaloPreDraw ); + halo->setCallback( SSG_CALLBACK_POSTDRAW, sgSunHaloPostDraw ); + sun_transform->addKid( orb ); + + 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 * RAD_TO_DEG < 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 ); + + 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(((RAD_TO_DEG * rightAscension)- 90.0), 0.0, 0.0, 1.0); + sgSetVec3( axis, 0.0, 0.0, 1.0 ); + sgMakeRotMat4( RA, (rightAscension * RAD_TO_DEG) - 90.0, axis ); + + // xglRotatef((RAD_TO_DEG * declination), 1.0, 0.0, 0.0); + sgSetVec3( axis, 1.0, 0.0, 0.0 ); + sgMakeRotMat4( DEC, declination * RAD_TO_DEG, axis ); + + // xglTranslatef(0,60000,0); + sgSetVec3( v, 0.0, 60000.0, 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 new file mode 100644 index 00000000..c9a6f8d9 --- /dev/null +++ b/simgear/sky/oursun.hxx @@ -0,0 +1,79 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _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( FGPath 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 new file mode 100644 index 00000000..3033e3b7 --- /dev/null +++ b/simgear/sky/sky.cxx @@ -0,0 +1,117 @@ +// 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#include // plib include + +#include "sky.hxx" + + +// Constructor +SGSky::SGSky( void ) { +} + + +// Destructor +SGSky::~SGSky( void ) { +} + + +// initialize the sky and connect the components to the scene graph at +// the provided branch +ssgBranch * SGSky::build( double sun_size, double moon_size, + int nplanets, sgdVec3 *planet_data, + double planet_dist, + int nstars, sgdVec3 *star_data, double star_dist ) +{ + sky_selector = new ssgSelector; + sky_transform = new ssgTransform; + + dome = new SGSkyDome; + sky_transform -> addKid( dome->build() ); + + planets = new SGStars; + sky_transform -> addKid( planets->build(nplanets, planet_data, + planet_dist) + ); + + stars = new SGStars; + sky_transform -> addKid( stars->build(nstars, star_data, star_dist) ); + + moon = new SGMoon; + sky_transform -> addKid( moon->build(tex_path, moon_size) ); + + oursun = new SGSun; + sky_transform -> addKid( oursun->build(tex_path, sun_size) ); + + sky_selector->addKid( sky_transform ); + sky_selector->clrTraversalMaskBits( SSGTRAV_HOT ); + + return sky_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 ) +{ + dome->repaint( sky_color, fog_color, sun_angle ); + oursun->repaint( sun_angle ); + moon->repaint( moon_angle ); + planets->repaint( sun_angle, nplanets, planet_data ); + stars->repaint( sun_angle, nstars, star_data ); + + 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, + double lon, double lat, 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 ); + + return true; +} diff --git a/simgear/sky/sky.hxx b/simgear/sky/sky.hxx new file mode 100644 index 00000000..355fe14b --- /dev/null +++ b/simgear/sky/sky.hxx @@ -0,0 +1,113 @@ +// sky.hxx -- 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 program is free software; you can redistribute it and/or +// modify it under the terms of the GNU General Public License as +// published by the Free Software Foundation; either version 2 of the +// License, or (at your option) any later version. +// +// This program is distributed in the hope that it will be useful, but +// WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// General Public License for more details. +// +// You should have received a copy of the GNU General Public License +// along with this program; if not, write to the Free Software +// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +// +// $Id$ + + +#ifndef _SG_SKY_HXX +#define _SG_SKY_HXX + + +#ifndef __cplusplus +# error This library requires C++ +#endif + + +#include // plib include + +#include + +#include "dome.hxx" +#include "moon.hxx" +#include "oursun.hxx" +#include "stars.hxx" + + +class SGSky { + + // components of the sky + SGSkyDome *dome; + SGSun *oursun; + SGMoon *moon; + SGStars *planets; + SGStars *stars; + + ssgSelector *sky_selector; + ssgTransform *sky_transform; + + FGPath tex_path; + +public: + + // Constructor + SGSky( void ); + + // Destructor + ~SGSky( void ); + + // initialize the sky and connect the components to the scene + // graph at the provided branch + ssgBranch *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. + // + // sun angle in degrees relative to verticle + // 0 degrees = high noon + // 90 degrees = sun rise/set + // 180 degrees = darkest midnight + 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. + bool reposition( sgVec3 view_pos, sgVec3 zero_elev, + double lon, double lat, double spin, + double gst, + double sun_ra, double sun_dec, double sun_dist, + double moon_ra, double moon_dec, double moon_dist ); + + // specify the texture path (optional, defaults to current directory) + inline void texture_path( const string& path ) { + tex_path = FGPath( path ); + } + + // enable the sky in the scene graph (default) + inline void enable() { sky_selector->select( 1 ); } + + // disable 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() { sky_selector->select( 0 ); } +}; + + +#endif // _SG_SKY_HXX + + diff --git a/simgear/sky/skydome.cxx b/simgear/sky/skydome.cxx deleted file mode 100644 index a834ada9..00000000 --- a/simgear/sky/skydome.cxx +++ /dev/null @@ -1,808 +0,0 @@ -// skydome.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 program is free software; you can redistribute it and/or -// modify it under the terms of the GNU General Public License as -// published by the Free Software Foundation; either version 2 of the -// License, or (at your option) any later version. -// -// This program is distributed in the hope that it will be useful, but -// WITHOUT ANY WARRANTY; without even the implied warranty of -// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU -// General Public License for more details. -// -// You should have received a copy of the GNU General Public License -// along with this program; if not, write to the Free Software -// Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. -// -// $Id$ - - -#ifdef HAVE_CONFIG_H -# include -#endif - -#ifdef HAVE_WINDOWS_H -# include -#endif - -#include - -#include -#include - -#include -#include -#include - -// #include -// #include -// #include
-// #include