summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChuyan Zhang <me@zcy.moe>2024-10-04 22:43:11 -0700
committerChuyan Zhang <me@zcy.moe>2024-10-04 22:43:11 -0700
commit1866dd531dffc4084dfaf261591bc7ac2a376d67 (patch)
tree55e6cbe7b54fc24fb80463f337a86089ef8b9bc3
parentd116dfacb8dc50ad9fb98d67d084d901ae95e456 (diff)
downloadiris-1866dd531dffc4084dfaf261591bc7ac2a376d67.tar.gz
iris-1866dd531dffc4084dfaf261591bc7ac2a376d67.zip
add basic gltf loader
-rw-r--r--src/gltf_loader.cpp67
-rw-r--r--src/render_assets.h34
-rw-r--r--xmake.lua6
3 files changed, 84 insertions, 23 deletions
diff --git a/src/gltf_loader.cpp b/src/gltf_loader.cpp
index 142b69f..bf64740 100644
--- a/src/gltf_loader.cpp
+++ b/src/gltf_loader.cpp
@@ -1,6 +1,6 @@
#include "gltf_loader.h"
#include "spdlog/spdlog.h"
-#include <concepts>
+#include <cstdint>
enum class SceneFileType {
GLTF,
@@ -79,6 +79,8 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
iris::Mesh iris_mesh {
.name = mesh.name,
.vertices = {},
+ .normals = {},
+ .texcoords = {},
.indices = {},
};
for (const auto &primitive : mesh.primitives) {
@@ -87,7 +89,7 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
const auto &index_buffer = model.buffers[index_buffer_view.buffer];
const uint8_t *index_data_ptr = index_buffer.data.data() + index_buffer_view.byteOffset + index_accessor.byteOffset;
- auto extract_index = [&index_data_ptr]<typename T>() -> T requires std::integral<T> {
+ auto extract = [&index_data_ptr]<typename T>() -> T {
const T *index_data = reinterpret_cast<const T *>(index_data_ptr);
index_data_ptr += sizeof(T);
return *index_data;
@@ -95,32 +97,32 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
switch (index_accessor.componentType) {
case TINYGLTF_COMPONENT_TYPE_BYTE:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<int8_t>());
+ iris_mesh.indices.push_back(extract.operator()<int8_t>());
}
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_BYTE:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<uint8_t>());
+ iris_mesh.indices.push_back(extract.operator()<uint8_t>());
}
break;
case TINYGLTF_COMPONENT_TYPE_SHORT:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<int16_t>());
+ iris_mesh.indices.push_back(extract.operator()<int16_t>());
}
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_SHORT:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<uint16_t>());
+ iris_mesh.indices.push_back(extract.operator()<uint16_t>());
}
break;
case TINYGLTF_COMPONENT_TYPE_INT:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<int32_t>());
+ iris_mesh.indices.push_back(extract.operator()<int32_t>());
}
break;
case TINYGLTF_COMPONENT_TYPE_UNSIGNED_INT:
for (size_t i = 0; i < index_accessor.count; i++) {
- iris_mesh.indices.push_back(extract_index.operator()<uint32_t>());
+ iris_mesh.indices.push_back(extract.operator()<uint32_t>());
}
break;
default:
@@ -135,7 +137,12 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
const auto &accessor = model.accessors[accessor_index];
const auto &buffer_view = model.bufferViews[accessor.bufferView];
const auto &buffer = model.buffers[buffer_view.buffer];
- const float *data = reinterpret_cast<const float *>(buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset);
+ const uint8_t *data = buffer.data.data() + buffer_view.byteOffset + accessor.byteOffset;
+ auto extract_data = [&data]<typename T>() -> T {
+ const T *typed_data = reinterpret_cast<const T *>(data);
+ data += sizeof(T);
+ return *typed_data;
+ };
// TODO: support other types. Currently only float3 is supported
if (accessor.type != TINYGLTF_TYPE_VEC3 || accessor.componentType != TINYGLTF_COMPONENT_TYPE_FLOAT) {
@@ -146,24 +153,20 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
// spdlog::info("attribute: {}, count: {}", attrib_name, accessor.count);
if (attrib_name == "POSITION") {
spdlog::info("loading POSITION, count {}", accessor.count);
+ 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++) {
- iris_mesh.vertices.push_back(data[i * 3 + 0]);
- iris_mesh.vertices.push_back(data[i * 3 + 1]);
- iris_mesh.vertices.push_back(data[i * 3 + 2]);
+ iris_mesh.vertices.push_back(extract_data.operator()<glm::vec3>());
}
} else if (attrib_name == "NORMAL") {
spdlog::info("loading NORMAL, count {}", accessor.count);
for (size_t i = 0; i < accessor.count; i++) {
- iris_mesh.vertices.push_back(data[i * 3 + 0]);
- iris_mesh.vertices.push_back(data[i * 3 + 1]);
- iris_mesh.vertices.push_back(data[i * 3 + 2]);
+ iris_mesh.normals.push_back(extract_data.operator()<glm::vec3>());
}
- // TODO reorder normals correctly
} else if (attrib_name == "TEXCOORD_0") {
spdlog::info("loading TEXCOORD_0, count {}", accessor.count);
for (size_t i = 0; i < accessor.count; i++) {
- iris_mesh.vertices.push_back(data[i * 2 + 0]);
- iris_mesh.vertices.push_back(data[i * 2 + 1]);
+ iris_mesh.texcoords.push_back(extract_data.operator()<glm::vec2>());
}
} else {
spdlog::warn("Unsupported attribute: {}", attrib_name);
@@ -179,5 +182,33 @@ bool load_gltf(const std::string_view path, iris::Scene &scene) {
scene.meshes.push_back(iris_mesh);
}
+ // TODO load materials and textures
+
+ for (const tinygltf::Camera &camera : model.cameras) {
+ iris::Camera iris_camera {
+ .position = glm::vec3(0.0f),
+ .direction = glm::vec3(0.0f),
+ .up = glm::vec3(0.0f, 1.0f, 0.0f),
+ };
+ spdlog::info("Camera: {}, type: {}", camera.name, camera.type);
+ if (camera.type == "perspective") {
+ const auto &perspective = camera.perspective;
+ iris_camera.intrinsic_tag = iris::Camera::Tag::Perspective;
+ iris_camera.intrinsic.perspective.fovx = 2 * glm::atan(glm::tan(perspective.yfov / 2) * perspective.aspectRatio);
+ iris_camera.intrinsic.perspective.fovy = perspective.yfov;
+ iris_camera.intrinsic.perspective.aspect = perspective.aspectRatio;
+ iris_camera.intrinsic.perspective.znear = perspective.znear;
+ iris_camera.intrinsic.perspective.zfar = perspective.zfar;
+ } else {
+ const auto &orthographic = camera.orthographic;
+ iris_camera.intrinsic_tag = iris::Camera::Tag::Orthographic;
+ iris_camera.intrinsic.orthographic.xmag = orthographic.xmag;
+ iris_camera.intrinsic.orthographic.ymag = orthographic.ymag;
+ iris_camera.intrinsic.orthographic.znear = orthographic.znear;
+ iris_camera.intrinsic.orthographic.zfar = orthographic.zfar;
+ }
+ scene.camera = iris_camera;
+ }
+
return true;
} \ No newline at end of file
diff --git a/src/render_assets.h b/src/render_assets.h
index 2dfff07..8c28ead 100644
--- a/src/render_assets.h
+++ b/src/render_assets.h
@@ -9,10 +9,14 @@ namespace iris {
struct Mesh {
std::string name;
- std::vector<float> vertices;
- std::vector<float> normals;
- std::vector<float> texcoords;
+ std::vector<glm::vec3> vertices;
+ std::vector<glm::vec3> normals;
+ std::vector<glm::vec2> texcoords;
std::vector<uint32_t> indices;
+
+ // AABB
+ glm::vec3 p_min;
+ glm::vec3 p_max;
};
struct Material {
@@ -23,6 +27,28 @@ struct Texture {
};
struct Camera {
+ enum struct Tag {
+ Perspective,
+ Orthographic,
+ } intrinsic_tag;
+ struct PerspectiveCamera {
+ float fovx;
+ float fovy;
+ float aspect;
+ float znear;
+ float zfar;
+ };
+
+ struct OrthographicCamera {
+ float xmag;
+ float ymag;
+ float znear;
+ float zfar;
+ };
+ union {
+ PerspectiveCamera perspective;
+ OrthographicCamera orthographic;
+ } intrinsic;
glm::vec3 position;
glm::vec3 direction;
glm::vec3 up;
@@ -33,7 +59,7 @@ struct Scene {
std::vector<Material> materials;
std::vector<Texture> textures;
- Camera camera_position;
+ Camera camera;
};
} // namespace iris \ No newline at end of file
diff --git a/xmake.lua b/xmake.lua
index 1171462..e634221 100644
--- a/xmake.lua
+++ b/xmake.lua
@@ -57,13 +57,17 @@ target("stb")
set_kind("headeronly")
add_includedirs(path.join(ext_dir, "stb"), {public = true})
+target("glm")
+ set_kind("headeronly")
+ add_includedirs(path.join(ext_dir, "glm"), {public = true})
+
-- Main executable target
target("iris_renderer")
set_kind("binary")
add_files(path.join(src_dir, "**.cpp"))
-- Link external libraries
- add_deps("argparse", "imgui", "tinygltf", "tinyobjloader", "stb")
+ add_deps("argparse", "imgui", "tinygltf", "tinyobjloader", "stb", "glm")
-- Add libraries
add_packages("vulkansdk", "glfw", "fmt", "vulkan-memory-allocator", "spdlog", "glm")