Become a MacRumors Supporter for $50/year with no ads, ability to filter front page stories, and private forums.

davbeck

macrumors regular
Original poster
May 16, 2008
104
0
Reno, NV
I am trying to figure out this crazy world of OpenGL, specifically on mac and iphone.

I have a function that takes a path to a image and turns it into an opengl texture. bmp seems to work fine but not png. The problem is that when I use NSBitmapImageRep to get the pixel data which represents it as having one pane. the cautionary if statement blocks any weird stuff from happening.

Code:
- (void)textureFromPath:(NSString *)path textureID:(GLuint *)texName {
	NSBitmapImageRep *bitmap = [NSBitmapImageRep imageRepWithContentsOfFile:path];
    int samplesPerPixel = 0;
	
	//glPixelStorei(GL_UNPACK_ROW_LENGTH, [bitmap pixelsWide]); // 4
    //glPixelStorei(GL_UNPACK_ALIGNMENT, 1); // 5
    if (*texName == 0)
		glGenTextures (1, texName);
	
	glBindTexture(GL_TEXTURE_2D, *texName);
    //glBindTexture(GL_TEXTURE_RECTANGLE_ARB, *texName);
	
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
                    GL_TEXTURE_MIN_FILTER, GL_LINEAR);
    samplesPerPixel = [bitmap samplesPerPixel];
	
	if(![bitmap isPlanar] &&
       (samplesPerPixel == 3 || samplesPerPixel == 4)) {
        glTexImage2D(GL_TEXTURE_2D,		//GL_TEXTURE_RECTANGLE_ARB,
                     0,
                     samplesPerPixel == 4 ? GL_RGBA8 : GL_RGB8,
                     [bitmap pixelsWide],
                     [bitmap pixelsHigh],
                     0,
                     samplesPerPixel == 4 ? GL_RGBA : GL_RGB,
                     GL_UNSIGNED_BYTE,
					 [bitmap bitmapData]);
    }
	[bitmap release];
}
 

kainjow

Moderator emeritus
Jun 15, 2000
7,958
7
Not sure about the png issue, but the [bitmap release] is incorrect as bitmap is an autoreleased object and calling release without a retain will cause it to crash later when it gets released by the autorelease pool.
 

davbeck

macrumors regular
Original poster
May 16, 2008
104
0
Reno, NV
Now that you mention it, it should crash later but it doesn't. curious.

I have attached an example of what happens when I try to bring in a png.
 

Attachments

  • color.png
    color.png
    8 KB · Views: 1,607
  • Picture 1.png
    Picture 1.png
    9.3 KB · Views: 1,597

lazydog

macrumors 6502a
Sep 3, 2005
709
6
Cramlington, UK
Hi
It looks to me like your image needs to be inverted… OpenGL uses the bottom left corner as ( 0, 0 ). The shearing effect might be because your image is using padding bytes at the end of each row, or the dimensions aren't a power of two.

b e n
 

davbeck

macrumors regular
Original poster
May 16, 2008
104
0
Reno, NV
I finally got it working using imageio. I am posting the function for future generations.

Code:
- (void)textureFromPath:(NSString *)path textureID:(GLuint *)texName {
	CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
        //xCode troughs a warning about using NSString instead of CFString but since they are compatible it works anyway.
	
	CGImageSourceRef myImageSourceRef = CGImageSourceCreateWithURL(url, NULL);
	CGImageRef myImageRef = CGImageSourceCreateImageAtIndex (myImageSourceRef, 0, NULL);
	size_t width = CGImageGetWidth(myImageRef);
	size_t height = CGImageGetHeight(myImageRef);
	
	CGRect rect = {{0, 0}, {width, height}};
	void * myData = calloc(width * 4, height);
	CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
	CGContextRef myBitmapContext = CGBitmapContextCreate (myData,
	 width, height, 8,
	 width*4, space,
	 kCGBitmapByteOrder32Host |
	 kCGImageAlphaPremultipliedFirst);
	CGContextDrawImage(myBitmapContext, rect, myImageRef);
	CGContextRelease(myBitmapContext);
	glPixelStorei(GL_UNPACK_ROW_LENGTH, width);
	glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
	glGenTextures(1, texName);
	glBindTexture(GL_TEXTURE_RECTANGLE_ARB, *texName);
	glTexParameteri(GL_TEXTURE_RECTANGLE_ARB,
					GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexImage2D(GL_TEXTURE_2D,
                 0,
                 GL_RGBA8,
                 width, height,
                 0,
                 GL_BGRA_EXT,
                 GL_UNSIGNED_INT_8_8_8_8_REV,
                 myData);
	free(myData);
}
 

Krevnik

macrumors 601
Sep 8, 2003
4,101
1,312
Code:
	CFURLRef url = CFURLCreateWithFileSystemPath(NULL, path, kCFURLPOSIXPathStyle, NO);
        //xCode troughs a warning about using NSString instead of CFString but since they are compatible it works anyway.

You can get rid of the warning by using an explicit type cast, like so:
Code:
	CFURLRef url = CFURLCreateWithFileSystemPath(NULL, (CFStringRef)path, kCFURLPOSIXPathStyle, NO);

Both types are pointers, so it will work. It will rid you of one more warning to worry about.
 
Register on MacRumors! This sidebar will go away, and you'll see fewer ads.