VTK
vtkOpenGLError.h
Go to the documentation of this file.
1 /*=========================================================================
2 
3  Program: Visualization Toolkit
4  Module: vtkOpenGL.h
5 
6  Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
7  All rights reserved.
8  See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
9 
10  This software is distributed WITHOUT ANY WARRANTY; without even
11  the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
12  PURPOSE. See the above copyright notice for more information.
13 
14 =========================================================================*/
15 #ifndef vtkOpenGLError_h
16 #define vtkOpenGLError_h
17 
18 #include "vtkgl.h"
19 #include "vtkSetGet.h"
20 
21 #ifndef NDEBUG
22 // debug build.
23 #define VTK_REPORT_OPENGL_ERRORS
24 #else // NDEBUG
25 // release build
26 /* #undef VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS */
27 #if defined(VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS)
28 #define VTK_REPORT_OPENGL_ERRORS
29 #endif // defined(VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS)
30 #endif // NDEBUG
31 
32 // Description:
33 // The following functions can be used to detect and report, and/or
34 // silently clear OpenGL error flags. These are not intended to be
35 // used driectly, instead use the following macros.
36 //
37 // vtkOpenGLClearErrorMacro() -- Silently clear OpenGL error flags.
38 //
39 // vtkOpenGLCheckErrorMacro(message) -- Check and clear OpenGL's error
40 // flags. Report errors detected via vtkErrorMacro.
41 //
42 // vtkOpenGLStaticCheckErrorMacro(message) -- Check and clear OpenGL's
43 // error flags. Report errors detected via vtkGenericWarningMacro.
44 // This may be used in static methods and outside of vtkObjects.
45 //
46 // The intended usage pattern is to 1) call vtkOpenGLClearErrorMacro
47 // at the top of, and 2) vtkOpenGLCheckErrorMacro at the bottom of
48 // methods that make OpenGL calls.
49 //
50 // By calling vtkOpenGLClearErrorMacro at the top of a method that
51 // makes OpenGL calls, you isolate the code and prevent it from
52 // detecting any preceding errors. By calling vtkOpenGLCheckErrorMacro
53 // at the bottom of the method you clear the error flags and report
54 // any errors that have occured in the method where they occured.
55 //
56 // The macros maybe completely disabled via the CMakeLists variable
57 // VTK_REPORT_OPENGL_ERRORS. Note that in that case error flags are
58 // never cleared so that if an error occurs the flags will remain dirty
59 // making it impossible for anyone else to use them reliably. Please
60 // don't disable them with out a good reason.
61 
62 
63 
64 // Description:
65 // Convert an OpenGL error code into a descriptive
66 // string.
67 inline
68 const char *vtkOpenGLStrError(unsigned int code)
69 {
70  switch(static_cast<GLenum>(code))
71  {
72  case GL_NO_ERROR:
73  return "No error";
74  case GL_INVALID_ENUM:
75  return "Invalid enum";
76  case GL_INVALID_VALUE:
77  return "Invalid value";
78  case GL_INVALID_OPERATION:
79  return "Invalid operation";
80  case GL_STACK_OVERFLOW:
81  return "Stack overflow";
82  case GL_STACK_UNDERFLOW:
83  return "Stack underflow";
84  case GL_OUT_OF_MEMORY:
85  return "Out of memory";
86  case vtkgl::TABLE_TOO_LARGE:
87  return "Table too large";
88  case vtkgl::INVALID_FRAMEBUFFER_OPERATION_EXT:
89  return "Invalid framebuffer operation";
90  case vtkgl::TEXTURE_TOO_LARGE_EXT:
91  return "Texture too large";
92  }
93  return "Unknown error";
94 }
95 
96 // Description:
97 // Check for OpenGL errors. Error status is querried until
98 // OpenGL reports no errors. The list of errors and their
99 // descriptions are returned in the user supplied arrays.
100 // User passes the size of the arrays as the first argument.
101 // Error flags will still be cleared if the user arays are
102 // less than the number of errors.
103 #if defined(VTK_REPORT_OPENGL_ERRORS)
104 inline
106  int maxNum,
107  unsigned int *errCode,
108  const char **errDesc)
109 {
110  int i = 0;
111  GLenum code = glGetError();
112  if (i < maxNum)
113  {
114  errCode[i] = static_cast<unsigned int>(code);
115  errDesc[i] = vtkOpenGLStrError(code);
116  }
117  while (code != GL_NO_ERROR && i < maxNum)
118  {
119  i++;
120  code = glGetError();
121  if (i < maxNum)
122  {
123  errCode[i] = static_cast<unsigned int>(code);
124  errDesc[i] = vtkOpenGLStrError(code);
125  }
126  }
127  return i;
128 }
129 #else
130 inline
132  int maxNum,
133  unsigned int *errCode,
134  const char **errDesc)
135 {
136  (void)maxNum;
137  (void)errCode;
138  (void)errDesc;
139  return 0;
140 }
141 #endif
142 
143 // Description:
144 // Send a set of errors collected by GetOpenGLErrors
145 // to the give stream. The number of errors is obtained
146 // in the return value of GetOpenGLErrors, while the max
147 // errors gives the size of the error arrays.
148 #if defined(VTK_REPORT_OPENGL_ERRORS)
149 inline
151  ostream &os,
152  int maxErrors,
153  int numErrors,
154  unsigned int *errCode,
155  const char **errDesc)
156 {
157  os << numErrors << " OpenGL errors detected" << endl;
158  for (int i=0; (i<numErrors)&&(i<maxErrors); ++i)
159  {
160  os << " " << i << " : (" << errCode[i] << ") " << errDesc[i] << endl;
161  }
162  if (numErrors>maxErrors)
163  {
164  os
165  << "More than " << maxErrors
166  << " detected! The remainder are not reported"
167  << endl;
168  }
169 }
170 #else
171 inline
173  ostream &os,
174  int maxErrors,
175  int numErrors,
176  unsigned int *errCode,
177  const char **errDesc)
178 {
179  (void)os;
180  (void)maxErrors;
181  (void)numErrors;
182  (void)errCode;
183  (void)errDesc;
184 }
185 #endif
186 
187 // Description:
188 // Clear OpenGL's error flags.
189 #if defined(VTK_REPORT_OPENGL_ERRORS)
190 inline
191 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
192 {
193  GLenum glError;
194  unsigned int i = 0;
195  do
196  {
197  glError = glGetError();
198  ++i;
199  }
200  while(i < maxErrors && glError != GL_NO_ERROR);
201 }
202 #else
203 inline
204 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
205 {
206  (void) maxErrors;
207 }
208 #endif
209 
210 #if !defined(VTK_REPORT_OPENGL_ERRORS)
211 # define vtkOpenGLClearErrorMacro()
212 # define vtkOpenGLCheckErrorMacro(message)
213 # define vtkOpenGLStaticCheckErrorMacro(message)
214 #else
215 # define vtkOpenGLClearErrorMacro() vtkClearOpenGLErrors(16);
216 # include <sstream> // for error macro
217 # define vtkOpenGLCheckErrorMacroImpl(ostr, message) \
218 { \
219  const int maxErrors = 16; \
220  unsigned int errCode[maxErrors] = {0}; \
221  const char *errDesc[maxErrors] = {NULL}; \
222  \
223  int numErrors \
224  = vtkGetOpenGLErrors( \
225  maxErrors, \
226  errCode, \
227  errDesc); \
228  \
229  if (numErrors) \
230  { \
231  std::ostringstream oss; \
232  vtkPrintOpenGLErrors( \
233  oss, \
234  maxErrors, \
235  numErrors, \
236  errCode, \
237  errDesc); \
238  \
239  ostr(<< message << " " << oss.str().c_str()); \
240  } \
241 }
242 # define vtkOpenGLCheckErrorMacro(message) \
243  vtkOpenGLCheckErrorMacroImpl(vtkErrorMacro, message)
244 # define vtkOpenGLStaticCheckErrorMacro(message) \
245  vtkOpenGLCheckErrorMacroImpl(vtkGenericWarningMacro, message)
246 #endif
247 
248 // Use this macro for fine grained error checking during
249 // debugging. It is removed for Release builds.
250 #ifdef NDEBUG
251 # define vtkOpenGLDebugClearErrorMacro()
252 # define vtkOpenGLDebugCheckErrorMacro(message)
253 #else
254 # define vtkOpenGLDebugClearErrorMacro() \
255  vtkOpenGLClearErrorMacro()
256 # define vtkOpenGLDebugCheckErrorMacro(message) \
257  vtkOpenGLStaticCheckErrorMacro(message)
258 #endif
259 
260 #endif
261 // VTK-HeaderTest-Exclude: vtkOpenGLError.h
void vtkClearOpenGLErrors(const unsigned int maxErrors=16)
int vtkGetOpenGLErrors(int maxNum, unsigned int *errCode, const char **errDesc)
const char * vtkOpenGLStrError(unsigned int code)
void vtkPrintOpenGLErrors(ostream &os, int maxErrors, int numErrors, unsigned int *errCode, const char **errDesc)