diff options
author | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
---|---|---|
committer | Peter Bengtsson <mail@peterbe.com> | 2020-12-08 14:41:45 -0500 |
commit | 1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch) | |
tree | 0dd8b084480983cf9f9680e8aedb92782a921b13 /files/es/web/api/webvr_api | |
parent | 4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff) | |
download | translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2 translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip |
initial commit
Diffstat (limited to 'files/es/web/api/webvr_api')
-rw-r--r-- | files/es/web/api/webvr_api/index.html | 256 | ||||
-rw-r--r-- | files/es/web/api/webvr_api/using_the_webvr_api/index.html | 448 |
2 files changed, 704 insertions, 0 deletions
diff --git a/files/es/web/api/webvr_api/index.html b/files/es/web/api/webvr_api/index.html new file mode 100644 index 0000000000..199e8f6458 --- /dev/null +++ b/files/es/web/api/webvr_api/index.html @@ -0,0 +1,256 @@ +--- +title: WebVR API +slug: Web/API/WebVR_API +tags: + - API + - Experimental + - Landing + - NeedsTranslation + - Reference + - TopicStub + - VR + - Virtual Reality + - WebVR +translation_of: Web/API/WebVR_API +--- +<div>{{SeeCompatTable}}{{APIRef("WebVR API")}}</div> + +<p class="summary">WebVR proporciona soporte para la exposición de dispositivos de realidad virtual — por ejemplo el visualizador de Oculus Rift o HTC Vive — para aplicaciones web, permitiendo a los desarrolladores traducir la información de posición y movimiento del visualizador al movimiento alrededor de una escena en 3D. Esto tiene numerosas aplicaciones interesantes, desde visitas virtuales de productos y aplicaciones de capacitación interactiva hasta juegos inmersivos en primera persona.</p> + +<h2 id="Concepts_and_usage">Concepts and usage</h2> + +<p>Any VR devices attached to your computer will be returned by the {{domxref("Navigator.getVRDisplays()")}} method; each one will be represented by a {{domxref("VRDisplay")}} object.</p> + +<p><img alt='Sketch of a person in a chair with wearing goggles labelled "Head mounted display (HMD)" facing a monitor with a webcam labelled "Position sensor"' src="https://mdn.mozillademos.org/files/11035/hw-setup.png" style="display: block; height: 78px; margin: 0px auto; width: 60%;"></p> + +<p>{{domxref("VRDisplay")}} is the central interface in the WebVR API — via its properties and methods you can access functionality to:</p> + +<ul> + <li>Retrieve useful information to allow us to identify the display, what capabilities it has, controllers associated with it, and more.</li> + <li>Retrieve {{domxref("VRFrameData", "frame data")}} for each frame of content you you want to present in a display, and submit those frames for display at a consistent rate.</li> + <li>Start and stop presenting to the display.</li> +</ul> + +<p>A typical (simple) WebVR app would work like so:</p> + +<ol> + <li>{{domxref("Navigator.getVRDisplays()")}} is used to get a reference to your VR display.</li> + <li>{{domxref("VRDisplay.requestPresent()")}} is used to start presenting to the VR display.</li> + <li>WebVR's dedicated {{domxref("VRDisplay.requestAnimationFrame()")}} method is used to run the app's rendering loop at the correct refresh rate for the display.</li> + <li>Inside the rendering loop, you grab the data required to display the current frame ({{domxref("VRDisplay.getFrameData()")}}), draw the displayed scene twice — once for the view in each eye, then submit the rendered view to the display to show to the user ({{domxref("VRDisplay.submitFrame()")}}).</li> +</ol> + +<p>In addition, WebVR 1.1 adds a number of events on the {{domxref("Window")}} object to allow JavaScript to respond to changes to the status of the display.</p> + +<div class="note"> +<p><strong>Note</strong>: You can find a lot more out about how the API works in our <a href="/en-US/docs/Web/API/WebVR_API/Using_the_WebVR_API">Using the WebVR API</a> and <a href="/en-US/docs/Web/API/WebVR_API/Concepts">WebVR Concepts</a> articles.</p> +</div> + +<h3 id="Using_controllers_Combining_WebVR_with_the_Gamepad_API">Using controllers: Combining WebVR with the Gamepad API</h3> + +<p>Many WebVR hardware setups feature controllers that go along with the headset. These can be used in WebVR apps via the <a href="/en-US/docs/Web/API/Gamepad_API">Gamepad API</a>, and specifically the <a href="/en-US/docs/Web/API/Gamepad_API#Experimental_Gamepad_extensions">Gamepad Extensions API</a> that adds API features for accessing <a href="/en-US/docs/Web/API/GamepadPose">controller pose</a>, <a href="/en-US/docs/Web/API/GamepadHapticActuator">haptic actuators</a>, and more.</p> + +<div class="note"> +<p><strong>Note</strong>: Our <a href="/en-US/docs/Web/API/WebVR_API/Using_VR_controllers_with_WebVR">Using VR controllers with WebVR</a> article explains the basics of how to use VR controllers with WebVR apps.</p> +</div> + +<h2 id="WebVR_Interfaces">WebVR Interfaces</h2> + +<dl> + <dt>{{domxref("VRDisplay")}}</dt> + <dd>Represents any VR device supported by this API. It includes generic information such as device IDs and descriptions, as well as methods for starting to present a VR scene, retrieving eye parameters and display capabilities, and other important functionality.</dd> + <dt>{{domxref("VRDisplayCapabilities")}}</dt> + <dd>Describes the capabilities of a {{domxref("VRDisplay")}} — it's features can be used to perform VR device capability tests, for example can it return position information.</dd> + <dt>{{domxref("VRDisplayEvent")}}</dt> + <dd>Represents the event object of WebVR-related events (see the {{anch("Window", "window object extensions")}} listed below).</dd> + <dt>{{domxref("VRFrameData")}}</dt> + <dd>Represents all the information needed to render a single frame of a VR scene; constructed by {{domxref("VRDisplay.getFrameData()")}}.</dd> + <dt>{{domxref("VRPose")}}</dt> + <dd>Represents the position state at a given timestamp (which includes orientation, position, velocity, and acceleration.)</dd> + <dt>{{domxref("VREyeParameters")}}</dt> + <dd>Provides access to all the information required to correctly render a scene for each given eye, including field of view information.</dd> + <dt>{{domxref("VRFieldOfView")}}</dt> + <dd>Represents a field of view defined by 4 different degree values describing the view from a center point.</dd> + <dt>{{domxref("VRLayerInit")}}</dt> + <dd>Represents a layer to be presented in a {{domxref("VRDisplay")}}.</dd> + <dt>{{domxref("VRStageParameters")}}</dt> + <dd>Represents the values describing the the stage area for devices that support room-scale experiences.</dd> +</dl> + +<h3 id="Extensions_to_other_interfaces">Extensions to other interfaces</h3> + +<p>The WebVR API extends the following APIs, adding the listed features.</p> + +<h4 id="Gamepad">Gamepad</h4> + +<dl> + <dt>{{domxref("Gamepad.displayId")}} {{readonlyInline}}</dt> + <dd><dfn>Returns the {{domxref("VRDisplay.displayId")}} of the associated {{domxref("VRDisplay")}} — the <code>VRDisplay</code> that the gamepad is controlling the displayed scene of.</dfn></dd> +</dl> + +<h4 id="Navigator">Navigator</h4> + +<dl> + <dt>{{domxref("Navigator.activeVRDisplays")}} {{readonlyInline}}</dt> + <dd>Returns an array containing every {{domxref("VRDisplay")}} object that is currently presenting ({{domxref("VRDisplay.ispresenting")}} is <code>true</code>).</dd> + <dt>{{domxref("Navigator.getVRDisplays()")}}</dt> + <dd>Returns a promise that resolves to an array of {{domxref("VRDisplay")}} objects representing any available VR displays connected to the computer.</dd> +</dl> + +<h4 id="Window_events">Window events</h4> + +<dl> + <dt>{{domxref("Window.onvrdisplaypresentchange")}}</dt> + <dd>Represents an event handler that will run when the presenting state of a VR display changes — i.e. goes from presenting to not presenting, or vice versa (when the {{event("vrdisplaypresentchange")}} event fires).</dd> + <dt>{{domxref("Window.onvrdisplayconnect")}}</dt> + <dd>Represents an event handler that will run when a compatible VR display has been connected to the computer (when the {{event("vrdisplayconnect")}} event fires).</dd> + <dt>{{domxref("Window.onvrdisplaydisconnect")}}</dt> + <dd>Represents an event handler that will run when a compatible VR display has been disconnected from the computer (when the {{event("vrdisplaydisconnect")}} event fires).</dd> + <dt>{{domxref("Window.onvrdisplayactivate")}}</dt> + <dd>Represents an event handler that will run when a display is able to be presented to (when the {{event("vrdisplayactivate")}} event fires), for example if an HMD has been moved to bring it out of standby, or woken up by being put on.</dd> + <dt>{{domxref("Window.onvrdisplaydeactivate")}}</dt> + <dd>Represents an event handler that will run when a display can no longer be presented to (when the {{event("vrdisplaydeactivate")}} event fires), for example if an HMD has gone into standby or sleep mode due to a period of inactivity.</dd> +</dl> + +<h4 id="Unimplemented_window_events">Unimplemented window events</h4> + +<p>The following events are listed in the spec, but do not currently seem to be implemented anywhere as yet.</p> + +<dl> + <dt>{{domxref("Window.onvrdisplayblur")}}</dt> + <dd>Represents an event handler that will run when presentation to a display has been paused for some reason by the browser, OS, or VR hardware (when the {{event("vrdisplayblur")}} event fires) — for example, while the user is interacting with a system menu or browser, to prevent tracking or loss of experience.</dd> + <dt>{{domxref("Window.onvrdisplayfocus")}}</dt> + <dd>Represents an event handler that will run when presentation to a display has resumed after being blurred (when the {{event("vrdisplayfocus")}} event fires).</dd> +</dl> + +<h2 id="Examples">Examples</h2> + +<p>You can find a number of examples at these locations:</p> + +<ul> + <li><a href="https://github.com/mdn/webvr-tests">webvr-tests</a> — very simple examples to accompany the MDN WebVR documentation.</li> + <li><a href="https://github.com/facebook/Carmel-Starter-Kit">Carmel starter kit</a> — nice simple, well-commented examples that go along with Carmel, Facebook's WebVR browser.</li> + <li><a href="https://webvr.info/samples/">WebVR.info samples</a> — slightly more in-depth examples plus source code</li> + <li><a href="https://webvr.rocks/firefox#demos">WebVR.rocks Firefox demos</a> — showcase examples</li> + <li><a href="https://aframe.io/">A-Frame homepage</a> — examples showing A-Frame usage</li> +</ul> + +<h2 id="Specifications">Specifications</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Specification</th> + <th scope="col">Status</th> + <th scope="col">Comment</th> + </tr> + <tr> + <td>{{SpecName("GamepadExtensions")}}</td> + <td>{{Spec2("GamepadExtensions")}}</td> + <td>Defines the <a href="/en-US/docs/Web/API/Gamepad_API#Experimental_Gamepad_extensions">Experimental Gamepad extensions</a>.</td> + </tr> + <tr> + <td>{{SpecName('WebVR 1.1')}}</td> + <td>{{Spec2('WebVR 1.1')}}</td> + <td>Initial definition</td> + </tr> + </tbody> +</table> + +<h2 id="Browser_compatibility">Browser compatibility</h2> + +<p>{{CompatibilityTable}}</p> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Chrome</th> + <th>Edge</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari (WebKit)</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}<sup>[1]</sup></td> + <td>{{CompatVersionUnknown}}</td> + <td>{{CompatGeckoDesktop(55)}}<sup>[2]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Gamepad extensions</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}<sup>[4]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Feature</th> + <th>Android</th> + <th>Edge</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Phone</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + <th>Chrome for Android</th> + <th>Samsung Internet for GearVR</th> + </tr> + <tr> + <td>Basic support</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatGeckoMobile(55)}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatVersionUnknown}}<sup>[3]</sup></td> + <td>{{CompatVersionUnknown}}<br> + </td> + </tr> + <tr> + <td>Gamepad extensions</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}<sup>[4]</sup></td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<p>[1] API Available on all platforms behind a flag, but currently only works on desktop in an <a href="https://webvr.info/get-chrome/">experimental version of Chrome</a> (other builds won't return any devices when {{domxref("Navigator.getVRDisplays()")}} is invoked).</p> + +<p>[2] Currently only Windows support is enabled by default. Mac support is <a href="https://hacks.mozilla.org/2017/06/announcing-webvr-on-mac/">available in Firefox Nightly</a>.</p> + +<p>[3] Currently supported only by Google Daydream.</p> + +<p>[4] Enabled in Firefox Nightly and Beta, versions 55 and above. Enabled/disabled by the <code>dom.gamepad-extensions.enabled</code> pref.</p> + +<h2 id="See_also">See also</h2> + +<ul> + <li><a href="https://vr.mozilla.org">vr.mozilla.org</a> — The main Mozilla landing pad for WebVR, with demos, utilities, and other information.</li> + <li><a href="https://aframe.io/">A-Frame</a> — Open source web framework for building VR experiences.</li> + <li><a href="https://webvr.info">webvr.info</a> — Up-to-date information about WebVR, browser setup, and community.</li> + <li><a href="http://mozvr.com/">MozVr.com</a> — Demos, downloads, and other resources from the Mozilla VR team.</li> + <li><a href="https://github.com/MozVR/vr-web-examples/tree/master/threejs-vr-boilerplate">threejs-vr-boilerplate</a> — A useful starter template for writing WebVR apps into.</li> + <li><a href="https://github.com/googlevr/webvr-polyfill/">Web VR polyfill</a> — JavaScript implementation of WebVR.</li> +</ul> diff --git a/files/es/web/api/webvr_api/using_the_webvr_api/index.html b/files/es/web/api/webvr_api/using_the_webvr_api/index.html new file mode 100644 index 0000000000..0a4bc67e58 --- /dev/null +++ b/files/es/web/api/webvr_api/using_the_webvr_api/index.html @@ -0,0 +1,448 @@ +--- +title: Uso de la API de WebVR +slug: Web/API/WebVR_API/Using_the_WebVR_API +tags: + - '1.1' + - API + - Canvas + - Realidad Virtual + - Tutorial + - VR + - WebGL + - WebVR +translation_of: Web/API/WebVR_API/Using_the_WebVR_API +--- +<div>{{APIRef("WebVR API")}}</div> + +<p class="summary"><span id="result_box" lang="es"><span>La API WebVR es una fantástica adición al kit de herramientas del desarrollador web, permitiendo que las escenas de WebGL sean presentadas en pantallas de realidad virtual como el Oculus Rift y HTC Vive.</span> <span>Pero, ¿cómo empezar a desarrollar aplicaciones VR para la Web?</span> <span>Este artículo le guiará a través de los fundamentos.</span></span></p> + +<div class="note"> +<p><span id="result_box" lang="es"><span><strong>Nota:</strong> La versión más estable de la API de WebVR (1.1) se ha implementado recientemente en Firefox 55 (Windows en versión de lanzamiento y Mac OS X sólo en Nightly) y también está disponible en Chrome cuando se usa con hardware de Google Daydream.</span> <span>También hay una evolución posterior de la especificación 2.0, pero esto está en una etapa temprana ahora mismo.</span> <span>Puede encontrar información sobre el estado más reciente de las especificaciones en </span></span> <a href="https://w3c.github.io/webvr/">WebVR Spec Version List</a>.</p> +</div> + +<h2 id="Empezando"><span class="short_text" id="result_box" lang="es"><span>Empezando</span></span></h2> + +<p><span class="short_text" id="result_box" lang="es"><span>Para empezar, necesita:</span></span></p> + +<ul> + <li><span class="short_text" id="result_box" lang="es"><span>Soporte de hardware VR.</span></span> + + <ul> + <li><span id="result_box" lang="es"><span>La opción más barata es utilizar un dispositivo móvil, compatible con el navegador y el dispositivo montado (por ejemplo, Google Cardboard).</span> <span>Esto no será una experiencia tan buena como el hardware dedicado, pero no necesitará comprar una computadora potente o una pantalla VR dedicada.</span></span></li> + <li><span id="result_box" lang="es"><span>El hardware dedicado puede ser costoso, pero proporciona una experiencia mejor.</span> <span>El hardware más compatible con WebVR en este momento es el HTC VIVE, y The Oculus Rift.</span> <span>La primera página de</span></span> <a href="https://webvr.info/">webvr.info</a> <span id="result_box" lang="es"><span>tiene alguna otra información útil sobre hardware disponible y qué navegador los soporta.</span></span></li> + </ul> + </li> + <li><span id="result_box" lang="es"><span>Una computadora lo suficientemente potente para manejar la representación / visualización de escenas VR usando su hardware VR dedicado, si es necesario.</span> <span>Para darle una idea de lo que usted necesita, mire la guía relevante para el VR que usted está comprando</span></span> ( p. ej.<a href="https://www.vive.com/us/ready/">VIVE READY Computers</a>).</li> + <li><span class="short_text" id="result_box" lang="es"><span>Se ha instalado un navegador de soporte: el último</span></span> <a href="https://www.mozilla.org/en-US/firefox/channel/desktop/">Firefox Nightly</a> o <a href="https://www.google.com/chrome/index.html">Chrome</a> <span id="result_box" lang="es"><span>son sus mejores opciones ahora, en el escritorio o móvil.</span></span></li> +</ul> + +<p><span id="result_box" lang="es"><span>Una vez que tengas todo montado, puedes probar si tu configuración funciona con WebVR yendo a nuestro</span></span> <a href="https://mdn.github.io/webvr-tests/aframe-demo/">simple A-Frame demo</a>, <span id="result_box" lang="es"><span>y ver si la escena se procesa y si puede entrar en el modo de visualización VR pulsando el botón en la parte inferior derecha.</span></span></p> + +<p><a href="https://aframe.io/">A-Frame</a> <span id="result_box" lang="es"><span>es de lejos la mejor opción si desea crear una escena 3D compatible con WebVR rápidamente, sin necesidad de entender un montón de código nuevo de JavaScript.</span> <span>Sin embargo, no te enseña cómo funciona la API WebVR en bruto, y esto es lo que veremos a continuación.</span></span></p> + +<h2 id="Introduccion_a_nuestra_demostración"><span class="short_text" id="result_box" lang="es"><span>Introduccion a nuestra demostración</span></span></h2> + +<p><span id="result_box" lang="es"><span>Para ilustrar cómo funciona la API de WebVR, estudiaremos nuestro ejemplo raw-webgl-example, que se parece un poco a esto:</span></span></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15121/Capture1.png" style="display: block; height: 761px; margin: 0px auto; width: 1341px;"></p> + +<div class="note"> +<p><span id="result_box" lang="es"><span><strong>Nota:</strong> Puedes encontrar el <a href="https://github.com/mdn/webvr-tests/tree/master/raw-webgl-example">código fuente de nuestra demo</a> en </span></span> GitHub, <span id="result_box" lang="es"><span>y <a href="https://mdn.github.io/webvr-tests/raw-webgl-example/">verlo en vivo </a>también. </span></span></p> +</div> + +<div class="note"> +<p><span id="result_box" lang="es"><span><strong>Nota:</strong> Si WebVR no funciona en su navegador, es posible que deba asegurarse de que se está ejecutando a través de su tarjeta gráfica.</span> <span>Por ejemplo, para las tarjetas NVIDIA, si el panel de control de NVIDIA se ha configurado correctamente, habrá una opción de menú contextual disponible - haga clic con el botón derecho del ratón en Firefox y seleccione <em>Ejecutar con procesador gráfico</em> > <em>Procesador NVIDIA de alto rendimiento.</em></span></span></p> +</div> + +<p><span id="result_box" lang="es"><span>Nuestra demo presenta el santo grial de las demostraciones de WebGL - un cubo 3D giratorio.</span> <span>Hemos implementado esto usando raw </span></span><a href="/en-US/docs/Web/API/WebGL_API">WebGL API</a> <span id="result_box" lang="es"><span>código.</span> <span>No enseñaremos ningún JavaScript básico o WebGL, solo las partes de WebVR.</span></span></p> + +<p><span class="short_text" id="result_box" lang="es"><span>Nuestra demo también cuenta con:</span></span></p> + +<ul> + <li><span id="result_box" lang="es"><span>Un botón para iniciar (y detener) la presentación de nuestra escena en la pantalla VR.</span></span></li> + <li><span id="result_box" lang="es"><span>Un botón para mostrar (y ocultar) los datos de pose VR, es decir, la posición y orientación del auricular, actualizados en tiempo real.</span></span></li> +</ul> + +<p><span class="short_text" id="result_box" lang="es"><span>Cuando miras a través del código fuente de</span></span><a href="https://github.com/mdn/webvr-tests/blob/master/raw-webgl-example/webgl-demo.js"> nuestro archivo JavaScript principal de demostraciones</a> , <span id="result_box" lang="es"><span>puede encontrar fácilmente las partes específicas de WebVR buscando la cadena "WebVR" en comentarios anteriores.</span></span></p> + +<div class="note"> +<p><span id="result_box" lang="es"><span><strong>Nota:</strong> Para obtener más información sobre JavaScript básico y WebGL, consulte nuestro </span></span><a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript">material de aprendizaje JavaScrip</a><span lang="es"><span> </span></span>, y nuestro <a href="/en-US/docs/Web/API/WebGL_API/Tutorial">WebGL Tutorial</a>.</p> +</div> + +<h2 id="¿Como_funciona"><span class="short_text" id="result_box" lang="es"><span>¿Como funciona?</span></span></h2> + +<p><span id="result_box" lang="es"><span>En este punto, veamos cómo funcionan las partes WebVR del código.</span></span></p> + +<p><span id="result_box" lang="es"><span>Una típica (simple) aplicación WebVR funciona de esta manera:</span></span></p> + +<ol> + <li>{{domxref("Navigator.getVRDisplays()")}} <span id="result_box" lang="es"><span>se utiliza para obtener una referencia a la visualización VR.</span></span></li> + <li>{{domxref("VRDisplay.requestPresent()")}} <span id="result_box" lang="es"><span>se utiliza para iniciar la presentación en la pantalla VR.</span></span></li> + <li><span class="short_text" id="result_box" lang="es"><span>WebVR's dedicado </span></span>{{domxref("VRDisplay.requestAnimationFrame()")}} <span id="result_box" lang="es"><span>se utiliza para ejecutar el bucle de representación de la aplicación a la velocidad de actualización correcta para la pantalla.</span></span></li> + <li><span id="result_box" lang="es"><span>Dentro del bucle de procesamiento, se capturan los datos necesarios para mostrar el marco actual </span></span>({{domxref("VRDisplay.getFrameData()")}}), <span id="result_box" lang="es"><span>dibuja la escena visualizada dos veces - una vez para la vista en cada ojo -</span> <span>luego envia la vista renderizada a la pantalla para mostrar al usuario a través de </span></span>({{domxref("VRDisplay.submitFrame()")}}).</li> +</ol> + +<p><span id="result_box" lang="es"><span>En las secciones siguientes veremos en detalle nuestra demostración raw-webgl y veremos dónde se utilizan exactamente las características anteriores.</span></span></p> + +<h3 id="Comenzando_con_algunas_variables"><span class="short_text" id="result_box" lang="es"><span>Comenzando con algunas variables</span></span></h3> + +<p><span id="result_box" lang="es"><span>El primer código relacionado con WebVR que encontrarás es el siguiente bloque:</span></span></p> + +<pre class="brush: js notranslate">// WebVR variables + +var frameData = new VRFrameData(); +var vrDisplay; +var btn = document.querySelector('.stop-start'); +var normalSceneFrame; +var vrSceneFrame; + +var poseStatsBtn = document.querySelector('.pose-stats'); +var poseStatsSection = document.querySelector('section'); +poseStatsSection.style.visibility = 'hidden'; // hide it initially + +var posStats = document.querySelector('.pos'); +var orientStats = document.querySelector('.orient'); +var linVelStats = document.querySelector('.lin-vel'); +var linAccStats = document.querySelector('.lin-acc'); +var angVelStats = document.querySelector('.ang-vel'); +var angAccStats = document.querySelector('.ang-acc'); +var poseStatsDisplayed = false;</pre> + +<p><span class="short_text" id="result_box" lang="es"><span>Vamos a explicar estos </span></span><span class="short_text" lang="es"><span>brevemente :</span></span></p> + +<ul> + <li><code>frameData</code> contains a {{domxref("VRFrameData")}} <span class="short_text" id="result_box" lang="es"><span>objeto, creado con el </span></span>{{domxref("VRFrameData.VRFrameData", "VRFrameData()")}} <span id="result_box" lang="es"><span>constructor.</span> <span>Esto es inicialmente vacío, pero contendrá más adelante los datos requeridos para rendir cada marco para mostrar en la exhibición de VR, actualizado constantemente mientras que se ejecuta el ciclo de la representación.</span></span></li> + <li><code>vrDisplay</code> <span id="result_box" lang="es"><span>comienza sin inicializarse, pero más adelante se realizará una referencia a nuestro auricular VR</span></span> ({{domxref("VRDisplay")}} —<span class="short_text" id="result_box" lang="es"><span> el objeto de control central de la API).</span></span></li> + <li><code>btn</code> y <code>poseStatsBtn</code> <span id="result_box" lang="es"><span>mantenga referencias a los dos botones que estamos usando para controlar nuestra aplicación.</span></span></li> + <li><code>normalSceneFrame</code> y <code>vrSceneFrame</code> <span id="result_box" lang="es"><span>no iniciados, pero más adelante contendrán referencias a</span></span> {{domxref("Window.requestAnimationFrame()")}} y {{domxref("VRDisplay.requestAnimationFrame()")}} <span id="result_box" lang="es"><span>llamadas - esto iniciará el funcionamiento de un bucle de renderizado normal, y un bucle de renderización WebVR especial;</span> <span>explicaremos la diferencia entre estos dos más adelante.</span></span></li> + <li><span id="result_box" lang="es"><span>Las otras variables almacenan referencias a diferentes partes del cuadro de visualización de datos de pose de VR, que se puede ver en la esquina inferior derecha de la interfaz de usuario.</span></span></li> +</ul> + +<h3 id="Cómo_obtener_una_referencia_a_nuestra_pantalla_VR"><span class="short_text" id="result_box" lang="es"><span>Cómo obtener una referencia a nuestra pantalla VR</span></span></h3> + +<p><span id="result_box" lang="es"><span>Una de las principales funciones dentro de nuestro código es start () - ejecutamos esta función cuando el cuerpo ha terminado de cargar:</span></span></p> + +<pre class="brush: js notranslate">// start +// +// Called when the body has loaded is created to get the ball rolling. + +document.body.onload = start;</pre> + +<p>Para empezar, <code>start()</code> <span id="result_box" lang="es"><span>recupera un contexto de WebGL para usarlo para renderizar gráficos 3D</span></span> {{htmlelement("canvas")}} <span class="short_text" id="result_box" lang="es"><span>elemento en </span></span><a href="https://github.com/mdn/webvr-tests/blob/master/raw-webgl-example/index.html">our HTML</a>. <span class="short_text" id="result_box" lang="es"><span>A continuación verificamos si la</span></span> <code>gl</code> <span class="short_text" id="result_box" lang="es"><span>contexto está disponible</span></span> — <span id="result_box" lang="es"><span>si es así, ejecutamos una serie de funciones para configurar la escena para su visualización.</span></span></p> + +<pre class="brush: js notranslate">function start() { + canvas = document.getElementById("glcanvas"); + + initWebGL(canvas); // Initialize the GL context + + // WebGL setup code here</pre> + +<p>Next, we start the process of actually rendering the scene onto the canvas, by setting the canvas to fill the entire browser viewport, and running the rendering loop (<code>drawScene()</code>) for the first time. This is the non-WebVR — normal — rendering loop.</p> + +<pre class="brush: js notranslate"> // draw the scene normally, without WebVR - for those who don't have it and want to see the scene in their browser + + canvas.width = window.innerWidth; + canvas.height = window.innerHeight; + drawScene();</pre> + +<p>Now onto our first WebVR-specific code. First of all, we check to see if {{domxref("Navigator.getVRDisplays")}} exists — this is the entry point into the API, and therefore good basic feature detection for WebVR. You'll see at the end of the block (inside the <code>else</code> clause) that if this doesn't exist, we log a message to indicate that WebVR 1.1 isn't supported by the browser.</p> + +<pre class="brush: js notranslate"> // WebVR: Check to see if WebVR is supported + if(navigator.getVRDisplays) { + console.log('WebVR 1.1 supported');</pre> + +<p>Inside our <code>if() { ... }</code> block, we run the {{domxref("Navigator.getVRDisplays()")}} function. This returns a promise, which is fulfilled with an array containing all the VR display devices connected to the computer. If none are connected, the array will be empty.</p> + +<pre class="brush: js notranslate"> // Then get the displays attached to the computer + navigator.getVRDisplays().then(function(displays) {</pre> + +<p>Inside the promise <code>then()</code> block, we check whether the array length is more than 0; if so, we set the value of our <code>vrDisplay</code> variable to the 0 index item inside the array. <code>vrDisplay</code> now contains a {{domxref("VRDisplay")}} object representing our connected display!</p> + +<pre class="brush: js notranslate"> // If a display is available, use it to present the scene + if(displays.length > 0) { + vrDisplay = displays[0]; + console.log('Display found');</pre> + +<div class="note"> +<p><span id="result_box" lang="es"><span><strong>Nota: </strong>Es poco probable que tenga varias pantallas VR conectadas a su computadora, y esto es sólo una demostración simple, por lo que esto lo hará por ahora.</span></span></p> +</div> + +<h3 id="Starting_and_stopping_the_VR_presentation">Starting and stopping the VR presentation</h3> + +<p>Now we have a {{domxref("VRDisplay")}} object, we can use it do a number of things. The next thing we want to do is wire up functionality to start and stop presentation of the WebGL content to the display.</p> + +<p>Continuing on with the previous code block, we now add an event listener to our start/stop button (<code>btn</code>) — when this button is clicked we want to check whether we are presenting to the display already (we do this in a fairly dumb fashion, by checking what the button <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code> contains).</p> + +<p>If the display is not already presenting, we use the {{domxref("VRDisplay.requestPresent()")}} method to request that the browser start presenting content to the display. This takes as a parameter an array of the {{domxref("VRLayerInit")}} objects representing the layers you want to present in the display.</p> + +<p>Since the maximum number of layers you can display is currently 1, and the only required object member is the {{domxref("VRLayerInit.source")}} property (which is a reference to the {{htmlelement("canvas")}} you want to present in that layer; the other parameters are given sensible defaults — see {{domxref("VRLayerInit.leftBounds", "leftBounds")}} and {{domxref("VRLayerInit.rightBounds", "rightBounds")}})), the parameter is simply [{ source: canvas }].</p> + +<p><code>requestPresent()</code> returns a promise that is fulfilled when the presentation begins successfully.</p> + +<pre class="brush: js notranslate"> // Starting the presentation when the button is clicked: It can only be called in response to a user gesture + btn.addEventListener('click', function() { + if(btn.textContent === 'Start VR display') { + vrDisplay.requestPresent([{ source: canvas }]).then(function() { + console.log('Presenting to WebVR display');</pre> + +<p>With our presentation request successful, we now want to start setting up to render content to present to the VRDisplay. First of all we set the canvas to the same size as the VR display area. We do this by getting the {{domxref("VREyeParameters")}} for both eyes using {{domxref("VRDisplay.getEyeParameters()")}}.</p> + +<p>We then do some simple math to calculate the total width of the VRDisplay rendering area based on the eye {{domxref("VREyeParameters.renderWidth")}} and {{domxref("VREyeParameters.renderHeight")}}.</p> + +<pre class="brush: js notranslate"> // Set the canvas size to the size of the vrDisplay viewport + + var leftEye = vrDisplay.getEyeParameters('left'); + var rightEye = vrDisplay.getEyeParameters('right'); + + canvas.width = Math.max(leftEye.renderWidth, rightEye.renderWidth) * 2; + canvas.height = Math.max(leftEye.renderHeight, rightEye.renderHeight);</pre> + +<p>Next, we {{domxref("Window.cancelAnimationFrame()", "cancel the animation loop")}} previously set in motion by the {{domxref("Window.requestAnimationFrame()")}} call inside the <code>drawScene()</code> function, and instead invoke <code>drawVRScene()</code>. This function renders the same scene as before, but with some special WebVR magic going on. The loop inside here is maintained by WebVR's special {{domxref("VRDisplay.requestAnimationFrame")}} method.</p> + +<pre class="brush: js notranslate"> // stop the normal presentation, and start the vr presentation + window.cancelAnimationFrame(normalSceneFrame); + drawVRScene();</pre> + +<p><span id="result_box" lang="es"><span>Finalmente, actualizamos el texto del botón para que la próxima vez que se presione, detenga la presentación en la pantalla VR.</span></span></p> + +<pre class="brush: js notranslate"> btn.textContent = 'Exit VR display'; + });</pre> + +<p><br> + To stop the VR presentation when the button is subsequently pressed, we call {{domxref("VRDisplay.exitPresent()")}}. We also reverse the button's text content, and swap over the <code>requestAnimationFrame</code> calls. You can see here that we are using {{domxref("VRDisplay.cancelAnimationFrame")}} to stop the VR rendering loop, and starting the normal rendering loop off again by calling <code>drawScene()</code>.</p> + +<pre class="brush: js notranslate"> } else { + vrDisplay.exitPresent(); + console.log('Stopped presenting to WebVR display'); + + btn.textContent = 'Start VR display'; + + // Stop the VR presentation, and start the normal presentation + vrDisplay.cancelAnimationFrame(vrSceneFrame); + drawScene(); + } + }); + } + }); + } else { + console.log('WebVR API not supported by this browser.'); + } + } +}</pre> + +<p><span id="result_box" lang="es"><span>Una vez iniciada la presentación, podrás ver la vista estereoscópica que se muestra en el navegador:</span></span></p> + +<p><img alt="" src="https://mdn.mozillademos.org/files/15123/Capture2.png" style="display: block; margin: 0 auto;"></p> + +<p><span id="result_box" lang="es"><span>A continuación, aprenderá cómo se produce realmente la vista estereoscópica.</span></span></p> + +<h3 id="Why_does_WebVR_have_its_own_requestAnimationFrame">Why does WebVR have its own requestAnimationFrame()?</h3> + +<p>This is a good question. The reason is that for smooth rendering inside the VR display, you need to render the content at the display's native refresh rate, not that of the computer. VR display refresh rates are greater than PC refresh rates, typically up to 90fps. The rate will be differ from the computer's core refresh rate.</p> + +<p>Note that when the VR display is not presenting, {{domxref("VRDisplay.requestAnimationFrame")}} runs identically to {{domxref("Window.requestAnimationFrame")}}, so if you wanted, you could just use a single rendering loop, rather than the two we are using in our app. We have used two because we wanted to do slightly different things depending on whether the VR display is presenting or not, and keep things separated for ease of comprehension.</p> + +<h3 id="Rendering_and_display">Rendering and display</h3> + +<p>At this point, we've seen all the code required to access the VR hardware, request that we present our scene to the hardware, and start running the rending loop. Let's now look at the code for the rendering loop, and explain how the WebVR-specific parts of it work.</p> + +<p>First of all, we begin the definition of our rendering loop function — <code>drawVRScene()</code>. The first thing we do inside here is make a call to {{domxref("VRDisplay.requestAnimationFrame()")}} to keep the loop running after it has been called once (this occurred earlier on in our code when we started presenting to the VR display). This call is set as the value of the global <code>vrSceneFrame</code> variable, so we can cancel the loop with a call to {{domxref("VRDisplay.cancelAnimationFrame()")}} once we exit VR presenting.</p> + +<pre class="brush: js notranslate">function drawVRScene() { + // WebVR: Request the next frame of the animation + vrSceneFrame = vrDisplay.requestAnimationFrame(drawVRScene);</pre> + +<p>Next, we call {{domxref("VRDisplay.getFrameData()")}}, passing it the name of the variable that we want to use to contain the frame data. We initialized this earlier on — <code>frameData</code>. After the call completes, this variable will contain the data need to render the next frame to the VR device, packaged up as a {{domxref("VRFrameData")}} object. This contains things like projection and view matrices for rendering the scene correctly for the left and right eye view, and the current {{domxref("VRPose")}} object, which contains data on the VR display such as orientation, position, etc.</p> + +<p>This has to be called on every frame so the rendered view is always up-to-date.</p> + +<pre class="brush: js notranslate"> // Populate frameData with the data of the next frame to display + vrDisplay.getFrameData(frameData);</pre> + +<p>Now we retrieve the current {{domxref("VRPose")}} from the {{domxref("VRFrameData.pose")}} property, store the position and orientation for use later on, and send the current pose to the pose stats box for display, if the <code>poseStatsDisplayed</code> variable is set to true.</p> + +<pre class="brush: js notranslate"> // You can get the position, orientation, etc. of the display from the current frame's pose + + var curFramePose = frameData.pose; + var curPos = curFramePose.position; + var curOrient = curFramePose.orientation; + if(poseStatsDisplayed) { + displayPoseStats(curFramePose); + }</pre> + +<p> We now clear the canvas before we start drawing on it, so that the next frame is clearly seen, and we don't also see previous rendered frames:</p> + +<pre class="brush: js notranslate"> // Clear the canvas before we start drawing on it. + + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);</pre> + +<p>We now render the view for both the left and right eyes. First of all we need to create projection and view locations for use in the rendering. these are {{domxref("WebGLUniformLocation")}} objects, created using the {{domxref("WebGLRenderingContext.getUniformLocation()")}} method, passing it the shader program's identifier and an identifying name as parameters.</p> + +<pre class="brush: js notranslate"> // WebVR: Create the required projection and view matrix locations needed + // for passing into the uniformMatrix4fv methods below + + var projectionMatrixLocation = gl.getUniformLocation(shaderProgram, "projMatrix"); + var viewMatrixLocation = gl.getUniformLocation(shaderProgram, "viewMatrix");</pre> + +<p>The next rendering step involves:</p> + +<ul> + <li>Specifying the viewport size for the left eye, using {{domxref("WebGLRenderingContext.viewport")}} — this is logically the first half of the canvas width, and the full canvas height.</li> + <li>Specifying the view and projection matrix values to use to render the left eye — this is done using the {{domxref("WebGLRenderingContext.uniformMatrix", "WebGLRenderingContext.uniformMatrix4fv")}} method, which is passed the location values we retrieved above, and the left matrices obtained from the {{domxref("VRFrameData")}} object.</li> + <li>Running the <code>drawGeometry()</code> function, which renders the actual scene — because of what we specified in the previous two steps, we will render it for the left eye only.</li> +</ul> + +<pre class="brush: js notranslate"> // WebVR: Render the left eye’s view to the left half of the canvas + gl.viewport(0, 0, canvas.width * 0.5, canvas.height); + gl.uniformMatrix4fv(projectionMatrixLocation, false, frameData.leftProjectionMatrix); + gl.uniformMatrix4fv(viewMatrixLocation, false, frameData.leftViewMatrix); + drawGeometry();</pre> + +<p>We now do exactly the same thing, but for the right eye:</p> + +<pre class="brush: js notranslate"> // WebVR: Render the right eye’s view to the right half of the canvas + gl.viewport(canvas.width * 0.5, 0, canvas.width * 0.5, canvas.height); + gl.uniformMatrix4fv(projectionMatrixLocation, false, frameData.rightProjectionMatrix); + gl.uniformMatrix4fv(viewMatrixLocation, false, frameData.rightViewMatrix); + drawGeometry();</pre> + +<p>Next we define our <code>drawGeometry()</code> function. Most of this is just general WebGL code required to draw our 3D cube. You'll see some WebVR-specific parts in the <code>mvTranslate()</code> and <code>mvRotate()</code> function calls — these pass matrices into the WebGL program that define the translation and rotation of the cube for the current frame</p> + +<p>You'll see that we are modifying these values by the position (<code>curPos</code>) and orientation (<code>curOrient</code>) of the VR display we got from the {{domxref("VRPose")}} object. The result is that, for example, as you move or rotate your head left, the x position value (<code>curPos[0]</code>) and y rotation value (<code>[curOrient[1]</code>) are added to the x translation value, meaning that the cube will move to the right, as you'd expect when you are looking at something and then move/turn your head left.</p> + +<p>This is a quick and dirty way to use VR pose data, but it illustrates the basic principle.</p> + +<pre class="brush: js notranslate"> function drawGeometry() { + // Establish the perspective with which we want to view the + // scene. Our field of view is 45 degrees, with a width/height + // ratio of 640:480, and we only want to see objects between 0.1 units + // and 100 units away from the camera. + + perspectiveMatrix = makePerspective(45, 640.0/480.0, 0.1, 100.0); + + // Set the drawing position to the "identity" point, which is + // the center of the scene. + + loadIdentity(); + + // Now move the drawing position a bit to where we want to start + // drawing the cube. + + mvTranslate([ + 0.0 - (curPos[0] * 25) + (curOrient[1] * 25), + 5.0 - (curPos[1] * 25) - (curOrient[0] * 25), + -15.0 - (curPos[2] * 25) + ]); + + // Save the current matrix, then rotate before we draw. + + mvPushMatrix(); + mvRotate(cubeRotation, [0.25, 0, 0.25 - curOrient[2] * 0.5]); + + // Draw the cube by binding the array buffer to the cube's vertices + // array, setting attributes, and pushing it to GL. + + gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesBuffer); + gl.vertexAttribPointer(vertexPositionAttribute, 3, gl.FLOAT, false, 0, 0); + + // Set the texture coordinates attribute for the vertices. + + gl.bindBuffer(gl.ARRAY_BUFFER, cubeVerticesTextureCoordBuffer); + gl.vertexAttribPointer(textureCoordAttribute, 2, gl.FLOAT, false, 0, 0); + + // Specify the texture to map onto the faces. + + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, cubeTexture); + gl.uniform1i(gl.getUniformLocation(shaderProgram, "uSampler"), 0); + + // Draw the cube. + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, cubeVerticesIndexBuffer); + setMatrixUniforms(); + gl.drawElements(gl.TRIANGLES, 36, gl.UNSIGNED_SHORT, 0); + + // Restore the original matrix + + mvPopMatrix(); + } +</pre> + +<p>The next bit of the code has nothing to do with WebVR — it just updates the rotation of the cube on each frame:</p> + +<pre class="brush: js notranslate"> // Update the rotation for the next draw, if it's time to do so. + + var currentTime = (new Date).getTime(); + if (lastCubeUpdateTime) { + var delta = currentTime - lastCubeUpdateTime; + + cubeRotation += (30 * delta) / 1000.0; + } + + lastCubeUpdateTime = currentTime;</pre> + +<p>The last part of the rendering loop involves us calling {{domxref("VRDisplay.submitFrame()")}} — now all the work has been done and we've rendered the display on the {{htmlelement("canvas")}}, this method then submits the frame to the VR display so it is displayed on there as well.</p> + +<pre class="brush: js notranslate"> // WebVR: Indicate that we are ready to present the rendered frame to the VR display + vrDisplay.submitFrame(); +}</pre> + +<h3 id="Displaying_the_pose_position_orientation_etc._data">Displaying the pose (position, orientation, etc.) data</h3> + +<p>In this section we'll discuss the <code>displayPoseStats()</code> function, which displays our updated pose data on each frame. The function is fairly simple.</p> + +<p>First of all, we store the six different property values obtainable from the {{domxref("VRPose")}} object in their own variables — each one is a {{domxref("Float32Array")}}.</p> + +<pre class="brush: js notranslate">function displayPoseStats(pose) { + var pos = pose.position; + var orient = pose.orientation; + var linVel = pose.linearVelocity; + var linAcc = pose.linearAcceleration; + var angVel = pose.angularVelocity; + var angAcc = pose.angularAcceleration;</pre> + +<p>We then write out the data into the information box, updating it on every frame. We've clamped each value to three decimal places using <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed">toFixed()</a></code>, as the values are hard to read otherwise.</p> + +<p>You should note that we've used a conditional expression to detect whether the linear acceleration and angular acceleration arrays are successfully returned before we display the data. These values are not reported by most VR hardware as yet, so the code would throw an error if we did not do this (the arrays return <code>null</code> if they are not successfully reported).</p> + +<pre class="brush: js notranslate"> posStats.textContent = 'Position: x ' + pos[0].toFixed(3) + ', y ' + pos[1].toFixed(3) + ', z ' + pos[2].toFixed(3); + orientStats.textContent = 'Orientation: x ' + orient[0].toFixed(3) + ', y ' + orient[1].toFixed(3) + ', z ' + orient[2].toFixed(3); + linVelStats.textContent = 'Linear velocity: x ' + linVel[0].toFixed(3) + ', y ' + linVel[1].toFixed(3) + ', z ' + linVel[2].toFixed(3); + angVelStats.textContent = 'Angular velocity: x ' + angVel[0].toFixed(3) + ', y ' + angVel[1].toFixed(3) + ', z ' + angVel[2].toFixed(3); + + if(linAcc) { + linAccStats.textContent = 'Linear acceleration: x ' + linAcc[0].toFixed(3) + ', y ' + linAcc[1].toFixed(3) + ', z ' + linAcc[2].toFixed(3); + } else { + linAccStats.textContent = 'Linear acceleration not reported'; + } + + if(angAcc) { + angAccStats.textContent = 'Angular acceleration: x ' + angAcc[0].toFixed(3) + ', y ' + angAcc[1].toFixed(3) + ', z ' + angAcc[2].toFixed(3); + } else { + angAccStats.textContent = 'Angular acceleration not reported'; + } +}</pre> + +<h2 id="WebVR_events">WebVR events</h2> + +<p>The WebVR spec features a number of events that are fired, allowing our app code to react to changes in the state of the VR display (see <a href="/en-US/docs/Web/API/WebVR_API#Window_events">Window events</a>). For example:</p> + +<ul> + <li>{{event("vrdisplaypresentchange")}} — Fires when the presenting state of a VR display changes — i.e. goes from presenting to not presenting, or vice versa.</li> + <li>{{event("vrdisplayconnect")}} — Fires when a compatible VR display has been connected to the computer.</li> + <li>{{event("vrdisplaydisconnect")}} — Fires when a compatible VR display has been disconnected from the computer.</li> +</ul> + +<p>To demonstrate how they work, our simple demo includes the following example:</p> + +<pre class="brush: js notranslate">window.addEventListener('vrdisplaypresentchange', function(e) { + console.log('Display ' + e.display.displayId + ' presentation has changed. Reason given: ' + e.reason + '.'); +});</pre> + +<p>As you can see, the {{domxref("VRDisplayEvent", "event object")}} provides two useful properties — {{domxref("VRDisplayEvent.display")}}, which contains a reference to the {{domxref("VRDisplay")}} the event was fired in response to, and {{domxref("VRDisplayEvent.reason")}}, which contains a human-readable reason why the event was fired.</p> + +<p>This is a very useful event; you could use it to handle cases where the display gets disconnected unexpectedly, stopping errors from being thrown and making sure the user is aware of the situation. In Google's Webvr.info presentation demo, the event is used to run an <a href="https://github.com/toji/webvr.info/blob/master/samples/03-vr-presentation.html#L174"><code>onVRPresentChange()</code> function</a>, which updates the UI controls as appropriate and resizes the canvas.</p> + +<h2 id="Summary">Summary</h2> + +<p>This article has given you the very basics of how to create a simple WebVR 1.1 app, to help you get started.</p> |