1 /*
2 PLIB - A Suite of Portable Game Libraries
3 Copyright (C) 1998,2002 Steve Baker
4
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Library General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version.
9
10 This library is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 Library General Public License for more details.
14
15 You should have received a copy of the GNU Library General Public
16 License along with this library; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
19 For further information visit http://plib.sourceforge.net
20
21 $Id: ssgaStars.cxx 1798 2003-09-26 14:54:20Z sjbaker $
22 */
23
24 // Written by Durk Talsma. Originally started October 1997, for distribution
25 // with the FlightGear project. Version 2 was written in August and
26 // September 1998. This code is based upon algorithms and data kindly
27 // provided by Mr. Paul Schlyter. (pausch@saaf.se).
28 //
29 // Separated out rendering pieces and converted to ssg by Curt Olson,
30 // March 2000
31 //
32 // Moved into ssgAux, July 2003.
33
34 #include "ssgaSky.h"
35
36
ssgaStarPreDraw(ssgEntity * e)37 static int ssgaStarPreDraw( ssgEntity *e )
38 {
39 ssgLeaf *f = (ssgLeaf *)e;
40 if ( f -> hasState () ) f->getState()->apply() ;
41
42 glPushAttrib( GL_DEPTH_BUFFER_BIT | GL_FOG_BIT );
43
44 //glDisable( GL_DEPTH_TEST );
45 glDisable( GL_FOG );
46 // glBlendFunc ( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA ) ;
47
48 return true;
49 }
50
51
ssgaStarPostDraw(ssgEntity * e)52 static int ssgaStarPostDraw( ssgEntity *e )
53 {
54 glPopAttrib();
55
56 return true;
57 }
58
59
ssgaStars(void)60 ssgaStars::ssgaStars( void ) :
61 stars_transform(0),
62 old_phase(-1)
63 {
64 }
65
66
~ssgaStars(void)67 ssgaStars::~ssgaStars( void )
68 {
69 ssgDeRefDelete( stars_transform );
70 }
71
72
build(int num,sgdVec3 * star_data,double star_dist)73 ssgBranch * ssgaStars::build( int num, sgdVec3 *star_data, double star_dist )
74 {
75 sgVec4 color;
76
77 // clean-up previous
78 ssgDeRefDelete( stars_transform );
79
80 // create new
81 stars_transform = new ssgTransform;
82 stars_transform->ref();
83
84 if ( star_data == NULL )
85 ulSetError(UL_WARNING, "null star data passed to ssgaStars::build()");
86
87 // set up the orb state
88 state = new ssgSimpleState();
89 state->disable( GL_LIGHTING );
90 state->disable( GL_CULL_FACE );
91 state->disable( GL_TEXTURE_2D );
92 state->enable( GL_COLOR_MATERIAL );
93 state->setColourMaterial( GL_AMBIENT_AND_DIFFUSE );
94 state->setMaterial( GL_EMISSION, 0, 0, 0, 1 );
95 state->setMaterial( GL_SPECULAR, 0, 0, 0, 1 );
96 state->enable( GL_BLEND );
97 state->disable( GL_ALPHA_TEST );
98
99 vl = new ssgVertexArray( num );
100 cl = new ssgColourArray( num );
101 // cl = new ssgColourArray( 1 );
102 // sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
103 // cl->add( color );
104
105 // Build ssg structure
106 sgVec3 p;
107 for ( int i = 0; i < num; ++i ) {
108 // position seeded to arbitrary values
109 sgSetVec3( p,
110 (float)( star_dist * cos( star_data[i][0] )
111 * cos( star_data[i][1] )),
112 (float)( star_dist * sin( star_data[i][0] )
113 * cos( star_data[i][1] )),
114 (float)( star_dist * sin( star_data[i][1] )));
115 vl->add( p );
116
117 // color (magnitude)
118 sgSetVec4( color, 1.0, 1.0, 1.0, 1.0 );
119 cl->add( color );
120 }
121
122 ssgLeaf *stars_obj =
123 new ssgVtxTable ( GL_POINTS, vl, NULL, NULL, cl );
124 stars_obj->setState( state );
125 stars_obj->setCallback( SSG_CALLBACK_PREDRAW, ssgaStarPreDraw );
126 stars_obj->setCallback( SSG_CALLBACK_POSTDRAW, ssgaStarPostDraw );
127
128 stars_transform->addKid( stars_obj );
129
130 return stars_transform;
131 }
132
133
reposition(sgVec3 p,double angle)134 bool ssgaStars::reposition( sgVec3 p, double angle )
135 {
136 sgMat4 T1, GST;
137 sgVec3 axis;
138
139 sgMakeTransMat4( T1, p );
140
141 sgSetVec3( axis, 0.0, 0.0, -1.0 );
142 sgMakeRotMat4( GST, (float)angle, axis );
143
144 sgMat4 TRANSFORM;
145 sgCopyMat4( TRANSFORM, T1 );
146 sgPreMultMat4( TRANSFORM, GST );
147
148 sgCoord skypos;
149 sgSetCoord( &skypos, TRANSFORM );
150
151 stars_transform->setTransform( &skypos );
152
153 return true;
154 }
155
156
repaint(double sol_angle,int num,sgdVec3 * star_data)157 bool ssgaStars::repaint( double sol_angle, int num, sgdVec3 *star_data )
158 {
159 double mag, nmag, alpha, factor, cutoff;
160 float *color;
161
162 int phase;
163
164 // determine which star structure to draw
165 if ( sol_angle > (0.5 * SGD_PI + 10.0 * SGD_DEGREES_TO_RADIANS ) ) {
166 // deep night
167 factor = 1.0;
168 cutoff = 4.5;
169 phase = 0;
170 }
171 else if ( sol_angle > (0.5 * SGD_PI + 8.8 * SGD_DEGREES_TO_RADIANS ) ) {
172 factor = 1.0;
173 cutoff = 3.8;
174 phase = 1;
175 }
176 else if ( sol_angle > (0.5 * SGD_PI + 7.5 * SGD_DEGREES_TO_RADIANS ) ) {
177 factor = 0.95;
178 cutoff = 3.1;
179 phase = 2;
180 }
181 else if ( sol_angle > (0.5 * SGD_PI + 7.0 * SGD_DEGREES_TO_RADIANS ) ) {
182 factor = 0.9;
183 cutoff = 2.4;
184 phase = 3;
185 }
186 else if ( sol_angle > (0.5 * SGD_PI + 6.5 * SGD_DEGREES_TO_RADIANS ) ) {
187 factor = 0.85;
188 cutoff = 1.8;
189 phase = 4;
190 }
191 else if ( sol_angle > (0.5 * SGD_PI + 6.0 * SGD_DEGREES_TO_RADIANS ) ) {
192 factor = 0.8;
193 cutoff = 1.2;
194 phase = 5;
195 }
196 else if ( sol_angle > (0.5 * SGD_PI + 5.5 * SGD_DEGREES_TO_RADIANS ) ) {
197 factor = 0.75;
198 cutoff = 0.6;
199 phase = 6;
200 }
201 else {
202 // early dusk or late dawn
203 factor = 0.7;
204 cutoff = 0.0;
205 phase = 7;
206 }
207
208 if( phase != old_phase ) {
209 old_phase = phase;
210 for ( int i = 0; i < num; ++i ) {
211 // if ( star_data[i][2] < min ) { min = star_data[i][2]; }
212 // if ( star_data[i][2] > max ) { max = star_data[i][2]; }
213
214 // magnitude ranges from -1 (bright) to 4 (dim). The
215 // range of star and planet magnitudes can actually go
216 // outside of this, but for our purpose, if it is brighter
217 // that -1, we'll color it full white/alpha anyway and 4
218 // is a convenient cutoff point which keeps the number of
219 // stars drawn at about 500.
220
221 // color (magnitude)
222 mag = star_data[i][2];
223 if ( mag < cutoff ) {
224 nmag = ( 4.5 - mag ) / 5.5; // translate to 0 ... 1.0 scale
225 // alpha = nmag * 0.7 + 0.3; // translate to a 0.3 ... 1.0 scale
226 alpha = nmag * 0.85 + 0.15; // translate to a 0.15 ... 1.0 scale
227 alpha *= factor; // dim when the sun is brighter
228 }
229 else {
230 alpha = 0.0;
231 }
232
233 if (alpha > 1.0) { alpha = 1.0; }
234 if (alpha < 0.0) { alpha = 0.0; }
235
236 color = cl->get( i );
237 sgSetVec4( color, 1.0, 1.0, 1.0, (float)alpha );
238 }
239 }
240
241 return true;
242 }
243