module Render.Unlit.Colored.Pipeline ( Pipeline , allocate , allocateWireframe ) where import RIO import Control.Monad.Trans.Resource (ResourceT) import Data.Tagged (Tagged(..)) import Vulkan.Core10 qualified as Vk import Vulkan.Zero (zero) import Engine.Vulkan.Pipeline qualified as Pipeline import Engine.Vulkan.Types (HasVulkan, HasRenderPass(..), DsBindings) import Render.Code (compileVert, compileFrag, glsl) import Render.DescSets.Set0 (Scene, vertexPos, instanceTransform) import Render.DescSets.Set0.Code (set0binding0) import Render.Unlit.Colored.Model qualified as Model type Config = Pipeline.Config '[Scene] Model.VertexAttrs Model.InstanceAttrs type Pipeline = Pipeline.Pipeline '[Scene] Model.VertexAttrs Model.InstanceAttrs allocate :: ( HasVulkan env , HasRenderPass renderpass ) => Bool -> Vk.SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline allocate useDepth multisample tset0 rp = do (_, p) <- Pipeline.allocate Nothing multisample (config useDepth tset0) rp pure p allocateWireframe :: ( HasVulkan env , HasRenderPass renderpass ) => Bool -> Vk.SampleCountFlagBits -> Tagged Scene DsBindings -> renderpass -> ResourceT (RIO env) Pipeline allocateWireframe useDepth multisample tset0 rp = do (_, p) <- Pipeline.allocate Nothing multisample (configWireframe useDepth tset0) rp pure p config :: Bool -> Tagged Scene DsBindings -> Config config useDepth (Tagged set0) = zero { Pipeline.cDescLayouts = Tagged @'[Scene] [set0] , Pipeline.cVertexCode = Just vertCode , Pipeline.cVertexInput = vertexInput , Pipeline.cFragmentCode = Just fragCode , Pipeline.cBlend = True , Pipeline.cDepthTest = useDepth , Pipeline.cDepthWrite = useDepth } where vertexInput = Pipeline.vertexInput [ vertexPos , (Vk.VERTEX_INPUT_RATE_VERTEX, Model.vkVertexAttrs) , instanceTransform ] configWireframe :: Bool -> Tagged Scene DsBindings -> Config configWireframe useDepth tset0 = (config useDepth tset0) { Pipeline.cTopology = Vk.PRIMITIVE_TOPOLOGY_LINE_LIST } vertCode :: ByteString vertCode = $(compileVert [glsl| #version 450 #extension GL_ARB_separate_shader_objects : enable ${set0binding0} layout(location = 0) in vec3 vPosition; layout(location = 1) in vec4 vColor; layout(location = 2) in mat4 iModel; layout(location = 0) out vec4 fColor; void main() { gl_Position = scene.projection * scene.view * iModel * vec4(vPosition, 1.0); fColor = vColor; fColor.rgb * fColor.a; } |]) fragCode :: ByteString fragCode = $(compileFrag [glsl| #version 450 #extension GL_ARB_separate_shader_objects : enable layout(location = 0) in vec4 fragColor; layout(location = 0) out vec4 outColor; void main() { outColor = fragColor; } |])