added mesh serialization

This commit is contained in:
Anselme 2016-06-14 17:46:01 +02:00
parent a70aaf7a31
commit 7c139a576a
5 changed files with 279 additions and 11 deletions

View File

@ -4,7 +4,13 @@
layout(triangles) in;
layout(triangle_strip, max_vertices = 18) out;
#ifdef POINT_LIGHT
uniform mat4 MVP[6];
#elif defined CASCADED
uniform mat4 frontShadowMVP;
uniform mat4 midShadowMVP;
uniform mat4 backShadowMVP;
#endif
out vec4 FragPos;

View File

@ -16,6 +16,7 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
"MESH_2D",
"TANGENT_SPACE",
"DOUBLE_SIDED",
"BILLBOARD",
"SHADOWED",
@ -199,6 +200,8 @@ unsigned int Mesh::getFlags()
if(!tangents.empty())
flags |= 1 << MESH_TANGENT_SPACE;
if(isDoubleSided)
flags |= 1 << MESH_DOUBLE_SIDED;
if(isBillboard)
flags |= 1 << MESH_BILLBOARD;
if(isShadowCaster)

View File

@ -31,6 +31,7 @@ public:
// 3D Geometric properties
MESH_TANGENT_SPACE,
MESH_DOUBLE_SIDED,
MESH_BILLBOARD,
MESH_SHADOWED,
@ -61,7 +62,15 @@ public:
// 3D public data
std::vector<glm::vec3> positions3D;
std::vector<glm::vec3> normals;
typedef struct
{
glm::vec3 tangent;
glm::vec3 binormal;
} Tangents;
std::vector<Tangents> tangents;
// 2D public data
std::vector<glm::vec2> positions2D;
@ -69,7 +78,7 @@ public:
std::vector<glm::vec2> texCoords;
std::vector<glm::vec3> instances_offsets;
std::vector<GLuint> indices;
/*************************************************************/
/* MAIN METHODS */
/*************************************************************/
@ -130,7 +139,8 @@ public:
/**
* @brief setDepth allows to set the depth of a 2D mesh, the depth must be between -1 and 1, -1 being the closest to the camera
*/
void setDepth(float d) {depth = d;}
void setDepth(float d) { depth = d; }
float getDepth() { return depth; }
/*************************************************************/
/* 3D MESH PROPERTIES */
@ -197,14 +207,6 @@ public:
protected:
typedef struct
{
glm::vec3 tangent;
glm::vec3 binormal;
} Tangents;
std::vector<Tangents> tangents;
Material* material;
bool isDoubleSided;
bool isBillboard;

238
src/serializers.cpp Normal file
View File

@ -0,0 +1,238 @@
#include "serializers.h"
#include <cstdio>
#include "mesh.h"
#include "light.h"
#include "texture.h"
namespace serializers
{
// STRUCTS
struct MeshHeader
{
unsigned int flags;
int nbPositions;
int depth;
int nbInstances_offsets;
int nbIndices;
};
struct LightHeader
{
};
struct TextureHeader
{
};
// PRIVATE FUNCTIONS
bool serializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file);
bool deserializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file);
template<typename T>
bool writeBuffer(const std::vector<T> &vec, std::FILE *file);
template<typename T>
bool readBuffer(std::vector<T> &vec, std::FILE *file);
// IMPLEMENTATIONS
template<typename T>
bool writeBuffer(const std::vector<T> &vec, std::FILE *file)
{
size_t nbWritten = std::fwrite(vec.data(), sizeof(T), vec.size(), file);
return (nbWritten == vec.size());
}
template<typename T>
bool readBuffer(std::vector<T> &vec, std::FILE *file)
{
size_t nbRead = std::fread(vec.data(), sizeof(T), vec.size(), file);
return (nbRead == vec.size());
}
bool saveMesh(const std::string &filename, Mesh *mesh)
{
// open file
std::FILE *file = std::fopen(filename.c_str(), "w");
if(file == NULL)
return false;
// creating header
MeshHeader header;
header.flags = mesh->getFlags();
if(header.flags & (1 << Mesh::MESH_3D))
header.nbPositions = mesh->positions3D.size();
else
{
mesh->positions2D.size();
header.depth = mesh->getDepth();
}
header.nbIndices = mesh->indices.size();
header.nbInstances_offsets = mesh->instances_offsets.size();
// serializing
bool ok = false;
if(header.nbPositions != 0)
ok = serializeMesh(mesh, header, file);
// finishing
std::fclose(file);
return ok;
}
bool serializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
{
// writing header
size_t nbWritten = std::fwrite(&header, sizeof(MeshHeader), 1, file);
if(nbWritten != 1)
return false;
// writing buffers
if(header.flags & (1 << Mesh::MESH_3D))
{
if(!writeBuffer(mesh->positions3D, file))
return false;
if(mesh->normals.size() == 0)
mesh->computeNormals();
if(!writeBuffer(mesh->normals, file))
return false;
if(header.flags & (1 << Mesh::MESH_TANGENT_SPACE))
{
if(!writeBuffer(mesh->tangents, file))
return false;
}
}
else
{
if(!writeBuffer(mesh->positions2D, file))
return false;
}
if(header.nbInstances_offsets)
{
if(!writeBuffer(mesh->instances_offsets, file))
return false;
}
if(header.nbIndices)
{
if(!writeBuffer(mesh->indices, file))
return false;
}
if(header.flags & (1 << Mesh::MESH_TEXTURABLE))
{
if(!writeBuffer(mesh->texCoords, file))
return false;
}
return true;
}
bool saveLight(const std::string &filename, Light *light)
{
std::FILE *file = std::fopen(filename.c_str(), "w");
if(file == NULL)
return false;
std::fclose(file);
}
Mesh* loadMesh(const std::string &filename)
{
// open file
std::FILE *file = std::fopen(filename.c_str(), "r");
if(file == NULL)
return NULL;
// reading header
MeshHeader header;
size_t nbRead = std::fread(&header, sizeof(MeshHeader), 1, file);
// deserializing mesh
bool ok = false;
Mesh *mesh = NULL;
if(nbRead == 1 && header.nbPositions != 0)
{
mesh = new Mesh();
ok = deserializeMesh(mesh, header, file);
}
// finishing
std::fclose(file);
if(!ok && mesh != NULL)
{
delete mesh;
mesh = NULL;
}
return mesh;
}
bool deserializeMesh(Mesh* mesh, const MeshHeader &header, FILE *file)
{
if(header.flags & (1 << Mesh::MESH_3D))
{
mesh->positions3D.reserve(header.nbPositions);
if(!readBuffer(mesh->positions3D, file))
return false;
mesh->normals.reserve(header.nbPositions);
if(!readBuffer(mesh->normals, file))
return false;
if(header.flags & (1 << Mesh::MESH_TANGENT_SPACE))
{
mesh->tangents.reserve(header.nbPositions);
if(!readBuffer(mesh->tangents, file))
return false;
}
}
else
{
mesh->positions2D.reserve(header.nbPositions);
if(!readBuffer(mesh->positions2D, file))
return false;
mesh->setDepth(header.depth);
}
if(header.nbInstances_offsets)
{
mesh->instances_offsets.reserve(header.nbInstances_offsets);
if(!readBuffer(mesh->instances_offsets, file))
return false;
}
if(header.nbIndices)
{
mesh->indices.reserve(header.nbIndices);
if(!readBuffer(mesh->indices, file))
return false;
}
if(header.flags & (1 << Mesh::MESH_TEXTURABLE))
{
mesh->texCoords.reserve(header.nbPositions);
if(!readBuffer(mesh->texCoords, file))
return false;
}
mesh->setIsBillboard(header.flags & (1 << Mesh::MESH_BILLBOARD));
mesh->setIsDoubleSided(header.flags & (1 << Mesh::MESH_DOUBLE_SIDED));
mesh->setIsShadowCaster(header.flags & (1 << Mesh::MESH_SHADOWED));
return true;
}
Light* loadLight(const std::string &filename)
{
}
}

19
src/serializers.h Normal file
View File

@ -0,0 +1,19 @@
#ifndef SERIALIZERS_H
#define SERIALIZERS_H
#include <string>
class Mesh;
class Light;
class Texture;
namespace Serializers
{
bool saveMesh(const std::string &filename, Mesh *mesh);
bool saveLight(const std::string &filename, Light *light);
Mesh* loadMesh(const std::string &filename);
Light* loadLight(const std::string &filename);
}
#endif // SERIALIZERS_H