Developpez.com

Plus de 2 000 forums
et jusqu'à 5 000 nouveaux messages par jour

Tutoriel Irrlicht 2

Carte Quake 3

Ce tutoriel est une traduction de l'anglais des tutoriels officiels d'Irrlicht.

Il explique comment charger une carte Quake 3, créer un SceneNode(1) pour optimiser la vitesse de rendu et comment créer une caméra contrôlée par l'utilisateur.

Avant de lire ce tutoriel, vous devriez lire le premier tutoriel « Hello World » si vous ne l'avez pas encore fait.

Commentez Donner une note à l'article (5)

Article lu   fois.

Les deux auteur et traducteur

Liens sociaux

Viadeo Twitter Facebook Share on Google+   

I. Configuration du projet

Image non disponible

Commençons comme l'exemple « Hello World » : nous incluons l'en-tête Irrlicht et un fichier supplémentaire pour être capable de demander à l'utilisateur un type de pilote via la console.

 
Sélectionnez
#include <irrlicht.h>
#include <iostream>

Comme déjà écrit dans l'exemple « Hello World », dans le moteur Irrlicht tout peut être trouvé dans le namespace « irr ». Pour avoir « irr:: » devant tous les noms de classes, nous disons au compilateur d'utiliser ce namespace dès maintenant et nous n'aurons plus à écrire « irr:: ». Il y a cinq autres sous-namespaces : « core », « scene », « video », « io » et « gui ». Contrairement à l'exemple « Hello World », nous n'utiliserons pas « using namespace » pour ces cinq namespaces, car ainsi, nous pourrons connaître l'emplacement de ces éléments. Mais si vous voulez, vous pouvez aussi inclure ces namespaces comme dans le précédent exemple.

 
Sélectionnez
using namespace irr;

Une fois encore, pour être capable d'utiliser le fichier Irrlicht.DLL nous devons le lier avec Irrlicht.lib. Nous pouvons mettre ces options dans la configuration du projet, mais pour le faire plus simplement, nous pouvons utiliser un « pragma comment lib » :

 
Sélectionnez
#ifdef _MSC_VER
#pragma comment(lib, "Irrlicht.lib")
#endif

Bon, commençons. Une fois encore, nous utilisons la méthode main() et non WinMain().

 
Sélectionnez
int main()
{

II. Choix du pilote vidéo

Comme dans l'exemple « Hello World », nous créons un IrrlichtDevice avec createDevice().

Mais maintenant nous demandons à l'utilisateur de choisir le pilote vidéo à utiliser. Le programme peut être lent à dessiner une grande carte Quake, mais juste pour tester nous rendons cette décision possible. Au lieu de copier tout ce code dans votre application, vous pouvez simplement inclure driverChoice.h du dossier « include » d'Irrlicht. La fonction driverChoiceConsole() fait exactement la même chose.

 
Sélectionnez
    // demande à l'utilisateur un driver à utiliser

    video::E_DRIVER_TYPE driverType;

    printf("Please select the driver you want for this example:\n"\
        " (a) OpenGL 1.5\n (b) Direct3D 9.0c\n (c) Direct3D 8.1\n"\
        " (d) Burning's Software Renderer\n (e) Software Renderer\n"\
        " (f) NullDevice\n (otherKey) exit\n\n");

    char i;
    std::cin >> i;

    switch(i)
    {
        case 'a': driverType = video::EDT_OPENGL;   break;
        case 'b': driverType = video::EDT_DIRECT3D9;break;
        case 'c': driverType = video::EDT_DIRECT3D8;break;
        case 'd': driverType = video::EDT_BURNINGSVIDEO;break;
        case 'e': driverType = video::EDT_SOFTWARE; break;
        case 'f': driverType = video::EDT_NULL;     break;
        default: return 1;
    }

    // créé le système et sort si la création échoue.

    IrrlichtDevice *device =
        createDevice(driverType, core::dimension2d<u32>(640, 480));

    if (device == 0)
        return 1; // on ne peut pas créer le driver sélectionné.

Récupérons un pointeur sur le pilote vidéo, ainsi nous n'aurons pas à appeler à chaque fois Image non disponibleirr::IrrlichtDevice::getVideoDriver() et irr::IrrlichtDevice::getSceneManager().

 
Sélectionnez
    video::IVideoDriver* driver = device->getVideoDriver();
    scene::ISceneManager* smgr = device->getSceneManager();

III. Chargement et affichage de la carte

Pour afficher la carte Quake 3, nous devons d'abord la charger. Les cartes Quake 3 sont stockées dans des fichiers .pk3 qui ne sont autres que des fichiers .zip. Nous ajoutons alors le fichier .pk3 à notre irr::io::IFileSystem. Après l'avoir ajouté, nous sommes capables de lire les fichiers de cette archive comme s'ils étaient directement stockés dans le disque.

 
Sélectionnez
    device->getFileSystem()->addFileArchive("../../media/map-20kdm2.pk3");

Maintenant nous pouvons charger les meshs en appelant Image non disponibleirr::scene::ISceneManager::getMesh(). Nous obtenons un pointeur sur un Image non disponibleirr::scene::IAnimatedMesh. Comme vous pouvez le savoir, les cartes Quake 3 ne sont pas réellement animées, elles possèdent seulement une très grande partie de géométrie statique avec quelques matériels attachés. L'IAnimatedMesh est donc constitué d'une seule image, nous obtenons donc la « première image » de « l'animation » qui est notre carte Quake et créons un nœud de l'octree(2) pour la scène en utilisant Image non disponibleirr::scene::ISceneManager::addOctreeSceneNode(). L'octree optimise un peu la scène en essayant de dessiner seulement la géométrie visible. Une alternative à l'octree pourrait être un Image non disponibleirr::scene::IMeshSceneNode qui dessinera toujours entièrement la géométrie du mesh sans optimisation. Essayons-le, utilisez Image non disponibleirr::scene::ISceneManager::addMeshSceneNode() à la place d'addOctreeSceneNode() et comparez-les primitives(3) dessinées par le pilote vidéo. (Il y a une méthode Image non disponibleirr::video::IVideoDriver::getPrimitiveCountDrawn() dans la classe irr::video::IVideoDriver). Notez que cette optimisation avec l'octree est utile seulement quand on dessine des grands meshs constitués de nombreuse géométrie.

 
Sélectionnez
    scene::IAnimatedMesh* mesh = smgr->getMesh("20kdm2.bsp");
    scene::ISceneNode* node = 0;

    if (mesh)
        node = smgr->addOctreeSceneNode(mesh->getMesh(0), 0, -1, 1024);
//      node = smgr->addMeshSceneNode(mesh->getMesh(0));

Parce que la carte n'était pas modélisée à l'origine (0,0,0) nous la déplaçons légèrement. Ceci est fait au niveau de Image non disponibleirr::scene::ISceneNode en utilisant les méthodes irr::scene::ISceneNode::setPosition() (dans notre cas), irr::scene::ISceneNode::setRotation(), et irr::scene::ISceneNode::setScale().

 
Sélectionnez
  if (node)
        node->setPosition(core::vector3df(-1300,-144,-1249));

IV. Création de la caméra

Maintenant, nous avons juste besoin d'une caméra pour regarder la carte Quake 3. Nous voulons créer une caméra contrôlée par l'utilisateur. Il y a plusieurs caméras disponibles dans le moteur Irrlicht. Par exemple, la « MayaCamera » peut être contrôlée comme une caméra Maya : rotation en pressant le bouton droit de la souris, zoom avec deux boutons pressés, translation en pressant le bouton gauche. Ceci peut être créé avec Image non disponibleirr::scene::ISceneManager::addCameraSceneNodeMaya(). Mais pour cet exemple, nous voulons créer une caméra qui se comporte comme celles des jeux de tir à la première personne (FPS(4)), nous utiliserons donc irr::scene::ISceneManager::addCameraSceneNodeFPS().

 
Sélectionnez
smgr->addCameraSceneNodeFPS();

Nous n'avons pas besoin de voir le curseur de la souris, donc nous le cachons via irr::IrrlichtDevice::ICursorControl.

 
Sélectionnez
    device->getCursorControl()->setVisible(false);

Nous avons tout fini, maintenant dessinons-le. Nous écrivons aussi le nombre d'images par seconde ainsi que les primitives dessinées dans le titre de la fenêtre. Le test avec Image non disponibleirr::IrrlichtDevice::isWindowActive() est optionnel, mais évite le moteur d'attraper le curseur de la souris après un changement de tâche lorsque d'autres programmes sont actifs. L'appel de irr::IrrlichtDevice::yield() va éviter la boucle principale de prendre tous les cycles CPU quand la fenêtre n'est pas active.

 
Sélectionnez
    int lastFPS = -1;

    while(device->run())
    {
        if (device->isWindowActive())
        {
            driver->beginScene(true, true, video::SColor(255,200,200,200));
            smgr->drawAll();
            driver->endScene();

            int fps = driver->getFPS();

            if (lastFPS != fps)
            {
                core::stringw str = L"Irrlicht Engine - Quake 3 Map example [";
                str += driver->getName();
                str += "] FPS:";
                str += fps;

                device->setWindowCaption(str.c_str());
                lastFPS = fps;
            }
        }
        else
            device->yield();
    }

À la fin, détruisons le système Irrlicht.

 
Sélectionnez
    device->drop();
    return 0;
}

Voilà, compilons et expérimentons le programme.

V. Conclusion

Vous pouvez désormais charger une carte Quake 3 en utilisant Irrlicht.

Dans le prochain tutoriel « Nœud de scène personnalisé », nous verrons comment créer un nœud de scène personnalisé et comment l'utiliser.

VI. Remerciements

Merci à Nikolaus Gebhardt de nous permettre de traduire ce tutoriel.

Merci à LittleWhite pour sa relecture technique ainsi qu'à zoom61 pour sa relecture orthographique.


« Nœud » de scène.
Un octree est un arbre où chaque nœud peut avoir huit enfants. C'est une structure couramment utilisée pour le partitionnement d'un espace 3D en sous ensemble.
Formes géométriques basique constituant des géométries plus complexes.
First person shooter.

  

Les sources présentées sur cette page sont libres de droits et vous pouvez les utiliser à votre convenance. Par contre, la page de présentation constitue une œuvre intellectuelle protégée par les droits d'auteur. Copyright © 2012 Neckara. Aucune reproduction, même partielle, ne peut être faite de ce site et de l'ensemble de son contenu : textes, documents, images, etc. sans l'autorisation expresse de l'auteur. Sinon vous encourez selon la loi jusqu'à trois ans de prison et jusqu'à 300 000 € de dommages et intérêts.