diff options
author | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-07-26 23:47:58 +0000 |
---|---|---|
committer | taw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5> | 2008-07-26 23:47:58 +0000 |
commit | fbc0bae8423e37cf6155fdc091ac02897a465adc (patch) | |
tree | e39326690eca2f08fe5c95305c1be31ebdd945c4 /src | |
parent | ed5740b6f667628f344d9dd17686424ce9e2de82 (diff) |
Add 'gentexture' utility
git-svn-id: svn://cook.msm.cam.ac.uk:745/thrust3d/thrust3d@177 84d2e878-0bd5-11dd-ad15-13eda11d74c5
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 4 | ||||
-rw-r--r-- | src/gentexture.c | 196 |
2 files changed, 199 insertions, 1 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index a3b6e6b..5539d18 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -1,10 +1,12 @@ -bin_PROGRAMS = thrust3d +bin_PROGRAMS = thrust3d gentexture thrust3d_SOURCES = main.c model.c render.c physics.c game.c texture.c utils.c audio.c render-text.c #glcheck_SOURCES = glcheck.c #glcheck_LDADD = -lglut +gentexture_SOURCES = gentexture.c + AM_CFLAGS = -Wall AM_CPPFLAGS = -DDATADIR=\""$(datadir)"/thrust3d\" diff --git a/src/gentexture.c b/src/gentexture.c new file mode 100644 index 0000000..d43f8b5 --- /dev/null +++ b/src/gentexture.c @@ -0,0 +1,196 @@ +/* + * gentexture.c + * + * Generate normal map stuff + * + * (c) 2008 Thomas White <taw27@cam.ac.uk> + * + * thrust3d - a silly game + * + */ + +#ifdef HAVE_CONFIG_H +#include <config.h> +#endif + +#include <png.h> +#include <stdlib.h> +#include <stdint.h> + +int main(int argc, char *argv[]) { + + FILE *fh; + png_bytep header; + png_structp png_ptr; + png_infop info_ptr; + png_infop end_info; + unsigned int width; + unsigned int height; + unsigned int bit_depth; + unsigned int channels; + png_bytep *row_pointers; + unsigned int x; + unsigned int y; + uint8_t *texels; + char *filename; + char *outfilename; + + filename = argv[1]; + outfilename = argv[2]; + + /* Open file */ + fh = fopen(filename, "rb"); + if ( !fh ) { + fprintf(stderr, "Couldn't open texture file '%s'\n", filename); + return 1; + } + + /* Check it's actually a PNG file */ + header = malloc(8); + fread(header, 1, 8, fh); + if ( png_sig_cmp(header, 0, 8)) { + fprintf(stderr, "Texture file '%s' is not a PNG file.\n", filename); + free(header); + fclose(fh); + return 1; + } + free(header); + + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if ( !png_ptr ) { + fprintf(stderr, "Couldn't create PNG read structure.\n"); + fclose(fh); + return 1; + } + + info_ptr = png_create_info_struct(png_ptr); + if ( !info_ptr ) { + png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + fprintf(stderr, "Couldn't create PNG info structure.\n"); + fclose(fh); + return 1; + } + + end_info = png_create_info_struct(png_ptr); + if ( !end_info ) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + printf("Couldn't create PNG end info structure.\n"); + fclose(fh); + return 1; + } + + if ( setjmp(png_jmpbuf(png_ptr)) ) { + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fh); + fprintf(stderr, "PNG read failed.\n"); + return 1; + } + + png_init_io(png_ptr, fh); + png_set_sig_bytes(png_ptr, 8); + + /* Read! */ + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + 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); + channels = png_get_channels(png_ptr, info_ptr); + if ( bit_depth != 8 ) { + fprintf(stderr, "Texture image '%s' doesn't have 8 bits per channel per pixel.\n", filename); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fh); + return 1; + } + if ( channels != 4 ) { + fprintf(stderr, "Texture image '%s' doesn't have 4 channels.\n", filename); + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fh); + return 1; + } + + /* Get image data */ + row_pointers = png_get_rows(png_ptr, info_ptr); + + texels = malloc(4*width*height); + for ( y=0; y<height; y++ ) { + for ( x=0; x<width; x++ ) { + + unsigned int r, g, b, a; + + r = row_pointers[y][(channels*x)+0]; + g = row_pointers[y][(channels*x)+1]; + b = row_pointers[y][(channels*x)+2]; + a = row_pointers[y][(channels*x)+3]; + + texels[4*(x + width*(height-1-y)) + 0] = r; + texels[4*(x + width*(height-1-y)) + 1] = g; + texels[4*(x + width*(height-1-y)) + 2] = b; + texels[4*(x + width*(height-1-y)) + 3] = a; + + } + } + + png_destroy_read_struct(&png_ptr, &info_ptr, &end_info); + fclose(fh); + + fh = fopen(outfilename, "wb"); + if (!fh) { + fprintf(stderr, "Couldn't open output file.\n"); + return 1; + } + png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if ( !png_ptr ) { + fprintf(stderr, "Couldn't create PNG write structure.\n"); + fclose(fh); + return 1; + } + info_ptr = png_create_info_struct(png_ptr); + if ( !info_ptr ) { + png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + fprintf(stderr, "Couldn't create PNG info structure.\n"); + fclose(fh); + return 1; + } + if ( setjmp(png_jmpbuf(png_ptr)) ) { + png_destroy_write_struct(&png_ptr, &info_ptr); + fclose(fh); + fprintf(stderr, "PNG write failed.\n"); + return 1; + } + png_init_io(png_ptr, fh); + + png_set_IHDR(png_ptr, info_ptr, width, height, 8, PNG_COLOR_TYPE_RGBA, PNG_INTERLACE_NONE, + PNG_COMPRESSION_TYPE_DEFAULT, PNG_FILTER_TYPE_DEFAULT); + + /* Write the image data */ + row_pointers = malloc(height*sizeof(png_bytep *)); + + for ( y=0; y<height; y++ ) { + row_pointers[y] = malloc(width*4); + for ( x=0; x<width; x++ ) { + + row_pointers[y][4*x+0] = texels[4*(x + width*(height-1-y)) + 0]; + row_pointers[y][4*x+1] = texels[4*(x + width*(height-1-y)) + 1]; + row_pointers[y][4*x+2] = texels[4*(x + width*(height-1-y)) + 2]; + row_pointers[y][4*x+3] = texels[4*(x + width*(height-1-y)) + 3]; + + } + } + + png_set_rows(png_ptr, info_ptr, row_pointers); + png_write_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + + png_destroy_write_struct(&png_ptr, &info_ptr); + for ( y=0; y<height; y++ ) { + free(row_pointers[y]); + } + free(row_pointers); + fclose(fh); + + free(texels); + + return 0; + +} + |