I’m currently working on a project that takes in n number of videos, slices them up into squares and draws them at somewhat random positions on the screen.
Basic movie loading, getting texture(s) from each movie and drawing using gl::draw
setup()… qtime::MovieGlRef movie = qtime::MovieGl::create (path);
…
update()… movieTexture = movie->getTexture();
…
draw()… gl::draw (movieTexture, src, dest);
…
Everything is looking and performing somewhat as expected, playing 10 videos at once is taking about 28-30% CPU on my Macbook Pro (2.3 GHz i7 w/ a GeForce GT 750M) (4 year old Macbook) on a debug build.
I’m at a point now where I’d like to add a shader and apply it to the texture(s) that are being drawn… Just trying to understand how cinder::gl/OpenGL work. My OpenGL plumbing chops are a bit rusty (currently reading lots of bits and pieces online and digging into “the” OpenGL book).
So my question is:
Can a shader be applied to a texture after it is drawn using gl::draw ?
I’m currently looking at gl::draw (const Texture2dRef &texture, const Area &srcArea, const Rectf &dstRect) implementation and from what I understand if I wanted to add a shader to a texture I would basically need to roll my own version of gl::drawTexture which would have my custom shader in addition to what the original IMPL is doing.
You can use a stock shader, your texture, and gl::drawSolidRect() to achieve what you need.
The stock shaders are generated based on a gl::ShaderDef() and are cached in the gl context. To have a look at what they can generate, try passing different gl::ShaderDef()s to the generation functions:
auto def = gl::ShaderDef().color().lambert();
auto vs = gl::env()->generateVertexShader( def );
auto fs = gl::env()->generateFragmentShader( def );
std::cout << vs << "\n===\n" << fs << std::endl;
To do what you need, you’ll have to do something like:
Your uvs might need to have their y components swapped if it comes in upside down. Also note that i’ve wrapped it in its own scope so that the gl::Scoped* classes can do their thing. This is also a prime candidate for instancing, where you can draw all the rectangles at once by providing an index into a texture array as a custom attribute, but i suggest you only worry about that if / when performance becomes an issue.
This is because quicktime uses the texture target GL_TEXTURE_RECTANGLE rather than GL_TEXTURE_2D. In your shader, change uTex0 to be of type sampler2DRect and you should be fine.