+ render(dest_fbo, {}, x, y, width, height);
+}
+
+void EffectChain::render_to_texture(const vector<DestinationTexture> &destinations, unsigned width, unsigned height)
+{
+ assert(finalized);
+ assert(!destinations.empty());
+
+ if (!has_dummy_effect) {
+ // We don't end in a compute shader, so there's nothing specific for us to do.
+ // Create an FBO for this set of textures, and just render to that.
+ GLuint texnums[4] = { 0, 0, 0, 0 };
+ for (unsigned i = 0; i < destinations.size() && i < 4; ++i) {
+ texnums[i] = destinations[i].texnum;
+ }
+ GLuint dest_fbo = resource_pool->create_fbo(texnums[0], texnums[1], texnums[2], texnums[3]);
+ render(dest_fbo, {}, 0, 0, width, height);
+ resource_pool->release_fbo(dest_fbo);
+ } else {
+ render((GLuint)-1, destinations, 0, 0, width, height);
+ }
+}
+
+void EffectChain::render(GLuint dest_fbo, const vector<DestinationTexture> &destinations, unsigned x, unsigned y, unsigned width, unsigned height)
+{
+ assert(finalized);
+ assert(destinations.size() <= 1);
+
+ // This needs to be set anew, in case we are coming from a different context
+ // from when we initialized.
+ check_error();
+ glDisable(GL_DITHER);
+ check_error();
+
+ const bool final_srgb = glIsEnabled(GL_FRAMEBUFFER_SRGB);
+ check_error();
+ bool current_srgb = final_srgb;
+