commit c628c73deac8ebecdb3f3a3322d903c08113af1c
parent 389c9fe6811e0655d250048eeb8f88cd1dcde86c
Author: Vincent Forest <vincent.forest@meso-star.com>
Date: Wed, 8 Mar 2017 15:32:35 +0100
Major refactoring of the draw functions
Provide a ssol_draw_draft and ssol_draw_pt functions.
Diffstat:
11 files changed, 365 insertions(+), 241 deletions(-)
diff --git a/cmake/CMakeLists.txt b/cmake/CMakeLists.txt
@@ -58,6 +58,7 @@ set(SSOL_FILES_SRC
ssol_device.c
ssol_draw.c
ssol_draw_pt.c
+ ssol_draw_draft.c
ssol_estimator.c
ssol_image.c
ssol_material.c
@@ -81,7 +82,7 @@ set(SSOL_FILES_INC
ssol_c.h
ssol_camera.h
ssol_device_c.h
- ssol_draw_pt.h
+ ssol_draw.h
ssol_estimator_c.h
ssol_image_c.h
ssol_material_c.h
@@ -126,15 +127,22 @@ rcmake_setup_devel(solstice-solver SolSolver ${VERSION} solstice/ssol_version.h)
# Add tests
################################################################################
if(NOT NO_TEST)
- function(new_test _name)
- add_executable(${_name}
- ${SSOL_SOURCE_DIR}/${_name}.c)
+ function(build_test _name)
+ add_executable(${_name} ${SSOL_SOURCE_DIR}/${_name}.c)
target_link_libraries(${_name}
solstice-solver solstice-test RSys Star3D StarSP)
- add_test(${_name} ${_name})
+ endfunction()
+
+ function(register_test _name)
+ add_test(${_name} ${ARGN})
rcmake_set_test_runtime_dirs(${_name} _runtime_dirs)
endfunction()
+ function(new_test _name)
+ build_test(${_name})
+ register_test(${_name} ${_name})
+ endfunction()
+
add_library(solstice-test STATIC
${SSOL_SOURCE_DIR}/test_ssol_geometries.h
${SSOL_SOURCE_DIR}/test_ssol_materials.h
@@ -145,7 +153,6 @@ if(NOT NO_TEST)
new_test(test_ssol_by_receiver_integration)
new_test(test_ssol_camera)
new_test(test_ssol_device)
- new_test(test_ssol_draw)
new_test(test_ssol_image)
new_test(test_ssol_material)
new_test(test_ssol_object)
@@ -162,6 +169,10 @@ if(NOT NO_TEST)
new_test(test_ssol_solver5)
new_test(test_ssol_solver6)
new_test(test_ssol_sun)
+
+ build_test(test_ssol_draw)
+ register_test(test_ssol_draw_draft test_ssol_draw draft)
+
endif()
################################################################################
diff --git a/src/ssol.h b/src/ssol.h
@@ -951,7 +951,16 @@ ssol_solve
struct ssol_estimator** estimator);
SSOL_API res_T
-ssol_draw
+ssol_draw_draft
+ (struct ssol_scene* scn,
+ struct ssol_camera* cam,
+ const size_t width, /* #pixels in X */
+ const size_t height, /* #pixels in Y */
+ ssol_write_pixels_T writer,
+ void* writer_data);
+
+SSOL_API res_T
+ssol_draw_pt
(struct ssol_scene* scn,
struct ssol_camera* cam,
const size_t width, /* #pixels in X */
diff --git a/src/ssol_device.c b/src/ssol_device.c
@@ -19,6 +19,7 @@
#include <rsys/logger.h>
#include <rsys/mem_allocator.h>
+#include <star/s3d.h>
#include <star/scpr.h>
#include <omp.h>
diff --git a/src/ssol_device_c.h b/src/ssol_device_c.h
@@ -19,7 +19,6 @@
#include <rsys/dynamic_array.h>
#include <rsys/free_list.h>
#include <rsys/ref_count.h>
-#include <star/s3d.h>
#define DARRAY_NAME byte
#define DARRAY_DATA char
@@ -35,6 +34,7 @@
#include <rsys/dynamic_array.h>
struct scpr_mesh;
+struct s3d_device;
struct ssol_device {
struct logger* logger;
diff --git a/src/ssol_draw.c b/src/ssol_draw.c
@@ -14,19 +14,10 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>. */
#include "ssol.h"
-#include "ssol_c.h"
-#include "ssol_camera.h"
#include "ssol_device_c.h"
-#include "ssol_draw_pt.h"
-#include "ssol_material_c.h"
-#include "ssol_object_c.h"
+#include "ssol_draw.h"
#include "ssol_scene_c.h"
-#include "ssol_shape_c.h"
-#include "ssol_sun_c.h"
-#include <rsys/double2.h>
-#include <rsys/double3.h>
-#include <rsys/math.h>
#include <star/s3d.h>
#include <omp.h>
@@ -51,61 +42,23 @@ morton2D_decode(const uint32_t u32)
}
static void
-Li_basic
- (struct ssol_scene* scn,
- struct s3d_scene_view* view,
- const float org[3],
- const float dir[3],
- double val[3])
-{
- const float range[2] = {0, FLT_MAX};
- struct ray_data ray_data = RAY_DATA_NULL;
- struct s3d_hit hit;
- ASSERT(scn && view && org && dir && val);
-
- ray_data.scn = scn;
- ray_data.discard_virtual_materials = 1;
- S3D(scene_view_trace_ray(view, org, dir, range, &ray_data, &hit));
- if(S3D_HIT_NONE(&hit)) {
- d3_splat(val, 0);
- } else {
- struct ssol_instance* inst;
- const struct shaded_shape* sshape;
- size_t isshape;
- float N[3]={0};
-
- /* Retrieve the hit shaded shape */
- inst = *htable_instance_find(&scn->instances_rt, &hit.prim.inst_id);
- isshape = *htable_shaded_shape_find
- (&inst->object->shaded_shapes_rt, &hit.prim.geom_id);
- sshape = darray_shaded_shape_cdata_get
- (&inst->object->shaded_shapes) + isshape;
-
- /* Retrieve and normalized the hit normal */
- switch(sshape->shape->type) {
- case SHAPE_MESH: f3_normalize(N, hit.normal); break;
- case SHAPE_PUNCHED: f3_normalize(N, f3_set_d3(N, ray_data.N)); break;
- default: FATAL("Unreachable code"); break;
- }
- ASSERT(f3_is_normalized(N));
- d3_splat(val, fabs(f3_dot(N, dir)));
- }
-}
-
-static void
draw_tile
(struct ssol_scene* scn,
- struct draw_pt_thread_context* ctx,
struct s3d_scene_view* view,
const struct ssol_camera* cam,
+ const int ithread,
+ const size_t spp,
const size_t origin[2], /* Tile origin */
const size_t size[2], /* Tile definition */
const float pix_sz[2], /* Normalized size of a pixel in the image plane */
- double* pixels)
+ double* pixels,
+ pixel_shader_T shader,
+ void* shader_data)
{
size_t npixels;
size_t mcode; /* Morton code of the tile pixel */
- ASSERT(scn && ctx && view && cam && origin && size && pix_sz && pixels);
+ ASSERT(scn && view && cam && spp && origin && size && pix_sz && pixels);
+ ASSERT(shader);
/* Adjust the #pixels to process them wrt a morton order */
npixels = round_up_pow2(MMAX(size[0], size[1]));
@@ -124,37 +77,25 @@ draw_tile
ipix[0] = ipix[0] + origin[0];
ipix[1] = ipix[1] + origin[1];
-#if 0
- draw_pt(scn, cam, view, ipix, pix_sz, 64, ctx, pixel);
-#else
- {
- float samp[2];
- float ray_org[3], ray_dir[3];
-
- samp[0] = ((float)ipix[0] + 0.5f) * pix_sz[0];
- samp[1] = ((float)ipix[1] + 0.5f) * pix_sz[1];
- camera_ray(cam, samp, ray_org, ray_dir);
-
- Li_basic(scn, view, ray_org, ray_dir, pixel);
- }
-#endif
+ shader(scn, cam, view, ithread, ipix, pix_sz, spp, pixel, shader_data);
}
}
/*******************************************************************************
- * Exported function
+ * Local function
******************************************************************************/
res_T
-ssol_draw
+draw
(struct ssol_scene* scn,
- struct ssol_camera* cam,
+ const struct ssol_camera* cam,
const size_t width,
const size_t height,
+ const size_t spp, /* #samples per pixel */
ssol_write_pixels_T writer,
- void* data)
+ void* writer_data,
+ pixel_shader_T pixel_shader,
+ void* pixel_shader_data)
{
- struct darray_draw_pt_thread_context thread_ctxs;
- struct ssp_rng_proxy* rng_proxy = NULL;
struct s3d_scene_view* view = NULL;
struct darray_byte* tiles = NULL;
int64_t mcode; /* Morton code of a tile */
@@ -163,32 +104,9 @@ ssol_draw
size_t i;
ATOMIC res = RES_OK;
- if(!scn || !cam || !width || !height || !writer)
+ if(!scn || !cam || !width || !height || !spp || !writer || !pixel_shader)
return RES_BAD_ARG;
- darray_draw_pt_thread_context_init(scn->dev->allocator, &thread_ctxs);
-
- /* Create a RNG proxy */
- res = ssp_rng_proxy_create
- (scn->dev->allocator, &ssp_rng_threefry, scn->dev->nthreads, &rng_proxy);
- if(res != RES_OK) goto error;
-
- /* Create the thread contexts */
- res = darray_draw_pt_thread_context_resize(&thread_ctxs, scn->dev->nthreads);
- if(res != RES_OK) goto error;
- FOR_EACH(i, 0, scn->dev->nthreads) {
- struct draw_pt_thread_context* ctx;
- struct ssp_rng* rng;
-
- ctx = darray_draw_pt_thread_context_data_get(&thread_ctxs)+i;
-
- res = ssp_rng_proxy_create_rng(rng_proxy, i, &rng);
- if(res != RES_OK) goto error;
-
- draw_pt_thread_context_setup(ctx, rng);
- SSP(rng_ref_put(rng));
- }
-
tiles = darray_tile_data_get(&scn->dev->tiles);
ASSERT(darray_tile_size_get(&scn->dev->tiles) == scn->dev->nthreads);
FOR_EACH(i, 0, scn->dev->nthreads) {
@@ -210,7 +128,6 @@ ssol_draw
#pragma omp parallel for schedule(dynamic, 1/*chunck size*/)
for(mcode=0; mcode<(int64_t)ntiles; ++mcode) {
- struct draw_pt_thread_context* ctx;
size_t tile_org[2];
size_t tile_sz[2];
const int ithread = omp_get_thread_num();
@@ -219,8 +136,6 @@ ssol_draw
if(ATOMIC_GET(&res) != RES_OK) continue;
- ctx = darray_draw_pt_thread_context_data_get(&thread_ctxs) + ithread;
-
tile_org[0] = morton2D_decode((uint32_t)(mcode>>0));
if(tile_org[0] >= ntiles_x) continue;
tile_org[1] = morton2D_decode((uint32_t)(mcode>>1));
@@ -233,9 +148,10 @@ ssol_draw
pixels = (double*)darray_byte_data_get(tiles+ithread);
- draw_tile(scn, ctx, view, cam, tile_org, tile_sz, pix_sz, pixels);
+ draw_tile(scn, view, cam, ithread, spp, tile_org, tile_sz, pix_sz, pixels,
+ pixel_shader, pixel_shader_data);
- res_local = writer(data, tile_org, tile_sz, SSOL_PIXEL_DOUBLE3, pixels);
+ res_local = writer(writer_data, tile_org, tile_sz, SSOL_PIXEL_DOUBLE3, pixels);
if(res_local != RES_OK) {
ATOMIC_SET(&res, res_local);
continue;
@@ -243,11 +159,10 @@ ssol_draw
}
exit:
- darray_draw_pt_thread_context_release(&thread_ctxs);
- if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy));
if(view) S3D(scene_view_ref_put(view));
return (res_T)res;
error:
goto exit;
}
+
diff --git a/src/ssol_draw.h b/src/ssol_draw.h
@@ -0,0 +1,52 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * 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_DRAW_H
+#define SSOL_DRAW_H
+
+#include "ssol.h"
+#include <rsys/rsys.h>
+
+/* Forward declarations */
+struct s3d_scene_view;
+struct ssf_bsdf;
+struct ssp_rng;
+
+typedef void
+(*pixel_shader_T)
+ (struct ssol_scene* scn,
+ const struct ssol_camera* cam,
+ struct s3d_scene_view* view,
+ const int ithread, /* Id of the thread invoking the function */
+ const size_t pix_coords[2], /* Image space pixel coordinates */
+ const float pix_sz[2], /* Normalized pixel size */
+ const size_t nsamples, /* #samples per pixel */
+ double pixel[3], /* Output pixel */
+ void* ctx); /* User defined data */
+
+extern LOCAL_SYM res_T
+draw
+ (struct ssol_scene* scn,
+ const struct ssol_camera* cam,
+ const size_t width,
+ const size_t height,
+ const size_t spp,
+ ssol_write_pixels_T writer,
+ void* writer_data,
+ pixel_shader_T pixel_shader,
+ void* pixel_shader_data);
+
+#endif /* SSOL_DRAW_H */
+
diff --git a/src/ssol_draw_draft.c b/src/ssol_draw_draft.c
@@ -0,0 +1,111 @@
+/* Copyright (C) CNRS 2016-2017
+ *
+ * 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_c.h"
+#include "ssol_camera.h"
+#include "ssol_draw.h"
+#include "ssol_object_c.h"
+#include "ssol_scene_c.h"
+#include "ssol_shape_c.h"
+
+#include <rsys/double3.h>
+#include <rsys/float3.h>
+
+#include <float.h>
+
+/*******************************************************************************
+ * Helper functions
+ ******************************************************************************/
+static void
+Li
+ (struct ssol_scene* scn,
+ struct s3d_scene_view* view,
+ const float org[3],
+ const float dir[3],
+ double val[3])
+{
+ const float range[2] = {0, FLT_MAX};
+ struct ray_data ray_data = RAY_DATA_NULL;
+ struct s3d_hit hit;
+ ASSERT(scn && view && org && dir && val);
+
+ ray_data.scn = scn;
+ ray_data.discard_virtual_materials = 1;
+ S3D(scene_view_trace_ray(view, org, dir, range, &ray_data, &hit));
+ if(S3D_HIT_NONE(&hit)) {
+ d3_splat(val, 0);
+ } else {
+ struct ssol_instance* inst;
+ const struct shaded_shape* sshape;
+ size_t isshape;
+ float N[3]={0};
+
+ /* Retrieve the hit shaded shape */
+ inst = *htable_instance_find(&scn->instances_rt, &hit.prim.inst_id);
+ isshape = *htable_shaded_shape_find
+ (&inst->object->shaded_shapes_rt, &hit.prim.geom_id);
+ sshape = darray_shaded_shape_cdata_get
+ (&inst->object->shaded_shapes) + isshape;
+
+ /* Retrieve and normalized the hit normal */
+ switch(sshape->shape->type) {
+ case SHAPE_MESH: f3_normalize(N, hit.normal); break;
+ case SHAPE_PUNCHED: f3_normalize(N, f3_set_d3(N, ray_data.N)); break;
+ default: FATAL("Unreachable code"); break;
+ }
+ ASSERT(f3_is_normalized(N));
+ d3_splat(val, fabs(f3_dot(N, dir)));
+ }
+}
+
+static void
+draw_pixel
+ (struct ssol_scene* scn,
+ const struct ssol_camera* cam,
+ struct s3d_scene_view* view,
+ const int ithread,
+ const size_t pix_coords[2], /* Image space pixel coordinates */
+ const float pix_sz[2], /* Normalized pixel size */
+ const size_t nsamples,
+ double pixel[3],
+ void* ctx)
+{
+ float samp[2];
+ float ray_org[3], ray_dir[3];
+ ASSERT(scn && cam && view && pix_coords && pix_sz && nsamples && pixel);
+ (void)ithread, (void)ctx, (void)nsamples;
+
+ samp[0] = ((float)pix_coords[0] + 0.5f) * pix_sz[0];
+ samp[1] = ((float)pix_coords[1] + 0.5f) * pix_sz[1];
+ camera_ray(cam, samp, ray_org, ray_dir);
+ Li(scn, view, ray_org, ray_dir, pixel);
+}
+
+
+/*******************************************************************************
+ * Exported function
+ ******************************************************************************/
+res_T
+ssol_draw_draft
+ (struct ssol_scene* scn,
+ struct ssol_camera* cam,
+ const size_t width,
+ const size_t height,
+ ssol_write_pixels_T writer,
+ void* data)
+{
+ return draw(scn, cam, width, height, 1, writer, data, draw_pixel, NULL);
+}
+
diff --git a/src/ssol_draw_pt.c b/src/ssol_draw_pt.c
@@ -15,7 +15,8 @@
#include "ssol_c.h"
#include "ssol_camera.h"
-#include "ssol_draw_pt.h"
+#include "ssol_device_c.h"
+#include "ssol_draw.h"
#include "ssol_material_c.h"
#include "ssol_object_c.h"
#include "ssol_scene_c.h"
@@ -33,10 +34,23 @@
/*******************************************************************************
* Per thread draw_pt context
******************************************************************************/
-res_T
-draw_pt_thread_context_init
+struct thread_context {
+ struct ssp_rng* rng;
+ struct ssf_bsdf* bsdf;
+};
+
+static void
+thread_context_release(struct thread_context* ctx)
+{
+ ASSERT(ctx);
+ if(ctx->rng) SSP(rng_ref_put(ctx->rng));
+ if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf));
+}
+
+static res_T
+thread_context_init
(struct mem_allocator* allocator,
- struct draw_pt_thread_context* ctx)
+ struct thread_context* ctx)
{
res_T res = RES_OK;
ASSERT(ctx);
@@ -46,22 +60,13 @@ draw_pt_thread_context_init
exit:
return res;
error:
- draw_pt_thread_context_release(ctx);
+ thread_context_release(ctx);
goto exit;
}
-void
-draw_pt_thread_context_release(struct draw_pt_thread_context* ctx)
-{
- ASSERT(ctx);
- if(ctx->rng) SSP(rng_ref_put(ctx->rng));
- if(ctx->bsdf) SSF(bsdf_ref_put(ctx->bsdf));
-}
-
-
-void
-draw_pt_thread_context_setup
- (struct draw_pt_thread_context* ctx,
+static void
+thread_context_setup
+ (struct thread_context* ctx,
struct ssp_rng* rng)
{
ASSERT(ctx && rng);
@@ -70,6 +75,13 @@ draw_pt_thread_context_setup
ctx->rng = rng;
}
+/* Declare the container of the per thread contexts */
+#define DARRAY_NAME thread_context
+#define DARRAY_DATA struct thread_context
+#define DARRAY_FUNCTOR_INIT thread_context_init
+#define DARRAY_FUNCTOR_RELEASE thread_context_release
+#include <rsys/dynamic_array.h>
+
/*******************************************************************************
* Helper functions
******************************************************************************/
@@ -105,9 +117,8 @@ sun_lighting
}
static void
-Li
- (struct ssol_scene* scn,
- struct draw_pt_thread_context* ctx,
+Li(struct ssol_scene* scn,
+ struct thread_context* ctx,
struct s3d_scene_view* view,
const float org[3],
const float dir[3],
@@ -213,25 +224,28 @@ Li
d3_splat(val, L);
}
-/*******************************************************************************
- * Local function
- ******************************************************************************/
-void
-draw_pt
+static void
+draw_pixel
(struct ssol_scene* scn,
const struct ssol_camera* cam,
struct s3d_scene_view* view,
+ const int ithread,
const size_t pix_coords[2], /* Image space pixel coordinates */
const float pix_sz[2], /* Normalized pixel size */
const size_t nsamples,
- struct draw_pt_thread_context* ctx,
- double pixel[3])
+ double pixel[3],
+ void* data)
{
+ struct darray_thread_context* thread_ctxs = data;
+ struct thread_context* ctx;
double L[3];
size_t isample;
- ASSERT(scn && cam && pix_coords && pix_sz && nsamples && ctx && pixel);
+ ASSERT(scn && cam && pix_coords && pix_sz && nsamples && pixel && ctx);
+ ASSERT((size_t)ithread < darray_thread_context_size_get(thread_ctxs));
+ ctx = darray_thread_context_data_get(thread_ctxs) + ithread;
d3_splat(pixel, 0);
+
FOR_EACH(isample, 0, nsamples) {
float samp[2]; /* Pixel sample */
float ray_org[3], ray_dir[3];
@@ -249,5 +263,60 @@ draw_pt
d3_add(pixel, pixel, L);
}
- d3_divd(pixel, pixel, (double)nsamples);
+ d3_divd(pixel, pixel, (double)nsamples); /* Expected value */
+}
+
+/*******************************************************************************
+ * Exported function
+ ******************************************************************************/
+res_T
+ssol_draw_pt
+ (struct ssol_scene* scn,
+ struct ssol_camera* cam,
+ const size_t width,
+ const size_t height,
+ ssol_write_pixels_T writer,
+ void* data)
+{
+ struct darray_thread_context thread_ctxs;
+ struct ssp_rng_proxy* rng_proxy = NULL;
+ size_t i;
+ res_T res = RES_OK;
+
+ if(!scn)
+ return RES_BAD_ARG;
+
+ darray_thread_context_init(scn->dev->allocator, &thread_ctxs);
+
+ /* Create a RNG proxy */
+ res = ssp_rng_proxy_create
+ (scn->dev->allocator, &ssp_rng_threefry, scn->dev->nthreads, &rng_proxy);
+ if(res != RES_OK) goto error;
+
+ /* Create the thread contexts */
+ res = darray_thread_context_resize(&thread_ctxs, scn->dev->nthreads);
+ if(res != RES_OK) goto error;
+ FOR_EACH(i, 0, scn->dev->nthreads) {
+ struct thread_context* ctx;
+ struct ssp_rng* rng;
+
+ ctx = darray_thread_context_data_get(&thread_ctxs)+i;
+
+ res = ssp_rng_proxy_create_rng(rng_proxy, i, &rng);
+ if(res != RES_OK) goto error;
+
+ thread_context_setup(ctx, rng);
+ SSP(rng_ref_put(rng));
+ }
+
+ /* Invoke the draw process */
+ res = draw(scn, cam, width, height, 4, writer, data, draw_pixel, &thread_ctxs);
+ if(res != RES_OK) goto error;
+
+exit:
+ darray_thread_context_release(&thread_ctxs);
+ if(rng_proxy) SSP(rng_proxy_ref_put(rng_proxy));
+ return (res_T)res;
+error:
+ goto exit;
}
diff --git a/src/ssol_draw_pt.h b/src/ssol_draw_pt.h
@@ -1,66 +0,0 @@
-/* Copyright (C) CNRS 2016-2017
- *
- * 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_DRAW_PT_H
-#define SSOL_DRAW_PT_H
-
-#include <rsys/dynamic_array.h>
-
-/* Forward declarations */
-struct s3d_scene_view;
-struct ssol_camera;
-struct ssol_scene;
-struct ssf_bsdf;
-struct ssp_rng;
-
-struct draw_pt_thread_context {
- struct ssp_rng* rng;
- struct ssf_bsdf* bsdf;
-};
-
-extern LOCAL_SYM res_T
-draw_pt_thread_context_init
- (struct mem_allocator* allocator,
- struct draw_pt_thread_context* ctx);
-
-extern LOCAL_SYM void
-draw_pt_thread_context_release
- (struct draw_pt_thread_context* ctx);
-
-extern LOCAL_SYM void
-draw_pt_thread_context_setup
- (struct draw_pt_thread_context* ctx,
- struct ssp_rng* rng);
-
-/* Declare the container of the per thread contexts */
-#define DARRAY_NAME draw_pt_thread_context
-#define DARRAY_DATA struct draw_pt_thread_context
-#define DARRAY_FUNCTOR_INIT draw_pt_thread_context_init
-#define DARRAY_FUNCTOR_RELEASE draw_pt_thread_context_release
-#include <rsys/dynamic_array.h>
-
-extern LOCAL_SYM void
-draw_pt
- (struct ssol_scene* scn,
- const struct ssol_camera* cam,
- struct s3d_scene_view* view,
- const size_t pix_coords[2],
- const float pix_sz[2],
- const size_t nsamples,
- struct draw_pt_thread_context* ctx,
- double radiance[3]);
-
-#endif /* SSOL_DRAW_PT_H */
-
diff --git a/src/ssol_object.c b/src/ssol_object.c
@@ -18,6 +18,8 @@
#include "ssol_object_c.h"
#include "ssol_shape_c.h"
+#include <star/s3d.h>
+
#include <rsys/ref_count.h>
#include <rsys/rsys.h>
#include <rsys/mem_allocator.h>
diff --git a/src/test_ssol_draw.c b/src/test_ssol_draw.c
@@ -23,6 +23,8 @@
#include <rsys/image.h>
#include <rsys/math.h>
+#include <string.h>
+
#define WIDTH 800
#define HEIGHT 600
#define PITCH (WIDTH*sizeof(unsigned char[3]))
@@ -186,8 +188,26 @@ main(int argc, char** argv)
const double tgt[3] = {278.0, 0.0, 273.0};
const double up[3] = {0.0, 0.0, 1.0};
double dir[3];
+ res_T (*draw_func)
+ (struct ssol_scene* scn,
+ struct ssol_camera* cam,
+ const size_t width,
+ const size_t height,
+ ssol_write_pixels_T writer,
+ void* data);
(void)argc, (void)argv;
+ if(argc <= 1) {
+ fprintf(stderr, "Usage: %s <draft|pt>\n", argv[0]);
+ return -1;
+ }
+
+ if(!strcmp(argv[1], "draft")) {
+ draw_func = ssol_draw_draft;
+ } else if(!strcmp(argv[1], "pt")) {
+ draw_func = ssol_draw_pt;
+ }
+
CHECK(mem_init_proxy_allocator(&allocator, &mem_default_allocator), RES_OK);
CHECK(ssol_device_create
@@ -212,38 +232,38 @@ main(int argc, char** argv)
pixels = MEM_CALLOC(&allocator, HEIGHT, PITCH);
NCHECK(pixels, NULL);
- CHECK(ssol_draw(NULL, NULL, 0, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, 0, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, 0, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, 0, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, WIDTH, WIDTH, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(NULL, cam, WIDTH, WIDTH, write_RGB8, pixels), RES_BAD_ARG);
- CHECK(ssol_draw(scn, cam, WIDTH, HEIGHT, write_RGB8, pixels), RES_OK);
+ CHECK(draw_func(NULL, NULL, 0, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, 0, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, 0, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, 0, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, WIDTH, 0, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, 0, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, WIDTH, WIDTH, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, WIDTH, HEIGHT, NULL, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, 0, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, WIDTH, 0, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, 0, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, NULL, WIDTH, HEIGHT, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(NULL, cam, WIDTH, WIDTH, write_RGB8, pixels), RES_BAD_ARG);
+ CHECK(draw_func(scn, cam, WIDTH, HEIGHT, write_RGB8, pixels), RES_OK);
CHECK(image_ppm_write_stream(stdout, WIDTH, HEIGHT, 3, pixels), RES_OK);