erebus

annotate liberebus/src/erebus.cc @ 3:a932848de652

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