Render JUCE component to OpenGL texture (offscreen if possible)


#1

Hi

I’m trying to use JUCE to render a certain component to an OpenGL texture and to send it through Spout to another program. If it’s possible this would have to be offscreen.

I tried several things but couldn’t find a way to do this. What would be the correct way to do this?

Thanks

Jannes


#2

You’d need to create an Image with the OpenGLImageType, then draw into it as usual with a Graphics object. Then you can grab its frame buffer and use that.

You will need an active GL context when you do this, though, so will need to actually have an OpenGLContext and do your rendering in its callback.


#3

Hi, thanks for the quick answer. But where do I draw the child components to the openglimagetype?

Now I go this:
#ifndef SPOUTCOMPONENT_H_INCLUDED
#define SPOUTCOMPONENT_H_INCLUDED

#include "JuceHeader.h"
#include "Spout\Spout.h"

class SpoutComponent : public juce::Component, public juce::OpenGLRenderer
{
public:
	SpoutComponent() {
		openGLContext.setComponentPaintingEnabled(true);
		openGLContext.setRenderer(this); //set openglrenderer to this
		openGLContext.setContinuousRepainting(true);
		openGLContext.attachTo(*this); //atach context to this
	}

	SpoutComponent() {
		openGLContext.detach();
	}

	// Overriding openglrenderer functions
	void newOpenGLContextCreated() override;
	void openGLContextClosing() override;
	void renderOpenGL() override {
		//render our opengl?
	}

	//override comoponent functions
	void resized() override {
		//set position from child components
	}

	OpenGLContext openGLContext; //our opengl context
	OpenGLImageType openGLimage;

private:
	
	//SPOUT
	ScopedPointer <SpoutSender> mySender;
	char name[256];

};

#endif

#4

Not really clear exactly what you’re trying to do, but maybe you want to use Component::paintEntireComponent ?


#5

Ok, let me explain it a bit better.

So I want to create a custom component that shows certain information. This component has to be sent through Spout (spout is a library to share graphics between programs). So I want to send this component to Resolume Arena to map the information in this VJ program.

So I want to know how to know how I get the OpenGL texture from this component to give it to the spout library to send this texture to the other program so I can use it in this. But I don’t know enough from the internals from JUCE and openGL to know where I should do this. Where should I do the paintEntireComponent, in the paint() function of the component?


#6

What you want is probably the OpenGL handle of the Texture Juce renders in so you can share it using Spout. I don’t know the specifics of the Juce OpenGL rendering but what you could do as well is render to an Image and convert that to a texture yourself. Using the BitmapData of the Juce Image that’s actually quite simple. But of course getting the Texure handle directly from Juce would be ideal. I guess Juce uses a render to texture mechanism. Let me know how you get on with this.

Edwin
Resolume


#7

Thanks Edwin,

I’ll dive deeper in the internal JUCE render engine. Another option is to do all the rendering directly in OpenGL, but I prefer to use the easy JUCE components to show stuff because I’m not an OpenGL expert.

Rendering to a image and then converting to a texture seems like (correct me if I’m wrong) going from GPU data --> CPU data --> GPU data and seems indeed a bit unnecesarry.

I’ll keep trying and will keep you posted!


#8

That’s right, you don’t want to use a normal image. But if you render to an OpenGLImageType like I suggested above, it’s 100% GPU.


#9

Ok thanks! I think I understand the logic behind it now


#10

Got it working: code might need some cleanup, this is just quickly done but might be usefull for others: