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 [2013/09/14 18:28] mickele [... e aggiungiamo un po' di Opengl] |
tutorial_qt:opengl_01 [2015/05/05 14:43] mickele |
||
---|---|---|---|
Linea 1: | Linea 1: | ||
- | ====== | + | ====== |
- | Con la nuova release delle [[http:// | + | Con la nuova release delle [[http:// |
+ | |||
+ | In questo articolo accenneremo | ||
===== Il perché di tanti cambiamenti ===== | ===== Il perché di tanti cambiamenti ===== | ||
- | I motivi di quello che sembrerebbe un restyling in realtà sono molto più profondi. Con le Qt5 si è cercato di utilizzare maggiormente | + | Chi di voi proviene dalla versione 4 delle Qt noterà molti cambiamenti nell' |
- | Con l' | + | Con l' |
- | ===== QGLWidget vs QWindow ===== | + | ~~READMORE~~ |
- | La prima grande novità riguarda la classe base che useremo per creare la nostra superficie. Nel passato si faceva riferimento alla classe [[http:// | + | ===== QGLWidget vs QWindow/QOpenGLWidget ===== |
- | Posto che è comunque sempre possibile ricorrere alla classe QGLWidget anche con le Qt5, il nuovo approccio proposto prevede l' | + | La prima grande novità riguarda la classe |
- | Una prima differenza è nel fatto che QGLWidget | + | Per quanto sia sempre possibile usare QGLWidget |
- | Un altra differenza riguarda le modalità di impiego. Derivando QGLwidget era necessario reimplementare i metodi virtuali // | ||
===== Partiamo da QWindow... ===== | ===== Partiamo da QWindow... ===== | ||
- | Iniziamo con un esempio concreto, creando | + | Vediaemo come creare |
- | + | | |
- | Creiamo la classe GLWindow che estende | + | * mentre con QGLWidget (e con QOpenGLWidget) è necessario ridefinire i metodi virtuali |
- | Avremo allora un file header glwindow.h | + | Creiamo la classe GLWindow |
+ | Avremo un file header glwindow.h che conterrà | ||
+ | class QOpenGLShaderProgram; | ||
#include < | #include < | ||
#include < | #include < | ||
Linea 34: | Linea 37: | ||
public: | public: | ||
explicit GLWindow(QWindow *parent = 0); | explicit GLWindow(QWindow *parent = 0); | ||
- | ... | ||
| | ||
private: | private: | ||
QOpenGLShaderProgram * m_program; | QOpenGLShaderProgram * m_program; | ||
QOpenGLContext * m_context; | QOpenGLContext * m_context; | ||
- | QOpenGLPaintDevice * m_device; | ||
| | ||
GLuint m_posAttr; | GLuint m_posAttr; | ||
GLuint m_colAttr; | GLuint m_colAttr; | ||
GLuint m_matrixUniform; | GLuint m_matrixUniform; | ||
+ | | ||
+ | void exposeEvent(QExposeEvent *event); | ||
+ | void resizeEvent(QResizeEvent *event); | ||
+ | virtual void initialize(); | ||
+ | virtual void initShaders(); | ||
+ | virtual void paint(); | ||
+ | virtual void paintGL(); | ||
}; | }; | ||
- | Inoltre, come potete vedere, introduciamo | + | Abbiamo introdotto |
- | Il costruttore di GLWindow si limita ad inizializzare | + | Il costruttore di GLWindow si limita ad inizializzare |
GLWindow:: | GLWindow:: | ||
QWindow(parent): | QWindow(parent): | ||
- | m_context(0), | + | m_context(0) |
- | | + | |
setSurfaceType(QWindow:: | setSurfaceType(QWindow:: | ||
+ | | ||
} | } | ||
- | 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 iene chiamato ogni volta che cambia la visibilità della nostra superficie. Se è visibile, | + | |
void GLWindow:: | void GLWindow:: | ||
Linea 66: | 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 | + | Il metodo resizeEvent() viene chiamato |
void GLWindow:: | void GLWindow:: | ||
- | glViewport(0, | + | |
+ | | ||
| | ||
if (isExposed()) | if (isExposed()) | ||
Linea 77: | Linea 85: | ||
} | } | ||
- | ===== ... e aggiungiamo un po' di Opengl | + | ===== Gli shader |
- | I metodi che vedremo ora, sia come denominazione che come struttura che come compiti, | + | Alla base della programmazione OpenGL moderna ci sono gli [[http:// |
- | Analizziamo prima il metodo paint(), | + | 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 | ||
void GLWindow:: | void GLWindow:: | ||
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 96: | Linea 112: | ||
needsInitialize = true; | needsInitialize = true; | ||
} | } | ||
+ | | ||
m_context-> | m_context-> | ||
+ | | ||
if(needsInitialize) { | if(needsInitialize) { | ||
initialize(); | initialize(); | ||
} | } | ||
- | + | | |
- | if (!m_device) | + | |
- | m_device = new QOpenGLPaintDevice; | + | |
- | + | ||
- | m_device-> | + | |
- | | + | |
paintGL(); | paintGL(); | ||
+ | | ||
m_context-> | m_context-> | ||
} | } | ||
- | Il metodo initialize() | + | Una volta sola, prima che avvenga il primo disegno, paint() inizializziamo m_context chiamando il metodo initialize() che imposta il contesto OpenGL |
void GLWindow:: | void GLWindow:: | ||
Linea 125: | Linea 136: | ||
glBlendFunc (GL_SRC_ALPHA, | glBlendFunc (GL_SRC_ALPHA, | ||
| | ||
- | m_posAttr = m_d-> | + | m_posAttr = m_program-> |
- | m_colAttr = m_d-> | + | m_colAttr = m_program-> |
- | m_matrixUniform = m_d-> | + | m_matrixUniform = m_program-> |
} | } | ||
- | 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 138: | 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_d-> | + | if (!m_program-> |
close(); | close(); | ||
- | | + | |
// Compile lo shader fragment | // Compile lo shader fragment | ||
- | if (!m_d-> | + | if (!m_program-> |
close(); | close(); | ||
+ | | ||
// Linka shaders | // Linka shaders | ||
- | if (!m_d-> | + | if (!m_program-> |
close(); | close(); | ||
} | } | ||
Linea 175: | Linea 186: | ||
- | Ed infine i comandi per disegnare il nostro triangolo | + | Ed infine |
void GLWindow:: | void GLWindow:: | ||
- | | + | |
- | + | ||
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); | ||
- | | + | |
- | | + | |
- | + | ||
QMatrix4x4 matrix; | QMatrix4x4 matrix; | ||
matrix.perspective(60, | matrix.perspective(60, | ||
matrix.translate(0, | matrix.translate(0, | ||
- | | + | |
- | | + | |
- | + | ||
- | | + | |
- | 0.0f, 0.707f, | + | |
- | -0.5f, -0.5f, | + | |
- | 0.5f, -0.5f | + | |
}; | }; | ||
- | | + | |
- | 1.0f, 0.0f, 0.0f, | + | m_program-> |
- | 0.0f, 1.0f, 0.0f, | + | m_program-> |
- | 0.0f, 0.0f, 1.0f | + | |
+ | QVector3D | ||
+ | | ||
+ | | ||
+ | | ||
}; | }; | ||
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | glEnableVertexAttribArray(1); | + | |
- | | + | |
glDrawArrays(GL_TRIANGLES, | glDrawArrays(GL_TRIANGLES, | ||
- | + | | |
- | glDisableVertexAttribArray(1); | + | |
- | glDisableVertexAttribArray(0); | + | |
- | | + | |
m_program-> | m_program-> | ||
} | } | ||
- | Per visualizzare quello che abbiamo creato ci serve un file mail.cpp molto semplice | + | Per visualizzare quello che abbiamo creato ci serve un file main.cpp |
#include < | #include < | ||
Linea 223: | 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 235: | Linea 244: | ||
{{ : | {{ : | ||
- | Tutti i file necessari sono contenuati | + | Tutti i file necessari sono contenuti |
- | ===== Per approfondire | + | ===== Articoli correlati ===== |
+ | |||
+ | <blog related> | ||
+ | blog | ||
+ | tag ' | ||
+ | </ | ||
+ | |||
+ | ===== Per approfondire ===== | ||
+ | |||
+ | ==== opengl | ||
* [[http:// | * [[http:// | ||
- | * [[http:// | + | * [[http:// |
* [[http:// | * [[http:// | ||
+ | * [[http:// | ||
+ | |||
+ | ==== Qt e opengl ==== | ||
+ | |||
* [[http:// | * [[http:// | ||
+ | * [[http:// | ||
+ | |||
+ | ===== Potrebbero interessarti anche... ===== | ||
+ | |||
+ | Un elenco degli altri articoli disponibili sull' | ||
+ | <blog related> | ||
+ | </ | ||
tutorial_qt/opengl_01.txt · Ultima modifica: 2015/05/05 14:43 da mickele