Orrery
A GPU-accelerated N-body gravitational simulator
Loading...
Searching...
No Matches
image.hpp File Reference

An 8-bit colour image, and the one format this project writes it in. More...

#include <cstddef>
#include <cstdint>
#include <filesystem>
#include <span>
#include <vector>
#include "orrery/viz/tone_map.hpp"

Go to the source code of this file.

Classes

class  orrery::viz::Image
 A rectangle of 8-bit RGB pixels, row-major from the top left. More...

Functions

void orrery::viz::tone_map_into (Image &image, std::span< const float > radiance, ToneMapping mapping, bool bottom_up)
 Fill image from a buffer of linear radiance, three floats per pixel.

Detailed Description

An 8-bit colour image, and the one format this project writes it in.

The exported frames are PPM: a five-byte magic, the dimensions and the maximum value in ASCII, then three bytes per pixel with no compression and no metadata. It is the plainest raster format that exists.

That is a deliberate choice against PNG, which would produce files a fifth of the size and would need either a compression library as a dependency or a deflate implementation written here. ADR-0037 records it. The short version is that these files exist to be consumed by an encoder within seconds of being written and then deleted: the demonstration writes a few thousand of them, hands the directory to ffmpeg, and what survives is the video. Paying for a dependency, or for several hundred lines of bit manipulation, to make a temporary file smaller is the wrong trade, and every image viewer and every encoder reads PPM already.

The one real cost is disc traffic: a thousand frames at 1920 by 1080 is six gigabytes rather than one. docs/visualisation.md gives the pipe that avoids writing them at all when only the video is wanted.

Function Documentation

◆ tone_map_into()

void orrery::viz::tone_map_into ( Image & image,
std::span< const float > radiance,
ToneMapping mapping,
bool bottom_up )

Fill image from a buffer of linear radiance, three floats per pixel.

radiance must hold width * height * 3 values. Each is exposed, put through the tone curve and encoded for display by tone_map.hpp.

bottom_up says the source's first row is the bottom of the picture, which is how OpenGL reports a framebuffer: its origin is the lower left corner, while every raster format in common use starts at the top. Getting this wrong produces an image that is upside down and otherwise perfect, which is mentioned here because it is the failure this parameter exists to prevent.