clray

annotate src/rt.cc @ 8:deaf85acf6af

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