tutorial_qt:opengl_01
Differenze
Queste sono le differenze tra la revisione selezionata e la versione attuale della pagina.
Entrambe le parti precedenti la revisione Revisione precedente Prossima revisione | Revisione precedente | ||
tutorial_qt:opengl_01 [2015/01/21 06:43] mickele |
tutorial_qt:opengl_01 [2015/05/05 14:43] (versione attuale) mickele |
||
---|---|---|---|
Linea 1: | Linea 1: | ||
- | ~~NEWSFEED~~ | + | ====== |
- | ====== | + | |
- | < | + | |
- | Con la nuova release delle [[http:// | + | Con la nuova release delle [[http:// |
- | In questo articolo accenneremo brevemente | + | In questo articolo accenneremo brevemente |
===== Il perché di tanti cambiamenti ===== | ===== Il perché di tanti cambiamenti ===== | ||
Linea 14: | Linea 12: | ||
~~READMORE~~ | ~~READMORE~~ | ||
- | </ | ||
- | ===== QGLWidget vs QWindow ===== | + | ===== QGLWidget vs QWindow/ |
La prima grande novità riguarda la classe base che useremo per creare la nostra superficie. Nel passato si faceva riferimento a [[http:// | La prima grande novità riguarda la classe base che useremo per creare la nostra superficie. Nel passato si faceva riferimento a [[http:// | ||
- | Per quanto sia sempre possibile usare QGLWidget anche con le Qt5, il nuovo approccio prevede l' | + | Per quanto sia sempre possibile usare QGLWidget anche con le Qt5, il nuovo approccio prevede l' |
- | + | ||
- | Quali le differenze tra le due classi? | + | |
- | + | ||
- | Una prima differenza è che QGLWidget deriva da QWidget, QWindow no, non avremo quindi a disposizione alcuni dei comodi strumenti presenti in QWidget. | + | |
- | + | ||
- | Un' | + | |
===== Partiamo da QWindow... ===== | ===== Partiamo da QWindow... ===== | ||
- | Iniziamo con un esempio concreto, creando | + | Vediaemo come creare |
+ | * QWindow non deriva da QWidget, non avremo quindi a disposizione alcuni dei comodi strumenti presenti in QWidget | ||
+ | * mentre con QGLWidget (e con QOpenGLWidget) è necessario ridefinire i metodi virtuali // | ||
- | Creiamo la classe GLWindow che estende QWindow e [[http:// | + | Creiamo la classe GLWindow che estende QWindow e [[http:// |
Avremo un file header glwindow.h che conterrà | Avremo un file header glwindow.h che conterrà | ||
Linea 61: | Linea 54: | ||
}; | }; | ||
- | Abbiamo introdotto alcuni | + | Abbiamo introdotto alcuni |
- | Il costruttore di GLWindow si limita ad inizializzare un attributo e a dire alle Qt che intendiamo disegnare sulla superficie | + | Il costruttore di GLWindow si limita ad inizializzare un attributo e a comunicare all' |
GLWindow:: | GLWindow:: | ||
Linea 73: | Linea 66: | ||
} | } | ||
- | La gestione degli eventi nel nostro primo esempio è molto semplice, ci basta reimplementare due metodi virtuali: void exposeEvent(QExposeEvent *event) e void resizeEvent(QResizeEvent *event). | + | Poichè le funzionalità che vogliamo implementare sono molto semplici, ci basta reimplementare due metodi virtuali: void exposeEvent(QExposeEvent *event) e void resizeEvent(QResizeEvent *event). Il primo viene chiamato ogni volta che cambia la visibilità della nostra superficie |
- | + | ||
- | Il primo viene chiamato ogni volta che cambia la visibilità della nostra superficie; se è visibile, | + | |
void GLWindow:: | void GLWindow:: | ||
Linea 82: | Linea 73: | ||
} | } | ||
- | Il metodo paint(), che vedremo tra poco, è quello che disegna il triangolo. | + | Il metodo paint(), che vedremo tra poco, disegna il triangolo. |
- | Il metodo resizeEvent() viene chiamato in concomitanza dei ridimensionamenti della superficie. In tal caso dovremo cambiare le dimensioni della finestra | + | Il metodo resizeEvent() viene chiamato in concomitanza dei ridimensionamenti della superficie. In tal caso dovremo cambiare le dimensioni della finestra |
void GLWindow:: | void GLWindow:: | ||
Linea 94: | Linea 85: | ||
} | } | ||
- | ===== ... e aggiungiamo un po' di Opengl | + | ===== Gli shader |
- | I metodi che vedremo ora, sia come denominazione che come struttura che come compiti, sono il risultato di una scelta personale e come tali possono essere modificati. Perciò, acquisita un po' di dimestichezza con le opengl, modificateli pure! | + | Alla base della programmazione OpenGL moderna ci sono gli [[http:// |
+ | |||
+ | Le prime versioni dello standard OpenGL prevedevano pipeline grafiche fisse: i calcoli eseguiti dalla scheda grafica erano di una tipologia ben specifica. Le Opengl 2.0 hanno introdotte per un primo livello di personalizzazione delle operazioni compiute dalla GPU che sono così diventate programmabili. Gli shader sono i programmi che carichiamo sulle schede grafiche. | ||
+ | |||
+ | Nella versione 5 delle Qt creiamo gli shader usando la classe [[http:// | ||
+ | |||
+ | ===== Opengl secondo la Qt-way ===== | ||
+ | |||
+ | I metodi che vedremo ora, sia come denominazione che come struttura che come compiti, sono il risultato di una scelta personale e come tali possono essere modificati. Perciò, acquisita un po' di dimestichezza con le OpenGL, modificateli pure! | ||
Analizziamo prima il metodo paint(), il cuore delle operazioni di disegno | Analizziamo prima il metodo paint(), il cuore delle operazioni di disegno | ||
Linea 103: | Linea 102: | ||
if (!isExposed()) | if (!isExposed()) | ||
return; | return; | ||
- | | + | |
bool needsInitialize = false; | bool needsInitialize = false; | ||
- | | + | |
if (!context) { | if (!context) { | ||
m_context = new QOpenGLContext(this); | m_context = new QOpenGLContext(this); | ||
Linea 113: | Linea 112: | ||
needsInitialize = true; | needsInitialize = true; | ||
} | } | ||
+ | | ||
m_context-> | m_context-> | ||
+ | | ||
if(needsInitialize) { | if(needsInitialize) { | ||
initialize(); | initialize(); | ||
} | } | ||
- | | + | |
paintGL(); | paintGL(); | ||
+ | | ||
m_context-> | m_context-> | ||
} | } | ||
- | Una volta sola, prima che avvenga il primo disegno, paint() | + | Una volta sola, prima che avvenga il primo disegno, paint() |
void GLWindow:: | void GLWindow:: | ||
Linea 143: | Linea 142: | ||
- | Il metodo initShaders() inizializza gli shaders. Più in particolare, | + | Il metodo initShaders() inizializza gli shaders |
* creiamo un oggetto QOpenGLShaderProgram | * creiamo un oggetto QOpenGLShaderProgram | ||
* associamo a questo oggetto il codice degli shaders, contenuto in due file esterni | * associamo a questo oggetto il codice degli shaders, contenuto in due file esterni | ||
Linea 150: | Linea 149: | ||
void GLWindow:: | void GLWindow:: | ||
m_context-> | m_context-> | ||
- | | + | |
m_program = new QOpenGLShaderProgram(this); | m_program = new QOpenGLShaderProgram(this); | ||
- | | + | |
// Compila lo shader dei vertici | // Compila lo shader dei vertici | ||
if (!m_program-> | if (!m_program-> | ||
close(); | close(); | ||
- | | + | |
// Compile lo shader fragment | // Compile lo shader fragment | ||
if (!m_program-> | if (!m_program-> | ||
close(); | close(); | ||
+ | | ||
// Linka shaders | // Linka shaders | ||
if (!m_program-> | if (!m_program-> | ||
Linea 187: | Linea 186: | ||
- | Ed infine i comandi per disegnare il nostro triangolo. In questo primo articolo ci limitiamo a passare ad ogni ridisegno i dati necessari. Per farlo usiamo prima il metodo enableAttributeArray() | + | Ed infine |
void GLWindow:: | void GLWindow:: | ||
m_context-> | m_context-> | ||
- | | + | |
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); | ||
- | | + | |
m_program-> | m_program-> | ||
- | | + | |
QMatrix4x4 matrix; | QMatrix4x4 matrix; | ||
matrix.perspective(60, | matrix.perspective(60, | ||
matrix.translate(0, | matrix.translate(0, | ||
- | | + | |
m_program-> | m_program-> | ||
- | | + | |
QVector2D vertices [] = { | QVector2D vertices [] = { | ||
QVector2D(0.0f, | QVector2D(0.0f, | ||
Linea 207: | Linea 206: | ||
QVector2D(0.5f, | QVector2D(0.5f, | ||
}; | }; | ||
- | | + | |
m_program-> | m_program-> | ||
m_program-> | m_program-> | ||
- | | + | |
QVector3D colors[] = { | QVector3D colors[] = { | ||
QVector3D(1.0f, | QVector3D(1.0f, | ||
Linea 216: | Linea 215: | ||
QVector3D(0.0f, | QVector3D(0.0f, | ||
}; | }; | ||
- | | + | |
m_program-> | m_program-> | ||
m_program-> | m_program-> | ||
- | | + | |
glDrawArrays(GL_TRIANGLES, | glDrawArrays(GL_TRIANGLES, | ||
- | | + | |
m_program-> | m_program-> | ||
} | } | ||
- | Per visualizzare quello che abbiamo creato ci serve un file mail.cpp | + | Per visualizzare quello che abbiamo creato ci serve un file main.cpp |
#include < | #include < | ||
Linea 233: | Linea 232: | ||
int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||
QGuiApplication app(argc, argv); | QGuiApplication app(argc, argv); | ||
- | | + | |
GLWindow window; | GLWindow window; | ||
window.resize(640, | window.resize(640, | ||
window.show(); | window.show(); | ||
- | | + | |
return app.exec(); | return app.exec(); | ||
} | } | ||
Linea 245: | Linea 244: | ||
{{ : | {{ : | ||
- | Tutti i file necessari sono contenuati | + | Tutti i file necessari sono contenuti |
+ | ===== Articoli correlati ===== | ||
- | ===== e poi... ===== | + | <blog related> |
- | + | | |
- | Nel prossimo articolo approfondiremo i comandi | + | |
+ | </ | ||
===== Per approfondire ===== | ===== Per approfondire ===== | ||
Linea 265: | Linea 266: | ||
* [[http:// | * [[http:// | ||
* [[http:// | * [[http:// | ||
- | + | ||
+ | ===== Potrebbero interessarti anche... ===== | ||
+ | |||
+ | Un elenco degli altri articoli disponibili sull' | ||
+ | <blog related> | ||
+ | </ | ||
tutorial_qt/opengl_01.1421819030.txt.gz · Ultima modifica: 2015/01/21 06:43 da mickele