From 46228e1c6071596e4ada187795658b066349b7ad Mon Sep 17 00:00:00 2001
From: Trevor Hollmann <thollmann@uni-koblenz.de>
Date: Fri, 25 Jun 2021 10:01:51 +0200
Subject: [PATCH] [#79] Load textures in extra function.

For the same reasons as with the attributes, see a few commits prior for
more info.
---
 .../src/vkcv/asset/asset_loader.cpp           | 94 +++++++++++--------
 1 file changed, 56 insertions(+), 38 deletions(-)

diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
index f01a4116..7da34745 100644
--- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
@@ -72,8 +72,58 @@ enum IndexType getIndexType(const enum fx::gltf::Accessor::ComponentType &type)
 }
 
 /**
- * This function fills the array of vertex attributes of a vkcv::asset::Mesh
- * object based on the description of attributes for a fx::gltf::Primitive.
+ * This function loads all the textures of a Scene described by the texture-
+ * and image- array of an fx::gltf::Document.
+ * @param tex_src The array of textures from a fx::gltf::Document
+ * @param img_src The array of images from a fx::gltf::Document
+ * @param dir	  The path of directory in which the glTF file is located
+ * @param dst	  The array from the vkcv::Scene to write the textures to
+ * @return	  ASSET_SUCCESS or ASSET_ERROR
+ */
+int loadTextures(const std::vector<fx::gltf::Texture> &tex_src,
+		const std::vector<fx::gltf::Image> &img_src,
+		const std::string &dir, std::vector<Texture> &dst)
+{
+	dst.clear();
+	dst.reserve(tex_src.size());
+	for (int i = 0; i < tex_src.size(); i++) {
+		// TODO Image objects in glTF can have a URI _or_ a bufferView
+		// and a mimeType; but here we are always assuming a URI.
+		std::string uri = dir + "/" + img_src[tex_src[i].source].uri;
+
+		int w, h, c;
+		uint8_t *data = stbi_load(uri.c_str(), &w, &h, &c, 4);
+		c = 4;	// FIXME hardcoded to always have RGBA channel layout
+		if (!data) {
+			vkcv_log(LogLevel::ERROR, "Failed to load image data from %s",
+					uri.c_str());
+			return ASSET_ERROR;
+		}
+
+		const size_t nbytes = w * h * c;
+		std::vector<uint8_t> imgdata;
+		imgdata.resize(nbytes);
+		if (!memcpy(imgdata.data(), data, nbytes)) {
+			vkcv_log(LogLevel::ERROR, "Failed to copy texture data");
+			free(data);
+			return ASSET_ERROR;
+		}
+		free(data);
+
+		dst.push_back({
+			tex_src[i].sampler,
+			static_cast<uint8_t>(c),
+			static_cast<uint16_t>(w), static_cast<uint16_t>(h),
+			imgdata
+		});
+	}
+	return ASSET_SUCCESS;
+}
+
+/**
+ * This function fills the array of vertex attributes of a VertexGroup (usually
+ * part of a vkcv::asset::Mesh) object based on the description of attributes
+ * for a fx::gltf::Primitive.
  * @param src The description of attribute objects from the fx-gltf library
  * @param dst The array of vertex attributes stored in an asset::Mesh object
  * @return return code
@@ -374,42 +424,10 @@ int loadScene(const std::string &path, Scene &scene){
                                                                             sceneObjects.nodes[m].matrix);
     }
 
-    if (sceneObjects.textures.size() > 0){
-        textures.reserve(sceneObjects.textures.size());
-
-        for(int k = 0; k < sceneObjects.textures.size(); k++){
-            const fx::gltf::Texture &tex = sceneObjects.textures[k];
-            const fx::gltf::Image &img = sceneObjects.images[tex.source];
-	    // TODO Image objects in glTF can have a URI _or_ a bufferView and
-	    // a mimeType; but here we are assuming to always find a URI.
-            std::string img_uri = dir + "/" + img.uri;
-            int w, h, c;
-            uint8_t *data = stbi_load(img_uri.c_str(), &w, &h, &c, 4);
-            c = 4;	// FIXME hardcoded to always have RGBA channel layout
-            if (!data) {
-                vkcv_log(LogLevel::ERROR, "Loading texture image data.")
-                return ASSET_ERROR;
-            }
-            const size_t byteLen = w * h * c;
-
-            std::vector<uint8_t> imgdata;
-            imgdata.resize(byteLen);
-            if (!memcpy(imgdata.data(), data, byteLen)) {
-                vkcv_log(LogLevel::ERROR, "Copying texture image data")
-                free(data);
-                return ASSET_ERROR;
-            }
-            free(data);
-
-            textures.push_back({
-                tex.sampler,
-                static_cast<uint8_t>(c),
-                static_cast<uint16_t>(w),
-                static_cast<uint16_t>(h),
-                imgdata
-            });
-
-        }
+    if (loadTextures(sceneObjects.textures, sceneObjects.images, dir, textures) != ASSET_SUCCESS) {
+	    size_t missing = sceneObjects.textures.size() - textures.size();
+	    vkcv_log(LogLevel::ERROR, "Failed to get %lu textures from glTF source '%s'",
+			    missing, path.c_str());
     }
 
     if (sceneObjects.materials.size() > 0){
-- 
GitLab