{-# OPTIONS_GHC -Wno-unused-imports #-}

-- |
-- [Previous Chapter: Your First Shader]("Mischief.Render.Tutorial.Start.Shader")
--
-- [Next Chapter: Shaders]("Mischief.Render.Tutorial.Shaders")
--
-- [Main Page]("Mischief.Render")
module Mischief.Render.Tutorial.Basics
  ( -- * 2.1. Sprites
    -- $intro

    -- * Windows and Cameras
    -- $cameras

    -- * Sprites
    -- $sprites

    -- * [Next Chapter: Shaders]("Mischief.Render.Tutorial.Shaders")
  )
where

import Mischief.Animation
import Mischief.Assets
import Mischief.ECS
import Mischief.Materials qualified as Mat
import Mischief.Materials.Fullscreen qualified as Full
import Mischief.Materials.Sprite qualified as Sprite
import Mischief.Math
import Mischief.Math.Transform qualified as Transform
import Mischief.Render
import Mischief.Render.Camera

-- $intro
-- This chapter will go over some of the basic rendering tools and how to use them.

-- $cameras
-- In order to get anything to render, you will need to spawn a window, and a camera that outputs to it.
--
-- @
-- window <- 'spawn' 'Window'
-- 'spawn_' ('Camera', 'Rel' 'OutputTo' window)
-- @
--
-- The window can be given a title using @'WindowTitle'@, a size using @'WindowSize'@ and flags using @'WindowFlags'@. You can find
-- more info in "Mischief.SDL.Window".
--
-- Each camera has a 'CameraTexture' component containing its texture. A view to the texture can be obtained using
-- 'cameraView'. Alternatively, 'cameraSwapView' will give you the view while swapping the actual camera's texture to a secondary one,
-- so that you can both read and output to it at the same time.

-- $sprites
-- In order to spawn a sprite you need to give it the entity of an Image asset. You also need to
-- provide it a material.
--
-- @
-- img <- 'load' \@'Image' \"foo.png\"
-- spawn_ ('Sprite' img, 'WithMaterial' \@'Sprite.SpriteMaterial')
-- @
--
-- Sprites accept all forms of transform manipulation: movement, rotation, scaling.
--
-- @
-- -- rotating all sprites by 0.2
-- 'query_' $ do
--   (entity, transform) <- ['q'|Entity, Transform / With Sprite|]
--   'qlift' $ 'insert' (Transform.'Transform.rotateZ' 0.2) entity
-- @
--
-- You can insert a custom @SpriteSlice@ to make the sprite only a slice of its texture:
--
-- @
-- 'insert' ('SpriteSlice' ('V2' 30 0) ('V2' 50 50))
-- @
--
-- You can set a custom @SpriteFlip@ to flip the sprite horizontally or vertically:
--
-- @
-- 'insert' ('SpriteFlip' {x = True, y = False}) sprite
-- @
--
-- Internally, the information from all these components is uploaded into a @'Sprite.SpriteData'@ buffer on each entity, which is bound to the materials
-- extending 'Sprite.SpriteMaterial'. It is then used when calling 'Sprite.sampleSprite'.