Flipping a texture loaded using QuickTime..

Craig
Unregistered
 
Post: #1
Hi,

I've just started developing on the mac (coming from a windows / directx background Ninja) and I was hoping someone could point me in the right direction on a better solution for this problem.

I'm loading in images from disk/memory and using the QuickTime API to decompress the images to make them suitable for use as an OpenGL texture. I've got everything working, but since QuickTime uses the top left as 0,0 and OpenGL uses bottom left as 0,0 the images are the wrong way round...

I need to be able to use non-power of two images, so I am stuck with using the GL_TEXTURE_RECTANGLE_EXT target which means I can't use the trick of flipping the texutre coordinates (since OpenGL can only clamp, or clap to edge using this extension? Thus it doesn't mirror it. I had the texture coordinate trick working with the GL_TEXTURE_2D target, but the same code wouldn't work with GL_TEXTURE_RECTANGLE_EXT).

This is the code I use to decompress the image data, I get _pQtGraphicsImporter from either GetGraphicsImporterForDataRef(..) or GetGraphicsImporterForFile(..).

Code:
+ (Image*) loadImageFromQuickTimeGraphicsImporter:(GraphicsImportComponent*) _pQtGraphicsImporter
{
    Rect imageBounds;    
    GWorldPtr qtGraphicsWorld = 0;
    OSErr error = noErr;
    ComponentResult result = noErr;
    
    result = GraphicsImportGetNaturalBounds((*_pQtGraphicsImporter), &imageBounds);
    
    if(noErr != result)
    {
        NSLog(@"Failed to get natural bounds");
    }
    
    // Check bounds
    if(imageBounds.top != 0)
    {
        return nil;
    }
    
    if(imageBounds.left != 0)
    {
        return nil;
    }
    
    // Get width/height
    int width = imageBounds.right;
    int height = imageBounds.bottom;    
    
    // Create buffer for image data to be "drawn" into, 32bit (i.e. 4 bytes per pixel)
    int imageDataBufferSize = 4 * width * height;
    void* pImageDataBuffer = malloc(imageDataBufferSize);

/*    // This doesn't work!? Just gives me a black texture
    // Flip image
    short tempTop = imageBounds.top;
    imageBounds.top = imageBounds.bottom;
    imageBounds.bottom = tempTop;
*/    
    // Create offscreen world using the buffer just created, the uncompressed image data will be "drawn" into here - we can then use this to create an OpenGL texture
    error = QTNewGWorldFromPtr(&qtGraphicsWorld, k32ARGBPixelFormat, &imageBounds, NULL, NULL, 0, pImageDataBuffer, 4 * width);
    
    if(noErr != error)
    {
        NSLog(@"Failed to create GWorld");
        free(pImageDataBuffer);
        return nil;
    }
    
    result = GraphicsImportSetGWorld(*_pQtGraphicsImporter, qtGraphicsWorld, NULL);
    
    if(noErr != result)
    {
        NSLog(@"Failed to set GWorld");
        free(pImageDataBuffer);
        return nil;
    }
    
    result = GraphicsImportDraw(*_pQtGraphicsImporter);

    if(noErr != result)
    {
        NSLog(@"Failed to decompress image");
        free(pImageDataBuffer);
        return nil;
    }

    // Release grahpics world
    DisposeGWorld(qtGraphicsWorld);
    
    // Create our Image object to hold this data
    // The image object will own this image data, the caller MUST release the image object once there are done with it. Otherwise the image data WILL be leaked!
    Image* image = [[Image alloc] initWithImageData:pImageDataBuffer imageDataSize:imageDataBufferSize imageWidth:width imageHeight:height];
    
    return image;
}

A bit of searching seemed to suggest I could "swap the top and bottom of the bounds rectangle" I pass to QTNewGWorldFromPtr(..) but unfortunatly when I tried that all I got was a black texture Sad As you can see I tried to do it like this...

Code:
short tempTop = imageBounds.top;
imageBounds.top = imageBounds.bottom;
imageBounds.bottom = tempTop;

.. is that the correct way?

I got around the problem by turning off culling and rotating the quad I've attached the texture to by 180 degrees around the y-axis, which works, but feels a little "hacky". I'm thinking there surely must be a better way to do this, which is also fast? I don't want to manually flip all the pixels myself as a post operaton.

Platform: Mac Mini 1.5GHz, 1GB RAM, OSX 10.4, Xcode 2.2

Thanks for your time,

Craig
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
You can perfectly well flip the texture coordinates (send 1 - t instead of t), but you can also have QuickTime flip the image for you. From memory, the rectangle you swap the top and bottom of is the one you pass to GraphicsImportDraw, but source that does it is here: http://onesadcookie.com/svn/repos/QTValuePak
Quote this message in a reply
Moderator
Posts: 1,140
Joined: 2005.07
Post: #3
I second the suggestion to flip your texture coordinates. It will definitely decrease load times. Or, if you want, you can also flip the images outside of your program, then you won't have to use the processor time to flip the images or flip the texture coordinates.
Quote this message in a reply
Sage
Posts: 1,232
Joined: 2002.10
Post: #4
Or flip your projection matrix so the origin is at the top left.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  Render video (e.g. QuickTime) to buffer or texture? Ingemar 14 13,567 Jun 8, 2011 04:09 PM
Last Post: mdejong1024
  Cocoa loaded textures have white edges Jake 6 4,258 May 6, 2005 09:17 AM
Last Post: Jake
  Streaming Quicktime to OpenGL Texture Holmes 5 4,938 Jul 12, 2004 10:54 PM
Last Post: kelvin
  SDL & Quicktime DM6 4 3,491 Jul 4, 2004 08:22 AM
Last Post: Steven
  Fully Loaded Question Muffinking 4 3,463 Jun 4, 2003 09:57 PM
Last Post: Iceman