Ein sofortiger Mode, Renderer Agnostic, Leichtes Debugg-API für C ++.
Diese Software ist gemeinfrei. Wenn diese Einweihung nicht anerkannt wird, erhalten Sie eine ewige, unwiderrufliche Lizenz zum Kopieren, Verteilern und Ändern des Quellcodes, wie Sie es für angepasst halten.
Der Quellcode wird ohne Garantie jeglicher Art "ausdrücklich oder stillschweigend" bereitgestellt. Es ist keine Zuordnung erforderlich, aber eine Erwähnung der Autoren wird geschätzt.
Debug -Draw ist eine einzelne Quelldateibibliothek, sodass die "Header" -Pedierungserklärungen und die Implementierung in derselben Datei enthalten sind ( debug_draw.hpp ). Dies sollte den Einsatz und die Integration in Ihre eigenen Projekte erleichtern. Alles, was Sie tun müssen, ist, die Bibliotheksdatei in einer Ihrer eigenen Quelldateien #include und definieren Sie DEBUG_DRAW_IMPLEMENTATION in dieser Datei, um die Implementierung zu generieren. Sie können auch die Bibliothek auch an anderen Stellen einbeziehen. Wenn DEBUG_DRAW_IMPLEMENTATION nicht definiert ist, wirkt sie als normale C ++ - Header -Datei. Beispiel:
In my_program.cpp :
# define DEBUG_DRAW_IMPLEMENTATION
# include " debug_draw.hpp " Jetzt in my_program.hpp oder einer anderen Header oder einer anderen Quelldatei können Sie sie als normaler C ++ - Header einfügen:
# include " debug_draw.hpp "Das war's, Sie sollten jetzt in der Lage sein, Debuggen in Ihre eigene Bewerbung aufzubauen.
Debug -Draw macht keine Annahmen über die unterliegende Renderer -API, daher kann sie sehr einfach in Direct3D oder OpenGL oder eine andere Rendering -Engine Ihrer Wahl integriert werden. Alles, was erforderlich ist, ist, dass Sie eine Implementierung für die dd::RenderInterface -Abstract -Klasse bereitstellen, die Debug -Zeichnen mit grundlegenden Methoden zum Zeichnen von Punkten, Linien und Zeichenglyphen bietet. Das Folgende ist, wie dd::RenderInterface aussieht:
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 ;
}; Nicht alle Methoden müssen implementiert werden, Sie entscheiden, welche Funktionen zu unterstützen sind! Schauen Sie sich den Quellcode zur Deklaration von RenderInterface an. Jede Methode ist gut kommentiert und beschreibt das erwartete Verhalten, das Sie implementieren sollten. Referenzimplementierungen des RenderInterface unter Verwendung von Standard -APIs wie OpenGL finden Sie in diesem Projekt im samples/ Verzeichnis.
Sobald Sie ein RenderInterface für Ihren Renderer implementiert haben, müssen Sie vor dem Gebrauch von Debug -Draw alles tun, um dd::initialize() einen Zeiger auf Ihr benutzerdefiniertes RenderInterface zu übergeben:
MyRenderInterface renderIface;
dd::initialize (&renderIface); Beachten Sie jedoch, dass Debugg -Zeichnen alle Primitiven zur Reduzierung der Anzahl der Aufrufe zum RenderInterface stellt. Daher erfolgt das Zeichnen nur bis zum Zeitpunkt des Aufrufens von dd::flush() , was normalerweise am Ende eines Rahmens durchgeführt wird, bevor Sie die Bildschirmpuffer drehen:
// 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());Das Gesamt -Setup sollte also ungefähr wie folgt aussehen:
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 bietet mehrere Compiler -Switches für die Konfiguration und Anpassung der Bibliothek. Überprüfen Sie die Dokumentation in debug_draw.hpp auf eine Liste aller Switches sowie eine detaillierte Beschreibung der einzelnen.
Die Bibliothek hat nur sehr wenige Sprachanforderungen. Eines seiner Hauptziele ist es, schmerzlos zu integrieren und tragbar zu sein. Die einzige Anforderung ist ein ziemlich neuer C ++ - Compiler mit minimaler Standardbibliotheksunterstützung. Einige C ++ 11 -Funktionen werden angenommen, wie nullptr und <cstdint> . Die enthaltenen Proben nutzen die C ++ - Standardbibliothek eine höhere Verwendung, um die Debug -Zeichnung mit Threads zu demonstrieren.
RTTI- und C ++ - Ausnahmen werden nicht verwendet , daher sollten Sie keine Probleme haben, die Bibliothek mit Projekten zu integrieren, die diese Funktionen deaktivieren.
Der Speicher Fußabdruck ist ebenfalls klein und Sie können die Speichermenge verwalten, die über die Anweisungen für Präprozessoren für die internen Warteschlangen verpflichtet wird. Derzeit plündern wir beim Start der Bibliothek nur eine kleine Menge dynamischer Speicher, um die Schriftglyphen für die Debug -Textzeichnungsfunktionen und für die Zeichnung von Warteschlangen und Bibliothekskontextdaten zu dekomprimieren.
Standardmäßig wird Debug-Draw einen statischen globalen Kontext intern verwenden und eine API im prozeduralen Stil bereitstellen, die nicht sicher ist . Dies ist der "klassische" Debug -Zeichnungsmodus, der am einfachsten zu verwenden und eingerichtet zu werden, aber die Bibliothek unterstützt auch zwei weitere Modi, die zum Kompilierzeit sicher und konfigurierbar sind:
DEBUG_DRAW_PER_THREAD_CONTEXT : Wenn dies vor der Implementierung definiert ist, verwendet die Bibliothek einen Thread-lokalen Kontext anstelle des globalen freigegebenen Standards. Dies ermöglicht es, die Bibliothek aus verschiedenen Threads zu rufen, da jeder ihren privaten Kontext führt und Warteschlangen zeichnet. Dieser Modus bietet dieselbe öffentliche Bibliotheksschnittstelle, erfordert jedoch den TLS -Support (Thread Local Storage) vom Compiler.
DEBUG_DRAW_EXPLICIT_CONTEXT : Wenn dies vor der Implementierung definiert ist, erwartet die Bibliothek, dass der Benutzer einen Handle für einen Kontext liefert. In diesem Modus wird der Typ dd::ContextHandle enthüllt und ändert jede Funktion in der Bibliothek, um diesen Handle als erstes Argument zu nutzen. In diesem Modus wird die Bibliothek vollständig staatenlos, so dass jeder Rendering -Thread, der in die Bibliothek aufruft, eine eigene Instanz des Debug -Zeichnungss erstellen und verwalten kann.
Der explizite Kontextmodus ist eine sauberere und mehr API im funktionalen Stil und sollte für neue Benutzer bevorzugt sein. Der Verfahrensmodus wird weiterhin als Standard für die Kompatibilität mit älteren Bibliotheksversionen aufbewahrt. Es wird jedoch empfohlen, den expliziten Kontextmodus zu verwenden, indem Sie #define DEBUG_DRAW_EXPLICIT_CONTEXT zusammen mit DEBUG_DRAW_IMPLEMENTATION hinzufügen. In Zukunft wird die prozedurale staatliche API zugunsten des expliziten veraltet.
Zeichnen einer Box mit einer Reihe von Koordinatenachsen in der Mitte:
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 ); Um eine Matrix -Transformation zu visualisieren, können Sie dd::axisTriad() verwenden, um die Transformation als drei Pfeile zu zeichnen:
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 ); Komplexere Proben und Beispiele zur Integration von Debug -Ziehungen mit Ihrem eigenen Renderer finden Sie in den samples/ Verzeichnissen. Jede in der öffentliche API bereitgestellte Funktion ist auch in der Header -Datei gut dokumentiert. Sie finden einen beschreibenden Header -Kommentar, bevor der von der Bibliothek exportierte Prototyp jeder öffentlichen Funktion.