1/*========================================================================= 2 3 Program: Visualization Toolkit 4 Module: vtkOpenGLError.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 "vtkSetGet.h" 19#include "vtk_glew.h" 20 21#cmakedefine 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. 58inline 59const char *vtkOpenGLStrError(unsigned int code) 60{ 61 switch(static_cast<GLenum>(code)) 62 { 63 case GL_NO_ERROR: 64 return "No error"; 65 case GL_INVALID_ENUM: 66 return "Invalid enum"; 67 case GL_INVALID_VALUE: 68 return "Invalid value"; 69 case GL_INVALID_OPERATION: 70 return "Invalid operation"; 71 case GL_OUT_OF_MEMORY: 72 return "Out of memory"; 73#if GL_ES_VERSION_2_0 != 1 74 case GL_STACK_OVERFLOW: 75 return "Stack overflow"; 76 case GL_STACK_UNDERFLOW: 77 return "Stack underflow"; 78 case GL_TABLE_TOO_LARGE: 79 return "Table too large"; 80 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: 81 return "Invalid framebuffer operation"; 82#endif 83 } 84 return "Unknown error"; 85} 86 87// Description: 88// Check for OpenGL errors. Error status is querried until 89// OpenGL reports no errors. The list of errors and their 90// descriptions are returned in the user supplied arrays. 91// User passes the size of the arrays as the first argument. 92// Error flags will still be cleared if the user arays are 93// less than the number of errors. 94#if defined(VTK_REPORT_OPENGL_ERRORS) 95inline 96int vtkGetOpenGLErrors( 97 int maxNum, 98 unsigned int *errCode, 99 const char **errDesc) 100{ 101 int i = 0; 102 GLenum code = glGetError(); 103 if (i < maxNum) 104 { 105 errCode[i] = static_cast<unsigned int>(code); 106 errDesc[i] = vtkOpenGLStrError(code); 107 } 108 while (code != GL_NO_ERROR && i < maxNum) 109 { 110 i++; 111 code = glGetError(); 112 if (i < maxNum) 113 { 114 errCode[i] = static_cast<unsigned int>(code); 115 errDesc[i] = vtkOpenGLStrError(code); 116 } 117 } 118 return i; 119} 120#else 121inline 122int vtkGetOpenGLErrors( 123 int maxNum, 124 unsigned int *errCode, 125 const char **errDesc) 126{ 127 (void)maxNum; 128 (void)errCode; 129 (void)errDesc; 130 return 0; 131} 132#endif 133 134// Description: 135// Send a set of errors collected by GetOpenGLErrors 136// to the give stream. The number of errors is obtained 137// in the return value of GetOpenGLErrors, while the max 138// errors gives the size of the error arrays. 139#if defined(VTK_REPORT_OPENGL_ERRORS) 140inline 141void vtkPrintOpenGLErrors( 142 ostream &os, 143 int maxErrors, 144 int numErrors, 145 unsigned int *errCode, 146 const char **errDesc) 147{ 148 os << numErrors << " OpenGL errors detected" << endl; 149 for (int i=0; (i<numErrors)&&(i<maxErrors); ++i) 150 { 151 os << " " << i << " : (" << errCode[i] << ") " << errDesc[i] << endl; 152 } 153 if (numErrors>maxErrors) 154 { 155 os 156 << "More than " << maxErrors 157 << " detected! The remainder are not reported" 158 << endl; 159 } 160} 161#else 162inline 163void vtkPrintOpenGLErrors( 164 ostream &os, 165 int maxErrors, 166 int numErrors, 167 unsigned int *errCode, 168 const char **errDesc) 169{ 170 (void)os; 171 (void)maxErrors; 172 (void)numErrors; 173 (void)errCode; 174 (void)errDesc; 175} 176#endif 177 178// Description: 179// Clear OpenGL's error flags. 180#if defined(VTK_REPORT_OPENGL_ERRORS) 181inline 182void vtkClearOpenGLErrors(const unsigned int maxErrors = 16) 183{ 184 GLenum glError; 185 unsigned int i = 0; 186 do 187 { 188 glError = glGetError(); 189 ++i; 190 } 191 while(i < maxErrors && glError != GL_NO_ERROR); 192} 193#else 194inline 195void vtkClearOpenGLErrors(const unsigned int maxErrors = 16) 196{ 197 (void) maxErrors; 198} 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(16); 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 253