Refactored meshes. Now we can merge them

master
Martin Felis 2017-02-18 17:38:21 +01:00
parent e0e57a2b4f
commit d994949b02
5 changed files with 95 additions and 197 deletions

View File

@ -37,7 +37,7 @@ CharacterEntity::CharacterEntity() {
Transform::fromTrans( Transform::fromTrans(
Vector3f (0.0f, 0.9 * 0.5f, 0.0f) Vector3f (0.0f, 0.9 * 0.5f, 0.0f)
), ),
bgfxutils::createUVSphere (45, 45, 0.9) Mesh::sCreateUVSphere(45, 45, 0.9)
); );
entity->mesh.addMesh( entity->mesh.addMesh(
@ -45,7 +45,7 @@ CharacterEntity::CharacterEntity() {
Transform::fromTrans( Transform::fromTrans(
Vector3f (0.0f, 0.55f, 0.0f) Vector3f (0.0f, 0.55f, 0.0f)
), ),
bgfxutils::createUVSphere (45, 45, 0.7) Mesh::sCreateUVSphere (45, 45, 0.7)
); );
entity->mesh.addMesh( entity->mesh.addMesh(
@ -53,7 +53,7 @@ CharacterEntity::CharacterEntity() {
Transform::fromTrans( Transform::fromTrans(
Vector3f (0.0f, 0.4f, 0.0f) 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); // state->character->entity->mesh = bgfxutils::createCuboid (1.f, 1.f, 1.f);

View File

@ -158,7 +158,7 @@ void MeshHierarchy::updateMatrices(const Matrix44f &world_transform) {
void MeshHierarchy::submit(const RenderState *state) { void MeshHierarchy::submit(const RenderState *state) {
for (uint32_t i = 0; i < meshes.size(); ++i) { 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; 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++) { for (size_t i = 0; i < lights.size(); i++) {
gLog ("Destroying light uniforms for light %d", i); gLog ("Destroying light uniforms for light %d", i);
bgfx::destroyFrameBuffer(lights[i].shadowMapFB); bgfx::destroyFrameBuffer(lights[i].shadowMapFB);
@ -1523,12 +1518,12 @@ void Renderer::paintGL() {
for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) { for (uint32_t j = 0; j < entities[i]->mesh.meshes.size(); ++j) {
bx::mtxMul( bx::mtxMul(
lightMtx, lightMtx,
entities[i]->mesh.meshMatrices[j].data(), entities[i]->mesh.meshMatrices[j].data(),
lights[0].mtxShadow lights[0].mtxShadow
); );
bgfx::setUniform(lights[0].u_lightMtx, lightMtx); bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfxutils::meshSubmit ( bgfxutils::meshSubmit (
entities[i]->mesh.meshes[j], entities[i]->mesh.meshes[j]->mBgfxMesh,
&s_renderStates[RenderState::ShadowMap], &s_renderStates[RenderState::ShadowMap],
1, 1,
entities[i]->mesh.meshMatrices[j].data() entities[i]->mesh.meshMatrices[j].data()
@ -1545,7 +1540,7 @@ void Renderer::paintGL() {
bgfx::setUniform(lights[0].u_lightMtx, lightMtx); bgfx::setUniform(lights[0].u_lightMtx, lightMtx);
bgfx::setUniform(u_color, entities[i]->color, 4); bgfx::setUniform(u_color, entities[i]->color, 4);
bgfxutils::meshSubmit ( bgfxutils::meshSubmit (
entities[i]->mesh.meshes[j], entities[i]->mesh.meshes[j]->mBgfxMesh,
&s_renderStates[RenderState::Scene], &s_renderStates[RenderState::Scene],
1, 1,
entities[i]->mesh.meshMatrices[j].data() entities[i]->mesh.meshMatrices[j].data()
@ -1760,36 +1755,6 @@ bool Renderer::destroyEntity(Entity* entity) {
return false; 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<tinyobj::shape_t> shapes;
std::vector<tinyobj::material_t> 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 // debug commands
void Renderer::drawDebugLine ( void Renderer::drawDebugLine (
const Vector3f &from, const Vector3f &from,

View File

@ -233,11 +233,11 @@ struct Transform {
struct MeshHierarchy { struct MeshHierarchy {
~MeshHierarchy() ~MeshHierarchy()
{ {
for (bgfxutils::Mesh* mesh : meshes) { for (Mesh* mesh : meshes) {
meshUnload(mesh); delete mesh;
} }
} }
std::vector<bgfxutils::Mesh*> meshes; std::vector<Mesh*> meshes;
/// index of the parent. Children must have higher indices than heir /// index of the parent. Children must have higher indices than heir
// parents // parents
@ -250,7 +250,7 @@ struct MeshHierarchy {
void addMesh( void addMesh(
const int parent_idx, const int parent_idx,
const Transform& transform, const Transform& transform,
bgfxutils::Mesh* mesh) { Mesh* mesh) {
assert (parent_idx == -1 || parent_idx < parent.size()); assert (parent_idx == -1 || parent_idx < parent.size());
parent.push_back(parent_idx); parent.push_back(parent_idx);
localTransforms.push_back(transform); localTransforms.push_back(transform);
@ -261,7 +261,6 @@ struct MeshHierarchy {
} else { } else {
meshMatrices.push_back(transform.toMatrix()); meshMatrices.push_back(transform.toMatrix());
} }
} }
void updateMatrices(const Matrix44f &world_transform); void updateMatrices(const Matrix44f &world_transform);
void submit(const RenderState *state); void submit(const RenderState *state);
@ -338,10 +337,6 @@ struct Renderer {
bgfx::UniformHandle sceneDefaultTextureSampler; bgfx::UniformHandle sceneDefaultTextureSampler;
bgfx::TextureHandle sceneDefaultTexture; bgfx::TextureHandle sceneDefaultTexture;
std::vector<bgfxutils::Mesh*> meshes;
typedef std::map<std::string, unsigned int> MeshIdMap;
MeshIdMap meshIdMap;
LightProbe mLightProbes[LightProbe::Count]; LightProbe mLightProbes[LightProbe::Count];
LightProbe::Enum mCurrentLightProbe; LightProbe::Enum mCurrentLightProbe;
@ -381,8 +376,6 @@ struct Renderer {
Entity* createEntity(); Entity* createEntity();
bool destroyEntity (Entity* entity); bool destroyEntity (Entity* entity);
bgfxutils::Mesh* loadMesh(const char* filename);
// debug commands // debug commands
void drawDebugLine ( void drawDebugLine (
const Vector3f &from, const Vector3f &from,

View File

@ -377,107 +377,6 @@ bgfx::TextureHandle loadTexture(const char* _name, uint32_t _flags, uint8_t _ski
return loadTexture(entry::getFileReader(), _name, _flags, _skip, _info); 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 struct Aabb
{ {
float m_min[3]; float m_min[3];
@ -984,11 +883,50 @@ Mesh *createMeshFromStdVectors (
return result; 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 // work arrays that we fill with data
std::vector<Vector4f> vertices; std::vector<Vector4f> &vertices = result->mVertices;
std::vector<Vector3f> normals; std::vector<Vector3f> &normals = result->mNormals;
std::vector<Vector4f> colors; std::vector<Vector4f> &colors = result->mColors;
Vector4f v0 ( 0.5 * width, -0.5 * height, 0.5 * depth, 1.f); 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); 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); vertices.push_back(v1);
normals.push_back(normal); 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 // work arrays that we fill with data
std::vector<Vector4f> vertices; std::vector<Vector4f> &vertices = result->mVertices;
std::vector<Vector3f> normals; std::vector<Vector3f> &normals = result->mNormals;
std::vector<Vector4f> colors; std::vector<Vector4f> &colors = result->mColors;
// fill arrays // fill arrays
float row_d = 1. / (rows); 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 // work arrays that we fill with data
std::vector<Vector4f> vertices; std::vector<Vector4f> &vertices = result->mVertices;
std::vector<Vector3f> normals; std::vector<Vector3f> &normals = result->mNormals;
std::vector<Vector4f> colors; std::vector<Vector4f> &colors = result->mColors;
float delta = 2. * M_PI / static_cast<float>(segments); float delta = 2. * M_PI / static_cast<float>(segments);
for (unsigned int i = 0; i < segments; i++) { for (unsigned int i = 0; i < segments; i++) {
@ -1226,9 +1172,7 @@ Mesh *createCylinder (int segments) {
normals.push_back(normal); normals.push_back(normal);
} }
return createMeshFromStdVectors (vertices, normals, colors); result->Update();
return result;
} }
}

View File

@ -6,8 +6,28 @@
#include "GLFW/glfw3.h" #include "GLFW/glfw3.h"
#include <bgfx/bgfx.h> #include <bgfx/bgfx.h>
// Forward declarations
struct RenderState; struct RenderState;
namespace bgfxutils {
struct Mesh;
}
struct Mesh {
bgfxutils::Mesh* mBgfxMesh = nullptr;
std::vector<Vector4f> mVertices;
std::vector<Vector3f> mNormals;
std::vector<Vector4f> 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 { namespace bgfxutils {
bgfx::ShaderHandle loadShader(const char *_name); 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, void calcTangents(void *_vertices, uint16_t _numVertices, bgfx::VertexDecl _decl, const uint16_t *_indices,
uint32_t _numIndices); 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); Mesh *meshLoad(const char *_filePath);
void meshUnload(Mesh *_mesh); void meshUnload(Mesh *_mesh);
MeshState *meshStateCreate();
void meshStateDestroy(MeshState *_meshState);
void meshSubmit(const Mesh *_mesh, uint8_t _id, bgfx::ProgramHandle _program, const float *_mtx, void meshSubmit(const Mesh *_mesh, uint8_t _id, bgfx::ProgramHandle _program, const float *_mtx,
uint64_t _state = BGFX_STATE_MASK); uint64_t _state = BGFX_STATE_MASK);
@ -57,9 +56,6 @@ namespace bgfxutils {
void meshTransform (Mesh* mesh, const float *mtx); 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 #endif