PeriDyno 1.0.0
Loading...
Searching...
No Matches
VulkanglTFModel.h
Go to the documentation of this file.
1/*
2* Vulkan glTF model and texture loading class based on tinyglTF (https://github.com/syoyo/tinygltf)
3*
4* Copyright (C) 2018 by Sascha Willems - www.saschawillems.de
5*
6* This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT)
7*/
8
9#pragma once
10
11#include <stdlib.h>
12#include <string>
13#include <fstream>
14#include <vector>
15
16#include "vulkan/vulkan.h"
17#include "VkContext.h"
18
19#include <ktx.h>
20#include <ktxvulkan.h>
21
22#define GLM_FORCE_RADIANS
23#define GLM_FORCE_DEPTH_ZERO_TO_ONE
24#include <glm/glm.hpp>
25#include <glm/gtc/matrix_transform.hpp>
26#include <glm/gtc/type_ptr.hpp>
27
28#define TINYGLTF_NO_STB_IMAGE_WRITE
29#ifdef VK_USE_PLATFORM_ANDROID_KHR
30#define TINYGLTF_ANDROID_LOAD_FROM_ASSETS
31#endif
32#include "tiny_gltf.h"
33
34#if defined(__ANDROID__)
35#include <android/asset_manager.h>
36#endif
37
38namespace vkglTF
39{
41 ImageBaseColor = 0x00000001,
42 ImageNormalMap = 0x00000002
43 };
44
45 extern VkDescriptorSetLayout descriptorSetLayoutImage;
46 extern VkDescriptorSetLayout descriptorSetLayoutUbo;
47 extern VkMemoryPropertyFlags memoryPropertyFlags;
48 extern uint32_t descriptorBindingFlags;
49
50 struct Node;
51
52 /*
53 glTF texture loading class
54 */
55 class Texture {
56 public:
57 Texture();
58 ~Texture();
59
61 VkImage image;
62 VkImageLayout imageLayout;
63 VkDeviceMemory deviceMemory;
64 VkImageView view;
65 uint32_t width, height;
66 uint32_t mipLevels;
67 uint32_t layerCount;
68 VkDescriptorImageInfo descriptor;
69 VkSampler sampler;
70 void updateDescriptor();
71 void destroy();
72 void fromglTfImage(tinygltf::Image& gltfimage, std::string path);
73 };
74
75 /*
76 glTF material class
77 */
78 class Material {
79 public:
83 float alphaCutoff = 1.0f;
84 float metallicFactor = 1.0f;
85 float roughnessFactor = 1.0f;
86 glm::vec4 baseColorFactor = glm::vec4(1.0f);
92
95
96 VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
97
98 Material(dyno::VkContext* device) : ctx(device) {};
99 void createDescriptorSet(VkDescriptorPool descriptorPool, VkDescriptorSetLayout descriptorSetLayout, uint32_t descriptorBindingFlags);
100 };
101
102 /*
103 glTF primitive
104 */
105 struct Primitive {
106 uint32_t firstIndex;
107 uint32_t indexCount;
108 uint32_t firstVertex;
109 uint32_t vertexCount;
111
112 struct Dimensions {
113 glm::vec3 min = glm::vec3(FLT_MAX);
114 glm::vec3 max = glm::vec3(-FLT_MAX);
115 glm::vec3 size;
116 glm::vec3 center;
117 float radius;
119
120 void setDimensions(glm::vec3 min, glm::vec3 max);
122 };
123
124 /*
125 glTF mesh
126 */
127 struct Mesh {
128 public:
129 Mesh(glm::mat4 matrix);
130 ~Mesh();
131
132 std::vector<Primitive*> primitives;
133 std::string name;
134
136 VkBuffer buffer;
137 VkDeviceMemory memory;
138 VkDescriptorBufferInfo descriptor;
139 VkDescriptorSet descriptorSet = VK_NULL_HANDLE;
140 void* mapped;
142
144 glm::mat4 matrix;
145 glm::mat4 jointMatrix[64]{};
146 float jointcount{ 0 };
148
149 protected:
151 };
152
153 /*
154 glTF skin
155 */
156 struct Skin {
157 std::string name;
158 Node* skeletonRoot = nullptr;
159 std::vector<glm::mat4> inverseBindMatrices;
160 std::vector<Node*> joints;
161 };
162
163 /*
164 glTF node
165 */
166 struct Node {
168 uint32_t index;
169 std::vector<Node*> children;
170 glm::mat4 matrix;
171 std::string name;
174 int32_t skinIndex = -1;
175 glm::vec3 translation{};
176 glm::vec3 scale{ 1.0f };
177 glm::quat rotation{};
178 glm::mat4 localMatrix();
179 glm::mat4 getMatrix();
180 void update();
181 ~Node();
182 };
183
184 /*
185 glTF animation channel
186 */
193
194 /*
195 glTF animation sampler
196 */
200 std::vector<float> inputs;
201 std::vector<glm::vec4> outputsVec4;
202 };
203
204 /*
205 glTF animation
206 */
207 struct Animation {
208 std::string name;
209 std::vector<AnimationSampler> samplers;
210 std::vector<AnimationChannel> channels;
211 float start = std::numeric_limits<float>::max();
212 float end = std::numeric_limits<float>::min();
213 };
214
215 /*
216 glTF default vertex layout with easy Vulkan mapping functions
217 */
219
220 struct Vertex {
221 glm::vec3 pos;
222 glm::vec3 normal;
223 glm::vec2 uv;
224 glm::vec4 color;
225 glm::vec4 joint0;
226 glm::vec4 weight0;
227 glm::vec4 tangent;
228 static VkVertexInputBindingDescription vertexInputBindingDescription;
229 static std::vector<VkVertexInputAttributeDescription> vertexInputAttributeDescriptions;
230 static VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo;
231 static VkVertexInputBindingDescription inputBindingDescription(uint32_t binding);
232 static VkVertexInputAttributeDescription inputAttributeDescription(uint32_t binding, uint32_t location, VertexComponent component);
233 static std::vector<VkVertexInputAttributeDescription> inputAttributeDescriptions(uint32_t binding, const std::vector<VertexComponent> components);
235 static VkPipelineVertexInputStateCreateInfo* getPipelineVertexInputState(const std::vector<VertexComponent> components);
236 };
237
239 None = 0x00000000,
242 FlipY = 0x00000004,
243 DontLoadImages = 0x00000008
244 };
245
247 BindImages = 0x00000001,
248 RenderOpaqueNodes = 0x00000002,
251 };
252
253 /*
254 glTF model loading and rendering class
255 */
256 class Model {
257 public:
258 Model();
259 ~Model();
260 void loadNode(vkglTF::Node* parent, const tinygltf::Node& node, uint32_t nodeIndex, const tinygltf::Model& model, std::vector<uint32_t>& indexBuffer, std::vector<Vertex>& vertexBuffer, float globalscale);
261 void loadSkins(tinygltf::Model& gltfModel);
262 void loadImages(tinygltf::Model& gltfModel);
263 void loadMaterials(tinygltf::Model& gltfModel);
264 void loadAnimations(tinygltf::Model& gltfModel);
265 void loadFromFile(std::string filename, uint32_t fileLoadingFlags = vkglTF::FileLoadingFlags::None, float scale = 1.0f);
266 void bindBuffers(VkCommandBuffer commandBuffer);
267 void drawNode(Node* node, VkCommandBuffer commandBuffer, uint32_t renderFlags = 0, VkPipelineLayout pipelineLayout = VK_NULL_HANDLE, uint32_t bindImageSet = 1);
268 void draw(VkCommandBuffer commandBuffer, uint32_t renderFlags = 0, VkPipelineLayout pipelineLayout = VK_NULL_HANDLE, uint32_t bindImageSet = 1);
269 void getNodeDimensions(Node* node, glm::vec3& min, glm::vec3& max);
270 void getSceneDimensions();
271 void updateAnimation(uint32_t index, float time);
272 Node* findNode(Node* parent, uint32_t index);
273 Node* nodeFromIndex(uint32_t index);
274 void prepareNodeDescriptor(vkglTF::Node* node, VkDescriptorSetLayout descriptorSetLayout);
275
276 private:
277 vkglTF::Texture* getTexture(uint32_t index);
279 void createEmptyTexture(VkQueue transferQueue);
280
281 protected:
283
284 public:
285 VkDescriptorPool descriptorPool;
286
287 struct Vertices {
288 int count;
289 VkBuffer buffer;
290 VkDeviceMemory memory;
292 struct Indices {
293 int count;
294 VkBuffer buffer;
295 VkDeviceMemory memory;
297
298 std::vector<Node*> nodes;
299 std::vector<Node*> linearNodes;
300
301 std::vector<Skin*> skins;
302
303 std::vector<Texture> textures;
304 std::vector<Material> materials;
305 std::vector<Animation> animations;
306
307 struct Dimensions {
308 glm::vec3 min = glm::vec3(FLT_MAX);
309 glm::vec3 max = glm::vec3(-FLT_MAX);
310 glm::vec3 size;
311 glm::vec3 center;
312 float radius;
314
316 bool buffersBound = false;
317 std::string path;
318 };
319}
Definition Node.h:68
vkglTF::Texture * specularGlossinessTexture
vkglTF::Texture * diffuseTexture
Material(dyno::VkContext *device)
vkglTF::Texture * metallicRoughnessTexture
dyno::VkContext * ctx
VkDescriptorSet descriptorSet
void createDescriptorSet(VkDescriptorPool descriptorPool, VkDescriptorSetLayout descriptorSetLayout, uint32_t descriptorBindingFlags)
vkglTF::Texture * normalTexture
glm::vec4 baseColorFactor
vkglTF::Texture * occlusionTexture
vkglTF::Texture * emissiveTexture
vkglTF::Texture * baseColorTexture
void loadFromFile(std::string filename, uint32_t fileLoadingFlags=vkglTF::FileLoadingFlags::None, float scale=1.0f)
void drawNode(Node *node, VkCommandBuffer commandBuffer, uint32_t renderFlags=0, VkPipelineLayout pipelineLayout=VK_NULL_HANDLE, uint32_t bindImageSet=1)
struct vkglTF::Model::Indices indices
void loadNode(vkglTF::Node *parent, const tinygltf::Node &node, uint32_t nodeIndex, const tinygltf::Model &model, std::vector< uint32_t > &indexBuffer, std::vector< Vertex > &vertexBuffer, float globalscale)
std::vector< Node * > nodes
struct vkglTF::Model::Vertices vertices
void bindBuffers(VkCommandBuffer commandBuffer)
vkglTF::Texture * getTexture(uint32_t index)
std::string path
std::vector< Texture > textures
void loadMaterials(tinygltf::Model &gltfModel)
void createEmptyTexture(VkQueue transferQueue)
void prepareNodeDescriptor(vkglTF::Node *node, VkDescriptorSetLayout descriptorSetLayout)
void updateAnimation(uint32_t index, float time)
VkDescriptorPool descriptorPool
Node * findNode(Node *parent, uint32_t index)
void getNodeDimensions(Node *node, glm::vec3 &min, glm::vec3 &max)
std::vector< Material > materials
void loadAnimations(tinygltf::Model &gltfModel)
std::vector< Animation > animations
std::vector< Skin * > skins
bool metallicRoughnessWorkflow
std::vector< Node * > linearNodes
void draw(VkCommandBuffer commandBuffer, uint32_t renderFlags=0, VkPipelineLayout pipelineLayout=VK_NULL_HANDLE, uint32_t bindImageSet=1)
Node * nodeFromIndex(uint32_t index)
void loadImages(tinygltf::Model &gltfModel)
vkglTF::Texture emptyTexture
dyno::VkContext * ctx
struct vkglTF::Model::Dimensions dimensions
void loadSkins(tinygltf::Model &gltfModel)
void fromglTfImage(tinygltf::Image &gltfimage, std::string path)
VkDescriptorImageInfo descriptor
dyno::VkContext * ctx
VkImageLayout imageLayout
VkDeviceMemory deviceMemory
VkDescriptorSetLayout descriptorSetLayoutImage
VkMemoryPropertyFlags memoryPropertyFlags
VkDescriptorSetLayout descriptorSetLayoutUbo
uint32_t descriptorBindingFlags
@ PreTransformVertices
@ PreMultiplyVertexColors
@ RenderAlphaBlendedNodes
@ RenderAlphaMaskedNodes
std::vector< AnimationSampler > samplers
std::vector< AnimationChannel > channels
InterpolationType interpolation
std::vector< glm::vec4 > outputsVec4
std::vector< float > inputs
VkDescriptorBufferInfo descriptor
dyno::VkContext * ctx
std::vector< Primitive * > primitives
struct vkglTF::Mesh::UniformBuffer uniformBuffer
Mesh(glm::mat4 matrix)
std::string name
struct vkglTF::Mesh::UniformBlock uniformBlock
std::vector< Node * > children
std::string name
glm::quat rotation
glm::vec3 translation
glm::mat4 getMatrix()
glm::mat4 localMatrix()
Primitive(uint32_t firstIndex, uint32_t indexCount, Material &material)
struct vkglTF::Primitive::Dimensions dimensions
void setDimensions(glm::vec3 min, glm::vec3 max)
std::string name
std::vector< glm::mat4 > inverseBindMatrices
std::vector< Node * > joints
static std::vector< VkVertexInputAttributeDescription > vertexInputAttributeDescriptions
static VkVertexInputAttributeDescription inputAttributeDescription(uint32_t binding, uint32_t location, VertexComponent component)
static VkPipelineVertexInputStateCreateInfo * getPipelineVertexInputState(const std::vector< VertexComponent > components)
Returns the default pipeline vertex input state create info structure for the requested vertex compon...
static VkVertexInputBindingDescription inputBindingDescription(uint32_t binding)
static std::vector< VkVertexInputAttributeDescription > inputAttributeDescriptions(uint32_t binding, const std::vector< VertexComponent > components)
static VkPipelineVertexInputStateCreateInfo pipelineVertexInputStateCreateInfo
static VkVertexInputBindingDescription vertexInputBindingDescription
#define max(x, y)
Definition svd3_cuda.h:41