„Grafika hibakezelés és tipikus hibák” változatai közötti eltérés
Új oldal, tartalma: „=== FAQ (avagy a grafika listán a legtöbb levelet generáló "misztikus" hibák) === * Fordításkor ilyen hibát kapok: <code>error: stray '\357' in program...</code…” |
|||
| (9 közbenső módosítás, amit egy másik szerkesztő végzett, nincs mutatva) | |||
| 23. sor: | 23. sor: | ||
float b=a/10; //értéke nem 0.5 lesz, hanem 0! | float b=a/10; //értéke nem 0.5 lesz, hanem 0! | ||
</pre> | </pre> | ||
* A hiba elkerülése végett használjunk cast-olást vagy típusos konstansokat: | |||
<pre> | <pre> | ||
float b=(float)a/10; | float b=(float)a/10; | ||
| 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 | ||
| 125. sor: | 127. sor: | ||
</pre> | </pre> | ||
* Ebből megtudod, hogy a hiba a 2. sorban még nem lépett fel, de a 7. már igen. Tehát a 4 OpenGL függvényhívás egyike a rossz, és az a gondja, hogy rossz enumot használsz (GL_INVALID_ENUM). A 4 függvényből csak kettőben van enum, a két glMatrixMode() hívásban. A kettő közül a 6. sor a rossz, az helyesen glMatrixMode(GL_MODELVIEW) lenne, mert a GL_MODELVIEW és a GL_MODELVIEW_MATRIX enumok nem ugyan arra valók. Ezt a hibát ennek a trükknek a használata nélkül nagyon nehéz lenne megtalálni, hiszen a kód jónak látszik, viszont a képernyőn nem látszódna semmi, vagy ha látszódna is, akkor annak semmi köze nem lenne ahhoz, amit rajzolni akartál. Egy ilyen hiba megtalálása még a legrutinosabbaknak is valószínűleg több órába telne. Ez az egyszerű függvény viszont szinte pontosan megmondta, hogy hol és mi a hiba. | * Ebből megtudod, hogy a hiba a 2. sorban még nem lépett fel, de a 7. már igen. Tehát a 4 OpenGL függvényhívás egyike a rossz, és az a gondja, hogy rossz enumot használsz (GL_INVALID_ENUM). A 4 függvényből csak kettőben van enum, a két glMatrixMode() hívásban. A kettő közül a 6. sor a rossz, az helyesen glMatrixMode(GL_MODELVIEW) lenne, mert a GL_MODELVIEW és a GL_MODELVIEW_MATRIX enumok nem ugyan arra valók. Ezt a hibát ennek a trükknek a használata nélkül nagyon nehéz lenne megtalálni, hiszen a kód jónak látszik, viszont a képernyőn nem látszódna semmi, vagy ha látszódna is, akkor annak semmi köze nem lenne ahhoz, amit rajzolni akartál. Egy ilyen hiba megtalálása még a legrutinosabbaknak is valószínűleg több órába telne. Ez az egyszerű függvény viszont szinte pontosan megmondta, hogy hol és mi a hiba. | ||
=== Nálam működik, a beadón viszont nem hibák === | |||
* 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: | |||
<br/> <syntaxhighlight lang="c"> | |||
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 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]] | ||