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