init method

Future<void> init([
  1. bool useDebugContext = false,
  2. bool useAngle = true
])

Implementation

Future<void> init([bool useDebugContext = false, bool useAngle = true]) async {
  if (_didInit) return;
  _isApple = Platform.isIOS || Platform.isMacOS;
  _useAngle = useAngle;
  _didInit = true;

  /// make sure we don't call this twice
  if (_display != nullptr) {
    return;
  }

  // Initialize native part of he plugin
  late final dynamic result;
  if (Platform.isAndroid && _useAngle) {
    result = await _channel.invokeMethod('initOpenGLAngle');
    _useAngle = !result['isEmulator'];
  } else {
    _useAngle = false;
    result = await _channel.invokeMethod('initOpenGL');
  }

  loadEGL(useAngle: _useAngle);
  angleConsole.info(result);

  if (result == null) {
    throw EglException('Plugin.initOpenGL didn\'t return anything. Something is really wrong!');
  }
  if (!_isApple) {
    final pluginContextAdress = result['context'] ?? result['openGLContext'];
    if (pluginContextAdress == null) {
      throw EglException('Plugin.initOpenGL didn\'t return a Context. Something is really wrong!');
    }

    _pluginContext = Pointer<Void>.fromAddress(pluginContextAdress);

    final dummySurfacePointer = result['dummySurface'] as int?;
    if (dummySurfacePointer == null) {
      throw EglException('Plugin.initOpenGL didn\'t return a dummy surface. Something is really wrong!');
    }
    _dummySurface = Pointer<Void>.fromAddress(dummySurfacePointer);
  }

  /// Init OpenGL on the Dart side too
  _display = eglGetDisplay();
  final initializeResult = eglInitialize(_display);

  debugPrint('EGL version: $initializeResult');

  late final Map<EglConfigAttribute, int> eglAttributes;

  /// In case the plugin returns its selected EGL config we use it.
  /// Finally this should be how all platforms behave. Till all platforms
  /// support this we leave this check here
  final eglConfigId = (result is Map && result.containsKey('eglConfigId'))? result['eglConfigId'] as int?: null;
  if (eglConfigId != null) {
    eglAttributes = {
      EglConfigAttribute.configId: eglConfigId,
    };
  } else {
    eglAttributes = {
      EglConfigAttribute.renderableType: EglValue.openglEs3Bit.toIntValue(),
      EglConfigAttribute.redSize: 8,
      EglConfigAttribute.greenSize: 8,
      EglConfigAttribute.blueSize: 8,
      EglConfigAttribute.alphaSize: 8,
      EglConfigAttribute.depthSize: 24,
      EglConfigAttribute.samples: 4,
      EglConfigAttribute.stencilSize: 8,
      EglConfigAttribute.sampleBuffers: 1,
    };
  }
  final chooseConfigResult = eglChooseConfig(
    _display,
    attributes: eglAttributes,
    maxConfigs: 1,
  );
  _EGLconfig = chooseConfigResult[0];

  _baseAppContext = eglCreateContext(
    _display,
    _EGLconfig,
    shareContext: _pluginContext == nullptr?null:_pluginContext,
    contextClientVersion: 3,
    isDebugContext: useDebugContext && !Platform.isAndroid
  );

  if(!_isApple){
    /// bind context to this thread. All following OpenGL calls from this thread will use this context
    eglMakeCurrent(_display, _dummySurface, _dummySurface, _baseAppContext);

    if (useDebugContext && Platform.isWindows) {
      _rawOpenGl.glEnable(GL_DEBUG_OUTPUT);
      _rawOpenGl.glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS);
      _rawOpenGl.glDebugMessageCallback(Pointer.fromFunction<GLDEBUGPROC>(glDebugOutput), nullptr);
      _rawOpenGl.glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DONT_CARE, 0, nullptr, GL_TRUE);
    }
  }
}