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 17:50] mickele [Partiamo da QWindow...] |
tutorial_qt:opengl_01 [2015/05/05 14:43] (versione attuale) 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 | + | ===== Gli shader ===== |
+ | |||
+ | Alla base della programmazione OpenGL moderna ci sono gli [[http://it.wikipedia.org/ | ||
+ | |||
+ | 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 | ||
+ | |||
+ | Nella versione 5 delle Qt creiamo gli shader usando la classe [[http:// | ||
+ | |||
+ | ===== Opengl | ||
- | Passiamo | + | I metodi che vedremo |
- | I metodi che vedremo ora, sia come denomiinazione che come struttura e compiti possono cambiare, perciò se ritenete | + | Analizziamo prima il metodo paint(), il cuore delle operazioni |
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-> | ||
} | } | ||
- | Alcuni comandi devono essere eseguiti una sola volta prima del primo disegno; li mettiamo nel metodo initialize() | + | Una volta sola, prima che avvenga il primo disegno, paint() inizializziamo m_context chiamando il metodo initialize() |
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-> |
} | } | ||
- | Effettuaimo l' | + | Il metodo initShaders() |
+ | * creiamo | ||
+ | * associamo | ||
+ | * linkiamo il codice | ||
void GLWindow:: | void GLWindow:: | ||
m_context-> | m_context-> | ||
- | + | | |
- | // Sovrasvcrive la codifica fintantoche' | + | |
- | setlocale(LC_NUMERIC, | + | |
- | | + | |
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(); | ||
- | | ||
- | // Ripristina la codifica del sistema | ||
- | setlocale(LC_ALL, | ||
} | } | ||
Linea 178: | 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, | ||
+ | | ||
+ | m_program-> | ||
+ | } | ||
+ | |||
+ | Per visualizzare quello che abbiamo creato ci serve un file main.cpp | ||
+ | |||
+ | #include < | ||
| | ||
- | glDisableVertexAttribArray(1); | + | #include " |
- | glDisableVertexAttribArray(0); | + | |
| | ||
- | m_program-> | + | int main(int argc, char **argv) { |
+ | QGuiApplication app(argc, argv); | ||
+ | |||
+ | GLWindow window; | ||
+ | window.resize(640, | ||
+ | window.show(); | ||
+ | |||
+ | return app.exec(); | ||
} | } | ||
Linea 222: | 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.1379173849.txt.gz · Ultima modifica: 2013/09/14 17:50 da mickele