Utilisation de DirectX dans vos applications .NET

Thomas Lebrun

Cet article vous enseignera les bases pour utiliser DirectX dans vos applications .NET.

- Titre : Utilisation de DirectX dans vos applications .NET

- Auteur : Thomas Lebrun

- Parution : 7 janvier 2005

- Mise à jour : 20 février 2013

- Licence : 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 ® 2005 Thomas Lebrun. 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.

Sommaire

- I. Introduction

- I-A. Qu'est-ce que DirectX ?

- I-B. Téléchargement/Installation du SDK

- II. Mise en œuvre

- II-A. Ajout des références

- II-B. Lire un fichier audio

- II-C. Lire un fichier vidéo

- II-D. Créer une fenêtre DirectX

- II-E. Contrôler le clavier avec DirectX

- II-F. Lire un son

- III. Conclusion

- IV. IV. Liens

- V. Téléchargements

I - Introduction

I-A - Qu'est-ce que DirectX ?

DirectX est une suite d'APIs multimédia intégrée au système d'exploitation Windows permettant d'exploiter les capacités matérielles d'un ordinateur.

DirectX fournit un ensemble de bibliothèques de fonctions essentiellement dédiées aux traitements audio/vidéo (carte vidéo, carte son, carte 3D, etc.) et aux périphériques d'entrée/sortie (Joystick, carte réseau, souris, etc.).

Ce produit n'étant pas libre, les sources ne sont pas rendues publiques, contrairement à la bibliothèque OpenGL, concurrente de Direct3D.

Malgré cela, il devient de plus en plus incontournable notamment dans le domaine de la programmation des jeux vidéo 3D.

DirectX est constitué de plusieurs modules plus ou moins indépendants les uns des autres, dont :

- Direct3D : gère l'affichage 3D ;

- DirectDraw : gère l'affichage 2D (intégré à Direct3D depuis la version 8) ;

- DirectInput : gère les périphériques d'entrée (Joystick, clavier, etc.) ;

- DirectPlay : gère les échanges de données par réseau (local ou Internet) ;

- DirectSound : gère les sons ;

- DirectMusic : gère la musique ;

- DirectVoice : gère les échanges vocaux en direct ;

- DirectShow : gère l'affichage et la capture de vidéo.

Actuellement, DirectX est en version 9.0c : vous pouvez le télécharge ici.

I-B - Téléchargement/Installation du SDK

Pour pouvoir développer avec DirectX, vous devez télécharger et installer le Software Development Kit (SDK) de DirectX.

Il contient tous les outils nécessaires pour concevoir des applications riches et interactives à la pointe des technologies multimédias et 3D.

Il contient les Runtimes, fichiers des entêtes et des librairies, des exemples de codes et d'applications, toute la documentation, des utilitaires DirectX et le support pour le développement en C++, C# et Visual Basic .NET.

Vous pouvez télécharger le Kit de Développement de DirectX 9.0c à cette adresse.

Une fois le SDK téléchargé, décompressez les fichiers dans un répertoire temporaire puis lancez l'installation comme n'importe quelle autre installation.

Une fois que tout est installé, redémarrez votre ordinateur: vous êtes maintenant prêt à utiliser DirectX dans vos applications .NET.

II - Mise en œuvre

II-A - Ajout des références

Avant de pouvoir commencer à utiliser les classes offertes par DirectX, vous devez ajouter les références adéquates à votre projet.

Pour cela, faites un clic droit sur « Références », puis cliquez sur « Ajouter une référence » : vous devez donc avoir un écran comme celui-ci :

Comme vous pouvez le voir, de nombreuses références sont disponibles: à vous d'ajouter celles dont vous avez besoin (et uniquement celles-là, afin de limiter le nombre de fichiers à déployer dans le cas où vous envisagez de déployer votre application).

Une fois les références ajoutées, vous pouvez donc commencer à coder.

Pour tenter d'illustrer au mieux les possibilités qui s'offrent à vous, je vais réaliser un ensemble d'applications simples, que nous étudierons tout au long de cet article.

II-B - Lire un fichier audio

Dans cette partie, nous allons réaliser un simple lecteur MP3, qui vous permettra de lire les fichiers audio.

Commencez alors par ajouter, à votre projet, la référence à Microsoft.DirectX.AudioVideoPlayback.

Une fois que vous l'avez fait, vous pouvez utiliser les classes permettant la lecture des fichiers audio, et en particulier la classe Microsoft.DirectX.AudioVideoPlayback.Audio.

Le constructeur de cette classe accepte en paramètre le chemin vers le fichier que vous souhaitez lire. Il est également possible de spécifier un booléen, indiquant si oui ou non la lecture doit commencer automatiquement.

Pour lancer la lecture, un simple appel à la méthode Play() est nécessaire.

Arrêter la lecture en cours est aussi simple que de la lancer: un appel à la méthode Stop() suffit.

Voyons ce que cela donne par le code :

Lecture d'un fichier audio

// Déclaration des variables
private Microsoft.DirectX.AudioVideoPlayback.Audio monAudio;

// Lecture du fichier
string sMaMusique = textBox1.Text.Trim();
monAudio = new Microsoft.DirectX.AudioVideoPlayback.Audio(sMaMusique);
monAudio.Play();

// Arrêt de la lecture
if ( monAudio != null )
{
monAudio.Stop();
}

Comme vous pouvez le constater, cela reste relativement simple. Il existe d'autre propriétés et méthodes de la classe AudioVideoPlayback.Audio : en voici une liste non-exhaustive:

- CurrentPosition: Permet de déterminer la position actuelle lors de la lecture du fichier ;

- Duration: Retourne, en seconde, la durée du fichier ;

- Pause(): Met la lecture en pause ;

- State: Retourne l'état en cours ;

- Volume: Indique la quantité de volume à atténuer.

II-C - Lire un fichier vidéo

Pour lire un fichier vidéo, la procédure est sensiblement la même que pour la lecture d'un fichier audio.

En effet, mis à part le changement du nom de la classe à utiliser, le reste est identique.

Par conséquent, vous devez donc utiliser maintenant Microsoft.DirectX.AudioVideoPlayback.Video pour lire les fichiers vidéo.

Lors de l'appel à la méthode Play(), une nouvelle fenêtre apparaîtra avec, à l'intérieur, la vidéo que vous avez choisie.

Lecture d'un fichier vidéo

// Déclaration des variables
private Microsoft.DirectX.AudioVideoPlayback.Video maVideo;

// Lecture du fichier
string sMaVideo = textBox1.Text.Trim();
maVideo = new Microsoft.DirectX.AudioVideoPlayback.Audio(sMaVideo);
maVideo.Play();

// Arrêt de la lecture
if ( maVideo != null )
{
maVideo.Stop();
}

L'avantage d'utiliser DirectX pour lire les fichiers vidéo est que cela vous permet d'utiliser les codecs installés sur l'ordinateur cible.

Ainsi, vous pourrez tout à fait lire un fichier encodé en MPEG-4, si le plugin est installé : vous n'êtes plus limité à la simple lecture des fichiers connus par Windows.

II-D - Créer une fenêtre DirectX

Pour créer une fenêtre DirectX dans votre application, vous devez tout d'abord rajouter deux références à votre projet :

- Microsoft.DirectX ;

- Microsoft.DirectX.DirectDraw.

Lorsque les références ont été rajoutées avec succès, pensez à faire les « using » (ou « Import ») correspondant dans votre code :

Ajout des using

using Microsoft.DirectX;
using Microsoft.DirectX.DirectDraw;

Vous êtes alors prêt à créer une fenêtre DirectX dans votre application.

Pour cela, vous allez utiliser trois classes:

- La classe Microsoft.DirectX.DirectDraw.Device : c'est elle qui est chargée de créer les objets DirectDraw et qui travaille avec les variables systèmes ;

- La classe Microsoft.DirectX.DirectDraw.Surface : une surface représente une zone linéaire dans la mémoire de votre carte graphique ;

- La classe Microsoft.DirectX.DirectDraw.SurfaceDescription : C'est la classe qui vous permet de travailler avec la « Surface ».

Pour simplifier, on peut dire qu'un « device » représente votre carte graphique, qu'une « surface » est une zone, dans la mémoire de votre carte vidéo et qu'une SurfaceDescription est ce qui vous permet de faire le lien entre les deux.

Voyons, par le code, ce que cela représente :

Création d'une fenêtre DirectX

// Le materiel à utiliser
private Device display;
// La surface avant
private Surface window = null;
// Description de la surface
private SurfaceDescription description = null;

...

description = new SurfaceDescription();

// Initialisation du matériel
display = new Device();

display.SetCooperativeLevel(this, CooperativeLevelFlags.FullscreenExclusive);

// On indique la résolution: 800x600 en 16 bits
display.SetDisplayMode(800, 600, 16, 0, false);

// On indique que c'est la surface à afficher
description.SurfaceCaps.PrimarySurface = true;

// On crée maintenant la surface, avec la description et le matériel indiqué
window = new Surface(description, display);

Comme vous pouvez le voir, la première chose à faire est donc d'appeler la méthode SetCooperativeLevel, qui accepte comme paramètre:

- Un contrôle parent: dans notre cas, il s'agit de la Form en cours ;

- Un CooperativeLevelFlags: il s'agit d'un drapeau qui indique comment doit se comporter la fenêtre que vous allez créer.

La liste de tous les CooperativeLevelFlags peut-être retrouvée ici les plus intéressants sont:

- FullscreenExclusive: qui permet à votre application de s'exécuter en plein écran ;

- Normal: qui fait en sorte que votre application s'exécute avec les paramètres que vous lui avez définis.

Une fois que vous avez fait cette partie, vous pouvez appeler SetDisplayMode, qui vous sert à définir la résolution que votre carte graphique doit adopter pour exécuter votre application.
Cette méthode prend en paramètre:

- La hauteur ;

- La largeur ;

- Le nombre de bits par pixel ;

- Le taux de rafraîchissement ;

- Un booléen indiquant s'il faut utiliser ou non, le mode VGA.

Lorsque cette méthode a été appelée, vous devez ensuite indiquer à DirectX que c'est cette surface qui doit être affichée à l'écran.

Cela se fait au moyen de :

Définition de la surface principale

description.SurfaceCaps.PrimarySurface = true;

Pour finir, il ne vous reste plus qu'a créer la surface et à l'afficher, en utilisant :

Création et affichage de la surface

window = new Surface(description, display);

Il existe plusieurs constructeurs différents pour Surface: celui que nous utilisons nous permet de créer notre surface avec les paramètres que nous avons définis (les autres constructeurs de Surface permettent, par exemple, d'ajouter un fond d'écran à la fenêtre).

Vous venez donc voir comment créer une fenêtre DirectX avec .NET.

Pour résumer, voici ce que vous devez retenir de cette partie

- SetCooperativeLevel permet de définir le mode de fonctionnement de votre application (plein écran, fenêtré, etc.) ;

- SetDisplayMode vous permet de définir la résolution d'écran que votre carte graphique doit adopter pour exécuter votre application ;

- SurfaceCaps.PrimarySurface vous permet d'indiquer la surface qui doit être affichée à l'écran.

II-E - Contrôler le clavier avec DirectX

DirectX vous permet de contrôler les périphériques attachés à votre ordinateur, par exemple le clavier ou la souris.

Nous allons voir, via un exemple, comment gérer le clavier.

Commencez par ajouter les deux références suivantes à votre projet :

- Microsoft.DirectX ;

- Microsoft.DirectX.DirectInput.

Ensuite, faites les using correspondant à ces deux références :

Ajout des using

using Microsoft.DirectX;
using Microsoft.DirectX.DirectInput;

À partir de maintenant, il vous est possible de manipuler les objets permettant le contrôle des périphériques.

Commencez par créer plusieurs objets:

- Un DirectInput.Device pour définir quel périphérique vous voulez contrôler ;

- Plusieurs DirectInput.Key pour indiquer quelles touches surveiller ;

- Un CooperativeLevelFlags, qui permet de déterminer comment l'instance de DirectInput.Device, en cours d'exécution, interagit avec le reste du système.

Voyons ce que cela donne :

Déclaration des variables

private Device clavier;
private Key Up = Key.UpArrow;
private Key Down = Key.DownArrow;
private Key _Left = Key.LeftArrow;
private Key _Right = Key.RightArrow;

// Flags
CooperativeLevelFlags flag;
flag = Microsoft.DirectX.DirectInput.CooperativeLevelFlags.NonExclusive;
flag |= Microsoft.DirectX.DirectInput.CooperativeLevelFlags.Background;

clavier = new Device(SystemGuid.Keyboard);
clavier.SetCooperativeLevel(this, flag);

// On obtient l'accès au clavier
clavier.Acquire();

La ligne qui permet de définir que l'on veut surveiller le clavier est celle-ci :

clavier = new Device(SystemGuid.Keyboard);

Device prend en paramètre un SystemGuid qui peut être :

- SystemGuid.Keyboard ;

- SystemGuid.Mouse.

La méthode Acquire() permet d'obtenir l'accès au périphérique: à partir du moment où on l'appelle, on commence à surveiller le périphérique spécifié.

Une fois que cette partie est terminée, vous devez spécifier à votre programme ce qu'il doit faire.

Admettons que nous désirons faire afficher, une fois le programme lancé, une MessageBox indiquant la touche sur laquelle nous avons appuyé.

Dans l'événement KeyDown de votre Form, ajoutez le code suivant :

Détection de la touche pressée

KeyboardState state = clavier.GetCurrentKeyboardState();

if ( state[Up] )
{
MessageBox.Show("Vous avez pressé la flèche " + Up.ToString());
}
else if ( state[Down] )
{
MessageBox.Show("Vous avez pressé la flèche " + Down.ToString());
}
else if ( state[_Left] )
{
MessageBox.Show("Vous avez pressé la flèche " + _Left.ToString());
}
else if ( state[_Right] )
{
MessageBox.Show("Vous avez pressé la flèche " + _Right.ToString());
}

Ici, nous récupérons des informations sur le clavier, au moyen de la méthode GetCurrentKeyboardState(). Nous stockons ces informations dans une variable de type KeyboardState, puis nous regardons si l'une des touches que nous avons définies précédemment se trouve dans ce tableau contenant les informations du clavier.

Si c'est bien le cas, nous affichons une boîte de dialogue indiquant sur quelle touche nous avons appuyé.

Je dois reconnaître que c'est peut-être un peu compliqué comme méthode pour juste savoir sur quelle touche un utilisateur a appuyé.

En effet, il est possible de faire la même chose de manière beaucoup plus simple grâce au framework .NET, mais dans ce cas, vous n'utiliseriez pas la technologie DirectX pour le faire.

De plus, ce n'est qu'un simple exemple des possibilités qui s'offrent à vous.

II-F - Lire un son

Lorsque vous utilisez DirectX, jouer un son est différent de jouer une musique. En effet, alors que les musiques sont jouées grâce à DirectMusic, la lecture des sons se fait au moyen de DirectSound.

C'est pourquoi nous allons voir maintenant comment faire pour que notre application puisse jouer un son.

Tout d'abord, il convient de définir ce qu'est un son. Voici une définition que l'on pourrait en donner: « Un son est un fichier audio, généralement de courte durée, et qui représente un bruit très court, tel que par exemple le bruit d'une porte qui claque, le bruit d'un laser, etc. À l'inverse des musiques qui sont généralement au format MP3 ou MIDI, les sons sont au format WAV. »

Il s'agit d'une description sommaire et improvisée, mais qui cadre bien la chose.

Nous avons donc vu que nous devions utiliser DirectSound pour jouer un son: ajoutez alors les références suivantes à votre projet :

- Microsoft.DirectX ;

- Microsoft.DirectX.DirectSound.

Puis faites les « using » correspondants :

Ajout des using

using Microsoft.DirectX;
using Microsoft.DirectX.DirectSound;

Une fois que c'est fait, vous devez déclarer les deux objets que nous allons utiliser :

- Un objet de type Device ;

- Un objet de type SecondaryBuffer.

Ce qui nous donne, dans le code :

// Création du device
private Device device = null;

//Création du buffer pour le son
private SecondaryBuffer Buffer = null;

Et dans le Form_Load, nous mettons :

//Création du device
device = new Device();

// On définit la priorité à donner au son
device.SetCooperativeLevel(this, CooperativeLevel.Priority);

À partir de là, votre device est prêt: il ne vous reste plus qu'a initialisé votre buffer et appeler les méthodes que vous désirez :

Initialisation du buffer

string sMonSon = textBox1.Text.Trim();

if ( sMonSon.Length == 0 )
{
MessageBox.Show("Vous devez rentrer un chemin vers un fichier audio", "Erreur", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
else
{
try
{
// Initialisation du buffer
Buffer = new SecondaryBuffer(sMonSon, device);

// On définit une priorité nulle et un flag à default: le son ne sera joué qu'une fois
Buffer.Play(0, BufferPlayFlags.Default);

}
catch(Exception Ex) // Pas bien d'intercepter Exception mais c'est pour aller au plus vite :)
{
MessageBox.Show(Ex.Message);
}
}

Pour lancer la lecture du son, un simple appel à la méthode Play() suffit. Cette méthode prend en paramètre deux arguments:

- Un entier, qui représente la priorité pour le son ;

- Un flag, de type BufferPlayFlags, qui indique comment doit être joué le son.

La liste des membres de l'énumération BufferPlayFlags peut être retrouvée ici. Voici les membres qui seront susceptibles de vous intéresser :

- Looping: Permet de jouer le son en boucle ;

- Default: Permet de ne jouer le son qu'une seule fois.

Bien sûr, d'autres membres, plus techniques, sont disponibles (tels que LocateInSoftware ou LocateInHardware) : à vous d'utiliser celui ou ceux qui sont adaptés à vos besoins.

III - Conclusion

Cet article vous a fourni de bonnes bases pour comprendre comment utiliser DirectX dans vos applications .NET.

Cependant, sachez que tout n'a pas pu être traité: en effet, DirectX est un domaine vaste et qui permet de réaliser de multitude de choses (pensez à tout ce que les jeux modernes peuvent faire).

C'est pourquoi si vous voulez en savoir plus, il vous faudra faire quelques petites recherches personnelles : un bon moyen d'apprendre non ? ;)

IV - IV. Liens

L'article d'Olivier Delmotte sur Managed DirectX : https://odelmotte.developpez.com/tutoriels/manageddirectx/

Le site Web de DirectX : http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnanchor/html/anch_directx.asp

V - Téléchargements

Video de démonstration : Format AVI (6,65 Mo)

Solution Visual Studio contenant l'ensemble des projets de l'article : Solution

Téléchargement de DirectX 9.0c : DirectX 9.0c

Téléchargement du SDK de DirectX 9.0c : SDK de DirectX 9.0c

Téléchargement des Extras pour DirectX 9.0c : Extras de DirectX 9.0c