WebGLMultiview.js 4.4 KB
Newer Older
1
function WebGLMultiview( requested, gl, canvas, extensions, capabilities ) {
2

F
Fernando Serrano 已提交
3
	this.isAvailable = function () {
4

F
Fernando Serrano 已提交
5
		return capabilities.multiview;
6

F
Fernando Serrano 已提交
7
	};
8

F
Fernando Serrano 已提交
9
	this.getMaxViews = function () {
10

F
Fernando Serrano 已提交
11
		return capabilities.maxMultiviewViews;
12

F
Fernando Serrano 已提交
13
	};
14

F
Fernando Serrano 已提交
15
	this.isEnabled = function () {
16

F
Fernando Serrano 已提交
17
		return requested && this.isAvailable();
18

F
Fernando Serrano 已提交
19
	};
20

21 22 23 24 25 26 27 28 29

	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 已提交
30
	}
31

F
Fernando Serrano 已提交
32 33
	var numViews = 2; // @todo Based on arrayCamera
	var framebuffer; // multiview framebuffer.
34 35 36 37
	var viewFramebuffer; // single views inside the multiview framebuffer.
	var framebufferWidth = 0;
	var framebufferHeight = 0;

38 39 40 41 42 43
	var texture = {
		color: null,
		depthStencil: null
	};


F
Fernando Serrano 已提交
44
  // @todo Get ArrayCamera
45 46
	this.createMultiviewRenderTargetTexture = function () {

F
Fernando Serrano 已提交
47
		var halfWidth = Math.floor( canvas.width * 0.5 );
48 49 50 51

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

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

54 55 56 57
		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 );
58 59
		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 );
60 61 62 63 64

		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 );
65 66
		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 );
67

68 69
		viewFramebuffer = new Array( numViews );
		for ( var viewIndex = 0; viewIndex < numViews; ++ viewIndex ) {
70

71 72
			viewFramebuffer[ viewIndex ] = gl.createFramebuffer();
			gl.bindFramebuffer( gl.FRAMEBUFFER, viewFramebuffer[ viewIndex ] );
73 74
			gl.framebufferTextureLayer( gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture.color, 0, viewIndex );

F
Fernando Serrano 已提交
75 76
		}

77 78
		framebufferWidth = halfWidth;
		framebufferHeight = canvas.height;
F
Fernando Serrano 已提交
79 80

	};
81

82
	this.bindMultiviewFrameBuffer = function ( camera ) {
83

F
Fernando Serrano 已提交
84 85 86 87
		var width = canvas.width;
		var height = canvas.height;

		if ( camera.isArrayCamera ) {
88

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

F
Fernando Serrano 已提交
92 93 94 95 96 97 98 99
			width *= bounds.z;
			height *= bounds.w;

		}

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

			console.log( 'WebGLMultiview: Updating multiview FBO with dimensions: ', width, height );
100
			gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.color );
F
Fernando Serrano 已提交
101
			gl.texImage3D( gl.TEXTURE_2D_ARRAY, 0, gl.RGBA8, width, height, numViews, 0, gl.RGBA, gl.UNSIGNED_BYTE, null );
102
			gl.bindTexture( gl.TEXTURE_2D_ARRAY, texture.depthStencil );
F
Fernando Serrano 已提交
103 104 105
			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;
106

F
Fernando Serrano 已提交
107
		}
108

109 110 111 112
		gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, framebuffer );

	};

113
	this.unbindMultiviewFrameBuffer = function ( camera ) {
114

F
Fernando Serrano 已提交
115
		gl.bindFramebuffer( gl.DRAW_FRAMEBUFFER, null );
116

F
Fernando Serrano 已提交
117
		if ( camera.isArrayCamera ) {
118

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

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

F
Fernando Serrano 已提交
123 124 125 126
				var x = bounds.x * canvas.width;
				var y = bounds.y * canvas.height;
				var width = bounds.z * canvas.width;
				var height = bounds.w * canvas.height;
127

F
Fernando Serrano 已提交
128 129
				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 );
130

F
Fernando Serrano 已提交
131
			}
132

F
Fernando Serrano 已提交
133
		} else {
134

F
Fernando Serrano 已提交
135 136
			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 );
137

F
Fernando Serrano 已提交
138
		}
139 140 141

	};

142

F
Fernando Serrano 已提交
143
	if ( this.isEnabled() ) {
144

F
Fernando Serrano 已提交
145
		this.createMultiviewRenderTargetTexture();
146

F
Fernando Serrano 已提交
147
	}
148 149 150 151

}

export { WebGLMultiview };