How do I blit pixel data to the screen using OpenGL ES?
I'm currently learning OpenGL ES for iPhone and I'm wondering how to take an array of RGB pixel data and blit it to the screen, so far all the tutorials I've found cover loading a pre-existing image into a texture and displaying it.
Here's how I've accomplished it using Core Graphics by creating an imageref then using a UIImage and UIImageView:
Code:
int screenWidth = (int)[[UIScreen mainScreen] bounds].size.width;
int screenHeight = (int)[[UIScreen mainScreen] bounds].size.height;
//Create blank image
CGImageRef blankImageRef = [self createBlankImageRef];
CFDataRef m_DataRef;
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(blankImageRef));
UInt8* bufferData = CFDataGetBytePtr(m_DataRef);
//Manipulate the image here
for(int x=0; x < screenWidth-1; x++)
{
int y = x;//*2;
[self setPixel:bufferData width:screenWidth x:x y:y r:255 g:0 b:0];
}
//Paint the image to the screen
CGImageRef imageRef = blankImageRef;
CGContextRef ctx;
ctx = CGBitmapContextCreate(bufferData,
CGImageGetWidth( imageRef ),
CGImageGetHeight( imageRef ),
8,
CGImageGetBytesPerRow( imageRef ),
CGImageGetColorSpace( imageRef ),
kCGImageAlphaPremultipliedLast );
screenImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage (ctx)];
CGContextRelease(ctx);
[imageView setImage:screenImage];
free(bufferData);
I'm currently learning OpenGL ES for iPhone and I'm wondering how to take an array of RGB pixel data and blit it to the screen, so far all the tutorials I've found cover loading a pre-existing image into a texture and displaying it.
Here's how I've accomplished it using Core Graphics by creating an imageref then using a UIImage and UIImageView:
Code:
int screenWidth = (int)[[UIScreen mainScreen] bounds].size.width;
int screenHeight = (int)[[UIScreen mainScreen] bounds].size.height;
//Create blank image
CGImageRef blankImageRef = [self createBlankImageRef];
CFDataRef m_DataRef;
m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(blankImageRef));
UInt8* bufferData = CFDataGetBytePtr(m_DataRef);
//Manipulate the image here
for(int x=0; x < screenWidth-1; x++)
{
int y = x;//*2;
[self setPixel:bufferData width:screenWidth x:x y:y r:255 g:0 b:0];
}
//Paint the image to the screen
CGImageRef imageRef = blankImageRef;
CGContextRef ctx;
ctx = CGBitmapContextCreate(bufferData,
CGImageGetWidth( imageRef ),
CGImageGetHeight( imageRef ),
8,
CGImageGetBytesPerRow( imageRef ),
CGImageGetColorSpace( imageRef ),
kCGImageAlphaPremultipliedLast );
screenImage = [UIImage imageWithCGImage:CGBitmapContextCreateImage (ctx)];
CGContextRelease(ctx);
[imageView setImage:screenImage];
free(bufferData);
Any ideas how I could accomplish this using OpenGL ES (currently using 1.0) instead of Core Graphics?
You'd create a framebuffer object, and load it using glloadData.
Textures are another way to do this. Take a look at the sample app GLCameraRipple that is in the Xcode 4.2 docs. It loads frames of video from the camera live as OpenGL textures, then transforms them using a mesh. Cool stuff.
Note that you really don't want to create a pixel buffer in main memory and install it on the graphics hardware. That defeats the purpose of hardware graphics acceleration. You tie up the CPU building all that pixel data, and then you tie up the whole system while you upload all that data to video memory.
Your setPixel code is a VERY slow way to draw. You're setting up a stack frame with byte parameters for for your R, G, and B values, then doing array math to calculate the index for each byte, then storing a single pixel's data into a Core Graphics context.
You should write your code to render your images directly in OpenGL.
Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.