createCubeTextureFromPixels method

  1. @override
TextureHandle createCubeTextureFromPixels({
  1. required int size,
  2. required TextureFormat format,
  3. required List<ByteData> faces,
  4. List<List<ByteData>>? mipLevels,
})
override

Uploads six square images as one cube texture.

faces are in the order every graphics API in use agrees on: +X, −X, +Y, −Y, +Z, −Z. Documented once, here, because it is the piece of this that has no natural check: a table with two entries transposed produces a sky that is complete, seamless and wrong, and it looks like a sky somebody authored badly rather than like a bug. The conformance check a cube map answers the face a direction points at draws six known directions against six known colours for exactly this, through the cube-sky stage pair, and names the transposed pair when it fails.

Every face is size by size — cube faces are square by definition, and a rectangular one is a mistake worth refusing rather than resizing.

Throws UnsupportedCapabilityException when the device cannot make cubes, and a DeviceResourceException when there are not six faces or a face is not the size its description says — the same rule as createTextureFromPixels, whose caller decides whether an asset that disagrees about its own dimensions costs a texture or the frame.

mipLevels are the smaller copies, from half size downwards: one entry per level, each holding six faces in the same order as faces. Null or empty gives a cube with a base level only, which is what a sky wants.

Roughness is what these are for. A sky is sampled at one level and needs none; a prefiltered radiance map is a cube whose levels are the roughness scale, each one the environment convolved a little further. That is the one use, and it is why this takes a chain the caller has already built rather than offering to generate one: the levels are not a box blur of each other, and a device that filled them by halving would produce something that looks nearly right and is wrong everywhere it matters.

Built above the seam for the same reason createTextureFromPixels's are — flutter_gpu has no generateMipmap — so both backends receive the same bytes and the two golden sets stay comparable.

Ask features.has(DeviceFeature.cubeTextures) first.

Implementation

@override
TextureHandle createCubeTextureFromPixels({
  required int size,
  required TextureFormat format,
  required List<ByteData> faces,
  // Recorded by no fake and refused by none: this backend answers the shape
  // of a call, not the contents of a texture.
  List<List<ByteData>>? mipLevels,
}) => faces.length == 6
    ? _born(
        wrapTexture(
          owner: this,
          backend: const Object(),
          width: size,
          height: size,
          format: format,
          type: TextureType.textureCube,
        ),
      )
    : throw refuseResource(
        'createCubeTextureFromPixels',
        'a cube has six faces and ${faces.length} were given',
      );