commit 7c8dcce2343e44eeea640bf406a53d533c6765bf
parent 5ccfdcb24c9e30b638685608e652fde3477eb5a4
Author: Christophe Coustet <christophe.coustet@meso-star.com>
Date: Tue, 28 Jun 2016 18:07:50 +0200
First try at materials
Diffstat:
5 files changed, 347 insertions(+), 0 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -48,6 +48,7 @@ set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
set(SSOL_FILES_SRC
ssol_device.c
+ ssol_material.c
ssol_shape.c)
set(SSOL_FILES_INC_API
@@ -55,6 +56,7 @@ set(SSOL_FILES_INC_API
set(SSOL_FILES_INC
ssol_device_c.h
+ ssol_material_c.h
ssol_shape_c.h)
set(SSOL_FILES_DOC COPYING README.md)
@@ -105,6 +107,7 @@ if(NOT NO_TEST)
endfunction()
new_test(test_ssol_device)
+ new_test(test_ssol_material)
new_test(test_ssol_shape)
endif(NOT NO_TEST)
diff --git a/src/ssol.h b/src/ssol.h
@@ -346,6 +346,11 @@ ssol_material_create_mirror
struct ssol_material** mtl);
SSOL_API res_T
+ssol_material_create_virtual
+ (struct ssol_device* dev,
+ struct ssol_material** mtl);
+
+SSOL_API res_T
ssol_material_ref_get
(struct ssol_material* mtl);
diff --git a/src/ssol_material.c b/src/ssol_material.c
@@ -0,0 +1,149 @@
+/* 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_material_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
+material_release(ref_T* ref)
+{
+ struct ssol_material* material;
+ ASSERT(ref);
+ material = CONTAINER_OF(ref, struct ssol_material, ref);
+
+ ASSERT(material->dev && material->dev->allocator);
+
+ SSOL(device_ref_put(material->dev));
+ MEM_RM(material->dev->allocator, material);
+}
+
+static INLINE res_T
+shader_ok(const struct ssol_mirror_shader* shader) {
+ if (!shader
+ || !shader->shading_normal
+ || !shader->reflectivity
+ || !shader->diffuse_specular_ratio
+ || !shader->roughness)
+ return RES_BAD_ARG;
+ return RES_OK;
+}
+
+/*******************************************************************************
+* Local functions
+******************************************************************************/
+
+static res_T
+ssol_material_create
+ (struct ssol_device* dev,
+ struct ssol_material** out_material,
+ enum material_type type)
+{
+ struct ssol_material* material = NULL;
+ res_T res = RES_OK;
+ if (!dev
+ || !out_material
+ || type < MATERIAL_FIRST_TYPE
+ || type > MATERIAL_LAST_TYPE) {
+ return RES_BAD_ARG;
+ }
+
+ material = (struct ssol_material*)MEM_CALLOC
+ (dev->allocator, 1, sizeof(struct ssol_material));
+ if (!material) {
+ res = RES_MEM_ERR;
+ goto error;
+ }
+
+ SSOL(device_ref_get(dev));
+ material->dev = dev;
+ ref_init(&material->ref);
+ material->type = type;
+
+exit:
+ if (out_material) *out_material = material;
+ return res;
+error:
+ if (material) {
+ SSOL(material_ref_put(material));
+ material = NULL;
+ }
+ goto exit;
+}
+
+/*******************************************************************************
+* Exported ssol_material functions
+******************************************************************************/
+
+res_T
+ssol_material_ref_get
+ (struct ssol_material* material)
+{
+ if (!material)
+ return RES_BAD_ARG;
+ ASSERT(MATERIAL_FIRST_TYPE <= material->type && material->type <= MATERIAL_LAST_TYPE);
+ ref_get(&material->ref);
+ return RES_OK;
+}
+
+res_T
+ssol_material_ref_put
+ (struct ssol_material* material)
+{
+ if (!material)
+ return RES_BAD_ARG;
+ ASSERT(MATERIAL_FIRST_TYPE <= material->type && material->type <= MATERIAL_LAST_TYPE);
+ ref_put(&material->ref, material_release);
+ return RES_OK;
+}
+
+res_T
+ssol_material_create_mirror
+ (struct ssol_device* dev,
+ struct ssol_material** out_material)
+{
+ return ssol_material_create(dev, out_material, MATERIAL_MIRROR);
+}
+
+res_T
+ssol_mirror_set_shader
+ (struct ssol_material* material,
+ const struct ssol_mirror_shader* shader)
+{
+ if (!material
+ || material->type != MATERIAL_MIRROR
+ || shader_ok(shader) != RES_OK)
+ return RES_BAD_ARG;
+
+ material->data.mirror = *shader;
+
+ return RES_OK;
+}
+
+res_T
+ssol_material_create_virtual
+(struct ssol_device* dev,
+ struct ssol_material** out_material)
+{
+ return ssol_material_create(dev, out_material, MATERIAL_VIRTUAL);
+}
diff --git a/src/ssol_material_c.h b/src/ssol_material_c.h
@@ -0,0 +1,40 @@
+/* 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_MATERIAL_C_H
+#define SSOL_MATERIAL_C_H
+
+#include <rsys/ref_count.h>
+
+enum material_type {
+ MATERIAL_VIRTUAL,
+ MATERIAL_MIRROR,
+
+ MATERIAL_FIRST_TYPE = MATERIAL_VIRTUAL,
+ MATERIAL_LAST_TYPE = MATERIAL_MIRROR
+};
+
+struct ssol_material {
+ enum material_type type;
+
+ union {
+ struct ssol_mirror_shader mirror;
+ } data;
+
+ struct ssol_device* dev;
+ ref_T ref;
+};
+
+#endif /* SSOL_MATERIAL_C_H */
diff --git a/src/test_ssol_material.c b/src/test_ssol_material.c
@@ -0,0 +1,149 @@
+/* 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
+get_shading_normal
+ (struct ssol_device* dev,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double uv[2],
+ const double wo[3],
+ double* val)
+{
+ int i;
+ (void) dev; (void) wavelength; (void) P; (void) uv; (void) wo;
+ for (i = 0; i < 3; i++) val[i] = Ng[i];
+}
+
+static void
+get_reflectivity
+ (struct ssol_device* dev,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double uv[2],
+ const double wo[3],
+ double* val)
+{
+ (void) dev; (void) wavelength; (void) P; (void) Ng; (void) uv; (void) wo;
+ *val = 1;
+}
+
+static void
+get_diffuse_specular_ratio
+ (struct ssol_device* dev,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double uv[2],
+ const double wo[3],
+ double* val)
+{
+ (void) dev; (void) wavelength; (void) P; (void) Ng; (void) uv; (void) wo;
+ *val = 0;
+}
+
+static void
+get_roughness
+ (struct ssol_device* dev,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double uv[2],
+ const double wo[3],
+ double* val)
+{
+ (void) dev; (void) wavelength; (void) P; (void) Ng; (void) uv; (void) wo;
+ *val = 0;
+}
+
+/*******************************************************************************
+* test main program
+******************************************************************************/
+int
+main(int argc, char** argv)
+{
+ struct logger logger;
+ struct mem_allocator allocator;
+ struct ssol_device* dev;
+ struct ssol_material* material;
+ struct ssol_mirror_shader shader;
+ (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_material_create_mirror(NULL, &material), RES_BAD_ARG);
+ CHECK(ssol_material_create_mirror(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_material_create_mirror(dev, &material), RES_OK);
+
+ CHECK(ssol_material_ref_get(material), RES_OK);
+ CHECK(ssol_material_ref_put(material), RES_OK);
+
+ shader.shading_normal = get_shading_normal;
+ shader.reflectivity = get_reflectivity;
+ shader.diffuse_specular_ratio = get_diffuse_specular_ratio;
+ shader.roughness = get_roughness;
+
+ CHECK(ssol_mirror_set_shader(NULL, &shader), RES_BAD_ARG);
+ CHECK(ssol_mirror_set_shader(material, NULL), RES_BAD_ARG);
+ CHECK(ssol_mirror_set_shader(material, &shader), RES_OK);
+
+ shader.shading_normal = NULL;
+ CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG);
+ shader.shading_normal = get_shading_normal;
+
+ shader.reflectivity = NULL;
+ CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG);
+ shader.reflectivity = get_reflectivity;
+
+ shader.diffuse_specular_ratio = NULL;
+ CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG);
+ shader.diffuse_specular_ratio = get_diffuse_specular_ratio;
+
+ shader.roughness = NULL;
+ CHECK(ssol_mirror_set_shader(material, &shader), RES_BAD_ARG);
+ shader.roughness = get_roughness;
+
+ CHECK(ssol_material_ref_put(material), RES_OK);
+
+ CHECK(ssol_material_create_virtual(NULL, &material), RES_BAD_ARG);
+ CHECK(ssol_material_create_virtual(dev, NULL), RES_BAD_ARG);
+ CHECK(ssol_material_create_virtual(dev, &material), RES_OK);
+
+ CHECK(ssol_material_ref_put(material), 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