Pārlūkot izejas kodu

Merge pull request #72361 from the-brickster/master

Incorporating the availability of screen and depth textures for the GLES3 backend
Yuri Sizov 2 gadi atpakaļ
vecāks
revīzija
fe0949e950

+ 22 - 0
drivers/gles3/rasterizer_scene_gles3.cpp

@@ -1994,6 +1994,28 @@ void RasterizerSceneGLES3::render_scene(const Ref<RenderSceneBuffers> &p_render_
 		_draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier, p_camera_data->view_count > 1, flip_y);
 	}
 
+	if (scene_state.used_screen_texture || scene_state.used_depth_texture) {
+		texture_storage->copy_scene_to_backbuffer(rt, scene_state.used_screen_texture, scene_state.used_depth_texture);
+		glBindFramebuffer(GL_READ_FRAMEBUFFER, rt->fbo);
+		glReadBuffer(GL_COLOR_ATTACHMENT0);
+		glBindFramebuffer(GL_DRAW_FRAMEBUFFER, rt->backbuffer_fbo);
+		if (scene_state.used_screen_texture) {
+			glBlitFramebuffer(0, 0, rt->size.x, rt->size.y,
+					0, 0, rt->size.x, rt->size.y,
+					GL_COLOR_BUFFER_BIT, GL_NEAREST);
+			glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 5);
+			glBindTexture(GL_TEXTURE_2D, rt->backbuffer);
+		}
+		if (scene_state.used_depth_texture) {
+			glBlitFramebuffer(0, 0, rt->size.x, rt->size.y,
+					0, 0, rt->size.x, rt->size.y,
+					GL_DEPTH_BUFFER_BIT, GL_NEAREST);
+			glActiveTexture(GL_TEXTURE0 + config->max_texture_image_units - 6);
+			glBindTexture(GL_TEXTURE_2D, rt->backbuffer_depth);
+		}
+		glBindFramebuffer(GL_FRAMEBUFFER, rt->fbo);
+	}
+
 	RENDER_TIMESTAMP("Render 3D Transparent Pass");
 	glEnable(GL_BLEND);
 

+ 61 - 0
drivers/gles3/storage/texture_storage.cpp

@@ -1782,7 +1782,64 @@ void TextureStorage::_create_render_target_backbuffer(RenderTarget *rt) {
 		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);
+		}
+		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_DEPTH_ATTACHMENT, rt->backbuffer_depth, 0, 0, rt->view_count);
+		} else {
+#else
+		{
+#endif
+			glFramebufferTexture2D(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_TEXTURE_2D, rt->backbuffer_depth, 0);
+		}
+	}
+}
 void TextureStorage::_clear_render_target(RenderTarget *rt) {
 	// there is nothing to clear when DIRECT_TO_SCREEN is used
 	if (rt->direct_to_screen) {
@@ -1848,6 +1905,10 @@ void TextureStorage::_clear_render_target(RenderTarget *rt) {
 		rt->backbuffer = 0;
 		rt->backbuffer_fbo = 0;
 	}
+	if (rt->backbuffer_depth != 0) {
+		glDeleteTextures(1, &rt->backbuffer_depth);
+		rt->backbuffer_depth = 0;
+	}
 	_render_target_clear_sdf(rt);
 }
 

+ 3 - 0
drivers/gles3/storage/texture_storage.h

@@ -345,6 +345,7 @@ struct RenderTarget {
 	GLuint depth = 0;
 	GLuint backbuffer_fbo = 0;
 	GLuint backbuffer = 0;
+	GLuint backbuffer_depth = 0;
 
 	GLuint color_internal_format = GL_RGBA8;
 	GLuint color_format = GL_RGBA;
@@ -604,6 +605,8 @@ public:
 	RenderTarget *get_render_target(RID p_rid) { return render_target_owner.get_or_null(p_rid); };
 	bool owns_render_target(RID p_rid) { return render_target_owner.owns(p_rid); };
 
+	void copy_scene_to_backbuffer(RenderTarget *rt, const bool uses_screen_texture, const bool uses_depth_texture);
+
 	virtual RID render_target_create() override;
 	virtual void render_target_free(RID p_rid) override;