00001
00002 #include "Error.h"
00003 #include "RenderTools.h"
00004
00005 namespace RenderTools{
00006
00007 vector<Error::Code> Error::s_ignore;
00008 vector<Error::Code> Error::s_errors;
00009 vector<Error::Code> Error::s_warnings;
00010 vector<string> Error::s_errorstrings;
00011 vector<string> Error::s_warningstrings;
00012
00013 Error::Error( void ){
00014 }
00015
00016 Error::~Error( void ){
00017 }
00018
00019 void Error::ignore( Code c ){
00020 #ifdef DEBUG
00021 if( find( s_ignore.begin(), s_ignore.end(), c ) != s_ignore.end() )return;
00022 s_ignore.push_back( c );
00023 #endif
00024 }
00025
00026 void Error::error( Code c, const char * file, int line, string msg ){
00027 #ifdef DEBUG
00028 string str = "("+msg+")";
00029 s_errors.push_back( c );
00030 s_errorstrings.push_back( str );
00031 assertNoErrors( file, line );
00032 #endif
00033 }
00034
00035 void Error::warning( Code c, const char *file, int line, string msg ){
00036 #ifdef DEBUG
00037 string str = string( basename(file) ) + string(":") + toString(line) + "("+msg+")";
00038 s_warnings.push_back( c );
00039 s_warningstrings.push_back( str );
00040 #endif
00041 }
00042
00043 Error::Code Error::_popWarning( string & str ){
00044 if( s_warnings.size() ){
00045 Code c = s_warnings[ s_warnings.size() - 1 ];
00046 str = s_warningstrings[ s_warningstrings.size() - 1 ];
00047 s_warnings.pop_back();
00048 s_warningstrings.pop_back();
00049 return( c );
00050 }
00051 else{
00052 return( ERROR_NO_ERROR );
00053 }
00054 }
00055
00056 Error::Code Error::_popError( string & str ){
00057 if( s_errors.size() ){
00058 Code c = s_errors[ s_errors.size() - 1 ];
00059 str = s_errorstrings[ s_errorstrings.size() - 1 ];
00060 s_errors.pop_back();
00061 s_errorstrings.pop_back();
00062 return( c );
00063 }
00064 else{
00065 return( ERROR_NO_ERROR );
00066 }
00067 }
00068
00069 int Error::dumpWarnings( const string & stream, int indent ){
00070 string str = ( stream == "cerr" ? "" : stream );
00071 Code code;
00072 string warn;
00073 int count = 0;
00074 while( ( code = _popWarning( warn ) ) != ERROR_NO_ERROR ){
00075 if( find( s_ignore.begin(), s_ignore.end(), code ) != s_ignore.end() )continue;
00076 string white = "";
00077 for( int i = 0; i < indent; i++ ) white += "\t";
00078 str += white + string("warning[")+ toString(count++) + string("]: ") + getErrorString( code ) + string(" ") + warn + "\n";
00079 }
00080 if( str == "" ){
00081 str = "no warnings\n";
00082 }
00083 if( stream == "cerr" ){
00084 cerr << str;
00085 }
00086 else{
00087 const_cast<string &>( stream ) = str;
00088 }
00089 return( count );
00090 }
00091
00092 int Error::dumpErrors( const string &stream, int indent ){
00093 string str = ( stream == "cerr" ? "" : stream );
00094 Code code;
00095 string err;
00096 int count = 0;
00097 while( ( code = _popError( err ) ) != ERROR_NO_ERROR ){
00098 string white = "";
00099 for( int i = 0; i < indent; i++ ) white += "\t";
00100 str += white + string("error[")+toString(count++)+string("] = ")+getErrorString( code )+"\n"+err+"\n";
00101 }
00102 if( stream == "cerr" ){
00103 cerr << str;
00104 }
00105 else{
00106 const_cast<string &>( stream ) = str;
00107 }
00108 return( count );
00109 }
00110
00111 bool Error::assertNoErrors( const char * file, int line, string msg ){
00112
00113 if( ! RenderTools::isInitialized() ){
00114 s_errors.push_back( Error::ITEM_NOT_INITIALIZED );
00115 s_errorstrings.push_back( "you need to call RenderTools::initialize() first ! " );
00116 }
00117
00118 #ifdef DEBUG
00119
00120 GLenum glerr = GL_NO_ERROR;
00121 if( RenderTools::isGLInitialized() ){
00122 glerr = glGetError();
00123 }
00124 #ifdef RT_CG
00125 CGerror cgerr = CG_NO_ERROR;
00126 if( RenderTools::isGLinitialized() ){
00127 const char *cgString = cgGetLastErrorString( & cgerr );
00128 }
00129 if( s_errors.size() || glerr != GL_NO_ERROR || cgerr != CG_NO_ERROR ){
00130 #else
00131 if( s_errors.size() || glerr != GL_NO_ERROR ){
00132 #endif
00133 string str = "RenderTools::assertNoError failed in "+string(basename(file)) + string(":") + toString(line) + "\n";
00134 if( msg != "" ){
00135 str += "\n("+msg+")\n";
00136 }
00137 #ifdef RT_CG
00138 if( cgerr != CG_NO_ERROR ){
00139 switch( cgerr ){
00140 case CG_COMPILER_ERROR: str += "CG_COMPILER_ERROR"; break;
00141 }
00142 }
00143 #endif
00144 if( glerr != GL_NO_ERROR ){
00145 str += "glErrorString() = ";
00146 switch( glerr ){
00147 #ifdef GL_INVALID_ENUM
00148 case GL_INVALID_ENUM: str += "GL_INVALID_ENUM"; break;
00149 #endif
00150 #ifdef GL_INVALID_VALUE
00151 case GL_INVALID_VALUE: str += "GL_INVALID_VALUE"; break;
00152 #endif
00153 #ifdef GL_INVALID_OPERATION
00154 case GL_INVALID_OPERATION: str += "GL_INVALID_OPERATION"; break;
00155 #endif
00156 #ifdef GL_STACK_OVERFLOW
00157 case GL_STACK_OVERFLOW: str += "GL_STACK_OVERFLOW"; break;
00158 #endif
00159 #ifdef GL_STACK_UNDERFLOW
00160 case GL_STACK_UNDERFLOW: str += "GL_STACK_UNDERFLOW"; break;
00161 #endif
00162 #ifdef GL_OUT_OF_MEMORY
00163 case GL_OUT_OF_MEMORY: str += "GL_OUT_OF_MEMORY"; break;
00164 #endif
00165 #ifdef GL_INVALID_FRAMEBUFFER_OPERATION_EXT
00166 case GL_INVALID_FRAMEBUFFER_OPERATION_EXT: str += "GL_INVALID_FRAMEBUFFER_OPERATION"; break;
00167 #endif
00168 default: str += "UNKNOWN ERROR"; break;
00169 }
00170 str += "\n";
00171 }
00172 #ifdef RT_GLEW
00173 if( RenderTools::isGLInitialized() ){
00174 if( ! ( strcmp( ( const char * )glewGetErrorString( glerr ), "No error" ) == 0 || \
00175 strcmp( ( const char * )glewGetErrorString( glerr ), "Unknown error" ) == 0 ) ){
00176 str += "glewGetErrorString() = " + string( (char *)glewGetErrorString( glerr ) );
00177 str += "\n";
00178 }
00179 }
00180 #endif
00181 if( s_errors.size() ){
00182 dumpErrors( str, 0 );
00183 }
00184 cerr << str;
00185 throw( str );
00186 return( false );
00187 }
00188
00189 #endif
00190
00191 return( true );
00192 }
00193
00194 bool Error::assertNoWarnings( const char * file, int line, string msg ){
00195 if( s_warnings.size() ){
00196 string str = "RenderTools::assertNoWarnings failed in "+string(basename(file)) + string(":") + toString(line) + "\n";
00197 if( msg != "" ){
00198 str += "\n("+msg+")\n";
00199 }
00200 dumpWarnings( str, 1 );
00201 throw( str );
00202 return( false );
00203 }
00204 return( true );
00205 }
00206
00207 string Error::getErrorString( Code error ){
00208 string str( "" );
00209 switch( error ){
00210 case ERROR_NO_ERROR: str += "ERROR_NO_ERROR"; break;
00211 case IMAGE_NOT_LOADED: str += "IMAGE_NOT_LOADED"; break;
00212 case TEXTURE_UNITS_EXCEEDED: str += "TEXTURE_UNITS_EXCEEDED"; break;
00213 case TEXTURE_ALLOCATION_FAILED: str += "TEXTURE_ALLOCATION_FAILED"; break;
00214 case TEXTURE_UPLOAD_FAILED: str += "TEXTURE_UPLOAD_FAILED"; break;
00215 case TOO_MANY_COLORBUFFERS: str += "TOO_MANY_COLORBUFFERS"; break;
00216 case DEPTHBUFFER_ALREADY_EXISTS: str += "DEPTHBUFFER_ALREADY_EXISTS"; break;
00217 case STENCILBUFFER_ALREADY_EXISTS: str += "STENCILBUFFER_ALREADY_EXISTS"; break;
00218 case RENDERBUFFER_TOO_LARGE: str += "RENDERBUFFER_TOO_LARGE"; break;
00219 case TEXTURE_IS_NULL: str += "TEXTURE_IS_NULL"; break;
00220 case RENDERBUFFER_UNACCEPTABLE_TYPE: str += "RENDERBUFFER_UNACCEPTABLE_TYPE"; break;
00221 case PROGRAM_DOES_NOT_EXIST: str += "PROGRAM_DOES_NOT_EXIST"; break;
00222 case PROGRAM_NOT_BOUND: str += "PROGRAM_NOT_BOUND"; break;
00223 case CANNOT_OPEN_FILE: str += "CANNOT_OPEN_FILE"; break;
00224 case FILE_NOT_FOUND: str += "FILE_NOT_FOUND"; break;
00225 case SHADER_COMPILE_FAILED: str += "SHADER_COMPILE_FAILED"; break;
00226 case SHADER_LINK_FAILED: str += "SHADER_LINK_FAILED"; break;
00227 case UNIFORM_NOT_IN_PROGRAM: str += "UNIFORM_NOT_IN_PROGRAM"; break;
00228 case OVERWRITING_UNIFORM_IN_PROGRAM: str += "OVERWRITING_UNIFORM_IN_PROGRAM"; break;
00229 case CAMERA_NOT_IN_GROUP: str += "CAMERA_NOT_IN_GROUP"; break;
00230 case FRAMEBUFFER_NOT_IN_GROUP: str += "FRAMEBUFFER_NOT_IN_GROUP"; break;
00231 case PROGRAM_NOT_IN_GROUP: str += "PROGRAM_NOT_IN_GROUP"; break;
00232 case STATESET_NOT_IN_GROUP: str += "STATESET_NOT_IN_GROUP"; break;
00233 case TEXTURE_NOT_IN_GROUP: str += "TEXTURE_NOT_IN_GROUP"; break;
00234 case FRAMEBUFFER_INCOMPLETE_ATTACHMENT: str += "FRAMEBUFFER_INCOMPLETE_ATTACHMENT"; break;
00235 case FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: str += "FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT"; break;
00236 case FRAMEBUFFER_INCOMPLETE_DIMENSIONS: str += "FRAMEBUFFER_INCOMPLETE_DIMENSIONS"; break;
00237 case FRAMEBUFFER_INCOMPLETE_FORMATS: str += "FRAMEBUFFER_INCOMPLETE_FORMATS"; break;
00238 case FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER: str += "FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER"; break;
00239 case FRAMEBUFFER_INCOMPLETE_READ_BUFFER: str += "FRAMEBUFFER_INCOMPLETE_READ_BUFFER"; break;
00240 case FRAMEBUFFER_UNSUPPORTED: str += "FRAMEBUFFER_UNSUPPORTED"; break;
00241 case ILLEGAL_WRAPMODE_FOR_RECTANGLE_EXT:
00242 str += "ILLEGAL_WRAPMODE_FOR_RECTANGLE_EXT";
00243 str += "\n\t\tmust be either GL_CLAMP, ..._TO_EDGE, or ..._TO_BORDER.\n\t\tsee http://www.opengl.org/registry/specs/ARB/sampler_rectangle.txt";
00244 break;
00245 case MIPMAP_REQUESTED_FOR_RECTANGLE_EXT:
00246 str += "MIPMAP_REQUESTED_FOR_RECTANGLE_EXT";
00247 str += " \n\t\tsee http://www.opengl.org/registry/specs/ARB/sampler_rectangle.txt";
00248 break;
00249 case PASS_DIMENSION_UNDEFINED: str += "PASS_DIMENSION_UNDEFINED"; break;
00250 case MEMORY_ALLOCATION_FAILED: str += "MEMORY_ALLOCATION_FAILED"; break;
00251 case TOO_MANY_NAMES: str += "TOO_MANY_NAMES"; break;
00252 case TOO_MANY_TEXTURES: str += "TOO_MANY_TEXTURES"; break;
00253 case PROGRAM_VALIDATION_FAILED: str += "PROGRAM_VALIDATION_FAILED"; break;
00254 case FILE_READ_FAILED: str += "FILE_READ_FAILED"; break;
00255 case OVERWRITING_ITEM_IN_GROUP: str += "OVERWRITING_ITEM_IN_GROUP"; break;
00256 case ITEM_NOT_IN_GROUP: str += "ITEM_NOT_FOUND_IN_GROUP"; break;
00257 case ITEM_ALREADY_EXISTS: str += "ITEM_ALREADY_EXISTS"; break;
00258 case NULL_POINTER: str += "NULL_POINTER"; break;
00259 case UNIFORM_COMPONENTS_EXCEEDED: str += "UNIFORM_COMPONENTS_EXCEEDED"; break;
00260 case WARNING: str += "WARNING"; break;
00261 case INDEX_OUT_OF_BOUNDS: str += "INDEX_OUT_OF_BOUNDS"; break;
00262 case AMBIGUOUS_PATH: str += "AMBIGUOUS_PATH"; break;
00263 case STACK_UNDERFLOW: str += "STACK_UNDERFLOW"; break;
00264 case BUFFER_HAS_NO_SIZE: str += "BUFFER_HAS_NO_SIZE"; break;
00265 case BUFFER_HAS_NO_VERTICES: str += "BUFFER_HAS_NO_VERTICES"; break;
00266 case BUFFER_HAS_NO_COLORS: str += "BUFFER_HAS_NO_COLORS"; break;
00267 case BUFFER_HAS_NO_NORMALS: str += "BUFFER_HAS_NO_NORMALS"; break;
00268 case BUFFER_HAS_NO_TEXCOORDS: str += "BUFFER_HAS_NO_TEXCOORDS"; break;
00269 case NODE_NOT_FOUND: str += "NODE_NOT_FOUND"; break;
00270 case NODE_HAS_PARENT_BUT_IS_NOT_CHILD: str += "NODE_HAS_PARENT_BUT_IS_NOT_CHILD"; break;
00271 case NODE_IS_CHILD_BUT_HAS_NO_PARENT: str += "NODE_IS_CHILD_BUT_HAS_NO_PARENT"; break;
00272 case DIVISION_BY_ZERO: str += "DIVISION_BY_ZERO"; break;
00273 case INVALID_VALUE: str += "INVALID_VALUE"; break;
00274 case WRONG_TYPE: str += "WRONG_TYPE"; break;
00275 case BAD_CAST: str += "BAD_CAST"; break;
00276 case UNSUPPORTED_TYPE: str += "UNSUPPORTED_TYPE"; break;
00277 case INCORRECT_TYPE: str += "INCORRECT_TYPE"; break;
00278 case ILLEGAL_WRITE: str += "ILLEGAL_WRITE"; break;
00279 case CONVERSION_ERROR: str += "CONVERSION_ERROR"; break;
00280 case TOO_MANY_ITEMS: str += "TOO_MANY_ITEMS"; break;
00281 case REINITIALIZATION: str += "REINITIALIZATION"; break;
00282 case PASS_INCOMPLETE: str += "PASS_INCOMPLETE"; break;
00283 case OVERWRITING_ITEM_IN_MANAGER: str += "OVERWRITING_ITEM_IN_MANAGER"; break;
00284 case ITEM_NOT_IN_MANAGER: str += "ITEM_NOT_IN_MANAGER"; break;
00285 case TRIANGULATION_FAILED: str += "TRIANGULATION_FAILED"; break;
00286 case CLIPPING_FAILED: str += "CLIPPING_FAILED"; break;
00287 case ARRAY_TYPE_UNSUPPORTED: str += "ARRAY_TYPE_UNSUPPORTED"; break;
00288 case ELEMENT_SIZE_UNSUPPORTED: str += "ELEMENT_SIZE_UNSUPPORTED"; break;
00289 case NO_ACTIVE_GROUP: str += "NO_ACTIVE_GROUP"; break;
00290 case ITEM_NOT_INITIALIZED: str += "ITEM_NOT_INITIALIZED"; break;
00291 case GLEW_INITIALIZATION_FAILED: str += "GLEW_INITIALIZATION_FAILED"; break;
00292 case PROPERTY_DOES_NOT_EXIST: str += "PROPERTY_DOES_NOT_EXIST"; break;
00293 case EMPTY_PATH: str += "EMPTY_PATH"; break;
00294
00295 }
00296 return( str );
00297 }
00298
00299 #ifndef RT_AS3
00300 void Error::checkFramebufferStatus( const char * file, int line, string msg ){
00301 # ifdef GL_EXT_framebuffer_object
00302 switch( glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT ) ){
00303 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_ATTACHMENT, file, line, msg); break;
00304 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, file, line, msg); break;
00305 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_DIMENSIONS, file, line, msg); break;
00306 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_FORMATS, file, line, msg); break;
00307 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER, file, line, msg); break;
00308 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_READ_BUFFER, file, line, msg); break;
00309 case GL_FRAMEBUFFER_UNSUPPORTED_EXT: Error::error( Error::FRAMEBUFFER_UNSUPPORTED, file, line, msg); break;
00310 }
00311 # elif GL_OES_framebuffer_object
00312 switch( glCheckFramebufferStatusOES( GL_FRAMEBUFFER_OES ) ){
00313 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_OES: Error::error( Error::FRAMEBUFFER_INCOMPLETE_ATTACHMENT, file, line, msg); break;
00314 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_OES: Error::error( Error::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, file, line, msg); break;
00315 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_OES: Error::error( Error::FRAMEBUFFER_INCOMPLETE_DIMENSIONS, file, line, msg); break;
00316 case GL_FRAMEBUFFER_INCOMPLETE_FORMATS_OES: Error::error( Error::FRAMEBUFFER_INCOMPLETE_FORMATS, file, line, msg); break;
00317 case GL_FRAMEBUFFER_UNSUPPORTED_OES: Error::error( Error::FRAMEBUFFER_UNSUPPORTED, file, line, msg); break;
00318 }
00319 # else
00320 switch( glCheckFramebufferStatus( GL_FRAMEBUFFER ) ){
00321 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_ATTACHMENT, file, line, msg); break;
00322 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT: Error::error( Error::FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT, file, line, msg); break;
00323 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS: Error::error( Error::FRAMEBUFFER_INCOMPLETE_DIMENSIONS, file, line, msg); break;
00324 case GL_FRAMEBUFFER_UNSUPPORTED: Error::error( Error::FRAMEBUFFER_UNSUPPORTED, file, line, msg); break;
00325 }
00326 # endif
00327
00328 assertNoErrors( file, line, "checkFramebufferStatus:before glGetInteger( GL_RED_BITS )" );
00329
00331 glGetInteger( GL_RED_BITS );
00332
00333 assertNoErrors( file, line, "checkFramebufferStatus:after glGetInteger( GL_RED_BITS )" );
00334 }
00335 #endif
00336
00337 };
00338