solstice

Compute collected power and efficiencies of a solar plant
git clone git://git.meso-star.com/solstice.git
Log | Files | Refs | README | LICENSE

solstice_draw.c (4009B)


      1 /* Copyright (C) 2018-2026 |Meso|Star> (contact@meso-star.com)
      2  * Copyright (C) 2016-2018 CNRS
      3  *
      4  * This program is free software: you can redistribute it and/or modify
      5  * it under the terms of the GNU General Public License as published by
      6  * the Free Software Foundation, either version 3 of the License, or
      7  * (at your option) any later version.
      8  *
      9  * This program is distributed in the hope that it will be useful,
     10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     12  * GNU General Public License for more details.
     13  *
     14  * You should have received a copy of the GNU General Public License
     15  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     16 
     17 #include "solstice_c.h"
     18 
     19 #include <rsys/image.h>
     20 #include <solstice/ssol.h>
     21 
     22 #define SCREEN_GAMMA 2.2
     23 
     24 /*******************************************************************************
     25  * Helper function
     26  ******************************************************************************/
     27 /* Assume that the pixel format of the src is DOUBLE3 and dst is UBYTE3 */
     28 static void
     29 tone_map(const double* src, uint8_t* dst, const size_t count)
     30 {
     31   size_t i;
     32   ASSERT(src && dst && count);
     33   FOR_EACH(i, 0, count) {
     34     double val[3];
     35     val[0] = pow(src[i*3/*#channels*/+0], 1/SCREEN_GAMMA);/* Gamma correction */
     36     val[1] = pow(src[i*3/*#channels*/+1], 1/SCREEN_GAMMA);/* Gamma correction */
     37     val[2] = pow(src[i*3/*#channels*/+2], 1/SCREEN_GAMMA);/* Gamma correction */
     38     val[0] = CLAMP(val[0], 0, 1);
     39     val[1] = CLAMP(val[1], 0, 1);
     40     val[2] = CLAMP(val[2], 0, 1);
     41     dst[i*3/*#channels*/ + 0] = (uint8_t)((val[0]*255) + 0.5/*round*/);
     42     dst[i*3/*#channels*/ + 1] = (uint8_t)((val[1]*255) + 0.5/*round*/);
     43     dst[i*3/*#channels*/ + 2] = (uint8_t)((val[2]*255) + 0.5/*round*/);
     44   }
     45 }
     46 
     47 static void
     48 tone_map_image(const struct ssol_image* img, uint8_t* dst)
     49 {
     50   struct ssol_image_layout layout;
     51   size_t irow = 0;
     52   char* mem;
     53   ASSERT(img && dst);
     54 
     55   SSOL(image_get_layout(img, &layout));
     56   ASSERT(layout.pixel_format == SSOL_PIXEL_DOUBLE3);
     57 
     58   SSOL(image_map(img, &mem));
     59   FOR_EACH(irow, 0, layout.height) {
     60     const void* src_row = ((char*)mem) + layout.offset + irow * layout.row_pitch;
     61     uint8_t* dst_row = dst + irow * layout.width * 3/*#channels*/;
     62     tone_map(src_row, dst_row, layout.width);
     63   }
     64 }
     65 
     66 /*******************************************************************************
     67  * Local functions
     68  ******************************************************************************/
     69 res_T
     70 solstice_draw(struct solstice* solstice)
     71 {
     72   struct ssol_image_layout layout;
     73   struct image img;
     74   size_t pitch;
     75   res_T res = RES_OK;
     76   ASSERT(solstice);
     77 
     78   SSOL(image_get_layout(solstice->framebuffer, &layout));
     79 
     80   pitch = layout.width * sizeof_image_format(IMAGE_RGB8);
     81   image_init(solstice->allocator, &img);
     82   res = image_setup(&img, layout.width, layout.height, pitch, IMAGE_RGB8, NULL);
     83   if(res != RES_OK) {
     84     fprintf(stderr, "Could not allocate the 8-bits image buffer.\n");
     85     res = RES_MEM_ERR;
     86     goto error;
     87   }
     88 
     89   switch(solstice->render_mode) {
     90     case SOLSTICE_ARGS_RENDER_DRAFT:
     91       res = ssol_draw_draft(solstice->scene, solstice->camera, layout.width,
     92         layout.height, solstice->spp, ssol_image_write, solstice->framebuffer);
     93       break;
     94     case SOLSTICE_ARGS_RENDER_PATH_TRACING:
     95       res = ssol_draw_pt(solstice->scene, solstice->camera, layout.width,
     96         layout.height, solstice->spp, solstice->up, ssol_image_write,
     97         solstice->framebuffer);
     98       break;
     99     default: FATAL("Unreachable code.\n");
    100   }
    101   if(res != RES_OK) {
    102     fprintf(stderr, "Rendering error\n");
    103     goto error;
    104   }
    105 
    106   tone_map_image(solstice->framebuffer, (uint8_t*)img.pixels);
    107 
    108   res = image_write_ppm_stream(&img, 0, solstice->output);
    109   if(res != RES_OK) {
    110     fprintf(stderr,
    111       "Could not write the rendered image to the output stream.\n");
    112     goto error;
    113   }
    114 
    115 exit:
    116   image_release(&img);
    117   return res;
    118 error:
    119   goto exit;
    120 }
    121