„Grafika hibakezelés és tipikus hibák” változatai közötti eltérés
a túl sok lett a zárójel egy linknél |
|||
| (6 közbenső módosítás, amit egy másik szerkesztő végzett, nincs mutatva) | |||
| 42. sor: | 42. sor: | ||
* Az OpenGL sajnos nem túl típusos, így ha egy függvényt rossz paraméterekkel hívunk meg, akkor az általában nem generál fordítási hibát, hanem szimplán csak nem működik. | * Az OpenGL sajnos nem túl típusos, így ha egy függvényt rossz paraméterekkel hívunk meg, akkor az általában nem generál fordítási hibát, hanem szimplán csak nem működik. | ||
** Az ilyen hibák megtalálása nagyon nehéz, mert csak annyit látsz, a program nem működik, de nem szól, hogy mivel van gondja. | ** Az ilyen hibák megtalálása nagyon nehéz, mert csak annyit látsz, a program nem működik, de nem szól, hogy mivel van gondja. | ||
** Szerencsére az OpenGL készítői gondoltak erre, és az ilyen hibák beállítanak egy flaget amit le lehet kérdezni. Ezt a glGetError() függvénnyel lehet megtenni. A függvény ömagában csak egy számot ad vissza, amit nehéz értelmezni, de itt van egy wrapper, ami emberileg is fogyaszható formába írja ki, hogy mi történt. Ezt persze a beadón nem lehet használni, de az otthoni változatba debuggoláshoz sokat segíthet. | ** Szerencsére az OpenGL készítői gondoltak erre, és az ilyen hibák beállítanak egy flaget amit le lehet kérdezni. Ezt a glGetError() függvénnyel lehet megtenni. A függvény ömagában csak egy számot ad vissza, amit nehéz értelmezni, de itt van egy wrapper, ami emberileg is fogyaszható formába írja ki, hogy mi történt. Ezt persze a beadón nem lehet használni, de az otthoni változatba debuggoláshoz sokat segíthet (nyugodtan formázd át a hibaüzenetet, olyanra, hogy neked tetszen). | ||
< | |||
<br/> <syntaxhighlight lang="c"> | |||
#include <iostream> | #include <iostream> | ||
#define CheckError() __CheckError(__FILE__, __PRETTY_FUNCTION__, __LINE__) | #define CheckError() __CheckError(__FILE__, __PRETTY_FUNCTION__, __LINE__) | ||
inline void __CheckError(const char *file, const char *func, int line) { | inline void __CheckError(const char *file, const char *func, int line) { | ||
GLenum error = glGetError(); | GLenum error = glGetError(); | ||
if(error != GL_NO_ERROR) { | if(error != GL_NO_ERROR) { | ||
std::cout << "\n---------========={[ "; | std::cout << "\n---------========={[ "; | ||
int err_len; | int err_len; | ||
switch(error) { | switch(error) { | ||
case GL_INVALID_ENUM: | case GL_INVALID_ENUM: | ||
std::cout << "GL_INVALID_ENUM"; | std::cout << "GL_INVALID_ENUM"; | ||
err_len = | err_len = sizeof("GL_INVALID_ENUM") - 1; | ||
break; | break; | ||
case GL_INVALID_VALUE: | case GL_INVALID_VALUE: | ||
std::cout << "GL_INVALID_VALUE"; | std::cout << "GL_INVALID_VALUE"; | ||
err_len = | err_len = sizeof("GL_INVALID_VALUE") - 1; | ||
break; | break; | ||
case GL_INVALID_OPERATION: | case GL_INVALID_OPERATION: | ||
std::cout << "GL_INVALID_OPERATION"; | std::cout << "GL_INVALID_OPERATION"; | ||
err_len = | err_len = sizeof("GL_INVALID_OPERATION") - 1; | ||
break; | break; | ||
case GL_STACK_OVERFLOW: | case GL_STACK_OVERFLOW: | ||
std::cout << "GL_STACK_OVERFLOW"; | std::cout << "GL_STACK_OVERFLOW"; | ||
err_len = | err_len = sizeof("GL_STACK_OVERFLOW") - 1; | ||
break; | break; | ||
case GL_STACK_UNDERFLOW: | case GL_STACK_UNDERFLOW: | ||
std::cout << "GL_STACK_UNDERFLOW"; | std::cout << "GL_STACK_UNDERFLOW"; | ||
err_len = | err_len = sizeof("GL_STACK_UNDERFLOW") - 1; | ||
break; | break; | ||
case GL_OUT_OF_MEMORY: | case GL_OUT_OF_MEMORY: | ||
std::cout << "GL_OUT_OF_MEMORY"; | std::cout << "GL_OUT_OF_MEMORY"; | ||
err_len = | err_len = sizeof("GL_OUT_OF_MEMORY") - 1; | ||
break; | break; | ||
case GL_INVALID_FRAMEBUFFER_OPERATION: | case GL_INVALID_FRAMEBUFFER_OPERATION: | ||
std::cout << "GL_INVALID_FRAMEBUFFER_OPERATION"; | std::cout << "GL_INVALID_FRAMEBUFFER_OPERATION"; | ||
err_len = | err_len = sizeof("GL_INVALID_FRAMEBUFFER_OPERATION") - 1; | ||
break; | break; | ||
}; | }; | ||
std::cout << " ]}=========---------\n" << std::endl; | std::cout << " ]}=========---------\n" << std::endl; | ||
std::cout << "A '" << func << "' | std::cout << "A '" << func << "' fuggvenyben" << std::endl; | ||
std::cout << "A '" << file << "' fajl " << line << ". soraban\n" << std::endl; | std::cout << "A '" << file << "' fajl " << line << ". soraban\n" << std::endl; | ||
int ending_line_length = err_len + 42; | int ending_line_length = err_len + 42; | ||
for(int i = 0; i < ending_line_length; i++) { | for(int i = 0; i < ending_line_length; i++) { | ||
| 100. sor: | 100. sor: | ||
} | } | ||
} | } | ||
</ | </syntaxhighlight> <br/> | ||
* A használata: | * A használata: | ||
** A kódba ha leírod, hogy CheckError(); akkor az kiirja, hogy addig volt-e hiba. | ** A kódba ha leírod, hogy CheckError(); akkor az kiirja, hogy addig volt-e hiba. | ||
** Példa: | ** Példa: | ||
< | |||
<br/> <syntaxhighlight lang="c"> | |||
1 void SetProjectionMatrix() { | 1 void SetProjectionMatrix() { | ||
2 CheckError(); | 2 CheckError(); | ||
| 114. sor: | 115. sor: | ||
7 CheckError(); | 7 CheckError(); | ||
8 } | 8 } | ||
</ | </syntaxhighlight> <br/> | ||
* A futtatás eredménye: | * A futtatás eredménye: | ||
<pre> | <pre> | ||
---------========={[ GL_INVALID_ENUM ]}=========--------- | ---------========={[ GL_INVALID_ENUM ]}=========--------- | ||
A 'void SetProjectionMatrix()' | A 'void SetProjectionMatrix()' fuggvenyben | ||
A 'main.cpp' fajl 7. soraban | A 'main.cpp' fajl 7. soraban | ||
| 130. sor: | 132. sor: | ||
* Szinte biztos, hogy NEM a beadó rossz, csak a kódodba van valamilyen rejtett hiba, ami nem definiált, implementáció függő viselkedést okoz, ami a te gépeden véletlenül pont azt csinálja, amit akartál, hogy csináljon, de egy másik gépen - mint pl. a beadón - már nem. | * Szinte biztos, hogy NEM a beadó rossz, csak a kódodba van valamilyen rejtett hiba, ami nem definiált, implementáció függő viselkedést okoz, ami a te gépeden véletlenül pont azt csinálja, amit akartál, hogy csináljon, de egy másik gépen - mint pl. a beadón - már nem. | ||
* Ilyen hibát c++-ba is tudsz véteni, pl : pow() negatív számokra: | * Ilyen hibát c++-ba is tudsz véteni, pl : pow() negatív számokra: | ||
< | <br/> <syntaxhighlight lang="c"> | ||
pow(-2, 2) == 4; // A kitevő egész, ez ok | pow(-2, 2) == 4; // A kitevő egész, ez ok | ||
pow(-2, 2.1f) = UNDEFINED // A kitevő valós, nem ok. A (-2)^2.1 egy komplex szám (4,0773 + 1,3248i). | |||
</ | </syntaxhighlight> <br/> | ||
* Az utóbbi kódra előfordulhat, hogy a pow függvény nálad a komplex eredmény valós részét adja vissza, a beadón viszont NAN-t, mondva, hogy komplex számot nem tud valóssá konvertálni helyesen. | * Az utóbbi kódra előfordulhat, hogy a pow függvény nálad a komplex eredmény valós részét adja vissza, a beadón viszont NAN-t, mondva, hogy komplex számot nem tud valóssá konvertálni helyesen. | ||
* Az OpenGL-be rengeteg ilyen van. És sajnos nincs ezek ellen | * Az OpenGL-be rengeteg ilyen van. És sajnos nincs ezek ellen más ellenszer, mint hogy az általad használt függvények [http://www.talisman.org/opengl-1.1/Reference.html dokumentációját] elolvasod, ahol leírják, hogy az milyen esetben okoz implementáció függő viselkedést. Szerencsére az esetek több mint 90%-ába ilyenkor a függvény generál egy hibát, amit az előbb bemutatott CheckError()-al el lehet kapni, de nem mindig. | ||
[[Category:Infoalap]] | [[Category:Infoalap]] | ||