merge native setImage with setImageWithDepth

This commit is contained in:
Nick Fisher
2025-06-17 13:25:53 +08:00
parent a91aaae131
commit 65ca59ff22
9 changed files with 94 additions and 378 deletions

View File

@@ -636,30 +636,6 @@ external bool Texture_loadImage(
int level, int level,
); );
@ffi.Native<
ffi.Bool Function(
ffi.Pointer<TEngine>,
ffi.Pointer<TTexture>,
ffi.Uint32,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32)>(isLeaf: true)
external bool Texture_setImage(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
int level,
ffi.Pointer<ffi.Uint8> data,
int size,
int width,
int height,
int channels,
int bufferFormat,
int pixelDataType,
);
@ffi.Native< @ffi.Native<
ffi.Bool Function( ffi.Bool Function(
@@ -677,7 +653,7 @@ external bool Texture_setImage(
ffi.Uint32, ffi.Uint32,
ffi.Uint32, ffi.Uint32,
ffi.Uint32)>(isLeaf: true) ffi.Uint32)>(isLeaf: true)
external bool Texture_setImageWithDepth( external bool Texture_setImage(
ffi.Pointer<TEngine> tEngine, ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture, ffi.Pointer<TTexture> tTexture,
int level, int level,
@@ -2531,33 +2507,6 @@ external void Texture_loadImageRenderThread(
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete, ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete,
); );
@ffi.Native<
ffi.Void Function(
ffi.Pointer<TEngine>,
ffi.Pointer<TTexture>,
ffi.Uint32,
ffi.Pointer<ffi.Uint8>,
ffi.Size,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32,
ffi.Uint32,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
isLeaf: true)
external void Texture_setImageRenderThread(
ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture,
int level,
ffi.Pointer<ffi.Uint8> data,
int size,
int width,
int height,
int channels,
int bufferFormat,
int pixelDataType,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>> onComplete,
);
@ffi.Native< @ffi.Native<
ffi.Void Function( ffi.Void Function(
@@ -2574,10 +2523,9 @@ external void Texture_setImageRenderThread(
ffi.Uint32, ffi.Uint32,
ffi.Uint32, ffi.Uint32,
ffi.Uint32, ffi.Uint32,
ffi.Uint32,
ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>( ffi.Pointer<ffi.NativeFunction<ffi.Void Function(ffi.Bool)>>)>(
isLeaf: true) isLeaf: true)
external void Texture_setImageWithDepthRenderThread( external void Texture_setImageRenderThread(
ffi.Pointer<TEngine> tEngine, ffi.Pointer<TEngine> tEngine,
ffi.Pointer<TTexture> tTexture, ffi.Pointer<TTexture> tTexture,
int level, int level,
@@ -2588,7 +2536,6 @@ external void Texture_setImageWithDepthRenderThread(
int z_offset, int z_offset,
int width, int width,
int height, int height,
int channels,
int depth, int depth,
int bufferFormat, int bufferFormat,
int pixelDataType, int pixelDataType,

View File

@@ -752,19 +752,8 @@ extension type NativeLibrary(JSObject _) implements JSObject {
int pixelDataType, int pixelDataType,
int level, int level,
); );
external int _Texture_setImage( external int _Texture_setImage(
Pointer<TEngine> tEngine,
Pointer<TTexture> tTexture,
int level,
Pointer<Uint8> data,
size_t size,
int width,
int height,
int channels,
int bufferFormat,
int pixelDataType,
);
external int _Texture_setImageWithDepth(
Pointer<TEngine> tEngine, Pointer<TEngine> tEngine,
Pointer<TTexture> tTexture, Pointer<TTexture> tTexture,
int level, int level,
@@ -775,7 +764,6 @@ extension type NativeLibrary(JSObject _) implements JSObject {
int z_offset, int z_offset,
int width, int width,
int height, int height,
int channels,
int depth, int depth,
int bufferFormat, int bufferFormat,
int pixelDataType, int pixelDataType,
@@ -1748,19 +1736,6 @@ extension type NativeLibrary(JSObject _) implements JSObject {
Pointer<self.NativeFunction<void Function(bool)>> onComplete, Pointer<self.NativeFunction<void Function(bool)>> onComplete,
); );
external void _Texture_setImageRenderThread( external void _Texture_setImageRenderThread(
Pointer<TEngine> tEngine,
Pointer<TTexture> tTexture,
int level,
Pointer<Uint8> data,
size_t size,
int width,
int height,
int channels,
int bufferFormat,
int pixelDataType,
Pointer<self.NativeFunction<void Function(bool)>> onComplete,
);
external void _Texture_setImageWithDepthRenderThread(
Pointer<TEngine> tEngine, Pointer<TEngine> tEngine,
Pointer<TTexture> tTexture, Pointer<TTexture> tTexture,
int level, int level,
@@ -1771,7 +1746,6 @@ extension type NativeLibrary(JSObject _) implements JSObject {
int z_offset, int z_offset,
int width, int width,
int height, int height,
int channels,
int depth, int depth,
int bufferFormat, int bufferFormat,
int pixelDataType, int pixelDataType,
@@ -3024,23 +2998,6 @@ bool Texture_loadImage(
} }
bool Texture_setImage( bool Texture_setImage(
self.Pointer<TEngine> tEngine,
self.Pointer<TTexture> tTexture,
int level,
self.Pointer<Uint8> data,
Dart__darwin_size_t size,
int width,
int height,
int channels,
int bufferFormat,
int pixelDataType,
) {
final result = _lib._Texture_setImage(tEngine.cast(), tTexture.cast(), level,
data, size, width, height, channels, bufferFormat, pixelDataType);
return result == 1;
}
bool Texture_setImageWithDepth(
self.Pointer<TEngine> tEngine, self.Pointer<TEngine> tEngine,
self.Pointer<TTexture> tTexture, self.Pointer<TTexture> tTexture,
int level, int level,
@@ -3051,12 +3008,11 @@ bool Texture_setImageWithDepth(
int z_offset, int z_offset,
int width, int width,
int height, int height,
int channels,
int depth, int depth,
int bufferFormat, int bufferFormat,
int pixelDataType, int pixelDataType,
) { ) {
final result = _lib._Texture_setImageWithDepth( final result = _lib._Texture_setImage(
tEngine.cast(), tEngine.cast(),
tTexture.cast(), tTexture.cast(),
level, level,
@@ -3067,7 +3023,6 @@ bool Texture_setImageWithDepth(
z_offset, z_offset,
width, width,
height, height,
channels,
depth, depth,
bufferFormat, bufferFormat,
pixelDataType); pixelDataType);
@@ -5083,46 +5038,17 @@ void Texture_setImageRenderThread(
int level, int level,
self.Pointer<Uint8> data, self.Pointer<Uint8> data,
Dart__darwin_size_t size, Dart__darwin_size_t size,
int x_offset,
int y_offset,
int z_offset,
int width, int width,
int height, int height,
int channels, int depth,
int bufferFormat, int bufferFormat,
int pixelDataType, int pixelDataType,
self.Pointer<self.NativeFunction<void Function(bool)>> onComplete, self.Pointer<self.NativeFunction<void Function(bool)>> onComplete,
) { ) {
final result = _lib._Texture_setImageRenderThread( final result = _lib._Texture_setImageRenderThread(
tEngine.cast(),
tTexture.cast(),
level,
data,
size,
width,
height,
channels,
bufferFormat,
pixelDataType,
onComplete.cast());
return result;
}
void Texture_setImageWithDepthRenderThread(
self.Pointer<TEngine> tEngine,
self.Pointer<TTexture> tTexture,
int level,
self.Pointer<Uint8> data,
Dart__darwin_size_t size,
int x_offset,
int y_offset,
int z_offset,
int width,
int height,
int channels,
int depth,
int bufferFormat,
int pixelDataType,
self.Pointer<self.NativeFunction<void Function(bool)>> onComplete,
) {
final result = _lib._Texture_setImageWithDepthRenderThread(
tEngine.cast(), tEngine.cast(),
tTexture.cast(), tTexture.cast(),
level, level,
@@ -5133,7 +5059,6 @@ void Texture_setImageWithDepthRenderThread(
z_offset, z_offset,
width, width,
height, height,
channels,
depth, depth,
bufferFormat, bufferFormat,
pixelDataType, pixelDataType,

View File

@@ -30,7 +30,8 @@ class FFITexture extends Texture {
@override @override
Future<void> generateMipmaps() async { Future<void> generateMipmaps() async {
await withVoidCallback((requestId, cb) => Texture_generateMipMapsRenderThread(pointer, _engine, requestId, cb)); await withVoidCallback((requestId, cb) =>
Texture_generateMipMapsRenderThread(pointer, _engine, requestId, cb));
} }
@override @override
@@ -73,7 +74,8 @@ class FFITexture extends Texture {
@override @override
Future<void> setImage(int level, Uint8List buffer, int width, int height, Future<void> setImage(int level, Uint8List buffer, int width, int height,
int channels, PixelDataFormat format, PixelDataType type) async { PixelDataFormat format, PixelDataType type,
{int depth = 1, int xOffset = 0, int yOffset = 0, int zOffset = 0 }) async {
final success = await withBoolCallback((cb) { final success = await withBoolCallback((cb) {
Texture_setImageRenderThread( Texture_setImageRenderThread(
_engine, _engine,
@@ -81,9 +83,10 @@ class FFITexture extends Texture {
level, level,
buffer.address, buffer.address,
buffer.lengthInBytes, buffer.lengthInBytes,
xOffset, yOffset, zOffset,
width, width,
height, height,
channels, depth,
format.index, format.index,
type.index, type.index,
cb); cb);
@@ -94,44 +97,6 @@ class FFITexture extends Texture {
} }
} }
@override
Future<void> setImage3D(
int level,
int xOffset,
int yOffset,
int zOffset,
int width,
int height,
int channels,
int depth,
Uint8List buffer,
PixelDataFormat format,
PixelDataType type) async {
throw UnimplementedError();
// final success = await withBoolCallback((cb) {
// Texture_setImageWithDepthRenderThread(
// _engine,
// pointer,
// level,
// buffer.address,
// buffer.lengthInBytes,
// 0,
// 0,
// zOffset,
// width,
// height,
// channels,
// depth,
// format.index,
// type.index,
// cb);
// });
// if (!success) {
// throw Exception("Failed to set image");
// }
}
@override @override
Future<void> setSubImage( Future<void> setSubImage(
int level, int level,

View File

@@ -333,30 +333,18 @@ abstract class Texture {
/// Sets the given [image] as the source data for this texture. /// Sets the given [image] as the source data for this texture.
/// ///
Future setLinearImage( Future setLinearImage(
covariant LinearImage image, PixelDataFormat format, PixelDataType type, {int level = 0}); covariant LinearImage image, PixelDataFormat format, PixelDataType type,
{int level = 0});
/// Sets the image data for a 2D texture or a texture level /// Sets the image data for a 2D texture or a texture level
Future setImage(int level, Uint8List buffer, int width, int height, Future<void> setImage(int level, Uint8List buffer, int width, int height,
int channels, PixelDataFormat format, PixelDataType type); PixelDataFormat format, PixelDataType type,
{int depth = 1, int xOffset = 0, int yOffset = 0, int zOffset = 0});
/// Sets the image data for a region of a 2D texture /// Sets the image data for a region of a 2D texture
Future setSubImage(int level, int xOffset, int yOffset, int width, int height, Future setSubImage(int level, int xOffset, int yOffset, int width, int height,
Uint8List buffer, PixelDataFormat format, PixelDataType type); Uint8List buffer, PixelDataFormat format, PixelDataType type);
/// Sets the image data for a 3D texture or cubemap
Future setImage3D(
int level,
int xOffset,
int yOffset,
int zOffset,
int width,
int height,
int channels,
int depth,
Uint8List buffer,
PixelDataFormat format,
PixelDataType type);
/// Sets an external image (like a video or camera frame) as the texture source /// Sets an external image (like a video or camera frame) as the texture source
Future setExternalImage(dynamic externalImage); Future setExternalImage(dynamic externalImage);
@@ -415,7 +403,8 @@ enum PixelDataFormat {
factory PixelDataFormat.fromValue(int value) { factory PixelDataFormat.fromValue(int value) {
return PixelDataFormat.values.firstWhere( return PixelDataFormat.values.firstWhere(
(format) => format.value == value, (format) => format.value == value,
orElse: () => throw ArgumentError('Invalid PixelDataFormat value: $value'), orElse: () =>
throw ArgumentError('Invalid PixelDataFormat value: $value'),
); );
} }
} }
@@ -473,7 +462,6 @@ enum PixelDataType {
} }
} }
@deprecated @deprecated
typedef ThermionTexture = Texture; typedef ThermionTexture = Texture;
@@ -488,29 +476,21 @@ abstract class LinearImage {
/// the corresponding size with the image set as mip-level 0. /// the corresponding size with the image set as mip-level 0.
/// ///
/// ///
static Future<Texture> decodeToTexture(Uint8List data, { static Future<Texture> decodeToTexture(Uint8List data,
TextureFormat textureFormat = TextureFormat.RGB32F, {TextureFormat textureFormat = TextureFormat.RGB32F,
PixelDataFormat pixelDataFormat = PixelDataFormat.RGB, PixelDataFormat pixelDataFormat = PixelDataFormat.RGB,
PixelDataType pixelDataType = PixelDataType.FLOAT, PixelDataType pixelDataType = PixelDataType.FLOAT,
int levels = 1, int levels = 1,
bool requireAlpha = false}) async { bool requireAlpha = false}) async {
final decodedImage = await FilamentApp.instance!.decodeImage(data, requireAlpha: requireAlpha); final decodedImage = await FilamentApp.instance!
.decodeImage(data, requireAlpha: requireAlpha);
final texture = await FilamentApp.instance!.createTexture( final texture = await FilamentApp.instance!.createTexture(
await decodedImage.getWidth(), await decodedImage.getWidth(), await decodedImage.getHeight(),
await decodedImage.getHeight(), textureFormat: textureFormat, levels: levels);
textureFormat: textureFormat,
levels:levels
);
await texture.setLinearImage( await texture.setLinearImage(decodedImage, pixelDataFormat, pixelDataType);
decodedImage,
pixelDataFormat,
pixelDataType
);
return texture; return texture;
} }
} }

View File

@@ -228,18 +228,6 @@ EMSCRIPTEN_KEEPALIVE bool Texture_loadImage(
int level int level
); );
EMSCRIPTEN_KEEPALIVE bool Texture_setImage( EMSCRIPTEN_KEEPALIVE bool Texture_setImage(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
uint8_t *data,
size_t size,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t bufferFormat,
uint32_t pixelDataType
);
EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth(
TEngine *tEngine, TEngine *tEngine,
TTexture *tTexture, TTexture *tTexture,
uint32_t level, uint32_t level,
@@ -250,7 +238,6 @@ EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth(
uint32_t z_offset, uint32_t z_offset,
uint32_t width, uint32_t width,
uint32_t height, uint32_t height,
uint32_t channels,
uint32_t depth, uint32_t depth,
uint32_t bufferFormat, uint32_t bufferFormat,
uint32_t pixelDataType uint32_t pixelDataType

View File

@@ -194,19 +194,6 @@ namespace thermion
void (*onComplete)(bool) void (*onComplete)(bool)
); );
void Texture_setImageRenderThread( void Texture_setImageRenderThread(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
uint8_t *data,
size_t size,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t bufferFormat,
uint32_t pixelDataType,
void (*onComplete)(bool)
);
void Texture_setImageWithDepthRenderThread(
TEngine *tEngine, TEngine *tEngine,
TTexture *tTexture, TTexture *tTexture,
uint32_t level, uint32_t level,
@@ -217,7 +204,6 @@ namespace thermion
uint32_t z_offset, uint32_t z_offset,
uint32_t width, uint32_t width,
uint32_t height, uint32_t height,
uint32_t channels,
uint32_t depth, uint32_t depth,
uint32_t bufferFormat, uint32_t bufferFormat,
uint32_t pixelDataType, uint32_t pixelDataType,

View File

@@ -532,62 +532,6 @@ namespace thermion
} }
EMSCRIPTEN_KEEPALIVE bool Texture_setImage( EMSCRIPTEN_KEEPALIVE bool Texture_setImage(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
uint8_t *data,
size_t size,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t tBufferFormat,
uint32_t tPixelDataType)
{
auto engine = reinterpret_cast<filament::Engine *>(tEngine);
auto texture = reinterpret_cast<filament::Texture *>(tTexture);
auto bufferFormat = static_cast<PixelBufferDescriptor::PixelDataFormat>(tBufferFormat);
auto pixelDataType = static_cast<PixelBufferDescriptor::PixelDataType>(tPixelDataType);
switch (bufferFormat)
{
case PixelBufferDescriptor::PixelDataFormat::RGB:
case PixelBufferDescriptor::PixelDataFormat::RGBA:
case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER:
case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER:
break;
default:
Log("Unsupported buffer format type : %d", bufferFormat);
return false;
}
// the texture upload is async, so we need to copy the buffer
auto *buffer = new std::vector<uint8_t>(size);
std::copy(data, data + size, buffer->begin());
filament::Texture::PixelBufferDescriptor::Callback freeCallback = [](void *buf, size_t,
void *data)
{
delete reinterpret_cast<std::vector<uint8_t> *>(data);
};
filament::Texture::PixelBufferDescriptor pbd(
buffer->data(),
size,
bufferFormat,
pixelDataType,
1, // alignment
0, // left
0, // top
0, // stride
freeCallback,
buffer);
texture->setImage(*engine, level, std::move(pbd));
return true;
}
EMSCRIPTEN_KEEPALIVE bool Texture_setImageWithDepth(
TEngine *tEngine, TEngine *tEngine,
TTexture *tTexture, TTexture *tTexture,
uint32_t level, uint32_t level,
@@ -598,7 +542,6 @@ namespace thermion
uint32_t z_offset, uint32_t z_offset,
uint32_t width, uint32_t width,
uint32_t height, uint32_t height,
uint32_t channels,
uint32_t depth, uint32_t depth,
uint32_t tBufferFormat, uint32_t tBufferFormat,
uint32_t tPixelDataType) uint32_t tPixelDataType)
@@ -608,31 +551,15 @@ namespace thermion
auto texture = reinterpret_cast<filament::Texture *>(tTexture); auto texture = reinterpret_cast<filament::Texture *>(tTexture);
auto bufferFormat = static_cast<PixelBufferDescriptor::PixelDataFormat>(tBufferFormat); auto bufferFormat = static_cast<PixelBufferDescriptor::PixelDataFormat>(tBufferFormat);
auto pixelDataType = static_cast<PixelBufferDescriptor::PixelDataType>(tPixelDataType); auto pixelDataType = static_cast<PixelBufferDescriptor::PixelDataType>(tPixelDataType);
TRACE("Setting texture image (depth %d, %dx%dx%d (%d bytes, z_offset %d)", depth, width, height, channels, size, z_offset); TRACE("Setting texture image for level %d, offset %dx%dx%d, depth %d", level, x_offset, y_offset, z_offset, depth);
switch (bufferFormat) switch (bufferFormat)
{ {
case PixelBufferDescriptor::PixelDataFormat::RGB: case PixelBufferDescriptor::PixelDataFormat::RGB:
case PixelBufferDescriptor::PixelDataFormat::RGBA: case PixelBufferDescriptor::PixelDataFormat::RGBA:
{
size_t expectedSize = width * height * channels * sizeof(float);
if (size != expectedSize)
{
Log("Size mismatch (expected %lu, got %lu)", expectedSize, size);
return false;
}
break;
}
case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER: case PixelBufferDescriptor::PixelDataFormat::RGB_INTEGER:
case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER: case PixelBufferDescriptor::PixelDataFormat::RGBA_INTEGER:
{
if (size != width * height * channels * sizeof(uint8_t))
{
Log("Size mismatch");
// return false;
}
break; break;
}
default: default:
Log("Unsupported buffer format type : %d", bufferFormat); Log("Unsupported buffer format type : %d", bufferFormat);
return false; return false;

View File

@@ -937,29 +937,6 @@ extern "C"
} }
EMSCRIPTEN_KEEPALIVE void Texture_setImageRenderThread( EMSCRIPTEN_KEEPALIVE void Texture_setImageRenderThread(
TEngine *tEngine,
TTexture *tTexture,
uint32_t level,
uint8_t *data,
size_t size,
uint32_t width,
uint32_t height,
uint32_t channels,
uint32_t bufferFormat,
uint32_t pixelDataType,
void (*onComplete)(bool))
{
std::packaged_task<void()> lambda(
[=]() mutable
{
bool result = Texture_setImage(tEngine, tTexture, level, data, size, width, height, channels,
bufferFormat, pixelDataType);
PROXY(onComplete(result));
});
auto fut = _renderThread->add_task(lambda);
}
EMSCRIPTEN_KEEPALIVE void Texture_setImageWithDepthRenderThread(
TEngine *tEngine, TEngine *tEngine,
TTexture *tTexture, TTexture *tTexture,
uint32_t level, uint32_t level,
@@ -970,7 +947,6 @@ extern "C"
uint32_t z_offset, uint32_t z_offset,
uint32_t width, uint32_t width,
uint32_t height, uint32_t height,
uint32_t channels,
uint32_t depth, uint32_t depth,
uint32_t bufferFormat, uint32_t bufferFormat,
uint32_t pixelDataType, uint32_t pixelDataType,
@@ -979,7 +955,7 @@ extern "C"
std::packaged_task<void()> lambda( std::packaged_task<void()> lambda(
[=]() mutable [=]() mutable
{ {
bool result = Texture_setImageWithDepth( bool result = Texture_setImage(
tEngine, tEngine,
tTexture, tTexture,
level, level,
@@ -990,7 +966,6 @@ extern "C"
z_offset, z_offset,
width, width,
height, height,
channels,
depth, depth,
bufferFormat, bufferFormat,
pixelDataType); pixelDataType);

View File

@@ -1,4 +1,5 @@
import 'dart:io'; import 'dart:io';
import 'package:image/image.dart';
import 'package:test/test.dart'; import 'package:test/test.dart';
import 'package:thermion_dart/thermion_dart.dart'; import 'package:thermion_dart/thermion_dart.dart';
import 'helpers.dart'; import 'helpers.dart';
@@ -8,12 +9,13 @@ void main() async {
await testHelper.setup(); await testHelper.setup();
group("image", () { group("image", () {
test('create 2D texture & set from decoded image', () async { test('set 2D texture from decoded image', () async {
await testHelper.withViewer((viewer) async { await testHelper.withViewer((viewer) async {
var imageData = File( var imageData = File(
"${testHelper.testDir}/assets/cube_texture_512x512.png", "${testHelper.testDir}/assets/cube_texture_512x512.png",
).readAsBytesSync(); ).readAsBytesSync();
final image = await FilamentApp.instance!.decodeImage(imageData); final image = await FilamentApp.instance!
.decodeImage(imageData, requireAlpha: true);
expect(await image.getChannels(), 4); expect(await image.getChannels(), 4);
expect(await image.getWidth(), 512); expect(await image.getWidth(), 512);
expect(await image.getHeight(), 512); expect(await image.getHeight(), 512);
@@ -32,6 +34,36 @@ void main() async {
}, bg: kRed); }, bg: kRed);
}); });
test('set cubemap texture from pixel buffer', () async {
await testHelper.withViewer((viewer) async {
final texture = await FilamentApp.instance!.createTexture(
1,
1,
depth: 6,
textureSamplerType: TextureSamplerType.SAMPLER_CUBEMAP,
textureFormat: TextureFormat.RGBA32F,
);
final byteBuffer = Float32List.fromList([
1.0,
1.0,
1.0,
1.0,
]);
for (int i = 0; i < 6; i++) {
await texture.setImage(
0,
byteBuffer.asUint8List(),
1,
1,
zOffset: i,
PixelDataFormat.RGBA,
PixelDataType.FLOAT,
);
}
await texture.dispose();
}, bg: kRed);
});
test('generate mipmaps', () async { test('generate mipmaps', () async {
await testHelper.withViewer((viewer) async { await testHelper.withViewer((viewer) async {
var imageData = File( var imageData = File(
@@ -49,7 +81,8 @@ void main() async {
var imageData = File( var imageData = File(
"${testHelper.testDir}/assets/cube_texture_512x512.png", "${testHelper.testDir}/assets/cube_texture_512x512.png",
).readAsBytesSync(); ).readAsBytesSync();
final image = await FilamentApp.instance!.decodeImage(imageData); final image = await FilamentApp.instance!
.decodeImage(imageData, requireAlpha: true);
expect(await image.getChannels(), 4); expect(await image.getChannels(), 4);
expect(await image.getWidth(), 512); expect(await image.getWidth(), 512);
expect(await image.getHeight(), 512); expect(await image.getHeight(), 512);
@@ -66,7 +99,6 @@ void main() async {
data.buffer.asUint8List(data.offsetInBytes), data.buffer.asUint8List(data.offsetInBytes),
512, 512,
512, 512,
4,
PixelDataFormat.RGBA, PixelDataFormat.RGBA,
PixelDataType.FLOAT, PixelDataType.FLOAT,
); );
@@ -90,18 +122,14 @@ void main() async {
for (int i = 0; i < depth; i++) { for (int i = 0; i < depth; i++) {
final buffer = Uint8List(width * height * channels * sizeOf<Float>()); final buffer = Uint8List(width * height * channels * sizeOf<Float>());
await texture.setImage3D( await texture.setImage(
0, 0,
0, buffer,
0,
i,
width, width,
height, height,
channels,
1,
buffer,
PixelDataFormat.RGBA, PixelDataFormat.RGBA,
PixelDataType.FLOAT, PixelDataType.FLOAT,
zOffset: i,
); );
} }
await texture.dispose(); await texture.dispose();
@@ -145,18 +173,14 @@ void main() async {
pixelBuffer.offsetInBytes, pixelBuffer.offsetInBytes,
); );
await texture.setImage3D( await texture.setImage(
0, 0,
0, byteBuffer,
0,
i,
width, width,
height, height,
channels,
1,
byteBuffer,
PixelDataFormat.RGBA, PixelDataFormat.RGBA,
PixelDataType.FLOAT, PixelDataType.FLOAT,
zOffset: i,
); );
} }