Stellarium  0.16.1
StelPainter.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2008 Fabien Chereau
4  *
5  * This program is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU General Public License
7  * as published by the Free Software Foundation; either version 2
8  * of the License, or (at your option) any later version.
9  *
10  * This program is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program; if not, write to the Free Software
17  * Foundation, Inc., 51 Franklin Street, Suite 500, Boston, MA 02110-1335, USA.
18  */
19 
20 #ifndef _STELPAINTER_HPP_
21 #define _STELPAINTER_HPP_
22 
23 #include "StelOpenGL.hpp"
24 #include "VecMath.hpp"
25 #include "StelSphereGeometry.hpp"
26 #include "StelProjectorType.hpp"
27 #include "StelProjector.hpp"
28 #include <QString>
29 #include <QVarLengthArray>
30 #include <QFontMetrics>
31 
32 class QOpenGLShaderProgram;
33 
40 class StelPainter : protected QOpenGLFunctions
41 {
42 public:
43  friend class VertexArrayProjector;
44 
47  {
52  };
53 
56  {
57  Points = 0x0000,
58  Lines = 0x0001,
59  LineLoop = 0x0002,
60  LineStrip = 0x0003,
61  Triangles = 0x0004,
62  TriangleStrip = 0x0005,
63  TriangleFan = 0x0006
64  };
65 
66  explicit StelPainter(const StelProjectorP& prj);
67  ~StelPainter();
68 
72  inline QOpenGLFunctions* glFuncs() { return this; }
73 
75  const StelProjectorP& getProjector() const {return prj;}
76  void setProjector(const StelProjectorP& p);
77 
79  void drawViewportShape(void);
80 
91  void drawText(float x, float y, const QString& str, float angleDeg=0.f,
92  float xshift=0.f, float yshift=0.f, bool noGravity=true);
93  void drawText(const Vec3d& v, const QString& str, float angleDeg=0.f,
94  float xshift=0.f, float yshift=0.f, bool noGravity=true);
95 
102  void drawSphericalRegion(const SphericalRegion* region, SphericalPolygonDrawMode drawMode=SphericalPolygonDrawModeFill, const SphericalCap* clippingCap=Q_NULLPTR, bool doSubDivise=true, double maxSqDistortion=5.);
103 
104  void drawGreatCircleArcs(const StelVertexArray& va, const SphericalCap* clippingCap=Q_NULLPTR);
105 
106  void drawSphericalTriangles(const StelVertexArray& va, bool textured, bool colored, const SphericalCap* clippingCap=Q_NULLPTR, bool doSubDivide=true, double maxSqDistortion=5.);
107 
115  void drawSmallCircleArc(const Vec3d& start, const Vec3d& stop, const Vec3d& rotCenter, void (*viewportEdgeIntersectCallback)(const Vec3d& screenPos, const Vec3d& direction, void* userData)=Q_NULLPTR, void* userData=Q_NULLPTR);
116 
123  void drawGreatCircleArc(const Vec3d& start, const Vec3d& stop, const SphericalCap* clippingCap=Q_NULLPTR, void (*viewportEdgeIntersectCallback)(const Vec3d& screenPos, const Vec3d& direction, void* userData)=Q_NULLPTR, void* userData=Q_NULLPTR);
124 
128  void drawPath(const QVector<Vec3d> &points, const QVector<Vec4f> &colors);
129 
131  void drawCircle(float x, float y, float r);
132 
139  void drawSprite2dMode(float x, float y, float radius);
140  void drawSprite2dMode(const Vec3d& v, float radius);
141 
143  void drawSprite2dModeNoDeviceScale(float x, float y, float radius);
144 
151  void drawSprite2dMode(float x, float y, float radius, float rotation);
152 
156  void drawPoint2d(float x, float y);
157 
163  void drawLine2d(float x1, float y1, float x2, float y2);
164 
172  void drawRect2d(float x, float y, float width, float height, bool textured=true);
173 
189  void sSphere(float radius, float oneMinusOblateness, int slices, int stacks, int orientInside = 0, bool flipTexture = false,
190  float topAngle=0.0f, float bottomAngle=M_PI);
191 
203  static StelVertexArray computeSphereNoLight(float radius, float oneMinusOblateness, int slices, int stacks,
204  int orientInside = 0, bool flipTexture = false,
205  float topAngle=0.0f, float bottomAngle=M_PI);
206 
208  void sCylinder(float radius, float height, int slices, int orientInside = 0);
209 
218  static void computeFanDisk(float radius, int innerFanSlices, int level, QVector<double>& vertexArr, QVector<float>& texCoordArr);
219 
221  void sSphereMap(float radius, int slices, int stacks, float textureFov = 2.f*M_PI, int orientInside = 0);
222 
224  void setFont(const QFont& font);
225 
227  void setColor(float r, float g, float b, float a=1.f);
228 
230  Vec4f getColor() const;
231 
233  QFontMetrics getFontMetrics() const;
234 
239  void setBlending(bool enableBlending, GLenum blendSrc = GL_SRC_ALPHA, GLenum blendDst = GL_ONE_MINUS_SRC_ALPHA);
240 
241  void setDepthTest(bool enable);
242 
243  void setDepthMask(bool enable);
244 
246  void setCullFace(bool enable);
247 
249  void setLineSmooth(bool enable);
250 
252  void setLineWidth(float width);
253 
256  static void initGLShaders();
257 
260  static void deinitGLShaders();
261 
262  // Thoses methods should eventually be replaced by a single setVertexArray
264  void setVertexPointer(int size, int type, const void* pointer) {
265  vertexArray.size = size; vertexArray.type = type; vertexArray.pointer = pointer;
266  }
267 
269  void setTexCoordPointer(int size, int type, const void* pointer)
270  {
271  texCoordArray.size = size; texCoordArray.type = type; texCoordArray.pointer = pointer;
272  }
273 
275  void setColorPointer(int size, int type, const void* pointer)
276  {
277  colorArray.size = size; colorArray.type = type; colorArray.pointer = pointer;
278  }
279 
281  void setNormalPointer(int type, const void* pointer)
282  {
283  normalArray.size = 3; normalArray.type = type; normalArray.pointer = pointer;
284  }
285 
287  void enableClientStates(bool vertex, bool texture=false, bool color=false, bool normal=false);
288 
291  void setArrays(const Vec3d* vertices, const Vec2f* texCoords=Q_NULLPTR, const Vec3f* colorArray=Q_NULLPTR, const Vec3f* normalArray=Q_NULLPTR);
292  void setArrays(const Vec3f* vertices, const Vec2f* texCoords=Q_NULLPTR, const Vec3f* colorArray=Q_NULLPTR, const Vec3f* normalArray=Q_NULLPTR);
293 
299  void drawFromArray(DrawingMode mode, int count, int offset=0, bool doProj=true, const unsigned short *indices=Q_NULLPTR);
300 
303  void drawStelVertexArray(const StelVertexArray& arr, bool checkDiscontinuity=true);
304 
307  static bool linkProg(class QOpenGLShaderProgram* prog, const QString& name);
308 
309 private:
310 
311  friend class StelTextureMgr;
312  friend class StelTexture;
313 
315  struct GLState
316  {
317  GLState(QOpenGLFunctions *gl);
318 
319  bool blend;
320  GLenum blendSrc, blendDst;
321  bool depthTest;
322  bool depthMask;
323  bool cullFace;
324  bool lineSmooth;
325  GLfloat lineWidth;
326 
328  void apply();
331  void reset();
332  private:
333  QOpenGLFunctions* gl;
334  } glState;
335 
336  // From text-use-opengl-buffer
337  static QCache<QByteArray, struct StringTexture> texCache;
338  struct StringTexture* getTexTexture(const QString& str, int pixelSize);
339 
341  typedef struct ArrayDesc
342  {
343  ArrayDesc() : size(0), type(0), pointer(Q_NULLPTR), enabled(false) {}
344  int size; // The number of coordinates per vertex.
345  int type; // The data type of each coordinate (GL_SHORT, GL_INT, GL_FLOAT, or GL_DOUBLE).
346  const void* pointer; // Pointer to the first coordinate of the first vertex in the array.
347  bool enabled; // Define whether the array is enabled or not.
348  } ArrayDesc;
349 
352  ArrayDesc projectArray(const ArrayDesc& array, int offset, int count, const unsigned short *indices=Q_NULLPTR);
353 
361  void projectSphericalTriangle(const SphericalCap* clippingCap, const Vec3d* vertices, QVarLengthArray<Vec3f, 4096>* outVertices,
362  const Vec2f* texturePos=Q_NULLPTR, QVarLengthArray<Vec2f, 4096>* outTexturePos=Q_NULLPTR,
363  const Vec3f* colors=Q_NULLPTR, QVarLengthArray<Vec3f, 4096>* outColors=Q_NULLPTR,
364  double maxSqDistortion=5., int nbI=0,
365  bool checkDisc1=true, bool checkDisc2=true, bool checkDisc3=true) const;
366 
367  void drawTextGravity180(float x, float y, const QString& str, float xshift = 0, float yshift = 0);
368 
369  // Used by the method below
370  static QVector<Vec2f> smallCircleVertexArray;
371  static QVector<Vec4f> smallCircleColorArray;
372  void drawSmallCircleVertexArray();
373 
375  StelProjectorP prj;
376 
377 #ifndef NDEBUG
378  static class QMutex* globalMutex;
380 #endif
381 
383  QFont currentFont;
384 
385  Vec4f currentColor;
386 
387  static QOpenGLShaderProgram* basicShaderProgram;
388  struct BasicShaderVars {
389  int projectionMatrix;
390  int color;
391  int vertex;
392  };
393  static BasicShaderVars basicShaderVars;
394 
395  static QOpenGLShaderProgram* colorShaderProgram;
396  static BasicShaderVars colorShaderVars;
397 
398  static QOpenGLShaderProgram* texturesShaderProgram;
399  struct TexturesShaderVars {
400  int projectionMatrix;
401  int texCoord;
402  int vertex;
403  int texColor;
404  int texture;
405  };
406  static TexturesShaderVars texturesShaderVars;
407  static QOpenGLShaderProgram* texturesColorShaderProgram;
408  struct TexturesColorShaderVars {
409  int projectionMatrix;
410  int texCoord;
411  int vertex;
412  int color;
413  int texture;
414  };
415  static TexturesColorShaderVars texturesColorShaderVars;
416 
417 
419  ArrayDesc vertexArray;
421  ArrayDesc texCoordArray;
423  ArrayDesc normalArray;
425  ArrayDesc colorArray;
426 };
427 
428 #endif // _STELPAINTER_HPP_
429 
void drawCircle(float x, float y, float r)
Draw a simple circle, 2d viewport coordinates in pixel.
void setBlending(bool enableBlending, GLenum blendSrc=GL_SRC_ALPHA, GLenum blendDst=GL_ONE_MINUS_SRC_ALPHA)
Enable OpenGL blending.
void setTexCoordPointer(int size, int type, const void *pointer)
use instead of glTexCoordPointer
void sCylinder(float radius, float height, int slices, int orientInside=0)
Re-implementation of gluCylinder : glu is overridden for non-standard projection. ...
static void deinitGLShaders()
Delete the OpenGL shaders objects.
void setLineSmooth(bool enable)
Enables/disables line smoothing. By default, smoothing is disabled.
Vec4f getColor() const
Get the color currently used for drawing.
void setCullFace(bool enable)
Set the OpenGL GL_CULL_FACE state, by default face culling is disabled.
Draw the interior of the polygon filled with the current texture multiplied by vertex colors...
Definition: StelPainter.hpp:51
void drawSprite2dMode(float x, float y, float radius)
Draw a square using the current texture at the given projected 2d position.
A SphericalCap is defined by a direction and an aperture.
void enableClientStates(bool vertex, bool texture=false, bool color=false, bool normal=false)
Simulates glEnableClientState, basically you describe what data the ::drawFromArray call has availabl...
void setColor(float r, float g, float b, float a=1.f)
Set the color to use for subsequent drawing.
void drawPath(const QVector< Vec3d > &points, const QVector< Vec4f > &colors)
Draw a curve defined by a list of points.
Draw the interior of the polygon filled with the current texture.
Definition: StelPainter.hpp:50
GL_TRIANGLE_FAN.
Definition: StelPainter.hpp:63
void setColorPointer(int size, int type, const void *pointer)
use instead of glColorPointer
static void initGLShaders()
Create the OpenGL shaders programs used by the StelPainter.
QOpenGLFunctions * glFuncs()
Returns a QOpenGLFunctions object suitable for drawing directly with OpenGL while this StelPainter is...
Definition: StelPainter.hpp:72
const StelProjectorP & getProjector() const
Return the instance of projector associated to this painter.
Definition: StelPainter.hpp:75
void drawPoint2d(float x, float y)
Draw a GL_POINT at the given position.
A templatized 2d vector compatible with openGL.
Definition: VecMath.hpp:32
void drawLine2d(float x1, float y1, float x2, float y2)
Draw a line between the 2 points.
void drawSphericalRegion(const SphericalRegion *region, SphericalPolygonDrawMode drawMode=SphericalPolygonDrawModeFill, const SphericalCap *clippingCap=Q_NULLPTR, bool doSubDivise=true, double maxSqDistortion=5.)
Draw the given SphericalRegion.
QSharedPointer< StelProjector > StelProjectorP
Shared pointer on a StelProjector instance (implement reference counting)
static StelVertexArray computeSphereNoLight(float radius, float oneMinusOblateness, int slices, int stacks, int orientInside=0, bool flipTexture=false, float topAngle=0.0f, float bottomAngle=M_PI)
Generate a StelVertexArray for a sphere.
static void computeFanDisk(float radius, int innerFanSlices, int level, QVector< double > &vertexArr, QVector< float > &texCoordArr)
Draw a disk with a special texturing mode having texture center at center of disk.
Draw the interior of the polygon.
Definition: StelPainter.hpp:48
Provides functions for performing openGL drawing operations.
Definition: StelPainter.hpp:40
void drawText(float x, float y, const QString &str, float angleDeg=0.f, float xshift=0.f, float yshift=0.f, bool noGravity=true)
Draw the string at the given position and angle with the given font.
void drawSmallCircleArc(const Vec3d &start, const Vec3d &stop, const Vec3d &rotCenter, void(*viewportEdgeIntersectCallback)(const Vec3d &screenPos, const Vec3d &direction, void *userData)=Q_NULLPTR, void *userData=Q_NULLPTR)
Draw a small circle arc between points start and stop with rotation point in rotCenter.
void drawStelVertexArray(const StelVertexArray &arr, bool checkDiscontinuity=true)
Draws the primitives defined in the StelVertexArray.
SphericalPolygonDrawMode
Define the drawing mode when drawing polygons.
Definition: StelPainter.hpp:46
void setNormalPointer(int type, const void *pointer)
use instead of glNormalPointer
GL_LINE_LOOP.
Definition: StelPainter.hpp:59
GL_TRIANGLE_STRIP.
Definition: StelPainter.hpp:62
void setVertexPointer(int size, int type, const void *pointer)
use instead of glVertexPointer
Abstract class defining a region of the sphere.
Base texture class.
Definition: StelTexture.hpp:41
void drawViewportShape(void)
Fill with black around the viewport.
Manage textures loading.
void setFont(const QFont &font)
Set the font to use for subsequent text drawing.
void drawGreatCircleArc(const Vec3d &start, const Vec3d &stop, const SphericalCap *clippingCap=Q_NULLPTR, void(*viewportEdgeIntersectCallback)(const Vec3d &screenPos, const Vec3d &direction, void *userData)=Q_NULLPTR, void *userData=Q_NULLPTR)
Draw a great circle arc between points start and stop.
void drawSprite2dModeNoDeviceScale(float x, float y, float radius)
Same as drawSprite2dMode but don&#39;t scale according to display device scaling.
void setLineWidth(float width)
Sets the line width. Default is 1.0f.
Define the StelProjectorP type.
void drawRect2d(float x, float y, float width, float height, bool textured=true)
Draw a rectangle using the current texture at the given projected 2d position.
Draw the boundary of the polygon.
Definition: StelPainter.hpp:49
QFontMetrics getFontMetrics() const
Get the font metrics for the current font.
static bool linkProg(class QOpenGLShaderProgram *prog, const QString &name)
Link an opengl program and show a message in case of error or warnings.
void drawFromArray(DrawingMode mode, int count, int offset=0, bool doProj=true, const unsigned short *indices=Q_NULLPTR)
Draws primitives using vertices from the arrays specified by setArrays() or enabled via enableClientS...
void setArrays(const Vec3d *vertices, const Vec2f *texCoords=Q_NULLPTR, const Vec3f *colorArray=Q_NULLPTR, const Vec3f *normalArray=Q_NULLPTR)
convenience method that enable and set all the given arrays.
Define all SphericalGeometry primitives as well as the SphericalRegionP type.
void sSphereMap(float radius, int slices, int stacks, float textureFov=2.f *M_PI, int orientInside=0)
Draw a fisheye texture in a sphere.
DrawingMode
Define the drawing mode when drawing vertex.
Definition: StelPainter.hpp:55
GL_LINE_STRIP.
Definition: StelPainter.hpp:60