added mesh serialization
This commit is contained in:
parent
a70aaf7a31
commit
7c139a576a
@ -4,7 +4,13 @@
|
|||||||
layout(triangles) in;
|
layout(triangles) in;
|
||||||
layout(triangle_strip, max_vertices = 18) out;
|
layout(triangle_strip, max_vertices = 18) out;
|
||||||
|
|
||||||
|
#ifdef POINT_LIGHT
|
||||||
uniform mat4 MVP[6];
|
uniform mat4 MVP[6];
|
||||||
|
#elif defined CASCADED
|
||||||
|
uniform mat4 frontShadowMVP;
|
||||||
|
uniform mat4 midShadowMVP;
|
||||||
|
uniform mat4 backShadowMVP;
|
||||||
|
#endif
|
||||||
|
|
||||||
out vec4 FragPos;
|
out vec4 FragPos;
|
||||||
|
|
||||||
|
@ -16,6 +16,7 @@ const char* const Mesh::flagStr[Mesh::NB_FLAGS] =
|
|||||||
"MESH_2D",
|
"MESH_2D",
|
||||||
|
|
||||||
"TANGENT_SPACE",
|
"TANGENT_SPACE",
|
||||||
|
"DOUBLE_SIDED",
|
||||||
"BILLBOARD",
|
"BILLBOARD",
|
||||||
"SHADOWED",
|
"SHADOWED",
|
||||||
|
|
||||||
@ -199,6 +200,8 @@ unsigned int Mesh::getFlags()
|
|||||||
|
|
||||||
if(!tangents.empty())
|
if(!tangents.empty())
|
||||||
flags |= 1 << MESH_TANGENT_SPACE;
|
flags |= 1 << MESH_TANGENT_SPACE;
|
||||||
|
if(isDoubleSided)
|
||||||
|
flags |= 1 << MESH_DOUBLE_SIDED;
|
||||||
if(isBillboard)
|
if(isBillboard)
|
||||||
flags |= 1 << MESH_BILLBOARD;
|
flags |= 1 << MESH_BILLBOARD;
|
||||||
if(isShadowCaster)
|
if(isShadowCaster)
|
||||||
|
20
src/mesh.h
20
src/mesh.h
@ -31,6 +31,7 @@ public:
|
|||||||
|
|
||||||
// 3D Geometric properties
|
// 3D Geometric properties
|
||||||
MESH_TANGENT_SPACE,
|
MESH_TANGENT_SPACE,
|
||||||
|
MESH_DOUBLE_SIDED,
|
||||||
MESH_BILLBOARD,
|
MESH_BILLBOARD,
|
||||||
MESH_SHADOWED,
|
MESH_SHADOWED,
|
||||||
|
|
||||||
@ -62,6 +63,14 @@ public:
|
|||||||
std::vector<glm::vec3> positions3D;
|
std::vector<glm::vec3> positions3D;
|
||||||
std::vector<glm::vec3> normals;
|
std::vector<glm::vec3> normals;
|
||||||
|
|
||||||
|
typedef struct
|
||||||
|
{
|
||||||
|
glm::vec3 tangent;
|
||||||
|
glm::vec3 binormal;
|
||||||
|
} Tangents;
|
||||||
|
|
||||||
|
std::vector<Tangents> tangents;
|
||||||
|
|
||||||
// 2D public data
|
// 2D public data
|
||||||
std::vector<glm::vec2> positions2D;
|
std::vector<glm::vec2> positions2D;
|
||||||
|
|
||||||
@ -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
|
* @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 */
|
/* 3D MESH PROPERTIES */
|
||||||
@ -197,14 +207,6 @@ public:
|
|||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
glm::vec3 tangent;
|
|
||||||
glm::vec3 binormal;
|
|
||||||
} Tangents;
|
|
||||||
|
|
||||||
std::vector<Tangents> tangents;
|
|
||||||
|
|
||||||
Material* material;
|
Material* material;
|
||||||
bool isDoubleSided;
|
bool isDoubleSided;
|
||||||
bool isBillboard;
|
bool isBillboard;
|
||||||
|
238
src/serializers.cpp
Normal file
238
src/serializers.cpp
Normal 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
19
src/serializers.h
Normal 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
|
Loading…
x
Reference in New Issue
Block a user