diff options
author | Stijn Buys <ingar@osirion.org> | 2008-08-23 12:04:21 +0000 |
---|---|---|
committer | Stijn Buys <ingar@osirion.org> | 2008-08-23 12:04:21 +0000 |
commit | 02e9a70009f79064043033abc5e597930aa11079 (patch) | |
tree | 606615f7ed162f9acc1e91f03b9745a12637d41a | |
parent | 375b7d96a3974a03416c600b579048e48f1580a2 (diff) |
PNG support
-rw-r--r-- | configure.in | 9 | ||||
-rw-r--r-- | doc/index.html | 4 | ||||
-rw-r--r-- | doc/installation.html | 3 | ||||
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/filesystem/diskfile.cc | 5 | ||||
-rw-r--r-- | src/filesystem/diskfile.h | 1 | ||||
-rw-r--r-- | src/filesystem/file.cc | 5 | ||||
-rw-r--r-- | src/filesystem/file.h | 2 | ||||
-rw-r--r-- | src/render/Makefile.am | 5 | ||||
-rw-r--r-- | src/render/image.h | 2 | ||||
-rw-r--r-- | src/render/pngfile.cc | 122 | ||||
-rw-r--r-- | src/render/pngfile.h | 34 | ||||
-rw-r--r-- | src/render/textures.cc | 34 | ||||
-rw-r--r-- | src/render/tga.cc | 2 |
14 files changed, 213 insertions, 17 deletions
diff --git a/configure.in b/configure.in index 1a6aee7..3c6db7a 100644 --- a/configure.in +++ b/configure.in @@ -193,6 +193,15 @@ else AC_SUBST(GL_LIBS) AC_SUBST(GL_CFLAGS) + AC_CHECK_HEADER(png.h, + HAVE_OPENGL=yes + AC_DEFINE(HAVE_PNG, 1, [Define this if you have libpng]), + AC_MSG_WARN([libpng include file png.h not found]) + ) + + LIBPNG_LIBS="-lpng" + AC_SUBST(LIBPNG_LIBS) + AC_CHECK_HEADER(AL/al.h, HAVE_OPENGL=yes AC_DEFINE(HAVE_OPENAL, 1, [Define this if you have OpenAL]), diff --git a/doc/index.html b/doc/index.html index 7974f9b..fd3006d 100644 --- a/doc/index.html +++ b/doc/index.html @@ -62,7 +62,7 @@ <h2> Project contributors </h2> -<p> + <table><TR> <td>Ingar=KCT=</td> <td>Game design, programming, modelling, graphics, sounds @@ -91,6 +91,8 @@ alpha testing </td></tr> </table> +<p> + Refer to the <A href="assets.html">list of assets</a> for a complete overview. <h2> Website </h2> diff --git a/doc/installation.html b/doc/installation.html index 7981a7f..545aff7 100644 --- a/doc/installation.html +++ b/doc/installation.html @@ -83,7 +83,7 @@ cd osirion-0.1_258-linux <tr><td>SDL</td><td>version 1.2 or newer</td></tr> <tr><td>OpenGL</td><td>version 1.1 or newer</td></tr> <tr><td>OpenAL</td><td>version 1.1 or newer</td></tr> - + <tr><td>libpng</td><td>version 1.2 or newer</td></tr> </table> <p> You will also need a recent version of gcc, GNU make, automake and libtool. @@ -92,6 +92,7 @@ cd osirion-0.1_258-linux supported by SDL, reports for other platforms (working or not) are welcome. I have succesfully compiled it myself on the following platforms: <table> + <tr><td>linux-x86_64</td><td>gcc 4.3.1</td></tr> <tr><td>linux-x86_64</td><td>gcc 4.1.2</td></tr> <tr><td>linux-i686</td><td>gcc 4.1.2</td></tr> <tr><td>mingw32 </td><td>gcc 4.2.2</td></tr> diff --git a/src/Makefile.am b/src/Makefile.am index 15dfcb9..a3a5c03 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -40,5 +40,5 @@ osirion_LDADD = $(top_builddir)/src/game/libgame.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/model/libmodel.la \ $(top_builddir)/src/math/libmath.la $(top_builddir)/src/auxiliary/libauxiliary.la \ $(top_builddir)/src/filesystem/libfilesystem.la $(top_builddir)/src/sys/libsys.la \ - $(top_builddir)/src/auxiliary/libauxiliary.la $(AL_LIBS) $(GL_LIBS) $(HOST_LIBS) $(ICON_CLIENT) + $(top_builddir)/src/auxiliary/libauxiliary.la $(AL_LIBS) $(GL_LIBS) $(HOST_LIBS) $(LIBPNG_LIBS) $(ICON_CLIENT) osirion_LDFLAGS = $(LIBSDL_LIBS) diff --git a/src/filesystem/diskfile.cc b/src/filesystem/diskfile.cc index 56e2727..6554f1e 100644 --- a/src/filesystem/diskfile.cc +++ b/src/filesystem/diskfile.cc @@ -20,6 +20,11 @@ DiskFile::~DiskFile() fclose(diskfile_handle); } +FILE *DiskFile::handle() +{ + return diskfile_handle; +} + bool DiskFile::open(const char *filename) { if (diskfile_handle) { diff --git a/src/filesystem/diskfile.h b/src/filesystem/diskfile.h index b71576d..7da1a88 100644 --- a/src/filesystem/diskfile.h +++ b/src/filesystem/diskfile.h @@ -31,6 +31,7 @@ public: virtual size_t read(void *buffer, size_t count); + virtual FILE *handle(); void skip(size_t count); private: diff --git a/src/filesystem/file.cc b/src/filesystem/file.cc index 07f8870..91ac9f9 100644 --- a/src/filesystem/file.cc +++ b/src/filesystem/file.cc @@ -13,5 +13,10 @@ File::File() {} File::~File() {} +FILE *File::handle() +{ + return 0; +} + } // namespace filesystem diff --git a/src/filesystem/file.h b/src/filesystem/file.h index 37ac8b4..daef174 100644 --- a/src/filesystem/file.h +++ b/src/filesystem/file.h @@ -27,6 +27,8 @@ public: /// close file virtual void close() = 0; + virtual FILE *handle(); + /// read bytes virtual size_t read(void *buffer, size_t count) = 0; diff --git a/src/render/Makefile.am b/src/render/Makefile.am index 7069f97..99b1847 100644 --- a/src/render/Makefile.am +++ b/src/render/Makefile.am @@ -9,7 +9,8 @@ endif librender_la_LDFLAGS = -avoid-version -no-undefined @GL_LIBS@ librender_la_LIBADD = $(top_builddir)/src/math/libmath.la -librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc render.cc \ - text.cc textures.cc tga.cc +librender_la_SOURCES = camera.cc draw.cc dust.cc gl.cc image.cc pngfile.cc \ + render.cc text.cc textures.cc tga.cc noinst_HEADERS = camera.h draw.h dust.h gl.h image.h render.h text.h textures.h \ tga.h +_SOURCES = pngfile.h diff --git a/src/render/image.h b/src/render/image.h index a129773..c9cc029 100644 --- a/src/render/image.h +++ b/src/render/image.h @@ -7,6 +7,8 @@ #ifndef __INCLUDED_RENDER_IMAGE_H__ #define __INCLUDED_RENDER_IMAGE_H__ +#include <string> + namespace render { /// RGB (24bpp) or RGBA (32bpp) image data diff --git a/src/render/pngfile.cc b/src/render/pngfile.cc new file mode 100644 index 0000000..14884f0 --- /dev/null +++ b/src/render/pngfile.cc @@ -0,0 +1,122 @@ +/* + render/png.cc + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + +/* +Notes: + +http://www.zarb.org/~gc/html/libpng.html + +*/ + +#include <string.h> +#include <png.h> + +#include <iostream> + +#include "filesystem/filesystem.h" +#include "render/pngfile.h" +#include "sys/sys.h" + +namespace render { + +Image *PNG::load(const char *filename) +{ + Image *image = 0; + + if (!filename) + return 0; + + filesystem::File *png_file = filesystem::open(filename); + if (!png_file) { + //con_warn << "Could not open " << filename << std::endl; + return 0; + } + + png_byte header[8]; + memset(header, 0, sizeof(header)); + + if (!png_file->read(header, 8)) { + con_warn << "Error reading " << filename << std::endl; + filesystem::close(png_file); + return 0; + } + if (png_sig_cmp(header, 0, 8)) { + con_warn << "Error reading " << filename << ": not a PNG file!" << std::endl; + filesystem::close(png_file); + return 0; + } + + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); + if (!png_ptr) { + con_warn << "Error reading " << filename << ": png_create_read_struct failed!" << std::endl; + filesystem::close(png_file); + return 0; + } + + png_infop info_ptr = png_create_info_struct(png_ptr); + if (!info_ptr) { + con_warn << "Error reading " << filename << ": png_create_info_struct failed!" << std::endl; + filesystem::close(png_file); + return 0; + } + if (setjmp(png_jmpbuf(png_ptr))) { + con_warn << "Error reading " << filename << ": error during init_io!" << std::endl; + filesystem::close(png_file); + return 0; + } + + /* read the PNG header */ + png_init_io(png_ptr, png_file->handle()); + png_set_sig_bytes(png_ptr, 8); + + png_read_info(png_ptr, info_ptr); + + int png_width = info_ptr->width; + int png_height = info_ptr->height; + //int png_color_type = info_ptr->color_type; + int png_depth = info_ptr->bit_depth; + + //int number_of_passes = png_set_interlace_handling(png_ptr); + png_set_interlace_handling(png_ptr); + png_read_update_info(png_ptr, info_ptr); + + if (png_depth != 8) { + con_warn << "Error reading " << filename << ": bits per channel must be 8!" << std::endl; + filesystem::close(png_file); + return 0; + } + + unsigned int channels = info_ptr->rowbytes / png_width; + image = new Image(png_width, png_height, channels); + + /* read image data */ + if (setjmp(png_jmpbuf(png_ptr))) { + con_warn << "Error reading " << filename << std::endl; + filesystem::close(png_file); + delete image; + return 0; + } + + png_bytep row_pointers[png_height]; + + for (size_t i=0; i < (size_t)png_height; i++) + row_pointers[i] = (png_bytep) (*image)[i * info_ptr->rowbytes]; + + png_read_image(png_ptr, row_pointers); + + filesystem::close(png_file); + + con_debug << " " << filename << " " << png_width << "x" << png_height << "x" << channels * png_depth << "bpp" << std::endl; + + return image; +} + +void PNG::save(const char *filename, Image & image) +{ + con_warn << "PNG::save stub" << std::endl; +} + +} diff --git a/src/render/pngfile.h b/src/render/pngfile.h new file mode 100644 index 0000000..a7beb7c --- /dev/null +++ b/src/render/pngfile.h @@ -0,0 +1,34 @@ +/* + render/png.h + This file is part of the Osirion project and is distributed under + the terms of the GNU General Public License version 2 +*/ + + +#ifndef _INCLUDED_RENDER_PNGFILE_H_ +#define _INCLUDED_RENDER_PNGFILE_H_ + +#include "render/image.h" + +namespace render +{ + +/// a class for loading and saving .png files +class PNG { + +public: + /// load a PNG image file from disk + /** @param filename short path to the filename to be loaded + */ + static Image *load(const char * filename); + + /// write an image to a PNG file + /** @param filename short path to the file to write the image data to + */ + static void save(const char *filename, Image & image); +}; + +} + +#endif //_INCLUDED_RENDER_PNGFILE_H_ + diff --git a/src/render/textures.cc b/src/render/textures.cc index 2bc6c05..6ceb7cd 100644 --- a/src/render/textures.cc +++ b/src/render/textures.cc @@ -9,6 +9,7 @@ #include "render/gl.h" #include "render/textures.h" #include "render/tga.h" +#include "render/pngfile.h" #include "sys/sys.h" #include "core/application.h" @@ -66,23 +67,34 @@ size_t Textures::load(std::string name, bool filter) if (it != registry.end()) return (*it).second; - // try the tga version - std::string filename(name); - filename.append(".tga"); - Image *image = TGA::load(filename.c_str()); - if (!image) { - // add to the registry with id 0 (texture not found) - registry[name] = 0; - return 0; - } - if (index == MAXTEXTURES) { con_error << "Texture limit " << MAXTEXTURES << " exceeded!" << std::endl; - delete image; registry[name] = 0; return 0; } + std::string filename; + Image *image = 0; + + // try the png version + filename.assign(name); + filename.append(".png"); + image = PNG::load(filename.c_str()); + + if (!image) { + // try the tga version + filename.assign(name); + filename.append(".tga"); + image = TGA::load(filename.c_str()); + + if (!image) { + // add to the registry with id 0 (texture not found) + con_warn << "Could not open " << filename << std::endl; + registry[name] = 0; + return 0; + } + } + size_t id = index; glGenTextures(1, &textures[id]); diff --git a/src/render/tga.cc b/src/render/tga.cc index 6a85130..9703ce8 100644 --- a/src/render/tga.cc +++ b/src/render/tga.cc @@ -51,7 +51,7 @@ Image *TGA::load(const char *filename) filesystem::File *tga_file = filesystem::open(filename); if (!tga_file) { - con_warn << "Could not open " << filename << std::endl; + //con_warn << "Could not open " << filename << std::endl; return 0; } |