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 (_display != nullptr) return;

  _isApple = Platform.isIOS || Platform.isMacOS;
  _useAngle = useAngle;

  // Initialize native part of he plugin
  late final dynamic result;
  if (Platform.isAndroid && _useAngle) {
    result = await _channel.invokeMethod('initOpenGLAngle');
    _useAngle = result['forceOpengl'] == null?_useAngle:!result['forceOpengl'];
    angleConsole.info("Force Opengl: ${result['forceOpengl']}");
  }
  else {
    _useAngle = false;
    result = await _channel.invokeMethod('initOpenGL');

    if(_isApple){
      _isApple = result['isSimulator'] == null?_isApple:!result['isSimulator'];
    }
  }

  _libEGL = EGL(useAngle: _useAngle);
  angleConsole.info(result);

  if (result == null) {
    throw EglException('Plugin.initOpenGL didn\'t return anything. Something is really wrong!');
  }

  if(Platform.isLinux){
    _baseAppContext = Pointer<Void>.fromAddress(result['context']);
    _libEGL!.makeCurrent(_baseAppContext);
    return;
  }

  if (Platform.isWindows || (Platform.isAndroid && !_useAngle)) {
    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);
  }

  if(Platform.isAndroid && !_useAngle){
    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 = _libEGL!.eglGetDisplay();
  final initializeResult = _libEGL!.eglInitialize(_display);

  angleConsole.info('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,
    };
  }

  final chooseConfigResult = _libEGL!.eglChooseConfig(
    _display,
    attributes: eglAttributes,
    maxConfigs: 1,
  );
  eglAttributes.clear();
  _EGLconfig = chooseConfigResult[0];

  _baseAppContext = _libEGL!.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
    _libEGL!.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);
    }
  }
}