From 25a6a6c4a205c9eccb8dc640d2c27eb160810953 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Branimir=20Karad=C5=BEi=C4=87?= Date: Tue, 20 Dec 2016 21:20:55 -0800 Subject: [PATCH] debugdraw: Added texture quad rendering. --- examples/29-debugdraw/debugdraw.cpp | 25 ++- examples/common/debugdraw/debugdraw.cpp | 241 +++++++++++++++++++++++- examples/common/debugdraw/debugdraw.h | 16 ++ 3 files changed, 275 insertions(+), 7 deletions(-) diff --git a/examples/29-debugdraw/debugdraw.cpp b/examples/29-debugdraw/debugdraw.cpp index 34b8648f6..58f09ea03 100644 --- a/examples/29-debugdraw/debugdraw.cpp +++ b/examples/29-debugdraw/debugdraw.cpp @@ -12,6 +12,19 @@ #include +void imageCheckerboard(void* _dst, uint32_t _width, uint32_t _height, uint32_t _step, uint32_t _0, uint32_t _1) +{ + uint32_t* dst = (uint32_t*)_dst; + for (uint32_t yy = 0; yy < _height; ++yy) + { + for (uint32_t xx = 0; xx < _width; ++xx) + { + uint32_t abgr = ( (xx/_step)&1) ^ ( (yy/_step)&1) ? _1 : _0; + *dst++ = abgr; + } + } +} + class DebugDrawApp : public entry::AppI { void init(int _argc, char** _argv) BX_OVERRIDE @@ -46,10 +59,17 @@ class DebugDrawApp : public entry::AppI cameraSetVerticalAngle(0.0f); ddInit(); + + uint8_t data[32*32*4]; + imageCheckerboard(data, 32, 32, 4, 0xff808080, 0xffc0c0c0); + + m_sprite = ddCreateSprite(32, 32, data); } virtual int shutdown() BX_OVERRIDE { + ddDestroy(m_sprite); + ddShutdown(); cameraDestroy(); @@ -180,8 +200,8 @@ class DebugDrawApp : public entry::AppI ddDrawCircle(normal, center, 1.0f, 0.5f + bx::fsin(time*10.0f) ); ddPop(); - ddSetSpin(time); - ddDrawQuad(normal, center, 2.0f); + //ddSetSpin(time); + ddDrawQuad(m_sprite, normal, center, 2.0f); } ddPop(); @@ -256,6 +276,7 @@ class DebugDrawApp : public entry::AppI } entry::MouseState m_mouseState; + SpriteHandle m_sprite; int64_t m_timeOffset; diff --git a/examples/common/debugdraw/debugdraw.cpp b/examples/common/debugdraw/debugdraw.cpp index 5a2ff915f..0229cdd4c 100644 --- a/examples/common/debugdraw/debugdraw.cpp +++ b/examples/common/debugdraw/debugdraw.cpp @@ -6,11 +6,13 @@ #include #include #include "debugdraw.h" +#include "../packrect.h" #include #include #include #include +#include struct DebugVertex { @@ -320,6 +322,50 @@ static const bgfx::EmbeddedShader s_embeddedShaders[] = BGFX_EMBEDDED_SHADER_END() }; +#define SPRITE_TEXTURE_SIZE 1024 + +template +struct SpriteT +{ + SpriteT() + : m_ra(TextureSizeT, TextureSizeT) + { + } + + SpriteHandle create(uint16_t _width, uint16_t _height) + { + SpriteHandle handle = { bx::HandleAlloc::invalid }; + + if (m_handleAlloc.getNumHandles() < m_handleAlloc.getMaxHandles() ) + { + Pack2D pack; + if (m_ra.find(_width, _height, pack) ) + { + handle.idx = m_handleAlloc.alloc(); + m_pack[handle.idx] = pack; + } + } + + return handle; + } + + void destroy(SpriteHandle _sprite) + { + const Pack2D& pack = m_pack[_sprite.idx]; + m_ra.clear(pack); + m_handleAlloc.free(_sprite.idx); + } + + const Pack2D& get(SpriteHandle _sprite) const + { + return m_pack[_sprite.idx]; + } + + bx::HandleAllocT m_handleAlloc; + Pack2D m_pack[MaxHandlesT]; + RectPack2DT<256> m_ra; +}; + struct DebugDraw { DebugDraw() @@ -384,7 +430,7 @@ struct DebugDraw u_params = bgfx::createUniform("u_params", bgfx::UniformType::Vec4, 4); s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); - m_texture = bgfx::createTexture2D(2048, 2048, false, 1, bgfx::TextureFormat::BGRA8); + m_texture = bgfx::createTexture2D(SPRITE_TEXTURE_SIZE, SPRITE_TEXTURE_SIZE, false, 1, bgfx::TextureFormat::BGRA8); void* vertices[Mesh::Count] = {}; uint16_t* indices[Mesh::Count] = {}; @@ -691,6 +737,7 @@ struct DebugDraw m_pos = 0; m_indexPos = 0; m_vertexPos = 0; + m_posQuad = 0; } void shutdown() @@ -706,6 +753,33 @@ struct DebugDraw bgfx::destroyTexture(m_texture); } + SpriteHandle createSprite(uint16_t _width, uint16_t _height, const void* _data) + { + SpriteHandle handle = m_sprite.create(_width, _height); + + if (isValid(handle) ) + { + const Pack2D& pack = m_sprite.get(handle); + bgfx::updateTexture2D( + m_texture + , 0 + , 0 + , pack.m_x + , pack.m_y + , pack.m_width + , pack.m_height + , bgfx::copy(_data, pack.m_width*pack.m_height*4) + ); + } + + return handle; + } + + void destroy(SpriteHandle _handle) + { + m_sprite.destroy(_handle); + } + void begin(uint8_t _viewId) { BX_CHECK(State::Count == m_state); @@ -735,6 +809,7 @@ struct DebugDraw { BX_CHECK(0 == m_stack, "Invalid stack %d.", m_stack); + flushQuad(); flush(); m_state = State::Count; @@ -790,8 +865,6 @@ struct DebugDraw void setState(bool _depthTest, bool _depthWrite, bool _clockwise) { - flush(); - const uint64_t depthTest = m_depthTestLess ? BGFX_STATE_DEPTH_TEST_LESS : BGFX_STATE_DEPTH_TEST_GREATER @@ -1291,6 +1364,94 @@ struct DebugDraw close(); } + void drawQuad(SpriteHandle _handle, const float* _normal, const float* _center, float _size) + { + if (m_posQuad == BX_COUNTOF(m_cacheQuad) ) + { + flushQuad(); + } + + const Attrib& attrib = m_attrib[m_stack]; + + float udir[3]; + float vdir[3]; + + bx::vec3TangentFrame(_normal, udir, vdir, attrib.m_spin); + + const Pack2D& pack = m_sprite.get(_handle); + const float invTextureSize = 1.0f/SPRITE_TEXTURE_SIZE; + const float us = pack.m_x * invTextureSize; + const float vs = pack.m_y * invTextureSize; + const float ue = (pack.m_x + pack.m_width ) * invTextureSize; + const float ve = (pack.m_y + pack.m_height) * invTextureSize; + + const float aspectRatio = float(pack.m_width)/float(pack.m_height); + const float halfExtentU = aspectRatio*_size*0.5f; + const float halfExtentV = 1.0f/aspectRatio*_size*0.5f; + + float umin[3]; + bx::vec3Mul(umin, udir, -halfExtentU); + + float umax[3]; + bx::vec3Mul(umax, udir, halfExtentU); + + float vmin[3]; + bx::vec3Mul(vmin, vdir, -halfExtentV); + + float vmax[3]; + bx::vec3Mul(vmax, vdir, halfExtentV); + + DebugUvVertex* vertex = &m_cacheQuad[m_posQuad]; + m_posQuad += 4; + + float pt[3]; + float tmp[3]; + bx::vec3Add(tmp, umin, vmin); + bx::vec3Add(pt, _center, tmp); + vertex->m_x = pt[0]; + vertex->m_y = pt[1]; + vertex->m_z = pt[2]; + vertex->m_u = us; + vertex->m_v = vs; + vertex->m_abgr = attrib.m_abgr; + ++vertex; + + bx::vec3Add(tmp, umax, vmin); + bx::vec3Add(pt, _center, tmp); + vertex->m_x = pt[0]; + vertex->m_y = pt[1]; + vertex->m_z = pt[2]; + vertex->m_u = ue; + vertex->m_v = vs; + vertex->m_abgr = attrib.m_abgr; + ++vertex; + + bx::vec3Add(tmp, umin, vmax); + bx::vec3Add(pt, _center, tmp); + vertex->m_x = pt[0]; + vertex->m_y = pt[1]; + vertex->m_z = pt[2]; + vertex->m_u = us; + vertex->m_v = ve; + vertex->m_abgr = attrib.m_abgr; + ++vertex; + + bx::vec3Add(tmp, umax, vmax); + bx::vec3Add(pt, _center, tmp); + vertex->m_x = pt[0]; + vertex->m_y = pt[1]; + vertex->m_z = pt[2]; + vertex->m_u = ue; + vertex->m_v = ve; + vertex->m_abgr = attrib.m_abgr; + ++vertex; + } + + void drawQuad(bgfx::TextureHandle _handle, const float* _normal, const float* _center, float _size) + { + BX_UNUSED(_handle, _normal, _center, _size); + } + void drawCone(const float* _from, const float* _to, float _radius) { const Attrib& attrib = m_attrib[m_stack]; @@ -1710,6 +1871,48 @@ private: } } + void flushQuad() + { + if (0 != m_posQuad) + { + const uint32_t numIndices = m_posQuad/4*6; + if (bgfx::checkAvailTransientBuffers(m_posQuad, DebugUvVertex::ms_decl, numIndices) ) + { + bgfx::TransientVertexBuffer tvb; + bgfx::allocTransientVertexBuffer(&tvb, m_posQuad, DebugUvVertex::ms_decl); + memcpy(tvb.data, m_cacheQuad, m_posQuad * DebugUvVertex::ms_decl.m_stride); + + bgfx::TransientIndexBuffer tib; + bgfx::allocTransientIndexBuffer(&tib, numIndices); + uint16_t* indices = (uint16_t*)tib.data; + for (uint16_t ii = 0, num = m_posQuad/4; ii < num; ++ii) + { + uint16_t startVertex = ii*4; + indices[0] = startVertex+0; + indices[1] = startVertex+1; + indices[2] = startVertex+2; + indices[3] = startVertex+1; + indices[4] = startVertex+3; + indices[5] = startVertex+2; + indices += 6; + } + + const Attrib& attrib = m_attrib[m_stack]; + + bgfx::setVertexBuffer(&tvb); + bgfx::setIndexBuffer(&tib); + bgfx::setState(0 + | (attrib.m_state & ~BGFX_STATE_CULL_MASK) + ); + bgfx::setTransform(m_mtx); + bgfx::setTexture(0, s_texColor, m_texture); + bgfx::submit(m_viewId, m_program[Program::FillTexture]); + } + + m_posQuad = 0; + } + } + struct State { enum Enum @@ -1726,11 +1929,16 @@ private: static const uint32_t stackSize = 16; BX_STATIC_ASSERT(cacheSize >= 3, "Cache must be at least 3 elements."); DebugVertex m_cache[cacheSize+1]; - uint32_t m_mtx; uint16_t m_indices[cacheSize*2]; uint16_t m_pos; uint16_t m_indexPos; uint16_t m_vertexPos; + + static const uint32_t cacheQuadSize = 1024; + DebugUvVertex m_cacheQuad[cacheQuadSize]; + uint16_t m_posQuad; + + uint32_t m_mtx; uint8_t m_viewId; uint8_t m_stack; bool m_depthTestLess; @@ -1752,7 +1960,10 @@ private: State::Enum m_state; Mesh m_mesh[Mesh::Count]; - + + typedef SpriteT<256, SPRITE_TEXTURE_SIZE> Sprite; + Sprite m_sprite; + bgfx::UniformHandle s_texColor; bgfx::TextureHandle m_texture; bgfx::ProgramHandle m_program[Program::Count]; @@ -1776,6 +1987,16 @@ void ddShutdown() s_dd.shutdown(); } +SpriteHandle ddCreateSprite(uint16_t _width, uint16_t _height, const void* _data) +{ + return s_dd.createSprite(_width, _height, _data); +} + +void ddDestroy(SpriteHandle _handle) +{ + s_dd.destroy(_handle); +} + void ddBegin(uint8_t _viewId) { s_dd.begin(_viewId); @@ -1911,6 +2132,16 @@ void ddDrawQuad(const float* _normal, const float* _center, float _size) s_dd.drawQuad(_normal, _center, _size); } +void ddDrawQuad(SpriteHandle _handle, const float* _normal, const float* _center, float _size) +{ + s_dd.drawQuad(_handle, _normal, _center, _size); +} + +void ddDrawQuad(bgfx::TextureHandle _handle, const float* _normal, const float* _center, float _size) +{ + s_dd.drawQuad(_handle, _normal, _center, _size); +} + void ddDrawCone(const void* _from, const void* _to, float _radius) { s_dd.drawCone(_from, _to, _radius); diff --git a/examples/common/debugdraw/debugdraw.h b/examples/common/debugdraw/debugdraw.h index c269938e8..da6eff7b1 100644 --- a/examples/common/debugdraw/debugdraw.h +++ b/examples/common/debugdraw/debugdraw.h @@ -21,12 +21,22 @@ struct Axis }; }; +struct SpriteHandle { uint16_t idx; }; + +inline bool isValid(SpriteHandle _handle) { return _handle.idx != UINT16_MAX; } + /// void ddInit(bool _depthTestLess = true, bx::AllocatorI* _allocator = NULL); /// void ddShutdown(); +/// +SpriteHandle ddCreateSprite(uint16_t _width, uint16_t _height, const void* _data); + +/// +void ddDestroy(SpriteHandle _handle); + /// void ddBegin(uint8_t _viewId); @@ -108,6 +118,12 @@ void ddDrawCircle(Axis::Enum _axis, float _x, float _y, float _z, float _radius, /// void ddDrawQuad(const float* _normal, const float* _center, float _size); +/// +void ddDrawQuad(SpriteHandle _handle, const float* _normal, const float* _center, float _size); + +/// +void ddDrawQuad(bgfx::TextureHandle _handle, const float* _normal, const float* _center, float _size); + /// void ddDrawCone(const void* _from, const void* _to, float _radius);