tags:

views:

114

answers:

2

Hello,

I am working on my first OpenGL application using Cocoa (I have used OpenGL ES on the iPhone) and I am having trouble loading a texture from an image file. Here is my texture loading code:

@interface MyOpenGLView : NSOpenGLView 
{
GLenum texFormat[ 1 ];   // Format of texture (GL_RGB, GL_RGBA)
NSSize texSize[ 1 ];     // Width and height

GLuint textures[1];     // Storage for one texture
}

- (BOOL) loadBitmap:(NSString *)filename intoIndex:(int)texIndex
{
BOOL success = FALSE;
NSBitmapImageRep *theImage;
int bitsPPixel, bytesPRow;
unsigned char *theImageData;

NSData* imgData = [NSData dataWithContentsOfFile:filename options:NSUncachedRead error:nil];

theImage = [NSBitmapImageRep imageRepWithData:imgData]; 

if( theImage != nil )
{
    bitsPPixel = [theImage bitsPerPixel];
    bytesPRow = [theImage bytesPerRow];
    if( bitsPPixel == 24 )        // No alpha channel
        texFormat[texIndex] = GL_RGB;
    else if( bitsPPixel == 32 )   // There is an alpha channel
        texFormat[texIndex] = GL_RGBA;
    texSize[texIndex].width = [theImage pixelsWide];
    texSize[texIndex].height = [theImage pixelsHigh];

    if( theImageData != NULL )
    {
        NSLog(@"Good so far...");
        success = TRUE;

        // Create the texture

        glGenTextures(1, &textures[texIndex]);

        NSLog(@"tex: %i", textures[texIndex]);

        NSLog(@"%i", glIsTexture(textures[texIndex]));

        glPixelStorei(GL_UNPACK_ROW_LENGTH, [theImage pixelsWide]);

        glPixelStorei(GL_UNPACK_ALIGNMENT, 1);

        // Typical texture generation using data from the bitmap
        glBindTexture(GL_TEXTURE_2D, textures[texIndex]);

        NSLog(@"%i", glIsTexture(textures[texIndex]));

        glTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, texSize[texIndex].width, texSize[texIndex].height, 0, texFormat[texIndex], GL_UNSIGNED_BYTE, [theImage bitmapData]);

        NSLog(@"%i", glIsTexture(textures[texIndex]));
    }
}


return success;
}

It seems that the glGenTextures() function is not actually creating a texture because textures[0] remains 0. Also, logging glIsTexture(textures[texIndex]) always returns false.

Any suggestions?

Thanks,

Kyle

+1  A: 
glGenTextures(1, &textures[texIndex] );

What is your textures definition?

glIsTexture only returns true if the texture is already ready. A name returned by glGenTextures, but not yet associated with a texture by calling glBindTexture, is not the name of a texture.

Check if the glGenTextures is by accident executed between glBegin and glEnd -- that's the only official failure reason.

Also:

Check if the texture is square and has dimensions that are a power of 2.

Although it isn't emphasized anywhere enough iPhone's OpenGL ES implementation requires them to be that way.

Kornel Kisielewicz
It is defined as `GLuint textures[1]` (I updated my post to include the header definition). I also check `glIsTexture()` after I call `glBindTexture()`, it still returns false. It isn't called between `glBegin()` and `glEnd()` either, it gets called in the initialization method before the timer gets started. The texture is a 256x256 PNG file.
Kyle
This is actually wrong. glIsTexture will return true for any texture name that was bound. It does not have to be "ready" (which, in OpenGL terms is called complete). Also, I'm surprised that iPhone textures have to be square. power of 2, yeah... but square ? I'm pretty sure the GL ES spec requires say a 32x16 texture to work.
Bahbar
@Bahbar: http://www.opengl.org/sdk/docs/man/xhtml/glIsTexture.xml
Kornel Kisielewicz
@Kornel: this page says exactly what I said. It needs to have been called with glBindTexture (i.e. it was previously bound). Nothing to do with being ready. what about the square bit ?
Bahbar
A: 

OK, I figured it out. It turns out that I was trying to load the textures before I set up my context. Once I put loading textures at the end of the initialization method, it worked fine.

Thanks for the answers.

Kyle

Kyle