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 }
|