clray

annotate src/rt.cc @ 4:3c95d568d3c7

wow a ball
author John Tsiombikas <nuclear@member.fsf.org>
date Thu, 15 Jul 2010 07:37:05 +0300
parents 88ac4eb2d18a
children 9f0ddb701882
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@2 2 #include <math.h>
nuclear@0 3 #include <assert.h>
nuclear@0 4 #include "ocl.h"
nuclear@0 5
nuclear@2 6 struct RendInfo {
nuclear@2 7 int xsz, ysz;
nuclear@3 8 int num_sph, num_lights;
nuclear@2 9 int max_iter;
nuclear@2 10 } __attribute__((packed));
nuclear@2 11
nuclear@1 12 struct Sphere {
nuclear@1 13 cl_float4 pos;
nuclear@1 14 cl_float radius;
nuclear@1 15
nuclear@4 16 cl_float4 kd, ks;
nuclear@4 17 cl_float spow;
nuclear@4 18 cl_float kr, kt;
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@3 25 struct Light {
nuclear@3 26 cl_float4 pos, color;
nuclear@3 27 } __attribute__((packed));
nuclear@1 28
nuclear@2 29
nuclear@3 30 static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg);
nuclear@3 31
nuclear@3 32 static Ray *prim_rays;
nuclear@3 33 static CLProgram *prog;
nuclear@3 34 static int global_size;
nuclear@3 35
nuclear@4 36 static Sphere sphlist[] = {
nuclear@4 37 {{0, 0, 8, 1}, 1.0, {0.7, 0.2, 0.15, 1}, {1, 1, 1, 1}, 60, 0, 0},
nuclear@4 38 {{-0.2, 0.4, 5, 1}, 0.25, {0.2, 0.9, 0.3, 1}, {1, 1, 1, 1}, 40, 0, 0}
nuclear@4 39 };
nuclear@4 40
nuclear@4 41 static Light lightlist[] = {
nuclear@4 42 {{-10, 10, -20, 1}, {1, 1, 1, 1}}
nuclear@4 43 };
nuclear@4 44
nuclear@4 45 static RendInfo rinf;
nuclear@4 46
nuclear@4 47
nuclear@3 48 bool init_renderer(int xsz, int ysz, float *fb)
nuclear@0 49 {
nuclear@4 50 // render info
nuclear@4 51 rinf.xsz = xsz;
nuclear@4 52 rinf.ysz = ysz;
nuclear@4 53 rinf.num_sph = sizeof sphlist / sizeof *sphlist;
nuclear@4 54 rinf.num_lights = sizeof lightlist / sizeof *lightlist;
nuclear@4 55 rinf.max_iter = 6;
nuclear@4 56
nuclear@3 57 /* calculate primary rays */
nuclear@3 58 prim_rays = new Ray[xsz * ysz];
nuclear@2 59
nuclear@2 60 for(int i=0; i<ysz; i++) {
nuclear@2 61 for(int j=0; j<xsz; j++) {
nuclear@2 62 prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0);
nuclear@2 63 }
nuclear@0 64 }
nuclear@0 65
nuclear@2 66 /* setup opencl */
nuclear@3 67 prog = new CLProgram("render");
nuclear@3 68 if(!prog->load("rt.cl")) {
nuclear@0 69 return 1;
nuclear@0 70 }
nuclear@0 71
nuclear@3 72 /* setup argument buffers */
nuclear@3 73 prog->set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb);
nuclear@3 74 prog->set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf);
nuclear@3 75 prog->set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist);
nuclear@3 76 prog->set_arg_buffer(3, ARG_RD, sizeof lightlist, lightlist);
nuclear@3 77 prog->set_arg_buffer(4, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
nuclear@2 78
nuclear@3 79 global_size = xsz * ysz;
nuclear@3 80 return true;
nuclear@3 81 }
nuclear@3 82
nuclear@3 83 void destroy_renderer()
nuclear@3 84 {
nuclear@3 85 delete [] prim_rays;
nuclear@3 86 delete prog;
nuclear@3 87 }
nuclear@3 88
nuclear@3 89 bool render()
nuclear@3 90 {
nuclear@3 91 if(!prog->run(1, global_size)) {
nuclear@3 92 return false;
nuclear@0 93 }
nuclear@0 94
nuclear@3 95 CLMemBuffer *mbuf = prog->get_arg_buffer(0);
nuclear@0 96 map_mem_buffer(mbuf, MAP_RD);
nuclear@3 97 /*if(!write_ppm("out.ppm", fb, xsz, ysz)) {
nuclear@2 98 return 1;
nuclear@3 99 }*/
nuclear@2 100 unmap_mem_buffer(mbuf);
nuclear@3 101 return true;
nuclear@0 102 }
nuclear@2 103
nuclear@3 104 static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg)
nuclear@2 105 {
nuclear@2 106 float vfov = M_PI * vfov_deg / 180.0;
nuclear@2 107 float aspect = (float)w / (float)h;
nuclear@2 108
nuclear@2 109 float ysz = 2.0;
nuclear@2 110 float xsz = aspect * ysz;
nuclear@2 111
nuclear@2 112 float px = ((float)x / (float)w) * xsz - xsz / 2.0;
nuclear@2 113 float py = 1.0 - ((float)y / (float)h) * ysz;
nuclear@2 114 float pz = 1.0 / tan(0.5 * vfov);
nuclear@2 115
nuclear@4 116 px *= 100.0;
nuclear@4 117 py *= 100.0;
nuclear@4 118 pz *= 100.0;
nuclear@2 119
nuclear@2 120 Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}};
nuclear@2 121 return ray;
nuclear@2 122 }