WebGLMultiview.js 4.4 KB
Newer Older
1 2 3 4
/**
 * @author fernandojsg / http://fernandojsg.com
 */

5
function WebGLMultiview( requested, gl, canvas, extensions, capabilities ) {
6

F
Fernando Serrano 已提交
7
	this.isAvailable = function () {
8

F
Fernando Serrano 已提交
9
		return capabilities.multiview;
10

F
Fernando Serrano 已提交
11
	};
12

F
Fernando Serrano 已提交
13
	this.getMaxViews = function () {
14

F
Fernando Serrano 已提交
15
		return capabilities.maxMultiviewViews;
16

F
Fernando Serrano 已提交
17
	};
18

F
Fernando Serrano 已提交
19
	this.isEnabled = function () {
20

F
Fernando Serrano 已提交
21
		return requested && this.isAvailable();
22

F
Fernando Serrano 已提交
23
	};
24

25 26 27 28 29 30 31 32 33

	if ( requested && ! this.isAvailable() ) {

		console.warn( 'WebGLRenderer: Multiview requested but not supported by the browser' );

	} else if ( requested !== false && this.isAvailable() ) {

		console.info( 'WebGLRenderer: Multiview enabled' );

F
Fernando Serrano 已提交
34
	}
35

F
Fernando Serrano 已提交
36 37
	var numViews = 2; // @todo Based on arrayCamera
	var framebuffer; // multiview framebuffer.
38 39 40 41
	var viewFramebuffer; // single views inside the multiview framebuffer.
	var framebufferWidth = 0;
	var framebufferHeight = 0;

42 43 44 45 46 47
	var texture = {
		color: null,
		depthStencil: null
	};


48
	// @todo Get ArrayCamera
49 50
	this.createMultiviewRenderTargetTexture = function () {

F
Fernando Serrano 已提交
51
		var halfWidth = Math.floor( canvas.width * 0.5 );
52 53 54 55

		framebuffer = gl.createFramebuffer();
		gl.bindFramebuffer( gl.FRAMEBUFFER, framebuffer );

F
Fernando Serrano 已提交
56
		var ext = extensions.get( 'OVR_multiview2' );
57

58 59 60 61
		texture.color = gl.createTexture();
		gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
		gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
		gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
62 63
		gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, halfWidth, canvas.height, numViews, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
		ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, 0, numViews );
64 65 66 67 68

		texture.depthStencil = gl.createTexture();
		gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.depthStencil );
		gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MAG_FILTER, gl.NEAREST );
		gl.texParameteri( gl.TEXTURE_2D_ARRAY, gl.TEXTURE_MIN_FILTER, gl.NEAREST );
69 70
		gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.DEPTH24_STENCIL8, halfWidth, canvas.height, numViews, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null );
		ext.framebufferTextureMultiviewOVR( gl.FRAMEBUFFER, gl.DEPTH_STENCIL_ATTACHMENT, texture.depthStencil, 0, 0, numViews );
71

72 73
		viewFramebuffer = new Array( numViews );
		for ( var viewIndex = 0; viewIndex < numViews; ++ viewIndex ) {
74

75 76
			viewFramebuffer[ viewIndex ] = gl.createFramebuffer();
			gl.bindFramebuffer( gl.FRAMEBUFFER, viewFramebuffer[ viewIndex ] );
77 78
			gl.framebufferTextureLayer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, viewIndex );

F
Fernando Serrano 已提交
79 80
		}

81 82
		framebufferWidth = halfWidth;
		framebufferHeight = canvas.height;
F
Fernando Serrano 已提交
83 84

	};
85

86
	this.bindMultiviewFrameBuffer = function ( camera ) {
87

F
Fernando Serrano 已提交
88 89 90 91
		var width = canvas.width;
		var height = canvas.height;

		if ( camera.isArrayCamera ) {
92

F
Fernando Serrano 已提交
93 94
			// Every camera must have the same size, so we just get the size from the first one
			var bounds = camera.cameras[ 0 ].bounds;
95

F
Fernando Serrano 已提交
96 97 98 99 100 101 102 103
			width *= bounds.z;
			height *= bounds.w;

		}

		if ( framebufferWidth < width || framebufferHeight < height ) {

			console.log( 'WebGLMultiview: Updating multiview FBO with dimensions: ', width, height );
104
			gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
F
Fernando Serrano 已提交
105
			gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, width, height, numViews, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
106
			gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.depthStencil );
F
Fernando Serrano 已提交
107 108 109
			gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.DEPTH24_STENCIL8, width, height, numViews, 0, gl.DEPTH_STENCIL, gl.UNSIGNED_INT_24_8, null );
			framebufferWidth = width;
			framebufferHeight = height;
110

F
Fernando Serrano 已提交
111
		}
112

113 114 115 116
		gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, framebuffer );

	};

117
	this.unbindMultiviewFrameBuffer = function ( camera ) {
118

F
Fernando Serrano 已提交
119
		gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );
120

F
Fernando Serrano 已提交
121
		if ( camera.isArrayCamera ) {
122

F
Fernando Serrano 已提交
123
			for ( var i = 0; i < camera.cameras.length; i ++ ) {
124

F
Fernando Serrano 已提交
125
				var bounds = camera.cameras[ i ].bounds;
126

F
Fernando Serrano 已提交
127 128 129 130
				var x = bounds.x * canvas.width;
				var y = bounds.y * canvas.height;
				var width = bounds.z * canvas.width;
				var height = bounds.w * canvas.height;
131

F
Fernando Serrano 已提交
132 133
				gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffer[ i ] );
				gl.blitFramebuffer( 0, 0, width, height, x, y, x + width, y + height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
134

F
Fernando Serrano 已提交
135
			}
136

F
Fernando Serrano 已提交
137
		} else {
138

F
Fernando Serrano 已提交
139 140
			gl.bindFramebuffer( gl.READ_FRAMEBUFFER, viewFramebuffer[ 0 ] );
			gl.blitFramebuffer( 0, 0, canvas.width, canvas.height, 0, 0, canvas.width, canvas.height, gl.COLOR_BUFFER_BIT, gl.NEAREST );
141

F
Fernando Serrano 已提交
142
		}
143 144 145

	};

146

F
Fernando Serrano 已提交
147
	if ( this.isEnabled() ) {
148

F
Fernando Serrano 已提交
149
		this.createMultiviewRenderTargetTexture();
150

F
Fernando Serrano 已提交
151
	}
152 153 154 155

}

export { WebGLMultiview };