add alpha/requireAlpha argument when decoding images

remove size checks from setImage (we are assuming the caller knows the correct size)
This also adds some monkey-patch methods to js_interop to convert Float32List to a UInt8List (but use this with care, because it will only work for emscripten-allocated objects)
This commit is contained in:
Nick Fisher
2025-05-29 22:26:42 +08:00
parent c789e75af5
commit 86894cf583
12 changed files with 115 additions and 61 deletions

View File

@@ -310,6 +310,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
TextureSamplerType textureSamplerType = TextureSamplerType.SAMPLER_2D,
TextureFormat textureFormat = TextureFormat.RGBA16F,
int? importedTextureHandle}) async {
var bitmask = flags.fold(0, (a, b) => a | b.value);
final texturePtr = await withPointerCallback<TTexture>((cb) {
@@ -362,19 +363,28 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
return FFITextureSampler(samplerPtr);
}
/// Decodes the image data into a native LinearImage (floating point).
/// If [requireAlpha] is true, the decoded image will always contain an
/// alpha channel (even if the original image did not contain one).
///
///
///
Future<LinearImage> decodeImage(Uint8List data) async {
final name = "image";
Future<LinearImage> decodeImage(Uint8List data, { String name = "image", bool requireAlpha = false}) async {
late Pointer stackPtr;
if (FILAMENT_WASM) {
//stackPtr = stackSave();
}
var now = DateTime.now();
var ptr = Image_decode(
data.address,
data.length,
name.toNativeUtf8().cast<Char>(),
requireAlpha
);
var finished = DateTime.now();
print(
"Image_decode (render thread) finished in ${finished.millisecondsSinceEpoch - now.millisecondsSinceEpoch}ms",
);
if (FILAMENT_WASM) {
@@ -1114,11 +1124,11 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
if (FILAMENT_WASM) {
stackPtr = stackSave();
}
TransformManager_setTransform(transformManager, entity, matrix4ToDouble4x4(transform));
TransformManager_setTransform(
transformManager, entity, matrix4ToDouble4x4(transform));
if (FILAMENT_WASM) {
stackRestore(stackPtr);
}
}
///
@@ -1129,7 +1139,7 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
if (FILAMENT_WASM) {
stackPtr = stackSave();
}
var transform = double4x4ToMatrix4(
TransformManager_getWorldTransform(transformManager, entity));
if (FILAMENT_WASM) {
@@ -1137,5 +1147,4 @@ class FFIFilamentApp extends FilamentApp<Pointer> {
}
return transform;
}
}

View File

@@ -165,15 +165,10 @@ class FFILinearImage extends LinearImage {
}
static Future<FFILinearImage> decode(Uint8List data,
[String name = "image"]) async {
final namePtr = name.toNativeUtf8();
final imagePtr = await withPointerCallback<TLinearImage>((cb) {
Image_decodeRenderThread(
data.address, data.lengthInBytes, namePtr.cast(), cb);
});
return FFILinearImage(imagePtr);
{String name = "image", bool requireAlpha = false}) async {
final image = await FilamentApp.instance!
.decodeImage(data, name: name, requireAlpha: requireAlpha);
return image as FFILinearImage;
}
Future<void> destroy() async {

View File

@@ -133,7 +133,7 @@ abstract class FilamentApp<T> {
///
/// Decodes the specified image data.
///
Future<LinearImage> decodeImage(Uint8List data);
Future<LinearImage> decodeImage(Uint8List data, { String name = "image", bool requireAlpha = false});
///
/// Creates an (empty) imge with the given dimensions.

View File

@@ -484,11 +484,17 @@ abstract class LinearImage {
Future<int> getHeight();
Future<int> getChannels();
/// Decodes the image contained in [data] and returns a texture of
/// the corresponding size with the image set as mip-level 0.
///
///
///
static Future<Texture> decodeToTexture(Uint8List data, { TextureFormat textureFormat = TextureFormat.RGB32F, PixelDataFormat pixelDataFormat = PixelDataFormat.RGB, PixelDataType pixelDataType = PixelDataType.FLOAT, int levels = 1}) async {
final decodedImage = await FilamentApp.instance!.decodeImage(data);
static Future<Texture> decodeToTexture(Uint8List data, {
TextureFormat textureFormat = TextureFormat.RGB32F,
PixelDataFormat pixelDataFormat = PixelDataFormat.RGB,
PixelDataType pixelDataType = PixelDataType.FLOAT,
int levels = 1,
bool requireAlpha = false}) async {
final decodedImage = await FilamentApp.instance!.decodeImage(data, requireAlpha: requireAlpha);
final texture = await FilamentApp.instance!.createTexture(
await decodedImage.getWidth(),