erebus

changeset 4:93894c232d65

more changes across the board
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 29 Apr 2014 07:38:40 +0300
parents a932848de652
children 9621beb22694
files .clang_complete .hgignore Makefile liberebus/Makefile liberebus/src/brdf.cc liberebus/src/brdf.h liberebus/src/erebus.cc liberebus/src/geomobj.cc liberebus/src/geomobj.h liberebus/src/material.cc liberebus/src/material.h liberebus/src/object.h liberebus/src/scene.cc liberebus/src/scene.h liberebus/src/snode.cc liberebus/src/snode.h src/main.cc
diffstat 17 files changed, 619 insertions(+), 318 deletions(-) [+]
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/.clang_complete	Tue Apr 29 07:38:40 2014 +0300
     1.3 @@ -0,0 +1,2 @@
     1.4 +-std=c++11
     1.5 +-Iliberebus/src
     2.1 --- a/.hgignore	Mon Apr 28 15:44:59 2014 +0300
     2.2 +++ b/.hgignore	Tue Apr 29 07:38:40 2014 +0300
     2.3 @@ -2,8 +2,10 @@
     2.4  \.d$
     2.5  \.swp$
     2.6  \.a$
     2.7 +\.so$
     2.8  \.so\.
     2.9 -\.dylib
    2.10 +\.dylib$
    2.11  \.suo$
    2.12  Debug/
    2.13  Release/
    2.14 +^erebus$
     3.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     3.2 +++ b/Makefile	Tue Apr 29 07:38:40 2014 +0300
     3.3 @@ -0,0 +1,28 @@
     3.4 +csrc = $(wildcard src/*.c)
     3.5 +ccsrc = $(wildcard src/*.cc)
     3.6 +obj = $(csrc:.c=.o) $(ccsrc:.cc=.o)
     3.7 +bin = erebus
     3.8 +
     3.9 +CFLAGS = -pedantic -Wall -g -Iliberebus/src
    3.10 +CXXFLAGS = -std=c++11 $(CFLAGS)
    3.11 +LDFLAGS = -Lliberebus -Wl,-rpath=liberebus $(libgl_$(sys)) -lm -lerebus -lvmath
    3.12 +
    3.13 +libgl_unix = -lGL -lGLU -lglut -lGLEW
    3.14 +libgl_mac = -framework OpenGL -framework GLUT -lGLEW
    3.15 +libgl_win = -lopengl32 -lglu32 -lglut32 -lglew32
    3.16 +
    3.17 +$(bin): $(obj) liberebus/liberebus.so
    3.18 +	$(CXX) -o $@ $(obj) $(LDFLAGS)
    3.19 +
    3.20 +.PHONY: clean
    3.21 +clean:
    3.22 +	rm -f $(obj) $(bin)
    3.23 +
    3.24 +uname = $(shell uname -s)
    3.25 +ifeq ($(uname), Darwin)
    3.26 +	sys = mac
    3.27 +else ifeq ($(findstring MINGW, $(uname)), MINGW)
    3.28 +	sys = win
    3.29 +else
    3.30 +	sys = unix
    3.31 +endif
     4.1 --- a/liberebus/Makefile	Mon Apr 28 15:44:59 2014 +0300
     4.2 +++ b/liberebus/Makefile	Tue Apr 29 07:38:40 2014 +0300
     4.3 @@ -27,6 +27,9 @@
     4.4  
     4.5  $(lib_so): $(obj)
     4.6  	$(CXX) -o $@ $(shared) $(obj) $(LDFLAGS)
     4.7 +	[ -n "$(devlink)" ] && \
     4.8 +		rm -f $(soname) $(devlink) && \
     4.9 +		ln -s $@ $(soname) && ln -s $(soname) $(devlink) || true
    4.10  
    4.11  $(lib_a): $(obj)
    4.12  	$(AR) rcs $@ $(obj)
    4.13 @@ -38,4 +41,4 @@
    4.14  
    4.15  .PHONY: clean
    4.16  clean:
    4.17 -	rm -f $(obj) $(lib_so) $(lib_a)
    4.18 +	rm -f $(obj) $(lib_so) $(lib_a) $(soname) $(devlink)
     5.1 --- a/liberebus/src/brdf.cc	Mon Apr 28 15:44:59 2014 +0300
     5.2 +++ b/liberebus/src/brdf.cc	Tue Apr 29 07:38:40 2014 +0300
     5.3 @@ -1,108 +1,9 @@
     5.4  #include "brdf.h"
     5.5  #include "erebus_impl.h"
     5.6  
     5.7 -ReflAttrib::ReflAttrib()
     5.8 -	: value(1), color(1, 1, 1), map(0)
     5.9 -{
    5.10 -}
    5.11 -
    5.12 -ReflAttrib::ReflAttrib(const Color &col, Texture *tex)
    5.13 -{
    5.14 -	set_color(col);
    5.15 -	map = tex;
    5.16 -}
    5.17 -
    5.18 -void ReflAttrib::set_value(float val)
    5.19 -{
    5.20 -	value = val;
    5.21 -	color = Color{val, val, val};
    5.22 -}
    5.23 -
    5.24 -void ReflAttrib::set_color(const Color &col)
    5.25 -{
    5.26 -	color = col;
    5.27 -	value = color_luminance(col);
    5.28 -}
    5.29 -
    5.30 -void ReflAttrib::set_map(Texture *tex)
    5.31 -{
    5.32 -	map = tex;
    5.33 -}
    5.34 -
    5.35 -Texture *ReflAttrib::get_map() const
    5.36 -{
    5.37 -	return map;
    5.38 -}
    5.39 -
    5.40 -float ReflAttrib::get_value() const
    5.41 -{
    5.42 -	return value;
    5.43 -}
    5.44 -
    5.45 -float ReflAttrib::get_value(float u, float v) const
    5.46 -{
    5.47 -	return map ? value * color_luminance(map->lookup(u, v)) : value;
    5.48 -}
    5.49 -
    5.50 -const Color &ReflAttrib::get_color() const
    5.51 -{
    5.52 -	return color;
    5.53 -}
    5.54 -
    5.55 -Color ReflAttrib::get_color(float u, float v) const
    5.56 -{
    5.57 -	return map ? color * map->lookup(u, v) : color;
    5.58 -}
    5.59 -
    5.60  // ---- class Reflectance ----
    5.61 -ReflAttrib Reflectance::def_attrib;
    5.62 -
    5.63  Reflectance::Reflectance()
    5.64  {
    5.65 -	set_default_attribs();
    5.66 -}
    5.67 -
    5.68 -void Reflectance::set_attrib(const char *name, const Color &color, Texture *tex)
    5.69 -{
    5.70 -	attrib[name] = ReflAttrib{color, tex};
    5.71 -}
    5.72 -
    5.73 -ReflAttrib &Reflectance::get_attrib(const char *name)
    5.74 -{
    5.75 -	auto it = attrib.find(name);
    5.76 -	if(it == attrib.end()) {
    5.77 -		return def_attrib;
    5.78 -	}
    5.79 -	return it->second;
    5.80 -}
    5.81 -
    5.82 -const ReflAttrib &Reflectance::get_attrib(const char *name) const
    5.83 -{
    5.84 -	auto it = attrib.find(name);
    5.85 -	if(it == attrib.end()) {
    5.86 -		return def_attrib;
    5.87 -	}
    5.88 -	return it->second;
    5.89 -}
    5.90 -
    5.91 -float Reflectance::get_attrib_value(const char *name) const
    5.92 -{
    5.93 -	return get_attrib(name).get_value();
    5.94 -}
    5.95 -
    5.96 -float Reflectance::get_attrib_value(const char *name, float u, float v) const
    5.97 -{
    5.98 -	return get_attrib(name).get_value(u, v);
    5.99 -}
   5.100 -
   5.101 -Color Reflectance::get_attrib_color(const char *name) const
   5.102 -{
   5.103 -	return get_attrib(name).get_color();
   5.104 -}
   5.105 -
   5.106 -Color Reflectance::get_attrib_color(const char *name, float u, float v) const
   5.107 -{
   5.108 -	return get_attrib(name).get_color(u, v);
   5.109  }
   5.110  
   5.111  float Reflectance::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const
   5.112 @@ -112,12 +13,6 @@
   5.113  }
   5.114  
   5.115  // --- class LambertRefl ---
   5.116 -
   5.117 -void LambertRefl::set_default_attribs()
   5.118 -{
   5.119 -	set_attrib("color", Color(1, 1, 1));
   5.120 -}
   5.121 -
   5.122  Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const
   5.123  {
   5.124  	Vector3 dir = Vector3{randf(-1, 1), randf(-1, 1), randf(-1, 1)}.normalized();
     6.1 --- a/liberebus/src/brdf.h	Mon Apr 28 15:44:59 2014 +0300
     6.2 +++ b/liberebus/src/brdf.h	Tue Apr 29 07:38:40 2014 +0300
     6.3 @@ -1,64 +1,19 @@
     6.4  #ifndef BRDF_H_
     6.5  #define BRDF_H_
     6.6  
     6.7 -#include <map>
     6.8 -#include <string>
     6.9 -#include "color.h"
    6.10  #include "texture.h"
    6.11  
    6.12 -class ReflAttrib {
    6.13 -private:
    6.14 -	float value;
    6.15 -	Color color;
    6.16 -	Texture *map;
    6.17 -
    6.18 -public:
    6.19 -
    6.20 -	ReflAttrib();
    6.21 -	explicit ReflAttrib(const Color &color, Texture *tex = 0);
    6.22 -
    6.23 -	void set_value(float val);
    6.24 -	void set_color(const Color &col);
    6.25 -
    6.26 -	void set_map(Texture *tex);
    6.27 -	Texture *get_map() const;
    6.28 -
    6.29 -	float get_value() const;
    6.30 -	float get_value(float u, float v) const;
    6.31 -	const Color &get_color() const;
    6.32 -	Color get_color(float u, float v) const;
    6.33 -};
    6.34 -
    6.35 -
    6.36  class Reflectance {
    6.37 -private:
    6.38 -	static ReflAttrib def_attrib;
    6.39 -	std::map<std::string, ReflAttrib> attrib;
    6.40 -
    6.41 -	virtual void set_default_attribs();
    6.42 -
    6.43  public:
    6.44  	Reflectance();
    6.45  	virtual ~Reflectance() = default;
    6.46  
    6.47 -	virtual void set_attrib(const char *name, const Color &color, Texture *tex = 0);
    6.48 -	virtual ReflAttrib &get_attrib(const char *name);
    6.49 -	virtual const ReflAttrib &get_attrib(const char *name) const;
    6.50 -
    6.51 -	virtual float get_attrib_value(const char *name) const;
    6.52 -	virtual float get_attrib_value(const char *name, float u, float v) const;
    6.53 -	virtual Color get_attrib_color(const char *name) const;
    6.54 -	virtual Color get_attrib_color(const char *name, float u, float v) const;
    6.55 -
    6.56  	virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0;
    6.57  	virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const;
    6.58  	virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0;
    6.59  };
    6.60  
    6.61  class LambertRefl : public Reflectance {
    6.62 -private:
    6.63 -	void set_default_attribs() override;
    6.64 -
    6.65  public:
    6.66  	Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override;
    6.67  	float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override;
     7.1 --- a/liberebus/src/erebus.cc	Mon Apr 28 15:44:59 2014 +0300
     7.2 +++ b/liberebus/src/erebus.cc	Tue Apr 29 07:38:40 2014 +0300
     7.3 @@ -5,6 +5,8 @@
     7.4  #include "erebus.h"
     7.5  #include "vmath/vector.h"
     7.6  #include "image.h"
     7.7 +#include "scene.h"
     7.8 +#include "geomobj.h"
     7.9  
    7.10  using namespace std::chrono;
    7.11  
    7.12 @@ -18,6 +20,8 @@
    7.13  #define INVALID_RECT	Rect{0, 0, 0, 0}
    7.14  
    7.15  struct erebus {
    7.16 +	Scene *scn;
    7.17 +
    7.18  	Image<float> fbimg;
    7.19  	Vector4 options[ERB_NUM_OPTIONS];
    7.20  
    7.21 @@ -43,6 +47,7 @@
    7.22  		return 0;
    7.23  	}
    7.24  
    7.25 +	ctx->scn = 0;
    7.26  	ctx->cur_time = 0;
    7.27  	ctx->cur_rect = INVALID_RECT;
    7.28  	return ctx;
    7.29 @@ -89,6 +94,11 @@
    7.30  void erb_begin_frame(struct erebus *ctx, long ms)
    7.31  {
    7.32  	ctx->cur_time = ms;
    7.33 +
    7.34 +	int xsz = ctx->options[ERB_OPT_WIDTH].x;
    7.35 +	int ysz = ctx->options[ERB_OPT_HEIGHT].x;
    7.36 +
    7.37 +	ctx->fbimg.create(xsz, ysz);
    7.38  }
    7.39  
    7.40  int erb_render(struct erebus *ctx, long timeout)
    7.41 @@ -107,6 +117,8 @@
    7.42  		ctx->cur_pixel_y = y;
    7.43  	}
    7.44  
    7.45 +	ctx->scn->update();
    7.46 +
    7.47  	if(timeout > 0) {
    7.48  		auto start_time = steady_clock::now();
    7.49  		while(duration_cast<milliseconds>(steady_clock::now() - start_time).count() < timeout) {
    7.50 @@ -137,10 +149,20 @@
    7.51  
    7.52  int erb_load_scene(struct erebus *ctx, const char *fname)
    7.53  {
    7.54 -	//delete ctx->scene;
    7.55 -	//ctx->scene = new Scene;
    7.56 +	delete ctx->scn;
    7.57 +	ctx->scn = new Scene;
    7.58  
    7.59 -	return false;	// TODO
    7.60 +	// XXX for now just create a test scene here
    7.61 +	Sphere *sph = new Sphere;
    7.62 +	SceneNode *sph_node = new SceneNode(sph);
    7.63 +	ctx->scn->add_object(sph);
    7.64 +	ctx->scn->add_node(sph_node);
    7.65 +
    7.66 +	TargetCamera *cam = new TargetCamera(Vector3(0, 0, -10), Vector3(0, 0, 0));
    7.67 +	//ctx->scn->add_object(cam);
    7.68 +	ctx->scn->use_camera(cam);
    7.69 +
    7.70 +	return 0;
    7.71  }
    7.72  
    7.73  }	// extern "C"
     8.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     8.2 +++ b/liberebus/src/geomobj.cc	Tue Apr 29 07:38:40 2014 +0300
     8.3 @@ -0,0 +1,87 @@
     8.4 +#include <float.h>
     8.5 +#include "geomobj.h"
     8.6 +
     8.7 +static LambertRefl lambert;
     8.8 +
     8.9 +GeomObject::GeomObject()
    8.10 +{
    8.11 +	brdf = &lambert;
    8.12 +}
    8.13 +
    8.14 +ObjType GeomObject::get_type() const
    8.15 +{
    8.16 +	return ObjType::geom;
    8.17 +}
    8.18 +
    8.19 +bool GeomObject::intersect(const Ray &ray, RayHit *hit) const
    8.20 +{
    8.21 +	return false;
    8.22 +}
    8.23 +
    8.24 +// --- class Sphere ---
    8.25 +
    8.26 +bool Sphere::intersect(const Ray &ray, RayHit *hit) const
    8.27 +{
    8.28 +	// assumes center is the origin and radius is 1
    8.29 +	float a = dot_product(ray.dir, ray.dir);
    8.30 +	float b = 2.0 * dot_product(ray.dir, ray.origin);
    8.31 +	float c = dot_product(ray.origin, ray.origin) - 1.0;
    8.32 +
    8.33 +	float d = b * b - 4.0 * a * c;
    8.34 +	if(d < 1e-4) return false;
    8.35 +
    8.36 +	float sqrt_d = sqrt(d);
    8.37 +	float t0 = (-b + sqrt_d) / (2.0 * a);
    8.38 +	float t1 = (-b - sqrt_d) / (2.0 * a);
    8.39 +
    8.40 +	if(t0 < 1e-4) t0 = t1;
    8.41 +	if(t1 < 1e-4) t1 = t0;
    8.42 +	float t = t0 < t1 ? t0 : t1;
    8.43 +	if(t < 1e-4) return false;
    8.44 +
    8.45 +	if(hit) {
    8.46 +		hit->dist = t;
    8.47 +		hit->obj = this;
    8.48 +		hit->subobj = 0;
    8.49 +	}
    8.50 +	return true;
    8.51 +}
    8.52 +
    8.53 +// --- class Box ---
    8.54 +
    8.55 +bool Box::intersect(const Ray &ray, RayHit *hit) const
    8.56 +{
    8.57 +	return false;
    8.58 +}
    8.59 +
    8.60 +// --- class Triangle ---
    8.61 +
    8.62 +bool Triangle::intersect(const Ray &ray, RayHit *hit) const
    8.63 +{
    8.64 +	return false;
    8.65 +}
    8.66 +
    8.67 +// --- class Mesh ---
    8.68 +
    8.69 +bool Mesh::intersect(const Ray &ray, RayHit *hit) const
    8.70 +{
    8.71 +	RayHit nearest;
    8.72 +	nearest.dist = FLT_MAX;
    8.73 +
    8.74 +	for(size_t i=0; i<faces.size(); i++) {
    8.75 +		if(faces[i].intersect(ray, hit)) {
    8.76 +			if(!hit) return true;
    8.77 +			if(hit->dist < nearest.dist) {
    8.78 +				nearest = *hit;
    8.79 +			}
    8.80 +		}
    8.81 +	}
    8.82 +
    8.83 +	if(nearest.dist < FLT_MAX) {
    8.84 +		*hit = nearest;
    8.85 +		hit->subobj = hit->obj;
    8.86 +		hit->obj = this;
    8.87 +		return true;
    8.88 +	}
    8.89 +	return false;
    8.90 +}
     9.1 --- a/liberebus/src/geomobj.h	Mon Apr 28 15:44:59 2014 +0300
     9.2 +++ b/liberebus/src/geomobj.h	Tue Apr 29 07:38:40 2014 +0300
     9.3 @@ -3,12 +3,16 @@
     9.4  
     9.5  #include <vector>
     9.6  #include "object.h"
     9.7 +#include "material.h"
     9.8  #include "brdf.h"
     9.9  
    9.10  class GeomObject : public Object {
    9.11  public:
    9.12 +	Material mtl;
    9.13  	Reflectance *brdf;
    9.14  
    9.15 +	GeomObject();
    9.16 +
    9.17  	ObjType get_type() const override;
    9.18  
    9.19  	bool intersect(const Ray &ray, RayHit *hit = 0) const override;
    10.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    10.2 +++ b/liberebus/src/material.cc	Tue Apr 29 07:38:40 2014 +0300
    10.3 @@ -0,0 +1,107 @@
    10.4 +#include "material.h"
    10.5 +
    10.6 +MatAttrib::MatAttrib()
    10.7 +	: value(1), color(1, 1, 1), map(0)
    10.8 +{
    10.9 +}
   10.10 +
   10.11 +MatAttrib::MatAttrib(const Color &col, Texture *tex)
   10.12 +{
   10.13 +	set_color(col);
   10.14 +	map = tex;
   10.15 +}
   10.16 +
   10.17 +void MatAttrib::set_value(float val)
   10.18 +{
   10.19 +	value = val;
   10.20 +	color = Color{val, val, val};
   10.21 +}
   10.22 +
   10.23 +void MatAttrib::set_color(const Color &col)
   10.24 +{
   10.25 +	color = col;
   10.26 +	value = color_luminance(col);
   10.27 +}
   10.28 +
   10.29 +void MatAttrib::set_map(Texture *tex)
   10.30 +{
   10.31 +	map = tex;
   10.32 +}
   10.33 +
   10.34 +Texture *MatAttrib::get_map() const
   10.35 +{
   10.36 +	return map;
   10.37 +}
   10.38 +
   10.39 +float MatAttrib::get_value() const
   10.40 +{
   10.41 +	return value;
   10.42 +}
   10.43 +
   10.44 +float MatAttrib::get_value(float u, float v) const
   10.45 +{
   10.46 +	return map ? value * color_luminance(map->lookup(u, v)) : value;
   10.47 +}
   10.48 +
   10.49 +const Color &MatAttrib::get_color() const
   10.50 +{
   10.51 +	return color;
   10.52 +}
   10.53 +
   10.54 +Color MatAttrib::get_color(float u, float v) const
   10.55 +{
   10.56 +	return map ? color * map->lookup(u, v) : color;
   10.57 +}
   10.58 +
   10.59 +
   10.60 +// --- class Material ---
   10.61 +
   10.62 +MatAttrib Material::def_attrib;
   10.63 +
   10.64 +Material::Material()
   10.65 +{
   10.66 +}
   10.67 +
   10.68 +void Material::set_attrib(const char *name, const Color &color, Texture *tex)
   10.69 +{
   10.70 +	attrib[name] = MatAttrib{color, tex};
   10.71 +}
   10.72 +
   10.73 +MatAttrib &Material::get_attrib(const char *name)
   10.74 +{
   10.75 +	auto it = attrib.find(name);
   10.76 +	if(it == attrib.end()) {
   10.77 +		return def_attrib;
   10.78 +	}
   10.79 +	return it->second;
   10.80 +}
   10.81 +
   10.82 +const MatAttrib &Material::get_attrib(const char *name) const
   10.83 +{
   10.84 +	auto it = attrib.find(name);
   10.85 +	if(it == attrib.end()) {
   10.86 +		return def_attrib;
   10.87 +	}
   10.88 +	return it->second;
   10.89 +}
   10.90 +
   10.91 +float Material::get_attrib_value(const char *name) const
   10.92 +{
   10.93 +	return get_attrib(name).get_value();
   10.94 +}
   10.95 +
   10.96 +float Material::get_attrib_value(const char *name, float u, float v) const
   10.97 +{
   10.98 +	return get_attrib(name).get_value(u, v);
   10.99 +}
  10.100 +
  10.101 +Color Material::get_attrib_color(const char *name) const
  10.102 +{
  10.103 +	return get_attrib(name).get_color();
  10.104 +}
  10.105 +
  10.106 +Color Material::get_attrib_color(const char *name, float u, float v) const
  10.107 +{
  10.108 +	return get_attrib(name).get_color(u, v);
  10.109 +}
  10.110 +
    11.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
    11.2 +++ b/liberebus/src/material.h	Tue Apr 29 07:38:40 2014 +0300
    11.3 @@ -0,0 +1,50 @@
    11.4 +#ifndef MATERIAL_H_
    11.5 +#define MATERIAL_H_
    11.6 +
    11.7 +#include <string>
    11.8 +#include <map>
    11.9 +#include "color.h"
   11.10 +#include "texture.h"
   11.11 +
   11.12 +class MatAttrib {
   11.13 +private:
   11.14 +	float value;
   11.15 +	Color color;
   11.16 +	Texture *map;
   11.17 +
   11.18 +public:
   11.19 +	MatAttrib();
   11.20 +	explicit MatAttrib(const Color &color, Texture *tex = 0);
   11.21 +
   11.22 +	void set_value(float val);
   11.23 +	void set_color(const Color &col);
   11.24 +
   11.25 +	void set_map(Texture *tex);
   11.26 +	Texture *get_map() const;
   11.27 +
   11.28 +	float get_value() const;
   11.29 +	float get_value(float u, float v) const;
   11.30 +	const Color &get_color() const;
   11.31 +	Color get_color(float u, float v) const;
   11.32 +};
   11.33 +
   11.34 +class Material {
   11.35 +private:
   11.36 +	static MatAttrib def_attrib;
   11.37 +	std::map<std::string, MatAttrib> attrib;
   11.38 +
   11.39 +public:
   11.40 +	Material();
   11.41 +
   11.42 +	void set_attrib(const char *name, const Color &color, Texture *tex = 0);
   11.43 +	MatAttrib &get_attrib(const char *name);
   11.44 +	const MatAttrib &get_attrib(const char *name) const;
   11.45 +
   11.46 +	float get_attrib_value(const char *name) const;
   11.47 +	float get_attrib_value(const char *name, float u, float v) const;
   11.48 +	Color get_attrib_color(const char *name) const;
   11.49 +	Color get_attrib_color(const char *name, float u, float v) const;
   11.50 +};
   11.51 +
   11.52 +
   11.53 +#endif	// MATERIAL_H_
    12.1 --- a/liberebus/src/object.h	Mon Apr 28 15:44:59 2014 +0300
    12.2 +++ b/liberebus/src/object.h	Tue Apr 29 07:38:40 2014 +0300
    12.3 @@ -8,7 +8,7 @@
    12.4  
    12.5  struct RayHit {
    12.6  	float dist;
    12.7 -	const Ray world_ray, local_ray;
    12.8 +	Ray world_ray, local_ray;
    12.9  
   12.10  	const Object *obj, *subobj;
   12.11  };
    13.1 --- a/liberebus/src/scene.cc	Mon Apr 28 15:44:59 2014 +0300
    13.2 +++ b/liberebus/src/scene.cc	Tue Apr 29 07:38:40 2014 +0300
    13.3 @@ -1,51 +1,77 @@
    13.4 -#include "scene.h"
    13.5 -
    13.6 -Scene::Scene()
    13.7 -{
    13.8 -	active_cam = 0;
    13.9 -}
   13.10 -
   13.11 -Scene::~Scene()
   13.12 -{
   13.13 -	for(auto obj : objects) {
   13.14 -		delete obj;
   13.15 -	}
   13.16 -	for(auto node : nodes) {
   13.17 -		delete node;
   13.18 -	}
   13.19 -}
   13.20 -
   13.21 -void Scene::add_object(Object *obj)
   13.22 -{
   13.23 -	objects.push_back(obj);
   13.24 -}
   13.25 -
   13.26 -int Scene::get_object_count() const
   13.27 -{
   13.28 -	return (int)objects.size();
   13.29 -}
   13.30 -
   13.31 -Object *Scene::get_object(int idx) const
   13.32 -{
   13.33 -	return objects[idx];
   13.34 -}
   13.35 -
   13.36 -void Scene::add_node(SceneNode *node)
   13.37 -{
   13.38 -	nodes.push_back(node);
   13.39 -}
   13.40 -
   13.41 -int Scene::get_node_count() const
   13.42 -{
   13.43 -	return (int)nodes.size();
   13.44 -}
   13.45 -
   13.46 -SceneNode *Scene::get_node(int idx) const
   13.47 -{
   13.48 -	return nodes[idx];
   13.49 -}
   13.50 -
   13.51 -bool Scene::intersect(const Ray &ray, RayHit *hit) const
   13.52 -{
   13.53 -
   13.54 -}
   13.55 \ No newline at end of file
   13.56 +#include "scene.h"
   13.57 +
   13.58 +Scene::Scene()
   13.59 +{
   13.60 +	active_cam = 0;
   13.61 +	root = new SceneNode;
   13.62 +}
   13.63 +
   13.64 +Scene::~Scene()
   13.65 +{
   13.66 +	for(auto obj : objects) {
   13.67 +		delete obj;
   13.68 +	}
   13.69 +	for(auto node : nodes) {
   13.70 +		delete node;
   13.71 +	}
   13.72 +	delete root;
   13.73 +}
   13.74 +
   13.75 +void Scene::add_object(Object *obj)
   13.76 +{
   13.77 +	objects.push_back(obj);
   13.78 +}
   13.79 +
   13.80 +int Scene::get_object_count() const
   13.81 +{
   13.82 +	return (int)objects.size();
   13.83 +}
   13.84 +
   13.85 +Object *Scene::get_object(int idx) const
   13.86 +{
   13.87 +	return objects[idx];
   13.88 +}
   13.89 +
   13.90 +void Scene::add_node(SceneNode *node)
   13.91 +{
   13.92 +	nodes.push_back(node);
   13.93 +
   13.94 +	if(!node->get_parent()) {
   13.95 +		root->add_child(node);
   13.96 +	}
   13.97 +}
   13.98 +
   13.99 +int Scene::get_node_count() const
  13.100 +{
  13.101 +	return (int)nodes.size();
  13.102 +}
  13.103 +
  13.104 +SceneNode *Scene::get_node(int idx) const
  13.105 +{
  13.106 +	return nodes[idx];
  13.107 +}
  13.108 +
  13.109 +void Scene::use_camera(Camera *cam)
  13.110 +{
  13.111 +	active_cam = cam;
  13.112 +}
  13.113 +
  13.114 +Camera *Scene::get_active_camera() const
  13.115 +{
  13.116 +	return active_cam;
  13.117 +}
  13.118 +
  13.119 +void Scene::update(long msec)
  13.120 +{
  13.121 +	root->update(msec);
  13.122 +}
  13.123 +
  13.124 +bool Scene::intersect(const Ray &ray, RayHit *hit) const
  13.125 +{
  13.126 +	return root->intersect(ray, hit);
  13.127 +}
  13.128 +
  13.129 +bool Scene::load(const char *fname)
  13.130 +{
  13.131 +	return false;	// TODO
  13.132 +}
    14.1 --- a/liberebus/src/scene.h	Mon Apr 28 15:44:59 2014 +0300
    14.2 +++ b/liberebus/src/scene.h	Tue Apr 29 07:38:40 2014 +0300
    14.3 @@ -10,6 +10,8 @@
    14.4  	std::vector<Object*> objects;
    14.5  	std::vector<SceneNode*> nodes;
    14.6  
    14.7 +	SceneNode *root;
    14.8 +
    14.9  	Camera *active_cam;
   14.10  
   14.11  public:
   14.12 @@ -24,7 +26,14 @@
   14.13  	int get_node_count() const;
   14.14  	SceneNode *get_node(int idx) const;
   14.15  
   14.16 +	void use_camera(Camera *cam);
   14.17 +	Camera *get_active_camera() const;
   14.18 +
   14.19 +	void update(long msec = 0);
   14.20 +
   14.21  	bool intersect(const Ray &ray, RayHit *hit) const;
   14.22 +
   14.23 +	bool load(const char *fname);
   14.24  };
   14.25  
   14.26  #endif	// SCENE_H_
    15.1 --- a/liberebus/src/snode.cc	Mon Apr 28 15:44:59 2014 +0300
    15.2 +++ b/liberebus/src/snode.cc	Tue Apr 29 07:38:40 2014 +0300
    15.3 @@ -1,111 +1,168 @@
    15.4 -#include <assert.h>
    15.5 -#include <algorithm>
    15.6 -#include "snode.h"
    15.7 -
    15.8 -void SceneNode::add_child(SceneNode *node)
    15.9 -{
   15.10 -	if(node->parent) {
   15.11 -		if(node->parent == this) {
   15.12 -			return;
   15.13 -		}
   15.14 -		node->parent->remove_child(node);
   15.15 -	}
   15.16 -
   15.17 -	children.push_back(node);
   15.18 -	node->parent = this;
   15.19 -}
   15.20 -
   15.21 -bool SceneNode::remove_child(SceneNode *node)
   15.22 -{
   15.23 -	auto it = std::find(children.begin(), children.end(), node);
   15.24 -	if(it != children.end()) {
   15.25 -		assert(node->parent == this);
   15.26 -		node->parent = 0;
   15.27 -	}
   15.28 -}
   15.29 -
   15.30 -int SceneNode::get_num_children() const
   15.31 -{
   15.32 -	return (int)children.size();
   15.33 -}
   15.34 -
   15.35 -SceneNode *SceneNode::get_child(int idx) const
   15.36 -{
   15.37 -	return children[idx];
   15.38 -}
   15.39 -
   15.40 -void SceneNode::set_position(const Vector3 &pos)
   15.41 -{
   15.42 -	this->pos = pos;
   15.43 -}
   15.44 -
   15.45 -void SceneNode::set_rotation(const Quaternion &rot)
   15.46 -{
   15.47 -	this->rot = rot;
   15.48 -}
   15.49 -
   15.50 -void SceneNode::set_scaling(const Vector3 &scale)
   15.51 -{
   15.52 -	this->scale = scale;
   15.53 -}
   15.54 -
   15.55 -
   15.56 -const Vector3 &SceneNode::get_node_position() const
   15.57 -{
   15.58 -	return pos;
   15.59 -}
   15.60 -
   15.61 -const Quaternion &SceneNode::get_node_rotation() const
   15.62 -{
   15.63 -	return rot;
   15.64 -}
   15.65 -
   15.66 -const Vector3 &SceneNode::get_node_scaling() const
   15.67 -{
   15.68 -	return scale;
   15.69 -}
   15.70 -
   15.71 -
   15.72 -Vector3 SceneNode::get_position() const
   15.73 -{
   15.74 -	return Vector3{0, 0, 0}.transformed(xform);
   15.75 -}
   15.76 -
   15.77 -Quaternion SceneNode::get_rotation() const
   15.78 -{
   15.79 -	return rot;	// TODO
   15.80 -}
   15.81 -
   15.82 -Vector3 SceneNode::get_scaling() const
   15.83 -{
   15.84 -	return scale;	// TODO
   15.85 -}
   15.86 -
   15.87 -
   15.88 -void SceneNode::update_node(long msec)
   15.89 -{
   15.90 -	xform.reset_identity();
   15.91 -	xform.translate(pos);
   15.92 -	xform.rotate(rot);
   15.93 -	xform.scale(scale);
   15.94 -
   15.95 -	if(parent) {
   15.96 -		xform = parent->xform * xform;
   15.97 -	}
   15.98 -	inv_xform = xform.inverse();
   15.99 -}
  15.100 -
  15.101 -void SceneNode::update(long msec)
  15.102 -{
  15.103 -	update_node(msec);
  15.104 -
  15.105 -	for(size_t i=0; i<children.size(); i++) {
  15.106 -		children[i]->update(msec);
  15.107 -	}
  15.108 -}
  15.109 -
  15.110 -
  15.111 -bool SceneNode::intersect(const Ray &ray, RayHit *hit) const
  15.112 -{
  15.113 -	Ray local_ray = ray.transformed(inv_xform);
  15.114 -}
  15.115 \ No newline at end of file
  15.116 +#include <float.h>
  15.117 +#include <assert.h>
  15.118 +#include <algorithm>
  15.119 +#include "snode.h"
  15.120 +
  15.121 +SceneNode::SceneNode()
  15.122 +	: scale(1, 1, 1)
  15.123 +{
  15.124 +	parent = 0;
  15.125 +}
  15.126 +
  15.127 +SceneNode::SceneNode(Object *obj)
  15.128 +	: scale(1, 1, 1)
  15.129 +{
  15.130 +	parent = 0;
  15.131 +	add_object(obj);
  15.132 +}
  15.133 +
  15.134 +void SceneNode::add_child(SceneNode *node)
  15.135 +{
  15.136 +	if(node->parent) {
  15.137 +		if(node->parent == this) {
  15.138 +			return;
  15.139 +		}
  15.140 +		node->parent->remove_child(node);
  15.141 +	}
  15.142 +
  15.143 +	children.push_back(node);
  15.144 +	node->parent = this;
  15.145 +}
  15.146 +
  15.147 +bool SceneNode::remove_child(SceneNode *node)
  15.148 +{
  15.149 +	auto it = std::find(children.begin(), children.end(), node);
  15.150 +	if(it != children.end()) {
  15.151 +		assert(node->parent == this);
  15.152 +		node->parent = 0;
  15.153 +		return true;
  15.154 +	}
  15.155 +	return false;
  15.156 +}
  15.157 +
  15.158 +int SceneNode::get_num_children() const
  15.159 +{
  15.160 +	return (int)children.size();
  15.161 +}
  15.162 +
  15.163 +SceneNode *SceneNode::get_child(int idx) const
  15.164 +{
  15.165 +	return children[idx];
  15.166 +}
  15.167 +
  15.168 +SceneNode *SceneNode::get_parent() const
  15.169 +{
  15.170 +	return parent;
  15.171 +}
  15.172 +
  15.173 +void SceneNode::add_object(Object *obj)
  15.174 +{
  15.175 +	if(std::find(this->obj.begin(), this->obj.end(), obj) == this->obj.end()) {
  15.176 +		this->obj.push_back(obj);
  15.177 +	}
  15.178 +}
  15.179 +
  15.180 +int SceneNode::get_num_objects() const
  15.181 +{
  15.182 +	return (int)obj.size();
  15.183 +}
  15.184 +
  15.185 +Object *SceneNode::get_object(int idx) const
  15.186 +{
  15.187 +	return obj[idx];
  15.188 +}
  15.189 +
  15.190 +void SceneNode::set_position(const Vector3 &pos)
  15.191 +{
  15.192 +	this->pos = pos;
  15.193 +}
  15.194 +
  15.195 +void SceneNode::set_rotation(const Quaternion &rot)
  15.196 +{
  15.197 +	this->rot = rot;
  15.198 +}
  15.199 +
  15.200 +void SceneNode::set_scaling(const Vector3 &scale)
  15.201 +{
  15.202 +	this->scale = scale;
  15.203 +}
  15.204 +
  15.205 +
  15.206 +const Vector3 &SceneNode::get_node_position() const
  15.207 +{
  15.208 +	return pos;
  15.209 +}
  15.210 +
  15.211 +const Quaternion &SceneNode::get_node_rotation() const
  15.212 +{
  15.213 +	return rot;
  15.214 +}
  15.215 +
  15.216 +const Vector3 &SceneNode::get_node_scaling() const
  15.217 +{
  15.218 +	return scale;
  15.219 +}
  15.220 +
  15.221 +
  15.222 +Vector3 SceneNode::get_position() const
  15.223 +{
  15.224 +	return Vector3{0, 0, 0}.transformed(xform);
  15.225 +}
  15.226 +
  15.227 +Quaternion SceneNode::get_rotation() const
  15.228 +{
  15.229 +	return rot;	// TODO
  15.230 +}
  15.231 +
  15.232 +Vector3 SceneNode::get_scaling() const
  15.233 +{
  15.234 +	return scale;	// TODO
  15.235 +}
  15.236 +
  15.237 +
  15.238 +void SceneNode::update_node(long msec)
  15.239 +{
  15.240 +	xform.reset_identity();
  15.241 +	xform.translate(pos);
  15.242 +	xform.rotate(rot);
  15.243 +	xform.scale(scale);
  15.244 +
  15.245 +	if(parent) {
  15.246 +		xform = parent->xform * xform;
  15.247 +	}
  15.248 +	inv_xform = xform.inverse();
  15.249 +}
  15.250 +
  15.251 +void SceneNode::update(long msec)
  15.252 +{
  15.253 +	update_node(msec);
  15.254 +
  15.255 +	for(size_t i=0; i<children.size(); i++) {
  15.256 +		children[i]->update(msec);
  15.257 +	}
  15.258 +}
  15.259 +
  15.260 +
  15.261 +bool SceneNode::intersect(const Ray &ray, RayHit *hit) const
  15.262 +{
  15.263 +	Ray local_ray = ray.transformed(inv_xform);
  15.264 +
  15.265 +	RayHit nearest;
  15.266 +	nearest.dist = FLT_MAX;
  15.267 +	for(size_t i=0; i<obj.size(); i++) {
  15.268 +		if(obj[i]->intersect(local_ray, hit)) {
  15.269 +			if(!hit) return true;
  15.270 +			if(hit->dist < nearest.dist) {
  15.271 +				nearest = *hit;
  15.272 +			}
  15.273 +		}
  15.274 +	}
  15.275 +
  15.276 +	if(nearest.dist < FLT_MAX) {
  15.277 +		*hit = nearest;
  15.278 +		hit->local_ray = local_ray;
  15.279 +		hit->world_ray = ray;
  15.280 +		return true;
  15.281 +	}
  15.282 +	return false;
  15.283 +}
    16.1 --- a/liberebus/src/snode.h	Mon Apr 28 15:44:59 2014 +0300
    16.2 +++ b/liberebus/src/snode.h	Tue Apr 29 07:38:40 2014 +0300
    16.3 @@ -20,12 +20,21 @@
    16.4  	Matrix4x4 inv_xform;
    16.5  
    16.6  public:
    16.7 +	SceneNode();
    16.8 +	explicit SceneNode(Object *obj);
    16.9 +
   16.10  	void add_child(SceneNode *node);
   16.11  	bool remove_child(SceneNode *node);
   16.12  
   16.13  	int get_num_children() const;
   16.14  	SceneNode *get_child(int idx) const;
   16.15  
   16.16 +	SceneNode *get_parent() const;
   16.17 +
   16.18 +	void add_object(Object *obj);
   16.19 +	int get_num_objects() const;
   16.20 +	Object *get_object(int idx) const;
   16.21 +
   16.22  	void set_position(const Vector3 &pos);
   16.23  	void set_rotation(const Quaternion &rot);
   16.24  	void set_scaling(const Vector3 &scale);
    17.1 --- a/src/main.cc	Mon Apr 28 15:44:59 2014 +0300
    17.2 +++ b/src/main.cc	Tue Apr 29 07:38:40 2014 +0300
    17.3 @@ -2,11 +2,13 @@
    17.4  #include <stdlib.h>
    17.5  #include <assert.h>
    17.6  #include "opengl.h"
    17.7 +#include "erebus.h"
    17.8  
    17.9  static bool init();
   17.10  static void cleanup();
   17.11  static void resize_rtarget(int xsz, int ysz);
   17.12  static void update_rect(int x, int y, int xsz, int ysz, float *pixels);
   17.13 +static void idle();
   17.14  static void display();
   17.15  static void reshape(int x, int y);
   17.16  static void keyb(unsigned char key, int x, int y);
   17.17 @@ -16,6 +18,10 @@
   17.18  static int width, height, rtex_width, rtex_height;
   17.19  static unsigned int rtex;
   17.20  
   17.21 +static erebus *erb;
   17.22 +static bool render_pending;
   17.23 +
   17.24 +
   17.25  int main(int argc, char **argv)
   17.26  {
   17.27  	glutInitWindowSize(1024, 600);
   17.28 @@ -38,11 +44,27 @@
   17.29  
   17.30  static bool init()
   17.31  {
   17.32 +	if(!(erb = erb_init())) {
   17.33 +		return false;
   17.34 +	}
   17.35 +	erb_setopti(erb, ERB_OPT_WIDTH, width);
   17.36 +	erb_setopti(erb, ERB_OPT_HEIGHT, height);
   17.37 +
   17.38 +	if(erb_load_scene(erb, "scene") == -1) {
   17.39 +		return false;
   17.40 +	}
   17.41 +
   17.42 +	printf("begin rendering\n");
   17.43 +	render_pending = true;
   17.44 +	glutIdleFunc(idle);
   17.45 +	erb_begin_frame(erb, 0);
   17.46 +
   17.47  	return true;
   17.48  }
   17.49  
   17.50  static void cleanup()
   17.51  {
   17.52 +	erb_destroy(erb);
   17.53  }
   17.54  
   17.55  static void resize_rtarget(int xsz, int ysz)
   17.56 @@ -92,8 +114,21 @@
   17.57  	glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels);
   17.58  }
   17.59  
   17.60 +static void idle()
   17.61 +{
   17.62 +	glutPostRedisplay();
   17.63 +}
   17.64 +
   17.65  static void display()
   17.66  {
   17.67 +	if(render_pending) {
   17.68 +		if(erb_render(erb, 128) == 0) {
   17.69 +			render_pending = false;
   17.70 +			glutIdleFunc(0);
   17.71 +		}
   17.72 +		update_rect(0, 0, width, height, erb_get_framebuffer(erb));
   17.73 +	}
   17.74 +
   17.75  	glBindTexture(GL_TEXTURE_2D, rtex);
   17.76  	glEnable(GL_TEXTURE_2D);
   17.77  
   17.78 @@ -117,6 +152,9 @@
   17.79  {
   17.80  	glViewport(0, 0, x, y);
   17.81  	resize_rtarget(x, y);
   17.82 +
   17.83 +	erb_setopti(erb, ERB_OPT_WIDTH, width);
   17.84 +	erb_setopti(erb, ERB_OPT_HEIGHT, height);
   17.85  }
   17.86  
   17.87  static void keyb(unsigned char key, int x, int y)
   17.88 @@ -124,6 +162,13 @@
   17.89  	switch(key) {
   17.90  	case 27:
   17.91  		exit(0);
   17.92 +
   17.93 +	case ' ':
   17.94 +		printf("begin rendering\n");
   17.95 +		render_pending = true;
   17.96 +		glutIdleFunc(idle);
   17.97 +		erb_begin_frame(erb, 0);
   17.98 +		break;
   17.99  	}
  17.100  }
  17.101