Porting SDL to Cocoa OpenGL view--texture problem

smittyz
Unregistered
 
Post: #1
Hey everyone.

I ported a project from last semester's graphics class from SDL to a native Cocoa OGL view. The work wasn't too bad, and I never really liked SDL anyway Wink

The problem I'm having is that for some reason, only two of my seven textures are loading properly. The others appear to be loaded corrupted. I'm using the same custom-targa class to do the image loading. All of the OpenGL code is being re-used exactly as-is from the SDL based program. Is there something "special" I have to do to get textures loaded properly when I'm not using SDL's window management (I was never using SDL to load images...). Here are two screenshots, the first from the working SDL based program, the second from the Cocoa based program.

Even the OpenGL profiler shows the textures as being corrupted once they are loaded. Thanks for anyone's insight.

[Image: pic1.png]

[Image: pic2.png]
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Impossible to say without showing us your texture loading code...
Quote this message in a reply
Moderator
Posts: 370
Joined: 2006.08
Post: #3
I'm assuming you enabled blending? (I think you have to do that to get textures working right, but it might be for lighting, lol Rasp)
-wyrmmage

Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Quote this message in a reply
smittyz
Unregistered
 
Post: #4
OneSadCookie Wrote:Impossible to say without showing us your texture loading code...

Wink Ok, here you go. Note the hardcoded GL_RGB pixel format is just my debugging. In my SDL based version, I actually had it hardcoded to GL_RGB, since is the format of all the images.

Code:
- (BOOL) loadTextures
{
    GLuint i;
    NSBundle *bundle;
    CTargaImage *img;
    
    bundle = [NSBundle bundleForClass:[self class]];

    NSAutoreleasePool *pool = [[NSAutoreleasePool alloc] init];
    
    for (i=0; i<NUM_TEXTURES; i++)
    {
        NSString *imgPath;

        if (imgPath = [bundle pathForResource:[NSString stringWithUTF8String:textureFiles[i]] ofType:@"tga"])
        {
            img = [[[CTargaImage alloc] init] autorelease];
            if ([img Load:[imgPath UTF8String]] == NO)
            {
                NSLog(@"couldn't load texture resource %@", imgPath);
                [img release];
                return NO;
            }
            //[img release];
        }
        else
        {
            NSLog(@"couldn't find resource in bundle");
            return NO;
        }

        
        //GLint imgType = [img imageColorDepth] == 32 ? GL_RGBA : GL_RGB;
        GLint imgType = GL_RGB;
        
         glGenTextures(1, &hTexture[i]);
        glBindTexture(GL_TEXTURE_2D, hTexture[i]);
            
        glTexImage2D(GL_TEXTURE_2D,
                     0,
                     imgType,
                     [img width],
                     [img height],
                     0,
                     imgType,
                     GL_UNSIGNED_BYTE,
                     [img imageData]);
        if (glGetError() != GL_NO_ERROR)
            NSLog(@"error with glTexImage");

        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    
    }
    
    [pool release];

    return YES;
}
Quote this message in a reply
smittyz
Unregistered
 
Post: #5
wyrmmage Wrote:I'm assuming you enabled blending? (I think you have to do that to get textures working right, but it might be for lighting, lol Rasp)
-wyrmmage

Don't have blending enabled, but it didn't make any difference...
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #6
You still haven't shown all the relevant code...
Quote this message in a reply
smittyz
Unregistered
 
Post: #7
OneSadCookie Wrote:You still haven't shown all the relevant code...

You asked for the texture loading code. If you want the targa image class, I'll post that up too. If there is something else specific I can provide, please let me know.

This code was ObjC-ified from a C++ class, and is based on the class provided with *Beginning OpenGL Game Programming* by Dave Astle.

Code:
#import <Cocoa/Cocoa.h>
#import "CTargaImage.h"


@implementation CTargaImage


#pragma mark --- Initialization ---

- (id) init
{
    self = [super init];
    if (self)
    {
        
    }
    return self;
}

/*
- (id) initWithFile:(NSString *) fileName
{
    self = [self init];
    if (self)
    {
        [self Load:fileName];
    }
    return self;
}
*/

- (void) dealloc
{
    [self Release];
    
    [super dealloc];
}



#pragma mark --- Class Implementation ---

- (void) SwapRedBlue
{
    switch (m_colorDepth)
    {
    case 32:
        {
            unsigned char temp;
            rgba_t* source = (rgba_t*)m_pImageData;

            for (int pixel = 0; pixel < (m_width * m_height); ++pixel)
            {
                temp = source[pixel].b;
                source[pixel].b = source[pixel].r;
                source[pixel].r = temp;
            }
        } break;
    case 24:
        {
            unsigned char temp;
            rgb_t* source = (rgb_t*)m_pImageData;

            for (int pixel = 0; pixel < (m_width * m_height); ++pixel)
            {
                temp = source[pixel].b;
                source[pixel].b = source[pixel].r;
                source[pixel].r = temp;
            }
        } break;
    default:
        // ignore other color depths
        break;
    }
}


- (BOOL) Load:(const char *) filename
{
    FILE *pFile = fopen(filename, "rb");

    if (!pFile)
        return NO;

    tgaheader_t tgaHeader;

    // read the TGA header
    fread(&tgaHeader, 1, sizeof(tgaheader_t), pFile);

    // see if the image type is one that we support (RGB, RGB RLE, GRAYSCALE, GRAYSCALE RLE)
    if ( ((tgaHeader.imageTypeCode != TGA_RGB) && (tgaHeader.imageTypeCode != TGA_GRAYSCALE) &&
         (tgaHeader.imageTypeCode != TGA_RGB_RLE) && (tgaHeader.imageTypeCode != TGA_GRAYSCALE_RLE)) ||
         tgaHeader.colorMapType != 0)
    {
        fclose(pFile);
        return NO;
    }

    // get image width and height
    m_width = tgaHeader.width;
    m_height = tgaHeader.height;

    // colormode -> 3 = BGR, 4 = BGRA
    int colorMode = tgaHeader.bpp / 8;

    // we don't handle less than 24 bit
    if (colorMode < 3)
    {
        fclose(pFile);
        return NO;
    }

    m_imageSize = m_width * m_height * colorMode;

    // allocate memory for TGA image data
    //m_pImageData = new unsigned char[m_imageSize];
    m_pImageData = malloc(sizeof(unsigned char) * m_imageSize);

    // skip past the id if there is one
    if (tgaHeader.idLength > 0)
        fseek(pFile, SEEK_CUR, tgaHeader.idLength);

    // read image data
    if (tgaHeader.imageTypeCode == TGA_RGB || tgaHeader.imageTypeCode == TGA_GRAYSCALE)
    {
        fread(m_pImageData, 1, m_imageSize, pFile);
    }
    else
    {
        // this is an RLE compressed image
        unsigned char iid;
        unsigned char length;
        rgba_t color = { 0, 0, 0, 0 };
        unsigned int i = 0;

        while (i < m_imageSize)
        {
            iid = fgetc(pFile);

            // see if this is run length data
            if (iid >= 128)// & 0x80)
            {
                // find the run length
                length = (unsigned char)(iid - 127);

                // next 3 (or 4) bytes are the repeated values
                color.b = (unsigned char)fgetc(pFile);
                color.g = (unsigned char)fgetc(pFile);
                color.r = (unsigned char)fgetc(pFile);

                if (colorMode == 4)
                    color.a = (unsigned char)fgetc(pFile);

                // save everything in this run
                while (length > 0)
                {
                    m_pImageData[i++] = color.b;
                    m_pImageData[i++] = color.g;
                    m_pImageData[i++] = color.r;

                    if (colorMode == 4)
                        m_pImageData[i++] = color.a;

                    --length;
                }
            }
            else
            {
                // the number of non RLE pixels
                length = (unsigned char) (iid + 1);

                while (length > 0)
                {
                    color.b = (unsigned char)fgetc(pFile);
                    color.g = (unsigned char)fgetc(pFile);
                    color.r = (unsigned char)fgetc(pFile);

                    if (colorMode == 4)
                        color.a = (unsigned char)fgetc(pFile);

                    m_pImageData[i++] = color.b;
                    m_pImageData[i++] = color.g;
                    m_pImageData[i++] = color.r;

                    if (colorMode == 4)
                        m_pImageData[i++] = color.a;

                    --length;
                }
            }
        }
    }

    fclose(pFile);

    switch(tgaHeader.imageTypeCode)
    {
    case TGA_RGB:
    case TGA_RGB_RLE:
        if (3 == colorMode)
        {
            m_imageDataFormat = IMAGE_RGB;
            m_imageDataType = IMAGE_DATA_UNSIGNED_BYTE;
            m_colorDepth = 24;
        }
        else
        {
            m_imageDataFormat = IMAGE_RGBA;
            m_imageDataType = IMAGE_DATA_UNSIGNED_BYTE;
            m_colorDepth = 32;
        }
        break;

    case TGA_GRAYSCALE:
    case TGA_GRAYSCALE_RLE:
        m_imageDataFormat = IMAGE_LUMINANCE;
        m_imageDataType = IMAGE_DATA_UNSIGNED_BYTE;
        m_colorDepth = 8;
        break;
    }

    if ((tgaHeader.imageDesc & TOP_LEFT) == TOP_LEFT)
        [self FlipVertical];
    
    // swap the red and blue components in the image data
    [self SwapRedBlue];
    
    return (m_pImageData != NULL);
}

- (BOOL) FlipVertical
{
    if (!m_pImageData)
        return NO;

    if (m_colorDepth == 32)
    {
        //rgba_t* tmpBits = new rgba_t[m_width];
        rgba_t *tmpBits = malloc(sizeof(rgba_t) * m_width);
        if (!tmpBits)
            return NO;
        
        int lineWidth = m_width * 4;

        rgba_t* top = (rgba_t*)m_pImageData;
        rgba_t* bottom = (rgba_t*)(m_pImageData + lineWidth*(m_height-1));

        for (int i = 0; i < (m_height / 2); ++i)
        {
            memcpy(tmpBits, top, lineWidth);
            memcpy(top, bottom, lineWidth);
            memcpy(bottom, tmpBits, lineWidth);

            top = (rgba_t*)((unsigned char*)top + lineWidth);
            bottom = (rgba_t* )((unsigned char*)bottom - lineWidth);
        }

        free(tmpBits);
        //delete [] tmpBits;
        tmpBits = 0;
    }
    else if (m_colorDepth == 24)
    {
        //rgb_t* tmpBits = new rgb_t[m_width];
        rgb_t *tmpBits = malloc(sizeof(rgb_t) * m_width);
        if (!tmpBits)
            return NO;

        int lineWidth = m_width * 3;

        rgb_t* top = (rgb_t*)m_pImageData;
        rgb_t* bottom = (rgb_t*)(m_pImageData + lineWidth*(m_height-1));

        for (int i = 0; i < (m_height / 2); ++i)
        {
            memcpy(tmpBits, top, lineWidth);
            memcpy(top, bottom, lineWidth);
            memcpy(bottom, tmpBits, lineWidth);

            top = (rgb_t*)((unsigned char*)top + lineWidth);
            bottom = (rgb_t*)((unsigned char*)bottom - lineWidth);
        }

        //delete [] tmpBits;
        free(tmpBits);
        tmpBits = 0;
    }

    return YES;
}

- (void) Release
{
//    delete [] m_pImageData;
    if (m_pImageData)
    {
        free(m_pImageData);
        m_pImageData = NULL;
    }
}

- (BOOL) ConvertRGBToRGBA:(unsigned char) alphaValue
{
    if ((m_colorDepth == 24) && (m_imageDataFormat == IMAGE_RGB))
    {
        //rgba_t *newImage = new rgba_t[m_width * m_height];
        rgba_t *newImage = malloc(sizeof(rgba_t) * m_width * m_height);

        if (!newImage)
            return NO;

        rgba_t *dest = newImage;
        rgb_t *src = (rgb_t*)m_pImageData;

        for (int x = 0; x < m_height; x++)
        {
            for (int y = 0; y < m_width; y++)
            {
                dest->r = src->r;
                dest->g = src->g;
                dest->b = src->b;
                dest->a = alphaValue;

                ++src;
                ++dest;
            }
        }

        free(m_pImageData);
        //delete [] m_pImageData;
        m_pImageData = (unsigned char*)newImage;

        m_colorDepth = 32;
        m_imageDataType = IMAGE_DATA_UNSIGNED_BYTE;
        m_imageDataFormat = IMAGE_RGBA;
        
        return YES;
    }

    return NO;
}

- (BOOL) ConvertRGBAToRGB
{
    if ((m_colorDepth == 32) && (m_imageDataFormat == IMAGE_RGBA))
    {
        //rgb_t *newImage = new rgb_t[m_width * m_height];
        rgb_t *newImage = malloc(sizeof(rgb_t) * m_width * m_height);

        if (!newImage)
            return NO;

        rgb_t *dest = newImage;
        rgba_t *src = (rgba_t*)m_pImageData;

        for (int x = 0; x < m_height; x++)
        {
            for (int y = 0; y < m_width; y++)
            {
                dest->r = src->r;
                dest->g = src->g;
                dest->b = src->b;

                ++src;
                ++dest;
            }
        }

        free(m_pImageData);
        //delete [] m_pImageData;
        m_pImageData = (unsigned char*)newImage;

        m_colorDepth = 24;
        m_imageDataType = IMAGE_DATA_UNSIGNED_BYTE;
        m_imageDataFormat = IMAGE_RGB;

        return YES;
    }

    return NO;
}


- (unsigned char *) imageData
{
    return m_pImageData;
}


- (unsigned char) imageColorDepth
{
    return m_colorDepth;
}

- (unsigned short) width
{
    return m_width;
}

- (unsigned short) height
{
    return m_height;
}

@end
Quote this message in a reply
smittyz
Unregistered
 
Post: #8
Well, I fixed the problem but am still not sure what the root cause was. I opened each of my textures in Gimp and re-saved them (made no other modifications) . They are all rendering fine now. Sorry for wasting everyone's time Smile
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  OpenGL ES Texture Masking airfire 6 13,710 Mar 17, 2014 07:07 PM
Last Post: baioses
  OpenGL ES Texture Compression ajrs84 9 3,201 May 7, 2013 03:36 PM
Last Post: ajrs84
  OpenGL Alpha Channel Problem Moganza 1 2,685 Jan 19, 2013 08:25 AM
Last Post: sealfin
  OpenGL ES Texture Masking dalasjoe sin 0 3,646 Apr 13, 2012 12:17 AM
Last Post: dalasjoe sin
  Opengl/Cocoa text rendering tesil 15 16,277 Mar 20, 2012 11:16 AM
Last Post: OneSadCookie