Missing GL interfaces make GLView fail

#1

I am following the GLView / expo-three example located here : https://github.com/expo/expo-three
expo-three, although it seems poorly maintained so far, is the recommended way to use Three.js with Expo (using the previous integration results in a warning telling us to use expo-three)

Compared to the example on github, the only difference is that my rendering function is :

return (
      <View style={styles.container}>
      <Text>TEST TEST TEST</Text>
        <Text>Changes you make will automatically reload.</Text>
        <Text>Shake your phone to open the developer menu.</Text>
        <Expo.GLView
          style={{ flex: 1, height: '100%', width: '100%' }}
          onContextCreate={this._onGLContextCreate}
        />
      </View>
    );

I am receiving the following error :

Upon inspecting the source code at GLView.js and debugging, the global.__EXGLContexts variable is undefined, which is causing the error.
Am I missing something ?

#2

cc @nikki - he can help you with this!

#3

GLView doesn’t work with remote debugging enabled if that’s what you’re trying to do. It needs to run on JavaScriptCore, which remote debugging skips.

#4

So that error is gone, thanks ! However I’m still not seeing anything

Among the WebGLRenderer support warnings (which are apparently to be expected), I’m also getting an other warning:

Possible Unhandled Promise Rejection (id: 0):
TypeError: undefined is not a function (evaluating 'window.addEventListener('vrdisplaypresentchange', onVRDisplayPresentChange, false)')
WebVRManager@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:97760:26
WebGLRenderer@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:98240:28
createRenderer@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:81499:33
_callee$@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:81409:60
tryCatch@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18293:44
invoke@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18481:30
http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18318:28
tryCatch@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18293:44
invoke@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18351:28
http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18381:17
tryCallTwo@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:17657:7
doResolve@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:17796:23
Promise@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:17678:12
callInvokeWithMethodAndArg@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18380:27
enqueue@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18385:155
http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18318:28
async@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:18396:67
_callee@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:81403:38
_onSurfaceCreate@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:53425:36
invokeGuardedCallback@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:11739:15
invokeGuardedCallback@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:11795:40
invokeGuardedCallbackAndCatchFirstError@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:11799:60
executeDispatch@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14869:58
executeDispatchesInOrder@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14888:20
executeDispatchesAndRelease@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23093:46
executeDispatchesAndReleaseTopLevel@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23104:37
forEachAccumulated@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23351:12
processEventQueue@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23198:25
runEventQueueInBatch@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23987:35
handleTopLevel@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23993:25
http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23943:45
fiberBatchedUpdates@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14711:12
performFiberBatchedUpdates@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14715:29
perform@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:25393:24
batchedUpdates@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:26548:33
batchedUpdates@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:25269:41
batchedUpdates@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14718:29
batchedUpdatesWithControlledComponents@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:14728:26
_receiveRootNodeIDEvent@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23942:40
receiveEvent@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:23949:52
__callFunction@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:3403:47
http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:3263:29
__guard@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:3375:11
callFunctionReturnFlushedQueue@http://192.168.0.111:19001/./node_modules/react-native-scripts/build/bin/crna-entry.bundle?platform=android&dev=true&hot=false&minify=false:3262:19
callFunctionReturnFlushedQueue@[native code]

It would seem that the addEventListener function is not available on window when Three is trying to access it. Yet debugging in my component shows that the method is indeed here, at least after Three has already been loaded.

Aside from that : what are your recommendations for debugging JS in an app using GLView ?

#5

@odusseys could you try forcing version 0.85.0 of three.js?

#6

Ok all of these issues should be fixed in the latest expo-three version.

#7

It’s me again ! So the issues I was having are indeed fixed in this version. However I am now trying to load an .obj file using Three.OBJLoader (from three-obj-loader). I’m not getting anything, although the equivalent code works in a browser.
Here’s the code I’m using

var resourcePath = '/resources/';
    var texture = await ExpoTHREE.createTextureAsync({
        asset: Expo.Asset.fromModule(require('./resources/texture.jpg')),
    });
    var obj = null;
    var objLoader = new THREE.OBJLoader();
    var material = new THREE.MeshStandardMaterial( {
        color: 0xffffff,
        roughness: 1.0,
        metalness: 0.0
    });

    objLoader.setPath(resourcePath);
    objLoader.load(
      'object.obj',
      function (object) {
        object.traverse(function (child) {
            if (child instanceof THREE.Mesh) {
              child.material = material;
              child.material.map = texture;
            }
        });
        obj = object;
        scene.add( object );
      }
    );

Now I’m guessing this has to do with the way Expo handles assets, although I have no idea how to handle the obj case.

#8

Never mind, read up on assets and clearly was doing it the wrong way. I managed to mimic the way you coded the texture import in your library ; since there is no way require an .obj file I just stored the text file in a string literal and used the Three.OBJLoader to parse it.

#9

You can require a .obj file if you add the “obj” extension to assetExts in app.json

#10

Hi Nikki, do you know if this would be fixed in next version?
Otherwise it is not possible to debug any scene with three.js…

#11

@denis82 fix which part? There are multiple issues in this thread. I’m guessing having GL during remote debugging? Unfortunately the current implementation of remote debugging in React Native runs in a different JavaScript context than the one on your device so this isn’t trivially fixable, and we have no plans at the moment to support that.

You’ll have to debug through other means, like adding extra output.