clray

diff src/clray.cc @ 2:41d6253492ad

pfffff
author John Tsiombikas <nuclear@member.fsf.org>
date Mon, 12 Jul 2010 10:38:07 +0300
parents 0b0e4d18d53f
children 88ac4eb2d18a
line diff
     1.1 --- a/src/clray.cc	Mon Jul 12 07:00:19 2010 +0300
     1.2 +++ b/src/clray.cc	Mon Jul 12 10:38:07 2010 +0300
     1.3 @@ -1,7 +1,16 @@
     1.4  #include <stdio.h>
     1.5 +#include <string.h>
     1.6 +#include <math.h>
     1.7 +#include <errno.h>
     1.8  #include <assert.h>
     1.9  #include "ocl.h"
    1.10  
    1.11 +struct RendInfo {
    1.12 +	int xsz, ysz;
    1.13 +	int num_sph;
    1.14 +	int max_iter;
    1.15 +} __attribute__((packed));
    1.16 +
    1.17  struct Sphere {
    1.18  	cl_float4 pos;
    1.19  	cl_float radius;
    1.20 @@ -14,43 +23,90 @@
    1.21  } __attribute__((packed));
    1.22  
    1.23  
    1.24 +Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg);
    1.25 +bool write_ppm(const char *fname, float *fb, int xsz, int ysz);
    1.26 +
    1.27  int main()
    1.28  {
    1.29 -	int data[] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16};
    1.30 -	int res[16];
    1.31 -	int count = sizeof data / sizeof *data;
    1.32 +	const int xsz = 800;
    1.33 +	const int ysz = 600;
    1.34  
    1.35 -	for(int i=0; i<count; i++) {
    1.36 -		printf("%d ", data[i]);
    1.37 +	Sphere sphlist[] = {
    1.38 +		{{0, 0, 10, 1}, 1.0, {1, 0, 0, 1}}
    1.39 +	};
    1.40 +	RendInfo rinf = {xsz, ysz, sizeof sphlist / sizeof *sphlist, 6};
    1.41 +	Ray *prim_rays = new Ray[xsz * ysz];
    1.42 +	float *fb = new float[xsz * ysz * 4];
    1.43 +
    1.44 +	/* calculate primary rays */
    1.45 +	for(int i=0; i<ysz; i++) {
    1.46 +		for(int j=0; j<xsz; j++) {
    1.47 +			prim_rays[i * xsz + j] = get_primary_ray(j, i, xsz, ysz, 45.0);
    1.48 +		}
    1.49  	}
    1.50 -	putchar('\n');
    1.51  
    1.52 -	CLProgram prog("test");
    1.53 -	if(!prog.load("test.cl")) {
    1.54 -		return 1;
    1.55 -	}
    1.56 -	if(!prog.set_arg_buffer(0, ARG_WR, sizeof res, res)) {
    1.57 -		return 1;
    1.58 -	}
    1.59 -	if(!prog.set_arg_buffer(1, ARG_RD, sizeof data, data)) {
    1.60 -		return 1;
    1.61 -	}
    1.62 -	if(!prog.set_argi(2, 100)) {
    1.63 +	/* setup opencl */
    1.64 +	CLProgram prog("render");
    1.65 +	if(!prog.load("rt.cl")) {
    1.66  		return 1;
    1.67  	}
    1.68  
    1.69 -	if(!prog.run(1, 16)) {
    1.70 +	prog.set_arg_buffer(0, ARG_WR, xsz * ysz * 4 * sizeof(float), fb);
    1.71 +	prog.set_arg_buffer(1, ARG_RD, sizeof rinf, &rinf);
    1.72 +	prog.set_arg_buffer(2, ARG_RD, sizeof sphlist, sphlist);
    1.73 +	prog.set_arg_buffer(3, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
    1.74 +
    1.75 +	if(!prog.run(1, xsz * ysz)) {
    1.76  		return 1;
    1.77  	}
    1.78  
    1.79 -	CLMemBuffer *mbuf = prog.get_arg_buffer(1);
    1.80 +	CLMemBuffer *mbuf = prog.get_arg_buffer(0);
    1.81  	map_mem_buffer(mbuf, MAP_RD);
    1.82 +	if(!write_ppm("out.ppm", fb, xsz, ysz)) {
    1.83 +		return 1;
    1.84 +	}
    1.85 +	unmap_mem_buffer(mbuf);
    1.86  
    1.87 -	for(int i=0; i<count; i++) {
    1.88 -		printf("%d ", res[i]);
    1.89 -	}
    1.90 -	putchar('\n');
    1.91 -	unmap_mem_buffer(mbuf);
    1.92 +	delete [] fb;
    1.93 +	delete [] prim_rays;
    1.94  
    1.95  	return 0;
    1.96  }
    1.97 +
    1.98 +Ray get_primary_ray(int x, int y, int w, int h, float vfov_deg)
    1.99 +{
   1.100 +	float vfov = M_PI * vfov_deg / 180.0;
   1.101 +	float aspect = (float)w / (float)h;
   1.102 +
   1.103 +	float ysz = 2.0;
   1.104 +	float xsz = aspect * ysz;
   1.105 +
   1.106 +	float px = ((float)x / (float)w) * xsz - xsz / 2.0;
   1.107 +	float py = 1.0 - ((float)y / (float)h) * ysz;
   1.108 +	float pz = 1.0 / tan(0.5 * vfov);
   1.109 +
   1.110 +	pz *= 1000.0;
   1.111 +
   1.112 +	Ray ray = {{0, 0, 0, 1}, {px, py, pz, 1}};
   1.113 +	return ray;
   1.114 +}
   1.115 +
   1.116 +bool write_ppm(const char *fname, float *fb, int xsz, int ysz)
   1.117 +{
   1.118 +	FILE *fp;
   1.119 +
   1.120 +	if(!(fp = fopen(fname, "wb"))) {
   1.121 +		fprintf(stderr, "write_ppm: failed to open file %s for writing: %s\n", fname, strerror(errno));
   1.122 +		return false;
   1.123 +	}
   1.124 +	fprintf(fp, "P6\n%d %d\n255\n", xsz, ysz);
   1.125 +
   1.126 +	for(int i=0; i<xsz * ysz * 4; i++) {
   1.127 +		if(i % 4 == 3) continue;
   1.128 +
   1.129 +		unsigned char c = (unsigned char)(fb[i] * 255.0);
   1.130 +		fputc(c, fp);
   1.131 +	}
   1.132 +	fclose(fp);
   1.133 +	return true;
   1.134 +}