test_s3d_primitive.c (11366B)
1 /* Copyright (C) 2015-2023 |Méso|Star> (contact@meso-star.com) 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 General Public License for more details. 12 * 13 * You should have received a copy of the GNU General Public License 14 * along with this program. If not, see <http://www.gnu.org/licenses/>. */ 15 16 #include "s3d.h" 17 #include "test_s3d_cbox.h" 18 #include "test_s3d_utils.h" 19 20 #include <rsys/float2.h> 21 #include <rsys/float3.h> 22 #include <rsys/math.h> 23 24 static const float plane_verts[] = { 25 0.f, 0.f, 0.f, 26 1.f, 0.f, 0.f, 27 1.f, 1.f, 0.f, 28 0.f, 1.f, 0.f 29 }; 30 static const unsigned plane_nverts = sizeof(plane_verts) / (sizeof(float)*3); 31 32 static const unsigned plane_ids[] = { 0, 1, 2, 2, 3, 0 }; 33 static const unsigned plane_ntris = sizeof(plane_ids) / (sizeof(unsigned)*3); 34 35 static void 36 plane_get_ids(const unsigned itri, unsigned ids[3], void* data) 37 { 38 const unsigned id = itri * 3; 39 (void)data; 40 CHK(ids != NULL); 41 CHK(itri < plane_ntris); 42 ids[0] = plane_ids[id + 0]; 43 ids[1] = plane_ids[id + 1]; 44 ids[2] = plane_ids[id + 2]; 45 } 46 47 static void 48 plane_get_pos(const unsigned ivert, float pos[3], void* data) 49 { 50 const unsigned i = ivert*3; 51 (void)data; 52 CHK(pos != NULL); 53 CHK(ivert < plane_nverts); 54 pos[0] = plane_verts[i + 0]; 55 pos[1] = plane_verts[i + 1]; 56 pos[2] = plane_verts[i + 2]; 57 } 58 59 static void 60 plane_get_uv(const unsigned ivert, float uv[2], void* data) 61 { 62 const unsigned i = ivert*3; 63 (void)data; 64 CHK(uv != NULL); 65 CHK(ivert < plane_nverts); 66 uv[0] = -plane_verts[i + 0]; 67 uv[1] = -plane_verts[i + 1]; 68 } 69 70 int 71 main(int argc, char** argv) 72 { 73 struct mem_allocator allocator; 74 struct s3d_device* dev; 75 struct s3d_scene* scn; 76 struct s3d_scene_view* scnview; 77 struct s3d_shape* walls; 78 struct s3d_shape* plane; 79 struct s3d_attrib attr; 80 struct s3d_primitive prim = S3D_PRIMITIVE_NULL; 81 struct s3d_vertex_data attribs[2]; 82 struct cbox_desc desc; 83 size_t nprims; 84 size_t i; 85 float transform[12]; 86 float vec[3]; 87 float uv[2]; 88 float area; 89 unsigned ntris, nverts; 90 unsigned walls_id; 91 char b; 92 (void)argc, (void)argv; 93 94 mem_init_proxy_allocator(&allocator, &mem_default_allocator); 95 96 CHK(s3d_device_create(NULL, &allocator, 1, &dev) == RES_OK); 97 CHK(s3d_scene_create(dev, &scn) == RES_OK); 98 CHK(s3d_shape_create_mesh(dev, &walls) == RES_OK); 99 CHK(s3d_shape_create_mesh(dev, &plane) == RES_OK); 100 CHK(s3d_shape_get_id(walls, &walls_id) == RES_OK); 101 CHK(s3d_scene_attach_shape(scn, walls) == RES_OK); 102 103 attribs[1].usage = S3D_ATTRIB_0; 104 attribs[1].type = S3D_FLOAT2; 105 attribs[1].get = plane_get_uv; 106 107 attribs[0].usage = S3D_POSITION; 108 attribs[0].type = S3D_FLOAT3; 109 attribs[0].get = cbox_get_position; 110 111 ntris = cbox_walls_ntris; 112 nverts = cbox_walls_nverts; 113 desc.vertices = cbox_walls; 114 desc.indices = cbox_walls_ids; 115 CHK(s3d_mesh_setup_indexed_vertices 116 (walls, ntris, cbox_get_ids, nverts, attribs, 1, &desc) == RES_OK); 117 118 attribs[0].get = plane_get_pos; 119 CHK(s3d_mesh_setup_indexed_vertices 120 (plane, plane_ntris, plane_get_ids, plane_nverts, attribs, 2, NULL) == RES_OK); 121 122 CHK(s3d_scene_view_create(scn, S3D_SAMPLE, &scnview) == RES_OK); 123 CHK(s3d_scene_view_sample(scnview, 0, 0, 0, &prim, uv) == RES_OK); 124 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 125 126 CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL, NULL) == RES_BAD_ARG); 127 CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL, NULL) == RES_BAD_ARG); 128 CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, uv, NULL) == RES_BAD_ARG); 129 CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, uv, NULL) == RES_BAD_ARG); 130 CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL, &attr) == RES_BAD_ARG); 131 CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL, &attr) == RES_BAD_ARG); 132 CHK(s3d_primitive_get_attrib(NULL, S3D_ATTRIBS_COUNT__, uv, &attr) == RES_BAD_ARG); 133 CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIBS_COUNT__, uv, &attr) == RES_BAD_ARG); 134 135 CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, NULL, NULL) == RES_BAD_ARG); 136 CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, NULL, NULL) == RES_BAD_ARG); 137 CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, uv, NULL) == RES_BAD_ARG); 138 CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, uv, NULL) == RES_BAD_ARG); 139 CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, NULL, &attr) == RES_BAD_ARG); 140 CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, NULL, &attr) == RES_BAD_ARG); 141 CHK(s3d_primitive_get_attrib(NULL, S3D_POSITION, uv, &attr) == RES_BAD_ARG); 142 CHK(s3d_primitive_get_attrib(&prim, S3D_POSITION, uv, &attr) == RES_OK); 143 CHK(attr.type == S3D_FLOAT3); 144 CHK(attr.usage == S3D_POSITION); 145 CHK(s3d_primitive_get_attrib(&prim, S3D_GEOMETRY_NORMAL, uv, &attr) == RES_OK); 146 CHK(attr.type == S3D_FLOAT3); 147 CHK(attr.usage == S3D_GEOMETRY_NORMAL); 148 CHK(s3d_primitive_get_attrib(&prim, S3D_ATTRIB_0, uv, &attr) == RES_BAD_ARG); 149 CHK(s3d_primitive_get_attrib(&S3D_PRIMITIVE_NULL, S3D_POSITION, uv, &attr) == RES_BAD_ARG); 150 151 CHK(s3d_primitive_has_attrib(NULL, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG); 152 CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIBS_COUNT__, NULL) == RES_BAD_ARG); 153 CHK(s3d_primitive_has_attrib(NULL, S3D_POSITION, NULL) == RES_BAD_ARG); 154 CHK(s3d_primitive_has_attrib(&prim, S3D_POSITION, NULL) == RES_BAD_ARG); 155 CHK(s3d_primitive_has_attrib(NULL, S3D_ATTRIBS_COUNT__, &b) == RES_BAD_ARG); 156 CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIBS_COUNT__, &b) == RES_BAD_ARG); 157 CHK(s3d_primitive_has_attrib(NULL, S3D_POSITION, &b) == RES_BAD_ARG); 158 CHK(s3d_primitive_has_attrib(&prim, S3D_POSITION, &b) == RES_OK); 159 CHK(b == 1); 160 CHK(s3d_primitive_has_attrib(&prim, S3D_GEOMETRY_NORMAL, &b) == RES_OK); 161 CHK(b == 1); 162 CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_0, &b) == RES_OK); 163 CHK(b == 0); 164 165 CHK(s3d_primitive_get_transform(NULL, NULL) == RES_BAD_ARG); 166 CHK(s3d_primitive_get_transform(&prim, NULL) == RES_BAD_ARG); 167 CHK(s3d_primitive_get_transform(NULL, transform) == RES_BAD_ARG); 168 CHK(s3d_primitive_get_transform(&prim, transform) == RES_OK); 169 CHK(f3_eq(transform + 0, f3(vec, 1.f, 0.f, 0.f)) == 1); 170 CHK(f3_eq(transform + 3, f3(vec, 0.f, 1.f, 0.f)) == 1); 171 CHK(f3_eq(transform + 6, f3(vec, 0.f, 0.f, 1.f)) == 1); 172 CHK(f3_eq(transform + 9, f3(vec, 0.f, 0.f, 0.f)) == 1); 173 174 CHK(s3d_scene_clear(scn) == RES_OK); 175 CHK(s3d_scene_attach_shape(scn, plane) == RES_OK); 176 177 CHK(s3d_scene_view_create(scn, S3D_GET_PRIMITIVE, &scnview) == RES_OK); 178 CHK(s3d_scene_view_primitives_count(scnview, &nprims) == RES_OK); 179 CHK(nprims == 2); 180 CHK(s3d_scene_view_get_primitive(scnview, 0, &prim) == RES_OK); 181 CHK(S3D_PRIMITIVE_EQ(&prim, &S3D_PRIMITIVE_NULL) == 0); 182 CHK(s3d_scene_view_ref_put(scnview) == RES_OK); 183 184 CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_0, &b) == RES_OK); 185 CHK(b == 1); 186 CHK(s3d_primitive_has_attrib(&prim, S3D_ATTRIB_1, &b) == RES_OK); 187 CHK(b == 0); 188 189 CHK(s3d_primitive_compute_area(NULL, NULL) == RES_BAD_ARG); 190 CHK(s3d_primitive_compute_area(&prim, NULL) == RES_BAD_ARG); 191 CHK(s3d_primitive_compute_area(NULL, &area) == RES_BAD_ARG); 192 CHK(s3d_primitive_compute_area(&prim, &area) == RES_OK); 193 CHK(eq_epsf(area, 0.5f, 1.e-6f) == 1); 194 195 CHK(s3d_primitive_sample(NULL, 1.f, 1.f, NULL) == RES_BAD_ARG); 196 CHK(s3d_primitive_sample(&prim, 1.f, 1.f, NULL) == RES_BAD_ARG); 197 CHK(s3d_primitive_sample(NULL, 0.f, 1.f, NULL) == RES_BAD_ARG); 198 CHK(s3d_primitive_sample(&prim, 0.f, 1.f, NULL) == RES_BAD_ARG); 199 CHK(s3d_primitive_sample(NULL, 1.f, 0.f, NULL) == RES_BAD_ARG); 200 CHK(s3d_primitive_sample(&prim, 1.f, 0.f, NULL) == RES_BAD_ARG); 201 CHK(s3d_primitive_sample(NULL, 0.f, 0.f, NULL) == RES_BAD_ARG); 202 CHK(s3d_primitive_sample(&prim, 0.f, 0.f, NULL) == RES_BAD_ARG); 203 CHK(s3d_primitive_sample(NULL, 1.f, 1.f, uv) == RES_BAD_ARG); 204 CHK(s3d_primitive_sample(&prim, 1.f, 1.f, uv) == RES_BAD_ARG); 205 CHK(s3d_primitive_sample(NULL, 0.f, 1.f, uv) == RES_BAD_ARG); 206 CHK(s3d_primitive_sample(&prim, 0.f, 1.f, uv) == RES_BAD_ARG); 207 CHK(s3d_primitive_sample(NULL, 1.f, 0.f, uv) == RES_BAD_ARG); 208 CHK(s3d_primitive_sample(&prim, 1.f, 0.f, uv) == RES_BAD_ARG); 209 CHK(s3d_primitive_sample(NULL, 0.f, 0.f, uv) == RES_BAD_ARG); 210 CHK(s3d_primitive_sample(&prim, 0.f, 0.f, uv) == RES_OK); 211 212 FOR_EACH(i, 0, 4096) { 213 CHK(s3d_primitive_sample 214 (&prim, rand_canonic(), rand_canonic(), uv) == RES_OK); 215 CHK(uv[0] >= 0.f); 216 CHK(uv[0] <= 1.f); 217 CHK(uv[1] >= 0.f); 218 CHK(uv[1] <= 1.f); 219 } 220 221 #define GET_VERTEX_ATTR s3d_triangle_get_vertex_attrib 222 CHK(GET_VERTEX_ATTR(NULL, 3, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG); 223 CHK(GET_VERTEX_ATTR(&prim, 3, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG); 224 CHK(GET_VERTEX_ATTR(NULL, 0, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG); 225 CHK(GET_VERTEX_ATTR(&prim, 0, S3D_GEOMETRY_NORMAL, NULL) == RES_BAD_ARG); 226 CHK(GET_VERTEX_ATTR(NULL, 3, S3D_POSITION, NULL) == RES_BAD_ARG); 227 CHK(GET_VERTEX_ATTR(&prim, 3, S3D_POSITION, NULL) == RES_BAD_ARG); 228 CHK(GET_VERTEX_ATTR(NULL, 0, S3D_POSITION, NULL) == RES_BAD_ARG); 229 CHK(GET_VERTEX_ATTR(&prim, 0, S3D_POSITION, NULL) == RES_BAD_ARG); 230 CHK(GET_VERTEX_ATTR(NULL, 3, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG); 231 CHK(GET_VERTEX_ATTR(&prim, 3, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG); 232 CHK(GET_VERTEX_ATTR(NULL, 0, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG); 233 CHK(GET_VERTEX_ATTR(&prim, 0, S3D_GEOMETRY_NORMAL, &attr) == RES_BAD_ARG); 234 CHK(GET_VERTEX_ATTR(NULL, 3, S3D_POSITION, &attr) == RES_BAD_ARG); 235 CHK(GET_VERTEX_ATTR(&prim, 3, S3D_POSITION, &attr) == RES_BAD_ARG); 236 CHK(GET_VERTEX_ATTR(NULL, 0, S3D_POSITION, &attr) == RES_BAD_ARG); 237 238 CHK(GET_VERTEX_ATTR(&prim, 0, S3D_POSITION, &attr) == RES_OK); 239 CHK(attr.type == S3D_FLOAT3); 240 CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[0]*3, 1.e-6f) == 1); 241 CHK(GET_VERTEX_ATTR(&prim, 1, S3D_POSITION, &attr) == RES_OK); 242 CHK(attr.type == S3D_FLOAT3); 243 CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[1]*3, 1.e-6f) == 1); 244 CHK(GET_VERTEX_ATTR(&prim, 2, S3D_POSITION, &attr) == RES_OK); 245 CHK(attr.type == S3D_FLOAT3); 246 CHK(f3_eq_eps(attr.value, plane_verts + plane_ids[2]*3, 1.e-6f) == 1); 247 248 CHK(GET_VERTEX_ATTR(&prim, 0, S3D_ATTRIB_0, &attr) == RES_OK); 249 CHK(attr.type == S3D_FLOAT2); 250 f2_minus(uv, plane_verts + plane_ids[0]*3); 251 CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1); 252 CHK(GET_VERTEX_ATTR(&prim, 1, S3D_ATTRIB_0, &attr) == RES_OK); 253 CHK(attr.type == S3D_FLOAT2); 254 f2_minus(uv, plane_verts + plane_ids[1]*3); 255 CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1); 256 CHK(GET_VERTEX_ATTR(&prim, 2, S3D_ATTRIB_0, &attr) == RES_OK); 257 CHK(attr.type == S3D_FLOAT2); 258 f2_minus(uv, plane_verts + plane_ids[2]*3); 259 CHK(f2_eq_eps(attr.value, uv, 1.e-6f) == 1); 260 #undef GET_VERTEX_ATTR 261 262 CHK(s3d_device_ref_put(dev) == RES_OK); 263 CHK(s3d_scene_ref_put(scn) == RES_OK); 264 CHK(s3d_shape_ref_put(walls) == RES_OK); 265 CHK(s3d_shape_ref_put(plane) == RES_OK); 266 267 check_memory_allocator(&allocator); 268 mem_shutdown_proxy_allocator(&allocator); 269 CHK(mem_allocated_size() == 0); 270 return 0; 271 } 272