summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2024-10-05 23:40:53 -0700
committerChuyan Zhang <me@zcy.moe>2024-10-05 23:40:53 -0700
commit9ed211d1ca084b25d1780da3bde19e9da64d4a4a (patch)
treef6cb6350a4999b153c4995a3b3ce3d1d71dea17f
parent1866dd531dffc4084dfaf261591bc7ac2a376d67 (diff)
downloadiris-9ed211d1ca084b25d1780da3bde19e9da64d4a4a.tar.gz
iris-9ed211d1ca084b25d1780da3bde19e9da64d4a4a.zip
glTF loader start working
-rw-r--r--.gitignore2
-rw-r--r--assets/Box/Box.gltf142
-rw-r--r--src/app.cpp13
-rw-r--r--src/gltf_loader.cpp78
-rw-r--r--src/gltf_loader.h10
-rw-r--r--src/render_assets.h8
-rw-r--r--src/vulkan_swapchain.cpp4
7 files changed, 236 insertions, 21 deletions
diff --git a/.gitignore b/.gitignore
index 125e2ae..ab3b6de 100644
--- a/.gitignore
+++ b/.gitignore
@@ -53,3 +53,5 @@ cmake-build-release/
imgui.ini
e.log
+assets/Avocado
+assets/Sponza
diff --git a/assets/Box/Box.gltf b/assets/Box/Box.gltf
new file mode 100644
index 0000000..7f603f0
--- /dev/null
+++ b/assets/Box/Box.gltf
@@ -0,0 +1,142 @@
+{
+ "asset": {
+ "generator": "COLLADA2GLTF",
+ "version": "2.0"
+ },
+ "scene": 0,
+ "scenes": [
+ {
+ "nodes": [
+ 0
+ ]
+ }
+ ],
+ "nodes": [
+ {
+ "children": [
+ 1
+ ],
+ "matrix": [
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ -1.0,
+ 0.0,
+ 0.0,
+ 1.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 0.0,
+ 1.0
+ ]
+ },
+ {
+ "mesh": 0
+ }
+ ],
+ "meshes": [
+ {
+ "primitives": [
+ {
+ "attributes": {
+ "NORMAL": 1,
+ "POSITION": 2
+ },
+ "indices": 0,
+ "mode": 4,
+ "material": 0
+ }
+ ],
+ "name": "Mesh"
+ }
+ ],
+ "accessors": [
+ {
+ "bufferView": 0,
+ "byteOffset": 0,
+ "componentType": 5123,
+ "count": 36,
+ "max": [
+ 23
+ ],
+ "min": [
+ 0
+ ],
+ "type": "SCALAR"
+ },
+ {
+ "bufferView": 1,
+ "byteOffset": 0,
+ "componentType": 5126,
+ "count": 24,
+ "max": [
+ 1.0,
+ 1.0,
+ 1.0
+ ],
+ "min": [
+ -1.0,
+ -1.0,
+ -1.0
+ ],
+ "type": "VEC3"
+ },
+ {
+ "bufferView": 1,
+ "byteOffset": 288,
+ "componentType": 5126,
+ "count": 24,
+ "max": [
+ 0.5,
+ 0.5,
+ 0.5
+ ],
+ "min": [
+ -0.5,
+ -0.5,
+ -0.5
+ ],
+ "type": "VEC3"
+ }
+ ],
+ "materials": [
+ {
+ "pbrMetallicRoughness": {
+ "baseColorFactor": [
+ 0.800000011920929,
+ 0.0,
+ 0.0,
+ 1.0
+ ],
+ "metallicFactor": 0.0
+ },
+ "name": "Red"
+ }
+ ],
+ "bufferViews": [
+ {
+ "buffer": 0,
+ "byteOffset": 576,
+ "byteLength": 72,
+ "target": 34963
+ },
+ {
+ "buffer": 0,
+ "byteOffset": 0,
+ "byteLength": 576,
+ "byteStride": 12,
+ "target": 34962
+ }
+ ],
+ "buffers": [
+ {
+ "byteLength": 648,
+ "uri": "Box0.bin"
+ }
+ ]
+}
diff --git a/src/app.cpp b/src/app.cpp
index 11a219d..2fd7c31 100644
--- a/src/app.cpp
+++ b/src/app.cpp
@@ -1,4 +1,6 @@
#include "imgui.h"
+#include "render_assets.h"
+#include "gltf_loader.h"
#include "vulkan_swapchain.h"
#include "imgui_impl_vulkan.h"
@@ -22,10 +24,15 @@ int main(int argc, char** argv) {
argparse::ArgumentParser program("Iris Renderer");
program.add_argument("width")
.help("display width of the window")
+ .default_value(1920)
.scan<'i', int>();
program.add_argument("height")
.help("display height of the window")
+ .default_value(1080)
.scan<'i', int>();
+ program.add_argument("scene")
+ .help("path to the scene file")
+ .default_value("assets/Box/Box.gltf");
try {
program.parse_args(argc, argv);
@@ -37,6 +44,7 @@ int main(int argc, char** argv) {
int window_width = program.get<int>("width");
int window_height = program.get<int>("height");
+ std::string scene_path = program.get<std::string>("scene");
if (!glfwInit()) {
const char* description = nullptr;
@@ -72,6 +80,11 @@ int main(int argc, char** argv) {
.flags = VMA_ALLOCATION_CREATE_DEDICATED_MEMORY_BIT,
.usage = VMA_MEMORY_USAGE_AUTO,
});
+ iris::Scene scene;
+ if (!load_gltf(scene_path, scene)) {
+ spdlog::critical("Failed to load glTF file");
+ abort();
+ }
// end load debug image
auto swapchain = iris::Swapchain(window, device, window_width, window_height);
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
index bf64740..684fa7f 100644
--- a/src/gltf_loader.cpp
+++ b/src/gltf_loader.cpp
@@ -1,4 +1,5 @@
#include "gltf_loader.h"
+#include "render_assets.h"
#include "spdlog/spdlog.h"
#include <cstdint>
@@ -75,15 +76,26 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
model.scenes.size(),
model.lights.size());
+
for (const auto &mesh : model.meshes) {
- iris::Mesh iris_mesh {
- .name = mesh.name,
- .vertices = {},
- .normals = {},
- .texcoords = {},
- .indices = {},
- };
+ auto mesh_primitive_counter = 0u;
+ const std::string mesh_name = mesh.name == "" ? "mesh" : mesh.name;
+
+ // TODO: A Mesh in glTF can have multiple primitives, each with its own set of attributes
+ // But our current abstract doesn't support multiple primitives within a mesh, so we load
+ // each primitive as a separate mesh instead. This is a temporary solution and should be fixed.
for (const auto &primitive : mesh.primitives) {
+ std::string name = mesh_name + "_" + std::to_string(mesh_primitive_counter++);
+ spdlog::info("loading mesh primitive: {}", name);
+ iris::Mesh iris_mesh {
+ .name = mesh.name,
+ .vertices = {},
+ .normals = {},
+ .texcoords = {},
+ .indices = {},
+ .material_index = primitive.material,
+ };
+
const auto &index_accessor = model.accessors[primitive.indices];
const auto &index_buffer_view = model.bufferViews[index_accessor.bufferView];
const auto &index_buffer = model.buffers[index_buffer_view.buffer];
@@ -144,15 +156,14 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
return *typed_data;
};
- // TODO: support other types. Currently only float3 is supported
- if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
- spdlog::error("Unsupported POSITION type: {}, {}", accessor.type, accessor.componentType);
- return false;
- }
-
// spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count);
if (attrib_name == "POSITION") {
spdlog::info("loading POSITION, count {}", accessor.count);
+ // TODO: support other types. Currently only float3 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
iris_mesh.p_min = glm::vec3(accessor.minValues[0], accessor.minValues[1], accessor.minValues[2]);
iris_mesh.p_max = glm::vec3(accessor.maxValues[0], accessor.maxValues[1], accessor.maxValues[2]);
for (size_t i = 0; i < accessor.count; i++) {
@@ -160,26 +171,65 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
}
} else if (attrib_name == "NORMAL") {
spdlog::info("loading NORMAL, count {}", accessor.count);
+ // TODO: support other types. Currently only float3 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
for (size_t i = 0; i < accessor.count; i++) {
iris_mesh.normals.push_back(extract_data.operator()<glm::vec3>());
}
} else if (attrib_name == "TEXCOORD_0") {
spdlog::info("loading TEXCOORD_0, count {}", accessor.count);
+ // TODO: support other types. Currently only float2 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC2 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
for (size_t i = 0; i < accessor.count; i++) {
iris_mesh.texcoords.push_back(extract_data.operator()<glm::vec2>());
}
+ } else if (attrib_name == "TANGENT") {
+ spdlog::info("loading TANGENT, count {}", accessor.count);
+ // TODO: support other types. Currently only float4 is supported
+ if (accessor.type != TINYGLTF_TYPE_VEC4 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
+ spdlog::error("Field {} type unsupported: {}, {}", attrib_name, accessor.type, accessor.componentType);
+ continue;
+ }
+ for (size_t i = 0; i < accessor.count; i++) {
+ iris_mesh.tangents.push_back(extract_data.operator()<glm::vec4>());
+ }
} else {
spdlog::warn("Unsupported attribute: {}", attrib_name);
}
}
+ break;
}
// TODO add support for other modes
default:
spdlog::error("Unsupported primitive mode: {}", primitive.mode);
return false;
}
+ scene.meshes.push_back(iris_mesh);
}
- scene.meshes.push_back(iris_mesh);
+ }
+
+ for (const tinygltf::Material &material : model.materials) {
+ const std::string material_name = material.name == "" ? "material" : material.name;
+ const auto &pbr = material.pbrMetallicRoughness;
+ iris::Material iris_material {
+ .name = material_name,
+ .base_color = glm::vec4(
+ pbr.baseColorFactor[0],
+ pbr.baseColorFactor[1],
+ pbr.baseColorFactor[2],
+ pbr.baseColorFactor[3]),
+ .metallic = float(pbr.metallicFactor),
+ .roughness = float(pbr.roughnessFactor),
+ };
+
+ // TODO: load texture information, skip for now
+ spdlog::info("Material: {}", material_name);
}
// TODO load materials and textures
diff --git a/src/gltf_loader.h b/src/gltf_loader.h
index c239bb2..4b3190b 100644
--- a/src/gltf_loader.h
+++ b/src/gltf_loader.h
@@ -1,11 +1,9 @@
-#pragma once
+#ifndef GLTF_LOADER_H
+#define GLTF_LOADER_H
#include <string_view>
#include "render_assets.h"
-
-#define TINYGLTF_IMPLEMENTATION
-#define STB_IMAGE_IMPLEMENTATION
-#define STB_IMAGE_WRITE_IMPLEMENTATION
#include "tiny_gltf.h"
-bool load_gltf(const std::string_view path, iris::Scene &scene); \ No newline at end of file
+bool load_gltf(const std::string_view path, iris::Scene &scene);
+#endif \ No newline at end of file
diff --git a/src/render_assets.h b/src/render_assets.h
index 8c28ead..113084a 100644
--- a/src/render_assets.h
+++ b/src/render_assets.h
@@ -12,7 +12,10 @@ struct Mesh {
std::vector<glm::vec3> vertices;
std::vector<glm::vec3> normals;
std::vector<glm::vec2> texcoords;
+ // Note: w component is a sign, 1.0 or -1.0
+ std::vector<glm::vec4> tangents;
std::vector<uint32_t> indices;
+ int32_t material_index;
// AABB
glm::vec3 p_min;
@@ -20,7 +23,10 @@ struct Mesh {
};
struct Material {
-
+ std::string name;
+ glm::vec4 base_color;
+ float metallic;
+ float roughness;
};
struct Texture {
diff --git a/src/vulkan_swapchain.cpp b/src/vulkan_swapchain.cpp
index 4e08049..b93b8a9 100644
--- a/src/vulkan_swapchain.cpp
+++ b/src/vulkan_swapchain.cpp
@@ -1,5 +1,9 @@
#include "vulkan_swapchain.h"
+#define TINYGLTF_IMPLEMENTATION
+#define STB_IMAGE_IMPLEMENTATION
+#define STB_IMAGE_WRITE_IMPLEMENTATION
+#include "tiny_gltf.h"
#include "GLFW/glfw3.h"
#include "imgui.h"
#include "imgui_impl_glfw.h"