Unravel Engine C++ Reference
Loading...
Searching...
No Matches
debugdraw.cpp
Go to the documentation of this file.
1/*
2 * Copyright 2011-2023 Branimir Karadzic. All rights reserved.
3 * License: https://github.com/bkaradzic/bgfx/blob/master/LICENSE
4 */
5
6#include "debugdraw.h"
7#include "../bgfx_utils.h"
8#include "../packrect.h"
9#include <bgfx/bgfx.h>
10#include <bgfx/embedded_shader.h>
11
12#include <bx/debug.h>
13#include <bx/handlealloc.h>
14#include <bx/math.h>
15#include <bx/mutex.h>
16#include <bx/sort.h>
17#include <bx/uint32_t.h>
18
19#ifndef DEBUG_DRAW_CONFIG_MAX_GEOMETRY
20#define DEBUG_DRAW_CONFIG_MAX_GEOMETRY 256
21#endif // DEBUG_DRAW_CONFIG_MAX_GEOMETRY
22
24{
25 float m_x;
26 float m_y;
27 float m_z;
28 float m_len;
29 uint32_t m_abgr;
30
31 static void init()
32 {
33 ms_layout.begin()
34 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
35 .add(bgfx::Attrib::TexCoord0, 1, bgfx::AttribType::Float)
36 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
37 .end();
38 }
39
40 static bgfx::VertexLayout ms_layout;
41};
42
43bgfx::VertexLayout DebugVertex::ms_layout;
44
46{
47 float m_x;
48 float m_y;
49 float m_z;
50 float m_u;
51 float m_v;
52 uint32_t m_abgr;
53
54 static void init()
55 {
56 ms_layout.begin()
57 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
58 .add(bgfx::Attrib::TexCoord0, 2, bgfx::AttribType::Float)
59 .add(bgfx::Attrib::Color0, 4, bgfx::AttribType::Uint8, true)
60 .end();
61 }
62
63 static bgfx::VertexLayout ms_layout;
64};
65
66bgfx::VertexLayout DebugUvVertex::ms_layout;
67
69{
70 float m_x;
71 float m_y;
72 float m_z;
73 uint8_t m_indices[4];
74
75 static void init()
76 {
77 ms_layout.begin()
78 .add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float)
79 .add(bgfx::Attrib::Indices, 4, bgfx::AttribType::Uint8)
80 .end();
81 }
82
83 static bgfx::VertexLayout ms_layout;
84};
85
86bgfx::VertexLayout DebugShapeVertex::ms_layout;
87
89{
90 float m_x;
91 float m_y;
92 float m_z;
93
94 static void init()
95 {
96 ms_layout.begin().add(bgfx::Attrib::Position, 3, bgfx::AttribType::Float).end();
97 }
98
99 static bgfx::VertexLayout ms_layout;
100};
101
102bgfx::VertexLayout DebugMeshVertex::ms_layout;
103
104static DebugShapeVertex s_quadVertices[4] = {
105 {-1.0f, 0.0f, 1.0f, {0, 0, 0, 0}},
106 {1.0f, 0.0f, 1.0f, {0, 0, 0, 0}},
107 {-1.0f, 0.0f, -1.0f, {0, 0, 0, 0}},
108 {1.0f, 0.0f, -1.0f, {0, 0, 0, 0}},
109
110};
111
112static const uint16_t s_quadIndices[6] = {
113 0,
114 1,
115 2,
116 1,
117 3,
118 2,
119};
120
121static DebugShapeVertex s_cubeVertices[8] = {
122 {-1.0f, 1.0f, 1.0f, {0, 0, 0, 0}},
123 {1.0f, 1.0f, 1.0f, {0, 0, 0, 0}},
124 {-1.0f, -1.0f, 1.0f, {0, 0, 0, 0}},
125 {1.0f, -1.0f, 1.0f, {0, 0, 0, 0}},
126 {-1.0f, 1.0f, -1.0f, {0, 0, 0, 0}},
127 {1.0f, 1.0f, -1.0f, {0, 0, 0, 0}},
128 {-1.0f, -1.0f, -1.0f, {0, 0, 0, 0}},
129 {1.0f, -1.0f, -1.0f, {0, 0, 0, 0}},
130};
131
132static const uint16_t s_cubeIndices[36] = {
133 0, 1, 2, // 0
134 1, 3, 2, 4, 6, 5, // 2
135 5, 6, 7, 0, 2, 4, // 4
136 4, 2, 6, 1, 5, 3, // 6
137 5, 7, 3, 0, 4, 1, // 8
138 4, 5, 1, 2, 3, 6, // 10
139 6, 3, 7,
140};
141
142static const uint8_t s_circleLod[] = {
143 37,
144 29,
145 23,
146 17,
147 11,
148};
149
150static uint8_t getCircleLod(uint8_t _lod)
151{
152 _lod = _lod > BX_COUNTOF(s_circleLod) - 1 ? BX_COUNTOF(s_circleLod) - 1 : _lod;
153 return s_circleLod[_lod];
154}
155
156static void circle(float* _out, float _angle)
157{
158 float sa = bx::sin(_angle);
159 float ca = bx::cos(_angle);
160 _out[0] = sa;
161 _out[1] = ca;
162}
163
164static void squircle(float* _out, float _angle)
165{
166 float sa = bx::sin(_angle);
167 float ca = bx::cos(_angle);
168 _out[0] = bx::sqrt(bx::abs(sa)) * bx::sign(sa);
169 _out[1] = bx::sqrt(bx::abs(ca)) * bx::sign(ca);
170}
171
172uint32_t genSphere(uint8_t _subdiv0,
173 void* _pos0 = NULL,
174 uint16_t _posStride0 = 0,
175 void* _normals0 = NULL,
176 uint16_t _normalStride0 = 0)
177{
178 if(NULL != _pos0)
179 {
180 struct Gen
181 {
182 Gen(void* _pos, uint16_t _posStride, void* _normals, uint16_t _normalStride, uint8_t _subdiv)
183 : m_pos((uint8_t*)_pos)
184 , m_normals((uint8_t*)_normals)
185 , m_posStride(_posStride)
186 , m_normalStride(_normalStride)
187 {
188 static const float scale = 1.0f;
189 static const float golden = 1.6180339887f;
190 static const float len = bx::sqrt(golden * golden + 1.0f);
191 static const float ss = 1.0f / len * scale;
192 static const float ll = ss * golden;
193
194 static const bx::Vec3 vv[] = {
195 {-ll, 0.0f, -ss},
196 {ll, 0.0f, -ss},
197 {ll, 0.0f, ss},
198 {-ll, 0.0f, ss},
199
200 {-ss, ll, 0.0f},
201 {ss, ll, 0.0f},
202 {ss, -ll, 0.0f},
203 {-ss, -ll, 0.0f},
204
205 {0.0f, -ss, ll},
206 {0.0f, ss, ll},
207 {0.0f, ss, -ll},
208 {0.0f, -ss, -ll},
209 };
210
211 m_numVertices = 0;
212
213 triangle(vv[0], vv[4], vv[3], scale, _subdiv);
214 triangle(vv[0], vv[10], vv[4], scale, _subdiv);
215 triangle(vv[4], vv[10], vv[5], scale, _subdiv);
216 triangle(vv[5], vv[10], vv[1], scale, _subdiv);
217 triangle(vv[5], vv[1], vv[2], scale, _subdiv);
218 triangle(vv[5], vv[2], vv[9], scale, _subdiv);
219 triangle(vv[5], vv[9], vv[4], scale, _subdiv);
220 triangle(vv[3], vv[4], vv[9], scale, _subdiv);
221
222 triangle(vv[0], vv[3], vv[7], scale, _subdiv);
223 triangle(vv[0], vv[7], vv[11], scale, _subdiv);
224 triangle(vv[11], vv[7], vv[6], scale, _subdiv);
225 triangle(vv[11], vv[6], vv[1], scale, _subdiv);
226 triangle(vv[1], vv[6], vv[2], scale, _subdiv);
227 triangle(vv[2], vv[6], vv[8], scale, _subdiv);
228 triangle(vv[8], vv[6], vv[7], scale, _subdiv);
229 triangle(vv[8], vv[7], vv[3], scale, _subdiv);
230
231 triangle(vv[0], vv[11], vv[10], scale, _subdiv);
232 triangle(vv[1], vv[10], vv[11], scale, _subdiv);
233 triangle(vv[2], vv[8], vv[9], scale, _subdiv);
234 triangle(vv[3], vv[9], vv[8], scale, _subdiv);
235 }
236
237 void addVert(const bx::Vec3& _v)
238 {
239 bx::store(m_pos, _v);
240 m_pos += m_posStride;
241
242 if(NULL != m_normals)
243 {
244 const bx::Vec3 normal = bx::normalize(_v);
245 bx::store(m_normals, normal);
246
247 m_normals += m_normalStride;
248 }
249
250 m_numVertices++;
251 }
252
253 void triangle(const bx::Vec3& _v0, const bx::Vec3& _v1, const bx::Vec3& _v2, float _scale, uint8_t _subdiv)
254 {
255 if(0 == _subdiv)
256 {
257 addVert(_v0);
258 addVert(_v1);
259 addVert(_v2);
260 }
261 else
262 {
263 const bx::Vec3 v01 = bx::mul(bx::normalize(bx::add(_v0, _v1)), _scale);
264 const bx::Vec3 v12 = bx::mul(bx::normalize(bx::add(_v1, _v2)), _scale);
265 const bx::Vec3 v20 = bx::mul(bx::normalize(bx::add(_v2, _v0)), _scale);
266
267 --_subdiv;
268 triangle(_v0, v01, v20, _scale, _subdiv);
269 triangle(_v1, v12, v01, _scale, _subdiv);
270 triangle(_v2, v20, v12, _scale, _subdiv);
271 triangle(v01, v12, v20, _scale, _subdiv);
272 }
273 }
274
275 uint8_t* m_pos;
276 uint8_t* m_normals;
277 uint16_t m_posStride;
278 uint16_t m_normalStride;
279 uint32_t m_numVertices;
280
281 } gen(_pos0, _posStride0, _normals0, _normalStride0, _subdiv0);
282 }
283
284 uint32_t numVertices = 20 * 3 * bx::uint32_max(1, (uint32_t)bx::pow(4.0f, _subdiv0));
285 return numVertices;
286}
287
288bx::Vec3 getPoint(Axis::Enum _axis, float _x, float _y)
289{
290 switch(_axis)
291 {
292 case Axis::X:
293 return {0.0f, _x, _y};
294 case Axis::Y:
295 return {_y, 0.0f, _x};
296 default:
297 break;
298 }
299
300 return {_x, _y, 0.0f};
301}
302
315
316static const bgfx::EmbeddedShader s_embeddedShaders[] = {BGFX_EMBEDDED_SHADER(vs_debugdraw_lines),
317 BGFX_EMBEDDED_SHADER(fs_debugdraw_lines),
318 BGFX_EMBEDDED_SHADER(vs_debugdraw_lines_stipple),
319 BGFX_EMBEDDED_SHADER(fs_debugdraw_lines_stipple),
320 BGFX_EMBEDDED_SHADER(vs_debugdraw_fill),
321 BGFX_EMBEDDED_SHADER(vs_debugdraw_fill_mesh),
322 BGFX_EMBEDDED_SHADER(fs_debugdraw_fill),
323 BGFX_EMBEDDED_SHADER(vs_debugdraw_fill_lit),
324 BGFX_EMBEDDED_SHADER(vs_debugdraw_fill_lit_mesh),
325 BGFX_EMBEDDED_SHADER(fs_debugdraw_fill_lit),
326 BGFX_EMBEDDED_SHADER(vs_debugdraw_fill_texture),
327 BGFX_EMBEDDED_SHADER(fs_debugdraw_fill_texture),
328
329 BGFX_EMBEDDED_SHADER_END()};
330
331#define SPRITE_TEXTURE_SIZE 1024
332
333template<uint16_t MaxHandlesT = 256, uint16_t TextureSizeT = 1024>
335{
336 SpriteT() : m_ra(TextureSizeT, TextureSizeT)
337 {
338 }
339
340 SpriteHandle create(uint16_t _width, uint16_t _height)
341 {
342 bx::MutexScope lock(m_lock);
343
344 SpriteHandle handle = {bx::kInvalidHandle};
345
346 if(m_handleAlloc.getNumHandles() < m_handleAlloc.getMaxHandles())
347 {
348 Pack2D pack;
349 if(m_ra.find(_width, _height, pack))
350 {
351 handle.idx = m_handleAlloc.alloc();
352
353 if(isValid(handle))
354 {
355 m_pack[handle.idx] = pack;
356 }
357 else
358 {
359 m_ra.clear(pack);
360 }
361 }
362 }
363
364 return handle;
365 }
366
367 void destroy(SpriteHandle _sprite)
368 {
369 const Pack2D& pack = m_pack[_sprite.idx];
370 m_ra.clear(pack);
371 m_handleAlloc.free(_sprite.idx);
372 }
373
374 const Pack2D& get(SpriteHandle _sprite) const
375 {
376 return m_pack[_sprite.idx];
377 }
378
379 bx::Mutex m_lock;
380 bx::HandleAllocT<MaxHandlesT> m_handleAlloc;
381 Pack2D m_pack[MaxHandlesT];
383};
384
385template<uint16_t MaxHandlesT = DEBUG_DRAW_CONFIG_MAX_GEOMETRY>
387{
389 {
390 }
391
392 GeometryHandle create(uint32_t _numVertices,
393 const DdVertex* _vertices,
394 uint32_t _numIndices,
395 const void* _indices,
396 bool _index32)
397 {
398 BX_UNUSED(_numVertices, _vertices, _numIndices, _indices, _index32);
399
401 {
402 bx::MutexScope lock(m_lock);
403 handle = {m_handleAlloc.alloc()};
404 }
405
406 if(isValid(handle))
407 {
408 Geometry& geometry = m_geometry[handle.idx];
409 geometry.m_vbh = bgfx::createVertexBuffer(bgfx::copy(_vertices, _numVertices * sizeof(DdVertex)),
411
412 geometry.m_topologyNumIndices[0] = _numIndices;
413 geometry.m_topologyNumIndices[1] = bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList,
414 NULL,
415 0,
416 _indices,
417 _numIndices,
418 _index32);
419
420 const uint32_t indexSize = _index32 ? sizeof(uint32_t) : sizeof(uint16_t);
421
422 const uint32_t numIndices = 0 + geometry.m_topologyNumIndices[0] + geometry.m_topologyNumIndices[1];
423 const bgfx::Memory* mem = bgfx::alloc(numIndices * indexSize);
424 uint8_t* indexData = mem->data;
425
426 bx::memCopy(indexData, _indices, _numIndices * indexSize);
427 bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList,
428 &indexData[geometry.m_topologyNumIndices[0] * indexSize],
429 geometry.m_topologyNumIndices[1] * indexSize,
430 _indices,
431 _numIndices,
432 _index32);
433
434 geometry.m_ibh = bgfx::createIndexBuffer(mem, _index32 ? BGFX_BUFFER_INDEX32 : BGFX_BUFFER_NONE);
435 }
436
437 return handle;
438 }
439
441 {
442 bx::MutexScope lock(m_lock);
443 Geometry& geometry = m_geometry[_handle.idx];
444 bgfx::destroy(geometry.m_vbh);
445 bgfx::destroy(geometry.m_ibh);
446
447 m_handleAlloc.free(_handle.idx);
448 }
449
450 struct Geometry
451 {
453 {
454 m_vbh.idx = bx::kInvalidHandle;
455 m_ibh.idx = bx::kInvalidHandle;
458 }
459
460 bgfx::VertexBufferHandle m_vbh;
461 bgfx::IndexBufferHandle m_ibh;
463 };
464
465 bx::Mutex m_lock;
466 bx::HandleAllocT<MaxHandlesT> m_handleAlloc;
467 Geometry m_geometry[MaxHandlesT];
468};
469
470struct Attrib
471{
472 uint64_t m_state;
474 float m_offset;
475 float m_scale;
476 float m_spin;
477 uint32_t m_abgr;
480 uint8_t m_lod;
481};
482
498
540
543
545{
546 void init(bx::AllocatorI* _allocator)
547 {
548 if(NULL == _allocator)
549 {
550 static bx::DefaultAllocator allocator;
551 m_allocator = &allocator;
552 }
553 else
554 {
555 m_allocator = _allocator;
556 }
557
562
563 bgfx::RendererType::Enum type = bgfx::getRendererType();
564
566 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_lines"),
567 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_lines"),
568 true);
569
571 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_lines_stipple"),
572 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_lines_stipple"),
573 true);
574
576 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_fill"),
577 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_fill"),
578 true);
579
581 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_fill_mesh"),
582 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_fill"),
583 true);
584
586 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_fill_lit"),
587 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_fill_lit"),
588 true);
589
591 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_fill_lit_mesh"),
592 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_fill_lit"),
593 true);
594
596 bgfx::createProgram(bgfx::createEmbeddedShader(s_embeddedShaders, type, "vs_debugdraw_fill_texture"),
597 bgfx::createEmbeddedShader(s_embeddedShaders, type, "fs_debugdraw_fill_texture"),
598 true);
599
600 u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 4);
601 s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Sampler);
602 m_texture =
603 bgfx::createTexture2D(SPRITE_TEXTURE_SIZE, SPRITE_TEXTURE_SIZE, false, 1, bgfx::TextureFormat::BGRA8);
604
605 void* vertices[DebugMesh::Count] = {};
606 uint16_t* indices[DebugMesh::Count] = {};
607 uint16_t stride = DebugShapeVertex::ms_layout.getStride();
608
609 uint32_t startVertex = 0;
610 uint32_t startIndex = 0;
611
612 for(uint32_t mesh = 0; mesh < 4; ++mesh)
613 {
615
616 const uint8_t tess = uint8_t(3 - mesh);
617 const uint32_t numVertices = genSphere(tess);
618 const uint32_t numIndices = numVertices;
619
620 vertices[id] = bx::alloc(m_allocator, numVertices * stride);
621 bx::memSet(vertices[id], 0, numVertices * stride);
622 genSphere(tess, vertices[id], stride);
623
624 uint16_t* trilist = (uint16_t*)bx::alloc(m_allocator, numIndices * sizeof(uint16_t));
625 for(uint32_t ii = 0; ii < numIndices; ++ii)
626 {
627 trilist[ii] = uint16_t(ii);
628 }
629
630 uint32_t numLineListIndices =
631 bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList, NULL, 0, trilist, numIndices, false);
632 indices[id] = (uint16_t*)bx::alloc(m_allocator, (numIndices + numLineListIndices) * sizeof(uint16_t));
633 uint16_t* indicesOut = indices[id];
634 bx::memCopy(indicesOut, trilist, numIndices * sizeof(uint16_t));
635
636 bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList,
637 &indicesOut[numIndices],
638 numLineListIndices * sizeof(uint16_t),
639 trilist,
640 numIndices,
641 false);
642
643 m_mesh[id].m_startVertex = startVertex;
644 m_mesh[id].m_numVertices = numVertices;
645 m_mesh[id].m_startIndex[0] = startIndex;
646 m_mesh[id].m_numIndices[0] = numIndices;
647 m_mesh[id].m_startIndex[1] = startIndex + numIndices;
648 m_mesh[id].m_numIndices[1] = numLineListIndices;
649
650 startVertex += numVertices;
651 startIndex += numIndices + numLineListIndices;
652
653 bx::free(m_allocator, trilist);
654 }
655
656 for(uint32_t mesh = 0; mesh < 4; ++mesh)
657 {
659
660 const uint32_t num = getCircleLod(uint8_t(mesh));
661 const float step = bx::kPi * 2.0f / num;
662
663 const uint32_t numVertices = num + 1;
664 const uint32_t numIndices = num * 6;
665 const uint32_t numLineListIndices = num * 4;
666
667 vertices[id] = bx::alloc(m_allocator, numVertices * stride);
668 indices[id] = (uint16_t*)bx::alloc(m_allocator, (numIndices + numLineListIndices) * sizeof(uint16_t));
669 bx::memSet(indices[id], 0, (numIndices + numLineListIndices) * sizeof(uint16_t));
670
671 DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id];
672 uint16_t* index = indices[id];
673
674 vertex[num].m_x = 0.0f;
675 vertex[num].m_y = 0.0f;
676 vertex[num].m_z = 0.0f;
677 vertex[num].m_indices[0] = 1;
678
679 for(uint32_t ii = 0; ii < num; ++ii)
680 {
681 const float angle = step * ii;
682
683 float xy[2];
684 circle(xy, angle);
685
686 vertex[ii].m_x = xy[1];
687 vertex[ii].m_y = 0.0f;
688 vertex[ii].m_z = xy[0];
689 vertex[ii].m_indices[0] = 0;
690
691 index[ii * 3 + 0] = uint16_t(num);
692 index[ii * 3 + 1] = uint16_t((ii + 1) % num);
693 index[ii * 3 + 2] = uint16_t(ii);
694
695 index[num * 3 + ii * 3 + 0] = 0;
696 index[num * 3 + ii * 3 + 1] = uint16_t(ii);
697 index[num * 3 + ii * 3 + 2] = uint16_t((ii + 1) % num);
698
699 index[numIndices + ii * 2 + 0] = uint16_t(ii);
700 index[numIndices + ii * 2 + 1] = uint16_t(num);
701
702 index[numIndices + num * 2 + ii * 2 + 0] = uint16_t(ii);
703 index[numIndices + num * 2 + ii * 2 + 1] = uint16_t((ii + 1) % num);
704 }
705
706 m_mesh[id].m_startVertex = startVertex;
707 m_mesh[id].m_numVertices = numVertices;
708 m_mesh[id].m_startIndex[0] = startIndex;
709 m_mesh[id].m_numIndices[0] = numIndices;
710 m_mesh[id].m_startIndex[1] = startIndex + numIndices;
711 m_mesh[id].m_numIndices[1] = numLineListIndices;
712
713 startVertex += numVertices;
714 startIndex += numIndices + numLineListIndices;
715 }
716
717 for(uint32_t mesh = 0; mesh < 4; ++mesh)
718 {
720
721 const uint32_t num = getCircleLod(uint8_t(mesh));
722 const float step = bx::kPi * 2.0f / num;
723
724 const uint32_t numVertices = num * 2;
725 const uint32_t numIndices = num * 12;
726 const uint32_t numLineListIndices = num * 6;
727
728 vertices[id] = bx::alloc(m_allocator, numVertices * stride);
729 indices[id] = (uint16_t*)bx::alloc(m_allocator, (numIndices + numLineListIndices) * sizeof(uint16_t));
730 bx::memSet(indices[id], 0, (numIndices + numLineListIndices) * sizeof(uint16_t));
731
732 DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id];
733 uint16_t* index = indices[id];
734
735 for(uint32_t ii = 0; ii < num; ++ii)
736 {
737 const float angle = step * ii;
738
739 float xy[2];
740 circle(xy, angle);
741
742 vertex[ii].m_x = xy[1];
743 vertex[ii].m_y = 0.0f;
744 vertex[ii].m_z = xy[0];
745 vertex[ii].m_indices[0] = 0;
746
747 vertex[ii + num].m_x = xy[1];
748 vertex[ii + num].m_y = 0.0f;
749 vertex[ii + num].m_z = xy[0];
750 vertex[ii + num].m_indices[0] = 1;
751
752 index[ii * 6 + 0] = uint16_t(ii + num);
753 index[ii * 6 + 1] = uint16_t((ii + 1) % num);
754 index[ii * 6 + 2] = uint16_t(ii);
755 index[ii * 6 + 3] = uint16_t(ii + num);
756 index[ii * 6 + 4] = uint16_t((ii + 1) % num + num);
757 index[ii * 6 + 5] = uint16_t((ii + 1) % num);
758
759 index[num * 6 + ii * 6 + 0] = uint16_t(0);
760 index[num * 6 + ii * 6 + 1] = uint16_t(ii);
761 index[num * 6 + ii * 6 + 2] = uint16_t((ii + 1) % num);
762 index[num * 6 + ii * 6 + 3] = uint16_t(num);
763 index[num * 6 + ii * 6 + 4] = uint16_t((ii + 1) % num + num);
764 index[num * 6 + ii * 6 + 5] = uint16_t(ii + num);
765
766 index[numIndices + ii * 2 + 0] = uint16_t(ii);
767 index[numIndices + ii * 2 + 1] = uint16_t(ii + num);
768
769 index[numIndices + num * 2 + ii * 2 + 0] = uint16_t(ii);
770 index[numIndices + num * 2 + ii * 2 + 1] = uint16_t((ii + 1) % num);
771
772 index[numIndices + num * 4 + ii * 2 + 0] = uint16_t(num + ii);
773 index[numIndices + num * 4 + ii * 2 + 1] = uint16_t(num + (ii + 1) % num);
774 }
775
776 m_mesh[id].m_startVertex = startVertex;
777 m_mesh[id].m_numVertices = numVertices;
778 m_mesh[id].m_startIndex[0] = startIndex;
779 m_mesh[id].m_numIndices[0] = numIndices;
780 m_mesh[id].m_startIndex[1] = startIndex + numIndices;
781 m_mesh[id].m_numIndices[1] = numLineListIndices;
782
783 startVertex += numVertices;
784 startIndex += numIndices + numLineListIndices;
785 }
786
787 for(uint32_t mesh = 0; mesh < 4; ++mesh)
788 {
790
791 const uint32_t num = getCircleLod(uint8_t(mesh));
792 const float step = bx::kPi * 2.0f / num;
793
794 const uint32_t numVertices = num * 2;
795 const uint32_t numIndices = num * 6;
796 const uint32_t numLineListIndices = num * 6;
797
798 vertices[id] = bx::alloc(m_allocator, numVertices * stride);
799 indices[id] = (uint16_t*)bx::alloc(m_allocator, (numIndices + numLineListIndices) * sizeof(uint16_t));
800 bx::memSet(indices[id], 0, (numIndices + numLineListIndices) * sizeof(uint16_t));
801
802 DebugShapeVertex* vertex = (DebugShapeVertex*)vertices[id];
803 uint16_t* index = indices[id];
804
805 for(uint32_t ii = 0; ii < num; ++ii)
806 {
807 const float angle = step * ii;
808
809 float xy[2];
810 circle(xy, angle);
811
812 vertex[ii].m_x = xy[1];
813 vertex[ii].m_y = 0.0f;
814 vertex[ii].m_z = xy[0];
815 vertex[ii].m_indices[0] = 0;
816
817 vertex[ii + num].m_x = xy[1];
818 vertex[ii + num].m_y = 0.0f;
819 vertex[ii + num].m_z = xy[0];
820 vertex[ii + num].m_indices[0] = 1;
821
822 index[ii * 6 + 0] = uint16_t(ii + num);
823 index[ii * 6 + 1] = uint16_t((ii + 1) % num);
824 index[ii * 6 + 2] = uint16_t(ii);
825 index[ii * 6 + 3] = uint16_t(ii + num);
826 index[ii * 6 + 4] = uint16_t((ii + 1) % num + num);
827 index[ii * 6 + 5] = uint16_t((ii + 1) % num);
828
829 // index[num*6+ii*6+0] = uint16_t(0);
830 // index[num*6+ii*6+1] = uint16_t(ii);
831 // index[num*6+ii*6+2] = uint16_t( (ii+1)%num);
832 // index[num*6+ii*6+3] = uint16_t(num);
833 // index[num*6+ii*6+4] = uint16_t( (ii+1)%num+num);
834 // index[num*6+ii*6+5] = uint16_t(ii+num);
835
836 index[numIndices + ii * 2 + 0] = uint16_t(ii);
837 index[numIndices + ii * 2 + 1] = uint16_t(ii + num);
838
839 index[numIndices + num * 2 + ii * 2 + 0] = uint16_t(ii);
840 index[numIndices + num * 2 + ii * 2 + 1] = uint16_t((ii + 1) % num);
841
842 index[numIndices + num * 4 + ii * 2 + 0] = uint16_t(num + ii);
843 index[numIndices + num * 4 + ii * 2 + 1] = uint16_t(num + (ii + 1) % num);
844 }
845
846 m_mesh[id].m_startVertex = startVertex;
847 m_mesh[id].m_numVertices = numVertices;
848 m_mesh[id].m_startIndex[0] = startIndex;
849 m_mesh[id].m_numIndices[0] = numIndices;
850 m_mesh[id].m_startIndex[1] = startIndex + numIndices;
851 m_mesh[id].m_numIndices[1] = numLineListIndices;
852
853 startVertex += numVertices;
854 startIndex += numIndices + numLineListIndices;
855 }
856
857 m_mesh[DebugMesh::Quad].m_startVertex = startVertex;
858 m_mesh[DebugMesh::Quad].m_numVertices = BX_COUNTOF(s_quadVertices);
859 m_mesh[DebugMesh::Quad].m_startIndex[0] = startIndex;
860 m_mesh[DebugMesh::Quad].m_numIndices[0] = BX_COUNTOF(s_quadIndices);
863 startVertex += BX_COUNTOF(s_quadVertices);
864 startIndex += BX_COUNTOF(s_quadIndices);
865
866 m_mesh[DebugMesh::Cube].m_startVertex = startVertex;
867 m_mesh[DebugMesh::Cube].m_numVertices = BX_COUNTOF(s_cubeVertices);
868 m_mesh[DebugMesh::Cube].m_startIndex[0] = startIndex;
869 m_mesh[DebugMesh::Cube].m_numIndices[0] = BX_COUNTOF(s_cubeIndices);
872 startVertex += m_mesh[DebugMesh::Cube].m_numVertices;
873 startIndex += m_mesh[DebugMesh::Cube].m_numIndices[0];
874
875 const bgfx::Memory* vb = bgfx::alloc(startVertex * stride);
876 const bgfx::Memory* ib = bgfx::alloc(startIndex * sizeof(uint16_t));
877
878 for(uint32_t mesh = DebugMesh::Sphere0; mesh < DebugMesh::Quad; ++mesh)
879 {
881 bx::memCopy(&vb->data[m_mesh[id].m_startVertex * stride], vertices[id], m_mesh[id].m_numVertices * stride);
882
883 bx::memCopy(&ib->data[m_mesh[id].m_startIndex[0] * sizeof(uint16_t)],
884 indices[id],
885 (m_mesh[id].m_numIndices[0] + m_mesh[id].m_numIndices[1]) * sizeof(uint16_t));
886
887 bx::free(m_allocator, vertices[id]);
888 bx::free(m_allocator, indices[id]);
889 }
890
891 bx::memCopy(&vb->data[m_mesh[DebugMesh::Quad].m_startVertex * stride], s_quadVertices, sizeof(s_quadVertices));
892
893 bx::memCopy(&ib->data[m_mesh[DebugMesh::Quad].m_startIndex[0] * sizeof(uint16_t)],
894 s_quadIndices,
895 sizeof(s_quadIndices));
896
897 bx::memCopy(&vb->data[m_mesh[DebugMesh::Cube].m_startVertex * stride], s_cubeVertices, sizeof(s_cubeVertices));
898
899 bx::memCopy(&ib->data[m_mesh[DebugMesh::Cube].m_startIndex[0] * sizeof(uint16_t)],
900 s_cubeIndices,
901 sizeof(s_cubeIndices));
902
903 m_vbh = bgfx::createVertexBuffer(vb, DebugShapeVertex::ms_layout);
904 m_ibh = bgfx::createIndexBuffer(ib);
905 }
906
907 void shutdown()
908 {
909 bgfx::destroy(m_ibh);
910 bgfx::destroy(m_vbh);
911 for(uint32_t ii = 0; ii < Program::Count; ++ii)
912 {
913 bgfx::destroy(m_program[ii]);
914 }
915 bgfx::destroy(u_params);
916 bgfx::destroy(s_texColor);
917 bgfx::destroy(m_texture);
918 }
919
920 SpriteHandle createSprite(uint16_t _width, uint16_t _height, const void* _data)
921 {
922 SpriteHandle handle = m_sprite.create(_width, _height);
923
924 if(isValid(handle))
925 {
926 const Pack2D& pack = m_sprite.get(handle);
927 bgfx::updateTexture2D(m_texture,
928 0,
929 0,
930 pack.m_x,
931 pack.m_y,
932 pack.m_width,
933 pack.m_height,
934 bgfx::copy(_data, pack.m_width * pack.m_height * 4));
935 }
936
937 return handle;
938 }
939
940 void destroy(SpriteHandle _handle)
941 {
942 m_sprite.destroy(_handle);
943 }
944
945 GeometryHandle createGeometry(uint32_t _numVertices,
946 const DdVertex* _vertices,
947 uint32_t _numIndices,
948 const void* _indices,
949 bool _index32)
950 {
951 return m_geometry.create(_numVertices, _vertices, _numIndices, _indices, _index32);
952 }
953
955 {
956 m_geometry.destroy(_handle);
957 }
958
959 bx::AllocatorI* m_allocator;
960
963
965
966 bgfx::UniformHandle s_texColor;
967 bgfx::TextureHandle m_texture;
968 bgfx::ProgramHandle m_program[Program::Count];
969 bgfx::UniformHandle u_params;
970
971 bgfx::VertexBufferHandle m_vbh;
972 bgfx::IndexBufferHandle m_ibh;
973};
974
975static DebugDrawShared s_dds;
976
978{
980 {
981 bx::memSet(&m_cache, 0, sizeof(m_cache));
982 bx::memSet(&m_cacheQuad, 0, sizeof(m_cacheQuad));
983 bx::memSet(&m_indices, 0, sizeof(m_indices));
984 }
985
986 void init(bgfx::Encoder* _encoder)
987 {
988 m_defaultEncoder = _encoder;
990 }
991
992 void shutdown()
993 {
994 }
995
996 void begin(bgfx::ViewId _viewId, bool _depthTestLess, bgfx::Encoder* _encoder)
997 {
998 BX_ASSERT(State::Count == m_state, "");
999
1000 m_viewId = _viewId;
1001 m_encoder = _encoder == NULL ? m_defaultEncoder : _encoder;
1003 m_stack = 0;
1004 m_depthTestLess = _depthTestLess;
1005
1006 m_pos = 0;
1007 m_indexPos = 0;
1008 m_vertexPos = 0;
1009 m_posQuad = 0;
1010
1011 Attrib& attrib = m_attrib[0];
1012 attrib.m_state = 0 | BGFX_STATE_WRITE_RGB |
1013 (m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LESS : BGFX_STATE_DEPTH_TEST_GREATER) |
1014 BGFX_STATE_CULL_CW | BGFX_STATE_WRITE_Z;
1015 attrib.m_scale = 1.0f;
1016 attrib.m_spin = 0.0f;
1017 attrib.m_offset = 0.0f;
1018 attrib.m_abgr = UINT32_MAX;
1019 attrib.m_stipple = false;
1020 attrib.m_wireframe = false;
1021 attrib.m_lod = 0;
1022 attrib.m_alphaBlend = true;
1023
1026
1028 for(auto& program : m_programStack)
1029 {
1030 program = {bgfx::kInvalidHandle};
1031 }
1032 }
1033
1034 void end()
1035 {
1036 BX_ASSERT(0 == m_stack, "Invalid stack %d.", m_stack);
1037
1038 flushQuad();
1039 flush();
1040
1041 m_encoder = NULL;
1043 }
1044
1045 void push()
1046 {
1047 BX_ASSERT(State::Count != m_state, "");
1048 ++m_stack;
1050 }
1051
1052 void pop()
1053 {
1054 BX_ASSERT(State::Count != m_state, "");
1055 const Attrib& curr = m_attrib[m_stack];
1056 const Attrib& prev = m_attrib[m_stack - 1];
1057 if(curr.m_stipple != prev.m_stipple || curr.m_state != prev.m_state)
1058 {
1059 flush();
1060 }
1061 --m_stack;
1062 }
1063
1064 void setDepthTestLess(bool _depthTestLess)
1065 {
1066 BX_ASSERT(State::Count != m_state, "");
1067 if(m_depthTestLess != _depthTestLess)
1068 {
1069 m_depthTestLess = _depthTestLess;
1070 Attrib& attrib = m_attrib[m_stack];
1071 if(attrib.m_state & BGFX_STATE_DEPTH_TEST_MASK)
1072 {
1073 flush();
1074 attrib.m_state &= ~BGFX_STATE_DEPTH_TEST_MASK;
1075 attrib.m_state |= _depthTestLess ? BGFX_STATE_DEPTH_TEST_LESS : BGFX_STATE_DEPTH_TEST_GREATER;
1076 }
1077 }
1078 }
1079
1080 void setTransform(const void* _mtx, uint16_t _num = 1, bool _flush = true)
1081 {
1082 BX_ASSERT(State::Count != m_state, "");
1083 if(_flush)
1084 {
1085 flush();
1086 }
1087
1089
1090 if(NULL == _mtx)
1091 {
1092 stack.reset();
1093 return;
1094 }
1095
1096 bgfx::Transform transform;
1097 stack.mtx = m_encoder->allocTransform(&transform, _num);
1098 stack.num = _num;
1099 stack.data = transform.data;
1100 bx::memCopy(transform.data, _mtx, _num * 64);
1101 }
1102
1103 void setTranslate(float _x, float _y, float _z)
1104 {
1105 float mtx[16];
1106 bx::mtxTranslate(mtx, _x, _y, _z);
1107 setTransform(mtx);
1108 }
1109
1110 void setTranslate(const float* _pos)
1111 {
1112 setTranslate(_pos[0], _pos[1], _pos[2]);
1113 }
1114
1115 void pushTransform(const void* _mtx, uint16_t _num, bool _flush = true)
1116 {
1117 BX_ASSERT(m_mtxStackCurrent < BX_COUNTOF(m_mtxStack), "Out of matrix stack!");
1118 BX_ASSERT(State::Count != m_state, "");
1119 if(_flush)
1120 {
1121 flush();
1122 }
1123
1124 float* mtx = NULL;
1125
1127
1128 if(NULL == stack.data)
1129 {
1130 mtx = (float*)_mtx;
1131 }
1132 else
1133 {
1134 mtx = (float*)BX_STACK_ALLOC(_num*64);
1135 for(uint16_t ii = 0; ii < _num; ++ii)
1136 {
1137 const float* mtxTransform = (const float*)_mtx;
1138 bx::mtxMul(&mtx[ii * 16], &mtxTransform[ii * 16], stack.data);
1139 }
1140 }
1141
1143 setTransform(mtx, _num, _flush);
1144 }
1145
1146 void popTransform(bool _flush = true)
1147 {
1148 BX_ASSERT(State::Count != m_state, "");
1149 if(_flush)
1150 {
1151 flush();
1152 }
1153
1155 }
1156
1157
1158 void pushProgram(bgfx::ProgramHandle _handle)
1159 {
1160 BX_ASSERT(State::Count != m_state, "");
1161
1163
1165 }
1166
1168 {
1169 BX_ASSERT(State::Count != m_state, "");
1170 BX_ASSERT(m_programStackCurrent > -1, "");
1171
1173 }
1174
1175 void pushTranslate(float _x, float _y, float _z)
1176 {
1177 float mtx[16];
1178 bx::mtxTranslate(mtx, _x, _y, _z);
1179 pushTransform(mtx, 1);
1180 }
1181
1182 void pushTranslate(const bx::Vec3& _pos)
1183 {
1184 pushTranslate(_pos.x, _pos.y, _pos.z);
1185 }
1186
1187 void setState(bool _depthTest, bool _depthWrite, bool _clockwise, bool _alphaWrite, bool _alphaBlend)
1188 {
1189 const uint64_t depthTest = m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LESS : BGFX_STATE_DEPTH_TEST_GREATER;
1190
1191 uint64_t state = m_attrib[m_stack].m_state & ~(0 | BGFX_STATE_DEPTH_TEST_MASK | BGFX_STATE_WRITE_Z |
1192 BGFX_STATE_CULL_CW | BGFX_STATE_CULL_CCW);
1193
1194 state |= _depthTest ? depthTest : 0;
1195
1196 state |= _depthWrite ? BGFX_STATE_WRITE_Z : 0;
1197
1198 state |= _alphaWrite ? BGFX_STATE_WRITE_A : 0;
1199
1200 state |= _clockwise ? BGFX_STATE_CULL_CW : BGFX_STATE_CULL_CCW;
1201
1202 if(m_attrib[m_stack].m_state != state || m_attrib[m_stack].m_alphaBlend != _alphaBlend)
1203 {
1204 flush();
1205 }
1206
1207 m_attrib[m_stack].m_state = state;
1208 m_attrib[m_stack].m_alphaBlend = _alphaBlend;
1209 }
1210
1211 void setColor(uint32_t _abgr)
1212 {
1213 BX_ASSERT(State::Count != m_state, "");
1214 m_attrib[m_stack].m_abgr = _abgr;
1215 }
1216
1217 void setLod(uint8_t _lod)
1218 {
1219 BX_ASSERT(State::Count != m_state, "");
1220 m_attrib[m_stack].m_lod = _lod;
1221 }
1222
1223 void setWireframe(bool _wireframe)
1224 {
1225 BX_ASSERT(State::Count != m_state, "");
1226 m_attrib[m_stack].m_wireframe = _wireframe;
1227 }
1228
1229 void setStipple(bool _stipple, float _scale = 1.0f, float _offset = 0.0f)
1230 {
1231 BX_ASSERT(State::Count != m_state, "");
1232
1233 Attrib& attrib = m_attrib[m_stack];
1234
1235 if(attrib.m_stipple != _stipple)
1236 {
1237 flush();
1238 }
1239
1240 attrib.m_stipple = _stipple;
1241 attrib.m_offset = _offset;
1242 attrib.m_scale = _scale;
1243 }
1244
1245 void setSpin(float _spin)
1246 {
1247 Attrib& attrib = m_attrib[m_stack];
1248 attrib.m_spin = _spin;
1249 }
1250
1251 void moveTo(float _x, float _y, float _z = 0.0f)
1252 {
1253 BX_ASSERT(State::Count != m_state, "");
1254
1255 softFlush();
1256
1258
1259 DebugVertex& vertex = m_cache[m_pos];
1260 vertex.m_x = _x;
1261 vertex.m_y = _y;
1262 vertex.m_z = _z;
1263
1264 Attrib& attrib = m_attrib[m_stack];
1265 vertex.m_abgr = attrib.m_abgr;
1266 vertex.m_len = attrib.m_offset;
1267
1269 }
1270
1271 void moveTo(const bx::Vec3& _pos)
1272 {
1273 BX_ASSERT(State::Count != m_state, "");
1274 moveTo(_pos.x, _pos.y, _pos.z);
1275 }
1276
1277 void moveTo(Axis::Enum _axis, float _x, float _y)
1278 {
1279 moveTo(getPoint(_axis, _x, _y));
1280 }
1281
1282 void lineTo(float _x, float _y, float _z = 0.0f)
1283 {
1284 BX_ASSERT(State::Count != m_state, "");
1285 if(State::None == m_state)
1286 {
1287 moveTo(_x, _y, _z);
1288 return;
1289 }
1290
1291 if(m_pos + 2 > uint16_t(BX_COUNTOF(m_cache)))
1292 {
1293 uint32_t pos = m_pos;
1294 uint32_t vertexPos = m_vertexPos;
1295
1296 flush();
1297
1298 bx::memCopy(&m_cache[0], &m_cache[vertexPos], sizeof(DebugVertex));
1299 if(vertexPos == pos)
1300 {
1301 m_pos = 1;
1302 }
1303 else
1304 {
1305 bx::memCopy(&m_cache[1], &m_cache[pos - 1], sizeof(DebugVertex));
1306 m_pos = 2;
1307 }
1308
1310 }
1311 else if(State::MoveTo == m_state)
1312 {
1313 ++m_pos;
1315 }
1316
1317 uint16_t prev = m_pos - 1;
1318 uint16_t curr = m_pos++;
1319 DebugVertex& vertex = m_cache[curr];
1320 vertex.m_x = _x;
1321 vertex.m_y = _y;
1322 vertex.m_z = _z;
1323
1324 Attrib& attrib = m_attrib[m_stack];
1325 vertex.m_abgr = attrib.m_abgr;
1326 vertex.m_len = attrib.m_offset;
1327
1328 float len = bx::length(bx::sub(bx::load<bx::Vec3>(&vertex.m_x), bx::load<bx::Vec3>(&m_cache[prev].m_x))) *
1329 attrib.m_scale;
1330 vertex.m_len = m_cache[prev].m_len + len;
1331
1332 m_indices[m_indexPos++] = prev;
1333 m_indices[m_indexPos++] = curr;
1334 }
1335
1336 void lineTo(const bx::Vec3& _pos)
1337 {
1338 BX_ASSERT(State::Count != m_state, "");
1339 lineTo(_pos.x, _pos.y, _pos.z);
1340 }
1341
1342 void lineTo(Axis::Enum _axis, float _x, float _y)
1343 {
1344 lineTo(getPoint(_axis, _x, _y));
1345 }
1346
1347 void close()
1348 {
1349 BX_ASSERT(State::Count != m_state, "");
1350 DebugVertex& vertex = m_cache[m_vertexPos];
1351 lineTo(vertex.m_x, vertex.m_y, vertex.m_z);
1352
1354 }
1355
1356 void draw(const bx::Aabb& _aabb)
1357 {
1358 const Attrib& attrib = m_attrib[m_stack];
1359 if(attrib.m_wireframe)
1360 {
1361 moveTo(_aabb.min.x, _aabb.min.y, _aabb.min.z);
1362 lineTo(_aabb.max.x, _aabb.min.y, _aabb.min.z);
1363 lineTo(_aabb.max.x, _aabb.max.y, _aabb.min.z);
1364 lineTo(_aabb.min.x, _aabb.max.y, _aabb.min.z);
1365 close();
1366
1367 moveTo(_aabb.min.x, _aabb.min.y, _aabb.max.z);
1368 lineTo(_aabb.max.x, _aabb.min.y, _aabb.max.z);
1369 lineTo(_aabb.max.x, _aabb.max.y, _aabb.max.z);
1370 lineTo(_aabb.min.x, _aabb.max.y, _aabb.max.z);
1371 close();
1372
1373 moveTo(_aabb.min.x, _aabb.min.y, _aabb.min.z);
1374 lineTo(_aabb.min.x, _aabb.min.y, _aabb.max.z);
1375
1376 moveTo(_aabb.max.x, _aabb.min.y, _aabb.min.z);
1377 lineTo(_aabb.max.x, _aabb.min.y, _aabb.max.z);
1378
1379 moveTo(_aabb.min.x, _aabb.max.y, _aabb.min.z);
1380 lineTo(_aabb.min.x, _aabb.max.y, _aabb.max.z);
1381
1382 moveTo(_aabb.max.x, _aabb.max.y, _aabb.min.z);
1383 lineTo(_aabb.max.x, _aabb.max.y, _aabb.max.z);
1384 }
1385 else
1386 {
1387 bx::Obb obb;
1388 toObb(obb, _aabb);
1389 draw(DebugMesh::Cube, obb.mtx, 1, false);
1390 }
1391 }
1392
1393 void draw(const bx::Cylinder& _cylinder, bool _capsule)
1394 {
1395 drawCylinder(_cylinder.pos, _cylinder.end, _cylinder.radius, _capsule);
1396 }
1397
1398 void draw(const bx::Disk& _disk)
1399 {
1400 drawCircle(_disk.normal, _disk.center, _disk.radius, 0.0f);
1401 }
1402
1403 void draw(const bx::Obb& _obb)
1404 {
1405 const Attrib& attrib = m_attrib[m_stack];
1406 if(attrib.m_wireframe)
1407 {
1408 pushTransform(_obb.mtx, 1);
1409
1410 moveTo(-1.0f, -1.0f, -1.0f);
1411 lineTo(1.0f, -1.0f, -1.0f);
1412 lineTo(1.0f, 1.0f, -1.0f);
1413 lineTo(-1.0f, 1.0f, -1.0f);
1414 close();
1415
1416 moveTo(-1.0f, 1.0f, 1.0f);
1417 lineTo(1.0f, 1.0f, 1.0f);
1418 lineTo(1.0f, -1.0f, 1.0f);
1419 lineTo(-1.0f, -1.0f, 1.0f);
1420 close();
1421
1422 moveTo(1.0f, -1.0f, -1.0f);
1423 lineTo(1.0f, -1.0f, 1.0f);
1424
1425 moveTo(1.0f, 1.0f, -1.0f);
1426 lineTo(1.0f, 1.0f, 1.0f);
1427
1428 moveTo(-1.0f, 1.0f, -1.0f);
1429 lineTo(-1.0f, 1.0f, 1.0f);
1430
1431 moveTo(-1.0f, -1.0f, -1.0f);
1432 lineTo(-1.0f, -1.0f, 1.0f);
1433
1434 popTransform();
1435 }
1436 else
1437 {
1438 draw(DebugMesh::Cube, _obb.mtx, 1, false);
1439 }
1440 }
1441
1442 void draw(const bx::Sphere& _sphere)
1443 {
1444 const Attrib& attrib = m_attrib[m_stack];
1445 float mtx[16];
1446 bx::mtxSRT(mtx,
1447 _sphere.radius,
1448 _sphere.radius,
1449 _sphere.radius,
1450 0.0f,
1451 0.0f,
1452 0.0f,
1453 _sphere.center.x,
1454 _sphere.center.y,
1455 _sphere.center.z);
1456 uint8_t lod = attrib.m_lod > DebugMesh::SphereMaxLod ? uint8_t(DebugMesh::SphereMaxLod) : attrib.m_lod;
1457 draw(DebugMesh::Enum(DebugMesh::Sphere0 + lod), mtx, 1, attrib.m_wireframe);
1458 }
1459
1460 void draw(const bx::Triangle& _triangle)
1461 {
1462 Attrib& attrib = m_attrib[m_stack];
1463 if(attrib.m_wireframe)
1464 {
1465 moveTo(_triangle.v0);
1466 lineTo(_triangle.v1);
1467 lineTo(_triangle.v2);
1468 close();
1469 }
1470 else
1471 {
1472 static_assert(sizeof(DdVertex) == sizeof(bx::Vec3), "");
1473
1474 uint64_t old = attrib.m_state;
1475 attrib.m_state &= ~BGFX_STATE_CULL_MASK;
1476
1477 draw(false, 3, reinterpret_cast<const DdVertex*>(&_triangle.v0.x), 0, NULL);
1478
1479 attrib.m_state = old;
1480 }
1481 }
1482
1483 void setUParams(const Attrib& _attrib, bool _wireframe)
1484 {
1485 const float flip = 0 == (_attrib.m_state & BGFX_STATE_CULL_CCW) ? 1.0f : -1.0f;
1486 const uint8_t alpha = _attrib.m_abgr >> 24;
1487 bool alphaBlend = _attrib.m_alphaBlend;
1488
1489 float params[4][4] = {
1490 {
1491 // lightDir
1492 0.0f * flip,
1493 -1.0f * flip,
1494 0.0f * flip,
1495 3.0f, // shininess
1496 },
1497 {
1498 // skyColor
1499 1.0f,
1500 0.9f,
1501 0.8f,
1502 0.0f, // unused
1503 },
1504 {
1505 // groundColor.xyz0
1506 0.2f,
1507 0.22f,
1508 0.5f,
1509 0.0f, // unused
1510 },
1511 {
1512 // matColor
1513 ((_attrib.m_abgr) & 0xff) / 255.0f,
1514 ((_attrib.m_abgr >> 8) & 0xff) / 255.0f,
1515 ((_attrib.m_abgr >> 16) & 0xff) / 255.0f,
1516 (alpha) / 255.0f,
1517 },
1518 };
1519
1520 bx::store(params[0], bx::normalize(bx::load<bx::Vec3>(params[0])));
1521 m_encoder->setUniform(s_dds.u_params, params, 4);
1522
1523 uint32_t blendFlags = alphaBlend ? BGFX_STATE_BLEND_ALPHA : 0;
1524 m_encoder->setState(0 | _attrib.m_state |
1525 (_wireframe ? BGFX_STATE_PT_LINES | BGFX_STATE_LINEAA | blendFlags
1526 : (alpha < 0xff) ? blendFlags
1527 : 0));
1528 }
1529
1530 void draw(GeometryHandle _handle)
1531 {
1532 const Geometry::Geometry& geometry = s_dds.m_geometry.m_geometry[_handle.idx];
1533 m_encoder->setVertexBuffer(0, geometry.m_vbh);
1534
1535 const Attrib& attrib = m_attrib[m_stack];
1536 const bool wireframe = attrib.m_wireframe;
1537 setUParams(attrib, wireframe);
1538
1539 if(wireframe)
1540 {
1541 m_encoder->setIndexBuffer(geometry.m_ibh,
1542 geometry.m_topologyNumIndices[0],
1543 geometry.m_topologyNumIndices[1]);
1544 }
1545 else if(0 != geometry.m_topologyNumIndices[0])
1546 {
1547 m_encoder->setIndexBuffer(geometry.m_ibh, 0, geometry.m_topologyNumIndices[0]);
1548 }
1549
1550 m_encoder->setTransform(m_mtxStack[m_mtxStackCurrent].mtx);
1551 bgfx::ProgramHandle program = s_dds.m_program[wireframe ? Program::FillMesh : Program::FillLitMesh];
1552 m_encoder->submit(m_viewId, program);
1553 }
1554
1555 void draw(bool _lineList,
1556 uint32_t _numVertices,
1557 const DdVertex* _vertices,
1558 uint32_t _numIndices,
1559 const uint16_t* _indices)
1560 {
1561 flush();
1562
1563 if(_numVertices == bgfx::getAvailTransientVertexBuffer(_numVertices, DebugMeshVertex::ms_layout))
1564 {
1565 bgfx::TransientVertexBuffer tvb;
1566 bgfx::allocTransientVertexBuffer(&tvb, _numVertices, DebugMeshVertex::ms_layout);
1567 bx::memCopy(tvb.data, _vertices, _numVertices * DebugMeshVertex::ms_layout.m_stride);
1568 m_encoder->setVertexBuffer(0, &tvb);
1569
1570 const Attrib& attrib = m_attrib[m_stack];
1571 const bool wireframe = _lineList || attrib.m_wireframe;
1572 setUParams(attrib, wireframe);
1573
1574 if(0 < _numIndices)
1575 {
1576 uint32_t numIndices = _numIndices;
1577 bgfx::TransientIndexBuffer tib;
1578 if(!_lineList && wireframe)
1579 {
1580 numIndices = bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList,
1581 NULL,
1582 0,
1583 _indices,
1584 _numIndices,
1585 false);
1586
1587 bgfx::allocTransientIndexBuffer(&tib, numIndices);
1588 bgfx::topologyConvert(bgfx::TopologyConvert::TriListToLineList,
1589 tib.data,
1590 numIndices * sizeof(uint16_t),
1591 _indices,
1592 _numIndices,
1593 false);
1594 }
1595 else
1596 {
1597 bgfx::allocTransientIndexBuffer(&tib, numIndices);
1598 bx::memCopy(tib.data, _indices, numIndices * sizeof(uint16_t));
1599 }
1600
1601 m_encoder->setIndexBuffer(&tib);
1602 }
1603
1604 m_encoder->setTransform(m_mtxStack[m_mtxStackCurrent].mtx);
1605 bgfx::ProgramHandle program = s_dds.m_program[wireframe ? Program::FillMesh : Program::FillLitMesh];
1606 m_encoder->submit(m_viewId, program);
1607 }
1608 }
1609
1610 void drawFrustum(const float* _viewProj)
1611 {
1612 bx::Plane planes[6] = {bx::InitNone, bx::InitNone, bx::InitNone, bx::InitNone, bx::InitNone, bx::InitNone};
1613 buildFrustumPlanes(planes, _viewProj);
1614
1615 const bx::Vec3 points[8] = {
1616 intersectPlanes(planes[0], planes[2], planes[4]),
1617 intersectPlanes(planes[0], planes[3], planes[4]),
1618 intersectPlanes(planes[0], planes[3], planes[5]),
1619 intersectPlanes(planes[0], planes[2], planes[5]),
1620 intersectPlanes(planes[1], planes[2], planes[4]),
1621 intersectPlanes(planes[1], planes[3], planes[4]),
1622 intersectPlanes(planes[1], planes[3], planes[5]),
1623 intersectPlanes(planes[1], planes[2], planes[5]),
1624 };
1625
1626 moveTo(points[0]);
1627 lineTo(points[1]);
1628 lineTo(points[2]);
1629 lineTo(points[3]);
1630 close();
1631
1632 moveTo(points[4]);
1633 lineTo(points[5]);
1634 lineTo(points[6]);
1635 lineTo(points[7]);
1636 close();
1637
1638 moveTo(points[0]);
1639 lineTo(points[4]);
1640
1641 moveTo(points[1]);
1642 lineTo(points[5]);
1643
1644 moveTo(points[2]);
1645 lineTo(points[6]);
1646
1647 moveTo(points[3]);
1648 lineTo(points[7]);
1649 }
1650
1651 void drawFrustum(const void* _viewProj)
1652 {
1653 drawFrustum((const float*)_viewProj);
1654 }
1655
1656 void drawArc(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _degrees)
1657 {
1658 const Attrib& attrib = m_attrib[m_stack];
1659 const uint32_t num = getCircleLod(attrib.m_lod);
1660 const float step = bx::kPi * 2.0f / num;
1661
1662 _degrees = bx::wrap(_degrees, 360.0f);
1663
1664 bx::Vec3 pos = getPoint(_axis, bx::sin(step * 0) * _radius, bx::cos(step * 0) * _radius);
1665
1666 moveTo({pos.x + _x, pos.y + _y, pos.z + _z});
1667
1668 uint32_t n = uint32_t(num * _degrees / 360.0f);
1669
1670 for(uint32_t ii = 1; ii < n + 1; ++ii)
1671 {
1672 pos = getPoint(_axis, bx::sin(step * ii) * _radius, bx::cos(step * ii) * _radius);
1673 lineTo({pos.x + _x, pos.y + _y, pos.z + _z});
1674 }
1675
1676 moveTo(_x, _y, _z);
1677 pos = getPoint(_axis, bx::sin(step * 0) * _radius, bx::cos(step * 0) * _radius);
1678 lineTo({pos.x + _x, pos.y + _y, pos.z + _z});
1679
1680 pos = getPoint(_axis, bx::sin(step * n) * _radius, bx::cos(step * n) * _radius);
1681 moveTo({pos.x + _x, pos.y + _y, pos.z + _z});
1682 lineTo(_x, _y, _z);
1683 }
1684
1685 void drawCircle(const bx::Vec3& _normal, const bx::Vec3& _center, float _radius, float _weight)
1686 {
1687 const Attrib& attrib = m_attrib[m_stack];
1688 const uint32_t num = getCircleLod(attrib.m_lod);
1689 const float step = bx::kPi * 2.0f / num;
1690 _weight = bx::clamp(_weight, 0.0f, 2.0f);
1691
1692 bx::Vec3 udir(bx::InitNone);
1693 bx::Vec3 vdir(bx::InitNone);
1694 bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
1695
1696 float xy0[2];
1697 float xy1[2];
1698 circle(xy0, 0.0f);
1699 squircle(xy1, 0.0f);
1700
1701 bx::Vec3 pos = bx::mul(udir, bx::lerp(xy0[0], xy1[0], _weight) * _radius);
1702 bx::Vec3 tmp0 = bx::mul(vdir, bx::lerp(xy0[1], xy1[1], _weight) * _radius);
1703 bx::Vec3 tmp1 = bx::add(pos, tmp0);
1704 bx::Vec3 tmp2 = bx::add(tmp1, _center);
1705 moveTo(tmp2);
1706
1707 for(uint32_t ii = 1; ii < num; ++ii)
1708 {
1709 float angle = step * ii;
1710 circle(xy0, angle);
1711 squircle(xy1, angle);
1712
1713 pos = bx::mul(udir, bx::lerp(xy0[0], xy1[0], _weight) * _radius);
1714 tmp0 = bx::mul(vdir, bx::lerp(xy0[1], xy1[1], _weight) * _radius);
1715 tmp1 = bx::add(pos, tmp0);
1716 tmp2 = bx::add(tmp1, _center);
1717 lineTo(tmp2);
1718 }
1719
1720 close();
1721 }
1722
1723 void drawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight)
1724 {
1725 const Attrib& attrib = m_attrib[m_stack];
1726 const uint32_t num = getCircleLod(attrib.m_lod);
1727 const float step = bx::kPi * 2.0f / num;
1728 _weight = bx::clamp(_weight, 0.0f, 2.0f);
1729
1730 float xy0[2];
1731 float xy1[2];
1732 circle(xy0, 0.0f);
1733 squircle(xy1, 0.0f);
1734
1735 bx::Vec3 pos =
1736 getPoint(_axis, bx::lerp(xy0[0], xy1[0], _weight) * _radius, bx::lerp(xy0[1], xy1[1], _weight) * _radius);
1737
1738 moveTo({pos.x + _x, pos.y + _y, pos.z + _z});
1739
1740 for(uint32_t ii = 1; ii < num; ++ii)
1741 {
1742 float angle = step * ii;
1743 circle(xy0, angle);
1744 squircle(xy1, angle);
1745
1746 pos = getPoint(_axis,
1747 bx::lerp(xy0[0], xy1[0], _weight) * _radius,
1748 bx::lerp(xy0[1], xy1[1], _weight) * _radius);
1749 lineTo({pos.x + _x, pos.y + _y, pos.z + _z});
1750 }
1751 close();
1752 }
1753
1754 void drawQuad(const bx::Vec3& _normal, const bx::Vec3& _center, float _size)
1755 {
1756 const Attrib& attrib = m_attrib[m_stack];
1757 if(attrib.m_wireframe)
1758 {
1759 bx::Vec3 udir(bx::InitNone);
1760 bx::Vec3 vdir(bx::InitNone);
1761 bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
1762
1763 const float halfExtent = _size * 0.5f;
1764
1765 const bx::Vec3 umin = bx::mul(udir, -halfExtent);
1766 const bx::Vec3 umax = bx::mul(udir, halfExtent);
1767 const bx::Vec3 vmin = bx::mul(vdir, -halfExtent);
1768 const bx::Vec3 vmax = bx::mul(vdir, halfExtent);
1769 const bx::Vec3 center = _center;
1770
1771 moveTo(bx::add(center, bx::add(umin, vmin)));
1772 lineTo(bx::add(center, bx::add(umax, vmin)));
1773 lineTo(bx::add(center, bx::add(umax, vmax)));
1774 lineTo(bx::add(center, bx::add(umin, vmax)));
1775
1776 close();
1777 }
1778 else
1779 {
1780 float mtx[16];
1781 bx::mtxFromNormal(mtx, _normal, _size * 0.5f, _center, attrib.m_spin);
1782 draw(DebugMesh::Quad, mtx, 1, false);
1783 }
1784 }
1785
1786 void drawQuad(SpriteHandle _handle, const bx::Vec3& _normal, const bx::Vec3& _center, float _size)
1787 {
1788 if(!isValid(_handle))
1789 {
1790 drawQuad(_normal, _center, _size);
1791 return;
1792 }
1793
1794 if(m_posQuad == BX_COUNTOF(m_cacheQuad))
1795 {
1796 flushQuad();
1797 }
1798
1799 const Attrib& attrib = m_attrib[m_stack];
1800
1801 bx::Vec3 udir(bx::InitNone);
1802 bx::Vec3 vdir(bx::InitNone);
1803 bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
1804
1805 const Pack2D& pack = s_dds.m_sprite.get(_handle);
1806 const float invTextureSize = 1.0f / SPRITE_TEXTURE_SIZE;
1807 const float us = pack.m_x * invTextureSize;
1808 const float vs = pack.m_y * invTextureSize;
1809 const float ue = (pack.m_x + pack.m_width) * invTextureSize;
1810 const float ve = (pack.m_y + pack.m_height) * invTextureSize;
1811
1812 const float aspectRatio = float(pack.m_width) / float(pack.m_height);
1813 const float halfExtentU = aspectRatio * _size * 0.5f;
1814 const float halfExtentV = 1.0f / aspectRatio * _size * 0.5f;
1815
1816 const bx::Vec3 umin = bx::mul(udir, -halfExtentU);
1817 const bx::Vec3 umax = bx::mul(udir, halfExtentU);
1818 const bx::Vec3 vmin = bx::mul(vdir, -halfExtentV);
1819 const bx::Vec3 vmax = bx::mul(vdir, halfExtentV);
1820 const bx::Vec3 center = _center;
1821
1823 m_posQuad += 4;
1824
1825 bx::store(&vertex->m_x, bx::add(center, bx::add(umin, vmin)));
1826 vertex->m_u = us;
1827 vertex->m_v = vs;
1828 vertex->m_abgr = attrib.m_abgr;
1829 ++vertex;
1830
1831 bx::store(&vertex->m_x, bx::add(center, bx::add(umax, vmin)));
1832 vertex->m_u = ue;
1833 vertex->m_v = vs;
1834 vertex->m_abgr = attrib.m_abgr;
1835 ++vertex;
1836
1837 bx::store(&vertex->m_x, bx::add(center, bx::add(umin, vmax)));
1838 vertex->m_u = us;
1839 vertex->m_v = ve;
1840 vertex->m_abgr = attrib.m_abgr;
1841 ++vertex;
1842
1843 bx::store(&vertex->m_x, bx::add(center, bx::add(umax, vmax)));
1844 vertex->m_u = ue;
1845 vertex->m_v = ve;
1846 vertex->m_abgr = attrib.m_abgr;
1847 ++vertex;
1848 }
1849
1850 void drawQuad(bgfx::TextureHandle _handle, const bx::Vec3& _normal, const bx::Vec3& _center, float _size)
1851 {
1852 // BX_UNUSED(_handle, _normal, _center, _size);
1853 if(!isValid(_handle))
1854 {
1855 drawQuad(_normal, _center, _size);
1856 return;
1857 }
1858
1859 flushQuad();
1860
1861 Attrib& attrib = m_attrib[m_stack];
1862
1863 if((attrib.m_state & BGFX_STATE_WRITE_A) == 0 && attrib.m_alphaBlend)
1864 attrib.m_state |= BGFX_STATE_BLEND_ALPHA;
1865
1866 bx::Vec3 udir(bx::InitNone);
1867 bx::Vec3 vdir(bx::InitNone);
1868 bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
1869
1870 const float us = 0.0f;
1871 const float vs = 0.0f;
1872 const float ue = 1.0f;
1873 const float ve = 1.0f;
1874
1875 const float aspectRatio = 1.0f;
1876 const float halfExtentU = aspectRatio * _size * 0.5f;
1877 const float halfExtentV = 1.0f / aspectRatio * _size * 0.5f;
1878
1879 const bx::Vec3 umin = bx::mul(udir, -halfExtentU);
1880 const bx::Vec3 umax = bx::mul(udir, halfExtentU);
1881 const bx::Vec3 vmin = bx::mul(vdir, -halfExtentV);
1882 const bx::Vec3 vmax = bx::mul(vdir, halfExtentV);
1883 const bx::Vec3 center = _center;
1884
1886 m_posQuad += 4;
1887
1888 bx::store(&vertex->m_x, bx::add(center, bx::add(umin, vmin)));
1889 vertex->m_u = us;
1890 vertex->m_v = vs;
1891 vertex->m_abgr = attrib.m_abgr;
1892 ++vertex;
1893
1894 bx::store(&vertex->m_x, bx::add(center, bx::add(umax, vmin)));
1895 vertex->m_u = ue;
1896 vertex->m_v = vs;
1897 vertex->m_abgr = attrib.m_abgr;
1898 ++vertex;
1899
1900 bx::store(&vertex->m_x, bx::add(center, bx::add(umin, vmax)));
1901 vertex->m_u = us;
1902 vertex->m_v = ve;
1903 vertex->m_abgr = attrib.m_abgr;
1904 ++vertex;
1905
1906 bx::store(&vertex->m_x, bx::add(center, bx::add(umax, vmax)));
1907 vertex->m_u = ue;
1908 vertex->m_v = ve;
1909 vertex->m_abgr = attrib.m_abgr;
1910 ++vertex;
1911
1912 auto original = s_dds.m_texture;
1913 s_dds.m_texture = _handle;
1914 flushQuad();
1915
1916 attrib.m_state &= ~BGFX_STATE_BLEND_ALPHA;
1917
1918 s_dds.m_texture = original;
1919 }
1920
1921 void drawCone(const bx::Vec3& _from, const bx::Vec3& _to, float _radius)
1922 {
1923 const Attrib& attrib = m_attrib[m_stack];
1924
1925 const bx::Vec3 normal = bx::normalize(bx::sub(_from, _to));
1926
1927 float mtx[2][16];
1928 bx::mtxFromNormal(mtx[0], normal, _radius, _from, attrib.m_spin);
1929
1930 bx::memCopy(mtx[1], mtx[0], 64);
1931 mtx[1][12] = _to.x;
1932 mtx[1][13] = _to.y;
1933 mtx[1][14] = _to.z;
1934
1935 uint8_t lod = attrib.m_lod > DebugMesh::ConeMaxLod ? uint8_t(DebugMesh::ConeMaxLod) : attrib.m_lod;
1936 draw(DebugMesh::Enum(DebugMesh::Cone0 + lod), mtx[0], 2, attrib.m_wireframe);
1937 }
1938
1939 void drawCylinder(const bx::Vec3& _from, const bx::Vec3& _to, float _radius, bool _capsule)
1940 {
1941 const Attrib& attrib = m_attrib[m_stack];
1942 const bx::Vec3 normal = bx::normalize(bx::sub(_from, _to));
1943
1944 float mtx[2][16];
1945 bx::mtxFromNormal(mtx[0], normal, _radius, _from, attrib.m_spin);
1946
1947 bx::memCopy(mtx[1], mtx[0], 64);
1948 mtx[1][12] = _to.x;
1949 mtx[1][13] = _to.y;
1950 mtx[1][14] = _to.z;
1951
1952 if(_capsule)
1953 {
1954 uint8_t lod = attrib.m_lod > DebugMesh::CapsuleMaxLod ? uint8_t(DebugMesh::CapsuleMaxLod) : attrib.m_lod;
1955 draw(DebugMesh::Enum(DebugMesh::Capsule0 + lod), mtx[0], 2, attrib.m_wireframe);
1956
1957 bx::Sphere sphere;
1958 sphere.center = _from;
1959 sphere.radius = _radius;
1960 draw(sphere);
1961
1962 sphere.center = _to;
1963 draw(sphere);
1964 }
1965 else
1966 {
1967 uint8_t lod = attrib.m_lod > DebugMesh::CylinderMaxLod ? uint8_t(DebugMesh::CylinderMaxLod) : attrib.m_lod;
1968 draw(DebugMesh::Enum(DebugMesh::Cylinder0 + lod), mtx[0], 2, attrib.m_wireframe);
1969 }
1970 }
1971
1972 void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight, float _thickness)
1973 {
1974 push();
1975
1976 if(_thickness > 0.0f)
1977 {
1978 const bx::Vec3 from = {_x, _y, _z};
1979 bx::Vec3 mid(bx::InitNone);
1980 bx::Vec3 to(bx::InitNone);
1981
1982 setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff);
1983 mid = {_x + _len - _thickness, _y, _z};
1984 to = {_x + _len, _y, _z};
1985 drawCylinder(from, mid, _thickness, false);
1986 drawCone(mid, to, _thickness);
1987
1988 setColor(Axis::Y == _highlight ? 0xff00ffff : 0xff00ff00);
1989 mid = {_x, _y + _len - _thickness, _z};
1990 to = {_x, _y + _len, _z};
1991 drawCylinder(from, mid, _thickness, false);
1992 drawCone(mid, to, _thickness);
1993
1994 setColor(Axis::Z == _highlight ? 0xff00ffff : 0xffff0000);
1995 mid = {_x, _y, _z + _len - _thickness};
1996 to = {_x, _y, _z + _len};
1997 drawCylinder(from, mid, _thickness, false);
1998 drawCone(mid, to, _thickness);
1999 }
2000 else
2001 {
2002 setColor(Axis::X == _highlight ? 0xff00ffff : 0xff0000ff);
2003 moveTo(_x, _y, _z);
2004 lineTo(_x + _len, _y, _z);
2005
2006 setColor(Axis::Y == _highlight ? 0xff00ffff : 0xff00ff00);
2007 moveTo(_x, _y, _z);
2008 lineTo(_x, _y + _len, _z);
2009
2010 setColor(Axis::Z == _highlight ? 0xff00ffff : 0xffff0000);
2011 moveTo(_x, _y, _z);
2012 lineTo(_x, _y, _z + _len);
2013 }
2014
2015 pop();
2016 }
2017
2018 void drawGrid(const bx::Vec3& _normal, const bx::Vec3& _center, uint32_t _size, float _step)
2019 {
2020 const Attrib& attrib = m_attrib[m_stack];
2021
2022 bx::Vec3 udir(bx::InitNone);
2023 bx::Vec3 vdir(bx::InitNone);
2024 bx::calcTangentFrame(udir, vdir, _normal, attrib.m_spin);
2025
2026 udir = bx::mul(udir, _step);
2027 vdir = bx::mul(vdir, _step);
2028
2029 const uint32_t num = (_size / 2) * 2 + 1;
2030 const float halfExtent = float(_size / 2);
2031
2032 const bx::Vec3 umin = bx::mul(udir, -halfExtent);
2033 const bx::Vec3 umax = bx::mul(udir, halfExtent);
2034 const bx::Vec3 vmin = bx::mul(vdir, -halfExtent);
2035 const bx::Vec3 vmax = bx::mul(vdir, halfExtent);
2036
2037 bx::Vec3 xs = bx::add(_center, bx::add(umin, vmin));
2038 bx::Vec3 xe = bx::add(_center, bx::add(umax, vmin));
2039 bx::Vec3 ys = bx::add(_center, bx::add(umin, vmin));
2040 bx::Vec3 ye = bx::add(_center, bx::add(umin, vmax));
2041
2042 for(uint32_t ii = 0; ii < num; ++ii)
2043 {
2044 moveTo(xs);
2045 lineTo(xe);
2046 xs = bx::add(xs, vdir);
2047 xe = bx::add(xe, vdir);
2048
2049 moveTo(ys);
2050 lineTo(ye);
2051 ys = bx::add(ys, udir);
2052 ye = bx::add(ye, udir);
2053 }
2054 }
2055
2056 void drawGrid(Axis::Enum _axis, const bx::Vec3& _center, uint32_t _size, float _step)
2057 {
2058 push();
2059 pushTranslate(_center);
2060
2061 const uint32_t num = (_size / 2) * 2 - 1;
2062 const float halfExtent = float(_size / 2) * _step;
2063
2064 setColor(0xff606060);
2065 float yy = -halfExtent + _step;
2066 for(uint32_t ii = 0; ii < num; ++ii)
2067 {
2068 moveTo(_axis, -halfExtent, yy);
2069 lineTo(_axis, halfExtent, yy);
2070
2071 moveTo(_axis, yy, -halfExtent);
2072 lineTo(_axis, yy, halfExtent);
2073
2074 yy += _step;
2075 }
2076
2077 setColor(0xff101010);
2078 moveTo(_axis, -halfExtent, -halfExtent);
2079 lineTo(_axis, -halfExtent, halfExtent);
2080 lineTo(_axis, halfExtent, halfExtent);
2081 lineTo(_axis, halfExtent, -halfExtent);
2082 close();
2083
2084 moveTo(_axis, -halfExtent, 0.0f);
2085 lineTo(_axis, halfExtent, 0.0f);
2086
2087 moveTo(_axis, 0.0f, -halfExtent);
2088 lineTo(_axis, 0.0f, halfExtent);
2089
2090 popTransform();
2091 pop();
2092 }
2093
2094 void drawOrb(float _x, float _y, float _z, float _radius, Axis::Enum _hightlight)
2095 {
2096 push();
2097
2098 setColor(Axis::X == _hightlight ? 0xff00ffff : 0xff0000ff);
2099 drawCircle(Axis::X, _x, _y, _z, _radius, 0.0f);
2100
2101 setColor(Axis::Y == _hightlight ? 0xff00ffff : 0xff00ff00);
2102 drawCircle(Axis::Y, _x, _y, _z, _radius, 0.0f);
2103
2104 setColor(Axis::Z == _hightlight ? 0xff00ffff : 0xffff0000);
2105 drawCircle(Axis::Z, _x, _y, _z, _radius, 0.0f);
2106
2107 pop();
2108 }
2109
2110 void draw(DebugMesh::Enum _mesh, const float* _mtx, uint16_t _num, bool _wireframe)
2111 {
2112 pushTransform(_mtx, _num, false /* flush */);
2113
2114 const DebugMesh& mesh = s_dds.m_mesh[_mesh];
2115
2116 if(0 != mesh.m_numIndices[_wireframe])
2117 {
2118 m_encoder->setIndexBuffer(s_dds.m_ibh, mesh.m_startIndex[_wireframe], mesh.m_numIndices[_wireframe]);
2119 }
2120
2121 const Attrib& attrib = m_attrib[m_stack];
2122 setUParams(attrib, _wireframe);
2123
2125 m_encoder->setTransform(stack.mtx, stack.num);
2126
2127 m_encoder->setVertexBuffer(0, s_dds.m_vbh, mesh.m_startVertex, mesh.m_numVertices);
2128 m_encoder->submit(m_viewId, s_dds.m_program[_wireframe ? Program::Fill : Program::Fill]);
2129
2130 popTransform(false /* flush */);
2131 }
2132
2134 {
2135 if(m_pos == uint16_t(BX_COUNTOF(m_cache)))
2136 {
2137 flush();
2138 }
2139 }
2140
2141 void flush()
2142 {
2143 if(0 != m_pos)
2144 {
2146 {
2147 bgfx::TransientVertexBuffer tvb;
2148 bgfx::allocTransientVertexBuffer(&tvb, m_pos, DebugVertex::ms_layout);
2149 bx::memCopy(tvb.data, m_cache, m_pos * DebugVertex::ms_layout.m_stride);
2150
2151 bgfx::TransientIndexBuffer tib;
2152 bgfx::allocTransientIndexBuffer(&tib, m_indexPos);
2153 bx::memCopy(tib.data, m_indices, m_indexPos * sizeof(uint16_t));
2154
2155 const Attrib& attrib = m_attrib[m_stack];
2156
2157 m_encoder->setVertexBuffer(0, &tvb);
2158 m_encoder->setIndexBuffer(&tib);
2159 m_encoder->setState(0 | BGFX_STATE_WRITE_RGB | BGFX_STATE_PT_LINES | attrib.m_state |
2160 BGFX_STATE_LINEAA | (attrib.m_alphaBlend ? BGFX_STATE_BLEND_ALPHA : 0));
2161 m_encoder->setTransform(m_mtxStack[m_mtxStackCurrent].mtx);
2162 bgfx::ProgramHandle program = s_dds.m_program[attrib.m_stipple ? 1 : 0];
2163 m_encoder->submit(m_viewId, program);
2164 }
2165
2167 m_pos = 0;
2168 m_indexPos = 0;
2169 m_vertexPos = 0;
2170 }
2171 }
2172
2174 {
2175 if(0 != m_posQuad)
2176 {
2177 const uint32_t numIndices = m_posQuad / 4 * 6;
2179 {
2180 bgfx::TransientVertexBuffer tvb;
2181 bgfx::allocTransientVertexBuffer(&tvb, m_posQuad, DebugUvVertex::ms_layout);
2182 bx::memCopy(tvb.data, m_cacheQuad, m_posQuad * DebugUvVertex::ms_layout.m_stride);
2183
2184 bgfx::TransientIndexBuffer tib;
2185 bgfx::allocTransientIndexBuffer(&tib, numIndices);
2186 uint16_t* indices = (uint16_t*)tib.data;
2187 for(uint16_t ii = 0, num = m_posQuad / 4; ii < num; ++ii)
2188 {
2189 uint16_t startVertex = ii * 4;
2190 indices[0] = startVertex + 0;
2191 indices[1] = startVertex + 1;
2192 indices[2] = startVertex + 2;
2193 indices[3] = startVertex + 1;
2194 indices[4] = startVertex + 3;
2195 indices[5] = startVertex + 2;
2196 indices += 6;
2197 }
2198
2199 const Attrib& attrib = m_attrib[m_stack];
2200
2201 m_encoder->setVertexBuffer(0, &tvb);
2202 m_encoder->setIndexBuffer(&tib);
2203 m_encoder->setState(0 | (attrib.m_state & ~BGFX_STATE_CULL_MASK));
2204 m_encoder->setTransform(m_mtxStack[m_mtxStackCurrent].mtx);
2205 m_encoder->setTexture(0, s_dds.s_texColor, s_dds.m_texture);
2206
2207 if(m_programStackCurrent >= 0)
2208 {
2210 }
2211 else
2212 {
2214 }
2215 }
2216
2217 m_posQuad = 0;
2218 }
2219 }
2220
2221 struct State
2222 {
2223 enum Enum
2224 {
2228
2229 Count
2231 };
2232
2233 static const uint32_t kCacheSize = 1024;
2234 static const uint32_t kStackSize = 16;
2235 static const uint32_t kCacheQuadSize = 1024;
2236 static_assert(kCacheSize >= 3, "Cache must be at least 3 elements.");
2237
2240 uint16_t m_indices[kCacheSize * 2];
2241 uint16_t m_pos;
2242 uint16_t m_posQuad;
2243 uint16_t m_indexPos;
2244 uint16_t m_vertexPos;
2246
2248 {
2249 void reset()
2250 {
2251 mtx = 0;
2252 num = 1;
2253 data = NULL;
2254 }
2255
2256 uint32_t mtx;
2257 uint16_t num;
2258 float* data;
2259 };
2260
2262
2264 bgfx::ProgramHandle m_programStack[32];
2265
2266 bgfx::ViewId m_viewId;
2267 uint8_t m_stack;
2269
2271
2273
2274 bgfx::Encoder* m_encoder;
2275 bgfx::Encoder* m_defaultEncoder;
2276};
2277
2278static bool s_initted = false;
2279static DebugDrawEncoderImpl s_dde;
2280static_assert(sizeof(DebugDrawEncoderImpl) <= sizeof(DebugDrawEncoder), "Size must match");
2281
2282void ddInit(bx::AllocatorI* _allocator)
2283{
2284 s_initted = true;
2285 s_dds.init(_allocator);
2286 s_dde.init(bgfx::begin());
2287}
2288
2290{
2291 if(s_initted)
2292 {
2293 s_dde.shutdown();
2294 s_dds.shutdown();
2295 }
2296}
2297
2298SpriteHandle ddCreateSprite(uint16_t _width, uint16_t _height, const void* _data)
2299{
2300 return s_dds.createSprite(_width, _height, _data);
2301}
2302
2304{
2305 s_dds.destroy(_handle);
2306}
2307
2308GeometryHandle ddCreateGeometry(uint32_t _numVertices,
2309 const DdVertex* _vertices,
2310 uint32_t _numIndices,
2311 const void* _indices,
2312 bool _index32)
2313{
2314 return s_dds.createGeometry(_numVertices, _vertices, _numIndices, _indices, _index32);
2315}
2316
2318{
2319 s_dds.destroy(_handle);
2320}
2321
2322#define DEBUG_DRAW_ENCODER(_func) reinterpret_cast<DebugDrawEncoderImpl*>(this)->_func
2323
2328
2333
2334void DebugDrawEncoder::begin(uint16_t _viewId, bool _depthTestLess, bgfx::Encoder* _encoder)
2335{
2336 DEBUG_DRAW_ENCODER(begin(_viewId, _depthTestLess, _encoder));
2337}
2338
2343
2348
2353
2354void DebugDrawEncoder::setDepthTestLess(bool _depthTestLess)
2355{
2356 DEBUG_DRAW_ENCODER(setDepthTestLess(_depthTestLess));
2357}
2358
2359void DebugDrawEncoder::setState(bool _depthTest, bool _depthWrite, bool _clockwise, bool _alphaWrite, bool _alphaBlend)
2360{
2361 DEBUG_DRAW_ENCODER(setState(_depthTest, _depthWrite, _clockwise, _alphaWrite, _alphaBlend));
2362}
2363
2364void DebugDrawEncoder::setColor(uint32_t _abgr)
2365{
2367}
2368
2370{
2372}
2373
2375{
2376 DEBUG_DRAW_ENCODER(setWireframe(_wireframe));
2377}
2378
2379void DebugDrawEncoder::setStipple(bool _stipple, float _scale, float _offset)
2380{
2381 DEBUG_DRAW_ENCODER(setStipple(_stipple, _scale, _offset));
2382}
2383
2385{
2387}
2388
2390{
2392}
2393
2394void DebugDrawEncoder::setTranslate(float _x, float _y, float _z)
2395{
2396 DEBUG_DRAW_ENCODER(setTranslate(_x, _y, _z));
2397}
2398
2400{
2402}
2403
2408
2409void DebugDrawEncoder::pushProgram(bgfx::ProgramHandle handle)
2410{
2412}
2413
2418
2419void DebugDrawEncoder::moveTo(float _x, float _y, float _z)
2420{
2421 DEBUG_DRAW_ENCODER(moveTo(_x, _y, _z));
2422}
2423
2424void DebugDrawEncoder::moveTo(const bx::Vec3& _pos)
2425{
2427}
2428
2429void DebugDrawEncoder::lineTo(float _x, float _y, float _z)
2430{
2431 DEBUG_DRAW_ENCODER(lineTo(_x, _y, _z));
2432}
2433
2434void DebugDrawEncoder::lineTo(const bx::Vec3& _pos)
2435{
2437}
2438
2443
2444void DebugDrawEncoder::draw(const bx::Aabb& _aabb)
2445{
2446 DEBUG_DRAW_ENCODER(draw(_aabb));
2447}
2448
2449void DebugDrawEncoder::draw(const bx::Cylinder& _cylinder)
2450{
2451 DEBUG_DRAW_ENCODER(draw(_cylinder, false));
2452}
2453
2454void DebugDrawEncoder::draw(const bx::Capsule& _capsule)
2455{
2456 DEBUG_DRAW_ENCODER(draw(*((const bx::Cylinder*)&_capsule), true));
2457}
2458
2459void DebugDrawEncoder::draw(const bx::Disk& _disk)
2460{
2461 DEBUG_DRAW_ENCODER(draw(_disk));
2462}
2463
2464void DebugDrawEncoder::draw(const bx::Obb& _obb)
2465{
2466 DEBUG_DRAW_ENCODER(draw(_obb));
2467}
2468
2469void DebugDrawEncoder::draw(const bx::Sphere& _sphere)
2470{
2471 DEBUG_DRAW_ENCODER(draw(_sphere));
2472}
2473
2474void DebugDrawEncoder::draw(const bx::Triangle& _triangle)
2475{
2476 DEBUG_DRAW_ENCODER(draw(_triangle));
2477}
2478
2479void DebugDrawEncoder::draw(const bx::Cone& _cone)
2480{
2481 DEBUG_DRAW_ENCODER(drawCone(_cone.pos, _cone.end, _cone.radius));
2482}
2483
2485{
2486 DEBUG_DRAW_ENCODER(draw(_handle));
2487}
2488
2489void DebugDrawEncoder::drawLineList(uint32_t _numVertices,
2490 const DdVertex* _vertices,
2491 uint32_t _numIndices,
2492 const uint16_t* _indices)
2493{
2494 DEBUG_DRAW_ENCODER(draw(true, _numVertices, _vertices, _numIndices, _indices));
2495}
2496
2497void DebugDrawEncoder::drawTriList(uint32_t _numVertices,
2498 const DdVertex* _vertices,
2499 uint32_t _numIndices,
2500 const uint16_t* _indices)
2501{
2502 DEBUG_DRAW_ENCODER(draw(false, _numVertices, _vertices, _numIndices, _indices));
2503}
2504
2505void DebugDrawEncoder::drawFrustum(const void* _viewProj)
2506{
2507 DEBUG_DRAW_ENCODER(drawFrustum(_viewProj));
2508}
2509
2510void DebugDrawEncoder::drawArc(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _degrees)
2511{
2512 DEBUG_DRAW_ENCODER(drawArc(_axis, _x, _y, _z, _radius, _degrees));
2513}
2514
2515void DebugDrawEncoder::drawCircle(const bx::Vec3& _normal, const bx::Vec3& _center, float _radius, float _weight)
2516{
2517 DEBUG_DRAW_ENCODER(drawCircle(_normal, _center, _radius, _weight));
2518}
2519
2520void DebugDrawEncoder::drawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight)
2521{
2522 DEBUG_DRAW_ENCODER(drawCircle(_axis, _x, _y, _z, _radius, _weight));
2523}
2524
2525void DebugDrawEncoder::drawQuad(const bx::Vec3& _normal, const bx::Vec3& _center, float _size)
2526{
2527 DEBUG_DRAW_ENCODER(drawQuad(_normal, _center, _size));
2528}
2529
2530void DebugDrawEncoder::drawQuad(SpriteHandle _handle, const bx::Vec3& _normal, const bx::Vec3& _center, float _size)
2531{
2532 DEBUG_DRAW_ENCODER(drawQuad(_handle, _normal, _center, _size));
2533}
2534
2535void DebugDrawEncoder::drawQuad(bgfx::TextureHandle _handle,
2536 const bx::Vec3& _normal,
2537 const bx::Vec3& _center,
2538 float _size)
2539{
2540 DEBUG_DRAW_ENCODER(drawQuad(_handle, _normal, _center, _size));
2541}
2542
2543void DebugDrawEncoder::drawCone(const bx::Vec3& _from, const bx::Vec3& _to, float _radius)
2544{
2545 DEBUG_DRAW_ENCODER(drawCone(_from, _to, _radius));
2546}
2547
2548void DebugDrawEncoder::drawCylinder(const bx::Vec3& _from, const bx::Vec3& _to, float _radius)
2549{
2550 DEBUG_DRAW_ENCODER(drawCylinder(_from, _to, _radius, false));
2551}
2552
2553void DebugDrawEncoder::drawCapsule(const bx::Vec3& _from, const bx::Vec3& _to, float _radius)
2554{
2555 DEBUG_DRAW_ENCODER(drawCylinder(_from, _to, _radius, true));
2556}
2557
2558void DebugDrawEncoder::drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight, float _thickness)
2559{
2560 DEBUG_DRAW_ENCODER(drawAxis(_x, _y, _z, _len, _highlight, _thickness));
2561}
2562
2563void DebugDrawEncoder::drawGrid(const bx::Vec3& _normal, const bx::Vec3& _center, uint32_t _size, float _step)
2564{
2565 DEBUG_DRAW_ENCODER(drawGrid(_normal, _center, _size, _step));
2566}
2567
2568void DebugDrawEncoder::drawGrid(Axis::Enum _axis, const bx::Vec3& _center, uint32_t _size, float _step)
2569{
2570 DEBUG_DRAW_ENCODER(drawGrid(_axis, _center, _size, _step));
2571}
2572
2573void DebugDrawEncoder::drawOrb(float _x, float _y, float _z, float _radius, Axis::Enum _highlight)
2574{
2575 DEBUG_DRAW_ENCODER(drawOrb(_x, _y, _z, _radius, _highlight));
2576}
2577
2582
bool checkAvailTransientBuffers(uint32_t _numVertices, const bgfx::VertexLayout &_layout, uint32_t _numIndices)
Definition bgfx_utils.h:61
manifold_type type
btVector3 normal
DebugDrawEncoderScopePush(DebugDrawEncoder &_dde)
bool find(uint16_t _width, uint16_t _height, Pack2D &_pack)
Definition packrect.h:44
void clear(const Pack2D &_pack)
Definition packrect.h:91
float scale
Definition hub.cpp:25
bool m_stipple
bool m_alphaBlend
float m_scale
float m_offset
uint32_t m_abgr
uint8_t m_lod
bool m_wireframe
uint64_t m_state
float m_spin
@ X
Definition debugdraw.h:17
@ Y
Definition debugdraw.h:18
@ Z
Definition debugdraw.h:19
void draw(const bx::Aabb &_aabb)
void lineTo(float _x, float _y, float _z=0.0f)
void drawQuad(const bx::Vec3 &_normal, const bx::Vec3 &_center, float _size)
void drawCone(const bx::Vec3 &_from, const bx::Vec3 &_to, float _radius)
void setSpin(float _spin)
void drawCylinder(const bx::Vec3 &_from, const bx::Vec3 &_to, float _radius)
void setColor(uint32_t _abgr)
void drawAxis(float _x, float _y, float _z, float _len=1.0f, Axis::Enum _highlight=Axis::Count, float _thickness=0.0f)
void setWireframe(bool _wireframe)
void setTransform(const void *_mtx)
void begin(uint16_t _viewId, bool _depthTestLess=true, bgfx::Encoder *_encoder=NULL)
void drawGrid(const bx::Vec3 &_normal, const bx::Vec3 &_center, uint32_t _size=20, float _step=1.0f)
void setState(bool _depthTest, bool _depthWrite, bool _clockwise, bool _alphaWrite=false, bool _alphaBlend=true)
void pushTransform(const void *_mtx)
void drawArc(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _degrees)
void drawCapsule(const bx::Vec3 &_from, const bx::Vec3 &_to, float _radius)
void drawOrb(float _x, float _y, float _z, float _radius, Axis::Enum _highlight=Axis::Count)
void drawTriList(uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices=0, const uint16_t *_indices=NULL)
void drawLineList(uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices=0, const uint16_t *_indices=NULL)
void drawFrustum(const void *_viewProj)
void pushProgram(bgfx::ProgramHandle _handle)
void moveTo(float _x, float _y, float _z=0.0f)
void drawCircle(const bx::Vec3 &_normal, const bx::Vec3 &_center, float _radius, float _weight=0.0f)
void setTranslate(float _x, float _y, float _z)
void setDepthTestLess(bool _depthTestLess)
void setStipple(bool _stipple, float _scale=1.0f, float _offset=0.0f)
void setLod(uint8_t _lod)
static const uint32_t kCacheSize
void pushTranslate(float _x, float _y, float _z)
void drawAxis(float _x, float _y, float _z, float _len, Axis::Enum _highlight, float _thickness)
void setSpin(float _spin)
static const uint32_t kCacheQuadSize
void draw(const bx::Sphere &_sphere)
void drawCone(const bx::Vec3 &_from, const bx::Vec3 &_to, float _radius)
void draw(const bx::Triangle &_triangle)
void setDepthTestLess(bool _depthTestLess)
void drawGrid(const bx::Vec3 &_normal, const bx::Vec3 &_center, uint32_t _size, float _step)
void moveTo(Axis::Enum _axis, float _x, float _y)
void drawQuad(bgfx::TextureHandle _handle, const bx::Vec3 &_normal, const bx::Vec3 &_center, float _size)
void drawOrb(float _x, float _y, float _z, float _radius, Axis::Enum _hightlight)
void setColor(uint32_t _abgr)
void draw(bool _lineList, uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices, const uint16_t *_indices)
void draw(const bx::Disk &_disk)
void drawGrid(Axis::Enum _axis, const bx::Vec3 &_center, uint32_t _size, float _step)
void setState(bool _depthTest, bool _depthWrite, bool _clockwise, bool _alphaWrite, bool _alphaBlend)
MatrixStack m_mtxStack[32]
void pushTranslate(const bx::Vec3 &_pos)
Attrib m_attrib[kStackSize]
void init(bgfx::Encoder *_encoder)
void lineTo(float _x, float _y, float _z=0.0f)
void pushProgram(bgfx::ProgramHandle _handle)
void draw(const bx::Aabb &_aabb)
void moveTo(float _x, float _y, float _z=0.0f)
void draw(DebugMesh::Enum _mesh, const float *_mtx, uint16_t _num, bool _wireframe)
void setStipple(bool _stipple, float _scale=1.0f, float _offset=0.0f)
void lineTo(Axis::Enum _axis, float _x, float _y)
void popTransform(bool _flush=true)
DebugVertex m_cache[kCacheSize+1]
void drawArc(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _degrees)
void pushTransform(const void *_mtx, uint16_t _num, bool _flush=true)
void setTransform(const void *_mtx, uint16_t _num=1, bool _flush=true)
bgfx::Encoder * m_encoder
void drawCircle(const bx::Vec3 &_normal, const bx::Vec3 &_center, float _radius, float _weight)
void lineTo(const bx::Vec3 &_pos)
void draw(GeometryHandle _handle)
bgfx::ViewId m_viewId
void draw(const bx::Cylinder &_cylinder, bool _capsule)
void drawCylinder(const bx::Vec3 &_from, const bx::Vec3 &_to, float _radius, bool _capsule)
void setLod(uint8_t _lod)
void setUParams(const Attrib &_attrib, bool _wireframe)
void moveTo(const bx::Vec3 &_pos)
void drawFrustum(const float *_viewProj)
bgfx::Encoder * m_defaultEncoder
void drawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, float _weight)
static const uint32_t kStackSize
bgfx::ProgramHandle m_programStack[32]
uint16_t m_indices[kCacheSize *2]
void drawQuad(SpriteHandle _handle, const bx::Vec3 &_normal, const bx::Vec3 &_center, float _size)
void draw(const bx::Obb &_obb)
void drawFrustum(const void *_viewProj)
void drawQuad(const bx::Vec3 &_normal, const bx::Vec3 &_center, float _size)
DebugUvVertex m_cacheQuad[kCacheQuadSize]
void setTranslate(const float *_pos)
void setTranslate(float _x, float _y, float _z)
void begin(bgfx::ViewId _viewId, bool _depthTestLess, bgfx::Encoder *_encoder)
void setWireframe(bool _wireframe)
bgfx::TextureHandle m_texture
Geometry m_geometry
SpriteHandle createSprite(uint16_t _width, uint16_t _height, const void *_data)
bgfx::VertexBufferHandle m_vbh
void destroy(SpriteHandle _handle)
GeometryHandle createGeometry(uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices, const void *_indices, bool _index32)
bgfx::UniformHandle u_params
void init(bx::AllocatorI *_allocator)
bgfx::ProgramHandle m_program[Program::Count]
bx::AllocatorI * m_allocator
bgfx::IndexBufferHandle m_ibh
DebugMesh m_mesh[DebugMesh::Count]
bgfx::UniformHandle s_texColor
void destroy(GeometryHandle _handle)
uint32_t m_startIndex[2]
uint32_t m_startVertex
uint32_t m_numIndices[2]
uint32_t m_numVertices
static bgfx::VertexLayout ms_layout
Definition debugdraw.cpp:99
static void init()
Definition debugdraw.cpp:94
static bgfx::VertexLayout ms_layout
Definition debugdraw.cpp:83
uint8_t m_indices[4]
Definition debugdraw.cpp:73
static void init()
Definition debugdraw.cpp:75
static void init()
Definition debugdraw.cpp:54
static bgfx::VertexLayout ms_layout
Definition debugdraw.cpp:63
uint32_t m_abgr
Definition debugdraw.cpp:52
uint32_t m_abgr
Definition debugdraw.cpp:29
static bgfx::VertexLayout ms_layout
Definition debugdraw.cpp:40
static void init()
Definition debugdraw.cpp:31
uint16_t idx
Definition debugdraw.h:41
bgfx::IndexBufferHandle m_ibh
uint32_t m_topologyNumIndices[2]
bgfx::VertexBufferHandle m_vbh
void destroy(GeometryHandle _handle)
bx::HandleAllocT< MaxHandlesT > m_handleAlloc
Geometry m_geometry[MaxHandlesT]
bx::Mutex m_lock
GeometryHandle create(uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices, const void *_indices, bool _index32)
uint16_t m_width
Definition packrect.h:15
uint16_t m_height
Definition packrect.h:16
uint16_t m_y
Definition packrect.h:14
uint16_t m_x
Definition packrect.h:13
uint16_t idx
Definition debugdraw.h:32
bx::Mutex m_lock
bx::HandleAllocT< MaxHandlesT > m_handleAlloc
const Pack2D & get(SpriteHandle _sprite) const
Pack2D m_pack[MaxHandlesT]
void destroy(SpriteHandle _sprite)
SpriteHandle create(uint16_t _width, uint16_t _height)
RectPack2DT< 256 > m_ra
gfx::uniform_handle handle
Definition uniform.cpp:9
uint32_t genSphere(uint8_t _subdiv0, void *_pos0=NULL, uint16_t _posStride0=0, void *_normals0=NULL, uint16_t _normalStride0=0)
#define SPRITE_TEXTURE_SIZE
#define DEBUG_DRAW_ENCODER(_func)
SpriteHandle ddCreateSprite(uint16_t _width, uint16_t _height, const void *_data)
void ddShutdown()
void ddInit(bx::AllocatorI *_allocator)
SpriteT< 256, SPRITE_TEXTURE_SIZE > Sprite
bx::Vec3 getPoint(Axis::Enum _axis, float _x, float _y)
GeometryT< DEBUG_DRAW_CONFIG_MAX_GEOMETRY > Geometry
GeometryHandle ddCreateGeometry(uint32_t _numVertices, const DdVertex *_vertices, uint32_t _numIndices, const void *_indices, bool _index32)
void ddDestroy(SpriteHandle _handle)
bool isValid(SpriteHandle _handle)
Definition debugdraw.h:34