WebGLRenderingContext: makeXRCompatible() 方法
该 WebGLRenderingContext
方法 makeXRCompatible()
确保 WebGLRenderingContext
描述的渲染上下文已准备好为其将要显示的沉浸式 WebXR 设备渲染场景。如有必要,WebGL 层可能会重新配置上下文,使其能够渲染到与最初不同的设备。
如果您有一个应用程序,它可以从标准 2D 显示器上开始呈现,然后过渡到 3D 沉浸式系统,则此方法很有用。
语法
makeXRCompatible()
参数
无。
返回值
异常
此方法不会抛出传统的异常;相反,该 promise 会拒绝,并将以下错误之一作为值传递到拒绝处理程序
AbortError
DOMException
-
如果将上下文切换到 WebXR 兼容上下文失败,则返回。
InvalidStateError
DOMException
-
如果 WebGL 上下文已丢失或没有可用的 WebXR 设备,则返回。
使用说明
因为 makeXRCompatible()
可能涉及使用新的渲染硬件替换底层的 WebGL 上下文,所以上下文的现有内容可能会丢失,因此需要重新渲染。这就是使用 webglcontextlost
和 webglcontextrestored
事件的原因:第一个事件为您提供了丢弃不再需要的任何内容的机会,而第二个事件为您提供了加载资源并准备在其新上下文中渲染场景的机会。
虽然此方法可通过 WebGLRenderingContext
接口获得,但它实际上是由 WebXR 设备 API 而不是 WebGL 定义的。
示例
此示例演示了您可能在游戏中找到的代码逻辑,该游戏使用 WebGL 显示菜单和其他 UI 启动,并使用 WebGL 渲染游戏玩法,但在其主菜单上有一个按钮,提供以 WebXR 模式启动游戏的选项。
HTML
按钮的 HTML 如下所示
<button class="green button" type="button">Start Game</button>
<button class="blue button use-webxr" type="button">
Start Game (VR mode)
</button>
第一个按钮启动游戏,继续像往常一样在屏幕上呈现游戏。第二个按钮将用于以 immersive-vr
模式启动游戏。请注意,VR 模式按钮上包含一个 use-webxr
类。这一点很重要,我们将在稍后探讨。
JavaScript
处理启动图形、切换到 VR 模式等的代码如下所示
const outputCanvas = document.querySelector(".output-canvas");
const gl = outputCanvas.getContext("webgl");
let xrSession = null;
let usingXR = false;
let currentScene = "scene1";
let glStartButton;
let xrStartButton;
window.addEventListener("load", (event) => {
loadSceneResources(currentScene);
glStartButton.addEventListener("click", handleStartButtonClick);
xrStartButton.addEventListener("click", handleStartButtonClick);
});
outputCanvas.addEventListener("webglcontextlost", (event) => {
/* The context has been lost but can be restored */
event.canceled = true;
});
/* When the GL context is reconnected, reload the resources for the
current scene. */
outputCanvas.addEventListener("webglcontextrestored", (event) => {
loadSceneResources(currentScene);
});
async function onStartedXRSession(xrSession) {
try {
await gl.makeXRCompatible();
} catch (err) {
switch (err) {
case AbortError:
showSimpleMessageBox(
"Unable to transfer the game to your XR headset.",
"Cancel",
);
break;
case InvalidStateError:
showSimpleMessageBox(
"You don't appear to have a compatible XR headset available.",
"Cancel",
);
break;
default:
handleFatalError(err);
break;
}
xrSession.end();
}
}
async function handleStartButtonClick(event) {
if (event.target.classList.contains("use-webxr") && navigator.xr) {
try {
xrSession = await navigator.xr.requestSession("immersive-vr");
usingXR = true;
} catch (err) {
xrSession = NULL;
usingXR = false;
}
}
startGame();
}
function startGame() {
currentScene = "scene1";
loadSceneResources(currentScene);
/* and so on */
}
它的工作原理是使用两个按钮,一个正常启动游戏,另一个以 VR 模式启动游戏。这两个按钮都使用 handleStartButtonClick()
函数作为其事件处理程序。该函数通过检查按钮上是否具有 use-webxr
类来确定用户点击的按钮是请求 immersive-vr
模式的那个。如果用户点击的按钮具有该类(并且我们已通过确保 navigator.xr
属性存在来确认 WebXR 可用),我们使用 requestSession()
请求一个新的 WebXR 会话并将 usingXR
标志设置为 true
。
如果点击了另一个按钮,我们确保 xrSession
为 NULL
并将 usingXR
清除为 false
。
然后调用 startGame()
函数以触发游戏玩法的开始。
为 webglcontextlost
和 webglcontextrestored
提供了处理程序;在第一种情况下,我们确保知道状态可以恢复,而在后一种情况下,我们实际上重新加载场景以确保我们拥有当前屏幕或耳机配置的正确资源。
规范
规范 |
---|
WebXR 设备 API # dom-webglrenderingcontextbase-makexrcompatible |
浏览器兼容性
BCD 表格仅在启用了 JavaScript 的浏览器中加载。