diff --git a/include/util/gen_tangents.h b/include/util/gen_tangents.h index 7b9637e..529fc23 100644 --- a/include/util/gen_tangents.h +++ b/include/util/gen_tangents.h @@ -1 +1,23 @@ -#pragma once \ No newline at end of file +#pragma once + +#include // uint32_t + +#include + +namespace engine { +struct Vertex; // resources/mesh.h +} + +namespace engine::util { + +/* + * Generate tangents for a given list of vertices. + * The provided vertices must be in proper order. + * Parameters: + * vertices (in/out) - vertices to modify with generated tangents (size can change) + * Returns: + * index list for the provided vertices + */ +std::vector GenTangents(std::vector& vertices); + +} // namespace engine::util \ No newline at end of file diff --git a/res/engine/shaders/fancy.frag b/res/engine/shaders/fancy.frag index 74f9785..2f1adef 100644 --- a/res/engine/shaders/fancy.frag +++ b/res/engine/shaders/fancy.frag @@ -119,7 +119,7 @@ void main() { lighting *= (1.0 - shadow); const vec3 ambient_light = vec3(0.09082, 0.13281, 0.18164) * 2.4 * 0.1; - //lighting += mix(ambient_light, texture(globalSetSkybox, R).rgb, metallic) * ao * diffuse_brdf; // this is NOT physically-based, it just looks cool + lighting += mix(ambient_light, texture(globalSetSkybox, R).rgb, metallic) * ao * diffuse_brdf; // this is NOT physically-based, it just looks cool lighting += (ambient_light * ao * diffuse_brdf); // tone mapping diff --git a/src/application.cpp b/src/application.cpp index f1b4b30..f0ea6af 100644 --- a/src/application.cpp +++ b/src/application.cpp @@ -333,7 +333,7 @@ void Application::GameLoop() if (ImGui::Button("Load glTF")) { #ifdef _WIN32 std::string path = std::filesystem::path(openGLTFDialog()).string(); - + LOG_ERROR("Not yet implemented!"); #endif } #ifndef _WIN32 diff --git a/src/util/gen_tangents.cpp b/src/util/gen_tangents.cpp index 0d00346..278a208 100644 --- a/src/util/gen_tangents.cpp +++ b/src/util/gen_tangents.cpp @@ -1 +1,81 @@ -#include "util/gen_tangents.h" \ No newline at end of file +#include "util/gen_tangents.h" + +#include + +#include "libs/mikktspace.h" +#include "libs/weldmesh.h" + +#include "resources/mesh.h" + +namespace engine::util { + +std::vector engine::util::GenTangents(std::vector& vertices) +{ + + using VertList = std::vector; + + SMikkTSpaceInterface mts_interface{}; + mts_interface.m_getNumFaces = [](const SMikkTSpaceContext* pContext) -> int { + auto vertices = static_cast(pContext->m_pUserData); + return static_cast(vertices->size() / 3); + }; + mts_interface.m_getNumVerticesOfFace = [](const SMikkTSpaceContext*, const int) -> int { return 3; }; + mts_interface.m_getPosition = [](const SMikkTSpaceContext* pContext, float fvPosOut[], const int iFace, const int iVert) -> void { + auto vertices = static_cast(pContext->m_pUserData); + const size_t i = static_cast(iFace) * 3 + static_cast(iVert); + const glm::vec3 pos = vertices->operator[](i).pos; + fvPosOut[0] = pos.x; + fvPosOut[1] = pos.y; + fvPosOut[2] = pos.z; + }; + mts_interface.m_getNormal = [](const SMikkTSpaceContext* pContext, float fvNormOut[], const int iFace, const int iVert) -> void { + auto vertices = static_cast(pContext->m_pUserData); + const size_t i = static_cast(iFace) * 3 + static_cast(iVert); + const glm::vec3 norm = vertices->operator[](i).norm; + fvNormOut[0] = norm.x; + fvNormOut[1] = norm.y; + fvNormOut[2] = norm.z; + }; + mts_interface.m_getTexCoord = [](const SMikkTSpaceContext* pContext, float fvTexcOut[], const int iFace, const int iVert) -> void { + auto vertices = static_cast(pContext->m_pUserData); + const size_t i = static_cast(iFace) * 3 + static_cast(iVert); + const glm::vec2 uv = vertices->operator[](i).uv; + fvTexcOut[0] = uv.x; + fvTexcOut[1] = uv.y; + }; + mts_interface.m_setTSpaceBasic = [](const SMikkTSpaceContext* pContext, const float fvTangent[], const float fSign, const int iFace, + const int iVert) -> void { + auto vertices = static_cast(pContext->m_pUserData); + const size_t i = static_cast(iFace) * 3 + static_cast(iVert); + vertices->operator[](i).tangent.x = fvTangent[0]; + vertices->operator[](i).tangent.y = fvTangent[1]; + vertices->operator[](i).tangent.z = fvTangent[2]; + vertices->operator[](i).tangent.w = fSign; + }; + SMikkTSpaceContext mts_context{}; + mts_context.m_pInterface = &mts_interface; + mts_context.m_pUserData = &vertices; + + bool tan_result = genTangSpaceDefault(&mts_context); + if (tan_result == false) throw std::runtime_error("Failed to generate tangents!"); + + // generate new vertex and index list without duplicates: + + std::vector remap_table(vertices.size()); // initialised to zeros + std::vector vertex_data_out(vertices.size()); // initialised to zeros + + const int new_vertex_count = WeldMesh(reinterpret_cast(remap_table.data()), reinterpret_cast(vertex_data_out.data()), reinterpret_cast(vertices.data()), + static_cast(vertices.size()), Vertex::FloatsPerVertex()); + assert(new_vertex_count >= 0); + + // get new vertices into the vector. + // This potentially modifies the size of the input 'vector' argument + vertices.resize(static_cast(new_vertex_count)); + for (size_t i = 0; i < static_cast(new_vertex_count); ++i) { + vertices[i] = vertex_data_out[i]; + } + + return remap_table; +} + +} // namespace engine::util \ No newline at end of file diff --git a/test/res/models/box.glb b/test/res/models/box.glb new file mode 100644 index 0000000..7b7b8db Binary files /dev/null and b/test/res/models/box.glb differ diff --git a/test/src/game.cpp b/test/src/game.cpp index 4fb9e27..1977e17 100644 --- a/test/src/game.cpp +++ b/test/src/game.cpp @@ -81,8 +81,8 @@ void PlayGame(GameSettings settings) engine::Entity camera_child = main_scene->CreateEntity("camera_child", camera, glm::vec3{0.0f, 0.0f, -3.0f}); main_scene->GetTransform(camera_child)->is_static = false; auto camren = main_scene->AddComponent(camera_child); - camren->visible = true; - camren->mesh = GenSphereMesh(app.renderer()->GetDevice(), 1.0f, 16); + camren->visible = false; + camren->mesh = GenSphereMesh(app.renderer()->GetDevice(), 1.0f, /*16*/32); camren->material = app.GetResource("builtin.default"); /* as of right now, the entity with tag 'camera' is used to build the view @@ -155,6 +155,12 @@ void PlayGame(GameSettings settings) engine::Entity tree = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/tree.glb"), true); main_scene->GetPosition(tree) = glm::vec3{-5.0f, -5.0f, 0.0f}; + + engine::Entity box = engine::util::LoadGLTF(*main_scene, app.GetResourcePath("models/box.glb"), true); + main_scene->GetPosition(box) = glm::vec3{ -5.0f, -17.0f, 0.1f }; + main_scene->GetScale(box) *= 10.0f; + main_scene->GetRotation(box) = glm::angleAxis(glm::pi(), glm::vec3{ 0.0f, 0.0f, 1.0f }); + main_scene->GetRotation(box) *= glm::angleAxis(glm::half_pi(), glm::vec3{ 1.0f, 0.0f, 0.0f }); } start_scene->GetSystem()->next_scene_ = main_scene; diff --git a/test/src/meshgen.cpp b/test/src/meshgen.cpp index ebabcb4..2ff2997 100644 --- a/test/src/meshgen.cpp +++ b/test/src/meshgen.cpp @@ -7,6 +7,7 @@ #include #include "resources/mesh.h" +#include "util/gen_tangents.h" std::unique_ptr GenSphereMesh(engine::GFXDevice* gfx, float r, int detail, bool wind_inside, bool flip_normals) { @@ -72,7 +73,9 @@ std::unique_ptr GenSphereMesh(engine::GFXDevice* gfx, float r, int } } - return std::make_unique(gfx, vertices); + std::vector indices = engine::util::GenTangents(vertices); + + return std::make_unique(gfx, vertices, indices); } std::unique_ptr GenCuboidMesh(engine::GFXDevice* gfx, float x, float y, float z, float tiling, bool wind_inside) @@ -83,56 +86,58 @@ std::unique_ptr GenCuboidMesh(engine::GFXDevice* gfx, float x, flo using namespace glm; - std::vector v{}; + std::vector vertices{}; // front - v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{0.0f, 0.0f, z}, {0.0f, -1.0f, 0.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); // back - v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, y, 0.0f}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{x, y, z}, {0.0f, 1.0f, 0.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); // left - v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, 0.0f, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, y, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, 0.0f, 0.0f}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, 0.0f, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{0.0f, y, z}, {-1.0f, 0.0f, 0.0f}, {0.0f, -1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); // right - v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, y, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, 0.0f, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, y, 0.0f}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, y, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{x, 0.0f, z}, {1.0f, 0.0f, 0.0f}, {0.0f, 1.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); // top - v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{0.0f, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{x, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{0.0f, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, 0.0f, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{x, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{0.0f, y, z}, {0.0f, 0.0f, 1.0f}, {1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); // bottom - v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); - v.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); - v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); - v.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); - v.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); + vertices.push_back({{x, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, tiling}}); + vertices.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, 0.0f, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, tiling}}); + vertices.push_back({{0.0f, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {tiling, 0.0f}}); + vertices.push_back({{x, y, 0.0f}, {0.0f, 0.0f, -1.0f}, {-1.0f, 0.0f, 0.0f, 1.0f}, {0.0f, 0.0f}}); if (wind_inside) { - for (size_t i = 0; i < v.size(); i += 3) { - std::swap(v[i], v[i + 2]); + for (size_t i = 0; i < vertices.size(); i += 3) { + std::swap(vertices[i], vertices[i + 2]); } } - return std::make_unique(gfx, v); + std::vector indices = engine::util::GenTangents(vertices); + + return std::make_unique(gfx, vertices, indices); }