content: {-# OPTIONS_GHC -Wno-missing-local-signatures #-}
  
  {-# LANGUAGE CPP                   #-}
  {-# LANGUAGE BlockArguments        #-}
  {-# LANGUAGE DataKinds             #-}
  {-# LANGUAGE FlexibleContexts      #-}
  {-# LANGUAGE PartialTypeSignatures #-}
  {-# LANGUAGE OverloadedLabels      #-}
  {-# LANGUAGE RebindableSyntax      #-}
  {-# LANGUAGE ScopedTypeVariables   #-}
  {-# LANGUAGE TypeApplications      #-}
  {-# LANGUAGE NamedWildCards        #-}
  {-# LANGUAGE TypeFamilies          #-}
  {-# LANGUAGE TypeOperators         #-}
  {-# LANGUAGE ViewPatterns          #-}
  
  module Shaders where
  
  import qualified Prelude
  
  -- fir
  import FIR
  import FIR.Syntax.Labels
  import Math.Linear
  
  -- ghengin
  import qualified Ghengin.Core.Shader as G
  
  width, height :: Prelude.Int
  (width, height) = (640, 480)
  
  --------------------------------------------------------------------------------
  -- Book of Shader: Uniforms
  --
  -- Bufferless rendering as seen in:
  --  https://www.saschawillems.de/blog/2016/08/13/vulkan-tutorial-on-rendering-a-fullscreen-quad-without-buffers/
  --------------------------------------------------------------------------------
  
  shaderPipelineSimple :: G.ShaderPipeline _
  shaderPipelineSimple
    = G.ShaderPipeline (StructInput @'[] @(Triangle List))
    G.:>-> vertexSimple
    G.:>-> fragmentSimple
  
  vertexSimple :: G.VertexShaderModule '[
      "out_uv" ':-> Output '[ Location 0 ] (V 2 Float)
    ] _
  vertexSimple = shader do
    vix <- #gl_VertexIndex
    let ux = convert ((vix `shiftL` (1 :: Code Word32)) .&. 2)
        uy = convert (vix .&. 2)
    #out_uv .= Vec2 ux uy
    #gl_Position .= Vec4 (ux*2 - 1) (uy*2 - 1) 0 1
  
  fragmentSimple :: G.FragmentShaderModule '[
      "in_uv" ':-> Input '[ Location 0 ] (V 2 Float)
    ] _
  fragmentSimple = shader do
    ~(Vec2 ix iy) <- #in_uv
    #out_colour .= Vec4 ix iy 0 1
  
  