Merge pull request #72361 from the-brickster/master

Incorporating the availability of screen and depth textures for the GLES3 backend
This commit is contained in:
Yuri Sizov 2023-03-27 16:24:01 +02:00 committed by GitHub
commit fe0949e950
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 0 deletions

View File

@ -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);

View File

@ -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);
}

View File

@ -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;