gl_image.h 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145
  1. // This file is part of Desktop App Toolkit,
  2. // a set of libraries for developing nice desktop applications.
  3. //
  4. // For license and copyright information please follow this link:
  5. // https://github.com/desktop-app/legal/blob/master/LEGAL
  6. //
  7. #pragma once
  8. #include "ui/gl/gl_math.h"
  9. #include <QtGui/QOpenGLFunctions>
  10. namespace Ui::GL {
  11. namespace details {
  12. void GenerateTextures(
  13. QOpenGLFunctions &f,
  14. gsl::span<GLuint> values,
  15. GLint filter,
  16. GLint clamp);
  17. void DestroyTextures(QOpenGLFunctions *f, gsl::span<GLuint> values);
  18. void GenerateFramebuffers(QOpenGLFunctions &f, gsl::span<GLuint> values);
  19. void DestroyFramebuffers(QOpenGLFunctions *f, gsl::span<GLuint> values);
  20. } // namespace details
  21. template <size_t Count>
  22. class Textures final {
  23. public:
  24. static_assert(Count > 0);
  25. void ensureCreated(
  26. QOpenGLFunctions &f,
  27. GLint filter = GL_LINEAR,
  28. GLint clamp = GL_CLAMP_TO_EDGE) {
  29. if (!created()) {
  30. details::GenerateTextures(
  31. f,
  32. gsl::make_span(_values),
  33. filter,
  34. clamp);
  35. }
  36. }
  37. void destroy(QOpenGLFunctions *f) {
  38. if (created()) {
  39. details::DestroyTextures(f, gsl::make_span(_values));
  40. }
  41. }
  42. void bind(QOpenGLFunctions &f, int index) const {
  43. Expects(index >= 0 && index < Count);
  44. f.glBindTexture(GL_TEXTURE_2D, _values[index]);
  45. }
  46. [[nodiscard]] GLuint id(int index) const {
  47. Expects(index >= 0 && index < Count);
  48. return _values[index];
  49. }
  50. [[nodiscard]] bool created() const {
  51. return (_values[0] != 0);
  52. }
  53. private:
  54. std::array<GLuint, Count> _values = { { 0 } };
  55. };
  56. template <size_t Count>
  57. class Framebuffers final {
  58. public:
  59. static_assert(Count > 0);
  60. void ensureCreated(QOpenGLFunctions &f) {
  61. if (!created()) {
  62. details::GenerateFramebuffers(f, gsl::make_span(_values));
  63. }
  64. }
  65. void destroy(QOpenGLFunctions *f) {
  66. if (created()) {
  67. details::DestroyFramebuffers(f, gsl::make_span(_values));
  68. }
  69. }
  70. void bind(QOpenGLFunctions &f, int index) const {
  71. Expects(index >= 0 && index < Count);
  72. f.glBindFramebuffer(GL_FRAMEBUFFER, _values[index]);
  73. }
  74. [[nodiscard]] bool created() const {
  75. return (_values[0] != 0);
  76. }
  77. private:
  78. std::array<GLuint, Count> _values = { { 0 } };
  79. };
  80. struct TexturedRect {
  81. Rect geometry;
  82. Rect texture;
  83. };
  84. class Image final {
  85. public:
  86. void setImage(QImage image, QSize subimage = QSize());
  87. [[nodiscard]] const QImage &image() const;
  88. [[nodiscard]] QImage takeImage();
  89. void invalidate();
  90. void bind(QOpenGLFunctions &f);
  91. void destroy(QOpenGLFunctions *f);
  92. [[nodiscard]] TexturedRect texturedRect(
  93. const QRect &geometry,
  94. const QRect &texture,
  95. const QRect &clip = QRect());
  96. explicit operator bool() const {
  97. return !_image.isNull();
  98. }
  99. private:
  100. QImage _image;
  101. QImage _storage;
  102. Textures<1> _textures;
  103. qint64 _cacheKey = 0;
  104. QSize _subimage;
  105. QSize _textureSize;
  106. };
  107. #if defined Q_OS_WIN && QT_VERSION < QT_VERSION_CHECK(6, 0, 0)
  108. inline constexpr auto kFormatRGBA = GL_BGRA_EXT;
  109. inline constexpr auto kSwizzleRedBlue = false;
  110. #else // Q_OS_WIN
  111. inline constexpr auto kFormatRGBA = GL_RGBA;
  112. inline constexpr auto kSwizzleRedBlue = true;
  113. #endif // Q_OS_WIN
  114. } // namespace Ui::GL