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