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