clray

changeset 29:353d80127627

doh ... it doesn't work
author John Tsiombikas <nuclear@member.fsf.org>
date Sat, 21 Aug 2010 20:51:57 +0100
parents 97cfd9675310
children 04803c702014
files rt.cl src/clray.cc src/rt.cc src/scene.cc src/scene.h
diffstat 5 files changed, 72 insertions(+), 27 deletions(-) [+]
line diff
     1.1 --- a/rt.cl	Sat Aug 21 03:42:49 2010 +0100
     1.2 +++ b/rt.cl	Sat Aug 21 20:51:57 2010 +0100
     1.3 @@ -59,7 +59,7 @@
     1.4  };
     1.5  
     1.6  struct KDNode {
     1.7 -	AABBox aabb;
     1.8 +	struct AABBox aabb;
     1.9  	int face_idx[32];
    1.10  	int num_faces;
    1.11  	int padding[3];
    1.12 @@ -161,9 +161,51 @@
    1.13  	return dcol + scol;
    1.14  }
    1.15  
    1.16 +#define STACK_SIZE	128
    1.17  bool find_intersection(struct Ray ray, const struct Scene *scn, struct SurfPoint *spres)
    1.18  {
    1.19 -	return false;
    1.20 +	struct SurfPoint sp0;
    1.21 +	sp0.t = 1.0;
    1.22 +	sp0.obj = 0;
    1.23 +
    1.24 +	int idxstack[STACK_SIZE];
    1.25 +	int sp = 0;			// points at the topmost element of the stack
    1.26 +	idxstack[sp] = 1;	// root at tree[1] (heap)
    1.27 +
    1.28 +	while(sp >= 0) {
    1.29 +		int idx = idxstack[sp--];	// remove this index from the stack and process it
    1.30 +
    1.31 +		global struct KDNode *node = scn->kdtree + idx;
    1.32 +
    1.33 +		if(intersect_aabb(ray, node->aabb)) {
    1.34 +			// leaf node ...
    1.35 +			if(node->num_faces) {
    1.36 +				// check each face in turn and update the nearest intersection as needed
    1.37 +				for(int i=0; i<node->num_faces; i++) {
    1.38 +					struct SurfPoint sp;
    1.39 +					int fidx = node->face_idx[i];
    1.40 +
    1.41 +					if(intersect(ray, scn->faces + fidx, &sp) && sp.t < sp0.t) {
    1.42 +						sp0 = sp;
    1.43 +					}
    1.44 +				}
    1.45 +			}
    1.46 +		} else {
    1.47 +			// internal node ... recurse to the children
    1.48 +			idxstack[++sp] = idx * 2;
    1.49 +			idxstack[++sp] = idx * 2 + 1;
    1.50 +		}
    1.51 +	}
    1.52 +
    1.53 +	if(!sp0.obj) {
    1.54 +		return false;
    1.55 +	}
    1.56 +
    1.57 +	if(spres) {
    1.58 +		*spres = sp0;
    1.59 +		spres->mat = scn->matlib[sp0.obj->matid];
    1.60 +	}
    1.61 +	return true;
    1.62  }
    1.63  
    1.64  /*bool find_intersection(struct Ray ray, const struct Scene *scn, struct SurfPoint *spres)
    1.65 @@ -236,7 +278,10 @@
    1.66  		return true;
    1.67  	}
    1.68  
    1.69 -	float4 bbox[2] = {aabb.min, aabb.max};
    1.70 +	float4 bbox[2] = {
    1.71 +		aabb.min.x, aabb.min.y, aabb.min.z, 0,
    1.72 +		aabb.max.x, aabb.max.y, aabb.max.z, 0
    1.73 +	};
    1.74  
    1.75  	int xsign = (int)(ray.dir.x < 0.0);
    1.76  	float invdirx = 1.0 / ray.dir.x;
    1.77 @@ -264,7 +309,7 @@
    1.78  		return false;
    1.79  	}
    1.80  
    1.81 -	return tmin < t1 && tmax > t0;
    1.82 +	return tmin < 1.0 && tmax > 0.0;
    1.83  }
    1.84  
    1.85  float4 reflect(float4 v, float4 n)
     2.1 --- a/src/clray.cc	Sat Aug 21 03:42:49 2010 +0100
     2.2 +++ b/src/clray.cc	Sat Aug 21 20:51:57 2010 +0100
     2.3 @@ -107,10 +107,6 @@
     2.4  	}
     2.5  	atexit(cleanup);
     2.6  
     2.7 -	if(!scn.build_kdtree()) {
     2.8 -		return 1;
     2.9 -	}
    2.10 -
    2.11  
    2.12  	/*glGenTextures(1, &tex);
    2.13  	glBindTexture(GL_TEXTURE_2D, tex);*/
     3.1 --- a/src/rt.cc	Sat Aug 21 03:42:49 2010 +0100
     3.2 +++ b/src/rt.cc	Sat Aug 21 20:51:57 2010 +0100
     3.3 @@ -90,7 +90,6 @@
     3.4  		fprintf(stderr, "failed to create kdtree buffer\n");
     3.5  		return false;
     3.6  	}
     3.7 -	int num_kdnodes = scn->get_num_kdnodes();
     3.8  
     3.9  	/* setup argument buffers */
    3.10  	prog->set_arg_buffer(KARG_FRAMEBUFFER, ARG_WR, xsz * ysz * 4 * sizeof(float));
    3.11 @@ -101,7 +100,7 @@
    3.12  	prog->set_arg_buffer(KARG_PRIM_RAYS, ARG_RD, xsz * ysz * sizeof *prim_rays, prim_rays);
    3.13  	prog->set_arg_buffer(KARG_XFORM, ARG_RD, 16 * sizeof(float));
    3.14  	prog->set_arg_buffer(KARG_INVTRANS_XFORM, ARG_RD, 16 * sizeof(float));
    3.15 -	prog->set_arg_buffer(KARG_KDTREE, ARG_RD, num_kdnodes * sizeof *kdbuf, kdbuf);
    3.16 +	prog->set_arg_buffer(KARG_KDTREE, ARG_RD, scn->get_kdtree_buffer_size(), kdbuf);
    3.17  
    3.18  	if(prog->get_num_args() < NUM_KERNEL_ARGS) {
    3.19  		return false;
     4.1 --- a/src/scene.cc	Sat Aug 21 03:42:49 2010 +0100
     4.2 +++ b/src/scene.cc	Sat Aug 21 20:51:57 2010 +0100
     4.3 @@ -70,7 +70,6 @@
     4.4  	facebuf = 0;
     4.5  	num_faces = -1;
     4.6  	kdtree = 0;
     4.7 -	num_kdnodes = -1;
     4.8  	kdbuf = 0;
     4.9  }
    4.10  
    4.11 @@ -172,25 +171,30 @@
    4.12  		((Scene*)this)->build_kdtree();
    4.13  	}
    4.14  
    4.15 -	if(!get_num_kdnodes()) {
    4.16 -		return 0;
    4.17 -	}
    4.18 +	int max_nodes = (int)pow(2, kdtree_depth(kdtree)) - 1;
    4.19 +	printf("allocating storage for the complete tree (%d)\n", max_nodes);
    4.20  
    4.21 -	kdbuf = new KDNodeGPU[num_kdnodes + 1];
    4.22 +	kdbuf = new KDNodeGPU[max_nodes + 1];
    4.23  	kdtree_gpu_flatten(kdbuf, 1, kdtree, get_face_buffer());
    4.24  	return kdbuf;
    4.25  }
    4.26  
    4.27 -int Scene::get_num_kdnodes() const
    4.28 +static int ipow(int x, int n)
    4.29  {
    4.30 -	if(num_kdnodes >= 0) {
    4.31 -		return num_kdnodes;
    4.32 +	assert(n >= 0);
    4.33 +
    4.34 +	int res = 1;
    4.35 +	for(int i=0; i<n; i++) {
    4.36 +		res *= x;
    4.37  	}
    4.38 -
    4.39 -	num_kdnodes = kdtree_nodes(kdtree);
    4.40 -	return num_kdnodes;
    4.41 +	return res;
    4.42  }
    4.43  
    4.44 +int Scene::get_kdtree_buffer_size() const
    4.45 +{
    4.46 +	// 2**depth - 1 nodes for the complete tree + 1 for the unused heap item 0.
    4.47 +	return ipow(2, kdtree_depth(kdtree)) * sizeof(KDNodeGPU);
    4.48 +}
    4.49  
    4.50  void Scene::draw_kdtree() const
    4.51  {
    4.52 @@ -255,6 +259,8 @@
    4.53  
    4.54  bool Scene::build_kdtree()
    4.55  {
    4.56 +	assert(kdtree == 0);
    4.57 +
    4.58  	const Face *faces = get_face_buffer();
    4.59  	int num_faces = get_num_faces();
    4.60  
    4.61 @@ -351,7 +357,7 @@
    4.62  		}
    4.63  	}
    4.64  
    4.65 -	printf("current cost: %f,   best_cost: %f\n", kd->cost, best_sum_cost);
    4.66 +	//printf("current cost: %f,   best_cost: %f\n", kd->cost, best_sum_cost);
    4.67  	if(best_sum_cost > kd->cost && (opt_max_items == 0 || kd->num_faces <= opt_max_items)) {
    4.68  		return true;	// stop splitting if it doesn't reduce the cost
    4.69  	}
    4.70 @@ -461,7 +467,7 @@
    4.71  			fprintf(stderr, "kdtree_gpu_flatten WARNING: more than %d faces in node, skipping!\n", (int)MAX_FACES);
    4.72  			break;
    4.73  		}
    4.74 -		dest->face_idx[dest->num_faces++] = *it - facebuf;
    4.75 +		dest->face_idx[dest->num_faces++] = *it++ - facebuf;
    4.76  	}
    4.77  
    4.78  	if(node->left) {
    4.79 @@ -475,10 +481,10 @@
    4.80  {
    4.81  	if(!node) return;
    4.82  
    4.83 -	for(int i=0; i<level; i++) {
    4.84 +	/*for(int i=0; i<level; i++) {
    4.85  		fputs("   ", stdout);
    4.86  	}
    4.87 -	printf("- %d (cost: %f)\n", node->num_faces, node->cost);
    4.88 +	printf("- %d (cost: %f)\n", node->num_faces, node->cost);*/
    4.89  
    4.90  	print_item_counts(node->left, level + 1);
    4.91  	print_item_counts(node->right, level + 1);
     5.1 --- a/src/scene.h	Sat Aug 21 03:42:49 2010 +0100
     5.2 +++ b/src/scene.h	Sat Aug 21 20:51:57 2010 +0100
     5.3 @@ -73,7 +73,6 @@
     5.4  	mutable int num_faces;
     5.5  
     5.6  	mutable KDNodeGPU *kdbuf;
     5.7 -	mutable int num_kdnodes;
     5.8  
     5.9  public:
    5.10  	std::vector<Mesh*> meshes;
    5.11 @@ -96,7 +95,7 @@
    5.12  
    5.13  	const Face *get_face_buffer() const;
    5.14  	const KDNodeGPU *get_kdtree_buffer() const;
    5.15 -	int get_num_kdnodes() const;
    5.16 +	int get_kdtree_buffer_size() const;
    5.17  
    5.18  	void draw_kdtree() const;
    5.19  	bool build_kdtree();