erebus
changeset 8:e2d9bf168a41
semi-works ...
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Sat, 24 May 2014 06:12:57 +0300 |
parents | f067148b3494 |
children | d38e13d6063c |
files | liberebus/src/camera.cc liberebus/src/camera.h liberebus/src/erebus.cc liberebus/src/erebus.h liberebus/src/geomobj.cc liberebus/src/geomobj.h liberebus/src/material.cc liberebus/src/rt.cc liberebus/src/rt.h liberebus/src/scene.cc liberebus/src/scene.h liberebus/src/snode.cc src/main.cc |
diffstat | 13 files changed, 229 insertions(+), 78 deletions(-) [+] |
line diff
1.1 --- a/liberebus/src/camera.cc Sat May 24 02:27:08 2014 +0300 1.2 +++ b/liberebus/src/camera.cc Sat May 24 06:12:57 2014 +0300 1.3 @@ -2,32 +2,25 @@ 1.4 #include <math.h> 1.5 #include "camera.h" 1.6 1.7 +#define DEFAULT_FOV DEG_TO_RAD(50) 1.8 + 1.9 static void calc_sample_pos_rec(int sidx, float xsz, float ysz, float *pos); 1.10 1.11 Camera::Camera() 1.12 { 1.13 - vfov = M_PI / 4.0; 1.14 + vfov = DEFAULT_FOV; 1.15 cached_matrix_valid = false; 1.16 - 1.17 - rdir_cache_width = rdir_cache_height = 0; 1.18 - rdir_cache_fov = 0; 1.19 - rdir_cache = 0; 1.20 } 1.21 1.22 Camera::Camera(const Vector3 &p) 1.23 : pos(p) 1.24 { 1.25 - vfov = M_PI / 4.0; 1.26 + vfov = DEFAULT_FOV; 1.27 cached_matrix_valid = false; 1.28 - 1.29 - rdir_cache_width = rdir_cache_height = 0; 1.30 - rdir_cache_fov = 0; 1.31 - rdir_cache = 0; 1.32 } 1.33 1.34 Camera::~Camera() 1.35 { 1.36 - delete [] rdir_cache; 1.37 } 1.38 1.39 void Camera::set_fov(float vfov) 1.40 @@ -77,38 +70,14 @@ 1.41 1.42 Ray Camera::get_primary_ray(int x, int y, int xsz, int ysz, int sample) const 1.43 { 1.44 -#pragma omp single 1.45 - { 1.46 - if(!rdir_cache || rdir_cache_width != xsz || rdir_cache_height != ysz || 1.47 - fabs(rdir_cache_fov - vfov) > 1e-4) { 1.48 - printf("calculating primary ray direction cache (%dx%d)\n", xsz, ysz); 1.49 - 1.50 - delete [] rdir_cache; 1.51 - rdir_cache = new Vector3[xsz * ysz]; 1.52 - 1.53 -#pragma omp parallel for 1.54 - for(int i=0; i<ysz; i++) { 1.55 - Vector3 *rdir = rdir_cache + i * xsz; 1.56 - for(int j=0; j<xsz; j++) { 1.57 - Vector2 ppos = calc_sample_pos(j, i, xsz, ysz, 0); 1.58 - 1.59 - rdir->x = ppos.x; 1.60 - rdir->y = ppos.y; 1.61 - rdir->z = 1.0 / tan(vfov / 2.0); 1.62 - rdir->normalize(); 1.63 - 1.64 - rdir++; 1.65 - } 1.66 - } 1.67 - rdir_cache_width = xsz; 1.68 - rdir_cache_height = ysz; 1.69 - rdir_cache_fov = vfov; 1.70 - } 1.71 - } 1.72 + Vector2 ppos = calc_sample_pos(x, y, xsz, ysz, sample); 1.73 1.74 Ray ray; 1.75 ray.origin = pos; 1.76 - ray.dir = rdir_cache[y * xsz + x]; 1.77 + ray.dir.x = ppos.x; 1.78 + ray.dir.y = ppos.y; 1.79 + ray.dir.z = 1.0 / tan(vfov / 2.0); 1.80 + ray.dir.normalize(); 1.81 1.82 // transform the ray direction with the camera matrix 1.83 Matrix4x4 mat = get_matrix();
2.1 --- a/liberebus/src/camera.h Sat May 24 02:27:08 2014 +0300 2.2 +++ b/liberebus/src/camera.h Sat May 24 06:12:57 2014 +0300 2.3 @@ -11,10 +11,6 @@ 2.4 mutable Matrix4x4 cached_matrix; 2.5 mutable bool cached_matrix_valid; 2.6 2.7 - mutable Vector3 *rdir_cache; 2.8 - mutable int rdir_cache_width, rdir_cache_height; 2.9 - mutable float rdir_cache_fov; 2.10 - 2.11 virtual void calc_matrix(Matrix4x4 *mat) const = 0; 2.12 2.13 Vector2 calc_sample_pos(int x, int y, int xsz, int ysz, int sample) const;
3.1 --- a/liberebus/src/erebus.cc Sat May 24 02:27:08 2014 +0300 3.2 +++ b/liberebus/src/erebus.cc Sat May 24 06:12:57 2014 +0300 3.3 @@ -9,6 +9,8 @@ 3.4 #include "geomobj.h" 3.5 #include "rt.h" 3.6 3.7 +#define INF_SAMPLES (INT_MAX / 2) 3.8 + 3.9 using namespace std::chrono; 3.10 3.11 struct Rect { 3.12 @@ -24,15 +26,17 @@ 3.13 Scene *scn; 3.14 3.15 Image<float> fbimg; 3.16 + Image<float> accum; // sample accumulator per pixel 3.17 Vector4 options[ERB_NUM_OPTIONS]; 3.18 3.19 // render state 3.20 long cur_time; 3.21 int cur_pixel_x, cur_pixel_y; 3.22 Rect cur_rect; 3.23 + int cur_sample; 3.24 }; 3.25 3.26 -static void render_pixel(struct erebus *ctx, int x, int y); 3.27 +static void render_pixel(struct erebus *ctx, int x, int y, int sample); 3.28 3.29 static std::mt19937 rnd_gen; 3.30 3.31 @@ -51,6 +55,8 @@ 3.32 ctx->scn = 0; 3.33 ctx->cur_time = 0; 3.34 ctx->cur_rect = INVALID_RECT; 3.35 + 3.36 + ctx->options[ERB_OPT_MAX_SAMPLES].x = (float)INF_SAMPLES; 3.37 return ctx; 3.38 } 3.39 3.40 @@ -94,12 +100,14 @@ 3.41 3.42 void erb_begin_frame(struct erebus *ctx, long ms) 3.43 { 3.44 + printf("starting new frame...\n"); 3.45 ctx->cur_time = ms; 3.46 3.47 int xsz = ctx->options[ERB_OPT_WIDTH].x; 3.48 int ysz = ctx->options[ERB_OPT_HEIGHT].x; 3.49 3.50 ctx->fbimg.create(xsz, ysz); 3.51 + ctx->accum.create(xsz, ysz); 3.52 } 3.53 3.54 int erb_render(struct erebus *ctx, long timeout) 3.55 @@ -113,31 +121,45 @@ 3.56 3.57 Rect rect{x, y, width, height}; 3.58 if(ctx->cur_rect != rect) { 3.59 + // starting a new rendering apparently 3.60 ctx->cur_rect = rect; 3.61 ctx->cur_pixel_x = x; 3.62 ctx->cur_pixel_y = y; 3.63 + ctx->cur_sample = 0; 3.64 } 3.65 3.66 ctx->scn->update(); 3.67 3.68 + int max_samples = ctx->options[ERB_OPT_MAX_SAMPLES].x; 3.69 + 3.70 if(timeout > 0) { 3.71 auto start_time = steady_clock::now(); 3.72 while(duration_cast<milliseconds>(steady_clock::now() - start_time).count() < timeout) { 3.73 - render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y); 3.74 + render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y, ctx->cur_sample); 3.75 3.76 if(++ctx->cur_pixel_x >= ctx->cur_rect.width) { 3.77 + ctx->cur_pixel_x = ctx->cur_rect.x; 3.78 if(++ctx->cur_pixel_y >= ctx->cur_rect.height) { 3.79 - ctx->cur_rect = INVALID_RECT; 3.80 - return 0; 3.81 + ctx->cur_pixel_y = ctx->cur_rect.y; 3.82 + if(++ctx->cur_sample >= max_samples) { 3.83 + ctx->cur_rect = INVALID_RECT; 3.84 + return 0; 3.85 + } 3.86 } 3.87 } 3.88 } 3.89 return 1; 3.90 } 3.91 3.92 + if(ctx->options[ERB_OPT_MAX_SAMPLES].x == (float)INF_SAMPLES) { 3.93 + max_samples = 128; 3.94 + } 3.95 + 3.96 for(int i=0; i<height; i++) { 3.97 for(int j=0; j<width; j++) { 3.98 - render_pixel(ctx, j, i); 3.99 + for(int k=0; k<max_samples; k++) { 3.100 + render_pixel(ctx, j, i, k); 3.101 + } 3.102 } 3.103 } 3.104 return 0; 3.105 @@ -155,11 +177,28 @@ 3.106 3.107 // XXX for now just create a test scene here 3.108 Sphere *sph = new Sphere; 3.109 + sph->mtl.set_attrib("albedo", Color(1.0, 0.3, 0.2)); 3.110 SceneNode *sph_node = new SceneNode(sph); 3.111 ctx->scn->add_object(sph); 3.112 ctx->scn->add_node(sph_node); 3.113 3.114 - TargetCamera *cam = new TargetCamera(Vector3(0, 0, -10), Vector3(0, 0, 0)); 3.115 + sph = new Sphere; 3.116 + sph->mtl.set_attrib("albedo", Color(0.3, 0.4, 1.0)); 3.117 + sph_node = new SceneNode(sph); 3.118 + sph_node->set_position(Vector3(0, -3.0, 0)); 3.119 + //sph_node->set_scaling(Vector3(4.0, 4.0, 4.0) * 0.3); 3.120 + ctx->scn->add_object(sph); 3.121 + ctx->scn->add_node(sph_node); 3.122 + 3.123 + Sphere *lt = new Sphere; 3.124 + lt->mtl.set_attrib("emissive", Color(10, 10, 10)); 3.125 + SceneNode *lt_node = new SceneNode(lt); 3.126 + lt_node->set_position(Vector3(-15, 15, -10)); 3.127 + lt_node->set_scaling(Vector3(5, 5, 5)); 3.128 + ctx->scn->add_object(lt); 3.129 + ctx->scn->add_node(lt_node); 3.130 + 3.131 + TargetCamera *cam = new TargetCamera(Vector3(0, 4, -8), Vector3(0, 0, 0)); 3.132 //ctx->scn->add_object(cam); 3.133 ctx->scn->use_camera(cam); 3.134 3.135 @@ -174,20 +213,28 @@ 3.136 return unirnd(rnd_gen); 3.137 } 3.138 3.139 -static void render_pixel(struct erebus *ctx, int x, int y) 3.140 +static void render_pixel(struct erebus *ctx, int x, int y, int sample) 3.141 { 3.142 Camera *cam = ctx->scn->get_active_camera(); 3.143 if(!cam) return; 3.144 3.145 int xsz = ctx->fbimg.get_width(); 3.146 int ysz = ctx->fbimg.get_height(); 3.147 - float *pix = ctx->fbimg.get_pixels() + (y * xsz + x) * 4; 3.148 + int offs = (y * xsz + x) * 4; 3.149 3.150 - Ray ray = cam->get_primary_ray(x, y, xsz, ysz, 0); 3.151 - //Color c = ray_trace(ray, ctx->scn, 0); 3.152 - Color c = ray.dir.normalized() * 0.5 + Vector3(0.5, 0.5, 0.5); 3.153 - pix[0] = 1.0;//c.x; 3.154 - pix[1] = c.y; 3.155 - pix[2] = c.z; 3.156 - pix[3] = c.w; 3.157 + float *pix = ctx->fbimg.get_pixels() + offs; 3.158 + float *accum = ctx->accum.get_pixels() + offs; 3.159 + 3.160 + Ray ray = cam->get_primary_ray(x, y, xsz, ysz, sample); 3.161 + Color c = ray_trace(ray, ctx->scn, 0); 3.162 + accum[0] += c.x; 3.163 + accum[1] += c.y; 3.164 + accum[2] += c.z; 3.165 + accum[3] += c.w; 3.166 + 3.167 + float inv_samples = 1.0f / (float)(sample + 1); 3.168 + pix[0] = accum[0] * inv_samples; 3.169 + pix[1] = accum[1] * inv_samples; 3.170 + pix[2] = accum[2] * inv_samples; 3.171 + pix[3] = accum[3] * inv_samples; 3.172 }
4.1 --- a/liberebus/src/erebus.h Sat May 24 02:27:08 2014 +0300 4.2 +++ b/liberebus/src/erebus.h Sat May 24 06:12:57 2014 +0300 4.3 @@ -7,6 +7,7 @@ 4.4 ERB_OPT_WIDTH, 4.5 ERB_OPT_HEIGHT, 4.6 ERB_OPT_MAX_ITER, 4.7 + ERB_OPT_MAX_SAMPLES, 4.8 ERB_OPT_NUM_THREADS, 4.9 ERB_OPT_GAMMA, 4.10
5.1 --- a/liberebus/src/geomobj.cc Sat May 24 02:27:08 2014 +0300 5.2 +++ b/liberebus/src/geomobj.cc Sat May 24 06:12:57 2014 +0300 5.3 @@ -18,6 +18,22 @@ 5.4 return false; 5.5 } 5.6 5.7 +Vector3 GeomObject::calc_normal(const RayHit &hit) const 5.8 +{ 5.9 + // when you look at singularities, the singularities always look back at you :) 5.10 + return -(hit.world_ray.dir).normalized(); 5.11 +} 5.12 + 5.13 +Vector3 GeomObject::calc_tangent(const RayHit &hit) const 5.14 +{ 5.15 + return Vector3(1, 0, 0); // whatever... 5.16 +} 5.17 + 5.18 +Vector2 GeomObject::calc_texcoords(const RayHit &hit) const 5.19 +{ 5.20 + return Vector2(); 5.21 +} 5.22 + 5.23 // --- class Sphere --- 5.24 5.25 bool Sphere::intersect(const Ray &ray, RayHit *hit) const 5.26 @@ -47,6 +63,40 @@ 5.27 return true; 5.28 } 5.29 5.30 +Vector3 Sphere::calc_normal(const RayHit &hit) const 5.31 +{ 5.32 + Vector3 pt = hit.world_ray.origin + hit.world_ray.dir * hit.dist; 5.33 + return pt.normalized(); 5.34 +} 5.35 + 5.36 +static inline Vector3 sphvec(float u, float v) 5.37 +{ 5.38 + float theta = u * M_PI * 2.0; 5.39 + float phi = v * M_PI; 5.40 + 5.41 + return Vector3(sin(theta) * sin(phi), cos(phi), cos(theta) * sin(phi)); 5.42 +} 5.43 + 5.44 +Vector3 Sphere::calc_tangent(const RayHit &hit) const 5.45 +{ 5.46 + Vector2 uv = calc_texcoords(hit); 5.47 + Vector3 pnext = sphvec(uv.x + 0.05, 0.5); 5.48 + Vector3 pprev = sphvec(uv.y - 0.05, 0.5); 5.49 + return (pnext - pprev).normalized(); 5.50 +} 5.51 + 5.52 +Vector2 Sphere::calc_texcoords(const RayHit &hit) const 5.53 +{ 5.54 + Vector3 pt = hit.world_ray.origin + hit.world_ray.dir * hit.dist; 5.55 + pt.normalize(); 5.56 + 5.57 + float theta = atan2(pt.z, pt.x); 5.58 + float phi = acos(pt.y); 5.59 + 5.60 + return Vector2(theta / M_PI + 0.5, phi / M_PI); 5.61 +} 5.62 + 5.63 + 5.64 // --- class Box --- 5.65 5.66 bool Box::intersect(const Ray &ray, RayHit *hit) const
6.1 --- a/liberebus/src/geomobj.h Sat May 24 02:27:08 2014 +0300 6.2 +++ b/liberebus/src/geomobj.h Sat May 24 06:12:57 2014 +0300 6.3 @@ -16,11 +16,19 @@ 6.4 ObjType get_type() const override; 6.5 6.6 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 6.7 + 6.8 + virtual Vector3 calc_normal(const RayHit &hit) const; 6.9 + virtual Vector3 calc_tangent(const RayHit &hit) const; 6.10 + virtual Vector2 calc_texcoords(const RayHit &hit) const; 6.11 }; 6.12 6.13 class Sphere : public GeomObject { 6.14 public: 6.15 bool intersect(const Ray &ray, RayHit *hit = 0) const override; 6.16 + 6.17 + Vector3 calc_normal(const RayHit &hit) const override; 6.18 + Vector3 calc_tangent(const RayHit &hit) const override; 6.19 + Vector2 calc_texcoords(const RayHit &hit) const override; 6.20 }; 6.21 6.22 class Box : public GeomObject {
7.1 --- a/liberebus/src/material.cc Sat May 24 02:27:08 2014 +0300 7.2 +++ b/liberebus/src/material.cc Sat May 24 06:12:57 2014 +0300 7.3 @@ -1,7 +1,7 @@ 7.4 #include "material.h" 7.5 7.6 MatAttrib::MatAttrib() 7.7 - : value(1), color(1, 1, 1), map(0) 7.8 + : value(0), color(0, 0, 0), map(0) 7.9 { 7.10 } 7.11
8.1 --- a/liberebus/src/rt.cc Sat May 24 02:27:08 2014 +0300 8.2 +++ b/liberebus/src/rt.cc Sat May 24 06:12:57 2014 +0300 8.3 @@ -1,16 +1,41 @@ 8.4 +#include <assert.h> 8.5 #include "rt.h" 8.6 +#include "erebus_impl.h" 8.7 + 8.8 +#define MAX_ITER 8 8.9 8.10 Color ray_trace(const Ray &ray, const Scene *scn, int iter) 8.11 { 8.12 RayHit hit; 8.13 if(!(scn->intersect(ray, &hit))) { 8.14 - return Color(0, 0, 0, 0); 8.15 + return scn->get_env_color(ray); 8.16 } 8.17 8.18 - return shade(hit, iter); 8.19 + return shade(hit, scn, iter); 8.20 } 8.21 8.22 -Color shade(const RayHit &hit, int iter) 8.23 +Color shade(const RayHit &hit, const Scene *scn, int iter) 8.24 { 8.25 - return Color(1, 0, 0, 1); 8.26 + assert(hit.obj->get_type() == ObjType::geom); 8.27 + const GeomObject *obj = (const GeomObject*)hit.obj; 8.28 + const Material *mtl = &obj->mtl; 8.29 + const Reflectance *brdf = obj->brdf; 8.30 + const Ray &ray = hit.world_ray; 8.31 + 8.32 + Vector3 norm = obj->calc_normal(hit); 8.33 + Vector2 texcoords = obj->calc_texcoords(hit); 8.34 + 8.35 + Color color = mtl->get_attrib_color("albedo", texcoords.x, texcoords.y); 8.36 + Color res = mtl->get_attrib_color("emissive") + color * scn->get_env().ambient; 8.37 + 8.38 + Vector3 sample_dir; 8.39 + float prob = brdf->sample(norm, -hit.world_ray.dir, &sample_dir); 8.40 + if(iter < MAX_ITER && randf() <= prob) { 8.41 + Ray sample_ray; 8.42 + sample_ray.origin = ray.origin + ray.dir * hit.dist; 8.43 + sample_ray.dir = sample_dir; 8.44 + 8.45 + res += ray_trace(sample_ray, scn, iter + 1) * color; 8.46 + } 8.47 + return res; 8.48 }
9.1 --- a/liberebus/src/rt.h Sat May 24 02:27:08 2014 +0300 9.2 +++ b/liberebus/src/rt.h Sat May 24 06:12:57 2014 +0300 9.3 @@ -6,6 +6,6 @@ 9.4 #include "scene.h" 9.5 9.6 Color ray_trace(const Ray &ray, const Scene *scn, int iter); 9.7 -Color shade(const RayHit &hit, int iter); 9.8 +Color shade(const RayHit &hit, const Scene *scn, int iter); 9.9 9.10 #endif // RT_H_
10.1 --- a/liberebus/src/scene.cc Sat May 24 02:27:08 2014 +0300 10.2 +++ b/liberebus/src/scene.cc Sat May 24 06:12:57 2014 +0300 10.3 @@ -1,5 +1,11 @@ 10.4 #include "scene.h" 10.5 10.6 +// default enviromental parameters 10.7 +Environment::Environment() 10.8 + : bgcolor(0.05, 0.05, 0.05), ambient(0.05, 0.05, 0.05) 10.9 +{ 10.10 +} 10.11 + 10.12 Scene::Scene() 10.13 { 10.14 active_cam = 0; 10.15 @@ -17,6 +23,32 @@ 10.16 delete root; 10.17 } 10.18 10.19 +void Scene::set_env(const Environment &env) 10.20 +{ 10.21 + this->env = env; 10.22 +} 10.23 + 10.24 +Environment &Scene::get_env() 10.25 +{ 10.26 + return env; 10.27 +} 10.28 + 10.29 +const Environment &Scene::get_env() const 10.30 +{ 10.31 + return env; 10.32 +} 10.33 + 10.34 +Color Scene::get_env_color() const 10.35 +{ 10.36 + return env.bgcolor; 10.37 +} 10.38 + 10.39 +Color Scene::get_env_color(const Ray &ray) const 10.40 +{ 10.41 + // TODO 10.42 + return get_env_color(); 10.43 +} 10.44 + 10.45 void Scene::add_object(Object *obj) 10.46 { 10.47 objects.push_back(obj);
11.1 --- a/liberebus/src/scene.h Sat May 24 02:27:08 2014 +0300 11.2 +++ b/liberebus/src/scene.h Sat May 24 06:12:57 2014 +0300 11.3 @@ -4,9 +4,20 @@ 11.4 #include <vector> 11.5 #include "snode.h" 11.6 #include "camera.h" 11.7 +#include "color.h" 11.8 + 11.9 +struct Environment { 11.10 + Color bgcolor; 11.11 + Color ambient; 11.12 + // TODO map & image-based lighting 11.13 + 11.14 + Environment(); 11.15 +}; 11.16 11.17 class Scene { 11.18 private: 11.19 + Environment env; 11.20 + 11.21 std::vector<Object*> objects; 11.22 std::vector<SceneNode*> nodes; 11.23 11.24 @@ -18,6 +29,13 @@ 11.25 Scene(); 11.26 ~Scene(); 11.27 11.28 + void set_env(const Environment &env); 11.29 + Environment &get_env(); 11.30 + const Environment &get_env() const; 11.31 + 11.32 + Color get_env_color() const; 11.33 + Color get_env_color(const Ray &ray) const; 11.34 + 11.35 void add_object(Object *obj); 11.36 int get_object_count() const; 11.37 Object *get_object(int idx) const;
12.1 --- a/liberebus/src/snode.cc Sat May 24 02:27:08 2014 +0300 12.2 +++ b/liberebus/src/snode.cc Sat May 24 06:12:57 2014 +0300 12.3 @@ -158,6 +158,15 @@ 12.4 } 12.5 } 12.6 12.7 + for(size_t i=0; i<children.size(); i++) { 12.8 + if(children[i]->intersect(ray, hit)) { 12.9 + if(!hit) return true; 12.10 + if(hit->dist < nearest.dist) { 12.11 + nearest = *hit; 12.12 + } 12.13 + } 12.14 + } 12.15 + 12.16 if(nearest.dist < FLT_MAX) { 12.17 *hit = nearest; 12.18 hit->local_ray = local_ray;
13.1 --- a/src/main.cc Sat May 24 02:27:08 2014 +0300 13.2 +++ b/src/main.cc Sat May 24 06:12:57 2014 +0300 13.3 @@ -44,8 +44,8 @@ 13.4 13.5 static bool init() 13.6 { 13.7 - width = glutGet(GLUT_WINDOW_WIDTH); 13.8 - height = glutGet(GLUT_WINDOW_HEIGHT); 13.9 + width = glutGet(GLUT_WINDOW_WIDTH) / 2; 13.10 + height = glutGet(GLUT_WINDOW_HEIGHT) / 2; 13.11 13.12 if(!(erb = erb_init())) { 13.13 return false; 13.14 @@ -62,6 +62,7 @@ 13.15 glutIdleFunc(idle); 13.16 erb_begin_frame(erb, 0); 13.17 13.18 + glEnable(GL_TEXTURE_2D); 13.19 return true; 13.20 } 13.21 13.22 @@ -74,14 +75,14 @@ 13.23 { 13.24 static unsigned char *defpix; 13.25 13.26 - width = xsz; 13.27 - height = ysz; 13.28 + width = xsz / 2; 13.29 + height = ysz / 2; 13.30 13.31 - if(xsz <= rtex_width && ysz <= rtex_height) { 13.32 + if(width <= rtex_width && height <= rtex_height) { 13.33 return; 13.34 } 13.35 - rtex_width = next_pow2(xsz); 13.36 - rtex_height = next_pow2(ysz); 13.37 + rtex_width = next_pow2(width); 13.38 + rtex_height = next_pow2(height); 13.39 13.40 printf("resizing framebuffer texture: %dx%d\n", rtex_width, rtex_height); 13.41 13.42 @@ -125,16 +126,13 @@ 13.43 static void display() 13.44 { 13.45 if(render_pending) { 13.46 - if(erb_render(erb, 128) == 0) { 13.47 + if(erb_render(erb, 64) == 0) { 13.48 render_pending = false; 13.49 glutIdleFunc(0); 13.50 } 13.51 update_rect(0, 0, width, height, erb_get_framebuffer(erb)); 13.52 } 13.53 13.54 - glBindTexture(GL_TEXTURE_2D, rtex); 13.55 - glEnable(GL_TEXTURE_2D); 13.56 - 13.57 float maxu = (float)width / (float)rtex_width; 13.58 float maxv = (float)height / (float)rtex_height; 13.59 13.60 @@ -145,8 +143,6 @@ 13.61 glTexCoord2f(0, 0); glVertex2f(-1, 1); 13.62 glEnd(); 13.63 13.64 - glDisable(GL_TEXTURE_2D); 13.65 - 13.66 glutSwapBuffers(); 13.67 assert(glGetError() == GL_NO_ERROR); 13.68 }