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.
Ultimi commenti