diff options
Diffstat (limited to '3rdparty/bgfx/examples/common/bgfx_utils.cpp')
-rw-r--r-- | 3rdparty/bgfx/examples/common/bgfx_utils.cpp | 476 |
1 files changed, 245 insertions, 231 deletions
diff --git a/3rdparty/bgfx/examples/common/bgfx_utils.cpp b/3rdparty/bgfx/examples/common/bgfx_utils.cpp index fd3b87251c5..ed8b4431424 100644 --- a/3rdparty/bgfx/examples/common/bgfx_utils.cpp +++ b/3rdparty/bgfx/examples/common/bgfx_utils.cpp @@ -1,5 +1,5 @@ /* - * Copyright 2011-2018 Branimir Karadzic. All rights reserved. + * Copyright 2011-2019 Branimir Karadzic. All rights reserved. * License: https://github.com/bkaradzic/bgfx#license-bsd-2-clause */ @@ -17,7 +17,7 @@ namespace stl = tinystl; #include <bx/readerwriter.h> #include <bx/string.h> #include "entry/entry.h" -#include <ib-compress/indexbufferdecompression.h> +#include <meshoptimizer/src/meshoptimizer.h> #include "bgfx_utils.h" @@ -110,6 +110,7 @@ static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name case bgfx::RendererType::Direct3D12: shaderPath = "shaders/dx11/"; break; case bgfx::RendererType::Gnm: shaderPath = "shaders/pssl/"; break; case bgfx::RendererType::Metal: shaderPath = "shaders/metal/"; break; + case bgfx::RendererType::Nvn: shaderPath = "shaders/nvn/"; break; case bgfx::RendererType::OpenGL: shaderPath = "shaders/glsl/"; break; case bgfx::RendererType::OpenGLES: shaderPath = "shaders/essl/"; break; case bgfx::RendererType::Vulkan: shaderPath = "shaders/spirv/"; break; @@ -124,7 +125,7 @@ static bgfx::ShaderHandle loadShader(bx::FileReaderI* _reader, const char* _name bx::strCat(filePath, BX_COUNTOF(filePath), ".bin"); bgfx::ShaderHandle handle = bgfx::createShader(loadMem(_reader, filePath) ); - bgfx::setName(handle, filePath); + bgfx::setName(handle, _name); return handle; } @@ -158,7 +159,7 @@ static void imageReleaseCb(void* _ptr, void* _userData) bimg::imageFree(imageContainer); } -bgfx::TextureHandle loadTexture(bx::FileReaderI* _reader, const char* _filePath, uint32_t _flags, uint8_t _skip, bgfx::TextureInfo* _info, bimg::Orientation::Enum* _orientation) +bgfx::TextureHandle loadTexture(bx::FileReaderI* _reader, const char* _filePath, uint64_t _flags, uint8_t _skip, bgfx::TextureInfo* _info, bimg::Orientation::Enum* _orientation) { BX_UNUSED(_skip); bgfx::TextureHandle handle = BGFX_INVALID_HANDLE; @@ -244,7 +245,7 @@ bgfx::TextureHandle loadTexture(bx::FileReaderI* _reader, const char* _filePath, return handle; } -bgfx::TextureHandle loadTexture(const char* _name, uint32_t _flags, uint8_t _skip, bgfx::TextureInfo* _info, bimg::Orientation::Enum* _orientation) +bgfx::TextureHandle loadTexture(const char* _name, uint64_t _flags, uint8_t _skip, bgfx::TextureInfo* _info, bimg::Orientation::Enum* _orientation) { return loadTexture(entry::getFileReader(), _name, _flags, _skip, _info, _orientation); } @@ -257,7 +258,7 @@ bimg::ImageContainer* imageLoad(const char* _filePath, bgfx::TextureFormat::Enum return bimg::imageParse(entry::getAllocator(), data, size, bimg::TextureFormat::Enum(_dstFormat) ); } -void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) +void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexLayout _layout, const uint16_t* _indices, uint32_t _numIndices) { struct PosTexcoord { @@ -285,14 +286,14 @@ void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl uint32_t i1 = indices[1]; uint32_t i2 = indices[2]; - bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _decl, _vertices, i0); - bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i0); + bgfx::vertexUnpack(&v0.m_x, bgfx::Attrib::Position, _layout, _vertices, i0); + bgfx::vertexUnpack(&v0.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i0); - bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1); - bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1); + bgfx::vertexUnpack(&v1.m_x, bgfx::Attrib::Position, _layout, _vertices, i1); + bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i1); - bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2); - bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2); + bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _layout, _vertices, i2); + bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _layout, _vertices, i2); const float bax = v1.m_x - v0.m_x; const float bay = v1.m_y - v0.m_y; @@ -333,300 +334,313 @@ void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl for (uint32_t ii = 0; ii < _numVertices; ++ii) { - const float* tanu = &tangents[ii*6]; - const float* tanv = &tangents[ii*6 + 3]; + const bx::Vec3 tanu = bx::load<bx::Vec3>(&tangents[ii*6]); + const bx::Vec3 tanv = bx::load<bx::Vec3>(&tangents[ii*6 + 3]); - float normal[4]; - bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii); - float ndt = bx::vec3Dot(normal, tanu); + float nxyzw[4]; + bgfx::vertexUnpack(nxyzw, bgfx::Attrib::Normal, _layout, _vertices, ii); - float nxt[3]; - bx::vec3Cross(nxt, normal, tanu); - - float tmp[3]; - tmp[0] = tanu[0] - normal[0] * ndt; - tmp[1] = tanu[1] - normal[1] * ndt; - tmp[2] = tanu[2] - normal[2] * ndt; + const bx::Vec3 normal = bx::load<bx::Vec3>(nxyzw); + const float ndt = bx::dot(normal, tanu); + const bx::Vec3 nxt = bx::cross(normal, tanu); + const bx::Vec3 tmp = bx::sub(tanu, bx::mul(normal, ndt) ); float tangent[4]; - bx::vec3Norm(tangent, tmp); + bx::store(tangent, bx::normalize(tmp) ); + tangent[3] = bx::dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; - tangent[3] = bx::vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; - bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii); + bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _layout, _vertices, ii); } delete [] tangents; } -struct Aabb -{ - float m_min[3]; - float m_max[3]; -}; - -struct Obb -{ - float m_mtx[16]; -}; -struct Sphere -{ - float m_center[3]; - float m_radius; -}; -struct Primitive +Group::Group() { - uint32_t m_startIndex; - uint32_t m_numIndices; - uint32_t m_startVertex; - uint32_t m_numVertices; - - Sphere m_sphere; - Aabb m_aabb; - Obb m_obb; -}; - -typedef stl::vector<Primitive> PrimitiveArray; + reset(); +} -struct Group +void Group::reset() { - Group() - { - reset(); - } - - void reset() - { - m_vbh.idx = bgfx::kInvalidHandle; - m_ibh.idx = bgfx::kInvalidHandle; - m_prims.clear(); - } - - bgfx::VertexBufferHandle m_vbh; - bgfx::IndexBufferHandle m_ibh; - Sphere m_sphere; - Aabb m_aabb; - Obb m_obb; - PrimitiveArray m_prims; -}; + m_vbh.idx = bgfx::kInvalidHandle; + m_ibh.idx = bgfx::kInvalidHandle; + m_numVertices = 0; + m_vertices = NULL; + m_numIndices = 0; + m_indices = NULL; + m_prims.clear(); +} namespace bgfx { - int32_t read(bx::ReaderI* _reader, bgfx::VertexDecl& _decl, bx::Error* _err = NULL); + int32_t read(bx::ReaderI* _reader, bgfx::VertexLayout& _layout, bx::Error* _err = NULL); } -struct Mesh +void Mesh::load(bx::ReaderSeekerI* _reader, bool _ramcopy) { - void load(bx::ReaderSeekerI* _reader) - { #define BGFX_CHUNK_MAGIC_VB BX_MAKEFOURCC('V', 'B', ' ', 0x1) +#define BGFX_CHUNK_MAGIC_VBC BX_MAKEFOURCC('V', 'B', 'C', 0x0) #define BGFX_CHUNK_MAGIC_IB BX_MAKEFOURCC('I', 'B', ' ', 0x0) -#define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x0) +#define BGFX_CHUNK_MAGIC_IBC BX_MAKEFOURCC('I', 'B', 'C', 0x1) #define BGFX_CHUNK_MAGIC_PRI BX_MAKEFOURCC('P', 'R', 'I', 0x0) - using namespace bx; - using namespace bgfx; - - Group group; - - bx::AllocatorI* allocator = entry::getAllocator(); - - uint32_t chunk; - bx::Error err; - while (4 == bx::read(_reader, chunk, &err) - && err.isOk() ) + using namespace bx; + using namespace bgfx; + + Group group; + + bx::AllocatorI* allocator = entry::getAllocator(); + + uint32_t chunk; + bx::Error err; + while (4 == bx::read(_reader, chunk, &err) + && err.isOk() ) + { + switch (chunk) { - switch (chunk) - { case BGFX_CHUNK_MAGIC_VB: + { + read(_reader, group.m_sphere); + read(_reader, group.m_aabb); + read(_reader, group.m_obb); + + read(_reader, m_layout); + + uint16_t stride = m_layout.getStride(); + + read(_reader, group.m_numVertices); + const bgfx::Memory* mem = bgfx::alloc(group.m_numVertices*stride); + read(_reader, mem->data, mem->size); + if ( _ramcopy ) { - read(_reader, group.m_sphere); - read(_reader, group.m_aabb); - read(_reader, group.m_obb); - - read(_reader, m_decl); - - uint16_t stride = m_decl.getStride(); - - uint16_t numVertices; - read(_reader, numVertices); - const bgfx::Memory* mem = bgfx::alloc(numVertices*stride); - read(_reader, mem->data, mem->size); - - group.m_vbh = bgfx::createVertexBuffer(mem, m_decl); + group.m_vertices = (uint8_t*)BX_ALLOC(allocator, group.m_numVertices*stride); + bx::memCopy(group.m_vertices, mem->data, mem->size); } + group.m_vbh = bgfx::createVertexBuffer(mem, m_layout); + } break; - - case BGFX_CHUNK_MAGIC_IB: + + case BGFX_CHUNK_MAGIC_VBC: + { + read(_reader, group.m_sphere); + read(_reader, group.m_aabb); + read(_reader, group.m_obb); + + read(_reader, m_layout); + + uint16_t stride = m_layout.getStride(); + + read(_reader, group.m_numVertices); + + const bgfx::Memory* mem = bgfx::alloc(group.m_numVertices*stride); + + uint32_t compressedSize; + bx::read(_reader, compressedSize); + + void* compressedVertices = BX_ALLOC(allocator, compressedSize); + bx::read(_reader, compressedVertices, compressedSize); + + meshopt_decodeVertexBuffer(mem->data, group.m_numVertices, stride, (uint8_t*)compressedVertices, compressedSize); + + BX_FREE(allocator, compressedVertices); + + if ( _ramcopy ) { - uint32_t numIndices; - read(_reader, numIndices); - const bgfx::Memory* mem = bgfx::alloc(numIndices*2); - read(_reader, mem->data, mem->size); - group.m_ibh = bgfx::createIndexBuffer(mem); + group.m_vertices = (uint8_t*)BX_ALLOC(allocator, group.m_numVertices*stride); + bx::memCopy(group.m_vertices, mem->data, mem->size); } + + group.m_vbh = bgfx::createVertexBuffer(mem, m_layout); + } break; + + case BGFX_CHUNK_MAGIC_IB: + { + read(_reader, group.m_numIndices); + const bgfx::Memory* mem = bgfx::alloc(group.m_numIndices*2); + read(_reader, mem->data, mem->size); + if ( _ramcopy ) + { + group.m_indices = (uint16_t*)BX_ALLOC(allocator, group.m_numIndices*2); + bx::memCopy(group.m_indices, mem->data, mem->size); + } + group.m_ibh = bgfx::createIndexBuffer(mem); + } + break; + case BGFX_CHUNK_MAGIC_IBC: + { + bx::read(_reader, group.m_numIndices); + + const bgfx::Memory* mem = bgfx::alloc(group.m_numIndices*2); + + uint32_t compressedSize; + bx::read(_reader, compressedSize); + + void* compressedIndices = BX_ALLOC(allocator, compressedSize); + + bx::read(_reader, compressedIndices, compressedSize); + + meshopt_decodeIndexBuffer(mem->data, group.m_numIndices, 2, (uint8_t*)compressedIndices, compressedSize); + + BX_FREE(allocator, compressedIndices); + + if ( _ramcopy ) { - uint32_t numIndices; - bx::read(_reader, numIndices); - - const bgfx::Memory* mem = bgfx::alloc(numIndices*2); - - uint32_t compressedSize; - bx::read(_reader, compressedSize); - - void* compressedIndices = BX_ALLOC(allocator, compressedSize); - - bx::read(_reader, compressedIndices, compressedSize); - - ReadBitstream rbs( (const uint8_t*)compressedIndices, compressedSize); - DecompressIndexBuffer( (uint16_t*)mem->data, numIndices / 3, rbs); - - BX_FREE(allocator, compressedIndices); - - group.m_ibh = bgfx::createIndexBuffer(mem); + group.m_indices = (uint16_t*)BX_ALLOC(allocator, group.m_numIndices*2); + bx::memCopy(group.m_indices, mem->data, mem->size); } + + group.m_ibh = bgfx::createIndexBuffer(mem); + } break; - + case BGFX_CHUNK_MAGIC_PRI: + { + uint16_t len; + read(_reader, len); + + stl::string material; + material.resize(len); + read(_reader, const_cast<char*>(material.c_str() ), len); + + uint16_t num; + read(_reader, num); + + for (uint32_t ii = 0; ii < num; ++ii) { - uint16_t len; read(_reader, len); - - stl::string material; - material.resize(len); - read(_reader, const_cast<char*>(material.c_str() ), len); - - uint16_t num; - read(_reader, num); - - for (uint32_t ii = 0; ii < num; ++ii) - { - read(_reader, len); - - stl::string name; - name.resize(len); - read(_reader, const_cast<char*>(name.c_str() ), len); - - Primitive prim; - read(_reader, prim.m_startIndex); - read(_reader, prim.m_numIndices); - read(_reader, prim.m_startVertex); - read(_reader, prim.m_numVertices); - read(_reader, prim.m_sphere); - read(_reader, prim.m_aabb); - read(_reader, prim.m_obb); - - group.m_prims.push_back(prim); - } - - m_groups.push_back(group); - group.reset(); + + stl::string name; + name.resize(len); + read(_reader, const_cast<char*>(name.c_str() ), len); + + Primitive prim; + read(_reader, prim.m_startIndex); + read(_reader, prim.m_numIndices); + read(_reader, prim.m_startVertex); + read(_reader, prim.m_numVertices); + read(_reader, prim.m_sphere); + read(_reader, prim.m_aabb); + read(_reader, prim.m_obb); + + group.m_prims.push_back(prim); } + + m_groups.push_back(group); + group.reset(); + } break; - + default: DBG("%08x at %d", chunk, bx::skip(_reader, 0) ); break; - } } } +} - void unload() +void Mesh::unload() +{ + bx::AllocatorI* allocator = entry::getAllocator(); + + for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) { - for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) + const Group& group = *it; + bgfx::destroy(group.m_vbh); + + if (bgfx::isValid(group.m_ibh) ) { - const Group& group = *it; - bgfx::destroy(group.m_vbh); + bgfx::destroy(group.m_ibh); + } + + if ( NULL != group.m_vertices ) + { + BX_FREE(allocator, group.m_vertices); + } - if (bgfx::isValid(group.m_ibh) ) - { - bgfx::destroy(group.m_ibh); - } + if ( NULL != group.m_indices ) + { + BX_FREE(allocator, group.m_indices); } - m_groups.clear(); } + m_groups.clear(); +} + +void Mesh::submit(bgfx::ViewId _id, bgfx::ProgramHandle _program, const float* _mtx, uint64_t _state) const +{ + if (BGFX_STATE_MASK == _state) + { + _state = 0 + | BGFX_STATE_WRITE_RGB + | BGFX_STATE_WRITE_A + | BGFX_STATE_WRITE_Z + | BGFX_STATE_DEPTH_TEST_LESS + | BGFX_STATE_CULL_CCW + | BGFX_STATE_MSAA + ; + } + + bgfx::setTransform(_mtx); + bgfx::setState(_state); + + for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) + { + const Group& group = *it; + + bgfx::setIndexBuffer(group.m_ibh); + bgfx::setVertexBuffer(0, group.m_vbh); + bgfx::submit(_id, _program, 0, it != itEnd-1); + } +} - void submit(bgfx::ViewId _id, bgfx::ProgramHandle _program, const float* _mtx, uint64_t _state) const +void Mesh::submit(const MeshState*const* _state, uint8_t _numPasses, const float* _mtx, uint16_t _numMatrices) const +{ + uint32_t cached = bgfx::setTransform(_mtx, _numMatrices); + + for (uint32_t pass = 0; pass < _numPasses; ++pass) { - if (BGFX_STATE_MASK == _state) + bgfx::setTransform(cached, _numMatrices); + + const MeshState& state = *_state[pass]; + bgfx::setState(state.m_state); + + for (uint8_t tex = 0; tex < state.m_numTextures; ++tex) { - _state = 0 - | BGFX_STATE_WRITE_RGB - | BGFX_STATE_WRITE_A - | BGFX_STATE_WRITE_Z - | BGFX_STATE_DEPTH_TEST_LESS - | BGFX_STATE_CULL_CCW - | BGFX_STATE_MSAA - ; + const MeshState::Texture& texture = state.m_textures[tex]; + bgfx::setTexture(texture.m_stage + , texture.m_sampler + , texture.m_texture + , texture.m_flags + ); } - - bgfx::setTransform(_mtx); - bgfx::setState(_state); - + for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) { const Group& group = *it; - + bgfx::setIndexBuffer(group.m_ibh); bgfx::setVertexBuffer(0, group.m_vbh); - bgfx::submit(_id, _program, 0, it != itEnd-1); - } - } - - void submit(const MeshState*const* _state, uint8_t _numPasses, const float* _mtx, uint16_t _numMatrices) const - { - uint32_t cached = bgfx::setTransform(_mtx, _numMatrices); - - for (uint32_t pass = 0; pass < _numPasses; ++pass) - { - bgfx::setTransform(cached, _numMatrices); - - const MeshState& state = *_state[pass]; - bgfx::setState(state.m_state); - - for (uint8_t tex = 0; tex < state.m_numTextures; ++tex) - { - const MeshState::Texture& texture = state.m_textures[tex]; - bgfx::setTexture(texture.m_stage - , texture.m_sampler - , texture.m_texture - , texture.m_flags - ); - } - - for (GroupArray::const_iterator it = m_groups.begin(), itEnd = m_groups.end(); it != itEnd; ++it) - { - const Group& group = *it; - - bgfx::setIndexBuffer(group.m_ibh); - bgfx::setVertexBuffer(0, group.m_vbh); - bgfx::submit(state.m_viewId, state.m_program, 0, it != itEnd-1); - } + bgfx::submit(state.m_viewId, state.m_program, 0, it != itEnd-1); } } +} - bgfx::VertexDecl m_decl; - typedef stl::vector<Group> GroupArray; - GroupArray m_groups; -}; - -Mesh* meshLoad(bx::ReaderSeekerI* _reader) +Mesh* meshLoad(bx::ReaderSeekerI* _reader, bool _ramcopy) { Mesh* mesh = new Mesh; - mesh->load(_reader); + mesh->load(_reader, _ramcopy); return mesh; } -Mesh* meshLoad(const char* _filePath) +Mesh* meshLoad(const char* _filePath, bool _ramcopy) { bx::FileReaderI* reader = entry::getFileReader(); if (bx::open(reader, _filePath) ) { - Mesh* mesh = meshLoad(reader); + Mesh* mesh = meshLoad(reader, _ramcopy); bx::close(reader); return mesh; } |