Stellarium 0.12.3
StelGLUtilityFunctions.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 _STELGLUTILITYFUNCTIONS_HPP_
21 #define _STELGLUTILITYFUNCTIONS_HPP_
22 
23 #include <QGLContext>
24 #include <QString>
25 
26 #include "StelGLCompatibility.hpp"
27 #include "StelRenderer.hpp"
28 #include "StelIndexBuffer.hpp"
29 #include "StelTextureParams.hpp"
30 #include "StelVertexAttribute.hpp"
31 #include "StelVertexBuffer.hpp"
32 
33 
42 inline GLint glAttributeType(const AttributeType type)
43 {
44  switch(type)
45  {
46  case AttributeType_Vec2f:
47  case AttributeType_Vec3f:
48  case AttributeType_Vec4f:
49  return GL_FLOAT;
50  default:
51  break;
52  }
53  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown vertex attribute type");
54 
55  // Prevents GCC from complaining about exiting a non-void function:
56  return -1;
57 }
58 
59 
68 inline const char* glslAttributeName(const AttributeInterpretation interpretation)
69 {
70  switch(interpretation)
71  {
72  case AttributeInterpretation_Position: return "vertex";
73  case AttributeInterpretation_TexCoord: return "texCoord";
74  case AttributeInterpretation_Normal: return "normal";
75  case AttributeInterpretation_Color: return "color";
76  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown vertex attribute interpretation");
77  }
78 
79  // Prevents GCC from complaining about exiting a non-void function:
80  return NULL;
81 }
82 
83 
95 inline GLenum gl1AttributeEnum(const AttributeInterpretation interpretation)
96 {
97  switch(interpretation)
98  {
99  case AttributeInterpretation_Position: return GL_VERTEX_ARRAY;
100  case AttributeInterpretation_TexCoord: return GL_TEXTURE_COORD_ARRAY;
101  case AttributeInterpretation_Normal: return GL_NORMAL_ARRAY;
102  case AttributeInterpretation_Color: return GL_COLOR_ARRAY;
103  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown vertex attribute interpretation");
104  }
105 
106  // Prevents GCC from complaining about exiting a non-void function:
107  return GL_VERTEX_ARRAY;
108 }
109 
113 inline GLint glPrimitiveType(const PrimitiveType type)
114 {
115  switch(type)
116  {
117  case PrimitiveType_Points: return GL_POINTS;
118  case PrimitiveType_Triangles: return GL_TRIANGLES;
119  case PrimitiveType_TriangleStrip: return GL_TRIANGLE_STRIP;
120  case PrimitiveType_TriangleFan: return GL_TRIANGLE_FAN;
121  case PrimitiveType_Lines: return GL_LINES;
122  case PrimitiveType_LineStrip: return GL_LINE_STRIP;
123  case PrimitiveType_LineLoop: return GL_LINE_LOOP;
124  }
125  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown graphics primitive type");
126 
127  // Prevents GCC from complaining about exiting a non-void function:
128  return -1;
129 }
130 
134 inline GLenum glIndexType(const IndexType indexType)
135 {
136  if(indexType == IndexType_U16) {return GL_UNSIGNED_SHORT;}
137  else if(indexType == IndexType_U32) {return GL_UNSIGNED_INT;}
138  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown index type");
139  // Prevents GCC from complaining about exiting a non-void function:
140  return -1;
141 }
142 
146 inline GLint glTextureWrap(const TextureWrap wrap)
147 {
148  switch(wrap)
149  {
150  case TextureWrap_Repeat: return GL_REPEAT;
151  case TextureWrap_ClampToEdge: return GL_CLAMP_TO_EDGE;
152  }
153  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown texture wrap mode");
154 
155  // Prevents GCC from complaining about exiting a non-void function:
156  return -1;
157 }
158 
162 inline QString glErrorToString(const GLenum error)
163 {
164  switch(error)
165  {
166  case GL_NO_ERROR: return "GL_NO_ERROR";
167  case GL_INVALID_ENUM: return "GL_INVALID_ENUM";
168  case GL_INVALID_VALUE: return "GL_INVALID_VALUE";
169  case GL_INVALID_OPERATION: return "GL_INVALID_OPERATION";
170  case GL_INVALID_FRAMEBUFFER_OPERATION: return "GL_INVALID_FRAMEBUFFER_OPERATION";
171  case GL_OUT_OF_MEMORY: return "GL_OUT_OF_MEMORY";
172  }
173  Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown GL error");
174 
175  // Prevents GCC from complaining about exiting a non-void function:
176  return QString();
177 }
178 
185 inline GLint glGetTextureInternalFormat(const QImage& image)
186 {
187  const bool gray = image.isGrayscale();
188  const bool alpha = image.hasAlphaChannel();
189  if(gray) {return alpha ? GL_LUMINANCE8_ALPHA8 : GL_LUMINANCE8;}
190  else {return alpha ? GL_RGBA8 : GL_RGB8;}
191 }
192 
197 inline GLint glGetTextureInternalFormat(const TextureDataFormat format)
198 {
199  switch(format)
200  {
201  case TextureDataFormat_RGBA_F32: return GL_RGBA32F; break;
202  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown texture data format");
203  }
204  // Avoid compiler warnings
205  return -1;
206 }
207 
215 inline GLenum glGetTextureLoadFormat(const QImage& image)
216 {
217  const bool gray = image.isGrayscale();
218  const bool alpha = image.hasAlphaChannel();
219  if(gray) {return alpha ? GL_LUMINANCE_ALPHA : GL_LUMINANCE;}
220  else {return alpha ? GL_RGBA : GL_RGB;}
221 }
222 
226 inline GLint glGetTextureLoadFormat(const TextureDataFormat format)
227 {
228  switch(format)
229  {
230  case TextureDataFormat_RGBA_F32: return GL_RGBA; break;
231  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown texture data format");
232  }
233  // Avoid compiler warnings
234  return -1;
235 }
236 
244 inline GLenum glGetTextureType(const QImage& image)
245 {
246  Q_UNUSED(image);
247  return GL_UNSIGNED_BYTE;
248 }
249 
253 inline GLint glGetTextureType(const TextureDataFormat format)
254 {
255  switch(format)
256  {
257  case TextureDataFormat_RGBA_F32: return GL_FLOAT; break;
258  default: Q_ASSERT_X(false, Q_FUNC_INFO, "Unknown texture data format");
259  }
260  // Avoid compiler warnings
261  return -1;
262 }
263 
267 inline bool glTextureSizeWithinLimits(const QSize size, const TextureDataFormat format)
268 {
269  const GLint internalFormat = glGetTextureInternalFormat(format);
270  const GLenum loadFormat = glGetTextureLoadFormat(format);
271  const GLenum type = glGetTextureType(format);
272 
273  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, size.width(), size.height(), 0,
274  loadFormat, type, NULL);
275 
276  GLint width = size.width();
277  GLint height = size.height();
278  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
279  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &height);
280 
281  return width != 0 && height != 0;
282 }
283 
289 inline bool glTextureSizeWithinLimits(const QImage& image)
290 {
291  const GLint internalFormat = glGetTextureInternalFormat(image);
292  const GLenum loadFormat = glGetTextureLoadFormat(image);
293  const GLenum type = glGetTextureType(image);
294 
295  glTexImage2D(GL_PROXY_TEXTURE_2D, 0, internalFormat, image.width(), image.height(), 0,
296  loadFormat, type, NULL);
297 
298  GLint width = image.width();
299  GLint height = image.height();
300  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &width);
301  glGetTexLevelParameteriv(GL_PROXY_TEXTURE_2D, 0, GL_TEXTURE_WIDTH, &height);
302 
303  return width != 0 && height != 0;
304 }
305 
314 inline void glEnsureTextureSizeWithinLimits(QImage& image)
315 {
316  while(!glTextureSizeWithinLimits(image))
317  {
318  if(image.width() <= 1)
319  {
320  Q_ASSERT_X(false, Q_FUNC_INFO, "Even a texture with width <= 1 is \"too large\": "
321  "maybe image format is invalid/not GL supported?");
322  }
323  image = image.scaledToWidth(image.width() / 2, Qt::FastTransformation);
324  }
325 }
326 
341 QString glFileSystemTexturePath(const QString& filename, const bool pvrSupported);
342 
349 inline void checkGLErrors(const QString& context)
350 {
351  const GLenum glError = glGetError();
352  if(glError == GL_NO_ERROR) {return;}
353 
354  qWarning() << "OpenGL error detected at " << context << " : "
355  << glErrorToString(glError);
356 }
357 
358 #endif // _STELGLUTILITYFUNCTIONS_HPP_