From cb1ad9f907a879a4402bcd121502f5e74aedd2f9 Mon Sep 17 00:00:00 2001 From: Miguel Date: Sat, 18 Jan 2025 23:42:15 +0100 Subject: cleanup and some tiny experiments --- main.cpp | 41 ++++++++++++++++++++++++----------------- shaders/shader.frag | 48 +++++++++++++++++++++++++++++++++++++++++++++++- shaders/shader.vert | 16 ++++++++++++---- 3 files changed, 83 insertions(+), 22 deletions(-) diff --git a/main.cpp b/main.cpp index b57659b..e098ea8 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,11 @@ // Coding along: https://docs.vulkan.org/tutorial/ +// comment and simplify and abstract away +// make pure/static as much as possible +// build with cmake for: linux/freebsd/mac/win/android/ios? +// raymarch game + + #define GLFW_INCLUDE_VULKAN #include @@ -30,6 +36,7 @@ public: private: + static const int MAX_FRAMES_IN_FLIGHT = 2; static const uint32_t WIDTH = 800; static const uint32_t HEIGHT = 600; @@ -220,7 +227,8 @@ private: scissor.extent = swapChainExtent; vkCmdSetScissor(commandBuffer, 0, 1, &scissor); - vkCmdDraw(commandBuffer, 3, 1, 0, 0); + // verex count, instance count, first vertex, first instance + vkCmdDraw(commandBuffer, 6, 1, 0, 0); vkCmdEndRenderPass(commandBuffer); if (vkEndCommandBuffer(commandBuffer) != VK_SUCCESS) { @@ -297,10 +305,10 @@ private: subpass.pColorAttachments = &colorAttachmentRef; VkSubpassDependency dependency{}; - dependency.srcSubpass = VK_SUBPASS_EXTERNAL; - dependency.dstSubpass = 0; + dependency.srcSubpass = VK_SUBPASS_EXTERNAL; // implicit subpass before OR after render pass (depends if defined on src or dst) dependency.srcStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.srcAccessMask = 0; + dependency.dstSubpass = 0; // our one and only pass dependency.dstStageMask = VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT; dependency.dstAccessMask = VK_ACCESS_COLOR_ATTACHMENT_WRITE_BIT; @@ -363,7 +371,7 @@ private: inputAssembly.sType = VK_STRUCTURE_TYPE_PIPELINE_INPUT_ASSEMBLY_STATE_CREATE_INFO; inputAssembly.topology = VK_PRIMITIVE_TOPOLOGY_TRIANGLE_LIST; inputAssembly.primitiveRestartEnable = VK_FALSE; - +/* VkViewport viewport{}; viewport.x = 0.0f; viewport.y = 0.0f; @@ -375,8 +383,9 @@ private: VkRect2D scissor{}; scissor.offset = {0, 0}; scissor.extent = swapChainExtent; +*/ -// DYN STATE? +// DYN STATE VkPipelineViewportStateCreateInfo viewportState{}; viewportState.sType = VK_STRUCTURE_TYPE_PIPELINE_VIEWPORT_STATE_CREATE_INFO; viewportState.viewportCount = 1; @@ -397,7 +406,6 @@ private: rasterizer.lineWidth = 1.0f; rasterizer.cullMode = VK_CULL_MODE_BACK_BIT; rasterizer.frontFace = VK_FRONT_FACE_CLOCKWISE; - rasterizer.depthBiasEnable = VK_FALSE; rasterizer.depthBiasConstantFactor = 0.0f; // Optional rasterizer.depthBiasClamp = 0.0f; // Optional @@ -534,6 +542,7 @@ private: uint32_t queueFamilyIndices[] = {indices.graphicsFamily.value(), indices.presentFamily.value()}; if (indices.graphicsFamily != indices.presentFamily) { + // handle swap chain across different queues createInfo.imageSharingMode = VK_SHARING_MODE_CONCURRENT; createInfo.queueFamilyIndexCount = 2; createInfo.pQueueFamilyIndices = queueFamilyIndices; @@ -542,10 +551,11 @@ private: createInfo.queueFamilyIndexCount = 0; // Optional createInfo.pQueueFamilyIndices = nullptr; // Optional } + createInfo.preTransform = swapChainSupport.capabilities.currentTransform; createInfo.compositeAlpha = VK_COMPOSITE_ALPHA_OPAQUE_BIT_KHR; createInfo.presentMode = presentMode; - createInfo.clipped = VK_TRUE; + createInfo.clipped = VK_TRUE; // don't care about pixels obscured by other windows (we do not need to read them back) createInfo.oldSwapchain = VK_NULL_HANDLE; if (vkCreateSwapchainKHR(device, &createInfo, nullptr, &swapChain) != VK_SUCCESS) { @@ -621,7 +631,7 @@ private: vkEnumeratePhysicalDevices(instance, &deviceCount, devices.data()); for (const auto& device : devices) - if (isDeviceSuitable(device)) { physicalDevice = device; break; } + if (isDeviceSuitable(device)) { if (physicalDevice == VK_NULL_HANDLE) physicalDevice=device; } if (physicalDevice == VK_NULL_HANDLE) throw std::runtime_error("failed to find a suitable GPU!"); } @@ -684,6 +694,7 @@ private: vkWaitForFences(device, 1, &inFlightFence, VK_TRUE, UINT64_MAX); vkResetFences(device, 1, &inFlightFence); + uint32_t imageIndex; vkAcquireNextImageKHR(device, swapChain, UINT64_MAX, imageAvailableSemaphore, VK_NULL_HANDLE, &imageIndex); vkResetCommandBuffer(commandBuffer, 0); @@ -691,30 +702,26 @@ private: VkSubmitInfo submitInfo{}; submitInfo.sType = VK_STRUCTURE_TYPE_SUBMIT_INFO; - VkSemaphore waitSemaphores[] = {imageAvailableSemaphore}; + VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; VkPipelineStageFlags waitStages[] = {VK_PIPELINE_STAGE_COLOR_ATTACHMENT_OUTPUT_BIT}; submitInfo.waitSemaphoreCount = 1; submitInfo.pWaitSemaphores = waitSemaphores; submitInfo.pWaitDstStageMask = waitStages; - - submitInfo.commandBufferCount = 1; - submitInfo.pCommandBuffers = &commandBuffer; - - VkSemaphore signalSemaphores[] = {renderFinishedSemaphore}; submitInfo.signalSemaphoreCount = 1; submitInfo.pSignalSemaphores = signalSemaphores; + submitInfo.commandBufferCount = 1; + submitInfo.pCommandBuffers = &commandBuffer; if (vkQueueSubmit(graphicsQueue, 1, &submitInfo, inFlightFence) != VK_SUCCESS) { throw std::runtime_error("failed to submit draw command buffer!"); } VkPresentInfoKHR presentInfo{}; + VkSwapchainKHR swapChains[] = {swapChain}; presentInfo.sType = VK_STRUCTURE_TYPE_PRESENT_INFO_KHR; presentInfo.waitSemaphoreCount = 1; presentInfo.pWaitSemaphores = signalSemaphores; - - VkSwapchainKHR swapChains[] = {swapChain}; presentInfo.swapchainCount = 1; presentInfo.pSwapchains = swapChains; presentInfo.pImageIndices = &imageIndex; @@ -778,7 +785,7 @@ private: return true; } - std::vector getRequiredExtensions() { + static std::vector getRequiredExtensions() { uint32_t glfwExtensionCount = 0; const char** glfwExtensions; glfwExtensions = glfwGetRequiredInstanceExtensions(&glfwExtensionCount); //e.g VK_KHR_surface diff --git a/shaders/shader.frag b/shaders/shader.frag index 7c5b0e7..7566a89 100644 --- a/shaders/shader.frag +++ b/shaders/shader.frag @@ -4,6 +4,52 @@ layout(location = 0) in vec3 fragColor; layout(location = 0) out vec4 outColor; +vec4 mainImage(); + void main() { - outColor = vec4(fragColor, 1.0); + if(mod (gl_FragCoord.x,3.0) < 1 && mod(gl_FragCoord.y,2.0) > 1) + outColor = vec4(1,1,1,1.0); + else + outColor = mainImage(); //vec4(fragColor, 1.0); + +} + + +// https://www.shadertoy.com/view/WdsGzM + +#define PI 3.14159265359 + +vec2 rotate2d(vec2 uv,float _angle){return mat2(cos(_angle),-sin(_angle),sin(_angle),cos(_angle)) * uv;} +vec2 scale2d(vec2 uv,float _scale){return uv * mat2(_scale,0.0,0.0,_scale);} + +float random (vec2 st) { + return fract(sin(dot(st.xy,vec2(20.,100.)))*10000.); +} + +vec4 mainImage() +{ + vec2 fragCoord; + fragCoord.x=gl_FragCoord.x; + fragCoord.y=gl_FragCoord.y; + int iTime = 0; + vec2 iResolution = vec2(800,600); + + /// + vec2 uv = fragCoord/iResolution.xy; + uv.x *= iResolution.x / iResolution.y; + uv=rotate2d(uv,1.+fract(iTime*0.02)*2.*PI); + uv*=5.+0.4*sin(iTime/2.); + + + vec2 pos = vec2(0.5)-fract(uv); + pos=rotate2d(pos,fract(iTime*0.4+random(floor(uv)))*2.*PI); + pos=scale2d(pos,0.5+sin(random(uv+fract(iTime)*2.*PI))); + + + float r = length(pos)*2.0; + float a = atan(pos.y,pos.x); + float f = smoothstep(-.0,1., cos(a*max(3.,floor(abs(uv.x))*floor(abs(uv.y)))))*0.3+0.5; + vec3 color = vec3( 1.-smoothstep(f,f+0.02,r) ); + return vec4(color*vec3(0.1,0.5*random(floor(uv)),0.8+0.1*sin(2.*PI*fract(iTime*0.3))),1.0); + } diff --git a/shaders/shader.vert b/shaders/shader.vert index f5b2f8d..e8c6a28 100644 --- a/shaders/shader.vert +++ b/shaders/shader.vert @@ -2,16 +2,24 @@ layout(location = 0) out vec3 fragColor; -vec2 positions[3] = vec2[]( +vec2 positions[6] = vec2[]( vec2(0.0, -0.5), vec2(0.5, 0.5), - vec2(-0.5, 0.5) + vec2(-0.5, 0.5), + + vec2(0, -1), + vec2(1, -1), + vec2(1, 1) ); -vec3 colors[3] = vec3[]( +vec3 colors[6] = vec3[]( vec3(1.0, 0.0, 0.0), vec3(0.0, 1.0, 0.0), - vec3(0.0, 0.0, 1.0) + vec3(0.0, 0.0, 1.0), + + vec3(0.0, 1.0, 1.0), + vec3(0.0, 1.0, 1.0), + vec3(0.0, 1.0, 1.0) ); void main() { -- cgit v1.2.3