์ดํ์ ์ฌ ๋ก๋ฉ์ ์ ๋๋ก ์ํํ๊ธฐ ์ ๊น์ง๋, ์ฌ๊ฐํ๋ณด๋ค ๋ ๋์ ๋ฉ์๊ฐ ํ์ํฉ๋๋ค. ์ด๋ฅผ ์ํด GLTF ํ์ผ๋ก๋ถํฐ ์ง์ค๋ฉํธ๋ฆฌ ์ ๋ณด๋ฅผ ์ ์ธํ ๋๋จธ์ง ์ ๋ณด๋ฅผ ๋ฌด์ํ๋ ๋จ์ํ ํธ๋ฒ์ ํตํด ์ด๋ฅผ ๋ถ๋ฌ์ค๊ฒ ์ต๋๋ค.
starting-point ๋ ํฌ์งํ ๋ฆฌ์๋ basic.glb๋ผ ๋ถ๋ฆฌ๋ GLTF ํ์ผ์ด ํฌํจ๋์ด ์์ต๋๋ค. ์ด ํ์ผ์๋ ์์ ์ ์ค์ฌ์ผ๋ก ๋ฐฐ์น๋ ํ๋ธ์ ๊ตฌ, ๊ทธ๋ฆฌ๊ณ ์์ญ์ด ๋จธ๋ฆฌ ๋ฉ์๊ฐ ๋ค์ด์์ต๋๋ค. ์ด์ฒ๋ผ ๋จ์ํ ํ์ผ์ด๊ธฐ ๋๋ฌธ์, ์ค์ GLTF ๋ก๋ฉ ์ค์ ์์ด๋ ์ฝ๊ฒ ๋ถ๋ฌ์ฌ ์ ์์ต๋๋ค.
GLTF ํ์ผ์ ๋ฉ์์ ๋ชฉ๋ก์ ํฌํจํ๋ฉฐ, ๊ฐ ๋ฉ์๋ ์ฌ๋ฌ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ก ๊ตฌ์ฑ๋ฉ๋๋ค. ์ด๋ ํ๋์ ๋ฉ์๊ฐ ์ฌ๋ฌ ๋จธํ ๋ฆฌ์ผ์ ์ฌ์ฉํ๋ ๊ฒฝ์ฐ๋ฅผ ์ฒ๋ฆฌํ๊ธฐ ์ํ ๊ตฌ์กฐ๋ก, ์ด๋ฅผ ๊ทธ๋ฆฌ๊ธฐ ์ํด ์ฌ๋ฌ ๋ฒ์ ๋๋ก์ฐ์ฝ์ด ํ์ํฉ๋๋ค. ๋ํ GLTF ํ์ผ์๋ ์ฌ-ํธ๋ฆฌ ํํ์ ์ฌ ๋ ธ๋๋ ํฌํจ๋์ด ์์ผ๋ฉฐ, ์ผ๋ถ ๋ ธ๋๋ ๋ฉ์๋ฅผ ํฌํจํฉ๋๋ค. ํ์ฌ๋ ๋ฉ์ ๋ฐ์ดํฐ๋ง ๋ก๋ฉํ๊ฒ ์ง๋ง, ์ถํ ์ ์ฒด ์ฌํธ๋ฆฌ์ ๋จธํ ๋ฆฌ์ผ๋ ๋ถ๋ฌ์ฌ ์์ ์ ๋๋ค.
ํ์ผ์ ๋ถ๋ฌ์ค๋ ๊ฒ๊ณผ ๊ด๋ จ๋ ์ฝ๋๋ vk_loader.cpp/h์ ์์ฑ๋์ด ์์ต๋๋ค.
๋จผ์ ๋ฉ์๋ฅผ ๋ถ๋ฌ์ค๋ ๋ฐ ํ์ํ ๋ ํด๋์ค๋ฅผ ์ถ๊ฐํฉ์๋ค.
#include <vk_types.h>
#include <unordered_map>
#include <filesystem>
struct GeoSurface {
uint32_t startIndex;
uint32_t count;
};
struct MeshAsset {
std::string name;
std::vector<GeoSurface> surfaces;
GPUMeshBuffers meshBuffers;
};
//forward declaration
class VulkanEngine;
์ฃผ์ด์ง MeshAsset์ ํ์ผ ์ด๋ฆ๊ณผ ๋ฉ์ ๋ฒํผ๋ฅผ ๊ฐ์ต๋๋ค. ๋ํ ํด๋น ๋ฉ์์ ํ์๋ฉ์๋ฅผ ๋ํ๋ด๋ GeoSurface ๊ฐ์ฒด์ ๋ฐฐ์ด๋ ํฌํจํฉ๋๋ค. ๊ฐ ์๋ธ๋ฉ์๋ฅผ ๋ ๋๋งํ ๋์๋ ๊ฐ๊ฐ ๋ณ๋์ ๋๋ก์ฐ์ฝ์ ์ํํ๊ฒ ๋ฉ๋๋ค. ์ฐ๋ฆฌ๋ ๋ชจ๋ ์๋ธ๋ฉ์์ ์ ์ ๋ฐ์ดํฐ๋ฅผ ํ๋์ ๋ฒํผ์ ์ด์ด๋ถ์ด๊ธฐ ๋๋ฌธ์, ๋๋ก์ฐ ์ฝ์์๋ StartIndex์ count๊ฐ์ ์ฌ์ฉํ๊ฒ ๋ฉ๋๋ค.
์ด๋ฅผ vk_loader.cpp์ ์ถ๊ฐํฉ์๋ค. ์ดํ ํ์ํ ๊ฒ์ ๋๋ค.
#include "stb_image.h"
#include <iostream>
#include <vk_loader.h>
#include "vk_engine.h"
#include "vk_initializers.h"
#include "vk_types.h"
#include <glm/gtx/quaternion.hpp>
#include <fastgltf/glm_element_traits.hpp>
#include <fastgltf/parser.hpp>
#include <fastgltf/tools.hpp>
ํ์ผ์ ๋ถ๋ฌ์ค๋ ํจ์๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
std::optional<std::vector<std::shared_ptr<MeshAsset>>> loadGltfMeshes(VulkanEngine* engine, std::filesystem::path filePath);
std::optional์ด ์ฒ์์ผ๋ก ๋ฑ์ฅํ๋ ๋ถ๋ถ์ ๋๋ค. std::optional์ ํ์ (์ฌ๊ธฐ์๋ ๋ฉ์ ์์ ์ vector)์ ๋ํํ๋ ํ์ค ํด๋์ค๋ก, ๊ฐ์ด ์๊ฑฐ๋ ์๋ฌ๊ฐ ๋ฐ์ํ ์ํ๋ฅผ ํํํ ์ ์๊ฒ ํด์ค๋๋ค. ์ฌ๋ฌ ์ด์ ๋ก ํ์ผ์ ๋ถ๋ฌ์ค๋ ๊ฒ์ด ์คํจํ ์ ์๊ธฐ ๋๋ฌธ์, null์ ๋ฐํํ ์ ์๊ฒ ํ๋ ํธ์ด ์ข์ต๋๋ค. ํ์ผ์ ๋ถ๋ฌ์ค๋๋ฐ ์๋ก์ด STL ๊ธฐ๋ฅ์ ํ์ฉํ๋ fastGltf ๋ผ์ด๋ธ๋ฌ๋ฆฌ๋ฅผ ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
์ด์ ํ์ผ์ ์ด์ด๋ด ์๋ค.
std::cout << "Loading GLTF: " << filePath << std::endl;
fastgltf::GltfDataBuffer data;
data.loadFromFile(filePath);
constexpr auto gltfOptions = fastgltf::Options::LoadGLBBuffers
| fastgltf::Options::LoadExternalBuffers;
fastgltf::Asset gltf;
fastgltf::Parser parser {};
auto load = parser.loadBinaryGLTF(&data, filePath.parent_path(), gltfOptions);
if (load) {
gltf = std::move(load.get());
} else {
fmt::print("Failed to load glTF: {} \n", fastgltf::to_underlying(load.error()));
return {};
}
์ง๊ธ์ ๋ฐ์ด๋๋ฆฌ GLTF๋ง์ ์ง์ํ๊ฒ ์ต๋๋ค. ๋ฐ๋ผ์ ๋จผ์ loadFromFile
๋ก ํ์ผ์ ์ด๊ณ loadBinaryGLTF๋ฅผ ํธ์ถํด ์ด๊ฒ ์ต๋๋ค. ์ด ๊ณผ์ ์์๋(์์ง ์ฌ์ฉํ์ง ์๋๋ผ๋) ์๋ ๊ฒฝ๋ก๋ฅผ ๊ณ์ฐํ๊ธฐ ์ํด ๋ถ๋ชจ ๋๋ ํ ๋ฆฌ ๊ฒฝ๋ก๊ฐ ํ์ํฉ๋๋ค.
๋ค์์ผ๋ก ๊ฐ ๋ฉ์๋ฅผ ์ํํ์ฌ ์ ์ ๊ณผ ์ธ๋ฑ์ค๋ฅผ ์์ std::vector๋ก ๋ณต์ฌํ๊ณ , ์ด๋ฅผ ์์ง์ ๋ฉ์๋ก ์
๋ก๋ ํ ๊ฒ์
๋๋ค. ์ด ๊ณผ์ ์์ ์ฌ๋ฌ MeshAsset
๊ฐ์ฒด๋ฅผ ๋ง๋ค์ด ๋ฐฐ์ด๋ก ๊ตฌ์ฑํ ๊ฒ์
๋๋ค.
std::vector<std::shared_ptr<MeshAsset>> meshes;
// use the same vectors for all meshes so that the memory doesnt reallocate as
// often
std::vector<uint32_t> indices;
std::vector<Vertex> vertices;
for (fastgltf::Mesh& mesh : gltf.meshes) {
MeshAsset newmesh;
newmesh.name = mesh.name;
// clear the mesh arrays each mesh, we dont want to merge them by error
indices.clear();
vertices.clear();
for (auto&& p : mesh.primitives) {
GeoSurface newSurface;
newSurface.startIndex = (uint32_t)indices.size();
newSurface.count = (uint32_t)gltf.accessors[p.indicesAccessor.value()].count;
size_t initial_vtx = vertices.size();
// load indexes
{
fastgltf::Accessor& indexaccessor = gltf.accessors[p.indicesAccessor.value()];
indices.reserve(indices.size() + indexaccessor.count);
fastgltf::iterateAccessor<std::uint32_t>(gltf, indexaccessor,
[&](std::uint32_t idx) {
indices.push_back(idx + initial_vtx);
});
}
// load vertex positions
{
fastgltf::Accessor& posAccessor = gltf.accessors[p.findAttribute("POSITION")->second];
vertices.resize(vertices.size() + posAccessor.count);
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, posAccessor,
[&](glm::vec3 v, size_t index) {
Vertex newvtx;
newvtx.position = v;
newvtx.normal = { 1, 0, 0 };
newvtx.color = glm::vec4 { 1.f };
newvtx.uv_x = 0;
newvtx.uv_y = 0;
vertices[initial_vtx + index] = newvtx;
});
}
// load vertex normals
auto normals = p.findAttribute("NORMAL");
if (normals != p.attributes.end()) {
fastgltf::iterateAccessorWithIndex<glm::vec3>(gltf, gltf.accessors[(*normals).second],
[&](glm::vec3 v, size_t index) {
vertices[initial_vtx + index].normal = v;
});
}
// load UVs
auto uv = p.findAttribute("TEXCOORD_0");
if (uv != p.attributes.end()) {
fastgltf::iterateAccessorWithIndex<glm::vec2>(gltf, gltf.accessors[(*uv).second],
[&](glm::vec2 v, size_t index) {
vertices[initial_vtx + index].uv_x = v.x;
vertices[initial_vtx + index].uv_y = v.y;
});
}
// load vertex colors
auto colors = p.findAttribute("COLOR_0");
if (colors != p.attributes.end()) {
fastgltf::iterateAccessorWithIndex<glm::vec4>(gltf, gltf.accessors[(*colors).second],
[&](glm::vec4 v, size_t index) {
vertices[initial_vtx + index].color = v;
});
}
newmesh.surfaces.push_back(newSurface);
}
// display the vertex normals
constexpr bool OverrideColors = true;
if (OverrideColors) {
for (Vertex& vtx : vertices) {
vtx.color = glm::vec4(vtx.normal, 1.f);
}
}
newmesh.meshBuffers = engine->uploadMesh(indices, vertices);
meshes.emplace_back(std::make_shared<MeshAsset>(std::move(newmesh)));
}
return meshes;
๋ฉ์์ ๊ฐ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ฅผ ์ํํ๋ฉด์ iterateAccessor
ํจ์๋ฅผ ์ฌ์ฉํด ์ํ๋ ์ ์ ๋ฐ์ดํฐ์ ์ ๊ทผํฉ๋๋ค. ์ฌ๋ฌ ํ๋ฆฌ๋ฏธํฐ๋ธ๋ฅผ ์ ์ ๋ฐฐ์ด์ ์ถ๊ฐํ ๋๋ ์ธ๋ฑ์ค ๋ฒํผ๋ ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑํด์ผ ํฉ๋๋ค. ๋ง์ง๋ง์ผ๋ก๋ uploadMesh๋ฅผ ํธ์ถํ์ฌ ์ต์ข
๋ฒํผ๋ฅผ ์์ฑํ๊ณ , ๋ฉ์ ๋ชฉ๋ก์ ๋ฐํํฉ๋๋ค.
์ปดํ์ผ ์ ํ๋๊ทธ์ธ OverrideColors๊ฐ ์ค์ ๋์ด ์๋ค๋ฉด, ์ ์ ์์์ ๋๋ฒ๊น ์ ์ ์ฉํ ๋ฒ์ ๋ฒกํฐ๋ก ๋ฎ์ด์๋๋ค.
์์น ๋ฐฐ์ด์ ํญ์ ์กด์ฌํ๋ฏ๋ก, Vertex ๊ตฌ์กฐ์ฒด๋ฅผ ์ด๊ธฐํํฉ๋๋ค. ๋ค๋ฅธ ๋ชจ๋ ์์ฑ์ ์กด์ฌ ์ฌ๋ถ๋ฅผ ํ์ธ ํ ์ด๊ธฐํํด์ผ ํฉ๋๋ค.
์ด์ ์ด๋ฅผ ๊ทธ๋ ค๋ด ์๋ค.
std::vector<std::shared_ptr<MeshAsset>> testMeshes;
๋จผ์ ์ด๋ฅผ VulkanEngine ํด๋์ค์ ์ถ๊ฐํฉ๋๋ค. init_default_data()
์์ ๋ถ๋ฌ์ vk_engine์ include ๋ชฉ๋ก์ #include <vk_loader.h>
๋ฅผ ์ถ๊ฐํฉ๋๋ค.
testMeshes = loadGltfMeshes(this,"..\\..\\assets\\basicmesh.glb").value();
์ ๊ณต๋ ํ์ผ์๋ ์ธ๋ฑ์ค 0๋ฒ์ ํ๋ธ, ์ธ๋ฑ์ค 1๋ฒ์ ๊ตฌ, ๊ทธ๋ฆฌ๊ณ ์ธ๋ฑ์ค 2๋ฒ์๋ ์์ญ์ด ๋จธ๋ฆฌ๊ฐ ํฌํจ๋์ด ์์ต๋๋ค. ๋ง์ง๋ง ๋ฉ์ ๊ฒ์ ๊ทธ๋ฆด ๊ฒ์ด๋ฉฐ, ์ด์ ์ ๊ทธ๋ฆฐ ์ฌ๊ฐํ ๋ฐ๋ก ๋ค์์ ๊ทธ๋ฆฌ๋๋ก ํ๊ฒ ์ต๋๋ค.
push_constants.vertexBuffer = testMeshes[2]->meshBuffers.vertexBufferAddress;
vkCmdPushConstants(cmd, _meshPipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(GPUDrawPushConstants), &push_constants);
vkCmdBindIndexBuffer(cmd, testMeshes[2]->meshBuffers.indexBuffer.buffer, 0, VK_INDEX_TYPE_UINT32);
vkCmdDrawIndexed(cmd, testMeshes[2]->surfaces[0].count, 1, testMeshes[2]->surfaces[0].startIndex, 0, 0);
์ด์ ์์ญ์ด ๋จธ๋ฆฌ๊ฐ ์์๊ณผ ํจ๊ป ๋ ๋๋ง ๋ ๊ฒ์ ๋ณผ ์ ์์ต๋๋ค. OverrideColors
๋ฅผ ์ง๊ธ์ true๋ก ์ค์ ํ๊ธฐ ๋๋ฌธ์ ๋ฒ์ ๋ฒกํฐ๊ฐ์ด ์์์ผ๋ก ๋ํ๋ฉ๋๋ค. ํ์ฌ ์
ฐ์ด๋์์๋ ์กฐ๋ช
์ด ์ ์ฉ๋์ง ์์๊ธฐ ๋๋ฌธ์, ์ด ์ต์
์ ๋๋ฉด ์์ญ์ด ๋จธ๋ฆฌ๋ ์์ํ ํฐ์์ผ๋ก ํ์๋ฉ๋๋ค.
์ด์ ์์ญ์ด ๋จธ๋ฆฌ๊ฐ ๋ณด์ด์ง๋ง, ๊ฑฐ๊พธ๋ก ๋ค์งํ ์์ต๋๋ค. ๋ณํ ํ๋ ฌ์ ์กฐ์ ํด๋ด ์๋ค.
GLTF์์ ์ถ์ OpenGL์์์ ๊ฐ์ต๋๋ค. OpenGL์์๋ Y์ถ์ด ์ ๋ฐฉํฅ์ ๊ฐ๋ฆฌํค์ง๋ง Vulkan์์๋ Y์ถ์ด ์๋ ๋ฐฉํฅ์ด๊ธฐ ๋๋ฌธ์ ๊ฒฐ๊ณผ์ ์ผ๋ก ํ๋ฉด์ด ๋ค์งํ ๋ณด์ด๊ฒ ๋ฉ๋๋ค. ์ด๋ฅผ ํด๊ฒฐํ๋ ๋ฐฉ๋ฒ์๋ 2๊ฐ์ง ๋ฐฉ๋ฒ์ด ์์ต๋๋ค. ํ๋๋ ๋ทฐํฌํธ๋ฅผ ๋ค์ง์ด ์ ์ฒด ๋ ๋๋ง ๊ฒฐ๊ณผ๋ฅผ ๋ค์ง๋ ๋ฐฉ์์ด๋ฉฐ, ์ด๋ DirectX์ ์ ์ฌํฉ๋๋ค. ๋ ๋ฒ์งธ๋ ํฌ์ ํ๋ ฌ์ Y์ถ ๋ฐ์ ์ ํฌํจํ๋ ๋ฐฉ์์ ๋๋ค. ์ฐ๋ฆฌ๋ ํ์๋ฅผ ์ํํ๊ฒ ์ต๋๋ค.
๋ ๋๋ง ์ฝ๋์์ ๋ ์ ์ ํ ๋ณํ ํ๋ ฌ์ ์ ์ฉํ๊ฒ ์ต๋๋ค. ์๋ ์ฝ๋๋ฅผ draw_geometry()
์ ํธ์์์ ํธ์ถ ์ง์ ์ ์ถ๊ฐํฉ๋๋ค.
glm::mat4 view = glm::translate(glm::vec3{ 0,0,-5 });
// camera projection
glm::mat4 projection = glm::perspective(glm::radians(70.f), (float)_drawExtent.width / (float)_drawExtent.height, 10000.f, 0.1f);
// invert the Y direction on projection matrix so that we are more similar
// to opengl and gltf axis
projection[1][1] *= -1;
push_constants.worldMatrix = projection * view;
#include <glm/gtx/transform.hpp>
๋ฅผ vk_engine์ ์๋จ์ ์ถ๊ฐํฉ๋๋ค. ๊ทธ๋ฌ๋ฉด cpp์์ ๋ณํ ํจ์๋ค์ ์ฌ์ฉํ ์ ์๊ฒ ๋ฉ๋๋ค.
๋จผ์ ์นด๋ฉ๋ผ ์์ ์ ๋ทฐ ํ๋ ฌ์ ๊ณ์ฐํฉ๋๋ค. ํ์ฌ๋ ๋ค๋ก ์์ง์ด๋ ๋ณํ ํ๋ ฌ๋ก ์ถฉ๋ถํฉ๋๋ค.
ํฌ์ ํ๋ ฌ์๋ ์ฝ๊ฐ์ ๊ผผ์๋ฅผ ์ฌ์ฉํ์ต๋๋ค. near ๊ฐ์๋ 10000์, far ๊ฐ์๋ 0.1์ ์ ๋ฌํจ์ ์ฃผ๋ชฉํ์ธ์. ๊น์ด๋ฅผ ๋ค์ง์ด 1์ด near plane, ๊น์ด 0์ด far plane์ด ๋๋๋ก ํ๊ธฐ ์ํจ์ ๋๋ค. ์ด ๋ฐฉ์์ ๊น์ด ํ ์คํธ์ ํ์ง์ ๋์ด๋ ๊ธฐ๋ฒ ์ค ํ๋์ ๋๋ค.
์ฌ๊ธฐ์ ์์ง์ ์คํํ๋ค๋ฉด ์์ญ์ด ๋ชจ๋ธ์ด ์ฝ๊ฐ ๊นจ์ง ๊ฒ์ฒ๋ผ ๋ณด์ผ ์ ์์ต๋๋ค. ๊น์ด ํ ์คํธ๋ฅผ ์ํํ์ง ์์๊ธฐ ๋๋ฌธ์ ๋๋ค. ๋ฐ๋ผ์ ๋จธ๋ฆฌ ๋ค์ชฝ์ ์ผ๊ฐํ์ด ์์ชฝ์ ์ผ๊ฐํ์ ๋ฎ์ด์จ ์๋ชป๋ ์ด๋ฏธ์ง๋ฅผ ์์ฑํ ๊ฒ์ ๋๋ค. ๊น์ด ํ ์คํธ๋ฅผ ๊ตฌํํด๋ด ์๋ค.
์ด์ ๋ ๋๋ง ์ drawimage์ ํจ๊ป ์ฌ์ฉํ ์๋ก์ด ์ด๋ฏธ์ง๋ฅผ VulkanEngineํด๋์ค์ ์ถ๊ฐํด๋ด ์๋ค.
AllocatedImage _drawImage;
AllocatedImage _depthImage;
์ด์ drawImage๋ฅผ ๋ฐ๋ผ init_swapchainํจ์์์ ์ด๊ธฐํํฉ๋๋ค.
_depthImage.imageFormat = VK_FORMAT_D32_SFLOAT;
_depthImage.imageExtent = drawImageExtent;
VkImageUsageFlags depthImageUsages{};
depthImageUsages |= VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT;
VkImageCreateInfo dimg_info = vkinit::image_create_info(_depthImage.imageFormat, depthImageUsages, drawImageExtent);
//allocate and create the image
vmaCreateImage(_allocator, &dimg_info, &rimg_allocinfo, &_depthImage.image, &_depthImage.allocation, nullptr);
//build a image-view for the draw image to use for rendering
VkImageViewCreateInfo dview_info = vkinit::imageview_create_info(_depthImage.imageFormat, _depthImage.image, VK_IMAGE_ASPECT_DEPTH_BIT);
VK_CHECK(vkCreateImageView(_device, &dview_info, nullptr, &_depthImage.imageView));
๊น์ด ์ด๋ฏธ์ง๋ drawImage์ ๋์ผํ ๋ฐฉ์์ผ๋ก ์ด๊ธฐํ๋์ง๋ง, Usageํ๋๊ทธ์ VK_IMAGE_USAGE_DEPTH_STENCIL_ATTACHMENT_BIT
๋ฅผ ์ ๋ฌํ๊ณ ์์ผ๋ฉฐ, ๊น์ด ํฌ๋งท์ผ๋ก VK_FORMAT_D32_SFLOAT
๋ฅผ ์ฌ์ฉํ๊ณ ์์ต๋๋ค.
๋ํ ๊น์ด ์ด๋ฏธ์ง๋ฅผ ์ญ์ ํ์ ๋ฃ๋ ๊ฒ์ ์์ง ๋ง์ธ์.
_mainDeletionQueue.push_function([=]() {
vkDestroyImageView(_device, _drawImage.imageView, nullptr);
vmaDestroyImage(_allocator, _drawImage.image, _drawImage.allocation);
vkDestroyImageView(_device, _depthImage.imageView, nullptr);
vmaDestroyImage(_allocator, _depthImage.image, _depthImage.allocation);
});
๋ ๋๋ง ๋ฃจํ์์ ๊น์ด ์ด๋ฏธ์ง๋ฅผ drawImage์์์ ๋์ผํ ๋ฐฉ์์ผ๋ก VK_IMAGE_LAYOUT_UNDEFINED
์์ VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL
๋ชจ๋๋ก ์ ํํ ๊ฒ์
๋๋ค. ์ด๋ draw_geometry()
ํธ์ถ ์ง์ ์ ์ํ๋ฉ๋๋ค.
vkutil::transition_image(cmd, _drawImage.image, VK_IMAGE_LAYOUT_GENERAL, VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL);
vkutil::transition_image(cmd, _depthImage.image, VK_IMAGE_LAYOUT_UNDEFINED, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
์ด์ renderPassBeginInfo๋ฅผ ์ด ๊น์ด ์ดํ์น๋จผํธ๋ฅผ ์ฌ์ฉํ๋๋ก ์ค์ ํ๊ณ , ์ฌ๋ฐ๋ฅด๊ฒ ์ด๊ธฐํํด์ผ ํฉ๋๋ค. draw_geometry()
์๋จ์ ์๋์ ๊ฐ์ด ๋ฐ๊ฟ์ค๋๋ค.
VkRenderingAttachmentInfo colorAttachment = vkinit::attachment_info(_drawImage.imageView, nullptr, VK_IMAGE_LAYOUT_GENERAL);
VkRenderingAttachmentInfo depthAttachment = vkinit::depth_attachment_info(_depthImage.imageView, VK_IMAGE_LAYOUT_DEPTH_ATTACHMENT_OPTIMAL);
VkRenderingInfo renderInfo = vkinit::rendering_info(_windowExtent, &colorAttachment, &depthAttachment);
rendering_info๋ฅผ ์ํด vkinit ๊ตฌ์กฐ์ฒด์ ๊น์ด ์ดํ์น๋จผํธ๋ฅผ ์ํ ๊ณต๊ฐ์ ๋ง๋ จํด๋์์ง๋ง, ๊น์ด ๊ฐ์ ์ฌ๋ฐ๋ฅด๊ฒ ์ด๊ธฐํํ๊ธฐ ์ํ clear ๊ฐ๋ ์ค์ ํด์ผ ํฉ๋๋ค. ์ด์ depth_attachment_info๋ฅผ ์ํด vkinit ๊ตฌํ๋ถ๋ฅผ ์ดํด๋ด ์๋ค.
VkRenderingAttachmentInfo vkinit::depth_attachment_info(
VkImageView view, VkImageLayout layout /*= VK_IMAGE_LAYOUT_COLOR_ATTACHMENT_OPTIMAL*/)
{
VkRenderingAttachmentInfo depthAttachment {};
depthAttachment.sType = VK_STRUCTURE_TYPE_RENDERING_ATTACHMENT_INFO;
depthAttachment.pNext = nullptr;
depthAttachment.imageView = view;
depthAttachment.imageLayout = layout;
depthAttachment.loadOp = VK_ATTACHMENT_LOAD_OP_CLEAR;
depthAttachment.storeOp = VK_ATTACHMENT_STORE_OP_STORE;
depthAttachment.clearValue.depthStencil.depth = 0.f;
return depthAttachment;
}
์์ ์ดํ์น๋จผํธ์์ ์ํํ๋ ์์ ๊ณผ ์ ์ฌํ์ง๋ง, loadOP๋ฅผ clear๋ก, ๊ทธ๋ฆฌ๊ณ ๊น์ด ์ด๊ธฐํ ๊ฐ์ 0.f๋ก ์ค์ ํ์ต๋๋ค. ๊น์ด 0์ far ๊ฐ์ผ๋ก, 1์ near ๊ฐ์ผ๋ก ์ฌ์ฉํ ๊ฒ์ ๋๋ค.
๋จ์ ์ผ์ ํ์ดํ๋ผ์ธ์์ ๊น์ดํ ์คํธ๋ฅผ ํ์ฑํํ๋ ๊ฒ์ ๋๋ค. ์์ฑํ pipelineBuilder์์ ๊น์ด ์ต์ ์ ๋ง๋ค์ด ๋์์ง๋ง ํ์ฑํํ์ง๋ ์์์ต๋๋ค. ํด๋น ๊ธฐ๋ฅ์ ์ฑ์ฐ๋ ํจ์๋ฅผ PipelineBuilder์ ์ถ๊ฐํฉ๋๋ค.
void PipelineBuilder::enable_depthtest(bool depthWriteEnable, VkCompareOp op)
{
_depthStencil.depthTestEnable = VK_TRUE;
_depthStencil.depthWriteEnable = depthWriteEnable;
_depthStencil.depthCompareOp = op;
_depthStencil.depthBoundsTestEnable = VK_FALSE;
_depthStencil.stencilTestEnable = VK_FALSE;
_depthStencil.front = {};
_depthStencil.back = {};
_depthStencil.minDepthBounds = 0.f;
_depthStencil.maxDepthBounds = 1.f;
}
์คํ ์ค ๋ถ๋ถ์ ์์ง ๋น์๋์ง๋ง, ๊น์ด ํ ์คํธ๋ฅผ ํ์ฑํ ํ ํ depthOp๋ฅผ ๊ตฌ์กฐ์ฒด์ ์ ๋ฌํฉ๋๋ค.
์ด์ ์ด ์ค์ ์ ์ค์ ํ์ดํ๋ผ์ธ ์์ฑ์ ๋ฐ์ํ ์ฐจ๋ก์
๋๋ค. init_mesh_pipeline
์ ๋ฐ๊ฟ๋ด
์๋ค.
//pipelineBuilder.disable_depthtest();
pipelineBuilder.enable_depthtest(true, VK_COMPARE_OP_GREATER_OR_EQUAL);
//connect the image format we will draw into, from draw image
pipelineBuilder.set_color_attachment_format(_drawImage.imageFormat);
pipelineBuilder.set_depth_format(_depthImage.imageFormat);
ํ์ดํ๋ผ์ธ ๋น๋์์ enable_depthtest ํจ์๋ฅผ ํธ์ถํ๊ณ , depthWrite๋ฅผ ํ์ฑํํ๋ฉฐ, ์ฐ์ฐ์๋ก GREATER_OR_EQUAL์ ์ ๋ฌํฉ๋๋ค. ์์ ์ค๋ช ํ ๊ฒ์ฒ๋ผ ๊น์ด 0์ด far์ด๊ณ 1์ด near์ด๋ฏ๋ก ํ์ฌ ํฝ์ ์ด ๊น์ด ์ด๋ฏธ์ง์ ๊ฐ๋ณด๋ค ๋ ํฐ ๊ฒฝ์ฐ์๋ง ๋ ๋๋ง๋๋๋ก ์ค์ ํ๋ ๊ฒ์ ๋๋ค.
init_triangle_pipeline
ํจ์์ set_depth_format
ํธ์ถ ๋ถ๋ถ๋ ์์ ํฉ๋๋ค. ๋น๋ก ๊น์ด ํ
์คํธ๊ฐ ๋นํ์ฑํ๋์๋๋ผ๋ ๋ ๋ ํจ์ค๊ฐ ์ฌ๋ฐ๋ฅด๊ฒ ์๋ํ๊ณ ๊ฒ์ฆ๋ ์ด์ด๊ฐ ๊ฒฝ๊ณ ๋ฅผ ์ถ๋ ฅํ์ง ์๋๋ก ์ ํํ ํฌ๋งท์ ์ค์ ํด์ผ ํฉ๋๋ค.
์ด์ ์์ง์ ์คํํ๋ฉด ์์ญ์ด ๋ชจ๋ธ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๋ ๋๋ง ๋ ๊ฒ์ ๋๋ค. ์ผ๊ฐํ๊ณผ ์ฌ๊ฐํ์๋ ๊น์ด ํ ์คํธ ์ค์ ์ด ๋์ง ์์๊ธฐ ๋๋ฌธ์ ๊น์ด ์ดํ์น๋จผํธ์์ ์ฝ๊ฑฐ๋ ์ฐ์ง ์์ผ๋ฉฐ, ๊ทธ ๊ฒฐ๊ณผ ๋ํ๋ค์ด ์์ญ์ด ๋ชจ๋ธ ๋ค์ ์์์๋ ์์ ๋ ๋๋ง๋ฉ๋๋ค.
์๋กญ๊ฒ ์์ฑ๋ ๋ฉ์๋ค์ ์ ๋ฆฌํ๊ธฐ ์ํด, cleanup ํจ์์์ ๋ฉ์ธ ์ญ์ ํ๋ฅผ ์ ๋ฆฌํ๊ธฐ ์ ์ ๋ฉ์ ๋ฐฐ์ด์ ํฌํจ๋ ๋ฒํผ๋ค์ ๋ช ์์ ์ผ๋ก ํ๊ดดํด ์ค๋๋ค.
for (auto& mesh : testMeshes) {
destroy_buffer(mesh->meshBuffers.indexBuffer);
destroy_buffer(mesh->meshBuffers.vertexBuffer);
}
_mainDeletionQueue.flush();
๋ค์ ์์
์ ์งํํ๊ธฐ ์ ์, ์ฌ๊ฐํ ๋ฉ์์ ๋ฐฐ๊ฒฝ์ ์ผ๊ฐํ ์ฝ๋๋ ์ง์ฐ๋๋ก ํ๊ฒ ์ต๋๋ค. ์ด์ ๋์ด์ ํ์ํ์ง ์์ต๋๋ค. init_triangle_pipeline
ํจ์์ ๊ด๋ จ๋ ๊ฐ์ฒด๋ค, ๊ทธ๋ฆฌ๊ณ init_default_data
์ ์๋ ์ฌ๊ฐํ๊ณผ ๊ด๋ จ ์ฝ๋๋ฅผ ์ ๊ฑฐํฉ๋๋ค. draw_geometry
์์๋ vkCmdSetViewport
์ vkCmdSetScissor
ํธ์ถ์ vkCmdBindPipeline(cmd,VK_PIPELINE_BIND_POINT_GRAPHICS, _meshPipeline);
ํธ์ถ ์ดํ๋ก ์ฎ๊ฒจ์ผ ํฉ๋๋ค. ์ผ๊ฐํ ํ์ดํ๋ผ์ธ์ ๋ฐ์ธ๋ฉํ๋ ์ฝ๋๊ฐ ์ญ์ ๋์๊ธฐ ๋๋ฌธ์, ํด๋น ์ํ ์ค์ ์ ํ์ดํ๋ผ์ธ ๋ฐ์ธ๋ฉ ์ดํ์ ์ํ๋์ด์ผ ํฉ๋๋ค.
๋ค์์ ํฌ๋ช ํ ๊ฐ์ฒด์ ๋ธ๋ ๋ฉ์ ์ค์ ํ๊ฒ ์ต๋๋ค.
Next: Blending