clray

annotate src/rt.cc @ 3:88ac4eb2d18a

added OpenGL display of the framebuffer
author John Tsiombikas <nuclear@member.fsf.org>
date Tue, 13 Jul 2010 03:38:29 +0300
parents src/clray.cc@41d6253492ad
children 3c95d568d3c7
rev   line source
nuclear@0 1 #include <stdio.h>
nuclear@2 2 #include <math.h>
nuclear@0 3 #include <assert.h>
nuclear@0 4 #include "ocl.h"
nuclear@0 5
nuclear@2 6 struct RendInfo {
nuclear@2 7 int xsz, ysz;
nuclear@3 8 int num_sph, num_lights;
nuclear@2 9 int max_iter;
nuclear@2 10 } __attribute__((packed));
nuclear@2 11
nuclear@1 12 struct Sphere {
nuclear@1 13 cl_float4 pos;
nuclear@1 14 cl_float radius;
nuclear@1 15
nuclear@1 16 cl_float4 color;
nuclear@1 17 } __attribute__((packed));
nuclear@1 18
nuclear@1 19 struct Ray {
nuclear@1 20 cl_float4 origin, dir;
nuclear@1 21 } __attribute__((packed));
nuclear@1 22
nuclear@3 23 struct Light {
nuclear@3 24 cl_float4 pos, color;
nuclear@3 25 } __attribute__((packed));
nuclear@1 26
nuclear@2 27
nuclear@3 28 static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg);
nuclear@3 29
nuclear@3 30 static Ray *prim_rays;
nuclear@3 31 static CLProgram *prog;
nuclear@3 32 static int global_size;
nuclear@3 33
nuclear@3 34 bool init_renderer(int xsz, int ysz, float *fb)
nuclear@0 35 {
nuclear@2 36 Sphere sphlist[] = {
nuclear@2 37 {{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}}
nuclear@2 38 };
nuclear@3 39 Light lightlist[] = {
nuclear@3 40 {{-10, 10, -20, 1}, {1, 1, 1, 1}}
nuclear@3 41 };
nuclear@3 42 RendInfo rinf = {
nuclear@3 43 xsz, ysz,
nuclear@3 44 sizeof sphlist / sizeof *sphlist,
nuclear@3 45 sizeof lightlist / sizeof *lightlist,
nuclear@3 46 6
nuclear@3 47 };
nuclear@3 48
nuclear@3 49 /* calculate primary rays */
nuclear@3 50 prim_rays = new Ray[xsz * ysz];
nuclear@2 51
nuclear@2 52 for(int i=0; i<ysz; i++) {
nuclear@2 53 for(int j=0; j<xsz; j++) {
nuclear@2 54 prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0);
nuclear@2 55 }
nuclear@0 56 }
nuclear@0 57
nuclear@2 58 /* setup opencl */
nuclear@3 59 prog = new CLProgram("render");
nuclear@3 60 if(!prog->load("rt.cl")) {
nuclear@0 61 return 1;
nuclear@0 62 }
nuclear@0 63
nuclear@3 64 /* setup argument buffers */
nuclear@3 65 prog->set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb);
nuclear@3 66 prog->set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf);
nuclear@3 67 prog->set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist);
nuclear@3 68 prog->set_arg_buffer(3, ARG_RD, sizeof lightlist, lightlist);
nuclear@3 69 prog->set_arg_buffer(4, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
nuclear@2 70
nuclear@3 71 global_size = xsz * ysz;
nuclear@3 72 return true;
nuclear@3 73 }
nuclear@3 74
nuclear@3 75 void destroy_renderer()
nuclear@3 76 {
nuclear@3 77 delete [] prim_rays;
nuclear@3 78 delete prog;
nuclear@3 79 }
nuclear@3 80
nuclear@3 81 bool render()
nuclear@3 82 {
nuclear@3 83 if(!prog->run(1, global_size)) {
nuclear@3 84 return false;
nuclear@0 85 }
nuclear@0 86
nuclear@3 87 CLMemBuffer *mbuf = prog->get_arg_buffer(0);
nuclear@0 88 map_mem_buffer(mbuf, MAP_RD);
nuclear@3 89 /*if(!write_ppm("out.ppm", fb, xsz, ysz)) {
nuclear@2 90 return 1;
nuclear@3 91 }*/
nuclear@2 92 unmap_mem_buffer(mbuf);
nuclear@3 93 return true;
nuclear@0 94 }
nuclear@2 95
nuclear@3 96 static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg)
nuclear@2 97 {
nuclear@2 98 float vfov = M_PI * vfov_deg / 180.0;
nuclear@2 99 float aspect = (float)w / (float)h;
nuclear@2 100
nuclear@2 101 float ysz = 2.0;
nuclear@2 102 float xsz = aspect * ysz;
nuclear@2 103
nuclear@2 104 float px = ((float)x / (float)w) * xsz - xsz / 2.0;
nuclear@2 105 float py = 1.0 - ((float)y / (float)h) * ysz;
nuclear@2 106 float pz = 1.0 / tan(0.5 * vfov);
nuclear@2 107
nuclear@2 108 pz *= 1000.0;
nuclear@2 109
nuclear@2 110 Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}};
nuclear@2 111 return ray;
nuclear@2 112 }