The JUCE cross-platform C++ framework, with DISTRHO/KXStudio specific changes
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

194 lines
7.1KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-11 by Raw Material Software Ltd.
  5. ------------------------------------------------------------------------------
  6. JUCE can be redistributed and/or modified under the terms of the GNU General
  7. Public License (Version 2), as published by the Free Software Foundation.
  8. A copy of the license is included in the JUCE distribution, or can be found
  9. online at www.gnu.org/licenses.
  10. JUCE is distributed in the hope that it will be useful, but WITHOUT ANY
  11. WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
  12. A PARTICULAR PURPOSE. See the GNU General Public License for more details.
  13. ------------------------------------------------------------------------------
  14. To release a closed-source product which uses JUCE, commercial licenses are
  15. available: visit www.rawmaterialsoftware.com/juce for more information.
  16. ==============================================================================
  17. */
  18. BEGIN_JUCE_NAMESPACE
  19. OpenGLFrameBufferImage::OpenGLFrameBufferImage (Image::PixelFormat format, int width, int height)
  20. : Image::SharedImage (format, width, height),
  21. pixelStride (4),
  22. lineStride (width * pixelStride)
  23. {
  24. frameBuffer.initialise (width, height);
  25. frameBuffer.clear (Colours::transparentBlack);
  26. }
  27. OpenGLFrameBufferImage::~OpenGLFrameBufferImage() {}
  28. LowLevelGraphicsContext* OpenGLFrameBufferImage::createLowLevelContext()
  29. {
  30. return new LowLevelGraphicsSoftwareRenderer (Image (this));
  31. }
  32. Image::SharedImage* OpenGLFrameBufferImage::clone()
  33. {
  34. OpenGLFrameBufferImage* im = new OpenGLFrameBufferImage (getPixelFormat(), getWidth(), getHeight());
  35. im->incReferenceCount();
  36. {
  37. Image newImage (im);
  38. Graphics g (newImage);
  39. g.drawImageAt (Image (this), 0, 0, false);
  40. }
  41. im->resetReferenceCount();
  42. return im;
  43. }
  44. Image::ImageType OpenGLFrameBufferImage::getType() const
  45. {
  46. return Image::NativeImage;
  47. }
  48. namespace OpenGLImageHelpers
  49. {
  50. struct Dummy
  51. {
  52. Dummy (OpenGLFrameBuffer&, int, int, int, int) noexcept {}
  53. static void read (OpenGLFrameBuffer&, Image::BitmapData& , int, int) noexcept {}
  54. static void write (const void*) noexcept {}
  55. };
  56. struct Reader
  57. {
  58. static void read (OpenGLFrameBuffer& frameBuffer, Image::BitmapData& bitmapData, int x, int y)
  59. {
  60. if (frameBuffer.makeCurrentTarget())
  61. {
  62. OpenGLHelpers::prepareFor2D (frameBuffer.getWidth(), frameBuffer.getHeight());
  63. glPixelStorei (GL_PACK_ALIGNMENT, 4);
  64. glReadPixels (x, y, bitmapData.width, bitmapData.height, GL_RGBA, GL_UNSIGNED_BYTE, bitmapData.data);
  65. frameBuffer.releaseCurrentTarget();
  66. }
  67. }
  68. };
  69. struct Writer
  70. {
  71. Writer (OpenGLFrameBuffer& frameBuffer_, int x, int y, int w, int h) noexcept
  72. : frameBuffer (frameBuffer_), area (x, y, w, h)
  73. {}
  74. void write (const void* const data) const noexcept
  75. {
  76. if (frameBuffer.makeCurrentTarget())
  77. {
  78. OpenGLHelpers::prepareFor2D (frameBuffer.getWidth(), frameBuffer.getHeight());
  79. glDisable (GL_DEPTH_TEST);
  80. glDisable (GL_BLEND);
  81. #if JUCE_OPENGL_ES
  82. // GLES has no glDrawPixels function, so we have to create a texture and draw it..
  83. GLuint temporaryTexture = 0;
  84. glGenTextures (1, &temporaryTexture);
  85. jassert (temporaryTexture != 0); // can't create a texture!
  86. if (temporaryTexture != 0)
  87. {
  88. glEnable (GL_TEXTURE_2D);
  89. glBindTexture (GL_TEXTURE_2D, temporaryTexture);
  90. glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
  91. glTexImage2D (GL_TEXTURE_2D, 0, GL_RGBA, area.getWidth(), area.getHeight(), 0,
  92. GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
  93. glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  94. glTexParameterf (GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  95. const int cropRect[4] = { 0, 0, area.getWidth(), area.getHeight() };
  96. glTexParameteriv (GL_TEXTURE_2D, GL_TEXTURE_CROP_RECT_OES, cropRect);
  97. glDrawTexiOES (area.getX(), area.getY(), 1, area.getWidth(), area.getHeight());
  98. glBindTexture (GL_TEXTURE_2D, 0);
  99. glDeleteTextures (1, &temporaryTexture);
  100. }
  101. #else
  102. glRasterPos2i (area.getX(), area.getY());
  103. glBindTexture (GL_TEXTURE_2D, 0);
  104. glPixelStorei (GL_UNPACK_ALIGNMENT, 4);
  105. glDrawPixels (area.getWidth(), area.getHeight(), GL_BGRA_EXT, GL_UNSIGNED_BYTE, data);
  106. #endif
  107. frameBuffer.releaseCurrentTarget();
  108. }
  109. }
  110. OpenGLFrameBuffer& frameBuffer;
  111. const Rectangle<int> area;
  112. JUCE_DECLARE_NON_COPYABLE (Writer);
  113. };
  114. template <class ReaderType, class WriterType>
  115. struct DataReleaser : public Image::BitmapData::BitmapDataReleaser
  116. {
  117. DataReleaser (OpenGLFrameBuffer& frameBuffer, size_t dataSize, int x, int y, int w, int h)
  118. : data (dataSize),
  119. writer (frameBuffer, x, y, w, h)
  120. {}
  121. ~DataReleaser()
  122. {
  123. writer.write (data);
  124. }
  125. static void initialise (OpenGLFrameBuffer& frameBuffer, Image::BitmapData& bitmapData, int x, int y)
  126. {
  127. DataReleaser* r = new DataReleaser (frameBuffer, bitmapData.lineStride * bitmapData.height,
  128. x, y, bitmapData.width, bitmapData.height);
  129. bitmapData.dataReleaser = r;
  130. bitmapData.data = r->data + x * bitmapData.pixelStride + y * bitmapData.lineStride;
  131. ReaderType::read (frameBuffer, bitmapData, x, y);
  132. }
  133. HeapBlock<uint8> data;
  134. WriterType writer;
  135. };
  136. }
  137. void OpenGLFrameBufferImage::initialiseBitmapData (Image::BitmapData& bitmapData, int x, int y,
  138. Image::BitmapData::ReadWriteMode mode)
  139. {
  140. using namespace OpenGLImageHelpers;
  141. bitmapData.pixelFormat = format;
  142. bitmapData.lineStride = lineStride;
  143. bitmapData.pixelStride = pixelStride;
  144. switch (mode)
  145. {
  146. case Image::BitmapData::writeOnly: DataReleaser<Dummy, Writer>::initialise (frameBuffer, bitmapData, x, y); break;
  147. case Image::BitmapData::readOnly: DataReleaser<Reader, Dummy> ::initialise (frameBuffer, bitmapData, x, y); break;
  148. case Image::BitmapData::readWrite: DataReleaser<Reader, Writer>::initialise (frameBuffer, bitmapData, x, y); break;
  149. default: jassertfalse; break;
  150. }
  151. }
  152. END_JUCE_NAMESPACE