From 79ededf7538742937dfc64f126094e3fa31f02b9 Mon Sep 17 00:00:00 2001
From: Trevor Hollmann <thollmann@uni-koblenz.de>
Date: Sat, 12 Jun 2021 12:42:23 +0200
Subject: [PATCH] [#63] Define and document material bitmask handling.

---
 .../include/vkcv/asset/asset_loader.hpp       | 38 ++++++++++++-------
 .../src/vkcv/asset/asset_loader.cpp           |  7 ++++
 2 files changed, 31 insertions(+), 14 deletions(-)

diff --git a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp
index e60d3b7f..0591ef3c 100644
--- a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp
+++ b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp
@@ -55,20 +55,6 @@ enum class PrimitiveMode : uint8_t {
 /* 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 };
 
-/* 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)
 	// NOTE: glTF defines samplers based on OpenGL, which can not be
@@ -101,6 +87,30 @@ typedef struct {
 	struct { float r, g, b; } emissiveFactor;
 } Material;
 
+/* Flags for the bit-mask in the Material struct. To check if a material has a
+ * certain texture target, you can use the hasTexture() function below, passing
+ * the material struct and the enum. */
+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. It is used for
+ * working with the bitmask of texture targets ("textureMask") in the Material
+ * struct:
+ * 	Material mat = ...;
+ * 	if (mat.textureMask & bitflag(PBRTextureTarget::baseColor)) {...}
+ * However, this logic is also encapsulated in the convenience-function
+ * materialHasTexture() so users of the asset loader module can avoid direct
+ * contact with bit-level operations. */
+#define bitflag(ENUM) (0x1u << ((unsigned)(ENUM)))
+
+/* To signal that a certain texture target is active in a Material struct, its
+ * bit is set in the textureMask. You can use this function to check that:
+ * Material mat = ...;
+ * if (materialHasTexture(&mat, baseColor)) {...} */
+bool materialHasTexture(const Material *const m, const PBRTextureTarget t);
+
 /* This struct represents one (possibly the only) part of a mesh. There is
  * always one vertexBuffer and zero or one indexBuffer (indexed rendering is
  * common but not always used). If there is no index buffer, this is indicated
diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
index 102e6921..cf033049 100644
--- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
@@ -241,6 +241,13 @@ int loadMesh(const std::string &path, Mesh &mesh) {
 	return 1;
 }
 
+
+bool materialHasTexture(const Material *const m, const PBRTextureTarget t)
+{
+	return m->textureMask & bitflag(t);
+}
+
+
 int loadScene(const std::string &path, Scene &scene){
     fx::gltf::Document sceneObjects;
 
-- 
GitLab