erebus

annotate 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
rev   line source
nuclear@0 1 #include <string.h>
nuclear@0 2 #include <limits.h>
nuclear@0 3 #include <chrono>
nuclear@0 4 #include <random>
nuclear@0 5 #include "erebus.h"
nuclear@0 6 #include "vmath/vector.h"
nuclear@0 7 #include "image.h"
nuclear@0 8
nuclear@0 9 using namespace std::chrono;
nuclear@0 10
nuclear@0 11 struct Rect {
nuclear@0 12 int x, y, width, height;
nuclear@0 13
nuclear@0 14 bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; }
nuclear@0 15 bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; }
nuclear@0 16 };
nuclear@0 17
nuclear@0 18 #define INVALID_RECT Rect{0, 0, 0, 0}
nuclear@0 19
nuclear@0 20 struct erebus {
nuclear@0 21 Image<float> fbimg;
nuclear@0 22 Vector4 options[ERB_NUM_OPTIONS];
nuclear@0 23
nuclear@0 24 // render state
nuclear@0 25 long cur_time;
nuclear@0 26 int cur_pixel_x, cur_pixel_y;
nuclear@0 27 Rect cur_rect;
nuclear@0 28 };
nuclear@0 29
nuclear@0 30 static void render_pixel(struct erebus *ctx, int x, int y);
nuclear@0 31
nuclear@0 32 static std::mt19937 rnd_gen;
nuclear@0 33
nuclear@0 34 extern "C" {
nuclear@0 35
nuclear@0 36 struct erebus *erb_init(void)
nuclear@0 37 {
nuclear@0 38 struct erebus *ctx;
nuclear@0 39 try {
nuclear@0 40 ctx = new struct erebus;
nuclear@0 41 }
nuclear@0 42 catch(...) {
nuclear@0 43 return 0;
nuclear@0 44 }
nuclear@0 45
nuclear@0 46 ctx->cur_time = 0;
nuclear@0 47 ctx->cur_rect = INVALID_RECT;
nuclear@0 48 return ctx;
nuclear@0 49 }
nuclear@0 50
nuclear@0 51 void erb_destroy(struct erebus *ctx)
nuclear@0 52 {
nuclear@0 53 delete ctx;
nuclear@0 54 }
nuclear@0 55
nuclear@0 56 void erb_setopti(struct erebus *ctx, enum erb_option opt, int val)
nuclear@0 57 {
nuclear@0 58 ctx->options[opt].x;
nuclear@0 59 }
nuclear@0 60 void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val)
nuclear@0 61 {
nuclear@0 62 ctx->options[opt].x = val;
nuclear@0 63 }
nuclear@0 64 void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec)
nuclear@0 65 {
nuclear@0 66 for(int i=0; i<4; i++) {
nuclear@0 67 ctx->options[opt][i] = vec[i];
nuclear@0 68 }
nuclear@0 69 }
nuclear@0 70
nuclear@0 71 int erb_getopti(struct erebus *ctx, enum erb_option opt)
nuclear@0 72 {
nuclear@0 73 return ctx->options[opt].x;
nuclear@0 74 }
nuclear@0 75 float erb_getoptf(struct erebus *ctx, enum erb_option opt)
nuclear@0 76 {
nuclear@0 77 return ctx->options[opt].x;
nuclear@0 78 }
nuclear@0 79 float *erb_getoptfv(struct erebus *ctx, enum erb_option opt)
nuclear@0 80 {
nuclear@0 81 return &ctx->options[opt].x;
nuclear@0 82 }
nuclear@0 83
nuclear@0 84 float *erb_get_framebuffer(struct erebus *ctx)
nuclear@0 85 {
nuclear@0 86 return ctx->fbimg.get_pixels();
nuclear@0 87 }
nuclear@0 88
nuclear@0 89 void erb_begin_frame(struct erebus *ctx, long ms)
nuclear@0 90 {
nuclear@0 91 ctx->cur_time = ms;
nuclear@0 92 }
nuclear@0 93
nuclear@0 94 int erb_render(struct erebus *ctx, long timeout)
nuclear@0 95 {
nuclear@0 96 return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout);
nuclear@0 97 }
nuclear@0 98
nuclear@0 99 int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout)
nuclear@0 100 {
nuclear@0 101 if(!width || !height) return -1;
nuclear@0 102
nuclear@0 103 Rect rect{x, y, width, height};
nuclear@0 104 if(ctx->cur_rect != rect) {
nuclear@0 105 ctx->cur_rect = rect;
nuclear@0 106 ctx->cur_pixel_x = x;
nuclear@0 107 ctx->cur_pixel_y = y;
nuclear@0 108 }
nuclear@0 109
nuclear@0 110 if(timeout > 0) {
nuclear@0 111 auto start_time = monotonic_clock::now();
nuclear@0 112 while(duration_cast<milliseconds>(monotonic_clock::now() - start_time).count() < timeout) {
nuclear@0 113 render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y);
nuclear@0 114
nuclear@0 115 if(++ctx->cur_pixel_x >= ctx->cur_rect.width) {
nuclear@0 116 if(++ctx->cur_pixel_y >= ctx->cur_rect.height) {
nuclear@0 117 ctx->cur_rect = INVALID_RECT;
nuclear@0 118 return 0;
nuclear@0 119 }
nuclear@0 120 }
nuclear@0 121 }
nuclear@0 122 return 1;
nuclear@0 123 }
nuclear@0 124
nuclear@0 125 for(int i=0; i<height; i++) {
nuclear@0 126 for(int j=0; j<width; j++) {
nuclear@0 127 render_pixel(ctx, j, i);
nuclear@0 128 }
nuclear@0 129 }
nuclear@0 130 return 0;
nuclear@0 131 }
nuclear@0 132
nuclear@0 133 int erb_get_progress(struct erebus *ctx)
nuclear@0 134 {
nuclear@0 135 return 0; // TODO
nuclear@0 136 }
nuclear@0 137
nuclear@0 138 int erb_load_scene(struct erebus *ctx, const char *fname)
nuclear@0 139 {
nuclear@0 140 //delete ctx->scene;
nuclear@0 141 //ctx->scene = new Scene;
nuclear@0 142
nuclear@0 143 return false; // TODO
nuclear@0 144 }
nuclear@0 145
nuclear@0 146 } // extern "C"
nuclear@0 147
nuclear@0 148 float randf(float low, float high)
nuclear@0 149 {
nuclear@0 150 std::uniform_real_distribution<float> unirnd(low, high);
nuclear@0 151 return unirnd(rnd_gen);
nuclear@0 152 }
nuclear@0 153
nuclear@0 154 static void render_pixel(struct erebus *ctx, int x, int y)
nuclear@0 155 {
nuclear@0 156 float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4;
nuclear@0 157 pix[0] = pix[1] = pix[2] = 0.0f;
nuclear@0 158 pix[3] = 1.0f;
nuclear@0 159 }