Pārlūkot izejas kodu

WebXR: Better errors when WebXR Layers or multiview are unavailable

David Snopek 1 mēnesi atpakaļ
vecāks
revīzija
9fc8dd686b

+ 22 - 3
modules/webxr/native/library_godot_webxr.js

@@ -94,7 +94,7 @@ const GodotWebXR = {
 				return layer;
 			}
 
-			if (!GodotWebXR.session || !GodotWebXR.gl_binding) {
+			if (!GodotWebXR.session || !GodotWebXR.gl_binding || !GodotWebXR.gl_binding.createProjectionLayer) {
 				return null;
 			}
 
@@ -293,10 +293,29 @@ const GodotWebXR = {
 			GodotWebXR.gl = gl;
 
 			gl.makeXRCompatible().then(function () {
-				GodotWebXR.gl_binding = new XRWebGLBinding(session, gl);
+				const throwNoWebXRLayersError = () => {
+					throw new Error('This browser doesn\'t support WebXR Layers (which Godot requires) nor is the polyfill in use. If you are the developer of this application, please consider including the polyfill.');
+				};
+
+				try {
+					GodotWebXR.gl_binding = new XRWebGLBinding(session, gl);
+				} catch (error) {
+					// We'll end up here for browsers that don't have XRWebGLBinding at all, or if the browser does support WebXR Layers,
+					// but is using the WebXR polyfill, so calling native XRWebGLBinding with the polyfilled XRSession won't work.
+					throwNoWebXRLayersError();
+				}
+
+				if (!GodotWebXR.gl_binding.createProjectionLayer) {
+					// On other browsers, XRWebGLBinding exists and works, but it doesn't support creating projection layers (which is
+					// contrary to the spec, which says this MUST be supported) and so the polyfill is required.
+					throwNoWebXRLayersError();
+				}
 
 				// This will trigger the layer to get created.
-				GodotWebXR.getLayer();
+				const layer = GodotWebXR.getLayer();
+				if (!layer) {
+					throw new Error('Unable to create WebXR Layer.');
+				}
 
 				function onReferenceSpaceSuccess(reference_space, reference_space_type) {
 					GodotWebXR.space = reference_space;

+ 7 - 0
modules/webxr/webxr_interface_js.cpp

@@ -291,10 +291,17 @@ bool WebXRInterfaceJS::initialize() {
 
 	if (!initialized) {
 		if (!godot_webxr_is_supported()) {
+			emit_signal("session_failed", "WebXR is unsupported by this web browser.");
+			return false;
+		}
+
+		if (session_mode == "immersive-vr" && !GLES3::Config::get_singleton()->multiview_supported) {
+			emit_signal("session_failed", "Stereo rendering in Godot requires multiview, but this web browser doesn't support it.");
 			return false;
 		}
 
 		if (requested_reference_space_types.is_empty()) {
+			emit_signal("session_failed", "No reference spaces were requested.");
 			return false;
 		}