VTK
dox/Builds/VTK/release/doxygen/Rendering/OpenGL/vtkOpenGLError.h
Go to the documentation of this file.
00001 /*=========================================================================
00002 
00003   Program:   Visualization Toolkit
00004   Module:    vtkOpenGL.h
00005 
00006   Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
00007   All rights reserved.
00008   See Copyright.txt or http://www.kitware.com/Copyright.htm for details.
00009 
00010      This software is distributed WITHOUT ANY WARRANTY; without even
00011      the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
00012      PURPOSE.  See the above copyright notice for more information.
00013 
00014 =========================================================================*/
00015 #ifndef __vtkOpenGLError_h
00016 #define __vtkOpenGLError_h
00017 
00018 #include "vtkgl.h"
00019 #include "vtkSetGet.h"
00020 
00021 #define VTK_REPORT_OPENGL_ERRORS
00022 
00023 // Description:
00024 // The following functions can be used to detect and report, and/or
00025 // silently clear OpenGL error flags. These are not intended to be
00026 // used driectly, instead use the following macros.
00027 //
00028 // vtkOpenGLClearErrorMacro() -- Silently clear OpenGL error flags.
00029 //
00030 // vtkOpenGLCheckErrorMacro(message) -- Check and clear OpenGL's error
00031 // flags. Report errors detected via vtkErrorMacro.
00032 //
00033 // vtkOpenGLStaticCheckErrorMacro(message) -- Check and clear OpenGL's
00034 // error flags. Report errors detected via vtkGenericWarningMacro.
00035 // This may be used in static methods and outside of vtkObjects.
00036 //
00037 // The intended usage pattern is to 1) call vtkOpenGLClearErrorMacro
00038 // at the top of, and 2) vtkOpenGLCheckErrorMacro at the bottom of
00039 // methods that make OpenGL calls.
00040 //
00041 // By calling vtkOpenGLClearErrorMacro at the top of a method that
00042 // makes OpenGL calls, you isolate the code and prevent it from
00043 // detecting any preceding errors. By calling vtkOpenGLCheckErrorMacro
00044 // at the bottom of the method you clear the error flags and report
00045 // any errors that have occured in the method where they occured.
00046 //
00047 // The macros maybe completely disabled via the CMakeLists variable
00048 // VTK_REPORT_OPENGL_ERRORS. Note that in that case error flags are
00049 // never cleared so that if an error occurs the flags will remain dirty
00050 // making it impossible for anyone else to use them reliably. Please
00051 // don't disable them with out a good reason.
00052 
00053 
00054 
00055 // Description:
00056 // Convert an OpenGL error code into a descriptive
00057 // string.
00058 inline
00059 const char *vtkOpenGLStrError(unsigned int code)
00060 {
00061   switch(static_cast<GLenum>(code))
00062     {
00063     case GL_NO_ERROR:
00064       return "No error";
00065       break;
00066     case GL_INVALID_ENUM:
00067       return "Invalid enum";
00068       break;
00069     case GL_INVALID_VALUE:
00070       return "Invalid value";
00071       break;
00072     case GL_INVALID_OPERATION:
00073       return "Invalid operation";
00074       break;
00075     case GL_STACK_OVERFLOW:
00076       return "Stack overflow";
00077       break;
00078     case GL_STACK_UNDERFLOW:
00079       return "Stack underflow";
00080       break;
00081     case GL_OUT_OF_MEMORY:
00082       return "Out of memory";
00083       break;
00084     case vtkgl::TABLE_TOO_LARGE:
00085       return "Table too large";
00086       break;
00087     case vtkgl::INVALID_FRAMEBUFFER_OPERATION_EXT:
00088       return "Invalid framebuffer operation";
00089       break;
00090     case vtkgl::TEXTURE_TOO_LARGE_EXT:
00091       return "Texture too large";
00092       break;
00093     }
00094   return "Unknown error";
00095 }
00096 
00097 // Description:
00098 // Check for OpenGL errors. Error status is querried until
00099 // OpenGL reports no errors. The list of errors and their
00100 // descriptions are returned in the user supplied arrays.
00101 // User passes the size of the arrays as the first argument.
00102 // Error flags will still be cleared if the user arays are
00103 // less than the number of errors.
00104 #if defined(VTK_REPORT_OPENGL_ERRORS)
00105 inline
00106 int vtkGetOpenGLErrors(
00107       int maxNum,
00108       unsigned int *errCode,
00109       const char **errDesc)
00110 {
00111   int i=0;
00112   GLenum code = glGetError();
00113   if (i<maxNum)
00114     {
00115     errCode[i] = static_cast<unsigned int>(code);
00116     errDesc[i] = vtkOpenGLStrError(code);
00117     }
00118   while (code!=GL_NO_ERROR)
00119     {
00120     i+=1;
00121     code = glGetError();
00122     if (i<maxNum)
00123       {
00124       errCode[i] = static_cast<unsigned int>(code);
00125       errDesc[i] = vtkOpenGLStrError(code);
00126       }
00127     }
00128   return i;
00129 }
00130 #else
00131 inline
00132 int vtkGetOpenGLErrors(
00133       int maxNum,
00134       unsigned int *errCode,
00135       const char **errDesc)
00136 {
00137   (void)maxNum;
00138   (void)errCode;
00139   (void)errDesc;
00140   return 0;
00141 }
00142 #endif
00143 
00144 // Description:
00145 // Send a set of errors collected by GetOpenGLErrors
00146 // to the give stream. The number of errors is obtained
00147 // in the return value of GetOpenGLErrors, while the max
00148 // errors gives the size of the error arrays.
00149 #if defined(VTK_REPORT_OPENGL_ERRORS)
00150 inline
00151 void vtkPrintOpenGLErrors(
00152       ostream &os,
00153       int maxErrors,
00154       int numErrors,
00155       unsigned int *errCode,
00156       const char **errDesc)
00157 {
00158   os << numErrors << " OpenGL errors detected" << endl;
00159   for (int i=0; (i<numErrors)&&(i<maxErrors); ++i)
00160     {
00161     os << "  " <<  i << " : (" << errCode[i] << ") " << errDesc[i] << endl;
00162     }
00163   if (numErrors>maxErrors)
00164     {
00165     os
00166       << "More than " << maxErrors
00167       << " detected! The remainder are not reported"
00168       << endl;
00169     }
00170 }
00171 #else
00172 inline
00173 void vtkPrintOpenGLErrors(
00174       ostream &os,
00175       int maxErrors,
00176       int numErrors,
00177       unsigned int *errCode,
00178       const char **errDesc)
00179 {
00180   (void)os;
00181   (void)maxErrors;
00182   (void)numErrors;
00183   (void)errCode;
00184   (void)errDesc;
00185 }
00186 #endif
00187 
00188 // Description:
00189 // Clear OpenGL's error flags.
00190 #if defined(VTK_REPORT_OPENGL_ERRORS)
00191 inline
00192 void vtkClearOpenGLErrors()
00193 {
00194   while (glGetError()!=GL_NO_ERROR){;}
00195 }
00196 #else
00197 inline
00198 void vtkClearOpenGLErrors(){}
00199 #endif
00200 
00201 #if !defined(VTK_REPORT_OPENGL_ERRORS)
00202 # define vtkOpenGLClearErrorMacro()
00203 # define vtkOpenGLCheckErrorMacro(message)
00204 # define vtkOpenGLStaticCheckErrorMacro(message)
00205 #else
00206 # define vtkOpenGLClearErrorMacro() vtkClearOpenGLErrors();
00207 # include <sstream> // for error macro
00208 # define vtkOpenGLCheckErrorMacroImpl(ostr, message) \
00209 {                                                    \
00210   const int maxErrors = 16;                          \
00211   unsigned int errCode[maxErrors] = {0};             \
00212   const char *errDesc[maxErrors] = {NULL};           \
00213                                                      \
00214   int numErrors                                      \
00215     = vtkGetOpenGLErrors(                            \
00216         maxErrors,                                   \
00217         errCode,                                     \
00218         errDesc);                                    \
00219                                                      \
00220   if (numErrors)                                     \
00221     {                                                \
00222     std::ostringstream oss;                          \
00223     vtkPrintOpenGLErrors(                            \
00224           oss,                                       \
00225           maxErrors,                                 \
00226           numErrors,                                 \
00227           errCode,                                   \
00228           errDesc);                                  \
00229                                                      \
00230     ostr(<< message << " " << oss.str().c_str());    \
00231     }                                                \
00232 }
00233 # define vtkOpenGLCheckErrorMacro(message) \
00234   vtkOpenGLCheckErrorMacroImpl(vtkErrorMacro, message)
00235 # define vtkOpenGLStaticCheckErrorMacro(message) \
00236   vtkOpenGLCheckErrorMacroImpl(vtkGenericWarningMacro, message)
00237 #endif
00238 
00239 // Use this macro for fine grained error checking during
00240 // debugging. It is removed for Release builds.
00241 #ifdef NDEBUG
00242 # define vtkOpenGLDebugClearErrorMacro()
00243 # define vtkOpenGLDebugCheckErrorMacro(message)
00244 #else
00245 # define vtkOpenGLDebugClearErrorMacro() \
00246   vtkOpenGLClearErrorMacro()
00247 # define vtkOpenGLDebugCheckErrorMacro(message) \
00248   vtkOpenGLStaticCheckErrorMacro(message)
00249 #endif
00250 
00251 #endif
00252 // VTK-HeaderTest-Exclude: vtkOpenGLError.h