commit 4b5750d5a7e4c978523bba6aecb322fe93c27112
parent bb45368afca9ceeb600ad1111da591702bec6a65
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Mon, 9 Mar 2015 14:44:30 +0100
Implement and test the s3d_scene_<attach_scene|clear> functions
Diffstat:
4 files changed, 58 insertions(+), 0 deletions(-)
diff --git a/src/s3d.h b/src/s3d.h
@@ -167,6 +167,12 @@ s3d_scene_attach_shape
(struct s3d_scene* scn,
struct s3d_shape* shp);
+/* Detach all the shapes from the scene and release the reference that the
+ * scene takes onto them */
+S3D_API res_T
+s3d_scene_clear
+ (struct s3d_scene* scn);
+
/* Trace a ray into the scene and return the closest intersection. The ray is
* defined by `origin' + t*`direction' = 0 with t in [`range[0]', `range[1]').
* Note that if range is degenerated (i.e. `range[0]' >= `range[1]') then the
diff --git a/src/s3d_scene.c b/src/s3d_scene.c
@@ -32,10 +32,12 @@
#include "s3d.h"
#include "s3d_device_c.h"
+#include "s3d_shape_c.h"
#include <rsys/mem_allocator.h>
struct s3d_scene {
+ struct list_node shapes; /* List of attached shapes */
struct s3d_device* dev;
ref_T ref;
};
@@ -50,6 +52,7 @@ scene_release(ref_T* ref)
struct s3d_device* dev;
ASSERT(ref);
scn = CONTAINER_OF(ref, struct s3d_scene, ref);
+ S3D(scene_clear(scn));
dev = scn->dev;
MEM_FREE(dev->allocator, scn);
S3D(device_ref_put(dev));
@@ -73,6 +76,7 @@ s3d_scene_create(struct s3d_device* dev, struct s3d_scene** out_scn)
res = RES_MEM_ERR;
goto error;
}
+ list_init(&scn->shapes);
ref_init(&scn->ref);
S3D(device_ref_get(dev));
scn->dev = dev;
@@ -104,3 +108,28 @@ s3d_scene_ref_put(struct s3d_scene* scn)
return RES_OK;
}
+res_T
+s3d_scene_attach_shape(struct s3d_scene* scn, struct s3d_shape* shape)
+{
+ if(!scn || !shape || !is_list_empty(&shape->scene_attachment))
+ return RES_BAD_ARG;
+ S3D(shape_ref_get(shape));
+ list_add_tail(&scn->shapes, &shape->scene_attachment);
+ return RES_OK;
+}
+
+res_T
+s3d_scene_clear(struct s3d_scene* scn)
+{
+ struct list_node* node, *tmp;
+ if(!scn)
+ return RES_BAD_ARG;
+
+ LIST_FOR_EACH_SAFE(node, tmp, &scn->shapes) {
+ struct s3d_shape* shape = CONTAINER_OF
+ (node, struct s3d_shape, scene_attachment);
+ S3D(shape_detach(shape));
+ }
+ return RES_OK;
+}
+
diff --git a/src/test_s3d_scene.c b/src/test_s3d_scene.c
@@ -39,17 +39,38 @@ main(int argc, char** argv)
struct mem_allocator allocator;
struct s3d_device* dev;
struct s3d_scene* scn;
+ struct s3d_shape* shapes[4];
+ const size_t nshapes = sizeof(shapes)/sizeof(struct s3d_shape*);
+ size_t i;
(void)argc, (void)argv;
mem_init_proxy_allocator(&allocator, &mem_default_allocator);
CHECK(s3d_device_create(NULL, &allocator, &dev), RES_OK);
+ FOR_EACH(i, 0, nshapes)
+ CHECK(s3d_shape_create(dev, shapes + i), RES_OK);
CHECK(s3d_scene_create(NULL, NULL), RES_BAD_ARG);
CHECK(s3d_scene_create(dev, NULL), RES_BAD_ARG);
CHECK(s3d_scene_create(NULL, &scn), RES_BAD_ARG);
CHECK(s3d_scene_create(dev, &scn), RES_OK);
+ CHECK(s3d_scene_attach_shape(NULL, NULL), RES_BAD_ARG);
+ CHECK(s3d_scene_attach_shape(scn, NULL), RES_BAD_ARG);
+ CHECK(s3d_scene_attach_shape(NULL, shapes[0]), RES_BAD_ARG);
+ CHECK(s3d_scene_attach_shape(scn, shapes[0]), RES_OK);
+ CHECK(s3d_scene_attach_shape(scn, shapes[0]), RES_BAD_ARG);
+ FOR_EACH(i, 1, nshapes) {
+ CHECK(s3d_scene_attach_shape(scn, shapes[i]), RES_OK);
+ CHECK(s3d_shape_ref_put(shapes[i]), RES_OK);
+ }
+
+ CHECK(s3d_scene_clear(NULL), RES_BAD_ARG);
+ CHECK(s3d_scene_clear(scn), RES_OK);
+ CHECK(s3d_scene_clear(scn), RES_OK);
+
+ CHECK(s3d_shape_ref_put(shapes[0]), RES_OK);
+
CHECK(s3d_scene_ref_get(NULL), RES_BAD_ARG);
CHECK(s3d_scene_ref_get(scn), RES_OK);
CHECK(s3d_scene_ref_put(NULL), RES_BAD_ARG);
@@ -63,3 +84,4 @@ main(int argc, char** argv)
CHECK(mem_allocated_size(), 0);
return 0;
}
+
diff --git a/src/test_s3d_shape.c b/src/test_s3d_shape.c
@@ -66,3 +66,4 @@ main(int argc, char** argv)
CHECK(mem_allocated_size(), 0);
return 0;
}
+