Compiler un effet (Direct3D 11)
Une fois qu’un effet a été créé, l’étape suivante consiste à compiler le code pour vérifier les problèmes de syntaxe.
Pour ce faire, appelez l’une des API de compilation (D3DX11CompileFromFile, D3DX11CompileFromMemoryou D3DX11CompileFromResource ). Ces API appellent le compilateur Effect fxc.exe, qui compile le code HLSL. C’est pour cette raison que la syntaxe du code dans un effet ressemble beaucoup à du code HLSL. (Il existe quelques exceptions qui seront gérées ultérieurement). Le compilateur Effect/compilateur HLSL, fxc.exe, est disponible dans le kit de développement logiciel (SDK) dans le dossier Utilities afin que les nuanceurs (ou effets) puissent être compilés hors connexion si vous le souhaitez. Consultez la documentation pour exécuter le compilateur à partir de la ligne de commande.
- Exemple
- Offre
- Recherche de fichiers include
- Macros
- Indicateurs de nuanceur HLSL
- Indicateurs FX
- Vérification des erreurs
- Rubriques connexes
Exemples
Voici un exemple de compilation d’un fichier Effect.
WCHAR str[MAX_PATH];
DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName, pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL, NULL, &pBlob, &pErrorBlob, NULL );
Includes
L’un des paramètres des API de compilation est une interface include. Générez l’une de ces si vous souhaitez inclure un comportement personnalisé lorsque le compilateur lit un fichier include. Le compilateur exécute ce comportement personnalisé chaque fois qu’il crée ou compile un effet (qui utilise le pointeur include). Pour implémenter un comportement include personnalisé, dérivez une classe de l’interface ID3DInclude . Cela fournit à votre classe deux méthodes : Open et Close. Implémentez le comportement personnalisé dans ces méthodes.
Recherche de fichiers include
Le pointeur que le compilateur transmet dans le paramètre pParentData à la méthode Open de votre gestionnaire include peut ne pas pointer vers le conteneur qui inclut le # fichier include dont le compilateur a besoin pour compiler le code de votre nuanceur. Autrement dit, le compilateur peut passer null dans pParentData. Par conséquent, nous recommandons que votre gestionnaire d’inclusion recherche sa propre liste d’emplacements include pour le contenu. Votre gestionnaire include peut ajouter dynamiquement de nouveaux emplacements include lorsqu’il reçoit ces emplacements dans les appels à sa méthode Open .
Dans l’exemple suivant, supposons que les fichiers include du code du nuanceur sont tous deux stockés dans le répertoire somewhereelse . Lorsque le compilateur appelle la méthode Open du gestionnaire include pour ouvrir et lire le contenu de somewhereelse \ foo. h, le gestionnaire include peut enregistrer l’emplacement du répertoire somewhereelse . Plus tard, lorsque le compilateur appelle la méthode Open du gestionnaire include pour ouvrir et lire le contenu de bar. h, le gestionnaire include peut effectuer une recherche automatique dans le répertoire somewhereelse pour bar. h.
Main.hlsl:
#include "somewhereelse\foo.h"
Foo.h:
#include "bar.h"
Macros
La compilation des effets peut également prendre un pointeur vers les macros définies ailleurs. Par exemple, supposons que vous souhaitiez modifier l’effet dans BasicHLSL10 pour utiliser deux macros : zéro et un. Le code d’effet qui utilise les deux macros est présenté ici.
if( bAnimate )
vAnimatedPos += float4(vNormal, zero) *
(sin(g_fTime+5.5)+0.5)*5;
Output.Diffuse.a = one;
Voici la déclaration pour les deux macros.
D3D10_SHADER_MACRO Shader_Macros[3] = { "zero", "0", "one", "1.0f", NULL, NULL };
Les macros sont un tableau de macros se terminant par un caractère NULL ; où chaque macro est définie à l’aide d’un struct de _ _ macro de nuanceur D3D10 .
Modifiez l’appel de l’effet de compilation pour prendre un pointeur vers les macros.
D3DX11CompileFromFile( str, Shader_Macros, NULL, pFunctionName,
pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL,
NULL, &pBlob, &pErrorBlob, NULL );
Indicateurs de nuanceur HLSL
Les indicateurs de nuanceur spécifient des contraintes de nuanceur pour le compilateur HLSL. Ces indicateurs affectent le code généré par le compilateur du nuanceur des manières suivantes :
- Optimisez la taille du code.
- Y compris les informations de débogage, qui empêchent le contrôle de Flow.
- Affecte la cible de compilation et si un nuanceur peut s’exécuter sur du matériel hérité.
Ces indicateurs peuvent être combinés de manière logique si vous n’avez pas spécifié deux caractéristiques conflictuelles. Pour obtenir la liste des indicateurs, consultez _ constantes de nuanceur D3D10.
Indicateurs FX
Utilisez ces indicateurs quand vous créez un effet pour définir le comportement de la compilation ou le comportement de l’effet d’exécution. Pour obtenir la liste des indicateurs, consultez _ constantes Effect D3D10.
Vérification des erreurs
Si, au cours de la compilation, une erreur se produit, l’API retourne une interface qui contient les erreurs du compilateur d’effet. Cette interface est appelée ID3DBlob. Elle n’est pas directement lisible ; Toutefois, en retournant un pointeur vers la mémoire tampon qui contient les données (qui est une chaîne), vous pouvez voir toutes les erreurs de compilation.
Cet exemple contient une erreur dans BasicHLSL. FX, la première déclaration de variable se produit deux fois.
//-------------------------------------------------------------------
// Global variables
//-------------------------------------------------------------------
float4 g_MaterialAmbientColor; // Material's ambient color
// Declare the same variable twice
float4 g_MaterialAmbientColor; // Material's ambient color
Cette erreur force le compilateur à retourner l’erreur suivante, comme illustré dans la capture d’écran suivante du Fenêtre Espion dans Microsoft Visual Studio.

Étant donné que le compilateur retourne l’erreur dans un pointeur LPVOID, effectuez un cast de celui-ci en une chaîne de caractères dans le Fenêtre Espion.
Voici le code qui retourne l’erreur de la compilation ayant échoué.
// Read the D3DX effect file
WCHAR str[MAX_PATH];
ID3DBlob* l_pBlob_Effect = NULL;
ID3DBlob* l_pBlob_Errors = NULL;
hr = DXUTFindDXSDKMediaFileCch( str, MAX_PATH, L"BasicHLSL10.fx" );
hr = D3DX11CompileFromFile( str, NULL, NULL, pFunctionName,
pProfile, D3D10_SHADER_ENABLE_STRICTNESS, NULL,
NULL, &pBlob, &pErrorBlob, NULL );
LPVOID l_pError = NULL;
if( pErrorBlob )
{
l_pError = pErrorBlob->GetBufferPointer();
// then cast to a char* to see it in the locals window
}