aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authortaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-07-26 23:47:58 +0000
committertaw27 <taw27@84d2e878-0bd5-11dd-ad15-13eda11d74c5>2008-07-26 23:47:58 +0000
commitfbc0bae8423e37cf6155fdc091ac02897a465adc (patch)
treee39326690eca2f08fe5c95305c1be31ebdd945c4 /src
parented5740b6f667628f344d9dd17686424ce9e2de82 (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.am4
-rw-r--r--src/gentexture.c196
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;
+
+}
+