# HG changeset patch # User John Tsiombikas # Date 1278920287 -10800 # Node ID 41d6253492ad6e027cc8ad573ca788bccbcadddd # Parent 0b0e4d18d53f6318cd681b1d11bbc93dc8369e29 pfffff diff -r 0b0e4d18d53f -r 41d6253492ad rt.cl --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/rt.cl Mon Jul 12 10:38:07 2010 +0300 @@ -0,0 +1,77 @@ +struct RendInfo { + int xsz, ysz; + int num_sph; + int max_iter; +}; + +struct Sphere { + float4 pos; + float radius; + float4 color; +}; + +struct Ray { + float4 origin, dir; +}; + +struct SurfPoint { + float t; + float3 pos, norm; +}; + +#define EPSILON 1e-6 + +bool intersect(struct Ray ray, __global const struct Sphere *sph, struct SurfPoint *sp); + +__kernel void render(__global float4 *fb, + __global const struct RendInfo *rinf, + __global const struct Sphere *sphlist, + __global const struct Ray *primrays) +{ + int idx = get_global_id(0); + + struct Ray ray = primrays[idx]; + struct SurfPoint sp; + + if(intersect(ray, sphlist, &sp)) { + fb[idx] = (float4)(1, 0, 0, 1); + } else { + fb[idx] = (float4)(0, 0, 0, 1); + } +} + +bool intersect(struct Ray ray, + __global const struct Sphere *sph, + struct SurfPoint *sp) +{ + float3 dir = ray.dir.xyz; + float3 orig = ray.origin.xyz; + float3 spos = sph->pos.xyz; + + float a = dot(dir, dir); + float b = 2.0 * dir.x * (orig.x - spos.x) + + 2.0 * dir.y * (orig.y - spos.y) + + 2.0 * dir.z * (orig.z - spos.z); + float c = dot(spos, spos) + dot(orig, orig) + + 2.0 * dot(-spos, orig) - sph->radius * sph->radius; + + float d = b * b - 4.0 * a * c; + if(d < 0.0) return false; + + float sqrt_d = sqrt(d); + float t1 = (-b + sqrt_d) / (2.0 * a); + float t2 = (-b - sqrt_d) / (2.0 * a); + + if(t1 < EPSILON) t1 = t2; + if(t2 < EPSILON) t2 = t1; + float t = t1 < t2 ? t1 : t2; + + if(t < EPSILON || t > 1.0) { + return false; + } + + sp->t = t; + sp->pos = orig + dir * sp->t; + sp->norm = (sp->pos - spos) / sph->radius; + return true; +} diff -r 0b0e4d18d53f -r 41d6253492ad src/clray.cc --- a/src/clray.cc Mon Jul 12 07:00:19 2010 +0300 +++ b/src/clray.cc Mon Jul 12 10:38:07 2010 +0300 @@ -1,7 +1,16 @@ #include +#include +#include +#include #include #include "ocl.h" +struct RendInfo { + int xsz, ysz; + int num_sph; + int max_iter; +} __attribute__((packed)); + struct Sphere { cl_float4 pos; cl_float radius; @@ -14,43 +23,90 @@ } __attribute__((packed)); +Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg); +bool write_ppm(const char *fname, float *fb, int xsz, int ysz); + int main() { - int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}; - int res[16]; - int count = sizeof data / sizeof *data; + const int xsz = 800; + const int ysz = 600; - for(int i=0; i