From 1ec28a3ebe9c2a6d2888e0d2faf5a79b51b75c35 Mon Sep 17 00:00:00 2001
From: Trevor Hollmann <thollmann@uni-koblenz.de>
Date: Fri, 4 Jun 2021 12:14:36 +0200
Subject: [PATCH] [#63] Remove texture_hack from Mesh.

The implementation in asset_loader.cpp is still a hack, as is the usage
in main.cpp, but the hack is now using the textures array of the mesh
and the struct could be cleaned up to get rid of the hack in the modules
interface.
---
 .../include/vkcv/asset/asset_loader.hpp       |  8 -----
 .../src/vkcv/asset/asset_loader.cpp           | 29 ++++++++++++++++---
 projects/first_mesh/src/main.cpp              |  7 +++--
 3 files changed, 30 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 c4459578..72679e27 100644
--- a/modules/asset_loader/include/vkcv/asset/asset_loader.hpp
+++ b/modules/asset_loader/include/vkcv/asset/asset_loader.hpp
@@ -129,14 +129,6 @@ typedef struct {
 	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 {
-		int w, h, ch;	// width, height and channels of image
-		uint8_t *img;	// raw bytes, free after use (deal with it)
-	} texture_hack;
 } Mesh;
 
 
diff --git a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
index e581f917..388d2a95 100644
--- a/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
+++ b/modules/asset_loader/src/vkcv/asset/asset_loader.cpp
@@ -182,11 +182,11 @@ int loadMesh(const std::string &path, Mesh &mesh) {
 		materials,
 		textures,
 		samplers,
-		0, 0, 0, NULL
 	};
 
 	// FIXME HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
 	// fail quietly if there is no texture
+	mesh.textures.reserve(1);
 	if (object.textures.size()) {
 		const std::string mime_type("image/jpeg");
 		const fx::gltf::Texture &tex = object.textures[0];
@@ -201,9 +201,30 @@ int loadMesh(const std::string &path, Mesh &mesh) {
 		size_t pos = path.find_last_of("/");
 		auto dir = path.substr(0, pos);
 		
-		mesh.texture_hack.img = stbi_load((dir + "/" + img.uri).c_str(),
-				&mesh.texture_hack.w, &mesh.texture_hack.h,
-				&mesh.texture_hack.ch, 4);
+		std::string img_uri = dir + "/" + img.uri;
+		int w, h, c;
+		// FIXME hardcoded to always have RGBA channel layout
+		uint8_t *data = stbi_load(img_uri.c_str(), &w, &h, &c, 4);
+		if (!data) {
+			std::cerr << "ERROR loading texture image data.\n";
+			return 0;
+		}
+		const size_t byteLen = w * h * c;
+
+		std::vector<uint8_t> imgdata;
+		imgdata.resize(byteLen);
+		if (!memcpy(imgdata.data(), data, byteLen)) {
+			std::cerr << "ERROR copying texture image data.\n";
+			free(data);
+			return 0;
+		}
+		free(data);
+
+		mesh.textures.push_back({
+			0, static_cast<uint8_t>(c),
+			static_cast<uint16_t>(w), static_cast<uint16_t>(h),
+			imgdata
+		});
 	}
 	// FIXME HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK HACK
 	return 1;
diff --git a/projects/first_mesh/src/main.cpp b/projects/first_mesh/src/main.cpp
index 306aa524..1225af1c 100644
--- a/projects/first_mesh/src/main.cpp
+++ b/projects/first_mesh/src/main.cpp
@@ -125,8 +125,11 @@ int main(int argc, const char** argv) {
 		return EXIT_FAILURE;
 	}
 	
-	vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, mesh.texture_hack.w, mesh.texture_hack.h);
-	texture.fill(mesh.texture_hack.img);
+	// FIXME There should be a test here to make sure there is at least 1
+	// texture in the mesh.
+	vkcv::asset::Texture &tex = mesh.textures[0];
+	vkcv::Image texture = core.createImage(vk::Format::eR8G8B8A8Srgb, tex.w, tex.h);
+	texture.fill(tex.data.data());
 
 	vkcv::SamplerHandle sampler = core.createSampler(
 		vkcv::SamplerFilterType::LINEAR,
-- 
GitLab