Stellarium 0.15.2
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. // NEW GZ
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)) : NULL;
90  }
91 
92  // NEW GZ
93  template <bool C, bool I>
94  const Vec3f* specColorAt(int i) const {
95  return C ? &colors.at(specIndiceAt<I>(i)) : NULL;
96  }
97 
98  template<bool I>
99  unsigned int specIndiceAt(unsigned int i) const {
100  return I ? indices.at(i) : i;
101  }
102 
103  template<bool T, bool I, bool C, class Func> // GZ added bool C
104  inline Func specForeachTriangle(Func func) const;
105 
106 };
107 
108 // Serialization routines
109 QDataStream& operator<<(QDataStream& out, const StelVertexArray&);
110 QDataStream& operator>>(QDataStream& in, StelVertexArray&);
111 
112 template<class Func>
113 Func StelVertexArray::foreachTriangle(Func func) const
114 {
115  // Here we just dispatch the method into one of the 8 possible cases // GZ NEW: 8, not 4, cases
116  bool textured = isTextured();
117  bool colored = isColored();
118  bool useIndice = isIndexed();
119 
120  if (textured)
121  {
122  if (useIndice)
123  {
124  if (colored)
125  return specForeachTriangle<true, true, true, Func>(func);
126  else
127  return specForeachTriangle<true, true, false, Func>(func);
128  }
129  else // not indiced
130  {
131  if (colored)
132  return specForeachTriangle<true, false, true, Func>(func);
133  else
134  return specForeachTriangle<true, false, false, Func>(func);
135  }
136  }
137  else // not textured
138  {
139  if (useIndice)
140  {
141  if (colored)
142  return specForeachTriangle<false, true, true, Func>(func);
143  else
144  return specForeachTriangle<false, true, false, Func>(func);
145  }
146  else // not indiced
147  {
148  if (colored)
149  return specForeachTriangle<false, false, true, Func>(func);
150  else
151  return specForeachTriangle<false, false, false, Func>(func);
152  }
153  }
154 }
155 
156 template<bool T, bool I, bool C, class Func>
157 Func StelVertexArray::specForeachTriangle(Func func) const
158 {
159  switch (primitiveType)
160  {
161  case StelVertexArray::Triangles:
162  Q_ASSERT(vertex.size() % 3 == 0);
163  for (int i = 0; i < vertex.size(); i += 3)
164  {
165  func(specVertexAt<I>(i), specVertexAt<I>(i+1), specVertexAt<I>(i+2),
166  specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1), specTexCoordAt<T, I>(i+2),
167  specColorAt<C, I>(i), specColorAt<C, I>(i+1), specColorAt<C, I>(i+2),
168  specIndiceAt<I>(i), specIndiceAt<I>(i+1), specIndiceAt<I>(i+2));
169  }
170  break;
171  case StelVertexArray::TriangleFan:
172  {
173  const Vec3d* v0 = specVertexAt<I>(0);
174  const Vec2f* t0 = specTexCoordAt<T, I>(0);
175  const Vec3f* c0 = specColorAt<C, I>(0);
176  unsigned int i0 = specIndiceAt<I>(0);
177  for (int i = 1; i < vertex.size() - 1; ++i)
178  {
179  func(v0, specVertexAt<I>(i), specVertexAt<I>(i+1),
180  t0, specTexCoordAt<T, I>(i), specTexCoordAt<T, I>(i+1),
181  c0, specColorAt<C, I>(i), specColorAt<C, I>(i+1),
182  i0, specIndiceAt<I>(i), specIndiceAt<I>(i+1));
183  }
184  break;
185  }
186  case StelVertexArray::TriangleStrip:
187  {
188  for (int i = 2; i < vertex.size(); ++i)
189  {
190  if (i % 2 == 0)
191  func(specVertexAt<I>(i-2), specVertexAt<I>(i-1), specVertexAt<I>(i),
192  specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i),
193  specColorAt<C, I>(i-2), specColorAt<C, I>(i-1), specColorAt<C, I>(i),
194  specIndiceAt<I>(i-2), specIndiceAt<I>(i-1), specIndiceAt<I>(i));
195  else
196  func(specVertexAt<I>(i-1), specVertexAt<I>(i-2), specVertexAt<I>(i),
197  specTexCoordAt<T, I>(i-1), specTexCoordAt<T, I>(i-2), specTexCoordAt<T, I>(i),
198  specColorAt<C, I>(i-1), specColorAt<C, I>(i-2), specColorAt<C, I>(i),
199  specIndiceAt<I>(i-1), specIndiceAt<I>(i-2), specIndiceAt<I>(i));
200  }
201  break;
202  }
203  default:
204  Q_ASSERT_X(0, Q_FUNC_INFO, "unsupported primitive type");
205  }
206  return func;
207 }
208 
209 
210 #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.