Stellarium 0.12.4
StelVertexAttribute.hpp
1 /*
2  * Stellarium
3  * Copyright (C) 2012 Ferdinand Majerech
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 _STELVERTEXATTRIBUTE_HPP_
21 #define _STELVERTEXATTRIBUTE_HPP_
22 
23 #include <QDebug>
24 #include <QString>
25 #include <QStringList>
26 #include <QVector>
27 
28 #include "VecMath.hpp"
29 
33 enum AttributeType
34 {
36  AttributeType_Vec4f = 0,
38  AttributeType_Vec3f = 1,
40  AttributeType_Vec2f = 2,
42  AttributeType_Max = 3
43 };
44 
53 inline int attributeDimensions(const AttributeType type)
54 {
55  static const int attributeDimensionsArray [AttributeType_Max] =
56  {4, 3, 2};
57  return attributeDimensionsArray[type];
58 }
59 
66 inline int attributeSize(const AttributeType type)
67 {
68  static const int attributeSizeArray [AttributeType_Max] =
69  {sizeof(Vec4f), sizeof(Vec3f), sizeof(Vec2f)};
70  return attributeSizeArray[type];
71 }
72 
77 enum AttributeInterpretation
78 {
80  AttributeInterpretation_Position = 0,
82  AttributeInterpretation_Color = 1,
84  AttributeInterpretation_Normal = 2,
86  AttributeInterpretation_TexCoord = 3,
88  AttributeInterpretation_MAX
89 };
90 
95 {
97  AttributeType type;
99  AttributeInterpretation interpretation;
100 
103 
110  StelVertexAttribute(const QString& attributeString)
111  {
112  const QString typeStr =
113  attributeString.section(' ', 0, 0, QString::SectionSkipEmpty);
114  const QString interpretationStr =
115  attributeString.section(' ', 1, 1, QString::SectionSkipEmpty);
116 
117  if(typeStr == "Vec2f") {type = AttributeType_Vec2f;}
118  else if(typeStr == "Vec3f") {type = AttributeType_Vec3f;}
119  else if(typeStr == "Vec4f") {type = AttributeType_Vec4f;}
120  else
121  {
122  qDebug() << "Unknown vertex attribute type: \"" << typeStr
123  << "\" in attribute \"" << attributeString << "\"";
124  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown vertex attribute type");
125  }
126 
127  if(interpretationStr == "Position")
128  {
129  interpretation = AttributeInterpretation_Position;
130  }
131  else if(interpretationStr == "Color")
132  {
133  interpretation = AttributeInterpretation_Color;
134  }
135  else if(interpretationStr == "Normal")
136  {
137  interpretation = AttributeInterpretation_Normal;
138  }
139  else if(interpretationStr == "TexCoord")
140  {
141  interpretation = AttributeInterpretation_TexCoord;
142  }
143  else
144  {
145  qDebug() << "Unknown vertex attribute interpretation: \"" << interpretationStr
146  << "\" in attribute \"" << attributeString << "\"";
147  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown vertex attribute interpretation");
148  }
149  }
150 
152  static QVector<StelVertexAttribute> parseAttributes(const char* const attribsCString)
153  {
154  QString attributes(attribsCString);
155  QVector<StelVertexAttribute> result;
156  const QStringList parts = attributes.split(",");
157  for(int part = 0; part < parts.size(); ++part)
158  {
159  result << StelVertexAttribute(parts.at(part));
160  }
161 
162 #ifndef NDEBUG
163  validateAttributes(result);
164 #endif
165  return result;
166  }
167 
168 private:
169 #ifndef NDEBUG
170 
171 
172 
173 
174  static void validateAttributes(const QVector<StelVertexAttribute>& attributes)
175  {
176  bool vertex, texCoord, normal, color;
177  vertex = texCoord = normal = color = false;
178 
179  // Ensure that every kind of vertex attribute is present at most once.
180  foreach(const StelVertexAttribute& attribute, attributes)
181  {
182  switch(attribute.interpretation)
183  {
184  case AttributeInterpretation_Position:
185  Q_ASSERT_X(!vertex, Q_FUNC_INFO,
186  "Vertex type has more than one vertex position attribute");
187  vertex = true;
188  break;
189  case AttributeInterpretation_TexCoord:
190  Q_ASSERT_X(attributeDimensions(attribute.type) == 2, Q_FUNC_INFO,
191  "Only 2D texture coordinates are supported at the moment");
192  Q_ASSERT_X(!texCoord,
193  Q_FUNC_INFO,
194  "Vertex type has more than one texture coordinate attribute");
195  texCoord = true;
196  break;
197  case AttributeInterpretation_Normal:
198  Q_ASSERT_X(attributeDimensions(attribute.type) == 3, Q_FUNC_INFO,
199  "Only 3D vertex normals are supported");
200  Q_ASSERT_X(!normal, Q_FUNC_INFO,
201  "Vertex type has more than one normal attribute");
202  normal = true;
203  break;
204  case AttributeInterpretation_Color:
205  Q_ASSERT_X(!color, Q_FUNC_INFO,
206  "Vertex type has more than one color attribute");
207  color = true;
208  break;
209  default:
210  Q_ASSERT_X(false, Q_FUNC_INFO,
211  "Unknown vertex attribute interpretation");
212  }
213  }
214 
215  Q_ASSERT_X(vertex, Q_FUNC_INFO,
216  "Vertex formats without a position attribute are not supported");
217  }
218 #endif
219 };
220 
239 #define VERTEX_ATTRIBUTES(...)\
240  static const QVector<StelVertexAttribute>& attributes()\
241  {\
242  static QVector<StelVertexAttribute> attribs =\
243  StelVertexAttribute::parseAttributes(#__VA_ARGS__);\
244  return attribs;\
245  }
246 
247 #endif // _STELVERTEXATTRIBUTE_HPP_