WebGLRenderingContext
方法
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.
let makeCompatPromise = webGLRenderingContext.makeXRCompatible();
None.
A
Promise
which successfully resolves once the WebGL context is ready to be used for rendering
WebXR
内容。
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.
因为
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 设备 API
rather than by WebGL.
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.
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.
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;
默认:
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.
| 规范 | 状态 | 注释 |
|---|---|---|
|
WebXR 设备 API
The definition of 'WebGLRenderingContext.makeXRCompatible()' in that specification. |
工作草案 | 初始定义 |
| 桌面 | 移动 | |||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|
makeXRCompatible
|
Chrome 79 | Edge 79 | Firefox No | IE No | Opera No | Safari No | WebView Android No | Chrome Android 79 | Firefox Android No | Opera Android No | Safari iOS No | Samsung Internet Android 11.2 |
完整支持
不支持
WebGLRenderingContext
activeTexture()
attachShader()
bindAttribLocation()
bindBuffer()
bindFramebuffer()
bindRenderbuffer()
bindTexture()
blendColor()
blendEquation()
blendEquationSeparate()
blendFunc()
blendFuncSeparate()
bufferData()
bufferSubData()
checkFramebufferStatus()
clear()
clearColor()
clearDepth()
clearStencil()
colorMask()
commit()
compileShader()
compressedTexImage[23]D()
compressedTexSubImage2D()
copyTexImage2D()
copyTexSubImage2D()
createBuffer()
createFramebuffer()
createProgram()
createRenderbuffer()
createShader()
createTexture()
cullFace()
deleteBuffer()
deleteFramebuffer()
deleteProgram()
deleteRenderbuffer()
deleteShader()
deleteTexture()
depthFunc()
depthMask()
depthRange()
detachShader()
disable()
disableVertexAttribArray()
drawArrays()
drawElements()
enable()
enableVertexAttribArray()
finish()
flush()
framebufferRenderbuffer()
framebufferTexture2D()
frontFace()
generateMipmap()
getActiveAttrib()
getActiveUniform()
getAttachedShaders()
getAttribLocation()
getBufferParameter()
getContextAttributes()
getError()
getExtension()
getFramebufferAttachmentParameter()
getParameter()
getProgramInfoLog()
getProgramParameter()
getRenderbufferParameter()
getShaderInfoLog()
getShaderParameter()
getShaderPrecisionFormat()
getShaderSource()
getSupportedExtensions()
getTexParameter()
getUniform()
getUniformLocation()
getVertexAttrib()
getVertexAttribOffset()
hint()
isBuffer()
isContextLost()
isEnabled()
isFramebuffer()
isProgram()
isRenderbuffer()
isShader()
isTexture()
lineWidth()
linkProgram()
pixelStorei()
polygonOffset()
readPixels()
renderbufferStorage()
sampleCoverage()
scissor()
shaderSource()
stencilFunc()
stencilFuncSeparate()
stencilMask()
stencilMaskSeparate()
stencilOp()
stencilOpSeparate()
texImage2D()
texParameter[fi]()
texSubImage2D()
uniform[1234][fi][v]()
uniformMatrix[234]fv()
useProgram()
validateProgram()
vertexAttrib[1234]f[v]()
vertexAttribPointer()
viewport()
ANGLE_instanced_arrays
EXT_blend_minmax
EXT_color_buffer_half_float
EXT_disjoint_timer_query
EXT_frag_depth
EXT_sRGB
EXT_shader_texture_lod
EXT_texture_filter_anisotropic
OES_element_index_uint
OES_standard_derivatives
OES_texture_float
OES_texture_float_linear
OES_texture_half_float
OES_texture_half_float_linear
OES_vertex_array_object
WEBGL_color_buffer_float
WEBGL_compressed_texture_atc
WEBGL_compressed_texture_etc1
WEBGL_compressed_texture_pvrtc
WEBGL_compressed_texture_s3tc
WEBGL_compressed_texture_s3tc_srgb
WEBGL_debug_renderer_info
WEBGL_debug_shaders
WEBGL_depth_texture
WEBGL_draw_buffers
WEBGL_lose_context
WebGL2RenderingContext
WebGLActiveInfo
WebGLBuffer
WebGLContextEvent
WebGLFramebuffer
WebGLObject
WebGLProgram
WebGLQuery
WebGLRenderbuffer
WebGLSampler
WebGLShader
WebGLShaderPrecisionFormat
WebGLSync
WebGLTexture
WebGLTransformFeedback
WebGLUniformLocation
WebGLVertexArrayObject