„Grafika hibakezelés és tipikus hibák” változatai közötti eltérés

Rohamcsiga (vitalap | szerkesztései)
Csala Tamás (vitalap | szerkesztései)
 
(5 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).
<pre>
 
<br/> <syntaxhighlight lang="c">
#include <iostream>
#include <iostream>
#include <cstring>
 
#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 = strlen("GL_INVALID_ENUM");
         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 = strlen("GL_INVALID_VALUE");
         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 = strlen("GL_INVALID_OPERATION");
         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 = strlen("GL_STACK_OVERFLOW");
         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 = strlen("GL_STACK_UNDERFLOW");
         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 = strlen("GL_OUT_OF_MEMORY");
         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 = strlen("GL_INVALID_FRAMEBUFFER_OPERATION");
         err_len = sizeof("GL_INVALID_FRAMEBUFFER_OPERATION") - 1;
         break;
         break;
     };
     };
 
     std::cout << " ]}=========---------\n" << std::endl;
     std::cout << " ]}=========---------\n" << std::endl;
 
     std::cout << "A '" << func << "' függvenyben" << std::endl;
     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:
   }
   }
}
}
</pre>
</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:
<pre>
 
<br/> <syntaxhighlight lang="c">
1    void SetProjectionMatrix() {
1    void SetProjectionMatrix() {
2      CheckError();
2      CheckError();
114. sor: 115. sor:
7      CheckError();
7      CheckError();
8    }
8    }
</pre>
</syntaxhighlight> <br/>
 
* A futtatás eredménye:
* A futtatás eredménye:
<pre>
<pre>
---------========={[ GL_INVALID_ENUM ]}=========---------
---------========={[ GL_INVALID_ENUM ]}=========---------


A 'void SetProjectionMatrix()' függvenyben
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:
<pre>
<br/> <syntaxhighlight lang="c">
     pow(-2, 2) == 4; // A kitevő egész, ez ok
     pow(-2, 2) == 4; // A kitevő egész, ez ok
De: pow(-2, 2.1f) = UNDEFINED // A kitevő valós, nem ok. A (-2)^2.1 egy komplex szám.
    pow(-2, 2.1f) = UNDEFINED // A kitevő valós, nem ok. A (-2)^2.1 egy komplex szám (4,0773 + 1,3248i).
</pre>
</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 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.
* 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]]