# HG changeset patch # User John Tsiombikas # Date 1398655870 -10800 # Node ID 474a0244f57d9654c3f04d4730d575798286e84a # Parent 59a72293f9bd688c0f4f3b490f0be96a4e2c1aca fixed specialization mistake fixed line endings added makefiles diff -r 59a72293f9bd -r 474a0244f57d .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Mon Apr 28 06:31:10 2014 +0300 @@ -0,0 +1,9 @@ +\.o$ +\.d$ +\.swp$ +\.a$ +\.so\. +\.dylib +\.suo$ +Debug/ +Release/ diff -r 59a72293f9bd -r 474a0244f57d liberebus/Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liberebus/Makefile Mon Apr 28 06:31:10 2014 +0300 @@ -0,0 +1,41 @@ +src = $(wildcard src/*.cc) +obj = $(src:.cc=.o) +dep = $(obj:.o=.d) + +name = erebus +lib_a = lib$(name).a + +api_major = 0 +api_minor = 1 + +CXXFLAGS = -std=c++11 -pedantic -Wall -g $(pic) +LDFLAGS = -lvmath -limago -lm + +ifeq ($(shell uname -s), Darwin) + shared = -dynamiclib + lib_so = lib$(name).dylib +else + shared = -shared -Wl,-soname=$(soname) + devlink = lib$(name).so + soname = lib$(name).so.$(api_major) + lib_so = lib$(name).so.$(api_major).$(api_minor) + pic = -fPIC +endif + +.PHONY: all +all: $(lib_so) $(lib_a) + +$(lib_so): $(obj) + $(CXX) -o $@ $(shared) $(obj) $(LDFLAGS) + +$(lib_a): $(obj) + $(AR) rcs $@ $(obj) + +-include $(dep) + +%.d: %.cc + @$(CPP) $(CXXFLAGS) $< -MM -MT $(@:.d=.o) >$@ + +.PHONY: clean +clean: + rm -f $(obj) $(lib_so) $(lib_a) diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/brdf.cc --- a/liberebus/src/brdf.cc Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/brdf.cc Mon Apr 28 06:31:10 2014 +0300 @@ -1,130 +1,130 @@ -#include "brdf.h" -#include "erebus_impl.h" - -ReflAttrib::ReflAttrib() - : value(1), color(1, 1, 1), map(0) -{ -} - -ReflAttrib::ReflAttrib(const Color &col, Texture *tex) -{ - set_color(col); - map = tex; -} - -void ReflAttrib::set_value(float val) -{ - value = val; - color = Color{val, val, val}; -} - -void ReflAttrib::set_color(const Color &col) -{ - color = col; - value = color_luminance(col); -} - -void ReflAttrib::set_map(Texture *tex) -{ - map = tex; -} - -Texture *ReflAttrib::get_map() const -{ - return map; -} - -float ReflAttrib::get_value() const -{ - return value; -} - -float ReflAttrib::get_value(float u, float v) const -{ - return map ? value * color_luminance(map->lookup(u, v)) : value; -} - -const Color &ReflAttrib::get_color() const -{ - return color; -} - -Color ReflAttrib::get_color(float u, float v) const -{ - return map ? color * map->lookup(u, v) : color; -} - -// ---- class Reflectance ---- -ReflAttrib Reflectance::def_attrib; - -Reflectance::Reflectance() -{ - set_default_attribs(); -} - -void Reflectance::set_attrib(const char *name, const Color &color, Texture *tex) -{ - attrib[name] = ReflAttrib{color, tex}; -} - -ReflAttrib &Reflectance::get_attrib(const char *name) -{ - auto it = attrib.find(name); - if(it == attrib.end()) { - return def_attrib; - } - return it->second; -} - -const ReflAttrib &Reflectance::get_attrib(const char *name) const -{ - auto it = attrib.find(name); - if(it == attrib.end()) { - return def_attrib; - } - return it->second; -} - -float Reflectance::get_attrib_value(const char *name) const -{ - return get_attrib(name).get_value(); -} - -float Reflectance::get_attrib_value(const char *name, float u, float v) const -{ - return get_attrib(name).get_value(u, v); -} - -Color Reflectance::get_attrib_color(const char *name) const -{ - return get_attrib(name).get_color(); -} - -Color Reflectance::get_attrib_color(const char *name, float u, float v) const -{ - return get_attrib(name).get_color(u, v); -} - -float Reflectance::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const -{ - *indir = sample_dir(norm, outdir); - return eval(norm, outdir, *indir); -} - -// --- class LambertRefl --- - -void LambertRefl::set_default_attribs() -{ - set_attrib("color", Color(1, 1, 1)); -} - -Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const -{ - Vector3 dir = Vector3{randf(-1, 1), randf(-1, 1), randf(-1, 1)}.normalized(); - return dot_product(dir, norm) < 0.0 ? -dir : dir; -} - -float LambertRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const -{ - return dot_product(norm, outdir); -} \ No newline at end of file +#include "brdf.h" +#include "erebus_impl.h" + +ReflAttrib::ReflAttrib() + : value(1), color(1, 1, 1), map(0) +{ +} + +ReflAttrib::ReflAttrib(const Color &col, Texture *tex) +{ + set_color(col); + map = tex; +} + +void ReflAttrib::set_value(float val) +{ + value = val; + color = Color{val, val, val}; +} + +void ReflAttrib::set_color(const Color &col) +{ + color = col; + value = color_luminance(col); +} + +void ReflAttrib::set_map(Texture *tex) +{ + map = tex; +} + +Texture *ReflAttrib::get_map() const +{ + return map; +} + +float ReflAttrib::get_value() const +{ + return value; +} + +float ReflAttrib::get_value(float u, float v) const +{ + return map ? value * color_luminance(map->lookup(u, v)) : value; +} + +const Color &ReflAttrib::get_color() const +{ + return color; +} + +Color ReflAttrib::get_color(float u, float v) const +{ + return map ? color * map->lookup(u, v) : color; +} + +// ---- class Reflectance ---- +ReflAttrib Reflectance::def_attrib; + +Reflectance::Reflectance() +{ + set_default_attribs(); +} + +void Reflectance::set_attrib(const char *name, const Color &color, Texture *tex) +{ + attrib[name] = ReflAttrib{color, tex}; +} + +ReflAttrib &Reflectance::get_attrib(const char *name) +{ + auto it = attrib.find(name); + if(it == attrib.end()) { + return def_attrib; + } + return it->second; +} + +const ReflAttrib &Reflectance::get_attrib(const char *name) const +{ + auto it = attrib.find(name); + if(it == attrib.end()) { + return def_attrib; + } + return it->second; +} + +float Reflectance::get_attrib_value(const char *name) const +{ + return get_attrib(name).get_value(); +} + +float Reflectance::get_attrib_value(const char *name, float u, float v) const +{ + return get_attrib(name).get_value(u, v); +} + +Color Reflectance::get_attrib_color(const char *name) const +{ + return get_attrib(name).get_color(); +} + +Color Reflectance::get_attrib_color(const char *name, float u, float v) const +{ + return get_attrib(name).get_color(u, v); +} + +float Reflectance::sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const +{ + *indir = sample_dir(norm, outdir); + return eval(norm, outdir, *indir); +} + +// --- class LambertRefl --- + +void LambertRefl::set_default_attribs() +{ + set_attrib("color", Color(1, 1, 1)); +} + +Vector3 LambertRefl::sample_dir(const Vector3 &norm, const Vector3 &outdir) const +{ + Vector3 dir = Vector3{randf(-1, 1), randf(-1, 1), randf(-1, 1)}.normalized(); + return dot_product(dir, norm) < 0.0 ? -dir : dir; +} + +float LambertRefl::eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const +{ + return dot_product(norm, outdir); +} diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/brdf.h --- a/liberebus/src/brdf.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/brdf.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,67 +1,67 @@ -#ifndef BRDF_H_ -#define BRDF_H_ - -#include -#include -#include "color.h" -#include "texture.h" - -class ReflAttrib { -private: - float value; - Color color; - Texture *map; - -public: - - ReflAttrib(); - explicit ReflAttrib(const Color &color, Texture *tex = 0); - - void set_value(float val); - void set_color(const Color &col); - - void set_map(Texture *tex); - Texture *get_map() const; - - float get_value() const; - float get_value(float u, float v) const; - const Color &get_color() const; - Color get_color(float u, float v) const; -}; - - -class Reflectance { -private: - static ReflAttrib def_attrib; - std::map attrib; - - virtual void set_default_attribs(); - -public: - Reflectance(); - virtual ~Reflectance() = default; - - virtual void set_attrib(const char *name, const Color &color, Texture *tex = 0); - virtual ReflAttrib &get_attrib(const char *name); - virtual const ReflAttrib &get_attrib(const char *name) const; - - virtual float get_attrib_value(const char *name) const; - virtual float get_attrib_value(const char *name, float u, float v) const; - virtual Color get_attrib_color(const char *name) const; - virtual Color get_attrib_color(const char *name, float u, float v) const; - - virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0; - virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const; - virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0; -}; - -class LambertRefl : public Reflectance { -private: - void set_default_attribs() override; - -public: - Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; - float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; -}; - -#endif // BRDF_H_ \ No newline at end of file +#ifndef BRDF_H_ +#define BRDF_H_ + +#include +#include +#include "color.h" +#include "texture.h" + +class ReflAttrib { +private: + float value; + Color color; + Texture *map; + +public: + + ReflAttrib(); + explicit ReflAttrib(const Color &color, Texture *tex = 0); + + void set_value(float val); + void set_color(const Color &col); + + void set_map(Texture *tex); + Texture *get_map() const; + + float get_value() const; + float get_value(float u, float v) const; + const Color &get_color() const; + Color get_color(float u, float v) const; +}; + + +class Reflectance { +private: + static ReflAttrib def_attrib; + std::map attrib; + + virtual void set_default_attribs(); + +public: + Reflectance(); + virtual ~Reflectance() = default; + + virtual void set_attrib(const char *name, const Color &color, Texture *tex = 0); + virtual ReflAttrib &get_attrib(const char *name); + virtual const ReflAttrib &get_attrib(const char *name) const; + + virtual float get_attrib_value(const char *name) const; + virtual float get_attrib_value(const char *name, float u, float v) const; + virtual Color get_attrib_color(const char *name) const; + virtual Color get_attrib_color(const char *name, float u, float v) const; + + virtual Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const = 0; + virtual float sample(const Vector3 &norm, const Vector3 &outdir, Vector3 *indir) const; + virtual float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const = 0; +}; + +class LambertRefl : public Reflectance { +private: + void set_default_attribs() override; + +public: + Vector3 sample_dir(const Vector3 &norm, const Vector3 &outdir) const override; + float eval(const Vector3 &norm, const Vector3 &outdir, const Vector3 &indir) const override; +}; + +#endif // BRDF_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/bvol.cc --- a/liberebus/src/bvol.cc Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/bvol.cc Mon Apr 28 06:31:10 2014 +0300 @@ -1,38 +1,38 @@ -#include "bvol.h" - -bool AABox::intersect(const Ray &ray) const -{ - Vector3 param[2] = {vmin, vmax}; - Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z); - int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0}; - - float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x; - float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x; - float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y; - float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y; - - if(tmin > tymax || tymin > tmax) { - return false; - } - if(tymin > tmin) { - tmin = tymin; - } - if(tymax < tmax) { - tmax = tymax; - } - - float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z; - float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z; - - if(tmin > tzmax || tzmin > tmax) { - return false; - } - if(tzmin > tmin) { - tmin = tzmin; - } - if(tzmax < tmax) { - tmax = tzmax; - } - - return true; -} \ No newline at end of file +#include "bvol.h" + +bool AABox::intersect(const Ray &ray) const +{ + Vector3 param[2] = {vmin, vmax}; + Vector3 inv_dir(1.0 / ray.dir.x, 1.0 / ray.dir.y, 1.0 / ray.dir.z); + int sign[3] = {inv_dir.x < 0, inv_dir.y < 0, inv_dir.z < 0}; + + float tmin = (param[sign[0]].x - ray.origin.x) * inv_dir.x; + float tmax = (param[1 - sign[0]].x - ray.origin.x) * inv_dir.x; + float tymin = (param[sign[1]].y - ray.origin.y) * inv_dir.y; + float tymax = (param[1 - sign[1]].y - ray.origin.y) * inv_dir.y; + + if(tmin > tymax || tymin > tmax) { + return false; + } + if(tymin > tmin) { + tmin = tymin; + } + if(tymax < tmax) { + tmax = tymax; + } + + float tzmin = (param[sign[2]].z - ray.origin.z) * inv_dir.z; + float tzmax = (param[1 - sign[2]].z - ray.origin.z) * inv_dir.z; + + if(tmin > tzmax || tzmin > tmax) { + return false; + } + if(tzmin > tmin) { + tmin = tzmin; + } + if(tzmax < tmax) { + tmax = tzmax; + } + + return true; +} diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/bvol.h --- a/liberebus/src/bvol.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/bvol.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,16 +1,16 @@ -#ifndef BVOL_H_ -#define BVOL_H_ - -#include "vmath/ray.h" - -class AABox { -public: - Vector3 vmin, vmax; - - AABox() : vmin(-0.5, -0.5, -0.5), vmax(0.5, 0.5, 0.5) {} - AABox(const Vector3 &v0, const Vector3 &v1) : vmin(v0), vmax(v1) {} - - bool intersect(const Ray &ray) const; -}; - -#endif // BVOL_H_ \ No newline at end of file +#ifndef BVOL_H_ +#define BVOL_H_ + +#include "vmath/ray.h" + +class AABox { +public: + Vector3 vmin, vmax; + + AABox() : vmin(-0.5, -0.5, -0.5), vmax(0.5, 0.5, 0.5) {} + AABox(const Vector3 &v0, const Vector3 &v1) : vmin(v0), vmax(v1) {} + + bool intersect(const Ray &ray) const; +}; + +#endif // BVOL_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/color.h --- a/liberebus/src/color.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/color.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,10 +1,10 @@ -#ifndef COLOR_H_ -#define COLOR_H_ - -#include "vmath/vector.h" - -typedef Vector3 Color; - -inline float color_luminance(const Color &c) { return c[0] * 0.2126 + c[1] * 0.7152 + c[2] * 0.0722; } - -#endif // COLOR_H_ \ No newline at end of file +#ifndef COLOR_H_ +#define COLOR_H_ + +#include "vmath/vector.h" + +typedef Vector3 Color; + +inline float color_luminance(const Color &c) { return c[0] * 0.2126 + c[1] * 0.7152 + c[2] * 0.0722; } + +#endif // COLOR_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/erebus.cc --- a/liberebus/src/erebus.cc Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/erebus.cc Mon Apr 28 06:31:10 2014 +0300 @@ -1,159 +1,159 @@ -#include -#include -#include -#include -#include "erebus.h" -#include "vmath/vector.h" -#include "image.h" - -using namespace std::chrono; - -struct Rect { - int x, y, width, height; - - bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; } - bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; } -}; - -#define INVALID_RECT Rect{0, 0, 0, 0} - -struct erebus { - Image fbimg; - Vector4 options[ERB_NUM_OPTIONS]; - - // render state - long cur_time; - int cur_pixel_x, cur_pixel_y; - Rect cur_rect; -}; - -static void render_pixel(struct erebus *ctx, int x, int y); - -static std::mt19937 rnd_gen; - -extern "C" { - -struct erebus *erb_init(void) -{ - struct erebus *ctx; - try { - ctx = new struct erebus; - } - catch(...) { - return 0; - } - - ctx->cur_time = 0; - ctx->cur_rect = INVALID_RECT; - return ctx; -} - -void erb_destroy(struct erebus *ctx) -{ - delete ctx; -} - -void erb_setopti(struct erebus *ctx, enum erb_option opt, int val) -{ - ctx->options[opt].x; -} -void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val) -{ - ctx->options[opt].x = val; -} -void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec) -{ - for(int i=0; i<4; i++) { - ctx->options[opt][i] = vec[i]; - } -} - -int erb_getopti(struct erebus *ctx, enum erb_option opt) -{ - return ctx->options[opt].x; -} -float erb_getoptf(struct erebus *ctx, enum erb_option opt) -{ - return ctx->options[opt].x; -} -float *erb_getoptfv(struct erebus *ctx, enum erb_option opt) -{ - return &ctx->options[opt].x; -} - -float *erb_get_framebuffer(struct erebus *ctx) -{ - return ctx->fbimg.get_pixels(); -} - -void erb_begin_frame(struct erebus *ctx, long ms) -{ - ctx->cur_time = ms; -} - -int erb_render(struct erebus *ctx, long timeout) -{ - return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout); -} - -int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout) -{ - if(!width || !height) return -1; - - Rect rect{x, y, width, height}; - if(ctx->cur_rect != rect) { - ctx->cur_rect = rect; - ctx->cur_pixel_x = x; - ctx->cur_pixel_y = y; - } - - if(timeout > 0) { - auto start_time = monotonic_clock::now(); - while(duration_cast(monotonic_clock::now() - start_time).count() < timeout) { - render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y); - - if(++ctx->cur_pixel_x >= ctx->cur_rect.width) { - if(++ctx->cur_pixel_y >= ctx->cur_rect.height) { - ctx->cur_rect = INVALID_RECT; - return 0; - } - } - } - return 1; - } - - for(int i=0; iscene; - //ctx->scene = new Scene; - - return false; // TODO -} - -} // extern "C" - -float randf(float low, float high) -{ - std::uniform_real_distribution unirnd(low, high); - return unirnd(rnd_gen); -} - -static void render_pixel(struct erebus *ctx, int x, int y) -{ - float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4; - pix[0] = pix[1] = pix[2] = 0.0f; - pix[3] = 1.0f; -} \ No newline at end of file +#include +#include +#include +#include +#include "erebus.h" +#include "vmath/vector.h" +#include "image.h" + +using namespace std::chrono; + +struct Rect { + int x, y, width, height; + + bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; } + bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; } +}; + +#define INVALID_RECT Rect{0, 0, 0, 0} + +struct erebus { + Image fbimg; + Vector4 options[ERB_NUM_OPTIONS]; + + // render state + long cur_time; + int cur_pixel_x, cur_pixel_y; + Rect cur_rect; +}; + +static void render_pixel(struct erebus *ctx, int x, int y); + +static std::mt19937 rnd_gen; + +extern "C" { + +struct erebus *erb_init(void) +{ + struct erebus *ctx; + try { + ctx = new struct erebus; + } + catch(...) { + return 0; + } + + ctx->cur_time = 0; + ctx->cur_rect = INVALID_RECT; + return ctx; +} + +void erb_destroy(struct erebus *ctx) +{ + delete ctx; +} + +void erb_setopti(struct erebus *ctx, enum erb_option opt, int val) +{ + ctx->options[opt].x = val; +} +void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val) +{ + ctx->options[opt].x = val; +} +void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec) +{ + for(int i=0; i<4; i++) { + ctx->options[opt][i] = vec[i]; + } +} + +int erb_getopti(struct erebus *ctx, enum erb_option opt) +{ + return ctx->options[opt].x; +} +float erb_getoptf(struct erebus *ctx, enum erb_option opt) +{ + return ctx->options[opt].x; +} +float *erb_getoptfv(struct erebus *ctx, enum erb_option opt) +{ + return &ctx->options[opt].x; +} + +float *erb_get_framebuffer(struct erebus *ctx) +{ + return ctx->fbimg.get_pixels(); +} + +void erb_begin_frame(struct erebus *ctx, long ms) +{ + ctx->cur_time = ms; +} + +int erb_render(struct erebus *ctx, long timeout) +{ + return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout); +} + +int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout) +{ + if(!width || !height) return -1; + + Rect rect{x, y, width, height}; + if(ctx->cur_rect != rect) { + ctx->cur_rect = rect; + ctx->cur_pixel_x = x; + ctx->cur_pixel_y = y; + } + + if(timeout > 0) { + auto start_time = steady_clock::now(); + while(duration_cast(steady_clock::now() - start_time).count() < timeout) { + render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y); + + if(++ctx->cur_pixel_x >= ctx->cur_rect.width) { + if(++ctx->cur_pixel_y >= ctx->cur_rect.height) { + ctx->cur_rect = INVALID_RECT; + return 0; + } + } + } + return 1; + } + + for(int i=0; iscene; + //ctx->scene = new Scene; + + return false; // TODO +} + +} // extern "C" + +float randf(float low, float high) +{ + std::uniform_real_distribution unirnd(low, high); + return unirnd(rnd_gen); +} + +static void render_pixel(struct erebus *ctx, int x, int y) +{ + float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4; + pix[0] = pix[1] = pix[2] = 0.0f; + pix[3] = 1.0f; +} diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/erebus.h --- a/liberebus/src/erebus.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/erebus.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,46 +1,46 @@ -#ifndef LIBEREBUS_H_ -#define LIBEREBUS_H_ - -struct erebus; - -enum erb_option { - ERB_OPT_WIDTH, - ERB_OPT_HEIGHT, - ERB_OPT_MAX_ITER, - ERB_OPT_NUM_THREADS, - ERB_OPT_GAMMA, - - ERB_NUM_OPTIONS -}; - -#ifdef __cplusplus -extern "C" { -#endif - -struct erebus *erb_init(void); -void erb_destroy(struct erebus *ctx); - -void erb_setopti(struct erebus *ctx, enum erb_option opt, int val); -void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val); -void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec); - -int erb_getopti(struct erebus *ctx, enum erb_option opt); -float erb_getoptf(struct erebus *ctx, enum erb_option opt); -float *erb_getoptfv(struct erebus *ctx, enum erb_option opt); - -float *erb_get_framebuffer(struct erebus *ctx); - -void erb_begin_frame(struct erebus *ctx, long ms); -int erb_render(struct erebus *ctx, long timeout); -int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout); - -int erb_get_progress(struct erebus *ctx); - -int erb_load_scene(struct erebus *ctx, const char *fname); - -#ifdef __cplusplus -} -#endif - - -#endif /* LIBEREBUS_H_ */ \ No newline at end of file +#ifndef LIBEREBUS_H_ +#define LIBEREBUS_H_ + +struct erebus; + +enum erb_option { + ERB_OPT_WIDTH, + ERB_OPT_HEIGHT, + ERB_OPT_MAX_ITER, + ERB_OPT_NUM_THREADS, + ERB_OPT_GAMMA, + + ERB_NUM_OPTIONS +}; + +#ifdef __cplusplus +extern "C" { +#endif + +struct erebus *erb_init(void); +void erb_destroy(struct erebus *ctx); + +void erb_setopti(struct erebus *ctx, enum erb_option opt, int val); +void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val); +void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec); + +int erb_getopti(struct erebus *ctx, enum erb_option opt); +float erb_getoptf(struct erebus *ctx, enum erb_option opt); +float *erb_getoptfv(struct erebus *ctx, enum erb_option opt); + +float *erb_get_framebuffer(struct erebus *ctx); + +void erb_begin_frame(struct erebus *ctx, long ms); +int erb_render(struct erebus *ctx, long timeout); +int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout); + +int erb_get_progress(struct erebus *ctx); + +int erb_load_scene(struct erebus *ctx, const char *fname); + +#ifdef __cplusplus +} +#endif + + +#endif /* LIBEREBUS_H_ */ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/erebus_impl.h --- a/liberebus/src/erebus_impl.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/erebus_impl.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,6 +1,6 @@ -#ifndef EREBUS_IMPL_H_ -#define EREBUS_IMPL_H_ - -float randf(float low = 0.0f, float high = 1.0f); - -#endif // EREBUS_IMPL_H_ \ No newline at end of file +#ifndef EREBUS_IMPL_H_ +#define EREBUS_IMPL_H_ + +float randf(float low = 0.0f, float high = 1.0f); + +#endif // EREBUS_IMPL_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/geomobj.h --- a/liberebus/src/geomobj.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/geomobj.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,50 +1,50 @@ -#ifndef GEOMOBJ_H_ -#define GEOMOBJ_H_ - -#include "object.h" -#include "brdf.h" - -class GeomObject : public Object { -public: - Reflectance *brdf; - - ObjType get_type() const override; - - bool intersect(const Ray &ray, RayHit *hit = 0) const override; -}; - -class Sphere : public GeomObject { -public: - bool intersect(const Ray &ray, RayHit *hit = 0) const override; -}; - -class Box : public GeomObject { -public: - bool intersect(const Ray &ray, RayHit *hit = 0) const override; -}; - -class Triangle : public GeomObject { -public: - Vector3 v[3]; - Vector3 normal; - Vector3 vnorm[3]; - Vector2 vtex[3]; - - bool intersect(const Ray &ray, RayHit *hit = 0) const override; -}; - -class Mesh : public GeomObject { -private: - std::vector faces; - -public: - void begin(); - void vertex(float x, float y, float z); - void normal(float x, float y, float z); - void texcoord(float u, float v); - void end(); - - bool intersect(const Ray &ray, RayHit *hit = 0) const override; -}; - -#endif // GEOMOBJ_H_ \ No newline at end of file +#ifndef GEOMOBJ_H_ +#define GEOMOBJ_H_ + +#include "object.h" +#include "brdf.h" + +class GeomObject : public Object { +public: + Reflectance *brdf; + + ObjType get_type() const override; + + bool intersect(const Ray &ray, RayHit *hit = 0) const override; +}; + +class Sphere : public GeomObject { +public: + bool intersect(const Ray &ray, RayHit *hit = 0) const override; +}; + +class Box : public GeomObject { +public: + bool intersect(const Ray &ray, RayHit *hit = 0) const override; +}; + +class Triangle : public GeomObject { +public: + Vector3 v[3]; + Vector3 normal; + Vector3 vnorm[3]; + Vector2 vtex[3]; + + bool intersect(const Ray &ray, RayHit *hit = 0) const override; +}; + +class Mesh : public GeomObject { +private: + std::vector faces; + +public: + void begin(); + void vertex(float x, float y, float z); + void normal(float x, float y, float z); + void texcoord(float u, float v); + void end(); + + bool intersect(const Ray &ray, RayHit *hit = 0) const override; +}; + +#endif // GEOMOBJ_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/image.inl --- a/liberebus/src/image.inl Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/image.inl Mon Apr 28 06:31:10 2014 +0300 @@ -118,7 +118,14 @@ return pixels; } -bool Image::load(const char *fname) +template +inline bool load_image(Image *img, const char *fname) +{ + return false; +} + +template <> +inline bool load_image(Image *img, const char *fname) { int xsz, ysz; unsigned char *pix = (unsigned char*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBA32); @@ -126,11 +133,13 @@ return false; } - create(xsz, ysz, pix); + img->create(xsz, ysz, pix); + img_free_pixels(pix); return true; } -bool Image::load(const char *fname) +template <> +inline bool load_image(Image *img, const char *fname) { int xsz, ysz; float *pix = (float*)img_load_pixels(fname, &xsz, &ysz, IMG_FMT_RGBAF); @@ -138,6 +147,13 @@ return false; } - create(xsz, ysz, pix); + img->create(xsz, ysz, pix); + img_free_pixels(pix); return true; -} \ No newline at end of file +} + +template +bool Image::load(const char *fname) +{ + return load_image(this, fname); +} diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/object.cc --- a/liberebus/src/object.cc Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/object.cc Mon Apr 28 06:31:10 2014 +0300 @@ -1,60 +1,60 @@ -#include "object.h" - -Object::Object() -{ - name = ""; - inv_xform_valid = false; -} - -ObjType Object::get_type() const -{ - return ObjType::null; -} - -void Object::set_name(const char *name) -{ - this->name = name; -} - -const char *Object::get_name() const -{ - return name.c_str(); -} - -void Object::set_xform(const Matrix4x4 &mat) -{ - xform = mat; - inv_xform_valid = false; -} - -void Object::set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat) -{ - xform = mat; - inv_xform = inv_mat; - inv_xform_valid = true; -} - -Matrix4x4 &Object::get_xform() -{ - inv_xform_valid = false; - return xform; -} - -const Matrix4x4 &Object::get_xform() const -{ - return xform; -} - -const Matrix4x4 &Object::get_inv_xform() const -{ - if(!inv_xform_valid) { - inv_xform = xform.inverse(); - inv_xform_valid = true; - } - return inv_xform; -} - -bool Object::intersect(const Ray &ray, RayHit *hit) const -{ - return false; -} \ No newline at end of file +#include "object.h" + +Object::Object() +{ + name = ""; + inv_xform_valid = false; +} + +ObjType Object::get_type() const +{ + return ObjType::null; +} + +void Object::set_name(const char *name) +{ + this->name = name; +} + +const char *Object::get_name() const +{ + return name.c_str(); +} + +void Object::set_xform(const Matrix4x4 &mat) +{ + xform = mat; + inv_xform_valid = false; +} + +void Object::set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat) +{ + xform = mat; + inv_xform = inv_mat; + inv_xform_valid = true; +} + +Matrix4x4 &Object::get_xform() +{ + inv_xform_valid = false; + return xform; +} + +const Matrix4x4 &Object::get_xform() const +{ + return xform; +} + +const Matrix4x4 &Object::get_inv_xform() const +{ + if(!inv_xform_valid) { + inv_xform = xform.inverse(); + inv_xform_valid = true; + } + return inv_xform; +} + +bool Object::intersect(const Ray &ray, RayHit *hit) const +{ + return false; +} diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/object.h --- a/liberebus/src/object.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/object.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,44 +1,44 @@ -#ifndef OBJECT_H_ -#define OBJECT_H_ - -#include -#include "vmath/ray.h" - -class Object; - -struct RayHit { - float dist; - const Ray world_ray, local_ray; - - const Object *obj, *subobj; -}; - -enum class ObjType { null, geom, camera }; - -class Object { -private: - std::string name; - Matrix4x4 xform; - mutable Matrix4x4 inv_xform; - mutable bool inv_xform_valid; - -public: - Object(); - virtual ~Object() = default; - - virtual ObjType get_type() const; - - virtual void set_name(const char *name); - virtual const char *get_name() const; - - virtual void set_xform(const Matrix4x4 &mat); - virtual void set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat); - - virtual Matrix4x4 &get_xform(); // invalidates inv_xform - virtual const Matrix4x4 &get_xform() const; - virtual const Matrix4x4 &get_inv_xform() const; - - virtual bool intersect(const Ray &ray, RayHit *hit = 0) const; -}; - -#endif // OBJECT_H_ \ No newline at end of file +#ifndef OBJECT_H_ +#define OBJECT_H_ + +#include +#include "vmath/ray.h" + +class Object; + +struct RayHit { + float dist; + const Ray world_ray, local_ray; + + const Object *obj, *subobj; +}; + +enum class ObjType { null, geom, camera }; + +class Object { +private: + std::string name; + Matrix4x4 xform; + mutable Matrix4x4 inv_xform; + mutable bool inv_xform_valid; + +public: + Object(); + virtual ~Object() = default; + + virtual ObjType get_type() const; + + virtual void set_name(const char *name); + virtual const char *get_name() const; + + virtual void set_xform(const Matrix4x4 &mat); + virtual void set_xform(const Matrix4x4 &mat, const Matrix4x4 &inv_mat); + + virtual Matrix4x4 &get_xform(); // invalidates inv_xform + virtual const Matrix4x4 &get_xform() const; + virtual const Matrix4x4 &get_inv_xform() const; + + virtual bool intersect(const Ray &ray, RayHit *hit = 0) const; +}; + +#endif // OBJECT_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/scene.h --- a/liberebus/src/scene.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/scene.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,30 +1,30 @@ -#ifndef SCENE_H_ -#define SCENE_H_ - -#include -#include "snode.h" -#include "camera.h" - -class Scene { -private: - std::vector objects; - std::vector nodes; - - Camera *active_cam; - -public: - Scene(); - ~Scene(); - - void add_object(Object *obj); - int get_object_count() const; - Object *get_object(int idx) const; - - void add_node(SceneNode *node); - int get_node_count() const; - SceneNode *get_node(int idx) const; - - bool intersect(const Ray &ray, RayHit *hit) const; -}; - -#endif // SCENE_H_ \ No newline at end of file +#ifndef SCENE_H_ +#define SCENE_H_ + +#include +#include "snode.h" +#include "camera.h" + +class Scene { +private: + std::vector objects; + std::vector nodes; + + Camera *active_cam; + +public: + Scene(); + ~Scene(); + + void add_object(Object *obj); + int get_object_count() const; + Object *get_object(int idx) const; + + void add_node(SceneNode *node); + int get_node_count() const; + SceneNode *get_node(int idx) const; + + bool intersect(const Ray &ray, RayHit *hit) const; +}; + +#endif // SCENE_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/snode.h --- a/liberebus/src/snode.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/snode.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,46 +1,46 @@ -#ifndef SNODE_H_ -#define SNODE_H_ - -#include -#include "object.h" -#include "vmath/vmath.h" - -class SceneNode { -private: - Vector3 pos; - Quaternion rot; - Vector3 scale; - - std::vector obj; - - SceneNode *parent; - std::vector children; - - Matrix4x4 node_xform, xform; - -public: - void add_child(SceneNode *node); - bool remove_child(SceneNode *node); - - int get_num_children() const; - SceneNode *get_child(int idx) const; - - void set_position(const Vector3 &pos); - void set_rotation(const Quaternion &rot); - void set_scaling(const Vector3 &scale); - - const Vector3 &get_node_position() const; - const Quaternion &get_node_rotation() const; - const Vector3 &get_node_scaling() const; - - Vector3 get_position() const; - Quaternion get_rotation() const; - Vector3 get_scaling() const; - - void update_node(long msec = 0); - void update(long msec = 0); - - bool intersect(const Ray &ray, RayHit *hit) const; -}; - -#endif // SNODE_H_ \ No newline at end of file +#ifndef SNODE_H_ +#define SNODE_H_ + +#include +#include "object.h" +#include "vmath/vmath.h" + +class SceneNode { +private: + Vector3 pos; + Quaternion rot; + Vector3 scale; + + std::vector obj; + + SceneNode *parent; + std::vector children; + + Matrix4x4 node_xform, xform; + +public: + void add_child(SceneNode *node); + bool remove_child(SceneNode *node); + + int get_num_children() const; + SceneNode *get_child(int idx) const; + + void set_position(const Vector3 &pos); + void set_rotation(const Quaternion &rot); + void set_scaling(const Vector3 &scale); + + const Vector3 &get_node_position() const; + const Quaternion &get_node_rotation() const; + const Vector3 &get_node_scaling() const; + + Vector3 get_position() const; + Quaternion get_rotation() const; + Vector3 get_scaling() const; + + void update_node(long msec = 0); + void update(long msec = 0); + + bool intersect(const Ray &ray, RayHit *hit) const; +}; + +#endif // SNODE_H_ diff -r 59a72293f9bd -r 474a0244f57d liberebus/src/texture.h --- a/liberebus/src/texture.h Mon Apr 28 05:58:22 2014 +0300 +++ b/liberebus/src/texture.h Mon Apr 28 06:31:10 2014 +0300 @@ -1,30 +1,30 @@ -#ifndef TEXTURE_H_ -#define TEXTURE_H_ - -#include "image.h" -#include "color.h" - -class Texture { -public: - Image img; - - inline Color lookup(float u, float v) const; - - bool load(const char *fname) { return img.load(fname); } -}; - - -inline Color Texture::lookup(float u, float v) const -{ - int xsz = img.get_width(); - int ysz = img.get_height(); - - int x = (float)u / (float)xsz; - int y = (float)v / (float)ysz; - - float *pix = img.get_pixels() + ((y % ysz) * xsz + (x % xsz)) * 4; - return Color(pix[0], pix[1], pix[2]); -} - - -#endif // TEXTURE_H_ \ No newline at end of file +#ifndef TEXTURE_H_ +#define TEXTURE_H_ + +#include "image.h" +#include "color.h" + +class Texture { +public: + Image img; + + inline Color lookup(float u, float v) const; + + bool load(const char *fname) { return img.load(fname); } +}; + + +inline Color Texture::lookup(float u, float v) const +{ + int xsz = img.get_width(); + int ysz = img.get_height(); + + int x = (float)u / (float)xsz; + int y = (float)v / (float)ysz; + + float *pix = img.get_pixels() + ((y % ysz) * xsz + (x % xsz)) * 4; + return Color(pix[0], pix[1], pix[2]); +} + + +#endif // TEXTURE_H_ diff -r 59a72293f9bd -r 474a0244f57d src/main.cc --- a/src/main.cc Mon Apr 28 05:58:22 2014 +0300 +++ b/src/main.cc Mon Apr 28 06:31:10 2014 +0300 @@ -1,141 +1,141 @@ -#include -#include -#include -#include "opengl.h" - -static bool init(); -static void cleanup(); -static void resize_rtarget(int xsz, int ysz); -static void update_rect(int x, int y, int xsz, int ysz, float *pixels); -static void display(); -static void reshape(int x, int y); -static void keyb(unsigned char key, int x, int y); -static void mouse(int bn, int st, int x, int y); -static int next_pow2(int x); - -static int width, height, rtex_width, rtex_height; -static unsigned int rtex; - -int main(int argc, char **argv) -{ - glutInitWindowSize(1024, 600); - glutInit(&argc, argv); - glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); - glutCreateWindow("erebus OpenGL frontend"); - - glutDisplayFunc(display); - glutReshapeFunc(reshape); - glutKeyboardFunc(keyb); - glutMouseFunc(mouse); - - if(!init()) { - return 1; - } - atexit(cleanup); - - glutMainLoop(); -} - -static bool init() -{ - return true; -} - -static void cleanup() -{ -} - -static void resize_rtarget(int xsz, int ysz) -{ - static unsigned char *defpix; - - width = xsz; - height = ysz; - - if(xsz <= rtex_width && ysz <= rtex_height) { - return; - } - rtex_width = next_pow2(xsz); - rtex_height = next_pow2(ysz); - - printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); - - if(!rtex) { - glGenTextures(1, &rtex); - } - - delete [] defpix; - defpix = new unsigned char[rtex_width * rtex_height * 4]; - unsigned char *ptr = defpix; - for(int i=0; i> 4) & 1) == ((j >> 4) & 1); - - int val = chess ? 64 : 48; - - *ptr++ = val; - *ptr++ = val; - *ptr++ = val; - *ptr++ = 255; - } - } - - glBindTexture(GL_TEXTURE_2D, rtex); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); - glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix); -} - -static void update_rect(int x, int y, int xsz, int ysz, float *pixels) -{ - glBindTexture(GL_TEXTURE_2D, rtex); - glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels); -} - -static void display() -{ - glBindTexture(GL_TEXTURE_2D, rtex); - glEnable(GL_TEXTURE_2D); - - float maxu = (float)width / (float)rtex_width; - float maxv = (float)height / (float)rtex_height; - - glBegin(GL_QUADS); - glTexCoord2f(0, maxv); glVertex2f(-1, -1); - glTexCoord2f(maxu, maxv); glVertex2f(1, -1); - glTexCoord2f(maxu, 0); glVertex2f(1, 1); - glTexCoord2f(0, 0); glVertex2f(-1, 1); - glEnd(); - - glDisable(GL_TEXTURE_2D); - - glutSwapBuffers(); - assert(glGetError() == GL_NO_ERROR); -} - -static void reshape(int x, int y) -{ - glViewport(0, 0, x, y); - resize_rtarget(x, y); -} - -static void keyb(unsigned char key, int x, int y) -{ - switch(key) { - case 27: - exit(0); - } -} - -static void mouse(int bn, int st, int x, int y) -{ -} - -static int next_pow2(int x) -{ - int res = 2; - while(res < x) { - res <<= 1; - } - return res; -} \ No newline at end of file +#include +#include +#include +#include "opengl.h" + +static bool init(); +static void cleanup(); +static void resize_rtarget(int xsz, int ysz); +static void update_rect(int x, int y, int xsz, int ysz, float *pixels); +static void display(); +static void reshape(int x, int y); +static void keyb(unsigned char key, int x, int y); +static void mouse(int bn, int st, int x, int y); +static int next_pow2(int x); + +static int width, height, rtex_width, rtex_height; +static unsigned int rtex; + +int main(int argc, char **argv) +{ + glutInitWindowSize(1024, 600); + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_RGB | GLUT_DOUBLE); + glutCreateWindow("erebus OpenGL frontend"); + + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyb); + glutMouseFunc(mouse); + + if(!init()) { + return 1; + } + atexit(cleanup); + + glutMainLoop(); +} + +static bool init() +{ + return true; +} + +static void cleanup() +{ +} + +static void resize_rtarget(int xsz, int ysz) +{ + static unsigned char *defpix; + + width = xsz; + height = ysz; + + if(xsz <= rtex_width && ysz <= rtex_height) { + return; + } + rtex_width = next_pow2(xsz); + rtex_height = next_pow2(ysz); + + printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); + + if(!rtex) { + glGenTextures(1, &rtex); + } + + delete [] defpix; + defpix = new unsigned char[rtex_width * rtex_height * 4]; + unsigned char *ptr = defpix; + for(int i=0; i> 4) & 1) == ((j >> 4) & 1); + + int val = chess ? 64 : 48; + + *ptr++ = val; + *ptr++ = val; + *ptr++ = val; + *ptr++ = 255; + } + } + + glBindTexture(GL_TEXTURE_2D, rtex); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA32F_ARB, rtex_width, rtex_height, 0, GL_RGBA, GL_UNSIGNED_BYTE, defpix); +} + +static void update_rect(int x, int y, int xsz, int ysz, float *pixels) +{ + glBindTexture(GL_TEXTURE_2D, rtex); + glTexSubImage2D(GL_TEXTURE_2D, 0, x, y, xsz, ysz, GL_RGBA, GL_FLOAT, pixels); +} + +static void display() +{ + glBindTexture(GL_TEXTURE_2D, rtex); + glEnable(GL_TEXTURE_2D); + + float maxu = (float)width / (float)rtex_width; + float maxv = (float)height / (float)rtex_height; + + glBegin(GL_QUADS); + glTexCoord2f(0, maxv); glVertex2f(-1, -1); + glTexCoord2f(maxu, maxv); glVertex2f(1, -1); + glTexCoord2f(maxu, 0); glVertex2f(1, 1); + glTexCoord2f(0, 0); glVertex2f(-1, 1); + glEnd(); + + glDisable(GL_TEXTURE_2D); + + glutSwapBuffers(); + assert(glGetError() == GL_NO_ERROR); +} + +static void reshape(int x, int y) +{ + glViewport(0, 0, x, y); + resize_rtarget(x, y); +} + +static void keyb(unsigned char key, int x, int y) +{ + switch(key) { + case 27: + exit(0); + } +} + +static void mouse(int bn, int st, int x, int y) +{ +} + +static int next_pow2(int x) +{ + int res = 2; + while(res < x) { + res <<= 1; + } + return res; +}