Stellarium  0.16.1
StelVertexArray.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2009 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 __STELVERTEXARRAY_HPP__
21 #define __STELVERTEXARRAY_HPP__
22 
23 #include "VecMath.hpp"
24 
25 #include <QVector>
26 #include <QDebug>
27 
29 {
30  // TODO maybe merge this with StelPainter DrawingMode
31  enum StelPrimitiveType
32  {
33  Points = 0x0000, // GL_POINTS
34  Lines = 0x0001, // GL_LINES
35  LineLoop = 0x0002, // GL_LINE_LOOP
36  LineStrip = 0x0003, // GL_LINE_STRIP
37  Triangles = 0x0004, // GL_TRIANGLES
38  TriangleStrip = 0x0005, // GL_TRIANGLE_STRIP
39  TriangleFan = 0x0006 // GL_TRIANGLE_FAN
40  };
41 
42  StelVertexArray(StelPrimitiveType pType=StelVertexArray::Triangles) : primitiveType(pType) {;}
43  StelVertexArray(const QVector<Vec3d>& v, StelPrimitiveType pType=StelVertexArray::Triangles,const QVector<Vec2f>& t=QVector<Vec2f>(), const QVector<unsigned short> i=QVector<unsigned short>()) :
44  vertex(v), texCoords(t), indices(i), primitiveType(pType) {;}
45 
49  QVector<Vec3d> vertex;
51  QVector<Vec2f> texCoords;
54  QVector<Vec3f> colors;
56  QVector<unsigned short> indices;
57 
58  StelPrimitiveType primitiveType;
59 
60  bool isIndexed() const {return !indices.isEmpty();}
61 
62  bool isTextured() const {return !texCoords.isEmpty();}
63 
64  bool isColored() const {return !colors.isEmpty();}
65 
66 
71  template<class Func>
72  inline Func foreachTriangle(Func func) const;
73 
76 
77 private:
78  // Below we define a few methods that are templated to be optimized according to different types of VertexArray :
79  // The template parameter <bool T> defines whether the array has a texture.
80  // The template parameter <bool I> defines whether the array is indexed.
81  // The template parameter <bool C> defines whether the array is colored.
82  template <bool I>
83  const Vec3d* specVertexAt(int i) const {
84  return &vertex.at(specIndiceAt<I>(i));
85  }
86 
87  template <bool T, bool I>
88  const Vec2f* specTexCoordAt(int i) const {
89  return T ? &texCoords.at(specIndiceAt<I>(i)) : Q_NULLPTR;
90  }
91 
92  template <bool C, bool I>
93  const Vec3f* specColorAt(int i) const {
94  return C ? &colors.at(specIndiceAt<I>(i)) : Q_NULLPTR;
95  }
96 
97  template<bool I>
98  unsigned int specIndiceAt(unsigned int i) const {
99  return I ? indices.at(i) : i;
100  }
101 
102  template<bool T, bool I, bool C, class Func>
103  inline Func specForeachTriangle(Func func) const;
104 
105 };
106 
107 // Serialization routines
108 QDataStream& operator<<(QDataStream& out, const StelVertexArray&);
109 QDataStream& operator>>(QDataStream& in, StelVertexArray&);
110 
111 template<class Func>
112 Func StelVertexArray::foreachTriangle(Func func) const
113 {
114  // Here we just dispatch the method into one of the 8 possible cases
115  bool textured = isTextured();
116  bool colored = isColored();
117  bool useIndice = isIndexed();
118 
119  if (textured)
120  {
121  if (useIndice)
122  {
123  if (colored)
124  return specForeachTriangle<true, true, true, Func>(func);
125  else
126  return specForeachTriangle<true, true, false, Func>(func);
127  }
128  else // not indiced
129  {
130  if (colored)
131  return specForeachTriangle<true, false, true, Func>(func);
132  else
133  return specForeachTriangle<true, false, false, Func>(func);
134  }
135  }
136  else // not textured
137  {
138  if (useIndice)
139  {
140  if (colored)
141  return specForeachTriangle<false, true, true, Func>(func);
142  else
143  return specForeachTriangle<false, true, false, Func>(func);
144  }
145  else // not indiced
146  {
147  if (colored)
148  return specForeachTriangle<false, false, true, Func>(func);
149  else
150  return specForeachTriangle<false, false, false, Func>(func);
151  }
152  }
153 }
154 
155 template<bool T, bool I, bool C, class Func>
156 Func StelVertexArray::specForeachTriangle(Func func) const
157 {
158  switch (primitiveType)
159  {
160  case StelVertexArray::Triangles:
161  Q_ASSERT(vertex.size() % 3 == 0);
162  for (int i = 0; i < vertex.size(); i += 3)
163  {
164  func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
165  specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
166  specColorAt<C, I>(i), specColorAt<C, I>(i+1), specColorAt<C, I>(i+2),
167  specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
168  }
169  break;
170  case StelVertexArray::TriangleFan:
171  {
172  const Vec3d* v0 = specVertexAt<I>(0);
173  const Vec2f* t0 = specTexCoordAt<T, I>(0);
174  const Vec3f* c0 = specColorAt<C, I>(0);
175  unsigned int i0 = specIndiceAt<I>(0);
176  for (int i = 1; i < vertex.size() - 1; ++i)
177  {
178  func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
179  t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
180  c0, specColorAt<C, I>(i), specColorAt<C, I>(i+1),
181  i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
182  }
183  break;
184  }
185  case StelVertexArray::TriangleStrip:
186  {
187  for (int i = 2; i < vertex.size(); ++i)
188  {
189  if (i % 2 == 0)
190  func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
191  specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
192  specColorAt<C, I>(i-2), specColorAt<C, I>(i-1), specColorAt<C, I>(i),
193  specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
194  else
195  func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
196  specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
197  specColorAt<C, I>(i-1), specColorAt<C, I>(i-2), specColorAt<C, I>(i),
198  specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
199  }
200  break;
201  }
202  default:
203  Q_ASSERT_X(0, Q_FUNC_INFO, "unsupported primitive type");
204  }
205  return func;
206 }
207 
208 
209 #endif // __STELVERTEXARRAY_HPP__
QVector< Vec2f > texCoords
OpenGL compatible array of edge flags to be displayed using vertex arrays.
Func foreachTriangle(Func func) const
call a function for each triangle of the array.
QVector< Vec3f > colors
OpenGL compatible array of vertex colors to be displayed using arrays.
A templatized 2d vector compatible with openGL.
Definition: VecMath.hpp:32
QDataStream & operator<<(QDataStream &out, const SphericalRegionP &region)
Serialize the passed SphericalRegionP into a binary blob.
Provide the main interface to all operations of projecting coordinates from sky to screen...
QVector< Vec3d > vertex
OpenGL compatible array of 3D vertex to be displayed using vertex arrays.
QDataStream & operator>>(QDataStream &in, SphericalRegionP &region)
Load the SphericalRegionP from a binary blob.
StelVertexArray removeDiscontinuousTriangles(const class StelProjector *prj) const
Create a copy of the array with all the triangles intersecting the projector discontinuity removed...
QVector< unsigned short > indices
OpenGL compatible array of indices for the vertex and the textures.