From d994949b0233457d951c93d075ec9698f8bef8b4 Mon Sep 17 00:00:00 2001 From: Martin Felis Date: Sat, 18 Feb 2017 17:38:21 +0100 Subject: [PATCH] Refactored meshes. Now we can merge them --- src/modules/CharacterModule.cc | 6 +- src/modules/RenderModule.cc | 43 +------- src/modules/RenderModule.h | 15 +-- src/modules/RenderUtils.cc | 184 ++++++++++++--------------------- src/modules/RenderUtils.h | 44 ++++---- 5 files changed, 95 insertions(+), 197 deletions(-) diff --git a/src/modules/CharacterModule.cc b/src/modules/CharacterModule.cc index bfcc767..4c85aac 100644 --- a/src/modules/CharacterModule.cc +++ b/src/modules/CharacterModule.cc @@ -37,7 +37,7 @@ CharacterEntity::CharacterEntity() { Transform::fromTrans( Vector3f (0.0f, 0.9 * 0.5f, 0.0f) ), - bgfxutils::createUVSphere (45, 45, 0.9) + Mesh::sCreateUVSphere(45, 45, 0.9) ); entity->mesh.addMesh( @@ -45,7 +45,7 @@ CharacterEntity::CharacterEntity() { Transform::fromTrans( Vector3f (0.0f, 0.55f, 0.0f) ), - bgfxutils::createUVSphere (45, 45, 0.7) + Mesh::sCreateUVSphere (45, 45, 0.7) ); entity->mesh.addMesh( @@ -53,7 +53,7 @@ CharacterEntity::CharacterEntity() { Transform::fromTrans( Vector3f (0.0f, 0.4f, 0.0f) ), - bgfxutils::createUVSphere (45, 45, 0.5) + Mesh::sCreateUVSphere (45, 45, 0.5) ); // state->character->entity->mesh = bgfxutils::createCuboid (1.f, 1.f, 1.f); diff --git a/src/modules/RenderModule.cc b/src/modules/RenderModule.cc index 4c33dc3..de329a0 100644 --- a/src/modules/RenderModule.cc +++ b/src/modules/RenderModule.cc @@ -158,7 +158,7 @@ void MeshHierarchy::updateMatrices(const Matrix44f &world_transform) { void MeshHierarchy::submit(const RenderState *state) { for (uint32_t i = 0; i < meshes.size(); ++i) { - bgfxutils::meshSubmit (meshes[i], state, 1, meshMatrices[i].data()); + bgfxutils::meshSubmit (meshes[i]->mBgfxMesh, state, 1, meshMatrices[i].data()); } }; @@ -1245,11 +1245,6 @@ void Renderer::shutdown() { entities[i] = NULL; } - for (size_t i = 0; i < meshes.size(); i++) { - bgfxutils::meshUnload(meshes[i]); - meshes[i] = NULL; - } - for (size_t i = 0; i < lights.size(); i++) { gLog ("Destroying light uniforms for light %d", i); bgfx::destroyFrameBuffer(lights[i].shadowMapFB); @@ -1523,12 +1518,12 @@ void Renderer::paintGL() { for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) { bx::mtxMul( lightMtx, - entities[i]->mesh.meshMatrices[j].data(), + entities[i]->mesh.meshMatrices[j].data(), lights[0].mtxShadow ); bgfx::setUniform(lights[0].u_lightMtx, lightMtx); bgfxutils::meshSubmit ( - entities[i]->mesh.meshes[j], + entities[i]->mesh.meshes[j]->mBgfxMesh, &s_renderStates[RenderState::ShadowMap], 1, entities[i]->mesh.meshMatrices[j].data() @@ -1545,7 +1540,7 @@ void Renderer::paintGL() { bgfx::setUniform(lights[0].u_lightMtx, lightMtx); bgfx::setUniform(u_color, entities[i]->color, 4); bgfxutils::meshSubmit ( - entities[i]->mesh.meshes[j], + entities[i]->mesh.meshes[j]->mBgfxMesh, &s_renderStates[RenderState::Scene], 1, entities[i]->mesh.meshMatrices[j].data() @@ -1760,36 +1755,6 @@ bool Renderer::destroyEntity(Entity* entity) { return false; } -bgfxutils::Mesh* Renderer::loadMesh(const char* filename) { - MeshIdMap::iterator mesh_iter = meshIdMap.find (filename); - bgfxutils::Mesh* result = NULL; - - if (mesh_iter == meshIdMap.end()) { - std::string filename_str (filename); - if (filename_str.substr(filename_str.size() - 4, 4) == ".obj") { - std::vector shapes; - std::vector materials; - - std::string err; - bool result = tinyobj::LoadObj(shapes, materials, err, filename); - - if (!result) { - std::cerr << "Error loading '" << filename << "': " << err << std::endl; - exit(-1); - } -// result = bgfxutils::createMeshFromVBO (vbo); - } else { - result = bgfxutils::meshLoad(filename); - } - meshes.push_back (result); - meshIdMap[filename] = meshes.size() - 1; - } else { - result = meshes[mesh_iter->second]; - } - - return result; -} - // debug commands void Renderer::drawDebugLine ( const Vector3f &from, diff --git a/src/modules/RenderModule.h b/src/modules/RenderModule.h index f9e8d0b..50accd7 100644 --- a/src/modules/RenderModule.h +++ b/src/modules/RenderModule.h @@ -233,11 +233,11 @@ struct Transform { struct MeshHierarchy { ~MeshHierarchy() { - for (bgfxutils::Mesh* mesh : meshes) { - meshUnload(mesh); + for (Mesh* mesh : meshes) { + delete mesh; } } - std::vector meshes; + std::vector meshes; /// index of the parent. Children must have higher indices than heir // parents @@ -250,7 +250,7 @@ struct MeshHierarchy { void addMesh( const int parent_idx, const Transform& transform, - bgfxutils::Mesh* mesh) { + Mesh* mesh) { assert (parent_idx == -1 || parent_idx < parent.size()); parent.push_back(parent_idx); localTransforms.push_back(transform); @@ -261,7 +261,6 @@ struct MeshHierarchy { } else { meshMatrices.push_back(transform.toMatrix()); } - } void updateMatrices(const Matrix44f &world_transform); void submit(const RenderState *state); @@ -338,10 +337,6 @@ struct Renderer { bgfx::UniformHandle sceneDefaultTextureSampler; bgfx::TextureHandle sceneDefaultTexture; - std::vector meshes; - typedef std::map MeshIdMap; - MeshIdMap meshIdMap; - LightProbe mLightProbes[LightProbe::Count]; LightProbe::Enum mCurrentLightProbe; @@ -381,8 +376,6 @@ struct Renderer { Entity* createEntity(); bool destroyEntity (Entity* entity); - bgfxutils::Mesh* loadMesh(const char* filename); - // debug commands void drawDebugLine ( const Vector3f &from, diff --git a/src/modules/RenderUtils.cc b/src/modules/RenderUtils.cc index 8430153..efd3f9d 100644 --- a/src/modules/RenderUtils.cc +++ b/src/modules/RenderUtils.cc @@ -377,107 +377,6 @@ bgfx::TextureHandle loadTexture(const char* _name, uint32_t _flags, uint8_t _ski return loadTexture(entry::getFileReader(), _name, _flags, _skip, _info); } -void calcTangents(void* _vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t* _indices, uint32_t _numIndices) -{ - struct PosTexcoord - { - float m_x; - float m_y; - float m_z; - float m_pad0; - float m_u; - float m_v; - float m_pad1; - float m_pad2; - }; - - float* tangents = new float[6*_numVertices]; - memset(tangents, 0, 6*_numVertices*sizeof(float) ); - - PosTexcoord v0; - PosTexcoord v1; - PosTexcoord v2; - - for (uint32_t ii = 0, num = _numIndices/3; ii < num; ++ii) - { - const uint16_t* indices = &_indices[ii*3]; - uint32_t i0 = indices[0]; - 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(&v1.m_x, bgfx::Attrib::Position, _decl, _vertices, i1); - bgfx::vertexUnpack(&v1.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i1); - - bgfx::vertexUnpack(&v2.m_x, bgfx::Attrib::Position, _decl, _vertices, i2); - bgfx::vertexUnpack(&v2.m_u, bgfx::Attrib::TexCoord0, _decl, _vertices, i2); - - const float bax = v1.m_x - v0.m_x; - const float bay = v1.m_y - v0.m_y; - const float baz = v1.m_z - v0.m_z; - const float bau = v1.m_u - v0.m_u; - const float bav = v1.m_v - v0.m_v; - - const float cax = v2.m_x - v0.m_x; - const float cay = v2.m_y - v0.m_y; - const float caz = v2.m_z - v0.m_z; - const float cau = v2.m_u - v0.m_u; - const float cav = v2.m_v - v0.m_v; - - const float det = (bau * cav - bav * cau); - const float invDet = 1.0f / det; - - const float tx = (bax * cav - cax * bav) * invDet; - const float ty = (bay * cav - cay * bav) * invDet; - const float tz = (baz * cav - caz * bav) * invDet; - - const float bx = (cax * bau - bax * cau) * invDet; - const float by = (cay * bau - bay * cau) * invDet; - const float bz = (caz * bau - baz * cau) * invDet; - - for (uint32_t jj = 0; jj < 3; ++jj) - { - float* tanu = &tangents[indices[jj]*6]; - float* tanv = &tanu[3]; - tanu[0] += tx; - tanu[1] += ty; - tanu[2] += tz; - - tanv[0] += bx; - tanv[1] += by; - tanv[2] += bz; - } - } - - for (uint32_t ii = 0; ii < _numVertices; ++ii) - { - const float* tanu = &tangents[ii*6]; - const float* tanv = &tangents[ii*6 + 3]; - - float normal[4]; - bgfx::vertexUnpack(normal, bgfx::Attrib::Normal, _decl, _vertices, ii); - float ndt = bx::vec3Dot(normal, tanu); - - 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; - - float tangent[4]; - bx::vec3Norm(tangent, tmp); - - tangent[3] = bx::vec3Dot(nxt, tanv) < 0.0f ? -1.0f : 1.0f; - bgfx::vertexPack(tangent, true, bgfx::Attrib::Tangent, _decl, _vertices, ii); - } - - delete [] tangents; -} - struct Aabb { float m_min[3]; @@ -984,11 +883,50 @@ Mesh *createMeshFromStdVectors ( return result; } -Mesh *createCuboid (float width, float height, float depth) { +void meshTransform (Mesh* mesh, const float *mtx) { +// void bgfx::vertexPack(const float _input[4], bool _inputNormalized, Attrib::Enum _attr, const VertexDecl &_decl, void *_data, uint32_t _index = 0) + +} + + + +} + +Mesh::~Mesh() { + if (mBgfxMesh != nullptr) { + mBgfxMesh->unload(); + delete mBgfxMesh; + mBgfxMesh = nullptr; + } +} + +void Mesh::Update() { + if (mBgfxMesh != nullptr) { + mBgfxMesh->unload(); + delete mBgfxMesh; + mBgfxMesh = nullptr; + } + + mBgfxMesh = bgfxutils::createMeshFromStdVectors (mVertices, mNormals, mColors); +} + +void Mesh::Merge (const Mesh& other, const Matrix44f &transform) { + for (int i = 0; i < other.mVertices.size(); ++i) { + mVertices.push_back (transform * other.mVertices[i]); + mNormals.push_back (Matrix33f(transform.block<3,3>(0,0)) * other.mNormals[i]); + + if (other.mColors.size() == other.mVertices.size()) + mColors.push_back(other.mColors[i]); + } +} + +Mesh* Mesh::sCreateCuboid (float width, float height, float depth) { + Mesh* result = new Mesh(); + // work arrays that we fill with data - std::vector vertices; - std::vector normals; - std::vector colors; + std::vector &vertices = result->mVertices; + std::vector &normals = result->mNormals; + std::vector &colors = result->mColors; Vector4f v0 ( 0.5 * width, -0.5 * height, 0.5 * depth, 1.f); Vector4f v1 ( 0.5 * width, -0.5 * height, -0.5 * depth, 1.f); @@ -1097,14 +1035,18 @@ Mesh *createCuboid (float width, float height, float depth) { vertices.push_back(v1); normals.push_back(normal); - return createMeshFromStdVectors (vertices, normals, colors); + result->Update(); + + return result; } -Mesh *createUVSphere (int rows, int segments, float radius) { +Mesh* Mesh::sCreateUVSphere (int rows, int segments, float radius) { + Mesh* result = new Mesh(); + // work arrays that we fill with data - std::vector vertices; - std::vector normals; - std::vector colors; + std::vector &vertices = result->mVertices; + std::vector &normals = result->mNormals; + std::vector &colors = result->mColors; // fill arrays float row_d = 1. / (rows); @@ -1150,14 +1092,18 @@ Mesh *createUVSphere (int rows, int segments, float radius) { } } - return createMeshFromStdVectors (vertices, normals, colors); + result->Update(); + + return result; } -Mesh *createCylinder (int segments) { +Mesh* Mesh::sCreateCylinder (int segments) { + Mesh* result = new Mesh(); + // work arrays that we fill with data - std::vector vertices; - std::vector normals; - std::vector colors; + std::vector &vertices = result->mVertices; + std::vector &normals = result->mNormals; + std::vector &colors = result->mColors; float delta = 2. * M_PI / static_cast(segments); for (unsigned int i = 0; i < segments; i++) { @@ -1226,9 +1172,7 @@ Mesh *createCylinder (int segments) { normals.push_back(normal); } - return createMeshFromStdVectors (vertices, normals, colors); + result->Update(); + + return result; } - -} - - diff --git a/src/modules/RenderUtils.h b/src/modules/RenderUtils.h index f35150e..b45e0e2 100644 --- a/src/modules/RenderUtils.h +++ b/src/modules/RenderUtils.h @@ -6,8 +6,28 @@ #include "GLFW/glfw3.h" #include +// Forward declarations struct RenderState; +namespace bgfxutils { +struct Mesh; +} + +struct Mesh { + bgfxutils::Mesh* mBgfxMesh = nullptr; + std::vector mVertices; + std::vector mNormals; + std::vector mColors; + + ~Mesh(); + void Update(); + void Merge (const Mesh& other, const Matrix44f &mat = Matrix44f::Identity()); + + static Mesh *sCreateCuboid (float width, float height, float depth); + static Mesh *sCreateUVSphere (int rows, int segments, float radius = 1.0f); + static Mesh *sCreateCylinder (int segments); +}; + namespace bgfxutils { bgfx::ShaderHandle loadShader(const char *_name); @@ -21,31 +41,10 @@ namespace bgfxutils { void calcTangents(void *_vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t *_indices, uint32_t _numIndices); - struct MeshState { - struct Texture { - uint32_t m_flags; - bgfx::UniformHandle m_sampler; - bgfx::TextureHandle m_texture; - uint8_t m_stage; - }; - - Texture m_textures[4]; - uint64_t m_state; - bgfx::ProgramHandle m_program; - uint8_t m_numTextures; - uint8_t m_viewId; - }; - - struct Mesh; - Mesh *meshLoad(const char *_filePath); void meshUnload(Mesh *_mesh); - MeshState *meshStateCreate(); - - void meshStateDestroy(MeshState *_meshState); - void meshSubmit(const Mesh *_mesh, uint8_t _id, bgfx::ProgramHandle _program, const float *_mtx, uint64_t _state = BGFX_STATE_MASK); @@ -57,9 +56,6 @@ namespace bgfxutils { void meshTransform (Mesh* mesh, const float *mtx); - Mesh *createCuboid (float width, float height, float depth); - Mesh *createUVSphere (int rows, int segments, float radius = 1.0f); - Mesh *createCylinder (int segments); } #endif