44f490073f2802a7c10b1d3773826ec2f973692a
[csgray] / src / main.c
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <string.h>
4 #include <errno.h>
5 #include "csgray.h"
6
7 static int save_image(const char *fname, float *pix, int xsz, int ysz);
8 static int parse_opt(int argc, char **argv);
9
10 static int width = 800, height = 600;
11 static const char *out_fname = "output.ppm";
12
13 int main(int argc, char **argv)
14 {
15         csg_object *oa, *ob, *oc, *lt;
16         float *pixels;
17
18         if(parse_opt(argc, argv) == -1) {
19                 return 1;
20         }
21
22         if(csg_init() == -1) {
23                 return 1;
24         }
25
26         if(!(pixels = malloc(width * height * 3 * sizeof *pixels))) {
27                 perror("failed to allocate framebuffer");
28                 return 1;
29         }
30
31         csg_view(0, 0, 5, 0, 0, 0);
32
33         oa = csg_sphere(0, 0, 0, 1);
34         csg_color(oa, 1, 0, 0);
35         ob = csg_sphere(-0.3, 0.7, 0.7, 0.7);
36         csg_color(ob, 0, 0, 1);
37         oc = csg_union(oa, ob);
38         csg_add_object(oc);
39
40         lt = csg_null(-4, 10, 20);
41         csg_emission(lt, 1, 1, 1);
42         csg_add_object(lt);
43
44         csg_render_image(pixels, width, height);
45         save_image(out_fname, pixels, width, height);
46
47         csg_destroy();
48         return 0;
49 }
50
51 static int save_image(const char *fname, float *pix, int xsz, int ysz)
52 {
53         int i;
54         FILE *fp;
55
56         if(!(fp = fopen(fname, "wb"))) {
57                 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
58                 return -1;
59         }
60
61         fprintf(fp, "P6\n%d %d\n65535\n", xsz, ysz);
62
63         for(i=0; i<xsz * ysz; i++) {
64                 unsigned int r = *pix++ * 65535.0f;
65                 unsigned int g = *pix++ * 65535.0f;
66                 unsigned int b = *pix++ * 65535.0f;
67
68                 if(r > 0xffff) r = 0xffff;
69                 if(g > 0xffff) g = 0xffff;
70                 if(b > 0xffff) b = 0xffff;
71
72                 fputc(r >> 8, fp);
73                 fputc(r, fp);
74                 fputc(g >> 8, fp);
75                 fputc(g, fp);
76                 fputc(b >> 8, fp);
77                 fputc(b, fp);
78         }
79         fclose(fp);
80         return 0;
81 }
82
83 static void print_usage(const char *argv0)
84 {
85         printf("Usage: %s [options] <csg file>\n", argv0);
86         printf("Options:\n");
87         printf(" -s <WxH>  output image resolution\n");
88         printf(" -o <file> output image file\n");
89         printf(" -h        print usage information and exit\n");
90 }
91
92 static int parse_opt(int argc, char **argv)
93 {
94         int i;
95
96         for(i=1; i<argc; i++) {
97                 if(argv[i][0] == '-') {
98                         if(argv[i][2] == 0) {
99                                 switch(argv[i][1]) {
100                                 case 's':
101                                         if(sscanf(argv[++i], "%dx%d", &width, &height) != 2) {
102                                                 fprintf(stderr, "-s must be followed by WIDTHxHEIGHT\n");
103                                                 return -1;
104                                         }
105                                         break;
106
107                                 case 'o':
108                                         out_fname = argv[++i];
109                                         break;
110
111                                 case 'h':
112                                         print_usage(argv[0]);
113                                         exit(0);
114
115                                 default:
116                                         fprintf(stderr, "invalid option: %s\n", argv[i]);
117                                         return -1;
118                                 }
119                         } else {
120                                 fprintf(stderr, "invalid option: %s\n", argv[i]);
121                                 return -1;
122                         }
123                 } else {
124                         fprintf(stderr, "unexpected argument: %s\n", argv[i]);
125                         return -1;
126                 }
127         }
128         return 0;
129 }