Opengl ES 2.0 - Load PNG with GLKit instead of OpenGL API - opengl-es-2.0

I have a piece of code that loads a textures using glTexImage2D like this:
// to test texturing
CGImageRef imageRef = [[UIImage imageNamed:#"Blob.png"] CGImage];
int width = CGImageGetWidth(imageRef);
int height = CGImageGetHeight(imageRef);
GLubyte* textureData = (GLubyte *)malloc(width * height * 4); // if 4 components per pixel (RGBA)
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
NSUInteger bytesPerPixel = 4;
NSUInteger bytesPerRow = bytesPerPixel * width;
NSUInteger bitsPerComponent = 8;
CGContextRef context = CGBitmapContextCreate(textureData, width, height,
bitsPerComponent, bytesPerRow, colorSpace,
kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
CGColorSpaceRelease(colorSpace);
CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
CGContextRelease(context);
glActiveTexture(GL_TEXTURE0);
glGenTextures(1, &texId);
glBindTexture(GL_TEXTURE_2D, texId);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, textureData);
glBindTexture(GL_TEXTURE_2D, 0);
I replaced the code with this, the code doesn throw any error but shows a black image instead.
NSError *error;
GLKTextureInfo *texture = [GLKTextureLoader textureWithContentsOfFile:[[NSBundle mainBundle] pathForResource:#"Blob.png" ofType:Nil]
options:Nil
error:&error]; assert(!error);
//bind the texture to texture unit 0
glActiveTexture(GL_TEXTURE0 + 0);
glBindTexture(texture.target, texture.name);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
glEnable(texture.target);
glBindTexture(GL_TEXTURE_2D, 0);
What could be the problem?
The project I want to port is at https://github.com/glman74/simpleFBO

pathForResource:#"Blob.png" ofType:Nil
Should be
pathForResource:#"Blob" ofType:#"png"
And most of the time you should use nil instead if Nil

This is how I've solved it:
This goes in the OpenGL initialisation code
NSError *error;
GLKTextureInfo *texture = [GLKTextureLoader
textureWithContentsOfFile:
[[NSBundle mainBundle] pathForResource:#"Blob.png" ofType:Nil]
options:Nil
error:&error];
And this goes in the rendering method, in this case glkView:drawInRect:
glBindTexture(GL_TEXTURE_2D, 0);

Related

CGBitmapContextCreateImage or CGContextDrawImage doesn't work

I can't solve this problem. Load image, convert to CGImageRef. Try to get bitmap context and render on the screen.
NSURL *imageFileURL = [NSURL fileURLWithPath:stringIMG];
CGImageSourceRef imageSource = CGImageSourceCreateWithURL((CFURLRef)imageFileURL, NULL);
CGImageRef imageRef = CGImageSourceCreateImageAtIndex(imageSource, 0, NULL);
NSInteger bitsPerComponent = CGImageGetBitsPerComponent(imageRef);
NSInteger bitsPerPixel = CGImageGetBitsPerPixel(imageRef);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(imageRef);
NSInteger bytesPerRow = CGImageGetBytesPerRow(imageRef);
NSInteger width = CGImageGetWidth(imageRef);
NSInteger height = CGImageGetHeight(imageRef);
CGColorSpaceRef colorspace = CGImageGetColorSpace(imageRef);
size_t rawData = bytesPerRow*height;
unsigned char *data = malloc(rawData);
memset(data2, 0, rawData);
CGContextRef context = CGBitmapContextCreate(data, width, height, bitsPerComponent, bytesPerRow, colorspace, bitmapInfo);
CGImageRef imageRef2 = CGBitmapContextCreateImage(context);
// CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef2);
UIImage *result = [UIImage imageWithCGImage:imageRef2];//if i do like this i got white empty screen
UIImageView *image = [[UIImageView alloc] initWithImage:result];
[self.view addSubview:image];// if i do like this i got black rectangle on the white screen
I have no idea. I check by breakpoint that context is not null. I don't know what should i do. Please maybe anyone can help me?
Category added it to UIImage for resizing using CoreGraphics
UIImage+Resize.h
#import <UIKit/UIKit.h>
#interface UIImage (Resizing)
-(UIImage*)resizedImageWithSize:(CGSize)size;
#end
UIImage+Resizing.m
#import "UIImage+Resizing.h"
#implementation UIImage (Resizing)
-(UIImage*)resizedImageWithSize:(CGSize)size {
CGImageRef cgImage = [self CGImage];
size_t bitsPerComponent = CGImageGetBitsPerComponent(cgImage);
size_t bytesPerRow = CGImageGetBytesPerRow(cgImage);
CGColorSpaceRef colorSpace = CGImageGetColorSpace(cgImage);
CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(cgImage);
CGContextRef context = CGBitmapContextCreate(nil, size.width, size.height, bitsPerComponent, bytesPerRow, colorSpace, bitmapInfo);
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGContextDrawImage(context, CGRectMake(0, 0, size.width, size.height), cgImage);
CGImageRef resizedImageRef = CGBitmapContextCreateImage(context);
UIImage *resizedImage = [UIImage imageWithCGImage:resizedImageRef];
CFRelease(resizedImageRef);
CFRelease(context);
return resizedImage;
}
#end

How to fix error when save UIImage with SPRectangle on IOS 6.0

This function return a black image. I use the Sparrow Library.
This is my code :
-(UIImage *) saveRectangle:(SPRectangle*)rectangle
{
int numberOfComponents = 8;
int width = rectangle.width;
int height = rectangle.height;
NSInteger bufferLenght = width * height * numberOfComponents;
NSMutableData * buffer= [NSMutableData dataWithLength:bufferLenght];
glPixelStorei(GL_PACK_ALIGNMENT, 4); // force 4 byte alignment
glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, [buffer mutableBytes]);
CGDataProviderRef ref = CGDataProviderCreateWithData(NULL, [buffer mutableBytes], bufferLenght, NULL);
CGImageRef iref = CGImageCreate(width, height, 8, 32, width * 4, CGColorSpaceCreateDeviceRGB(), kCGBitmapByteOrderDefault, ref, NULL, true, kCGRenderingIntentDefault);
uint32_t* pixels = (uint32_t *)malloc(bufferLenght);
CGContextRef context = CGBitmapContextCreate(pixels, width, height, 8, width*4, CGImageGetColorSpace(iref), kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Big);
CGContextTranslateCTM(context, 0.0, height);
CGContextScaleCTM(context, 1.0, -1.0);
CGContextDrawImage(context, CGRectMake(0.0, 0.0, width, height), iref);
CGImageRef outputRef = CGBitmapContextCreateImage(context);
free(pixels);
return [UIImage imageWithCGImage:outputRef];
}
The code you show has very little Sparrow code to it (other than the SPRectangle which is very akin to a CGRect). Sounds like you're trying to save a capture of a rectangular area of a Sparrow scene. Sparrow intends to abstract you from the OpenGL implementation details. Are you sure it wouldn't be easier to just use an SPRenderTexture? http://doc.sparrow-framework.org/core/Classes/SPRenderTexture.html
Also be sure you want to return an UIImage and not a SPImage. Hope it helps.

Drawing textures in OpenGL objective c os x

I tried to display a picture, but it is not displayed.
Here is my code for an NSOpenGLView subclass:
//
// MyOpenGLView.m
// OpenGLTests
//
// Created by Tom Schamberger on 10.12.12.
// Copyright (c) 2012 Tom Schamberger. All rights reserved.
//
#import "MyOpenGLView.h"
#implementation MyOpenGLView
- (id)initWithFrame:(NSRect)frame
{
NSOpenGLPixelFormat * pf = [MyOpenGLView basicPixelFormat];
self = [super initWithFrame: frame pixelFormat: pf];
return self;
}
+ (NSOpenGLPixelFormat*) basicPixelFormat
{
NSOpenGLPixelFormatAttribute attributes [] = {
NSOpenGLPFAWindow,
NSOpenGLPFADoubleBuffer, // double buffered
NSOpenGLPFADepthSize, (NSOpenGLPixelFormatAttribute)16, // 16 bit depth buffer
(NSOpenGLPixelFormatAttribute)nil
};
return [[NSOpenGLPixelFormat alloc] initWithAttributes:attributes];
}
- (void) prepareOpenGL
{
glEnable(GL_DEPTH_TEST);
glShadeModel(GL_SMOOTH);
glEnable(GL_CULL_FACE);
glFrontFace(GL_CCW);
glPolygonOffset (1.0f, 1.0f);
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);
if([self loadTextures])
NSLog(#"Load");
}
- (void)drawRect:(NSRect)dirtyRect
{
glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBindTexture( GL_TEXTURE_2D, texture);
glPolygonMode(GL_FRONT_AND_BACK,GL_LINE);
glColor3f(1, 1, 1);
glBegin( GL_QUADS );
glTexCoord2f( 0.0f, 0.0f);
glVertex2f( -0.5f, -0.5f);
glTexCoord2f( 1.0f, 0.0f);
glVertex2f( 0.5f, -0.5f);
glTexCoord2f( 1.0f, 1.0f);
glVertex2f( 0.5f, 0.5f);
glTexCoord2f( 0.0f, 1.0f);
glVertex2f( -0.5f, 0.5f);
glEnd();
glFlush();
}
- (BOOL) loadTextures
{
NSImage *img = [NSImage imageNamed:#"NeHe.bmp"];
if(img == nil)
return FALSE;
else if(img.size.height == 0 || img.size.width == 0)
return FALSE;
NSBitmapImageRep *rep = [[NSBitmapImageRep alloc] initWithData: [img TIFFRepresentation]];
glGenTextures( 1, &texture);
glBindTexture( GL_TEXTURE_2D, texture);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_BASE_LEVEL, 0);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAX_LEVEL, 0);
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, rep.size.width,
rep.size.height, 0, GL_RGB,
GL_UNSIGNED_BYTE, rep.bitmapData);
return TRUE;
}
#end
It draws a rectangle, but the texture is not displayed.
You should probably set you clear color alpha to 0.0 rather than 0.5
This code for loading a texture works.
backGroundPath = #"Background.bmp";
NSData* backGroundData = [NSData dataWithContentsOfFile:backGroundPath options:NSUncachedRead error:nil];
backGroundImage = [NSBitmapImageRep imageRepWithData:backGroundData];
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
glGenTextures( 1, backGroundTexture);
glBindTexture(GL_TEXTURE_2D, backGroundTexture[0]);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER,
GL_NEAREST);
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,
GL_NEAREST);
glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, backGroundImage.size.width,
backGroundImage.size.height, 0, GL_RGBA, GL_UNSIGNED_BYTE,
backGroundImage.bitmapData);

Rotated image should also follow the same pattern without white space

I am Rotating the image by using this code
- (CGImageRef)CGImageRotatedByAngle:(CGImageRef)imgRef angle:(CGFloat)angle
{
CGFloat angleInRadians = angle * (M_PI / 360);
CGFloat width = CGImageGetWidth(imgRef);
CGFloat height = CGImageGetHeight(imgRef);
CGRect imgRect = CGRectMake(0, 0, width, height);
CGAffineTransform transform = CGAffineTransformMakeRotation(angleInRadians);
CGRect rotatedRect = CGRectApplyAffineTransform(imgRect, transform);
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
CGContextRef bmContext = CGBitmapContextCreate(NULL,
rotatedRect.size.width,
rotatedRect.size.height,
8,
0,
colorSpace,
kCGImageAlphaPremultipliedFirst);
CGContextSetAllowsAntialiasing(bmContext, YES);
CGContextSetShouldAntialias(bmContext, YES);
CGContextSetInterpolationQuality(bmContext, kCGInterpolationHigh);
CGColorSpaceRelease(colorSpace);
CGContextTranslateCTM(bmContext,
+(rotatedRect.size.width/2),
+(rotatedRect.size.height/2));
CGContextRotateCTM(bmContext, angleInRadians);
CGContextTranslateCTM(bmContext,
-(rotatedRect.size.width/2),
-(rotatedRect.size.height/2));
CGContextDrawImage(bmContext, CGRectMake(0, 0,
rotatedRect.size.width,
rotatedRect.size.height),
imgRef);
CGImageRef rotatedImage = CGBitmapContextCreateImage(bmContext);
CFRelease(bmContext);
// [(id)rotatedImage autorelease];
return rotatedImage;
}
By this i am having the resultant image like this..
those white spaces should not be there and it should follow the same pattern of that size with out that white spaces around..the rotated image....
Please help..Thanks in advance

It says memory leaks when i do CGColorSpaceRelease(colorspace);..........not able to get error

CGColorSpaceRef colorspace = CGImageGetColorSpace(image);
CGContextRef context = CGBitmapContextCreate(NULL, width, height,
CGImageGetBitsPerComponent(image),
CGImageGetBytesPerRow(image),
colorspace,
CGImageGetAlphaInfo(image));
CGColorSpaceRelease(colorspace);
if(context == NULL)
return nil;
CGContextDrawImage(context, CGRectMake(0, 0, width, height), image);
CGImageRef imgRef = CGBitmapContextCreateImage(context);
CGContextRelease(context);
This is my full code....
CGBitmapContextCreate returns an object through the COPY operation. You need to release it too.
you must call CGContextRelease on context.