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
|
// Création de la Cubemap dans initializeGL()
void loadTextures()
{
...
QImage posx = QImage("xpos.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
QImage negx = QImage("xneg.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
QImage posy = QImage("ypos.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
QImage negy = QImage("yneg.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
QImage posz = QImage("zpos.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
QImage negz = QImage("zneg.png").mirrored().convertToFormat(QImage::Format_RGBA8888);
m_skybox = new QOpenGLTexture(QOpenGLTexture::TargetCubeMap);
if (!m_skybox->isCreated())
m_skybox->create()
glBindTexture(GL_TEXTURE_CUBE_MAP, m_skybox->textureId());
m_skybox->setFormat(QOpenGLTexture::RGBAFormat);
m_skybox->setSize(posx.width(), posx.height(), posx.depth());
m_skybox->generateMipMaps();
m_skybox->allocateStorage();
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapPositiveX, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)posx.constBits());
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapNegativeX, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)negx.constBits());
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapPositiveY, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)posy.constBits());
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapNegativeY, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)negy.constBits());
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapPositiveZ, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)posz.constBits());
m_skybox->setData(0, 0, QOpenGLTexture::CubeMapNegativeZ, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, (const void*)negz.constBits());
m_skybox->setWrapMode(QOpenGLTexture::ClampToEdge);
qDebug() << QString("Nombre de faces de m_skybox: " + QString::number(m_skybox->faces())); // Bizarre, le nombre de faces est 1 et pas 6...
}
// Affichage dans paintGL()
void Widget::paintGL()
{
// Clear color and depth buffer
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
// Rendering skybox
glDisable(GL_DEPTH_TEST);
glBindTexture(GL_TEXTURE_CUBE_MAP, m_skybox->textureId());
m_skyboxProg->bind();
QMatrix4x4 mv; // On va envoyer la matrive ModelView mais sans les translations
mv.lookAt(QVector3D(0, 0, 0), m_target-m_eye, QVector3D(0, 1, 0));
m_skyboxProg->setUniformValue("mv_matrix", mv);
m_skyboxProg->setUniformValue("proj_matrix", m_projection);
m_skyboxProg->setUniformValue("skybox", 0); // 0 pour Texture Unit 0
m_SBvao->bind();
m_skybox->bind(0); // on bind à Texture Unit 0
glDrawArrays(GL_TRIANGLES, 0, 9*12);
m_skybox->release();
m_SBvao->release();
m_skyboxProg->release();
glEnable(GL_DEPTH_TEST);
...
}
// Vertex Shader
uniform mat4 mv_matrix; // Même matrice ModelView que celle utilisée pour afficher le reste de la scène, mais qui ne contient pas les translations effectuées pour que la skybox reste centrée sur la caméra
uniform mat4 proj_matrix;
attribute vec4 a_position;
varying vec3 v_texcoord;
void main()
{
// La position finale du vertex aura subi les rotations de la caméra mais pas les translations:
gl_Position = proj_matrix * mv_matrix * a_position;
// On passe au fragment shader le vertex tel quel
v_texcoord = a_position.xyz;
}
// Fragment Shader
uniform samplerCube skybox;
varying vec3 v_texcoord;
void main()
{
// Les coordonnées inchangées du vertex (v_texcoord)sont utilisées pour trouver sa couleur dans le cubemap (skybox)
gl_FragColor = textureCube(skybox, v_texcoord);
} |
Partager