From 7abe0c51fc87e90674427c5ac5848f394af4575a Mon Sep 17 00:00:00 2001 From: John Tsiombikas Date: Tue, 27 Mar 2018 19:47:08 +0300 Subject: [PATCH] working hack. now do it properly with intervals --- RUN | 2 +- src/csgray.c | 17 ++++++++-------- src/geom.c | 53 +++++++++++++++++++++++++++++++++++++++++------- src/main.c | 63 +++++++++++++++++++++++++++++++++++++--------------------- 4 files changed, 96 insertions(+), 39 deletions(-) diff --git a/RUN b/RUN index 728ad5c..7cf8029 100755 --- a/RUN +++ b/RUN @@ -1,4 +1,4 @@ #!/bin/sh rm -f output.ppm -./csgray && display output.ppm +./csgray $* && display output.ppm diff --git a/src/csgray.c b/src/csgray.c index 53b0146..fe0228a 100644 --- a/src/csgray.c +++ b/src/csgray.c @@ -23,7 +23,7 @@ int csg_init(void) oblist = 0; plights = 0; - csg_ambient(0.05, 0.05, 0.05); + csg_ambient(0, 0, 0); csg_view(0, 0, 5, 0, 0, 0); csg_fov(50); @@ -198,7 +198,7 @@ csg_object *csg_plane(float x, float y, float z, float nx, float ny, float nz) o->plane.ny = ny; o->plane.nz = nz; o->plane.d = x * nx + y * ny + z * nz; - return 0; + return o; } csg_object *csg_box(float x, float y, float z, float xsz, float ysz, float zsz) @@ -326,7 +326,7 @@ static int ray_trace(struct ray *ray, float *col) static void shade(float *col, struct ray *ray, struct hit *hit) { - float ndotl, len; + float ndotl, len, falloff; csg_object *o, *lt = plights; float dcol[3], scol[3] = {0}; float ldir[3]; @@ -350,24 +350,25 @@ static void shade(float *col, struct ray *ray, struct hit *hit) sray.dy = ldir[1]; sray.dz = ldir[2]; - if(!find_intersection(&sray, &tmphit) || tmphit.t < 1.0f) { + if(1) {//!find_intersection(&sray, &tmphit) || tmphit.t > 1.0f) { if((len = sqrt(ldir[0] * ldir[0] + ldir[1] * ldir[1] + ldir[2] * ldir[2])) != 0.0f) { float s = 1.0f / len; ldir[0] *= s; ldir[1] *= s; ldir[2] *= s; } + falloff = 1.0f / (len * len); if((ndotl = hit->nx * ldir[0] + hit->ny * ldir[1] + hit->nz * ldir[2]) < 0.0f) { ndotl = 0.0f; } - dcol[0] += o->ob.r * lt->ob.emr * ndotl; - dcol[1] += o->ob.g * lt->ob.emg * ndotl; - dcol[2] += o->ob.b * lt->ob.emb * ndotl; + dcol[0] += o->ob.r * lt->ob.emr * ndotl * falloff; + dcol[1] += o->ob.g * lt->ob.emg * ndotl * falloff; + dcol[2] += o->ob.b * lt->ob.emb * ndotl * falloff; } - lt = lt->ob.next; + lt = lt->ob.plt_next; } col[0] = dcol[0] + scol[0]; diff --git a/src/geom.c b/src/geom.c index dba62ed..1961aed 100644 --- a/src/geom.c +++ b/src/geom.c @@ -101,9 +101,6 @@ struct hit *ray_sphere(struct ray *ray, csg_object *o) t[1] = tmp; } - if(t[0] < EPSILON) t[0] = EPSILON; - if(t[1] < EPSILON) t[1] = EPSILON; - hitlist = hit = alloc_hits(2); for(i=0; i<2; i++) { float c[3] = {0, 0, 0}; @@ -139,15 +136,16 @@ struct hit *ray_plane(struct ray *ray, csg_object *o) xform_ray(&locray, o->ob.inv_xform); + ndotr = o->plane.nx * locray.dx + o->plane.ny * locray.dy + o->plane.nz * locray.dz; + if(fabs(ndotr) < EPSILON) return 0; + vx = o->plane.nx * o->plane.d - locray.x; vy = o->plane.ny * o->plane.d - locray.y; vz = o->plane.nz * o->plane.d - locray.z; ndotv = o->plane.nx * vx + o->plane.ny * vy + o->plane.nz * vz; - if(fabs(ndotv) < EPSILON) return 0; - ndotr = o->plane.nx * locray.dx + o->plane.ny * locray.dy + o->plane.nz * locray.dz; - t = ndotr / ndotv; + t = ndotv / ndotr; if(t > EPSILON) { hit = alloc_hits(1); @@ -186,9 +184,50 @@ struct hit *ray_csg_isect(struct ray *ray, csg_object *o) return 0; } +static struct hit *first(struct hit *hlist) +{ + return hlist; +} + +static struct hit *last(struct hit *hlist) +{ + while(hlist->next) { + hlist = hlist->next; + } + return hlist; +} + struct hit *ray_csg_sub(struct ray *ray, csg_object *o) { - return 0; + struct hit *hita, *hitb, *lasthit, tmp; + + hita = ray_intersect(ray, o->sub.a); + hitb = ray_intersect(ray, o->sub.b); + + if(!hita) return 0; + if(!hitb) return hita; + + if(first(hita)->t < first(hitb)->t) { + free_hit_list(hitb); + return hita; + } + if(first(hita)->t < (lasthit = last(hitb))->t) { + /* overlapping */ + tmp = *hitb; + *hitb = *lasthit; + + free_hit_list(tmp.next); + + hitb->nx = -hitb->nx; + hitb->ny = -hitb->ny; + hitb->nz = -hitb->nz; + + free_hit_list(hita); + return hitb; + } + + free_hit_list(hitb); + return hita; } diff --git a/src/main.c b/src/main.c index 44f4900..d6aac1c 100644 --- a/src/main.c +++ b/src/main.c @@ -1,18 +1,25 @@ #include #include #include +#include #include #include "csgray.h" +#define DFL_WIDTH 800 +#define DFL_HEIGHT 600 +#define DFL_GAMMA 2.2f +#define DFL_OUTFILE "output.ppm" + static int save_image(const char *fname, float *pix, int xsz, int ysz); static int parse_opt(int argc, char **argv); -static int width = 800, height = 600; -static const char *out_fname = "output.ppm"; +static int width = DFL_WIDTH, height = DFL_HEIGHT; +static float inv_gamma = 1.0f / DFL_GAMMA; +static const char *out_fname = DFL_OUTFILE; int main(int argc, char **argv) { - csg_object *oa, *ob, *oc, *lt; + csg_object *oa, *ob, *oc, *obj; float *pixels; if(parse_opt(argc, argv) == -1) { @@ -31,15 +38,19 @@ int main(int argc, char **argv) csg_view(0, 0, 5, 0, 0, 0); oa = csg_sphere(0, 0, 0, 1); - csg_color(oa, 1, 0, 0); - ob = csg_sphere(-0.3, 0.7, 0.7, 0.7); - csg_color(ob, 0, 0, 1); - oc = csg_union(oa, ob); + csg_color(oa, 1, 0.1, 0.05); + ob = csg_sphere(0.3, 0.7, 0.7, 0.7); + csg_color(ob, 0.2, 0.3, 1); + oc = csg_subtraction(oa, ob); csg_add_object(oc); - lt = csg_null(-4, 10, 20); - csg_emission(lt, 1, 1, 1); - csg_add_object(lt); + obj = csg_plane(0, -1, 0, 0, 1, 0); + csg_color(obj, 0.4, 0.7, 0.4); + csg_add_object(obj); + + obj = csg_null(-6, 10, 10); + csg_emission(obj, 80, 80, 80); + csg_add_object(obj); csg_render_image(pixels, width, height); save_image(out_fname, pixels, width, height); @@ -58,22 +69,19 @@ static int save_image(const char *fname, float *pix, int xsz, int ysz) return -1; } - fprintf(fp, "P6\n%d %d\n65535\n", xsz, ysz); + fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz); for(i=0; i 0xffff) r = 0xffff; - if(g > 0xffff) g = 0xffff; - if(b > 0xffff) b = 0xffff; + if(r > 255) r = 255; + if(g > 255) g = 255; + if(b > 255) b = 255; - fputc(r >> 8, fp); fputc(r, fp); - fputc(g >> 8, fp); fputc(g, fp); - fputc(b >> 8, fp); fputc(b, fp); } fclose(fp); @@ -84,9 +92,10 @@ static void print_usage(const char *argv0) { printf("Usage: %s [options] \n", argv0); printf("Options:\n"); - printf(" -s output image resolution\n"); - printf(" -o output image file\n"); - printf(" -h print usage information and exit\n"); + printf(" -s output image resolution (default: %dx%d)\n", DFL_WIDTH, DFL_HEIGHT); + printf(" -g set output gamma (default: %g)\n", DFL_GAMMA); + printf(" -o output image file (default: %s)\n", DFL_OUTFILE); + printf(" -h print usage information and exit\n"); } static int parse_opt(int argc, char **argv) @@ -104,6 +113,14 @@ static int parse_opt(int argc, char **argv) } break; + case 'g': + if((inv_gamma = atof(argv[++i])) == 0.0f) { + fprintf(stderr, "-g must be followed by a non-zero gamma value\n"); + return -1; + } + inv_gamma = 1.0f / inv_gamma; + break; + case 'o': out_fname = argv[++i]; break; -- 1.7.10.4