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