diff --git a/ui/gl/gl_image.cpp b/ui/gl/gl_image.cpp index 291bbe1..c96f9b1 100644 --- a/ui/gl/gl_image.cpp +++ b/ui/gl/gl_image.cpp @@ -32,7 +32,21 @@ void DestroyTextures(QOpenGLFunctions &f, gsl::span values) { ranges::fill(values, 0); } +void GenerateFramebuffers(QOpenGLFunctions &f, gsl::span values) { + Expects(!values.empty()); + + f.glGenFramebuffers(values.size(), values.data()); +} + +void DestroyFramebuffers(QOpenGLFunctions &f, gsl::span values) { + Expects(!values.empty()); + + f.glDeleteTextures(values.size(), values.data()); + ranges::fill(values, 0); +} + } // namespace details + void Image::setImage(QImage image) { _image = std::move(image); } diff --git a/ui/gl/gl_image.h b/ui/gl/gl_image.h index 0a83888..1d82fac 100644 --- a/ui/gl/gl_image.h +++ b/ui/gl/gl_image.h @@ -16,6 +16,9 @@ namespace details { void GenerateTextures(QOpenGLFunctions &f, gsl::span values); void DestroyTextures(QOpenGLFunctions &f, gsl::span values); +void GenerateFramebuffers(QOpenGLFunctions &f, gsl::span values); +void DestroyFramebuffers(QOpenGLFunctions &f, gsl::span values); + } // namespace details template @@ -40,6 +43,43 @@ public: f.glBindTexture(GL_TEXTURE_2D, _values[index]); } + [[nodiscard]] GLuint id(int index) const { + Expects(index >= 0 && index < Count); + + return _values[index]; + } + + [[nodiscard]] bool created() const { + return (_values[0] != 0); + } + +private: + std::array _values = { { 0 } }; + +}; + +template +class Framebuffers final { +public: + static_assert(Count > 0); + + void ensureCreated(QOpenGLFunctions &f) { + if (!created()) { + details::GenerateFramebuffers(f, gsl::make_span(_values)); + } + } + void destroy(QOpenGLFunctions &f) { + if (created()) { + details::DestroyFramebuffers(f, gsl::make_span(_values)); + } + } + + void bind(QOpenGLFunctions &f, int index) const { + Expects(index >= 0 && index < Count); + + f.glBindFramebuffer(GL_FRAMEBUFFER, _values[index]); + } + [[nodiscard]] bool created() const { return (_values[0] != 0); }