// 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.
+// 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., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
//
// $Id$
+#ifdef HAVE_CONFIG_H
+# include <simgear_config.h>
+#endif
#include <simgear/compiler.h>
#include <stdio.h>
-#include STL_IOSTREAM
-
-#include <plib/sg.h>
-#include <plib/ssg.h>
+#include <iostream>
+
+#include <osg/Array>
+#include <osg/AlphaFunc>
+#include <osg/BlendFunc>
+#include <osg/CullFace>
+#include <osg/Geometry>
+#include <osg/Geode>
+#include <osg/Node>
+#include <osg/ShadeModel>
+#include <osg/TexEnv>
+#include <osg/Texture2D>
#include <simgear/constants.h>
+#include <simgear/screen/colors.hxx>
+#include <simgear/scene/model/model.hxx>
+#include <simgear/misc/PathOptions.hxx>
#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
-
+using namespace simgear;
// Constructor
-SGMoon::SGMoon( void ) {
+SGMoon::SGMoon( void ) :
+ prev_moon_angle(-1)
+{
}
// build the moon object
-ssgBranch * SGMoon::build( SGPath path, double moon_size ) {
+osg::Node*
+SGMoon::build( SGPath path, double moon_size ) {
+
+ osg::Node* orb = SGMakeSphere(moon_size, 15, 15);
+ osg::StateSet* stateSet = orb->getOrCreateStateSet();
+ stateSet->setRenderBinDetails(-5, "RenderBin");
// 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 );
+ osg::ref_ptr<osgDB::ReaderWriter::Options> options
+ = makeOptionsFromPath(path);
+
+ osg::Texture2D* texture = SGLoadTexture2D("moon.png", options.get());
+ stateSet->setTextureAttributeAndModes(0, texture, osg::StateAttribute::ON);
+ osg::TexEnv* texEnv = new osg::TexEnv;
+ texEnv->setMode(osg::TexEnv::MODULATE);
+ stateSet->setTextureAttribute(0, texEnv, osg::StateAttribute::ON);
+
+ orb_material = new osg::Material;
+ orb_material->setColorMode(osg::Material::DIFFUSE);
+ orb_material->setDiffuse(osg::Material::FRONT_AND_BACK,
+ osg::Vec4(1, 1, 1, 1));
+ orb_material->setAmbient(osg::Material::FRONT_AND_BACK,
+ osg::Vec4(0, 0, 0, 1));
+ orb_material->setEmission(osg::Material::FRONT_AND_BACK,
+ osg::Vec4(0, 0, 0, 1));
+ orb_material->setSpecular(osg::Material::FRONT_AND_BACK,
+ osg::Vec4(0, 0, 0, 1));
+ orb_material->setShininess(osg::Material::FRONT_AND_BACK, 0);
+ stateSet->setAttribute(orb_material.get());
+ stateSet->setMode(GL_LIGHTING, osg::StateAttribute::ON);
+ stateSet->setMode(GL_DEPTH_TEST, osg::StateAttribute::OFF);
+ stateSet->setMode(GL_FOG, osg::StateAttribute::OFF);
+ osg::ShadeModel* shadeModel = new osg::ShadeModel;
+ shadeModel->setMode(osg::ShadeModel::SMOOTH);
+ stateSet->setAttributeAndModes(shadeModel);
+ osg::CullFace* cullFace = new osg::CullFace;
+ cullFace->setMode(osg::CullFace::BACK);
+ stateSet->setAttributeAndModes(cullFace);
+
+ osg::BlendFunc* blendFunc = new osg::BlendFunc;
+ blendFunc->setFunction(osg::BlendFunc::SRC_ALPHA, osg::BlendFunc::ONE);
+ stateSet->setAttributeAndModes(blendFunc);
+
+ osg::AlphaFunc* alphaFunc = new osg::AlphaFunc;
+ alphaFunc->setFunction(osg::AlphaFunc::GREATER);
+ alphaFunc->setReferenceValue(0.01);
+ stateSet->setAttribute(alphaFunc);
+ stateSet->setMode(GL_ALPHA_TEST, osg::StateAttribute::ON);
// 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 = new osg::MatrixTransform;
- // moon_transform->addKid( halo );
- moon_transform->addKid( orb );
+ moon_transform->addChild( orb );
- return moon_transform;
+ return moon_transform.get();
}
// 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 );
+ if (prev_moon_angle == moon_angle)
+ return true;
- // temp test, forces the color to always be white
- // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
+ prev_moon_angle = moon_angle;
- 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 moon_factor = 4*cos(moon_angle);
+
+ if (moon_factor > 1) moon_factor = 1.0;
+ if (moon_factor < -1) moon_factor = -1.0;
+ moon_factor = moon_factor/2 + 0.5;
+
+ osg::Vec4 color;
+ color[1] = sqrt(moon_factor);
+ color[0] = sqrt(color[1]);
+ color[2] = moon_factor * moon_factor;
+ color[2] *= color[2];
+ color[3] = 1.0;
+
+ gamma_correct_rgb( color._v );
- float *ptr;
- ptr = cl->get( 0 );
- sgCopyVec4( ptr, color );
- }
+ orb_material->setDiffuse(osg::Material::FRONT_AND_BACK, color);
return true;
}
// 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,
+bool SGMoon::reposition( 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 );
+ osg::Matrix T2, RA, DEC;
- // xglTranslatef(0,moon_dist);
- sgSetVec3( v, 0.0, moon_dist, 0.0 );
- sgMakeTransMat4( T2, v );
+ RA.makeRotate(rightAscension - 90.0 * SGD_DEGREES_TO_RADIANS,
+ osg::Vec3(0, 0, 1));
- sgMat4 TRANSFORM;
- sgCopyMat4( TRANSFORM, T1 );
- sgPreMultMat4( TRANSFORM, GST );
- sgPreMultMat4( TRANSFORM, RA );
- sgPreMultMat4( TRANSFORM, DEC );
- sgPreMultMat4( TRANSFORM, T2 );
+ DEC.makeRotate(declination, osg::Vec3(1, 0, 0));
- sgCoord skypos;
- sgSetCoord( &skypos, TRANSFORM );
+ T2.makeTranslate(osg::Vec3(0, moon_dist, 0));
- moon_transform->setTransform( &skypos );
+ moon_transform->setMatrix(T2*DEC*RA);
return true;
}