wasabia / three_dart

three.js rewrite by Dart, Dart 3D library. an easy to use, lightweight, cross-platform, general purpose 3D library.
MIT License
450 stars 80 forks source link

create texture from canvas instead of importing from .png file (similar to CanvasTexture in js) #119

Open AlexanderMonneret opened 1 year ago

AlexanderMonneret commented 1 year ago

i'm new to flutter, i'm trying to dynamically change the UV Texture of the 3D model while the app is running. I thought about overwriting the .png texture file in assets but this isn't allowed in Flutter. the alternative is to generate the texture with a function and render it on the 3d model.

the problem is the textureloader only accepts a path or url, is it possible to modify it so it accepts an image object to load the texture dynamically?

thanks in advance,

cheers from Germany!

wasabia commented 1 year ago

maybe you need update flutter canvas, read pixels from flutter canvas, then use DataTexture which accept pixels data

AlexanderMonneret commented 1 year ago

thanks for the quick response!! I have tried the following but it didn't work :/ the DataTexutre.LoadAsync() is also not implemented I would really appreciate it if you would provide an example

// funtionc that generates an image

generateAndSaveGrid() async {
    // Define the size of the grid and the size of each square
    final gridSize = Size(3 * 100.0, 10 * 100.0);
    final squareSize = 100.0;

    // Create a PictureRecorder to record the painting
    PictureRecorder recorder = PictureRecorder();
    Canvas canvas = Canvas(recorder);

    // Paint each square with a random color
    Random random = Random();
    var index = 0;
    for (int i = 0; i < 3; i++) {
      for (int j = 0; j < 10; j++) {
        Paint paint = Paint()
          ..color = Color.fromARGB(255, random.nextInt(256),
              random.nextInt(256), random.nextInt(256));
        index++;
        canvas.drawRect(
            Rect.fromLTWH(
                i * squareSize, j * squareSize, squareSize, squareSize),
            paint);
      }
    }

    // Create a picture from the recorded painting
    Picture picture = recorder.endRecording();

    // Convert the picture to an image
    ui.Image imago =
        await picture.toImage(gridSize.width.floor(), gridSize.height.floor());
    ByteData? byteData = await imago.toByteData(format: ui.ImageByteFormat.png);

    return byteData;
//var textureLoader = three.TextureLoader(null);
//texture = await textureLoader.loadAsync('assets/bracelet/uv.png');
var mapImage = generateAndSaveGrid();
var texture = three.DataTexture(mapImage, 300, 1000);
wasabia commented 1 year ago

this is an example use DataTexture https://github.com/wasabia/three_dart/blob/74a1af0e6f725b0ad64b8adccdc6e87ea52a3497/example/lib/webgl_materials.dart#L216

read pixels from canvas then copy to three_dart, maybe performance is bad, if change texture high frequency

if you need better performance, should use OpenGL share context create texture share to three_dart, Develop native flutter plugins yourself 😄

AlexanderMonneret commented 1 year ago

It worked! thank you so much!!! :D :D