clray

diff 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
line diff
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/src/rt.cc	Tue Jul 13 03:38:29 2010 +0300
     1.3 @@ -0,0 +1,112 @@
     1.4 +#include <stdio.h>
     1.5 +#include <math.h>
     1.6 +#include <assert.h>
     1.7 +#include "ocl.h"
     1.8 +
     1.9 +struct RendInfo {
    1.10 +	int xsz, ysz;
    1.11 +	int num_sph, num_lights;
    1.12 +	int max_iter;
    1.13 +} __attribute__((packed));
    1.14 +
    1.15 +struct Sphere {
    1.16 +	cl_float4 pos;
    1.17 +	cl_float radius;
    1.18 +
    1.19 +	cl_float4 color;
    1.20 +} __attribute__((packed));
    1.21 +
    1.22 +struct Ray {
    1.23 +	cl_float4 origin, dir;
    1.24 +} __attribute__((packed));
    1.25 +
    1.26 +struct Light {
    1.27 +	cl_float4 pos, color;
    1.28 +} __attribute__((packed));
    1.29 +
    1.30 +
    1.31 +static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg);
    1.32 +
    1.33 +static Ray *prim_rays;
    1.34 +static CLProgram *prog;
    1.35 +static int global_size;
    1.36 +
    1.37 +bool init_renderer(int xsz, int ysz, float *fb)
    1.38 +{
    1.39 +	Sphere sphlist[] = {
    1.40 +		{{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}}
    1.41 +	};
    1.42 +	Light lightlist[] = {
    1.43 +		{{-10, 10, -20, 1}, {1, 1, 1, 1}}
    1.44 +	};
    1.45 +	RendInfo rinf = {
    1.46 +		xsz, ysz,
    1.47 +		sizeof sphlist / sizeof *sphlist,
    1.48 +		sizeof lightlist / sizeof *lightlist,
    1.49 +		6
    1.50 +	};
    1.51 +	
    1.52 +	/* calculate primary rays */
    1.53 +	prim_rays = new Ray[xsz * ysz];
    1.54 +
    1.55 +	for(int i=0; i<ysz; i++) {
    1.56 +		for(int j=0; j<xsz; j++) {
    1.57 +			prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0);
    1.58 +		}
    1.59 +	}
    1.60 +
    1.61 +	/* setup opencl */
    1.62 +	prog = new CLProgram("render");
    1.63 +	if(!prog->load("rt.cl")) {
    1.64 +		return 1;
    1.65 +	}
    1.66 +
    1.67 +	/* setup argument buffers */
    1.68 +	prog->set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb);
    1.69 +	prog->set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf);
    1.70 +	prog->set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist);
    1.71 +	prog->set_arg_buffer(3, ARG_RD, sizeof lightlist, lightlist);
    1.72 +	prog->set_arg_buffer(4, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
    1.73 +
    1.74 +	global_size = xsz * ysz;
    1.75 +	return true;
    1.76 +}
    1.77 +
    1.78 +void destroy_renderer()
    1.79 +{
    1.80 +	delete [] prim_rays;
    1.81 +	delete prog;
    1.82 +}
    1.83 +
    1.84 +bool render()
    1.85 +{
    1.86 +	if(!prog->run(1, global_size)) {
    1.87 +		return false;
    1.88 +	}
    1.89 +
    1.90 +	CLMemBuffer *mbuf = prog->get_arg_buffer(0);
    1.91 +	map_mem_buffer(mbuf, MAP_RD);
    1.92 +	/*if(!write_ppm("out.ppm", fb, xsz, ysz)) {
    1.93 +		return 1;
    1.94 +	}*/
    1.95 +	unmap_mem_buffer(mbuf);
    1.96 +	return true;
    1.97 +}
    1.98 +
    1.99 +static Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg)
   1.100 +{
   1.101 +	float vfov = M_PI * vfov_deg / 180.0;
   1.102 +	float aspect = (float)w / (float)h;
   1.103 +
   1.104 +	float ysz = 2.0;
   1.105 +	float xsz = aspect * ysz;
   1.106 +
   1.107 +	float px = ((float)x / (float)w) * xsz - xsz / 2.0;
   1.108 +	float py = 1.0 - ((float)y / (float)h) * ysz;
   1.109 +	float pz = 1.0 / tan(0.5 * vfov);
   1.110 +
   1.111 +	pz *= 1000.0;
   1.112 +
   1.113 +	Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}};
   1.114 +	return ray;
   1.115 +}