Select Git revision
test_LLO.py
Forked from
finesse / pykat
Source project has a limited visibility.
-
Andreas Freise authoredAndreas Freise authored
Starsphere.cpp 23.02 KiB
#include "Starsphere.h"
Starsphere::Starsphere() : AbstractGraphicsEngine()
{
Axes=0, Stars=0, Constellations=0, Pulsars=0;
LLOmarker=0, LHOmarker=0, GEOmarker=0;
sphGrid=0, SNRs=0, SearchMarker=0;
/**
* Parameters and State info
*/
sphRadius = 5.5;
featureFlags = 0;
/**
* Viewpoint (can be changed with mouse)
*/
viewpt_azimuth = 30.0;
viewpt_elev = 23.6;
viewpt_radius = 7.6;
wobble_amp = 37.0;
wobble_period = 17.0;
zoom_amp = 0.00;
zoom_period = 29.0;
rotation_offset = 0.0;
rotation_speed = 180.0;
m_RefreshSearchMarker = true;
}
Starsphere::~Starsphere()
{
if(m_PolygonFont) delete m_PolygonFont;
}
/**
* sphVertex3D() creates a GL vertex in 3D sky sphere coordinates
* sphVertex() creates a GL vertex on the surface of the sky sphere.
* Use either like glVertex().
*/
void Starsphere::sphVertex3D(GLfloat RAdeg, GLfloat DEdeg, GLfloat radius)
{
GLfloat x, y, z;
x = radius * COS(DEdeg) * COS(RAdeg);
z = -radius * COS(DEdeg) * SIN(RAdeg);
y = radius * SIN(DEdeg);
glVertex3f(x, y, z);
return;
}
void Starsphere::sphVertex(GLfloat RAdeg, GLfloat DEdeg)
{
sphVertex3D(RAdeg, DEdeg, sphRadius);
}
/**
* Star Marker:
* Makes a marker for one star at a given position and angular size.
*/
void Starsphere::star_marker(float RAdeg, float DEdeg, float size)
{
glPointSize((GLfloat) size);
glBegin(GL_POINTS);
sphVertex((GLfloat) RAdeg, (GLfloat) DEdeg);
glEnd();
return;
}
/**
* Create Stars: markers for each star
*/
void Starsphere::make_stars()
{
GLfloat mag_size;
int i, j;
bool is_dupe;
int Ndupes=0;
if (!Stars)
Stars = glGenLists(1);
glNewList(Stars, GL_COMPILE);
glColor3f(1.0, 1.0, 1.0);
/**
* At some point in the future star_info[][] will also contain
* star magnitude and the marker size will vary with this.
*/
for (i=0; i < Nstars; i++) {
// same stars appear more than once in constallations so ignore dupes
is_dupe=false;
for (j=0; j< i; j++) {
if (star_info[j][0] == star_info[i][0] && star_info[j][0]
== star_info[i][0]) {
is_dupe=true;
Ndupes++;
break;
}
}
if (!is_dupe) {
// mag_size = 0.05 + 0.50*rand()/RAND_MAX;
mag_size = 4.0;
star_marker(star_info[i][0], star_info[i][1], mag_size);
}
}
glEndList();
}
/**
* Pulsar Markers:
*/
void Starsphere::make_pulsars()
{
GLfloat mag_size=3.0;
int i;
if (!Pulsars)
Pulsars = glGenLists(1);
glNewList(Pulsars, GL_COMPILE);
glColor3f(0.80, 0.0, 0.85); // _P_ulsars are _P_urple
for (i=0; i < Npulsars; i++) {
star_marker(pulsar_info[i][0], pulsar_info[i][1], mag_size);
}
glEndList();
}
/**
* Super Novae Remenants (SNRs):
*/
void Starsphere::make_snrs()
{
GLfloat mag_size=3.0;
int i;
if (!SNRs)
SNRs = glGenLists(1);
glNewList(SNRs, GL_COMPILE);
glColor3f(0.7, 0.176, 0.0); // _S_NRs are _S_ienna
for (i=0; i < NSNRs; i++) {
star_marker(SNR_info[i][0], SNR_info[i][1], mag_size);
}
glEndList();
}
/**
* Create Constellations:
* draws line links between pairs of stars in the list.
*/
void Starsphere::make_constellations()
{
GLint star_num=0;
if (!Constellations)
Constellations = glGenLists(1);
glNewList(Constellations, GL_COMPILE);
glLineWidth(1.0);
glColor3f(0.7, 0.7, 0.0); // light yellow
glBegin(GL_LINES); // draws lines between *pairs* of vertices
for (star_num=0; star_num < Nstars; ++star_num) {
sphVertex(star_info[star_num][0], star_info[star_num][1]);
star_num++;
sphVertex(star_info[star_num][0], star_info[star_num][1]);
}
glEnd();
glEndList();
}
/**
* Create markers on sky sphere for LLO, LHO, and GEO
* IFO corner positions are from Myers' personal GPS and are +/- 100m
*/
/**
* RAofZenith(time, longitude)
*
* Computes the Right Ascention of the zenith at a given time (from
* the Unix epoch, in seconds) at a given Longitude (in degrees). From
* 'The Cambridge Handbook of Physics Formulas', Graham Woan, 2003
* edition, CUP. (NOT the first edition), p177.
*/
GLfloat Starsphere::RAofZenith(double T, GLfloat LONdeg)
{
// unix epoch at 12h 1/1/2000
const double T_0 = 946728000.0;
// UT seconds of the day
double T_s = fmod(T, 24.0*3600.0);
// Julian centuries since 12h 1/1/2000 and 0h today
double T_c = (T - T_s - T_0)/3155760000.0;
// GMST at 0h today in seconds
double GMST0 = 6.0*3600.0 + 41.0*60.0 + 50.54841 + (8640184.812866
+ 0.093104*T_c)*T_c;
// GMST now in seconds
double GMST = GMST0 + 1.002738*T_s;
// longitude defined as west positive
GLfloat alpha = (GMST/(24.0*3600.0))*360.0 - LONdeg;
return alpha;
}
/**
* Draw the observatories at their zenith positions
*/
void Starsphere::make_obs()
{
GLfloat Lat, Lon; // Latitute/Longitude of IFO is
GLfloat RAdeg, DEdeg; // converted to RA/DEC of sky sphere position
GLfloat radius; // radius of sphere for obs
GLfloat arm_len_deg=3.000; // lenght of arms, in degrees (not to scale)
GLfloat h2=0.400; // slight offset for H2 arms
// get current time and UTC offset (for zenith position)
m_ObservatoryDrawTimeLocal = dtime();
time_t local = m_ObservatoryDrawTimeLocal;
tm *utc = gmtime(&local);
double utcOffset = difftime(local, mktime(utc));
double observatoryDrawTimeGMT = m_ObservatoryDrawTimeLocal - utcOffset;
radius = 1.0*sphRadius; // radius of sphere on which they are drawn
float lineSize = 4.0;
/**
* LIGO Livingston Observatory:
*/
Lat= 30.56377;
Lon= 90.77408;
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
if (!LLOmarker)
LLOmarker = glGenLists(1);
glNewList(LLOmarker, GL_COMPILE);
glColor3f(0.0, 1.0, 0.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg-arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// East/West arm:
sphVertex3D(RAdeg-arm_len_deg, DEdeg, radius);
glEnd();
// arm joint H2
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
glEndList();
/**
* LIGO Hanford Observatory: H1 and H2
*/
Lat= 46.45510;
Lon= 119.40627;
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
if (!LHOmarker)
LHOmarker = glGenLists(1);
glNewList(LHOmarker, GL_COMPILE);
glColor3f(0.0, 0.0, 1.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg+arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// East/West arm:
sphVertex3D(RAdeg-arm_len_deg, DEdeg, radius);
glEnd();
glBegin(GL_LINE_STRIP);
// North/South arm, H2:
sphVertex3D(RAdeg-h2, DEdeg+arm_len_deg/2.0+h2/2.0, radius);
sphVertex3D(RAdeg-h2, DEdeg+h2/2.0, radius);
// East/West arm, H2;
sphVertex3D(RAdeg-arm_len_deg/2.0-h2, DEdeg+h2/2.0, radius);
glEnd();
// arm joint H1
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
// arm joint H2
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg-h2, DEdeg+h2/2.0, radius);
glEnd();
glEndList();
/**
* GEO600 Interferometer:
*/
Lat= 52.24452;
Lon= -9.80683;
arm_len_deg=1.50; // not to scale
RAdeg= RAofZenith(observatoryDrawTimeGMT, Lon);
DEdeg= Lat;
if (!GEOmarker)
GEOmarker = glGenLists(1);
glNewList(GEOmarker, GL_COMPILE);
glColor3f(1.0, 0.0, 0.0);
glLineWidth(lineSize);
glBegin(GL_LINE_STRIP);
// North/South arm:
sphVertex3D(RAdeg, DEdeg+arm_len_deg, radius);
sphVertex3D(RAdeg, DEdeg, radius);
// West/East arm:
sphVertex3D(RAdeg+arm_len_deg, DEdeg, radius);
glEnd();
// arm joint
glPointSize((GLfloat) lineSize);
glBegin(GL_POINTS);
sphVertex3D(RAdeg, DEdeg, radius);
glEnd();
glEndList();
return;
}
void Starsphere::make_search_marker(GLfloat RAdeg, GLfloat DEdeg, GLfloat size)
{
GLfloat x, y;
GLfloat r1, r2, r3;
float theta;
int i, Nstep=20;
// r1 is inner circle, r2 is outer circle, r3 is crosshairs
r1 = size, r2=3*size, r3=4*size;
// delete any existing marker, then create a new one
if (SearchMarker) {
glDeleteLists(SearchMarker, SearchMarker);
}
SearchMarker = glGenLists(1);
glNewList(SearchMarker, GL_COMPILE);
// start gunsight drawing
glPushMatrix();
glLineWidth(3.0);
glColor3f(1.0, 0.5, 0.0); // Orange
// First rotate east to the RA position around y
glRotatef(RAdeg, 0.0, 1.0, 0.0);
// Then rotate up to DEC position around z (not x)
glRotatef(DEdeg, 0.0, 0.0, 1.0);
// Inner circle
glBegin(GL_LINE_LOOP);
for (i=0; i<Nstep; i++) {
theta = i*360.0/Nstep;
x = r1*COS(theta);
y = r1*SIN(theta);
sphVertex(x, y);
}
glEnd();
// Outer circle
glBegin(GL_LINE_LOOP);
for (i=0; i<Nstep; i++) {
theta = i*360.0/Nstep;
x = r2*COS(theta);
y = r2*SIN(theta);
sphVertex(x, y);
}
glEnd();
// Arms that form the gunsight
glBegin(GL_LINES);
// North arm:
sphVertex(0.0, +r1);
sphVertex(0.0, +r3);
// South arm:
sphVertex(0.0, -r1);
sphVertex(0.0, -r3);
// East arm:
sphVertex(-r1, 0.0);
sphVertex(-r3, 0.0);
// West arm:
sphVertex(+r1, 0.0);
sphVertex(+r3, 0.0);
glEnd();
glPopMatrix();
// searchlight line out to marker (OFF!)
if (false) {
glBegin(GL_LINES);
sphVertex3D(RAdeg, DEdeg, 0.50*sphRadius);
sphVertex3D(RAdeg, DEdeg, 0.95*sphRadius);
glEnd();
}
glEndList();
}
/**
* XYZ coordinate axes: (if we want them - most useful for testing)
*/
void Starsphere::make_axes()
{
GLfloat axl=10.0;
if (!Axes)
Axes = glGenLists(1);
glNewList(Axes, GL_COMPILE);
glLineWidth(2.0);
glBegin(GL_LINES);
glColor3f(1.0, 0.0, 0.0);
glVertex3f(-axl, 0.0, 0.0);
glVertex3f(axl, 0.0, 0.0);
glColor3f(0.0, 1.0, 0.0);
glVertex3f(0.0, -axl, 0.0);
glVertex3f(0.0, axl, 0.0);
glColor3f(0.0, 0.0, 1.0);
glVertex3f(0.0, 0.0, -axl);
glVertex3f(0.0, 0.0, axl);
glEnd();
glEndList();
}
/**
* RA/DEC coordinate grid on the sphere
*/
void Starsphere::make_globe()
{
int hr, j, i, iMax=100;
GLfloat RAdeg, DEdeg;
if (!sphGrid)
sphGrid = glGenLists(1);
glNewList(sphGrid, GL_COMPILE);
glLineWidth(1.0);
// Lines of constant Right Ascencion (East Longitude)
for (hr=0; hr<24; hr++) {
RAdeg=hr*15.0;
glColor3f(0.25, 0.25, 0.25);
if (hr==0)
glColor3f(0.55, 0.55, 0.55);
glBegin(GL_LINE_STRIP);
for (i=0; i<=iMax; i++) {
DEdeg = i*180.0/iMax - 90.0;
sphVertex(RAdeg, DEdeg);
}
glEnd();
}
// Lines of constant Declination (Lattitude)
for (j=1; j<=12; j++) {
DEdeg = 90.0 - j*15.0;
glBegin(GL_LINE_STRIP);
for (i=0; i<=iMax; i++) {
RAdeg = i*360.0/iMax;
sphVertex(RAdeg, DEdeg);
}
glEnd();
}
glEndList();
}
/**
* Window resize/remap
*/
void Starsphere::resize(const int width, const int height)
{
/* Adjust aspect ratio and projection */
glViewport(0, 0, (GLsizei) width, (GLsizei) height);
aspect = (float)width / (float)height;
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(95.0, aspect, 0.50, 25.0);
glMatrixMode(GL_MODELVIEW);
}
/**
* What to do when graphics are "initialized".
*/
void Starsphere::initialize(const int width, const int height, const Resource *font)
{
// setup initial dimensions
resize(width, height);
// create font instance using font resource (base address + size)
m_PolygonFont = new FTGLPolygonFont(&font->data()->at(0), font->data()->size());
m_PolygonFont->CharMap(ft_encoding_unicode);
// m_PolygonFont->Depth(0.05);
m_PolygonFont->FaceSize(1);
// Drawing setup:
glClearColor(0.0, 0.0, 0.0, 0.0); // background is black
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
// some polishing
glShadeModel(GL_SMOOTH);
glEnable(GL_POINT_SMOOTH);
glEnable(GL_LINE_SMOOTH);
// FSAA will only be enabled when needed!
glDisable(GL_MULTISAMPLE_ARB);
glHint(GL_POINT_SMOOTH_HINT, GL_NICEST);
glHint(GL_LINE_SMOOTH_HINT, GL_NICEST);
glHint(GL_FOG_HINT, GL_DONT_CARE);
glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
glEnable(GL_BLEND);
glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
/* Enable depth buffering for 3D graphics */
glClearDepth(1.0f);
glEnable(GL_DEPTH_TEST);
glDepthFunc(GL_LEQUAL);
/* Fog aids depth perception */
glEnable(GL_FOG);
glFogi(GL_FOG_MODE, GL_EXP2);
glFogf(GL_FOG_DENSITY, 0.085);
/* Create pre-drawn display lists */
make_stars();
make_constellations();
make_pulsars();
make_snrs();
make_axes();
make_globe();
make_obs();
setFeature(STARS, true);
setFeature(CONSTELLATIONS, true);
setFeature(PULSARS, true);
setFeature(OBSERVATORIES, true);
setFeature(SNRS, true);
setFeature(GLOBE, true);
setFeature(SEARCHINFO, true);
setFeature(LOGO, true);
setFeature(MARKER, true);
glDisable(GL_CLIP_PLANE0);
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
glFlush();
}
/**
* Rendering routine: this is what does the drawing:
*/
void Starsphere::render(const double timeOfDay)
{
GLfloat xvp, yvp, zvp, vp_theta, vp_phi, vp_rad;
GLfloat Zrot = 0.0, Zobs=0.0;
double revs, t, dt = 0;
static double start_time=-1.0, last_time=-1.0;
// Calculate the real time t since we started (or reset) and the
// time dt since the last render() call. Both may be useful
// for timing animations. Note that time_of_day is dtime().
if (start_time < 0.0)
start_time = timeOfDay;
t = timeOfDay - start_time;
if (last_time < 0.0)
last_time = timeOfDay - 0.01;
dt = timeOfDay - last_time;
last_time = timeOfDay; // remember for next time
// Now determine the rotation angle based on the time since start
// It is negative to get the rotation direction correct (the sun
// rises in the East, so the sky sphere rotates E to W).
Zrot = t*rotation_speed/60.0;
revs = Zrot/360.0;
Zrot = -360.0 * (revs - (int)revs);
// And start drawing...
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Now draw the scene...
glLoadIdentity();
// Vary the viewpoint with both a long period wobble of the elevation
// of the view and a longer period zoom in/out that might even penetrate
// The starsphere for a brief time. Increase the power in pow(,) to
// make the visit inside briefer.
vp_theta = 90.0 - viewpt_elev + wobble_amp*sin(PI2*t/(wobble_period*60.0));
vp_phi = viewpt_azimuth;
vp_rad = viewpt_radius - zoom_amp*sin(PI2*t/(zoom_period*60.0));
if (vp_rad <0.0)
vp_rad = 0.0; // cannot pass origin (confusing)
// TRIED THIS TOO: -zoom_amp*pow(fabs(sin(PI2*t/(zoom_period*60.0))),3);
xvp = vp_rad * SIN(vp_theta) * SIN(vp_phi);
zvp = vp_rad * SIN(vp_theta) * COS(vp_phi);
yvp = vp_rad * COS(vp_theta);
gluLookAt(xvp, yvp, zvp, // eyes position
0.0, 0.0, 0.0, // looking toward here
0.0, 1.0, 0.0); // which way is up? y axis!
// Draw axes before any rotation so they stay put
if (isFeature(AXES))
glCallList(Axes);
// Draw the sky sphere, with rotation:
glPushMatrix();
glRotatef(Zrot - rotation_offset, 0.0, 1.0, 0.0);
/* stars, pulsars, supernovae */
if (isFeature(STARS))
glCallList(Stars);
if (isFeature(PULSARS))
glCallList(Pulsars);
if (isFeature(SNRS))
glCallList(SNRs);
if (isFeature(CONSTELLATIONS))
glCallList(Constellations);
if (isFeature(GLOBE))
glCallList(sphGrid);
/* Observatories move an extra 15 degrees/hr since they were drawn */
if (isFeature(OBSERVATORIES)) {
glPushMatrix();
Zobs = (timeOfDay - m_ObservatoryDrawTimeLocal) * 15.0/3600.0;
glRotatef(Zobs, 0.0, 1.0, 0.0);
glCallList(LLOmarker);
glCallList(LHOmarker);
glCallList(GEOmarker);
glPopMatrix();
}
if (isFeature(MARKER)) {
if(m_RefreshSearchMarker) {
make_search_marker(m_CurrentRightAscension, m_CurrentDeclination, 0.5);
m_RefreshSearchMarker = false;
}
else {
glCallList(SearchMarker);
}
}
glPopMatrix();
// draw 2D vectorized HUD
if(isFeature(LOGO) || isFeature(SEARCHINFO)) {
static const GLfloat xStartPosLeft = 0.008;
const GLfloat xStartPosRight = 1 * aspect - 0.145;
static const GLfloat yStartPosTop = 0.975;
static const GLfloat yStartPosBottom = 0.07;
static const GLfloat fontScaleLarge = 0.0225;
static const GLfloat fontScaleMedium = 0.0131;
static const GLfloat fontScaleSmall = 0.0131;
// static const GLfloat yOffset = (font->Ascender() + font->Descender());
static const GLfloat yOffsetLarge = 0.015;
static const GLfloat yOffsetMedium = 0.015;
// disable depth testing since we're in 2D mode
glDisable(GL_DEPTH_TEST);
// enable FSAA
glEnable(GL_MULTISAMPLE_ARB);
// save current state
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glLoadIdentity();
glOrtho(0, 1 * aspect, 0, 1, -1, 1);
glMatrixMode(GL_MODELVIEW);
glPushMatrix();
glLoadIdentity();
if (isFeature(LOGO)) {
glPushMatrix();
glColor3f(1.0, 1.0, 0.0);
glTranslatef(xStartPosLeft, yStartPosTop, 0);
glScalef(fontScaleLarge, fontScaleLarge, 1.0);
m_PolygonFont->Render("Einstein@Home");
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 0.5);
glTranslatef(xStartPosLeft, yStartPosTop - yOffsetLarge, 0);
glScalef(fontScaleMedium, fontScaleMedium, 1.0);
m_PolygonFont->Render("World Year of Physics 2005");
glPopMatrix();
}
if (isFeature(SEARCHINFO)) {
// left info block
glPushMatrix();
glColor3f(1.0, 1.0, 0.0);
glTranslatef(xStartPosLeft, yStartPosBottom, 0);
glScalef(fontScaleMedium, fontScaleMedium, 1.0);
m_PolygonFont->Render("BOINC Statistics");
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 0.5);
glTranslatef(xStartPosLeft, yStartPosBottom - yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_UserName.c_str());
glLoadIdentity();
glTranslatef(xStartPosLeft, yStartPosBottom - 2*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_TeamName.c_str());
glLoadIdentity();
glTranslatef(xStartPosLeft, yStartPosBottom - 3*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_UserCredit.c_str());
glLoadIdentity();
glTranslatef(xStartPosLeft, yStartPosBottom - 4*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_UserRACredit.c_str());
glPopMatrix();
// right info block
glPushMatrix();
glColor3f(1.0, 1.0, 0.0);
glTranslatef(xStartPosRight, yStartPosBottom, 0);
glScalef(fontScaleMedium, fontScaleMedium, 1.0);
m_PolygonFont->Render("Search Information");
glLoadIdentity();
glColor4f(1.0, 1.0, 1.0, 0.5);
glTranslatef(xStartPosRight, yStartPosBottom - yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_WUSkyPosRightAscension.c_str());
glLoadIdentity();
glTranslatef(xStartPosRight, yStartPosBottom - 2*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_WUSkyPosDeclination.c_str());
glLoadIdentity();
glTranslatef(xStartPosRight, yStartPosBottom - 3*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_WUPercentDone.c_str());
glLoadIdentity();
glTranslatef(xStartPosRight, yStartPosBottom - 4*yOffsetMedium, 0);
glScalef(fontScaleSmall, fontScaleSmall, 1.0);
m_PolygonFont->Render(m_WUCPUTime.c_str());
glPopMatrix();
}
// restore original state
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
glPopMatrix();
// disable FSAA
glDisable(GL_MULTISAMPLE_ARB);
// enable depth testing since we're leaving 2D mode
glEnable(GL_DEPTH_TEST);
}
glFlush();
SDL_GL_SwapBuffers();
}
void Starsphere::mouseButtonEvent(const int positionX, const int positionY, const int buttonPressed)
{
}
void Starsphere::mouseMoveEvent(const int deltaX, const int deltaY, const int buttonPressed)
{
switch(buttonPressed) {
case MouseButtonLeft:
rotateSphere(deltaX, deltaY);
break;
case MouseButtonRight:
zoomSphere(deltaY);
break;
default:
break;
}
}
void Starsphere::keyboardPressEvent(const int keyPressed)
{
switch(keyPressed) {
case KeyS:
setFeature(STARS, isFeature(STARS) ? false : true);
break;
case KeyC:
setFeature(CONSTELLATIONS, isFeature(CONSTELLATIONS) ? false : true);
break;
case KeyO:
setFeature(OBSERVATORIES, isFeature(OBSERVATORIES) ? false : true);
break;
case KeyX:
setFeature(XRAYS, isFeature(XRAYS) ? false : true);
break;
case KeyP:
setFeature(PULSARS, isFeature(PULSARS) ? false : true);
break;
case KeyR:
setFeature(SNRS, isFeature(SNRS) ? false : true);
break;
case KeyG:
setFeature(GLOBE, isFeature(GLOBE) ? false : true);
break;
case KeyA:
setFeature(AXES, isFeature(AXES) ? false : true);
break;
case KeyI:
setFeature(SEARCHINFO, isFeature(SEARCHINFO) ? false : true);
break;
case KeyL:
setFeature(LOGO, isFeature(LOGO) ? false : true);
break;
case KeyM:
setFeature(MARKER, isFeature(MARKER) ? false : true);
break;
default:
break;
}
}
/**
* View control
*/
void Starsphere::rotateSphere(const int relativeRotation,
const int relativeElevation)
{
// elevation
viewpt_elev += relativeElevation/10.0;
if (viewpt_elev > 89.0)
viewpt_elev = +89.0;
if (viewpt_elev < -89.0)
viewpt_elev = -89.0;
// rotation
rotation_offset -= relativeRotation/10.0;
}
void Starsphere::zoomSphere(const int relativeZoom)
{
// zoom
viewpt_radius -= relativeZoom/10.0;
if (viewpt_radius > 15.0)
viewpt_radius = 15.0;
if (viewpt_radius < 0.5)
viewpt_radius = 0.5;
}
/**
* Feature control
*/
void Starsphere::setFeature(const int feature, const bool enable)
{
featureFlags = enable ? (featureFlags | feature) : (featureFlags & ~feature);
}
bool Starsphere::isFeature(const int feature)
{
return ((featureFlags & feature) == feature ? true : false);
}
void Starsphere::refreshBOINCInformation()
{
// call base class implementation
AbstractGraphicsEngine::refreshBOINCInformation();
// prepare conversion buffer
stringstream buffer;
buffer.precision(2);
buffer.setf(ios::fixed, ios::floatfield);
buffer.fill('0');
buffer.setf(ios::right, ios::adjustfield);
// store content required for our HUD (user info)
m_UserName = "User: " + boincAdapter.userName();
m_TeamName = "Team: " + boincAdapter.teamName();
buffer << "Project Credit: " << fixed << boincAdapter.userCredit() << ends;
m_UserCredit = buffer.str();
buffer.str("");
buffer << "Project RAC: " << fixed << boincAdapter.userRACredit() << ends;
m_UserRACredit = buffer.str();
buffer.str("");
// store content required for our HUD (search info)
if(m_CurrentRightAscension != boincAdapter.wuSkyPosRightAscension()) {
// we've got a new position, update search marker and HUD
m_CurrentRightAscension = boincAdapter.wuSkyPosRightAscension();
m_RefreshSearchMarker = true;
buffer << "Ascension: " << fixed << m_CurrentRightAscension * 360/PI2 << " deg" << ends;
m_WUSkyPosRightAscension = buffer.str();
buffer.str("");
}
if(m_CurrentDeclination != boincAdapter.wuSkyPosDeclination()) {
// we've got a new position, update search marker and HUD
m_CurrentDeclination = boincAdapter.wuSkyPosDeclination();
m_RefreshSearchMarker = true;
buffer << "Declination: " << fixed << m_CurrentDeclination * 360/PI2 << " deg" << ends;
m_WUSkyPosDeclination = buffer.str();
buffer.str("");
}
buffer << "Completed: " << fixed << boincAdapter.wuFractionDone() * 100 << " %" << ends;
m_WUPercentDone = buffer.str();
buffer.str("");
const double cputime = boincAdapter.wuCPUTime();
const int hrs = cputime / 3600;
const int min = (cputime - hrs*3600) / 60;
const int sec = cputime - (hrs*3600 + min*60);
buffer << "CPU Time: " << right << setw(2) << hrs << ":"
<< right << setw(2) << min << ":"
<< right << setw(2) << sec << ends;
m_WUCPUTime = buffer.str();
}