From f084d6093c3299c7978893e9ba7b67ad246a153a Mon Sep 17 00:00:00 2001 From: Sascha Willems Date: Sat, 6 Aug 2022 10:16:54 +0200 Subject: [PATCH] Slightly reworked glTF samples Parent matrices are now applied (where available) Now more in line with the base code glTF loader Refs #964 --- data/shaders/glsl/gltfloading/mesh.frag | 2 +- data/shaders/glsl/gltfloading/mesh.frag.spv | Bin 2024 -> 2008 bytes data/shaders/glsl/gltfloading/mesh.vert | 5 +- data/shaders/glsl/gltfloading/mesh.vert.spv | Bin 3212 -> 3396 bytes data/shaders/hlsl/gltfloading/mesh.frag | 2 +- data/shaders/hlsl/gltfloading/mesh.frag.spv | Bin 1776 -> 1752 bytes data/shaders/hlsl/gltfloading/mesh.vert | 6 +-- data/shaders/hlsl/gltfloading/mesh.vert.spv | Bin 2400 -> 2516 bytes examples/gltfloading/gltfloading.cpp | 47 +++++++++++------- .../gltfscenerendering/gltfscenerendering.cpp | 46 +++++++++-------- .../gltfscenerendering/gltfscenerendering.h | 13 +++-- 11 files changed, 71 insertions(+), 50 deletions(-) diff --git a/data/shaders/glsl/gltfloading/mesh.frag b/data/shaders/glsl/gltfloading/mesh.frag index fb415cef..866dd316 100644 --- a/data/shaders/glsl/gltfloading/mesh.frag +++ b/data/shaders/glsl/gltfloading/mesh.frag @@ -17,7 +17,7 @@ void main() vec3 N = normalize(inNormal); vec3 L = normalize(inLightVec); vec3 V = normalize(inViewVec); - vec3 R = reflect(-L, N); + vec3 R = reflect(L, N); vec3 diffuse = max(dot(N, L), 0.15) * inColor; vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75); outFragColor = vec4(diffuse * color.rgb + specular, 1.0); diff --git a/data/shaders/glsl/gltfloading/mesh.frag.spv b/data/shaders/glsl/gltfloading/mesh.frag.spv index 5cd562653a43a2f4e3575be29980fd2deef432dd..00c5c46a45b9941d4a8407d03e5a1486b1dd4378 100644 GIT binary patch delta 787 zcmXw%$x1^(6hv>EIHHIkqApYrQ83O!95Wc_SzNjjjUWh4WF1|IJ3(}#zmd=I2i&{y z7hDLQdcNDCNZsn{+tuCgyZN)ZDN)s1YZk1*>TLJ9=_nMQ&%gRc%f5X0N$KMF28vQ+g_rB_7z&l2a2U!Hi0^M5nL$f3Wi~Gt!|TPUy32c=jp|%Bg}W7= z1JWEl^jV@#0P@lAzb?euG!d%cNx*pdNEBNX+Pz)ybS0m>4CO^k+F}TFgGNlMhd}^q zAO$p^VZ%ZGHRtO_;acbQ7`zv}Mz>%#4wpx|dh7U;K)nad%8^0$;|-?ZZQzLp3Nj6( zX^{fx9MarB16L@oXW{+81I)qYk?sK&;Qs;2W-{nOd@>VHcJeQy9>>Gv;W;3W!sz9t z`R2=T1yrreUIF!BkMBo^S&cR68iD=QAilsiBTv_OV-pwsDd(%dgCX22h>xH;$m delta 803 zcmXw%%Pxaa6ot=eOG$`GL@+=iLZa?e-KwSTml8uGp%RJ2rRn%*AZ8M&39sQXynwlh zS1^$H)}OP_pOt^@wfEU)oy%9-Pg`p;F_3o7yC%N!OY4a*yo|iqbt>K{gW?!{Q6@b%^<$Nb>~N1ij;Fps$y82kE8pd#f3O7tYoO} zfER%@LqC1ih?4++ZZX8Apk=X;fTsYX{+X<_%e2+@!gC+R)U}TyinPQi$bjV#kHPyu z3zL)|2Oew!)heIIzzBckY~CbX^DLf%4}jPBRGgcJt42D#qxd{#3DkTTs6gjs4YKe~ z@Js_4nFG=^M+USnX;wcEmnn-E;6uO+EW%YIy~Rc8*uXM@8Bl>PNITbMt%O_;f7R)- z%*-lWm!le)(MynKi?73FP_Yhw12ls&?@624jDo0yhD_+@9>Z?8;A)~{x2D^0E%Xp- wcHpX$eiV**7cO1Hv^}^qtzp{Ieh{_jAs*%O0H}c`DBlINJ3TMu{%DZ{{}!7&HUIzs diff --git a/data/shaders/glsl/gltfloading/mesh.vert b/data/shaders/glsl/gltfloading/mesh.vert index 2760684e..e2da4ece 100644 --- a/data/shaders/glsl/gltfloading/mesh.vert +++ b/data/shaders/glsl/gltfloading/mesh.vert @@ -10,6 +10,7 @@ layout (set = 0, binding = 0) uniform UBOScene mat4 projection; mat4 view; vec4 lightPos; + vec4 viewPos; } uboScene; layout(push_constant) uniform PushConsts { @@ -32,6 +33,6 @@ void main() vec4 pos = uboScene.view * vec4(inPos, 1.0); outNormal = mat3(uboScene.view) * inNormal; vec3 lPos = mat3(uboScene.view) * uboScene.lightPos.xyz; - outLightVec = lPos - pos.xyz; - outViewVec = -pos.xyz; + outLightVec = uboScene.lightPos.xyz - pos.xyz; + outViewVec = uboScene.viewPos.xyz - pos.xyz; } \ No newline at end of file diff --git a/data/shaders/glsl/gltfloading/mesh.vert.spv b/data/shaders/glsl/gltfloading/mesh.vert.spv index cf6fc4ac34758c1159e7f64a2d1acf8dcb20d627..4fe54ca90a060b0128efceed21f91f47db70256f 100644 GIT binary patch delta 407 zcmYk2u}T9`5JhKpHycrc1R)SbG;Zk+Sg2r^E`ES%jH_;9j1o|+L~JdTCHNh(g+E~H zmsnd0o-01cz~Q~QbKlJHp4uO)jX28cW^RkNVAn5=kr!`wQ(sA~W}9Xf!%dOj9!{p^ zm(RSY9-^K%yL06X%X9e|zf#PTnJ=e*FE@}ytE#1I-YmGP*|sIN&N-|)_4lN6K%+kC z0Jh)=_OP@#Phe1fFJ<>ZIYrrp9?P<|oq;r=aERcMuBx9y4)X0Y{`g-DQ%B^QI)pIe sg1huEV{A4yi9!*Ega?;s^Gi+0r3ppwho!F2Xln9lDgBJJADlbz3r}z?1ONa4 delta 219 zcmX>i)g#Hv%%sfDz`)4B0fgBTd9xYQH&zxiPGXwEn7(-`lRx9+AIuacAsL8+fEdIV1JWr#Y%|%EM|rXgFGo%qkOxwc z3dD8{%nV6D8YBi&odIOq0I@&NB_Pu>ffytP!XUs1#7sb3549}|$OfqanUxNtLHxf! IRTe-D0G+cPF#rGn diff --git a/data/shaders/hlsl/gltfloading/mesh.frag b/data/shaders/hlsl/gltfloading/mesh.frag index 914421a0..a574c7a1 100644 --- a/data/shaders/hlsl/gltfloading/mesh.frag +++ b/data/shaders/hlsl/gltfloading/mesh.frag @@ -24,7 +24,7 @@ float4 main(VSOutput input) : SV_TARGET float3 N = normalize(input.Normal); float3 L = normalize(input.LightVec); float3 V = normalize(input.ViewVec); - float3 R = reflect(-L, N); + float3 R = reflect(L, N); float3 diffuse = max(dot(N, L), 0.0) * input.Color; float3 specular = pow(max(dot(R, V), 0.0), 16.0) * float3(0.75, 0.75, 0.75); return float4(diffuse * color.rgb + specular, 1.0); diff --git a/data/shaders/hlsl/gltfloading/mesh.frag.spv b/data/shaders/hlsl/gltfloading/mesh.frag.spv index a801c5f2114e0f397e424ddabce3fe5173ec1f66..4eafff863c6604e2e264c40899236d08812e6d97 100644 GIT binary patch delta 375 zcmXw!O=s}LlUXrx1-h_D z;psU%gEeVtL2lP6c#EBukUZSCN9wI&Z$PxJ56S;SD%GQ4(YIRF(wux8Ayme7VmtQN zvF4+Ep!FE(H$H1aZjHZG+mffbRQs%IY_|CiFL@&Fzy=<$-~kFXSbgvPb50I7_$L*K delta 399 zcmXw!O-=$q6od2{n(oO| zUUj{C)vpivG0z+IUQ?<`y3+bD|IErt7rN#A2!^1gW;j2=?b`tN?!m7z=A`GJ@2sds zFgyBIzzz7q;j|af1@@$=67JLo;9HzD1}VdRXQbXF_BvGi+92gmrAh^YP4Bu4m%hRW z5tI;Ir|#oYZ*VVW-!5u1xOD=xjnA9It@}&b0&dOAp0%aKA4FgB!He#wE8qYRxPKjL MgB8!ce@>G4U&CBWs{bV8Qr}#6Q5#^^1w` zvpc6*I?Z9ud+z7V%#v##>vXQoIoIRX^q1A=+Px%~V6>O?W5Mrjg$?+25f&Yyyr>{j zFn3OLUeqP(7UlFqzb%Kneiy{YzxV6qqwPqn{5ldDJfghpFN*&%A4pe7cy#**(a-v~ zIE<9NAS-OB=QynYLT|RzwHyA}iEGheDo<^x6sR4Q2)l-W72 zTMstYDy!1uH96+!<(rFNt3j}_(DY$`URMoPgAEkKV&2hFoFuYf$T z-tjvTSuFZTcIsuk8x}Iwk|u-7m@`iTeGbeQPjy<}Y+POQ(z;>tT6MRd1n}|NaMeWp19&pKHvmf;s`+jBR z97^)ItsNepJKCwoYPc(&8o=~;Pdo9*gZ+K&*pqWwn0~mw$iVc#eIy3h-a%Ui6U#6? zF+aoD^WF>>#q)mgAzn#4cPEQ^e}?Iq+=j8|{bh0bKft+3Wg3%?TrB4DSDif2KBHXp z{ZK@2hR4Md3(Q;}iKyT7kHu4eMO8D~vWWR`k09)r?Gq6?v*Y_|cHB|3<9mm$qNtqB zgoycOV?FosPqN{Tz7SD2%VaObBcoT7O?nyq)ihPk^pyyI?9p@IPZby4ln6cfO!nH# zsncX{#3QFilTC}q7d!G3@2$t$T%i9D%zH+J9AZ%~^_kB*@x(xGKC|MHL#$SxImz%L zj`>u?&w0|;^r`9GxbyQOY9ThZ^g(@95qAJRXUBV35ZT%B{ow5AZ_(>4=X)@^i<8v=dMhxsM_lkJS&9}^Qe-Mw(Vt*8m3}Us$UX=_RV!zW3=go1B@SWP} c8=kku9f#+gasT1Fv=alqTRXM>Qwe|XND&;S4c literal 2400 zcmZ9MYfn=_5QY~@i=ZNiT)bfm-qEV4h$2EM2pHs4#KfvXQoIoIRf>7Ui-+JhwLG1?3IvEX+%;|6@Y2#XF;UQ`e% zm^<5_OBtigNm)-;zUKzjNZ#pL_N4;Z`D6ejQ#0k0>wu^Ws0vN75BMk8W>2`Ck8$ z#)+~QWQ7g&9L4n?=*^b8cH(c_X)QTGPP`uN&Dh<(6Q93!c(7ef8VBiSBQ2i*??e1% z$LcrvTHo<;@~&6=-hR9rr}0tU%R2oW;zs#sbH7}RKCW!6L~DshBd+<;6Ml0ovQ|IrvVQcA-?4~T zya$%mu%u}q!w$XOL(^wv*<5DV>^R3oPYq!D zyRDsgVx zE5jx6*Y!IxgbuP5(eV z^;c9ivwbLHKHMP)J7!xJp)`<5w#F| zPDCHnH!tE2py%v(4^@$!9p4Vlj{X*c&T=jW8FH58wAgPY!-m-Avm~C`K`it69qL(@ w3_t9CDK9my1pG!fmAAur!1HdXAD%bEU4`$`&OL_bt>6#OJ0bo*Wt|fJ2aOk$zyJUM diff --git a/examples/gltfloading/gltfloading.cpp b/examples/gltfloading/gltfloading.cpp index 1aa42647..7a38fcef 100644 --- a/examples/gltfloading/gltfloading.cpp +++ b/examples/gltfloading/gltfloading.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - glTF scene loading and rendering * -* Copyright (C) 2020-2021 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2020-2022 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) */ @@ -78,9 +78,14 @@ public: // A node represents an object in the glTF scene graph struct Node { Node* parent; - std::vector children; + std::vector children; Mesh mesh; glm::mat4 matrix; + ~Node() { + for (auto& child : children) { + delete child; + } + } }; // A glTF material stores information in e.g. the texture that is attached to it and colors @@ -109,10 +114,13 @@ public: std::vector images; std::vector textures; std::vector materials; - std::vector nodes; + std::vector nodes; ~VulkanglTFModel() { + for (auto node : nodes) { + delete node; + } // Release all Vulkan resources allocated for the model vkDestroyBuffer(vulkanDevice->logicalDevice, vertices.buffer, nullptr); vkFreeMemory(vulkanDevice->logicalDevice, vertices.memory, nullptr); @@ -195,29 +203,30 @@ public: void loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFModel::Node* parent, std::vector& indexBuffer, std::vector& vertexBuffer) { - VulkanglTFModel::Node node{}; - node.matrix = glm::mat4(1.0f); + VulkanglTFModel::Node* node = new VulkanglTFModel::Node{}; + node->matrix = glm::mat4(1.0f); + node->parent = parent; // Get the local node matrix // It's either made up from translation, rotation, scale or a 4x4 matrix if (inputNode.translation.size() == 3) { - node.matrix = glm::translate(node.matrix, glm::vec3(glm::make_vec3(inputNode.translation.data()))); + node->matrix = glm::translate(node->matrix, glm::vec3(glm::make_vec3(inputNode.translation.data()))); } if (inputNode.rotation.size() == 4) { glm::quat q = glm::make_quat(inputNode.rotation.data()); - node.matrix *= glm::mat4(q); + node->matrix *= glm::mat4(q); } if (inputNode.scale.size() == 3) { - node.matrix = glm::scale(node.matrix, glm::vec3(glm::make_vec3(inputNode.scale.data()))); + node->matrix = glm::scale(node->matrix, glm::vec3(glm::make_vec3(inputNode.scale.data()))); } if (inputNode.matrix.size() == 16) { - node.matrix = glm::make_mat4x4(inputNode.matrix.data()); + node->matrix = glm::make_mat4x4(inputNode.matrix.data()); }; // Load node's children if (inputNode.children.size() > 0) { for (size_t i = 0; i < inputNode.children.size(); i++) { - loadNode(input.nodes[inputNode.children[i]], input , &node, indexBuffer, vertexBuffer); + loadNode(input.nodes[inputNode.children[i]], input , node, indexBuffer, vertexBuffer); } } @@ -309,7 +318,7 @@ public: primitive.firstIndex = firstIndex; primitive.indexCount = indexCount; primitive.materialIndex = glTFPrimitive.material; - node.mesh.primitives.push_back(primitive); + node->mesh.primitives.push_back(primitive); } } @@ -326,20 +335,20 @@ public: */ // Draw a single node including child nodes (if present) - void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node node) + void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFModel::Node* node) { - if (node.mesh.primitives.size() > 0) { + if (node->mesh.primitives.size() > 0) { // Pass the node's matrix via push constants // Traverse the node hierarchy to the top-most parent to get the final matrix of the current node - glm::mat4 nodeMatrix = node.matrix; - VulkanglTFModel::Node* currentParent = node.parent; + glm::mat4 nodeMatrix = node->matrix; + VulkanglTFModel::Node* currentParent = node->parent; while (currentParent) { nodeMatrix = currentParent->matrix * nodeMatrix; currentParent = currentParent->parent; } // Pass the final matrix to the vertex shader using push constants vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix); - for (VulkanglTFModel::Primitive& primitive : node.mesh.primitives) { + for (VulkanglTFModel::Primitive& primitive : node->mesh.primitives) { if (primitive.indexCount > 0) { // Get the texture index for this primitive VulkanglTFModel::Texture texture = textures[materials[primitive.materialIndex].baseColorTextureIndex]; @@ -349,7 +358,7 @@ public: } } } - for (auto& child : node.children) { + for (auto& child : node->children) { drawNode(commandBuffer, pipelineLayout, child); } } @@ -382,6 +391,7 @@ public: glm::mat4 projection; glm::mat4 model; glm::vec4 lightPos = glm::vec4(5.0f, 5.0f, -5.0f, 1.0f); + glm::vec4 viewPos; } values; } shaderData; @@ -404,7 +414,7 @@ public: camera.type = Camera::CameraType::lookat; camera.flipY = true; camera.setPosition(glm::vec3(0.0f, -0.1f, -1.0f)); - camera.setRotation(glm::vec3(0.0f, -135.0f, 0.0f)); + camera.setRotation(glm::vec3(0.0f, 45.0f, 0.0f)); camera.setPerspective(60.0f, (float)width / (float)height, 0.1f, 256.0f); } @@ -707,6 +717,7 @@ public: { shaderData.values.projection = camera.matrices.perspective; shaderData.values.model = camera.matrices.view; + shaderData.values.viewPos = camera.viewPos; memcpy(shaderData.buffer.mapped, &shaderData.values, sizeof(shaderData.values)); } diff --git a/examples/gltfscenerendering/gltfscenerendering.cpp b/examples/gltfscenerendering/gltfscenerendering.cpp index 9090317a..7ba5ee0f 100644 --- a/examples/gltfscenerendering/gltfscenerendering.cpp +++ b/examples/gltfscenerendering/gltfscenerendering.cpp @@ -1,7 +1,7 @@ /* * Vulkan Example - Scene rendering * -* Copyright (C) 2020-2021 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2020-202- by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * @@ -20,6 +20,9 @@ VulkanglTFScene::~VulkanglTFScene() { + for (auto node : nodes) { + delete node; + } // Release all Vulkan resources allocated for the model vkDestroyBuffer(vulkanDevice->logicalDevice, vertices.buffer, nullptr); vkFreeMemory(vulkanDevice->logicalDevice, vertices.memory, nullptr); @@ -87,30 +90,31 @@ void VulkanglTFScene::loadMaterials(tinygltf::Model& input) void VulkanglTFScene::loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFScene::Node* parent, std::vector& indexBuffer, std::vector& vertexBuffer) { - VulkanglTFScene::Node node{}; - node.name = inputNode.name; + VulkanglTFScene::Node* node = new VulkanglTFScene::Node{}; + node->name = inputNode.name; + node->parent = parent; // Get the local node matrix // It's either made up from translation, rotation, scale or a 4x4 matrix - node.matrix = glm::mat4(1.0f); + node->matrix = glm::mat4(1.0f); if (inputNode.translation.size() == 3) { - node.matrix = glm::translate(node.matrix, glm::vec3(glm::make_vec3(inputNode.translation.data()))); + node->matrix = glm::translate(node->matrix, glm::vec3(glm::make_vec3(inputNode.translation.data()))); } if (inputNode.rotation.size() == 4) { glm::quat q = glm::make_quat(inputNode.rotation.data()); - node.matrix *= glm::mat4(q); + node->matrix *= glm::mat4(q); } if (inputNode.scale.size() == 3) { - node.matrix = glm::scale(node.matrix, glm::vec3(glm::make_vec3(inputNode.scale.data()))); + node->matrix = glm::scale(node->matrix, glm::vec3(glm::make_vec3(inputNode.scale.data()))); } if (inputNode.matrix.size() == 16) { - node.matrix = glm::make_mat4x4(inputNode.matrix.data()); + node->matrix = glm::make_mat4x4(inputNode.matrix.data()); }; // Load node's children if (inputNode.children.size() > 0) { for (size_t i = 0; i < inputNode.children.size(); i++) { - loadNode(input.nodes[inputNode.children[i]], input, &node, indexBuffer, vertexBuffer); + loadNode(input.nodes[inputNode.children[i]], input, node, indexBuffer, vertexBuffer); } } @@ -210,7 +214,7 @@ void VulkanglTFScene::loadNode(const tinygltf::Node& inputNode, const tinygltf:: primitive.firstIndex = firstIndex; primitive.indexCount = indexCount; primitive.materialIndex = glTFPrimitive.material; - node.mesh.primitives.push_back(primitive); + node->mesh.primitives.push_back(primitive); } } @@ -232,23 +236,23 @@ VkDescriptorImageInfo VulkanglTFScene::getTextureDescriptor(const size_t index) */ // Draw a single node including child nodes (if present) -void VulkanglTFScene::drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFScene::Node node) +void VulkanglTFScene::drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFScene::Node* node) { - if (!node.visible) { + if (!node->visible) { return; } - if (node.mesh.primitives.size() > 0) { + if (node->mesh.primitives.size() > 0) { // Pass the node's matrix via push constants // Traverse the node hierarchy to the top-most parent to get the final matrix of the current node - glm::mat4 nodeMatrix = node.matrix; - VulkanglTFScene::Node* currentParent = node.parent; + glm::mat4 nodeMatrix = node->matrix; + VulkanglTFScene::Node* currentParent = node->parent; while (currentParent) { nodeMatrix = currentParent->matrix * nodeMatrix; currentParent = currentParent->parent; } // Pass the final matrix to the vertex shader using push constants vkCmdPushConstants(commandBuffer, pipelineLayout, VK_SHADER_STAGE_VERTEX_BIT, 0, sizeof(glm::mat4), &nodeMatrix); - for (VulkanglTFScene::Primitive& primitive : node.mesh.primitives) { + for (VulkanglTFScene::Primitive& primitive : node->mesh.primitives) { if (primitive.indexCount > 0) { VulkanglTFScene::Material& material = materials[primitive.materialIndex]; // POI: Bind the pipeline for the node's material @@ -258,7 +262,7 @@ void VulkanglTFScene::drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout p } } } - for (auto& child : node.children) { + for (auto& child : node->children) { drawNode(commandBuffer, pipelineLayout, child); } } @@ -641,21 +645,21 @@ void VulkanExample::OnUpdateUIOverlay(vks::UIOverlay* overlay) if (overlay->header("Visibility")) { if (overlay->button("All")) { - std::for_each(glTFScene.nodes.begin(), glTFScene.nodes.end(), [](VulkanglTFScene::Node &node) { node.visible = true; }); + std::for_each(glTFScene.nodes.begin(), glTFScene.nodes.end(), [](VulkanglTFScene::Node* node) { node->visible = true; }); buildCommandBuffers(); } ImGui::SameLine(); if (overlay->button("None")) { - std::for_each(glTFScene.nodes.begin(), glTFScene.nodes.end(), [](VulkanglTFScene::Node &node) { node.visible = false; }); + std::for_each(glTFScene.nodes.begin(), glTFScene.nodes.end(), [](VulkanglTFScene::Node* node) { node->visible = false; }); buildCommandBuffers(); } ImGui::NewLine(); // POI: Create a list of glTF nodes for visibility toggle ImGui::BeginChild("#nodelist", ImVec2(200.0f * overlay->scale, 340.0f * overlay->scale), false); - for (auto &node : glTFScene.nodes) + for (auto& node : glTFScene.nodes) { - if (overlay->checkBox(node.name.c_str(), &node.visible)) + if (overlay->checkBox(node->name.c_str(), &node->visible)) { buildCommandBuffers(); } diff --git a/examples/gltfscenerendering/gltfscenerendering.h b/examples/gltfscenerendering/gltfscenerendering.h index 1e1d673c..b29c90b1 100644 --- a/examples/gltfscenerendering/gltfscenerendering.h +++ b/examples/gltfscenerendering/gltfscenerendering.h @@ -1,7 +1,7 @@ /* * Vulkan Example - Scene rendering * -* Copyright (C) 2020 by Sascha Willems - www.saschawillems.de +* Copyright (C) 2020-2022 by Sascha Willems - www.saschawillems.de * * This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) * @@ -76,11 +76,16 @@ public: // A node represents an object in the glTF scene graph struct Node { Node* parent; - std::vector children; + std::vector children; Mesh mesh; glm::mat4 matrix; std::string name; bool visible = true; + ~Node() { + for (auto& child : children) { + delete child; + } + } }; // A glTF material stores information in e.g. the texture that is attached to it and colors @@ -113,7 +118,7 @@ public: std::vector images; std::vector textures; std::vector materials; - std::vector nodes; + std::vector nodes; std::string path; @@ -123,7 +128,7 @@ public: void loadTextures(tinygltf::Model& input); void loadMaterials(tinygltf::Model& input); void loadNode(const tinygltf::Node& inputNode, const tinygltf::Model& input, VulkanglTFScene::Node* parent, std::vector& indexBuffer, std::vector& vertexBuffer); - void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFScene::Node node); + void drawNode(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout, VulkanglTFScene::Node* node); void draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout); };