clray

annotate src/rt.cc @ 11:d9a1bab1c3f5

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