erebus

changeset 34:d15ee526daa6

- changed the UI font, made it a bit smaller - fixed the text positioning in the status bar - added ThreadPool::clear to remove all pending jobs - fixed the TargetCamera matrix calculation to avoid singularities when the camera looks straight up or down. - fixed ommited normalization in TargetCamera's matrix calculation - added paths/sec display in the status bar
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 08 Jun 2014 08:12:05 +0300
parents 2c768a49e86e
children 4901cf062c70
files Makefile data/serif.glyphmap liberebus/Makefile liberebus/src/brdf.cc liberebus/src/camera.cc liberebus/src/erebus.cc liberebus/src/threadpool.cc liberebus/src/threadpool.h src/main.cc
diffstat 9 files changed, 91 insertions(+), 35 deletions(-) [+]
line diff
     1.1 --- a/Makefile	Sat Jun 07 14:21:56 2014 +0300
     1.2 +++ b/Makefile	Sun Jun 08 08:12:05 2014 +0300
     1.3 @@ -3,9 +3,9 @@
     1.4  obj = $(csrc:.c=.o) $(ccsrc:.cc=.o)
     1.5  bin = erebus
     1.6  
     1.7 -opt = -O3 -ffast-math
     1.8 -dbg = -g
     1.9 -warn = -Wall
    1.10 +export opt = -O3 -ffast-math
    1.11 +export dbg = -g
    1.12 +export warn = -Wall
    1.13  
    1.14  CFLAGS = -pedantic $(warn) $(opt) $(dbg) -Iliberebus/src
    1.15  CXXFLAGS = -std=c++11 $(CFLAGS)
    1.16 @@ -22,10 +22,17 @@
    1.17  liberebus:
    1.18  	$(MAKE) -C liberebus
    1.19  
    1.20 +.PHONY: liberebus-clean
    1.21 +liberebus-clean:
    1.22 +	$(MAKE) -C liberebus clean
    1.23 +
    1.24  .PHONY: clean
    1.25  clean:
    1.26  	rm -f $(obj) $(bin)
    1.27  
    1.28 +.PHONY: cleanall
    1.29 +cleanall: clean liberebus-clean
    1.30 +
    1.31  uname = $(shell uname -s)
    1.32  ifeq ($(uname), Darwin)
    1.33  	sys = mac
     2.1 Binary file data/serif.glyphmap has changed
     3.1 --- a/liberebus/Makefile	Sat Jun 07 14:21:56 2014 +0300
     3.2 +++ b/liberebus/Makefile	Sun Jun 08 08:12:05 2014 +0300
     3.3 @@ -8,8 +8,8 @@
     3.4  api_major = 0
     3.5  api_minor = 1
     3.6  
     3.7 -CXXFLAGS = -std=c++11 -pedantic -Wall -g $(pic)
     3.8 -LDFLAGS = -lvmath -limago -lm
     3.9 +CXXFLAGS = -std=c++11 -pthread -pedantic $(warn) $(dbg) $(opt) $(pic)
    3.10 +LDFLAGS = -pthread -lvmath -limago -lm
    3.11  
    3.12  ifeq ($(shell uname -s), Darwin)
    3.13  	shared = -dynamiclib
     4.1 --- a/liberebus/src/brdf.cc	Sat Jun 07 14:21:56 2014 +0300
     4.2 +++ b/liberebus/src/brdf.cc	Sun Jun 08 08:12:05 2014 +0300
     4.3 @@ -18,7 +18,7 @@
     4.4  	}
     4.5  
     4.6  	tangent = Vector3(1.0f, 0.0f, 0.0f);
     4.7 -	if(fabs(fabs(dot_product(normal, tangent)) - 1.0f) < 1e-4f) {
     4.8 +	if(1.0 - fabs(dot_product(normal, tangent)) < 1e-4f) {
     4.9  		tangent = Vector3(0.0f, 0.0f, 1.0f);
    4.10  	}
    4.11  	Vector3 bitan = cross_product(normal, tangent);
     5.1 --- a/liberebus/src/camera.cc	Sat Jun 07 14:21:56 2014 +0300
     5.2 +++ b/liberebus/src/camera.cc	Sun Jun 08 08:12:05 2014 +0300
     5.3 @@ -108,9 +108,14 @@
     5.4  
     5.5  void TargetCamera::calc_matrix(Matrix4x4 *mat) const
     5.6  {
     5.7 -	Vector3 up(0, 1, 0);
     5.8 +	Vector3 up{0, 1, 0};
     5.9  	Vector3 dir = (target - pos).normalized();
    5.10 -	Vector3 right = cross_product(up, dir);
    5.11 +
    5.12 +	if(1.0 - fabs(dot_product(dir, up)) < 1e-4) {
    5.13 +		up = Vector3(0, 0, 1);
    5.14 +	}
    5.15 +
    5.16 +	Vector3 right = cross_product(up, dir).normalized();
    5.17  	up = cross_product(dir, right);
    5.18  
    5.19  	*mat = Matrix4x4(
     6.1 --- a/liberebus/src/erebus.cc	Sat Jun 07 14:21:56 2014 +0300
     6.2 +++ b/liberebus/src/erebus.cc	Sun Jun 08 08:12:05 2014 +0300
     6.3 @@ -133,6 +133,7 @@
     6.4  		int num_threads = erb_getopti(ctx, ERB_OPT_NUM_THREADS);
     6.5  		ctx->tpool = new ThreadPool(num_threads);
     6.6  	}
     6.7 +	ctx->tpool->clear_work();	// remove any previously pending jobs
     6.8  
     6.9  	++ctx->cur_frame;
    6.10  	ctx->cur_sample = 0;
    6.11 @@ -214,9 +215,7 @@
    6.12  int erb_get_status(struct erebus *ctx, struct erb_render_status *stat)
    6.13  {
    6.14  	long pending = ctx->tpool->pending();
    6.15 -	if(!pending) {
    6.16 -		return -1;
    6.17 -	}
    6.18 +
    6.19  	int xsz = ctx->fbimg.get_width();
    6.20  	int ysz = ctx->fbimg.get_height();
    6.21  	int xblocks = (xsz + BLKSZ - 1) / BLKSZ;
    6.22 @@ -232,9 +231,17 @@
    6.23  	if((stat->max_samples = erb_getopti(ctx, ERB_OPT_MAX_SAMPLES)) == INF_SAMPLES) {
    6.24  		stat->max_samples = stat->samples;
    6.25  
    6.26 -		stat->progress_percent = 100 * stat->blocks / stat->max_blocks;
    6.27 +		if(stat->max_blocks) {
    6.28 +			stat->progress_percent = 100 * stat->blocks / stat->max_blocks;
    6.29 +		} else {
    6.30 +			stat->progress_percent = 0;
    6.31 +		}
    6.32  	} else {
    6.33 -		stat->progress_percent = 100 * stat->samples / stat->max_samples;
    6.34 +		if(stat->max_samples) {
    6.35 +			stat->progress_percent = 100 * stat->samples / stat->max_samples;
    6.36 +		} else {
    6.37 +			stat->progress_percent = 0;
    6.38 +		}
    6.39  	}
    6.40  	return 0;
    6.41  }
     7.1 --- a/liberebus/src/threadpool.cc	Sat Jun 07 14:21:56 2014 +0300
     7.2 +++ b/liberebus/src/threadpool.cc	Sun Jun 08 08:12:05 2014 +0300
     7.3 @@ -33,10 +33,7 @@
     7.4  ThreadPool::~ThreadPool()
     7.5  {
     7.6  #ifdef _MSC_VER
     7.7 -	workq_mutex.lock();
     7.8 -	workq.clear();
     7.9 -	qsize = 0;
    7.10 -	workq_mutex.unlock();
    7.11 +	clear_work();
    7.12  #endif
    7.13  
    7.14  	quit = true;
    7.15 @@ -79,6 +76,13 @@
    7.16  	workq_condvar.notify_all();
    7.17  }
    7.18  
    7.19 +void ThreadPool::clear_work()
    7.20 +{
    7.21 +	std::unique_lock<std::mutex> lock(workq_mutex);
    7.22 +	workq.clear();
    7.23 +	qsize = 0;
    7.24 +}
    7.25 +
    7.26  int ThreadPool::queued() const
    7.27  {
    7.28  	std::unique_lock<std::mutex> lock(workq_mutex);
     8.1 --- a/liberebus/src/threadpool.h	Sat Jun 07 14:21:56 2014 +0300
     8.2 +++ b/liberebus/src/threadpool.h	Sun Jun 08 08:12:05 2014 +0300
     8.3 @@ -32,11 +32,13 @@
     8.4  	void thread_func();
     8.5  
     8.6  public:
     8.7 -	ThreadPool(int num_threads = -1);
     8.8 +	// passing num_threads == -1 auto-detects based on number of processors
     8.9 +	explicit ThreadPool(int num_threads = -1);
    8.10  	~ThreadPool();
    8.11  
    8.12  	void add_work(std::function<void ()> func);
    8.13  	void add_work(std::function<void ()> work_func, std::function<void ()> done_func);
    8.14 +	void clear_work();
    8.15  
    8.16  	// returns the number of queued work items
    8.17  	int queued() const;
     9.1 --- a/src/main.cc	Sat Jun 07 14:21:56 2014 +0300
     9.2 +++ b/src/main.cc	Sun Jun 08 08:12:05 2014 +0300
     9.3 @@ -1,5 +1,6 @@
     9.4  #include <stdio.h>
     9.5  #include <stdlib.h>
     9.6 +#include <string.h>
     9.7  #include <assert.h>
     9.8  #include <signal.h>
     9.9  #include <vector>
    9.10 @@ -88,10 +89,10 @@
    9.11  	width = glutGet(GLUT_WINDOW_WIDTH) / opt_imgscale;
    9.12  	height = glutGet(GLUT_WINDOW_HEIGHT) / opt_imgscale;
    9.13  
    9.14 +	//if(!(font = dtx_open_font("/usr/share/fonts/opentype/linux-libertine/LinLibertine_R.otf", 22))) {
    9.15  	if(!(font = dtx_open_font_glyphmap("data/serif.glyphmap"))) {
    9.16  		fprintf(stderr, "warning: failed to load font!\n");
    9.17  	}
    9.18 -	dtx_use_font(font, 24);
    9.19  
    9.20  	if(!(erb = erb_init())) {
    9.21  		return false;
    9.22 @@ -244,6 +245,9 @@
    9.23  	float maxu = (float)width / (float)rtex_width;
    9.24  	float maxv = (float)height / (float)rtex_height;
    9.25  
    9.26 +	glEnable(GL_TEXTURE_2D);
    9.27 +	glBindTexture(GL_TEXTURE_2D, rtex);
    9.28 +
    9.29  	glBegin(GL_QUADS);
    9.30  	glColor4f(1, 1, 1, 1);
    9.31  	glTexCoord2f(0, maxv); glVertex2f(-1, -1);
    9.32 @@ -267,7 +271,6 @@
    9.33  
    9.34  	bool show_progress = opt_samples > 0;
    9.35  
    9.36 -	glPushAttrib(GL_ENABLE_BIT);
    9.37  	glDisable(GL_TEXTURE_2D);
    9.38  
    9.39  	glMatrixMode(GL_PROJECTION);
    9.40 @@ -279,40 +282,68 @@
    9.41  	glPushMatrix();
    9.42  	glLoadIdentity();
    9.43  
    9.44 -	int font_height = dtx_glyph_height('Q');
    9.45 +	dtx_box bbox;
    9.46 +	dtx_glyph_box('Q', &bbox);
    9.47 +
    9.48 +	// draw progress/status bar
    9.49 +	int bar_height = bbox.height + 4;
    9.50  	int prog_width = show_progress ? status.progress_percent * win_width / 100 : 0;
    9.51  
    9.52  	glBegin(GL_QUADS);
    9.53  	glColor4f(0, 0, 0, 1);
    9.54  	glVertex2f(prog_width, 0);
    9.55  	glVertex2f(win_width, 0);
    9.56 -	glVertex2f(win_width, font_height);
    9.57 -	glVertex2f(prog_width, font_height);
    9.58 +	glVertex2f(win_width, bar_height);
    9.59 +	glVertex2f(prog_width, bar_height);
    9.60  
    9.61  	glColor4f(0.25, 0, 0, 1);
    9.62  	glVertex2f(0, 0);
    9.63  	glVertex2f(prog_width, 0);
    9.64 -	glVertex2f(prog_width, font_height);
    9.65 -	glVertex2f(0, font_height);
    9.66 +	glVertex2f(prog_width, bar_height);
    9.67 +	glVertex2f(0, bar_height);
    9.68  	glEnd();
    9.69  
    9.70 -	glTranslatef(5, 5, 0);
    9.71 +	// draw the text
    9.72 +	glTranslatef(bbox.x + 2, bbox.y + 2, 0);
    9.73  
    9.74  	glColor4f(1, 1, 1, 1);
    9.75  
    9.76  	if(opt_samples > 0) {
    9.77 -		dtx_printf("samples: %d / %d\n", status.samples, status.max_samples);
    9.78 +		dtx_printf("samples: %ld / %ld", status.samples, status.max_samples);
    9.79  
    9.80 -		glTranslatef(win_width - dtx_string_width("progress: 100%") - 5, 0, 0);
    9.81 -		dtx_printf("progress: %d%%\n", status.progress_percent);
    9.82 +		glLoadIdentity();
    9.83 +		glTranslatef(win_width - dtx_string_width("progress: 100%") - 2, bbox.y + 2, 0);
    9.84 +		dtx_printf("progress: %ld%%", status.progress_percent);
    9.85  	} else {
    9.86 -		dtx_printf("samples: %d\n", status.samples);
    9.87 +		dtx_printf("samples: %ld", status.samples);
    9.88  	}
    9.89 +
    9.90 +	// samples/sec display
    9.91 +	static long paths_per_sec, prev_msec, prev_paths;
    9.92 +
    9.93 +	long msec = duration_cast<milliseconds>(steady_clock::now() - start_time).count();
    9.94 +	long dt = msec - prev_msec;
    9.95 +
    9.96 +	if(dt >= 1500) {	// average over 1.5 seconds
    9.97 +		long paths = status.samples * width * height;
    9.98 +		if(prev_msec > 0 && prev_paths <= paths) {	// check valid interval (not a restart or whatever)
    9.99 +			paths_per_sec = 1000 * (paths - prev_paths) / dt;
   9.100 +		}
   9.101 +		prev_msec = msec;
   9.102 +		prev_paths = paths;
   9.103 +	}
   9.104 +
   9.105 +	glLoadIdentity();
   9.106 +	glTranslatef((win_width - dtx_string_width("paths/s: 999999")) / 2, bbox.y + 2, 0);
   9.107 +	if(paths_per_sec) {
   9.108 +		dtx_printf("paths/s: %ld", paths_per_sec);
   9.109 +	} else {
   9.110 +		dtx_printf("paths/s: ???");
   9.111 +	}
   9.112 +
   9.113  	glPopMatrix();
   9.114  	glMatrixMode(GL_PROJECTION);
   9.115  	glPopMatrix();
   9.116 -
   9.117 -	glPopAttrib();
   9.118  }
   9.119  
   9.120  static void save_image(const char *fname)
   9.121 @@ -344,12 +375,12 @@
   9.122  		begin_frame(0);
   9.123  		break;
   9.124  
   9.125 -	case '`':
   9.126 +	case '\b':
   9.127  		printf("saving image.\n");
   9.128  		save_image();
   9.129  		break;
   9.130  
   9.131 -	case 'p':
   9.132 +	case '`':
   9.133  		show_status = !show_status;
   9.134  		glutPostRedisplay();
   9.135  		break;
   9.136 @@ -451,4 +482,4 @@
   9.137  	}
   9.138  
   9.139  	return true;
   9.140 -}
   9.141 \ No newline at end of file
   9.142 +}