1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117
| WinGL::WinGL( const QGLFormat& format, QWidget* parent )
: QGLWidget( format, parent ),
m_vrtxBuf( QGLBuffer::VertexBuffer )
{
this->setGeometry(100,100,640,480);
// Défini un triangle
pts[0] = -0.5f; pts[1] = -0.5f; pts[2] = 0.0f; pts[3] = 1.0f;
pts[4] = 0.5f; pts[5] = -0.5f; pts[6] = 0.0f; pts[7] = 1.0f;
pts[8] = 0.0f; pts[9] = 0.5f; pts[10] = 0.0f; pts[11] = 1.0f;
// Orientation et position de départ camera
xrot = 0; // Une valeur différente donne un résultat faux
yrot = 0; // Une valeur différente donne un résultat faux
zrot = 10;
dist = -1; // Une valeur différente donne un résultat faux
}
void WinGL::initializeGL(){
qDebug();
QGLFormat glFormat = QGLWidget::format();
if (!glFormat.sampleBuffers()) qDebug() << "Ne peut pas activer les buffers";
// Couleur d'effacement
glClearColor(0.0f, 0.0f, 0.2f, 1.0f);
// Chargement vertex shader
bool ret = false;
ret = m_shadProg.addShaderFromSourceFile(QGLShader::Vertex, ":/vertex.shad");
if (!ret) qDebug() << "Vertex shader : " << m_shadProg.log();
// Chargement fragment shader
ret = m_shadProg.addShaderFromSourceFile(QGLShader::Fragment, ":/fragment.shad");
if (!ret) qDebug() << "Fragment shader : " << m_shadProg.log();
// Liaison des shader au programme
ret = m_shadProg.link();
if (!ret) qDebug() << "Echec liaison shadProg : " << m_shadProg.log();
// Génère un identifiant sur les matrices de projection
m_matLoc = m_shadProg.uniformLocation("matLoc");
if (m_matLoc == -1) qDebug() << "Echec identifiant matrice !";
// Création d'un vertex buffer
ret = m_vrtxBuf.create();
if (!ret) qDebug() << "Echec création buffer !";
// Attache le vertex buffer au context GL
ret = m_vrtxBuf.bind();
if (!ret) qDebug() << "Echec contextualisation du vertex buffer !";
// Affecte le tableau de points au vertex buffer
m_vrtxBuf.allocate(pts, 12 * sizeof(float));
// Attache le programme au context GL
ret = m_shadProg.bind();
if (!ret) qDebug() << "Echec contextualisation du programme !";
// Assigne le vertex buffer au programme
m_shadProg.setAttributeBuffer("vrtx", GL_FLOAT, 0, 4);
// Active le vertex buffer pour le programme
m_shadProg.enableAttributeArray("vrtx");
}
void WinGL::resizeGL(int w, int h){
// Met à jour la taille de la fenêtre
glViewport( 0, 0, w, qMax( h, 1 ) );
}
void WinGL::paintGL(){
// Efface les buffers
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glEnable(GL_DEPTH_TEST);
glPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
// Renseigne la matrice de projection
QMatrix4x4 proj;
proj.perspective(60.0, this->width() / this->height(), 0.1, 100.0);
// Renseigne la matrice du modèle
QMatrix4x4 model;
model.rotate(xrot, 1.0, 0.0, 0.0);
model.rotate(yrot, 0.0, 1.0, 0.0);
model.rotate(zrot, 0.0, 0.0, 1.0);
// Renseigne la matrice de vue
QMatrix4x4 view;
view.translate(0.0, 0.0, dist);
QMatrix4x4 result;
result = proj * view * model;
// Calcul du point 2D correspondant au triangle affiché
QVector4D ec1 = result * QVector4D(pts[0], pts[1], pts[2], pts[3]);
// Conversion en pixel pour controler
int xpx1 = (ec1.x() * this->width() / 2) + (this->width() / 2);
int ypx1 = (this->height() / 2) - (ec1.y() * this->height() / 2);
// idem point 2
QVector4D ec2 = result * QVector4D(pts[4], pts[5], pts[6], pts[7]);
int xpx2 = (ec2.x() * this->width() / 2) + (this->width() / 2);
int ypx2 = (this->height() / 2) - (ec2.y() * this->height() / 2);
// idem point 3
QVector4D ec3 = result * QVector4D(pts[8], pts[9], pts[10], pts[11]);
int xpx3 = (ec3.x() * this->width() / 2) + (this->width() / 2);
int ypx3 = (this->height() / 2) - (ec3.y() * this->height() / 2);
qDebug() << "pt1(" << xpx1 << "," << ypx1 << ")" << " pt2(" << xpx2 << "," << ypx2 << ")" << " pt3(" << xpx3 << "," << ypx3 << ")";
// Assigne la matrice résultante au programme
m_shadProg.setUniformValue(m_matLoc, result);
// Affiche le triangle
glDrawArrays(GL_TRIANGLES, 0, m_vrtxBuf.size());
glDisableClientState(GL_VERTEX_ARRAY);
} |
Partager