M2 - Images

TP 1 - Affichage efficace



mise à jour gKit b69 17/12/2010




Prise en main

installez gKit et parcourez la doc.

Ce qu'il faut retenir : la classe gk::App permet de construire une application openGL, elle crée une fenetre et un contexte de rendu openGL et permet également de gérer les évènements claviers, souris, joysticks, etc facilement.

Pour construire une application, il faut dériver la classe gk::App et redéfinir les méthodes suivantes :
L'application minimale que vous pouvez modifier pour réaliser le tp se trouve dans glmain.cpp.

Contrôle au clavier, souris, joystick :

La fonction key( code ) renvoie l'état d'une touche : 1 si la touche est appuyée, 0 si la touche est relachée.
Cette fonction renvoie une référence sur la valeur, ce qui permet de la modifier, par exemple, key('a')= 0.

Pour tester l'état d'une touche comme les fléches de directions, il suffit d'utiliser les codes SDLK_xxx correspondants. Il est également possible de connaître l'état des touches spéciales : shift, control, etc : SDL_GetModState( ), les codes SDLK_xxx associés sont en bas de la page des codes SDLK_xxx. Il est également possible de modifier l'état de ces touches spéciales avec SDL_SetModState( ).

La gestion de la souris se fait directement en utilisant les fonctions de libSDL : SDL_GetMouseState( ), SDL_GetRelativeMouseState( ).

Le manuel de programmation complet de libSDL est également disponible.


Partie 1 : Affichage avec vertex buffer / index buffer.

Les vertex et index buffers seront donc crées et initialisés dans la méthode init( ).
Quelques méthodes utiles de gk::Mesh :
Si les normales ne sont pas disponibles, il est possible de les calculer avec la méthode gk::Mesh::buildNormals( ).
En résumé, pour charger un objet et récupérer ses normales :

gk::Mesh *mesh= gk:MeshIO::read("xxx.obj");
if(mesh->normalCount() != mesh->positionCount())
    mesh->buildNormals();


Autre remarque : utilisation de gk::Transform pour construire les matrices de transformation openGL.

Utilisez la méthode gk::Transform::matrix( ) pour obtenir la matrice directe et gk::Transform::inverseMatrix( ) pour la matrice inverse. Ne pas oublier qu' openGL utilise une convention différente pour représenter ses matrices, il faut impérativement utiliser glLoadTransposeMatrixf( ), et glMultTransposeMatrixf( ).

exemple :
glMatrixMode(GL_PROJECTION);
glLoadTransposeMatrixf( gk::Perspective(50.f, 1.f, 1.f, 1000.f).matrix() );


exercice :

Chargez un objet et affichez-le en utilisant un vertex buffer et un index buffer.
Structurez correctement votre code, en utilisant les methodes init( ), quit( ) et draw( ).

La méthode draw( ) commence par redimensionner et effacer le buffer de dessin. Ensuite, décrire la projection de la caméra, puis pour chaque objet à afficher : décrire la matrice local vers camera (modelview), et affichez l'objet.

Derniere remarque : pensez à désactiver tous les états openGL modifiés.


Partie 2 : Afficher plusieurs objets.

exercice 1 : description hiérarchique de scène.

Utilisez directement la classe gk::Scene et dérivez gk::ISceneObject pour afficher un ensemble d'objets.

exercice 2 : visibilité.

Testez la visibilité de la boite englobante d'un objet avant de l'afficher.

exercice 3 : visibilité hiérarchique.

Construisez une scène étendue composée d'un grand nombre d'objets : une grille de bigguy, par exemple.
Dans ce cas, la camera ne peut observer qu'un nombre limité d'objets, comment les identifier rapidement ?

Proposez une solution simple utilisant la classe gk::Scene.
Proposez une solution plus efficace, a priori basée sur une hiérarchie, pourquoi la classe gk::Scene n'est elle pas vraiment adaptée ? existe-t-il une modification simple ?

exercice 4 : minimiser les changements d'états == économiser openGL.

Lisez la présentation gdc 2003 : "batch, batch, batch"
Quelle conclusion peut on en tirer ?
Quelles conséquences sur la manière de représenter un objet et d'afficher un groupe d'objets ?

Proposez une solution simple mais plus efficace que la version actuelle.





Annexe : shadercc

    Dans l'archive gKit_b69 se trouve un programme shdercc, compilez-le et copiez le à la racine de votre compte, ou dans un repértoire local/bin.
 
    Pour compiler vos shaders et vérifier qu'il n'y a pas d'erreurs de syntaxe et de casts avant d'éxécuter votre programme complet :

        ~/repertoire/shadercc -c shader.vsl

    Pensez à ajouter #version 120  (pour opengl2) ou #version 330 (pour opengl 3.3) au début du source des shaders pour détecter le maximum d'erreurs / warnings. shadercc affiche également la ligne du source correspondant à l'erreur détectée en utilisant un format d'erreur standard, résultat, il s'intègre facilement à un éditeur ...

    Démonstration :

intégration shadercc avec SciTE


Intégration de shadercc dans SciTE

    Ouvrez les propriétés utilisateur : menu 'Options', option 'Open User Options File', copiez - collez les lignes suivantes :

# extensions de fichiers reconnues
file.patterns.cpp=*.c;*.cpp;*.cs;*.h;*.hpp;*.fsl;*.vsl;*.gsl;*.esl;*.csl

# compilation des shaders glsl
shadercc=shadercc -c $(FileNameExt)
command.compile.*.vsl=$(shadercc)
command.compile.*.gsl=$(shadercc)
command.compile.*.csl=$(shadercc)
command.compile.*.esl=$(shadercc)
command.compile.*.fsl=$(shadercc)

    Enregistrez le fichier, fermez SciTE, rouvrez-le et éditez un shader (utilisez une extension .v?? pour un vertex shader et .f?? pour un fragment shader). Dans le menu Tools, l'option Compile est maintenant disponible (Ctrl-F7). Appuyez ensuite sur F4 pour visualiser les différentes erreurs (éventuelles, bien sur !).

Intégration de shadercc dans Gedit

    ajoutez le plug-in "external tools" à gedit, menu edit, preferences, plugins.
    ouvrez le menu Tools / External Tools, option Manage external tool.
    creez un nouvel outil (bouton +), appelez-le shadercc, il ne reste plus qu'à le configurer.
    copiez-collez le script suivant dans la zone commande :

#!/bin/sh
$HOME/repertoire/shadercc -c $GEDIT_CURRENT_DOCUMENT_NAME

et sélectionnez les options d'exécution :
    input : current document,
    ouput : display in bottom pane,
    applicability : all documents


capture configuration gedit


    lorsqu'une erreur est affichée dans la console ou s'exécute shadercc, cliquez-dessus pour éditer la ligne correspondante dans vos sources.