Instabilita' OpenGL e glEdgeFlag

Matteo - 26 apr 2005 02:01

Lavoro da anni con OpenGL e in questi anni ho riscontrato ogni tipo di problema di incompatibilita', soprattutto su piattaforma Windows. Sebbene OpenGL sia essenzialmente cross-platform su questa piattaforma i produttori di driver prediligono sicuramente il supporto per Direct3D, anche perche' M$ paga profumatamente e i clienti pure...

Comunque, dicevo, molti clienti hanno mandato report di crash con ogni scheda grafica: Matrox, ATI, NVidia... non se ne salva nessuna, anche se devo dire che le segnalazioni di problemi di chi ha schede NVidia sono molto minori in numero. Le ATI soffrono principalmente perche', sebbene molto diffuse, la casa madre da' in licenza il chip ed i driver a produttori secondari che personalizzano entrambi: ad esempio moltissimi portatili PC con ATI Radeon degli ultimi anni arrivano all'acquirente con pessimi driver ASUS non aggiornati, che generano problemi a non finire, anche e soprattutto con applicazioni opengl. E naturalmente chi ci fa brutta figura sono i fornitori del software, non quelli dei driver... Vabbe' si va fuori tema :)

Veniamo al dunque. Un crash che si presentava su diverse schede era dovuto all'uso della funzione glEdgeFlag. Questa funzione, come saprete, imposta il successivo vertice come il primo di uno spigolo da disegnare con una linea nel caso si stia definendo un poligono. Per evitare problemi, nonostante la documentazione non lo dica, questa funzione va chiamata SEMPRE tra un glBegin ed il successivo glEnd, ovvero all'interno della definizione del poligono stesso: se non lo fate, rischiate di vedere l'applicazione funzionare perfettamente sul vostro computer e sapere che crasha miseramente su quello del cliente (ovviamente, seguendo la nota legge di Murphy, la situazione non sara' mai invertita). E' inoltre saggio anche evitare di chiamare questa funzione troppe volte: alcune schede non gradiscono tale premura. Consiglio di creare una funzione "proxy" apposita che memorizza il flag di edge corrente (parte sempre di default a true per ogni contesto opengl) e che chiama glEdgeFlag solo se viene chiesto di invertire il flag.

Aggiornamento

Ci sono stati altri sviluppi, che mi hanno portato ad includere tra le preferenze dell'applicazione principale di cui mi occupo, la possibilita' di disabilitare del tutto la visualizzazione degli edge dei poligoni. Tale disattivazione comporta la totale assenza di chiamate a glEdgeFlag, cosa che aumenta drasticamente la stabilita' dell'applicazione. Addirittura ho avuto crash con l'uso di glEdgeFlag utilizzando la libreria di reference software MesaGL...

Un'ulteriore modifica all'applicazione, che ho ritenuto opportuno fare sulla base di bugfix operati da M$ su vecchie versioni di Windows, riguarda la sostituzione di tutte le chiamate a glEnd con una funzione custom che naturalmente chiama glEnd, ma incrementa anche un contatore e ogni 200 chiamate - mi pare - chiama anche glFlush, che fa si' che le istruzioni date fino a quel momento siano svolte. glFlush e' comoda nel senso che non blocca l'esecuzione del programma, ma si limita a "suggerire" al driver di inviare le operazioni alla scheda grafica, in modo parallelo: quindi non rallenta molto l'esecuzione. Il vantaggio, ed il bug che sarebbe alla base della modifica, sarebbe che si evitano eventuali overflow di buffer interni ai driver video che tengono traccia delle primitive e delle operazioni richieste.

 
Weblog Koan Progetti Foto Contatti DW.net map