Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Save jellyr/1e8b1944aee7dcfdfa1e6e0fcf9cd104 to your computer and use it in GitHub Desktop.
Save jellyr/1e8b1944aee7dcfdfa1e6e0fcf9cd104 to your computer and use it in GitHub Desktop.
Transparent OpenGL Component for JUCE
#include "TransparentOpenGLComponent.h"
using namespace juce;
TransparentOpenGLComponent::TransparentOpenGLComponent()
{
openGLContext.setComponentPaintingEnabled (true);
openGLContext.setRenderer (this);
openGLContext.setContinuousRepainting (true);
openGLContext.attachTo (*this);
}
TransparentOpenGLComponent::~TransparentOpenGLComponent()
{
openGLContext.detach();
}
static Point<int> getGlViewPortSize()
{
GLint viewport[4];
glGetIntegerv (GL_VIEWPORT, viewport);
return Point<int> (viewport[2], viewport[3]);
}
void TransparentOpenGLComponent::renderOpenGL()
{
{
const Point<int> newViewportSize = getGlViewPortSize();
if (viewportSize != newViewportSize)
{
viewportSize = newViewportSize;
backgroundTexture.loadImage (renderBackground());
}
}
backgroundTexture.bind();
Rectangle<int> textureSize (backgroundTexture.getWidth(), backgroundTexture.getHeight());
openGLContext.copyTexture (textureSize, textureSize, viewportSize.getX(), viewportSize.getY(), false);
renderOverBackground (viewportSize);
}
void TransparentOpenGLComponent::newOpenGLContextCreated()
{
viewportSize = Point<int> (0, 0);
}
void TransparentOpenGLComponent::openGLContextClosing()
{
backgroundTexture.release();
}
Image TransparentOpenGLComponent::renderBackground()
{
Image backgroundImage (Image::ARGB, viewportSize.getX(), viewportSize.getY(), false);
{
Graphics g (backgroundImage);
g.addTransform (AffineTransform::scale ((float) viewportSize.getX() / (float) getWidth(), (float) viewportSize.getY() / (float) getHeight()));
renderParentsToBackground (g, *this);
}
return backgroundImage;
}
void TransparentOpenGLComponent::renderParentsToBackground (Graphics &g, Component& component)
{
Component* parent = component.getParentComponent();
if (parent == nullptr)
{
component.paintEntireComponent (g, false);
return;
}
Graphics::ScopedSaveState saveState (g);
g.addTransform (AffineTransform::translation (- component.getBounds().getTopLeft()));
g.addTransform (component.getTransform().inverted());
renderParentsToBackground (g, *parent);
}
#ifndef TRANSPARENTOPENGLCOMPONENT_H_INCLUDED
#define TRANSPARENTOPENGLCOMPONENT_H_INCLUDED
#include "JuceHeader.h"
// A Component with an attached OpenGLContext which saves the background under it,
// and within the OpenGL context draws the background first, and then calls
// its subclass's renderOverBackground method to draw.
//
// Assumptions:
// * The background is constant.
// * This component, its parent, and ancestors, do not have overlapping sibling components.
class TransparentOpenGLComponent : public juce::Component, public juce::OpenGLRenderer
{
public:
TransparentOpenGLComponent();
virtual ~TransparentOpenGLComponent();
virtual void renderOverBackground (juce::Point<int> viewportSize) = 0;
// Sub-classes overriding this must call these in their overrides.
void newOpenGLContextCreated() override;
void openGLContextClosing() override;
juce::OpenGLContext openGLContext;
protected:
juce::Image renderBackground();
private:
void renderOpenGL() override;
void renderParentsToBackground (juce::Graphics& g, juce::Component&);
juce::Point<int> viewportSize;
juce::OpenGLTexture backgroundTexture;
};
#endif // TRANSPARENTOPENGLCOMPONENT_H_INCLUDED
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment