libpng transparency problem

Moderator
Posts: 373
Joined: 2006.08
Post: #1
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

Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #2
Code looks fine. Try turning on blending or something.
Quote this message in a reply
Moderator
Posts: 373
Joined: 2006.08
Post: #3
ok, thanks, I'll try experimenting with some other programs that export transparencies Smile
-wyrmmage

Worlds at War (Current Project) - http://www.awkward-games.com/forum/
Quote this message in a reply
Luminary
Posts: 5,143
Joined: 2002.04
Post: #4
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.
Quote this message in a reply
Post Reply 

Possibly Related Threads...
Thread: Author Replies: Views: Last Post
  libPng And Memory Access Violations Jaden 12 12,721 Sep 4, 2013 04:50 AM
Last Post: miye
  Sprite transparency in OpenGL? Guest! 26 30,673 Feb 17, 2012 09:24 AM
Last Post: Skorche
  OpenGL ES 2.0, 2D Alpha Transparency Artifacts Macmenace 3 8,206 Mar 28, 2010 11:18 PM
Last Post: AnotherJake
  libpng loading junk at bottom of my OpenGL textures...? BinarySpike 6 6,300 Apr 19, 2007 12:20 PM
Last Post: BinarySpike
  Trouble writing PNGs with 16 bits per channel using libpng flash 2 3,938 Aug 28, 2006 11:01 AM
Last Post: flash