diff --git a/data/shaders/geometryshader/base.frag.spv b/data/shaders/geometryshader/base.frag.spv index 6c9ae8d4..06ab7a2f 100644 Binary files a/data/shaders/geometryshader/base.frag.spv and b/data/shaders/geometryshader/base.frag.spv differ diff --git a/data/shaders/geometryshader/base.vert b/data/shaders/geometryshader/base.vert index fd878f24..8f66ad20 100644 --- a/data/shaders/geometryshader/base.vert +++ b/data/shaders/geometryshader/base.vert @@ -8,6 +8,11 @@ layout (location = 1) in vec3 inNormal; layout (location = 0) out vec3 outNormal; +out gl_PerVertex +{ + vec4 gl_Position; +}; + void main(void) { outNormal = inNormal; diff --git a/data/shaders/geometryshader/base.vert.spv b/data/shaders/geometryshader/base.vert.spv index e25ad582..056dbb71 100644 Binary files a/data/shaders/geometryshader/base.vert.spv and b/data/shaders/geometryshader/base.vert.spv differ diff --git a/data/shaders/geometryshader/mesh.frag b/data/shaders/geometryshader/mesh.frag index ef1a83ca..90463067 100644 --- a/data/shaders/geometryshader/mesh.frag +++ b/data/shaders/geometryshader/mesh.frag @@ -3,23 +3,21 @@ #extension GL_ARB_separate_shader_objects : enable #extension GL_ARB_shading_language_420pack : enable -layout (location = 0) in vec2 vTexcoord; -layout (location = 1) in vec3 vNormal; -layout (location = 2) in vec3 vColor; -layout (location = 3) in vec3 vEyePos; -layout (location = 4) in vec3 vLightVec; +layout (location = 0) in vec3 inNormal; +layout (location = 1) in vec3 inColor; +layout (location = 2) in vec3 inViewVec; +layout (location = 3) in vec3 inLightVec; layout (location = 0) out vec4 outFragColor; void main() { - vec3 Eye = normalize(-vEyePos); - vec3 Reflected = normalize(reflect(-vLightVec, vNormal)); - - vec4 IAmbient = vec4(0.2, 0.2, 0.2, 1.0); - vec4 IDiffuse = vec4(0.5, 0.5, 0.5, 0.5) * max(dot(vNormal, vLightVec), 0.0); - float specular = 0.75; - vec4 ISpecular = vec4(0.5, 0.5, 0.5, 1.0) * pow(max(dot(Reflected, Eye), 0.0), 0.8) * specular; - - outFragColor = vec4((IAmbient + IDiffuse) * vec4(vColor, 1.0) + ISpecular); + vec3 N = normalize(inNormal); + vec3 L = normalize(inLightVec); + vec3 V = normalize(inViewVec); + vec3 R = reflect(-L, N); + vec3 ambient = vec3(0.1); + vec3 diffuse = max(dot(N, L), 0.0) * vec3(1.0); + vec3 specular = pow(max(dot(R, V), 0.0), 16.0) * vec3(0.75); + outFragColor = vec4((ambient + diffuse) * inColor.rgb + specular, 1.0); } \ No newline at end of file diff --git a/data/shaders/geometryshader/mesh.frag.spv b/data/shaders/geometryshader/mesh.frag.spv index ecc1c6c3..50714dbe 100644 Binary files a/data/shaders/geometryshader/mesh.frag.spv and b/data/shaders/geometryshader/mesh.frag.spv differ diff --git a/data/shaders/geometryshader/mesh.vert b/data/shaders/geometryshader/mesh.vert index a92776de..06ff4f9b 100644 --- a/data/shaders/geometryshader/mesh.vert +++ b/data/shaders/geometryshader/mesh.vert @@ -5,28 +5,34 @@ layout (location = 0) in vec4 inPos; layout (location = 1) in vec3 inNormal; -layout (location = 2) in vec2 inTexCoord; -layout (location = 3) in vec3 inColor; +layout (location = 2) in vec3 inColor; -layout (binding = 0) uniform UBO +layout (set = 0, binding = 0) uniform UBO { mat4 projection; mat4 model; } ubo; -layout (location = 0) out vec2 vTexcoord; -layout (location = 1) out vec3 vNormal; -layout (location = 2) out vec3 vColor; -layout (location = 3) out vec3 vEyePos; -layout (location = 4) out vec3 vLightVec; +layout (location = 0) out vec3 outNormal; +layout (location = 1) out vec3 outColor; +layout (location = 2) out vec3 outViewVec; +layout (location = 3) out vec3 outLightVec; + +out gl_PerVertex +{ + vec4 gl_Position; +}; void main() { - vTexcoord = inTexCoord.st; - vNormal = inNormal; - vColor = inColor; + outNormal = inNormal; + outColor = inColor; gl_Position = ubo.projection * ubo.model * inPos; - vEyePos = vec3(ubo.model * inPos); - vec4 lightPos = vec4(0.0, 0.0, 0.0, 1.0) * ubo.model; - vLightVec = normalize(lightPos.xyz - vEyePos); + + vec4 pos = ubo.model * vec4(inPos.xyz, 1.0); + outNormal = mat3(ubo.model) * inNormal; + + vec3 lightPos = vec3(1.0f, -1.0f, 1.0f); + outLightVec = lightPos.xyz - pos.xyz; + outViewVec = -pos.xyz; } diff --git a/data/shaders/geometryshader/mesh.vert.spv b/data/shaders/geometryshader/mesh.vert.spv index c50e6546..a1c31ca3 100644 Binary files a/data/shaders/geometryshader/mesh.vert.spv and b/data/shaders/geometryshader/mesh.vert.spv differ diff --git a/data/shaders/geometryshader/normaldebug.geom b/data/shaders/geometryshader/normaldebug.geom index 058018f5..0a436e74 100644 --- a/data/shaders/geometryshader/normaldebug.geom +++ b/data/shaders/geometryshader/normaldebug.geom @@ -18,7 +18,7 @@ layout (location = 0) out vec3 outColor; void main(void) { - float normalLength = 0.015; + float normalLength = 0.02; for(int i=0; i vertexLayout = { vkMeshLoader::VERTEX_LAYOUT_POSITION, vkMeshLoader::VERTEX_LAYOUT_NORMAL, - vkMeshLoader::VERTEX_LAYOUT_UV + vkMeshLoader::VERTEX_LAYOUT_COLOR }; class VulkanExample : public VulkanExampleBase { public: + bool displayNormals = true; + struct { VkPipelineVertexInputStateCreateInfo inputState; std::vector bindingDescriptions; @@ -72,6 +74,7 @@ public: { zoom = -8.0f; rotation = glm::vec3(0.0f, -25.0f, 0.0f); + enableTextOverlay = true; title = "Vulkan Example - Geometry shader"; } @@ -91,6 +94,16 @@ public: vkTools::destroyUniformData(device, &uniformData.GS); } + void reBuildCommandBuffers() + { + if (!checkCommandBuffers()) + { + destroyCommandBuffers(); + createCommandBuffers(); + } + buildCommandBuffers(); + } + void buildCommandBuffers() { VkCommandBufferBeginInfo cmdBufInfo = vkTools::initializers::commandBufferBeginInfo(); @@ -108,32 +121,20 @@ public: renderPassBeginInfo.clearValueCount = 2; renderPassBeginInfo.pClearValues = clearValues; - VkResult err; - for (int32_t i = 0; i < drawCmdBuffers.size(); ++i) { // Set target frame buffer renderPassBeginInfo.framebuffer = frameBuffers[i]; - err = vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo); - assert(!err); + VK_CHECK_RESULT(vkBeginCommandBuffer(drawCmdBuffers[i], &cmdBufInfo)); vkCmdBeginRenderPass(drawCmdBuffers[i], &renderPassBeginInfo, VK_SUBPASS_CONTENTS_INLINE); - VkViewport viewport = vkTools::initializers::viewport( - (float)width, - (float)height, - 0.0f, - 1.0f + VkViewport viewport = vkTools::initializers::viewport((float)width, (float)height, 0.0f, 1.0f ); vkCmdSetViewport(drawCmdBuffers[i], 0, 1, &viewport); - VkRect2D scissor = vkTools::initializers::rect2D( - width, - height, - 0, - 0 - ); + VkRect2D scissor = vkTools::initializers::rect2D(width, height, 0, 0); vkCmdSetScissor(drawCmdBuffers[i], 0, 1, &scissor); vkCmdSetLineWidth(drawCmdBuffers[i], 1.0f); @@ -149,43 +150,18 @@ public: vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); // Normal debugging - vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.normals); - vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); + if (displayNormals) + { + vkCmdBindPipeline(drawCmdBuffers[i], VK_PIPELINE_BIND_POINT_GRAPHICS, pipelines.normals); + vkCmdDrawIndexed(drawCmdBuffers[i], meshes.object.indexCount, 1, 0, 0, 0); + } vkCmdEndRenderPass(drawCmdBuffers[i]); - err = vkEndCommandBuffer(drawCmdBuffers[i]); - assert(!err); + VK_CHECK_RESULT(vkEndCommandBuffer(drawCmdBuffers[i])); } } - void draw() - { - VkResult err; - - // Get next image in the swap chain (back/front buffer) - err = swapChain.acquireNextImage(semaphores.presentComplete, ¤tBuffer); - assert(!err); - - submitPostPresentBarrier(swapChain.buffers[currentBuffer].image); - - // Command buffer to be sumitted to the queue - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; - - // Submit to queue - err = vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE); - assert(!err); - - submitPrePresentBarrier(swapChain.buffers[currentBuffer].image); - - err = swapChain.queuePresent(queue, currentBuffer, semaphores.renderComplete); - assert(!err); - - err = vkQueueWaitIdle(queue); - assert(!err); - } - void loadMeshes() { loadMesh(getAssetPath() + "models/suzanne.obj", &meshes.object, vertexLayout, 0.25f); @@ -221,12 +197,12 @@ public: VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 3); - // Location 2 : Texture coordinates + // Location 2 : Color vertices.attributeDescriptions[2] = vkTools::initializers::vertexInputAttributeDescription( VERTEX_BUFFER_BIND_ID, 2, - VK_FORMAT_R32G32_SFLOAT, + VK_FORMAT_R32G32B32_SFLOAT, sizeof(float) * 6); // Assign to vertex buffer @@ -251,8 +227,7 @@ public: poolSizes.data(), 2); - VkResult vkRes = vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool); - assert(!vkRes); + VK_CHECK_RESULT(vkCreateDescriptorPool(device, &descriptorPoolInfo, nullptr, &descriptorPool)); } void setupDescriptorSetLayout() @@ -276,16 +251,14 @@ public: setLayoutBindings.data(), setLayoutBindings.size()); - VkResult err = vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout); - assert(!err); + VK_CHECK_RESULT(vkCreateDescriptorSetLayout(device, &descriptorLayout, nullptr, &descriptorSetLayout)); VkPipelineLayoutCreateInfo pPipelineLayoutCreateInfo = vkTools::initializers::pipelineLayoutCreateInfo( &descriptorSetLayout, 1); - err = vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout); - assert(!err); + VK_CHECK_RESULT(vkCreatePipelineLayout(device, &pPipelineLayoutCreateInfo, nullptr, &pipelineLayout)); } void setupDescriptorSet() @@ -296,8 +269,7 @@ public: &descriptorSetLayout, 1); - VkResult vkRes = vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet); - assert(!vkRes); + VK_CHECK_RESULT(vkAllocateDescriptorSets(device, &allocInfo, &descriptorSet)); std::vector writeDescriptorSets = { @@ -320,8 +292,6 @@ public: void preparePipelines() { - VkResult err; - VkPipelineInputAssemblyStateCreateInfo inputAssemblyState = vkTools::initializers::pipelineInputAssemblyStateCreateInfo( VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST, @@ -398,18 +368,14 @@ public: pipelineCreateInfo.renderPass = renderPass; // Normal debugging pipeline - err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.normals); - assert(!err); + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.normals)); // Solid rendering pipeline - // Shader shaderStages[0] = loadShader(getAssetPath() + "shaders/geometryshader/mesh.vert.spv", VK_SHADER_STAGE_VERTEX_BIT); shaderStages[1] = loadShader(getAssetPath() + "shaders/geometryshader/mesh.frag.spv", VK_SHADER_STAGE_FRAGMENT_BIT); pipelineCreateInfo.stageCount = 2; - err = vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid); - assert(!err); - - } + VK_CHECK_RESULT(vkCreateGraphicsPipelines(device, pipelineCache, 1, &pipelineCreateInfo, nullptr, &pipelines.solid)); + } // Prepare and initialize uniform buffer containing shader uniforms void prepareUniformBuffers() @@ -417,8 +383,9 @@ public: // Vertex shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(uboVS), - &uboVS, + nullptr, &uniformData.VS.buffer, &uniformData.VS.memory, &uniformData.VS.descriptor); @@ -426,8 +393,9 @@ public: // Geometry shader uniform buffer block createBuffer( VK_BUFFER_USAGE_UNIFORM_BUFFER_BIT, + VK_MEMORY_PROPERTY_HOST_VISIBLE_BIT | VK_MEMORY_PROPERTY_HOST_COHERENT_BIT, sizeof(uboGS), - &uboGS, + nullptr, &uniformData.GS.buffer, &uniformData.GS.memory, &uniformData.GS.descriptor); @@ -438,33 +406,41 @@ public: void updateUniformBuffers() { // Vertex shader - glm::mat4 viewMatrix = glm::mat4(); uboVS.projection = glm::perspective(glm::radians(60.0f), (float)width / (float)height, 0.001f, 256.0f); - viewMatrix = glm::translate(viewMatrix, glm::vec3(0.0f, 0.0f, zoom)); + glm::mat4 viewMatrix = glm::translate(glm::mat4(), glm::vec3(0.0f, 0.0f, zoom)); - float offset = 0.5f; - int uboIndex = 1; - uboVS.model = glm::mat4(); - uboVS.model = viewMatrix * glm::translate(uboVS.model, glm::vec3(0, 0, 0)); + uboVS.model = viewMatrix * glm::translate(glm::mat4(), cameraPos); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.x), glm::vec3(1.0f, 0.0f, 0.0f)); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.y), glm::vec3(0.0f, 1.0f, 0.0f)); uboVS.model = glm::rotate(uboVS.model, glm::radians(rotation.z), glm::vec3(0.0f, 0.0f, 1.0f)); uint8_t *pData; - VkResult err = vkMapMemory(device, uniformData.VS.memory, 0, sizeof(uboVS), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.VS.memory, 0, sizeof(uboVS), 0, (void **)&pData)); memcpy(pData, &uboVS, sizeof(uboVS)); vkUnmapMemory(device, uniformData.VS.memory); // Geometry shader uboGS.model = uboVS.model; uboGS.projection = uboVS.projection; - err = vkMapMemory(device, uniformData.GS.memory, 0, sizeof(uboGS), 0, (void **)&pData); - assert(!err); + VK_CHECK_RESULT(vkMapMemory(device, uniformData.GS.memory, 0, sizeof(uboGS), 0, (void **)&pData)); memcpy(pData, &uboGS, sizeof(uboGS)); vkUnmapMemory(device, uniformData.GS.memory); } + void draw() + { + VulkanExampleBase::prepareFrame(); + + // Command buffer to be sumitted to the queue + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &drawCmdBuffers[currentBuffer]; + + // Submit to queue + VK_CHECK_RESULT(vkQueueSubmit(queue, 1, &submitInfo, VK_NULL_HANDLE)); + + VulkanExampleBase::submitFrame(); + } + void prepare() { VulkanExampleBase::prepare(); @@ -483,15 +459,40 @@ public: { if (!prepared) return; - vkDeviceWaitIdle(device); draw(); - vkDeviceWaitIdle(device); } virtual void viewChanged() { updateUniformBuffers(); } + + void toggleNormals() + { + displayNormals = !displayNormals; + reBuildCommandBuffers(); + } + + + virtual void keyPressed(uint32_t keyCode) + { + switch (keyCode) + { + case 0x4E: + case GAMEPAD_BUTTON_A: + toggleNormals(); + break; + } + } + + virtual void getOverlayText(VulkanTextOverlay *textOverlay) + { +#if defined(__ANDROID__) + textOverlay->addText("Press \"Button A\" to toggle normals", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); +#else + textOverlay->addText("Press \"n\" to toggle normals", 5.0f, 85.0f, VulkanTextOverlay::alignLeft); +#endif + } }; VulkanExample *vulkanExample;