commit cfeb38895a8d20f44378ebd7ffd70219c02ec1bd
parent 67a225f5693979547da10f56587412c51dde5ab4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Fri, 24 Jun 2016 18:34:11 +0200
Add missing files.
Diffstat:
| A | src/ssol_shape.c | | | 288 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/ssol_shape_c.h | | | 50 | ++++++++++++++++++++++++++++++++++++++++++++++++++ |
| A | src/test_ssol_shape.c | | | 158 | +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ |
3 files changed, 496 insertions(+), 0 deletions(-)
diff --git a/src/ssol_shape.c b/src/ssol_shape.c
@@ -0,0 +1,287 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ssol.h"
+#include "ssol_shape_c.h"
+#include "ssol_device_c.h"
+
+#include <rsys\rsys.h>
+#include <rsys\mem_allocator.h>
+#include <rsys\ref_count.h>
+
+/*******************************************************************************
+* Helper functions
+******************************************************************************/
+
+static void
+shape_mesh_release(ref_T* ref)
+{
+ struct shape_mesh* mesh;
+ ASSERT(ref);
+
+ mesh = CONTAINER_OF(ref, struct shape_mesh, ref);
+ if (mesh->shape) S3D(shape_ref_put(mesh->shape));
+ ASSERT(mesh->dev && mesh->dev->allocator);
+ MEM_RM(mesh->dev->allocator, mesh);
+ SSOL(device_ref_put(mesh->dev));
+}
+
+static void
+shape_mesh_ref_get(struct shape_mesh* mesh)
+{
+ ASSERT(mesh);
+ ref_get(&mesh->ref);
+}
+
+static void
+shape_mesh_ref_put(struct shape_mesh* mesh)
+{
+ ASSERT(mesh);
+ ref_put(&mesh->ref, shape_mesh_release);
+}
+
+static void
+shape_release(ref_T* ref)
+{
+ struct ssol_shape* shape;
+ ASSERT(ref);
+ shape = CONTAINER_OF(ref, struct ssol_shape, ref);
+
+ switch (shape->type) {
+ case SHAPE_NONE:
+ break;
+ case SHAPE_MESH:
+ if (shape->data.mesh) shape_mesh_ref_put(shape->data.mesh);
+ break;
+ case SHAPE_PUNCHED:
+ if (shape->data.punched) /* TODO */;
+ break;
+ default: FATAL("Unreachable code \n"); break;
+ }
+
+ ASSERT(shape->dev);
+ MEM_RM(shape->dev->allocator, shape);
+ SSOL(device_ref_put(shape->dev));
+}
+
+/*******************************************************************************
+* Local functions
+******************************************************************************/
+
+static res_T
+shape_create(struct ssol_device* dev, struct ssol_shape** out_shape)
+{
+ struct ssol_shape* shape = NULL;
+ res_T res = RES_OK;
+
+ ASSERT(dev && out_shape);
+
+ shape = (struct ssol_shape*)MEM_CALLOC
+ (dev->allocator, 1, sizeof(struct ssol_shape));
+ if (!shape) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ SSOL(device_ref_get(dev));
+ shape->dev = dev;
+ ref_init(&shape->ref);
+ shape->type = SHAPE_NONE;
+
+exit:
+ if (out_shape) *out_shape = shape;
+ return res;
+error:
+ if (shape) {
+ SSOL(shape_ref_put(shape));
+ shape = NULL;
+ }
+ goto exit;
+
+}
+
+static res_T
+shape_mesh_create
+(struct ssol_device* dev,
+ struct shape_mesh** out_mesh)
+{
+ struct shape_mesh* mesh = NULL;
+ res_T res = RES_OK;
+
+ mesh = (struct shape_mesh*)MEM_CALLOC
+ (dev->allocator, 1, sizeof(struct shape_mesh));
+ if (!mesh) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ res = s3d_shape_create_mesh(dev->s3d, &mesh->shape);
+ if (res != RES_OK)
+ goto error;
+
+ SSOL(device_ref_get(dev));
+ mesh->dev = dev;
+ ref_init(&mesh->ref);
+
+exit:
+ if (out_mesh) *out_mesh = mesh;
+ return res;
+error:
+ if (mesh) {
+ shape_mesh_ref_put(mesh);
+ mesh = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+* Exported ssol_shape functions
+******************************************************************************/
+
+res_T
+ssol_shape_create_mesh
+ (struct ssol_device* dev,
+ struct ssol_shape** out_shape)
+{
+ struct ssol_shape* shape = NULL;
+ res_T res = RES_OK;
+
+ if (!dev || !out_shape) {
+ res = RES_BAD_ARG;
+ goto error;
+ }
+
+ res = shape_create(dev, &shape);
+ if (res != RES_OK)
+ goto error;
+
+ res = shape_mesh_create(dev, &shape->data.mesh);
+ if (res != RES_OK)
+ goto error;
+
+ shape->type = SHAPE_MESH;
+ shape->dev = dev;
+ ref_init(&shape->ref);
+
+exit:
+ if (out_shape) *out_shape = shape;
+ return res;
+error:
+ if (shape) {
+ SSOL(shape_ref_put(shape));
+ shape = NULL;
+ }
+ goto exit;
+}
+
+res_T
+ssol_shape_create_punched_surface
+ (struct ssol_device* dev,
+ struct ssol_shape** out_shape)
+{
+ res_T res = RES_OK;
+
+ if (!dev || !out_shape) {
+ return RES_BAD_ARG;
+ }
+
+ return res;
+}
+
+res_T
+ssol_shape_ref_get
+(struct ssol_shape* shape)
+{
+ if (!shape) return RES_BAD_ARG;
+ ref_get(&shape->ref);
+ return RES_OK;
+}
+
+res_T
+ssol_shape_ref_put
+(struct ssol_shape* shape)
+{
+ if (!shape) return RES_BAD_ARG;
+ ref_put(&shape->ref, shape_release);
+ return RES_OK;
+}
+
+res_T
+ssol_punched_surface_setup
+ (struct ssol_shape* shape,
+ const struct ssol_punched_surface* punched_surface)
+{
+ res_T res = RES_OK;
+
+ if (!shape || shape->type != SHAPE_PUNCHED || !punched_surface) {
+ return RES_BAD_ARG;
+ }
+
+ return res;
+}
+
+res_T
+ssol_mesh_setup
+ (struct ssol_shape* shape,
+ const unsigned ntris,
+ void(*get_indices)(const unsigned itri, unsigned ids[3], void* ctx),
+ const unsigned nverts,
+ const struct ssol_vertex_data attribs [],
+ const unsigned nattribs,
+ void* data)
+{
+ struct s3d_vertex_data* _attrib3 = NULL;
+ res_T res = RES_OK;
+ unsigned i;
+
+ if (!shape || shape->type != SHAPE_MESH || !get_indices) {
+ return RES_BAD_ARG;
+ }
+ if (!ntris || !nverts || !attribs || !nattribs) {
+ return RES_BAD_ARG;
+ }
+ ASSERT(shape->ref);
+ ASSERT(shape->dev && shape->dev->allocator && shape->data.mesh);
+
+ _attrib3 = (struct s3d_vertex_data*)MEM_CALLOC
+ (shape->dev->allocator, nattribs, sizeof(struct s3d_vertex_data));
+ if (!_attrib3) {
+ return RES_MEM_ERR;
+ }
+
+ for (i = 0; i < nattribs; i++) {
+ _attrib3[i].get = attribs[i].get;
+ switch (attribs[i].usage) {
+ case SSOL_POSITION:
+ _attrib3[i].usage = S3D_POSITION;
+ _attrib3[i].type = S3D_FLOAT3;
+ break;
+ case SSOL_NORMAL:
+ _attrib3[i].usage = S3D_GEOMETRY_NORMAL;
+ _attrib3[i].type = S3D_FLOAT3;
+ break;
+ case SSOL_TEXCOORD:
+ _attrib3[i].usage = S3D_ATTRIB_0;
+ _attrib3[i].type = S3D_FLOAT2;
+ break;
+ default:
+ FATAL("Unreachable code \n");
+ break;
+ }
+ }
+ res = s3d_mesh_setup_indexed_vertices(shape->data.mesh->shape, ntris, get_indices, nverts, _attrib3, nattribs, data);
+ MEM_RM(shape->dev->allocator, _attrib3);
+ return res;
+}
+\ No newline at end of file
diff --git a/src/ssol_shape_c.h b/src/ssol_shape_c.h
@@ -0,0 +1,50 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifndef SSOL_SHAPE_C_H
+#define SSOL_SHAPE_C_H
+
+#include <rsys/ref_count.h>
+
+enum shape_type {
+ SHAPE_NONE,
+ SHAPE_MESH,
+ SHAPE_PUNCHED
+};
+
+struct shape_mesh {
+ struct s3d_shape* shape;
+
+ struct ssol_device* dev;
+ ref_T ref;
+};
+
+struct shape_punched {
+ char TODO;
+};
+
+struct ssol_shape {
+ enum shape_type type;
+
+ union {
+ struct shape_mesh* mesh;
+ struct shape_punched* punched;
+ } data;
+
+ struct ssol_device* dev;
+ ref_T ref;
+};
+
+#endif /* SSOL_SHAPE_C_H */
diff --git a/src/test_ssol_shape.c b/src/test_ssol_shape.c
@@ -0,0 +1,157 @@
+/* Copyright (C) CNRS 2016
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+*
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+*
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#include "ssol.h"
+#include "test_ssol_utils.h"
+
+#include <rsys/logger.h>
+
+static void
+log_stream(const char* msg, void* ctx)
+{
+ ASSERT(msg);
+ (void) msg, (void) ctx;
+ printf("%s\n", msg);
+}
+
+/*******************************************************************************
+* Box
+******************************************************************************/
+struct cbox_desc {
+ const float* vertices;
+ const unsigned* indices;
+};
+
+static const float cbox_walls [] = {
+ 552.f, 0.f, 0.f,
+ 0.f, 0.f, 0.f,
+ 0.f, 559.f, 0.f,
+ 552.f, 559.f, 0.f,
+ 552.f, 0.f, 548.f,
+ 0.f, 0.f, 548.f,
+ 0.f, 559.f, 548.f,
+ 552.f, 559.f, 548.f
+};
+const unsigned cbox_walls_nverts = sizeof(cbox_walls) / sizeof(float[3]);
+
+const unsigned cbox_walls_ids [] = {
+ 0, 1, 2, 2, 3, 0, /* Bottom */
+ 4, 5, 6, 6, 7, 4, /* Top */
+ 1, 2, 6, 6, 5, 1, /* Left */
+ 0, 3, 7, 7, 4, 0, /* Right */
+ 2, 3, 7, 7, 6, 2 /* Back */
+};
+const unsigned cbox_walls_ntris = sizeof(cbox_walls_ids) / sizeof(unsigned[3]);
+
+static const struct cbox_desc cbox_walls_desc = { cbox_walls, cbox_walls_ids };
+
+/*******************************************************************************
+* Callbacks
+******************************************************************************/
+static INLINE void
+cbox_get_ids(const unsigned itri, unsigned ids[3], void* data)
+{
+ const unsigned id = itri * 3;
+ struct cbox_desc* desc = data;
+ NCHECK(desc, NULL);
+ ids[0] = desc->indices[id + 0];
+ ids[1] = desc->indices[id + 1];
+ ids[2] = desc->indices[id + 2];
+}
+
+static INLINE void
+cbox_get_position(const unsigned ivert, float position[3], void* data)
+{
+ struct cbox_desc* desc = data;
+ NCHECK(desc, NULL);
+ position[0] = desc->vertices[ivert * 3 + 0];
+ position[1] = desc->vertices[ivert * 3 + 1];
+ position[2] = desc->vertices[ivert * 3 + 2];
+}
+
+static INLINE void
+cbox_get_normal(const unsigned ivert, float normal[3], void* data)
+{
+ (void) ivert, (void) data;
+ normal[0] = 1.f;
+ normal[1] = 0.f;
+ normal[2] = 0.f;
+}
+
+static INLINE void
+cbox_get_uv(const unsigned ivert, float uv[2], void* data)
+{
+ (void) ivert, (void) data;
+ uv[0] = -1.f;
+ uv[1] = 1.f;
+}
+
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct ssol_device* dev;
+ struct ssol_shape* shape;
+ struct ssol_vertex_data attribs[3];
+ void* data = (void*) &cbox_walls_desc;
+ (void) argc, (void) argv;
+
+ mem_init_proxy_allocator(&allocator, &mem_default_allocator);
+
+ CHECK(logger_init(&allocator, &logger), RES_OK);
+ logger_set_stream(&logger, LOG_OUTPUT, log_stream, NULL);
+ logger_set_stream(&logger, LOG_ERROR, log_stream, NULL);
+ logger_set_stream(&logger, LOG_WARNING, log_stream, NULL);
+
+ CHECK(ssol_device_create(&logger, &allocator, SSOL_NTHREADS_DEFAULT, 0, &dev), RES_OK);
+
+ CHECK(ssol_shape_create_mesh(NULL, NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_create_mesh(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_create_mesh(NULL, &shape), RES_BAD_ARG);
+ CHECK(ssol_shape_create_mesh(dev, &shape), RES_OK);
+
+ CHECK(ssol_shape_ref_get(NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_ref_get(shape), RES_OK);
+
+ CHECK(ssol_shape_ref_put(NULL), RES_BAD_ARG);
+ CHECK(ssol_shape_ref_put(shape), RES_OK);
+
+ attribs[0].usage = SSOL_POSITION;
+ attribs[0].get = cbox_get_position;
+ attribs[1].usage = SSOL_NORMAL;
+ attribs[1].get = cbox_get_normal;
+ attribs[2].usage = SSOL_TEXCOORD;
+ attribs[2].get = cbox_get_uv;
+
+ CHECK(ssol_mesh_setup(NULL, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, 0, cbox_get_ids, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, NULL, cbox_walls_nverts, attribs, 1, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, 0, attribs, 1, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, NULL, 1, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 0, data), RES_BAD_ARG);
+ CHECK(ssol_mesh_setup(shape, cbox_walls_ntris, cbox_get_ids, cbox_walls_nverts, attribs, 3, data), RES_OK);
+
+ CHECK(ssol_shape_ref_put(shape), RES_OK);
+ CHECK(ssol_device_ref_put(dev), RES_OK);
+
+ logger_release(&logger);
+
+ check_memory_allocator(&allocator);
+ mem_shutdown_proxy_allocator(&allocator);
+ CHECK(mem_allocated_size(), 0);
+
+ return 0;
+}
+\ No newline at end of file