diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index d5f840d..269f46b 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -181,7 +181,11 @@ int main(int argc, char *argv[]) { se::ecs::Entity entity = scene->create_entity(); //entity.add_component("examples/dev_testing/resources/dragon.obj"); //entity.add_component("examples/dev_testing/resources/stall.obj"); - entity.add_component("examples/dev_testing/resources/backpack/backpack.obj"); + + // Backpack model required vertically flipped texture coords. + auto& model_comp = entity.add_component("examples/dev_testing/resources/backpack/backpack.obj"); + model_comp.model.vertically_flip_tex_coords(); + //entity.add_component("examples/dev_testing/resources/scientist/scientist.fbx"); //entity.add_component("examples/dev_testing/resources/paradigm/paradigm.fbx"); //entity.add_component(); diff --git a/include/simpleengine/ecs/component/model_component.h b/include/simpleengine/ecs/component/model_component.h index 359298e..cac09de 100644 --- a/include/simpleengine/ecs/component/model_component.h +++ b/include/simpleengine/ecs/component/model_component.h @@ -18,7 +18,8 @@ namespace simpleengine { } - ModelComponent(std::string model_file_path) : model(model_file_path) { + ModelComponent(std::string model_file_path, int model_processing_flags = gfx::ModelProcessingFlags::MdlProcFlag_NONE, + int assimp_flags = 0) : model(model_file_path, model_processing_flags, assimp_flags) { } }; diff --git a/include/simpleengine/gfx/model.h b/include/simpleengine/gfx/model.h index c525c51..a49773d 100644 --- a/include/simpleengine/gfx/model.h +++ b/include/simpleengine/gfx/model.h @@ -10,6 +10,12 @@ //#include namespace simpleengine::gfx { + enum ModelProcessingFlags : uint8_t { + MdlProcFlag_NONE = 0b00000000, + MdlProcFlag_FLIP_TEX_COORDS_VERTICALLY = 0b00000001, + MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY = 0b00000010, + }; + /** * @brief A Model is a group of Meshes read from the 3D model file. * @@ -20,10 +26,12 @@ namespace simpleengine::gfx { class Model : public simpleengine::Transformable { protected: std::string model_directory; // May be needed + int additional_assimp_flags; + int model_processing_flags; public: std::vector meshes; - Model(std::string file_path); + Model(std::string file_path, int model_processing_flags = ModelProcessingFlags::MdlProcFlag_NONE, int assimp_flags = 0); void load_model(std::string path); void process_node(std::unordered_map>>& processed_textures, aiNode* node, const aiScene* scene); @@ -31,5 +39,12 @@ namespace simpleengine::gfx { std::unordered_map> load_all_textures(aiMaterial* material); std::vector> load_material_texture(std::unordered_map>>& processed_textures, aiMaterial* material, aiTextureType type); + + protected: + void post_process(); + public: + + void vertically_flip_tex_coords(); + void horizontally_flip_tex_coords(); }; } \ No newline at end of file diff --git a/include/simpleengine/gfx/texture.h b/include/simpleengine/gfx/texture.h index 981f0e2..302f14b 100644 --- a/include/simpleengine/gfx/texture.h +++ b/include/simpleengine/gfx/texture.h @@ -1,5 +1,6 @@ #pragma once +#include #ifdef __linux__ #include #include @@ -17,6 +18,13 @@ #include namespace simpleengine::gfx { + enum TextureFlags : uint8_t { + TexFlags_IMG_2D = 0b00000001, + TexFlags_FLIP_VERTICALLY = 0b00000010, + TexFlags_FLIP_HORIZONTALLY = 0b00000100, + TexFlags_MIPMAP = 0b00001000, + }; + class Texture { private: unsigned char* img_data; // TODO Free this if its not used anymore @@ -39,7 +47,8 @@ namespace simpleengine::gfx { * @param img_2d Whether or not the texture is 2D. * @param mipmap Whether or not to generate mipmaps for this texture. */ - Texture(const char* path, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true); + Texture(const char* path, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = TextureFlags::TexFlags_IMG_2D | + TextureFlags::TexFlags_MIPMAP); /** * @brief Construct a new Texture object from the loaded file buffer. @@ -49,7 +58,8 @@ namespace simpleengine::gfx { * @param img_2d Whether or not the texture is 2D. * @param mipmap Whether or not to generate mipmaps for this texture. */ - Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true); + Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = TextureFlags::TexFlags_IMG_2D | + TextureFlags::TexFlags_MIPMAP); /** * @brief Construct a new Texture object from the loaded file buffer. @@ -58,7 +68,8 @@ namespace simpleengine::gfx { * @param img_2d Whether or not the texture is 2D. * @param mipmap Whether or not to generate mipmaps for this texture. */ - Texture(std::vector buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true); + Texture(std::vector buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = TextureFlags::TexFlags_IMG_2D | + TextureFlags::TexFlags_MIPMAP); static Texture white_texture(); diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index 4968035..44ccea2 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -14,15 +14,26 @@ #include namespace simpleengine::gfx { - Model::Model(std::string file_path) { + Model::Model(std::string file_path, int model_processing_flags, int assimp_flags): model_processing_flags(model_processing_flags), + additional_assimp_flags(assimp_flags) { load_model(file_path); } + void Model::post_process() { + if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_FLIP_TEX_COORDS_VERTICALLY) { + vertically_flip_tex_coords(); + } + + if (model_processing_flags & ModelProcessingFlags::MdlProcFlag_FLIP_TEX_COORDS_HORIZONTALLY) { + horizontally_flip_tex_coords(); + } + } + void Model::load_model(std::string path) { Assimp::Importer importer; // assimp post processing options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html - const aiScene *scene = importer.ReadFile(path, aiProcess_Triangulate | aiProcess_FlipUVs); + const aiScene *scene = importer.ReadFile(path, additional_assimp_flags | aiProcess_Triangulate | aiProcess_FlipUVs); if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) { std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl; @@ -33,6 +44,8 @@ namespace simpleengine::gfx { std::unordered_map>> processed_textures; process_node(processed_textures, scene->mRootNode, scene); + + post_process(); } void Model::process_node(std::unordered_map>>& processed_textures, aiNode* node, const aiScene* scene) { @@ -164,7 +177,7 @@ namespace simpleengine::gfx { ss << model_directory << "/" << texture_path; std::string full_path = ss.str(); - Texture texture(full_path.c_str(), type, true, true); + Texture texture(full_path.c_str(), type, /* TextureFlags::TexFlags_FLIP_VERTICALLY | */ TextureFlags::TexFlags_IMG_2D | TextureFlags::TexFlags_MIPMAP); texture.path = texture_path; textures.emplace_back(std::make_shared(texture)); @@ -173,4 +186,20 @@ namespace simpleengine::gfx { return textures; } + + void Model::vertically_flip_tex_coords() { + for (auto& mesh : meshes) { + for (auto& vertex : mesh.vertices) { + vertex.tex_coord.y *= -1; + } + } + } + + void Model::horizontally_flip_tex_coords() { + for (auto& mesh : meshes) { + for (auto& vertex : mesh.vertices) { + vertex.tex_coord.x *= -1; + } + } + } } // namespace simpleengine::gfx \ No newline at end of file diff --git a/src/gfx/texture.cpp b/src/gfx/texture.cpp index d3cdedc..72923b5 100644 --- a/src/gfx/texture.cpp +++ b/src/gfx/texture.cpp @@ -4,7 +4,11 @@ #include namespace simpleengine::gfx { - Texture::Texture(const char* path, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap): type(type) { + Texture::Texture(const char* path, aiTextureType type, int flags): type(type) { + bool img_2d = flags & TextureFlags::TexFlags_IMG_2D; + bool flip_vertically = flags & TextureFlags::TexFlags_FLIP_VERTICALLY; + bool mipmap = flags & TextureFlags::TexFlags_MIPMAP; + image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D; glGenTextures(1, &texture_id); @@ -39,7 +43,11 @@ namespace simpleengine::gfx { unbind(); } - Texture::Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap): type(type) { + Texture::Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type, int flags): type(type) { + bool img_2d = flags & TextureFlags::TexFlags_IMG_2D; + bool flip_vertically = flags & TextureFlags::TexFlags_FLIP_VERTICALLY; + bool mipmap = flags & TextureFlags::TexFlags_MIPMAP; + image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D; glGenTextures(1, &texture_id); @@ -74,8 +82,8 @@ namespace simpleengine::gfx { unbind(); } - Texture::Texture(std::vector buffer, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap) : - Texture(buffer.data(), buffer.size(), type, img_2d, mipmap) { + Texture::Texture(std::vector buffer, aiTextureType type, int flags) : + Texture(buffer.data(), buffer.size(), type, flags) { }