commit 26edc230c7a0b699c4b369926e168a68319e0d84
parent 054fb381cc6c2698ddb7964213f28f0fc6d78cb0
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Fri, 2 Dec 2016 14:40:00 +0100
First draft of the solstice application
Declare the solstice data structure and implement the
solstice_create_ssol_material and solstice_get_ssol_material functions.
Diffstat:
6 files changed, 324 insertions(+), 39 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -56,8 +56,8 @@ set(VERSION_MINOR 1)
set(VERSION_PATCH 0)
set(VERSION ${VERSION_MAJOR}.${VERSION_MINOR}.${VERSION_PATCH})
-set(SOLSTICE_FILES_SRC solstice.c)
-set(SOLSTICE_FILES_INC )
+set(SOLSTICE_FILES_SRC solstice.c solstice_material.c)
+set(SOLSTICE_FILES_INC solstice.h solstice_c.h)
set(SOLSTICE_FILES_DOC COPYING README.md)
# Prepend each file in the `SOLSTICE_FILES_<SRC|INC>' list by `SOLSTICE_SOURCE_DIR'
@@ -69,8 +69,10 @@ if(CMAKE_COMPILER_IS_GNUCC)
set(MATH_LIB m)
endif()
-add_executable(solstice ${SOLSTICE_SOURCE_DIR}/solstice.c)
-target_link_libraries(solstice LibYAML RSys ${MATH_LIB} solparser SolAnim SolSolver)
+add_library(sollib STATIC ${SOLSTICE_FILES_SRC} ${SOLSTICE_FILES_INC})
+add_executable(solstice ${SOLSTICE_SOURCE_DIR}/main.c)
+target_link_libraries(solstice
+ LibYAML RSys ${MATH_LIB} sollib solparser SolAnim SolSolver)
set_target_properties(solstice PROPERTIES
VERSION ${VERSION}
SOVERSION ${VERSION_MAJOR})
diff --git a/src/solstice.c b/src/main.c
diff --git a/src/solstice.c b/src/solstice.c
@@ -13,51 +13,51 @@
* 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 "solstice.h"
#include "parser/solparser.h"
-#include <rsys/rsys.h>
-int
-main(int argc, char** argv)
-{
- FILE* file = NULL;
- struct solparser* parser = NULL;
- res_T res;
- int err = 0;
- int i;
-
- if(argc < 2) {
- fprintf(stderr, "Usage: %s FILE [FILE ...]\n", argv[0]);
- err = 1;
- goto error;
- }
+#include <solstice/ssol.h>
- res = solparser_create(NULL, &parser);
- if(res != RES_OK) goto error;
-
- FOR_EACH(i, 1, argc) {
- file = fopen(argv[i], "rb");
- if(!file) {
- fprintf(stderr, "Could not open the file `%s'.\n", argv[i]);
- goto error;
- }
+/*******************************************************************************
+ * Solstice local functions
+ ******************************************************************************/
+res_T
+solstice_init(struct mem_allocator* allocator, struct solstice* solstice)
+{
+ res_T res = RES_OK;
+ ASSERT(solstice);
- res = solparser_setup(parser, argv[i], file);
- if(res != RES_OK) break;
+ memset(solstice, 0, sizeof(struct solstice));
+ htable_material_init(allocator, &solstice->materials);
+ htable_object_init(allocator, &solstice->objects);
- do {
- res = solparser_load(parser);
- } while(res != RES_BAD_OP);
+ res = ssol_device_create
+ (NULL, allocator, SSOL_NTHREADS_DEFAULT, 0, &solstice->ssol);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the Solstice Solver device.\n");
+ goto error;
+ }
- fclose(file);
- file = NULL;
+ res = solparser_create(allocator, &solstice->parser);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the Solstice Parser.\n");
+ goto error;
}
exit:
- if(parser) solparser_ref_put(parser);
- if(file) fclose(file);
- return err;
+ return res;
error:
- err = -1;
+ solstice_release(solstice);
goto exit;
}
+void
+solstice_release(struct solstice* solstice)
+{
+ ASSERT(solstice);
+ if(solstice->ssol) SSOL(device_ref_put(solstice->ssol));
+ if(solstice->parser) solparser_ref_put(solstice->parser);
+ htable_material_release(&solstice->materials);
+ htable_object_release(&solstice->objects);
+}
+
diff --git a/src/solstice.h b/src/solstice.h
@@ -0,0 +1,57 @@
+/* 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 SOLSTICE_H
+#define SOLSTICE_H
+
+#include "parser/solparser_material.h"
+
+#include <rsys/hash_table.h>
+#include <rsys/mem_allocator.h>
+
+struct solparser;
+struct ssol_device;
+struct ssol_material;
+struct ssol_object;
+
+#define HTABLE_NAME material
+#define HTABLE_KEY size_t
+#define HTABLE_DATA struct ssol_material*
+#include <rsys/hash_table.h>
+
+#define HTABLE_NAME object
+#define HTABLE_KEY size_t
+#define HTABLE_DATA struct ssol_object*
+#include <rsys/hash_table.h>
+
+struct solstice {
+ struct ssol_device* ssol;
+ struct solparser* parser;
+
+ struct htable_material materials;
+ struct htable_object objects;
+};
+
+extern LOCAL_SYM res_T
+solstice_init
+ (struct mem_allocator* allocator, /* May be NULL <=> use default allocator */
+ struct solstice* solstice);
+
+extern LOCAL_SYM void
+solstice_release
+ (struct solstice* solstice);
+
+#endif /* SOLSTICE_H */
+
diff --git a/src/solstice_c.h b/src/solstice_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 SOLSTICE_C_H
+#define SOLSTICE_C_H
+
+#include "solstice.h"
+#include "parser/solparser.h"
+
+extern LOCAL_SYM res_T
+solstice_create_ssol_material
+ (struct solstice* solstice,
+ const struct solparser_material_id mtl_id);
+
+/* Return NULL if the material does not exist */
+static FINLINE struct ssol_material*
+solstice_get_ssol_material
+ (struct solstice* solstice,
+ const struct solparser_material_id mtl_id)
+{
+ struct ssol_material** pmtl;
+ ASSERT(solstice);
+ pmtl = htable_material_find(&solstice->materials, &mtl_id.i);
+ return pmtl ? *pmtl : NULL;
+}
+
+#endif /* SOLSTICE_C_H */
+
diff --git a/src/solstice_material.c b/src/solstice_material.c
@@ -0,0 +1,186 @@
+/* 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 "solstice.h"
+#include "solstice_c.h"
+
+#include <solstice/ssol.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+mirror_get_normal
+ (struct ssol_device* dev,
+ struct ssol_param_buffer* buf,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double Ns[3],
+ const double uv[2],
+ const double w[3],
+ double* val)
+{
+ (void)dev, (void)buf, (void)wavelength, (void)P, (void)Ng, (void)uv, (void)w;
+ val[0] = Ns[0];
+ val[1] = Ns[1];
+ val[2] = Ns[2];
+}
+
+static void
+mirror_get_reflectivity
+ (struct ssol_device* dev,
+ struct ssol_param_buffer* buf,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double Ns[3],
+ const double uv[2],
+ const double w[3],
+ double* val)
+{
+ const void* p;
+ (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
+ SSOL(param_buffer_get(buf, "reflectivity", &p));
+ *val = *(double*)p;
+}
+
+static void
+mirror_get_roughness
+ (struct ssol_device* dev,
+ struct ssol_param_buffer* buf,
+ const double wavelength,
+ const double P[3],
+ const double Ng[3],
+ const double Ns[3],
+ const double uv[2],
+ const double w[3],
+ double* val)
+{
+ const void* p;
+ (void)dev, (void)wavelength, (void)P, (void)Ng, (void)Ns, (void)uv, (void)w;
+ SSOL(param_buffer_get(buf, "roughness", &p));
+ *val = *(double*)p;
+}
+
+static res_T
+create_material_matte
+ (struct solstice* solstice,
+ const struct solparser_material_matte* matte,
+ struct ssol_material** out_mtl)
+{
+ (void)solstice, (void)matte, (void)out_mtl;
+ /* TODO when the matte material will be available in Solstice Solver */
+ return RES_BAD_ARG;
+}
+
+static res_T
+create_material_mirror
+ (struct solstice* solstice,
+ const struct solparser_material_mirror* mirror,
+ struct ssol_material** out_mtl)
+{
+ struct ssol_mirror_shader shader = SSOL_MIRROR_SHADER_NULL;
+ struct ssol_material* mtl = NULL;
+ struct ssol_param_buffer* pbuf = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice && mirror && out_mtl);
+
+ res = ssol_material_create_mirror(solstice->ssol, &mtl);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the Solstice Solver mirror material.\n");
+ goto error;
+ }
+
+ res = ssol_param_buffer_create(solstice->ssol, &pbuf);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not create the Solstice Solver parameter buffer.\n");
+ goto error;
+ }
+
+ res = ssol_param_buffer_set(pbuf, "reflectivity", sizeof(double),
+ ALIGNOF(double), &mirror->reflectivity);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Could not set the mirror reflectivity into the parameter buffer.\n");
+ goto error;
+ }
+
+ res = ssol_param_buffer_set(pbuf, "roughness", sizeof(double),
+ ALIGNOF(double), &mirror->roughness);
+ if(res != RES_OK) {
+ fprintf(stderr,
+ "Could not set the material roughness into the parameter buffer.\n");
+ goto error;
+ }
+
+ shader.normal = mirror_get_normal;
+ shader.reflectivity = mirror_get_reflectivity;
+ shader.roughness = mirror_get_roughness;
+ SSOL(mirror_set_shader(mtl, &shader));
+ SSOL(material_set_param_buffer(mtl, pbuf));
+
+exit:
+ if(pbuf) SSOL(param_buffer_ref_put(pbuf));
+ *out_mtl = mtl;
+ return res;
+error:
+ if(mtl) SSOL(material_ref_put(mtl));
+ goto exit;
+}
+
+/*******************************************************************************
+ * Local functions
+ ******************************************************************************/
+res_T
+solstice_create_ssol_material
+ (struct solstice* solstice,
+ const struct solparser_material_id mtl_id)
+{
+ const struct solparser_material* mtl;
+ const struct solparser_material_matte* matte;
+ const struct solparser_material_mirror* mirror;
+ struct ssol_material* ssol_mtl = NULL;
+ res_T res = RES_OK;
+ ASSERT(solstice);
+
+ mtl = solparser_get_material(solstice->parser, mtl_id);
+ ASSERT(mtl);
+
+ switch(mtl->type) {
+ case SOLPARSER_MATERIAL_MIRROR:
+ mirror = solparser_get_material_mirror(solstice->parser, mtl->data.mirror);
+ res = create_material_mirror(solstice, mirror, &ssol_mtl);
+ break;
+ case SOLPARSER_MATERIAL_MATTE:
+ matte = solparser_get_material_matte(solstice->parser, mtl->data.matte);
+ res = create_material_matte(solstice, matte, &ssol_mtl);
+ default: FATAL("Unreachable code.\n"); break;
+ }
+ if(res != RES_OK) goto error;
+
+ res = htable_material_set(&solstice->materials, &mtl_id.i, &ssol_mtl);
+ if(res != RES_OK) {
+ fprintf(stderr, "Could not register the material into solstice.\n");
+ goto error;
+ }
+
+exit:
+ return res;
+error:
+ if(ssol_mtl) SSOL(material_ref_put(ssol_mtl));
+ goto exit;
+}
+