diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index 97fd39515290ac9235b3936d44d3e40a584ef84f..671fd4209fbbc1d793e832af472381f471c6316e 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -3,6 +3,7 @@ #include <string.h> // memcpy(3) #include <stdlib.h> // calloc(3) #include <fx/gltf.h> +#include <vulkan/vulkan.hpp> #define STB_IMAGE_IMPLEMENTATION #define STBI_ONLY_JPEG #define STBI_ONLY_PNG @@ -123,6 +124,67 @@ bool materialHasTexture(const Material *const m, const PBRTextureTarget t) return m->textureMask & bitflag(t); } +int translateSamplerMode(const fx::gltf::Sampler::WrappingMode mode) +{ + switch (mode) { + case fx::gltf::Sampler::WrappingMode::ClampToEdge: + return VK_SAMPLER_ADDRESS_MODE_CLAMP_TO_EDGE; + case fx::gltf::Sampler::WrappingMode::MirroredRepeat: + return VK_SAMPLER_ADDRESS_MODE_MIRRORED_REPEAT; + case fx::gltf::Sampler::WrappingMode::Repeat: + default: + return VK_SAMPLER_ADDRESS_MODE_REPEAT; + } +} + +int translateSampler(const fx::gltf::Sampler &src, vkcv::asset::Sampler &dst) +{ + dst.minLOD = 0; + dst.maxLOD = VK_LOD_CLAMP_NONE; + + switch (src.minFilter) { + case fx::gltf::Sampler::MinFilter::None: + case fx::gltf::Sampler::MinFilter::Nearest: + dst.minFilter = VK_FILTER_NEAREST; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + dst.maxLOD = 0.25; + case fx::gltf::Sampler::MinFilter::Linear: + dst.minFilter = VK_FILTER_LINEAR; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + dst.maxLOD = 0.25; + case fx::gltf::Sampler::MinFilter::NearestMipMapNearest: + dst.minFilter = VK_FILTER_NEAREST; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + case fx::gltf::Sampler::MinFilter::LinearMipMapNearest: + dst.minFilter = VK_FILTER_LINEAR; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_NEAREST; + case fx::gltf::Sampler::MinFilter::NearestMipMapLinear: + dst.minFilter = VK_FILTER_NEAREST; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + case fx::gltf::Sampler::MinFilter::LinearMipMapLinear: + dst.minFilter = VK_FILTER_LINEAR; + dst.mipmapMode = VK_SAMPLER_MIPMAP_MODE_LINEAR; + } + + switch (src.magFilter) { + case fx::gltf::Sampler::MagFilter::None: + case fx::gltf::Sampler::MagFilter::Nearest: + dst.magFilter = VK_FILTER_NEAREST; + case fx::gltf::Sampler::MagFilter::Linear: + dst.magFilter = VK_FILTER_LINEAR; + } + + dst.addressModeU = translateSamplerMode(src.wrapS); + dst.addressModeV = translateSamplerMode(src.wrapT); + // XXX What's a good heuristic for W? + if (src.wrapS == src.wrapT) + dst.addressModeW = dst.addressModeU; + else + dst.addressModeW = VK_SAMPLER_ADDRESS_MODE_REPEAT; + + return 1; // TODO return vkcv::success +} + int loadScene(const std::string &path, Scene &scene){ fx::gltf::Document sceneObjects; @@ -221,8 +283,8 @@ int loadScene(const std::string &path, Scene &scene){ } } - const fx::gltf::BufferView& vertexBufferView = sceneObjects.bufferViews[posAccessor.bufferView]; - const fx::gltf::Buffer& vertexBuffer = sceneObjects.buffers[vertexBufferView.buffer]; + const fx::gltf::BufferView& vertexBufferView = sceneObjects.bufferViews[posAccessor.bufferView]; + const fx::gltf::Buffer& vertexBuffer = sceneObjects.buffers[vertexBufferView.buffer]; // only copy relevant part of vertex data uint32_t relevantBufferOffset = std::numeric_limits<uint32_t>::max(); @@ -307,7 +369,7 @@ int loadScene(const std::string &path, Scene &scene){ free(data); textures.push_back({ - 0, + tex.sampler, static_cast<uint8_t>(c), static_cast<uint16_t>(w), static_cast<uint16_t>(h), @@ -350,11 +412,18 @@ int loadScene(const std::string &path, Scene &scene){ material.emissiveFactor[1], material.emissiveFactor[2] } - }); } } + samplers.reserve(sceneObjects.samplers.size()); + for (const auto &it : sceneObjects.samplers) { + samplers.push_back({}); + auto &sampler = samplers.back(); + if (translateSampler(it, sampler) != 1) // TODO use vkcv::success + return 0; // TODO use vkcv::error + } + scene = { meshes, vertexGroups,