diff --git a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp index 24687e846ff9eae3275de357331a825f0b4ed2c3..44befb95c3ccc54fb6cf06810cbe2767bf4879ce 100644 --- a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp +++ b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp @@ -50,11 +50,51 @@ enum PrimitiveMode { POINTS=0, LINES, LINELOOP, LINESTRIP, TRIANGLES, TRIANGLESTRIP, TRIANGLEFAN }; + /* The indices in the index buffer can be of different bit width. */ enum IndexType { UINT32=0, UINT16=1, UINT8=2 }; +/* Flags for the bit-mask in the Material struct. Use the bitof() macro to + * translate the enums value when checking a flag of the mask: + * Material mat = ...; + * if (mat.textureMask & bitflag(PBRTextureTarget::baseColor)) {...} */ +// TODO Maybe it's easier to replace the bitflag() macro with a "hasTexture()" +// macro that already combines the logical AND with the bitflag? +enum class PBRTextureTarget { + baseColor=1, metalRough=2, normal=4, occlusion=8, emissive=16 +}; + +/* This macro translates the index of an enum in the defined order to an + * integer with a single bit set in the corresponding place. */ +#define bitflag(ENUM) (0x1u << (ENUM)) + +typedef struct { + // TODO define struct for samplers (low priority) +} Sampler; + +typedef struct { + uint8_t sampler; // index into the Meshes samplers array + uint8_t channels; // number of channels + uint16_t w, h; // width and height of the texture + std::vector<uint8_t> data; // binary data of the decoded texture +} Texture; + +/* The asset loader module only supports the PBR-MetallicRoughness model for + * materials. + * NOTE: Only a single UV-texture is currently supported to reduce the + * complexity at first. Later, there will need to be an association between + * each of the texture targets in the Material struct and a VertexAttribute of + * a VertexBuffer that defines the UV coordinates for that texture. */ typedef struct { - // TODO not yet needed for the first (unlit) triangle + uint8_t textureMask; // bit mask with active texture targets + // Indices into the Mesh.textures array + uint8_t baseColor, metalRough, normal, occlusion, emissive; + // Scaling factors for each texture target + struct { float r, g, b, a; } baseColorFactor; + float metallicFactor, roughnessFactor; + float normalScale; + float occlusionStrength; + struct { float r, g, b; } emissiveFactor; } Material; /* This struct represents one (possibly the only) part of a mesh. There is @@ -84,6 +124,10 @@ typedef struct { std::string name; std::vector<VertexGroup> vertexGroups; std::vector<Material> materials; + std::vector<Texture> textures; + std::vector<Sampler> samplers; + // TODO Replace usage of the texture_hack everywhere with use of the + // textures, materials and sampler-arrays. // FIXME Dirty hack to get one(!) texture for our cube demo // hardcoded to always have RGBA channel layout struct { diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp index e660b442d0b9a0208f95c9d753ef19e926bcac44..e581f917b706296808dcb776a77781f2efce55e5 100644 --- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp +++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp @@ -173,11 +173,15 @@ int loadMesh(const std::string &path, Mesh &mesh) { }); std::vector<Material> materials; + std::vector<Texture> textures; + std::vector<Sampler> samplers; mesh = { object.meshes[0].name, vertexGroups, materials, + textures, + samplers, 0, 0, 0, NULL };