clray
diff src/clray.cc @ 2:41d6253492ad
pfffff
author | John Tsiombikas <nuclear@member.fsf.org> |
---|---|
date | Mon, 12 Jul 2010 10:38:07 +0300 |
parents | 0b0e4d18d53f |
children | 88ac4eb2d18a |
line diff
1.1 --- a/src/clray.cc Mon Jul 12 07:00:19 2010 +0300 1.2 +++ b/src/clray.cc Mon Jul 12 10:38:07 2010 +0300 1.3 @@ -1,7 +1,16 @@ 1.4 #include <stdio.h> 1.5 +#include <string.h> 1.6 +#include <math.h> 1.7 +#include <errno.h> 1.8 #include <assert.h> 1.9 #include "ocl.h" 1.10 1.11 +struct RendInfo { 1.12 + int xsz, ysz; 1.13 + int num_sph; 1.14 + int max_iter; 1.15 +} __attribute__((packed)); 1.16 + 1.17 struct Sphere { 1.18 cl_float4 pos; 1.19 cl_float radius; 1.20 @@ -14,43 +23,90 @@ 1.21 } __attribute__((packed)); 1.22 1.23 1.24 +Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg); 1.25 +bool write_ppm(const char *fname, float *fb, int xsz, int ysz); 1.26 + 1.27 int main() 1.28 { 1.29 - int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; 1.30 - int res[16]; 1.31 - int count = sizeof data / sizeof *data; 1.32 + const int xsz = 800; 1.33 + const int ysz = 600; 1.34 1.35 - for(int i=0; i<count; i++) { 1.36 - printf("%d ", data[i]); 1.37 + Sphere sphlist[] = { 1.38 + {{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}} 1.39 + }; 1.40 + RendInfo rinf = {xsz, ysz, sizeof sphlist / sizeof *sphlist, 6}; 1.41 + Ray *prim_rays = new Ray[xsz * ysz]; 1.42 + float *fb = new float[xsz * ysz * 4]; 1.43 + 1.44 + /* calculate primary rays */ 1.45 + for(int i=0; i<ysz; i++) { 1.46 + for(int j=0; j<xsz; j++) { 1.47 + prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0); 1.48 + } 1.49 } 1.50 - putchar('\n'); 1.51 1.52 - CLProgram prog("test"); 1.53 - if(!prog.load("test.cl")) { 1.54 - return 1; 1.55 - } 1.56 - if(!prog.set_arg_buffer(0, ARG_WR, sizeof res, res)) { 1.57 - return 1; 1.58 - } 1.59 - if(!prog.set_arg_buffer(1, ARG_RD, sizeof data, data)) { 1.60 - return 1; 1.61 - } 1.62 - if(!prog.set_argi(2, 100)) { 1.63 + /* setup opencl */ 1.64 + CLProgram prog("render"); 1.65 + if(!prog.load("rt.cl")) { 1.66 return 1; 1.67 } 1.68 1.69 - if(!prog.run(1, 16)) { 1.70 + prog.set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb); 1.71 + prog.set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf); 1.72 + prog.set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist); 1.73 + prog.set_arg_buffer(3, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays); 1.74 + 1.75 + if(!prog.run(1, xsz * ysz)) { 1.76 return 1; 1.77 } 1.78 1.79 - CLMemBuffer *mbuf = prog.get_arg_buffer(1); 1.80 + CLMemBuffer *mbuf = prog.get_arg_buffer(0); 1.81 map_mem_buffer(mbuf, MAP_RD); 1.82 + if(!write_ppm("out.ppm", fb, xsz, ysz)) { 1.83 + return 1; 1.84 + } 1.85 + unmap_mem_buffer(mbuf); 1.86 1.87 - for(int i=0; i<count; i++) { 1.88 - printf("%d ", res[i]); 1.89 - } 1.90 - putchar('\n'); 1.91 - unmap_mem_buffer(mbuf); 1.92 + delete [] fb; 1.93 + delete [] prim_rays; 1.94 1.95 return 0; 1.96 } 1.97 + 1.98 +Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg) 1.99 +{ 1.100 + float vfov = M_PI * vfov_deg / 180.0; 1.101 + float aspect = (float)w / (float)h; 1.102 + 1.103 + float ysz = 2.0; 1.104 + float xsz = aspect * ysz; 1.105 + 1.106 + float px = ((float)x / (float)w) * xsz - xsz / 2.0; 1.107 + float py = 1.0 - ((float)y / (float)h) * ysz; 1.108 + float pz = 1.0 / tan(0.5 * vfov); 1.109 + 1.110 + pz *= 1000.0; 1.111 + 1.112 + Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}}; 1.113 + return ray; 1.114 +} 1.115 + 1.116 +bool write_ppm(const char *fname, float *fb, int xsz, int ysz) 1.117 +{ 1.118 + FILE *fp; 1.119 + 1.120 + if(!(fp = fopen(fname, "wb"))) { 1.121 + fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno)); 1.122 + return false; 1.123 + } 1.124 + fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz); 1.125 + 1.126 + for(int i=0; i<xsz * ysz * 4; i++) { 1.127 + if(i % 4 == 3) continue; 1.128 + 1.129 + unsigned char c = (unsigned char)(fb[i] * 255.0); 1.130 + fputc(c, fp); 1.131 + } 1.132 + fclose(fp); 1.133 + return true; 1.134 +}