iDevGames Forums
libpng transparency problem - Printable Version

+- iDevGames Forums (http://www.idevgames.com/forums)
+-- Forum: Development Zone (/forum-3.html)
+--- Forum: Graphics & Audio Programming (/forum-9.html)
+--- Thread: libpng transparency problem (/thread-3453.html)



libpng transparency problem - wyrmmage - Mar 1, 2007 04:15 PM

I'm using a bit of modified code that I got from OneSadCookie's site at sometime in the past (can't remember the link, sorry)...anyway, I'm basically loading the data from a .png image and feeding it to OpenGl to create my texture...it works fine, but it doesn't seem to support transparency in the images. This may be a bit much to ask, but...here's the code, if you could look through it, I would be grateful Smile

Code:
FILE *PNG_file = fopen(fileName, "rb");
    if (PNG_file == NULL)
    {
        fprintf(stderr, "Can't open PNG file %s\n", fileName);
    }
    
    GLubyte PNG_header[PNG_HEADER_SIZE];
    
    fread(PNG_header, 1, PNG_HEADER_SIZE, PNG_file);
    if (png_sig_cmp(PNG_header, 0, PNG_HEADER_SIZE) != 0)
    {
        fprintf(stderr, "%s is not a PNG file\n", fileName);
    }
    
    png_structp PNG_reader
        = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (PNG_reader == NULL)
    {
        fprintf(stderr, "Can't start reading PNG file %s\n", fileName);
        fclose(PNG_file);
    }

    png_infop PNG_info = png_create_info_struct(PNG_reader);
    if (PNG_info == NULL)
    {
        fprintf(stderr, "Can't get info for PNG file %s\n", fileName);
        png_destroy_read_struct(&PNG_reader, NULL, NULL);
        fclose(PNG_file);
    }

    png_infop PNG_end_info = png_create_info_struct(PNG_reader);
    if (PNG_end_info == NULL)
    {
        fprintf(stderr, "Can't get end info for PNG file %s\n", fileName);
        png_destroy_read_struct(&PNG_reader, &PNG_info, NULL);
        fclose(PNG_file);
    }
    
    if (setjmp(png_jmpbuf(PNG_reader)))
    {
        fprintf(stderr, "Can't load PNG file %s\n", fileName);
        png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
        fclose(PNG_file);
    }
    
    png_init_io(PNG_reader, PNG_file);
    png_set_sig_bytes(PNG_reader, PNG_HEADER_SIZE);
    
    png_read_info(PNG_reader, PNG_info);
    
    png_uint_32 width, height;
    width = png_get_image_width(PNG_reader, PNG_info);
    height = png_get_image_height(PNG_reader, PNG_info);
    
    png_uint_32 bit_depth, color_type;
    bit_depth = png_get_bit_depth(PNG_reader, PNG_info);
    color_type = png_get_color_type(PNG_reader, PNG_info);
    
    if (color_type == PNG_COLOR_TYPE_PALETTE)
    {
    //png_set_palette_to_rgb(PNG_reader);
    png_set_palette_to_rgb(PNG_reader);
    }
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
    {
    png_set_gray_1_2_4_to_8(PNG_reader);
    }
    if (color_type == PNG_COLOR_TYPE_GRAY || color_type == PNG_COLOR_TYPE_GRAY_ALPHA)
    {
    png_set_gray_to_rgb(PNG_reader);
    }
    if (png_get_valid(PNG_reader, PNG_info, PNG_INFO_tRNS))
    {
    png_set_tRNS_to_alpha(PNG_reader);
    }
    else
    {
    png_set_filler(PNG_reader, 0xff, PNG_FILLER_AFTER);
    }
    if (bit_depth == 16)
    {
        png_set_strip_16(PNG_reader);
    }
    
    png_read_update_info(PNG_reader, PNG_info);
    
    png_byte* PNG_image_buffer = (png_byte*)malloc(4 * width * height);
    png_byte** PNG_rows = (png_byte**)malloc(height * sizeof(png_byte*));
    
    unsigned int row;
    for (row = 0; row < height; ++row)
    {
        PNG_rows[height - 1 - row] = PNG_image_buffer + (row * 4 * width);
    }
    
    png_read_image(PNG_reader, PNG_rows);
    
    free(PNG_rows);
    
    png_destroy_read_struct(&PNG_reader, &PNG_info, &PNG_end_info);
    fclose(PNG_file);
    
    imageWidth = width;
    imageHeight = height;
    data = PNG_image_buffer;
    
    
// Generate one texture and let m_uiTexID be our handle to it
    glGenTextures(1, &m_uiTexID);
  
    // Here we set up the filtering.
    glBindTexture(GL_TEXTURE_2D, m_uiTexID);
    glTexEnvf( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );
    glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER,GL_LINEAR_MIPMAP_NEAREST);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);
    glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT);

    // and here we feed our width, height and pixels to OpenGL
    gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA, imageWidth, imageHeight, GL_RGBA, GL_UNSIGNED_BYTE, data);

Thanks everyone Smile
-wyrmmage


libpng transparency problem - OneSadCookie - Mar 1, 2007 04:28 PM

Code looks fine. Try turning on blending or something.


libpng transparency problem - wyrmmage - Mar 1, 2007 04:39 PM

ok, thanks, I'll try experimenting with some other programs that export transparencies Smile
-wyrmmage


libpng transparency problem - OneSadCookie - Mar 1, 2007 05:53 PM

If Preview shows the PNG transparent, it should look transparent when loaded with that code.

Much more likely than that your graphics program is buggy is that the software you've written that's loading the image is buggy. In particular, transparency is not automatic in OpenGL. You need to set an appropriate blend function and enable blending.