forked from glampert/debug-draw
-
Notifications
You must be signed in to change notification settings - Fork 0
/
debug_draw.hpp
3294 lines (2946 loc) · 135 KB
/
debug_draw.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
// ================================================================================================
// -*- C++ -*-
// File: debug_draw.hpp
// Author: Guilherme R. Lampert
// Brief: Debug Draw - an immediate-mode, renderer agnostic, lightweight debug drawing API.
// ================================================================================================
#ifndef DEBUG_DRAW_HPP
#define DEBUG_DRAW_HPP
// ========================================================
// Library Overview:
// ========================================================
//
// ---------
// LICENSE
// ---------
// This software is in the public domain. Where that dedication is not recognized,
// you are granted a perpetual, irrevocable license to copy, distribute, and modify
// this file as you see fit.
//
// The source code is provided "as is", without warranty of any kind, express or implied.
// No attribution is required, but a mention about the author(s) is appreciated.
//
// -------------
// QUICK SETUP
// -------------
// In *one* C++ source file, *before* including this file, do this:
//
// #define DEBUG_DRAW_IMPLEMENTATION
//
// To enable the implementation. Further includes of this
// file *should not* redefine DEBUG_DRAW_IMPLEMENTATION.
// Example:
//
// In my_program.cpp:
//
// #define DEBUG_DRAW_IMPLEMENTATION
// #include "debug_draw.hpp"
//
// In my_program.hpp:
//
// #include "debug_draw.hpp"
//
// ----------------------
// COMPILATION SWITCHES
// ----------------------
//
// DEBUG_DRAW_CXX11_SUPPORTED
// Enables the use of some C++11 features. If your compiler supports C++11
// or better, you should define this switch globally or before every inclusion
// of this file. If it is not defined, we try to guess it from the value of the
// '__cplusplus' built-in macro constant.
//
// DEBUG_DRAW_MAX_*
// Sizes of internal intermediate buffers, which are allocated on initialization
// by the implementation. If you need to draw more primitives than the sizes of
// these buffers, you need to redefine the macros and recompile.
//
// DEBUG_DRAW_VERTEX_BUFFER_SIZE
// Size in dd::DrawVertex elements of the intermediate vertex buffer used
// to batch primitives before sending them to dd::RenderInterface. A bigger
// buffer will reduce the number of calls to dd::RenderInterface when drawing
// large sets of debug primitives.
//
// DEBUG_DRAW_OVERFLOWED(message)
// An error handler called if any of the DEBUG_DRAW_MAX_* sizes overflow.
// By default it just prints a message to stderr.
//
// DEBUG_DRAW_USE_STD_MATH
// If defined to nonzero, uses cmath/math.h. If you redefine it to zero before
// the library implementation, it will force the use of local replacements
// for the Standard Library. This might be useful if you want to avoid the
// dependency. It is defined to zero by default (i.e. we use cmath by default).
//
// DEBUG_DRAW_*_TYPE_DEFINED
// The compound types used by Debug Draw can also be customized.
// By default, ddVec3 and ddMat4x4 are plain C-arrays, but you can
// redefine them to use your own classes or structures (see below).
// ddStr is by default a std::string, but you can redefine it to
// a custom string type if necessary. The only requirements are that
// it provides a 'c_str()' method returning a null terminated
// const char* string and an assignment operator (=).
//
// DEBUG_DRAW_STR_DEALLOC_FUNC(str)
// If you define a custom string type for ddStr and it requires some
// extra cleanup besides the class destructor, you might define this
// function macro to perform said cleanup. It is called by dd::clear()
// and dd::shutdown() on every instance of the internal DebugString buffer.
//
// DEBUG_DRAW_NO_DEFAULT_COLORS
// If defined, doesn't add the set of predefined color constants inside
// dd::colors:: namespace. Each color is a ddVec3, so you can define this
// to prevent adding more global data to the binary if you don't need them.
//
// DEBUG_DRAW_PER_THREAD_CONTEXT
// If defined, a per-thread global context will be created for Debug Draw.
// This allows having an instance of the library for each thread in
// your application. You must then call initialize/shutdown/flush/etc
// for each thread that wishes to use the library. If this is not
// defined it defaults to a single threaded global context.
//
// DEBUG_DRAW_EXPLICIT_CONTEXT
// If defined, each Debug Draw function will expect and additional argument
// (the first one) which is the library context instance. This is an alternative
// to DEBUG_DRAW_PER_THREAD_CONTEXT to allow having multiple instances of the
// library in the same application. This flag is mutually exclusive with
// DEBUG_DRAW_PER_THREAD_CONTEXT.
//
// -------------------
// MEMORY ALLOCATION
// -------------------
// Debug Draw will only perform a couple of memory allocations during startup to decompress
// the built-in glyph bitmap used for debug text rendering and to allocate the vertex buffers
// and intermediate draw/batch buffers and context data used internally.
//
// Memory allocation and deallocation for Debug Draw will be done via:
//
// DD_MALLOC(size)
// DD_MFREE(ptr)
//
// These two macros can be redefined if you'd like to supply you own memory allocator.
// By default, they are defined to use std::malloc and std::free, respectively.
// Note: If you redefine one, you must also provide the other.
//
// --------------------------------
// INTERFACING WITH YOUR RENDERER
// --------------------------------
// Debug Draw doesn't touch on any renderer-specific aspects or APIs, instead you provide
// the library with all of it's rendering needs via the dd::RenderInterface abstract class.
//
// See the declaration of dd::RenderInterface for details. Not all methods are
// required. In fact, you could also implement a full no-op RenderInterface that
// disables debug drawing by simply inheriting from dd::RenderInterface and not overriding
// any of the methods (or even easier, call dd::initialize(nullptr) to make everything a no-op).
//
// For examples on how to implement your own dd::RenderInterface, see the accompanying samples.
// You can also find them in the source code repository for this project:
// https://github.com/glampert/debug-draw
//
// ------------------
// CONVENTIONS USED
// ------------------
// Points and lines are always specified in world-space positions. This also
// applies to shapes drawn from lines, like boxes, spheres, cones, etc.
//
// 2D screen-text is in screen-space pixels (from 0,0 in the upper-left
// corner of the screen to screen_width-1 and screen_height-1).
// RenderInterface::drawGlyphList() also receives vertexes in screen-space.
//
// We make some usage of matrices for things like the projected text labels.
// Matrix layout used is column-major and vectors multiply as columns.
// This is the convention normally used by standard OpenGL.
//
// C++ Exceptions are not used. Little error checking is provided or
// done inside the library. We favor simpler, faster and easier to maintain
// code over more sophisticated error handling. The rationale is that a
// debug drawing API doesn't have to be very robust, since it won't make
// into the final release executable in most cases.
//
// ========================================================
// Configurable compilation switches:
// ========================================================
//
// If the user didn't specify if C++11 or above are supported, try to guess
// from the value of '__cplusplus'. It should be 199711L for pre-C++11 compilers
// and 201103L in those supporting C++11, but this is not a guarantee that all
// C++11 features will be available and stable, so again, we are making a guess.
// It is recommended to instead supply the DEBUG_DRAW_CXX11_SUPPORTED switch
// yourself before including this file.
//
#ifndef DEBUG_DRAW_CXX11_SUPPORTED
#if (__cplusplus > 199711L)
#define DEBUG_DRAW_CXX11_SUPPORTED 1
#endif // __cplusplus
#endif // DEBUG_DRAW_CXX11_SUPPORTED
//
// Max elements of each type at any given time.
// We supply these reasonable defaults, but you can provide your
// own tunned values to save memory or fit all of your debug data.
// These are hard constraints. If not enough, change and recompile.
//
#ifndef DEBUG_DRAW_MAX_STRINGS
#define DEBUG_DRAW_MAX_STRINGS 512
#endif // DEBUG_DRAW_MAX_STRINGS
#ifndef DEBUG_DRAW_MAX_POINTS
#define DEBUG_DRAW_MAX_POINTS 8192
#endif // DEBUG_DRAW_MAX_POINTS
#ifndef DEBUG_DRAW_MAX_LINES
#define DEBUG_DRAW_MAX_LINES 32768
#endif // DEBUG_DRAW_MAX_LINES
//
// Size in vertexes of a local buffer we use to sort elements
// drawn with and without depth testing before submitting them to
// the dd::RenderInterface. A larger buffer will require less flushes
// (e.g. dd::RenderInterface calls) when drawing large amounts of
// primitives. Less will obviously save more memory. Each DrawVertex
// is about 32 bytes in size, we keep a context-specific array
// with this many entries.
//
#ifndef DEBUG_DRAW_VERTEX_BUFFER_SIZE
#define DEBUG_DRAW_VERTEX_BUFFER_SIZE 4096
#endif // DEBUG_DRAW_VERTEX_BUFFER_SIZE
//
// This macro is called with an error message if any of the above
// sizes is overflowed during runtime. In a debug build, you might
// keep this enabled to be able to log and find out if more space
// is needed for the debug data arrays. Default output is stderr.
//
#ifndef DEBUG_DRAW_OVERFLOWED
#include <cstdio>
#define DEBUG_DRAW_OVERFLOWED(message) std::fprintf(stderr, "%s\n", message)
#endif // DEBUG_DRAW_OVERFLOWED
//
// Use <math.h> and <float.h> for trigonometry functions by default.
// If you wish to avoid those dependencies, DD provides local approximations
// of the required functions as a portable replacement. Just define
// DEBUG_DRAW_USE_STD_MATH to zero before including this file.
//
#ifndef DEBUG_DRAW_USE_STD_MATH
#define DEBUG_DRAW_USE_STD_MATH 1
#endif // DEBUG_DRAW_USE_STD_MATH
// ========================================================
// Overridable Debug Draw types:
// ========================================================
#include <cstddef>
#include <cstdint>
//
// Following typedefs are not members of the dd:: namespace to allow easy redefinition by the user.
// If you provide a custom implementation for them before including this file, be sure to
// also define the proper DEBUG_DRAW_*_TYPE_DEFINED switch to disable the default typedefs.
//
// The only requirement placed on the vector/matrix types is that they provide
// an array subscript operator [] and have the expected number of elements. Apart
// from that, they could be structs, classes, what-have-you. POD types are recommended
// but not mandatory.
//
#ifndef DEBUG_DRAW_VEC3_TYPE_DEFINED
// ddVec3:
// A small array of floats with at least three elements, but
// it could have more for alignment purposes, extra slots are ignored.
// A custom ddVec3 type must provide the array subscript operator.
typedef float ddVec3[3];
// ddVec3_In/ddVec3_Out:
// Since our default ddVec3 is a plain C-array, it decays to a pointer
// when passed as an input parameter to a function, so we can use it directly.
// If you change it to some structured type, it might be more efficient
// passing by const reference instead, however, some platforms have optimized
// hardware registers for vec3s/vec4s, so passing by value might also be efficient.
typedef const ddVec3 ddVec3_In;
typedef ddVec3 ddVec3_Out;
#define DEBUG_DRAW_VEC3_TYPE_DEFINED 1
#endif // DEBUG_DRAW_VEC3_TYPE_DEFINED
#ifndef DEBUG_DRAW_MAT4X4_TYPE_DEFINED
// ddMat4x4:
// Homogeneous matrix of 16 floats, representing rotations as well as
// translation/scaling and projections. The internal matrix layout used by this
// library is COLUMN-MAJOR, vectors multiplying as columns (usual OpenGL convention).
// Column-major matrix layout:
// c.0 c.1 c.2 c.3
// r.0 | 0.x 4.x 8.x 12.x |
// r.1 | 1.y 5.y 9.y 13.y |
// r.2 | 2.z 6.z 10.z 14.z |
// r.3 | 3.w 7.w 11.w 15.w |
// If your custom matrix type uses row-major format internally, you'll
// have to transpose them before passing your matrices to the DD functions.
// We use the array subscript operator internally, so it must also be provided.
typedef float ddMat4x4[4 * 4];
// ddMat4x4_In/ddMat4x4_Out:
// Since our default ddMat4x4 is a plain C-array, it decays to a pointer
// when passed as an input parameter to a function, so we can use it directly.
// If you change it to some structured type, it might be more efficient
// passing by const reference instead.
typedef const ddMat4x4 ddMat4x4_In;
typedef ddMat4x4 ddMat4x4_Out;
#define DEBUG_DRAW_MAT4X4_TYPE_DEFINED 1
#endif // DEBUG_DRAW_MAT4X4_TYPE_DEFINED
#ifndef DEBUG_DRAW_STRING_TYPE_DEFINED
// ddStr:
// String type used internally to store the debug text strings.
// A custom string type must provide at least an assignment
// operator (=) and a 'c_str()' method that returns a
// null-terminated const char* string pointer. That's it.
// An array subscript operator [] is not required for ddStr.
#include <string>
typedef std::string ddStr;
typedef const ddStr & ddStr_In;
typedef ddStr & ddStr_Out;
#define DEBUG_DRAW_STRING_TYPE_DEFINED 1
#endif // DEBUG_DRAW_STRING_TYPE_DEFINED
namespace dd
{
// ========================================================
// Optional built-in colors in RGB float format:
// ========================================================
#ifndef DEBUG_DRAW_NO_DEFAULT_COLORS
namespace colors
{
extern const ddVec3 AliceBlue;
extern const ddVec3 AntiqueWhite;
extern const ddVec3 Aquamarine;
extern const ddVec3 Azure;
extern const ddVec3 Beige;
extern const ddVec3 Bisque;
extern const ddVec3 Black;
extern const ddVec3 BlanchedAlmond;
extern const ddVec3 Blue;
extern const ddVec3 BlueViolet;
extern const ddVec3 Brown;
extern const ddVec3 BurlyWood;
extern const ddVec3 CadetBlue;
extern const ddVec3 Chartreuse;
extern const ddVec3 Chocolate;
extern const ddVec3 Coral;
extern const ddVec3 CornflowerBlue;
extern const ddVec3 Cornsilk;
extern const ddVec3 Crimson;
extern const ddVec3 Cyan;
extern const ddVec3 DarkBlue;
extern const ddVec3 DarkCyan;
extern const ddVec3 DarkGoldenRod;
extern const ddVec3 DarkGray;
extern const ddVec3 DarkGreen;
extern const ddVec3 DarkKhaki;
extern const ddVec3 DarkMagenta;
extern const ddVec3 DarkOliveGreen;
extern const ddVec3 DarkOrange;
extern const ddVec3 DarkOrchid;
extern const ddVec3 DarkRed;
extern const ddVec3 DarkSalmon;
extern const ddVec3 DarkSeaGreen;
extern const ddVec3 DarkSlateBlue;
extern const ddVec3 DarkSlateGray;
extern const ddVec3 DarkTurquoise;
extern const ddVec3 DarkViolet;
extern const ddVec3 DeepPink;
extern const ddVec3 DeepSkyBlue;
extern const ddVec3 DimGray;
extern const ddVec3 DodgerBlue;
extern const ddVec3 FireBrick;
extern const ddVec3 FloralWhite;
extern const ddVec3 ForestGreen;
extern const ddVec3 Gainsboro;
extern const ddVec3 GhostWhite;
extern const ddVec3 Gold;
extern const ddVec3 GoldenRod;
extern const ddVec3 Gray;
extern const ddVec3 Green;
extern const ddVec3 GreenYellow;
extern const ddVec3 HoneyDew;
extern const ddVec3 HotPink;
extern const ddVec3 IndianRed;
extern const ddVec3 Indigo;
extern const ddVec3 Ivory;
extern const ddVec3 Khaki;
extern const ddVec3 Lavender;
extern const ddVec3 LavenderBlush;
extern const ddVec3 LawnGreen;
extern const ddVec3 LemonChiffon;
extern const ddVec3 LightBlue;
extern const ddVec3 LightCoral;
extern const ddVec3 LightCyan;
extern const ddVec3 LightGoldenYellow;
extern const ddVec3 LightGray;
extern const ddVec3 LightGreen;
extern const ddVec3 LightPink;
extern const ddVec3 LightSalmon;
extern const ddVec3 LightSeaGreen;
extern const ddVec3 LightSkyBlue;
extern const ddVec3 LightSlateGray;
extern const ddVec3 LightSteelBlue;
extern const ddVec3 LightYellow;
extern const ddVec3 Lime;
extern const ddVec3 LimeGreen;
extern const ddVec3 Linen;
extern const ddVec3 Magenta;
extern const ddVec3 Maroon;
extern const ddVec3 MediumAquaMarine;
extern const ddVec3 MediumBlue;
extern const ddVec3 MediumOrchid;
extern const ddVec3 MediumPurple;
extern const ddVec3 MediumSeaGreen;
extern const ddVec3 MediumSlateBlue;
extern const ddVec3 MediumSpringGreen;
extern const ddVec3 MediumTurquoise;
extern const ddVec3 MediumVioletRed;
extern const ddVec3 MidnightBlue;
extern const ddVec3 MintCream;
extern const ddVec3 MistyRose;
extern const ddVec3 Moccasin;
extern const ddVec3 NavajoWhite;
extern const ddVec3 Navy;
extern const ddVec3 OldLace;
extern const ddVec3 Olive;
extern const ddVec3 OliveDrab;
extern const ddVec3 Orange;
extern const ddVec3 OrangeRed;
extern const ddVec3 Orchid;
extern const ddVec3 PaleGoldenRod;
extern const ddVec3 PaleGreen;
extern const ddVec3 PaleTurquoise;
extern const ddVec3 PaleVioletRed;
extern const ddVec3 PapayaWhip;
extern const ddVec3 PeachPuff;
extern const ddVec3 Peru;
extern const ddVec3 Pink;
extern const ddVec3 Plum;
extern const ddVec3 PowderBlue;
extern const ddVec3 Purple;
extern const ddVec3 RebeccaPurple;
extern const ddVec3 Red;
extern const ddVec3 RosyBrown;
extern const ddVec3 RoyalBlue;
extern const ddVec3 SaddleBrown;
extern const ddVec3 Salmon;
extern const ddVec3 SandyBrown;
extern const ddVec3 SeaGreen;
extern const ddVec3 SeaShell;
extern const ddVec3 Sienna;
extern const ddVec3 Silver;
extern const ddVec3 SkyBlue;
extern const ddVec3 SlateBlue;
extern const ddVec3 SlateGray;
extern const ddVec3 Snow;
extern const ddVec3 SpringGreen;
extern const ddVec3 SteelBlue;
extern const ddVec3 Tan;
extern const ddVec3 Teal;
extern const ddVec3 Thistle;
extern const ddVec3 Tomato;
extern const ddVec3 Turquoise;
extern const ddVec3 Violet;
extern const ddVec3 Wheat;
extern const ddVec3 White;
extern const ddVec3 WhiteSmoke;
extern const ddVec3 Yellow;
extern const ddVec3 YellowGreen;
} // namespace colors
#endif // DEBUG_DRAW_NO_DEFAULT_COLORS
// ========================================================
// Optional explicit context mode:
// ========================================================
#ifdef DEBUG_DRAW_EXPLICIT_CONTEXT
struct OpaqueContextType { };
typedef OpaqueContextType * ContextHandle;
#define DD_EXPLICIT_CONTEXT_ONLY(...) __VA_ARGS__
#else // !DEBUG_DRAW_EXPLICIT_CONTEXT
#define DD_EXPLICIT_CONTEXT_ONLY(...) /* nothing */
#endif // DEBUG_DRAW_EXPLICIT_CONTEXT
// ========================================================
// Debug Draw functions:
// - Durations are always in milliseconds.
// - Colors are RGB floats in the [0,1] range.
// - Positions are in world-space, unless stated otherwise.
// ========================================================
// Add a point in 3D space to the debug draw queue.
// Point is expressed in world-space coordinates.
// Note that not all renderer support configurable point
// size, so take the 'size' parameter as a hint only
void point(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In pos,
ddVec3_In color,
float size = 1.0f,
int durationMillis = 0,
bool depthEnabled = true);
// Add a 3D line to the debug draw queue. Note that
// lines are expressed in world coordinates, and so are
// all wireframe primitives which are built from lines.
void line(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In from,
ddVec3_In to,
ddVec3_In color,
int durationMillis = 0,
bool depthEnabled = true);
// Add a 2D text string as an overlay to the current view, using a built-in font.
// Position is in screen-space pixels, origin at the top-left corner of the screen.
// The third element (Z) of the position vector is ignored.
// Note: Newlines and tabs are handled (1 tab = 4 spaces).
void screenText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
const char * str,
ddVec3_In pos,
ddVec3_In color,
float scaling = 1.0f,
int durationMillis = 0);
// Add a 3D text label centered at the given world position that
// gets projected to screen-space. The label always faces the viewer.
// sx/sy, sw/sh are the viewport coordinates/size, in pixels.
// 'vpMatrix' is the view * projection transform to map the text from 3D to 2D.
void projectedText(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
const char * str,
ddVec3_In pos,
ddVec3_In color,
ddMat4x4_In vpMatrix,
int sx, int sy,
int sw, int sh,
float scaling = 1.0f,
int durationMillis = 0);
// Add a set of three coordinate axis depicting the position and orientation of the given transform.
// 'size' defines the size of the arrow heads. 'length' defines the length of the arrow's base line.
void axisTriad(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddMat4x4_In transform,
float size,
float length,
int durationMillis = 0,
bool depthEnabled = true);
// Add a 3D line with an arrow-like end to the debug draw queue.
// 'size' defines the arrow head size. 'from' and 'to' the length of the arrow's base line.
void arrow(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In from,
ddVec3_In to,
ddVec3_In color,
float size,
int durationMillis = 0,
bool depthEnabled = true);
// Add an axis-aligned cross (3 lines converging at a point) to the debug draw queue.
// 'length' defines the length of the crossing lines.
// 'center' is the world-space point where the lines meet.
void cross(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In center,
float length,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe circle to the debug draw queue.
void circle(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In center,
ddVec3_In planeNormal,
ddVec3_In color,
float radius,
float numSteps,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe plane in 3D space to the debug draw queue.
// If 'normalVecScale' is not zero, a line depicting the plane normal is also draw.
void plane(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In center,
ddVec3_In planeNormal,
ddVec3_In planeColor,
ddVec3_In normalVecColor,
float planeScale,
float normalVecScale,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe sphere to the debug draw queue.
void sphere(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In center,
ddVec3_In color,
float radius,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe cone to the debug draw queue.
// The cone 'apex' is the point where all lines meet.
// The length of the 'dir' vector determines the thickness.
// 'baseRadius' & 'apexRadius' are in degrees.
void cone(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In apex,
ddVec3_In dir,
ddVec3_In color,
float baseRadius,
float apexRadius,
int durationMillis = 0,
bool depthEnabled = true);
// Wireframe box from the eight points that define it.
void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
const ddVec3 points[8],
ddVec3_In color,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe box to the debug draw queue.
void box(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In center,
ddVec3_In color,
float width,
float height,
float depth,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe Axis Aligned Bounding Box (AABB) to the debug draw queue.
void aabb(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In mins,
ddVec3_In maxs,
ddVec3_In color,
int durationMillis = 0,
bool depthEnabled = true);
// Add a wireframe frustum pyramid to the debug draw queue.
// 'invClipMatrix' is the inverse of the matrix defining the frustum
// (AKA clip) volume, which normally consists of the projection * view matrix.
// E.g.: inverse(projMatrix * viewMatrix)
void frustum(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddMat4x4_In invClipMatrix,
ddVec3_In color,
int durationMillis = 0,
bool depthEnabled = true);
// Add a vertex normal for debug visualization.
// The normal vector 'normal' is assumed to be already normalized.
void vertexNormal(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In origin,
ddVec3_In normal,
float length,
int durationMillis = 0,
bool depthEnabled = true);
// Add a "tangent basis" at a given point in world space.
// Color scheme used is: normal=WHITE, tangent=YELLOW, bi-tangent=MAGENTA.
// The normal vector, tangent and bi-tangent vectors are assumed to be already normalized.
void tangentBasis(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
ddVec3_In origin,
ddVec3_In normal,
ddVec3_In tangent,
ddVec3_In bitangent,
float lengths,
int durationMillis = 0,
bool depthEnabled = true);
// Makes a 3D square grid of lines along the X and Z planes.
// 'y' defines the height in the Y axis where the grid is placed.
// The grid will go from 'mins' to 'maxs' units in both the X and Z.
// 'step' defines the gap between each line of the grid.
void xzSquareGrid(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
float mins,
float maxs,
float y,
float step,
ddVec3_In color,
int durationMillis = 0,
bool depthEnabled = true);
// ========================================================
// Debug Draw vertex type:
// The only drawing type the user has to interface with.
// ========================================================
union DrawVertex
{
struct
{
float x, y, z;
float r, g, b;
float size;
} point;
struct
{
float x, y, z;
float r, g, b;
} line;
struct
{
float x, y;
float u, v;
float r, g, b;
} glyph;
};
//
// Opaque handle to a texture object.
// Used by the debug text drawing functions.
//
struct OpaqueTextureType { };
typedef OpaqueTextureType * GlyphTextureHandle;
// ========================================================
// Debug Draw rendering callbacks:
// Implementation is provided by the user so we don't
// tie this code directly to a specific rendering API.
// ========================================================
class RenderInterface
{
public:
//
// These are called by dd::flush() before any drawing and after drawing is finished.
// User can override these to perform any common setup for subsequent draws and to
// cleanup afterwards. By default, no-ops stubs are provided.
//
virtual void beginDraw();
virtual void endDraw();
//
// Create/free the glyph bitmap texture used by the debug text drawing functions.
// The debug renderer currently only creates one of those on startup.
//
// You're not required to implement these two if you don't care about debug text drawing.
// Default no-op stubs are provided by default, which disable debug text rendering.
//
// Texture dimensions are in pixels, data format is always 8-bits per pixel (Grayscale/GL_RED).
// The pixel values range from 255 for a pixel within a glyph to 0 for a transparent pixel.
// If createGlyphTexture() returns null, the renderer will disable all text drawing functions.
//
virtual GlyphTextureHandle createGlyphTexture(int width, int height, const void * pixels);
virtual void destroyGlyphTexture(GlyphTextureHandle glyphTex);
//
// Batch drawing methods for the primitives used by the debug renderer.
// If you don't wish to support a given primitive type, don't override the method.
//
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);
// User defined cleanup. Nothing by default.
virtual ~RenderInterface() = 0;
};
// ========================================================
// Housekeeping functions:
// ========================================================
// Flags for dd::flush()
enum FlushFlags
{
FlushPoints = 1 << 1,
FlushLines = 1 << 2,
FlushText = 1 << 3,
FlushAll = (FlushPoints | FlushLines | FlushText)
};
// Initialize with the user-supplied renderer interface.
// Given object must remain valid until after dd::shutdown() is called!
// If 'renderer' is null, the Debug Draw functions become no-ops, but
// can still be safely called.
bool initialize(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle * outCtx,) RenderInterface * renderer);
// After this is called, it is safe to dispose the dd::RenderInterface instance
// you passed to dd::initialize(). Shutdown will also attempt to free the glyph texture.
void shutdown(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));
// Test if the Debug Draw library is currently initialized and has a render interface.
bool isInitialized(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));
// Test if there's data in the debug draw queue and dd::flush() should be called.
bool hasPendingDraws(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));
// Manually removes all queued debug render data without drawing.
// This is not normally called. To draw stuff, call dd::flush() instead.
void clear(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx));
// Actually calls the dd::RenderInterface to consume the debug draw queues.
// Objects that have expired their lifetimes get removed. Pass the current
// application time in milliseconds to remove timed objects that have expired.
// Passing zero removes all objects after they get drawn, regardless of lifetime.
void flush(DD_EXPLICIT_CONTEXT_ONLY(ContextHandle ctx,)
std::int64_t currTimeMillis = 0,
std::uint32_t flags = FlushAll);
} // namespace dd
// ================== End of header file ==================
#endif // DEBUG_DRAW_HPP
// ================== End of header file ==================
// ================================================================================================
//
// Debug Draw Implementation
//
// ================================================================================================
#ifdef DEBUG_DRAW_IMPLEMENTATION
#ifndef DD_MALLOC
#include <cstdlib>
#define DD_MALLOC std::malloc
#define DD_MFREE std::free
#endif // DD_MALLOC
#if DEBUG_DRAW_USE_STD_MATH
#include <math.h>
#include <float.h>
#endif // DEBUG_DRAW_USE_STD_MATH
namespace dd
{
#if defined(FLT_EPSILON) && DEBUG_DRAW_USE_STD_MATH
static const float FloatEpsilon = FLT_EPSILON;
#else // !FLT_EPSILON || !DEBUG_DRAW_USE_STD_MATH
static const float FloatEpsilon = 1e-14;
#endif // FLT_EPSILON && DEBUG_DRAW_USE_STD_MATH
#if defined(M_PI) && DEBUG_DRAW_USE_STD_MATH
static const float PI = M_PI;
#else // !M_PI || !DEBUG_DRAW_USE_STD_MATH
static const float PI = 3.1415926535897931f;
#endif // M_PI && DEBUG_DRAW_USE_STD_MATH
static const float HalfPI = PI * 0.5f;
static const float TAU = PI * 2.0f;
template<typename T>
static inline float degreesToRadians(const T degrees)
{
return (static_cast<float>(degrees) * PI / 180.0f);
}
template<typename T, int Size>
static inline int arrayLength(const T (&)[Size])
{
return Size;
}
// ========================================================
// Built-in color constants:
// ========================================================
#ifndef DEBUG_DRAW_NO_DEFAULT_COLORS
namespace colors
{
const ddVec3 AliceBlue = {0.941176f, 0.972549f, 1.000000f};
const ddVec3 AntiqueWhite = {0.980392f, 0.921569f, 0.843137f};
const ddVec3 Aquamarine = {0.498039f, 1.000000f, 0.831373f};
const ddVec3 Azure = {0.941176f, 1.000000f, 1.000000f};
const ddVec3 Beige = {0.960784f, 0.960784f, 0.862745f};
const ddVec3 Bisque = {1.000000f, 0.894118f, 0.768627f};
const ddVec3 Black = {0.000000f, 0.000000f, 0.000000f};
const ddVec3 BlanchedAlmond = {1.000000f, 0.921569f, 0.803922f};
const ddVec3 Blue = {0.000000f, 0.000000f, 1.000000f};
const ddVec3 BlueViolet = {0.541176f, 0.168627f, 0.886275f};
const ddVec3 Brown = {0.647059f, 0.164706f, 0.164706f};
const ddVec3 BurlyWood = {0.870588f, 0.721569f, 0.529412f};
const ddVec3 CadetBlue = {0.372549f, 0.619608f, 0.627451f};
const ddVec3 Chartreuse = {0.498039f, 1.000000f, 0.000000f};
const ddVec3 Chocolate = {0.823529f, 0.411765f, 0.117647f};
const ddVec3 Coral = {1.000000f, 0.498039f, 0.313726f};
const ddVec3 CornflowerBlue = {0.392157f, 0.584314f, 0.929412f};
const ddVec3 Cornsilk = {1.000000f, 0.972549f, 0.862745f};
const ddVec3 Crimson = {0.862745f, 0.078431f, 0.235294f};
const ddVec3 Cyan = {0.000000f, 1.000000f, 1.000000f};
const ddVec3 DarkBlue = {0.000000f, 0.000000f, 0.545098f};
const ddVec3 DarkCyan = {0.000000f, 0.545098f, 0.545098f};
const ddVec3 DarkGoldenRod = {0.721569f, 0.525490f, 0.043137f};
const ddVec3 DarkGray = {0.662745f, 0.662745f, 0.662745f};
const ddVec3 DarkGreen = {0.000000f, 0.392157f, 0.000000f};
const ddVec3 DarkKhaki = {0.741176f, 0.717647f, 0.419608f};
const ddVec3 DarkMagenta = {0.545098f, 0.000000f, 0.545098f};
const ddVec3 DarkOliveGreen = {0.333333f, 0.419608f, 0.184314f};
const ddVec3 DarkOrange = {1.000000f, 0.549020f, 0.000000f};
const ddVec3 DarkOrchid = {0.600000f, 0.196078f, 0.800000f};
const ddVec3 DarkRed = {0.545098f, 0.000000f, 0.000000f};
const ddVec3 DarkSalmon = {0.913725f, 0.588235f, 0.478431f};
const ddVec3 DarkSeaGreen = {0.560784f, 0.737255f, 0.560784f};
const ddVec3 DarkSlateBlue = {0.282353f, 0.239216f, 0.545098f};
const ddVec3 DarkSlateGray = {0.184314f, 0.309804f, 0.309804f};
const ddVec3 DarkTurquoise = {0.000000f, 0.807843f, 0.819608f};
const ddVec3 DarkViolet = {0.580392f, 0.000000f, 0.827451f};
const ddVec3 DeepPink = {1.000000f, 0.078431f, 0.576471f};
const ddVec3 DeepSkyBlue = {0.000000f, 0.749020f, 1.000000f};
const ddVec3 DimGray = {0.411765f, 0.411765f, 0.411765f};
const ddVec3 DodgerBlue = {0.117647f, 0.564706f, 1.000000f};
const ddVec3 FireBrick = {0.698039f, 0.133333f, 0.133333f};
const ddVec3 FloralWhite = {1.000000f, 0.980392f, 0.941176f};
const ddVec3 ForestGreen = {0.133333f, 0.545098f, 0.133333f};
const ddVec3 Gainsboro = {0.862745f, 0.862745f, 0.862745f};
const ddVec3 GhostWhite = {0.972549f, 0.972549f, 1.000000f};
const ddVec3 Gold = {1.000000f, 0.843137f, 0.000000f};
const ddVec3 GoldenRod = {0.854902f, 0.647059f, 0.125490f};
const ddVec3 Gray = {0.501961f, 0.501961f, 0.501961f};
const ddVec3 Green = {0.000000f, 0.501961f, 0.000000f};
const ddVec3 GreenYellow = {0.678431f, 1.000000f, 0.184314f};
const ddVec3 HoneyDew = {0.941176f, 1.000000f, 0.941176f};
const ddVec3 HotPink = {1.000000f, 0.411765f, 0.705882f};
const ddVec3 IndianRed = {0.803922f, 0.360784f, 0.360784f};
const ddVec3 Indigo = {0.294118f, 0.000000f, 0.509804f};
const ddVec3 Ivory = {1.000000f, 1.000000f, 0.941176f};
const ddVec3 Khaki = {0.941176f, 0.901961f, 0.549020f};
const ddVec3 Lavender = {0.901961f, 0.901961f, 0.980392f};
const ddVec3 LavenderBlush = {1.000000f, 0.941176f, 0.960784f};
const ddVec3 LawnGreen = {0.486275f, 0.988235f, 0.000000f};
const ddVec3 LemonChiffon = {1.000000f, 0.980392f, 0.803922f};
const ddVec3 LightBlue = {0.678431f, 0.847059f, 0.901961f};
const ddVec3 LightCoral = {0.941176f, 0.501961f, 0.501961f};
const ddVec3 LightCyan = {0.878431f, 1.000000f, 1.000000f};
const ddVec3 LightGoldenYellow = {0.980392f, 0.980392f, 0.823529f};
const ddVec3 LightGray = {0.827451f, 0.827451f, 0.827451f};
const ddVec3 LightGreen = {0.564706f, 0.933333f, 0.564706f};
const ddVec3 LightPink = {1.000000f, 0.713726f, 0.756863f};
const ddVec3 LightSalmon = {1.000000f, 0.627451f, 0.478431f};
const ddVec3 LightSeaGreen = {0.125490f, 0.698039f, 0.666667f};
const ddVec3 LightSkyBlue = {0.529412f, 0.807843f, 0.980392f};
const ddVec3 LightSlateGray = {0.466667f, 0.533333f, 0.600000f};
const ddVec3 LightSteelBlue = {0.690196f, 0.768627f, 0.870588f};
const ddVec3 LightYellow = {1.000000f, 1.000000f, 0.878431f};
const ddVec3 Lime = {0.000000f, 1.000000f, 0.000000f};
const ddVec3 LimeGreen = {0.196078f, 0.803922f, 0.196078f};
const ddVec3 Linen = {0.980392f, 0.941176f, 0.901961f};
const ddVec3 Magenta = {1.000000f, 0.000000f, 1.000000f};
const ddVec3 Maroon = {0.501961f, 0.000000f, 0.000000f};
const ddVec3 MediumAquaMarine = {0.400000f, 0.803922f, 0.666667f};
const ddVec3 MediumBlue = {0.000000f, 0.000000f, 0.803922f};
const ddVec3 MediumOrchid = {0.729412f, 0.333333f, 0.827451f};
const ddVec3 MediumPurple = {0.576471f, 0.439216f, 0.858824f};
const ddVec3 MediumSeaGreen = {0.235294f, 0.701961f, 0.443137f};
const ddVec3 MediumSlateBlue = {0.482353f, 0.407843f, 0.933333f};
const ddVec3 MediumSpringGreen = {0.000000f, 0.980392f, 0.603922f};
const ddVec3 MediumTurquoise = {0.282353f, 0.819608f, 0.800000f};
const ddVec3 MediumVioletRed = {0.780392f, 0.082353f, 0.521569f};
const ddVec3 MidnightBlue = {0.098039f, 0.098039f, 0.439216f};
const ddVec3 MintCream = {0.960784f, 1.000000f, 0.980392f};
const ddVec3 MistyRose = {1.000000f, 0.894118f, 0.882353f};
const ddVec3 Moccasin = {1.000000f, 0.894118f, 0.709804f};
const ddVec3 NavajoWhite = {1.000000f, 0.870588f, 0.678431f};
const ddVec3 Navy = {0.000000f, 0.000000f, 0.501961f};
const ddVec3 OldLace = {0.992157f, 0.960784f, 0.901961f};
const ddVec3 Olive = {0.501961f, 0.501961f, 0.000000f};
const ddVec3 OliveDrab = {0.419608f, 0.556863f, 0.137255f};
const ddVec3 Orange = {1.000000f, 0.647059f, 0.000000f};
const ddVec3 OrangeRed = {1.000000f, 0.270588f, 0.000000f};
const ddVec3 Orchid = {0.854902f, 0.439216f, 0.839216f};
const ddVec3 PaleGoldenRod = {0.933333f, 0.909804f, 0.666667f};
const ddVec3 PaleGreen = {0.596078f, 0.984314f, 0.596078f};
const ddVec3 PaleTurquoise = {0.686275f, 0.933333f, 0.933333f};
const ddVec3 PaleVioletRed = {0.858824f, 0.439216f, 0.576471f};
const ddVec3 PapayaWhip = {1.000000f, 0.937255f, 0.835294f};
const ddVec3 PeachPuff = {1.000000f, 0.854902f, 0.725490f};
const ddVec3 Peru = {0.803922f, 0.521569f, 0.247059f};
const ddVec3 Pink = {1.000000f, 0.752941f, 0.796078f};
const ddVec3 Plum = {0.866667f, 0.627451f, 0.866667f};
const ddVec3 PowderBlue = {0.690196f, 0.878431f, 0.901961f};
const ddVec3 Purple = {0.501961f, 0.000000f, 0.501961f};
const ddVec3 RebeccaPurple = {0.400000f, 0.200000f, 0.600000f};
const ddVec3 Red = {1.000000f, 0.000000f, 0.000000f};
const ddVec3 RosyBrown = {0.737255f, 0.560784f, 0.560784f};
const ddVec3 RoyalBlue = {0.254902f, 0.411765f, 0.882353f};
const ddVec3 SaddleBrown = {0.545098f, 0.270588f, 0.074510f};
const ddVec3 Salmon = {0.980392f, 0.501961f, 0.447059f};
const ddVec3 SandyBrown = {0.956863f, 0.643137f, 0.376471f};
const ddVec3 SeaGreen = {0.180392f, 0.545098f, 0.341176f};
const ddVec3 SeaShell = {1.000000f, 0.960784f, 0.933333f};
const ddVec3 Sienna = {0.627451f, 0.321569f, 0.176471f};
const ddVec3 Silver = {0.752941f, 0.752941f, 0.752941f};
const ddVec3 SkyBlue = {0.529412f, 0.807843f, 0.921569f};
const ddVec3 SlateBlue = {0.415686f, 0.352941f, 0.803922f};
const ddVec3 SlateGray = {0.439216f, 0.501961f, 0.564706f};
const ddVec3 Snow = {1.000000f, 0.980392f, 0.980392f};
const ddVec3 SpringGreen = {0.000000f, 1.000000f, 0.498039f};
const ddVec3 SteelBlue = {0.274510f, 0.509804f, 0.705882f};
const ddVec3 Tan = {0.823529f, 0.705882f, 0.549020f};
const ddVec3 Teal = {0.000000f, 0.501961f, 0.501961f};
const ddVec3 Thistle = {0.847059f, 0.749020f, 0.847059f};
const ddVec3 Tomato = {1.000000f, 0.388235f, 0.278431f};
const ddVec3 Turquoise = {0.250980f, 0.878431f, 0.815686f};
const ddVec3 Violet = {0.933333f, 0.509804f, 0.933333f};
const ddVec3 Wheat = {0.960784f, 0.870588f, 0.701961f};
const ddVec3 White = {1.000000f, 1.000000f, 1.000000f};
const ddVec3 WhiteSmoke = {0.960784f, 0.960784f, 0.960784f};
const ddVec3 Yellow = {1.000000f, 1.000000f, 0.000000f};
const ddVec3 YellowGreen = {0.603922f, 0.803922f, 0.196078f};
} // namespace colors
#endif // DEBUG_DRAW_NO_DEFAULT_COLORS
// ========================================================
// Embedded bitmap font for debug text rendering:
// ========================================================
struct FontChar
{
std::uint16_t x;
std::uint16_t y;