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
--- 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')
--- 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)
--- 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 <stdio.h>
-#include <stdlib.h>
-#include <png.h>
-
-#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);
-}
--- 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
--- 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");
}
}
--- 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");
}
}
--- 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
--- /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
--- 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);
--- 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 = []
--- /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 <stdio.h>
+
+#ifdef HAVE_PNG
+# include <png.h>
+#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
+}
--- 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;