erebus

diff liberebus/src/erebus.cc @ 0:4abdce1361b9

initial commit
author John Tsiombikas <nuclear@member.fsf.org>
date Sun, 27 Apr 2014 16:02:47 +0300
parents
children 474a0244f57d
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/liberebus/src/erebus.cc	Sun Apr 27 16:02:47 2014 +0300
     1.3 @@ -0,0 +1,159 @@
     1.4 +#include <string.h>
     1.5 +#include <limits.h>
     1.6 +#include <chrono>
     1.7 +#include <random>
     1.8 +#include "erebus.h"
     1.9 +#include "vmath/vector.h"
    1.10 +#include "image.h"
    1.11 +
    1.12 +using namespace std::chrono;
    1.13 +
    1.14 +struct Rect {
    1.15 +	int x, y, width, height;
    1.16 +
    1.17 +	bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; }
    1.18 +	bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; }
    1.19 +};
    1.20 +
    1.21 +#define INVALID_RECT	Rect{0, 0, 0, 0}
    1.22 +
    1.23 +struct erebus {
    1.24 +	Image<float> fbimg;
    1.25 +	Vector4 options[ERB_NUM_OPTIONS];
    1.26 +
    1.27 +	// render state
    1.28 +	long cur_time;
    1.29 +	int cur_pixel_x, cur_pixel_y;
    1.30 +	Rect cur_rect;
    1.31 +};
    1.32 +
    1.33 +static void render_pixel(struct erebus *ctx, int x, int y);
    1.34 +
    1.35 +static std::mt19937 rnd_gen;
    1.36 +
    1.37 +extern "C" {
    1.38 +
    1.39 +struct erebus *erb_init(void)
    1.40 +{
    1.41 +	struct erebus *ctx;
    1.42 +	try {
    1.43 +		ctx = new struct erebus;
    1.44 +	}
    1.45 +	catch(...) {
    1.46 +		return 0;
    1.47 +	}
    1.48 +
    1.49 +	ctx->cur_time = 0;
    1.50 +	ctx->cur_rect = INVALID_RECT;
    1.51 +	return ctx;
    1.52 +}
    1.53 +
    1.54 +void erb_destroy(struct erebus *ctx)
    1.55 +{
    1.56 +	delete ctx;
    1.57 +}
    1.58 +
    1.59 +void erb_setopti(struct erebus *ctx, enum erb_option opt, int val)
    1.60 +{
    1.61 +	ctx->options[opt].x;
    1.62 +}
    1.63 +void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val)
    1.64 +{
    1.65 +	ctx->options[opt].x = val;
    1.66 +}
    1.67 +void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec)
    1.68 +{
    1.69 +	for(int i=0; i<4; i++) {
    1.70 +		ctx->options[opt][i] = vec[i];
    1.71 +	}
    1.72 +}
    1.73 +
    1.74 +int erb_getopti(struct erebus *ctx, enum erb_option opt)
    1.75 +{
    1.76 +	return ctx->options[opt].x;
    1.77 +}
    1.78 +float erb_getoptf(struct erebus *ctx, enum erb_option opt)
    1.79 +{
    1.80 +	return ctx->options[opt].x;
    1.81 +}
    1.82 +float *erb_getoptfv(struct erebus *ctx, enum erb_option opt)
    1.83 +{
    1.84 +	return &ctx->options[opt].x;
    1.85 +}
    1.86 +
    1.87 +float *erb_get_framebuffer(struct erebus *ctx)
    1.88 +{
    1.89 +	return ctx->fbimg.get_pixels();
    1.90 +}
    1.91 +
    1.92 +void erb_begin_frame(struct erebus *ctx, long ms)
    1.93 +{
    1.94 +	ctx->cur_time = ms;
    1.95 +}
    1.96 +
    1.97 +int erb_render(struct erebus *ctx, long timeout)
    1.98 +{
    1.99 +	return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout);
   1.100 +}
   1.101 +
   1.102 +int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout)
   1.103 +{
   1.104 +	if(!width || !height) return -1;
   1.105 +
   1.106 +	Rect rect{x, y, width, height};
   1.107 +	if(ctx->cur_rect != rect) {
   1.108 +		ctx->cur_rect = rect;
   1.109 +		ctx->cur_pixel_x = x;
   1.110 +		ctx->cur_pixel_y = y;
   1.111 +	}
   1.112 +
   1.113 +	if(timeout > 0) {
   1.114 +		auto start_time = monotonic_clock::now();
   1.115 +		while(duration_cast<milliseconds>(monotonic_clock::now() - start_time).count() < timeout) {
   1.116 +			render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y);
   1.117 +
   1.118 +			if(++ctx->cur_pixel_x >= ctx->cur_rect.width) {
   1.119 +				if(++ctx->cur_pixel_y >= ctx->cur_rect.height) {
   1.120 +					ctx->cur_rect = INVALID_RECT;
   1.121 +					return 0;
   1.122 +				}
   1.123 +			}
   1.124 +		}
   1.125 +		return 1;
   1.126 +	}
   1.127 +
   1.128 +	for(int i=0; i<height; i++) {
   1.129 +		for(int j=0; j<width; j++) {
   1.130 +			render_pixel(ctx, j, i);
   1.131 +		}
   1.132 +	}
   1.133 +	return 0;
   1.134 +}
   1.135 +
   1.136 +int erb_get_progress(struct erebus *ctx)
   1.137 +{
   1.138 +	return 0;	// TODO
   1.139 +}
   1.140 +
   1.141 +int erb_load_scene(struct erebus *ctx, const char *fname)
   1.142 +{
   1.143 +	//delete ctx->scene;
   1.144 +	//ctx->scene = new Scene;
   1.145 +
   1.146 +	return false;	// TODO
   1.147 +}
   1.148 +
   1.149 +}	// extern "C"
   1.150 +
   1.151 +float randf(float low, float high)
   1.152 +{
   1.153 +	std::uniform_real_distribution<float> unirnd(low, high);
   1.154 +	return unirnd(rnd_gen);
   1.155 +}
   1.156 +
   1.157 +static void render_pixel(struct erebus *ctx, int x, int y)
   1.158 +{
   1.159 +	float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4;
   1.160 +	pix[0] = pix[1] = pix[2] = 0.0f;
   1.161 +	pix[3] = 1.0f;
   1.162 +}
   1.163 \ No newline at end of file