---
title: "Blitting"
output: rmarkdown::html_vignette
vignette: >
  %\VignetteIndexEntry{Blitting}
  %\VignetteEngine{knitr::rmarkdown}
  %\VignetteEncoding{UTF-8}
---

```{r, include = FALSE}
knitr::opts_chunk$set(
  collapse = TRUE,
  comment = "#>"
)
set.seed(1)
```

```{r setup, echo = FALSE}
library(nara)
```

[Blitting](https://en.wikipedia.org/wiki/Bit_blit) is a term used in computer
graphics to describe the copying of whole or part of one image into another.

This copying is optinised for speed and forms a significant part of the 
underlying mechanics for 2D games and interactive applications.  For example:

* putting a players character on the scrolling background in a game
* Assembling a background image from a small library of tiled images
* Placing pre-rendered pieces on a game board


`{nara}` includes two blitting functions:

* `nr_blit()`
    * Blit a single source image at one (or multiple) locations in the destination
      image.
* `nr_blit_multi()`
    * Define a complex sequence of blitting operations using a data.frame
    
# `nr_blit()`

Use `nr_blit()` when you want to use a single source image only
    
### Blit a single image

```{r}
library(nara)

# Create a canvas to draw on
w <- 300
h <- 300
nr <- nr_new(w, h, 'grey90')

# Place a deer on the canvas
nr_blit(nr, deer[[1]], w/2, h/2)

plot(nr)
```    
    
    
### Blit a single image to multiple locations


```{r}
# Create a canvas to draw on
nr <- nr_new(w, h, 'grey90')

# Place a deer on the canvas at many locations
xs <- runif(20, 0, w)
ys <- runif(20, 0, h)
nr_blit(nr, deer[[1]], xs, ys)

plot(nr)
```
    
    
### Blit a single image to multiple locations with varying angles and scales


```{r}
# Create a canvas to draw on
nr <- nr_new(w, h, 'grey90')

# Place a deer on the canvas at many locations
xs <- runif(20, 0, w)
ys <- runif(20, 0, h)
angles <- runif(20, 0, 2*pi)
scales <- runif(20, 0.5, 2)
nr_blit(nr, deer[[1]], xs, ys, angle = angles, scale = scales)

plot(nr)
```



# `nr_blit_multi()`

If you have multiple source images to blit, there are two possible approaches:

* Loop over the images and blit them one-at-a-time with `nr_blit()`
* Set-up a configuration data.frame and blit them all-at-once with `nr_blit_multi()`

For most simple tasks, `nr_blit()` should be sufficient.

For larger structures, it may be useful to store blitting parameters in a data.frame
for organisation purposes. 

The `{nara}` packages includes a `tileset` (a list of nativerasters which 
can *tile* together to form an image) and a `tileset_config` giving one 
possible arrangement of tiles.

Combining `tileset` with `tileset_config` in `nr_blit_multi()` creates a 
complex image with a single function call.


```{r}
head(tileset_config)

w <- 70 * 11
h <- 70 * 8
nr <- nr_new(w, h, fill = 'lightblue')
nr_blit_multi(nr, tileset, config = tileset_config)

plot(nr)
```





### Blit with a mask

`{nara}` supports masked rendering of most drawing operations.

`blit_mask_begin()` and `blit_mask_end()` are used to delineate the use
of a mask on an image.

```{r}
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
# Setup a drawing canvas and an image to use as a mask
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
w <- 300
h <- 300
canvas <- nr_new(w, h, fill = 'lightblue')
mask   <- nr_new(w, h, fill = 'transparent')

# Set the top-left area of the mask to be the active area by making it 
# not transparent
nr_rect(mask, x=0, y=0, w=w/2, h=h/2)
plot(mask)

# Attach the mask to the canvas
nr_mask_begin(canvas, mask)
{
  # Draw random deer on the image - 
  xs <- runif(50, 0, w)
  ys <- runif(50, 0, h)
  nr_blit(canvas, deer[[1]], xs, ys)
}
nr_mask_end(canvas) # Finalise the masked operation


plot(canvas)
```
















