Understanding 1D Arrays for 2D Pixel Storage in Graphics

Let’s look at how each pixel’s colour is stored in a single 32-bit integer using the RGBA format

1D Array Representation

The buffer is a 1D array that stores the pixel colors for each pixel in the window. The array’s length is width * height, and each entry in the array is a 32-bit integer (u32), which represents the color of a pixel in RGBA format (though in this case, it’s grayscale, so the R, G, and B channels are all the same).

For example, if the window is 4×2 pixels, you would have 8 entries in the 1D buffer, one for each pixel. Each entry would hold a 32-bit value that represents the color of that pixel.


Color Encoding (using u32):

Each Pixel(x, y) is stored as a u32, with its color encoded in RGBA format. Since the code uses grayscale, each pixel’s R, G, and B values are the same, and the alpha (A) is fully opaque (255).

For example:

If the brightness of a pixel is 128 (a middle gray value), the color encoding would look like this:

Alpha: 255 = 0xFF
Red: 128 = 0x80
Green: 128 = 0x80
Blue: 128 = 0x80

How 2D Coordinates Map to 1D Index:

For any pixel at 2D coordinates (row, column), its index in the 1D array can be calculated with this formula:

index = row * width + column

Flattened Hex Array

0x00, 0x00, 0x00, 0x00, // Pixel 0 (transparent)
0x00, 0x00, 0x00, 0x00, // Pixel 1 (transparent)
0x00, 0x00, 0x00, 0x00, // Pixel 2 (transparent)
0x00, 0x00, 0x00, 0x00, // Pixel 3 (transparent)
0x00, 0x00, 0x00, 0x00, // Pixel 4 (transparent)
0xFF, 0x00, 0x00, 0xFF, // Pixel 5 (red)
0x00, 0x00, 0x00, 0x00, // Pixel 6 (transparent)
0x00, 0x00, 0x00, 0x00 // Pixel 7 (transparent)

To calculate the array position of a pixel in a 2D grid stored as a 1D array, you can use the formula:

position = row * width + column

Explanation

  • row: The 0-based index of the row where the pixel is located.
  • column: The 0-based index of the column where the pixel is located.
  • width: The total number of pixels in a row (image width).

Example

For a 4×2 image (4 pixels wide and 2 pixels high):

  • Width = 4 (pixels per row)
  • Row indices: 0 (top) and 1 (bottom)
  • Column indices: 0, 1, 2, 3 (left to right)

Find the Array Position of Pixel in Row 1, Column 2:

  1. Substitute:
  • row = 1 (second row)
  • column = 2 (third pixel in the row)
  • width = 4
  1. Calculate:
   position = row * width + column
            = 1 * 4 + 2
            = 4 + 2
            = 6
  1. Result:
    The pixel at Row 1, Column 2 is at index 6 in the 1D array.

Adapting for Bytes (e.g., RGBA Format)

If each pixel is represented by multiple bytes (e.g., 4 bytes for RGBA), you multiply the position by the bytes-per-pixel (BPP):

byte_position = position * BPP

For example, with 4 bytes per pixel:

  • Index = 6
  • Bytes per pixel = 4
  • Byte position = 6 * 4 = 24

Thus, the pixel’s data starts at byte 24 in the 1D array.

Example minifb code in Rust

While we’re experimenting, let’s add some text to our minifb frame buffer code using the rusttype crate


hello rust
Rust Programming

Previous article

flatten v flat_map
Rust Programming

Next article

Rust Benchmark