OpenGL 读取显示PNG图片(C/C++版)

是用了第三方库libpng

参考前面一篇读取BMP的文章

头文件

#include "libpng/png.h"

...

typedef struct{
    GLsizei width;
    GLsizei height;
    GLenum format;
    GLint internalFormat;
    GLuint id;
    GLubyte *texels;
}gl_texture_t;
/* Texture id for the demo */

 gl_texture_t *ReadPNGFromFile(const char *filename);
    GLuint loadPNGTexture(const char *filename);

 

源文件

ps:在一个外文网站看到的,链接地址忘了,对它进行了一些修改,如果觉得过多就自己修改吧。

有些确实是不大必要的

gl_texture_t * SilderBar::ReadPNGFromFile (const char *filename)
{
    gl_texture_t *texinfo;
    png_byte magic[8];
    png_structp png_ptr;
    png_infop info_ptr;
    int bit_depth, color_type;
    FILE *fp = NULL;
    png_bytep *row_pointers = NULL;
    png_uint_32 w, h;
    int i;
    /* Open image file */
    fp = fopen (filename, "rb");
    if (!fp)
    {
        fprintf (stderr, "error: couldn't open \"%s\"!\n", filename);
        return NULL;
    }
    /* Read magic number */
    fread (magic, 1, sizeof (magic), fp);
    /* Check for valid magic number */
    if (!png_check_sig (magic, sizeof (magic)))
    {
        fprintf (stderr, "error: \"%s\" is not a valid PNG image!\n", filename);
        fclose (fp);
        return NULL;
    }
    /* Create a png read struct */
    png_ptr = png_create_read_struct (PNG_LIBPNG_VER_STRING, NULL, NULL, NULL);
    if (!png_ptr)
    {
        fclose (fp);
        return NULL;
    }
    /* Create a png info struct */
    info_ptr = png_create_info_struct (png_ptr);
    if (!info_ptr)
    {
        fclose (fp);
        png_destroy_read_struct (&png_ptr, NULL, NULL);
        return NULL;
    }
    /* Create our OpenGL texture object */
    texinfo = (gl_texture_t *) malloc (sizeof (gl_texture_t));
    /* Initialize the setjmp for returning properly after a libpng error occured */
    if (setjmp (png_jmpbuf (png_ptr)))
    {
        fclose (fp);
        png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
        if (row_pointers) free (row_pointers);
        if (texinfo) {
            if (texinfo->texels)
                free (texinfo->texels);
            free (texinfo);
        }
        return NULL;
    }
    /* Setup libpng for using standard C fread() function with our FILE pointer */
    png_init_io (png_ptr, fp);
    /* Tell libpng that we have already read the magic number */
    png_set_sig_bytes (png_ptr, sizeof (magic));
    /* Read png info */
    png_read_info (png_ptr, info_ptr);
    /* Get some usefull information from header */
    bit_depth = png_get_bit_depth (png_ptr, info_ptr);
    color_type = png_get_color_type (png_ptr, info_ptr);
    /* Convert index color images to RGB images */
    if (color_type == PNG_COLOR_TYPE_PALETTE)
        png_set_palette_to_rgb (png_ptr);
    /* Convert 1-2-4 bits grayscale images to 8 bits grayscale. */
    if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8)
        png_set_gray_1_2_4_to_8 (png_ptr);
    if (png_get_valid (png_ptr, info_ptr, PNG_INFO_tRNS))
        png_set_tRNS_to_alpha (png_ptr);
    if (bit_depth == 16) png_set_strip_16 (png_ptr);
    else if (bit_depth < 8) png_set_packing (png_ptr);
    /* Update info structure to apply transformations */
    png_read_update_info (png_ptr, info_ptr);
    /* Retrieve updated information */
    png_get_IHDR (png_ptr, info_ptr, &w, &h, &bit_depth, &color_type, NULL, NULL, NULL);
    texinfo->width = w;
    texinfo->height = h;
    /* Get image format and components per pixel */
    GetPNGtextureInfo (color_type, texinfo);
    /* We can now allocate memory for storing pixel data */
    texinfo->texels = (GLubyte *)malloc (sizeof (GLubyte) * texinfo->width * texinfo->height * texinfo->internalFormat);
    /* Setup a pointer array. Each one points at the begening of a row. */
    row_pointers = (png_bytep *)malloc (sizeof (png_bytep) * texinfo->height);
    for (i = 0; i < texinfo->height; ++i)
    {
        row_pointers[i] = (png_bytep)(texinfo->texels + ((texinfo->height - (i + 1)) * texinfo->width * texinfo->internalFormat));
    }
    /* Read pixel data using row pointers */
    png_read_image (png_ptr, row_pointers);
    /* Finish decompression and release memory */
    png_read_end (png_ptr, NULL);
    png_destroy_read_struct (&png_ptr, &info_ptr, NULL);
    /* We don't need row pointers anymore */
    free (row_pointers);
    fclose (fp);
    return texinfo;
}

GLuint SilderBar::loadPNGTexture (const char *filename)
{
    gl_texture_t *png_tex = NULL;
    GLuint tex_id = 0;
    GLint alignment;
    png_tex = ReadPNGFromFile (filename);
    if (png_tex && png_tex->texels)
    {
        /* Generate texture */
        glGenTextures (1, &png_tex->id);
        glBindTexture (GL_TEXTURE_2D, png_tex->id);
        /* Setup some parameters for texture filters and mipmapping */
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        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);
        glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE);
       
        glGetIntegerv (GL_UNPACK_ALIGNMENT, &alignment);
        glPixelStorei (GL_UNPACK_ALIGNMENT, 1);
        glTexImage2D (GL_TEXTURE_2D, 0, png_tex->internalFormat, png_tex->width, png_tex->height, 0, png_tex->format, GL_UNSIGNED_BYTE, png_tex->texels);

        glPixelStorei (GL_UNPACK_ALIGNMENT, alignment);
        tex_id = png_tex->id;
        /* OpenGL has its own copy of texture data */
        free (png_tex->texels);
        free (png_tex);
    }
    return tex_id;
}

 

画图

//防止反复读取

   if(zSlider == 0)
    {
        zSlider = loadPNGTexture(FileNamePng);
    }

//透明效果
    glEnable (GL_BLEND);
    glBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);

 

    glEnable(GL_TEXTURE_2D);
    glLoadIdentity();
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
    glBindTexture(GL_TEXTURE_2D, zSlider);
    glBegin(GL_POLYGON);
        glTexCoord2f(0.0f, 0.0f); glVertex3f(0.0f, 0.0f, 0.0f);
        glTexCoord2f(0.0f, 1.0f); glVertex3f(0.0f, 0.3f, 0.0f);
        glTexCoord2f(1.0f, 1.0f); glVertex3f(0.2f, 0.3f,0.0f);
        glTexCoord2f(1.0f, 0.0f); glVertex3f(0.2f, 0.0f, 0.0f);
    glEnd();
    glDisable(GL_TEXTURE_2D);
    glDisable (GL_BLEND);

 

你可能感兴趣的:(OpenGL 读取显示PNG图片(C/C++版))