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.

228 lines
8.8KB

  1. /*
  2. ==============================================================================
  3. This file is part of the JUCE library - "Jules' Utility Class Extensions"
  4. Copyright 2004-9 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. #include "../jucedemo_headers.h"
  19. #if JUCE_OPENGL
  20. //==============================================================================
  21. class DemoOpenGLCanvas : public OpenGLComponent,
  22. public Timer
  23. {
  24. public:
  25. DemoOpenGLCanvas()
  26. : rotation (0.0f),
  27. delta (1.0f),
  28. textScrollPos (200)
  29. {
  30. startTimer (20);
  31. }
  32. // when the component creates a new internal context, this is called, and
  33. // we'll use the opportunity to create some images to use as textures.
  34. void newOpenGLContextCreated()
  35. {
  36. logoImage = createLogoImage();
  37. dynamicTextureImage = Image (Image::ARGB, 128, 128, true, OpenGLImageType());
  38. }
  39. void mouseDown (const MouseEvent& e)
  40. {
  41. draggableOrientation.mouseDown (e.getPosition());
  42. }
  43. void mouseDrag (const MouseEvent& e)
  44. {
  45. draggableOrientation.mouseDrag (e.getPosition());
  46. delta = e.getDistanceFromDragStartX() / 100.0f;
  47. repaint();
  48. }
  49. void resized()
  50. {
  51. draggableOrientation.setViewport (getLocalBounds());
  52. }
  53. void renderOpenGL()
  54. {
  55. OpenGLHelpers::clear (Colours::darkgrey.withAlpha (1.0f));
  56. updateTextureImage(); // this will update our dynamically-changing texture image.
  57. drawBackground2DStuff(); // draws some 2D content to demonstrate the OpenGLRenderer class
  58. // Having used the juce 2D renderer, it will have messed-up a whole load of GL state, so
  59. // we'll put back any important settings before doing our normal GL 3D drawing..
  60. glEnable (GL_DEPTH_TEST);
  61. glDepthFunc (GL_LESS);
  62. glEnable (GL_BLEND);
  63. glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
  64. glEnable (GL_TEXTURE_2D);
  65. OpenGLHelpers::setPerspective (45.0, getWidth() / (double) getHeight(), 0.1, 100.0);
  66. glTranslatef (0.0f, 0.0f, -5.0f);
  67. draggableOrientation.applyToOpenGLMatrix();
  68. // logoImage and dynamicTextureImage are actually OpenGL images, so we can use this utility function to
  69. // extract the frame buffer which is their backing store, and use it directly.
  70. OpenGLFrameBuffer* tex1 = OpenGLImageType::getFrameBufferFrom (logoImage);
  71. OpenGLFrameBuffer* tex2 = OpenGLImageType::getFrameBufferFrom (dynamicTextureImage);
  72. jassert (tex1 != nullptr && tex2 != nullptr); // (this would mean that our images weren't created correctly)
  73. // This draws the sides of our spinning cube.
  74. // I've used some of the juce helper functions, but you can also just use normal GL calls here too.
  75. tex1->draw3D (-1.0f, 1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, Colours::white);
  76. tex1->draw3D (-1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, Colours::white);
  77. tex1->draw3D (-1.0f, -1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, -1.0f, -1.0f, 1.0f, Colours::white);
  78. tex2->draw3D (-1.0f, 1.0f, -1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, Colours::white);
  79. tex2->draw3D ( 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, 1.0f, 1.0f, -1.0f, 1.0f, 1.0f, -1.0f, -1.0f, Colours::white);
  80. tex2->draw3D (-1.0f, 1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, -1.0f, 1.0f, -1.0f, 1.0f, 1.0f, Colours::white);
  81. drawForeground2DStuff(); // draws our scrolling text overlay
  82. }
  83. void updateTextureImage()
  84. {
  85. // This image is a special framebuffer-backed image, so when we draw to it, the context
  86. // will render directly into its framebuffer
  87. dynamicTextureImage.clear (dynamicTextureImage.getBounds(), Colours::red.withRotatedHue (fabsf (::sinf (rotation / 300.0f))).withAlpha (0.7f));
  88. Graphics g (dynamicTextureImage);
  89. g.setFont (dynamicTextureImage.getHeight() / 3.0f);
  90. g.setColour (Colours::black);
  91. drawScrollingMessage (g, dynamicTextureImage.getHeight() / 2);
  92. }
  93. void drawBackground2DStuff()
  94. {
  95. OpenGLRenderer glRenderer (*this); // Create an OpenGLRenderer that will draw into this GL window..
  96. Graphics g (&glRenderer); // ..and then wrap it in a normal Graphics object so we can draw with it.
  97. // This stuff just creates a spinning star shape and fills it..
  98. Path p;
  99. const float scale = getHeight() * 0.4f;
  100. p.addStar (getLocalBounds().getCentre().toFloat(), 7,
  101. scale + ::cosf (rotation * 0.0021f) * scale / 2,
  102. scale + ::sinf (rotation * 0.001f) * scale / 2, rotation / 50.0f);
  103. g.setGradientFill (ColourGradient (Colours::green.withRotatedHue (fabsf (::sinf (rotation / 300.0f))),
  104. 0, 0,
  105. Colours::green.withRotatedHue (fabsf (::cosf (rotation / -431.0f))),
  106. 0, (float) getHeight(), false));
  107. g.fillPath (p);
  108. }
  109. void drawForeground2DStuff()
  110. {
  111. OpenGLRenderer glRenderer (*this); // Create an OpenGLRenderer that will draw into this GL window..
  112. Graphics g (&glRenderer); // ..and then wrap it in a normal Graphics object so we can draw with it.
  113. // Then, just draw our scolling text like we would in any other component.
  114. g.setColour (Colours::blue.withAlpha (0.5f));
  115. g.setFont (30.0f, Font::bold);
  116. drawScrollingMessage (g, getHeight() / 2);
  117. }
  118. void drawScrollingMessage (Graphics& g, int y) const
  119. {
  120. g.drawSingleLineText ("The background, foreground and texture are all being drawn using the OpenGLRenderer class, which "
  121. "lets you use a standard JUCE 2D graphics context to render directly onto an OpenGL window or framebuffer... ",
  122. (int) -std::fmod (textScrollPos, 2500.0f), y);
  123. }
  124. void timerCallback()
  125. {
  126. rotation += delta;
  127. textScrollPos += 1.4f;
  128. repaint();
  129. }
  130. private:
  131. Image logoImage, dynamicTextureImage;
  132. float rotation, delta, textScrollPos;
  133. Draggable3DOrientation draggableOrientation;
  134. // Functions to create a couple of images to use as textures..
  135. static Image createLogoImage()
  136. {
  137. Image image (Image::ARGB, 256, 256, true, OpenGLImageType());
  138. Graphics g (image);
  139. g.fillAll (Colours::lightgrey.withAlpha (0.8f));
  140. g.drawImageWithin (ImageFileFormat::loadFrom (BinaryData::juce_png, BinaryData::juce_pngSize),
  141. 0, 0, image.getWidth(), image.getHeight(), RectanglePlacement::stretchToFit);
  142. drawRandomStars (g, image.getWidth(), image.getHeight());
  143. return image;
  144. }
  145. static void drawRandomStars (Graphics& g, int w, int h)
  146. {
  147. Random r;
  148. for (int i = 10; --i >= 0;)
  149. {
  150. Path pp;
  151. pp.addStar (Point<float> (r.nextFloat() * w, r.nextFloat() * h), r.nextInt (8) + 3, 10.0f, 20.0f, 0.0f);
  152. g.setColour (Colours::pink.withAlpha (0.4f));
  153. g.fillPath (pp);
  154. }
  155. }
  156. };
  157. //==============================================================================
  158. class OpenGLDemo : public Component
  159. {
  160. public:
  161. OpenGLDemo()
  162. : Component ("OpenGL")
  163. {
  164. addAndMakeVisible (&canvas);
  165. }
  166. void resized()
  167. {
  168. canvas.setBounds (10, 10, getWidth() - 20, getHeight() - 50);
  169. }
  170. private:
  171. DemoOpenGLCanvas canvas;
  172. JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR (OpenGLDemo);
  173. };
  174. //==============================================================================
  175. Component* createOpenGLDemo()
  176. {
  177. return new OpenGLDemo();
  178. }
  179. #endif