Une API de dessin de débogage légère en mode immédiat, rendu agnostique et léger pour C ++.
Ce logiciel est dans le domaine public. Lorsque ce dévouement n'est pas reconnu, vous obtenez une licence perpétuelle et irrévocable pour copier, distribuer et modifier le code source comme vous le voyez.
Le code source est fourni "tel quel", sans garantie d'aucune sorte, express ou implicite. Aucune attribution n'est requise, mais une mention concernant les auteurs n'est appréciée.
Debug Draw est une bibliothèque de fichiers source unique, de sorte que les déclarations de transfert "d'en-tête" et l'implémentation sont contenues dans le même fichier ( debug_draw.hpp ). Cela devrait faciliter le déploiement et l'intégration avec vos propres projets. Tout ce que vous avez à faire est #include le fichier de bibliothèque dans l'un de vos propres fichiers source et de définir DEBUG_DRAW_IMPLEMENTATION dans ce fichier pour générer l'implémentation. Vous pouvez également inclure la bibliothèque dans d'autres endroits. Lorsque DEBUG_DRAW_IMPLEMENTATION n'est pas défini, il agit comme un fichier d'en-tête C ++ normal. Exemple:
Dans my_program.cpp :
# define DEBUG_DRAW_IMPLEMENTATION
# include " debug_draw.hpp " Maintenant, dans my_program.hpp ou tout autre en-tête ou fichier source, vous pouvez l'inclure comme un en-tête C ++ normal:
# include " debug_draw.hpp "Voilà, vous devriez maintenant être en mesure de créer un tirage de débogage dans votre propre application.
Debug Draw ne fait pas d'hypothèses sur l'API Renderer sous-tend, il peut donc être intégré très facilement avec Direct3D ou OpenGL ou tout autre moteur de rendu de votre choix. Tout ce qui est requis, c'est que vous fournissiez une implémentation pour la classe abstraite dd::RenderInterface , qui fournit un tirage de débogage avec des méthodes de base pour dessiner des points, des lignes et des glyphes de caractère. Ce qui suit est à quoi ressemble dd::RenderInterface :
class RenderInterface
{
public:
virtual void beginDraw ();
virtual void endDraw ();
virtual GlyphTextureHandle createGlyphTexture ( int width, int height, const void * pixels);
virtual void destroyGlyphTexture (GlyphTextureHandle glyphTex);
virtual void drawPointList ( const DrawVertex * points, int count, bool depthEnabled);
virtual void drawLineList ( const DrawVertex * lines, int count, bool depthEnabled);
virtual void drawGlyphList ( const DrawVertex * glyphs, int count, GlyphTextureHandle glyphTex);
virtual ~RenderInterface () = 0 ;
}; Toutes les méthodes ne doivent pas être implémentées, vous décidez quelles fonctionnalités prennent en charge! Consultez le code source de la déclaration de RenderInterface . Chaque méthode est bien commentée et décrit le comportement attendu que vous devez mettre en œuvre. Pour les implémentations de référence de la RenderInterface à l'aide d'API standard comme OpenGL, reportez-vous aux samples/ répertoire de ce projet.
Une fois que vous avez implémenté une RenderInterface pour votre rendu, tout ce que vous avez à faire avant de commencer à utiliser le dessin de débogage est d'appeler dd::initialize() en le transmettant un pointeur sur votre RenderInterface :
MyRenderInterface renderIface;
dd::initialize (&renderIface); Notez cependant que le débogage dessine des lots de toutes les primitives pour réduire le nombre d'appels à RenderInterface , de sorte que le dessin ne se déroulera réellement qu'au moment où vous appelez dd::flush() , qui se fait normalement à la fin d'un cadre, avant de retourner les tampons d'écran:
// You only have to pass the current time if you have timed debug
// draws in the queues. Otherwise just omit the argument or pass 0.
dd::flush (getTimeMilliseconds());La configuration globale devrait donc ressembler à ce qui suit:
class MyRenderInterface : public dd ::RenderInterface
{
// Cherrypick the methods you want to implement or implement them all
...
};
int main ()
{
MyRenderInterface renderIface;
dd::initialize (&renderIface);
while (!quitting)
{
// Any other drawing that you already do
...
// Call any dd:: functions to add debug primitives to the draw queues
...
dd::flush ( getTimeMilliseconds ());
// Swap buffers to present the scene
...
}
dd::shutdown ();
} Debug Draw fournit plusieurs commutateurs de compilateur pour la configuration et la personnalisation de la bibliothèque. Consultez la documentation dans debug_draw.hpp pour une liste de tous les commutateurs plus une description détaillée de chacun.
La bibliothèque a très peu d'exigences linguistiques. L'un de ses principaux objectifs est d'être indolore à intégrer et portable. La seule exigence est un compilateur C ++ assez récent avec un support de bibliothèque standard minimal. Certaines fonctionnalités C ++ 11 sont supposées, telles que nullptr et <cstdint> . Les échantillons inclus utilisent plus lourds la bibliothèque standard C ++ pour démontrer l'utilisation de débogage de débogage avec des threads.
Les exceptions RTTI et C ++ ne sont pas utilisées , vous ne devez donc avoir aucun problème à intégrer la bibliothèque avec des projets qui désactivent ces fonctionnalités.
L'empreinte de la mémoire est également petite et vous pouvez gérer la quantité de mémoire qui s'engage dans les files d'attente internes via des directives de préprocesseur. Nous allons actuellement seulement une petite quantité de mémoire dynamique au démarrage de la bibliothèque pour décompresser les glyphes de police pour les fonctions de dessin de texte de débogage et pour les files d'attente de dessin et les données de contexte de la bibliothèque.
Par défaut, Debug Draw utilisera un contexte global statique en interne, fournissant une API de style procédural qui n'est pas sûr . Il s'agit du mode de dessin de débogage "classique" qui est le plus facile à utiliser et à configurer, mais la bibliothèque prend également en charge deux autres modes qui sont sûrs et configurables au moment de la compilation:
DEBUG_DRAW_PER_THREAD_CONTEXT : Si cela est défini avant l'implémentation, la bibliothèque utilisera un contexte de thread-local au lieu de la valeur par défaut partagée globale. Cela permet d'appeler la bibliothèque à partir de différents threads, car chacun conservera son contexte privé et dessinera des files d'attente. Ce mode fournit la même interface de bibliothèque publique mais nécessite une prise en charge TLS (Thread Local Storage) à partir du compilateur.
DEBUG_DRAW_EXPLICIT_CONTEXT : Si cela est défini avant l'implémentation, la bibliothèque s'attend à ce que l'utilisateur fournit une poignée à un contexte. Ce mode expose le type dd::ContextHandle et modifie chaque fonction de la bibliothèque pour prendre cette poignée comme premier argument. Ce mode rend la bibliothèque sans état, de sorte que chaque thread de rendu qui appelle dans la bibliothèque peut créer et maintenir sa propre instance de débogage.
Le mode de contexte explicite est une API plus propre et plus fonctionnelle et devrait être celle préférée pour les nouveaux utilisateurs. Le mode procédural est toujours conservé par défaut de compatibilité avec les versions de bibliothèque plus anciennes, mais il est recommandé d'utiliser le mode de contexte explicite en ajoutant #define DEBUG_DRAW_EXPLICIT_CONTEXT avec DEBUG_DRAW_IMPLEMENTATION . À l'avenir, l'API procédurale est déconseillée en faveur de la procédure explicite.
Dessin d'une boîte avec un ensemble de axes de coordonnées en son centre:
const ddVec3 boxColor = { 0 . 0f , 0 . 8f , 0 . 8f };
const ddVec3 boxCenter = { 0 . 0f , 0 . 0f , 3 . 0f };
dd::box (boxCenter, boxColor, 1 . 5f , 1 . 5f , 1 . 5f );
dd::cross (boxCenter, 1 . 0f ); Pour visualiser une transformée de matrice, vous pouvez utiliser dd::axisTriad() pour dessiner la transformée en trois flèches:
const ddMat4x4 transform = { // The identity matrix
1 . 0f , 0 . 0f , 0 . 0f , 0 . 0f ,
0 . 0f , 1 . 0f , 0 . 0f , 0 . 0f ,
0 . 0f , 0 . 0f , 1 . 0f , 0 . 0f ,
0 . 0f , 0 . 0f , 0 . 0f , 1 . 0f
};
dd::axisTriad (transform, 0 . 3f , 2 . 0f ); Des échantillons et des exemples plus complexes sur la façon d'intégrer le débogage de débogage avec votre propre rendu peuvent être trouvés à l'intérieur des samples/ répertoire. Chaque fonction fournie dans l'API publique est également bien documentée dans le fichier d'en-tête. Vous trouverez un commentaire d'en-tête descriptif avant le prototype de chaque fonction publique exportée par la bibliothèque.