diff --git a/project-words.txt b/project-words.txt index 69ccd82..fca2429 100644 --- a/project-words.txt +++ b/project-words.txt @@ -26,6 +26,7 @@ SUBPASS subpasses subresource Subresource +succ swapchain Swapchain SWAPCHAIN diff --git a/src/Draw.hs b/src/Draw.hs index 37fb799..1428747 100644 --- a/src/Draw.hs +++ b/src/Draw.hs @@ -20,7 +20,7 @@ import Control.Monad.IO.Class (MonadIO(liftIO)) drawFrame :: (MonadResource m) => EngineData - -> STM.TMVar Bool + -> STM.TMVar Pipelines -> m () drawFrame engineData switch = do @@ -61,11 +61,13 @@ drawFrame engineData switch = do (engineRenderPass engineData) (engineFramebuffers engineData V.! fromIntegral index) (engineWindowDimensions engineData) - (if switchState - then + (case switchState of + Rainbow -> redEnginePipelines engineData V.! fromIntegral index - else + Red -> rainbowEnginePipelines engineData V.! fromIntegral index + Green -> + meshPipeline engineData V.! fromIntegral index ) let submitInfo = Vk.zero diff --git a/src/GraphicsPipeline.hs b/src/GraphicsPipeline.hs index b2e6fa4..dad0ae9 100644 --- a/src/GraphicsPipeline.hs +++ b/src/GraphicsPipeline.hs @@ -237,7 +237,7 @@ createGraphicsPipelines , Vk.attachments = V.singleton colorBlendAttachment } pipelineCreateInfo = Vk.zero - { Vk.stageCount = 2 + { Vk.stageCount = fromIntegral (V.length pipelineStagesCreateInfos) , Vk.stages = pipelineStagesCreateInfos , Vk.vertexInputState = Just $ Vk.SomeStruct pipelineVertexInputCreateInfo , Vk.inputAssemblyState = diff --git a/src/Init.hs b/src/Init.hs index e782a68..026e739 100644 --- a/src/Init.hs +++ b/src/Init.hs @@ -88,10 +88,12 @@ initVulkan window = do redFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/red.frag" "frag" rainbowVertexShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.vert" "vert" rainbowFragmentShader <- loadShader vulkanLogicalDevice "shadersrc/rainbow.frag" "frag" + meshVertexShader <- loadShader vulkanLogicalDevice "shadersrc/mesh.vert" "vert" renderPass <- createRenderPass vulkanLogicalDevice (Khr.format surfaceFormat) pipelineLayout <- createPipelineLayout vulkanLogicalDevice let redContainer = ShaderContainer (Just redVertexShader) (Just redFragmentShader) - let rainbowContainer = ShaderContainer (Just rainbowVertexShader) (Just rainbowFragmentShader) + rainbowContainer = ShaderContainer (Just rainbowVertexShader) (Just rainbowFragmentShader) + meshContainer = ShaderContainer (Just meshVertexShader) Nothing redPipelines <- createGraphicsPipelines vulkanLogicalDevice @@ -108,6 +110,14 @@ initVulkan window = do dimensions (length imageViews) pipelineLayout + meshPipelines <- + createGraphicsPipelines + vulkanLogicalDevice + renderPass + meshContainer + dimensions + (length imageViews) + pipelineLayout frameBuffers <- createFramebuffer vulkanLogicalDevice renderPass imageViews dimensions @@ -127,10 +137,9 @@ initVulkan window = do frameBuffers redPipelines rainbowPipelines - undefined -- placeholder for meshPipeline + meshPipelines renderPass inFlightFence imageAvailableSemaphore renderFinishedSemaphore mesh - diff --git a/src/Main.hs b/src/Main.hs index 8957b60..0a0feec 100644 --- a/src/Main.hs +++ b/src/Main.hs @@ -28,7 +28,7 @@ main = runResourceT $ do -- create abort condition for upcoming lop quit <- liftIO $ STM.newTMVarIO True - secondPipeline <- liftIO $ STM.newTMVarIO False + showPipeline <- liftIO $ STM.newTMVarIO Rainbow -- main loop whileM_ @@ -36,7 +36,7 @@ main = runResourceT $ do ) ( do -- draw - drawFrame engineData secondPipeline + drawFrame engineData showPipeline -- poll events evs <- liftIO SDL.pollEvents -- flip abort condition on window close @@ -48,8 +48,14 @@ main = runResourceT $ do case dat of SDL.KeyboardEventData _ SDL.Released _ (SDL.Keysym _ SDL.KeycodeSpace _) -> liftIO $ STM.atomically $ do - state <- STM.readTMVar secondPipeline - void $ STM.swapTMVar secondPipeline (not state) + state <- STM.readTMVar showPipeline + void $ STM.swapTMVar showPipeline + (if state /= maxBound then succ state else state) + SDL.KeyboardEventData _ SDL.Released _ (SDL.Keysym _ SDL.KeycodeTab _) -> + liftIO $ STM.atomically $ do + state <- STM.readTMVar showPipeline + void $ STM.swapTMVar showPipeline + (if state /= minBound then pred state else state) _ -> return () _ -> return () ) diff --git a/src/Memory.hs b/src/Memory.hs index 0a4ea13..0eb74f4 100644 --- a/src/Memory.hs +++ b/src/Memory.hs @@ -38,7 +38,7 @@ initAllocator physicalDevice device instance' = do (_, allocator) <- allocate (VMA.createAllocator allocatorInfo) (\allocator -> do - print ("destroying allocator" :: String) + putStrLn "destroying allocator" VMA.destroyAllocator allocator ) diff --git a/src/Mesh.hs b/src/Mesh.hs index e89c2ee..0bc3707 100644 --- a/src/Mesh.hs +++ b/src/Mesh.hs @@ -48,7 +48,7 @@ uploadMesh vertices allocator = do return (Mesh vertices (AllocatedBuffer buffer allocation)) ) (\(Mesh _ (AllocatedBuffer buffer allocation)) -> do - print ("destroying mesh" :: String) + putStrLn "destroying mesh" VMA.destroyBuffer allocator buffer allocation ) diff --git a/src/Types.hs b/src/Types.hs index 46ffe25..c0dcfea 100644 --- a/src/Types.hs +++ b/src/Types.hs @@ -1,3 +1,4 @@ +{-# LANGUAGE DuplicateRecordFields #-} module Types where import qualified Data.Vector as V @@ -7,8 +8,16 @@ import Foreign.C.Types (CInt) import Linear import qualified SDL import qualified Vulkan as Vk +import qualified Vulkan.Core10 as Vk +import qualified Vulkan.Zero as Vk import qualified VulkanMemoryAllocator as VMA +data Pipelines + = Rainbow + | Red + | Green + deriving (Eq, Ord, Enum, Bounded) + data ShaderContainer = ShaderContainer { containedVertexShader :: Maybe Vk.ShaderModule , containedFragmentShader :: Maybe Vk.ShaderModule @@ -60,6 +69,51 @@ instance Storable Vertex where alignment _ = undefined +class VertexInputDescribable v where + + getVertexDescription :: v -> VertexInputDescription + +instance VertexInputDescribable Vertex where + + getVertexDescription v = + let mainBinding = Vk.zero + { Vk.binding = 0 + , Vk.stride = fromIntegral (sizeOf v) + , Vk.inputRate = Vk.VERTEX_INPUT_RATE_VERTEX + } :: Vk.VertexInputBindingDescription + positionAttribute = Vk.zero + { Vk.binding = 0 + , Vk.location = 0 + , Vk.format = Vk.FORMAT_R32G32B32_SFLOAT + , Vk.offset = 0 + } :: Vk.VertexInputAttributeDescription + normalAttribute = Vk.zero + { Vk.binding = 0 + , Vk.location = 1 + , Vk.format = Vk.FORMAT_R32G32B32_SFLOAT + , Vk.offset = fromIntegral (sizeOf (vertexPosition v)) + } :: Vk.VertexInputAttributeDescription + colorAttribute = Vk.zero + { Vk.binding = 0 + , Vk.location = 2 + , Vk.format = Vk.FORMAT_R32G32B32A32_SFLOAT + , Vk.offset = fromIntegral (sizeOf (vertexPosition v) + sizeOf (vertexNormal v)) + } :: Vk.VertexInputAttributeDescription + in + VertexInputDescription + { vidBindings = V.fromList [ mainBinding ] + , vidAttributes = V.fromList + [ positionAttribute + , normalAttribute + , colorAttribute + ] + } + +data VertexInputDescription = VertexInputDescription + { vidBindings :: V.Vector Vk.VertexInputBindingDescription + , vidAttributes :: V.Vector Vk.VertexInputAttributeDescription + } + data Mesh = Mesh { meshVertices :: V.Vector Vertex , meshBuffer :: AllocatedBuffer