erebus

changeset 2:474a0244f57d

fixed specialization mistake fixed line endings added makefiles
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 28 Apr 2014 06:31:10 +0300
parents 59a72293f9bd
children a932848de652
files .hgignore liberebus/Makefile liberebus/src/brdf.cc liberebus/src/brdf.h liberebus/src/bvol.cc liberebus/src/bvol.h liberebus/src/color.h liberebus/src/erebus.cc liberebus/src/erebus.h liberebus/src/erebus_impl.h liberebus/src/geomobj.h liberebus/src/image.inl liberebus/src/object.cc liberebus/src/object.h liberebus/src/scene.h liberebus/src/snode.h liberebus/src/texture.h src/main.cc
diffstat 18 files changed, 944 insertions(+), 878 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.hgignore	Mon Apr 28 06:31:10 2014 +0300
     1.3 @@ -0,0 +1,9 @@
     1.4 +\.o$
     1.5 +\.d$
     1.6 +\.swp$
     1.7 +\.a$
     1.8 +\.so\.
     1.9 +\.dylib
    1.10 +\.suo$
    1.11 +Debug/
    1.12 +Release/
     2.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     2.2 +++ b/liberebus/Makefile	Mon Apr 28 06:31:10 2014 +0300
     2.3 @@ -0,0 +1,41 @@
     2.4 +src = $(wildcard src/*.cc)
     2.5 +obj = $(src:.cc=.o)
     2.6 +dep = $(obj:.o=.d)
     2.7 +
     2.8 +name = erebus
     2.9 +lib_a = lib$(name).a
    2.10 +
    2.11 +api_major = 0
    2.12 +api_minor = 1
    2.13 +
    2.14 +CXXFLAGS = -std=c++11 -pedantic -Wall -g $(pic)
    2.15 +LDFLAGS = -lvmath -limago -lm
    2.16 +
    2.17 +ifeq ($(shell uname -s), Darwin)
    2.18 +	shared = -dynamiclib
    2.19 +	lib_so = lib$(name).dylib
    2.20 +else
    2.21 +	shared = -shared -Wl,-soname=$(soname)
    2.22 +	devlink = lib$(name).so
    2.23 +	soname = lib$(name).so.$(api_major)
    2.24 +	lib_so = lib$(name).so.$(api_major).$(api_minor)
    2.25 +	pic = -fPIC
    2.26 +endif
    2.27 +
    2.28 +.PHONY: all
    2.29 +all: $(lib_so) $(lib_a)
    2.30 +
    2.31 +$(lib_so): $(obj)
    2.32 +	$(CXX) -o $@ $(shared) $(obj) $(LDFLAGS)
    2.33 +
    2.34 +$(lib_a): $(obj)
    2.35 +	$(AR) rcs $@ $(obj)
    2.36 +
    2.37 +-include $(dep)
    2.38 +
    2.39 +%.d: %.cc
    2.40 +	@$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@
    2.41 +
    2.42 +.PHONY: clean
    2.43 +clean:
    2.44 +	rm -f $(obj) $(lib_so) $(lib_a)
     3.1 --- a/liberebus/src/brdf.cc	Mon Apr 28 05:58:22 2014 +0300
     3.2 +++ b/liberebus/src/brdf.cc	Mon Apr 28 06:31:10 2014 +0300
     3.3 @@ -1,130 +1,130 @@
     3.4 -#include "brdf.h"
     3.5 -#include "erebus_impl.h"
     3.6 -
     3.7 -ReflAttrib::ReflAttrib()
     3.8 -	: value(1), color(1, 1, 1), map(0)
     3.9 -{
    3.10 -}
    3.11 -
    3.12 -ReflAttrib::ReflAttrib(const Color &col, Texture *tex)
    3.13 -{
    3.14 -	set_color(col);
    3.15 -	map = tex;
    3.16 -}
    3.17 -
    3.18 -void ReflAttrib::set_value(float val)
    3.19 -{
    3.20 -	value = val;
    3.21 -	color = Color{val, val, val};
    3.22 -}
    3.23 -
    3.24 -void ReflAttrib::set_color(const Color &col)
    3.25 -{
    3.26 -	color = col;
    3.27 -	value = color_luminance(col);
    3.28 -}
    3.29 -
    3.30 -void ReflAttrib::set_map(Texture *tex)
    3.31 -{
    3.32 -	map = tex;
    3.33 -}
    3.34 -
    3.35 -Texture *ReflAttrib::get_map() const
    3.36 -{
    3.37 -	return map;
    3.38 -}
    3.39 -
    3.40 -float ReflAttrib::get_value() const
    3.41 -{
    3.42 -	return value;
    3.43 -}
    3.44 -
    3.45 -float ReflAttrib::get_value(float u, float v) const
    3.46 -{
    3.47 -	return map ? value * color_luminance(map->lookup(u, v)) : value;
    3.48 -}
    3.49 -
    3.50 -const Color &ReflAttrib::get_color() const
    3.51 -{
    3.52 -	return color;
    3.53 -}
    3.54 -
    3.55 -Color ReflAttrib::get_color(float u, float v) const
    3.56 -{
    3.57 -	return map ? color * map->lookup(u, v) : color;
    3.58 -}
    3.59 -
    3.60 -// ---- class Reflectance ----
    3.61 -ReflAttrib Reflectance::def_attrib;
    3.62 -
    3.63 -Reflectance::Reflectance()
    3.64 -{
    3.65 -	set_default_attribs();
    3.66 -}
    3.67 -
    3.68 -void Reflectance::set_attrib(const char *name, const Color &color, Texture *tex)
    3.69 -{
    3.70 -	attrib[name] = ReflAttrib{color, tex};
    3.71 -}
    3.72 -
    3.73 -ReflAttrib &Reflectance::get_attrib(const char *name)
    3.74 -{
    3.75 -	auto it = attrib.find(name);
    3.76 -	if(it == attrib.end()) {
    3.77 -		return def_attrib;
    3.78 -	}
    3.79 -	return it->second;
    3.80 -}
    3.81 -
    3.82 -const ReflAttrib &Reflectance::get_attrib(const char *name) const
    3.83 -{
    3.84 -	auto it = attrib.find(name);
    3.85 -	if(it == attrib.end()) {
    3.86 -		return def_attrib;
    3.87 -	}
    3.88 -	return it->second;
    3.89 -}
    3.90 -
    3.91 -float Reflectance::get_attrib_value(const char *name) const
    3.92 -{
    3.93 -	return get_attrib(name).get_value();
    3.94 -}
    3.95 -
    3.96 -float Reflectance::get_attrib_value(const char *name, float u, float v) const
    3.97 -{
    3.98 -	return get_attrib(name).get_value(u, v);
    3.99 -}
   3.100 -
   3.101 -Color Reflectance::get_attrib_color(const char *name) const
   3.102 -{
   3.103 -	return get_attrib(name).get_color();
   3.104 -}
   3.105 -
   3.106 -Color Reflectance::get_attrib_color(const char *name, float u, float v) const
   3.107 -{
   3.108 -	return get_attrib(name).get_color(u, v);
   3.109 -}
   3.110 -
   3.111 -float Reflectance::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const
   3.112 -{
   3.113 -	*indir = sample_dir(norm, outdir);
   3.114 -	return eval(norm, outdir, *indir);
   3.115 -}
   3.116 -
   3.117 -// --- class LambertRefl ---
   3.118 -
   3.119 -void LambertRefl::set_default_attribs()
   3.120 -{
   3.121 -	set_attrib("color", Color(1, 1, 1));
   3.122 -}
   3.123 -
   3.124 -Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const
   3.125 -{
   3.126 -	Vector3 dir = Vector3{randf(-1, 1), randf(-1, 1), randf(-1, 1)}.normalized();
   3.127 -	return dot_product(dir, norm) < 0.0 ? -dir : dir;
   3.128 -}
   3.129 -
   3.130 -float LambertRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const
   3.131 -{
   3.132 -	return dot_product(norm, outdir);
   3.133 -}
   3.134 \ No newline at end of file
   3.135 +#include "brdf.h"
   3.136 +#include "erebus_impl.h"
   3.137 +
   3.138 +ReflAttrib::ReflAttrib()
   3.139 +	: value(1), color(1, 1, 1), map(0)
   3.140 +{
   3.141 +}
   3.142 +
   3.143 +ReflAttrib::ReflAttrib(const Color &col, Texture *tex)
   3.144 +{
   3.145 +	set_color(col);
   3.146 +	map = tex;
   3.147 +}
   3.148 +
   3.149 +void ReflAttrib::set_value(float val)
   3.150 +{
   3.151 +	value = val;
   3.152 +	color = Color{val, val, val};
   3.153 +}
   3.154 +
   3.155 +void ReflAttrib::set_color(const Color &col)
   3.156 +{
   3.157 +	color = col;
   3.158 +	value = color_luminance(col);
   3.159 +}
   3.160 +
   3.161 +void ReflAttrib::set_map(Texture *tex)
   3.162 +{
   3.163 +	map = tex;
   3.164 +}
   3.165 +
   3.166 +Texture *ReflAttrib::get_map() const
   3.167 +{
   3.168 +	return map;
   3.169 +}
   3.170 +
   3.171 +float ReflAttrib::get_value() const
   3.172 +{
   3.173 +	return value;
   3.174 +}
   3.175 +
   3.176 +float ReflAttrib::get_value(float u, float v) const
   3.177 +{
   3.178 +	return map ? value * color_luminance(map->lookup(u, v)) : value;
   3.179 +}
   3.180 +
   3.181 +const Color &ReflAttrib::get_color() const
   3.182 +{
   3.183 +	return color;
   3.184 +}
   3.185 +
   3.186 +Color ReflAttrib::get_color(float u, float v) const
   3.187 +{
   3.188 +	return map ? color * map->lookup(u, v) : color;
   3.189 +}
   3.190 +
   3.191 +// ---- class Reflectance ----
   3.192 +ReflAttrib Reflectance::def_attrib;
   3.193 +
   3.194 +Reflectance::Reflectance()
   3.195 +{
   3.196 +	set_default_attribs();
   3.197 +}
   3.198 +
   3.199 +void Reflectance::set_attrib(const char *name, const Color &color, Texture *tex)
   3.200 +{
   3.201 +	attrib[name] = ReflAttrib{color, tex};
   3.202 +}
   3.203 +
   3.204 +ReflAttrib &Reflectance::get_attrib(const char *name)
   3.205 +{
   3.206 +	auto it = attrib.find(name);
   3.207 +	if(it == attrib.end()) {
   3.208 +		return def_attrib;
   3.209 +	}
   3.210 +	return it->second;
   3.211 +}
   3.212 +
   3.213 +const ReflAttrib &Reflectance::get_attrib(const char *name) const
   3.214 +{
   3.215 +	auto it = attrib.find(name);
   3.216 +	if(it == attrib.end()) {
   3.217 +		return def_attrib;
   3.218 +	}
   3.219 +	return it->second;
   3.220 +}
   3.221 +
   3.222 +float Reflectance::get_attrib_value(const char *name) const
   3.223 +{
   3.224 +	return get_attrib(name).get_value();
   3.225 +}
   3.226 +
   3.227 +float Reflectance::get_attrib_value(const char *name, float u, float v) const
   3.228 +{
   3.229 +	return get_attrib(name).get_value(u, v);
   3.230 +}
   3.231 +
   3.232 +Color Reflectance::get_attrib_color(const char *name) const
   3.233 +{
   3.234 +	return get_attrib(name).get_color();
   3.235 +}
   3.236 +
   3.237 +Color Reflectance::get_attrib_color(const char *name, float u, float v) const
   3.238 +{
   3.239 +	return get_attrib(name).get_color(u, v);
   3.240 +}
   3.241 +
   3.242 +float Reflectance::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const
   3.243 +{
   3.244 +	*indir = sample_dir(norm, outdir);
   3.245 +	return eval(norm, outdir, *indir);
   3.246 +}
   3.247 +
   3.248 +// --- class LambertRefl ---
   3.249 +
   3.250 +void LambertRefl::set_default_attribs()
   3.251 +{
   3.252 +	set_attrib("color", Color(1, 1, 1));
   3.253 +}
   3.254 +
   3.255 +Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const
   3.256 +{
   3.257 +	Vector3 dir = Vector3{randf(-1, 1), randf(-1, 1), randf(-1, 1)}.normalized();
   3.258 +	return dot_product(dir, norm) < 0.0 ? -dir : dir;
   3.259 +}
   3.260 +
   3.261 +float LambertRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const
   3.262 +{
   3.263 +	return dot_product(norm, outdir);
   3.264 +}
     4.1 --- a/liberebus/src/brdf.h	Mon Apr 28 05:58:22 2014 +0300
     4.2 +++ b/liberebus/src/brdf.h	Mon Apr 28 06:31:10 2014 +0300
     4.3 @@ -1,67 +1,67 @@
     4.4 -#ifndef BRDF_H_
     4.5 -#define BRDF_H_
     4.6 -
     4.7 -#include <map>
     4.8 -#include <string>
     4.9 -#include "color.h"
    4.10 -#include "texture.h"
    4.11 -
    4.12 -class ReflAttrib {
    4.13 -private:
    4.14 -	float value;
    4.15 -	Color color;
    4.16 -	Texture *map;
    4.17 -
    4.18 -public:
    4.19 -
    4.20 -	ReflAttrib();
    4.21 -	explicit ReflAttrib(const Color &color, Texture *tex = 0);
    4.22 -
    4.23 -	void set_value(float val);
    4.24 -	void set_color(const Color &col);
    4.25 -
    4.26 -	void set_map(Texture *tex);
    4.27 -	Texture *get_map() const;
    4.28 -
    4.29 -	float get_value() const;
    4.30 -	float get_value(float u, float v) const;
    4.31 -	const Color &get_color() const;
    4.32 -	Color get_color(float u, float v) const;
    4.33 -};
    4.34 -
    4.35 -
    4.36 -class Reflectance {
    4.37 -private:
    4.38 -	static ReflAttrib def_attrib;
    4.39 -	std::map<std::string, ReflAttrib> attrib;
    4.40 -
    4.41 -	virtual void set_default_attribs();
    4.42 -
    4.43 -public:
    4.44 -	Reflectance();
    4.45 -	virtual ~Reflectance() = default;
    4.46 -
    4.47 -	virtual void set_attrib(const char *name, const Color &color, Texture *tex = 0);
    4.48 -	virtual ReflAttrib &get_attrib(const char *name);
    4.49 -	virtual const ReflAttrib &get_attrib(const char *name) const;
    4.50 -
    4.51 -	virtual float get_attrib_value(const char *name) const;
    4.52 -	virtual float get_attrib_value(const char *name, float u, float v) const;
    4.53 -	virtual Color get_attrib_color(const char *name) const;
    4.54 -	virtual Color get_attrib_color(const char *name, float u, float v) const;
    4.55 -
    4.56 -	virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0;
    4.57 -	virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const;
    4.58 -	virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0;
    4.59 -};
    4.60 -
    4.61 -class LambertRefl : public Reflectance {
    4.62 -private:
    4.63 -	void set_default_attribs() override;
    4.64 -
    4.65 -public:
    4.66 -	Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override;
    4.67 -	float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override;
    4.68 -};
    4.69 -
    4.70 -#endif	// BRDF_H_
    4.71 \ No newline at end of file
    4.72 +#ifndef BRDF_H_
    4.73 +#define BRDF_H_
    4.74 +
    4.75 +#include <map>
    4.76 +#include <string>
    4.77 +#include "color.h"
    4.78 +#include "texture.h"
    4.79 +
    4.80 +class ReflAttrib {
    4.81 +private:
    4.82 +	float value;
    4.83 +	Color color;
    4.84 +	Texture *map;
    4.85 +
    4.86 +public:
    4.87 +
    4.88 +	ReflAttrib();
    4.89 +	explicit ReflAttrib(const Color &color, Texture *tex = 0);
    4.90 +
    4.91 +	void set_value(float val);
    4.92 +	void set_color(const Color &col);
    4.93 +
    4.94 +	void set_map(Texture *tex);
    4.95 +	Texture *get_map() const;
    4.96 +
    4.97 +	float get_value() const;
    4.98 +	float get_value(float u, float v) const;
    4.99 +	const Color &get_color() const;
   4.100 +	Color get_color(float u, float v) const;
   4.101 +};
   4.102 +
   4.103 +
   4.104 +class Reflectance {
   4.105 +private:
   4.106 +	static ReflAttrib def_attrib;
   4.107 +	std::map<std::string, ReflAttrib> attrib;
   4.108 +
   4.109 +	virtual void set_default_attribs();
   4.110 +
   4.111 +public:
   4.112 +	Reflectance();
   4.113 +	virtual ~Reflectance() = default;
   4.114 +
   4.115 +	virtual void set_attrib(const char *name, const Color &color, Texture *tex = 0);
   4.116 +	virtual ReflAttrib &get_attrib(const char *name);
   4.117 +	virtual const ReflAttrib &get_attrib(const char *name) const;
   4.118 +
   4.119 +	virtual float get_attrib_value(const char *name) const;
   4.120 +	virtual float get_attrib_value(const char *name, float u, float v) const;
   4.121 +	virtual Color get_attrib_color(const char *name) const;
   4.122 +	virtual Color get_attrib_color(const char *name, float u, float v) const;
   4.123 +
   4.124 +	virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0;
   4.125 +	virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const;
   4.126 +	virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0;
   4.127 +};
   4.128 +
   4.129 +class LambertRefl : public Reflectance {
   4.130 +private:
   4.131 +	void set_default_attribs() override;
   4.132 +
   4.133 +public:
   4.134 +	Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override;
   4.135 +	float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override;
   4.136 +};
   4.137 +
   4.138 +#endif	// BRDF_H_
     5.1 --- a/liberebus/src/bvol.cc	Mon Apr 28 05:58:22 2014 +0300
     5.2 +++ b/liberebus/src/bvol.cc	Mon Apr 28 06:31:10 2014 +0300
     5.3 @@ -1,38 +1,38 @@
     5.4 -#include "bvol.h"
     5.5 -
     5.6 -bool AABox::intersect(const Ray &ray) const
     5.7 -{
     5.8 -	Vector3 param[2] = {vmin, vmax};
     5.9 -	Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z);
    5.10 -	int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0};
    5.11 -
    5.12 -	float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x;
    5.13 -	float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x;
    5.14 -	float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y;
    5.15 -	float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y;
    5.16 -
    5.17 -	if(tmin > tymax || tymin > tmax) {
    5.18 -		return false;
    5.19 -	}
    5.20 -	if(tymin > tmin) {
    5.21 -		tmin = tymin;
    5.22 -	}
    5.23 -	if(tymax < tmax) {
    5.24 -		tmax = tymax;
    5.25 -	}
    5.26 -
    5.27 -	float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z;
    5.28 -	float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z;
    5.29 -
    5.30 -	if(tmin > tzmax || tzmin > tmax) {
    5.31 -		return false;
    5.32 -	}
    5.33 -	if(tzmin > tmin) {
    5.34 -		tmin = tzmin;
    5.35 -	}
    5.36 -	if(tzmax < tmax) {
    5.37 -		tmax = tzmax;
    5.38 -	}
    5.39 -
    5.40 -	return true;
    5.41 -}
    5.42 \ No newline at end of file
    5.43 +#include "bvol.h"
    5.44 +
    5.45 +bool AABox::intersect(const Ray &ray) const
    5.46 +{
    5.47 +	Vector3 param[2] = {vmin, vmax};
    5.48 +	Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z);
    5.49 +	int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0};
    5.50 +
    5.51 +	float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x;
    5.52 +	float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x;
    5.53 +	float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y;
    5.54 +	float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y;
    5.55 +
    5.56 +	if(tmin > tymax || tymin > tmax) {
    5.57 +		return false;
    5.58 +	}
    5.59 +	if(tymin > tmin) {
    5.60 +		tmin = tymin;
    5.61 +	}
    5.62 +	if(tymax < tmax) {
    5.63 +		tmax = tymax;
    5.64 +	}
    5.65 +
    5.66 +	float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z;
    5.67 +	float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z;
    5.68 +
    5.69 +	if(tmin > tzmax || tzmin > tmax) {
    5.70 +		return false;
    5.71 +	}
    5.72 +	if(tzmin > tmin) {
    5.73 +		tmin = tzmin;
    5.74 +	}
    5.75 +	if(tzmax < tmax) {
    5.76 +		tmax = tzmax;
    5.77 +	}
    5.78 +
    5.79 +	return true;
    5.80 +}
     6.1 --- a/liberebus/src/bvol.h	Mon Apr 28 05:58:22 2014 +0300
     6.2 +++ b/liberebus/src/bvol.h	Mon Apr 28 06:31:10 2014 +0300
     6.3 @@ -1,16 +1,16 @@
     6.4 -#ifndef BVOL_H_
     6.5 -#define BVOL_H_
     6.6 -
     6.7 -#include "vmath/ray.h"
     6.8 -
     6.9 -class AABox {
    6.10 -public:
    6.11 -	Vector3 vmin, vmax;
    6.12 -
    6.13 -	AABox() : vmin(-0.5, -0.5, -0.5), vmax(0.5, 0.5, 0.5) {}
    6.14 -	AABox(const Vector3 &v0, const Vector3 &v1) : vmin(v0), vmax(v1) {}
    6.15 -
    6.16 -	bool intersect(const Ray &ray) const;
    6.17 -};
    6.18 -
    6.19 -#endif	// BVOL_H_
    6.20 \ No newline at end of file
    6.21 +#ifndef BVOL_H_
    6.22 +#define BVOL_H_
    6.23 +
    6.24 +#include "vmath/ray.h"
    6.25 +
    6.26 +class AABox {
    6.27 +public:
    6.28 +	Vector3 vmin, vmax;
    6.29 +
    6.30 +	AABox() : vmin(-0.5, -0.5, -0.5), vmax(0.5, 0.5, 0.5) {}
    6.31 +	AABox(const Vector3 &v0, const Vector3 &v1) : vmin(v0), vmax(v1) {}
    6.32 +
    6.33 +	bool intersect(const Ray &ray) const;
    6.34 +};
    6.35 +
    6.36 +#endif	// BVOL_H_
     7.1 --- a/liberebus/src/color.h	Mon Apr 28 05:58:22 2014 +0300
     7.2 +++ b/liberebus/src/color.h	Mon Apr 28 06:31:10 2014 +0300
     7.3 @@ -1,10 +1,10 @@
     7.4 -#ifndef COLOR_H_
     7.5 -#define COLOR_H_
     7.6 -
     7.7 -#include "vmath/vector.h"
     7.8 -
     7.9 -typedef Vector3 Color;
    7.10 -
    7.11 -inline float color_luminance(const Color &c) { return c[0] * 0.2126 + c[1] * 0.7152 + c[2] * 0.0722; }
    7.12 -
    7.13 -#endif	// COLOR_H_
    7.14 \ No newline at end of file
    7.15 +#ifndef COLOR_H_
    7.16 +#define COLOR_H_
    7.17 +
    7.18 +#include "vmath/vector.h"
    7.19 +
    7.20 +typedef Vector3 Color;
    7.21 +
    7.22 +inline float color_luminance(const Color &c) { return c[0] * 0.2126 + c[1] * 0.7152 + c[2] * 0.0722; }
    7.23 +
    7.24 +#endif	// COLOR_H_
     8.1 --- a/liberebus/src/erebus.cc	Mon Apr 28 05:58:22 2014 +0300
     8.2 +++ b/liberebus/src/erebus.cc	Mon Apr 28 06:31:10 2014 +0300
     8.3 @@ -1,159 +1,159 @@
     8.4 -#include <string.h>
     8.5 -#include <limits.h>
     8.6 -#include <chrono>
     8.7 -#include <random>
     8.8 -#include "erebus.h"
     8.9 -#include "vmath/vector.h"
    8.10 -#include "image.h"
    8.11 -
    8.12 -using namespace std::chrono;
    8.13 -
    8.14 -struct Rect {
    8.15 -	int x, y, width, height;
    8.16 -
    8.17 -	bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; }
    8.18 -	bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; }
    8.19 -};
    8.20 -
    8.21 -#define INVALID_RECT	Rect{0, 0, 0, 0}
    8.22 -
    8.23 -struct erebus {
    8.24 -	Image<float> fbimg;
    8.25 -	Vector4 options[ERB_NUM_OPTIONS];
    8.26 -
    8.27 -	// render state
    8.28 -	long cur_time;
    8.29 -	int cur_pixel_x, cur_pixel_y;
    8.30 -	Rect cur_rect;
    8.31 -};
    8.32 -
    8.33 -static void render_pixel(struct erebus *ctx, int x, int y);
    8.34 -
    8.35 -static std::mt19937 rnd_gen;
    8.36 -
    8.37 -extern "C" {
    8.38 -
    8.39 -struct erebus *erb_init(void)
    8.40 -{
    8.41 -	struct erebus *ctx;
    8.42 -	try {
    8.43 -		ctx = new struct erebus;
    8.44 -	}
    8.45 -	catch(...) {
    8.46 -		return 0;
    8.47 -	}
    8.48 -
    8.49 -	ctx->cur_time = 0;
    8.50 -	ctx->cur_rect = INVALID_RECT;
    8.51 -	return ctx;
    8.52 -}
    8.53 -
    8.54 -void erb_destroy(struct erebus *ctx)
    8.55 -{
    8.56 -	delete ctx;
    8.57 -}
    8.58 -
    8.59 -void erb_setopti(struct erebus *ctx, enum erb_option opt, int val)
    8.60 -{
    8.61 -	ctx->options[opt].x;
    8.62 -}
    8.63 -void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val)
    8.64 -{
    8.65 -	ctx->options[opt].x = val;
    8.66 -}
    8.67 -void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec)
    8.68 -{
    8.69 -	for(int i=0; i<4; i++) {
    8.70 -		ctx->options[opt][i] = vec[i];
    8.71 -	}
    8.72 -}
    8.73 -
    8.74 -int erb_getopti(struct erebus *ctx, enum erb_option opt)
    8.75 -{
    8.76 -	return ctx->options[opt].x;
    8.77 -}
    8.78 -float erb_getoptf(struct erebus *ctx, enum erb_option opt)
    8.79 -{
    8.80 -	return ctx->options[opt].x;
    8.81 -}
    8.82 -float *erb_getoptfv(struct erebus *ctx, enum erb_option opt)
    8.83 -{
    8.84 -	return &ctx->options[opt].x;
    8.85 -}
    8.86 -
    8.87 -float *erb_get_framebuffer(struct erebus *ctx)
    8.88 -{
    8.89 -	return ctx->fbimg.get_pixels();
    8.90 -}
    8.91 -
    8.92 -void erb_begin_frame(struct erebus *ctx, long ms)
    8.93 -{
    8.94 -	ctx->cur_time = ms;
    8.95 -}
    8.96 -
    8.97 -int erb_render(struct erebus *ctx, long timeout)
    8.98 -{
    8.99 -	return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout);
   8.100 -}
   8.101 -
   8.102 -int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout)
   8.103 -{
   8.104 -	if(!width || !height) return -1;
   8.105 -
   8.106 -	Rect rect{x, y, width, height};
   8.107 -	if(ctx->cur_rect != rect) {
   8.108 -		ctx->cur_rect = rect;
   8.109 -		ctx->cur_pixel_x = x;
   8.110 -		ctx->cur_pixel_y = y;
   8.111 -	}
   8.112 -
   8.113 -	if(timeout > 0) {
   8.114 -		auto start_time = monotonic_clock::now();
   8.115 -		while(duration_cast<milliseconds>(monotonic_clock::now() - start_time).count() < timeout) {
   8.116 -			render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y);
   8.117 -
   8.118 -			if(++ctx->cur_pixel_x >= ctx->cur_rect.width) {
   8.119 -				if(++ctx->cur_pixel_y >= ctx->cur_rect.height) {
   8.120 -					ctx->cur_rect = INVALID_RECT;
   8.121 -					return 0;
   8.122 -				}
   8.123 -			}
   8.124 -		}
   8.125 -		return 1;
   8.126 -	}
   8.127 -
   8.128 -	for(int i=0; i<height; i++) {
   8.129 -		for(int j=0; j<width; j++) {
   8.130 -			render_pixel(ctx, j, i);
   8.131 -		}
   8.132 -	}
   8.133 -	return 0;
   8.134 -}
   8.135 -
   8.136 -int erb_get_progress(struct erebus *ctx)
   8.137 -{
   8.138 -	return 0;	// TODO
   8.139 -}
   8.140 -
   8.141 -int erb_load_scene(struct erebus *ctx, const char *fname)
   8.142 -{
   8.143 -	//delete ctx->scene;
   8.144 -	//ctx->scene = new Scene;
   8.145 -
   8.146 -	return false;	// TODO
   8.147 -}
   8.148 -
   8.149 -}	// extern "C"
   8.150 -
   8.151 -float randf(float low, float high)
   8.152 -{
   8.153 -	std::uniform_real_distribution<float> unirnd(low, high);
   8.154 -	return unirnd(rnd_gen);
   8.155 -}
   8.156 -
   8.157 -static void render_pixel(struct erebus *ctx, int x, int y)
   8.158 -{
   8.159 -	float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4;
   8.160 -	pix[0] = pix[1] = pix[2] = 0.0f;
   8.161 -	pix[3] = 1.0f;
   8.162 -}
   8.163 \ No newline at end of file
   8.164 +#include <string.h>
   8.165 +#include <limits.h>
   8.166 +#include <chrono>
   8.167 +#include <random>
   8.168 +#include "erebus.h"
   8.169 +#include "vmath/vector.h"
   8.170 +#include "image.h"
   8.171 +
   8.172 +using namespace std::chrono;
   8.173 +
   8.174 +struct Rect {
   8.175 +	int x, y, width, height;
   8.176 +
   8.177 +	bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; }
   8.178 +	bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; }
   8.179 +};
   8.180 +
   8.181 +#define INVALID_RECT	Rect{0, 0, 0, 0}
   8.182 +
   8.183 +struct erebus {
   8.184 +	Image<float> fbimg;
   8.185 +	Vector4 options[ERB_NUM_OPTIONS];
   8.186 +
   8.187 +	// render state
   8.188 +	long cur_time;
   8.189 +	int cur_pixel_x, cur_pixel_y;
   8.190 +	Rect cur_rect;
   8.191 +};
   8.192 +
   8.193 +static void render_pixel(struct erebus *ctx, int x, int y);
   8.194 +
   8.195 +static std::mt19937 rnd_gen;
   8.196 +
   8.197 +extern "C" {
   8.198 +
   8.199 +struct erebus *erb_init(void)
   8.200 +{
   8.201 +	struct erebus *ctx;
   8.202 +	try {
   8.203 +		ctx = new struct erebus;
   8.204 +	}
   8.205 +	catch(...) {
   8.206 +		return 0;
   8.207 +	}
   8.208 +
   8.209 +	ctx->cur_time = 0;
   8.210 +	ctx->cur_rect = INVALID_RECT;
   8.211 +	return ctx;
   8.212 +}
   8.213 +
   8.214 +void erb_destroy(struct erebus *ctx)
   8.215 +{
   8.216 +	delete ctx;
   8.217 +}
   8.218 +
   8.219 +void erb_setopti(struct erebus *ctx, enum erb_option opt, int val)
   8.220 +{
   8.221 +	ctx->options[opt].x = val;
   8.222 +}
   8.223 +void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val)
   8.224 +{
   8.225 +	ctx->options[opt].x = val;
   8.226 +}
   8.227 +void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec)
   8.228 +{
   8.229 +	for(int i=0; i<4; i++) {
   8.230 +		ctx->options[opt][i] = vec[i];
   8.231 +	}
   8.232 +}
   8.233 +
   8.234 +int erb_getopti(struct erebus *ctx, enum erb_option opt)
   8.235 +{
   8.236 +	return ctx->options[opt].x;
   8.237 +}
   8.238 +float erb_getoptf(struct erebus *ctx, enum erb_option opt)
   8.239 +{
   8.240 +	return ctx->options[opt].x;
   8.241 +}
   8.242 +float *erb_getoptfv(struct erebus *ctx, enum erb_option opt)
   8.243 +{
   8.244 +	return &ctx->options[opt].x;
   8.245 +}
   8.246 +
   8.247 +float *erb_get_framebuffer(struct erebus *ctx)
   8.248 +{
   8.249 +	return ctx->fbimg.get_pixels();
   8.250 +}
   8.251 +
   8.252 +void erb_begin_frame(struct erebus *ctx, long ms)
   8.253 +{
   8.254 +	ctx->cur_time = ms;
   8.255 +}
   8.256 +
   8.257 +int erb_render(struct erebus *ctx, long timeout)
   8.258 +{
   8.259 +	return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout);
   8.260 +}
   8.261 +
   8.262 +int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout)
   8.263 +{
   8.264 +	if(!width || !height) return -1;
   8.265 +
   8.266 +	Rect rect{x, y, width, height};
   8.267 +	if(ctx->cur_rect != rect) {
   8.268 +		ctx->cur_rect = rect;
   8.269 +		ctx->cur_pixel_x = x;
   8.270 +		ctx->cur_pixel_y = y;
   8.271 +	}
   8.272 +
   8.273 +	if(timeout > 0) {
   8.274 +		auto start_time = steady_clock::now();
   8.275 +		while(duration_cast<milliseconds>(steady_clock::now() - start_time).count() < timeout) {
   8.276 +			render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y);
   8.277 +
   8.278 +			if(++ctx->cur_pixel_x >= ctx->cur_rect.width) {
   8.279 +				if(++ctx->cur_pixel_y >= ctx->cur_rect.height) {
   8.280 +					ctx->cur_rect = INVALID_RECT;
   8.281 +					return 0;
   8.282 +				}
   8.283 +			}
   8.284 +		}
   8.285 +		return 1;
   8.286 +	}
   8.287 +
   8.288 +	for(int i=0; i<height; i++) {
   8.289 +		for(int j=0; j<width; j++) {
   8.290 +			render_pixel(ctx, j, i);
   8.291 +		}
   8.292 +	}
   8.293 +	return 0;
   8.294 +}
   8.295 +
   8.296 +int erb_get_progress(struct erebus *ctx)
   8.297 +{
   8.298 +	return 0;	// TODO
   8.299 +}
   8.300 +
   8.301 +int erb_load_scene(struct erebus *ctx, const char *fname)
   8.302 +{
   8.303 +	//delete ctx->scene;
   8.304 +	//ctx->scene = new Scene;
   8.305 +
   8.306 +	return false;	// TODO
   8.307 +}
   8.308 +
   8.309 +}	// extern "C"
   8.310 +
   8.311 +float randf(float low, float high)
   8.312 +{
   8.313 +	std::uniform_real_distribution<float> unirnd(low, high);
   8.314 +	return unirnd(rnd_gen);
   8.315 +}
   8.316 +
   8.317 +static void render_pixel(struct erebus *ctx, int x, int y)
   8.318 +{
   8.319 +	float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4;
   8.320 +	pix[0] = pix[1] = pix[2] = 0.0f;
   8.321 +	pix[3] = 1.0f;
   8.322 +}
     9.1 --- a/liberebus/src/erebus.h	Mon Apr 28 05:58:22 2014 +0300
     9.2 +++ b/liberebus/src/erebus.h	Mon Apr 28 06:31:10 2014 +0300
     9.3 @@ -1,46 +1,46 @@
     9.4 -#ifndef LIBEREBUS_H_
     9.5 -#define LIBEREBUS_H_
     9.6 -
     9.7 -struct erebus;
     9.8 -
     9.9 -enum erb_option {
    9.10 -	ERB_OPT_WIDTH,
    9.11 -	ERB_OPT_HEIGHT,
    9.12 -	ERB_OPT_MAX_ITER,
    9.13 -	ERB_OPT_NUM_THREADS,
    9.14 -	ERB_OPT_GAMMA,
    9.15 -
    9.16 -	ERB_NUM_OPTIONS
    9.17 -};
    9.18 -
    9.19 -#ifdef __cplusplus
    9.20 -extern "C" {
    9.21 -#endif
    9.22 -
    9.23 -struct erebus *erb_init(void);
    9.24 -void erb_destroy(struct erebus *ctx);
    9.25 -
    9.26 -void erb_setopti(struct erebus *ctx, enum erb_option opt, int val);
    9.27 -void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val);
    9.28 -void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec);
    9.29 -
    9.30 -int erb_getopti(struct erebus *ctx, enum erb_option opt);
    9.31 -float erb_getoptf(struct erebus *ctx, enum erb_option opt);
    9.32 -float *erb_getoptfv(struct erebus *ctx, enum erb_option opt);
    9.33 -
    9.34 -float *erb_get_framebuffer(struct erebus *ctx);
    9.35 -
    9.36 -void erb_begin_frame(struct erebus *ctx, long ms);
    9.37 -int erb_render(struct erebus *ctx, long timeout);
    9.38 -int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout);
    9.39 -
    9.40 -int erb_get_progress(struct erebus *ctx);
    9.41 -
    9.42 -int erb_load_scene(struct erebus *ctx, const char *fname);
    9.43 -
    9.44 -#ifdef __cplusplus
    9.45 -}
    9.46 -#endif
    9.47 -
    9.48 -
    9.49 -#endif	/* LIBEREBUS_H_ */
    9.50 \ No newline at end of file
    9.51 +#ifndef LIBEREBUS_H_
    9.52 +#define LIBEREBUS_H_
    9.53 +
    9.54 +struct erebus;
    9.55 +
    9.56 +enum erb_option {
    9.57 +	ERB_OPT_WIDTH,
    9.58 +	ERB_OPT_HEIGHT,
    9.59 +	ERB_OPT_MAX_ITER,
    9.60 +	ERB_OPT_NUM_THREADS,
    9.61 +	ERB_OPT_GAMMA,
    9.62 +
    9.63 +	ERB_NUM_OPTIONS
    9.64 +};
    9.65 +
    9.66 +#ifdef __cplusplus
    9.67 +extern "C" {
    9.68 +#endif
    9.69 +
    9.70 +struct erebus *erb_init(void);
    9.71 +void erb_destroy(struct erebus *ctx);
    9.72 +
    9.73 +void erb_setopti(struct erebus *ctx, enum erb_option opt, int val);
    9.74 +void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val);
    9.75 +void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec);
    9.76 +
    9.77 +int erb_getopti(struct erebus *ctx, enum erb_option opt);
    9.78 +float erb_getoptf(struct erebus *ctx, enum erb_option opt);
    9.79 +float *erb_getoptfv(struct erebus *ctx, enum erb_option opt);
    9.80 +
    9.81 +float *erb_get_framebuffer(struct erebus *ctx);
    9.82 +
    9.83 +void erb_begin_frame(struct erebus *ctx, long ms);
    9.84 +int erb_render(struct erebus *ctx, long timeout);
    9.85 +int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout);
    9.86 +
    9.87 +int erb_get_progress(struct erebus *ctx);
    9.88 +
    9.89 +int erb_load_scene(struct erebus *ctx, const char *fname);
    9.90 +
    9.91 +#ifdef __cplusplus
    9.92 +}
    9.93 +#endif
    9.94 +
    9.95 +
    9.96 +#endif	/* LIBEREBUS_H_ */
    10.1 --- a/liberebus/src/erebus_impl.h	Mon Apr 28 05:58:22 2014 +0300
    10.2 +++ b/liberebus/src/erebus_impl.h	Mon Apr 28 06:31:10 2014 +0300
    10.3 @@ -1,6 +1,6 @@
    10.4 -#ifndef EREBUS_IMPL_H_
    10.5 -#define EREBUS_IMPL_H_
    10.6 -
    10.7 -float randf(float low = 0.0f, float high = 1.0f);
    10.8 -
    10.9 -#endif	// EREBUS_IMPL_H_
   10.10 \ No newline at end of file
   10.11 +#ifndef EREBUS_IMPL_H_
   10.12 +#define EREBUS_IMPL_H_
   10.13 +
   10.14 +float randf(float low = 0.0f, float high = 1.0f);
   10.15 +
   10.16 +#endif	// EREBUS_IMPL_H_
    11.1 --- a/liberebus/src/geomobj.h	Mon Apr 28 05:58:22 2014 +0300
    11.2 +++ b/liberebus/src/geomobj.h	Mon Apr 28 06:31:10 2014 +0300
    11.3 @@ -1,50 +1,50 @@
    11.4 -#ifndef GEOMOBJ_H_
    11.5 -#define GEOMOBJ_H_
    11.6 -
    11.7 -#include "object.h"
    11.8 -#include "brdf.h"
    11.9 -
   11.10 -class GeomObject : public Object {
   11.11 -public:
   11.12 -	Reflectance *brdf;
   11.13 -
   11.14 -	ObjType get_type() const override;
   11.15 -
   11.16 -	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.17 -};
   11.18 -
   11.19 -class Sphere : public GeomObject {
   11.20 -public:
   11.21 -	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.22 -};
   11.23 -
   11.24 -class Box : public GeomObject {
   11.25 -public:
   11.26 -	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.27 -};
   11.28 -
   11.29 -class Triangle : public GeomObject {
   11.30 -public:
   11.31 -	Vector3 v[3];
   11.32 -	Vector3 normal;
   11.33 -	Vector3 vnorm[3];
   11.34 -	Vector2 vtex[3];
   11.35 -
   11.36 -	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.37 -};
   11.38 -
   11.39 -class Mesh : public GeomObject {
   11.40 -private:
   11.41 -	std::vector<Triangle> faces;
   11.42 -
   11.43 -public:
   11.44 -	void begin();
   11.45 -	void vertex(float x, float y, float z);
   11.46 -	void normal(float x, float y, float z);
   11.47 -	void texcoord(float u, float v);
   11.48 -	void end();
   11.49 -
   11.50 -	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.51 -};
   11.52 -
   11.53 -#endif	// GEOMOBJ_H_
   11.54 \ No newline at end of file
   11.55 +#ifndef GEOMOBJ_H_
   11.56 +#define GEOMOBJ_H_
   11.57 +
   11.58 +#include "object.h"
   11.59 +#include "brdf.h"
   11.60 +
   11.61 +class GeomObject : public Object {
   11.62 +public:
   11.63 +	Reflectance *brdf;
   11.64 +
   11.65 +	ObjType get_type() const override;
   11.66 +
   11.67 +	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.68 +};
   11.69 +
   11.70 +class Sphere : public GeomObject {
   11.71 +public:
   11.72 +	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.73 +};
   11.74 +
   11.75 +class Box : public GeomObject {
   11.76 +public:
   11.77 +	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.78 +};
   11.79 +
   11.80 +class Triangle : public GeomObject {
   11.81 +public:
   11.82 +	Vector3 v[3];
   11.83 +	Vector3 normal;
   11.84 +	Vector3 vnorm[3];
   11.85 +	Vector2 vtex[3];
   11.86 +
   11.87 +	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
   11.88 +};
   11.89 +
   11.90 +class Mesh : public GeomObject {
   11.91 +private:
   11.92 +	std::vector<Triangle> faces;
   11.93 +
   11.94 +public:
   11.95 +	void begin();
   11.96 +	void vertex(float x, float y, float z);
   11.97 +	void normal(float x, float y, float z);
   11.98 +	void texcoord(float u, float v);
   11.99 +	void end();
  11.100 +
  11.101 +	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
  11.102 +};
  11.103 +
  11.104 +#endif	// GEOMOBJ_H_
    12.1 --- a/liberebus/src/image.inl	Mon Apr 28 05:58:22 2014 +0300
    12.2 +++ b/liberebus/src/image.inl	Mon Apr 28 06:31:10 2014 +0300
    12.3 @@ -118,7 +118,14 @@
    12.4  	return pixels;
    12.5  }
    12.6  
    12.7 -bool Image<unsigned char>::load(const char *fname)
    12.8 +template <typename T>
    12.9 +inline bool load_image(Image<T> *img, const char *fname)
   12.10 +{
   12.11 +	return false;
   12.12 +}
   12.13 +
   12.14 +template <>
   12.15 +inline bool load_image<unsigned char>(Image<unsigned char> *img, const char *fname)
   12.16  {
   12.17  	int xsz, ysz;
   12.18  	unsigned char *pix = (unsigned char*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32);
   12.19 @@ -126,11 +133,13 @@
   12.20  		return false;
   12.21  	}
   12.22  
   12.23 -	create(xsz, ysz, pix);
   12.24 +	img->create(xsz, ysz, pix);
   12.25 +	img_free_pixels(pix);
   12.26  	return true;
   12.27  }
   12.28  
   12.29 -bool Image<float>::load(const char *fname)
   12.30 +template <>
   12.31 +inline bool load_image<float>(Image<float> *img, const char *fname)
   12.32  {
   12.33  	int xsz, ysz;
   12.34  	float *pix = (float*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBAF);
   12.35 @@ -138,6 +147,13 @@
   12.36  		return false;
   12.37  	}
   12.38  
   12.39 -	create(xsz, ysz, pix);
   12.40 +	img->create(xsz, ysz, pix);
   12.41 +	img_free_pixels(pix);
   12.42  	return true;
   12.43 -}
   12.44 \ No newline at end of file
   12.45 +}
   12.46 +
   12.47 +template <typename T>
   12.48 +bool Image<T>::load(const char *fname)
   12.49 +{
   12.50 +	return load_image(this, fname);
   12.51 +}
    13.1 --- a/liberebus/src/object.cc	Mon Apr 28 05:58:22 2014 +0300
    13.2 +++ b/liberebus/src/object.cc	Mon Apr 28 06:31:10 2014 +0300
    13.3 @@ -1,60 +1,60 @@
    13.4 -#include "object.h"
    13.5 -
    13.6 -Object::Object()
    13.7 -{
    13.8 -	name = "<unnamed>";
    13.9 -	inv_xform_valid = false;
   13.10 -}
   13.11 -
   13.12 -ObjType Object::get_type() const
   13.13 -{
   13.14 -	return ObjType::null;
   13.15 -}
   13.16 -
   13.17 -void Object::set_name(const char *name)
   13.18 -{
   13.19 -	this->name = name;
   13.20 -}
   13.21 -
   13.22 -const char *Object::get_name() const
   13.23 -{
   13.24 -	return name.c_str();
   13.25 -}
   13.26 -
   13.27 -void Object::set_xform(const Matrix4x4 &mat)
   13.28 -{
   13.29 -	xform = mat;
   13.30 -	inv_xform_valid = false;
   13.31 -}
   13.32 -
   13.33 -void Object::set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat)
   13.34 -{
   13.35 -	xform = mat;
   13.36 -	inv_xform = inv_mat;
   13.37 -	inv_xform_valid = true;
   13.38 -}
   13.39 -
   13.40 -Matrix4x4 &Object::get_xform()
   13.41 -{
   13.42 -	inv_xform_valid = false;
   13.43 -	return xform;
   13.44 -}
   13.45 -
   13.46 -const Matrix4x4 &Object::get_xform() const
   13.47 -{
   13.48 -	return xform;
   13.49 -}
   13.50 -
   13.51 -const Matrix4x4 &Object::get_inv_xform() const
   13.52 -{
   13.53 -	if(!inv_xform_valid) {
   13.54 -		inv_xform = xform.inverse();
   13.55 -		inv_xform_valid = true;
   13.56 -	}
   13.57 -	return inv_xform;
   13.58 -}
   13.59 -
   13.60 -bool Object::intersect(const Ray &ray, RayHit *hit) const
   13.61 -{
   13.62 -	return false;
   13.63 -}
   13.64 \ No newline at end of file
   13.65 +#include "object.h"
   13.66 +
   13.67 +Object::Object()
   13.68 +{
   13.69 +	name = "<unnamed>";
   13.70 +	inv_xform_valid = false;
   13.71 +}
   13.72 +
   13.73 +ObjType Object::get_type() const
   13.74 +{
   13.75 +	return ObjType::null;
   13.76 +}
   13.77 +
   13.78 +void Object::set_name(const char *name)
   13.79 +{
   13.80 +	this->name = name;
   13.81 +}
   13.82 +
   13.83 +const char *Object::get_name() const
   13.84 +{
   13.85 +	return name.c_str();
   13.86 +}
   13.87 +
   13.88 +void Object::set_xform(const Matrix4x4 &mat)
   13.89 +{
   13.90 +	xform = mat;
   13.91 +	inv_xform_valid = false;
   13.92 +}
   13.93 +
   13.94 +void Object::set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat)
   13.95 +{
   13.96 +	xform = mat;
   13.97 +	inv_xform = inv_mat;
   13.98 +	inv_xform_valid = true;
   13.99 +}
  13.100 +
  13.101 +Matrix4x4 &Object::get_xform()
  13.102 +{
  13.103 +	inv_xform_valid = false;
  13.104 +	return xform;
  13.105 +}
  13.106 +
  13.107 +const Matrix4x4 &Object::get_xform() const
  13.108 +{
  13.109 +	return xform;
  13.110 +}
  13.111 +
  13.112 +const Matrix4x4 &Object::get_inv_xform() const
  13.113 +{
  13.114 +	if(!inv_xform_valid) {
  13.115 +		inv_xform = xform.inverse();
  13.116 +		inv_xform_valid = true;
  13.117 +	}
  13.118 +	return inv_xform;
  13.119 +}
  13.120 +
  13.121 +bool Object::intersect(const Ray &ray, RayHit *hit) const
  13.122 +{
  13.123 +	return false;
  13.124 +}
    14.1 --- a/liberebus/src/object.h	Mon Apr 28 05:58:22 2014 +0300
    14.2 +++ b/liberebus/src/object.h	Mon Apr 28 06:31:10 2014 +0300
    14.3 @@ -1,44 +1,44 @@
    14.4 -#ifndef OBJECT_H_
    14.5 -#define OBJECT_H_
    14.6 -
    14.7 -#include <string>
    14.8 -#include "vmath/ray.h"
    14.9 -
   14.10 -class Object;
   14.11 -
   14.12 -struct RayHit {
   14.13 -	float dist;
   14.14 -	const Ray world_ray, local_ray;
   14.15 -
   14.16 -	const Object *obj, *subobj;
   14.17 -};
   14.18 -
   14.19 -enum class ObjType { null, geom, camera };
   14.20 -
   14.21 -class Object {
   14.22 -private:
   14.23 -	std::string name;
   14.24 -	Matrix4x4 xform;
   14.25 -	mutable Matrix4x4 inv_xform;
   14.26 -	mutable bool inv_xform_valid;
   14.27 -
   14.28 -public:
   14.29 -	Object();
   14.30 -	virtual ~Object() = default;
   14.31 -
   14.32 -	virtual ObjType get_type() const;
   14.33 -
   14.34 -	virtual void set_name(const char *name);
   14.35 -	virtual const char *get_name() const;
   14.36 -
   14.37 -	virtual void set_xform(const Matrix4x4 &mat);
   14.38 -	virtual void set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat);
   14.39 -
   14.40 -	virtual Matrix4x4 &get_xform();	// invalidates inv_xform
   14.41 -	virtual const Matrix4x4 &get_xform() const;
   14.42 -	virtual const Matrix4x4 &get_inv_xform() const;
   14.43 -
   14.44 -	virtual bool intersect(const Ray &ray, RayHit *hit = 0) const;
   14.45 -};
   14.46 -
   14.47 -#endif	// OBJECT_H_
   14.48 \ No newline at end of file
   14.49 +#ifndef OBJECT_H_
   14.50 +#define OBJECT_H_
   14.51 +
   14.52 +#include <string>
   14.53 +#include "vmath/ray.h"
   14.54 +
   14.55 +class Object;
   14.56 +
   14.57 +struct RayHit {
   14.58 +	float dist;
   14.59 +	const Ray world_ray, local_ray;
   14.60 +
   14.61 +	const Object *obj, *subobj;
   14.62 +};
   14.63 +
   14.64 +enum class ObjType { null, geom, camera };
   14.65 +
   14.66 +class Object {
   14.67 +private:
   14.68 +	std::string name;
   14.69 +	Matrix4x4 xform;
   14.70 +	mutable Matrix4x4 inv_xform;
   14.71 +	mutable bool inv_xform_valid;
   14.72 +
   14.73 +public:
   14.74 +	Object();
   14.75 +	virtual ~Object() = default;
   14.76 +
   14.77 +	virtual ObjType get_type() const;
   14.78 +
   14.79 +	virtual void set_name(const char *name);
   14.80 +	virtual const char *get_name() const;
   14.81 +
   14.82 +	virtual void set_xform(const Matrix4x4 &mat);
   14.83 +	virtual void set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat);
   14.84 +
   14.85 +	virtual Matrix4x4 &get_xform();	// invalidates inv_xform
   14.86 +	virtual const Matrix4x4 &get_xform() const;
   14.87 +	virtual const Matrix4x4 &get_inv_xform() const;
   14.88 +
   14.89 +	virtual bool intersect(const Ray &ray, RayHit *hit = 0) const;
   14.90 +};
   14.91 +
   14.92 +#endif	// OBJECT_H_
    15.1 --- a/liberebus/src/scene.h	Mon Apr 28 05:58:22 2014 +0300
    15.2 +++ b/liberebus/src/scene.h	Mon Apr 28 06:31:10 2014 +0300
    15.3 @@ -1,30 +1,30 @@
    15.4 -#ifndef SCENE_H_
    15.5 -#define SCENE_H_
    15.6 -
    15.7 -#include <vector>
    15.8 -#include "snode.h"
    15.9 -#include "camera.h"
   15.10 -
   15.11 -class Scene {
   15.12 -private:
   15.13 -	std::vector<Object*> objects;
   15.14 -	std::vector<SceneNode*> nodes;
   15.15 -
   15.16 -	Camera *active_cam;
   15.17 -
   15.18 -public:
   15.19 -	Scene();
   15.20 -	~Scene();
   15.21 -
   15.22 -	void add_object(Object *obj);
   15.23 -	int get_object_count() const;
   15.24 -	Object *get_object(int idx) const;
   15.25 -
   15.26 -	void add_node(SceneNode *node);
   15.27 -	int get_node_count() const;
   15.28 -	SceneNode *get_node(int idx) const;
   15.29 -
   15.30 -	bool intersect(const Ray &ray, RayHit *hit) const;
   15.31 -};
   15.32 -
   15.33 -#endif	// SCENE_H_
   15.34 \ No newline at end of file
   15.35 +#ifndef SCENE_H_
   15.36 +#define SCENE_H_
   15.37 +
   15.38 +#include <vector>
   15.39 +#include "snode.h"
   15.40 +#include "camera.h"
   15.41 +
   15.42 +class Scene {
   15.43 +private:
   15.44 +	std::vector<Object*> objects;
   15.45 +	std::vector<SceneNode*> nodes;
   15.46 +
   15.47 +	Camera *active_cam;
   15.48 +
   15.49 +public:
   15.50 +	Scene();
   15.51 +	~Scene();
   15.52 +
   15.53 +	void add_object(Object *obj);
   15.54 +	int get_object_count() const;
   15.55 +	Object *get_object(int idx) const;
   15.56 +
   15.57 +	void add_node(SceneNode *node);
   15.58 +	int get_node_count() const;
   15.59 +	SceneNode *get_node(int idx) const;
   15.60 +
   15.61 +	bool intersect(const Ray &ray, RayHit *hit) const;
   15.62 +};
   15.63 +
   15.64 +#endif	// SCENE_H_
    16.1 --- a/liberebus/src/snode.h	Mon Apr 28 05:58:22 2014 +0300
    16.2 +++ b/liberebus/src/snode.h	Mon Apr 28 06:31:10 2014 +0300
    16.3 @@ -1,46 +1,46 @@
    16.4 -#ifndef SNODE_H_
    16.5 -#define SNODE_H_
    16.6 -
    16.7 -#include <vector>
    16.8 -#include "object.h"
    16.9 -#include "vmath/vmath.h"
   16.10 -
   16.11 -class SceneNode {
   16.12 -private:
   16.13 -	Vector3 pos;
   16.14 -	Quaternion rot;
   16.15 -	Vector3 scale;
   16.16 -
   16.17 -	std::vector<Object*> obj;
   16.18 -
   16.19 -	SceneNode *parent;
   16.20 -	std::vector<SceneNode*> children;
   16.21 -
   16.22 -	Matrix4x4 node_xform, xform;
   16.23 -
   16.24 -public:
   16.25 -	void add_child(SceneNode *node);
   16.26 -	bool remove_child(SceneNode *node);
   16.27 -
   16.28 -	int get_num_children() const;
   16.29 -	SceneNode *get_child(int idx) const;
   16.30 -
   16.31 -	void set_position(const Vector3 &pos);
   16.32 -	void set_rotation(const Quaternion &rot);
   16.33 -	void set_scaling(const Vector3 &scale);
   16.34 -
   16.35 -	const Vector3 &get_node_position() const;
   16.36 -	const Quaternion &get_node_rotation() const;
   16.37 -	const Vector3 &get_node_scaling() const;
   16.38 -
   16.39 -	Vector3 get_position() const;
   16.40 -	Quaternion get_rotation() const;
   16.41 -	Vector3 get_scaling() const;
   16.42 -
   16.43 -	void update_node(long msec = 0);
   16.44 -	void update(long msec = 0);
   16.45 -
   16.46 -	bool intersect(const Ray &ray, RayHit *hit) const;
   16.47 -};
   16.48 -
   16.49 -#endif	// SNODE_H_
   16.50 \ No newline at end of file
   16.51 +#ifndef SNODE_H_
   16.52 +#define SNODE_H_
   16.53 +
   16.54 +#include <vector>
   16.55 +#include "object.h"
   16.56 +#include "vmath/vmath.h"
   16.57 +
   16.58 +class SceneNode {
   16.59 +private:
   16.60 +	Vector3 pos;
   16.61 +	Quaternion rot;
   16.62 +	Vector3 scale;
   16.63 +
   16.64 +	std::vector<Object*> obj;
   16.65 +
   16.66 +	SceneNode *parent;
   16.67 +	std::vector<SceneNode*> children;
   16.68 +
   16.69 +	Matrix4x4 node_xform, xform;
   16.70 +
   16.71 +public:
   16.72 +	void add_child(SceneNode *node);
   16.73 +	bool remove_child(SceneNode *node);
   16.74 +
   16.75 +	int get_num_children() const;
   16.76 +	SceneNode *get_child(int idx) const;
   16.77 +
   16.78 +	void set_position(const Vector3 &pos);
   16.79 +	void set_rotation(const Quaternion &rot);
   16.80 +	void set_scaling(const Vector3 &scale);
   16.81 +
   16.82 +	const Vector3 &get_node_position() const;
   16.83 +	const Quaternion &get_node_rotation() const;
   16.84 +	const Vector3 &get_node_scaling() const;
   16.85 +
   16.86 +	Vector3 get_position() const;
   16.87 +	Quaternion get_rotation() const;
   16.88 +	Vector3 get_scaling() const;
   16.89 +
   16.90 +	void update_node(long msec = 0);
   16.91 +	void update(long msec = 0);
   16.92 +
   16.93 +	bool intersect(const Ray &ray, RayHit *hit) const;
   16.94 +};
   16.95 +
   16.96 +#endif	// SNODE_H_
    17.1 --- a/liberebus/src/texture.h	Mon Apr 28 05:58:22 2014 +0300
    17.2 +++ b/liberebus/src/texture.h	Mon Apr 28 06:31:10 2014 +0300
    17.3 @@ -1,30 +1,30 @@
    17.4 -#ifndef TEXTURE_H_
    17.5 -#define TEXTURE_H_
    17.6 -
    17.7 -#include "image.h"
    17.8 -#include "color.h"
    17.9 -
   17.10 -class Texture {
   17.11 -public:
   17.12 -	Image<float> img;
   17.13 -
   17.14 -	inline Color lookup(float u, float v) const;
   17.15 -
   17.16 -	bool load(const char *fname) { return img.load(fname); }
   17.17 -};
   17.18 -
   17.19 -
   17.20 -inline Color Texture::lookup(float u, float v) const
   17.21 -{
   17.22 -	int xsz = img.get_width();
   17.23 -	int ysz = img.get_height();
   17.24 -
   17.25 -	int x = (float)u / (float)xsz;
   17.26 -	int y = (float)v / (float)ysz;
   17.27 -
   17.28 -	float *pix = img.get_pixels() + ((y % ysz) * xsz + (x % xsz)) * 4;
   17.29 -	return Color(pix[0], pix[1], pix[2]);
   17.30 -}
   17.31 -
   17.32 -
   17.33 -#endif	// TEXTURE_H_
   17.34 \ No newline at end of file
   17.35 +#ifndef TEXTURE_H_
   17.36 +#define TEXTURE_H_
   17.37 +
   17.38 +#include "image.h"
   17.39 +#include "color.h"
   17.40 +
   17.41 +class Texture {
   17.42 +public:
   17.43 +	Image<float> img;
   17.44 +
   17.45 +	inline Color lookup(float u, float v) const;
   17.46 +
   17.47 +	bool load(const char *fname) { return img.load(fname); }
   17.48 +};
   17.49 +
   17.50 +
   17.51 +inline Color Texture::lookup(float u, float v) const
   17.52 +{
   17.53 +	int xsz = img.get_width();
   17.54 +	int ysz = img.get_height();
   17.55 +
   17.56 +	int x = (float)u / (float)xsz;
   17.57 +	int y = (float)v / (float)ysz;
   17.58 +
   17.59 +	float *pix = img.get_pixels() + ((y % ysz) * xsz + (x % xsz)) * 4;
   17.60 +	return Color(pix[0], pix[1], pix[2]);
   17.61 +}
   17.62 +
   17.63 +
   17.64 +#endif	// TEXTURE_H_
    18.1 --- a/src/main.cc	Mon Apr 28 05:58:22 2014 +0300
    18.2 +++ b/src/main.cc	Mon Apr 28 06:31:10 2014 +0300
    18.3 @@ -1,141 +1,141 @@
    18.4 -#include <stdio.h>
    18.5 -#include <stdlib.h>
    18.6 -#include <assert.h>
    18.7 -#include "opengl.h"
    18.8 -
    18.9 -static bool init();
   18.10 -static void cleanup();
   18.11 -static void resize_rtarget(int xsz, int ysz);
   18.12 -static void update_rect(int x, int y, int xsz, int ysz, float *pixels);
   18.13 -static void display();
   18.14 -static void reshape(int x, int y);
   18.15 -static void keyb(unsigned char key, int x, int y);
   18.16 -static void mouse(int bn, int st, int x, int y);
   18.17 -static int next_pow2(int x);
   18.18 -
   18.19 -static int width, height, rtex_width, rtex_height;
   18.20 -static unsigned int rtex;
   18.21 -
   18.22 -int main(int argc, char **argv)
   18.23 -{
   18.24 -	glutInitWindowSize(1024, 600);
   18.25 -	glutInit(&argc, argv);
   18.26 -	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
   18.27 -	glutCreateWindow("erebus OpenGL frontend");
   18.28 -
   18.29 -	glutDisplayFunc(display);
   18.30 -	glutReshapeFunc(reshape);
   18.31 -	glutKeyboardFunc(keyb);
   18.32 -	glutMouseFunc(mouse);
   18.33 -
   18.34 -	if(!init()) {
   18.35 -		return 1;
   18.36 -	}
   18.37 -	atexit(cleanup);
   18.38 -
   18.39 -	glutMainLoop();
   18.40 -}
   18.41 -
   18.42 -static bool init()
   18.43 -{
   18.44 -	return true;
   18.45 -}
   18.46 -
   18.47 -static void cleanup()
   18.48 -{
   18.49 -}
   18.50 -
   18.51 -static void resize_rtarget(int xsz, int ysz)
   18.52 -{
   18.53 -	static unsigned char *defpix;
   18.54 -
   18.55 -	width = xsz;
   18.56 -	height = ysz;
   18.57 -
   18.58 -	if(xsz <= rtex_width && ysz <= rtex_height) {
   18.59 -		return;
   18.60 -	}
   18.61 -	rtex_width = next_pow2(xsz);
   18.62 -	rtex_height = next_pow2(ysz);
   18.63 -
   18.64 -	printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height);
   18.65 -
   18.66 -	if(!rtex) {
   18.67 -		glGenTextures(1, &rtex);
   18.68 -	}
   18.69 -
   18.70 -	delete [] defpix;
   18.71 -	defpix = new unsigned char[rtex_width * rtex_height * 4];
   18.72 -	unsigned char *ptr = defpix;
   18.73 -	for(int i=0; i<rtex_height; i++) {
   18.74 -		for(int j=0; j<rtex_width; j++) {
   18.75 -			bool chess = ((i >> 4) & 1) == ((j >> 4) & 1);
   18.76 -
   18.77 -			int val = chess ? 64 : 48;
   18.78 -
   18.79 -			*ptr++ = val;
   18.80 -			*ptr++ = val;
   18.81 -			*ptr++ = val;
   18.82 -			*ptr++ = 255;
   18.83 -		}
   18.84 -	}
   18.85 -
   18.86 -	glBindTexture(GL_TEXTURE_2D, rtex);
   18.87 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
   18.88 -	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
   18.89 -	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix);
   18.90 -}
   18.91 -
   18.92 -static void update_rect(int x, int y, int xsz, int ysz, float *pixels)
   18.93 -{
   18.94 -	glBindTexture(GL_TEXTURE_2D, rtex);
   18.95 -	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels);
   18.96 -}
   18.97 -
   18.98 -static void display()
   18.99 -{
  18.100 -	glBindTexture(GL_TEXTURE_2D, rtex);
  18.101 -	glEnable(GL_TEXTURE_2D);
  18.102 -
  18.103 -	float maxu = (float)width / (float)rtex_width;
  18.104 -	float maxv = (float)height / (float)rtex_height;
  18.105 -
  18.106 -	glBegin(GL_QUADS);
  18.107 -	glTexCoord2f(0, maxv); glVertex2f(-1, -1);
  18.108 -	glTexCoord2f(maxu, maxv); glVertex2f(1, -1);
  18.109 -	glTexCoord2f(maxu, 0); glVertex2f(1, 1);
  18.110 -	glTexCoord2f(0, 0); glVertex2f(-1, 1);
  18.111 -	glEnd();
  18.112 -
  18.113 -	glDisable(GL_TEXTURE_2D);
  18.114 -
  18.115 -	glutSwapBuffers();
  18.116 -	assert(glGetError() == GL_NO_ERROR);
  18.117 -}
  18.118 -
  18.119 -static void reshape(int x, int y)
  18.120 -{
  18.121 -	glViewport(0, 0, x, y);
  18.122 -	resize_rtarget(x, y);
  18.123 -}
  18.124 -
  18.125 -static void keyb(unsigned char key, int x, int y)
  18.126 -{
  18.127 -	switch(key) {
  18.128 -	case 27:
  18.129 -		exit(0);
  18.130 -	}
  18.131 -}
  18.132 -
  18.133 -static void mouse(int bn, int st, int x, int y)
  18.134 -{
  18.135 -}
  18.136 -
  18.137 -static int next_pow2(int x)
  18.138 -{
  18.139 -	int res = 2;
  18.140 -	while(res < x) {
  18.141 -		res <<= 1;
  18.142 -	}
  18.143 -	return res;
  18.144 -}
  18.145 \ No newline at end of file
  18.146 +#include <stdio.h>
  18.147 +#include <stdlib.h>
  18.148 +#include <assert.h>
  18.149 +#include "opengl.h"
  18.150 +
  18.151 +static bool init();
  18.152 +static void cleanup();
  18.153 +static void resize_rtarget(int xsz, int ysz);
  18.154 +static void update_rect(int x, int y, int xsz, int ysz, float *pixels);
  18.155 +static void display();
  18.156 +static void reshape(int x, int y);
  18.157 +static void keyb(unsigned char key, int x, int y);
  18.158 +static void mouse(int bn, int st, int x, int y);
  18.159 +static int next_pow2(int x);
  18.160 +
  18.161 +static int width, height, rtex_width, rtex_height;
  18.162 +static unsigned int rtex;
  18.163 +
  18.164 +int main(int argc, char **argv)
  18.165 +{
  18.166 +	glutInitWindowSize(1024, 600);
  18.167 +	glutInit(&argc, argv);
  18.168 +	glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE);
  18.169 +	glutCreateWindow("erebus OpenGL frontend");
  18.170 +
  18.171 +	glutDisplayFunc(display);
  18.172 +	glutReshapeFunc(reshape);
  18.173 +	glutKeyboardFunc(keyb);
  18.174 +	glutMouseFunc(mouse);
  18.175 +
  18.176 +	if(!init()) {
  18.177 +		return 1;
  18.178 +	}
  18.179 +	atexit(cleanup);
  18.180 +
  18.181 +	glutMainLoop();
  18.182 +}
  18.183 +
  18.184 +static bool init()
  18.185 +{
  18.186 +	return true;
  18.187 +}
  18.188 +
  18.189 +static void cleanup()
  18.190 +{
  18.191 +}
  18.192 +
  18.193 +static void resize_rtarget(int xsz, int ysz)
  18.194 +{
  18.195 +	static unsigned char *defpix;
  18.196 +
  18.197 +	width = xsz;
  18.198 +	height = ysz;
  18.199 +
  18.200 +	if(xsz <= rtex_width && ysz <= rtex_height) {
  18.201 +		return;
  18.202 +	}
  18.203 +	rtex_width = next_pow2(xsz);
  18.204 +	rtex_height = next_pow2(ysz);
  18.205 +
  18.206 +	printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height);
  18.207 +
  18.208 +	if(!rtex) {
  18.209 +		glGenTextures(1, &rtex);
  18.210 +	}
  18.211 +
  18.212 +	delete [] defpix;
  18.213 +	defpix = new unsigned char[rtex_width * rtex_height * 4];
  18.214 +	unsigned char *ptr = defpix;
  18.215 +	for(int i=0; i<rtex_height; i++) {
  18.216 +		for(int j=0; j<rtex_width; j++) {
  18.217 +			bool chess = ((i >> 4) & 1) == ((j >> 4) & 1);
  18.218 +
  18.219 +			int val = chess ? 64 : 48;
  18.220 +
  18.221 +			*ptr++ = val;
  18.222 +			*ptr++ = val;
  18.223 +			*ptr++ = val;
  18.224 +			*ptr++ = 255;
  18.225 +		}
  18.226 +	}
  18.227 +
  18.228 +	glBindTexture(GL_TEXTURE_2D, rtex);
  18.229 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
  18.230 +	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
  18.231 +	glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix);
  18.232 +}
  18.233 +
  18.234 +static void update_rect(int x, int y, int xsz, int ysz, float *pixels)
  18.235 +{
  18.236 +	glBindTexture(GL_TEXTURE_2D, rtex);
  18.237 +	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels);
  18.238 +}
  18.239 +
  18.240 +static void display()
  18.241 +{
  18.242 +	glBindTexture(GL_TEXTURE_2D, rtex);
  18.243 +	glEnable(GL_TEXTURE_2D);
  18.244 +
  18.245 +	float maxu = (float)width / (float)rtex_width;
  18.246 +	float maxv = (float)height / (float)rtex_height;
  18.247 +
  18.248 +	glBegin(GL_QUADS);
  18.249 +	glTexCoord2f(0, maxv); glVertex2f(-1, -1);
  18.250 +	glTexCoord2f(maxu, maxv); glVertex2f(1, -1);
  18.251 +	glTexCoord2f(maxu, 0); glVertex2f(1, 1);
  18.252 +	glTexCoord2f(0, 0); glVertex2f(-1, 1);
  18.253 +	glEnd();
  18.254 +
  18.255 +	glDisable(GL_TEXTURE_2D);
  18.256 +
  18.257 +	glutSwapBuffers();
  18.258 +	assert(glGetError() == GL_NO_ERROR);
  18.259 +}
  18.260 +
  18.261 +static void reshape(int x, int y)
  18.262 +{
  18.263 +	glViewport(0, 0, x, y);
  18.264 +	resize_rtarget(x, y);
  18.265 +}
  18.266 +
  18.267 +static void keyb(unsigned char key, int x, int y)
  18.268 +{
  18.269 +	switch(key) {
  18.270 +	case 27:
  18.271 +		exit(0);
  18.272 +	}
  18.273 +}
  18.274 +
  18.275 +static void mouse(int bn, int st, int x, int y)
  18.276 +{
  18.277 +}
  18.278 +
  18.279 +static int next_pow2(int x)
  18.280 +{
  18.281 +	int res = 2;
  18.282 +	while(res < x) {
  18.283 +		res <<= 1;
  18.284 +	}
  18.285 +	return res;
  18.286 +}