Repository: godotengine/godot
File: drivers/gles3/storage/texture_storage.cpp (C++)

Code before:

		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}
}

void TextureStorage::_clear_render_target(RenderTarget *rt) {
	// there is nothing to clear when DIRECT_TO_SCREEN is used
	if (rt->direct_to_screen) {
		return;
	}

	// Dispose of the cached fbo's and the allocated textures
	for (KeyValue<uint32_t, RenderTarget::RTOverridden::FBOCacheEntry> &E : rt->overridden.fbo_cache) {
		glDeleteTextures(E.value.allocated_textures.size(), E.value.allocated_textures.ptr());
		// Don't delete the current FBO, we'll do that a couple lines down.
		if (E.value.fbo != rt->fbo) {
			glDeleteFramebuffers(1, &E.value.fbo);
		}
	}
	rt->overridden.fbo_cache.clear();

	if (rt->fbo) {
		glDeleteFramebuffers(1, &rt->fbo);
		rt->fbo = 0;
	}

	if (rt->overridden.color.is_null()) {
		if (rt->texture.is_valid()) {
			Texture *tex = get_texture(rt->texture);
			tex->alloc_height = 0;
			tex->alloc_width = 0;
			tex->width = 0;
			tex->height = 0;
			tex->active = false;
			tex->render_target = nullptr;
			tex->is_render_target = false;
		}
	} else {
		Texture *tex = get_texture(rt->overridden.color);
		tex->render_target = nullptr;
		tex->is_render_target = false;
	}

	if (rt->overridden.color.is_valid()) {
		rt->overridden.color = RID();
	} else if (rt->color) {

Review comment (suggestion):
If using multiview, I don't think the backbuffer can be shared with 2D as in 2D the backbuffer is always assumed to be a Texture_2D. We may need to create a separate backbuffer for multiview

@dsnopek How does 2D rendering work in XR when using Multiview? Does it just render to the first view index, or does it require using both views? From my brief look at the shader code and canvas render code it looks like 2D rendering should still just take place on a texture2D

Code after:

		glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);

		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
	}
}
void GLES3::TextureStorage::copy_scene_to_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture) {
	if (rt->backbuffer != 0 && rt->backbuffer_depth != 0) {
		return;
	}

	Config *config = Config::get_singleton();
	bool use_multiview = rt->view_count > 1 && config->multiview_supported;
	GLenum texture_target = use_multiview ? GL_TEXTURE_2D_ARRAY : GL_TEXTURE_2D;
	if (rt->backbuffer_fbo == 0) {
		glGenFramebuffers(1, &rt->backbuffer_fbo);
	}
	glBindFramebuffer(GL_FRAMEBUFFER, rt->backbuffer_fbo);
	if (rt->backbuffer == 0 && uses_screen_texture) {
		glGenTextures(1, &rt->backbuffer);
		glBindTexture(texture_target, rt->backbuffer);
		if (use_multiview) {
			glTexImage3D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, rt->view_count, 0, rt->color_format, rt->color_type, nullptr);
		} else {
			glTexImage2D(texture_target, 0, rt->color_internal_format, rt->size.x, rt->size.y, 0, rt->color_format, rt->color_type, nullptr);
		}

		glTexParameteri(texture_target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
		glTexParameteri(texture_target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
		glTexParameteri(texture_target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
		glTexParameteri(texture_target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
#ifndef IOS_ENABLED
		if (use_multiview) {
			glFramebufferTextureMultiviewOVR(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, rt->backbuffer, 0, 0, rt->view_count);
		} else {
#else
		{
#endif
			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, rt->backbuffer, 0);
		}
	}
	if (rt->backbuffer_depth == 0 && uses_depth_texture) {
		glGenTextures(1, &rt->backbuffer_depth);
		glBindTexture(texture_target, rt->backbuffer_depth);
		if (use_multiview) {
			glTexImage3D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, rt->view_count, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);
		} else {
			glTexImage2D(texture_target, 0, GL_DEPTH_COMPONENT24, rt->size.x, rt->size.y, 0, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT, nullptr);