flutter_angle 0.0.5 copy "flutter_angle: ^0.0.5" to clipboard
flutter_angle: ^0.0.5 copied to clipboard

Flutters Almost Native Graphics Layer Engine is made by google to use OpenGL ES API calls to one of the hardware-supported APIs available for that platform.

example/lib/main.dart

import 'dart:async';

import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter/scheduler.dart';
import 'package:flutter/services.dart';
import 'package:flutter_angle/flutter_angle.dart';
import 'learn_gl.dart';

void main() {
  runApp(MyApp());
}

class MyApp extends StatefulWidget {
  @override
  _MyAppState createState() => _MyAppState();
}

class _MyAppState extends State<MyApp> with SingleTickerProviderStateMixin {
  final textures = <FlutterAngleTexture>[];
  int textureId = -1;
  int textureId2 = -1;
  Lesson? lesson;
  Lesson? lesson2;
  static const textureWidth = 640;
  static const textureHeight = 320;
  static const aspect = textureWidth / textureHeight;

  double dpr = 1.0;
  late double width;
  late double height;
  Size? screenSize;

  @override
  void initState() {
    super.initState();
  }

  // Platform messages are asynchronous, so we initialize in an async method.
  Future<void> initPlatformState() async {
    didInit = true;
    final mq = MediaQuery.of(context);
    screenSize = mq.size;
    dpr = mq.devicePixelRatio;

    width = screenSize!.width;
    height = width;

    await FlutterAngle.initOpenGL(true);

    final options = AngleOptions(
      width: textureWidth, 
      height: textureHeight, 
      dpr: dpr,
    );

    try {
      textures.add(await FlutterAngle.createTexture(options));
      textures.add(await FlutterAngle.createTexture(options));
    } on PlatformException catch (e) {
      print("failed to get texture id $e");
      return;
    }

    //resetLessons();
    lesson = Lesson3(textures[0].getContext());
    lesson2 = Lesson5(textures[1].getContext());

    /// Updating all Textues takes a slighllty less than 150ms
    /// so we can't get much faster than this at the moment because it could happen that
    /// the timer starts a new async function while the last one hasn't finished
    /// which creates an OpenGL Exception
    if (!mounted) return;
    setState(() {
      textureId = textures[0].textureId;
      textureId2 = textures[1].textureId;
    });
    // timer = Timer.periodic(const Duration(milliseconds: 16), updateTexture);
    ticker = createTicker(updateTexture);
    ticker.start();
  }

  Stopwatch stopwatch = Stopwatch();

  late Ticker ticker;
  static bool updating = false;
  int animationCounter = 0;
  int totalTime = 0;
  int iterationCount = 60;
  int framesOver = 0;
  bool didInit = false;
  void updateTexture(_) async {
    if (textureId < 0) return;
    if (!updating) {
      updating = true;
      stopwatch.reset();
      stopwatch.start();
      textures[0].activate();
      lesson?.handleKeys();
      lesson?.animate(animationCounter += 2);
      lesson?.drawScene(-1, 0, aspect);
      await textures[0].signalNewFrameAvailable();
      stopwatch.stop();
      totalTime += stopwatch.elapsedMilliseconds;
      if (stopwatch.elapsedMilliseconds > 16) {
        framesOver++;
      }
      if (--iterationCount == 0) {
        // print('Time: ${totalTime / 60} - Framesover $framesOver');
        totalTime = 0;
        iterationCount = 60;
        framesOver = 0;
      }
      textures[1].activate();
      lesson2?.handleKeys();
      lesson2?.animate(animationCounter += 2);
      lesson2?.drawScene(-1, 0, aspect);
      await textures[1].signalNewFrameAvailable();
      updating = false;
    } else {
      print('Too slow');
    }
  }

  void dispose() {
    ticker.dispose();
    lesson?.dispose();
    lesson2?.dispose();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        backgroundColor: Colors.red,
        appBar: AppBar(
          title: const Text('Plugin example app'),
        ),
        body: LayoutBuilder(builder: (context, constraints) {
          final useRow = constraints.maxWidth > constraints.maxHeight;
          if(!didInit){
            initPlatformState();
          }
          return GestureDetector(
            onVerticalDragStart: verticalDragStart,
            onVerticalDragUpdate: verticalDragUpdate,
            onHorizontalDragStart: horizontalDragStart,
            onHorizontalDragUpdate: horizontalDragUpdate,
            child: Container(
              child: 
              kIsWeb?
                useRow
                  ? Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Expanded(child: 
                        Transform.scale(
                          scaleY: -1,
                          child: HtmlElementView(viewType: textureId.toString()),
                        ) 
                      ),
                      Expanded(child: 
                        Transform.scale(
                          scaleY: -1,
                          child: HtmlElementView(viewType: textureId2.toString()),
                        ) 
                      ),
                    ],
                  )
                : Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Expanded(child: 
                        Transform.scale(
                          scaleY: -1,
                          child: HtmlElementView(viewType: textureId.toString()),
                        ) 
                      ),
                      Expanded(child: 
                        Transform.scale(
                          scaleY: -1,
                          child: HtmlElementView(viewType: textureId2.toString()),
                        ) 
                      ),
                    ],
                  )
                :useRow
                  ? Row(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Expanded(child: Texture(textureId: textureId)),
                      Expanded(child: Texture(textureId: textureId2)),
                    ],
                  )
                : Column(
                    mainAxisSize: MainAxisSize.min,
                    children: [
                      Expanded(child: Texture(textureId: textureId)),
                      Expanded(child: Texture(textureId: textureId2)),
                    ],
                  ),
            ),
          );
        }),
      ),
    );
  }

  double lastVertical = 0;

  double lastHorizontal = 0;

  void verticalDragStart(DragStartDetails details) {}

  void verticalDragUpdate(DragUpdateDetails details) {
    if (details.delta.dy < 0) {
      movement = Directions.up;
      print('up');
    } else if (details.delta.dy > 0) {
      print('down');
      movement = Directions.down;
    }
  }

  void horizontalDragStart(DragStartDetails details) {}
  void horizontalDragUpdate(DragUpdateDetails details) {
    if (details.delta.dx < 0) {
      movement = Directions.right;
      print('right');
    } else if (details.delta.dx > 0) {
      movement = Directions.left;
      print('left');
    }
  }
}
4
likes
130
points
1.46k
downloads

Publisher

unverified uploader

Weekly Downloads

Flutters Almost Native Graphics Layer Engine is made by google to use OpenGL ES API calls to one of the hardware-supported APIs available for that platform.

Repository (GitHub)
View/report issues

Topics

#opengl #angle #glsl

Documentation

API reference

License

MIT (license)

Dependencies

dylib, ffi, flutter, flutter_angle_darwin, logger

More

Packages that depend on flutter_angle