Formalize renderer material contracts and harden backpack import
This commit is contained in:
@@ -15,6 +15,13 @@
|
||||
#include <fstream>
|
||||
#include <thread>
|
||||
|
||||
#ifdef _WIN32
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
using namespace XCEngine::Resources;
|
||||
using namespace XCEngine::Containers;
|
||||
|
||||
@@ -24,6 +31,10 @@ std::string GetMeshFixturePath(const char* fileName) {
|
||||
return (std::filesystem::path(XCENGINE_TEST_FIXTURES_DIR) / "Resources" / "Mesh" / fileName).string();
|
||||
}
|
||||
|
||||
std::filesystem::path GetRepositoryRoot() {
|
||||
return std::filesystem::path(__FILE__).parent_path().parent_path().parent_path().parent_path();
|
||||
}
|
||||
|
||||
XCEngine::Core::uint32 GetFirstSectionMaterialIndex(const Mesh& mesh) {
|
||||
if (mesh.GetSections().Empty()) {
|
||||
return 0;
|
||||
@@ -202,6 +213,119 @@ TEST(MeshLoader, ImportsMaterialTexturesFromObj) {
|
||||
delete mesh;
|
||||
}
|
||||
|
||||
TEST(MeshLoader, ProjectBackpackSampleImportsMaterialTextures) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path repositoryRoot = GetRepositoryRoot();
|
||||
const fs::path projectRoot = repositoryRoot / "project";
|
||||
const fs::path backpackMeshPath = projectRoot / "Assets" / "Models" / "backpack" / "backpack.obj";
|
||||
const fs::path assimpDllPath = repositoryRoot / "engine" / "third_party" / "assimp" / "bin" / "assimp-vc143-mt.dll";
|
||||
|
||||
if (!fs::exists(backpackMeshPath)) {
|
||||
GTEST_SKIP() << "Backpack sample mesh is not available in the local project fixture.";
|
||||
}
|
||||
|
||||
ASSERT_TRUE(fs::exists(assimpDllPath));
|
||||
|
||||
#ifdef _WIN32
|
||||
struct DllGuard {
|
||||
HMODULE module = nullptr;
|
||||
~DllGuard() {
|
||||
if (module != nullptr) {
|
||||
FreeLibrary(module);
|
||||
}
|
||||
}
|
||||
} dllGuard;
|
||||
dllGuard.module = LoadLibraryW(assimpDllPath.wstring().c_str());
|
||||
ASSERT_NE(dllGuard.module, nullptr);
|
||||
#endif
|
||||
|
||||
ResourceManager& manager = ResourceManager::Get();
|
||||
manager.Initialize();
|
||||
manager.SetResourceRoot(projectRoot.string().c_str());
|
||||
|
||||
MeshLoader loader;
|
||||
const LoadResult result = loader.Load(backpackMeshPath.string().c_str());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
auto* mesh = static_cast<Mesh*>(result.resource);
|
||||
ASSERT_NE(mesh, nullptr);
|
||||
ASSERT_FALSE(mesh->GetMaterials().Empty());
|
||||
|
||||
Material* material = GetFirstSectionMaterial(*mesh);
|
||||
ASSERT_NE(material, nullptr);
|
||||
EXPECT_EQ(material->GetTextureBindingCount(), 1u);
|
||||
EXPECT_EQ(material->GetTextureBindingName(0), "_MainTex");
|
||||
EXPECT_EQ(
|
||||
fs::path(material->GetTextureBindingPath(0).CStr()).lexically_normal().generic_string(),
|
||||
(projectRoot / "Assets" / "Models" / "backpack" / "diffuse.jpg").lexically_normal().generic_string());
|
||||
|
||||
delete mesh;
|
||||
manager.SetResourceRoot("");
|
||||
manager.Shutdown();
|
||||
}
|
||||
|
||||
TEST(MeshLoader, ProjectBackpackSampleArtifactRetainsSectionMaterialTextures) {
|
||||
namespace fs = std::filesystem;
|
||||
|
||||
const fs::path repositoryRoot = GetRepositoryRoot();
|
||||
const fs::path projectRoot = repositoryRoot / "project";
|
||||
const fs::path backpackMeshPath = projectRoot / "Assets" / "Models" / "backpack" / "backpack.obj";
|
||||
const fs::path assimpDllPath = repositoryRoot / "engine" / "third_party" / "assimp" / "bin" / "assimp-vc143-mt.dll";
|
||||
|
||||
if (!fs::exists(backpackMeshPath)) {
|
||||
GTEST_SKIP() << "Backpack sample mesh is not available in the local project fixture.";
|
||||
}
|
||||
|
||||
ASSERT_TRUE(fs::exists(assimpDllPath));
|
||||
|
||||
#ifdef _WIN32
|
||||
struct DllGuard {
|
||||
HMODULE module = nullptr;
|
||||
~DllGuard() {
|
||||
if (module != nullptr) {
|
||||
FreeLibrary(module);
|
||||
}
|
||||
}
|
||||
} dllGuard;
|
||||
dllGuard.module = LoadLibraryW(assimpDllPath.wstring().c_str());
|
||||
ASSERT_NE(dllGuard.module, nullptr);
|
||||
#endif
|
||||
|
||||
ResourceManager& manager = ResourceManager::Get();
|
||||
manager.Initialize();
|
||||
manager.SetResourceRoot(projectRoot.string().c_str());
|
||||
|
||||
AssetDatabase database;
|
||||
database.Initialize(projectRoot.string().c_str());
|
||||
|
||||
AssetDatabase::ResolvedAsset resolvedAsset;
|
||||
ASSERT_TRUE(database.EnsureArtifact("Assets/Models/backpack/backpack.obj", ResourceType::Mesh, resolvedAsset));
|
||||
ASSERT_TRUE(resolvedAsset.artifactReady);
|
||||
|
||||
MeshLoader loader;
|
||||
const LoadResult result = loader.Load(resolvedAsset.artifactMainPath.CStr());
|
||||
ASSERT_TRUE(result);
|
||||
ASSERT_NE(result.resource, nullptr);
|
||||
|
||||
auto* mesh = static_cast<Mesh*>(result.resource);
|
||||
ASSERT_NE(mesh, nullptr);
|
||||
ASSERT_FALSE(mesh->GetSections().Empty());
|
||||
ASSERT_FALSE(mesh->GetMaterials().Empty());
|
||||
|
||||
Material* sectionMaterial = GetFirstSectionMaterial(*mesh);
|
||||
ASSERT_NE(sectionMaterial, nullptr);
|
||||
EXPECT_EQ(sectionMaterial->GetTextureBindingCount(), 1u);
|
||||
EXPECT_EQ(sectionMaterial->GetTextureBindingName(0), "_MainTex");
|
||||
EXPECT_FALSE(sectionMaterial->GetTextureBindingPath(0).Empty());
|
||||
|
||||
delete mesh;
|
||||
database.Shutdown();
|
||||
manager.SetResourceRoot("");
|
||||
manager.Shutdown();
|
||||
}
|
||||
|
||||
TEST(MeshLoader, AssetDatabaseCreatesModelArtifactAndReusesItWithoutReimport) {
|
||||
namespace fs = std::filesystem;
|
||||
using namespace std::chrono_literals;
|
||||
|
||||
Reference in New Issue
Block a user