Uma API de Debug leve e de depuração leve, de modo imediato, para C ++.
Este software está em domínio público. Onde essa dedicação não é reconhecida, você recebe uma licença perpétua e irrevogável para copiar, distribuir e modificar o código -fonte como você achar adequado.
O código -fonte é fornecido "como está", sem garantia de qualquer tipo, expresso ou implícito. Nenhuma atribuição é necessária, mas uma menção sobre o (s) autor (s) é apreciada.
O Debug Draw é uma biblioteca de arquivos de origem única; portanto, as declarações de avanço "cabeçalho" e a implementação estão contidas no mesmo arquivo ( debug_draw.hpp ). Isso deve facilitar a implantação e a integração com seus próprios projetos. Tudo o que você precisa fazer é #include o arquivo da biblioteca em um de seus próprios arquivos de origem e definir DEBUG_DRAW_IMPLEMENTATION nesse arquivo para gerar a implementação. Você também pode incluir a biblioteca em outros lugares. Quando DEBUG_DRAW_IMPLEMENTATION não é definido, ele atua como um arquivo de cabeçalho C ++ normal. Exemplo:
Em my_program.cpp :
# define DEBUG_DRAW_IMPLEMENTATION
# include " debug_draw.hpp " Agora em my_program.hpp ou em qualquer outro cabeçalho ou arquivo de origem, você pode incluí -lo como um cabeçalho C ++ normal:
# include " debug_draw.hpp "É isso, agora você deve ser capaz de criar a depuração em seu próprio aplicativo.
O Debug Draw não faz suposições sobre a API de renderizador subjacente, por isso pode ser integrada com muita facilidade com o Direct3D ou OpenGL ou qualquer outro mecanismo de renderização de sua escolha. Tudo o que é necessário é que você forneça uma implementação para a classe abstrata dd::RenderInterface , que fornece Depuração com métodos básicos para desenhar pontos, linhas e glifos de caracteres. A seguir, é como se parece 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 ;
}; Nem todos os métodos precisam ser implementados, você decide quais recursos suportar! Procure o código -fonte para a declaração de RenderInterface . Cada método é bem comentado e descreve o comportamento esperado que você deve implementar. Para implementações de referência da RenderInterface usando APIs padrão como o OpenGL, consulte as samples/ diretório neste projeto.
Depois de implementar um RenderInterface para o seu renderizador, tudo o que você precisa fazer antes de começar a usar o Debug Draw é ligar para dd::initialize() , passando um ponteiro para o seu RenderInterface personalizado:
MyRenderInterface renderIface;
dd::initialize (&renderIface); Observe, no entanto, que o Debug Draw lotes de todos os primitivos para reduzir o número de chamadas para RenderInterface , portanto, o desenho só ocorrerá quando você ligar dd::flush() , que normalmente é feito no final de um quadro, antes de lançar os buffers de tela:
// 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());Portanto, a configuração geral deve se parecer com o seguinte:
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 ();
} O Debug Draw fornece vários comutadores do compilador para configuração e personalização da biblioteca. Verifique a documentação em debug_draw.hpp para obter uma lista de todos os comutadores e descrição detalhada de cada um.
A biblioteca possui muito poucos requisitos de idioma. Um de seus principais objetivos é ser indolor para integrar e portátil. O único requisito é um compilador C ++ bastante recente com suporte mínimo de biblioteca padrão. Alguns recursos C ++ 11 são assumidos, como nullptr e <cstdint> . As amostras incluídas fazem uso mais pesado da biblioteca padrão C ++ para demonstrar o uso de depuração com threads.
As exceções RTTI e C ++ não são usadas ; portanto, você não deve ter problemas para integrar a biblioteca com projetos que desativam esses recursos.
A pegada de memória também é pequena e você pode gerenciar a quantidade de memória que se compromete com as filas internas por meio de diretivas de pré -processador. Atualmente, alocamos apenas uma pequena quantidade de memória dinâmica na inicialização da biblioteca para descomprimir os glifos de fonte para as funções de desenho de texto de depuração e para as filas de desenho e dados de contexto da biblioteca.
Por padrão, o Debug Draw usará um contexto global estático internamente, fornecendo uma API de estilo processual que não é seguro . Este é o modo de desenho de depuração "clássico" que é o mais fácil de usar e configurar, mas a biblioteca também suporta outros dois modos que são seguros e configuráveis no horário de compilação:
DEBUG_DRAW_PER_THREAD_CONTEXT : Se isso for definido antes da implementação, a biblioteca usará um contexto local de Thread em vez do padrão compartilhado global. Isso permite chamar a biblioteca de diferentes threads, pois cada um manterá seu contexto privado e desenhará filas. Este modo fornece a mesma interface da biblioteca pública, mas requer o suporte TLS (Thread Storage Local) do compilador.
DEBUG_DRAW_EXPLICIT_CONTEXT : Se isso for definido antes da implementação, a biblioteca espera que o usuário forneça um identificador a um contexto. Este modo expõe o tipo dd::ContextHandle e altera cada função na biblioteca para considerar esse identificador como o primeiro argumento. Esse modo torna a biblioteca totalmente apátrida, para que cada encadeamento de renderização que chama a biblioteca possa criar e manter sua própria instância de Debug Draw.
O modo de contexto explícito é uma API mais limpa e mais funcional e deve ser a preferida para novos usuários. O modo processual ainda é mantido como padrão para compatibilidade com versões mais antigas da biblioteca, mas é recomendável que você use o modo de contexto explícito, adicionando #define DEBUG_DRAW_EXPLICIT_CONTEXT juntamente com DEBUG_DRAW_IMPLEMENTATION . No futuro, a API de Estado processual será preterida em favor do explícito.
Desenhando uma caixa com um conjunto de eixos de coordenadas em seu centro:
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 ); Para visualizar uma transformação da matriz, você pode usar dd::axisTriad() para desenhar a transformação como três setas:
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 ); Amostras e exemplos mais complexos sobre como integrar o Debug Draw com seu próprio renderizador podem ser encontrados dentro das samples/ diretório. Cada função fornecida na API pública também está bem documentada no arquivo de cabeçalho. Você encontrará um comentário descritivo do cabeçalho antes do protótipo de cada função pública exportada pela biblioteca.