diff options
Diffstat (limited to '3rdparty/bgfx/examples/common/ps/particle_system.cpp')
-rw-r--r-- | 3rdparty/bgfx/examples/common/ps/particle_system.cpp | 137 |
1 files changed, 119 insertions, 18 deletions
diff --git a/3rdparty/bgfx/examples/common/ps/particle_system.cpp b/3rdparty/bgfx/examples/common/ps/particle_system.cpp index 4e135048dd2..34ea0261969 100644 --- a/3rdparty/bgfx/examples/common/ps/particle_system.cpp +++ b/3rdparty/bgfx/examples/common/ps/particle_system.cpp @@ -8,6 +8,7 @@ #include "particle_system.h" #include "../bgfx_utils.h" +#include "../packrect.h" #include <bx/easing.h> #include <bx/crtimpl.h> @@ -183,6 +184,49 @@ namespace ps ; } +#define SPRITE_TEXTURE_SIZE 1024 + template<uint16_t MaxHandlesT = 256, uint16_t TextureSizeT = 1024> + struct SpriteT + { + SpriteT() + : m_ra(TextureSizeT, TextureSizeT) + { + } + + EmitterSpriteHandle create(uint16_t _width, uint16_t _height) + { + EmitterSpriteHandle 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(EmitterSpriteHandle _sprite) + { + const Pack2D& pack = m_pack[_sprite.idx]; + m_ra.clear(pack); + m_handleAlloc.free(_sprite.idx); + } + + const Pack2D& get(EmitterSpriteHandle _sprite) const + { + return m_pack[_sprite.idx]; + } + + bx::HandleAllocT<MaxHandlesT> m_handleAlloc; + Pack2D m_pack[MaxHandlesT]; + RectPack2DT<256> m_ra; + }; + struct Emitter { void create(EmitterShape::Enum _shape, EmitterDirection::Enum _direction, uint32_t _maxParticles); @@ -191,7 +235,7 @@ namespace ps void reset() { m_num = 0; - memset(&m_aabb, 0, sizeof(Aabb) ); + bx::memSet(&m_aabb, 0, sizeof(Aabb) ); } void update(float _dt) @@ -206,7 +250,7 @@ namespace ps { if (ii != num-1) { - memcpy(&particle, &m_particles[num-1], sizeof(Particle) ); + bx::memCopy(&particle, &m_particles[num-1], sizeof(Particle) ); --ii; } @@ -310,7 +354,7 @@ namespace ps bx::vec3MulMtx(particle.end[0], end, mtx); bx::vec3Add(particle.end[1], particle.end[0], gravity); - memcpy(particle.rgba, m_uniforms.m_rgba, BX_COUNTOF(m_uniforms.m_rgba)*sizeof(uint32_t) ); + bx::memCopy(particle.rgba, m_uniforms.m_rgba, BX_COUNTOF(m_uniforms.m_rgba)*sizeof(uint32_t) ); particle.blendStart = bx::flerp(m_uniforms.m_blendStart[0], m_uniforms.m_blendStart[1], bx::frnd(&m_rng) ); particle.blendEnd = bx::flerp(m_uniforms.m_blendEnd[0], m_uniforms.m_blendEnd[1], bx::frnd(&m_rng) ); @@ -322,7 +366,7 @@ namespace ps } } - uint32_t render(const float* _mtxView, const float* _eye, uint32_t _first, uint32_t _max, ParticleSort* _outSort, PosColorTexCoord0Vertex* _outVertices) + uint32_t render(const float _uv[4], const float* _mtxView, const float* _eye, uint32_t _first, uint32_t _max, ParticleSort* _outSort, PosColorTexCoord0Vertex* _outVertices) { bx::EaseFn easeRgba = s_easeFunc[m_uniforms.m_easeRgba]; bx::EaseFn easePos = s_easeFunc[m_uniforms.m_easePos]; @@ -385,8 +429,8 @@ namespace ps bx::vec3Sub(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; - vertex->m_u = 0.0f; - vertex->m_v = 0.0f; + vertex->m_u = _uv[0]; + vertex->m_v = _uv[1]; vertex->m_blend = blend; ++vertex; @@ -394,8 +438,8 @@ namespace ps bx::vec3Sub(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; - vertex->m_u = 1.0f; - vertex->m_v = 0.0f; + vertex->m_u = _uv[2]; + vertex->m_v = _uv[1]; vertex->m_blend = blend; ++vertex; @@ -403,8 +447,8 @@ namespace ps bx::vec3Add(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; - vertex->m_u = 1.0f; - vertex->m_v = 1.0f; + vertex->m_u = _uv[2]; + vertex->m_v = _uv[3]; vertex->m_blend = blend; ++vertex; @@ -412,8 +456,8 @@ namespace ps bx::vec3Add(&vertex->m_x, tmp, vdir); aabbExpand(aabb, &vertex->m_x); vertex->m_abgr = abgr; - vertex->m_u = 0.0f; - vertex->m_v = 1.0f; + vertex->m_u = _uv[0]; + vertex->m_v = _uv[3]; vertex->m_blend = blend; ++vertex; } @@ -466,7 +510,13 @@ namespace ps m_num = 0; s_texColor = bgfx::createUniform("s_texColor", bgfx::UniformType::Int1); - m_particleTexture = loadTexture("textures/particle.ktx"); + m_texture = bgfx::createTexture2D( + SPRITE_TEXTURE_SIZE + , SPRITE_TEXTURE_SIZE + , false + , 1 + , bgfx::TextureFormat::BGRA8 + ); bgfx::RendererType::Enum type = bgfx::getRendererType(); m_particleProgram = bgfx::createProgram( @@ -479,7 +529,7 @@ namespace ps void shutdown() { bgfx::destroyProgram(m_particleProgram); - bgfx::destroyTexture(m_particleTexture); + bgfx::destroyTexture(m_texture); bgfx::destroyUniform(s_texColor); bx::destroyHandleAlloc(m_allocator, m_emitterAlloc); @@ -488,6 +538,33 @@ namespace ps m_allocator = NULL; } + EmitterSpriteHandle createSprite(uint16_t _width, uint16_t _height, const void* _data) + { + EmitterSpriteHandle 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(EmitterSpriteHandle _handle) + { + m_sprite.destroy(_handle); + } + void update(float _dt) { uint32_t numParticles = 0; @@ -535,7 +612,18 @@ namespace ps { const uint16_t idx = m_emitterAlloc->getHandleAt(ii); Emitter& emitter = m_emitter[idx]; - pos += emitter.render(_mtxView, _eye, pos, max, particleSort, vertices); + + const Pack2D& pack = m_sprite.get(emitter.m_uniforms.m_handle); + const float invTextureSize = 1.0f/SPRITE_TEXTURE_SIZE; + const float uv[4] = + { + pack.m_x * invTextureSize, + pack.m_y * invTextureSize, + (pack.m_x + pack.m_width ) * invTextureSize, + (pack.m_y + pack.m_height) * invTextureSize, + }; + + pos += emitter.render(uv, _mtxView, _eye, pos, max, particleSort, vertices); } qsort(particleSort @@ -569,7 +657,7 @@ namespace ps ); bgfx::setVertexBuffer(&tvb); bgfx::setIndexBuffer(&tib); - bgfx::setTexture(0, s_texColor, m_particleTexture); + bgfx::setTexture(0, s_texColor, m_texture); bgfx::submit(_view, m_particleProgram); } } @@ -602,7 +690,7 @@ namespace ps } else { - memcpy(&emitter.m_uniforms, _uniforms, sizeof(EmitterUniforms) ); + bx::memCopy(&emitter.m_uniforms, _uniforms, sizeof(EmitterUniforms) ); } } @@ -631,8 +719,11 @@ namespace ps bx::HandleAlloc* m_emitterAlloc; Emitter* m_emitter; + typedef SpriteT<256, SPRITE_TEXTURE_SIZE> Sprite; + Sprite m_sprite; + bgfx::UniformHandle s_texColor; - bgfx::TextureHandle m_particleTexture; + bgfx::TextureHandle m_texture; bgfx::ProgramHandle m_particleProgram; uint32_t m_num; @@ -672,6 +763,16 @@ void psShutdown() s_ctx.shutdown(); } +EmitterSpriteHandle psCreateSprite(uint16_t _width, uint16_t _height, const void* _data) +{ + return s_ctx.createSprite(_width, _height, _data); +} + +void psDestroy(EmitterSpriteHandle _handle) +{ + s_ctx.destroy(_handle); +} + EmitterHandle psCreateEmitter(EmitterShape::Enum _shape, EmitterDirection::Enum _direction, uint32_t _maxParticles) { return s_ctx.createEmitter(_shape, _direction, _maxParticles); |