aboutsummaryrefslogtreecommitdiff
path: root/files/fi/web/api/webvr_api
diff options
context:
space:
mode:
authorPeter Bengtsson <mail@peterbe.com>2020-12-08 14:41:45 -0500
committerPeter Bengtsson <mail@peterbe.com>2020-12-08 14:41:45 -0500
commit1109132f09d75da9a28b649c7677bb6ce07c40c0 (patch)
tree0dd8b084480983cf9f9680e8aedb92782a921b13 /files/fi/web/api/webvr_api
parent4b1a9203c547c019fc5398082ae19a3f3d4c3efe (diff)
downloadtranslated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.gz
translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.tar.bz2
translated-content-1109132f09d75da9a28b649c7677bb6ce07c40c0.zip
initial commit
Diffstat (limited to 'files/fi/web/api/webvr_api')
-rw-r--r--files/fi/web/api/webvr_api/index.html250
-rw-r--r--files/fi/web/api/webvr_api/using_the_webvr_api/index.html438
2 files changed, 688 insertions, 0 deletions
diff --git a/files/fi/web/api/webvr_api/index.html b/files/fi/web/api/webvr_api/index.html
new file mode 100644
index 0000000000..e3b73598f2
--- /dev/null
+++ b/files/fi/web/api/webvr_api/index.html
@@ -0,0 +1,250 @@
+---
+title: WebVR API
+slug: Web/API/WebVR_API
+tags:
+ - API
+ - Experimental
+ - Expérimental(2)
+ - Landing
+ - NeedsTranslation
+ - Reference
+ - Référence(2)
+ - TopicStub
+ - VR
+ - Virtual Reality
+ - WebVR
+translation_of: Web/API/WebVR_API
+---
+<p>{{SeeCompatTable}}{{APIRef("WebVR API")}}</p>
+
+<p>WebVR -rajapinta tarjoaa tuen VR-laitteiden — kuten Oculus Rift tai HTC Vive -silmikoiden — käyttämiseen webbisovelluksille, jolloin kehittäjät voivat muuttaa silmikolta saadun sijainti- ja liiketiedon 3D-skenessä liikkumistiedoksi. Tämä mahdollistaa useita kiinnostavia sovellusmahdollisuuksia aina virtuaalisista tuote-esittelyistä ja interaktiivisista treenisovelluksista immersiivisiin FPS-räiskintäpeleihin.</p>
+
+<h2 id="Perusperiaatteet_ja_käyttö">Perusperiaatteet ja käyttö</h2>
+
+<p>Metodi {{domxref("Navigator.getVRDisplays()")}} hakee kaikki tietokoneeseen liitetyt VR-laitteet; jokaista näistä vastaa {{domxref("VRDisplay")}} -tyyppinen objekti.</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")}} on perusrajapinta WebVR API:in — sen ominaisuuksien ja metodien avulla voit esimerkiksi:</p>
+
+<ul>
+ <li>Hakea tiedot näyttölaitteen tunnistamiseen, sen ominaisuudet ja siihen liitetyt ohjaimet.</li>
+ <li>Hakea kunkin näytettäväksi tarkoitetun sisältöruudun {{domxref("VRFrameData", "frame data")}} ja toimittaa ruudut näytölle oikealla taajuudella.</li>
+ <li>Käynnistää ja pysäyttää näyttämisen.</li>
+</ul>
+
+<p>Tyypillinen (yksinkertainen) WebVR-sovellus toimisi esimerkiksi näin:</p>
+
+<ol>
+ <li>{{domxref("Navigator.getVRDisplays()")}} -metodilla haetaan viittaus VR-näyttöön.</li>
+ <li>{{domxref("VRDisplay.requestPresent()")}} -metodilla käynnistetään näyttäminen.</li>
+ <li>WebVR:n omalla versiolla {{domxref("VRDisplay.requestAnimationFrame()")}} -methodista suoritetaan sovelluksen renderöintisilmukkaa näytölle sopivalla virkistystaajuudella.</li>
+ <li>Renderöintisilmukassa haetaan ruudun näyttämiseen tarvittavat tiedot ({{domxref("VRDisplay.getFrameData()")}}) -metodilla, piirretään näytettävä skene kaksi kertaa — siis kerran molemmille silmille, ja sen jälkeen toimitetaan renderöity näkymä näytölle käyttäjälle näytettäväksi metodilla ({{domxref("VRDisplay.submitFrame()")}}).</li>
+</ol>
+
+<p>Tämän lisäksi WebVR 1.1 lisää useita tapahtumia (event) {{domxref("Window")}} -objektiin, jolloin JavaScriptillä voidaan reagoida näytön tilan muutoksiin.</p>
+
+<p><strong>Huom</strong>: APIn toiminnasta löytyy paljon lisätietoa artikkeleista <a href="/en-US/docs/Web/API/WebVR_API/Using_the_WebVR_API">Using the WebVR API</a> ja <a href="/en-US/docs/Web/API/WebVR_API/Concepts">WebVR Concepts</a>.</p>
+
+<h3 id="Ohjaimien_käyttö_WebVRn_yhdistäminen_Gamepad_APIin">Ohjaimien käyttö: WebVR:n yhdistäminen Gamepad API:in</h3>
+
+<p>Useissa WebVR-laitekokoonpanoissa silmikon mukana on käytettävissä erillinen ohjain. Ohjaimia voidaan käyttää WebVR-sovelluksissa <a href="/en-US/docs/Web/API/Gamepad_API">Gamepad API</a>:n kautta, ja erityisesti <a href="/en-US/docs/Web/API/Gamepad_API#Experimental_Gamepad_extensions">Gamepad Extensions API:n</a>, joka lisää mukaan ohjaimen asentotiedon (<a href="/en-US/docs/Web/API/GamepadPose">controller pose</a>), tuntoperusteiset laitteet (<a href="/en-US/docs/Web/API/GamepadHapticActuator">haptic actuators</a>) ja muita vastaavia.</p>
+
+<p><strong>Huom</strong>: Artikkeli <a href="/en-US/docs/Web/API/WebVR_API/Using_VR_controllers_with_WebVR">Using VR controllers with WebVR</a> selittää perusteet VR-ohjaimien käytöstä WebVR-sovelluksissa.</p>
+
+<h2 id="WebVR_rajapinnat">WebVR rajapinnat</h2>
+
+<dl>
+ <dt>{{domxref("VRDisplay")}}</dt>
+ <dd>Edustaa mitä tahnsa APIn tukemaa VR-laitetta. Siinä on mukana yleistiedot laittesta, kuten laitteen tunnisteet (ID) ja kuvaukset sekä metodit VR-skenen esittämisen käynnistämiseen, silmäparametrien ja näytön ominaisuuksien hakemiseen ja muut olennaiset toiminnat.</dd>
+ <dt>{{domxref("VRDisplayCapabilities")}}</dt>
+ <dd>Esittää {{domxref("VRDisplay")}}:n ominaisuudet — näillä voidaan testata, saako laitteelta esimerkiksi sijaintitietoa.</dd>
+ <dt>{{domxref("VRDisplayEvent")}}</dt>
+ <dd>Edustaa WebVR-kohtaisen tapahtuman tapahtumaobjektia (kts. {{anch("Window", "window object extensions")}} alempana).</dd>
+ <dt>{{domxref("VRFrameData")}}</dt>
+ <dd>Vastaa kaikkea tietoa, mitä yksittäisen VR-skenen ruudun renderöintiin tarvitaan; metodi {{domxref("VRDisplay.getFrameData()")}} hakee nämä tiedot.</dd>
+ <dt>{{domxref("VRPose")}}</dt>
+ <dd>Edustaa tietyllä ajanhetkellä vallitsevaa sijaintitietoa (johon kuuluvat suunta, sijainti, nopeus ja kiihtyvyys.)</dd>
+ <dt>{{domxref("VREyeParameters")}}</dt>
+ <dd>Tarjoaa pääsyn kaikkeen tietoon, joka tarvitaan skenen renderöintiin oikein kullekin silmälle, esimerkiksi näkökentän laajuuden.</dd>
+ <dt>{{domxref("VRFieldOfView")}}</dt>
+ <dd>Näkökenttätieto, joka on määritelty keskipisteestä katsottuna neljällä asteluvulla.</dd>
+ <dt>{{domxref("VRLayerInit")}}</dt>
+ <dd>Tämä on {{domxref("VRDisplay")}}-näytöllä esitettävä kuvan eräs taso (layer).</dd>
+ <dt>{{domxref("VRStageParameters")}}</dt>
+ <dd>Huoneskaalaa tukevien laitteiden kanssa käytettävissä sovelluksissa "näyttämöalueen" tiedot löytyvät tästä.</dd>
+</dl>
+
+<h3 id="Laajennukset_muihin_rajapintoihin">Laajennukset muihin rajapintoihin</h3>
+
+<p>WebVR API laajentaa joitakin API-rajapintoja lisäten seuraavat ominaisuudet.</p>
+
+<h4 id="Gamepad">Gamepad</h4>
+
+<dl>
+ <dt>{{domxref("Gamepad.displayId")}} {{readonlyInline}}</dt>
+ <dd>Palauttaa liitetyn {{domxref("VRDisplay")}} tunnisteen {{domxref("VRDisplay.displayId")}} — <code>VRDisplay</code> , jonka skeneä gamepad ohjaa.</dd>
+</dl>
+
+<h4 id="Navigator">Navigator</h4>
+
+<dl>
+ <dt>{{domxref("Navigator.activeVRDisplays")}} {{readonlyInline}}</dt>
+ <dd>Palauttaa taulukon, jossa on mukana jokainen {{domxref("VRDisplay")}}, joka esittää parhaillaan ({{domxref("VRDisplay.ispresenting")}} on <code>true</code>).</dd>
+ <dt>{{domxref("Navigator.getVRDisplays()")}}</dt>
+ <dd>Palauttaa promise-objektin, joka sisältää taulukon {{domxref("VRDisplay")}} objekteja, jotka vastaavat kaikkia tietokoneeseen liitettyjä VR-näyttöjä.</dd>
+</dl>
+
+<h4 id="Window-tapahtumat">Window-tapahtumat</h4>
+
+<dl>
+ <dt>{{domxref("Window.onvrdisplaypresentchange")}}</dt>
+ <dd>Edustaa tapahtumankäsittelijää (event handler), joka suoritetaan, kun VR_näytön esittämistila muuttuu — esimerkiksi tilasta 'esittää' tilaan 'ei esitä' tai päinvastoin (kun tapahtuma {{event("vrdisplaypresentchange")}} signaloidaan).</dd>
+ <dt>{{domxref("Window.onvrdisplayconnect")}}</dt>
+ <dd>Tämä tapahtumankäsittelijä suoritetaan, kun yhteensopiva VR-näyttö on kytketty tietokoneeseen (tapahtuma {{event("vrdisplayconnect")}} ).</dd>
+ <dt>{{domxref("Window.onvrdisplaydisconnect")}}</dt>
+ <dd>Tämä tapahtumankäsittelijä suoritetaan, kun yhteensopiva VR-näyttö irrotetaan tietokoneesta (kun tapahtuma {{event("vrdisplaydisconnect")}} signaloidaan).</dd>
+ <dt>{{domxref("Window.onvrdisplayactivate")}}</dt>
+ <dd>Edustaa taphtumaa, joka suoritetaan, kun näyttö on valmis esittämään sisältöä (tapahtuma {{event("vrdisplayactivate")}} ),esimerkiksi kun silmikko aktivoituu virransäästötilasta tai puetaan päälle.</dd>
+ <dt>{{domxref("Window.onvrdisplaydeactivate")}}</dt>
+ <dd>Tämä tapahtumankäsittelijä suoritetaan, kun näytölle ei voi enää esittää sisältöä (kun tapahtuma {{event("vrdisplaydeactivate")}} signaloidaan), esimerkiksi syystä, että silmikkonäyttö on siirtynyt virransäästötilaan käyttämättömyyden vuoksi.</dd>
+</dl>
+
+<h4 id="Windown_tapahtumat_jotka_eivät_ole_käytettävissä">Window:n tapahtumat, jotka eivät ole käytettävissä</h4>
+
+<p>Seuraavat tapahtumat löytyvät APIn määrittelystä, mutta niiden toteutusta ei tunnu vielä löytyvän mistään selaimista.</p>
+
+<dl>
+ <dt>{{domxref("Window.onvrdisplayblur")}}</dt>
+ <dd>Edustaa tapahtumankäsittelijää, joka suoritetaan kun selain, käyttöjärjestelmä tai VR-laitteisto on keskeyttänyt esittämisen näytölle jostain syystä (tapahtuman {{event("vrdisplayblur")}} johdosta) — esimerkiksi käytettäessä järjestelmän valikkoa tai selainta. Tarkoitus on estää seurantaa tai VR-kokemuksen menetystä.</dd>
+ <dt>{{domxref("Window.onvrdisplayfocus")}}</dt>
+ <dd>Tämä tapahtumankäsittelijä suoritetaan, kun esittäminen näytöllä palautuu edellisen tapahtuman jälkeen (tapahtumasta {{event("vrdisplayfocus")}} ).</dd>
+</dl>
+
+<h2 id="Esimerkkejä">Esimerkkejä</h2>
+
+<p>Näiltä sivustoilta töydät useita esimerkkejä:</p>
+
+<ul>
+ <li><a href="https://github.com/mdn/webvr-tests">webvr-tests</a> — hyvin yksinkertaisia esimerkkejä MDN:n WebVR dokumentaation tueksi.</li>
+ <li><a href="https://github.com/facebook/Carmel-Starter-Kit">Carmel starter kit</a> — mukavia yksinkertaisia ja hyvin kommentoituja esimerkkejä, jotka tulevat Carmel:in, Facebookin WebVR-selaimen mukana.</li>
+ <li><a href="https://webvr.info/samples/">WebVR.info samples</a> — hieman syvemmälle meneviä esimerkkejä lähdekoodeineen</li>
+ <li><a href="https://webvr.rocks/firefox#demos">WebVR.rocks Firefox demos</a> — demottavia esimerkkejä</li>
+ <li><a href="https://aframe.io/">A-Frame homepage</a> — esimerkkejä A-Frame:n käytöstä</li>
+</ul>
+
+<h2 id="Spesifikaatiot">Spesifikaatiot</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>Määrittää <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>Alkuperäinen</td>
+ </tr>
+ </tbody>
+</table>
+
+<h2 id="Selainyhteensopivuus">Selainyhteensopivuus</h2>
+
+<p>{{CompatibilityTable}}</p>
+
+<table class="compat-table">
+ <tbody>
+ <tr>
+ <th>Ominaisuus</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>Perus</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 -laajennukset</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>
+
+<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>{{CompatNo}}</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>
+
+<p>[1] API käytettävissä (Available) kaikilla alustoilla lipulla, mutta tällä hetkellä toimii ainoastaan kokeellisessa työpöytäversiossa (<a href="https://webvr.info/get-chrome/">experimental version of Chrome)</a> (muut versiot eivät palauta yhtään laitetta metodia {{domxref("Navigator.getVRDisplays()")}} kutsuttaessa).</p>
+
+<p>[2] Tällä hetkellä ainoastaan Windows ja Mac OSX tuki on oletuksena päällä.</p>
+
+<p>[3] Nyt ainoastaan laitteella Google Daydream.</p>
+
+<p>[4] Päällä Firefox Nightly ja Beta -versioissa 55 ja uudempi. Käytetään valinnalla <code>dom.gamepad-extensions.enabled</code>.</p>
+
+<h2 id="Katso_myös">Katso myös</h2>
+
+<ul>
+ <li><a href="https://vr.mozilla.org">vr.mozilla.org</a> — Mozillan WebVR:n aloitussivu, jossa on demoja, apuohjelmia ja muuta tietoa.</li>
+ <li><a href="https://aframe.io/">A-Frame</a> — Open source web-sovelluskehys VR-kokemuksien rakentamiseen.</li>
+ <li><a href="https://webvr.info">webvr.info</a> — Ajantasaista tietoa WebVR:stä, selaintuesta ja yhteisöstä.</li>
+ <li><a href="http://mozvr.com/">MozVr.com</a> — Demoja, latauslinkkejä ja muuta Mozillan VR-ryhmän tarjoamia resursseja.</li>
+ <li><a href="https://github.com/MozVR/vr-web-examples/tree/master/threejs-vr-boilerplate">threejs-vr-boilerplate</a> — Käyttökelpoinen mallipohja, jonka päälle WebVR-sovellus on helppo rakentaa.</li>
+ <li><a href="https://github.com/googlevr/webvr-polyfill/">Web VR polyfill</a> — JavaScript -toteutus WebVR:n toiminnoista.</li>
+</ul>
diff --git a/files/fi/web/api/webvr_api/using_the_webvr_api/index.html b/files/fi/web/api/webvr_api/using_the_webvr_api/index.html
new file mode 100644
index 0000000000..b4cf17e315
--- /dev/null
+++ b/files/fi/web/api/webvr_api/using_the_webvr_api/index.html
@@ -0,0 +1,438 @@
+---
+title: Using the WebVR API
+slug: Web/API/WebVR_API/Using_the_WebVR_API
+translation_of: Web/API/WebVR_API/Using_the_WebVR_API
+---
+<div>{{APIRef("WebVR API")}}</div>
+
+<p class="summary">WebVR API on hieno lisä webkehittäjän työkaluihin. Sen avulla WebGL- näkymä (scene) voidaan esittää Oculus Riftin and HTC Viven tapaisissa VR-näytöissä. Mutta miten pääset alkuun VR appsien tekemiseen webbiin? Tämä juttu opastaa sinut perusteisiin.</p>
+
+<div class="note">
+<p><strong>Huom</strong>: WebVR APIn vakain versio — 1.1 — on vasta implementoitu Firefox 55:een (Windowsin release-versio, Mac OS X :ssa vain 'Nightly'), ja sen saa myös Chrome:en käytettäessä Google Daydream -laitteistoa. Speksistä on myös tuoreempi versio — 2.0 — mutta se on kovin keskeneräinen. Lisätietoja viimeisimmästä speksistä löytyy linkistä <a href="https://w3c.github.io/webvr/">WebVR Spec Version List</a>.</p>
+</div>
+
+<h2 id="Aloitus">Aloitus</h2>
+
+<p>Päästäksesi alkuun tarvitset:</p>
+
+<ul>
+ <li>Tuetun VR-laitteiston.
+ <ul>
+ <li>halvin vaihtoehto on mobiililaite, tuettu selain, ja silmikkonäyttö, johon mobiililaitteen saa asetettua (esim. Google Cardboard). Tämä ei vastaa käyttökokemukseltaan aivan tarkoitukseen suunniteltua laitteistoa, mutta selviät ostamatta teho-PC:tä tai erityistä VR-näyttöä.</li>
+ <li>VR-laitteisto saattaa olla hinnakas, mutta sillä saadaan parempi käyttökokemus. Parhaiten WebVR-yhteensopivia laitteita ovat tällä hetkellä HTC VIVE ja The Oculus Rift. <a href="https://webvr.info/">webvr.info</a> :n etusivulla on lisätietoa laitteiden tarjonnasta ja selaintuesta niille.</li>
+ </ul>
+ </li>
+ <li>Mahdollisesti vaaditun riittävän tehokkaan tetokoneen VR-näkymien prosessointiin ja näyttämiseen VR-laitteistollesi. Koneen speksejä varten tutki sen VR-laitteiston vaatimuksia (e.g. <a href="https://www.vive.com/us/ready/">VIVE READY Computers</a>), jonka aiot hankkia.</li>
+ <li>Tuettu selain tulee olla asennettu — uusin <a href="https://www.mozilla.org/en-US/firefox/channel/desktop/">Firefox Nightly</a> tai <a href="https://www.google.com/chrome/index.html">Chrome</a> ovat parhaat vaihtoehdot tällä hetkellä, PC:lle tai mobiiliin.</li>
+</ul>
+
+<p>Kun laitteisto ja ohjelmistot on asennettu, voit testata, toimiiko kokoonpanosi WebVR:n kanssa tästä linkistä - <a href="https://mdn.github.io/webvr-tests/aframe-demo/">simple A-Frame demo</a>, ja näet, saadaanko näkymä näkyviin ja pääsetkö VR-moodiin oikean alareunan painikkeella.</p>
+
+<p><a href="https://aframe.io/">A-Frame</a> on paras vaihtoehto päästä tekemään nopeasti WebVR-yhteensopivia 3D-näkymiä, ilman että tarvitsee ymmärtää rivikaupalla uutta JavaScript -koodia. Se ei kuitenkaan opeta, kuinka raaka WebVR API toimii ja siihen paneudummekin seuraavaksi.</p>
+
+<h2 id="Demon_esittely">Demon esittely</h2>
+
+<p>WebVR API :n toiminnan esdittelemiseksi tutustumme puhtaasti webgl:ää sisältävään esimerkkiimme, joka näyttää vähän tältä:</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><strong>Huom</strong>: Demon lähdekoodi - <a href="https://github.com/mdn/webvr-tests/tree/master/raw-webgl-example">source code</a> - löytyy GitHubista ja livelinkki siihen on tässä: <a href="https://mdn.github.io/webvr-tests/raw-webgl-example/">view it live</a>.</p>
+</div>
+
+<div class="note">
+<p><strong>Huom</strong>: Ellei WebVR ei ala toimia selaimessa, varmista, että sitä ajetaan grafiikkakortin kautta. Esimerkiksi NVIDIA :lla sen omassa ohjauspaneelissa on pikavalikkovalinta <em><strong>Firefox</strong></em>, josta valitaan <em>Run with graphics processor &gt; High-performance NVIDIA processor</em>.</p>
+</div>
+
+<p>Demossa on kaikkien WebGL-demojen äiti — pyörivä  3D-kuutio. Toteutimme sen puhtaasti <a href="/en-US/docs/Web/API/WebGL_API">WebGL API</a> :n koodilla. Tässä ei käsitellä perus JavaScriptiä tai WebGL:ää, vaan pelkästään WebVR osia.</p>
+
+<p>Demosta löytyy myös:</p>
+
+<ul>
+ <li>Painike, jolla näkymä saadaan päälle VR-näyttöön (ja pois).</li>
+ <li>Painike, joka näyttää (ja piilottaa) VR:n 'pose' -tiedot - eli silmikon sijainnin ja suunnan - reaaliajassa.</li>
+</ul>
+
+<p>Kun tutustut lähdekoodin päätiedostoon -<a href="https://github.com/mdn/webvr-tests/blob/master/raw-webgl-example/webgl-demo.js"> main JavaScript file</a> - löydät WebVR-osat koodista kommenttien "WebVR" tekstien avulla.</p>
+
+<div class="note">
+<p><strong>Huom</strong>: JavaScriptin ja WebGL:n perusteista lisätietoja löytyy tutoriaaleista <a href="/en-US/docs/Learn/JavaScript">JavaScript learning material</a> ja <a href="/en-US/docs/Web/API/WebGL_API/Tutorial">WebGL Tutorial</a>.</p>
+</div>
+
+<h2 id="Miten_se_toimii">Miten se toimii?</h2>
+
+<p>Tässä vaiheessa katsotaan koodin WebVR-osien toiminta.</p>
+
+<p>Tyypillinen (yksinkertainen) WebVR sovellus toimii näin:</p>
+
+<ol>
+ <li>{{domxref("Navigator.getVRDisplays()")}} hakee viittauksen VR-näyttöösi.</li>
+ <li>{{domxref("VRDisplay.requestPresent()")}} :ä käytetään käynnistämään esittäminen VR-näytölle.</li>
+ <li>WebVR:n omaa {{domxref("VRDisplay.requestAnimationFrame()")}} -metodia käytetään suorittamaan sovelluksen renderöintisilmukkaa näytölle sopivalla virkistystaajuudella.</li>
+ <li>Renderöintisilmukassa haet ruudun näyttämiseen vaaditun datan ({{domxref("VRDisplay.getFrameData()")}}), piirrät näytettävän skenen kahdesti — molemmille silmille — ja toimitat renderöidyn näkymän näytölle käyttäjälle näytettäväksi metodilla ({{domxref("VRDisplay.submitFrame()")}}).</li>
+</ol>
+
+<p>Alla olevissa kappaleissa tutustutaan webgl-demoihimme yksityiskohtaisemmin ja nähdään tarkemmin, missä edellä mainittuja ominaisuuksia käytetään.</p>
+
+<h3 id="Aloitetaan_muuttujilla">Aloitetaan muuttujilla</h3>
+
+<p>Ensimmäinen esimerkki WebVR:n käytöstä näkyy alla olevassa koodissa:</p>
+
+<pre class="brush: js">// 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>Lyhyet selitykset ovat siis tarpeen:</p>
+
+<ul>
+ <li><code>frameData</code> sisältää {{domxref("VRFrameData")}} olion, joka on tehty {{domxref("VRFrameData.VRFrameData", "VRFrameData()")}} -muodostimella. Tämä on alkuaan tyhjä, mutta sisältää myöhemmin VR-näytölle näytettävien ruutujen renderöintiin tarvittavat tiedot, ja ne päivitetään aina renderöintisilmukassa uudelleen.</li>
+ <li><code>vrDisplay</code> on alkuun alustamaton, mutta siinä on myöhemmin viittaus VR-silmikkoomme ({{domxref("VRDisplay")}} — joka on API:n keskeinen ohjattava kohde).</li>
+ <li><code>btn</code> ja <code>poseStatsBtn</code> viittaavat sovelluksen ohjaamiseen käytettyihin painikkeisiin.</li>
+ <li><code>normalSceneFrame</code> ja <code>vrSceneFrame</code> ovat aluksi alustamattomia, mutta myöhemmin viittaavat {{domxref("Window.requestAnimationFrame()")}} ja {{domxref("VRDisplay.requestAnimationFrame()")}} metodeihin — nämä alustavat normaalin ja WebVR-spesifisen renderöintisilmukan suorittamisen; niiden välisestä erosta selitetään hieman jäljempänä.</li>
+ <li>Muut muuttujat sisältävät viittauksia käyttöliittymän oikeassa alakulmassa näkyvän VR-sijainnin ja suuntauksen näyttävän tietolaatikon eri osiin.</li>
+</ul>
+
+<h3 id="VR-näytön_hakeminen">VR-näytön hakeminen</h3>
+
+<p>Koodimme tärkeimpiä metodeja on <code>start()</code> — tämä suoritetaan, kun sivun body-osa on ladattu valmiiksi:</p>
+
+<pre class="brush: js">// start
+//
+// Called when the body has loaded is created to get the ball rolling.
+
+document.body.onload = start;</pre>
+
+<p>Aluksi<code>start()</code> hakee webbisivumme - <a href="https://github.com/mdn/webvr-tests/blob/master/raw-webgl-example/index.html">our HTML</a> - {{htmlelement("canvas")}} -osaan renderöitävään 3D-grafiikkaan tarvitun WebGL -ympäristön. Sitten tarkistetaan, että <code>gl</code> -ympäristö on käytettävissä — jos on, suoritetaan muutama metodi näytettävän skenen alustamiseksi.</p>
+
+<pre class="brush: js">function start() {
+ canvas = document.getElementById("glcanvas");
+
+ initWebGL(canvas); // Initialize the GL context
+
+ // WebGL setup code here</pre>
+
+<p>Seuraavaksi aloitetaan varsinainen näyttöprosessi. Siinä asetetaan canvas-elementti näyttämään selaimen koko näytettävä ala ja suorittamalla renderöintisilmukka(<code>drawScene()</code>) ensimmäisen kerran. Tässä siis ei-WebVR osuus— se normaali renderöintisilmukka.</p>
+
+<pre class="brush: js"> // 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>Seuraavaksi tulee sitten ensimmäinen pala WebVR-koodia. Aluksi tarkistetaan, onko VR-näyttöjä edes käytettävissä {{domxref("Navigator.getVRDisplays")}}  — tästä alkaa API:n käyttö ja tämä on hyvä paikka WebVR:n ominaisuuksien tarkistamiseen. Koodilohkon lopussa (<code>else</code> -osassa) näkyy, että ellei sopivia näyttöjä ole, näytetään viesti, ettei selain tue WebVR 1.1 :ää.</p>
+
+<pre class="brush: js"> // WebVR: Check to see if WebVR is supported
+ if(navigator.getVRDisplays) {
+ console.log('WebVR 1.1 supported');</pre>
+
+<p><code>if() { ... }</code> koodilohkossa suoritetaan {{domxref("Navigator.getVRDisplays()")}} metodi. Tämä palauttaa <a href="/en-US/docs/Web/JavaScript/Guide/Using_promises">promise</a>-olion, jonka sisältönä on lista tietokoneeseen kytketyistä VR-näytöistä. Se on tyhjä, ellei näyttöjä ole..</p>
+
+<pre class="brush: js"> // Then get the displays attached to the computer
+ navigator.getVRDisplays().then(function(displays) {</pre>
+
+<p>Promise-olion <code>then()</code> -lohkossa tarkistetaan, että listan pituus on suurempi kuin 0; näin ollessa asetetaan <code>vrDisplay</code> -muuttujamme arvoksi listan ensimmäisen -indeksistä 0 löytyvän - alkion arvo. <code>vrDisplay</code> sisältää nyt {{domxref("VRDisplay")}} olion, joka vastaa laitteeseen liitettyä näyttöä!</p>
+
+<pre class="brush: js"> // If a display is available, use it to present the scene
+ if(displays.length &gt; 0) {
+ vrDisplay = displays[0];
+ console.log('Display found');</pre>
+
+<div class="note">
+<p><strong>Huom</strong>: On epätavallista, että tietokoneeseen olisi kytketty useita VR-näyttöjä, joten tätä yksinkertaista demoa varten usean näytön vaihtoehtoa ei huomioida.</p>
+</div>
+
+<h3 id="VR-esityksen_käynnistys_ja_pysäytys">VR-esityksen käynnistys ja pysäytys</h3>
+
+<p>Nyt kun käytössä on {{domxref("VRDisplay")}} olio, sen avulla voidaan tehdä useita juttuja. Seuraavaksi haluamme käynnistää toiminnot WebGL-sisällön näyttämisen aloittamiseksi ja lopettamiseksi.</p>
+
+<p>Jatkaaksemme edellisestä koodilohkosta, lisäämme käynnistys/pysäytys -painikkeeseemme (<code>btn</code>) tapahtumankuuntelijan (event listener) — ja painiketta klikattaessa halutaan tarkistaa, joko esitys näytölle on käynnissä (toteutus tälle on hieman kökkö ja perustuu painikkeen tekstin, <code><a href="/en-US/docs/Web/API/Node/textContent">textContent</a></code>, tutkimiseen).</p>
+
+<p>Ellei esitys näyttöön ole vielä käynnissä, käytetään {{domxref("VRDisplay.requestPresent()")}} -metodia pyytämään selainta käynnistämään esitys näytölle. Parametrinä metodille annetaan lista {{domxref("VRLayerInit")}} olioita, jotka vastaavat näytettäväksi haluttuja näyttötasoja.</p>
+
+<p>Koska tällä hetkellä on mahdollista esittää vain yksi näyttötaso, ja ainoa vaadittu olion jäsen on {{domxref("VRLayerInit.source")}} -ominaisuus (joka viittaa tuossa näyttötasossa näytettäväksi tarkoitettuun {{htmlelement("canvas")}} :iin; annetaan muille parametreille järkevät oletusarvot — kts. {{domxref("VRLayerInit.leftBounds", "leftBounds")}} ja {{domxref("VRLayerInit.rightBounds", "rightBounds")}})), parametri on yksinkertaisesti [{ source: canvas }].</p>
+
+<p><code>requestPresent()</code> palauttaa promise-olion, joka saa sisällön, kun esittäminen käynnistyy onnistuneesti.</p>
+
+<pre class="brush: js"> // 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>Nyt kun esittämispyyntö oli ok, halutaan seuraavaksi asettaa renderöintisisältö esitettäväksi VR-näytölle. Aivan ensimmäiseksi asetetaan canvas samankokoiseksi VR-näytön näyttöalueen kanssa. Tämä onnistuu hakemalla {{domxref("VREyeParameters")}} molemmille silmille käyttäen metodia {{domxref("VRDisplay.getEyeParameters()")}}.</p>
+
+<p>Sen jälkeen lasketaan yksinkertaisesti VR-näytön kokonaisala silmän ominaisuuksien {{domxref("VREyeParameters.renderWidth")}} ja {{domxref("VREyeParameters.renderHeight")}} avulla.</p>
+
+<pre class="brush: js"> // 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>Seuraavaksi pysäytetään renderöintisilmukka {{domxref("Window.cancelAnimationFrame()", "cancel the animation loop")}}, joka aiemmin käynnistyi {{domxref("Window.requestAnimationFrame()")}} kutsulla <code>drawScene()</code> -metodista ja sen sijaan kutsutaan<code>drawVRScene()</code>:ä. Tämä metodi renderöi saman skenen kuin aiempikin käyttäen nyt VR-kohtaisia temppuja. Tämän renderöintisilmukan hallinta on nyt vastaavalla WebVR-versiolla, {{domxref("VRDisplay.requestAnimationFrame")}} -metodilla.</p>
+
+<pre class="brush: js"> // stop the normal presentation, and start the vr presentation
+ window.cancelAnimationFrame(normalSceneFrame);
+ drawVRScene();</pre>
+
+<p>Lopuksi päivitetään painikkeen teksti, jolloin seuraavalla klikkauskerralla painike tuleekin pysäyttämään esityksen VR-näytöllä.</p>
+
+<pre class="brush: js"> btn.textContent = 'Exit VR display';
+ });</pre>
+
+<p><br>
+ VR-näytöllä esittämisen pysäyttämiseksi painikkeen seuraavalla klikkauksella kutsutaan {{domxref("VRDisplay.exitPresent()")}} -metodia. Painikkeen teksti vaihdetaan taas toiseksi ja <code>requestAnimationFrame</code> -kutsut vaihdetaan taas keskenään. Tästä näkyy, että käytetään metodia {{domxref("VRDisplay.cancelAnimationFrame")}} VR-renderöintisilmukan pysäyttämiseen ja normaalin skenen renderöinti käynnistyy <code>drawScene()</code>-metodilla.</p>
+
+<pre class="brush: js"> } 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>Kun esittäminen käynnistyy, selaimessa näkyy stereoskooppinen näkymä:</p>
+
+<p><img alt="" src="https://mdn.mozillademos.org/files/15123/Capture2.png" style="display: block; margin: 0 auto;"></p>
+
+<p>Seuraavasta opitaan, miten stereonäkymä varsinaisesti tehdään.</p>
+
+<h3 id="Miksi_WebVRllä_on_oma_requestAnimationFrame()">Miksi WebVR:llä on oma requestAnimationFrame()?</h3>
+
+<p>Tämä on hyvä kysymys. Perussyy on sulava renderöinti VR-näytössä, joka saadaan aikaan käyttämällä VR-näytön omaa näytönpäivitysnopeutta eikä tietokoneen. VR-näytön päivitysnopeudet ovat tietokonetta suurempia, yleisesti jopa  90fps. Tämä poikkeaa tietokoneen peruspäivitysnopeudesta.</p>
+
+<p>Huomaa, että kun VR-näytössä ei esitetä, {{domxref("VRDisplay.requestAnimationFrame")}} toimii identtisesti {{domxref("Window.requestAnimationFrame")}}:n kanssa, joten halutessasi voisit käyttää vain yhtä renderöintisilmukkaa tekemämme sovelluksen kahden silmukan sijaan. Sovelluksessa käytetään kahta, koska VR-esityksen ollessa päällä halutaan tehdä hieman eri asioita kuin ilman sitä, ja nämä halutaan selkeyden vuoksi erottaa.</p>
+
+<h3 id="Renderöinti_ja_näyttäminen">Renderöinti ja näyttäminen</h3>
+
+<p>Tässä vaiheessa on nähty kaikki koodi, mikä tarvitaan VR-laitteiston hakemiseen, skenen näyttöpyynnön lähettämiseen ja renderöintisilmukan käynnistämiseen. Seuraavaksi kurkataan renderöintisilmukan sisälle ja selitetään, miten sen WebVR-spesifiset osat toimivat.</p>
+
+<p>Aluksi tarkastellaan renderöintisilmukkametodin  — <code>drawVRScene()</code> määrittelyä. Ensimmäinen tehtävä on kutsua {{domxref("VRDisplay.requestAnimationFrame()")}} -metodia silmukan toiston jatkamiseksi ensimmäisen kutsukerran jälkeen (tämä tehtiin aiemmin koodissa, kun VR-näytölle esittäminen aloitettiin). Tämä metodikutsu asetetaan globaalin <code>vrSceneFrame</code> -muuttujan arvoksi, jotta silmukka saadaan keskeytettyä {{domxref("VRDisplay.cancelAnimationFrame()")}} -metodilla, kun VR-esitys loppuu.</p>
+
+<pre class="brush: js">function drawVRScene() {
+ // WebVR: Request the next frame of the animation
+ vrSceneFrame = vrDisplay.requestAnimationFrame(drawVRScene);</pre>
+
+<p>Seuraavaksi kutsutaan metodia {{domxref("VRDisplay.getFrameData()")}}, joka saa parametriksi muuttujanimen, johon ruudun tiedot halutaan. Tämähän alustettiin jo aiemmin nimellä  <code>frameData</code>. Metodin suorittamisen jälkeen tässä muuttujassa on tarpeelliset tiedot seuraavan ruudun renderöintiin VR -laitteelle pakattuna {{domxref("VRFrameData")}} -olioon. Mukana on tieto projektio- ja näkymämatriiseista, joiden avulla skene saadaan renderöityä oikein vasemmalle ja oikealle silmälle sekä ajantasainen {{domxref("VRPose")}} -olio, jossa on mm. VR-näytön suunta- ja sijaintitiedot.</p>
+
+<p>Tätä tulee kutsua joka ruudun kohdalla, jotta renderöity näkymä olisi ajantasainen.</p>
+
+<pre class="brush: js"> // Populate frameData with the data of the next frame to display
+ vrDisplay.getFrameData(frameData);</pre>
+
+<p>Seuraavaksi haetaan senhetkinen {{domxref("VRPose")}} ominaisuudesta {{domxref("VRFrameData.pose")}}, tallennetaan sijainti ja suunta myöhempää käyttöä varten ja lähetetään pose-tieto näytettäväksi sivun tilatietoruutuun, siis mikäli <code>poseStatsDisplayed</code> -muuttuja on saanut arvon true.</p>
+
+<pre class="brush: js"> // 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>  Seuraavaksi canvas:in sisältö tyhjennetään ennen uuden piirron aloittamista, jotta seuraava ruutu piirrettäisiin puhtaalle pohjalle, eikä aiempi ruutu olisi alla sotkemassa:</p>
+
+<pre class="brush: js"> // Clear the canvas before we start drawing on it.
+
+ gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);</pre>
+
+<p>Nyt renderöidään molempien silmien näkymä. Aluksi tarvitaan projektion ja näkymän sijainti renderöintiä varten. Nämä ovat {{domxref("WebGLUniformLocation")}} -olioita, jotka on luotu {{domxref("WebGLRenderingContext.getUniformLocation()")}} -metodilla käyttäen parametreinä shader-ohjelman tunnusta ja nimitunnistetta.</p>
+
+<pre class="brush: js"> // 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>Seuraava renderöintivaihe sisältää:</p>
+
+<ul>
+ <li>Viewportin koon määrittäminen vasemmalle silmälle  {{domxref("WebGLRenderingContext.viewport")}} -metodilla — tämä on tietenkin canvas:in leveyden ensimmäinen puolikas kertaa sen täysi korkeus.</li>
+ <li>Vasemmalle silmälle renderöintiin käytettävät näkymä- ja projektiomatriisien arvojen määrittäminen — tämä tehdään käyttämällä {{domxref("WebGLRenderingContext.uniformMatrix", "WebGLRenderingContext.uniformMatrix4fv")}} -metodia, joka saa parametrikseen yllä haetut sijaintitiedot ja {{domxref("VRFrameData")}} -oliolta saatavat vasemman puolen matriisit.</li>
+ <li><code>drawGeometry()</code> funktion suorittaminen, joka suorittaa varsinaisen skenen renderöinnin — ja edellisistä vaiheista johtuen siis vain vasemmalle silmälle.</li>
+</ul>
+
+<pre class="brush: js"> // 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>Ja sama oikealle silmälle:</p>
+
+<pre class="brush: js"> // 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>Seuraavaksi määritellään<code>drawGeometry()</code> funktio. Suurin osa siitä koostuu tavallisesta WebGL -koodista, jolla saadaan piirrettyä 3D-kuutio. WebVR-spesifisiä osia löytyy <code>mvTranslate()</code> ja<code>mvRotate()</code> funktiokutsuista — ne välittävät matriisit WebGL-ohjelmalle, joka määrittää sen hetkiselle ruudulle kuution sijainnin ja kierron.</p>
+
+<p>Kuten huomaat, näitä arvoja muokataan {{domxref("VRPose")}} -oliolta saaduilla VR-näytön sijainti- (<code>curPos</code>) ja kiertotiedoilla (<code>curOrient</code>). Sen seurauksena esimerkiksi päätä vasemmalle käännettäessä kuvassa näkyvä kuutio siirtyy aivan odotetustikin oikealle, kun  x-sijaintitieto (<code>curPos[0]</code>) ja y-kiertotieto (<code>[curOrient[1]</code>) lisätään x-translaatioarvoon.</p>
+
+<p>Tämä on 'quick and dirty' -tapa käyttää VR pose-tietoa, mutta se näyttänee kuitenkin perusidean.</p>
+
+<pre class="brush: js"> 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>Seuraava koodipalanen ei liity mitenkään WebVR:ään — siinä vain kierretään kuutiota joka ruudun osalta:</p>
+
+<pre class="brush: js"> // 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>Renderöintisilmukan viimeiseen osaan kuuluu {{domxref("VRDisplay.submitFrame()")}} -metodin kutsuminen — kaikki tarpeellinen on nyt tehty ja näyttö on renderöity {{htmlelement("canvas")}} :iin, tämä metodi sitten toimittaa ruudun VR-näytölle, jolloin se ruutu näkyy myös siinä.</p>
+
+<pre class="brush: js"> // WebVR: Indicate that we are ready to present the rendered frame to the VR display
+ vrDisplay.submitFrame();
+}</pre>
+
+<h3 id="Pose_(sijainti_kierto_ym.)_-tiedon_näyttäminen">Pose (sijainti, kierto, ym.) -tiedon näyttäminen</h3>
+
+<p>Tässä osassa tutustutaan <code>displayPoseStats()</code> -funktioon, joka näyttää kunkin ruudun päivitetyt pose-tiedot. Kyseinen funktio on melko yksinkertainen.</p>
+
+<p>Aluksi tallennetaan {{domxref("VRPose")}}-oliolta saadut kuusi ominaisuutta omiin muuttujiin — ne ovat tyyppiä {{domxref("Float32Array")}}.</p>
+
+<pre class="brush: js">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>Sitten tiedot kirjoitetaan tietolaatikkoon ja päivitetään ne joka ruudun kohdalla. Arvot on pyöristetty <code><a href="/en-US/docs/Web/JavaScript/Reference/Global_Objects/Number/toFixed">toFixed()</a></code> -metodilla luettavuuden vuoksi.</p>
+
+<p>Huomaa ehtolause lineaarisen ja kulmakiihtyvyyden vektorien arvojen tarkastamisessa - siinä varmistetaan ennen näyttämistä, että arvot on tosiaan saatu luettua. Useimmilta VR-laitteistolta näitä arvoja ei vielä saada, joten ilman tarkistamista seuraisi virhetoiminta (ellei arvoja saada, vektorien arvoksi tulee <code>null</code>).</p>
+
+<pre class="brush: js"> 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_-tapahtumat">WebVR -tapahtumat</h2>
+
+<p>The WebVR spesifikaatiossa on määritetty useita liipaistavia tapahtumia (event), ja näin koodilla voidaan reagoida VR-näytön tilan muutoksiin (vrt. <a href="/en-US/docs/Web/API/WebVR_API#Window_events">Window events</a>). Esimerkiksi:</p>
+
+<ul>
+ <li>{{event("vrdisplaypresentchange")}} — Liipaistaan, kun VR-näytön esittämistila muuttuu — esim. esitetään -&gt; ei esitetä, ja päinvastoin.</li>
+ <li>{{event("vrdisplayconnect")}} — Saadaan, kun yhteensopiva VR-näyttö on liitetty tietokoneeseen.</li>
+ <li>{{event("vrdisplaydisconnect")}} — Tapahtuma VR-näytön irrotuksesta.</li>
+</ul>
+
+<p>Demossa on seuraava esimerkki tapahtumista:</p>
+
+<pre class="brush: js">window.addEventListener('vrdisplaypresentchange', function(e) {
+ console.log('Display ' + e.display.displayId + ' presentation has changed. Reason given: ' + e.reason + '.');
+});</pre>
+
+<p>Kuten näet {{domxref("VRDisplayEvent", "event object")}} tarjoaa kaksi hyödyllistä ominaisuutta — {{domxref("VRDisplayEvent.display")}}, joka viittaa {{domxref("VRDisplay")}} tapahtuman tuottajaan, ja {{domxref("VRDisplayEvent.reason")}}, jossa on selkokielinen syy tapahtumaan.</p>
+
+<p>Tämä on hyvin käyttökelpoinen tapahtuma; sitä voidaan käyttää huomaan yllättävä näytön irrotus, joka estäää tarpeettomat virheviestit ja kertoo tilanteen käyttäjälle. Googlen Webvr.info -esitysdemossa tapahtumaa käytetään suorittamaan <a href="https://github.com/toji/webvr.info/blob/master/samples/03-vr-presentation.html#L174"><code>onVRPresentChange()</code> funktio</a>, joka päivittää käyttöliittymän kontrollit tilannetta vastaaviksi ja muuttaa canvasin kokoa.</p>
+
+<h2 id="Yhteenveto">Yhteenveto</h2>
+
+<p>Tässä artikkelissa kerrottiin hyvin yksinkertaisen WebVR 1.1 sovelluksen tekemisestä, jonka avulla pääset alkuun sovellusten kehittämisessä.</p>