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)