# HG changeset patch # User Radek Brich # Date 1209375851 -7200 # Node ID f7edb3b908169f2862593312d9994cc913a4f38c # Parent 1081e3dd3f3e421a184a5752116e391c67e767c8 merge pixmap handling from sampler, material.h and ccdemos's image module to new Pixmap class add check for PNG library, allow writing PNG file from a Pixmap simplify demos using new methods from Sampler and Pixmap diff -r 1081e3dd3f3e -r f7edb3b90816 SConstruct --- a/SConstruct Sun Apr 27 22:55:17 2008 +0200 +++ b/SConstruct Mon Apr 28 11:44:11 2008 +0200 @@ -48,6 +48,9 @@ opt.Save('.optioncache', env) Help(opt.GenerateHelpText(env)) + +### configure + platform = 'unknown' def CheckPlatform(context): global platform @@ -104,11 +107,9 @@ conf.CheckGCC() conf.CheckIntelC() conf.CheckCPUFlags() -env = conf.Finish() - -if intelc and env['intelc']: - Tool("intelc").generate(env) +if intelc and conf.env['intelc']: + Tool("intelc").generate(conf.env) cc = 'intelc' elif gcc: cc = 'gcc' @@ -119,17 +120,17 @@ if cc == 'intelc': add_flags += cpuflags_intelc + ' ' -if env['precision'] == 'double': +if conf.env['precision'] == 'double': add_flags += '-DPYRIT_DOUBLE ' elif cc == 'gcc': add_flags += '-fsingle-precision-constant ' -add_flags += env['flags'] +add_flags += conf.env['flags'] if cc == 'intelc': - env.Append(CCFLAGS="-O3 -w1 " + add_flags) + conf.env.Append(CCFLAGS="-O3 -w1 " + add_flags) elif cc == 'gcc': - env.Append(CCFLAGS="-O3 -Wall -pipe " + add_flags) + conf.env.Append(CCFLAGS="-O3 -Wall -pipe " + add_flags) # CCFLAGS= -fno-strict-aliasing else: print "No supported compiler found." @@ -138,11 +139,19 @@ print "Using compiler: " + cc print "Additional flags: " + add_flags -# pthread -if env['PLATFORM'] == 'win32': - env.Append(LIBS=["pthreadGC2"]) +if conf.CheckLibWithHeader('png', 'png.h', 'C'): + conf.env.Append(CCFLAGS='-DHAVE_PNG') + conf.env.Append(LIBS=['png']) + +if conf.env['PLATFORM'] == 'win32': + conf.env.Append(LIBS=["pthreadGC2"]) else: - env.Append(CCFLAGS="-pthread ") + conf.env.Append(CCFLAGS="-pthread ") + +env = conf.Finish() + + +### build targets (lib, pymodule) = SConscript('src/SConscript', build_dir='build/lib', duplicate=0, exports='env') diff -r 1081e3dd3f3e -r f7edb3b90816 ccdemos/SConscript --- a/ccdemos/SConscript Sun Apr 27 22:55:17 2008 +0200 +++ b/ccdemos/SConscript Mon Apr 28 11:44:11 2008 +0200 @@ -1,18 +1,16 @@ Import('env lib') myenv = env.Clone() myenv.Append(CPPPATH = ['.','#include'], LIBPATH='#build/lib') -myenv.Prepend(LIBS=['pyrit','png']) +myenv.Prepend(LIBS=['pyrit']) sdlenv = myenv.Clone() sdlenv.ParseConfig('sh sdl-config --cflags --libs') l = [] -image_obj = myenv.Object('image.c', CC="$CXX") -l.append( image_obj ) l.append( sdlenv.Program(['realtime.cc']) ) l.append( sdlenv.Program(['realtime_bunny.cc']) ) l.append( sdlenv.Program(['realtime_dragon.cc']) ) -l.append( sdlenv.Program(['spheres_shadow.cc']+image_obj) ) -l.append( sdlenv.Program(['textures.cc']+image_obj) ) +l.append( sdlenv.Program(['spheres_shadow.cc']) ) +l.append( sdlenv.Program(['textures.cc']) ) myenv.Alias('cc-demos', l) diff -r 1081e3dd3f3e -r f7edb3b90816 ccdemos/image.c --- a/ccdemos/image.c Sun Apr 27 22:55:17 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,116 +0,0 @@ -/* This code is part of RGB Image Library - see URL: xxx */ - -/************************************************************************** - -RGB Image Library (rgbimagelib) -File: image.c - -Copyright (c) 2006 Radek Brich - -Permission is hereby granted, free of charge, to any person -obtaining a copy of this software and associated documentation -files (the "Software"), to deal in the Software without -restriction, including without limitation the rights to use, -copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the -Software is furnished to do so, subject to the following -conditions: - -The above copyright notice and this permission notice shall be -included in all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, -EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES -OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND -NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT -HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, -WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING -FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR -OTHER DEALINGS IN THE SOFTWARE. - -**************************************************************************/ - -#include -#include -#include - -#include "image.h" - -int new_image(struct image **img, int width, int height, int pixelsize) -{ - *img = (struct image *) malloc(sizeof(struct image)); - (*img)->pixel_size = pixelsize; - (*img)->width = width; - (*img)->height = height; - (*img)->data = (unsigned char *) malloc(width * height * pixelsize); - return(0); -} - -void destroy_image(struct image **img) -{ - free((*img)->data); - free(*img); - *img = NULL; -} - -/* funkce pro ulozeni obrazku do PNG souboru (vyuziva knihovnu libpng) */ -int save_png(const char *fname, struct image *img) -{ - int y; /* pomocna promenna pro pruchod radku obrazu */ - FILE *f; - png_structp png; /* PNG data */ - png_infop pnginfo; /* PNG info */ - unsigned char *data; - - if ((f = fopen(fname, "wb")) == NULL) - return (0); - - png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - if (!png) { - fclose(f); - return (0); - } - - pnginfo = png_create_info_struct(png); - if (!pnginfo) { - fclose(f); - png_destroy_write_struct(&png, 0); - return (0); - } - - if (setjmp(png_jmpbuf(png))) { - fclose(f); - png_destroy_info_struct(png, &pnginfo); - png_destroy_write_struct(&png, &pnginfo); - return (0); - } - - /* predat knihovne PNG ukazatel na soubor */ - png_init_io(png, f); - - /* parametry PNG */ - png_set_compression_level(png, Z_BEST_COMPRESSION); - png_set_IHDR(png, pnginfo, img->width, img->height, 8, PNG_COLOR_TYPE_RGB, - PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, - PNG_FILTER_TYPE_DEFAULT); - png_set_sRGB(png, pnginfo, PNG_sRGB_INTENT_PERCEPTUAL); - png_set_sRGB_gAMA_and_cHRM(png, pnginfo, PNG_INFO_sRGB); - - /* zapsat hlavicku */ - png_write_info(png, pnginfo); - - /* zapsat data */ - data = img->data; - for (y = 0; y < img->height; y++, data += img->width * img->pixel_size) - png_write_row(png, (png_byte *) data); - - /* ukoncit soubor a uvolnit pomocne struktury */ - png_write_end(png, pnginfo); - png_destroy_info_struct(png, &pnginfo); - png_destroy_write_struct(&png, 0); - - fclose(f); - - return (1); -} diff -r 1081e3dd3f3e -r f7edb3b90816 ccdemos/image.h --- a/ccdemos/image.h Sun Apr 27 22:55:17 2008 +0200 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,20 +0,0 @@ -#ifndef IMAGE_H -#define IMAGE_H - -#define IMG_GRAYSCALE 1 -#define IMG_RGB 3 - -/* raw image */ -struct image { - int pixel_size; /* should be 1 for grayscale and 3 for RGB*/ - int width; - int height; - unsigned char *data; -}; - -int new_image(struct image **img, int width, int height, int pixelsize); -void destroy_image(struct image **img); - -int save_png(const char *fname, struct image *img); - -#endif diff -r 1081e3dd3f3e -r f7edb3b90816 ccdemos/spheres_shadow.cc --- a/ccdemos/spheres_shadow.cc Sun Apr 27 22:55:17 2008 +0200 +++ b/ccdemos/spheres_shadow.cc Mon Apr 28 11:44:11 2008 +0200 @@ -1,7 +1,6 @@ #include "raytracer.h" #include "octree.h" -#include "image.h" #include "common_sdl.h" Camera cam; @@ -108,24 +107,10 @@ if (argc == 2 && !strcmp(argv[1], "-r")) { pyrit_verbosity = 2; - Float *fdata = (Float *) malloc(w*h*3*sizeof(Float)); - DefaultSampler sampler(fdata, w, h); + DefaultSampler sampler(w, h); sampler.setOversample(2); rt.setSampler(&sampler); rt.render(); - - struct image *img; - new_image(&img, w, h, 3); - - Float *fd = fdata; - for (unsigned char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) { - if (*fd > 1.0) - *cd = 255; - else - *cd = (unsigned char)(*fd * 255.0); - } - free(fdata); - save_png("spheres_shadow.png", img); - destroy_image(&img); + sampler.getPixmap().writePNG("spheres_shadow.png"); } } diff -r 1081e3dd3f3e -r f7edb3b90816 ccdemos/textures.cc --- a/ccdemos/textures.cc Sun Apr 27 22:55:17 2008 +0200 +++ b/ccdemos/textures.cc Mon Apr 28 11:44:11 2008 +0200 @@ -1,7 +1,6 @@ #include "raytracer.h" #include "octree.h" -#include "image.h" #include "common_sdl.h" Camera cam(Vector3(0.,6.,6.), Vector3(0.,2.,-7.), Vector3(0.,0.,-1.)); @@ -141,26 +140,12 @@ if (argc == 2 && !strcmp(argv[1], "-r")) { pyrit_verbosity = 2; - Float *fdata = (Float *) malloc(w*h*3*sizeof(Float)); rt.ambientOcclusion(300, 5.0, 0.5); - DefaultSampler sampler(fdata, w, h); + DefaultSampler sampler(w, h); sampler.setOversample(2); sampler.setSubsample(1); rt.setSampler(&sampler); rt.render(); - - struct image *img; - new_image(&img, w, h, 3); - - Float *fd = fdata; - for (unsigned char *cd = img->data; cd != img->data + w*h*3; cd++, fd++) { - if (*fd > 1.0) - *cd = 255; - else - *cd = (unsigned char)(*fd * 255.0); - } - free(fdata); - save_png("textures.png", img); - destroy_image(&img); + sampler.getPixmap().writePNG("textures.png"); } } diff -r 1081e3dd3f3e -r f7edb3b90816 include/material.h --- a/include/material.h Sun Apr 27 22:55:17 2008 +0200 +++ b/include/material.h Mon Apr 28 11:44:11 2008 +0200 @@ -29,6 +29,7 @@ #include "common.h" #include "vector.h" +#include "pixmap.h" /** * perlin noise @@ -225,24 +226,6 @@ }; /** - * pixmap for image texture - */ -class Pixmap -{ - Colour *data; - int w,h; -public: - Pixmap(): data(NULL), w(0), h(0) {}; - Pixmap(Float *adata, int aw, int ah): - data((Colour*)(adata)), w(aw), h(ah) {}; - void setData(Float *adata, int aw, int ah) - { data = (Colour*)adata; w = aw; h = ah; }; - Colour get(int x, int y) { return data[y*w + x]; }; - int getWidth() { return w; }; - int getHeight() { return h; }; -}; - -/** * 2D image texture */ class ImageTexture: public Texture2D diff -r 1081e3dd3f3e -r f7edb3b90816 include/pixmap.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/include/pixmap.h Mon Apr 28 11:44:11 2008 +0200 @@ -0,0 +1,63 @@ +/* + * pixmap.h: 2D image class + * + * This file is part of Pyrit Ray Tracer. + * + * Copyright 2008 Radek Brich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#ifndef PIXMAP_H +#define PIXMAP_H + +#include "common.h" +#include "vector.h" + +/** + * 2D pixmap + */ +class Pixmap +{ + union + { + Colour *data; + Float *fdata; + }; + int w,h; + bool refdata; +public: + Pixmap(): data(NULL), w(0), h(0), refdata(true) {}; + Pixmap(Float *afdata, int aw, int ah): + fdata(afdata), w(aw), h(ah), refdata(true) {}; + Pixmap(int aw, int ah): + data(new Colour[aw*ah]), w(aw), h(ah), refdata(false) {}; + virtual ~Pixmap() { if (!refdata) delete[] data; }; + + void setData(Float *afdata, int aw, int ah) + { fdata = afdata; w = aw; h = ah; }; + Colour get(int x, int y) { return data[y*w + x]; }; + const int &getWidth() { return w; }; + const int &getHeight() { return h; }; + Float*& getFloatData() { return fdata; }; + unsigned char *getCharData() const; + int writePNG(const char *fname) const; +}; + +#endif diff -r 1081e3dd3f3e -r f7edb3b90816 include/sampler.h --- a/include/sampler.h Sun Apr 27 22:55:17 2008 +0200 +++ b/include/sampler.h Mon Apr 28 11:44:11 2008 +0200 @@ -29,6 +29,7 @@ #include "common.h" #include "vector.h" +#include "pixmap.h" using namespace std; @@ -56,19 +57,23 @@ class Sampler { protected: - Float *buffer; - int w,h; + + Pixmap pixmap; bool packetable; public: - Sampler(Float *abuffer, int &aw, int &ah): - buffer(abuffer), w(aw), h(ah), packetable(false) {}; + Sampler(Float *buffer, const int &w, const int &h): + pixmap(buffer, w, h), packetable(false) {}; + Sampler(const int &w, const int &h): + pixmap(w, h), packetable(false) {}; virtual ~Sampler() {}; - void resetBuffer(Float *abuffer, int &aw, int &ah) { buffer = abuffer; w = aw; h = ah; }; + void resetBuffer(Float *buffer, int &w, int &h) + { pixmap.setData(buffer, w, h); }; virtual void init() = 0; virtual int initSampleSet() = 0; virtual bool nextSample(Sample *s) = 0; virtual void saveSample(Sample &samp, Colour &col) = 0; bool packetableSamples() { return packetable; }; + const Pixmap &getPixmap() { return pixmap; }; }; /** @@ -82,8 +87,10 @@ int oversample; // 0 = no, 1 = 4x, 2 = 9x, 3 = 16x int sx,sy,osa_samp; // current sample properties public: - DefaultSampler(Float *abuffer, int &aw, int &ah): - Sampler(abuffer, aw, ah), phase(-1), subsample(0), oversample(0) {}; + DefaultSampler(Float *buffer, const int &w, const int &h): + Sampler(buffer, w, h), phase(-1), subsample(0), oversample(0) {}; + DefaultSampler(const int &w, const int &h): + Sampler(w, h), phase(-1), subsample(0), oversample(0) {}; void init(); int initSampleSet(); bool nextSample(Sample *s); diff -r 1081e3dd3f3e -r f7edb3b90816 src/SConscript --- a/src/SConscript Sun Apr 27 22:55:17 2008 +0200 +++ b/src/SConscript Mon Apr 28 11:44:11 2008 +0200 @@ -18,7 +18,7 @@ sources = [ 'raytracer.cc', 'scene.cc', 'shapes.cc', 'sampler.cc', 'container.cc', 'kdtree.cc', 'octree.cc', 'material.cc', - 'serialize.cc'] + 'serialize.cc', 'pixmap.cc'] objs = [] shared_objs = [] diff -r 1081e3dd3f3e -r f7edb3b90816 src/pixmap.cc --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pixmap.cc Mon Apr 28 11:44:11 2008 +0200 @@ -0,0 +1,113 @@ +/* + * pixmap.cc: 2D image class + * + * This file is part of Pyrit Ray Tracer. + * + * Copyright 2008 Radek Brich + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +#include + +#ifdef HAVE_PNG +# include +#endif + +#include "pixmap.h" + +unsigned char *Pixmap::getCharData() const +{ + unsigned char *cdata = new unsigned char[w*h*3]; + Float *fd = fdata; + for (unsigned char *cd = cdata; cd != cdata + w*h*3; cd++, fd++) + { + if (*fd > 1.0) + *cd = 255; + else + *cd = (unsigned char)(*fd * 255.0); + } + return cdata; +} + +int Pixmap::writePNG(const char *fname) const +{ +#ifndef HAVE_PNG + return -3; +#else + int y; + FILE *f; + png_structp png; /* PNG data */ + png_infop pnginfo; /* PNG info */ + unsigned char *cdata, *d; + + if ((f = fopen(fname, "wb")) == NULL) + return -1; + + png = png_create_write_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + if (!png) { + fclose(f); + return -2; + } + + pnginfo = png_create_info_struct(png); + if (!pnginfo) { + fclose(f); + png_destroy_write_struct(&png, 0); + return -2; + } + + if (setjmp(png_jmpbuf(png))) { + fclose(f); + png_destroy_info_struct(png, &pnginfo); + png_destroy_write_struct(&png, &pnginfo); + return -2; + } + + /* predat knihovne PNG ukazatel na soubor */ + png_init_io(png, f); + + /* parametry PNG */ + png_set_compression_level(png, Z_BEST_COMPRESSION); + png_set_IHDR(png, pnginfo, w, h, 8, PNG_COLOR_TYPE_RGB, + PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_DEFAULT, + PNG_FILTER_TYPE_DEFAULT); + png_set_sRGB(png, pnginfo, PNG_sRGB_INTENT_PERCEPTUAL); + png_set_sRGB_gAMA_and_cHRM(png, pnginfo, PNG_INFO_sRGB); + + /* zapsat hlavicku */ + png_write_info(png, pnginfo); + + /* zapsat data */ + d = cdata = getCharData(); + for (y = 0; y < h; y++, d += w * 3) + png_write_row(png, (png_byte *) d); + + /* ukoncit soubor a uvolnit pomocne struktury */ + png_write_end(png, pnginfo); + png_destroy_info_struct(png, &pnginfo); + png_destroy_write_struct(&png, 0); + + fclose(f); + + delete[] cdata; + + return 0; +#endif +} diff -r 1081e3dd3f3e -r f7edb3b90816 src/sampler.cc --- a/src/sampler.cc Sun Apr 27 22:55:17 2008 +0200 +++ b/src/sampler.cc Mon Apr 28 11:44:11 2008 +0200 @@ -39,6 +39,9 @@ { static const int gridsamples[] = {1,5,9,16}; const int samples = gridsamples[oversample]; + const int &w = pixmap.getWidth(), &h = pixmap.getHeight(); + Float *&buffer = pixmap.getFloatData(); + if ( phase == 0 ) { if (subsample > 1) @@ -141,6 +144,9 @@ bool DefaultSampler::nextSample(Sample* s) { + const int &w = pixmap.getWidth(), &h = pixmap.getHeight(); + Float *&buffer = pixmap.getFloatData(); + if (phase == 1) { // subsampling @@ -268,7 +274,8 @@ void DefaultSampler::saveSample(Sample &samp, Colour &col) { - Float *buf = buffer + 3*(samp.sy * w + samp.sx); + Float *buf = pixmap.getFloatData() + + 3*(samp.sy * pixmap.getWidth() + samp.sx); if (phase == 2 && oversample) { *(buf+0) += col.r;