
.. _program_listing_file_Src_GraphicsEngineVulkan_scene_ObjLoader.ixx:

Program Listing for File ObjLoader.ixx
======================================

|exhale_lsh| :ref:`Return to documentation for file <file_Src_GraphicsEngineVulkan_scene_ObjLoader.ixx>` (``Src/GraphicsEngineVulkan/scene/ObjLoader.ixx``)

.. |exhale_lsh| unicode:: U+021B0 .. UPWARDS ARROW WITH TIP LEFTWARDS

.. code-block:: cpp

   module;
   #include <tiny_obj_loader.h>
   #include <memory>
   #include <string>
   #include <vector>
   #include <vulkan/vulkan.hpp>
   
   export module kataglyphis.vulkan.obj_loader;
   
   import kataglyphis.vulkan.obj_material;
   import kataglyphis.vulkan.vertex;
   import kataglyphis.vulkan.model;
   import kataglyphis.vulkan.device;
   // Re-exported: MeshRange appears in getMeshRanges()'s return type, so consumers
   // (and the parse tests) that import this module see it without a second import.
   export import kataglyphis.vulkan.mesh_range;
   
   export namespace Kataglyphis {
   
   std::string resolveObjTexturePath(const std::string &baseDir, const std::string &mapKd);
   
   class ObjLoader
   {
     public:
       ObjLoader(const std::shared_ptr<VulkanDevice> &device, vk::CommandPool command_pool);
   
       ObjLoader() = default;
   
       std::shared_ptr<Model> loadModel(const std::string &modelFile);
   
       bool parseCpu(const std::string &modelFile);
   
       std::shared_ptr<Model> uploadParsed();
   
       void adoptParsed(ObjLoader &&other)
       {
           vertices = std::move(other.vertices);
           indices = std::move(other.indices);
           materials = std::move(other.materials);
           materialIndex = std::move(other.materialIndex);
           textures = std::move(other.textures);
           textureSrgb = std::move(other.textureSrgb);
           meshRanges = std::move(other.meshRanges);
       }
   
       const std::vector<Vertex> &getVertices() const { return vertices; }
       const std::vector<unsigned int> &getIndices() const { return indices; }
       const std::vector<ObjMaterial> &getMaterials() const { return materials; }
       const std::vector<unsigned int> &getMaterialIndices() const { return materialIndex; }
       const std::vector<std::string> &getTextureNames() const { return textures; }
       const std::vector<unsigned char> &getTextureSrgbFlags() const { return textureSrgb; }
   
       const std::vector<MeshRange> &getMeshRanges() const { return meshRanges; }
   
     private:
       std::shared_ptr<VulkanDevice> device;
       vk::CommandPool command_pool;
   
       std::vector<Vertex> vertices;
       std::vector<unsigned int> indices;
       std::vector<ObjMaterial> materials;
       std::vector<unsigned int> materialIndex;
       std::vector<std::string> textures;
       // Parallel to textures: 1 = upload sRGB-decoded (diffuse), 0 = linear
       // (normal maps). Same convention as GltfLoader's textureSrgb.
       std::vector<unsigned char> textureSrgb;
       // One slice per OBJ shape; see MeshRange / getMeshRanges.
       std::vector<MeshRange> meshRanges;
   
       // Both take an ALREADY PARSED reader. The file used to be parsed once per
       // function - twice per model - which for the bundled 27 MB OBJ is around
       // 190 ms of duplicated work at the measured ~7 ms/MB (BM_ObjParse_Suzanne).
       // modelFile is still needed: texture paths resolve relative to it.
       void loadTexturesAndMaterials(const tinyobj::ObjReader &reader, const std::string &modelFile);
       void loadVertices(const tinyobj::ObjReader &reader);
   };
   }// namespace Kataglyphis
