diff --git a/shaders/shadow.geom.glsl b/shaders/shadow.geom.glsl index b20b04e..ea50e6d 100644 --- a/shaders/shadow.geom.glsl +++ b/shaders/shadow.geom.glsl @@ -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; diff --git a/src/mesh.cpp b/src/mesh.cpp index aecce41..e949191 100644 --- a/src/mesh.cpp +++ b/src/mesh.cpp @@ -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) diff --git a/src/mesh.h b/src/mesh.h index dfaf51f..0c7b457 100644 --- a/src/mesh.h +++ b/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 positions3D; std::vector normals; - + + typedef struct + { + glm::vec3 tangent; + glm::vec3 binormal; + } Tangents; + + std::vector tangents; + // 2D public data std::vector positions2D; @@ -69,7 +78,7 @@ public: std::vector texCoords; std::vector instances_offsets; std::vector 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; - Material* material; bool isDoubleSided; bool isBillboard; diff --git a/src/serializers.cpp b/src/serializers.cpp new file mode 100644 index 0000000..1cd3c88 --- /dev/null +++ b/src/serializers.cpp @@ -0,0 +1,238 @@ +#include "serializers.h" + +#include + +#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 +bool writeBuffer(const std::vector &vec, std::FILE *file); + +template +bool readBuffer(std::vector &vec, std::FILE *file); + +// IMPLEMENTATIONS + +template +bool writeBuffer(const std::vector &vec, std::FILE *file) +{ + size_t nbWritten = std::fwrite(vec.data(), sizeof(T), vec.size(), file); + return (nbWritten == vec.size()); +} + +template +bool readBuffer(std::vector &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) +{ + +} + +} diff --git a/src/serializers.h b/src/serializers.h new file mode 100644 index 0000000..c59d899 --- /dev/null +++ b/src/serializers.h @@ -0,0 +1,19 @@ +#ifndef SERIALIZERS_H +#define SERIALIZERS_H + +#include + +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