clray

annotate src/rt.cc @ 9:a09622aaa043

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