/* Copyright (C) 2000 Xavier Hosxe This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ /* * Png algorithm from the libpng.... * */ #include "pngtex.hpp" PngTex::PngTex() { width=0; height=0; openGL_tex = NULL; } PngTex::PngTex(const char* file_name) { FILE *fp = fopen(file_name, "rb"); png_byte header[8]; png_structp png_ptr; openGL_tex = NULL; if (!fp) { printf("Error while loading '%s'\n", file_name); exit(12); } // Read a chunk to check if this is indeed a png file... fread( header, 1, sizeof(header), fp); if (png_sig_cmp(header, (png_size_t)0, 4)) { printf("not png type %s", file_name); exit(12); } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (!png_ptr) { printf( "error while reading png_structp"); exit(12); } png_infop info_ptr = png_create_info_struct(png_ptr); if (!info_ptr) { png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); printf( "error while reading info_struct"); exit(12); } png_infop end_info = png_create_info_struct(png_ptr); if (!end_info) { png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); printf( "error while reading info_struct"); exit(12); } png_init_io(png_ptr, fp); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, &compression_type, &filter_type); png_bytep * row_pointers ; row_pointers = new png_bytep[height]; png_uint_32 row; for (row = 0; row < height; row++) { int size; row_pointers[row] = new png_byte[(size=png_get_rowbytes(png_ptr, info_ptr))]; } png_read_image(png_ptr, row_pointers); openGL_tex= new char[height*width*4]; png_uint_32 i,j; for(j = 0; j < height; j++) { for (i=0; i < width;i++) { int scale = 3 + (PNG_COLOR_TYPE_RGB_ALPHA==color_type); openGL_tex[(j*width+i)*4 ] = (char)*(char*)( row_pointers[j] +i*scale) ; openGL_tex[(j*width+i)*4 +1 ] = (char)*(char*)( row_pointers[j] +i*scale +1 ) ; openGL_tex[(j*width+i)*4 +2 ] = (char)*(char*)( row_pointers[j] +i*scale +2 ) ; if (color_type==PNG_COLOR_TYPE_RGB) openGL_tex[(j*width+i)*4 +3 ] = (char)255 ; else openGL_tex[(j*width+i)*4 +3 ] = (char)*(char*)( row_pointers[j] +i*scale +3 ) ; } } png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); fclose(fp); for (row = 0; row < height; row++) { delete [] row_pointers[row]; } delete []row_pointers; } void PngTex::bindToTexture(GLuint &texture) { glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glGenTextures(1, & texture ); glBindTexture(GL_TEXTURE_2D, texture); gluBuild2DMipmaps(GL_TEXTURE_2D, GL_RGBA16, width, height, GL_RGBA, GL_UNSIGNED_BYTE, openGL_tex); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR); /* glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST_MIPMAP_NEAREST); */ glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); } PngTex::~PngTex() { if (openGL_tex!=NULL) delete []openGL_tex; }