10#include "skyglpainter.h"
13#include <Eigen/Geometry>
19#include "kstarsdata.h"
22#include "texturemanager.h"
24#include "skycomponents/linelist.h"
25#include "skycomponents/skiphashlist.h"
26#include "skycomponents/linelistlabel.h"
27#include "skycomponents/skymapcomposite.h"
28#include "skycomponents/flagcomponent.h"
29#include "skycomponents/satellitescomponent.h"
30#include "skycomponents/supernovaecomponent.h"
31#include "skycomponents/constellationartcomponent.h"
32#include "skyobjects/kscomet.h"
33#include "skyobjects/ksasteroid.h"
34#include "skyobjects/trailobject.h"
35#include "skyobjects/satellite.h"
36#include "skyobjects/supernova.h"
37#include "skyobjects/constellationsart.h"
39Eigen::Vector2f SkyGLPainter::m_vertex[NUMTYPES][6 * BUFSIZE];
40Eigen::Vector2f SkyGLPainter::m_texcoord[NUMTYPES][6 * BUFSIZE];
41Eigen::Vector3f SkyGLPainter::m_color[NUMTYPES][6 * BUFSIZE];
42int SkyGLPainter::m_idx[NUMTYPES];
43bool SkyGLPainter::m_init =
false;
45SkyGLPainter::SkyGLPainter(QGLWidget *widget) :
SkyPainter()
50 qDebug() <<
"Initializing texcoord arrays...\n";
51 for (
int i = 0; i < NUMTYPES; ++i)
54 for (
int j = 0; j < BUFSIZE; ++j)
56 m_texcoord[i][6 * j + 0] = Eigen::Vector2f(0, 0);
57 m_texcoord[i][6 * j + 1] = Eigen::Vector2f(1, 0);
58 m_texcoord[i][6 * j + 2] = Eigen::Vector2f(0, 1);
59 m_texcoord[i][6 * j + 3] = Eigen::Vector2f(0, 1);
60 m_texcoord[i][6 * j + 4] = Eigen::Vector2f(1, 0);
61 m_texcoord[i][6 * j + 5] = Eigen::Vector2f(1, 1);
69void SkyGLPainter::drawBuffer(
int type)
72 if (type > SkyObject::TYPE_UNKNOWN)
73 type = SkyObject::TYPE_UNKNOWN;
79 glEnable(GL_TEXTURE_2D);
84 TextureManager::bindTexture(
"open-cluster", m_widget);
87 TextureManager::bindTexture(
"globular-cluster", m_widget);
90 TextureManager::bindTexture(
"planetary-nebula", m_widget);
95 TextureManager::bindTexture(
"gaseous-nebula", m_widget);
99 TextureManager::bindTexture(
"galaxy", m_widget);
102 TextureManager::bindTexture(
"galaxy-cluster", m_widget);
107 TextureManager::bindTexture(
"star", m_widget);
112 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
113 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE);
114 glEnableClientState(GL_VERTEX_ARRAY);
115 glEnableClientState(GL_COLOR_ARRAY);
116 glEnableClientState(GL_TEXTURE_COORD_ARRAY);
118 glVertexPointer(2, GL_FLOAT, 0, &m_vertex[type]);
119 glTexCoordPointer(2, GL_FLOAT, 0, &m_texcoord[type]);
120 glColorPointer(3, GL_FLOAT, 0, &m_color[type]);
122 glDrawArrays(GL_TRIANGLES, 0, 6 * m_idx[type]);
125 glDisableClientState(GL_VERTEX_ARRAY);
126 glDisableClientState(GL_COLOR_ARRAY);
127 glDisableClientState(GL_TEXTURE_COORD_ARRAY);
130bool SkyGLPainter::addItem(
SkyPoint *p,
int type,
float width,
char sp)
132 bool visible =
false;
133 Eigen::Vector2f vec = m_proj->
toScreenVec(p,
true, &visible);
138 if (type > SkyObject::TYPE_UNKNOWN)
139 type = SkyObject::TYPE_UNKNOWN;
142 if (m_idx[type] == BUFSIZE)
147 int i = 6 * m_idx[
type];
148 float w = width / 2.;
150 m_vertex[
type][i + 0] = vec + Eigen::Vector2f(-w, -w);
151 m_vertex[
type][i + 1] = vec + Eigen::Vector2f(w, -w);
152 m_vertex[
type][i + 2] = vec + Eigen::Vector2f(-w, w);
153 m_vertex[
type][i + 3] = vec + Eigen::Vector2f(-w, w);
154 m_vertex[
type][i + 4] = vec + Eigen::Vector2f(w, -w);
155 m_vertex[
type][i + 5] = vec + Eigen::Vector2f(w, w);
157 Eigen::Vector3f c(1., 1., 1.);
158 if (sp !=
'x' && Options::starColorMode() != 0)
161 switch (Options::starColorMode())
164 c = Eigen::Vector3f(255. / 255., 0., 0.);
167 c = Eigen::Vector3f(0., 0., 0.);
170 c = Eigen::Vector3f(1., 1., 1.);
183 starColor.
setRgb(153, 153, 255);
187 starColor.
setRgb(151, 233, 255);
191 starColor.
setRgb(153, 255, 255);
195 starColor.
setRgb(219, 255, 135);
199 starColor.
setRgb(255, 255, 153);
203 starColor.
setRgb(255, 193, 153);
207 starColor.
setRgb(255, 153, 153);
210 starColor.
setRgb(m_pen[0] * 255, m_pen[1] * 255, m_pen[2] * 255);
213 starColor.
setRgb(153, 255, 255);
219 starColor.
getHsv(&h, &s, &v);
220 s = (Options::starColorIntensity() / 10.) *
222 starColor.
setHsv(h, s, v);
225 c = Eigen::Vector3f(starColor.
redF(), starColor.
greenF(), starColor.
blueF());
227 for (
int j = 0; j < 6; ++j)
229 m_color[
type][i + j] = c;
236void SkyGLPainter::drawTexturedRectangle(
const QImage &img,
const Eigen::Vector2f &pos,
const float angle,
const float sizeX,
240 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
241 glTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
242 glEnable(GL_TEXTURE_2D);
243 TextureManager::bindFromImage(img, m_widget);
247 glTranslatef(pos.x(), pos.y(), 0);
248 glRotatef(angle, 0, 0, 1);
249 glScalef(sizeX, sizeY, 1);
257 glVertex2f(-0.5, -0.5);
260 glVertex2f(0.5, -0.5);
263 glVertex2f(0.5, 0.5);
266 glVertex2f(-0.5, 0.5);
278 float zoom = Options::zoomFactor();
279 float fakeStarSize = (10.0 + log10(zoom) - log10(MINZOOM)) * (10 - planet->
mag()) / 10;
280 fakeStarSize = qMin(fakeStarSize, 20.f);
283 if (size < fakeStarSize || planet->image().isNull())
292 else if (planet->
name() ==
xi18n(
"Mars"))
305 return addItem(planet, planet->
type(), qMin(fakeStarSize, (
float)20.), spType);
310 bool visible =
false;
311 Eigen::Vector2f pos = m_proj->
toScreenVec(planet,
true, &visible);
316 if (planet->
name() ==
"Saturn")
319 drawTexturedRectangle(planet->
image(), pos, m_proj->
findPA(planet, pos.x(), pos.y()), size, size);
324bool SkyGLPainter::drawPointSource(
const SkyPoint *loc,
float mag,
char sp)
329 return addItem(loc, SkyObject::STAR,
starWidth(mag), sp);
332void SkyGLPainter::drawSkyPolygon(
LineList *list)
335 bool isVisible, isVisibleLast;
337 Eigen::Vector2f oLast = m_proj->
toScreenVec(pLast,
true, &isVisibleLast);
343 polygon.
reserve(points->size());
344 for (
int i = 0; i < points->size(); ++i)
347 Eigen::Vector2f oThis = m_proj->
toScreenVec(pThis,
true, &isVisible);
351 if (isVisible && isVisibleLast)
355 else if (isVisibleLast)
357 Eigen::Vector2f oMid = m_proj->
clipLineVec(pLast, pThis);
362 Eigen::Vector2f oMid = m_proj->
clipLineVec(pThis, pLast);
369 isVisibleLast = isVisible;
374#define KSTARS_ASSUME_CONVEXITY false
377 drawPolygon(polygon, KSTARS_ASSUME_CONVEXITY);
386 for (
int i = 0; i < NUMTYPES; ++i)
391 glDisable(GL_TEXTURE_2D);
392 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
396 glClear(GL_STENCIL_BUFFER_BIT);
397 glColorMask(0, 0, 0, 0);
398 glEnable(GL_STENCIL_TEST);
399 glStencilFunc(GL_ALWAYS, 0, 0);
400 glStencilOp(GL_INVERT, GL_INVERT, GL_INVERT);
403 glEnableClientState(GL_VERTEX_ARRAY);
404 glVertexPointer(2, GL_FLOAT, 0, polygon.
data());
405 glDrawArrays(GL_TRIANGLE_FAN, 0, polygon.
size());
406 glDisableClientState(GL_VERTEX_ARRAY);
409 glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
410 glColorMask(1, 1, 1, 1);
411 glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
414 glVertex2f(0, m_widget->height());
415 glVertex2f(m_widget->width(), m_widget->height());
416 glVertex2f(m_widget->width(), 0);
418 glDisable(GL_STENCIL_TEST);
422 glEnableClientState(GL_VERTEX_ARRAY);
423 glVertexPointer(2, GL_FLOAT, 0, polygon.
data());
424 glDrawArrays(GL_POLYGON, 0, polygon.
size());
425 glDisableClientState(GL_VERTEX_ARRAY);
429void SkyGLPainter::drawHorizon(
bool filled,
SkyPoint *labelPoint,
bool *drawLabel)
437 glDisableClientState(GL_COLOR_ARRAY);
438 drawPolygon(ground,
false,
false);
442 glDisable(GL_TEXTURE_2D);
443 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
444 glEnableClientState(GL_VERTEX_ARRAY);
445 glVertexPointer(2, GL_FLOAT, 0, ground.
data());
446 glDrawArrays(GL_LINE_LOOP, 0, ground.
size());
447 glDisableClientState(GL_VERTEX_ARRAY);
453void SkyGLPainter::drawSkyPolyline(
LineList *list, SkipHashList *skipList, LineListLabel *label)
455 glDisable(GL_TEXTURE_2D);
456 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
457 glBegin(GL_LINE_STRIP);
459 bool isVisible, isVisibleLast;
460 Eigen::Vector2f oLast = m_proj->
toScreenVec(points->first(),
true, &isVisibleLast);
465 glVertex2fv(oLast.data());
468 for (
int i = 1; i < points->size(); ++i)
470 Eigen::Vector2f oThis = m_proj->
toScreenVec(points->at(i),
true, &isVisible);
474 bool doSkip = (skipList ? skipList->skip(i) :
false);
477 bool shouldEnd = doSkip;
481 if (isVisible && isVisibleLast)
483 glVertex2fv(oThis.data());
486 label->updateLabelCandidates(oThis.x(), oThis.y(), list, i);
489 else if (isVisibleLast)
491 Eigen::Vector2f oMid = m_proj->
clipLineVec(points->at(i - 1), points->at(i));
492 glVertex2fv(oMid.data());
499 Eigen::Vector2f oMid = m_proj->
clipLineVec(points->at(i), points->at(i - 1));
500 glVertex2fv(oMid.data());
501 glVertex2fv(oThis.data());
508 glBegin(GL_LINE_STRIP);
511 glVertex2fv(oThis.data());
515 isVisibleLast = isVisible;
533 Eigen::Vector2f vec = m_proj->
toScreenVec(obj,
true, &visible);
534 if (!visible || !m_proj->
onScreen(vec))
536 const float size = 30.;
538 drawTexturedRectangle(obsmarker, vec, 0, size, size);
542void SkyGLPainter::drawFlags()
548 bool visible =
false;
552 for (i = 0; i < data->
skyComposite()->flags()->size(); i++)
564 if (!visible || !m_proj->
onScreen(vec))
570 drawTexturedRectangle(img, vec, 0, img.
width(), img.
height());
576void SkyGLPainter::drawText(
int x,
int y,
const QString text,
QFont font,
QColor color)
582 int longest, tex_size = 2;
586 const QRect bounding_rect = fm.boundingRect(text);
589 if (bounding_rect.
width() > bounding_rect.
height())
590 longest = bounding_rect.
width();
592 longest = bounding_rect.
height();
594 while (tex_size < longest)
605 p.drawText(0, tex_size / 2, text);
609 float w = text_image.width();
610 float h = text_image.height();
611 float vx = x + 0.5 * w + 10;
613 drawTexturedRectangle(text_image, Eigen::Vector2f(vx, vy), 0, w, h);
622 bool aVisible, bVisible;
623 Eigen::Vector2f aScreen = m_proj->
toScreenVec(a,
true, &aVisible);
624 Eigen::Vector2f bScreen = m_proj->
toScreenVec(b,
true, &bVisible);
626 glDisable(GL_TEXTURE_2D);
627 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
628 glBegin(GL_LINE_STRIP);
631 if (aVisible && bVisible)
634 glVertex2fv(aScreen.data());
635 glVertex2fv(bScreen.data());
640 glVertex2fv(aScreen.data());
646 glVertex2fv(bScreen.data());
653void SkyGLPainter::drawSkyBackground()
655 glDisable(GL_TEXTURE_2D);
658 glClear(GL_COLOR_BUFFER_BIT);
661void SkyGLPainter::end()
663 for (
int i = 0; i < NUMTYPES; ++i)
669void SkyGLPainter::begin()
671 m_proj = m_sm->projector();
674 glViewport(0, 0, m_widget->width(), m_widget->height());
675 glMatrixMode(GL_PROJECTION);
677 glOrtho(0, m_widget->width(), m_widget->height(), 0, -1, 1);
680 glMatrixMode(GL_MODELVIEW);
684 glDisable(GL_LIGHTING);
685 glDisable(GL_COLOR_MATERIAL);
686 glDisable(GL_CULL_FACE);
687 glDisable(GL_DEPTH_TEST);
688 glDepthMask(GL_FALSE);
690 glEnable(GL_POINT_SMOOTH);
691 glEnable(GL_LINE_SMOOTH);
692 glEnable(GL_POLYGON_SMOOTH);
693 glLineStipple(1, 0xCCCC);
699void SkyGLPainter::setBrush(
const QBrush &brush)
709void SkyGLPainter::setPen(
const QPen &pen)
713 glColor4fv(m_pen.data());
714 glLineWidth(pen.
widthF());
717 glEnable(GL_LINE_STIPPLE);
721 glDisable(GL_LINE_STIPPLE);
725void SkyGLPainter::drawSatellite(
Satellite *sat)
728 bool visible =
false;
729 Eigen::Vector2f pos, vertex;
735 if (!visible || !m_proj->
onScreen(pos))
738 if (Options::drawSatellitesLikeStars())
740 drawPointSource(sat, 3.5,
'B');
749 glDisable(GL_TEXTURE_2D);
750 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
753 vertex = pos + Eigen::Vector2f(-1.0, -1.0);
754 glVertex2fv(vertex.data());
755 vertex = pos + Eigen::Vector2f(1.0, -1.0);
756 glVertex2fv(vertex.data());
757 vertex = pos + Eigen::Vector2f(1.0, 1.0);
758 glVertex2fv(vertex.data());
759 vertex = pos + Eigen::Vector2f(-1.0, 1.0);
760 glVertex2fv(vertex.data());
765 if (Options::showSatellitesLabels())
769bool SkyGLPainter::drawSupernova(
Supernova *sup)
772 bool visible =
false;
773 Eigen::Vector2f pos, vertex;
779 if (!visible || !m_proj->
onScreen(pos))
783 glDisable(GL_TEXTURE_2D);
784 glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
787 vertex = pos + Eigen::Vector2f(2.0, 0.0);
788 glVertex2fv(vertex.data());
789 vertex = pos + Eigen::Vector2f(-2.0, 0.0);
790 glVertex2fv(vertex.data());
794 vertex = pos + Eigen::Vector2f(0.0, 2.0);
795 glVertex2fv(vertex.data());
796 vertex = pos + Eigen::Vector2f(0.0, -2.0);
797 glVertex2fv(vertex.data());
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Information about a ConstellationsArt object.
QColor labelColor(int index)
Get label color.
QString label(int index)
Get label.
QString imageName(int index)
Get image name.
QImage image(int index)
Get image.
const CachingDms * lat() const
A subclass of TrailObject that provides additional information needed for most solar system objects.
const QImage & image() const
KStarsData is the backbone of KStars.
ColorScheme * colorScheme()
SkyMapComposite * skyComposite()
A simple data container used by LineListIndex.
double findPA(const SkyObject *o, float x, float y) const
Determine the on-screen position angle of a SkyObject.
bool onScreen(const QPointF &p) const
Check whether the projected point is on-screen.
virtual Eigen::Vector2f toScreenVec(const SkyPoint *o, bool oRefract=true, bool *onVisibleHemisphere=nullptr) const
Given the coordinates of the SkyPoint argument, determine the pixel coordinates in the SkyMap.
Eigen::Vector2f clipLineVec(SkyPoint *p1, SkyPoint *p2) const
ASSUMES *p1 did not clip but *p2 did.
bool checkVisibility(const SkyPoint *p) const
Determine if the skypoint p is likely to be visible in the display window.
virtual QVector< Eigen::Vector2f > groundPoly(SkyPoint *labelpoint=nullptr, bool *drawLabel=nullptr) const
Get the ground polygon.
Represents an artificial satellites.
void drawLabel(Satellite *sat, const QPointF &pos)
Draw label of a satellite.
Provides all necessary information about an object in the sky: its coordinates, name(s),...
virtual QString name(void) const
Draws things on the sky, without regard to backend.
float starWidth(float mag) const
Get the width of a star of magnitude mag.
The sky coordinates of a point in the sky.
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Represents the supernova object.
static const QImage & getImage(const QString &name)
Return texture image.
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
QString xi18n(const char *text, const TYPE &arg...)
Type type(const QSqlDatabase &db)
KIOCORE_EXPORT QStringList list(const QString &fileClass)
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
QString label(StandardShortcut id)
float alphaF() const const
float blueF() const const
void getHsv(int *h, int *s, int *v, int *a) const const
float greenF() const const
void setHsv(int h, int s, int v, int a)
const_reference at(qsizetype i) const const
void reserve(qsizetype size)
qsizetype size() const const
QColor color() const const
Qt::PenStyle style() const const
qreal widthF() const const
bool isEmpty() const const