clray

view 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 source
1 #include <stdio.h>
2 #include <string.h>
3 #include <math.h>
4 #include <errno.h>
5 #include <assert.h>
6 #include "ocl.h"
8 struct RendInfo {
9 int xsz, ysz;
10 int num_sph;
11 int max_iter;
12 } __attribute__((packed));
14 struct Sphere {
15 cl_float4 pos;
16 cl_float radius;
18 cl_float4 color;
19 } __attribute__((packed));
21 struct Ray {
22 cl_float4 origin, dir;
23 } __attribute__((packed));
26 Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg);
27 bool write_ppm(const char *fname, float *fb, int xsz, int ysz);
29 int main()
30 {
31 const int xsz = 800;
32 const int ysz = 600;
34 Sphere sphlist[] = {
35 {{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}}
36 };
37 RendInfo rinf = {xsz, ysz, sizeof sphlist / sizeof *sphlist, 6};
38 Ray *prim_rays = new Ray[xsz * ysz];
39 float *fb = new float[xsz * ysz * 4];
41 /* calculate primary rays */
42 for(int i=0; i<ysz; i++) {
43 for(int j=0; j<xsz; j++) {
44 prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0);
45 }
46 }
48 /* setup opencl */
49 CLProgram prog("render");
50 if(!prog.load("rt.cl")) {
51 return 1;
52 }
54 prog.set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb);
55 prog.set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf);
56 prog.set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist);
57 prog.set_arg_buffer(3, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
59 if(!prog.run(1, xsz * ysz)) {
60 return 1;
61 }
63 CLMemBuffer *mbuf = prog.get_arg_buffer(0);
64 map_mem_buffer(mbuf, MAP_RD);
65 if(!write_ppm("out.ppm", fb, xsz, ysz)) {
66 return 1;
67 }
68 unmap_mem_buffer(mbuf);
70 delete [] fb;
71 delete [] prim_rays;
73 return 0;
74 }
76 Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg)
77 {
78 float vfov = M_PI * vfov_deg / 180.0;
79 float aspect = (float)w / (float)h;
81 float ysz = 2.0;
82 float xsz = aspect * ysz;
84 float px = ((float)x / (float)w) * xsz - xsz / 2.0;
85 float py = 1.0 - ((float)y / (float)h) * ysz;
86 float pz = 1.0 / tan(0.5 * vfov);
88 pz *= 1000.0;
90 Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}};
91 return ray;
92 }
94 bool write_ppm(const char *fname, float *fb, int xsz, int ysz)
95 {
96 FILE *fp;
98 if(!(fp = fopen(fname, "wb"))) {
99 fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno));
100 return false;
101 }
102 fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
104 for(int i=0; i<xsz * ysz * 4; i++) {
105 if(i % 4 == 3) continue;
107 unsigned char c = (unsigned char)(fb[i] * 255.0);
108 fputc(c, fp);
109 }
110 fclose(fp);
111 return true;
112 }