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

Code before:
	RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);

	_render_list_template<PASS_MODE_COLOR>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());

	if (draw_sky) {
		RENDER_TIMESTAMP("Render Sky");
		if (scene_state.current_depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED) {
			glEnable(GL_DEPTH_TEST);
			scene_state.current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_ENABLED;
		}
		glEnable(GL_DEPTH_TEST);
		glDepthMask(GL_FALSE);
		glDisable(GL_BLEND);
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
		scene_state.current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_ENABLED;
		scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
		scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;

		_draw_sky(render_data.environment, render_data.cam_projection, render_data.cam_transform, sky_energy_multiplier, p_camera_data->view_count > 1, flip_y);
	}

	RENDER_TIMESTAMP("Render 3D Transparent Pass");
	glEnable(GL_BLEND);

	//Render transparent pass
	RenderListParameters render_list_params_alpha(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);

	_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true);

	if (!flip_y) {
		// Restore the default winding order.
		glFrontFace(GL_CCW);
	}

	if (rb.is_valid()) {
		_render_buffers_debug_draw(rb, p_shadow_atlas, p_occluder_debug_tex);
	}
	glDisable(GL_BLEND);
	texture_storage->render_target_disable_clear_request(rb->render_target);
}

template <PassMode p_pass_mode>
void RasterizerSceneGLES3::_render_list_template(RenderListParameters *p_params, const RenderDataGLES3 *p_render_data, uint32_t p_from_element, uint32_t p_to_element, bool p_alpha_pass) {
	GLES3::MeshStorage *mesh_storage = GLES3::MeshStorage::get_singleton();
	GLES3::ParticlesStorage *particles_storage = GLES3::ParticlesStorage::get_singleton();
	GLES3::MaterialStorage *material_storage = GLES3::MaterialStorage::get_singleton();
	GLES3::TextureStorage *texture_storage = GLES3::TextureStorage::get_singleton();
	GLES3::Config *config = GLES3::Config::get_singleton();

	GLuint prev_vertex_array_gl = 0;

Review comment (suggestion):
```suggestion
		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);
```
We need to specify the READ_FRAMEBUFFER or else it can try to read from the last buffer specified as the READ_FRAMEBUFFER

Code after:
	RenderListParameters render_list_params(render_list[RENDER_LIST_OPAQUE].elements.ptr(), render_list[RENDER_LIST_OPAQUE].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);

	_render_list_template<PASS_MODE_COLOR>(&render_list_params, &render_data, 0, render_list[RENDER_LIST_OPAQUE].elements.size());

	if (draw_sky) {
		RENDER_TIMESTAMP("Render Sky");
		if (scene_state.current_depth_test != GLES3::SceneShaderData::DEPTH_TEST_ENABLED) {
			glEnable(GL_DEPTH_TEST);
			scene_state.current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_ENABLED;
		}
		glEnable(GL_DEPTH_TEST);
		glDepthMask(GL_FALSE);
		glDisable(GL_BLEND);
		glEnable(GL_CULL_FACE);
		glCullFace(GL_BACK);
		scene_state.current_depth_test = GLES3::SceneShaderData::DEPTH_TEST_ENABLED;
		scene_state.current_depth_draw = GLES3::SceneShaderData::DEPTH_DRAW_DISABLED;
		scene_state.cull_mode = GLES3::SceneShaderData::CULL_BACK;

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

	//Render transparent pass
	RenderListParameters render_list_params_alpha(render_list[RENDER_LIST_ALPHA].elements.ptr(), render_list[RENDER_LIST_ALPHA].elements.size(), reverse_cull, spec_constant_base_flags, use_wireframe);

	_render_list_template<PASS_MODE_COLOR_TRANSPARENT>(&render_list_params_alpha, &render_data, 0, render_list[RENDER_LIST_ALPHA].elements.size(), true);