erebus

annotate liberebus/src/erebus.cc @ 4:93894c232d65

more changes across the board
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 29 Apr 2014 07:38:40 +0300
parents 474a0244f57d
children 9621beb22694
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@4 8 #include "scene.h"
nuclear@4 9 #include "geomobj.h"
nuclear@2 10
nuclear@2 11 using namespace std::chrono;
nuclear@2 12
nuclear@2 13 struct Rect {
nuclear@2 14 int x, y, width, height;
nuclear@2 15
nuclear@2 16 bool operator ==(const Rect &r) { return memcmp(this, &r, sizeof r) == 0; }
nuclear@2 17 bool operator !=(const Rect &r) { return memcmp(this, &r, sizeof r) != 0; }
nuclear@2 18 };
nuclear@2 19
nuclear@2 20 #define INVALID_RECT Rect{0, 0, 0, 0}
nuclear@2 21
nuclear@2 22 struct erebus {
nuclear@4 23 Scene *scn;
nuclear@4 24
nuclear@2 25 Image<float> fbimg;
nuclear@2 26 Vector4 options[ERB_NUM_OPTIONS];
nuclear@2 27
nuclear@2 28 // render state
nuclear@2 29 long cur_time;
nuclear@2 30 int cur_pixel_x, cur_pixel_y;
nuclear@2 31 Rect cur_rect;
nuclear@2 32 };
nuclear@2 33
nuclear@2 34 static void render_pixel(struct erebus *ctx, int x, int y);
nuclear@2 35
nuclear@2 36 static std::mt19937 rnd_gen;
nuclear@2 37
nuclear@2 38 extern "C" {
nuclear@2 39
nuclear@2 40 struct erebus *erb_init(void)
nuclear@2 41 {
nuclear@2 42 struct erebus *ctx;
nuclear@2 43 try {
nuclear@2 44 ctx = new struct erebus;
nuclear@2 45 }
nuclear@2 46 catch(...) {
nuclear@2 47 return 0;
nuclear@2 48 }
nuclear@2 49
nuclear@4 50 ctx->scn = 0;
nuclear@2 51 ctx->cur_time = 0;
nuclear@2 52 ctx->cur_rect = INVALID_RECT;
nuclear@2 53 return ctx;
nuclear@2 54 }
nuclear@2 55
nuclear@2 56 void erb_destroy(struct erebus *ctx)
nuclear@2 57 {
nuclear@2 58 delete ctx;
nuclear@2 59 }
nuclear@2 60
nuclear@2 61 void erb_setopti(struct erebus *ctx, enum erb_option opt, int val)
nuclear@2 62 {
nuclear@2 63 ctx->options[opt].x = val;
nuclear@2 64 }
nuclear@2 65 void erb_setoptf(struct erebus *ctx, enum erb_option opt, float val)
nuclear@2 66 {
nuclear@2 67 ctx->options[opt].x = val;
nuclear@2 68 }
nuclear@2 69 void erb_setoptfv(struct erebus *ctx, enum erb_option opt, float *vec)
nuclear@2 70 {
nuclear@2 71 for(int i=0; i<4; i++) {
nuclear@2 72 ctx->options[opt][i] = vec[i];
nuclear@2 73 }
nuclear@2 74 }
nuclear@2 75
nuclear@2 76 int erb_getopti(struct erebus *ctx, enum erb_option opt)
nuclear@2 77 {
nuclear@2 78 return ctx->options[opt].x;
nuclear@2 79 }
nuclear@2 80 float erb_getoptf(struct erebus *ctx, enum erb_option opt)
nuclear@2 81 {
nuclear@2 82 return ctx->options[opt].x;
nuclear@2 83 }
nuclear@2 84 float *erb_getoptfv(struct erebus *ctx, enum erb_option opt)
nuclear@2 85 {
nuclear@2 86 return &ctx->options[opt].x;
nuclear@2 87 }
nuclear@2 88
nuclear@2 89 float *erb_get_framebuffer(struct erebus *ctx)
nuclear@2 90 {
nuclear@2 91 return ctx->fbimg.get_pixels();
nuclear@2 92 }
nuclear@2 93
nuclear@2 94 void erb_begin_frame(struct erebus *ctx, long ms)
nuclear@2 95 {
nuclear@2 96 ctx->cur_time = ms;
nuclear@4 97
nuclear@4 98 int xsz = ctx->options[ERB_OPT_WIDTH].x;
nuclear@4 99 int ysz = ctx->options[ERB_OPT_HEIGHT].x;
nuclear@4 100
nuclear@4 101 ctx->fbimg.create(xsz, ysz);
nuclear@2 102 }
nuclear@2 103
nuclear@2 104 int erb_render(struct erebus *ctx, long timeout)
nuclear@2 105 {
nuclear@2 106 return erb_render_rect(ctx, 0, 0, ctx->fbimg.get_width(), ctx->fbimg.get_height(), timeout);
nuclear@2 107 }
nuclear@2 108
nuclear@2 109 int erb_render_rect(struct erebus *ctx, int x, int y, int width, int height, long timeout)
nuclear@2 110 {
nuclear@2 111 if(!width || !height) return -1;
nuclear@2 112
nuclear@2 113 Rect rect{x, y, width, height};
nuclear@2 114 if(ctx->cur_rect != rect) {
nuclear@2 115 ctx->cur_rect = rect;
nuclear@2 116 ctx->cur_pixel_x = x;
nuclear@2 117 ctx->cur_pixel_y = y;
nuclear@2 118 }
nuclear@2 119
nuclear@4 120 ctx->scn->update();
nuclear@4 121
nuclear@2 122 if(timeout > 0) {
nuclear@2 123 auto start_time = steady_clock::now();
nuclear@2 124 while(duration_cast<milliseconds>(steady_clock::now() - start_time).count() < timeout) {
nuclear@2 125 render_pixel(ctx, ctx->cur_pixel_x, ctx->cur_pixel_y);
nuclear@2 126
nuclear@2 127 if(++ctx->cur_pixel_x >= ctx->cur_rect.width) {
nuclear@2 128 if(++ctx->cur_pixel_y >= ctx->cur_rect.height) {
nuclear@2 129 ctx->cur_rect = INVALID_RECT;
nuclear@2 130 return 0;
nuclear@2 131 }
nuclear@2 132 }
nuclear@2 133 }
nuclear@2 134 return 1;
nuclear@2 135 }
nuclear@2 136
nuclear@2 137 for(int i=0; i<height; i++) {
nuclear@2 138 for(int j=0; j<width; j++) {
nuclear@2 139 render_pixel(ctx, j, i);
nuclear@2 140 }
nuclear@2 141 }
nuclear@2 142 return 0;
nuclear@2 143 }
nuclear@2 144
nuclear@2 145 int erb_get_progress(struct erebus *ctx)
nuclear@2 146 {
nuclear@2 147 return 0; // TODO
nuclear@2 148 }
nuclear@2 149
nuclear@2 150 int erb_load_scene(struct erebus *ctx, const char *fname)
nuclear@2 151 {
nuclear@4 152 delete ctx->scn;
nuclear@4 153 ctx->scn = new Scene;
nuclear@2 154
nuclear@4 155 // XXX for now just create a test scene here
nuclear@4 156 Sphere *sph = new Sphere;
nuclear@4 157 SceneNode *sph_node = new SceneNode(sph);
nuclear@4 158 ctx->scn->add_object(sph);
nuclear@4 159 ctx->scn->add_node(sph_node);
nuclear@4 160
nuclear@4 161 TargetCamera *cam = new TargetCamera(Vector3(0, 0, -10), Vector3(0, 0, 0));
nuclear@4 162 //ctx->scn->add_object(cam);
nuclear@4 163 ctx->scn->use_camera(cam);
nuclear@4 164
nuclear@4 165 return 0;
nuclear@2 166 }
nuclear@2 167
nuclear@2 168 } // extern "C"
nuclear@2 169
nuclear@2 170 float randf(float low, float high)
nuclear@2 171 {
nuclear@2 172 std::uniform_real_distribution<float> unirnd(low, high);
nuclear@2 173 return unirnd(rnd_gen);
nuclear@2 174 }
nuclear@2 175
nuclear@2 176 static void render_pixel(struct erebus *ctx, int x, int y)
nuclear@2 177 {
nuclear@2 178 float *pix = ctx->fbimg.get_pixels() + (y * ctx->fbimg.get_width() + x) * 4;
nuclear@2 179 pix[0] = pix[1] = pix[2] = 0.0f;
nuclear@2 180 pix[3] = 1.0f;
nuclear@2 181 }