Add multiview to the opengl3 driver

This commit is contained in:
David Snopek
2022-09-04 09:56:24 -05:00
parent a8c805be29
commit 398ee08375
24 changed files with 423 additions and 81 deletions

View File

@@ -65,7 +65,7 @@ extern int godot_webxr_get_view_count();
extern int *godot_webxr_get_render_target_size();
extern float *godot_webxr_get_transform_for_eye(int p_eye);
extern float *godot_webxr_get_projection_for_eye(int p_eye);
extern void godot_webxr_commit_for_eye(int p_eye, unsigned int p_destination_fbo);
extern void godot_webxr_commit(unsigned int p_texture);
extern void godot_webxr_sample_controller_data();
extern int godot_webxr_get_controller_count();

View File

@@ -337,20 +337,18 @@ const GodotWebXR = {
return buf;
},
godot_webxr_commit_for_eye__proxy: 'sync',
godot_webxr_commit_for_eye__sig: 'vii',
godot_webxr_commit_for_eye: function (p_eye, p_destination_fbo) {
godot_webxr_commit__proxy: 'sync',
godot_webxr_commit__sig: 'vi',
godot_webxr_commit: function (p_texture) {
if (!GodotWebXR.session || !GodotWebXR.pose) {
return;
}
const view_index = (p_eye === 2 /* ARVRInterface::EYE_RIGHT */) ? 1 : 0;
const glLayer = GodotWebXR.session.renderState.baseLayer;
const view = GodotWebXR.pose.views[view_index];
const viewport = glLayer.getViewport(view);
const views = GodotWebXR.pose.views;
const gl = GodotWebXR.gl;
const framebuffer = GL.framebuffers[p_destination_fbo];
const texture = GL.textures[p_texture];
const orig_framebuffer = gl.getParameter(gl.FRAMEBUFFER_BINDING);
const orig_read_framebuffer = gl.getParameter(gl.READ_FRAMEBUFFER_BINDING);
@@ -359,14 +357,27 @@ const GodotWebXR = {
// Copy from Godot render target into framebuffer from WebXR.
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, framebuffer);
gl.readBuffer(gl.COLOR_ATTACHMENT0);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, glLayer.framebuffer);
for (let i = 0; i < views.length; i++) {
const viewport = glLayer.getViewport(views[i]);
// Flip Y upside down on destination.
gl.blitFramebuffer(0, 0, viewport.width, viewport.height,
viewport.x, viewport.height, viewport.width, viewport.y,
gl.COLOR_BUFFER_BIT, gl.NEAREST);
const read_fbo = gl.createFramebuffer();
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, read_fbo);
if (views.length > 1) {
gl.framebufferTextureLayer(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, texture, 0, i);
} else {
gl.framebufferTexture2D(gl.READ_FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, texture, 0);
}
gl.readBuffer(gl.COLOR_ATTACHMENT0);
gl.bindFramebuffer(gl.DRAW_FRAMEBUFFER, glLayer.framebuffer);
// Flip Y upside down on destination.
gl.blitFramebuffer(0, 0, viewport.width, viewport.height,
viewport.x, viewport.y + viewport.height, viewport.x + viewport.width, viewport.y,
gl.COLOR_BUFFER_BIT, gl.NEAREST);
gl.bindFramebuffer(gl.READ_FRAMEBUFFER, null);
gl.deleteFramebuffer(read_fbo);
}
// Restore state.
gl.bindFramebuffer(gl.FRAMEBUFFER, orig_framebuffer);

View File

@@ -415,8 +415,7 @@ Vector<BlitToScreen> WebXRInterfaceJS::post_draw_viewport(RID p_render_target, c
GLES3::RenderTarget *rt = texture_storage->get_render_target(p_render_target);
// @todo Support multiple eyes!
godot_webxr_commit_for_eye(1, rt->fbo);
godot_webxr_commit(rt->color);
return blit_to_screen;
};