loader_aw

Load OBJ/MTL file formats
git clone git://git.meso-star.fr/loader_aw.git
Log | Files | Refs | README | LICENSE

test_aw_mtl.c (11864B)


      1 /* Copyright (C) 2014-2017, 2020-2023 Vincent Forest (vaplv@free.fr)
      2  *
      3  * This program is free software: you can redistribute it and/or modify
      4  * it under the terms of the GNU General Public License as published by
      5  * the Free Software Foundation, either version 3 of the License, or
      6  * (at your option) any later version.
      7  *
      8  * This program is distributed in the hope that it will be useful,
      9  * but WITHOUT ANY WARRANTY; without even the implied warranty of
     10  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
     11  * GNU Lesser General Public License for more details.
     12  *
     13  * You should have received a copy of the GNU Lesser General Public License
     14  * along with this program. If not, see <http://www.gnu.org/licenses/>. */
     15 
     16 #include "aw.h"
     17 
     18 #include <rsys/double3.h>
     19 #include <rsys/logger.h>
     20 #include <rsys/mem_allocator.h>
     21 
     22 #include <string.h>
     23 
     24 static void
     25 test_common(struct aw_mtl* mtl)
     26 {
     27   static const char* mtl_common =
     28     "#!\n"
     29     "newmtl my_mtl\n"
     30     "\n"
     31     "Ka 0.0435 0.0436 0.0437\n"
     32     "Kd 0.1086 0.1087 0.1088\n"
     33     "Ks 0 0 0\n"
     34     "Tf xyz 0.987 0.988 0.989\n"
     35     "illum 6\n"
     36     "d -halo 0.66\n"
     37     "Ns 10.0\n"
     38     "sharpness 60\n"
     39     "Ni 1.19713\n"
     40     "\n"
     41     "map_Ka -s 1 1 1 -o 0 0 0 -mm 0 1 chrome.mpc\n"
     42     "map_Kd -s 1 1 1 -o 0 0 0 -mm 0 1 chrome.mpc\n"
     43     "map_Ks -s 1 1 1 -o 0 0 0 -mm 0 1 chrome.mpc\n"
     44     "map_Ns -s 1 1 1 -o 0 0 0 -mm 0 1 wisp.mps\n"
     45     "map_d -s 1 1 1 -o 0 0 0 -mm 0 1 wisp.mps\n"
     46     "disp -s 1 1 .5 wisp.mps\n"
     47     "decal -s 1 1 1 -o 0 0 0 -mm 0 1 sand.mps\n"
     48     "refl -type sphere -mm 0 1 clouds.mpc\n"
     49     "\n"
     50     "bump -s 1 1 1 -o 0 0 0 -bm 1 sand.mpb";
     51   FILE* file;
     52   size_t nmtls;
     53   double tmp[3];
     54   struct aw_material mat;
     55 
     56   CHK(mtl != NULL);
     57 
     58   file = fopen("test_mtl_common.mtl", "w");
     59   CHK(file != NULL);
     60   fwrite(mtl_common, sizeof(char), strlen(mtl_common), file);
     61   CHK(fclose(file) == 0);
     62 
     63   CHK(aw_mtl_load(NULL, NULL) == RES_BAD_ARG);
     64   CHK(aw_mtl_load(mtl, NULL) == RES_BAD_ARG);
     65   CHK(aw_mtl_load(NULL, "test_mtl_common.mtl") == RES_BAD_ARG);
     66   CHK(aw_mtl_load(mtl, "none.mtl") == RES_IO_ERR);
     67   CHK(aw_mtl_load(mtl, "test_mtl_common.mtl") == RES_OK);
     68 
     69   CHK(aw_mtl_get_materials_count(NULL, NULL) == RES_BAD_ARG);
     70   CHK(aw_mtl_get_materials_count(mtl, NULL) == RES_BAD_ARG);
     71   CHK(aw_mtl_get_materials_count(NULL, &nmtls) == RES_BAD_ARG);
     72   CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
     73 
     74   CHK(nmtls == 1);
     75 
     76   CHK(aw_mtl_clear(NULL) == RES_BAD_ARG);
     77   CHK(aw_mtl_clear(mtl) == RES_OK);
     78   CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
     79   CHK(nmtls == 0);
     80 
     81   CHK(aw_mtl_load(mtl, "test_mtl_common.mtl") == RES_OK);
     82 
     83   CHK(aw_mtl_get_material(NULL, 0, &mat) == RES_BAD_ARG);
     84   CHK(aw_mtl_get_material(mtl, SIZE_MAX, &mat) == RES_BAD_ARG);
     85   CHK(aw_mtl_get_material(mtl, 0, NULL) == RES_BAD_ARG);
     86   CHK(aw_mtl_get_material(mtl, 0, &mat) == RES_OK);
     87 
     88   CHK(!strcmp(mat.name, "my_mtl"));
     89   CHK(mat.ambient.color_space == AW_COLOR_RGB);
     90   d3(tmp, 0.0435, 0.0436, 0.0437);
     91   CHK(d3_eq(mat.ambient.value, tmp));
     92 
     93   CHK(mat.diffuse.color_space == AW_COLOR_RGB);
     94   d3(tmp, 0.1086, 0.1087, 0.1088);
     95   CHK(d3_eq(mat.diffuse.value, tmp));
     96 
     97   CHK(mat.specular.color_space == AW_COLOR_RGB);
     98   d3_splat(tmp, 0);
     99   CHK(d3_eq(mat.specular.value, tmp));
    100 
    101   CHK(mat.transmission.color_space == AW_COLOR_XYZ);
    102   d3(tmp, 0.987, 0.988, 0.989);
    103   CHK(d3_eq(mat.transmission.value, tmp));
    104 
    105   CHK(mat.specular_exponent == 10.0);
    106   CHK(mat.refraction_index == 1.19713);
    107   CHK(mat.illumination_model == 6);
    108 
    109   CHK(!strcmp(mat.ambient_map.filename, "chrome.mpc"));
    110   CHK(mat.ambient_map.options_mask == 0);
    111   CHK(mat.ambient_map.image_bias == 0.f);
    112   CHK(mat.ambient_map.image_scale == 1.f);
    113   CHK(d3_eq(mat.ambient_map.texcoord_bias, d3_splat(tmp, 0.0)));
    114   CHK(d3_eq(mat.ambient_map.texcoord_scale, d3_splat(tmp, 1.0)));
    115   CHK(d3_eq(mat.ambient_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
    116 
    117   CHK(!strcmp(mat.diffuse_map.filename, "chrome.mpc"));
    118   CHK(mat.diffuse_map.options_mask == 0);
    119   CHK(mat.diffuse_map.image_bias == 0.f);
    120   CHK(mat.diffuse_map.image_scale == 1.f);
    121   CHK(d3_eq(mat.diffuse_map.texcoord_bias, d3_splat(tmp, 0.0)));
    122   CHK(d3_eq(mat.diffuse_map.texcoord_scale, d3_splat(tmp, 1.0)));
    123   CHK(d3_eq(mat.diffuse_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
    124 
    125   CHK(!strcmp(mat.specular_map.filename, "chrome.mpc"));
    126   CHK(mat.specular_map.options_mask == 0);
    127   CHK(mat.specular_map.image_bias == 0.0);
    128   CHK(mat.specular_map.image_scale == 1.0);
    129   CHK(d3_eq(mat.specular_map.texcoord_bias, d3_splat(tmp, 0.0)));
    130   CHK(d3_eq(mat.specular_map.texcoord_scale, d3_splat(tmp, 1.0)));
    131   CHK(d3_eq(mat.specular_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
    132 
    133   CHK(!strcmp(mat.specular_exponent_map.filename, "wisp.mps"));
    134   CHK(mat.specular_exponent_map.options_mask == 0);
    135   CHK(mat.specular_exponent_map.image_bias == 0.0);
    136   CHK(mat.specular_exponent_map.image_scale == 1.0);
    137   CHK(d3_eq(mat.specular_exponent_map.texcoord_scale, d3_splat(tmp, 1.0)));
    138   CHK(d3_eq(mat.specular_exponent_map.texcoord_bias, d3_splat(tmp, 0.0)));
    139   CHK(d3_eq(mat.specular_exponent_map.texcoord_turbulence, tmp) == 1);
    140   CHK(mat.specular_exponent_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
    141 
    142   CHK(!strcmp(mat.bump_map.filename, "sand.mpb"));
    143   CHK(mat.bump_map.options_mask == 0);
    144   CHK(mat.bump_map.image_bias == 0.0);
    145   CHK(mat.bump_map.image_scale == 1.0);
    146   CHK(d3_eq(mat.bump_map.texcoord_scale, d3_splat(tmp, 1.0)));
    147   CHK(d3_eq(mat.bump_map.texcoord_bias, d3_splat(tmp, 0.0)));
    148   CHK(d3_eq(mat.bump_map.texcoord_turbulence, tmp) == 1);
    149   CHK(mat.bump_map.scalar == AW_MAP_CHANNEL_LUMINANCE);
    150   CHK(mat.bump_map.bump_multiplier == 1.0);
    151 
    152   CHK(aw_mtl_purge(NULL) == RES_BAD_ARG);
    153   CHK(aw_mtl_purge(mtl) == RES_OK);
    154   CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
    155   CHK(nmtls == 0);
    156 }
    157 
    158 static void
    159 test_multiple_materials(struct aw_mtl* mtl)
    160 {
    161   const char* mtl_multi =
    162     "newmtl material_0\n"
    163     "\tNs 8.0\n"
    164     "\tNi 1.5\n"
    165     "\td 1.0\n"
    166     "\tTf 1.0 1 1\n"
    167     "\tillum 2\n"
    168     "\tKa 0 0 0\n"
    169     "\tKd 0.734118\t0.730588 0.674118\n"
    170     "\tKs 0 0 0\n"
    171     "\tmap_Ka my_long_and_verbose_filename_of_a_RED_GREEN_BLUE_1024x64_image.png\n"
    172     "\tmap_Kd tp.png\n"
    173     "\n"
    174     "newmtl textured_material\n"
    175     "Ns 6\n"
    176     "Ni 1.70\n"
    177     "d 1\n"
    178     "Tf 1 1.2 1.3 \n"
    179     "illum 0\n"
    180     "Ka\t\t 0 0 0\n"
    181     "Kd \t 0.734118 0.709412 0.674118\n"
    182     "Ks 0 0 0\n"
    183     "map_Ka\ttex6x6.png\n"
    184     "map_Kd tex6x6.png\n"
    185     "bump -imfchan r -bm 0.2 tex6x6-bump.png\n"
    186     "\n"
    187     "newmtl hello_world\n"
    188     "Ns 8\n"
    189     "Ni 1.5\n"
    190     "d 1\n"
    191     "Tr 0\n"
    192     "Tf 1 1 1\n"
    193     "illum 2\n"
    194     "Ka\t0 \t0\t0000\n"
    195     "Kd 0.546274 0.219608   0.183922\n"
    196     "Ks 2\n";
    197   FILE* file;
    198   size_t nmtls;
    199   double tmp[3];
    200   struct aw_material mat;
    201 
    202   CHK(mtl != NULL);
    203 
    204   file = fopen("test_mtl_multi.mtl", "w+");
    205   CHK(file != NULL);
    206   fwrite(mtl_multi, sizeof(char), strlen(mtl_multi), file);
    207   CHK(fseek(file, 0, SEEK_SET) == 0);
    208 
    209   CHK(aw_mtl_load_stream(NULL, file, NULL) == RES_BAD_ARG);
    210   CHK(aw_mtl_load_stream(mtl, NULL, NULL) == RES_BAD_ARG);
    211   CHK(aw_mtl_load_stream(mtl, file, NULL) == RES_OK);
    212   CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
    213   CHK(nmtls == 3);
    214 
    215   CHK(aw_mtl_get_material(mtl, 0, &mat) == RES_OK);
    216   CHK(!strcmp(mat.name, "material_0"));
    217   CHK(mat.specular_exponent == 8.f);
    218   CHK(mat.refraction_index == 1.5f);
    219   CHK(mat.transmission.color_space == AW_COLOR_RGB);
    220   CHK(d3_eq(mat.transmission.value, d3_splat(tmp, 1.0)));
    221   CHK(mat.illumination_model == 2);
    222   CHK(mat.ambient.color_space == AW_COLOR_RGB);
    223   CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
    224   CHK(mat.diffuse.color_space == AW_COLOR_RGB);
    225   CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.734118, 0.730588, 0.674118)));
    226   CHK(mat.specular.color_space == AW_COLOR_RGB);
    227   CHK(d3_eq(mat.specular.value, d3_splat(tmp, 0.0)));
    228   CHK(!strcmp
    229     (mat.ambient_map.filename,
    230      "my_long_and_verbose_filename_of_a_RED_GREEN_BLUE_1024x64_image.png"));
    231   CHK(mat.ambient_map.options_mask == 0);
    232   CHK(mat.ambient_map.image_bias == 0.0);
    233   CHK(mat.ambient_map.image_scale == 1.0);
    234   CHK(d3_eq(mat.ambient_map.texcoord_bias, d3_splat(tmp, 0.0)));
    235   CHK(d3_eq(mat.ambient_map.texcoord_scale, d3_splat(tmp, 1.0)));
    236   CHK(d3_eq(mat.ambient_map.texcoord_turbulence, d3_splat(tmp, 0.0)));
    237   CHK(mat.ambient_map.resolution == 0);
    238   CHK(!strcmp(mat.diffuse_map.filename, "tp.png"));
    239   CHK(!mat.specular_map.filename);
    240   CHK(!mat.specular_exponent_map.filename);
    241   CHK(!mat.bump_map.filename);
    242 
    243   CHK(aw_mtl_get_material(mtl, 1, &mat) == RES_OK);
    244   CHK(!strcmp(mat.name, "textured_material"));
    245   CHK(mat.specular_exponent == 6.0);
    246   CHK(mat.refraction_index == 1.7);
    247   CHK(mat.transmission.color_space == AW_COLOR_RGB);
    248   CHK(d3_eq(mat.transmission.value, d3(tmp, 1.0, 1.2, 1.3)));
    249   CHK(mat.illumination_model == 0);
    250   CHK(mat.ambient.color_space == AW_COLOR_RGB);
    251   CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
    252   CHK(mat.diffuse.color_space == AW_COLOR_RGB);
    253   CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.734118, 0.709412, 0.674118)));
    254   CHK(mat.specular.color_space == AW_COLOR_RGB);
    255   CHK(d3_eq(mat.specular.value, d3_splat(tmp, 0.0)));
    256   CHK(!strcmp(mat.ambient_map.filename, "tex6x6.png"));
    257   CHK(!strcmp(mat.diffuse_map.filename, "tex6x6.png"));
    258   CHK(!strcmp(mat.bump_map.filename, "tex6x6-bump.png"));
    259   CHK(mat.bump_map.scalar == AW_MAP_CHANNEL_RED);
    260   CHK(mat.bump_map.bump_multiplier == 0.2);
    261   CHK(!mat.specular_exponent_map.filename);
    262 
    263   CHK(aw_mtl_get_material(mtl, 2, &mat) == RES_OK);
    264   CHK(!strcmp(mat.name, "hello_world"));
    265   CHK(mat.specular_exponent == 8.0);
    266   CHK(mat.refraction_index == 1.5);
    267   CHK(mat.transmission.color_space == AW_COLOR_RGB);
    268   CHK(d3_eq(mat.transmission.value, d3_splat(tmp, 1.0)));
    269   CHK(mat.illumination_model == 2);
    270   CHK(mat.ambient.color_space == AW_COLOR_RGB);
    271   CHK(d3_eq(mat.ambient.value, d3_splat(tmp, 0.0)));
    272   CHK(mat.diffuse.color_space == AW_COLOR_RGB);
    273   CHK(d3_eq(mat.diffuse.value, d3(tmp, 0.546274, 0.219608, 0.183922)));
    274   CHK(mat.specular.color_space == AW_COLOR_RGB);
    275   CHK(d3_eq(mat.specular.value, d3_splat(tmp, 2.0)));
    276   CHK(!mat.ambient_map.filename);
    277   CHK(!mat.diffuse_map.filename);
    278   CHK(!mat.bump_map.filename);
    279   CHK(!mat.specular_exponent_map.filename);
    280 
    281   CHK(fclose(file) == 0);
    282 }
    283 
    284 static void
    285 test_unloadable(struct aw_mtl* mtl)
    286 {
    287   const char* mtl0 =
    288     "newmtl material_0\n"
    289     "\tNs 8.0\n"
    290     "\tNii 1.5\n"
    291     "\td 1.0\n"
    292     "\tTf 1.0 1 1\n"
    293     "\tillum 2\n"
    294     "\tKa 0 0 0\n"
    295     "\tmap_Kambient hop.png\n"
    296     "\tKd\n"
    297     "\tKs 0 0 0\n";
    298   FILE* file;
    299   size_t nmtls;
    300 
    301   CHK(mtl != NULL);
    302 
    303   file = fopen("mtl0.mtl", "w");
    304   CHK(file != NULL);
    305   fwrite(mtl0, sizeof(char), strlen(mtl0), file);
    306   CHK(fclose(file) == 0);
    307 
    308   CHK(aw_mtl_load(mtl, "mtl0.mtl") == RES_BAD_ARG);
    309   CHK(aw_mtl_get_materials_count(mtl, &nmtls) == RES_OK);
    310   CHK(nmtls == 0);
    311 }
    312 int
    313 main(int argc, char** argv)
    314 {
    315   struct mem_allocator allocator;
    316   struct aw_mtl* mtl;
    317   (void)argc, (void)argv;
    318 
    319   mem_init_proxy_allocator(&allocator, &mem_default_allocator);
    320 
    321   CHK(aw_mtl_create(LOGGER_DEFAULT, NULL, 1, NULL) == RES_BAD_ARG);
    322   CHK(aw_mtl_create(LOGGER_DEFAULT, &allocator, 1, NULL) == RES_BAD_ARG);
    323   CHK(aw_mtl_create(LOGGER_DEFAULT, NULL, 1, &mtl) == RES_OK);
    324 
    325   CHK(aw_mtl_ref_get(NULL) == RES_BAD_ARG);
    326   CHK(aw_mtl_ref_get(mtl) == RES_OK);
    327   CHK(aw_mtl_ref_put(NULL) == RES_BAD_ARG);
    328   CHK(aw_mtl_ref_put(mtl) == RES_OK);
    329   CHK(aw_mtl_ref_put(mtl) == RES_OK);
    330 
    331   CHK(aw_mtl_create(NULL, &allocator, 1, &mtl) == RES_OK);
    332 
    333   test_common(mtl);
    334   test_multiple_materials(mtl);
    335   test_unloadable(mtl);
    336 
    337   CHK(aw_mtl_ref_put(mtl) == RES_OK);
    338 
    339   if(MEM_ALLOCATED_SIZE(&allocator)) {
    340     char dump[512];
    341     MEM_DUMP(&allocator, dump, sizeof(dump)/sizeof(char));
    342     fprintf(stderr, "%s\n", dump);
    343     FATAL("Memory leaks\n");
    344   }
    345   mem_shutdown_proxy_allocator(&allocator);
    346   CHK(mem_allocated_size() == 0);
    347   return 0;
    348 }
    349