Kstars

skyglpainter.cpp
1 /*
2  SPDX-FileCopyrightText: 2010 Henry de Valence <[email protected]>
3 
4  SPDX-License-Identifier: GPL-2.0-or-later
5 */
6 
7 #ifdef _WIN32
8 #include <windows.h>
9 #endif
10 #include "skyglpainter.h"
11 
12 #include <cstddef>
13 #include <Eigen/Geometry>
14 
15 #include <GL/gl.h>
16 #include <QGLWidget>
17 
18 #include "skymap.h"
19 #include "kstarsdata.h"
20 #include "Options.h"
21 
22 #include "texturemanager.h"
23 
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"
38 
39 Eigen::Vector2f SkyGLPainter::m_vertex[NUMTYPES][6 * BUFSIZE];
40 Eigen::Vector2f SkyGLPainter::m_texcoord[NUMTYPES][6 * BUFSIZE];
41 Eigen::Vector3f SkyGLPainter::m_color[NUMTYPES][6 * BUFSIZE];
42 int SkyGLPainter::m_idx[NUMTYPES];
43 bool SkyGLPainter::m_init = false;
44 
45 SkyGLPainter::SkyGLPainter(QGLWidget *widget) : SkyPainter()
46 {
47  m_widget = widget;
48  if (!m_init)
49  {
50  qDebug() << "Initializing texcoord arrays...\n";
51  for (int i = 0; i < NUMTYPES; ++i)
52  {
53  m_idx[i] = 0;
54  for (int j = 0; j < BUFSIZE; ++j)
55  {
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);
62  }
63  }
64  //Generate textures that were loaded before the SkyMap was
65  m_init = true;
66  }
67 }
68 
69 void SkyGLPainter::drawBuffer(int type)
70 {
71  // Prevent crash if type > UNKNOWN
72  if (type > SkyObject::TYPE_UNKNOWN)
73  type = SkyObject::TYPE_UNKNOWN;
74 
75  //printf("Drawing buffer for type %d, has %d objects\n", type, m_idx[type]);
76  if (m_idx[type] == 0)
77  return;
78 
79  glEnable(GL_TEXTURE_2D);
80  switch (type)
81  {
82  case 3:
83  case 13:
84  TextureManager::bindTexture("open-cluster", m_widget);
85  break;
86  case 4:
87  TextureManager::bindTexture("globular-cluster", m_widget);
88  break;
89  case 6:
90  TextureManager::bindTexture("planetary-nebula", m_widget);
91  break;
92  case 5:
93  case 7:
94  case 15:
95  TextureManager::bindTexture("gaseous-nebula", m_widget);
96  break;
97  case 8:
98  case 16:
99  TextureManager::bindTexture("galaxy", m_widget);
100  break;
101  case 14:
102  TextureManager::bindTexture("galaxy-cluster", m_widget);
103  break;
104  case 0:
105  case 1:
106  default:
107  TextureManager::bindTexture("star", m_widget);
108  break;
109  }
110 
111  glEnable(GL_BLEND);
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);
117 
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]);
121 
122  glDrawArrays(GL_TRIANGLES, 0, 6 * m_idx[type]);
123  m_idx[type] = 0;
124 
125  glDisableClientState(GL_VERTEX_ARRAY);
126  glDisableClientState(GL_COLOR_ARRAY);
127  glDisableClientState(GL_TEXTURE_COORD_ARRAY);
128 }
129 
130 bool SkyGLPainter::addItem(SkyPoint *p, int type, float width, char sp)
131 {
132  bool visible = false;
133  Eigen::Vector2f vec = m_proj->toScreenVec(p, true, &visible);
134  if (!visible)
135  return false;
136 
137  // Prevent crash if type > UNKNOWN
138  if (type > SkyObject::TYPE_UNKNOWN)
139  type = SkyObject::TYPE_UNKNOWN;
140 
141  //If the buffer is full, flush it
142  if (m_idx[type] == BUFSIZE)
143  {
144  drawBuffer(type);
145  }
146 
147  int i = 6 * m_idx[type];
148  float w = width / 2.;
149 
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);
156 
157  Eigen::Vector3f c(1., 1., 1.);
158  if (sp != 'x' && Options::starColorMode() != 0)
159  {
160  // We have a star and aren't drawing real star colors
161  switch (Options::starColorMode())
162  {
163  case 1: // solid red
164  c = Eigen::Vector3f(255. / 255., 0., 0.);
165  break;
166  case 2: // solid black
167  c = Eigen::Vector3f(0., 0., 0.);
168  break;
169  case 3: // Solid white
170  c = Eigen::Vector3f(1., 1., 1.);
171  break;
172  }
173  }
174  else
175  {
176  QColor starColor;
177 
178  // Set RGB values into QColor
179  switch (sp)
180  {
181  case 'o':
182  case 'O':
183  starColor.setRgb(153, 153, 255);
184  break;
185  case 'b':
186  case 'B':
187  starColor.setRgb(151, 233, 255);
188  break;
189  case 'a':
190  case 'A':
191  starColor.setRgb(153, 255, 255);
192  break;
193  case 'f':
194  case 'F':
195  starColor.setRgb(219, 255, 135);
196  break;
197  case 'g':
198  case 'G':
199  starColor.setRgb(255, 255, 153);
200  break;
201  case 'k':
202  case 'K':
203  starColor.setRgb(255, 193, 153);
204  break;
205  case 'm':
206  case 'M':
207  starColor.setRgb(255, 153, 153);
208  break;
209  case 'x':
210  starColor.setRgb(m_pen[0] * 255, m_pen[1] * 255, m_pen[2] * 255);
211  break;
212  default:
213  starColor.setRgb(153, 255, 255);
214  break; // If we don't know what spectral type, we use the same as 'A' (See SkyQPainter)
215  }
216 
217  // Convert to HSV space using QColor's methods and adjust saturation.
218  int h, s, v;
219  starColor.getHsv(&h, &s, &v);
220  s = (Options::starColorIntensity() / 10.) *
221  200.; // Rewrite the saturation based on the star color intensity setting, 200 is the hard-wired max saturation, just to approximately match up with QPainter mode.
222  starColor.setHsv(h, s, v);
223 
224  // Get RGB ratios and put them in 'c'
225  c = Eigen::Vector3f(starColor.redF(), starColor.greenF(), starColor.blueF());
226  }
227  for (int j = 0; j < 6; ++j)
228  {
229  m_color[type][i + j] = c;
230  }
231 
232  ++m_idx[type];
233  return true;
234 }
235 
236 void SkyGLPainter::drawTexturedRectangle(const QImage &img, const Eigen::Vector2f &pos, const float angle, const float sizeX,
237  const float sizeY)
238 {
239  // Set up texture
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);
244 
245  // Render rectangle
246  glPushMatrix();
247  glTranslatef(pos.x(), pos.y(), 0);
248  glRotatef(angle, 0, 0, 1);
249  glScalef(sizeX, sizeY, 1);
250 
251  glBegin(GL_QUADS);
252  // Note! Y coordinate of texture is mirrored w.r.t. to
253  // vertex coordinates to account for difference between
254  // OpenGL and QPainter coordinate system.
255  // Otherwise image would appear mirrored
256  glTexCoord2f(0, 1);
257  glVertex2f(-0.5, -0.5);
258 
259  glTexCoord2f(1, 1);
260  glVertex2f(0.5, -0.5);
261 
262  glTexCoord2f(1, 0);
263  glVertex2f(0.5, 0.5);
264 
265  glTexCoord2f(0, 0);
266  glVertex2f(-0.5, 0.5);
267  glEnd();
268 
269  glPopMatrix();
270 }
271 
272 bool SkyGLPainter::drawPlanet(KSPlanetBase *planet)
273 {
274  //If it's surely not visible, just stop now
275  if (!m_proj->checkVisibility(planet))
276  return false;
277 
278  float zoom = Options::zoomFactor();
279  float fakeStarSize = (10.0 + log10(zoom) - log10(MINZOOM)) * (10 - planet->mag()) / 10;
280  fakeStarSize = qMin(fakeStarSize, 20.f);
281 
282  float size = planet->angSize() * dms::PI * zoom / 10800.0;
283  if (size < fakeStarSize || planet->image().isNull())
284  {
285  // Draw them as bright stars of appropriate color instead of images
286  char spType;
287  //FIXME: do these need i18n?
288  if (planet->name() == xi18n("Sun"))
289  {
290  spType = 'G';
291  }
292  else if (planet->name() == xi18n("Mars"))
293  {
294  spType = 'K';
295  }
296  else if (planet->name() == xi18n("Jupiter") || planet->name() == xi18n("Mercury") ||
297  planet->name() == xi18n("Saturn"))
298  {
299  spType = 'F';
300  }
301  else
302  {
303  spType = 'B';
304  }
305  return addItem(planet, planet->type(), qMin(fakeStarSize, (float)20.), spType);
306  }
307  else
308  {
309  // Draw them as textures
310  bool visible = false;
311  Eigen::Vector2f pos = m_proj->toScreenVec(planet, true, &visible);
312  if (!visible)
313  return false;
314 
315  //Because Saturn has rings, we inflate its image size by a factor 2.5
316  if (planet->name() == "Saturn")
317  size *= 2.5;
318 
319  drawTexturedRectangle(planet->image(), pos, m_proj->findPA(planet, pos.x(), pos.y()), size, size);
320  return true;
321  }
322 }
323 
324 bool SkyGLPainter::drawPointSource(const SkyPoint *loc, float mag, char sp)
325 {
326  //If it's surely not visible, just stop now
327  if (!m_proj->checkVisibility(loc))
328  return false;
329  return addItem(loc, SkyObject::STAR, starWidth(mag), sp);
330 }
331 
332 void SkyGLPainter::drawSkyPolygon(LineList *list)
333 {
334  SkyList *points = list->points();
335  bool isVisible, isVisibleLast;
336  SkyPoint *pLast = points->last();
337  Eigen::Vector2f oLast = m_proj->toScreenVec(pLast, true, &isVisibleLast);
338  // & with the result of checkVisibility to clip away things below horizon
339  isVisibleLast &= m_proj->checkVisibility(pLast);
340 
341  //Guess that we will require around the same number of items as in points.
342  QVector<Eigen::Vector2f> polygon;
343  polygon.reserve(points->size());
344  for (int i = 0; i < points->size(); ++i)
345  {
346  SkyPoint *pThis = points->at(i);
347  Eigen::Vector2f oThis = m_proj->toScreenVec(pThis, true, &isVisible);
348  // & with the result of checkVisibility to clip away things below horizon
349  isVisible &= m_proj->checkVisibility(pThis);
350 
351  if (isVisible && isVisibleLast)
352  {
353  polygon << oThis;
354  }
355  else if (isVisibleLast)
356  {
357  Eigen::Vector2f oMid = m_proj->clipLineVec(pLast, pThis);
358  polygon << oMid;
359  }
360  else if (isVisible)
361  {
362  Eigen::Vector2f oMid = m_proj->clipLineVec(pThis, pLast);
363  polygon << oMid;
364  polygon << oThis;
365  }
366 
367  pLast = pThis;
368  oLast = oThis;
369  isVisibleLast = isVisible;
370  }
371 
372 // false -> makes kstars slower but is always accurate
373 // true -> faster but potentially results in incorrect rendering
374 #define KSTARS_ASSUME_CONVEXITY false
375  if (polygon.size())
376  {
377  drawPolygon(polygon, KSTARS_ASSUME_CONVEXITY);
378  }
379 }
380 
381 void SkyGLPainter::drawPolygon(const QVector<Eigen::Vector2f> &polygon, bool convex, bool flush_buffers)
382 {
383  //Flush all buffers
384  if (flush_buffers)
385  {
386  for (int i = 0; i < NUMTYPES; ++i)
387  {
388  drawBuffer(i);
389  }
390  }
391  glDisable(GL_TEXTURE_2D);
392  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
393  if (!convex)
394  {
395  //Set up the stencil buffer and disable the color buffer
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);
401  //Now draw a triangle fan. Because of the GL_INVERT,
402  //this will fill the stencil buffer with odd-even fill.
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);
407 
408  //Now draw the stencil:
409  glStencilFunc(GL_NOTEQUAL, 0, 0xffffffff);
410  glColorMask(1, 1, 1, 1);
411  glStencilOp(GL_KEEP, GL_KEEP, GL_KEEP);
412  glBegin(GL_QUADS);
413  glVertex2f(0, 0);
414  glVertex2f(0, m_widget->height());
415  glVertex2f(m_widget->width(), m_widget->height());
416  glVertex2f(m_widget->width(), 0);
417  glEnd();
418  glDisable(GL_STENCIL_TEST);
419  }
420  else
421  {
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);
426  }
427 }
428 
429 void SkyGLPainter::drawHorizon(bool filled, SkyPoint *labelPoint, bool *drawLabel)
430 {
431  QVector<Eigen::Vector2f> ground = m_proj->groundPoly(labelPoint, drawLabel);
432 
433  if (ground.size())
434  {
435  if (filled)
436  {
437  glDisableClientState(GL_COLOR_ARRAY);
438  drawPolygon(ground, false, false);
439  }
440  else
441  {
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);
448  }
449  }
450 }
451 
452 //This implementation is *correct* but slow.
453 void SkyGLPainter::drawSkyPolyline(LineList *list, SkipHashList *skipList, LineListLabel *label)
454 {
455  glDisable(GL_TEXTURE_2D);
456  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
457  glBegin(GL_LINE_STRIP);
458  SkyList *points = list->points();
459  bool isVisible, isVisibleLast;
460  Eigen::Vector2f oLast = m_proj->toScreenVec(points->first(), true, &isVisibleLast);
461  // & with the result of checkVisibility to clip away things below horizon
462  isVisibleLast &= m_proj->checkVisibility(points->first());
463  if (isVisibleLast)
464  {
465  glVertex2fv(oLast.data());
466  }
467 
468  for (int i = 1; i < points->size(); ++i)
469  {
470  Eigen::Vector2f oThis = m_proj->toScreenVec(points->at(i), true, &isVisible);
471  // & with the result of checkVisibility to clip away things below horizon
472  isVisible &= m_proj->checkVisibility(points->at(i));
473 
474  bool doSkip = (skipList ? skipList->skip(i) : false);
475  //This tells us whether we need to end the current line or whether we
476  //are to keep drawing into it. If we skip, then we are going to have to end.
477  bool shouldEnd = doSkip;
478 
479  if (!doSkip)
480  {
481  if (isVisible && isVisibleLast)
482  {
483  glVertex2fv(oThis.data());
484  if (label)
485  {
486  label->updateLabelCandidates(oThis.x(), oThis.y(), list, i);
487  }
488  }
489  else if (isVisibleLast)
490  {
491  Eigen::Vector2f oMid = m_proj->clipLineVec(points->at(i - 1), points->at(i));
492  glVertex2fv(oMid.data());
493  //If the last point was visible but this one isn't we are at
494  //the end of a strip, so we need to end
495  shouldEnd = true;
496  }
497  else if (isVisible)
498  {
499  Eigen::Vector2f oMid = m_proj->clipLineVec(points->at(i), points->at(i - 1));
500  glVertex2fv(oMid.data());
501  glVertex2fv(oThis.data());
502  }
503  }
504 
505  if (shouldEnd)
506  {
507  glEnd();
508  glBegin(GL_LINE_STRIP);
509  if (isVisible)
510  {
511  glVertex2fv(oThis.data());
512  }
513  }
514 
515  isVisibleLast = isVisible;
516  }
517  glEnd();
518 }
519 
520 //FIXME: implement these two
521 
522 void SkyGLPainter::drawObservingList(const QList<SkyObject *> &obs)
523 {
524  // TODO: Generalize to drawTargetList or something like that. Make
525  // texture changeable etc.
526  // TODO: Draw labels when required
527 
528  foreach (SkyObject *obj, obs)
529  {
530  if (!m_proj->checkVisibility(obj))
531  continue;
532  bool visible;
533  Eigen::Vector2f vec = m_proj->toScreenVec(obj, true, &visible);
534  if (!visible || !m_proj->onScreen(vec))
535  continue;
536  const float size = 30.;
537  QImage obsmarker = TextureManager::getImage("obslistsymbol");
538  drawTexturedRectangle(obsmarker, vec, 0, size, size);
539  }
540 }
541 
542 void SkyGLPainter::drawFlags()
543 {
544  KStarsData *data = KStarsData::Instance();
545  SkyPoint *point;
546  QImage image;
547  const QString label;
548  bool visible = false;
549  Eigen::Vector2f vec;
550  int i;
551 
552  for (i = 0; i < data->skyComposite()->flags()->size(); i++)
553  {
554  point = data->skyComposite()->flags()->pointList().at(i);
555  image = data->skyComposite()->flags()->image(i);
556 
557  // Set Horizontal coordinates
558  point->EquatorialToHorizontal(data->lst(), data->geo()->lat());
559 
560  // Get flag position on screen
561  vec = m_proj->toScreenVec(point, true, &visible);
562 
563  // Return if flag is not visible
564  if (!visible || !m_proj->onScreen(vec))
565  continue;
566 
567  const QImage &img =
568  data->skyComposite()->flags()->imageName(i) == "Default" ? TextureManager::getImage("defaultflag") : image;
569 
570  drawTexturedRectangle(img, vec, 0, img.width(), img.height());
571  drawText(vec.x(), vec.y(), data->skyComposite()->flags()->label(i), QFont("Courier New", 10, QFont::Bold),
572  data->skyComposite()->flags()->labelColor(i));
573  }
574 }
575 
576 void SkyGLPainter::drawText(int x, int y, const QString text, QFont font, QColor color)
577 {
578  // Return if text is empty
579  if (text.isEmpty())
580  return;
581 
582  int longest, tex_size = 2;
583 
584  // Get size of text
585  QFontMetrics fm(font);
586  const QRect bounding_rect = fm.boundingRect(text);
587 
588  // Compute texture size
589  if (bounding_rect.width() > bounding_rect.height())
590  longest = bounding_rect.width();
591  else
592  longest = bounding_rect.height();
593 
594  while (tex_size < longest)
595  {
596  tex_size *= 2;
597  }
598 
599  // Create image of text
600  QImage text_image(tex_size, tex_size, QImage::Format_ARGB32);
601  text_image.fill(Qt::transparent);
602  QPainter p(&text_image);
603  p.setFont(font);
604  p.setPen(color);
605  p.drawText(0, tex_size / 2, text);
606  p.end();
607 
608  // Create texture
609  float w = text_image.width();
610  float h = text_image.height();
611  float vx = x + 0.5 * w + 10;
612  float vy = y - 10;
613  drawTexturedRectangle(text_image, Eigen::Vector2f(vx, vy), 0, w, h);
614 }
615 
616 bool SkyGLPainter::drawConstellationArtImage(ConstellationsArt *obj)
617 {
618 }
619 
620 void SkyGLPainter::drawSkyLine(SkyPoint *a, SkyPoint *b)
621 {
622  bool aVisible, bVisible;
623  Eigen::Vector2f aScreen = m_proj->toScreenVec(a, true, &aVisible);
624  Eigen::Vector2f bScreen = m_proj->toScreenVec(b, true, &bVisible);
625 
626  glDisable(GL_TEXTURE_2D);
627  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
628  glBegin(GL_LINE_STRIP);
629 
630  //THREE CASES:
631  if (aVisible && bVisible)
632  {
633  //Both a,b visible, so paint the line normally:
634  glVertex2fv(aScreen.data());
635  glVertex2fv(bScreen.data());
636  }
637  else if (aVisible)
638  {
639  //a is visible but b isn't:
640  glVertex2fv(aScreen.data());
641  glVertex2fv(m_proj->clipLineVec(a, b).data());
642  }
643  else if (bVisible)
644  {
645  //b is visible but a isn't:
646  glVertex2fv(bScreen.data());
647  glVertex2fv(m_proj->clipLineVec(b, a).data());
648  } //FIXME: what if both are offscreen but the line isn't?
649 
650  glEnd();
651 }
652 
653 void SkyGLPainter::drawSkyBackground()
654 {
655  glDisable(GL_TEXTURE_2D);
656  QColor bg = KStarsData::Instance()->colorScheme()->colorNamed("SkyColor");
657  glClearColor(bg.redF(), bg.greenF(), bg.blueF(), bg.alphaF());
658  glClear(GL_COLOR_BUFFER_BIT);
659 }
660 
661 void SkyGLPainter::end()
662 {
663  for (int i = 0; i < NUMTYPES; ++i)
664  {
665  drawBuffer(i);
666  }
667 }
668 
669 void SkyGLPainter::begin()
670 {
671  m_proj = m_sm->projector();
672 
673  //Load ortho projection
674  glViewport(0, 0, m_widget->width(), m_widget->height());
675  glMatrixMode(GL_PROJECTION);
676  glLoadIdentity();
677  glOrtho(0, m_widget->width(), m_widget->height(), 0, -1, 1);
678 
679  //reset modelview matrix
680  glMatrixMode(GL_MODELVIEW);
681  glLoadIdentity();
682 
683  //Set various parameters
684  glDisable(GL_LIGHTING);
685  glDisable(GL_COLOR_MATERIAL);
686  glDisable(GL_CULL_FACE);
687  glDisable(GL_DEPTH_TEST);
688  glDepthMask(GL_FALSE);
689  glPointSize(1.);
690  glEnable(GL_POINT_SMOOTH);
691  glEnable(GL_LINE_SMOOTH);
692  glEnable(GL_POLYGON_SMOOTH);
693  glLineStipple(1, 0xCCCC);
694  glEnable(GL_BLEND);
695 
696  glClearStencil(0);
697 }
698 
699 void SkyGLPainter::setBrush(const QBrush &brush)
700 {
701  Q_UNUSED(brush);
702  /*
703  QColor c = brush.color();
704  m_pen = Eigen::Vector4f( c.redF(), c.greenF(), c.blueF(), c.alphaF() );
705  glColor4fv( m_pen.data() );
706  */
707 }
708 
709 void SkyGLPainter::setPen(const QPen &pen)
710 {
711  QColor c = pen.color();
712  m_pen = Eigen::Vector4f(c.redF(), c.greenF(), c.blueF(), c.alphaF());
713  glColor4fv(m_pen.data());
714  glLineWidth(pen.widthF());
715  if (pen.style() != Qt::SolidLine)
716  {
717  glEnable(GL_LINE_STIPPLE);
718  }
719  else
720  {
721  glDisable(GL_LINE_STIPPLE);
722  }
723 }
724 
725 void SkyGLPainter::drawSatellite(Satellite *sat)
726 {
727  KStarsData *data = KStarsData::Instance();
728  bool visible = false;
729  Eigen::Vector2f pos, vertex;
730 
731  sat->HorizontalToEquatorial(data->lst(), data->geo()->lat());
732 
733  pos = m_proj->toScreenVec(sat, true, &visible);
734 
735  if (!visible || !m_proj->onScreen(pos))
736  return;
737 
738  if (Options::drawSatellitesLikeStars())
739  {
740  drawPointSource(sat, 3.5, 'B');
741  }
742  else
743  {
744  if (sat->isVisible())
745  setPen(data->colorScheme()->colorNamed("VisibleSatColor"));
746  else
747  setPen(data->colorScheme()->colorNamed("SatColor"));
748 
749  glDisable(GL_TEXTURE_2D);
750  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
751  glBegin(GL_QUADS);
752 
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());
761 
762  glEnd();
763  }
764 
765  if (Options::showSatellitesLabels())
766  data->skyComposite()->satellites()->drawLabel(sat, QPointF(pos.x(), pos.y()));
767 }
768 
769 bool SkyGLPainter::drawSupernova(Supernova *sup)
770 {
771  KStarsData *data = KStarsData::Instance();
772  bool visible = false;
773  Eigen::Vector2f pos, vertex;
774 
775  sup->HorizontalToEquatorial(data->lst(), data->geo()->lat());
776 
777  pos = m_proj->toScreenVec(sup, true, &visible);
778 
779  if (!visible || !m_proj->onScreen(pos))
780  return false;
781  setPen(data->colorScheme()->colorNamed("SupernovaColor"));
782 
783  glDisable(GL_TEXTURE_2D);
784  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
785 
786  glBegin(GL_LINES);
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());
791  glEnd();
792 
793  glBegin(GL_LINES);
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());
798  glEnd();
799 
800  return true;
801 }
qreal greenF() const const
bool isVisible()
Definition: satellite.cpp:1294
static constexpr double PI
PI is a const static member; it's public so that it can be used anywhere, as long as dms....
Definition: dms.h:380
qreal widthF() const const
qreal redF() const const
int height() const const
T & last()
QImage image(int index)
Get image.
qreal blueF() const const
Type type(const QSqlDatabase &db)
Stores dms coordinates for a point in the sky. for converting between coordinate systems.
Definition: skypoint.h:44
CachingDms * lst()
Definition: kstarsdata.h:223
virtual QString name(void) const
Definition: skyobject.h:145
int width() const const
float mag() const
Definition: skyobject.h:206
KIOFILEWIDGETS_EXPORT QStringList list(const QString &fileClass)
void setHsv(int h, int s, int v, int a)
QString xi18n(const char *text, const TYPE &arg...)
QColor labelColor(int index)
Get label color.
T * data()
T & first()
void EquatorialToHorizontal(const CachingDms *LST, const CachingDms *lat)
Determine the (Altitude, Azimuth) coordinates of the SkyPoint from its (RA, Dec) coordinates,...
Definition: skypoint.cpp:77
int type(void) const
Definition: skyobject.h:188
QAction * zoom(const QObject *recvr, const char *slot, QObject *parent)
const QImage & image() const
Definition: ksplanetbase.h:127
const CachingDms * lat() const
Definition: geolocation.h:70
Qt::PenStyle style() const const
const T & at(int i) const const
ColorScheme * colorScheme()
Definition: kstarsdata.h:171
bool isEmpty() const const
GeoLocation * geo()
Definition: kstarsdata.h:229
const T & at(int i) const const
Draws things on the sky, without regard to backend.
Definition: skypainter.h:37
void reserve(int size)
qreal alphaF() const const
SkyMapComposite * skyComposite()
Definition: kstarsdata.h:165
QString label(StandardShortcut id)
double angSize() const
Definition: ksplanetbase.h:184
void drawLabel(Satellite *sat, const QPointF &pos)
Draw label of a satellite.
int height() const const
void setRgb(int r, int g, int b, int a)
QString label(int index)
Get label.
static const QImage & getImage(const QString &name)
Return texture image.
QString imageName(int index)
Get image name.
QColor color() const const
void HorizontalToEquatorial(const dms *LST, const dms *lat)
Determine the (RA, Dec) coordinates of the SkyPoint from its (Altitude, Azimuth) coordinates,...
Definition: skypoint.cpp:143
int size() const const
void getHsv(int *h, int *s, int *v, int *a) const const
SolidLine
Information about a ConstellationsArt object. This class represents a constellation image.
QColor colorNamed(const QString &name) const
Retrieve a color by name.
Definition: colorscheme.cpp:86
Information about an object in the sky.
Definition: skyobject.h:41
transparent
Provides necessary information about objects in the solar system.
Definition: ksplanetbase.h:49
int width() const const
This file is part of the KDE documentation.
Documentation copyright © 1996-2022 The KDE developers.
Generated on Fri Aug 12 2022 04:00:58 by doxygen 1.8.17 written by Dimitri van Heesch, © 1997-2006

KDE's Doxygen guidelines are available online.