Texture Mapping on Mac OS X doesn't work

Started by
5 comments, last by Dave Hunt 10 years, 11 months ago

Hi together,

I am currently facing an issue running my OpenGL App.

First i startet to use the GLUT functions to create my rendering Context (Window).

Inside the App I initialized textures using glGenTexture and glTexImage2D and so on.

Now I switched to NSOpenGLView and NSOpenGLPixelFormat.

I copied the whole Code that worked fine for me in my GLUT App but I am getting a white window.

When I take out my rendering and just clear the Color_Buffer to yellow I get a yellow window (as expected).

Even if I only draw on the right half of the screen it comes up white on the whole screen.

Now to my implementation :)

Inside the NSOpenglView drawrect function i call:


    [[self openGLContext] clearDrawable];
    [[self openGLContext] setView:self];
    [[self openGLContext] makeCurrentContext];
    
    NSRect backingBounds = [self convertRectToBacking:[self bounds]];
    
    GLsizei backingPixelWidth  = (GLsizei)(backingBounds.size.width),
    backingPixelHeight = (GLsizei)(backingBounds.size.height);
    
    glViewport(0, 0, backingPixelWidth, backingPixelHeight);
    glEnable(GL_TEXTURE_2D);
    glClearColor(1, 1, 0, 0);
    glClear(GL_COLOR_BUFFER_BIT);
    [interface draw];
    
    [[self openGLContext] flushBuffer];
    [NSOpenGLContext clearCurrentContext];

I create a normal window with an OpenGLContext.

Do I have to initiate my OpenGL Stuff anywhere special? Stuff like glEnable(GL_Texture_2D) ?

I hope someone of you already had this issue.

I appreciate any help :)

Advertisement

So, you're having trouble drawing textures, but you haven't shown any of the code that loads the textures or draws them. We're going to need to see more code if we're going to help you.

The most common cause of your problem is that the texture(s) failed to load properly, or you failed to set the texture onto the device before drawing (glBindTexture).

Thanks for your answer.

The code for loading textures is as follows:


-(BOOL)loadTexture:(NSString *)_name {
    if ([_name isEqualToString:@""]) {
        return NO;
    }
    NSString *substring = [_name substringFromIndex:_name.length-4];
    if ([substring isNotEqualTo:@".JPG"] && [substring isNotEqualTo:@".jpg"] && [substring isNotEqualTo:@".png"]) {
        return NO;
    }
    NSBundle *bundle = [NSBundle mainBundle];
    NSString *path = bundle.bundlePath;
    path = [NSString stringWithFormat:@"%@/Contents/Resources/%@",path,_name];

    NSImage *image = [[NSImage alloc] initWithContentsOfFile:path];
    if (image == nil) {
        return NO;
    }
    NSRect bigRect;
    bigRect.origin = NSZeroPoint;
    bigRect.size = [image size];
    [image lockFocus];
    NSBitmapImageRep *upsideDown = [[NSBitmapImageRep alloc] initWithFocusedViewRect: bigRect];
    [image unlockFocus];
    
    // since OpenGL draws images upside down, we need to flip this image along
    // the y axis. I know a cool trick for doing this when texture mapping,
    // but I want something a little more general for now
    NSInteger bytesPerRow = [upsideDown bytesPerRow];
    NSInteger bitsPerPixel = [upsideDown bitsPerPixel];
    BOOL hasAlpha = [upsideDown hasAlpha];
    NSInteger height = (int)bigRect.size.height;
    NSBitmapImageRep *_imageRep = [[NSBitmapImageRep alloc]
                 initWithBitmapDataPlanes:NULL
                 pixelsWide:(int)bigRect.size.width
                 pixelsHigh:height
                 bitsPerSample:[upsideDown bitsPerSample]
                 samplesPerPixel:[upsideDown samplesPerPixel]
                 hasAlpha:hasAlpha
                 isPlanar:[upsideDown isPlanar]
                 colorSpaceName:NSCalibratedRGBColorSpace
                 bytesPerRow:bytesPerRow
                 bitsPerPixel:bitsPerPixel];
    unsigned char *from = [upsideDown bitmapData];
    unsigned char *to = [_imageRep bitmapData];
    for (int i = 0; i < height; i++) {
        bcopy((from + bytesPerRow + i), (to + bytesPerRow + (height - i - 1)), bytesPerRow);
    }
    
    GLenum format;
    format = hasAlpha ? GL_RGBA : GL_RGB;
    GLuint _tex;
    glGenTextures(1, &_tex);
    glBindTexture(GL_TEXTURE_2D, _tex);
    
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glPixelStorei(GL_UNPACK_ROW_LENGTH, (GLint)bytesPerRow / (bitsPerPixel >> 3));
    glTexImage2D(GL_TEXTURE_2D,
                0,
                GL_RGBA,
                bigRect.size.width,
                bigRect.size.height,
                0,
                format,
                GL_UNSIGNED_BYTE,
                from);
    
    [image release];
    [upsideDown release];
    [_imageRep release];
    
    texturename[texturecount] = _name;
    [texturename[texturecount] retain];
    int *temp = malloc((texturecount*sizeof(int))+1*sizeof(int));
    for (int count = 0; count<texturecount; count++) {
        temp[count] = textureid[count];
    }
    free(textureid);
    textureid = temp;
    textureid[texturecount] = _tex;
    texturecount ++;
    return YES;
}

It's a whole lot of Code I copied it from another thread.

It worked fine for my old app.

I have a class called TextureLoader which keeps all the information like texture name and the corresponding opengl name as an int.

When a texture is asked for it will beloaded by the TextureLoader


-(GLuint)textureidforTexturename:(NSString *)_name {
    for (int x = 0; x < texturecount; x++) {
        if ([texturename[x] isEqualToString:_name]) {
            return textureid[x];
        }
    }
    if ([self loadTexture:_name]) {
        return textureid[texturecount-1];
    }
    else {
        printf("not found\n");
        return 0; 
    }
}

So what I do at the start of my app is create a window and inside a NSOpenGLView.

when I just clear the buffer and draw on the right side of my screen it comes up yellow and red for example. So this works.

Tanks a lot :)

And the code that actually draws using a texture?

Also, you might want to add a call to glGetError and see if an error is being generated. If glGetError returns a non-zero value, then you can start tracking down which GL function set the error.

Finally, you might want to read Apple's OpenGL Programming Guide for Mac. There is good information there on where to put the various initialization bits, etc.

You can try debugging with OpenGL Profiler, it will show you if there are any errors in your OpenGL calls, and you can even make it break the execution like a breakpoint when an error is thrown. You might need to download Graphics Tools for XCode to get the OpenGL Profiler.

Many thanks for your answers Dave and patrrr,

It was a result of many thinks that are different from cocoa and glut.

First I had to call the makeCurrentContext for the NSOpenglContext which set up the Context.

I somehow had to call it explicitly.

And another reason was that glut get(GLUT_WINDOW_WIDTH) and the corresponding GLUT_WINDOW_HEIGHT didn't work under cocoa.

they both returned 0. I set up my interface using the width and height of the window to make it more smooth.

And cause they both returned 0 my glviewport for the interface was set to 0,0,0,0. :(

Terrible mistake sorry for wasting you time :)

But thanks to your replies i figured it out Tanks!! :)

Excellent. Glad you got it sorted out.

This topic is closed to new replies.

Advertisement