From dbc12e422c3f383541db9162da9726ccb7ea7afa Mon Sep 17 00:00:00 2001 From: SeanOMik Date: Wed, 28 Sep 2022 21:21:47 -0400 Subject: [PATCH] Get specular maps working and make them optional --- .clang-tidy | 37 ++++++ CMake/Getassimp.cmake | 13 ++ CMakeLists.txt | 9 +- cmrc | 2 +- examples/dev_testing/src/main.cpp | 123 +++++++++---------- include/simpleengine/gfx/model.h | 2 +- include/simpleengine/gfx/texture.h | 32 ++++- resources/shaders/core/3d/fragment_core.glsl | 7 +- src/gfx/model.cpp | 10 +- src/gfx/renderer.cpp | 17 +-- src/gfx/texture.cpp | 49 ++++++-- 11 files changed, 198 insertions(+), 103 deletions(-) create mode 100644 .clang-tidy create mode 100644 CMake/Getassimp.cmake diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 0000000..66b1807 --- /dev/null +++ b/.clang-tidy @@ -0,0 +1,37 @@ +--- +Checks: 'clang-diagnostic-*,clang-analyzer-*,cppcoreguidelines-*,modernize-*,-modernize-use-trailing-return-type' +WarningsAsErrors: true +HeaderFilterRegex: '' +AnalyzeTemporaryDtors: false +FormatStyle: google +CheckOptions: + - key: cert-dcl16-c.NewSuffixes + value: 'L;LL;LU;LLU' + - key: cert-oop54-cpp.WarnOnlyIfThisHasSuspiciousField + value: '0' + - key: cppcoreguidelines-explicit-virtual-functions.IgnoreDestructors + value: '1' + - key: cppcoreguidelines-non-private-member-variables-in-classes.IgnoreClassesWithAllMemberVariablesBeingPublic + value: '1' + - key: google-readability-braces-around-statements.ShortStatementLines + value: '1' + - key: google-readability-function-size.StatementThreshold + value: '800' + - key: google-readability-namespace-comments.ShortNamespaceLines + value: '10' + - key: google-readability-namespace-comments.SpacesBeforeComments + value: '2' + - key: modernize-loop-convert.MaxCopySize + value: '16' + - key: modernize-loop-convert.MinConfidence + value: reasonable + - key: modernize-loop-convert.NamingStyle + value: CamelCase + - key: modernize-pass-by-value.IncludeStyle + value: llvm + - key: modernize-replace-auto-ptr.IncludeStyle + value: llvm + - key: modernize-use-nullptr.NullMacros + value: 'NULL' +... + diff --git a/CMake/Getassimp.cmake b/CMake/Getassimp.cmake new file mode 100644 index 0000000..7438198 --- /dev/null +++ b/CMake/Getassimp.cmake @@ -0,0 +1,13 @@ +include(ExternalProject) +ExternalProject_Add(external_assimp + GIT_REPOSITORY https://github.com/assimp/assimp.git + GIT_TAG v5.2.5 + GIT_SUBMODULES_RECURSE true + GIT_PROGRESS true + CMAKE_ARGS + -D CMAKE_INSTALL_PREFIX=${CMAKE_CURRENT_BINARY_DIR} + -D CMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + -D ASSIMP_INSTALL=NO + -D ASSIMP_BUILD_TESTS=NO +) +message("Downloaded assimp library") \ No newline at end of file diff --git a/CMakeLists.txt b/CMakeLists.txt index d30ac6b..500cdae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,7 +21,7 @@ find_package(GLEW REQUIRED) find_package(glfw3 CONFIG REQUIRED) find_package(glm CONFIG REQUIRED) find_package(OpenGL REQUIRED) -find_package(assimp REQUIRED) +find_package(assimp CONFIG REQUIRED) # Link sources file(GLOB_RECURSE source_list src/*.cpp) @@ -45,7 +45,12 @@ target_link_libraries(simpleengine PUBLIC GLEW::GLEW) target_link_libraries(simpleengine PUBLIC glfw) target_link_libraries(simpleengine PUBLIC ${GLM_LIBRARIES}) target_link_libraries(simpleengine PUBLIC ${OPENGL_LIBRARIES}) -target_link_libraries(simpleengine PUBLIC assimp) +if(WIN32) + target_link_libraries(simpleengine PUBLIC assimp::assimp) +else() + target_link_libraries(simpleengine PUBLIC assimp) +endif() + target_link_libraries(simpleengine PRIVATE simpleengine_resources) # Include some dependencies' include directories diff --git a/cmrc b/cmrc index e386a62..a64bea5 160000 --- a/cmrc +++ b/cmrc @@ -1 +1 @@ -Subproject commit e386a629eb537d384811e598a3c96b9ca928f65e +Subproject commit a64bea50c05594c8e7cf1f08e441bb9507742e2e diff --git a/examples/dev_testing/src/main.cpp b/examples/dev_testing/src/main.cpp index 240d593..15aaf60 100644 --- a/examples/dev_testing/src/main.cpp +++ b/examples/dev_testing/src/main.cpp @@ -1,8 +1,6 @@ #include "simpleengine/camera.h" #include "simpleengine/ecs/component/mesh_component.h" -#include #include "simpleengine/ecs/component/transform_component.h" -#include #include "simpleengine/ecs/entity.h" #include "simpleengine/gfx/light.h" #include "simpleengine/gfx/material.h" @@ -11,23 +9,25 @@ #include "simpleengine/gfx/renderer.h" #include "simpleengine/gfx/texture.h" #include "simpleengine/vector.h" -#include -#include +#include +#include #include -#include #include -#include -#include #include +#include +#include +#include #include +#include +#include +#include #include #include -#include -#include #include #include +#include #include #include @@ -46,14 +46,14 @@ public: frame_count = 0; } - virtual void update(const float& delta_time) { + virtual void update(const float &delta_time) { double current_time = glfwGetTime(); frame_count++; // Check if the last print was 1 second ago. if (current_time - last_frame_time >= 1.0) { - double ms_per_frame = 1000 / (double) frame_count; - + double ms_per_frame = 1000 / (double)frame_count; + printf("%d fps, %f ms/frame\n", frame_count, ms_per_frame); frame_count = 0; last_frame_time += 1.0; @@ -61,7 +61,7 @@ public: } }; -std::string read_resource_shader(const std::string& path) { +std::string read_resource_shader(const std::string &path) { auto fs = cmrc::resource_shaders::get_filesystem(); cmrc::file vertex_file = fs.open(path); @@ -79,14 +79,12 @@ int main(int argc, char *argv[]) { auto white_texture = se::gfx::Texture::white_texture(); // white_texture.shine_damper = 10; - //white_texture.reflectivity = 1; - /* auto dragon = std::make_shared(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/dragon.obj"); - dragon->translate(0.f, -5.f, -15.f); - game.add_event(dragon); */ + // white_texture.reflectivity = 1; + /* auto dragon = std::make_shared(game.get_window(), core_shader, white_texture, + "examples/dev_testing/resources/dragon.obj"); dragon->translate(0.f, -5.f, -15.f); game.add_event(dragon); */ - /* auto cube = std::make_shared(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/cube.obj"); - cube->translate(0.f, -5.f, -15.f); - game.add_event(cube); + /* auto cube = std::make_shared(game.get_window(), core_shader, white_texture, + "examples/dev_testing/resources/cube.obj"); cube->translate(0.f, -5.f, -15.f); game.add_event(cube); se::gfx::Texture grass("examples/dev_testing/resources/grass.png"); auto terrain = std::make_shared(game.get_window(), core_shader, grass, 0, 0); @@ -94,9 +92,8 @@ int main(int argc, char *argv[]) { game.add_event(terrain); */ /* se::gfx::Texture stall_texture("examples/dev_testing/resources/stallTextureb.png"); - auto stall = std::make_shared(game.get_window(), core_shader, stall_texture, "examples/dev_testing/resources/stall.obj"); - stall->translate(10.f, -5.f, 0.f); - stall->rotate_y(90.f); + auto stall = std::make_shared(game.get_window(), core_shader, stall_texture, + "examples/dev_testing/resources/stall.obj"); stall->translate(10.f, -5.f, 0.f); stall->rotate_y(90.f); game.add_event(stall); */ /* std::vector square_vertices = { @@ -118,9 +115,8 @@ int main(int argc, char *argv[]) { game.add_event(square); */ /* se::gfx::Texture white_texture("examples/dev_testing/resources/white_texture.png"); - auto cube = std::make_shared(game.get_window(), core_shader, white_texture, "examples/dev_testing/resources/cube.obj"); - cube->translate(-1.25f, 0.f, -1.f); - game.add_event(cube); */ + auto cube = std::make_shared(game.get_window(), core_shader, white_texture, + "examples/dev_testing/resources/cube.obj"); cube->translate(-1.25f, 0.f, -1.f); game.add_event(cube); */ /* std::vector tri_vertices = { { se::Vectorf(-0.5f, -0.5f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, // top right @@ -134,36 +130,30 @@ int main(int argc, char *argv[]) { game.add_event(tri); */ std::vector cube_vertices = { - { se::Vectorf(-1.f, -1.f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f) }, - { se::Vectorf(1.f, -1.f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f) }, - { se::Vectorf(1.f, 1.f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 0.f) }, - { se::Vectorf(-1.f, 1.f, -1.f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 0.f) }, - { se::Vectorf(-1, -1, -1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 0.f) }, + {se::Vectorf(-1.f, -1.f, -1.f), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 0.f)}, + {se::Vectorf(1.f, -1.f, -1.f), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 0.f)}, + {se::Vectorf(1.f, 1.f, -1.f), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 0.f)}, + {se::Vectorf(-1.f, 1.f, -1.f), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 0.f)}, + {se::Vectorf(-1, -1, -1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 0.f)}, - { se::Vectorf(-1, -1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 1.f) }, - { se::Vectorf(1, -1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 1.f) }, - { se::Vectorf(1, 1, 1), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 1.f) }, - { se::Vectorf(-1, 1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 1.f) }, - { se::Vectorf(-1, -1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 1.f) }, + {se::Vectorf(-1, -1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 1.f)}, + {se::Vectorf(1, -1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 1.f)}, + {se::Vectorf(1, 1, 1), glm::vec3(0.f, 0.f, 1.f), glm::vec2(2.f, 1.f)}, + {se::Vectorf(-1, 1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(3.f, 1.f)}, + {se::Vectorf(-1, -1, 1), glm::vec3(1.f, 1.f, 0.f), glm::vec2(4.f, 1.f)}, - { se::Vectorf(-1, 1, -1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, -1.f) }, - { se::Vectorf(1, 1, -1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, -1.f) }, + {se::Vectorf(-1, 1, -1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, -1.f)}, + {se::Vectorf(1, 1, -1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, -1.f)}, - { se::Vectorf(-1, 1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 2.f) }, - { se::Vectorf(1, 1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 2.f) }, + {se::Vectorf(-1, 1, 1), glm::vec3(1.f, 0.f, 0.f), glm::vec2(0.f, 2.f)}, + {se::Vectorf(1, 1, 1), glm::vec3(0.f, 1.f, 0.f), glm::vec2(1.f, 2.f)}, }; - std::vector cube_indicies = { - 0, 1, 5, 5, 1, 6, - 1, 2, 6, 6, 2, 7, - 2, 3, 7, 7, 3, 8, - 3, 4, 8, 8, 4, 9, - 10, 11, 0, 0, 11, 1, - 5, 6, 12, 12, 6, 13 - }; + std::vector cube_indicies = {0, 1, 5, 5, 1, 6, 1, 2, 6, 6, 2, 7, 2, 3, 7, 7, 3, 8, + 3, 4, 8, 8, 4, 9, 10, 11, 0, 0, 11, 1, 5, 6, 12, 12, 6, 13}; // Create a renderer - auto renderer = std::make_shared(game.get_window(), core_shader); + auto renderer = std::make_shared(game.get_window(), core_shader); game.add_renderable(renderer); // Create a Scene and give it the renderer @@ -172,26 +162,27 @@ int main(int argc, char *argv[]) { // Create an Entity in the Scene and add components to it. 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/dragon.obj"); + // entity.add_component("examples/dev_testing/resources/stall.obj"); + // Backpack model required vertically flipped texture coords. - /* auto& model_comp = entity.add_component("examples/dev_testing/resources/backpack/backpack.obj"); + /* 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/viper/viper.obj"); - entity.add_component("examples/dev_testing/resources/halot/chief.fbx"); + // entity.add_component("examples/dev_testing/resources/viper/viper.obj"); + // entity.add_component("examples/dev_testing/resources/halot/chief.fbx"); + entity.add_component("examples/dev_testing/resources/planks/planks.fbx"); - //entity.add_component("examples/dev_testing/resources/scientist/scientist.fbx"); - //entity.add_component("examples/dev_testing/resources/paradigm/paradigm.fbx"); - //entity.add_component(); - auto& transform_comp = entity.add_component(); + // entity.add_component("examples/dev_testing/resources/scientist/scientist.fbx"); + // entity.add_component("examples/dev_testing/resources/paradigm/paradigm.fbx"); + // entity.add_component(); + auto &transform_comp = entity.add_component(); transform_comp.translate(7.f, -4.f, 0.f); - transform_comp.scale(0.05f); - //transform_comp.rotate_z(-90.f); - transform_comp.rotate_y(-90.f); - transform_comp.rotate_x(-90.f); - + // transform_comp.scale(0.05f); + // transform_comp.rotate_z(-90.f); + // transform_comp.rotate_y(-90.f); + // transform_comp.rotate_x(-90.f); // Create the entity and add the model component to it. /* auto entity = std::make_shared(); @@ -212,10 +203,10 @@ int main(int argc, char *argv[]) { game.add_event(fps_counter); game.set_enable_vsync(true); - //game.set_fps_limit(120); + // game.set_fps_limit(120); int res = game.run(); renderer->destroy(); - + return res; } \ No newline at end of file diff --git a/include/simpleengine/gfx/model.h b/include/simpleengine/gfx/model.h index a49773d..db36ef4 100644 --- a/include/simpleengine/gfx/model.h +++ b/include/simpleengine/gfx/model.h @@ -38,7 +38,7 @@ namespace simpleengine::gfx { gfx::Mesh process_mesh(std::unordered_map>>& processed_textures, aiMesh* mesh, const aiScene* scene); std::unordered_map> load_all_textures(aiMaterial* material); - std::vector> load_material_texture(std::unordered_map>>& processed_textures, aiMaterial* material, aiTextureType type); + std::vector> load_material_texture(std::unordered_map>>& processed_textures, aiMaterial* material, aiTextureType type, TextureFlags texture_color); protected: void post_process(); diff --git a/include/simpleengine/gfx/texture.h b/include/simpleengine/gfx/texture.h index 302f14b..32bffab 100644 --- a/include/simpleengine/gfx/texture.h +++ b/include/simpleengine/gfx/texture.h @@ -23,6 +23,9 @@ namespace simpleengine::gfx { TexFlags_FLIP_VERTICALLY = 0b00000010, TexFlags_FLIP_HORIZONTALLY = 0b00000100, TexFlags_MIPMAP = 0b00001000, + TexFlags_NO_COLOR = 0b00010000, + TexFlags_RGB = 0b00100000, + TexFlags_RGBA = 0b01000000, }; class Texture { @@ -34,6 +37,26 @@ namespace simpleengine::gfx { Texture() = default; public: + /** + * @brief The default Texture flags not including the color. + * + * The default flags are `TexFlags_IMG_2D | TexFlags_MIPMAP` + * + * @see simpleengine::gfx::Texture::default_flags + * + */ + static constexpr int default_flags_no_color = TexFlags_IMG_2D | TexFlags_MIPMAP; + + /** + * @brief The default Texture flags including the color. + * + * The default flags are `TexFlags_IMG_2D | TexFlags_MIPMAP | TexFlags_RGBA` + * + * @see simpleengine::gfx::Texture::default_flags_no_color + * + */ + static constexpr int default_flags = default_flags_no_color | TexFlags_RGBA; + int height; int width; int channels; @@ -47,8 +70,7 @@ 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, int flags = TextureFlags::TexFlags_IMG_2D | - TextureFlags::TexFlags_MIPMAP); + Texture(const char* path, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = Texture::default_flags); /** * @brief Construct a new Texture object from the loaded file buffer. @@ -58,8 +80,7 @@ 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, int flags = TextureFlags::TexFlags_IMG_2D | - TextureFlags::TexFlags_MIPMAP); + Texture(const unsigned char *const buffer, int buffer_length, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = Texture::default_flags); /** * @brief Construct a new Texture object from the loaded file buffer. @@ -68,8 +89,7 @@ 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, int flags = TextureFlags::TexFlags_IMG_2D | - TextureFlags::TexFlags_MIPMAP); + Texture(std::vector buffer, aiTextureType type = aiTextureType::aiTextureType_DIFFUSE, int flags = Texture::default_flags); static Texture white_texture(); diff --git a/resources/shaders/core/3d/fragment_core.glsl b/resources/shaders/core/3d/fragment_core.glsl index add12b2..d93f7df 100644 --- a/resources/shaders/core/3d/fragment_core.glsl +++ b/resources/shaders/core/3d/fragment_core.glsl @@ -17,6 +17,8 @@ const int SAMP_SPECULAR = 1; struct Material { sampler2D diffuse; + + bool has_specular_map; sampler2D specular_map; float ambient_strength; @@ -63,7 +65,10 @@ vec3 calculate_lighting() { float spec = pow(max(dot(view_dir, reflect_dir), -0.f), 32 * u_material.shine_factor); vec3 specular = specular_strength * (spec * u_material.specular_strength) * u_light_color; - //specular = specular * vec3(texture(u_material.specular_map, vs_texcoord)); // TODO check if its set before applying it. + // Check if the specular map is set before trying to set it + if (u_material.has_specular_map) { + specular = specular * texture(u_material.specular_map, vs_texcoord).r; + } return ambient + diffuse + specular; } \ No newline at end of file diff --git a/src/gfx/model.cpp b/src/gfx/model.cpp index ae7beb9..718e23a 100644 --- a/src/gfx/model.cpp +++ b/src/gfx/model.cpp @@ -111,17 +111,17 @@ namespace simpleengine::gfx { // Load Diffuse texture maps aiTextureType loading_type = aiTextureType_DIFFUSE; - std::vector> diffuse_maps = load_material_texture(processed_textures, material, loading_type); + std::vector> diffuse_maps = load_material_texture(processed_textures, material, loading_type, TextureFlags::TexFlags_RGBA); if (!diffuse_maps.empty()) textures.emplace(loading_type, diffuse_maps); // Load specular texture maps loading_type = aiTextureType_SPECULAR; - std::vector> spec_maps = load_material_texture(processed_textures, material, loading_type); + std::vector> spec_maps = load_material_texture(processed_textures, material, loading_type, TextureFlags::TexFlags_NO_COLOR); if (!spec_maps.empty()) textures.emplace(loading_type, spec_maps); // Load normals texture maps loading_type = aiTextureType_NORMALS; - std::vector> normal_maps = load_material_texture(processed_textures, material, loading_type); + std::vector> normal_maps = load_material_texture(processed_textures, material, loading_type, TextureFlags::TexFlags_NO_COLOR); if (!normal_maps.empty()) textures.emplace(loading_type, normal_maps); // TODO Handle other types of texture maps @@ -170,7 +170,7 @@ namespace simpleengine::gfx { return {}; } - std::vector> Model::load_material_texture(std::unordered_map>>& processed_textures, aiMaterial* material, aiTextureType type) { + std::vector> Model::load_material_texture(std::unordered_map>>& processed_textures, aiMaterial* material, aiTextureType type, TextureFlags texture_color) { std::vector> textures; for (int i = 0; i < material->GetTextureCount(type); i++) { @@ -197,7 +197,7 @@ namespace simpleengine::gfx { ss << model_directory << "/" << texture_path; std::string full_path = ss.str(); - Texture texture(full_path.c_str(), type, TextureFlags::TexFlags_IMG_2D | TextureFlags::TexFlags_MIPMAP); + Texture texture(full_path.c_str(), type, Texture::default_flags_no_color | texture_color); texture.path = texture_path; textures.emplace_back(std::make_shared(texture)); diff --git a/src/gfx/renderer.cpp b/src/gfx/renderer.cpp index 826ed7d..6377cfa 100644 --- a/src/gfx/renderer.cpp +++ b/src/gfx/renderer.cpp @@ -112,28 +112,19 @@ namespace simpleengine::gfx { glActiveTexture(GL_TEXTURE0); diffuse_map->bind(); + // Apply the specular map if it exists auto specular_maps = material->textures.find(aiTextureType_SPECULAR); - - if (specular_maps != material->textures.end()) { auto spec = specular_maps->second.front(); + shader.set_uniform_int("u_material.has_specular_map", 1, false); shader.set_uniform_int("u_material.specular_map", 1, false); glActiveTexture(GL_TEXTURE1); spec->bind(); + } else { + shader.set_uniform_int("u_material.has_specular_map", 0, false); } - - //diffuse_map - /* for (const auto& texture : diffuse_maps->second) { - // We can only bind to 16 textures at a time (indexes are 0-15) - if (texture_count >= 16) break; - - glActiveTexture(GL_TEXTURE0 + texture_count); - glBindTextureUnit(texture_count, texture->get_texture_id()); - - texture_count++; - } */ } mesh.vao.bind(); diff --git a/src/gfx/texture.cpp b/src/gfx/texture.cpp index ad0bede..4e2fc3d 100644 --- a/src/gfx/texture.cpp +++ b/src/gfx/texture.cpp @@ -1,4 +1,5 @@ #include "gfx/texture.h" +#include #define STB_IMAGE_IMPLEMENTATION #include @@ -9,6 +10,24 @@ namespace simpleengine::gfx { bool flip_vertically = flags & TextureFlags::TexFlags_FLIP_VERTICALLY; bool mipmap = flags & TextureFlags::TexFlags_MIPMAP; + // Get the color channel type for opengl, and get + // the channel count for loading the texture with stb_image + int gl_color_channels; + int channel_count; + if (flags & TexFlags_RGBA) { + channel_count = 4; + gl_color_channels = GL_RGBA; + } else if (flags & TexFlags_RGB) { + channel_count = 3; + gl_color_channels = GL_RGB; + } else if (flags & TexFlags_NO_COLOR) { + channel_count = 1; + gl_color_channels = GL_RED; + } else { + std::cerr << "Texture color flag is missing!! Specify TexFlags_RGBA" << std::endl; + throw std::runtime_error("Texture color flag is missing!! Specify TexFlags_RGBA"); + } + image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D; glGenTextures(1, &texture_id); @@ -23,8 +42,7 @@ namespace simpleengine::gfx { stbi_set_flip_vertically_on_load(flip_vertically); - // Read 4 channels (RGBA) - img_data = stbi_load(path, &width, &height, &channels, 4); + img_data = stbi_load(path, &width, &height, &channels, channel_count); if(!img_data) { const char* failure = stbi_failure_reason(); std::cerr << "Failed to load texture! (" << failure << ")" << std::endl; @@ -32,7 +50,7 @@ namespace simpleengine::gfx { } std::cout << "Loaded image with a width of " << width << "px, a height of " << height << "px and " << channels << " channels" << std::endl; - glTexImage2D(image_type_gl, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data); + glTexImage2D(image_type_gl, 0, gl_color_channels, width, height, 0, gl_color_channels, GL_UNSIGNED_BYTE, img_data); if (mipmap) { glGenerateMipmap(image_type_gl); @@ -48,6 +66,24 @@ namespace simpleengine::gfx { bool flip_vertically = flags & TextureFlags::TexFlags_FLIP_VERTICALLY; bool mipmap = flags & TextureFlags::TexFlags_MIPMAP; + // Get the color channel type for opengl, and get + // the channel count for loading the texture with stb_image + int gl_color_channels; + int channel_count; + if (flags & TexFlags_RGBA) { + channel_count = 4; + gl_color_channels = GL_RGBA; + } else if (flags & TexFlags_RGB) { + channel_count = 3; + gl_color_channels = GL_RGB; + } else if (flags & TexFlags_NO_COLOR) { + channel_count = 1; + gl_color_channels = GL_RED; + } else { + std::cerr << "Texture color flag is missing!! Specify TexFlags_RGBA" << std::endl; + throw std::runtime_error("Texture color flag is missing!! Specify TexFlags_RGBA"); + } + image_type_gl = img_2d ? GL_TEXTURE_2D : GL_TEXTURE_3D; glGenTextures(1, &texture_id); @@ -62,8 +98,7 @@ namespace simpleengine::gfx { stbi_set_flip_vertically_on_load(flip_vertically); - // Read 4 channels (RGBA) - img_data = stbi_load_from_memory(buffer, buffer_length, &width, &height, &channels, 4); + img_data = stbi_load_from_memory(buffer, buffer_length, &width, &height, &channels, channel_count); if(!img_data) { const char* failure = stbi_failure_reason(); std::cerr << "Failed to load texture! (" << failure << ")" << std::endl; @@ -71,7 +106,7 @@ namespace simpleengine::gfx { } std::cout << "Loaded image with a width of " << width << "px, a height of " << height << "px and " << channels << " channels" << std::endl; - glTexImage2D(image_type_gl, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, img_data); + glTexImage2D(image_type_gl, 0, gl_color_channels, width, height, 0, gl_color_channels, GL_UNSIGNED_BYTE, img_data); if (mipmap) { glGenerateMipmap(image_type_gl); @@ -117,8 +152,6 @@ namespace simpleengine::gfx { texture.unbind(); - - return texture; }