Strumenti Utente



indice

Qt e OpenGL - Vertex Buffer Object con la classe QOpenGLBuffer

Abbiamo visto nei precedenti articoli come accedere ala funzionalità di OpenGL derivando le classi QWindow e QOpenGLWidget.

Vedremo ora come creare un Vertex Buffer Object con le librerie Qt. Un Vertex Buffer Object (d'ora in poi VBO) è un caratteristica delle OpenGL che permette di caricare sulla memoria della GPU informazioni specifiche per ciascun vertice, rendendole disponibili per le successive fasi di disegno. In questo modo si evitano continui passaggi di dati dalla CPU alla GPU ad ogni ridisegno della scena, ottimizzando l'impiego delle risorse. Le informazioni che possono essere passate spaziano da singoli valori numerici a vettori di qualsiasi dimensione, purché prefissata.

I VBO in generale

Analizziamo quali sono le API OpenGL necessarie per creare i VBO. Per farlo partiremo dal codice del precedente articolo.

Un metodo molto semplice per accedere direttamente alle API OpenGL è derivare dalla classe QOpenGLFunctions. Pertanto la nostra classe GLWidget deriverà sia da QOpenGLWidget che da QOpenGLFunctions

class GLWidget : public QOpenGLWidget, public QOpenGLFunctions

Non è però sufficiente: è necessario lanciare initializeOpenGLFunctions() nel metodo in initializeGL()

Qt e OpenGL - Intro alla classe QOpenGLWidget

Nel precedente articolo su Qt5 e le Opengl abbiamo cominciato a vedere come utilizzare la nuova infrastruttura Opengl introdotta nelle Qt5 derivando dalla classe QWindow. Abbiamo anche evidenziato che la classe QGLWidget già presente nelle Qt4, benché ancora presente in Qt5, è stata dichiarata obsoleta, senza che ne venisse fornito un vero e proprio sostituto. Questo è stato vero fino alla versione 5.4 con cui finalmente la vecchia QGLWidget è stata aggiornata alla nuova infrastruttura, diventando QOpenGLWidget.

Quando usare QWindow e quando QOpenGLWidget

QOpenGLWidget deriva da QWidget, quindi se abbiamo realizzato la nostra interfaccia usando oggetti derivati da QWidget, ci sarà più comodo usare QOpenGLWidget che potrà essere inserito direttamente nel layout come qualsiasi altro QWidget. Se invece non abbiamo bisogno di QWidget, ad esempio perché stiamo lavorando con QtQuick, allora preferiremo QWindow.

Qt e OpenGL - Introduzione

Con la nuova release delle Qt sono state introdotte nuove classi per l'impiego delle librerie grafiche Opengl.

In questo articolo accenneremo brevemente alle principali novità introdotte e vedremo un esempio applicativo disegneremo un triangolo in una classe derivata da QWindow. Nell'articolo Qt e OpenGL: Intro alla classe QOpenGLWidget potete invece vedere come realizzare lo stesso risultato reimplementando la classe QOpenGLWidget.

Il perché di tanti cambiamenti

Chi di voi proviene dalla versione 4 delle Qt noterà molti cambiamenti nell'impiego delle librerie Opengl all'interno del framework. I motivi di quello che sembrerebbe un restyling in realtà sono molto più profondi. Con le Qt5 si è cercato di utilizzare maggiormente la GPU per renderizzare la grafica delle interfacce. Per fare questo molte funzionalità che prima erano all'interno del modulo QtOpengl sono state estese al modulo QtGui.

Con l'occasione però sono state scritte nuova classi: ad esempio la classe QGlContext è stata riscritta nella classe QOpenglContext, QGlShaderProgram è diventata QOpenglShaderProgam etc. Le nuova classi, rispetto alle precedenti, hanno prestazioni leggermente migliori, hanno delle API più semplici e permettono l'impiego di un QOpenglContext su più superfici. Per approfondire l'argomento vi consiglio di leggere cosa dice in merito uno degli sviluppatori delle Qt all'indirizzo http://permalink.gmane.org/gmane.comp.lib.qt.devel/9065.

Qt-builds: in cinque minuti un ambiente di sviluppo per le Qt su Windows

Su Linux è tutto più facile!

Avere un ambiente di sviluppo funzionante per le Qt su linux è molto semplice. A seconda della distro che avete installato, di solito è sufficiente una semplice riga di comando.

Se lavoriamo con Archlinux, ad esempio, useremo

pacman -Sy gcc qt5-base qtcreator 

per avere tutto quello di cui abbiamo bisogno per partire con lo sviluppo

E su Windows?

Nonostante usualmente lavori con linux, a volte ho la necessità di scrivere applicazioni su Windows impiegando le librerie Qt. E su Windows le cose non sono così semplici come per linux. Chi si è trovato nella stessa situazione sa che tra incompatibilità binarie e modifiche al registro di sistema non sempre tutto fila liscio.

Ad esempio, l'SDK ufficiale delle Qt fino a poco tempo fa installava una versione di mingw (alias gcc per Windows) talmente tanto vecchiotta (la 4.4), da rendere necessaria la ricompilazione delle Qt con una versione di mingw più aggiornata, con tempi di attesa biblici e un sacco di modifiche da apportare al codice sorgente. A questo si aggiunge la necessità di avere alcune utility di solito non disponibili su windows (git, svn, bunzip…) per le quali è necessario partire alla ricerca dei singoli binari. Ma non finisce qui, perché i vari binari devono interagire tra di loro, ecco allora che si deve intervenire sulla variabile PATH piuttosto che sul registro di sistema. Insomma, per avere un ambiente di sviluppo pienamente funzionante è necessaria in media un'oretta di lavoro.

L'alternativa a tutto questo è incredibilmente semplice: un progetto disponibile su sourceforge chiamato Qt-builds.

Memorizzare un puntatore in una classe QVariant

 

Alla pagina http://blog.bigpixel.ro/2010/04/storing-pointer-in-qvariant/ ho trovato un metodo molto utile per memorizzare puntatori di qualunque tipo in un oggetto di tipo QVariant.

Per chi non fosse pratico della programmazione "Model/View" delle librerie Qt, diciamo che separando il modello dei nostri dati dalla relativa interfaccia grafica, il passaggio delle informazioni tra i due avviene attraverso oggetti di tipo QVariant, contenitori generici che possono contenere praticamente di tutto. I metodi della classe QVariant ci pemettono di gestire facilmente oggetto di tipo double, int, QString. Meno immediato è il passaggio di puntatori a classi personalizzate che adesso analizzeremo.

Vediamo i dettagli su come procedere.

Supponiamo di avere un puntatore

MyClass * pointer

Possiamo memorizzare il contenuto del puntatore in un oggetto QVariant mediante

QVariant v = qVariantFromValue((void *) pointer );

Volendo recuperare il puntatore dall'oggetto QVariant ricorriamo alle righe di codice

pointer = (MyClass *) v.value<void *>();

Possiamo semplificare quest'operazione ricorrendo ad un template contenente due metodi di tipo statico

template <class T> class VariantPtr
{
public:
    static T* asPtr(QVariant v)
    {
	return  (T *) v.value<void *>();
    }
    static QVariant asQVariant(T* ptr)
    {
	return qVariantFromValue((void *) ptr);
    }
};

E' possibile ora riscrivere le linee di codice viste sopra per memorizzazione e recuperare il puntatore dall'oggetto Qvariant. Per copiare il valore del puntatore ricorriamo a

QVariant v = VPtr<MyClass>::asQVariant(p);

Per recuperarlo invece usiamo il codice

MyClass *p1 = VPtr<MyClass>::asPtr(v);

indice.txt · Ultima modifica: 2013/07/08 10:00 da mickele

Facebook Twitter Google+ Digg Reddit LinkedIn StumbleUpon Email