Skip to content

Commit

Permalink
WebVR multiview sample
Browse files Browse the repository at this point in the history
  • Loading branch information
MortimerGoro committed Sep 21, 2017
1 parent 6c6596f commit 103485f
Show file tree
Hide file tree
Showing 2 changed files with 112 additions and 14 deletions.
64 changes: 59 additions & 5 deletions tests/html/webvr/js/vr-cube-island.js
Expand Up @@ -25,6 +25,27 @@ window.VRCubeIsland = (function () {
"}",
].join("\n");

var cubeIslandVSMultiview = [
"#version 300 es",
"#extension GL_OVR_multiview2 : require",
"#define VIEW_ID gl_ViewID_OVR",
"layout(num_views=2) in;",

"uniform mat4 leftProjectionMat;",
"uniform mat4 leftModelViewMat;",
"uniform mat4 rightProjectionMat;",
"uniform mat4 rightModelViewMat;",
"in vec3 position;",
"in vec2 texCoord;",
"out vec2 vTexCoord;",

"void main() {",
" vTexCoord = texCoord;",
" mat4 m = VIEW_ID == 0u ? (leftProjectionMat * leftModelViewMat) : (rightProjectionMat * rightModelViewMat);",
" gl_Position = m * vec4( position, 1.0 );",
"}",
].join("\n");

var cubeIslandFS = [
"precision mediump float;",
"uniform sampler2D diffuse;",
Expand All @@ -35,6 +56,19 @@ window.VRCubeIsland = (function () {
"}",
].join("\n");

var cubeIslandFSMultiview = [
"#version 300 es",
"precision mediump float;",
"uniform sampler2D diffuse;",
"in vec2 vTexCoord;",
"out vec4 color;",

"void main() {",
" color = texture(diffuse, vTexCoord);",
"}",
].join("\n");


var CubeIsland = function (gl, texture, width, depth) {
this.gl = gl;

Expand All @@ -51,6 +85,15 @@ window.VRCubeIsland = (function () {
});
this.program.link();

this.program_multiview = new WGLUProgram(gl);
this.program_multiview.attachShaderSource(cubeIslandVSMultiview, gl.VERTEX_SHADER);
this.program_multiview.attachShaderSource(cubeIslandFSMultiview, gl.FRAGMENT_SHADER);
this.program_multiview.bindAttribLocation({
position: 0,
texCoord: 1
});
this.program_multiview.link();

this.vertBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();

Expand Down Expand Up @@ -171,14 +214,25 @@ window.VRCubeIsland = (function () {
this.indexCount = cubeIndices.length;
};

CubeIsland.prototype.render = function (projectionMat, modelViewMat, stats) {
CubeIsland.prototype.render = function (projectionMat, modelViewMat, stats, multiview) {
var gl = this.gl;
var program = this.program;

program.use();
if (multiview) {
console.log("render multiview");
program = this.program_multiview;
program.use();
gl.uniformMatrix4fv(program.uniform.leftProjectionMat, false, projectionMat[0]);
gl.uniformMatrix4fv(program.uniform.rightProjectionMat, false, projectionMat[1]);
gl.uniformMatrix4fv(program.uniform.leftModelViewMat, false, modelViewMat[0]);
gl.uniformMatrix4fv(program.uniform.rightModelViewMat, false, modelViewMat[1]);
}
else {
program.use();
gl.uniformMatrix4fv(program.uniform.projectionMat, false, projectionMat);
gl.uniformMatrix4fv(program.uniform.modelViewMat, false, modelViewMat);
}

gl.uniformMatrix4fv(program.uniform.projectionMat, false, projectionMat);
gl.uniformMatrix4fv(program.uniform.modelViewMat, false, modelViewMat);

gl.bindBuffer(gl.ARRAY_BUFFER, this.vertBuffer);
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
Expand All @@ -195,7 +249,7 @@ window.VRCubeIsland = (function () {

gl.drawElements(gl.TRIANGLES, this.indexCount, gl.UNSIGNED_SHORT, 0);

if (stats) {
if (stats && !multiview) {
// To ensure that the FPS counter is visible in VR mode we have to
// render it as part of the scene.
mat4.fromTranslation(this.statsMat, [0, 1.5, -this.depth * 0.5]);
Expand Down
62 changes: 53 additions & 9 deletions tests/html/webvr/room-scale.html
Expand Up @@ -79,6 +79,7 @@
var frameData = null;
var projectionMat = mat4.create();
var viewMat = mat4.create();
var viewMat2 = mat4.create();
var vrPresentButton = null;

// ===================================================
Expand Down Expand Up @@ -132,7 +133,11 @@
// ================================

function onVRRequestPresent () {
vrDisplay.requestPresent([{ source: webglCanvas }]).then(function () {
var attributes = {
depth: true,
multiview: true,
};
vrDisplay.requestPresent([{ source: webglCanvas, attributes: attributes}]).then(function () {
}, function () {
VRSamplesUtil.addError("requestPresent failed.", 2000);
});
Expand Down Expand Up @@ -250,12 +255,16 @@
}
}

function renderSceneView (projection, view, pose) {
cubeIsland.render(projection, view, stats);
function renderSceneView (projection, view, pose, multiview) {
cubeIsland.render(projection, view, stats, multiview);

// For fun, draw a blue cube where the players head would have been if
// we weren't taking the stageParameters into account. It'll start in
// the center of the floor.
if (multiview) {
// TODO: adapt debugGeom for multiview
return;
}
var orientation = pose.orientation;
var position = pose.position;
if (!orientation) { orientation = [0, 0, 0, 1]; }
Expand All @@ -275,13 +284,48 @@
vrDisplay.getFrameData(frameData);

if (vrDisplay.isPresenting) {
gl.viewport(0, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.leftViewMatrix);
renderSceneView(frameData.leftProjectionMatrix, viewMat, frameData.pose);
var views = vrDisplay.getViews ? vrDisplay.getViews() : [];

if (views.length > 0) {
var view = views[0];
gl.enable(gl.SCISSOR_TEST);
for (var i = 0; i < views.length; ++i) {
var view = views[i];
var multiview = view.getAttributes().multiview;
console.log("multiview: " + multiview);
var viewport = view.getViewport();
gl.bindFramebuffer(gl.FRAMEBUFFER, view.framebuffer);
gl.viewport(viewport.x, viewport.y, viewport.width, viewport.height);
gl.scissor(viewport.x, viewport.y, viewport.width, viewport.height);
gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT);
if (multiview) {
var projections = [frameData.leftProjectionMatrix, frameData.rightProjectionMatrix];
getStandingViewMatrix(viewMat, frameData.leftViewMatrix);
getStandingViewMatrix(viewMat2, frameData.rightViewMatrix);
var viewMats = [viewMat, viewMat2];
renderSceneView(projections, viewMats, frameData.pose, /*multiview*/ true);
break;
}
else {
// Direct render to VR framebuffer
getStandingViewMatrix(viewMat, i == 0 ? frameData.leftViewMatrix : frameData.rightViewMatrix);
renderSceneView(i == 0 ? frameData.leftProjectionMatrix : frameData.rightProjectionMatrix, viewMat, frameData.pose);
}

}
gl.disable(gl.SCISSOR_TEST);
}
else {
gl.viewport(0, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.leftViewMatrix);
renderSceneView(frameData.leftProjectionMatrix, viewMat, frameData.pose);

gl.viewport(webglCanvas.width * 0.5, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.rightViewMatrix);
renderSceneView(frameData.rightProjectionMatrix, viewMat, frameData.pose);
}


gl.viewport(webglCanvas.width * 0.5, 0, webglCanvas.width * 0.5, webglCanvas.height);
getStandingViewMatrix(viewMat, frameData.rightViewMatrix);
renderSceneView(frameData.rightProjectionMatrix, viewMat, frameData.pose);

vrDisplay.submitFrame();
} else {
Expand Down

0 comments on commit 103485f

Please sign in to comment.