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 #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