packages feed

keid-render-basic-0.1.8.0: src/Render/Unlit/Line2d/Draw.hs

{-# LANGUAGE OverloadedLists #-}

module Render.Unlit.Line2d.Draw where

import RIO

import Vulkan.Core10 qualified as Vk
import Vulkan.NamedType ((:::))

import Engine.Vulkan.Types (Bound(..))
import Render.Unlit.Line2d.Model qualified as Model
import Resource.Buffer qualified as Buffer

batch
  :: (MonadIO m, Foldable t)
  => Vk.CommandBuffer
  -> Model.Segment
  -> Buffer.Allocated s Model.InstanceAttrs
  -> t ("firstInstance" ::: Word32, "instanceCount" ::: Word32)
  -> Bound dsl vertices instances m ()
batch cmd vertices points ranges =
  when (Buffer.aUsed points >= 2) do -- XXX: at least one segment to draw
    bind cmd vertices points
    -- TODO: check bindings
    Bound $
      traverse_ (segments cmd vertices) ranges

single
  :: MonadIO m
  => Vk.CommandBuffer
  -> Model.Segment
  -> Buffer.Allocated s Model.InstanceAttrs
  -> Bound dsl vertices instances m ()
single cmd vertices points =
  batch cmd vertices points $
    Just
      ( 0
      , Buffer.aUsed points
      )

bind
  :: MonadIO io
  => Vk.CommandBuffer
  -> Model.Segment
  -> Model.Buffer s
  -> io ()
bind cmd vertices points = do
  Vk.cmdBindVertexBuffers
    cmd
    0
    buffers
    offsets
  where
    buffers =
      [ Buffer.aBuffer vertices
      , Buffer.aBuffer points
      , Buffer.aBuffer points
      ]

    offsets =
      [ 0
      , 0
      , 4*4 + 4*4 -- vec4, vec4
      ]

segments
  :: MonadIO io
  => Vk.CommandBuffer
  -> Buffer.Allocated s a
  -> ("firstInstance" ::: Word32, "instanceCount" ::: Word32)
  -> io ()
segments cmd vertices (offset, size) =
  when (numSegments > 0) $
    Vk.cmdDraw
      cmd
      vertexCount
      instanceCount
      firstVertex
      firstInstance
  where
    firstVertex = 0
    vertexCount = Buffer.aUsed vertices

    numSegments = size - 1
    firstInstance = offset
    instanceCount = numSegments