af2b2d9df078d2298a35e693a6e5f8521b6a53ad
[erebus2020] / liberebus / src / erebus.c
1 #include <stdio.h>
2 #include "erebus.h"
3
4 struct erb_rend {
5         int fb_width, fb_height, fb_npix;
6         float *fb_pixels;
7         int *fb_nsamples;
8 };
9
10 struct erb_rend *erb_create(void)
11 {
12         struct erb_rend *erb;
13
14         if(!(erb = calloc(1, sizeof *erb))) {
15                 return 0;
16         }
17         return erb;
18 }
19
20 void erb_destroy(struct erb_rend *erb)
21 {
22         if(!erb) return;
23         free(erb->fb_pixels);
24         free(erb);
25 }
26
27 int erb_allocframe(struct erb_rend *erb, int width, int height)
28 {
29         float *newfb;
30         int *newns;
31         int npix;
32
33         if(width == erb->fb_width && height == erb->fb_height) {
34                 return 0;
35         }
36
37         npix = width * height;
38
39         if(!(newfb = malloc(npix * 3 * sizeof *erb->fb_pixels))) {
40                 goto err;
41         }
42         if(!(newns = malloc(npix * sizeof *erb->fb_nsamples))) {
43                 free(newfb);
44                 goto err;
45         }
46
47         free(erb->fb_pixels);
48         free(erb->fb_nsamples);
49
50         erb->fb_pixels = newfb;
51         erb->fb_nsamples = newns;
52         erb->fb_width = width;
53         erb->fb_height = height;
54         erb->fb_npix = npix;
55         return 0;
56
57 err:
58         fprintf(stderr, "erb_allocframe: failed to allocate %dx%d framebuffer\n", width, height);
59         return -1;
60 }
61
62 float *erb_getframe(struct erb_rend *erb)
63 {
64         return erb->fb_pixels;
65 }
66
67 void erb_begin(struct erb_rend *erb)
68 {
69         memset(erb->fb_pixels, 0, erb->fb_npix * 3 * sizeof *erb->fb_pixels);
70         memset(erb->fb_nsamples, 0, erb->fb_npix * sizeof *erb->fb_nsamples);
71 }
72
73 float *erb_end(struct erb_rend *erb)
74 {
75         int i, n;
76         float s;
77         float *pptr = erb->fb_pixels;
78         int *nptr = erb->fb_nsamples;
79
80         for(i=0; i<erb->fb_npix; i++) {
81                 n = *nptr;
82                 if(n > 1) {
83                         s = 1.0f / n;
84                         *pptr++ *= s;
85                         *pptr++ *= s;
86                         *pptr++ *= s;
87                         *nptr++ = 1;
88                 } else {
89                         pptr += 3;
90                         nptr++;
91                 }
92         }
93
94         return erb->fb_pixels;
95 }