clray

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