Vous êtes nouveau sur Developpez.com ? Créez votre compte ou connectez-vous afin de pouvoir participer !

Vous devez avoir un compte Developpez.com et être connecté pour pouvoir participer aux discussions.

Vous n'avez pas encore de compte Developpez.com ? Créez-en un en quelques instants, c'est entièrement gratuit !

Si vous disposez déjà d'un compte et qu'il est bien activé, connectez-vous à l'aide du formulaire ci-dessous.

Identifiez-vous
Identifiant
Mot de passe
Mot de passe oublié ?
Créer un compte

L'inscription est gratuite et ne vous prendra que quelques instants !

Je m'inscris !

En direct des Qt DevDays 2012
Détails techniques sur l'utilisation d'OpenGL moderne dans Qt 5

Le , par LittleWhite

0PARTAGES

4  0 
Il est vrai qu'hier je n'ai pas donné beaucoup d'informations techniques. Maintenant que j'ai un peu plus de temps, je peux vous expliquer les nouveautés dans la création d'applications OpenGL de Qt 5.

Initialisation d'OpenGL dans Qt 5

Tout d'abord, si vous voulez faire une fenêtre utilisant OpenGL, vous n'avez plus besoin d'hériter votre classe de QGLWidget mais simplement de la nouvelle classe QWindow (qui remplace QWidget). Lors de sa construction, vous devriez appeler la fonction setSurfaceType() avec comme paramètre OpenGLSurface afin d'avoir une fenêtre OpenGL. Voici l'exemple d'une classe Window qui hérite de QWindow afin de mettre en place une fenêtre OpenGL :
Code : Sélectionner tout
1
2
3
4
5
6
7
Window::Window( QScreen* screen )
    	: QWindow( screen )
{
    // Indique à Qt que nous allons utiliser OpenGL avec cette fenêtre
    setSurfaceType(OpenGLSurface);

    ...
(Note : QWindow hérite de QSurface)

Toutefois, nous n'avons pas encore configuré OpenGL. Pour cela, nous utilisons deux classes :
  • QSurfaceFormat
  • QOpenGLContext


Sean Harmer compare QSurfaceFormat à un papier et QOpenGLContext à un crayon.

Plus précisément, QSurfaceFormat permet de définir la version d'OpenGL (setMajorVersion() et setMinorVersion()), le profile (core ou deprecated) à utiliser (setProtile()), mais aussi le niveau de multisampling (anti-aliasing), la taille du buffer de profondeur, ...
Code : Sélectionner tout
1
2
3
4
5
6
7
// Spécifie le format que nous voulons
QSurfaceFormat format;
format.setDepthBufferSize( 24 );
format.setMajorVersion( 3 );
format.setMinorVersion( 3 );
format.setSamples( 4 );
format.setProfile( QSurfaceFormat::CoreProfile );
Une fois le format configuré, il faut l'indiquer au QOpenGLContext :
Code : Sélectionner tout
1
2
3
4
// Créer un contexte OpenGL
m_context = new QOpenGLContext;
m_context->setFormat( format );
m_context->create();
Le contexte doit par la suite être passé à une scène (classe héritant de QAbstractScene).

Chaque fois que vous devez agir sur ce contexte OpenGL (initialisation d'OpenGL, mis à jour des buffers, affichage, ...) il faut rendre le context actif :
Code : Sélectionner tout
m_context->makeCurrent(this);
(makeCurrent() accepte un paramètre de type pointeur sur QSurface).

(Note : un contexte ne peut être actif que dans un thread à la fois)

Pour l'affichage, nous pouvons imaginer le code suivant :
Code : Sélectionner tout
1
2
3
4
5
6
7
8
9
10
11
void Window::paintGL()
{
    // Rend le contexte actif
    m_context->makeCurrent( this );

    // Effectue le rendu (dans le back buffer)
    m_scene->render();

    // Échange les front/back buffers
    m_context->swapBuffers( this );
}
Par défaut, Qt utilise du double buffering.

Gestion des extensions

La gestion a changé dans cette nouvelle version de Qt. Tout d'abord, la classe QOpenGLContext vous permet de récupérer une liste d'extensions sous la forme d'un QSet<QByteArray> avec la méthode extensions(). De plus, cette même classe intègre une seconde fonction : hasExtension() qui retourne un boolean indiquant si l'extension est supportée par la machine ou non.
Bien sur, la fonction getProcAddress() permettant de récupérer les pointeurs de fonctions sur les fonctions des extensions OpenGL est toujours présente. Mais son usage a été limité car elle était source de problèmes. Pour remplacer cet ancien mécanisme, la classe QOpenGLContext expose une fonction functions() qui retourne un QOpenGLFunctions*. Cette dernière contient des méthodes pour appeler les fonctions OpenGL.
Par contre, OpenGLFunctions ne fournit pas toutes les fonctions disponibles dans OpenGL (surtout si une nouvelle spécification OpenGL est créée), ni les fonctions pour toutes les extensions.
De plus, Qt 5 propose des factory de fonctions appelées QOpenGLVersionFunctionsFactory (implémenté sous la forme d'un singleton). Cette classe aurait dû être intégrée directement dans QOpenGLContext, mais elle n'était pas prête pour Qt 5.0. Elle le sera dans Qt 5.1.

L'avantage est que la classe ajoute des vérifications au moment de la compilation.

Le code d'exemple utilisé pendant la formation est disponible : http://qt.developpez.com/evenement/2.../dd-opengl.zip

Une erreur dans cette actualité ? Signalez-le nous !

Avatar de froggy25
Membre à l'essai https://www.developpez.com
Le 14/11/2012 à 17:15
Merci pour ces compte-rendus, bon boulot

*a de la lecture*
0  0