added mesh serialization
This commit is contained in:
parent
a70aaf7a31
commit
7c139a576a
@ -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;
|
||||
|
||||
|
@ -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)
|
||||
|
24
src/mesh.h
24
src/mesh.h
@ -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
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