WebGLRenderingContext.makeXRCompatible() - Web APIs 编辑

The WebGLRenderingContext method makeXRCompatible() ensures that the rendering context described by the WebGLRenderingContext is ready to render the scene for the immersive WebXR device on which it will be displayed. If necessary, the WebGL layer may reconfigure the context to be ready to render to a different device than it originally was.

This is useful if you have an application which can start out being presented on a standard 2D display but can then be transitioned to a 3D immersion system.

Syntax

let makeCompatPromise = webGLRenderingContext.makeXRCompatible();

Parameters

None.

Return value

A Promise which successfully resolves once the WebGL context is ready to be used for rendering WebXR content.

Exceptions

This method doesn't throw traditional exceptions; instead, the promise rejects with one of the following errors as the value passed into the rejection handler:

AbortError
Switching the context over to the WebXR-compatible context failed.
InvalidStateError
The WebGL context has been lost or there is no available WebXR device.

Usage notes

Because makeXRCompatible() may involve replacing the underlying WebGL context with a new one that uses the new rendering hardware, the existing contents of the context may be lost and, therefore, would need to be re-rendered. This is why the webglcontextlost and webglcontextrestored events are used: the first gives you the opportunity to discard anything you won't need anymore, while the second gives you the opportunity to load resources and prepare to render the scene in its new context.

While this method is available through the WebGLRenderingContext interface, it's actually defined by the WebXR Device API rather than by WebGL.

Examples

This example demonstrates code logic you might find in a game that starts up using WebGL to display menus and other UI, and uses WebGL to render gameplay, but has a button on its main menu that offers an option to start the game in WebXR mode.

HTML

The HTML for the buttons looks lke this:

<button class="green button" type="button">Start Game</button>
<button class="blue button use-webxr" type="button">Start Game (VR mode)</button>

The first button starts the game, continuing to present the game onscreen as usual. The second button will be used to start the game in immersive-vr mode. Note the inclusion of a use-webxr class on the VR mode button. This is important, which we'll explore shortly.

JavaScript

The code that handles starting up graphics, switching to VR mode, and so forth looks like this:

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 */
}

This works by having two buttons, one which starts the game normally and the other which starts the game in VR mode. These both use the handleStartButtonClick() function as their event handler. The function determines that the button clicked was the one requesting immersive-vr mode by checking to see if the button has the use-webxr class on it. If the button clicked by the user has that class (and we've confirmed that WebXR is available by ensuring that the navigator.xr property exists), we use requestSession() to request a new WebXR session and set the usingXR flag to true.

If the other button was clicked, we ensure that xrSession is NULL and clear usingXR to false.

Then the startGame() function is called to trigger the beginning of gameplay.

Handlers are provided for both webglcontextlost and webglcontextrestored; in the first case, we make sure we're aware that the state can be recovered, while in the latter we actually reload the scene to ensure we have the correct resources for the current screen or headset configuration.

Specifications

SpecificationStatusComment
WebXR Device API
The definition of 'WebGLRenderingContext.makeXRCompatible()' in that specification.
Working DraftInitial definition

Browser compatibility

BCD tables only load in the browser

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据

词条统计

浏览:74 次

字数:8502

最后编辑:7 年前

编辑次数:0 次

    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文