Skip to content
Snippets Groups Projects
Verified Commit 49047a5e authored by Tobias Frisch's avatar Tobias Frisch
Browse files

[#79] Asset-Loader refactoring mostly done

parent f087c54e
No related branches found
No related tags found
1 merge request!69Resolve "Rework Asset Loader API"
Pipeline #26457 failed
...@@ -49,14 +49,24 @@ namespace vkcv::asset { ...@@ -49,14 +49,24 @@ namespace vkcv::asset {
* (TRIANGLES) if no mode is given in the file. * (TRIANGLES) if no mode is given in the file.
*/ */
enum class PrimitiveMode : uint8_t { enum class PrimitiveMode : uint8_t {
POINTS=0, LINES, LINELOOP, LINESTRIP, TRIANGLES, TRIANGLESTRIP, POINTS = 0,
TRIANGLEFAN LINES = 1,
LINELOOP = 2,
LINESTRIP = 3,
TRIANGLES = 4,
TRIANGLESTRIP = 5,
TRIANGLEFAN = 6
}; };
/** /**
* The indices in the index buffer can be of different bit width. * The indices in the index buffer can be of different bit width.
*/ */
enum class IndexType : uint8_t { UNDEFINED=0, UINT8=1, UINT16=2, UINT32=3 }; enum class IndexType : uint8_t {
UNDEFINED=0,
UINT8=1,
UINT16=2,
UINT32=3
};
/** /**
* This struct defines a sampler for a texture object. All values here can * This struct defines a sampler for a texture object. All values here can
...@@ -67,25 +77,29 @@ enum class IndexType : uint8_t { UNDEFINED=0, UINT8=1, UINT16=2, UINT32=3 }; ...@@ -67,25 +77,29 @@ enum class IndexType : uint8_t { UNDEFINED=0, UINT8=1, UINT16=2, UINT32=3 };
* Since glTF does not specify border sampling for more than two dimensions, * Since glTF does not specify border sampling for more than two dimensions,
* the addressModeW is hardcoded to a default: VK_SAMPLER_ADDRESS_MODE_REPEAT. * the addressModeW is hardcoded to a default: VK_SAMPLER_ADDRESS_MODE_REPEAT.
*/ */
typedef struct { struct Sampler {
int minFilter, magFilter; int minFilter, magFilter;
int mipmapMode; int mipmapMode;
float minLOD, maxLOD; float minLOD, maxLOD;
int addressModeU, addressModeV, addressModeW; int addressModeU, addressModeV, addressModeW;
} Sampler; };
/** /**
* This struct describes a loaded texture. * This struct describes a loaded texture.
* Note that textures are currently always loaded with 4 channels as RGBA, even * Note that textures are currently always loaded with 4 channels as RGBA, even
* if the image has just RGB or is grayscale. * if the image has just RGB or is grayscale.
*/ */
typedef struct { struct Texture {
int uri; // index into the URIs array of the Scene std::filesystem::path path; // file path of the encoded texture data
int sampler; // index into the sampler array of the Scene int sampler; // index into the sampler array of the Scene
uint8_t channels; // number of channels
uint16_t w, h; // width and height of the texture union { int width; int w; };
std::vector<uint8_t> data; // binary data of the decoded texture union { int height; int h; };
} Texture; int channels;
// binary data of the decoded texture
std::vector<char*> data;
};
/** /**
* Flags for the bit-mask in the Material struct. To check if a material has a * Flags for the bit-mask in the Material struct. To check if a material has a
...@@ -93,7 +107,11 @@ typedef struct { ...@@ -93,7 +107,11 @@ typedef struct {
* the material struct and the enum. * the material struct and the enum.
*/ */
enum class PBRTextureTarget { enum class PBRTextureTarget {
baseColor=1, metalRough=2, normal=4, occlusion=8, emissive=16 baseColor=1,
metalRough=2,
normal=4,
occlusion=8,
emissive=16
}; };
/** /**
...@@ -112,10 +130,12 @@ enum class PBRTextureTarget { ...@@ -112,10 +130,12 @@ enum class PBRTextureTarget {
* The asset loader module only supports the PBR-MetallicRoughness model for * The asset loader module only supports the PBR-MetallicRoughness model for
* materials. * materials.
*/ */
typedef struct { struct Material {
uint16_t textureMask; // bit mask with active texture targets uint16_t textureMask; // bit mask with active texture targets
// Indices into the Scene.textures vector // Indices into the Scene.textures vector
int baseColor, metalRough, normal, occlusion, emissive; int baseColor, metalRough, normal, occlusion, emissive;
// Scaling factors for each texture target // Scaling factors for each texture target
struct { float r, g, b, a; } baseColorFactor; struct { float r, g, b, a; } baseColorFactor;
float metallicFactor, roughnessFactor; float metallicFactor, roughnessFactor;
...@@ -128,12 +148,13 @@ typedef struct { ...@@ -128,12 +148,13 @@ typedef struct {
* struct, its bit is set in the textureMask. You can use this function * struct, its bit is set in the textureMask. You can use this function
* to check that: * to check that:
* if (myMaterial.hasTexture(baseColor)) {...} * if (myMaterial.hasTexture(baseColor)) {...}
*
* @param t The target to query for * @param t The target to query for
* @return Boolean to signal whether the texture target is active in * @return Boolean to signal whether the texture target is active in
* the material. * the material.
*/ */
bool hasTexture(const PBRTextureTarget t) const; bool hasTexture(PBRTextureTarget target) const;
} Material; };
/* With these enums, 0 is reserved to signal uninitialized or invalid data. */ /* With these enums, 0 is reserved to signal uninitialized or invalid data. */
enum class PrimitiveType : uint32_t { enum class PrimitiveType : uint32_t {
...@@ -157,21 +178,28 @@ enum class PrimitiveType : uint32_t { ...@@ -157,21 +178,28 @@ enum class PrimitiveType : uint32_t {
* avoid exposing that dependency, thus it is re-defined here. * avoid exposing that dependency, thus it is re-defined here.
*/ */
enum class ComponentType : uint16_t { enum class ComponentType : uint16_t {
NONE = 0, INT8 = 5120, UINT8 = 5121, INT16 = 5122, UINT16 = 5123, NONE = 0,
UINT32 = 5125, FLOAT32 = 5126 INT8 = 5120,
UINT8 = 5121,
INT16 = 5122,
UINT16 = 5123,
UINT32 = 5125,
FLOAT32 = 5126
}; };
/** /**
* This struct describes one vertex attribute of a vertex buffer. * This struct describes one vertex attribute of a vertex buffer.
*/ */
typedef struct { struct VertexAttribute {
PrimitiveType type; // POSITION, NORMAL, ... PrimitiveType type; // POSITION, NORMAL, ...
uint32_t offset; // offset in bytes uint32_t offset; // offset in bytes
uint32_t length; // length of ... in bytes uint32_t length; // length of ... in bytes
uint32_t stride; // stride in bytes uint32_t stride; // stride in bytes
ComponentType componentType; // eg. 5126 for float ComponentType componentType; // eg. 5126 for float
uint8_t componentCount; // eg. 3 for vec3 uint8_t componentCount; // eg. 3 for vec3
} VertexAttribute; };
/** /**
* This struct represents one (possibly the only) part of a mesh. There is * This struct represents one (possibly the only) part of a mesh. There is
...@@ -180,100 +208,96 @@ typedef struct { ...@@ -180,100 +208,96 @@ typedef struct {
* by indexBuffer.data being empty. Each vertex buffer can have one or more * by indexBuffer.data being empty. Each vertex buffer can have one or more
* vertex attributes. * vertex attributes.
*/ */
typedef struct { struct VertexGroup {
enum PrimitiveMode mode; // draw as points, lines or triangle? enum PrimitiveMode mode; // draw as points, lines or triangle?
size_t numIndices, numVertices; size_t numIndices;
size_t numVertices;
struct { struct {
int uri; // index into the URIs array of Scene
enum IndexType type; // data type of the indices enum IndexType type; // data type of the indices
std::vector<uint8_t> data; // binary data of the index buffer std::vector<uint8_t> data; // binary data of the index buffer
} indexBuffer; } indexBuffer;
struct { struct {
int uri; // index into the URIs array of Scene
std::vector<uint8_t> data; // binary data of the vertex buffer std::vector<uint8_t> data; // binary data of the vertex buffer
std::vector<VertexAttribute> attributes; // description of one std::vector<VertexAttribute> attributes; // description of one
} vertexBuffer; } vertexBuffer;
struct { float x, y, z; } min; // bounding box lower left struct { float x, y, z; } min; // bounding box lower left
struct { float x, y, z; } max; // bounding box upper right struct { float x, y, z; } max; // bounding box upper right
int materialIndex; // index to one of the materials int materialIndex; // index to one of the materials
} VertexGroup; };
/** /**
* This struct represents a single mesh as it was loaded from a glTF file. It * This struct represents a single mesh as it was loaded from a glTF file. It
* consists of at least one VertexGroup, which then references other resources * consists of at least one VertexGroup, which then references other resources
* such as Materials. * such as Materials.
*/ */
typedef struct { struct Mesh {
std::string name; std::string name;
std::array<float, 16> modelMatrix; std::array<float, 16> modelMatrix;
std::vector<int> vertexGroups; std::vector<int> vertexGroups;
} Mesh; };
/**
* The scene struct is simply a collection of objects in the scene as well as
* the resources used by those objects.
* Note that parent-child relations are not yet possible.
*/
typedef struct {
std::vector<Mesh> meshes;
std::vector<VertexGroup> vertexGroups;
std::vector<Material> materials;
std::vector<Texture> textures;
std::vector<Sampler> samplers;
std::vector<std::string> uris;
} Scene;
/**
* Load every mesh from the glTF file, as well as materials, textures and other
* associated objects.
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the
* content of the glTF file being loaded.
*/
int loadScene(const std::filesystem::path &path, Scene &scene);
/** /**
* Parse the given glTF file and create a shallow description of the content. * The scene struct is simply a collection of objects in the scene as well as
* Only the meta-data of the objects in the scene is loaded, not the binary * the resources used by those objects.
* content. The rationale is to provide a means of probing the content of a * Note that parent-child relations are not yet possible.
* glTF file without the costly process of loading and decoding large amounts */
* of data. The returned Scene struct can be used to search for specific meshes struct Scene {
* in the scene, that can then be loaded on their own using the loadMesh() std::vector<Mesh> meshes;
* function. Note that the Scene struct received as output argument will be std::vector<VertexGroup> vertexGroups;
* overwritten by this function. std::vector<Material> materials;
* After this function completes, the returned Scene struct is completely std::vector<Texture> textures;
* initialized and all information is final, except for the missing binary std::vector<Sampler> samplers;
* data. This means that indices to vectors will remain valid even when the std::vector<std::string> uris;
* shallow scene struct is filled with data by loadMesh(). };
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the
* meta-data of all objects described in the glTF file.
*/
int probeScene(const std::filesystem::path &path, Scene &scene);
/** /**
* This function loads a single mesh from the given file and adds it to the * Parse the given glTF file and create a shallow description of the content.
* given scene. The scene must already be initialized (via probeScene()). * Only the meta-data of the objects in the scene is loaded, not the binary
* The mesh_index refers to the Scenes meshes array and identifies the mesh to * content. The rationale is to provide a means of probing the content of a
* load. To find the mesh you want, iterate over the probed scene and check the * glTF file without the costly process of loading and decoding large amounts
* meshes details (eg. name). * of data. The returned Scene struct can be used to search for specific meshes
* Besides the mesh, this function will also add any associated data to the * in the scene, that can then be loaded on their own using the loadMesh()
* Scene struct such as Materials and Textures required by the Mesh. * function. Note that the Scene struct received as output argument will be
* * overwritten by this function.
* @param path must be the path to a glTF- or glb-file. * After this function completes, the returned Scene struct is completely
* @param scene is the scene struct to which the results will be written. * initialized and all information is final, except for the missing binary
*/ * data. This means that indices to vectors will remain valid even when the
int loadMesh(Scene &scene, int mesh_index); * shallow scene struct is filled with data by loadMesh().
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the
* meta-data of all objects described in the glTF file.
*/
int probeScene(const std::filesystem::path &path, Scene &scene);
struct TextureData { /**
int width; * This function loads a single mesh from the given file and adds it to the
int height; * given scene. The scene must already be initialized (via probeScene()).
int componentCount; * The mesh_index refers to the Scenes meshes array and identifies the mesh to
std::vector<char*> data; * load. To find the mesh you want, iterate over the probed scene and check the
}; * meshes details (eg. name).
* Besides the mesh, this function will also add any associated data to the
* Scene struct such as Materials and Textures required by the Mesh.
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is the scene struct to which the results will be written.
*/
int loadMesh(Scene &scene, int mesh_index);
/**
* Load every mesh from the glTF file, as well as materials, textures and other
* associated objects.
*
* @param path must be the path to a glTF- or glb-file.
* @param scene is a reference to a Scene struct that will be filled with the
* content of the glTF file being loaded.
*/
int loadScene(const std::filesystem::path &path, Scene &scene);
TextureData loadTexture(const std::filesystem::path& path); Texture loadTexture(const std::filesystem::path& path);
} }
This diff is collapsed.
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment