#include #include #include #include #include #include int nTex; TEXLIST *texlist; GLuint LoadTexture(char *filename) { FILE *file; GLuint tex; char *name; png_byte header[8]; png_structp png_ptr; png_infop info_ptr; png_bytep *row_pointers; png_bytep data; png_uint_32 width, height; int bit_depth, color_type, i; GLenum format; for(i = 0; i < nTex; i++) { if(strcasecmp(filename, texlist[i].name) == 0) return texlist[i].id; } name = malloc(strlen(filename)+5); strcpy(name, "tex/"); strcat(name, filename); file = fopen(name, "rb"); free(name); if(!file) return 0; fread(&header, 1, sizeof(header), file); if(png_sig_cmp(header, 0, sizeof(header))) { fclose(file); return 0; } png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if(!png_ptr) { fclose(file); return 0; } info_ptr = png_create_info_struct(png_ptr); if(!info_ptr) { png_destroy_read_struct(&png_ptr, NULL, NULL); fclose(file); return 0; } if(setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(file); return 0; } png_init_io(png_ptr, file); png_set_sig_bytes(png_ptr, sizeof(header)); png_read_info(png_ptr, info_ptr); width = png_get_image_width(png_ptr, info_ptr); height = png_get_image_height(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); if(color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if(color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) png_set_expand_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 < 8) png_set_packing(png_ptr); png_read_update_info(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); if((bit_depth != 8 && bit_depth != 16) || color_type & PNG_COLOR_MASK_PALETTE) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(file); return 0; } data = png_malloc(png_ptr, png_get_rowbytes(png_ptr, info_ptr)*height); row_pointers = png_malloc(png_ptr, height*png_sizeof(png_bytep)); for(i = 0; i < height; i++) row_pointers[i] = data + png_get_rowbytes(png_ptr, info_ptr)*i; png_read_image(png_ptr, row_pointers); switch(color_type) { case PNG_COLOR_TYPE_GRAY: format = GL_LUMINANCE; break; case PNG_COLOR_TYPE_GRAY_ALPHA: format = GL_LUMINANCE_ALPHA; break; case PNG_COLOR_TYPE_RGB: format = GL_RGB; break; case PNG_COLOR_TYPE_RGBA: format = GL_RGBA; break; default: png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(file); return 0; } glGenTextures(1, &tex); glBindTexture(GL_TEXTURE_2D, tex); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexImage2D(GL_TEXTURE_2D, 0, png_get_channels(png_ptr, info_ptr), width, height, 0, format, (bit_depth == 8) ? GL_UNSIGNED_BYTE : GL_UNSIGNED_SHORT, data); png_free(png_ptr, row_pointers); png_free(png_ptr, data); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); fclose(file); nTex++; if(nTex == 1) texlist = malloc(sizeof(TEXLIST)); else texlist = realloc(texlist, sizeof(TEXLIST)*nTex); strcpy(texlist[nTex-1].name, filename); texlist[nTex-1].id = tex; return tex; }