Page MenuHomec4science

glwidget.cc
No OneTemporary

File Metadata

Created
Wed, Dec 4, 23:27

glwidget.cc

#include <QMatrix4x4>
#include "glwidget.h"
#include "vertex_shader.h" // Identifiants Qt de nos différents attributs
// ======================================================================
void GLWidget::initializeGL()
{
/* Initialise notre vue OpenGL.
* Dans cet exemple, nous créons et activons notre shader.
*
* En raison du contenu des fichiers *.glsl, le shader de cet exemple
* NE permet QUE de dessiner des primitives colorées
* (pas de textures, brouillard, reflets de la lumière ou autres).
*
* Il est séparé en deux parties VERTEX et FRAGMENT.
* Le VERTEX :
* - récupère pour chaque sommet des primitives de couleur (dans
* l'attribut couleur) et de position (dans l'attribut sommet)
* - multiplie l'attribut sommet par les matrices 'vue_modele' et
* 'projection' et donne le résultat à OpenGL
* - passe la couleur au shader FRAGMENT.
*
* Le FRAGMENT :
* - applique la couleur qu'on lui donne
*/
prog.addShaderFromSourceFile(QGLShader::Vertex, ":/vertex_shader.glsl");
prog.addShaderFromSourceFile(QGLShader::Fragment, ":/fragment_shader.glsl");
/* Identifie les deux attributs du shader de cet exemple
* (voir vertex_shader.glsl).
*
* L'attribut identifié par 0 est particulier, il permet d'envoyer un
* nouveau "point" à OpenGL
*
* C'est pourquoi il devra obligatoirement être spécifié et en dernier
* (après la couleur dans cet exemple, voir plus bas).
*/
prog.bindAttributeLocation("sommet", SommetId);
prog.bindAttributeLocation("couleur", CouleurId);
// Compilation du shader OpenGL
prog.link();
// Activation du shader
prog.bind();
/* Activation du "Test de profondeur" et du "Back-face culling"
* Le Test de profondeur permet de dessiner un objet à l'arrière-plan
* partielement caché par d'autres objets.
*
* Le Back-face culling consiste à ne dessiner que les face avec ordre
* de déclaration dans le sens trigonométrique.
*/
glEnable(GL_DEPTH_TEST);
glEnable(GL_CULL_FACE);
}
// ======================================================================
void GLWidget::resizeGL(int width, int height)
{
/* On commence par dire sur quelle partie de la
* fenêtre OpenGL doit dessiner.
* Ici on lui demande de dessiner sur toute la fenêtre.
*/
glViewport(0, 0, width, height);
/* Puis on modifie la matrice de projection du shader.
* Pour ce faire on crée une matrice identité (constructeur
* par défaut), on la multiplie par la droite par une matrice
* de perspective.
* Plus de détail sur cette matrice
* http://www.songho.ca/opengl/gl_projectionmatrix.html
* Puis on upload la matrice sur le shader avec la méthode
* setUniformValue
*/
QMatrix4x4 matrice;
matrice.perspective(70.0, qreal(width) / qreal(height ? height : 1.0), 1e-3, 1e5);
prog.setUniformValue("projection", matrice);
}
// ======================================================================
void GLWidget::paintGL()
{
// On commence par effacer ce qu'il y avait à l'écran
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
/* Puis on crée une matrice identitée (constructeur par défaut)
* que l'on multiplie à droite par une matrice de translation
* avec comme vecteur de translation (0,0,-2).
* Finalement, on envoie cette matrice au shader.
*
* Sur notre shader (voir les sources .glsl), il y a deux matrices
* projection et vue_modele.
* Les sommets dessinés seront multipliés par la matrice vue_modele
* puis par projection avant d'être dessiné sur l'écran.
*/
QMatrix4x4 matrice;
matrice.translate(0.0, 0.0, -2.0);
prog.setUniformValue("vue_modele", matrice);
// On dessine un joli triangle coloré
glBegin(GL_TRIANGLES);
prog.setAttributeValue(CouleurId, 1.0, 0.0, 0.0); // rouge
prog.setAttributeValue(SommetId, 0.0, 0.0, 0.0);
prog.setAttributeValue(CouleurId, 0.0, 1.0, 0.0); // vert
prog.setAttributeValue(SommetId, 1.0, 0.0, 0.0);
prog.setAttributeValue(CouleurId, 0.0, 0.0, 1.0); // bleu
prog.setAttributeValue(SommetId, 1.0, 1.0, 0.0);
glEnd();
}

Event Timeline