2005-04-18 15:27:00 +00:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <string.h>
|
|
|
|
#include <GL/gl.h>
|
|
|
|
#include <zoom/texture.h>
|
2007-05-11 19:37:01 +00:00
|
|
|
#include <png.h>
|
2005-04-18 15:27:00 +00:00
|
|
|
|
|
|
|
|
|
|
|
int nTex;
|
|
|
|
TEXLIST *texlist;
|
|
|
|
|
2007-05-11 19:37:01 +00:00
|
|
|
|
2005-04-18 15:27:00 +00:00
|
|
|
GLuint LoadTexture(char *filename) {
|
2007-05-11 19:37:01 +00:00
|
|
|
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;
|
2005-04-18 15:27:00 +00:00
|
|
|
}
|