Add some simple post processing stuff for flipping model texture coords

This commit is contained in:
SeanOMik 2022-09-27 00:26:50 -04:00
parent 475bb08f0e
commit ab09107d23
Signed by: SeanOMik
GPG Key ID: 568F326C7EB33ACB
6 changed files with 81 additions and 13 deletions

View File

@ -181,7 +181,11 @@ int main(int argc, char *argv[]) {
se::ecs::Entity entity = scene->create_entity(); se::ecs::Entity entity = scene->create_entity();
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/dragon.obj"); //entity.add_component<se::ModelComponent>("examples/dev_testing/resources/dragon.obj");
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/stall.obj"); //entity.add_component<se::ModelComponent>("examples/dev_testing/resources/stall.obj");
entity.add_component<se::ModelComponent>("examples/dev_testing/resources/backpack/backpack.obj");
// Backpack model required vertically flipped texture coords.
auto& model_comp = entity.add_component<se::ModelComponent>("examples/dev_testing/resources/backpack/backpack.obj");
model_comp.model.vertically_flip_tex_coords();
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx"); //entity.add_component<se::ModelComponent>("examples/dev_testing/resources/scientist/scientist.fbx");
//entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx"); //entity.add_component<se::ModelComponent>("examples/dev_testing/resources/paradigm/paradigm.fbx");
//entity.add_component<se::RotatingComponent>(); //entity.add_component<se::RotatingComponent>();

View File

@ -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) {
} }
}; };

View File

@ -10,6 +10,12 @@
//#include <assimp/mesh.h> //#include <assimp/mesh.h>
namespace simpleengine::gfx { 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. * @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 { class Model : public simpleengine::Transformable {
protected: protected:
std::string model_directory; // May be needed std::string model_directory; // May be needed
int additional_assimp_flags;
int model_processing_flags;
public: public:
std::vector<gfx::Mesh> meshes; std::vector<gfx::Mesh> 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 load_model(std::string path);
void process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene); void process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene);
@ -31,5 +39,12 @@ namespace simpleengine::gfx {
std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material); std::unordered_map<aiTextureType, std::vector<Texture>> load_all_textures(aiMaterial* material);
std::vector<std::shared_ptr<Texture>> load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type); std::vector<std::shared_ptr<Texture>> load_material_texture(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiMaterial* material, aiTextureType type);
protected:
void post_process();
public:
void vertically_flip_tex_coords();
void horizontally_flip_tex_coords();
}; };
} }

View File

@ -1,5 +1,6 @@
#pragma once #pragma once
#include <cstdint>
#ifdef __linux__ #ifdef __linux__
#include <GL/glew.h> #include <GL/glew.h>
#include <GL/gl.h> #include <GL/gl.h>
@ -17,6 +18,13 @@
#include <iostream> #include <iostream>
namespace simpleengine::gfx { namespace simpleengine::gfx {
enum TextureFlags : uint8_t {
TexFlags_IMG_2D = 0b00000001,
TexFlags_FLIP_VERTICALLY = 0b00000010,
TexFlags_FLIP_HORIZONTALLY = 0b00000100,
TexFlags_MIPMAP = 0b00001000,
};
class Texture { class Texture {
private: private:
unsigned char* img_data; // TODO Free this if its not used anymore 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 img_2d Whether or not the texture is 2D.
* @param mipmap Whether or not to generate mipmaps for this texture. * @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. * @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 img_2d Whether or not the texture is 2D.
* @param mipmap Whether or not to generate mipmaps for this texture. * @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. * @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 img_2d Whether or not the texture is 2D.
* @param mipmap Whether or not to generate mipmaps for this texture. * @param mipmap Whether or not to generate mipmaps for this texture.
*/ */
Texture(std::vector<unsigned char> buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, bool img_2d = true, bool flip_vertically = false, bool mipmap = true); Texture(std::vector<unsigned char> buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = TextureFlags::TexFlags_IMG_2D |
TextureFlags::TexFlags_MIPMAP);
static Texture white_texture(); static Texture white_texture();

View File

@ -14,15 +14,26 @@
#include <vector> #include <vector>
namespace simpleengine::gfx { 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); 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) { void Model::load_model(std::string path) {
Assimp::Importer importer; Assimp::Importer importer;
// assimp post processing options: http://assimp.sourceforge.net/lib_html/postprocess_8h.html // 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) { if (!scene || scene->mFlags & AI_SCENE_FLAGS_INCOMPLETE || !scene->mRootNode) {
std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl; std::cout << "ERROR::ASSIMP::" << importer.GetErrorString() << std::endl;
@ -33,6 +44,8 @@ namespace simpleengine::gfx {
std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> processed_textures; std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>> processed_textures;
process_node(processed_textures, scene->mRootNode, scene); process_node(processed_textures, scene->mRootNode, scene);
post_process();
} }
void Model::process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene) { void Model::process_node(std::unordered_map<aiTextureType, std::vector<std::shared_ptr<Texture>>>& processed_textures, aiNode* node, const aiScene* scene) {
@ -164,7 +177,7 @@ namespace simpleengine::gfx {
ss << model_directory << "/" << texture_path; ss << model_directory << "/" << texture_path;
std::string full_path = ss.str(); 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; texture.path = texture_path;
textures.emplace_back(std::make_shared<Texture>(texture)); textures.emplace_back(std::make_shared<Texture>(texture));
@ -173,4 +186,20 @@ namespace simpleengine::gfx {
return textures; 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 } // namespace simpleengine::gfx

View File

@ -4,7 +4,11 @@
#include <stb_image.h> #include <stb_image.h>
namespace simpleengine::gfx { 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; image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
glGenTextures(1, &texture_id); glGenTextures(1, &texture_id);
@ -39,7 +43,11 @@ namespace simpleengine::gfx {
unbind(); 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; image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D;
glGenTextures(1, &texture_id); glGenTextures(1, &texture_id);
@ -74,8 +82,8 @@ namespace simpleengine::gfx {
unbind(); unbind();
} }
Texture::Texture(std::vector<unsigned char> buffer, aiTextureType type, bool img_2d, bool flip_vertically, bool mipmap) : Texture::Texture(std::vector<unsigned char> buffer, aiTextureType type, int flags) :
Texture(buffer.data(), buffer.size(), type, img_2d, mipmap) { Texture(buffer.data(), buffer.size(), type, flags) {
} }