27 #include <Eigen/Geometry> 
   28 USING_PART_OF_NAMESPACE_EIGEN
 
   29 using Eigen::Rotation2Df;
 
   55 Vector2f SkyGLPainter::m_vertex[NUMTYPES][6*BUFSIZE];
 
   56 Vector2f SkyGLPainter::m_texcoord[NUMTYPES][6*BUFSIZE];
 
   57 Vector3f SkyGLPainter::m_color[NUMTYPES][6*BUFSIZE];
 
   58 int      SkyGLPainter::m_idx[NUMTYPES];
 
   59 bool     SkyGLPainter::m_init = 
false;
 
   68         kDebug() << 
"Initializing texcoord arrays...\n";
 
   69         for(
int i = 0; i < NUMTYPES; ++i) {
 
   71             for(
int j = 0; j < BUFSIZE; ++j) {
 
   72                 m_texcoord[i][6*j +0] = Vector2f(0,0);
 
   73                 m_texcoord[i][6*j +1] = Vector2f(1,0);
 
   74                 m_texcoord[i][6*j +2] = Vector2f(0,1);
 
   75                 m_texcoord[i][6*j +3] = Vector2f(0,1);
 
   76                 m_texcoord[i][6*j +4] = Vector2f(1,0);
 
   77                 m_texcoord[i][6*j +5] = Vector2f(1,1);
 
   85 void SkyGLPainter::drawBuffer(
int type)
 
   92     if( m_idx[type] == 0 ) 
return;
 
   94     glEnable(GL_TEXTURE_2D);
 
   96         case 3: 
case 13:          TextureManager::bindTexture(
"open-cluster",     m_widget); 
break;
 
   97         case 4:                   TextureManager::bindTexture(
"globular-cluster", m_widget); 
break;
 
   98         case 6:                   TextureManager::bindTexture(
"planetary-nebula", m_widget); 
break;
 
   99         case 5: 
case 7: 
case 15:  TextureManager::bindTexture(
"gaseous-nebula",   m_widget); 
break;
 
  100         case 8: 
case 16:          TextureManager::bindTexture(
"galaxy",           m_widget); 
break;
 
  101         case 14:                  TextureManager::bindTexture(
"galaxy-cluster",   m_widget); 
break;
 
  102         case 0: 
case 1: 
default:  TextureManager::bindTexture(
"star",             m_widget); 
break;
 
  105     glEnable( GL_BLEND );
 
  106     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
  107     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
 
  108     glEnableClientState(GL_VERTEX_ARRAY);
 
  109     glEnableClientState(GL_COLOR_ARRAY);
 
  110     glEnableClientState(GL_TEXTURE_COORD_ARRAY);
 
  112     glVertexPointer  (2,GL_FLOAT,0, &m_vertex[type]);
 
  113     glTexCoordPointer(2,GL_FLOAT,0, &m_texcoord[type]);
 
  114     glColorPointer   (3,GL_FLOAT,0, &m_color[type]);
 
  116     glDrawArrays(GL_TRIANGLES, 0, 6*m_idx[type]);
 
  119     glDisableClientState(GL_VERTEX_ARRAY);
 
  120     glDisableClientState(GL_COLOR_ARRAY);
 
  121     glDisableClientState(GL_TEXTURE_COORD_ARRAY);
 
  124 bool SkyGLPainter::addItem(
SkyPoint* p, 
int type, 
float width, 
char sp)
 
  126     bool visible = 
false;
 
  127     Vector2f vec = m_proj->
toScreenVec(p,
true,&visible);
 
  128     if(!visible) 
return false;
 
  135     if(m_idx[type] == BUFSIZE) {
 
  139     int i = 6*m_idx[type];
 
  142     m_vertex[type][i + 0] = vec + Vector2f(-w,-w);
 
  143     m_vertex[type][i + 1] = vec + Vector2f( w,-w);
 
  144     m_vertex[type][i + 2] = vec + Vector2f(-w, w);
 
  145     m_vertex[type][i + 3] = vec + Vector2f(-w, w);
 
  146     m_vertex[type][i + 4] = vec + Vector2f( w,-w);
 
  147     m_vertex[type][i + 5] = vec + Vector2f( w, w);
 
  149     Vector3f c(1.,1.,1.);
 
  154             c = Vector3f( 255./255., 0., 0. ); 
break;
 
  156             c = Vector3f( 0., 0., 0. ); 
break;
 
  158             c = Vector3f( 1., 1., 1. ); 
break;
 
  166         case 'o': 
case 'O': starColor.setRgb( 153, 153, 255); 
break;
 
  167         case 'b': 
case 'B': starColor.setRgb( 151, 233, 255); 
break;
 
  168         case 'a': 
case 'A': starColor.setRgb( 153, 255, 255); 
break;
 
  169         case 'f': 
case 'F': starColor.setRgb( 219, 255, 135); 
break;
 
  170         case 'g': 
case 'G': starColor.setRgb( 255, 255, 153); 
break;
 
  171         case 'k': 
case 'K': starColor.setRgb( 255, 193, 153); 
break;
 
  172         case 'm': 
case 'M': starColor.setRgb( 255, 153, 153); 
break;
 
  173         case 'x':           starColor.setRgb( m_pen[0] * 255, m_pen[1] * 255, m_pen[2] *255 ); 
break;
 
  174         default:            starColor.setRgb( 153, 255, 255); 
break; 
 
  179         starColor.getHsv( &h, &s, &v );
 
  181         starColor.setHsv( h, s, v );
 
  184         c = Vector3f( starColor.redF(), starColor.greenF(), starColor.blueF() );
 
  187     for(
int j = 0; j < 6; ++j) {
 
  188         m_color[type][i+j] = c;
 
  195 void SkyGLPainter::drawTexturedRectangle( 
const QImage& img,
 
  196                                           const Vector2f& pos, 
const float angle,
 
  197                                           const float sizeX,   
const float sizeY )
 
  200     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
  201     glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
 
  202     glEnable(GL_TEXTURE_2D);
 
  203     TextureManager::bindFromImage( img, m_widget );
 
  207     glTranslatef( pos.x(), pos.y(), 0 );
 
  208     glRotatef( angle, 0, 0, 1 );
 
  209     glScalef( sizeX, sizeY, 1 );
 
  216         glTexCoord2f( 0,    1   );
 
  217         glVertex2f(  -0.5, -0.5 );
 
  219         glTexCoord2f( 1,    1   );
 
  220         glVertex2f(   0.5, -0.5 );
 
  222         glTexCoord2f( 1,    0   );
 
  223         glVertex2f(   0.5,  0.5 );
 
  225         glTexCoord2f( 0,    0   );
 
  226         glVertex2f(  -0.5,  0.5 );
 
  239     float fakeStarSize = ( 10.0 + log10( zoom ) - log10( 
MINZOOM ) ) * ( 10 - planet->
mag() ) / 10;
 
  240     fakeStarSize = qMin(fakeStarSize, 20.
f);
 
  243     if( size < fakeStarSize || planet->image().isNull() )
 
  248         if( planet->
name() == i18n( 
"Sun" ) ) {
 
  250         } 
else if( planet->
name() == i18n(
"Mars") ) {
 
  252         } 
else if( planet->
name() == i18n(
"Jupiter") || planet->
name() == i18n(
"Mercury") || planet->
name() == i18n(
"Saturn") ) {
 
  257         return addItem(planet, planet->
type(), qMin(fakeStarSize,(
float)20.),spType);
 
  260         bool visible = 
false;
 
  261         Vector2f pos = m_proj->
toScreenVec(planet,
true,&visible);
 
  266         if( planet->
name() == 
"Saturn" )
 
  269         drawTexturedRectangle( planet->
image(),
 
  270                                pos, m_proj->
findPA(planet, pos.x(), pos.y()),
 
  281     int type = obj->
type();
 
  293     bool visible = 
false;
 
  294     Vector2f vec = m_proj->
toScreenVec(obj,
true,&visible);
 
  299     float pa = m_proj->
findPA(obj, vec[0], vec[1]) * (M_PI/180.0);
 
  302     float h = w * obj->
e();
 
  316     if( drawImage  &&  !obj->
image().isNull() ) {
 
  317         drawTexturedRectangle( obj->
image(), vec, pa, w, h);
 
  320         if(m_idx[type] == BUFSIZE)
 
  323         const int i = 6*m_idx[type];
 
  324         m_vertex[type][i + 0] = vec + r * Vector2f(-w,-h);
 
  325         m_vertex[type][i + 1] = vec + r * Vector2f( w,-h);
 
  326         m_vertex[type][i + 2] = vec + r * Vector2f(-w, h);
 
  327         m_vertex[type][i + 3] = vec + r * Vector2f(-w, h);
 
  328         m_vertex[type][i + 4] = vec + r * Vector2f( w,-h);
 
  329         m_vertex[type][i + 5] = vec + r * Vector2f( w, h);
 
  330         Vector3f c( m_pen[0], m_pen[1], m_pen[2] );
 
  332         for(
int j = 0; j < 6; ++j)
 
  333             m_color[type][i+j] = c;
 
  350     bool isVisible, isVisibleLast;
 
  352     Vector2f  oLast = m_proj->
toScreenVec( pLast, 
true, &isVisibleLast );
 
  357     QVector<Vector2f> polygon;
 
  358     polygon.reserve(points->size());
 
  359     for ( 
int i = 0; i < points->size(); ++i ) {
 
  361         Vector2f oThis = m_proj->
toScreenVec( pThis, 
true, &isVisible );
 
  365         if ( isVisible && isVisibleLast ) {
 
  367         } 
else if ( isVisibleLast ) {
 
  368             Vector2f oMid = m_proj->
clipLineVec( pLast, pThis );
 
  370         } 
else if ( isVisible ) {
 
  371             Vector2f oMid = m_proj->
clipLineVec( pThis, pLast );
 
  378         isVisibleLast = isVisible;
 
  383     #define KSTARS_ASSUME_CONVEXITY false 
  384     if ( polygon.size() ) {
 
  389 void SkyGLPainter::drawPolygon(
const QVector<Vector2f>& polygon, 
bool convex, 
bool flush_buffers)
 
  392     if( flush_buffers ) {
 
  393         for(
int i = 0; i < NUMTYPES; ++i) {
 
  397     glDisable(GL_TEXTURE_2D);
 
  398     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
  401         glClear(GL_STENCIL_BUFFER_BIT);
 
  402         glColorMask(0,0,0,0);
 
  403         glEnable(GL_STENCIL_TEST);
 
  404         glStencilFunc(GL_ALWAYS, 0, 0);
 
  405         glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
 
  408         glEnableClientState(GL_VERTEX_ARRAY);
 
  409         glVertexPointer(2,GL_FLOAT,0, polygon.data() );
 
  410         glDrawArrays(GL_TRIANGLE_FAN, 0, polygon.size());
 
  411         glDisableClientState(GL_VERTEX_ARRAY);
 
  414         glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
 
  415         glColorMask(1,1,1,1);
 
  416         glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
 
  419         glVertex2f(0,m_widget->height());
 
  420         glVertex2f(m_widget->width(),m_widget->height());
 
  421         glVertex2f(m_widget->width(),0);
 
  423         glDisable(GL_STENCIL_TEST);
 
  425         glEnableClientState(GL_VERTEX_ARRAY);
 
  426         glVertexPointer(2,GL_FLOAT,0, polygon.data() );
 
  427         glDrawArrays(GL_POLYGON, 0, polygon.size());
 
  428         glDisableClientState(GL_VERTEX_ARRAY);
 
  434     QVector<Vector2f> ground = m_proj->
groundPoly( labelPoint, drawLabel );
 
  436     if( ground.size() ) {
 
  438             glDisableClientState( GL_COLOR_ARRAY );
 
  439             drawPolygon( ground, 
false, 
false );
 
  441             glDisable( GL_TEXTURE_2D );
 
  442             glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
  443             glEnableClientState( GL_VERTEX_ARRAY );
 
  444             glVertexPointer( 2, GL_FLOAT, 0, ground.data() );
 
  445             glDrawArrays( GL_LINE_LOOP, 0, ground.size() );
 
  446             glDisableClientState( GL_VERTEX_ARRAY );
 
  454     glDisable(GL_TEXTURE_2D);
 
  455     glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
 
  456     glBegin(GL_LINE_STRIP);
 
  458     bool isVisible, isVisibleLast;
 
  459     Vector2f oLast = m_proj->
toScreenVec(points->first(), 
true, &isVisibleLast);
 
  462     if( isVisibleLast ) { glVertex2fv(oLast.data()); }
 
  464     for(
int i = 1; i < points->size(); ++i) {
 
  465         Vector2f oThis = m_proj->
toScreenVec( points->at(i), 
true, &isVisible);
 
  469         bool doSkip = (skipList ? skipList->
skip(i) : 
false);
 
  472         bool shouldEnd = doSkip;
 
  475             if( isVisible && isVisibleLast ) {
 
  476                 glVertex2fv(oThis.data());
 
  480             } 
else if( isVisibleLast ) {
 
  481                 Vector2f oMid = m_proj->
clipLineVec( points->at(i-1), points->at(i) );
 
  482                 glVertex2fv(oMid.data());
 
  486             } 
else if( isVisible ) {
 
  487                 Vector2f oMid = m_proj->
clipLineVec( points->at(i), points->at(i-1) );
 
  488                 glVertex2fv(oMid.data());
 
  489                 glVertex2fv(oThis.data());
 
  495             glBegin(GL_LINE_STRIP);
 
  497                 glVertex2fv(oThis.data());
 
  501         isVisibleLast = isVisible;
 
  518         Vector2f vec = m_proj->
toScreenVec(obj, 
true, &visible);
 
  519         if( !visible || !m_proj->
onScreen(vec) ) 
continue;
 
  520         const float size = 30.;
 
  522     drawTexturedRectangle( obsmarker, vec, 0,size,size );
 
  533     bool visible = 
false;
 
  545         vec = m_proj->
toScreenVec( point, 
true, &visible );
 
  548         if( !visible || !m_proj->
onScreen( vec ) )
 
  555         drawTexturedRectangle( img, vec, 0, img.width(), img.height() );
 
  558                   QFont( 
"Courier New", 10, QFont::Bold ),
 
  566     if ( text.isEmpty() )
 
  569     int longest, tex_size = 2;
 
  572     QFontMetrics fm( font );
 
  573     const QRect bounding_rect = fm.boundingRect( text );
 
  576     if ( bounding_rect.width() > bounding_rect.height() )
 
  577         longest = bounding_rect.width();
 
  579         longest = bounding_rect.height();
 
  581     while ( tex_size < longest ) {
 
  586     QImage text_image( tex_size, tex_size, QImage::Format_ARGB32 );
 
  587     text_image.fill( Qt::transparent );
 
  588     QPainter p( &text_image );
 
  591     p.drawText( 0, tex_size/2, text );
 
  595     float w = text_image.width();
 
  596     float h = text_image.height();
 
  597     float vx = x + 0.5*w + 10;
 
  599     drawTexturedRectangle( text_image, Vector2f(vx,vy), 0, w, h );
 
  604     bool aVisible, bVisible;
 
  605     Vector2f aScreen = m_proj->
toScreenVec( a, 
true, &aVisible );
 
  606     Vector2f bScreen = m_proj->
toScreenVec( b, 
true, &bVisible );
 
  608     glDisable( GL_TEXTURE_2D );
 
  609     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
  610     glBegin( GL_LINE_STRIP );
 
  613     if( aVisible && bVisible ) {
 
  615         glVertex2fv( aScreen.data() );
 
  616         glVertex2fv( bScreen.data() );
 
  617     } 
else if( aVisible ) {
 
  619         glVertex2fv( aScreen.data() );
 
  621     } 
else if( bVisible ) {
 
  623         glVertex2fv( bScreen.data() );
 
  632     glDisable(GL_TEXTURE_2D);
 
  634     glClearColor( bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF() );
 
  635     glClear(GL_COLOR_BUFFER_BIT);
 
  640     for(
int i = 0; i < NUMTYPES; ++i) {
 
  650     glViewport(0,0,m_widget->width(),m_widget->height());
 
  651     glMatrixMode(GL_PROJECTION);
 
  653     glOrtho(0,m_widget->width(), m_widget->height(),0, -1,1);
 
  656     glMatrixMode(GL_MODELVIEW);
 
  660     glDisable(GL_LIGHTING);
 
  661     glDisable(GL_COLOR_MATERIAL);
 
  662     glDisable(GL_CULL_FACE);
 
  663     glDisable(GL_DEPTH_TEST);
 
  664     glDepthMask(GL_FALSE);
 
  666     glEnable(GL_POINT_SMOOTH);
 
  667     glEnable(GL_LINE_SMOOTH);
 
  668     glEnable(GL_POLYGON_SMOOTH);
 
  669     glLineStipple(1,0xCCCC);
 
  687     QColor c = pen.color();
 
  688     m_pen = Vector4f( c.redF(), c.greenF(), c.blueF(), c.alphaF() );
 
  689     glColor4fv( m_pen.data() );
 
  690     glLineWidth(pen.widthF());
 
  691     if( pen.style() != Qt::SolidLine ) {
 
  692         glEnable(GL_LINE_STIPPLE);
 
  694         glDisable(GL_LINE_STIPPLE);
 
  701     bool visible = 
false;
 
  702     Vector2f pos, vertex;
 
  708     if( !visible || !m_proj->
onScreen( pos ) )
 
  719         glDisable( GL_TEXTURE_2D );
 
  720         glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
  723         vertex = pos + Vector2f( -1.0, -1.0 );
 
  724         glVertex2fv(vertex.data());
 
  725         vertex = pos + Vector2f(  1.0, -1.0 );
 
  726         glVertex2fv(vertex.data());
 
  727         vertex = pos + Vector2f(  1.0,  1.0 );
 
  728         glVertex2fv(vertex.data());
 
  729         vertex = pos + Vector2f( -1.0,  1.0 );
 
  730         glVertex2fv(vertex.data());
 
  742     bool visible = 
false;
 
  743     Vector2f pos, vertex;
 
  749     if( !visible || !m_proj->
onScreen( pos ) )
 
  753     glDisable( GL_TEXTURE_2D );
 
  754     glBlendFunc( GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA );
 
  757     vertex = pos + Vector2f(  2.0, 0.0 );
 
  758     glVertex2fv(vertex.data());
 
  759     vertex = pos + Vector2f( -2.0, 0.0 );
 
  760     glVertex2fv(vertex.data());
 
  764     vertex = pos + Vector2f( 0.0,  2.0 );
 
  765     glVertex2fv(vertex.data());
 
  766     vertex = pos + Vector2f( 0.0, -2.0 );
 
  767     glVertex2fv(vertex.data());
 
int size()
Return the numbers of flags. 
 
QString imageName(int index)
Get image name. 
 
SkyGLPainter(QGLWidget *widget)
 
bool onScreen(const QPointF &p) const 
Check whether the projected point is on-screen. 
 
virtual Vector2f toScreenVec(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=0) const 
Given the coordinates of the SkyPoint argument, determine the pixel coordinates in the SkyMap...
 
virtual QVector< Vector2f > groundPoly(SkyPoint *labelpoint=0, bool *drawLabel=0) const 
Get the ground polygon. 
 
virtual bool drawSupernova(Supernova *sup)
Draw a Supernova. 
 
QVector< SkyPoint * > SkyList
 
KStarsData is the backbone of KStars. 
 
ColorScheme * colorScheme()
 
virtual void drawFlags()
Draw flags. 
 
static KStarsData * Instance()
 
virtual void drawHorizon(bool filled, SkyPoint *labelPoint=0, bool *drawLabel=0)
 
QColor colorNamed(const QString &name) const 
Retrieve a color by name. 
 
virtual void end()
End and finalize painting. 
 
static const QImage & getImage(const QString &name)
Return texture image. 
 
bool checkVisibility(SkyPoint *p) const 
Determine if the skypoint p is likely to be visible in the display window. 
 
void drawText(int x, int y, const QString text, QFont font, QColor color)
 
static bool showSatellitesLabels()
Get Draw satellite labels? 
 
SatellitesComponent * satellites()
 
double findPA(SkyObject *o, float x, float y) const 
Determine the on-screen position angle of a SkyObject. 
 
QImage image(int index)
Get image. 
 
The sky coordinates of a point in the sky. 
 
float starWidth(float mag) const 
Get the width of a star of magnitude mag. 
 
QString label(int index)
Get label. 
 
static uint starColorIntensity()
Get Saturation level of star colors. 
 
Represents the supernova object. 
 
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates, given the local sidereal time and the observer's latitude. 
 
Vector2f clipLineVec(SkyPoint *p1, SkyPoint *p2) const 
ASSUMES *p1 did not clip but *p2 did. 
 
virtual void drawSkyPolygon(LineList *list)
Draw a polygon in the sky. 
 
SkyMapComposite * skyComposite()
 
virtual void drawSkyBackground()
Draw the sky background. 
 
virtual bool drawDeepSkyObject(DeepSkyObject *obj, bool drawImage=false)
Draw a deep sky object. 
 
QList< SkyPoint * > & pointList()
 
void EquatorialToHorizontal(const dms *LST, const dms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates, given the local sidereal time and the observer's latitude. 
 
const QImage & image() const 
 
Provides all necessary information about a deep-sky object: data inherited from SkyObject (coordinate...
 
virtual void drawSkyPolyline(LineList *list, SkipList *skipList=0, LineListLabel *label=0)
Draw a polyline in the sky. 
 
virtual bool drawPointSource(SkyPoint *loc, float mag, char sp= 'A')
Draw a point source (e.g., a star). 
 
static bool drawSatellitesLikeStars()
Get If selected, satellites will be draw like stars, otherwise, draw satellites as small colored squa...
 
void drawLabel(Satellite *sat, QPointF pos)
Draw label of a satellite. 
 
virtual bool drawPlanet(KSPlanetBase *planet)
Draw a planet. 
 
QColor labelColor(int index)
Get label color. 
 
static double zoomFactor()
Get Zoom Factor, in pixels per radian. 
 
#define KSTARS_ASSUME_CONVEXITY
 
static uint starColorMode()
Get Mode for rendering stars. 
 
virtual void drawSkyLine(SkyPoint *a, SkyPoint *b)
Draw a line between points in the sky. 
 
Represents an artificial satellites. 
 
A subclass of TrailObject that provides additional information needed for most solar system objects...
 
virtual void setPen(const QPen &pen)
Set the pen of the painter. 
 
virtual void drawObservingList(const QList< SkyObject * > &obs)
Draw the symbols for the observing list. 
 
virtual QString name(void) const 
 
Provides all necessary information about an object in the sky: its coordinates, name(s), type, magnitude, and QStringLists of URLs for images and webpages regarding the object. 
 
virtual void drawSatellite(Satellite *sat)
Draw a satellite. 
 
const Projector * projector() const 
Get the current projector. 
 
Draws things on the sky, without regard to backend. 
 
virtual void begin()
Begin painting. 
 
virtual void setBrush(const QBrush &brush)
Set the brush of the painter. 
 
void updateLabelCandidates(qreal x, qreal y, LineList *lineList, int i)