diff --git a/homework/homework1/homework1.cpp b/homework/homework1/homework1.cpp index 44be147..5282594 100644 --- a/homework/homework1/homework1.cpp +++ b/homework/homework1/homework1.cpp @@ -199,7 +199,7 @@ } - + /* // load skins from glTF model void VulkanglTFModel::loadSkins(tinygltf::Model& input) { @@ -249,8 +249,8 @@ - } - + }*/ + //glTF nodes loading helper function //rewrite node loader,simplify logic //Search node from parent to children by index @@ -634,7 +634,7 @@ } // Draw the glTF scene starting at the top-level-nodes - void VulkanglTFModel::draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout) + void VulkanglTFModel::draw(VkCommandBuffer commandBuffer, VkPipelineLayout pipelineLayout ) { // All vertices and indices are stored in single buffers, so we only need to bind once VkDeviceSize offsets[1] = { 0 }; @@ -755,7 +755,7 @@ void VulkanExample::setupFrameBuffer() samplerCI.minLod = 0.0f; samplerCI.maxLod = 1.0f; samplerCI.borderColor = VK_BORDER_COLOR_FLOAT_OPAQUE_WHITE; - + VK_CHECK_RESULT(vkCreateSampler(device, &samplerCI, nullptr, &colorSampler)); if (tonemappingDescriptorSet != VK_NULL_HANDLE) { auto imageInfo = vks::initializers::descriptorImageInfo(colorSampler, pbrFrameBuffer.color.imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); @@ -780,11 +780,11 @@ void VulkanExample::getEnabledFeatures() VkClearValue clearValues[2]; clearValues[0].color = defaultClearColor; - clearValues[0].color = { { 0.25f, 0.25f, 0.25f, 1.0f } };; + clearValues[0].color = { { 0.25f, 0.25f, 0.25f, 1.0f } }; clearValues[1].depthStencil = { 1.0f, 0 }; VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); - renderPassBeginInfo.renderPass = renderPass; + renderPassBeginInfo.renderPass = pbrFrameBuffer.fbo.renderPass; renderPassBeginInfo.renderArea.offset.x = 0; renderPassBeginInfo.renderArea.offset.y = 0; renderPassBeginInfo.renderArea.extent.width = width; @@ -797,40 +797,41 @@ void VulkanExample::getEnabledFeatures() for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { - renderPassBeginInfo.framebuffer = frameBuffers[i]; + renderPassBeginInfo.framebuffer = pbrFrameBuffer.fbo.frameBuffer; VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); // Bind scene matrices descriptor to set 0 - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayout, 0, 1, &descriptorSet, 0, nullptr); + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.pbrLayout, 0, 1, &descriptorSet, 0, nullptr); + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.pbrLayout, 6, 1, &skinDescriptorSet, 0, nullptr); vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, wireframe ? pipelines.wireframe : pipelines.solid); - glTFModel.draw(drawCmdBuffers[i], pipelineLayout); - drawUI(drawCmdBuffers[i]); + glTFModel.draw(drawCmdBuffers[i], pipelineLayouts.pbrLayout); vkCmdEndRenderPass(drawCmdBuffers[i]); + + { + VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); + renderPassBeginInfo.renderPass = renderPass; + renderPassBeginInfo.framebuffer = VulkanExampleBase::frameBuffers[i]; + renderPassBeginInfo.renderArea.extent.width = width; + renderPassBeginInfo.renderArea.extent.height = height; + renderPassBeginInfo.clearValueCount = 2; + renderPassBeginInfo.pClearValues = clearValues; + + vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); + vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); + vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); + vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.tonemappingLayout, 0, 1, &tonemappingDescriptorSet, 0, NULL); + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toneMapping); + vkCmdDraw(drawCmdBuffers[i], 3, 1, 0, 0); + drawUI(drawCmdBuffers[i]); + vkCmdEndRenderPass(drawCmdBuffers[i]); + } VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); - - //tonemapping render pass - VkRenderPassBeginInfo renderPassBeginInfo = vks::initializers::renderPassBeginInfo(); - renderPassBeginInfo.renderPass = renderPass; - renderPassBeginInfo.framebuffer = VulkanExampleBase::frameBuffers[i]; - renderPassBeginInfo.renderArea.extent.width = width; - renderPassBeginInfo.renderArea.extent.height = height; - renderPassBeginInfo.clearValueCount = 2; - renderPassBeginInfo.pClearValues = clearValues; - - vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); - vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); - vkCmdBindDescriptorSets(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelineLayouts.tonemappingLayout, 0, 1, &tonemappingDescriptorSet, 0, NULL); - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.toneMapping); - vkCmdDraw(drawCmdBuffers[i], 3, 1, 0, 0); - drawUI(drawCmdBuffers[i]); - vkCmdEndRenderPass(drawCmdBuffers[i]); } } - void VulkanExample::loadglTFFile(std::string filename, VulkanglTFModel& model, bool bSkyboxFlag = false) + void VulkanExample::loadglTFFile(std::string filename, VulkanglTFModel& model, bool bSkyboxFlag) { tinygltf::Model glTFInput; tinygltf::TinyGLTF gltfContext; @@ -838,49 +839,31 @@ void VulkanExample::getEnabledFeatures() this->device = device; +#if defined(__ANDROID__) + // On Android all assets are packed with the apk in a compressed form, so we need to open them using the asset manager + // We let tinygltf handle this, by passing the asset manager of our app + tinygltf::asset_manager = androidApp->activity->assetManager; +#endif bool fileLoaded = gltfContext.LoadASCIIFromFile(&glTFInput, &error, &warning, filename); // Pass some Vulkan resources required for setup and rendering to the glTF model loading class - glTFModel.vulkanDevice = vulkanDevice; - glTFModel.copyQueue = queue; + model.vulkanDevice = vulkanDevice; + model.copyQueue = queue; std::vector indexBuffer; std::vector vertexBuffer; - if (fileLoaded) - { - glTFModel.nodeCount = static_cast(glTFInput.nodes.size()); - glTFModel.loadImages(glTFInput); - glTFModel.loadMaterials(glTFInput); - glTFModel.loadTextures(glTFInput); - //glTFModel.loadSkins(glTFInput); + if (fileLoaded) { + model.nodeCount = static_cast(glTFInput.nodes.size()); + model.loadImages(glTFInput); + model.loadMaterials(glTFInput); + model.loadTextures(glTFInput); const tinygltf::Scene& scene = glTFInput.scenes[0]; for (size_t i = 0; i < scene.nodes.size(); i++) { const tinygltf::Node node = glTFInput.nodes[scene.nodes[i]]; - glTFModel.loadNode(node, glTFInput, nullptr,scene.nodes[i], indexBuffer, vertexBuffer); + model.loadNode(node, glTFInput, nullptr, scene.nodes[i], indexBuffer, vertexBuffer); } - - glTFModel.loadAnimations(glTFInput); - // update joint in nodes - /* - - for (auto node : glTFModel.nodes) - { - - glTFModel.updateJoints(node); - } - - for (size_t i = 0; i < glTFModel.nodes.size(); i++) - { - if (glTFModel.nodes[i]->skin > -1) - { - glTFModel.updateJoints(glTFModel.nodes[i]); - } - else - { - continue; - } - }*/ + model.loadAnimations(glTFInput); } else { vks::tools::exitFatal("Could not open the glTF file.\n\nThe file is part of the additional asset pack.\n\nRun \"download_assets.py\" in the repository root to download the latest version.", -1); @@ -893,9 +876,12 @@ void VulkanExample::getEnabledFeatures() size_t vertexBufferSize = vertexBuffer.size() * sizeof(VulkanglTFModel::Vertex); size_t indexBufferSize = indexBuffer.size() * sizeof(uint32_t); - glTFModel.indices.count = static_cast(indexBuffer.size()); + model.indices.count = static_cast(indexBuffer.size()); - + struct StagingBuffer { + VkBuffer buffer; + VkDeviceMemory memory; + } vertexStaging, indexStaging; // Create host visible staging buffers (source) VK_CHECK_RESULT(vulkanDevice->createBuffer( @@ -919,15 +905,14 @@ void VulkanExample::getEnabledFeatures() VK_BUFFER_USAGE_VERTEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, vertexBufferSize, - &glTFModel.vertices.buffer, - &glTFModel.vertices.memory)); - + &model.vertices.buffer, + &model.vertices.memory)); VK_CHECK_RESULT(vulkanDevice->createBuffer( VK_BUFFER_USAGE_INDEX_BUFFER_BIT | VK_BUFFER_USAGE_TRANSFER_DST_BIT, VK_MEMORY_PROPERTY_DEVICE_LOCAL_BIT, indexBufferSize, - &glTFModel.indices.buffer, - &glTFModel.indices.memory)); + &model.indices.buffer, + &model.indices.memory)); // Copy data from staging buffers (host) do device local buffer (gpu) VkCommandBuffer copyCmd = vulkanDevice->createCommandBuffer(VK_COMMAND_BUFFER_LEVEL_PRIMARY, true); @@ -937,16 +922,15 @@ void VulkanExample::getEnabledFeatures() vkCmdCopyBuffer( copyCmd, vertexStaging.buffer, - glTFModel.vertices.buffer, + model.vertices.buffer, 1, ©Region); copyRegion.size = indexBufferSize; - vkCmdCopyBuffer( copyCmd, indexStaging.buffer, - glTFModel.indices.buffer, + model.indices.buffer, 1, ©Region); @@ -985,9 +969,8 @@ void VulkanExample::getEnabledFeatures() vks::initializers::descriptorPoolSize(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER,1) }; - const uint32_t maxSetCount = static_cast(glTFModel.images.size()) + 6; - // Number of descriptor sets = One for the scene ubo + one per image + one per skin - //const uint32_t maxSetCount = static_cast(glTFModel.images.size()) + static_cast(glTFModel.skins.size()) + 1+ 6 ; + // One set for matrices and one per model image/texture + const uint32_t maxSetCount = static_cast(glTFModel.images.size()) + 6; VkDescriptorPoolCreateInfo descriptorPoolInfo = vks::initializers::descriptorPoolCreateInfo(poolSizes, maxSetCount); VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); @@ -1000,17 +983,17 @@ void VulkanExample::getEnabledFeatures() vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 3), }; VkDescriptorSetLayoutCreateInfo descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(setLayoutBindings); - // Descriptor set layout for passing matrices VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.matrices)); - // Descriptor set layout for material uniform buffer + VkDescriptorSetLayoutBinding materialBufferLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_UNIFORM_BUFFER, VK_SHADER_STAGE_FRAGMENT_BIT, 0); descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(&materialBufferLayoutBinding, 1); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.materialUniform)); + // Descriptor set layout for passing material textures VkDescriptorSetLayoutBinding setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, VK_SHADER_STAGE_FRAGMENT_BIT, 0); descriptorSetLayoutCI = vks::initializers::descriptorSetLayoutCreateInfo(&setLayoutBinding, 1); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.textures)); - // Descriptor set layout for ssbo + setLayoutBinding = vks::initializers::descriptorSetLayoutBinding(VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, VK_SHADER_STAGE_VERTEX_BIT, 0); VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorSetLayoutCI, nullptr, &descriptorSetLayouts.ssbo)); // Descriptor set layout for passing skin joint matrices @@ -1033,7 +1016,7 @@ void VulkanExample::getEnabledFeatures() descriptorSetLayouts.ssbo, }; VkPipelineLayoutCreateInfo pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(setLayouts.data(), static_cast(setLayouts.size())); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayout)); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayouts.pbrLayout)); /* // We will use push constants to push the local matrices of a primitive to the vertex shader @@ -1057,7 +1040,8 @@ void VulkanExample::getEnabledFeatures() vkUpdateDescriptorSets(device, 4, writeDescriptorSets.data(), 0, nullptr); // Descriptor set for glTF model skin joint matrices - if (glTFModel.skins.size() > 0) + /* + if (glTFModel.skins.size() > 0) { for (auto& skin : glTFModel.skins) { @@ -1068,13 +1052,7 @@ void VulkanExample::getEnabledFeatures() } } else - { - const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.ssbo, 1); - VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &skinDescriptorSet)); - VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(skinDescriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &shaderData.skinSSBO.descriptor); - vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr); - } - + */ for (auto& material : glTFModel.materials) { @@ -1092,16 +1070,22 @@ void VulkanExample::getEnabledFeatures() VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(image.descriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &image.texture.descriptor); vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr); } - - //tonemapping pipline layout { - VkPipelineLayoutCreateInfo piplineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.textures, 1); - VK_CHECK_RESULT(vkCreatePipelineLayout(device, &piplineLayoutCI, nullptr, &pipelineLayouts.tonemappingLayout)); + const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.ssbo, 1); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &skinDescriptorSet)); + VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(skinDescriptorSet, VK_DESCRIPTOR_TYPE_STORAGE_BUFFER, 0, &shaderData.skinSSBO.descriptor); + vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr); + } + + //Tone Mapping pipeline layout + { + auto pipelineLayoutCI = vks::initializers::pipelineLayoutCreateInfo(&descriptorSetLayouts.textures, 1); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pipelineLayoutCI, nullptr, &pipelineLayouts.tonemappingLayout)); const VkDescriptorSetAllocateInfo allocInfo = vks::initializers::descriptorSetAllocateInfo(descriptorPool, &descriptorSetLayouts.textures, 1); VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &tonemappingDescriptorSet)); - VkDescriptorImageInfo imageInfo = vks::initializers::descriptorImageInfo(colorSampler, pbrFrameBuffer.color.imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); + auto imageInfo = vks::initializers::descriptorImageInfo(colorSampler, pbrFrameBuffer.color.imageView, VK_IMAGE_LAYOUT_SHADER_READ_ONLY_OPTIMAL); VkWriteDescriptorSet writeDescriptorSet = vks::initializers::writeDescriptorSet(tonemappingDescriptorSet, VK_DESCRIPTOR_TYPE_COMBINED_IMAGE_SAMPLER, 0, &imageInfo); vkUpdateDescriptorSets(device, 1, &writeDescriptorSet, 0, nullptr); }