[quote author=“memo”]anton aka vade has an awesome Quartz Composer plugin (mac osx) to capture any part of the screen and retrieve it as an opengl texture. Everything stays on gpu so super fast. It’s opensource so maybe you can dig out the relevant bits. I think to make it cross platform shouldn’t be too complicated as it’s mostly opengl, but I may be wrong.
http://002.vade.info/?page-id=4[/quote]
That program has this function:
static GLuint _CreateWindowTexture(CGLContextObj internalContext, CGLContextObj mainDrawingContext, NSInteger width, NSInteger height, NSInteger originX, NSInteger originY,NSRect bounds)
{
CGLContextObj cgl_ctx = internalContext;
// Thread lock OpenGL Context
CGLLockContext(cgl_ctx);
GLuint mTextureName;
GLenum theError = GL_NO_ERROR;
// set up our texture storage for copying
glPixelStorei(GL_UNPACK_ALIGNMENT, 4);
glPixelStorei(GL_PACK_ROW_LENGTH, 0);
glPixelStorei(GL_PACK_SKIP_ROWS, 0);
glPixelStorei(GL_PACK_SKIP_PIXELS, 0);
// Create and configure the texture - rectangluar coords
glGenTextures(1, &mTextureName);
glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mTextureName);
glTexParameteri(GL_TEXTURE_RECTANGLE_ARB, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
// define our texture - we're allowd to supply a null pointer since we are letting the GPU handle texture storage.
glTexImage2D(GL_TEXTURE_RECTANGLE_ARB,0,GL_RGBA, width,height,0,GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, NULL);
// read from the front buffer
glReadBuffer(GL_FRONT);
// glBindTexture(GL_TEXTURE_RECTANGLE_ARB, mTextureName);
// copy contents of a portion of the buffer to our texture
glCopyTexSubImage2D(GL_TEXTURE_RECTANGLE_ARB, 0, 0, 0, originX, originY, width, height);
// fin
glFlush();
// Thread unlock
CGLUnlockContext(cgl_ctx);
//Check for OpenGL errors
theError = glGetError();
if(theError) {
NSLog(@"v002ScreenCapture: OpenGL texture creation failed (error 0x%04X)", theError);
CGLUnlockContext(cgl_ctx); // Thread unlock
return 0;
}
return mTextureName;
}
I’m not sure about the context parts but the straight opengl looks portable. I’ll have to experiment.
I think screen capture is a good generic capability- though it can be slow and inefficient, sometimes it’s the only way to get output from one program into another that doesn’t require external hardware. Maybe eventually there will be an official loadScreenData() that can grab from anywhere on the screen.