2012-11-18 10 views
9

Od jakiegoś czasu pracuję nad programem GL i nagle zaczęły pojawiać się błędy. Po próbując rozwiązać te na chwilę Napisałem krótki program testowy, który generuje ten sam problem:nieprawidłowa operacja na glEnd bez przyczyny?

#include <GL/glut.h> 
#include <iostream> 

#define CHECK_GL_ERR() printError(__LINE__) 

void printError(int line) 
{ 
     GLenum err = glGetError(); 
     if(err != GL_NO_ERROR) 
     { 
       std::cerr << "GL error on line " << line << ": " << gluErrorString(err) << std::endl; 
     } 
} 

void displayFunc() 
{ 
     CHECK_GL_ERR(); 
     glBegin(GL_POINTS); 
     CHECK_GL_ERR(); 
     glVertex3f(0, 0, 0); 
     CHECK_GL_ERR(); 
     glEnd(); 
     CHECK_GL_ERR(); //line 23 
     exit(0); 
} 

int main(int argc, char **argv) 
{ 
     glutInit(&argc, argv); 
     glutInitWindowSize(300, 300); 
     glutCreateWindow("Test"); 

     glutDisplayFunc(displayFunc); 

     glutMainLoop(); 
} 

Kiedy uruchomić ten program daje wynik:

GL error on line 23: invalid operation 

więc wydaje się, że glEnd(); powoduje błąd. Docs powiedzieć:

GL_INVALID_OPERATION jest generowany jeśli glEnd jest wykonywany bez poprzedzony glBegin.

Co nie jest w moim kodzie. Czy ktokolwiek widzi, dlaczego ten kod wyświetla komunikat o błędzie?

PS: Oczywiście wiem, że glBegin/End został wycofany/usunięty przez długi czas, ale jest to bardzo wygodne, aby zhakować razem małe ilości kodu. Program również działał bez błędów, dopóki GL nie zdecydował się na zrzędę.

EDIT

Właśnie zrobiłem ślad z glslDevil który dał:

W! Program Start 
| glXQueryExtension(0x1ab03f0, (nil), (nil)) 
| glXChooseFBConfig(0x1ab03f0, 0, 0x7fffb8fcf8b0, 0x7fffb8fcf8a4) 
| glXGetVisualFromFBConfig(0x1ab03f0, 0x111) 
| glXGetProcAddressARB(0x7f93c37526e5) 
| glXCreateNewContext(0x1ab03f0, 0x111, 32788, (nil), 1) 
| glXIsDirect(0x1ab03f0, 0x1ac8de8) 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glDrawBuffer(GL_FRONT) 
| glReadBuffer(GL_FRONT) 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glViewport(0, 0, 300, 300) 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glGetError() 
| glBegin(GL_POINTS) 
| glGetError() 
| glVertex3f(0,000000, 0,000000, 0,000000) 
| glGetError() 
| glEnd() 
W! OpenGL error GL_INVALID_OPERATION detected 
| glGetError() 
| glXMakeContextCurrent(0x1ab03f0, 123731970, 123731970, 0x1ac8de8) 
| glXDestroyContext(0x1ab03f0, 0x1ac8de8) 
E! Child process exited 
W! Program termination forced! 
+0

Czyszczenie i następnie odbudowa projekt mógłby prawdopodobnie rozwiązać ten rodzaj „niespodzianka” problem .. –

+0

Jak widać ten krótki przykład w pełni odsłania błąd i zbudowany od podstaw, aby mieć demo. Ale tylko ze względu na kompletność: usunąłem pliki binarne i zrekompilowałem je, a błąd pozostaje tam, gdzie jest. – Nobody

+0

Błąd potwierdzony w systemie Ubuntu 12.04, gcc 4.6.3. –

Odpowiedz

13

Po pewnym testów, znalazłem program ma dwie proste kwestie:

  1. Nie wolno użyj glGetError wewnątrz bloku glBegin/glEnd. The API jest ścisły o tym. Ale błąd występuje tylko po glEnd. Jeśli czytasz API, zauważysz, że błąd może się rozprzestrzeniać: zdarza się to tylko po zakończeniu glEnd.
  2. Błąd segmentacji występuje podczas korzystania z funkcji exit (0) wewnątrz funkcji wyświetlania (dzieje się tak tylko w przypadku sterownika Intel). Dzieje się tak, ponieważ kontekst GL nie został jeszcze uwolniony i pojawia się błąd sterownika. Dlatego powinieneś unikać wyjścia wewnątrz funkcji wyświetlania.
+0

Wow Oszukałem się z makrem i zapomniałem, że glGetError to samo połączenie GL. Dzięki za badania w tej sprawie. O punkcie 2 Nie używam sterownika Intel i wyjście zostało dodane tylko, aby zapobiec wielokrotnemu wykonaniu, po tym jak program nie robi nic więcej w tym momencie. – Nobody

Powiązane problemy