3
* Copyright (C) 2002 Fabien Chereau
5
* This program is free software; you can redistribute it and/or
6
* modify it under the terms of the GNU General Public License
7
* as published by the Free Software Foundation; either version 2
8
* of the License, or (at your option) any later version.
10
* This program 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
13
* GNU General Public License for more details.
15
* You should have received a copy of the GNU General Public License
16
* along with this program; if not, write to the Free Software
17
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21
#include "s_texture.h"
22
#include "stel_utility.h"
24
// rms added color as parameter
25
SkyGrid::SkyGrid(SKY_GRID_TYPE grid_type, unsigned int _nb_meridian, unsigned int _nb_parallel, double _radius,
26
unsigned int _nb_alt_segment, unsigned int _nb_azi_segment) :
27
nb_meridian(_nb_meridian), nb_parallel(_nb_parallel), radius(_radius),
28
nb_alt_segment(_nb_alt_segment), nb_azi_segment(_nb_azi_segment), color(0.2,0.2,0.2)
30
transparent_top = true;
34
case ALTAZIMUTAL : proj_func = &Projector::project_local; break;
35
case EQUATORIAL : proj_func = &Projector::project_earth_equ; break;
36
default : proj_func = &Projector::project_earth_equ;
39
// Alt points are the points to draw along the meridian
40
alt_points = new Vec3f*[nb_meridian];
41
for (unsigned int nm=0;nm<nb_meridian;++nm)
43
alt_points[nm] = new Vec3f[nb_alt_segment+1];
44
for (unsigned int i=0;i<nb_alt_segment+1;++i)
46
sphe_to_rect((float)nm/(nb_meridian)*2.f*M_PI,
47
(float)i/nb_alt_segment*M_PI-M_PI_2, alt_points[nm][i]);
48
alt_points[nm][i] *= radius;
52
// Alt points are the points to draw along the meridian
53
azi_points = new Vec3f*[nb_parallel];
54
for (unsigned int np=0;np<nb_parallel;++np)
56
azi_points[np] = new Vec3f[nb_azi_segment+1];
57
for (unsigned int i=0;i<nb_azi_segment+1;++i)
59
sphe_to_rect((float)i/(nb_azi_segment)*2.f*M_PI,
60
(float)(np+1)/(nb_parallel+1)*M_PI-M_PI_2, azi_points[np][i]);
61
azi_points[np][i] *= radius;
68
for (unsigned int nm=0;nm<nb_meridian;++nm)
70
delete [] alt_points[nm];
74
for (unsigned int np=0;np<nb_parallel;++np)
76
delete [] azi_points[np];
80
if (font) delete font;
85
void SkyGrid::set_font(float font_size, const string& font_name)
87
font = new s_font(font_size, font_name);
91
void SkyGrid::draw(const Projector* prj) const
93
if (!fader.getInterstate()) return;
95
glDisable(GL_TEXTURE_2D);
97
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
102
prj->set_orthographic_projection(); // set 2D coordinate
105
for (unsigned int nm=0;nm<nb_meridian;++nm)
107
if (transparent_top) // Transparency for the first and last points
109
if ((prj->*proj_func)(alt_points[nm][0], pt1) &&
110
(prj->*proj_func)(alt_points[nm][1], pt2) )
112
const double dx = pt1[0]-pt2[0];
113
const double dy = pt1[1]-pt2[1];
114
const double dq = dx*dx+dy*dy;
115
if (dq < 1024*1024) {
116
glColor4f(color[0],color[1],color[2],0.f);
119
glVertex2f(pt1[0],pt1[1]);
120
glColor4f(color[0],color[1],color[2],fader.getInterstate());
121
glVertex2f(pt2[0],pt2[1]);
126
glColor4f(color[0],color[1],color[2],fader.getInterstate());
128
for (unsigned int i=1;i<nb_alt_segment-1;++i)
130
if ((prj->*proj_func)(alt_points[nm][i], pt1) &&
131
(prj->*proj_func)(alt_points[nm][i+1], pt2) )
133
const double dx = pt1[0]-pt2[0];
134
const double dy = pt1[1]-pt2[1];
135
const double dq = dx*dx+dy*dy;
136
if (dq < 1024*1024) {
138
glVertex2f(pt1[0],pt1[1]);
139
glVertex2f(pt2[0],pt2[1]);
142
static char str[255]; // TODO use c++ string
144
glEnable(GL_TEXTURE_2D);
148
// TODO: allow for other numbers of meridians and parallels without
149
// screwing up labels?
150
if( gtype == EQUATORIAL && i == 8 ) {
152
// draw labels along equator for RA
153
const double d = sqrt(dq);
155
angle = acos((pt1[1]-pt2[1])/d);
156
if( pt1[0] < pt2[0] ) {
160
sprintf( str, "%dh", nm);
162
prj->set_orthographic_projection();
164
glTranslatef(pt2[0],pt2[1],0);
165
glRotatef(90+angle*180./M_PI,0,0,-1);
166
font->print(2,-2,str);
168
prj->reset_perspective_projection();
171
} else if (nm % 8 == 0 && i != 16) {
173
const double d = sqrt(dq);
175
angle = acos((pt1[1]-pt2[1])/d);
176
if( pt1[0] < pt2[0] ) {
180
sprintf( str, "%d", (i-8)*10);
182
if( gtype == ALTAZIMUTAL ||
183
(gtype == EQUATORIAL && i > 8)) {
187
prj->set_orthographic_projection();
189
glTranslatef(pt2[0],pt2[1],0);
190
glRotatef(angle*180./M_PI,0,0,-1);
191
font->print(2,-2,str);
192
prj->reset_perspective_projection();
195
glDisable(GL_TEXTURE_2D);
202
if ((prj->*proj_func)(alt_points[nm][nb_alt_segment-1], pt1) &&
203
(prj->*proj_func)(alt_points[nm][nb_alt_segment], pt2) )
205
const double dx = pt1[0]-pt2[0];
206
const double dy = pt1[1]-pt2[1];
207
const double dq = dx*dx+dy*dy;
208
if (dq < 1024*1024) {
209
glColor4f(color[0],color[1],color[2],fader.getInterstate());
211
glVertex2f(pt1[0],pt1[1]);
212
glColor4f(color[0],color[1],color[2],0.f);
213
glVertex2f(pt2[0],pt2[1]);
221
glColor4f(color[0],color[1],color[2],fader.getInterstate());
222
for (unsigned int i=0;i<nb_alt_segment;++i)
224
if ((prj->*proj_func)(alt_points[nm][i], pt1) &&
225
(prj->*proj_func)(alt_points[nm][i+1], pt2) )
227
const double dx = pt1[0]-pt2[0];
228
const double dy = pt1[1]-pt2[1];
229
const double dq = dx*dx+dy*dy;
230
if (dq < 1024*1024) {
232
glVertex2f(pt1[0],pt1[1]);
233
glVertex2f(pt2[0],pt2[1]);
242
glColor4f(color[0],color[1],color[2],fader.getInterstate());
243
for (unsigned int np=0;np<nb_parallel;++np)
245
for (unsigned int i=0;i<nb_azi_segment;++i)
247
if ((prj->*proj_func)(azi_points[np][i], pt1) &&
248
(prj->*proj_func)(azi_points[np][i+1], pt2) )
250
const double dx = pt1[0]-pt2[0];
251
const double dy = pt1[1]-pt2[1];
252
const double dq = dx*dx+dy*dy;
253
if (dq < 1024*1024) {
255
glVertex2f(pt1[0],pt1[1]);
256
glVertex2f(pt2[0],pt2[1]);
263
prj->reset_perspective_projection();
267
SkyLine::SkyLine(SKY_LINE_TYPE _line_type, double _radius, unsigned int _nb_segment) :
268
radius(_radius), nb_segment(_nb_segment), color(0.f, 0.f, 1.f), font(NULL)
270
float inclinaison = 0.f;
271
line_type = _line_type;
275
case LOCAL : proj_func = &Projector::project_local; break;
276
case MERIDIAN : proj_func = &Projector::project_local;
277
inclinaison = 90; break;
278
case ECLIPTIC : proj_func = &Projector::project_j2000;
279
inclinaison = 23.4392803055555555556; break;
280
case EQUATOR : proj_func = &Projector::project_earth_equ; break;
281
default : proj_func = &Projector::project_earth_equ;
284
Mat4f r = Mat4f::xrotation(inclinaison*M_PI/180.f);
286
// Ecliptic month labels need to be redone
287
// correct for month labels
288
// TODO: can make this more accurate
289
// if(line_type == ECLIPTIC ) r = r * Mat4f::zrotation(-77.9*M_PI/180.);
291
// Points to draw along the circle
292
points = new Vec3f[nb_segment+1];
293
for (unsigned int i=0;i<nb_segment+1;++i)
295
sphe_to_rect((float)i/(nb_segment)*2.f*M_PI, 0.f, points[i]);
297
points[i].transfo4d(r);
305
if (font) delete font;
309
void SkyLine::set_font(float font_size, const string& font_name)
311
if (font) delete font;
312
font = new s_font(font_size, font_name);
316
void SkyLine::draw(const Projector* prj) const
318
if (!fader.getInterstate()) return;
323
glColor4f(color[0], color[1], color[2], fader.getInterstate());
324
glDisable(GL_TEXTURE_2D);
326
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // Normal transparency mode
328
prj->set_orthographic_projection(); // set 2D coordinate
330
for (unsigned int i=0;i<nb_segment;++i)
332
if ((prj->*proj_func)(points[i], pt1) &&
333
(prj->*proj_func)(points[i+1], pt2) )
335
const double dx = pt1[0]-pt2[0];
336
const double dy = pt1[1]-pt2[1];
337
const double dq = dx*dx+dy*dy;
338
if (dq < 1024*1024) {
342
// TODO: allow for other numbers of meridians and parallels without
343
// screwing up labels?
346
glVertex2f(pt1[0],pt1[1]);
347
glVertex2f(pt2[0],pt2[1]);
351
if(line_type == MERIDIAN) {
352
const double d = sqrt(dq);
354
angle = acos((pt1[1]-pt2[1])/d);
355
if( pt1[0] < pt2[0] ) {
360
std::ostringstream oss;
362
if(i<=8) oss << (i+1)*10;
370
glTranslatef(pt2[0],pt2[1],0);
371
glRotatef(180+angle*180./M_PI,0,0,-1);
377
glEnable(GL_TEXTURE_2D);
379
if(font) font->print(2,-2,oss.str());
381
glDisable(GL_TEXTURE_2D);
386
if(line_type == EQUATOR && (i+1) % 2 == 0) {
388
const double d = sqrt(dq);
390
angle = acos((pt1[1]-pt2[1])/d);
391
if( pt1[0] < pt2[0] ) {
396
std::ostringstream oss;
398
if((i+1)/2 == 24) oss << "0h";
399
else oss << (i+1)/2 << "h";
402
glTranslatef(pt2[0],pt2[1],0);
403
glRotatef(180+angle*180./M_PI,0,0,-1);
409
glEnable(GL_TEXTURE_2D);
411
if(font) font->print(2,-2,oss.str());
413
glDisable(GL_TEXTURE_2D);
417
// Draw months on ecliptic
419
if(line_type == ECLIPTIC && (i+3) % 4 == 0) {
421
const double d = sqrt(dq);
423
angle = acos((pt1[1]-pt2[1])/d);
424
if( pt1[0] < pt2[0] ) {
429
std::ostringstream oss;
434
glTranslatef(pt2[0],pt2[1],0);
435
glRotatef(-90+angle*180./M_PI,0,0,-1);
437
glEnable(GL_TEXTURE_2D);
439
if(font) font->print(0,-2,oss.str());
441
glDisable(GL_TEXTURE_2D);
451
prj->reset_perspective_projection();
455
Cardinals::Cardinals(float _radius) : radius(_radius), font(NULL), color(0.6,0.2,0.2)
457
// Default labels - if sky locale specified, loaded later
458
// Improvement for gettext translation
465
Cardinals::~Cardinals()
467
if (font) delete font;
472
* Set the font for cardinal points
473
* @param font_size size in pixel
474
* @param font_name name of the font
476
void Cardinals::set_font(float font_size, const string& font_name)
478
font = new s_font(font_size, font_name);
482
// Draw the cardinals points : N S E W
483
// handles special cases at poles
484
void Cardinals::draw(const Projector* prj, double latitude, bool gravityON) const
487
if (!fader.getInterstate()) return;
497
// fun polar special cases
498
if(latitude == 90.0 ) d[0] = d[1] = d[2] = d[3] = sSouth;
499
if(latitude == -90.0 ) d[0] = d[1] = d[2] = d[3] = sNorth;
501
glColor4f(color[0],color[1],color[2],fader.getInterstate());
503
glEnable(GL_TEXTURE_2D);
504
// Normal transparency mode
505
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
510
prj->set_orthographic_projection();
512
float shift = font->getStrLen(sNorth)/2;
514
if (prj->getFlagGravityLabels())
517
pos.set(-1.f, 0.f, 0.22f);
518
if (prj->project_local(pos,xy)) prj->print_gravity180(font, xy[0], xy[1], d[0], -shift, -shift);
521
pos.set(1.f, 0.f, 0.22f);
522
if (prj->project_local(pos,xy)) prj->print_gravity180(font, xy[0], xy[1], d[1], -shift, -shift);
525
pos.set(0.f, 1.f, 0.22f);
526
if (prj->project_local(pos,xy)) prj->print_gravity180(font, xy[0], xy[1], d[2], -shift, -shift);
529
pos.set(0.f, -1.f, 0.22f);
530
if (prj->project_local(pos,xy)) prj->print_gravity180(font, xy[0], xy[1], d[3], -shift, -shift);
535
pos.set(-1.f, 0.f, 0.f);
536
if (prj->project_local(pos,xy)) font->print(xy[0]-shift, xy[1]-shift, d[0]);
539
pos.set(1.f, 0.f, 0.f);
540
if (prj->project_local(pos,xy)) font->print(xy[0]-shift, xy[1]-shift, d[1]);
543
pos.set(0.f, 1.f, 0.f);
544
if (prj->project_local(pos,xy)) font->print(xy[0]-shift, xy[1]-shift, d[2]);
547
pos.set(0.f, -1.f, 0.f);
548
if (prj->project_local(pos,xy)) font->print(xy[0]-shift, xy[1]-shift, d[3]);
551
prj->reset_perspective_projection();
554
// Translate cardinal labels with gettext to current sky language
555
void Cardinals::translateLabels(Translator& trans)
557
sNorth = trans.translate("N");
558
sSouth = trans.translate("S");
559
sEast = trans.translate("E");
560
sWest = trans.translate("W");
563
// Class which manages the displaying of the Milky Way
564
MilkyWay::MilkyWay(float _radius) : radius(_radius), color(1.f, 1.f, 1.f)
569
MilkyWay::~MilkyWay()
575
void MilkyWay::set_texture(const string& tex_file, bool blend)
578
tex = new s_texture(tex_file,!blend ? TEX_LOAD_TYPE_PNG_SOLID_REPEAT : TEX_LOAD_TYPE_PNG_BLEND3);
580
// big performance improvement to cache this
581
tex_avg_luminance = tex->get_average_luminance();
585
void MilkyWay::set_intensity(float _intensity)
587
intensity = _intensity;
590
void MilkyWay::draw(ToneReproductor * eye, const Projector* prj, const Navigator* nav) const
592
assert(tex); // A texture must be loaded before calling this
593
// Scotopic color = 0.25, 0.25 in xyY mode. Global stars luminance ~= 0.001 cd/m^2
594
Vec3f c = Vec3f(0.25f*fader.getInterstate(), 0.25f*fader.getInterstate(),
595
intensity*0.002f*fader.getInterstate()/tex_avg_luminance);
598
glEnable(GL_CULL_FACE);
599
glEnable(GL_TEXTURE_2D);
601
glBindTexture(GL_TEXTURE_2D, tex->getID());
603
prj->sSphere(radius,1.0,20,20,
604
nav->get_j2000_to_eye_mat()*
605
Mat4d::xrotation(M_PI/180*23)*
606
Mat4d::yrotation(M_PI/180*120)*
607
Mat4d::zrotation(M_PI/180*7), 1);
609
glDisable(GL_CULL_FACE);
612
void MilkyWay::draw_chart(ToneReproductor * eye, const Projector* prj, const Navigator* nav)
614
assert(tex); // A texture must be loaded before calling this
617
glEnable(GL_CULL_FACE);
618
glEnable(GL_TEXTURE_2D);
620
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
621
glBindTexture(GL_TEXTURE_2D, tex->getID());
623
prj->sSphere(radius,1.0,20,20,
624
nav->get_j2000_to_eye_mat()*
625
Mat4d::xrotation(M_PI/180*23)*
626
Mat4d::yrotation(M_PI/180*120)*
627
Mat4d::zrotation(M_PI/180*7), 1);
629
glDisable(GL_CULL_FACE);
632
// Draw a point... (used for tests)
633
void Draw::drawPoint(float X,float Y,float Z)
635
glColor3f(0.8, 1.0, 0.8);
636
glDisable(GL_TEXTURE_2D);
637
//glEnable(GL_BLEND);