Partager via


Utilisation de nuanceurs dans Direct3D 10

Le pipeline comporte trois étapes de nuanceur et chacune est programmée avec un nuanceur HLSL. Tous les nuanceurs Direct3D 10 sont écrits en HLSL, ciblant le modèle de nuanceur 4.

Différences entre Direct3D 9 et Direct3D 10 :

  • Contrairement aux modèles de nuanceur Direct3D 9 qui peuvent être créés dans un langage d’assembly intermédiaire, les nuanceurs de modèle de nuanceur 4.0 sont créés uniquement dans HLSL. La compilation hors connexion de nuanceurs en bytecode consommable pour l’appareil est toujours prise en charge et recommandée dans la plupart des scénarios.

Cet exemple utilise uniquement un nuanceur de vertex. Étant donné que tous les nuanceurs sont créés à partir du cœur de nuanceur commun, apprendre à utiliser un nuanceur de vertex est très similaire à l’utilisation d’un nuanceur de géométrie ou de pixels.

Une fois que vous avez créé un nuanceur HLSL (cet exemple utilise le nuanceur de vertex HLSLWithoutFX.vsh), vous devez le préparer pour la phase de pipeline particulière qui l’utilisera. Pour ce faire, vous devez :

Ces étapes doivent être répétées pour chaque nuanceur dans le pipeline.

Compiler un nuanceur

La première étape consiste à compiler le nuanceur, à case activée pour vérifier que vous avez correctement codé les instructions HLSL. Pour ce faire, appelez D3D10CompileShader et fournissez-lui plusieurs paramètres, comme illustré ici :

    IPD3D10Blob * pBlob;
    
        
    // Compile the vertex shader from the file
    D3D10CompileShader( strPath, strlen( strPath ), "HLSLWithoutFX.vsh", 
        NULL, NULL, "Ripple", "vs_4_0", dwShaderFlags, &pBlob, NULL );

Cette fonction prend les paramètres suivants :

  • Nom du fichier ( et longueur de la chaîne de nom en octets ) qui contient le nuanceur. Cet exemple utilise un nuanceur de vertex uniquement (dans le fichier HLSLWithoutFX.vsh où l’extension de fichier .vsh est une abréviation du nuanceur de vertex).

  • Nom de la fonction nuanceur. Cet exemple compile un nuanceur de vertex à partir de la fonction Ripple qui prend une seule entrée et retourne un struct de sortie (la fonction provient de l’exemple HLSLWithoutFX) :

    VS_OUTPUT Ripple( in float2 vPosition : POSITION )
    
  • Pointeur vers toutes les macros utilisées par le nuanceur. Utilisez D3D10_SHADER_MACRO pour vous aider à définir vos macros ; Créez simplement une chaîne de nom qui contient tous les noms de macros (chaque nom étant séparé par un espace) et une chaîne de définition (avec chaque corps de macro séparé par un espace). Les deux chaînes doivent être terminées par null.

  • Pointeur vers tous les autres fichiers que vous devez inclure pour que vos nuanceurs se compilent. Cela utilise l’interface ID3D10Include qui a deux méthodes implémentées par l’utilisateur : Ouvrir et Fermer. Pour que cela fonctionne, vous devez implémenter le corps des méthodes Open et Close ; dans la méthode Open, ajoutez le code que vous utiliserez pour ouvrir les fichiers include de votre choix. Dans la fonction Close, ajoutez le code pour fermer les fichiers lorsque vous avez terminé avec eux.

  • Nom de la fonction de nuanceur à compiler. Ce nuanceur compile la fonction Ripple.

  • Profil de nuanceur à cibler lors de la compilation. Étant donné que vous pouvez compiler une fonction dans un nuanceur de vertex, de géométrie ou de pixels, le profil indique au compilateur quel type de nuanceur et quel modèle de nuanceur comparer le code.

  • Indicateurs du compilateur de nuanceur. Ces indicateurs indiquent au compilateur les informations à placer dans la sortie compilée et la façon dont vous souhaitez optimiser le code de sortie : pour la vitesse, pour le débogage, etc. Pour obtenir la liste des indicateurs disponibles, consultez Constantes d’effet (Direct3D 10 ). L’exemple contient du code que vous pouvez utiliser pour définir les valeurs d’indicateur de compilateur pour votre projet. Il s’agit principalement de savoir si vous souhaitez ou non générer des informations de débogage.

  • Pointeur vers la mémoire tampon qui contient le code de nuanceur compilé. La mémoire tampon contient également toutes les informations de débogage et de table de symboles incorporées demandées par les indicateurs du compilateur.

  • Pointeur vers une mémoire tampon qui contient une liste des erreurs et des avertissements rencontrés pendant la compilation, qui sont les mêmes messages que ceux que vous verriez dans la sortie de débogage si vous exécutiez le débogueur lors de la compilation du nuanceur. NULL est une valeur acceptable lorsque vous ne souhaitez pas que les erreurs soient retournées dans une mémoire tampon.

Si le nuanceur se compile correctement, un pointeur vers le code du nuanceur est retourné en tant qu’interface ID3D10Blob. Il s’agit de l’interface Blob, car le pointeur est vers un emplacement en mémoire composé d’un tableau de DWORD. L’interface est fournie pour vous permettre d’obtenir un pointeur vers le nuanceur compilé dont vous aurez besoin à l’étape suivante.

À compter du Kit de développement logiciel (SDK) de décembre 2006, le compilateur HLSL DirectX 10 est désormais le compilateur par défaut dans DirectX 9 et DirectX 10. Pour plus d’informations, consultez Effect-Compiler Tool .

Obtenir un pointeur vers un nuanceur compilé

Plusieurs méthodes d’API nécessitent un pointeur vers un nuanceur compilé. Cet argument est généralement appelé pShaderBytecode , car il pointe vers un nuanceur compilé représenté sous la forme d’une séquence de codes d’octet. Pour obtenir un pointeur vers un nuanceur compilé, commencez par compiler le nuanceur en appelant D3D10CompileShader ou une fonction similaire. Si la compilation réussit, le nuanceur compilé est retourné dans une interface ID3D10Blob . Enfin, utilisez la méthode GetBufferPointer pour retourner le pointeur.

Créer un objet Nuanceur

Une fois le nuanceur compilé, appelez CreateVertexShader pour créer l’objet nuanceur :

    ID3D10VertexShader ** ppVertexShader
    ID3D10Blob pBlob;


    // Create the vertex shader
    hr = pd3dDevice->CreateVertexShader( (DWORD*)pBlob->GetBufferPointer(),
        pBlob->GetBufferSize(), &ppVertexShader );

    // Release the pointer to the compiled shader once you are done with it
    pBlob->Release();

Pour créer l’objet nuanceur, passez le pointeur vers le nuanceur compilé dans CreateVertexShader. Étant donné que vous deviez d’abord compiler correctement le nuanceur, cet appel passera presque certainement, sauf si vous rencontrez un problème de mémoire sur votre ordinateur.

Vous pouvez créer autant d’objets de nuanceur que vous le souhaitez et simplement conserver des pointeurs vers eux. Ce même mécanisme fonctionne pour les nuanceurs de géométrie et de pixels en supposant que vous faites correspondre les profils de nuanceur (lorsque vous appelez la méthode compile) aux noms d’interface (lorsque vous appelez la méthode create).

Définir l’objet Nuanceur

La dernière étape consiste à définir le nuanceur sur l’étape du pipeline. Étant donné qu’il existe trois étapes de nuanceur dans le pipeline, vous devez effectuer trois appels d’API, un pour chaque étape.

    // Set a vertex shader
    pd3dDevice->VSSetShader( g_pVS10 );

L’appel à VSSetShader prend le pointeur vers le nuanceur de vertex créé à l’étape 1. Cela définit le nuanceur dans l’appareil. L’étape du nuanceur de vertex est maintenant initialisée avec son code de nuanceur de vertex. Il ne reste plus qu’à initialiser toutes les variables de nuanceur.

Répéter pour les 3 étapes du nuanceur

Répétez ces mêmes étapes pour créer n’importe quel nuanceur de vertex ou de pixels ou même un nuanceur de géométrie qui génère une sortie vers le nuanceur de pixels.

Compilation des nuanceurs

Guide de programmation pour HLSL