mirror of
https://github.com/bkaradzic/bgfx.git
synced 2026-02-17 20:52:36 +01:00
debugdraw: Added texture quad rendering.
This commit is contained in:
@@ -6,11 +6,13 @@
|
||||
#include <bgfx/bgfx.h>
|
||||
#include <bgfx/embedded_shader.h>
|
||||
#include "debugdraw.h"
|
||||
#include "../packrect.h"
|
||||
|
||||
#include <bx/fpumath.h>
|
||||
#include <bx/radixsort.h>
|
||||
#include <bx/uint32_t.h>
|
||||
#include <bx/crtimpl.h>
|
||||
#include <bx/handlealloc.h>
|
||||
|
||||
struct DebugVertex
|
||||
{
|
||||
@@ -320,6 +322,50 @@ static const bgfx::EmbeddedShader s_embeddedShaders[] =
|
||||
BGFX_EMBEDDED_SHADER_END()
|
||||
};
|
||||
|
||||
#define SPRITE_TEXTURE_SIZE 1024
|
||||
|
||||
template<uint16_t MaxHandlesT = 256, uint16_t TextureSizeT = 1024>
|
||||
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<MaxHandlesT> 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);
|
||||
|
||||
Reference in New Issue
Block a user