debugdraw: Added texture quad rendering.

This commit is contained in:
Branimir Karadžić 2016-12-20 21:20:55 -08:00
Родитель 93b2dee899
Коммит 25a6a6c4a2
3 изменённых файлов: 275 добавлений и 7 удалений

Просмотреть файл

@ -12,6 +12,19 @@
#include <bx/uint32_t.h>
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;

Просмотреть файл

@ -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);

Просмотреть файл

@ -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);