initOpenGL static method

Future<void> initOpenGL([
  1. bool useDebugContext = false
])

Implementation

static Future<void> initOpenGL([bool useDebugContext = false]) async {
  /// make sure we don't call this twice
  if (_display != nullptr) {
    return;
  }
  loadEGL();
  // Initialize native part of he plugin
  final result = await _channel.invokeMethod('initOpenGL');
  angleConsole.info(result);
  if (result == null) {
    throw EglException('Plugin.initOpenGL didn\'t return anything. Something is really wrong!');
  }

  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['eglConfigId'] as int?;
  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];

  // The following code is helpful to debug EGL issues
  // final existingConfigs = eglGetConfigs(_display, maxConfigs: 50);
  // print('Number of configs ${existingConfigs.length}');
  // for (int i = 0; i < existingConfigs.length; i++) {
  //   print('\nConfig No: $i');
  //   printConfigAttributes(_display, existingConfigs[i]);
  // }

  _baseAppContext = eglCreateContext(_display, _EGLconfig,
    // we link both contexts so that app and plugin can share OpenGL Objects
    shareContext: _pluginContext,
    contextClientVersion: 3,
    // Android does not support debugContexts
    isDebugContext: useDebugContext && !Platform.isAndroid
  );

  /// 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);
  }

  print("DONE");
}