是用了第三方库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);