10 #define DFL_GAMMA 2.2f
11 #define DFL_OUTFILE "output.ppm"
13 static int save_image(const char *fname, float *pix, int xsz, int ysz);
14 static int parse_opt(int argc, char **argv);
16 static int width = DFL_WIDTH, height = DFL_HEIGHT;
17 static float inv_gamma = 1.0f / DFL_GAMMA;
18 static const char *out_fname = DFL_OUTFILE;
19 static const char *in_fname;
21 int main(int argc, char **argv)
23 csg_object *oa, *ob, *oc, *obj;
26 if(parse_opt(argc, argv) == -1) {
30 if(csg_init() == -1) {
34 if(csg_load(in_fname) == -1) {
38 if(!(pixels = malloc(width * height * 3 * sizeof *pixels))) {
39 perror("failed to allocate framebuffer");
44 csg_view(0, 0, 5, 0, 0, 0);
46 oa = csg_sphere(0, 0, 0, 1);
47 csg_color(oa, 1, 0.1, 0.05);
48 csg_roughness(oa, 0.3);
49 ob = csg_sphere(0.3, 0.7, 0.7, 0.7);
50 csg_color(ob, 0.2, 0.3, 1);
51 csg_roughness(ob, 0.3);
52 oc = csg_subtraction(oa, ob);
56 ob = csg_sphere(-0.9, -0.1, 0.7, 0.5);
57 csg_color(ob, 1, 0.9, 0.2);
58 csg_roughness(ob, 0.3);
60 oc = csg_subtraction(oa, ob);
64 obj = csg_plane(0, -1, 0, 0, 1, 0);
65 csg_color(obj, 0.4, 0.7, 0.4);
68 obj = csg_null(-4, 10, 10);
69 csg_emission(obj, 80, 80, 80);
73 csg_render_image(pixels, width, height);
74 save_image(out_fname, pixels, width, height);
80 static int save_image(const char *fname, float *pix, int xsz, int ysz)
85 if(!(fp = fopen(fname, "wb"))) {
86 fprintf(stderr, "failed to open %s for writing: %s\n", fname, strerror(errno));
90 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
92 for(i=0; i<xsz * ysz; i++) {
93 unsigned int r = pow(*pix++, inv_gamma) * 255.0f;
94 unsigned int g = pow(*pix++, inv_gamma) * 255.0f;
95 unsigned int b = pow(*pix++, inv_gamma) * 255.0f;
109 static void print_usage(const char *argv0)
111 printf("Usage: %s [options] <csg file>\n", argv0);
112 printf("Options:\n");
113 printf(" -s <WxH> output image resolution (default: %dx%d)\n", DFL_WIDTH, DFL_HEIGHT);
114 printf(" -g <gamma> set output gamma (default: %g)\n", DFL_GAMMA);
115 printf(" -o <file> output image file (default: %s)\n", DFL_OUTFILE);
116 printf(" -h print usage information and exit\n");
119 static int parse_opt(int argc, char **argv)
123 for(i=1; i<argc; i++) {
124 if(argv[i][0] == '-') {
125 if(argv[i][2] == 0) {
128 if(sscanf(argv[++i], "%dx%d", &width, &height) != 2) {
129 fprintf(stderr, "-s must be followed by WIDTHxHEIGHT\n");
135 if((inv_gamma = atof(argv[++i])) == 0.0f) {
136 fprintf(stderr, "-g must be followed by a non-zero gamma value\n");
139 inv_gamma = 1.0f / inv_gamma;
143 out_fname = argv[++i];
147 print_usage(argv[0]);
151 fprintf(stderr, "invalid option: %s\n", argv[i]);
155 fprintf(stderr, "invalid option: %s\n", argv[i]);
160 fprintf(stderr, "unexpected argument: %s\n", argv[i]);
168 fprintf(stderr, "you need to pass a scene file to read\n");