1 /* 2 * Implementation of IDirect3DRMMeshBuilderX and IDirect3DRMMesh interfaces 3 * 4 * Copyright 2010, 2012 Christian Costa 5 * Copyright 2011 André Hentschel 6 * 7 * This library is free software; you can redistribute it and/or 8 * modify it under the terms of the GNU Lesser General Public 9 * License as published by the Free Software Foundation; either 10 * version 2.1 of the License, or (at your option) any later version. 11 * 12 * This library is distributed in the hope that it will be useful, 13 * but WITHOUT ANY WARRANTY; without even the implied warranty of 14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 15 * Lesser General Public License for more details. 16 * 17 * You should have received a copy of the GNU Lesser General Public 18 * License along with this library; if not, write to the Free Software 19 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA 20 */ 21 22 #include "config.h" 23 #include "wine/port.h" 24 25 #include "d3drm_private.h" 26 27 WINE_DEFAULT_DEBUG_CHANNEL(d3drm); 28 29 struct coords_2d 30 { 31 D3DVALUE u; 32 D3DVALUE v; 33 }; 34 35 struct mesh_material 36 { 37 D3DCOLOR color; 38 IDirect3DRMMaterial2 *material; 39 IDirect3DRMTexture3 *texture; 40 }; 41 42 char templates[] = { 43 "xof 0302txt 0064" 44 "template Header" 45 "{" 46 "<3D82AB43-62DA-11CF-AB39-0020AF71E433>" 47 "WORD major;" 48 "WORD minor;" 49 "DWORD flags;" 50 "}" 51 "template Vector" 52 "{" 53 "<3D82AB5E-62DA-11CF-AB39-0020AF71E433>" 54 "FLOAT x;" 55 "FLOAT y;" 56 "FLOAT z;" 57 "}" 58 "template Coords2d" 59 "{" 60 "<F6F23F44-7686-11CF-8F52-0040333594A3>" 61 "FLOAT u;" 62 "FLOAT v;" 63 "}" 64 "template Matrix4x4" 65 "{" 66 "<F6F23F45-7686-11CF-8F52-0040333594A3>" 67 "array FLOAT matrix[16];" 68 "}" 69 "template ColorRGBA" 70 "{" 71 "<35FF44E0-6C7C-11CF-8F52-0040333594A3>" 72 "FLOAT red;" 73 "FLOAT green;" 74 "FLOAT blue;" 75 "FLOAT alpha;" 76 "}" 77 "template ColorRGB" 78 "{" 79 "<D3E16E81-7835-11CF-8F52-0040333594A3>" 80 "FLOAT red;" 81 "FLOAT green;" 82 "FLOAT blue;" 83 "}" 84 "template IndexedColor" 85 "{" 86 "<1630B820-7842-11CF-8F52-0040333594A3>" 87 "DWORD index;" 88 "ColorRGBA indexColor;" 89 "}" 90 "template Boolean" 91 "{" 92 "<537DA6A0-CA37-11D0-941C-0080C80CFA7B>" 93 "DWORD truefalse;" 94 "}" 95 "template Boolean2d" 96 "{" 97 "<4885AE63-78E8-11CF-8F52-0040333594A3>" 98 "Boolean u;" 99 "Boolean v;" 100 "}" 101 "template MaterialWrap" 102 "{" 103 "<4885AE60-78E8-11CF-8F52-0040333594A3>" 104 "Boolean u;" 105 "Boolean v;" 106 "}" 107 "template TextureFilename" 108 "{" 109 "<A42790E1-7810-11CF-8F52-0040333594A3>" 110 "STRING filename;" 111 "}" 112 "template Material" 113 "{" 114 "<3D82AB4D-62DA-11CF-AB39-0020AF71E433>" 115 "ColorRGBA faceColor;" 116 "FLOAT power;" 117 "ColorRGB specularColor;" 118 "ColorRGB emissiveColor;" 119 "[...]" 120 "}" 121 "template MeshFace" 122 "{" 123 "<3D82AB5F-62DA-11CF-AB39-0020AF71E433>" 124 "DWORD nFaceVertexIndices;" 125 "array DWORD faceVertexIndices[nFaceVertexIndices];" 126 "}" 127 "template MeshFaceWraps" 128 "{" 129 "<ED1EC5C0-C0A8-11D0-941C-0080C80CFA7B>" 130 "DWORD nFaceWrapValues;" 131 "array Boolean2d faceWrapValues[nFaceWrapValues];" 132 "}" 133 "template MeshTextureCoords" 134 "{" 135 "<F6F23F40-7686-11CF-8F52-0040333594A3>" 136 "DWORD nTextureCoords;" 137 "array Coords2d textureCoords[nTextureCoords];" 138 "}" 139 "template MeshMaterialList" 140 "{" 141 "<F6F23F42-7686-11CF-8F52-0040333594A3>" 142 "DWORD nMaterials;" 143 "DWORD nFaceIndexes;" 144 "array DWORD faceIndexes[nFaceIndexes];" 145 "[Material]" 146 "}" 147 "template MeshNormals" 148 "{" 149 "<F6F23F43-7686-11CF-8F52-0040333594A3>" 150 "DWORD nNormals;" 151 "array Vector normals[nNormals];" 152 "DWORD nFaceNormals;" 153 "array MeshFace faceNormals[nFaceNormals];" 154 "}" 155 "template MeshVertexColors" 156 "{" 157 "<1630B821-7842-11CF-8F52-0040333594A3>" 158 "DWORD nVertexColors;" 159 "array IndexedColor vertexColors[nVertexColors];" 160 "}" 161 "template Mesh" 162 "{" 163 "<3D82AB44-62DA-11CF-AB39-0020AF71E433>" 164 "DWORD nVertices;" 165 "array Vector vertices[nVertices];" 166 "DWORD nFaces;" 167 "array MeshFace faces[nFaces];" 168 "[...]" 169 "}" 170 "template FrameTransformMatrix" 171 "{" 172 "<F6F23F41-7686-11CF-8F52-0040333594A3>" 173 "Matrix4x4 frameMatrix;" 174 "}" 175 "template Frame" 176 "{" 177 "<3D82AB46-62DA-11CF-AB39-0020AF71E433>" 178 "[...]" 179 "}" 180 "template FloatKeys" 181 "{" 182 "<10DD46A9-775B-11CF-8F52-0040333594A3>" 183 "DWORD nValues;" 184 "array FLOAT values[nValues];" 185 "}" 186 "template TimedFloatKeys" 187 "{" 188 "<F406B180-7B3B-11CF-8F52-0040333594A3>" 189 "DWORD time;" 190 "FloatKeys tfkeys;" 191 "}" 192 "template AnimationKey" 193 "{" 194 "<10DD46A8-775B-11CF-8F52-0040333594A3>" 195 "DWORD keyType;" 196 "DWORD nKeys;" 197 "array TimedFloatKeys keys[nKeys];" 198 "}" 199 "template AnimationOptions" 200 "{" 201 "<E2BF56C0-840F-11CF-8F52-0040333594A3>" 202 "DWORD openclosed;" 203 "DWORD positionquality;" 204 "}" 205 "template Animation" 206 "{" 207 "<3D82AB4F-62DA-11CF-AB39-0020AF71E433>" 208 "[...]" 209 "}" 210 "template AnimationSet" 211 "{" 212 "<3D82AB50-62DA-11CF-AB39-0020AF71E433>" 213 "[Animation]" 214 "}" 215 "template InlineData" 216 "{" 217 "<3A23EEA0-94B1-11D0-AB39-0020AF71E433>" 218 "[BINARY]" 219 "}" 220 "template Url" 221 "{" 222 "<3A23EEA1-94B1-11D0-AB39-0020AF71E433>" 223 "DWORD nUrls;" 224 "array STRING urls[nUrls];" 225 "}" 226 "template ProgressiveMesh" 227 "{" 228 "<8A63C360-997D-11D0-941C-0080C80CFA7B>" 229 "[Url,InlineData]" 230 "}" 231 "template Guid" 232 "{" 233 "<A42790E0-7810-11CF-8F52-0040333594A3>" 234 "DWORD data1;" 235 "WORD data2;" 236 "WORD data3;" 237 "array UCHAR data4[8];" 238 "}" 239 "template StringProperty" 240 "{" 241 "<7F0F21E0-BFE1-11D1-82C0-00A0C9697271>" 242 "STRING key;" 243 "STRING value;" 244 "}" 245 "template PropertyBag" 246 "{" 247 "<7F0F21E1-BFE1-11D1-82C0-00A0C9697271>" 248 "[StringProperty]" 249 "}" 250 "template ExternalVisual" 251 "{" 252 "<98116AA0-BDBA-11D1-82C0-00A0C9697271>" 253 "Guid guidExternalVisual;" 254 "[...]" 255 "}" 256 "template RightHanded" 257 "{" 258 "<7F5D5EA0-D53A-11D1-82C0-00A0C9697271>" 259 "DWORD bRightHanded;" 260 "}" 261 }; 262 263 BOOL d3drm_array_reserve(void **elements, SIZE_T *capacity, SIZE_T element_count, SIZE_T element_size) 264 { 265 SIZE_T new_capacity, max_capacity; 266 void *new_elements; 267 268 if (element_count <= *capacity) 269 return TRUE; 270 271 max_capacity = ~(SIZE_T)0 / element_size; 272 if (max_capacity < element_count) 273 return FALSE; 274 275 new_capacity = max(*capacity, 4); 276 while (new_capacity < element_count && new_capacity <= max_capacity / 2) 277 new_capacity *= 2; 278 279 if (new_capacity < element_count) 280 new_capacity = max_capacity; 281 282 if (!(new_elements = heap_realloc(*elements, new_capacity * element_size))) 283 return FALSE; 284 285 *elements = new_elements; 286 *capacity = new_capacity; 287 return TRUE; 288 } 289 290 static inline struct d3drm_mesh *impl_from_IDirect3DRMMesh(IDirect3DRMMesh *iface) 291 { 292 return CONTAINING_RECORD(iface, struct d3drm_mesh, IDirect3DRMMesh_iface); 293 } 294 295 static inline struct d3drm_mesh_builder *impl_from_IDirect3DRMMeshBuilder2(IDirect3DRMMeshBuilder2 *iface) 296 { 297 return CONTAINING_RECORD(iface, struct d3drm_mesh_builder, IDirect3DRMMeshBuilder2_iface); 298 } 299 300 static inline struct d3drm_mesh_builder *impl_from_IDirect3DRMMeshBuilder3(IDirect3DRMMeshBuilder3 *iface) 301 { 302 return CONTAINING_RECORD(iface, struct d3drm_mesh_builder, IDirect3DRMMeshBuilder3_iface); 303 } 304 305 static inline struct d3drm_wrap *impl_from_IDirect3DRMWrap(IDirect3DRMWrap *iface) 306 { 307 return CONTAINING_RECORD(iface, struct d3drm_wrap, IDirect3DRMWrap_iface); 308 } 309 310 static void clean_mesh_builder_data(struct d3drm_mesh_builder *mesh_builder) 311 { 312 DWORD i; 313 314 IDirect3DRMMeshBuilder3_SetName(&mesh_builder->IDirect3DRMMeshBuilder3_iface, NULL); 315 heap_free(mesh_builder->vertices); 316 mesh_builder->vertices = NULL; 317 mesh_builder->nb_vertices = 0; 318 mesh_builder->vertices_size = 0; 319 heap_free(mesh_builder->normals); 320 mesh_builder->normals = NULL; 321 mesh_builder->nb_normals = 0; 322 mesh_builder->normals_size = 0; 323 heap_free(mesh_builder->pFaceData); 324 mesh_builder->pFaceData = NULL; 325 mesh_builder->face_data_size = 0; 326 mesh_builder->nb_faces = 0; 327 heap_free(mesh_builder->pCoords2d); 328 mesh_builder->pCoords2d = NULL; 329 mesh_builder->nb_coords2d = 0; 330 for (i = 0; i < mesh_builder->nb_materials; i++) 331 { 332 if (mesh_builder->materials[i].material) 333 IDirect3DRMMaterial2_Release(mesh_builder->materials[i].material); 334 if (mesh_builder->materials[i].texture) 335 IDirect3DRMTexture3_Release(mesh_builder->materials[i].texture); 336 } 337 mesh_builder->nb_materials = 0; 338 heap_free(mesh_builder->materials); 339 mesh_builder->materials = NULL; 340 heap_free(mesh_builder->material_indices); 341 mesh_builder->material_indices = NULL; 342 } 343 344 static HRESULT WINAPI d3drm_mesh_builder2_QueryInterface(IDirect3DRMMeshBuilder2 *iface, REFIID riid, void **out) 345 { 346 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 347 348 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 349 350 if (IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder2) 351 || IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder) 352 || IsEqualGUID(riid, &IID_IDirect3DRMVisual) 353 || IsEqualGUID(riid, &IID_IDirect3DRMObject) 354 || IsEqualGUID(riid, &IID_IUnknown)) 355 { 356 *out = &mesh_builder->IDirect3DRMMeshBuilder2_iface; 357 } 358 else if (IsEqualGUID(riid, &IID_IDirect3DRMMeshBuilder3)) 359 { 360 *out = &mesh_builder->IDirect3DRMMeshBuilder3_iface; 361 } 362 else 363 { 364 *out = NULL; 365 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 366 return E_NOINTERFACE; 367 } 368 369 IUnknown_AddRef((IUnknown *)*out); 370 return S_OK; 371 } 372 373 static ULONG WINAPI d3drm_mesh_builder2_AddRef(IDirect3DRMMeshBuilder2 *iface) 374 { 375 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 376 ULONG refcount = InterlockedIncrement(&mesh_builder->ref); 377 378 TRACE("%p increasing refcount to %u.\n", mesh_builder, refcount); 379 380 return refcount; 381 } 382 383 static ULONG WINAPI d3drm_mesh_builder2_Release(IDirect3DRMMeshBuilder2 *iface) 384 { 385 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 386 ULONG refcount = InterlockedDecrement(&mesh_builder->ref); 387 388 TRACE("%p decreasing refcount to %u.\n", mesh_builder, refcount); 389 390 if (!refcount) 391 { 392 d3drm_object_cleanup((IDirect3DRMObject *)iface, &mesh_builder->obj); 393 clean_mesh_builder_data(mesh_builder); 394 if (mesh_builder->material) 395 IDirect3DRMMaterial2_Release(mesh_builder->material); 396 if (mesh_builder->texture) 397 IDirect3DRMTexture3_Release(mesh_builder->texture); 398 IDirect3DRM_Release(mesh_builder->d3drm); 399 heap_free(mesh_builder); 400 } 401 402 return refcount; 403 } 404 405 static HRESULT WINAPI d3drm_mesh_builder2_Clone(IDirect3DRMMeshBuilder2 *iface, 406 IUnknown *outer, REFIID iid, void **out) 407 { 408 FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out); 409 410 return E_NOTIMPL; 411 } 412 413 static HRESULT WINAPI d3drm_mesh_builder2_AddDestroyCallback(IDirect3DRMMeshBuilder2 *iface, 414 D3DRMOBJECTCALLBACK cb, void *ctx) 415 { 416 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 417 418 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 419 420 return IDirect3DRMMeshBuilder3_AddDestroyCallback(&mesh_builder->IDirect3DRMMeshBuilder3_iface, cb, ctx); 421 } 422 423 static HRESULT WINAPI d3drm_mesh_builder2_DeleteDestroyCallback(IDirect3DRMMeshBuilder2 *iface, 424 D3DRMOBJECTCALLBACK cb, void *ctx) 425 { 426 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 427 428 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 429 430 return IDirect3DRMMeshBuilder3_DeleteDestroyCallback(&mesh_builder->IDirect3DRMMeshBuilder3_iface, cb, ctx); 431 } 432 433 static HRESULT WINAPI d3drm_mesh_builder3_SetAppData(IDirect3DRMMeshBuilder3 *iface, DWORD data) 434 { 435 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 436 437 TRACE("iface %p, data %#x.\n", iface, data); 438 439 mesh_builder->obj.appdata = data; 440 441 return D3DRM_OK; 442 } 443 444 static HRESULT WINAPI d3drm_mesh_builder2_SetAppData(IDirect3DRMMeshBuilder2 *iface, DWORD data) 445 { 446 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 447 448 TRACE("iface %p, data %#x.\n", iface, data); 449 450 return d3drm_mesh_builder3_SetAppData(&mesh_builder->IDirect3DRMMeshBuilder3_iface, data); 451 } 452 453 static DWORD WINAPI d3drm_mesh_builder3_GetAppData(IDirect3DRMMeshBuilder3 *iface) 454 { 455 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 456 457 TRACE("iface %p.\n", iface); 458 459 return mesh_builder->obj.appdata; 460 } 461 462 static DWORD WINAPI d3drm_mesh_builder2_GetAppData(IDirect3DRMMeshBuilder2 *iface) 463 { 464 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 465 466 TRACE("iface %p.\n", iface); 467 468 return d3drm_mesh_builder3_GetAppData(&mesh_builder->IDirect3DRMMeshBuilder3_iface); 469 } 470 471 static HRESULT WINAPI d3drm_mesh_builder2_SetName(IDirect3DRMMeshBuilder2 *iface, const char *name) 472 { 473 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 474 475 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 476 477 return IDirect3DRMMeshBuilder3_SetName(&mesh_builder->IDirect3DRMMeshBuilder3_iface, name); 478 } 479 480 static HRESULT WINAPI d3drm_mesh_builder2_GetName(IDirect3DRMMeshBuilder2 *iface, DWORD *size, char *name) 481 { 482 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 483 484 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 485 486 return IDirect3DRMMeshBuilder3_GetName(&mesh_builder->IDirect3DRMMeshBuilder3_iface, size, name); 487 } 488 489 static HRESULT WINAPI d3drm_mesh_builder2_GetClassName(IDirect3DRMMeshBuilder2 *iface, DWORD *size, char *name) 490 { 491 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 492 493 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 494 495 return IDirect3DRMMeshBuilder3_GetClassName(&mesh_builder->IDirect3DRMMeshBuilder3_iface, size, name); 496 } 497 498 static HRESULT WINAPI d3drm_mesh_builder2_Load(IDirect3DRMMeshBuilder2 *iface, void *filename, 499 void *name, D3DRMLOADOPTIONS flags, D3DRMLOADTEXTURECALLBACK cb, void *ctx) 500 { 501 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 502 503 TRACE("iface %p, filename %p, name %p, flags %#x, cb %p, ctx %p.\n", 504 iface, filename, name, flags, cb, ctx); 505 506 if (cb) 507 FIXME("Texture callback is not yet supported\n"); 508 509 return IDirect3DRMMeshBuilder3_Load(&mesh_builder->IDirect3DRMMeshBuilder3_iface, 510 filename, name, flags, NULL, ctx); 511 } 512 513 static HRESULT WINAPI d3drm_mesh_builder2_Save(IDirect3DRMMeshBuilder2 *iface, 514 const char *filename, D3DRMXOFFORMAT format, D3DRMSAVEOPTIONS flags) 515 { 516 FIXME("iface %p, filename %s, format %#x, flags %#x stub!\n", 517 iface, debugstr_a(filename), format, flags); 518 519 return E_NOTIMPL; 520 } 521 522 static HRESULT WINAPI d3drm_mesh_builder2_Scale(IDirect3DRMMeshBuilder2 *iface, 523 D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) 524 { 525 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 526 527 TRACE("iface %p, sx %.8e, sy %.8e, sz %.8e.\n", iface, sx, sy, sz); 528 529 return IDirect3DRMMeshBuilder3_Scale(&mesh_builder->IDirect3DRMMeshBuilder3_iface, sx, sy, sz); 530 } 531 532 static HRESULT WINAPI d3drm_mesh_builder2_Translate(IDirect3DRMMeshBuilder2 *iface, 533 D3DVALUE tx, D3DVALUE ty, D3DVALUE tz) 534 { 535 FIXME("iface %p, tx %.8e, ty %.8e, tz %.8e stub!\n", iface, tx, ty, tz); 536 537 return E_NOTIMPL; 538 } 539 540 static HRESULT WINAPI d3drm_mesh_builder2_SetColorSource(IDirect3DRMMeshBuilder2 *iface, D3DRMCOLORSOURCE source) 541 { 542 FIXME("iface %p, source %#x stub!\n", iface, source); 543 544 return E_NOTIMPL; 545 } 546 547 static HRESULT WINAPI d3drm_mesh_builder2_GetBox(IDirect3DRMMeshBuilder2 *iface, D3DRMBOX *box) 548 { 549 FIXME("iface %p, box %p stub!\n", iface, box); 550 551 return E_NOTIMPL; 552 } 553 554 static HRESULT WINAPI d3drm_mesh_builder2_GenerateNormals(IDirect3DRMMeshBuilder2 *iface) 555 { 556 FIXME("iface %p stub!\n", iface); 557 558 return E_NOTIMPL; 559 } 560 561 static D3DRMCOLORSOURCE WINAPI d3drm_mesh_builder2_GetColorSource(IDirect3DRMMeshBuilder2 *iface) 562 { 563 FIXME("iface %p stub!\n", iface); 564 565 return E_NOTIMPL; 566 } 567 568 static HRESULT WINAPI d3drm_mesh_builder2_AddMesh(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMMesh *mesh) 569 { 570 FIXME("iface %p, mesh %p stub!\n", iface, mesh); 571 572 return E_NOTIMPL; 573 } 574 575 static HRESULT WINAPI d3drm_mesh_builder2_AddMeshBuilder(IDirect3DRMMeshBuilder2 *iface, 576 IDirect3DRMMeshBuilder *mesh_builder) 577 { 578 FIXME("iface %p, mesh_builder %p stub!\n", iface, mesh_builder); 579 580 return E_NOTIMPL; 581 } 582 583 static HRESULT WINAPI d3drm_mesh_builder2_AddFrame(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMFrame *frame) 584 { 585 FIXME("iface %p, frame %p stub!\n", iface, frame); 586 587 return E_NOTIMPL; 588 } 589 590 static HRESULT WINAPI d3drm_mesh_builder2_AddFace(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMFace *face) 591 { 592 FIXME("iface %p, face %p stub!\n", iface, face); 593 594 return E_NOTIMPL; 595 } 596 597 static HRESULT WINAPI d3drm_mesh_builder2_AddFaces(IDirect3DRMMeshBuilder2 *iface, 598 DWORD vertex_count, D3DVECTOR *vertices, DWORD normal_count, D3DVECTOR *normals, 599 DWORD *face_data, IDirect3DRMFaceArray **array) 600 { 601 FIXME("iface %p, vertex_count %u, vertices %p, normal_count %u, normals %p, face_data %p, array %p stub!\n", 602 iface, vertex_count, vertices, normal_count, normals, face_data, array); 603 604 return E_NOTIMPL; 605 } 606 607 static HRESULT WINAPI d3drm_mesh_builder2_ReserveSpace(IDirect3DRMMeshBuilder2 *iface, 608 DWORD vertex_count, DWORD normal_count, DWORD face_count) 609 { 610 FIXME("iface %p, vertex_count %u, normal_count %u, face_count %u stub!\n", 611 iface, vertex_count, normal_count, face_count); 612 613 return E_NOTIMPL; 614 } 615 616 static HRESULT WINAPI d3drm_mesh_builder2_SetColorRGB(IDirect3DRMMeshBuilder2 *iface, 617 D3DVALUE red, D3DVALUE green, D3DVALUE blue) 618 { 619 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 620 621 TRACE("iface %p, red %.8e, green %.8e, blue %.8e.\n", iface, red, green, blue); 622 623 return IDirect3DRMMeshBuilder3_SetColorRGB(&mesh_builder->IDirect3DRMMeshBuilder3_iface, red, green, blue); 624 } 625 626 static HRESULT WINAPI d3drm_mesh_builder2_SetColor(IDirect3DRMMeshBuilder2 *iface, D3DCOLOR color) 627 { 628 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 629 630 TRACE("iface %p, color 0x%08x.\n", iface, color); 631 632 return IDirect3DRMMeshBuilder3_SetColor(&mesh_builder->IDirect3DRMMeshBuilder3_iface, color); 633 } 634 635 static HRESULT WINAPI d3drm_mesh_builder2_SetTexture(IDirect3DRMMeshBuilder2 *iface, 636 IDirect3DRMTexture *texture) 637 { 638 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 639 IDirect3DRMTexture3 *texture3 = NULL; 640 HRESULT hr = D3DRM_OK; 641 642 TRACE("iface %p, texture %p.\n", iface, texture); 643 644 if (texture) 645 hr = IDirect3DRMTexture_QueryInterface(texture, &IID_IDirect3DRMTexture3, (void **)&texture3); 646 if (SUCCEEDED(hr)) 647 hr = IDirect3DRMMeshBuilder3_SetTexture(&mesh_builder->IDirect3DRMMeshBuilder3_iface, texture3); 648 if (texture3) 649 IDirect3DRMTexture3_Release(texture3); 650 651 return hr; 652 } 653 654 static HRESULT WINAPI d3drm_mesh_builder2_SetMaterial(IDirect3DRMMeshBuilder2 *iface, 655 IDirect3DRMMaterial *material) 656 { 657 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 658 659 TRACE("iface %p, material %p.\n", iface, material); 660 661 return IDirect3DRMMeshBuilder3_SetMaterial(&mesh_builder->IDirect3DRMMeshBuilder3_iface, 662 (IDirect3DRMMaterial2 *)material); 663 } 664 665 static HRESULT WINAPI d3drm_mesh_builder2_SetTextureTopology(IDirect3DRMMeshBuilder2 *iface, 666 BOOL wrap_u, BOOL wrap_v) 667 { 668 FIXME("iface %p, wrap_u %#x, wrap_v %#x stub!\n", iface, wrap_u, wrap_v); 669 670 return E_NOTIMPL; 671 } 672 673 static HRESULT WINAPI d3drm_mesh_builder2_SetQuality(IDirect3DRMMeshBuilder2 *iface, 674 D3DRMRENDERQUALITY quality) 675 { 676 FIXME("iface %p, quality %#x stub!\n", iface, quality); 677 678 return E_NOTIMPL; 679 } 680 681 static HRESULT WINAPI d3drm_mesh_builder2_SetPerspective(IDirect3DRMMeshBuilder2 *iface, BOOL enable) 682 { 683 FIXME("iface %p, enable %#x stub!\n", iface, enable); 684 685 return E_NOTIMPL; 686 } 687 688 static HRESULT WINAPI d3drm_mesh_builder2_SetVertex(IDirect3DRMMeshBuilder2 *iface, 689 DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z) 690 { 691 FIXME("iface %p, index %u, x %.8e, y %.8e, z %.8e stub!\n", iface, index, x, y, z); 692 693 return E_NOTIMPL; 694 } 695 696 static HRESULT WINAPI d3drm_mesh_builder2_SetNormal(IDirect3DRMMeshBuilder2 *iface, 697 DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z) 698 { 699 FIXME("iface %p, index %u, x %.8e, y %.8e, z %.8e stub!\n", iface, index, x, y, z); 700 701 return E_NOTIMPL; 702 } 703 704 static HRESULT WINAPI d3drm_mesh_builder2_SetTextureCoordinates(IDirect3DRMMeshBuilder2 *iface, 705 DWORD index, D3DVALUE u, D3DVALUE v) 706 { 707 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 708 709 TRACE("iface %p, index %u, u %.8e, v %.8e.\n", iface, index, u, v); 710 711 return IDirect3DRMMeshBuilder3_SetTextureCoordinates(&mesh_builder->IDirect3DRMMeshBuilder3_iface, 712 index, u, v); 713 } 714 715 static HRESULT WINAPI d3drm_mesh_builder2_SetVertexColor(IDirect3DRMMeshBuilder2 *iface, 716 DWORD index, D3DCOLOR color) 717 { 718 FIXME("iface %p, index %u, color 0x%08x stub!\n", iface, index, color); 719 720 return E_NOTIMPL; 721 } 722 723 static HRESULT WINAPI d3drm_mesh_builder2_SetVertexColorRGB(IDirect3DRMMeshBuilder2 *iface, 724 DWORD index, D3DVALUE red, D3DVALUE green, D3DVALUE blue) 725 { 726 FIXME("iface %p, index %u, red %.8e, green %.8e, blue %.8e stub!\n", 727 iface, index, red, green, blue); 728 729 return E_NOTIMPL; 730 } 731 732 static HRESULT WINAPI d3drm_mesh_builder2_GetFaces(IDirect3DRMMeshBuilder2 *iface, 733 IDirect3DRMFaceArray **array) 734 { 735 FIXME("iface %p, array %p stub!\n", iface, array); 736 737 return E_NOTIMPL; 738 } 739 740 static HRESULT WINAPI d3drm_mesh_builder2_GetVertices(IDirect3DRMMeshBuilder2 *iface, 741 DWORD *vertex_count, D3DVECTOR *vertices, DWORD *normal_count, D3DVECTOR *normals, 742 DWORD *face_data_size, DWORD *face_data) 743 { 744 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 745 746 TRACE("iface %p, vertex_count %p, vertices %p, normal_count %p, normals %p, face_data_size %p, face_data %p.\n", 747 iface, vertex_count, vertices, normal_count, normals, face_data_size, face_data); 748 749 if (vertices && (!vertex_count || (*vertex_count < mesh_builder->nb_vertices))) 750 return D3DRMERR_BADVALUE; 751 if (vertex_count) 752 *vertex_count = mesh_builder->nb_vertices; 753 if (vertices && mesh_builder->nb_vertices) 754 memcpy(vertices, mesh_builder->vertices, mesh_builder->nb_vertices * sizeof(*vertices)); 755 756 if (normals && (!normal_count || (*normal_count < mesh_builder->nb_normals))) 757 return D3DRMERR_BADVALUE; 758 if (normal_count) 759 *normal_count = mesh_builder->nb_normals; 760 if (normals && mesh_builder->nb_normals) 761 memcpy(normals, mesh_builder->normals, mesh_builder->nb_normals * sizeof(*normals)); 762 763 if (face_data && (!face_data_size || (*face_data_size < mesh_builder->face_data_size))) 764 return D3DRMERR_BADVALUE; 765 if (face_data_size) 766 *face_data_size = mesh_builder->face_data_size; 767 if (face_data && mesh_builder->face_data_size) 768 memcpy(face_data, mesh_builder->pFaceData, mesh_builder->face_data_size * sizeof(*face_data)); 769 770 return D3DRM_OK; 771 } 772 773 static HRESULT WINAPI d3drm_mesh_builder2_GetTextureCoordinates(IDirect3DRMMeshBuilder2 *iface, 774 DWORD index, D3DVALUE *u, D3DVALUE *v) 775 { 776 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 777 778 TRACE("iface %p, index %u, u %p, v %p.\n", iface, index, u, v); 779 780 return IDirect3DRMMeshBuilder3_GetTextureCoordinates(&mesh_builder->IDirect3DRMMeshBuilder3_iface, 781 index, u, v); 782 } 783 784 static int WINAPI d3drm_mesh_builder2_AddVertex(IDirect3DRMMeshBuilder2 *iface, 785 D3DVALUE x, D3DVALUE y, D3DVALUE z) 786 { 787 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 788 789 TRACE("iface %p, x %.8e, y %.8e, z %.8e.\n", iface, x, y, z); 790 791 return IDirect3DRMMeshBuilder3_AddVertex(&mesh_builder->IDirect3DRMMeshBuilder3_iface, x, y, z); 792 } 793 794 static int WINAPI d3drm_mesh_builder2_AddNormal(IDirect3DRMMeshBuilder2 *iface, 795 D3DVALUE x, D3DVALUE y, D3DVALUE z) 796 { 797 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 798 799 TRACE("iface %p, x %.8e, y %.8e, z %.8e.\n", iface, x, y, z); 800 801 return IDirect3DRMMeshBuilder3_AddNormal(&mesh_builder->IDirect3DRMMeshBuilder3_iface, x, y, z); 802 } 803 804 static HRESULT WINAPI d3drm_mesh_builder2_CreateFace(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMFace **face) 805 { 806 struct d3drm_face *object; 807 HRESULT hr; 808 809 TRACE("iface %p, face %p.\n", iface, face); 810 811 if (FAILED(hr = d3drm_face_create(&object))) 812 return hr; 813 814 *face = &object->IDirect3DRMFace_iface; 815 816 return S_OK; 817 } 818 819 static D3DRMRENDERQUALITY WINAPI d3drm_mesh_builder2_GetQuality(IDirect3DRMMeshBuilder2 *iface) 820 { 821 FIXME("iface %p stub!\n", iface); 822 823 return 0; 824 } 825 826 static BOOL WINAPI d3drm_mesh_builder2_GetPerspective(IDirect3DRMMeshBuilder2 *iface) 827 { 828 FIXME("iface %p stub!\n", iface); 829 830 return FALSE; 831 } 832 833 static int WINAPI d3drm_mesh_builder2_GetFaceCount(IDirect3DRMMeshBuilder2 *iface) 834 { 835 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 836 837 TRACE("iface %p.\n", iface); 838 839 return mesh_builder->nb_faces; 840 } 841 842 static int WINAPI d3drm_mesh_builder2_GetVertexCount(IDirect3DRMMeshBuilder2 *iface) 843 { 844 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 845 846 TRACE("iface %p.\n", iface); 847 848 return mesh_builder->nb_vertices; 849 } 850 851 static D3DCOLOR WINAPI d3drm_mesh_builder2_GetVertexColor(IDirect3DRMMeshBuilder2 *iface, DWORD index) 852 { 853 FIXME("iface %p, index %u stub!\n", iface, index); 854 855 return 0; 856 } 857 858 static HRESULT WINAPI d3drm_mesh_builder2_CreateMesh(IDirect3DRMMeshBuilder2 *iface, IDirect3DRMMesh **mesh) 859 { 860 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder2(iface); 861 862 TRACE("iface %p, mesh %p.\n", iface, mesh); 863 864 return IDirect3DRMMeshBuilder3_CreateMesh(&mesh_builder->IDirect3DRMMeshBuilder3_iface, mesh); 865 } 866 867 static HRESULT WINAPI d3drm_mesh_builder2_GenerateNormals2(IDirect3DRMMeshBuilder2 *iface, 868 D3DVALUE crease, DWORD flags) 869 { 870 FIXME("iface %p, crease %.8e, flags %#x stub!\n", iface, crease, flags); 871 872 return E_NOTIMPL; 873 } 874 875 static HRESULT WINAPI d3drm_mesh_builder2_GetFace(IDirect3DRMMeshBuilder2 *iface, 876 DWORD index, IDirect3DRMFace **face) 877 { 878 FIXME("iface %p, index %u, face %p stub!\n", iface, index, face); 879 880 return E_NOTIMPL; 881 } 882 883 static const struct IDirect3DRMMeshBuilder2Vtbl d3drm_mesh_builder2_vtbl = 884 { 885 d3drm_mesh_builder2_QueryInterface, 886 d3drm_mesh_builder2_AddRef, 887 d3drm_mesh_builder2_Release, 888 d3drm_mesh_builder2_Clone, 889 d3drm_mesh_builder2_AddDestroyCallback, 890 d3drm_mesh_builder2_DeleteDestroyCallback, 891 d3drm_mesh_builder2_SetAppData, 892 d3drm_mesh_builder2_GetAppData, 893 d3drm_mesh_builder2_SetName, 894 d3drm_mesh_builder2_GetName, 895 d3drm_mesh_builder2_GetClassName, 896 d3drm_mesh_builder2_Load, 897 d3drm_mesh_builder2_Save, 898 d3drm_mesh_builder2_Scale, 899 d3drm_mesh_builder2_Translate, 900 d3drm_mesh_builder2_SetColorSource, 901 d3drm_mesh_builder2_GetBox, 902 d3drm_mesh_builder2_GenerateNormals, 903 d3drm_mesh_builder2_GetColorSource, 904 d3drm_mesh_builder2_AddMesh, 905 d3drm_mesh_builder2_AddMeshBuilder, 906 d3drm_mesh_builder2_AddFrame, 907 d3drm_mesh_builder2_AddFace, 908 d3drm_mesh_builder2_AddFaces, 909 d3drm_mesh_builder2_ReserveSpace, 910 d3drm_mesh_builder2_SetColorRGB, 911 d3drm_mesh_builder2_SetColor, 912 d3drm_mesh_builder2_SetTexture, 913 d3drm_mesh_builder2_SetMaterial, 914 d3drm_mesh_builder2_SetTextureTopology, 915 d3drm_mesh_builder2_SetQuality, 916 d3drm_mesh_builder2_SetPerspective, 917 d3drm_mesh_builder2_SetVertex, 918 d3drm_mesh_builder2_SetNormal, 919 d3drm_mesh_builder2_SetTextureCoordinates, 920 d3drm_mesh_builder2_SetVertexColor, 921 d3drm_mesh_builder2_SetVertexColorRGB, 922 d3drm_mesh_builder2_GetFaces, 923 d3drm_mesh_builder2_GetVertices, 924 d3drm_mesh_builder2_GetTextureCoordinates, 925 d3drm_mesh_builder2_AddVertex, 926 d3drm_mesh_builder2_AddNormal, 927 d3drm_mesh_builder2_CreateFace, 928 d3drm_mesh_builder2_GetQuality, 929 d3drm_mesh_builder2_GetPerspective, 930 d3drm_mesh_builder2_GetFaceCount, 931 d3drm_mesh_builder2_GetVertexCount, 932 d3drm_mesh_builder2_GetVertexColor, 933 d3drm_mesh_builder2_CreateMesh, 934 d3drm_mesh_builder2_GenerateNormals2, 935 d3drm_mesh_builder2_GetFace, 936 }; 937 938 static HRESULT WINAPI d3drm_mesh_builder3_QueryInterface(IDirect3DRMMeshBuilder3 *iface, REFIID riid, void **out) 939 { 940 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 941 942 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 943 944 return d3drm_mesh_builder2_QueryInterface(&mesh_builder->IDirect3DRMMeshBuilder2_iface, riid, out); 945 } 946 947 static ULONG WINAPI d3drm_mesh_builder3_AddRef(IDirect3DRMMeshBuilder3 *iface) 948 { 949 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 950 951 TRACE("iface %p.\n", iface); 952 953 return d3drm_mesh_builder2_AddRef(&mesh_builder->IDirect3DRMMeshBuilder2_iface); 954 } 955 956 static ULONG WINAPI d3drm_mesh_builder3_Release(IDirect3DRMMeshBuilder3 *iface) 957 { 958 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 959 960 TRACE("iface %p.\n", iface); 961 962 return d3drm_mesh_builder2_Release(&mesh_builder->IDirect3DRMMeshBuilder2_iface); 963 } 964 965 static HRESULT WINAPI d3drm_mesh_builder3_Clone(IDirect3DRMMeshBuilder3 *iface, 966 IUnknown *outer, REFIID iid, void **out) 967 { 968 FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out); 969 970 return E_NOTIMPL; 971 } 972 973 static HRESULT WINAPI d3drm_mesh_builder3_AddDestroyCallback(IDirect3DRMMeshBuilder3 *iface, 974 D3DRMOBJECTCALLBACK cb, void *ctx) 975 { 976 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 977 978 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 979 980 return d3drm_object_add_destroy_callback(&mesh_builder->obj, cb, ctx); 981 } 982 983 static HRESULT WINAPI d3drm_mesh_builder3_DeleteDestroyCallback(IDirect3DRMMeshBuilder3 *iface, 984 D3DRMOBJECTCALLBACK cb, void *ctx) 985 { 986 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 987 988 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 989 990 return d3drm_object_delete_destroy_callback(&mesh_builder->obj, cb, ctx); 991 } 992 993 static HRESULT WINAPI d3drm_mesh_builder3_SetName(IDirect3DRMMeshBuilder3 *iface, const char *name) 994 { 995 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 996 997 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 998 999 return d3drm_object_set_name(&mesh_builder->obj, name); 1000 } 1001 1002 static HRESULT WINAPI d3drm_mesh_builder3_GetName(IDirect3DRMMeshBuilder3 *iface, 1003 DWORD *size, char *name) 1004 { 1005 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1006 1007 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 1008 1009 return d3drm_object_get_name(&mesh_builder->obj, size, name); 1010 } 1011 1012 static HRESULT WINAPI d3drm_mesh_builder3_GetClassName(IDirect3DRMMeshBuilder3 *iface, 1013 DWORD *size, char *name) 1014 { 1015 struct d3drm_mesh_builder *meshbuilder = impl_from_IDirect3DRMMeshBuilder3(iface); 1016 1017 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 1018 1019 return d3drm_object_get_class_name(&meshbuilder->obj, size, name); 1020 } 1021 1022 HRESULT load_mesh_data(IDirect3DRMMeshBuilder3 *iface, IDirectXFileData *pData, 1023 D3DRMLOADTEXTURECALLBACK load_texture_proc, void *arg) 1024 { 1025 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1026 IDirectXFileData *pData2 = NULL; 1027 const GUID* guid; 1028 DWORD size; 1029 BYTE *ptr; 1030 HRESULT hr; 1031 HRESULT ret = D3DRMERR_BADOBJECT; 1032 DWORD* faces_vertex_idx_data = NULL; 1033 DWORD* faces_vertex_idx_ptr; 1034 DWORD faces_vertex_idx_size; 1035 DWORD* faces_normal_idx_data = NULL; 1036 DWORD* faces_normal_idx_ptr = NULL; 1037 DWORD* faces_data_ptr; 1038 DWORD faces_data_size = 0; 1039 DWORD i; 1040 1041 TRACE("(%p)->(%p)\n", mesh_builder, pData); 1042 1043 hr = IDirectXFileData_GetName(pData, NULL, &size); 1044 if (hr != DXFILE_OK) 1045 return hr; 1046 if (size) 1047 { 1048 char *name; 1049 1050 if (!(name = heap_alloc(size))) 1051 return E_OUTOFMEMORY; 1052 1053 if (SUCCEEDED(hr = IDirectXFileData_GetName(pData, name, &size))) 1054 IDirect3DRMMeshBuilder3_SetName(iface, name); 1055 heap_free(name); 1056 if (hr != DXFILE_OK) 1057 return hr; 1058 } 1059 1060 TRACE("Mesh name is %s\n", debugstr_a(mesh_builder->obj.name)); 1061 1062 mesh_builder->nb_normals = 0; 1063 1064 hr = IDirectXFileData_GetData(pData, NULL, &size, (void**)&ptr); 1065 if (hr != DXFILE_OK) 1066 goto end; 1067 1068 mesh_builder->nb_vertices = *(DWORD*)ptr; 1069 mesh_builder->nb_faces = *(DWORD*)(ptr + sizeof(DWORD) + mesh_builder->nb_vertices * sizeof(D3DVECTOR)); 1070 faces_vertex_idx_size = size - sizeof(DWORD) - mesh_builder->nb_vertices * sizeof(D3DVECTOR) - sizeof(DWORD); 1071 1072 TRACE("Mesh: nb_vertices = %lu, nb_faces = %d, faces_vertex_idx_size = %d\n", mesh_builder->nb_vertices, 1073 mesh_builder->nb_faces, faces_vertex_idx_size); 1074 1075 if (!d3drm_array_reserve((void **)&mesh_builder->vertices, &mesh_builder->vertices_size, mesh_builder->nb_vertices, 1076 sizeof(*mesh_builder->vertices))) 1077 { 1078 hr = E_OUTOFMEMORY; 1079 goto end; 1080 } 1081 memcpy(mesh_builder->vertices, ptr + sizeof(DWORD), mesh_builder->nb_vertices * sizeof(D3DVECTOR)); 1082 1083 faces_vertex_idx_ptr = faces_vertex_idx_data = heap_alloc(faces_vertex_idx_size); 1084 memcpy(faces_vertex_idx_data, ptr + sizeof(DWORD) + mesh_builder->nb_vertices * sizeof(D3DVECTOR) + sizeof(DWORD), 1085 faces_vertex_idx_size); 1086 1087 /* Each vertex index will have its normal index counterpart so just allocate twice the size */ 1088 mesh_builder->pFaceData = heap_alloc(faces_vertex_idx_size * 2); 1089 faces_data_ptr = (DWORD*)mesh_builder->pFaceData; 1090 1091 while (1) 1092 { 1093 IDirectXFileObject *object; 1094 1095 hr = IDirectXFileData_GetNextObject(pData, &object); 1096 if (hr == DXFILEERR_NOMOREOBJECTS) 1097 { 1098 TRACE("No more object\n"); 1099 break; 1100 } 1101 if (hr != DXFILE_OK) 1102 goto end; 1103 1104 hr = IDirectXFileObject_QueryInterface(object, &IID_IDirectXFileData, (void**)&pData2); 1105 IDirectXFileObject_Release(object); 1106 if (hr != DXFILE_OK) 1107 goto end; 1108 1109 hr = IDirectXFileData_GetType(pData2, &guid); 1110 if (hr != DXFILE_OK) 1111 goto end; 1112 1113 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid)); 1114 1115 if (IsEqualGUID(guid, &TID_D3DRMMeshNormals)) 1116 { 1117 DWORD nb_faces_normals; 1118 DWORD faces_normal_idx_size; 1119 1120 hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr); 1121 if (hr != DXFILE_OK) 1122 goto end; 1123 1124 mesh_builder->nb_normals = *(DWORD*)ptr; 1125 nb_faces_normals = *(DWORD*)(ptr + sizeof(DWORD) + mesh_builder->nb_normals * sizeof(D3DVECTOR)); 1126 1127 TRACE("MeshNormals: nb_normals = %lu, nb_faces_normals = %d\n", mesh_builder->nb_normals, nb_faces_normals); 1128 if (nb_faces_normals != mesh_builder->nb_faces) 1129 WARN("nb_face_normals (%d) != nb_faces (%d)\n", nb_faces_normals, mesh_builder->nb_faces); 1130 1131 if (!d3drm_array_reserve((void **)&mesh_builder->normals, &mesh_builder->normals_size, 1132 mesh_builder->nb_normals, sizeof(*mesh_builder->normals))) 1133 { 1134 hr = E_OUTOFMEMORY; 1135 goto end; 1136 } 1137 memcpy(mesh_builder->normals, ptr + sizeof(DWORD), mesh_builder->nb_normals * sizeof(D3DVECTOR)); 1138 1139 faces_normal_idx_size = size - (2 * sizeof(DWORD) + mesh_builder->nb_normals * sizeof(D3DVECTOR)); 1140 faces_normal_idx_ptr = faces_normal_idx_data = heap_alloc(faces_normal_idx_size); 1141 memcpy(faces_normal_idx_data, ptr + sizeof(DWORD) + mesh_builder->nb_normals * sizeof(D3DVECTOR) 1142 + sizeof(DWORD), faces_normal_idx_size); 1143 } 1144 else if (IsEqualGUID(guid, &TID_D3DRMMeshTextureCoords)) 1145 { 1146 hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr); 1147 if (hr != DXFILE_OK) 1148 goto end; 1149 1150 mesh_builder->nb_coords2d = *(DWORD*)ptr; 1151 1152 TRACE("MeshTextureCoords: nb_coords2d = %d\n", mesh_builder->nb_coords2d); 1153 1154 mesh_builder->pCoords2d = heap_calloc(mesh_builder->nb_coords2d, sizeof(*mesh_builder->pCoords2d)); 1155 memcpy(mesh_builder->pCoords2d, ptr + sizeof(DWORD), mesh_builder->nb_coords2d * sizeof(*mesh_builder->pCoords2d)); 1156 } 1157 else if (IsEqualGUID(guid, &TID_D3DRMMeshMaterialList)) 1158 { 1159 DWORD nb_materials; 1160 DWORD nb_face_indices; 1161 DWORD data_size; 1162 IDirectXFileObject *child; 1163 DWORD i = 0; 1164 float* values; 1165 struct d3drm_texture *texture_object; 1166 1167 TRACE("Process MeshMaterialList\n"); 1168 1169 hr = IDirectXFileData_GetData(pData2, NULL, &size, (void**)&ptr); 1170 if (hr != DXFILE_OK) 1171 goto end; 1172 1173 nb_materials = *(DWORD*)ptr; 1174 nb_face_indices = *(DWORD*)(ptr + sizeof(DWORD)); 1175 data_size = 2 * sizeof(DWORD) + nb_face_indices * sizeof(DWORD); 1176 1177 TRACE("nMaterials = %u, nFaceIndexes = %u\n", nb_materials, nb_face_indices); 1178 1179 if (size != data_size) 1180 WARN("Returned size %u does not match expected one %u\n", size, data_size); 1181 1182 if (!(mesh_builder->material_indices = heap_calloc(nb_face_indices, 1183 sizeof(*mesh_builder->material_indices)))) 1184 goto end; 1185 memcpy(mesh_builder->material_indices, ptr + 2 * sizeof(DWORD), 1186 nb_face_indices * sizeof(*mesh_builder->material_indices)); 1187 1188 if (!(mesh_builder->materials = heap_calloc(nb_materials, sizeof(*mesh_builder->materials)))) 1189 { 1190 heap_free(mesh_builder->material_indices); 1191 goto end; 1192 } 1193 mesh_builder->nb_materials = nb_materials; 1194 1195 while (SUCCEEDED(hr = IDirectXFileData_GetNextObject(pData2, &child)) && (i < nb_materials)) 1196 { 1197 IDirectXFileData *data; 1198 IDirectXFileDataReference *reference; 1199 IDirectXFileObject *material_child; 1200 struct d3drm_material *object; 1201 1202 hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileData, (void **)&data); 1203 if (FAILED(hr)) 1204 { 1205 hr = IDirectXFileObject_QueryInterface(child, &IID_IDirectXFileDataReference, (void **)&reference); 1206 IDirectXFileObject_Release(child); 1207 if (FAILED(hr)) 1208 goto end; 1209 1210 hr = IDirectXFileDataReference_Resolve(reference, &data); 1211 IDirectXFileDataReference_Release(reference); 1212 if (FAILED(hr)) 1213 goto end; 1214 } 1215 else 1216 { 1217 IDirectXFileObject_Release(child); 1218 } 1219 1220 hr = d3drm_material_create(&object, mesh_builder->d3drm); 1221 if (FAILED(hr)) 1222 { 1223 IDirectXFileData_Release(data); 1224 goto end; 1225 } 1226 mesh_builder->materials[i].material = &object->IDirect3DRMMaterial2_iface; 1227 1228 hr = IDirectXFileData_GetData(data, NULL, &size, (void**)&ptr); 1229 if (hr != DXFILE_OK) 1230 { 1231 IDirectXFileData_Release(data); 1232 goto end; 1233 } 1234 1235 if (size != 44) 1236 WARN("Material size %u does not match expected one %u\n", size, 44); 1237 1238 values = (float*)ptr; 1239 1240 d3drm_set_color(&mesh_builder->materials[i].color, values[0], values[1], values[2], values[3]); 1241 1242 IDirect3DRMMaterial2_SetAmbient(mesh_builder->materials[i].material, values[0], values [1], values[2]); /* Alpha ignored */ 1243 IDirect3DRMMaterial2_SetPower(mesh_builder->materials[i].material, values[4]); 1244 IDirect3DRMMaterial2_SetSpecular(mesh_builder->materials[i].material, values[5], values[6], values[7]); 1245 IDirect3DRMMaterial2_SetEmissive(mesh_builder->materials[i].material, values[8], values[9], values[10]); 1246 1247 mesh_builder->materials[i].texture = NULL; 1248 1249 hr = IDirectXFileData_GetNextObject(data, &material_child); 1250 if (hr == S_OK) 1251 { 1252 IDirectXFileData *data; 1253 char **filename; 1254 1255 if (FAILED(hr = IDirectXFileObject_QueryInterface(material_child, 1256 &IID_IDirectXFileData, (void **)&data))) 1257 { 1258 IDirectXFileDataReference *reference; 1259 1260 if (SUCCEEDED(IDirectXFileObject_QueryInterface(material_child, 1261 &IID_IDirectXFileDataReference, (void **)&reference))) 1262 { 1263 hr = IDirectXFileDataReference_Resolve(reference, &data); 1264 IDirectXFileDataReference_Release(reference); 1265 } 1266 } 1267 IDirectXFileObject_Release(material_child); 1268 if (FAILED(hr)) 1269 goto end; 1270 1271 hr = IDirectXFileData_GetType(data, &guid); 1272 if (hr != DXFILE_OK) 1273 goto end; 1274 if (!IsEqualGUID(guid, &TID_D3DRMTextureFilename)) 1275 { 1276 WARN("Not a texture filename\n"); 1277 goto end; 1278 } 1279 1280 size = 4; 1281 hr = IDirectXFileData_GetData(data, NULL, &size, (void**)&filename); 1282 if (SUCCEEDED(hr)) 1283 { 1284 if (load_texture_proc) 1285 { 1286 IDirect3DRMTexture *texture; 1287 1288 hr = load_texture_proc(*filename, arg, &texture); 1289 if (SUCCEEDED(hr)) 1290 { 1291 hr = IDirect3DTexture_QueryInterface(texture, &IID_IDirect3DRMTexture3, 1292 (void **)&mesh_builder->materials[i].texture); 1293 IDirect3DTexture_Release(texture); 1294 } 1295 } 1296 else 1297 { 1298 HANDLE file; 1299 1300 /* If the texture file is not found, no texture is associated with the material */ 1301 file = CreateFileA(*filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL); 1302 if (file != INVALID_HANDLE_VALUE) 1303 { 1304 CloseHandle(file); 1305 if (FAILED(hr = d3drm_texture_create(&texture_object, NULL))) 1306 { 1307 IDirectXFileData_Release(data); 1308 goto end; 1309 } 1310 mesh_builder->materials[i].texture = &texture_object->IDirect3DRMTexture3_iface; 1311 } 1312 } 1313 } 1314 IDirectXFileData_Release(data); 1315 } 1316 else if (hr != DXFILEERR_NOMOREOBJECTS) 1317 { 1318 goto end; 1319 } 1320 hr = S_OK; 1321 1322 IDirectXFileData_Release(data); 1323 i++; 1324 } 1325 if (hr == S_OK) 1326 { 1327 IDirectXFileObject_Release(child); 1328 WARN("Found more sub-objects than expected\n"); 1329 } 1330 else if (hr != DXFILEERR_NOMOREOBJECTS) 1331 { 1332 goto end; 1333 } 1334 hr = S_OK; 1335 } 1336 else 1337 { 1338 FIXME("Unknown GUID %s, ignoring...\n", debugstr_guid(guid)); 1339 } 1340 1341 IDirectXFileData_Release(pData2); 1342 pData2 = NULL; 1343 } 1344 1345 if (!mesh_builder->nb_normals) 1346 { 1347 /* Allocate normals, one per vertex */ 1348 if (!d3drm_array_reserve((void **)&mesh_builder->normals, &mesh_builder->normals_size, 1349 mesh_builder->nb_vertices, sizeof(*mesh_builder->normals))) 1350 goto end; 1351 memset(mesh_builder->normals, 0, mesh_builder->nb_vertices * sizeof(*mesh_builder->normals)); 1352 } 1353 1354 for (i = 0; i < mesh_builder->nb_faces; i++) 1355 { 1356 DWORD j; 1357 DWORD nb_face_indexes; 1358 D3DVECTOR face_normal; 1359 1360 if (faces_vertex_idx_size < sizeof(DWORD)) 1361 WARN("Not enough data to read number of indices of face %d\n", i); 1362 1363 nb_face_indexes = *(faces_data_ptr + faces_data_size++) = *(faces_vertex_idx_ptr++); 1364 faces_vertex_idx_size--; 1365 if (faces_normal_idx_data && (*(faces_normal_idx_ptr++) != nb_face_indexes)) 1366 WARN("Faces indices number mismatch\n"); 1367 1368 if (faces_vertex_idx_size < (nb_face_indexes * sizeof(DWORD))) 1369 WARN("Not enough data to read all indices of face %d\n", i); 1370 1371 if (!mesh_builder->nb_normals) 1372 { 1373 /* Compute face normal */ 1374 if (nb_face_indexes > 2 1375 && faces_vertex_idx_ptr[0] < mesh_builder->nb_vertices 1376 && faces_vertex_idx_ptr[1] < mesh_builder->nb_vertices 1377 && faces_vertex_idx_ptr[2] < mesh_builder->nb_vertices) 1378 { 1379 D3DVECTOR a, b; 1380 1381 D3DRMVectorSubtract(&a, &mesh_builder->vertices[faces_vertex_idx_ptr[2]], &mesh_builder->vertices[faces_vertex_idx_ptr[1]]); 1382 D3DRMVectorSubtract(&b, &mesh_builder->vertices[faces_vertex_idx_ptr[0]], &mesh_builder->vertices[faces_vertex_idx_ptr[1]]); 1383 D3DRMVectorCrossProduct(&face_normal, &a, &b); 1384 D3DRMVectorNormalize(&face_normal); 1385 } 1386 else 1387 { 1388 face_normal.u1.x = 0.0f; 1389 face_normal.u2.y = 0.0f; 1390 face_normal.u3.z = 0.0f; 1391 } 1392 } 1393 1394 for (j = 0; j < nb_face_indexes; j++) 1395 { 1396 /* Copy vertex index */ 1397 *(faces_data_ptr + faces_data_size++) = *faces_vertex_idx_ptr; 1398 /* Copy normal index */ 1399 if (mesh_builder->nb_normals) 1400 { 1401 /* Read from x file */ 1402 *(faces_data_ptr + faces_data_size++) = *(faces_normal_idx_ptr++); 1403 } 1404 else 1405 { 1406 DWORD vertex_idx = *faces_vertex_idx_ptr; 1407 if (vertex_idx >= mesh_builder->nb_vertices) 1408 { 1409 WARN("Found vertex index %u but only %lu vertices available => use index 0\n", vertex_idx, 1410 mesh_builder->nb_vertices); 1411 vertex_idx = 0; 1412 } 1413 *(faces_data_ptr + faces_data_size++) = vertex_idx; 1414 /* Add face normal to vertex normal */ 1415 D3DRMVectorAdd(&mesh_builder->normals[vertex_idx], &mesh_builder->normals[vertex_idx], &face_normal); 1416 } 1417 faces_vertex_idx_ptr++; 1418 } 1419 faces_vertex_idx_size -= nb_face_indexes; 1420 } 1421 1422 /* Last DWORD must be 0 */ 1423 *(faces_data_ptr + faces_data_size++) = 0; 1424 1425 /* Set size (in number of DWORD) of all faces data */ 1426 mesh_builder->face_data_size = faces_data_size; 1427 1428 if (!mesh_builder->nb_normals) 1429 { 1430 /* Normalize all normals */ 1431 for (i = 0; i < mesh_builder->nb_vertices; i++) 1432 { 1433 D3DRMVectorNormalize(&mesh_builder->normals[i]); 1434 } 1435 mesh_builder->nb_normals = mesh_builder->nb_vertices; 1436 } 1437 1438 /* If there is no texture coordinates, generate default texture coordinates (0.0f, 0.0f) for each vertex */ 1439 if (!mesh_builder->pCoords2d) 1440 { 1441 mesh_builder->nb_coords2d = mesh_builder->nb_vertices; 1442 mesh_builder->pCoords2d = heap_calloc(mesh_builder->nb_coords2d, sizeof(*mesh_builder->pCoords2d)); 1443 for (i = 0; i < mesh_builder->nb_coords2d; ++i) 1444 { 1445 mesh_builder->pCoords2d[i].u = 0.0f; 1446 mesh_builder->pCoords2d[i].v = 0.0f; 1447 } 1448 } 1449 1450 TRACE("Mesh data loaded successfully\n"); 1451 1452 ret = D3DRM_OK; 1453 1454 end: 1455 1456 heap_free(faces_normal_idx_data); 1457 heap_free(faces_vertex_idx_data); 1458 1459 return ret; 1460 } 1461 1462 static HRESULT WINAPI d3drm_mesh_builder3_Load(IDirect3DRMMeshBuilder3 *iface, void *filename, 1463 void *name, D3DRMLOADOPTIONS loadflags, D3DRMLOADTEXTURE3CALLBACK cb, void *arg) 1464 { 1465 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1466 DXFILELOADOPTIONS load_options; 1467 IDirectXFile *dxfile = NULL; 1468 IDirectXFileEnumObject *enum_object = NULL; 1469 IDirectXFileData *data = NULL; 1470 const GUID* guid; 1471 DWORD size; 1472 struct d3drm_file_header *header; 1473 HRESULT hr; 1474 HRESULT ret = D3DRMERR_BADOBJECT; 1475 1476 TRACE("iface %p, filename %p, name %p, loadflags %#x, cb %p, arg %p.\n", 1477 iface, filename, name, loadflags, cb, arg); 1478 1479 clean_mesh_builder_data(mesh_builder); 1480 1481 if (loadflags == D3DRMLOAD_FROMMEMORY) 1482 { 1483 load_options = DXFILELOAD_FROMMEMORY; 1484 } 1485 else if (loadflags == D3DRMLOAD_FROMFILE) 1486 { 1487 load_options = DXFILELOAD_FROMFILE; 1488 TRACE("Loading from file %s\n", debugstr_a(filename)); 1489 } 1490 else 1491 { 1492 FIXME("Load options %d not supported yet\n", loadflags); 1493 return E_NOTIMPL; 1494 } 1495 1496 hr = DirectXFileCreate(&dxfile); 1497 if (hr != DXFILE_OK) 1498 goto end; 1499 1500 hr = IDirectXFile_RegisterTemplates(dxfile, templates, strlen(templates)); 1501 if (hr != DXFILE_OK) 1502 goto end; 1503 1504 hr = IDirectXFile_CreateEnumObject(dxfile, filename, load_options, &enum_object); 1505 if (hr != DXFILE_OK) 1506 goto end; 1507 1508 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data); 1509 if (hr != DXFILE_OK) 1510 goto end; 1511 1512 hr = IDirectXFileData_GetType(data, &guid); 1513 if (hr != DXFILE_OK) 1514 goto end; 1515 1516 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid)); 1517 1518 if (!IsEqualGUID(guid, &TID_DXFILEHeader)) 1519 { 1520 ret = D3DRMERR_BADFILE; 1521 goto end; 1522 } 1523 1524 hr = IDirectXFileData_GetData(data, NULL, &size, (void**)&header); 1525 if ((hr != DXFILE_OK) || (size != sizeof(*header))) 1526 goto end; 1527 1528 TRACE("Version is %u.%u, flags %#x.\n", header->major, header->minor, header->flags); 1529 1530 /* Version must be 1.0.x */ 1531 if ((header->major != 1) || (header->minor != 0)) 1532 { 1533 ret = D3DRMERR_BADFILE; 1534 goto end; 1535 } 1536 1537 IDirectXFileData_Release(data); 1538 data = NULL; 1539 1540 hr = IDirectXFileEnumObject_GetNextDataObject(enum_object, &data); 1541 if (hr != DXFILE_OK) 1542 { 1543 ret = D3DRMERR_NOTFOUND; 1544 goto end; 1545 } 1546 1547 hr = IDirectXFileData_GetType(data, &guid); 1548 if (hr != DXFILE_OK) 1549 goto end; 1550 1551 TRACE("Found object type whose GUID = %s\n", debugstr_guid(guid)); 1552 1553 if (!IsEqualGUID(guid, &TID_D3DRMMesh)) 1554 { 1555 ret = D3DRMERR_NOTFOUND; 1556 goto end; 1557 } 1558 1559 /* We don't care about the texture interface version since we rely on QueryInterface */ 1560 hr = load_mesh_data(iface, data, (D3DRMLOADTEXTURECALLBACK)cb, arg); 1561 if (hr == S_OK) 1562 ret = D3DRM_OK; 1563 1564 end: 1565 1566 if (data) 1567 IDirectXFileData_Release(data); 1568 if (enum_object) 1569 IDirectXFileEnumObject_Release(enum_object); 1570 if (dxfile) 1571 IDirectXFile_Release(dxfile); 1572 1573 if (ret != D3DRM_OK) 1574 clean_mesh_builder_data(mesh_builder); 1575 1576 return ret; 1577 } 1578 1579 static HRESULT WINAPI d3drm_mesh_builder3_Save(IDirect3DRMMeshBuilder3 *iface, 1580 const char *filename, D3DRMXOFFORMAT format, D3DRMSAVEOPTIONS flags) 1581 { 1582 FIXME("iface %p, filename %s, format %#x, flags %#x stub!\n", 1583 iface, debugstr_a(filename), format, flags); 1584 1585 return E_NOTIMPL; 1586 } 1587 1588 static HRESULT WINAPI d3drm_mesh_builder3_Scale(IDirect3DRMMeshBuilder3 *iface, 1589 D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) 1590 { 1591 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1592 DWORD i; 1593 1594 TRACE("iface %p, sx %.8e, sy %.8e, sz %.8e.\n", iface, sx, sy, sz); 1595 1596 for (i = 0; i < mesh_builder->nb_vertices; ++i) 1597 { 1598 mesh_builder->vertices[i].u1.x *= sx; 1599 mesh_builder->vertices[i].u2.y *= sy; 1600 mesh_builder->vertices[i].u3.z *= sz; 1601 } 1602 1603 /* Normals are not affected by Scale */ 1604 1605 return D3DRM_OK; 1606 } 1607 1608 static HRESULT WINAPI d3drm_mesh_builder3_Translate(IDirect3DRMMeshBuilder3 *iface, 1609 D3DVALUE tx, D3DVALUE ty, D3DVALUE tz) 1610 { 1611 FIXME("iface %p, tx %.8e, ty %.8e, tz %.8e stub!\n", iface, tx, ty, tz); 1612 1613 return E_NOTIMPL; 1614 } 1615 1616 static HRESULT WINAPI d3drm_mesh_builder3_SetColorSource(IDirect3DRMMeshBuilder3 *iface, 1617 D3DRMCOLORSOURCE source) 1618 { 1619 FIXME("iface %p, source %#x stub!\n", iface, source); 1620 1621 return E_NOTIMPL; 1622 } 1623 1624 static HRESULT WINAPI d3drm_mesh_builder3_GetBox(IDirect3DRMMeshBuilder3 *iface, D3DRMBOX *box) 1625 { 1626 FIXME("iface %p, box %p stub!\n", iface, box); 1627 1628 return E_NOTIMPL; 1629 } 1630 1631 static HRESULT WINAPI d3drm_mesh_builder3_GenerateNormals(IDirect3DRMMeshBuilder3 *iface, 1632 D3DVALUE crease, DWORD flags) 1633 { 1634 FIXME("iface %p, crease %.8e, flags %#x stub!\n", iface, crease, flags); 1635 1636 return E_NOTIMPL; 1637 } 1638 1639 static D3DRMCOLORSOURCE WINAPI d3drm_mesh_builder3_GetColorSource(IDirect3DRMMeshBuilder3 *iface) 1640 { 1641 FIXME("iface %p stub!\n", iface); 1642 1643 return E_NOTIMPL; 1644 } 1645 1646 static HRESULT WINAPI d3drm_mesh_builder3_AddMesh(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMMesh *mesh) 1647 { 1648 FIXME("iface %p, mesh %p stub!\n", iface, mesh); 1649 1650 return E_NOTIMPL; 1651 } 1652 1653 static HRESULT WINAPI d3drm_mesh_builder3_AddMeshBuilder(IDirect3DRMMeshBuilder3 *iface, 1654 IDirect3DRMMeshBuilder3 *mesh_builder, DWORD flags) 1655 { 1656 FIXME("iface %p, mesh_builder %p, flags %#x stub!\n", iface, mesh_builder, flags); 1657 1658 return E_NOTIMPL; 1659 } 1660 1661 static HRESULT WINAPI d3drm_mesh_builder3_AddFrame(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMFrame3 *frame) 1662 { 1663 FIXME("iface %p, frame %p stub!\n", iface, frame); 1664 1665 return E_NOTIMPL; 1666 } 1667 1668 static HRESULT WINAPI d3drm_mesh_builder3_AddFace(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMFace2 *face) 1669 { 1670 FIXME("iface %p, face %p stub!\n", iface, face); 1671 1672 return E_NOTIMPL; 1673 } 1674 1675 static HRESULT WINAPI d3drm_mesh_builder3_AddFaces(IDirect3DRMMeshBuilder3 *iface, 1676 DWORD vertex_count, D3DVECTOR *vertices, DWORD normal_count, D3DVECTOR *normals, 1677 DWORD *face_data, IDirect3DRMFaceArray **array) 1678 { 1679 FIXME("iface %p, vertex_count %u, vertices %p, normal_count %u, normals %p, face_data %p array %p stub!\n", 1680 iface, vertex_count, vertices, normal_count, normals, face_data, array); 1681 1682 return E_NOTIMPL; 1683 } 1684 1685 static HRESULT WINAPI d3drm_mesh_builder3_ReserveSpace(IDirect3DRMMeshBuilder3 *iface, 1686 DWORD vertex_count, DWORD normal_count, DWORD face_count) 1687 { 1688 FIXME("iface %p, vertex_count %u, normal_count %u, face_count %u stub!\n", 1689 iface, vertex_count, normal_count, face_count); 1690 1691 return E_NOTIMPL; 1692 } 1693 1694 static HRESULT WINAPI d3drm_mesh_builder3_SetColorRGB(IDirect3DRMMeshBuilder3 *iface, 1695 D3DVALUE red, D3DVALUE green, D3DVALUE blue) 1696 { 1697 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1698 1699 TRACE("iface %p, red %.8e, green %.8e, blue %.8e.\n", iface, red, green, blue); 1700 1701 d3drm_set_color(&mesh_builder->color, red, green, blue, 1.0f); 1702 1703 return D3DRM_OK; 1704 } 1705 1706 static HRESULT WINAPI d3drm_mesh_builder3_SetColor(IDirect3DRMMeshBuilder3 *iface, D3DCOLOR color) 1707 { 1708 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1709 1710 TRACE("iface %p, color 0x%08x.\n", iface, color); 1711 1712 mesh_builder->color = color; 1713 1714 return D3DRM_OK; 1715 } 1716 1717 static HRESULT WINAPI d3drm_mesh_builder3_SetTexture(IDirect3DRMMeshBuilder3 *iface, 1718 IDirect3DRMTexture3 *texture) 1719 { 1720 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1721 1722 TRACE("iface %p, texture %p.\n", iface, texture); 1723 1724 if (texture) 1725 IDirect3DRMTexture3_AddRef(texture); 1726 if (mesh_builder->texture) 1727 IDirect3DRMTexture3_Release(mesh_builder->texture); 1728 mesh_builder->texture = texture; 1729 1730 return D3DRM_OK; 1731 } 1732 1733 static HRESULT WINAPI d3drm_mesh_builder3_SetMaterial(IDirect3DRMMeshBuilder3 *iface, 1734 IDirect3DRMMaterial2 *material) 1735 { 1736 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1737 1738 TRACE("iface %p, material %p.\n", iface, material); 1739 1740 if (material) 1741 IDirect3DRMTexture2_AddRef(material); 1742 if (mesh_builder->material) 1743 IDirect3DRMTexture2_Release(mesh_builder->material); 1744 mesh_builder->material = material; 1745 1746 return D3DRM_OK; 1747 } 1748 1749 static HRESULT WINAPI d3drm_mesh_builder3_SetTextureTopology(IDirect3DRMMeshBuilder3 *iface, 1750 BOOL wrap_u, BOOL wrap_v) 1751 { 1752 FIXME("iface %p, wrap_u %#x, wrap_v %#x stub!\n", iface, wrap_u, wrap_v); 1753 1754 return E_NOTIMPL; 1755 } 1756 1757 static HRESULT WINAPI d3drm_mesh_builder3_SetQuality(IDirect3DRMMeshBuilder3 *iface, 1758 D3DRMRENDERQUALITY quality) 1759 { 1760 FIXME("iface %p, quality %#x stub!\n", iface, quality); 1761 1762 return E_NOTIMPL; 1763 } 1764 1765 static HRESULT WINAPI d3drm_mesh_builder3_SetPerspective(IDirect3DRMMeshBuilder3 *iface, 1766 BOOL enable) 1767 { 1768 FIXME("iface %p, enable %#x stub!\n", iface, enable); 1769 1770 return E_NOTIMPL; 1771 } 1772 1773 static HRESULT WINAPI d3drm_mesh_builder3_SetVertex(IDirect3DRMMeshBuilder3 *iface, 1774 DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z) 1775 { 1776 FIXME("iface %p, index %u, x %.8e, y %.8e, z %.8e stub!\n", iface, index, x, y, z); 1777 1778 return E_NOTIMPL; 1779 } 1780 1781 static HRESULT WINAPI d3drm_mesh_builder3_SetNormal(IDirect3DRMMeshBuilder3 *iface, 1782 DWORD index, D3DVALUE x, D3DVALUE y, D3DVALUE z) 1783 { 1784 FIXME("iface %p, index %u, x %.8e, y %.8e, z %.8e stub!\n", iface, index, x, y, z); 1785 1786 return E_NOTIMPL; 1787 } 1788 1789 static HRESULT WINAPI d3drm_mesh_builder3_SetTextureCoordinates(IDirect3DRMMeshBuilder3 *iface, 1790 DWORD index, D3DVALUE u, D3DVALUE v) 1791 { 1792 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1793 1794 TRACE("iface %p, index %u, u %.8e, v %.8e.\n", iface, index, u, v); 1795 1796 if (index >= mesh_builder->nb_coords2d) 1797 return D3DRMERR_BADVALUE; 1798 1799 mesh_builder->pCoords2d[index].u = u; 1800 mesh_builder->pCoords2d[index].v = v; 1801 1802 return D3DRM_OK; 1803 } 1804 1805 static HRESULT WINAPI d3drm_mesh_builder3_SetVertexColor(IDirect3DRMMeshBuilder3 *iface, 1806 DWORD index, D3DCOLOR color) 1807 { 1808 FIXME("iface %p, index %u, color 0x%08x stub!\n", iface, index, color); 1809 1810 return E_NOTIMPL; 1811 } 1812 1813 static HRESULT WINAPI d3drm_mesh_builder3_SetVertexColorRGB(IDirect3DRMMeshBuilder3 *iface, 1814 DWORD index, D3DVALUE red, D3DVALUE green, D3DVALUE blue) 1815 { 1816 FIXME("iface %p, index %u, red %.8e, green %.8e, blue %.8e stub!\n", 1817 iface, index, red, green, blue); 1818 1819 return E_NOTIMPL; 1820 } 1821 1822 static HRESULT WINAPI d3drm_mesh_builder3_GetFaces(IDirect3DRMMeshBuilder3 *iface, 1823 IDirect3DRMFaceArray **array) 1824 { 1825 FIXME("iface %p, array %p stub!\n", iface, array); 1826 1827 return E_NOTIMPL; 1828 } 1829 1830 static HRESULT WINAPI d3drm_mesh_builder3_GetGeometry(IDirect3DRMMeshBuilder3 *iface, 1831 DWORD *vertex_count, D3DVECTOR *vertices, DWORD *normal_count, D3DVECTOR *normals, 1832 DWORD *face_data_size, DWORD *face_data) 1833 { 1834 FIXME("iface %p, vertex_count %p, vertices %p, normal_count %p, normals %p, " 1835 "face_data_size %p, face_data %p stub!\n", 1836 iface, vertex_count, vertices, normal_count, normals, face_data_size, face_data); 1837 1838 return E_NOTIMPL; 1839 } 1840 1841 static HRESULT WINAPI d3drm_mesh_builder3_GetTextureCoordinates(IDirect3DRMMeshBuilder3 *iface, 1842 DWORD index, D3DVALUE *u, D3DVALUE *v) 1843 { 1844 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1845 1846 TRACE("iface %p, index %u, u %p, v %p.\n", iface, index, u, v); 1847 1848 if (index >= mesh_builder->nb_coords2d) 1849 return D3DRMERR_BADVALUE; 1850 1851 *u = mesh_builder->pCoords2d[index].u; 1852 *v = mesh_builder->pCoords2d[index].v; 1853 1854 return D3DRM_OK; 1855 } 1856 1857 static int WINAPI d3drm_mesh_builder3_AddVertex(IDirect3DRMMeshBuilder3 *iface, 1858 D3DVALUE x, D3DVALUE y, D3DVALUE z) 1859 { 1860 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1861 1862 TRACE("iface %p, x %.8e, y %.8e, z %.8e.\n", iface, x, y, z); 1863 1864 if (!d3drm_array_reserve((void **)&mesh_builder->vertices, &mesh_builder->vertices_size, 1865 mesh_builder->nb_vertices + 1, sizeof(*mesh_builder->vertices))) 1866 return 0; 1867 1868 mesh_builder->vertices[mesh_builder->nb_vertices].u1.x = x; 1869 mesh_builder->vertices[mesh_builder->nb_vertices].u2.y = y; 1870 mesh_builder->vertices[mesh_builder->nb_vertices].u3.z = z; 1871 1872 return mesh_builder->nb_vertices++; 1873 } 1874 1875 static int WINAPI d3drm_mesh_builder3_AddNormal(IDirect3DRMMeshBuilder3 *iface, 1876 D3DVALUE x, D3DVALUE y, D3DVALUE z) 1877 { 1878 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1879 1880 TRACE("iface %p, x %.8e, y %.8e, z %.8e.\n", iface, x, y, z); 1881 1882 if (!d3drm_array_reserve((void **)&mesh_builder->normals, &mesh_builder->normals_size, 1883 mesh_builder->nb_normals + 1, sizeof(*mesh_builder->normals))) 1884 return 0; 1885 1886 mesh_builder->normals[mesh_builder->nb_normals].u1.x = x; 1887 mesh_builder->normals[mesh_builder->nb_normals].u2.y = y; 1888 mesh_builder->normals[mesh_builder->nb_normals].u3.z = z; 1889 1890 return mesh_builder->nb_normals++; 1891 } 1892 1893 static HRESULT WINAPI d3drm_mesh_builder3_CreateFace(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMFace2 **face) 1894 { 1895 struct d3drm_face *object; 1896 HRESULT hr; 1897 1898 TRACE("iface %p, face %p.\n", iface, face); 1899 1900 if (FAILED(hr = d3drm_face_create(&object))) 1901 return hr; 1902 1903 *face = &object->IDirect3DRMFace2_iface; 1904 1905 return S_OK; 1906 } 1907 1908 static D3DRMRENDERQUALITY WINAPI d3drm_mesh_builder3_GetQuality(IDirect3DRMMeshBuilder3 *iface) 1909 { 1910 FIXME("iface %p stub!\n", iface); 1911 1912 return 0; 1913 } 1914 1915 static BOOL WINAPI d3drm_mesh_builder3_GetPerspective(IDirect3DRMMeshBuilder3 *iface) 1916 { 1917 FIXME("iface %p stub!\n", iface); 1918 1919 return FALSE; 1920 } 1921 1922 static int WINAPI d3drm_mesh_builder3_GetFaceCount(IDirect3DRMMeshBuilder3 *iface) 1923 { 1924 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1925 1926 TRACE("iface %p.\n", iface); 1927 1928 return mesh_builder->nb_faces; 1929 } 1930 1931 static int WINAPI d3drm_mesh_builder3_GetVertexCount(IDirect3DRMMeshBuilder3 *iface) 1932 { 1933 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1934 1935 TRACE("iface %p.\n", iface); 1936 1937 return mesh_builder->nb_vertices; 1938 } 1939 1940 static D3DCOLOR WINAPI d3drm_mesh_builder3_GetVertexColor(IDirect3DRMMeshBuilder3 *iface, 1941 DWORD index) 1942 { 1943 FIXME("iface %p, index %u stub!\n", iface, index); 1944 1945 return 0; 1946 } 1947 1948 static HRESULT WINAPI d3drm_mesh_builder3_CreateMesh(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMMesh **mesh) 1949 { 1950 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 1951 HRESULT hr; 1952 D3DRMGROUPINDEX group; 1953 1954 TRACE("iface %p, mesh %p.\n", iface, mesh); 1955 1956 if (!mesh) 1957 return E_POINTER; 1958 1959 hr = IDirect3DRM_CreateMesh(mesh_builder->d3drm, mesh); 1960 if (FAILED(hr)) 1961 return hr; 1962 1963 /* If there is mesh data, create a group and put data inside */ 1964 if (mesh_builder->nb_vertices) 1965 { 1966 DWORD i, j; 1967 int k; 1968 D3DRMVERTEX* vertices; 1969 1970 if (!(vertices = heap_calloc(mesh_builder->nb_vertices, sizeof(*vertices)))) 1971 { 1972 IDirect3DRMMesh_Release(*mesh); 1973 return E_OUTOFMEMORY; 1974 } 1975 for (i = 0; i < mesh_builder->nb_vertices; i++) 1976 vertices[i].position = mesh_builder->vertices[i]; 1977 hr = IDirect3DRMMesh_SetVertices(*mesh, 0, 0, mesh_builder->nb_vertices, vertices); 1978 heap_free(vertices); 1979 1980 /* Groups are in reverse order compared to materials list in X file */ 1981 for (k = mesh_builder->nb_materials - 1; k >= 0; k--) 1982 { 1983 unsigned* face_data; 1984 unsigned* out_ptr; 1985 DWORD* in_ptr = mesh_builder->pFaceData; 1986 ULONG vertex_per_face = 0; 1987 BOOL* used_vertices; 1988 unsigned nb_vertices = 0; 1989 unsigned nb_faces = 0; 1990 1991 if (!(used_vertices = heap_calloc(mesh_builder->face_data_size, sizeof(*used_vertices)))) 1992 { 1993 IDirect3DRMMesh_Release(*mesh); 1994 return E_OUTOFMEMORY; 1995 } 1996 1997 if (!(face_data = heap_calloc(mesh_builder->face_data_size, sizeof(*face_data)))) 1998 { 1999 heap_free(used_vertices); 2000 IDirect3DRMMesh_Release(*mesh); 2001 return E_OUTOFMEMORY; 2002 } 2003 out_ptr = face_data; 2004 2005 /* If all faces have the same number of vertex, set vertex_per_face */ 2006 for (i = 0; i < mesh_builder->nb_faces; i++) 2007 { 2008 /* Process only faces belonging to the group */ 2009 if (mesh_builder->material_indices[i] == k) 2010 { 2011 if (vertex_per_face && (vertex_per_face != *in_ptr)) 2012 break; 2013 vertex_per_face = *in_ptr; 2014 } 2015 in_ptr += 1 + *in_ptr * 2; 2016 } 2017 if (i != mesh_builder->nb_faces) 2018 vertex_per_face = 0; 2019 2020 /* Put only vertex indices */ 2021 in_ptr = mesh_builder->pFaceData; 2022 for (i = 0; i < mesh_builder->nb_faces; i++) 2023 { 2024 DWORD nb_indices = *in_ptr++; 2025 2026 /* Skip faces not belonging to the group */ 2027 if (mesh_builder->material_indices[i] != k) 2028 { 2029 in_ptr += 2 * nb_indices; 2030 continue; 2031 } 2032 2033 /* Don't put nb indices when vertex_per_face is set */ 2034 if (vertex_per_face) 2035 *out_ptr++ = nb_indices; 2036 2037 for (j = 0; j < nb_indices; j++) 2038 { 2039 *out_ptr = *in_ptr++; 2040 used_vertices[*out_ptr++] = TRUE; 2041 /* Skip normal index */ 2042 in_ptr++; 2043 } 2044 2045 nb_faces++; 2046 } 2047 2048 for (i = 0; i < mesh_builder->nb_vertices; i++) 2049 if (used_vertices[i]) 2050 nb_vertices++; 2051 2052 hr = IDirect3DRMMesh_AddGroup(*mesh, nb_vertices, nb_faces, vertex_per_face, face_data, &group); 2053 heap_free(used_vertices); 2054 heap_free(face_data); 2055 if (SUCCEEDED(hr)) 2056 hr = IDirect3DRMMesh_SetGroupColor(*mesh, group, mesh_builder->materials[k].color); 2057 if (SUCCEEDED(hr)) 2058 hr = IDirect3DRMMesh_SetGroupMaterial(*mesh, group, 2059 (IDirect3DRMMaterial *)mesh_builder->materials[k].material); 2060 if (SUCCEEDED(hr) && mesh_builder->materials[k].texture) 2061 { 2062 IDirect3DRMTexture *texture; 2063 2064 IDirect3DRMTexture3_QueryInterface(mesh_builder->materials[k].texture, 2065 &IID_IDirect3DRMTexture, (void **)&texture); 2066 hr = IDirect3DRMMesh_SetGroupTexture(*mesh, group, texture); 2067 IDirect3DRMTexture_Release(texture); 2068 } 2069 if (FAILED(hr)) 2070 { 2071 IDirect3DRMMesh_Release(*mesh); 2072 return hr; 2073 } 2074 } 2075 } 2076 2077 return D3DRM_OK; 2078 } 2079 2080 static HRESULT WINAPI d3drm_mesh_builder3_GetFace(IDirect3DRMMeshBuilder3 *iface, 2081 DWORD index, IDirect3DRMFace2 **face) 2082 { 2083 FIXME("iface %p, index %u, face %p stub!\n", iface, index, face); 2084 2085 return E_NOTIMPL; 2086 } 2087 2088 static HRESULT WINAPI d3drm_mesh_builder3_GetVertex(IDirect3DRMMeshBuilder3 *iface, 2089 DWORD index, D3DVECTOR *vector) 2090 { 2091 FIXME("iface %p, index %u, vector %p stub!\n", iface, index, vector); 2092 2093 return E_NOTIMPL; 2094 } 2095 2096 static HRESULT WINAPI d3drm_mesh_builder3_GetNormal(IDirect3DRMMeshBuilder3 *iface, 2097 DWORD index, D3DVECTOR *vector) 2098 { 2099 FIXME("iface %p, index %u, vector %p stub!\n", iface, index, vector); 2100 2101 return E_NOTIMPL; 2102 } 2103 2104 static HRESULT WINAPI d3drm_mesh_builder3_DeleteVertices(IDirect3DRMMeshBuilder3 *iface, 2105 DWORD start_idx, DWORD count) 2106 { 2107 FIXME("iface %p, start_idx %u, count %u stub!\n", iface, start_idx, count); 2108 2109 return E_NOTIMPL; 2110 } 2111 2112 static HRESULT WINAPI d3drm_mesh_builder3_DeleteNormals(IDirect3DRMMeshBuilder3 *iface, 2113 DWORD start_idx, DWORD count) 2114 { 2115 FIXME("iface %p, start_idx %u, count %u stub!\n", iface, start_idx, count); 2116 2117 return E_NOTIMPL; 2118 } 2119 2120 static HRESULT WINAPI d3drm_mesh_builder3_DeleteFace(IDirect3DRMMeshBuilder3 *iface, IDirect3DRMFace2 *face) 2121 { 2122 FIXME("iface %p, face %p stub!\n", iface, face); 2123 2124 return E_NOTIMPL; 2125 } 2126 2127 static HRESULT WINAPI d3drm_mesh_builder3_Empty(IDirect3DRMMeshBuilder3 *iface, DWORD flags) 2128 { 2129 FIXME("iface %p, flags %#x stub!\n", iface, flags); 2130 2131 return E_NOTIMPL; 2132 } 2133 2134 static HRESULT WINAPI d3drm_mesh_builder3_Optimize(IDirect3DRMMeshBuilder3 *iface, DWORD flags) 2135 { 2136 FIXME("iface %p, flags %#x stub!\n", iface, flags); 2137 2138 return E_NOTIMPL; 2139 } 2140 2141 static HRESULT WINAPI d3drm_mesh_builder3_AddFacesIndexed(IDirect3DRMMeshBuilder3 *iface, 2142 DWORD flags, DWORD *indices, DWORD *start_idx, DWORD *count) 2143 { 2144 FIXME("iface %p, flags %#x, indices %p, start_idx %p, count %p stub!\n", 2145 iface, flags, indices, start_idx, count); 2146 2147 return E_NOTIMPL; 2148 } 2149 2150 static HRESULT WINAPI d3drm_mesh_builder3_CreateSubMesh(IDirect3DRMMeshBuilder3 *iface, IUnknown **mesh) 2151 { 2152 FIXME("iface %p, mesh %p stub!\n", iface, mesh); 2153 2154 return E_NOTIMPL; 2155 } 2156 2157 static HRESULT WINAPI d3drm_mesh_builder3_GetParentMesh(IDirect3DRMMeshBuilder3 *iface, 2158 DWORD flags, IUnknown **parent) 2159 { 2160 FIXME("iface %p, flags %#x, parent %p stub!\n", iface, flags, parent); 2161 2162 return E_NOTIMPL; 2163 } 2164 2165 static HRESULT WINAPI d3drm_mesh_builder3_GetSubMeshes(IDirect3DRMMeshBuilder3 *iface, 2166 DWORD *count, IUnknown **meshes) 2167 { 2168 FIXME("iface %p, count %p, meshes %p stub!\n", iface, count, meshes); 2169 2170 return E_NOTIMPL; 2171 } 2172 2173 static HRESULT WINAPI d3drm_mesh_builder3_DeleteSubMesh(IDirect3DRMMeshBuilder3 *iface, IUnknown *mesh) 2174 { 2175 FIXME("iface %p, mesh %p stub!\n", iface, mesh); 2176 2177 return E_NOTIMPL; 2178 } 2179 2180 static HRESULT WINAPI d3drm_mesh_builder3_Enable(IDirect3DRMMeshBuilder3 *iface, DWORD index) 2181 { 2182 FIXME("iface %p, index %u stub!\n", iface, index); 2183 2184 return E_NOTIMPL; 2185 } 2186 2187 static HRESULT WINAPI d3drm_mesh_builder3_GetEnable(IDirect3DRMMeshBuilder3 *iface, DWORD *indices) 2188 { 2189 FIXME("iface %p, indices %p stub!\n", iface, indices); 2190 2191 return E_NOTIMPL; 2192 } 2193 2194 static HRESULT WINAPI d3drm_mesh_builder3_AddTriangles(IDirect3DRMMeshBuilder3 *iface, 2195 DWORD flags, DWORD format, DWORD vertex_count, void *data) 2196 { 2197 FIXME("iface %p, flags %#x, format %#x, vertex_count %u, data %p stub!\n", 2198 iface, flags, format, vertex_count, data); 2199 2200 return E_NOTIMPL; 2201 } 2202 2203 static HRESULT WINAPI d3drm_mesh_builder3_SetVertices(IDirect3DRMMeshBuilder3 *iface, 2204 DWORD start_idx, DWORD count, D3DVECTOR *vector) 2205 { 2206 FIXME("iface %p, start_idx %u, count %u, vector %p stub!\n", iface, start_idx, count, vector); 2207 2208 return E_NOTIMPL; 2209 } 2210 2211 static HRESULT WINAPI d3drm_mesh_builder3_GetVertices(IDirect3DRMMeshBuilder3 *iface, 2212 DWORD start_idx, DWORD *vertex_count, D3DVECTOR *vertices) 2213 { 2214 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 2215 DWORD count = mesh_builder->nb_vertices - start_idx; 2216 2217 TRACE("iface %p, start_idx %u, vertex_count %p, vertices %p.\n", 2218 iface, start_idx, vertex_count, vertices); 2219 2220 if (vertex_count) 2221 *vertex_count = count; 2222 if (vertices && mesh_builder->nb_vertices) 2223 memcpy(vertices, mesh_builder->vertices + start_idx, count * sizeof(*vertices)); 2224 2225 return D3DRM_OK; 2226 } 2227 2228 static HRESULT WINAPI d3drm_mesh_builder3_SetNormals(IDirect3DRMMeshBuilder3 *iface, 2229 DWORD start_idx, DWORD count, D3DVECTOR *vector) 2230 { 2231 FIXME("iface %p, start_idx %u, count %u, vector %p stub!\n", 2232 iface, start_idx, count, vector); 2233 2234 return E_NOTIMPL; 2235 } 2236 2237 static HRESULT WINAPI d3drm_mesh_builder3_GetNormals(IDirect3DRMMeshBuilder3 *iface, 2238 DWORD start_idx, DWORD *normal_count, D3DVECTOR *normals) 2239 { 2240 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 2241 DWORD count = mesh_builder->nb_normals - start_idx; 2242 2243 TRACE("iface %p, start_idx %u, normal_count %p, normals %p.\n", 2244 iface, start_idx, normal_count, normals); 2245 2246 if (normal_count) 2247 *normal_count = count; 2248 if (normals && mesh_builder->nb_normals) 2249 memcpy(normals, &mesh_builder->normals[start_idx], count * sizeof(*normals)); 2250 2251 return D3DRM_OK; 2252 } 2253 2254 static int WINAPI d3drm_mesh_builder3_GetNormalCount(IDirect3DRMMeshBuilder3 *iface) 2255 { 2256 struct d3drm_mesh_builder *mesh_builder = impl_from_IDirect3DRMMeshBuilder3(iface); 2257 2258 TRACE("iface %p.\n", iface); 2259 2260 return mesh_builder->nb_normals; 2261 } 2262 2263 static const struct IDirect3DRMMeshBuilder3Vtbl d3drm_mesh_builder3_vtbl = 2264 { 2265 d3drm_mesh_builder3_QueryInterface, 2266 d3drm_mesh_builder3_AddRef, 2267 d3drm_mesh_builder3_Release, 2268 d3drm_mesh_builder3_Clone, 2269 d3drm_mesh_builder3_AddDestroyCallback, 2270 d3drm_mesh_builder3_DeleteDestroyCallback, 2271 d3drm_mesh_builder3_SetAppData, 2272 d3drm_mesh_builder3_GetAppData, 2273 d3drm_mesh_builder3_SetName, 2274 d3drm_mesh_builder3_GetName, 2275 d3drm_mesh_builder3_GetClassName, 2276 d3drm_mesh_builder3_Load, 2277 d3drm_mesh_builder3_Save, 2278 d3drm_mesh_builder3_Scale, 2279 d3drm_mesh_builder3_Translate, 2280 d3drm_mesh_builder3_SetColorSource, 2281 d3drm_mesh_builder3_GetBox, 2282 d3drm_mesh_builder3_GenerateNormals, 2283 d3drm_mesh_builder3_GetColorSource, 2284 d3drm_mesh_builder3_AddMesh, 2285 d3drm_mesh_builder3_AddMeshBuilder, 2286 d3drm_mesh_builder3_AddFrame, 2287 d3drm_mesh_builder3_AddFace, 2288 d3drm_mesh_builder3_AddFaces, 2289 d3drm_mesh_builder3_ReserveSpace, 2290 d3drm_mesh_builder3_SetColorRGB, 2291 d3drm_mesh_builder3_SetColor, 2292 d3drm_mesh_builder3_SetTexture, 2293 d3drm_mesh_builder3_SetMaterial, 2294 d3drm_mesh_builder3_SetTextureTopology, 2295 d3drm_mesh_builder3_SetQuality, 2296 d3drm_mesh_builder3_SetPerspective, 2297 d3drm_mesh_builder3_SetVertex, 2298 d3drm_mesh_builder3_SetNormal, 2299 d3drm_mesh_builder3_SetTextureCoordinates, 2300 d3drm_mesh_builder3_SetVertexColor, 2301 d3drm_mesh_builder3_SetVertexColorRGB, 2302 d3drm_mesh_builder3_GetFaces, 2303 d3drm_mesh_builder3_GetGeometry, 2304 d3drm_mesh_builder3_GetTextureCoordinates, 2305 d3drm_mesh_builder3_AddVertex, 2306 d3drm_mesh_builder3_AddNormal, 2307 d3drm_mesh_builder3_CreateFace, 2308 d3drm_mesh_builder3_GetQuality, 2309 d3drm_mesh_builder3_GetPerspective, 2310 d3drm_mesh_builder3_GetFaceCount, 2311 d3drm_mesh_builder3_GetVertexCount, 2312 d3drm_mesh_builder3_GetVertexColor, 2313 d3drm_mesh_builder3_CreateMesh, 2314 d3drm_mesh_builder3_GetFace, 2315 d3drm_mesh_builder3_GetVertex, 2316 d3drm_mesh_builder3_GetNormal, 2317 d3drm_mesh_builder3_DeleteVertices, 2318 d3drm_mesh_builder3_DeleteNormals, 2319 d3drm_mesh_builder3_DeleteFace, 2320 d3drm_mesh_builder3_Empty, 2321 d3drm_mesh_builder3_Optimize, 2322 d3drm_mesh_builder3_AddFacesIndexed, 2323 d3drm_mesh_builder3_CreateSubMesh, 2324 d3drm_mesh_builder3_GetParentMesh, 2325 d3drm_mesh_builder3_GetSubMeshes, 2326 d3drm_mesh_builder3_DeleteSubMesh, 2327 d3drm_mesh_builder3_Enable, 2328 d3drm_mesh_builder3_GetEnable, 2329 d3drm_mesh_builder3_AddTriangles, 2330 d3drm_mesh_builder3_SetVertices, 2331 d3drm_mesh_builder3_GetVertices, 2332 d3drm_mesh_builder3_SetNormals, 2333 d3drm_mesh_builder3_GetNormals, 2334 d3drm_mesh_builder3_GetNormalCount, 2335 }; 2336 2337 HRESULT d3drm_mesh_builder_create(struct d3drm_mesh_builder **mesh_builder, IDirect3DRM *d3drm) 2338 { 2339 static const char classname[] = "Builder"; 2340 struct d3drm_mesh_builder *object; 2341 2342 TRACE("mesh_builder %p.\n", mesh_builder); 2343 2344 if (!(object = heap_alloc_zero(sizeof(*object)))) 2345 return E_OUTOFMEMORY; 2346 2347 object->IDirect3DRMMeshBuilder2_iface.lpVtbl = &d3drm_mesh_builder2_vtbl; 2348 object->IDirect3DRMMeshBuilder3_iface.lpVtbl = &d3drm_mesh_builder3_vtbl; 2349 object->ref = 1; 2350 object->d3drm = d3drm; 2351 IDirect3DRM_AddRef(object->d3drm); 2352 2353 d3drm_object_init(&object->obj, classname); 2354 2355 *mesh_builder = object; 2356 2357 return S_OK; 2358 } 2359 2360 static HRESULT WINAPI d3drm_mesh_QueryInterface(IDirect3DRMMesh *iface, REFIID riid, void **out) 2361 { 2362 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 2363 2364 if (IsEqualGUID(riid, &IID_IDirect3DRMMesh) 2365 || IsEqualGUID(riid, &IID_IDirect3DRMVisual) 2366 || IsEqualGUID(riid, &IID_IDirect3DRMObject) 2367 || IsEqualGUID(riid, &IID_IUnknown)) 2368 { 2369 IDirect3DRMMesh_AddRef(iface); 2370 *out = iface; 2371 return S_OK; 2372 } 2373 2374 WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid)); 2375 2376 *out = NULL; 2377 return E_NOINTERFACE; 2378 } 2379 2380 static ULONG WINAPI d3drm_mesh_AddRef(IDirect3DRMMesh *iface) 2381 { 2382 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2383 ULONG refcount = InterlockedIncrement(&mesh->ref); 2384 2385 TRACE("%p increasing refcount to %u.\n", iface, refcount); 2386 2387 return refcount; 2388 } 2389 2390 static ULONG WINAPI d3drm_mesh_Release(IDirect3DRMMesh *iface) 2391 { 2392 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2393 ULONG refcount = InterlockedDecrement(&mesh->ref); 2394 2395 TRACE("%p decreasing refcount to %u.\n", iface, refcount); 2396 2397 if (!refcount) 2398 { 2399 DWORD i; 2400 2401 d3drm_object_cleanup((IDirect3DRMObject *)iface, &mesh->obj); 2402 IDirect3DRM_Release(mesh->d3drm); 2403 for (i = 0; i < mesh->nb_groups; ++i) 2404 { 2405 heap_free(mesh->groups[i].vertices); 2406 heap_free(mesh->groups[i].face_data); 2407 if (mesh->groups[i].material) 2408 IDirect3DRMMaterial2_Release(mesh->groups[i].material); 2409 if (mesh->groups[i].texture) 2410 IDirect3DRMTexture3_Release(mesh->groups[i].texture); 2411 } 2412 heap_free(mesh->groups); 2413 heap_free(mesh); 2414 } 2415 2416 return refcount; 2417 } 2418 2419 static HRESULT WINAPI d3drm_mesh_Clone(IDirect3DRMMesh *iface, 2420 IUnknown *outer, REFIID iid, void **out) 2421 { 2422 FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out); 2423 2424 return E_NOTIMPL; 2425 } 2426 2427 static HRESULT WINAPI d3drm_mesh_AddDestroyCallback(IDirect3DRMMesh *iface, 2428 D3DRMOBJECTCALLBACK cb, void *ctx) 2429 { 2430 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2431 2432 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 2433 2434 return d3drm_object_add_destroy_callback(&mesh->obj, cb, ctx); 2435 } 2436 2437 static HRESULT WINAPI d3drm_mesh_DeleteDestroyCallback(IDirect3DRMMesh *iface, 2438 D3DRMOBJECTCALLBACK cb, void *ctx) 2439 { 2440 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2441 2442 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 2443 2444 return d3drm_object_delete_destroy_callback(&mesh->obj, cb, ctx); 2445 } 2446 2447 static HRESULT WINAPI d3drm_mesh_SetAppData(IDirect3DRMMesh *iface, DWORD data) 2448 { 2449 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2450 2451 TRACE("iface %p, data %#x.\n", iface, data); 2452 2453 mesh->obj.appdata = data; 2454 2455 return D3DRM_OK; 2456 } 2457 2458 static DWORD WINAPI d3drm_mesh_GetAppData(IDirect3DRMMesh *iface) 2459 { 2460 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2461 2462 TRACE("iface %p.\n", iface); 2463 2464 return mesh->obj.appdata; 2465 } 2466 2467 static HRESULT WINAPI d3drm_mesh_SetName(IDirect3DRMMesh *iface, const char *name) 2468 { 2469 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2470 2471 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 2472 2473 return d3drm_object_set_name(&mesh->obj, name); 2474 } 2475 2476 static HRESULT WINAPI d3drm_mesh_GetName(IDirect3DRMMesh *iface, DWORD *size, char *name) 2477 { 2478 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2479 2480 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 2481 2482 return d3drm_object_get_name(&mesh->obj, size, name); 2483 } 2484 2485 static HRESULT WINAPI d3drm_mesh_GetClassName(IDirect3DRMMesh *iface, DWORD *size, char *name) 2486 { 2487 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2488 2489 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 2490 2491 return d3drm_object_get_class_name(&mesh->obj, size, name); 2492 } 2493 2494 static HRESULT WINAPI d3drm_mesh_Scale(IDirect3DRMMesh *iface, 2495 D3DVALUE sx, D3DVALUE sy, D3DVALUE sz) 2496 { 2497 FIXME("iface %p, sx %.8e, sy %.8e, sz %.8e stub!\n", iface, sx, sy, sz); 2498 2499 return E_NOTIMPL; 2500 } 2501 2502 static HRESULT WINAPI d3drm_mesh_Translate(IDirect3DRMMesh *iface, 2503 D3DVALUE tx, D3DVALUE ty, D3DVALUE tz) 2504 { 2505 FIXME("iface %p, tx %.8e, ty %.8e, tz %.8e stub!\n", iface, tx, ty, tz); 2506 2507 return E_NOTIMPL; 2508 } 2509 2510 static HRESULT WINAPI d3drm_mesh_GetBox(IDirect3DRMMesh *iface, D3DRMBOX *box) 2511 { 2512 FIXME("iface %p, box %p stub!\n", iface, box); 2513 2514 return E_NOTIMPL; 2515 } 2516 2517 static HRESULT WINAPI d3drm_mesh_AddGroup(IDirect3DRMMesh *iface, unsigned vertex_count, 2518 unsigned face_count, unsigned vertex_per_face, unsigned *face_data, D3DRMGROUPINDEX *id) 2519 { 2520 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2521 struct mesh_group *group; 2522 2523 TRACE("iface %p, vertex_count %u, face_count %u, vertex_per_face %u, face_data %p, id %p.\n", 2524 iface, vertex_count, face_count, vertex_per_face, face_data, id); 2525 2526 if (!face_data || !id) 2527 return E_POINTER; 2528 2529 if (!d3drm_array_reserve((void **)&mesh->groups, &mesh->groups_size, mesh->nb_groups + 1, sizeof(*mesh->groups))) 2530 return E_OUTOFMEMORY; 2531 2532 group = mesh->groups + mesh->nb_groups; 2533 2534 if (!(group->vertices = heap_calloc(vertex_count, sizeof(*group->vertices)))) 2535 return E_OUTOFMEMORY; 2536 group->nb_vertices = vertex_count; 2537 group->nb_faces = face_count; 2538 group->vertex_per_face = vertex_per_face; 2539 2540 if (vertex_per_face) 2541 { 2542 group->face_data_size = face_count * vertex_per_face; 2543 } 2544 else 2545 { 2546 unsigned i; 2547 unsigned nb_indices; 2548 unsigned* face_data_ptr = face_data; 2549 group->face_data_size = 0; 2550 2551 for (i = 0; i < face_count; i++) 2552 { 2553 nb_indices = *face_data_ptr; 2554 group->face_data_size += nb_indices + 1; 2555 face_data_ptr += nb_indices; 2556 } 2557 } 2558 2559 if (!(group->face_data = heap_calloc(group->face_data_size, sizeof(*group->face_data)))) 2560 { 2561 heap_free(group->vertices); 2562 return E_OUTOFMEMORY; 2563 } 2564 memcpy(group->face_data, face_data, group->face_data_size * sizeof(*face_data)); 2565 2566 group->material = NULL; 2567 group->texture = NULL; 2568 2569 *id = mesh->nb_groups++; 2570 2571 return D3DRM_OK; 2572 } 2573 2574 static HRESULT WINAPI d3drm_mesh_SetVertices(IDirect3DRMMesh *iface, D3DRMGROUPINDEX group_id, 2575 unsigned int start_idx, unsigned int count, D3DRMVERTEX *values) 2576 { 2577 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2578 2579 TRACE("iface %p, group_id %#x, start_idx %u, count %u, values %p.\n", 2580 iface, group_id, start_idx, count, values); 2581 2582 if (group_id >= mesh->nb_groups) 2583 return D3DRMERR_BADVALUE; 2584 2585 if ((start_idx + count - 1) >= mesh->groups[group_id].nb_vertices) 2586 return D3DRMERR_BADVALUE; 2587 2588 if (!values) 2589 return E_POINTER; 2590 2591 memcpy(mesh->groups[group_id].vertices + start_idx, values, count * sizeof(*values)); 2592 2593 return D3DRM_OK; 2594 } 2595 2596 static HRESULT WINAPI d3drm_mesh_SetGroupColor(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id, D3DCOLOR color) 2597 { 2598 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2599 2600 TRACE("iface %p, id %#x, color 0x%08x.\n", iface, id, color); 2601 2602 if (id >= mesh->nb_groups) 2603 return D3DRMERR_BADVALUE; 2604 2605 mesh->groups[id].color = color; 2606 2607 return D3DRM_OK; 2608 } 2609 2610 static HRESULT WINAPI d3drm_mesh_SetGroupColorRGB(IDirect3DRMMesh *iface, 2611 D3DRMGROUPINDEX id, D3DVALUE red, D3DVALUE green, D3DVALUE blue) 2612 { 2613 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2614 2615 TRACE("iface %p, id %#x, red %.8e, green %.8e, blue %.8e.\n", iface, id, red, green, blue); 2616 2617 if (id >= mesh->nb_groups) 2618 return D3DRMERR_BADVALUE; 2619 2620 d3drm_set_color(&mesh->groups[id].color, red, green, blue, 1.0f); 2621 2622 return D3DRM_OK; 2623 } 2624 2625 static HRESULT WINAPI d3drm_mesh_SetGroupMapping(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id, D3DRMMAPPING value) 2626 { 2627 FIXME("iface %p, id %#x, value %#x stub!\n", iface, id, value); 2628 2629 return E_NOTIMPL; 2630 } 2631 2632 static HRESULT WINAPI d3drm_mesh_SetGroupQuality(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id, D3DRMRENDERQUALITY value) 2633 { 2634 FIXME("iface %p, id %#x, value %#x stub!\n", iface, id, value); 2635 2636 return E_NOTIMPL; 2637 } 2638 2639 static HRESULT WINAPI d3drm_mesh_SetGroupMaterial(IDirect3DRMMesh *iface, 2640 D3DRMGROUPINDEX id, IDirect3DRMMaterial *material) 2641 { 2642 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2643 2644 TRACE("iface %p, id %#x, material %p.\n", iface, id, material); 2645 2646 if (id >= mesh->nb_groups) 2647 return D3DRMERR_BADVALUE; 2648 2649 if (mesh->groups[id].material) 2650 IDirect3DRMMaterial2_Release(mesh->groups[id].material); 2651 2652 mesh->groups[id].material = (IDirect3DRMMaterial2 *)material; 2653 2654 if (material) 2655 IDirect3DRMMaterial2_AddRef(mesh->groups[id].material); 2656 2657 return D3DRM_OK; 2658 } 2659 2660 static HRESULT WINAPI d3drm_mesh_SetGroupTexture(IDirect3DRMMesh *iface, 2661 D3DRMGROUPINDEX id, IDirect3DRMTexture *texture) 2662 { 2663 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2664 2665 TRACE("iface %p, id %#x, texture %p.\n", iface, id, texture); 2666 2667 if (id >= mesh->nb_groups) 2668 return D3DRMERR_BADVALUE; 2669 2670 if (mesh->groups[id].texture) 2671 IDirect3DRMTexture3_Release(mesh->groups[id].texture); 2672 2673 if (!texture) 2674 { 2675 mesh->groups[id].texture = NULL; 2676 return D3DRM_OK; 2677 } 2678 2679 return IDirect3DRMTexture3_QueryInterface(texture, &IID_IDirect3DRMTexture, (void **)&mesh->groups[id].texture); 2680 } 2681 2682 static DWORD WINAPI d3drm_mesh_GetGroupCount(IDirect3DRMMesh *iface) 2683 { 2684 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2685 2686 TRACE("iface %p.\n", iface); 2687 2688 return mesh->nb_groups; 2689 } 2690 2691 static HRESULT WINAPI d3drm_mesh_GetGroup(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id, unsigned *vertex_count, 2692 unsigned *face_count, unsigned *vertex_per_face, DWORD *face_data_size, unsigned *face_data) 2693 { 2694 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2695 2696 TRACE("iface %p, id %#x, vertex_count %p, face_count %p, vertex_per_face %p, face_data_size %p, face_data %p.\n", 2697 iface, id, vertex_count, face_count, vertex_per_face, face_data_size,face_data); 2698 2699 if (id >= mesh->nb_groups) 2700 return D3DRMERR_BADVALUE; 2701 2702 if (vertex_count) 2703 *vertex_count = mesh->groups[id].nb_vertices; 2704 if (face_count) 2705 *face_count = mesh->groups[id].nb_faces; 2706 if (vertex_per_face) 2707 *vertex_per_face = mesh->groups[id].vertex_per_face; 2708 if (face_data_size) 2709 *face_data_size = mesh->groups[id].face_data_size; 2710 if (face_data) 2711 memcpy(face_data, mesh->groups[id].face_data, mesh->groups[id].face_data_size * sizeof(*face_data)); 2712 2713 return D3DRM_OK; 2714 } 2715 2716 static HRESULT WINAPI d3drm_mesh_GetVertices(IDirect3DRMMesh *iface, 2717 D3DRMGROUPINDEX group_id, DWORD start_idx, DWORD count, D3DRMVERTEX *vertices) 2718 { 2719 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2720 2721 TRACE("iface %p, group_id %#x, start_idx %u, count %u, vertices %p.\n", 2722 iface, group_id, start_idx, count, vertices); 2723 2724 if (group_id >= mesh->nb_groups) 2725 return D3DRMERR_BADVALUE; 2726 2727 if ((start_idx + count - 1) >= mesh->groups[group_id].nb_vertices) 2728 return D3DRMERR_BADVALUE; 2729 2730 if (!vertices) 2731 return E_POINTER; 2732 2733 memcpy(vertices, mesh->groups[group_id].vertices + start_idx, count * sizeof(*vertices)); 2734 2735 return D3DRM_OK; 2736 } 2737 2738 static D3DCOLOR WINAPI d3drm_mesh_GetGroupColor(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id) 2739 { 2740 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2741 2742 TRACE("iface %p, id %#x.\n", iface, id); 2743 2744 return mesh->groups[id].color; 2745 } 2746 2747 static D3DRMMAPPING WINAPI d3drm_mesh_GetGroupMapping(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id) 2748 { 2749 FIXME("iface %p, id %#x stub!\n", iface, id); 2750 2751 return 0; 2752 } 2753 static D3DRMRENDERQUALITY WINAPI d3drm_mesh_GetGroupQuality(IDirect3DRMMesh *iface, D3DRMGROUPINDEX id) 2754 { 2755 FIXME("iface %p, id %#x stub!\n", iface, id); 2756 2757 return 0; 2758 } 2759 2760 static HRESULT WINAPI d3drm_mesh_GetGroupMaterial(IDirect3DRMMesh *iface, 2761 D3DRMGROUPINDEX id, IDirect3DRMMaterial **material) 2762 { 2763 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2764 2765 TRACE("iface %p, id %#x, material %p.\n", iface, id, material); 2766 2767 if (id >= mesh->nb_groups) 2768 return D3DRMERR_BADVALUE; 2769 2770 if (!material) 2771 return E_POINTER; 2772 2773 if (mesh->groups[id].material) 2774 IDirect3DRMTexture_QueryInterface(mesh->groups[id].material, &IID_IDirect3DRMMaterial, (void **)material); 2775 else 2776 *material = NULL; 2777 2778 return D3DRM_OK; 2779 } 2780 2781 static HRESULT WINAPI d3drm_mesh_GetGroupTexture(IDirect3DRMMesh *iface, 2782 D3DRMGROUPINDEX id, IDirect3DRMTexture **texture) 2783 { 2784 struct d3drm_mesh *mesh = impl_from_IDirect3DRMMesh(iface); 2785 2786 TRACE("iface %p, id %#x, texture %p.\n", iface, id, texture); 2787 2788 if (id >= mesh->nb_groups) 2789 return D3DRMERR_BADVALUE; 2790 2791 if (!texture) 2792 return E_POINTER; 2793 2794 if (mesh->groups[id].texture) 2795 IDirect3DRMTexture_QueryInterface(mesh->groups[id].texture, &IID_IDirect3DRMTexture, (void **)texture); 2796 else 2797 *texture = NULL; 2798 2799 return D3DRM_OK; 2800 } 2801 2802 static const struct IDirect3DRMMeshVtbl d3drm_mesh_vtbl = 2803 { 2804 d3drm_mesh_QueryInterface, 2805 d3drm_mesh_AddRef, 2806 d3drm_mesh_Release, 2807 d3drm_mesh_Clone, 2808 d3drm_mesh_AddDestroyCallback, 2809 d3drm_mesh_DeleteDestroyCallback, 2810 d3drm_mesh_SetAppData, 2811 d3drm_mesh_GetAppData, 2812 d3drm_mesh_SetName, 2813 d3drm_mesh_GetName, 2814 d3drm_mesh_GetClassName, 2815 d3drm_mesh_Scale, 2816 d3drm_mesh_Translate, 2817 d3drm_mesh_GetBox, 2818 d3drm_mesh_AddGroup, 2819 d3drm_mesh_SetVertices, 2820 d3drm_mesh_SetGroupColor, 2821 d3drm_mesh_SetGroupColorRGB, 2822 d3drm_mesh_SetGroupMapping, 2823 d3drm_mesh_SetGroupQuality, 2824 d3drm_mesh_SetGroupMaterial, 2825 d3drm_mesh_SetGroupTexture, 2826 d3drm_mesh_GetGroupCount, 2827 d3drm_mesh_GetGroup, 2828 d3drm_mesh_GetVertices, 2829 d3drm_mesh_GetGroupColor, 2830 d3drm_mesh_GetGroupMapping, 2831 d3drm_mesh_GetGroupQuality, 2832 d3drm_mesh_GetGroupMaterial, 2833 d3drm_mesh_GetGroupTexture, 2834 }; 2835 2836 HRESULT d3drm_mesh_create(struct d3drm_mesh **mesh, IDirect3DRM *d3drm) 2837 { 2838 static const char classname[] = "Mesh"; 2839 struct d3drm_mesh *object; 2840 2841 TRACE("mesh %p, d3drm %p.\n", mesh, d3drm); 2842 2843 if (!(object = heap_alloc_zero(sizeof(*object)))) 2844 return E_OUTOFMEMORY; 2845 2846 object->IDirect3DRMMesh_iface.lpVtbl = &d3drm_mesh_vtbl; 2847 object->ref = 1; 2848 object->d3drm = d3drm; 2849 IDirect3DRM_AddRef(object->d3drm); 2850 2851 d3drm_object_init(&object->obj, classname); 2852 2853 *mesh = object; 2854 2855 return S_OK; 2856 } 2857 2858 static HRESULT WINAPI d3drm_wrap_QueryInterface(IDirect3DRMWrap *iface, REFIID riid, void **out) 2859 { 2860 TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out); 2861 2862 if (IsEqualGUID(riid, &IID_IDirect3DRMWrap) 2863 || IsEqualGUID(riid, &IID_IDirect3DRMObject) 2864 || IsEqualGUID(riid, &IID_IUnknown)) 2865 { 2866 IDirect3DRMWrap_AddRef(iface); 2867 *out = iface; 2868 return S_OK; 2869 } 2870 2871 WARN("%s not implemented.\n", debugstr_guid(riid)); 2872 2873 *out = NULL; 2874 return CLASS_E_CLASSNOTAVAILABLE; 2875 } 2876 2877 static ULONG WINAPI d3drm_wrap_AddRef(IDirect3DRMWrap *iface) 2878 { 2879 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2880 ULONG refcount = InterlockedIncrement(&wrap->ref); 2881 2882 TRACE("%p increasing refcount to %u.\n", iface, refcount); 2883 2884 return refcount; 2885 } 2886 2887 static ULONG WINAPI d3drm_wrap_Release(IDirect3DRMWrap *iface) 2888 { 2889 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2890 ULONG refcount = InterlockedDecrement(&wrap->ref); 2891 2892 TRACE("%p decreasing refcount to %u.\n", iface, refcount); 2893 2894 if (!refcount) 2895 { 2896 d3drm_object_cleanup((IDirect3DRMObject *)iface, &wrap->obj); 2897 heap_free(wrap); 2898 } 2899 2900 return refcount; 2901 } 2902 2903 static HRESULT WINAPI d3drm_wrap_Clone(IDirect3DRMWrap *iface, 2904 IUnknown *outer, REFIID iid, void **out) 2905 { 2906 FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out); 2907 2908 return E_NOTIMPL; 2909 } 2910 2911 static HRESULT WINAPI d3drm_wrap_AddDestroyCallback(IDirect3DRMWrap *iface, 2912 D3DRMOBJECTCALLBACK cb, void *ctx) 2913 { 2914 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2915 2916 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 2917 2918 return d3drm_object_add_destroy_callback(&wrap->obj, cb, ctx); 2919 } 2920 2921 static HRESULT WINAPI d3drm_wrap_DeleteDestroyCallback(IDirect3DRMWrap *iface, 2922 D3DRMOBJECTCALLBACK cb, void *ctx) 2923 { 2924 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2925 2926 TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx); 2927 2928 return d3drm_object_delete_destroy_callback(&wrap->obj, cb, ctx); 2929 } 2930 2931 static HRESULT WINAPI d3drm_wrap_SetAppData(IDirect3DRMWrap *iface, DWORD data) 2932 { 2933 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2934 2935 TRACE("iface %p, data %#x.\n", iface, data); 2936 2937 wrap->obj.appdata = data; 2938 2939 return D3DRM_OK; 2940 } 2941 2942 static DWORD WINAPI d3drm_wrap_GetAppData(IDirect3DRMWrap *iface) 2943 { 2944 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2945 2946 TRACE("iface %p.\n", iface); 2947 2948 return wrap->obj.appdata; 2949 } 2950 2951 static HRESULT WINAPI d3drm_wrap_SetName(IDirect3DRMWrap *iface, const char *name) 2952 { 2953 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2954 2955 TRACE("iface %p, name %s.\n", iface, debugstr_a(name)); 2956 2957 return d3drm_object_set_name(&wrap->obj, name); 2958 } 2959 2960 static HRESULT WINAPI d3drm_wrap_GetName(IDirect3DRMWrap *iface, DWORD *size, char *name) 2961 { 2962 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2963 2964 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 2965 2966 return d3drm_object_get_name(&wrap->obj, size, name); 2967 } 2968 2969 static HRESULT WINAPI d3drm_wrap_GetClassName(IDirect3DRMWrap *iface, DWORD *size, char *name) 2970 { 2971 struct d3drm_wrap *wrap = impl_from_IDirect3DRMWrap(iface); 2972 2973 TRACE("iface %p, size %p, name %p.\n", iface, size, name); 2974 2975 return d3drm_object_get_class_name(&wrap->obj, size, name); 2976 } 2977 2978 static HRESULT WINAPI d3drm_wrap_Init(IDirect3DRMWrap *iface, D3DRMWRAPTYPE type, IDirect3DRMFrame *reference, 2979 D3DVALUE ox, D3DVALUE oy, D3DVALUE oz, D3DVALUE dx, D3DVALUE dy, D3DVALUE dz, D3DVALUE ux, 2980 D3DVALUE uy, D3DVALUE uz, D3DVALUE ou, D3DVALUE ov, D3DVALUE su, D3DVALUE sv) 2981 { 2982 FIXME("iface %p, type %d, reference frame %p, ox %.8e, oy %.8e, oz %.8e, dx %.8e, dy %.8e, dz %.8e, ux %.8e, " 2983 "uy %.8e, uz %.8e, ou %.8e, ov %.8e, su %.8e, sv %.8e.\n", iface, type, reference, ox, oy, oz, dx, dy, dz, 2984 ux, uy, uz, ou, ov, su, sv); 2985 2986 return E_NOTIMPL; 2987 } 2988 2989 static HRESULT WINAPI d3drm_wrap_Apply(IDirect3DRMWrap *iface, IDirect3DRMObject *object) 2990 { 2991 FIXME("iface %p, object %p.\n", iface, object); 2992 2993 return E_NOTIMPL; 2994 } 2995 2996 static HRESULT WINAPI d3drm_wrap_ApplyRelative(IDirect3DRMWrap *iface, IDirect3DRMFrame *frame, 2997 IDirect3DRMObject *object) 2998 { 2999 FIXME("iface %p, frame %p, object %p.\n", iface, frame, object); 3000 3001 return E_NOTIMPL; 3002 } 3003 3004 static const struct IDirect3DRMWrapVtbl d3drm_wrap_vtbl = 3005 { 3006 d3drm_wrap_QueryInterface, 3007 d3drm_wrap_AddRef, 3008 d3drm_wrap_Release, 3009 d3drm_wrap_Clone, 3010 d3drm_wrap_AddDestroyCallback, 3011 d3drm_wrap_DeleteDestroyCallback, 3012 d3drm_wrap_SetAppData, 3013 d3drm_wrap_GetAppData, 3014 d3drm_wrap_SetName, 3015 d3drm_wrap_GetName, 3016 d3drm_wrap_GetClassName, 3017 d3drm_wrap_Init, 3018 d3drm_wrap_Apply, 3019 d3drm_wrap_ApplyRelative, 3020 }; 3021 3022 HRESULT d3drm_wrap_create(struct d3drm_wrap **wrap, IDirect3DRM *d3drm) 3023 { 3024 static const char classname[] = ""; 3025 struct d3drm_wrap *object; 3026 3027 TRACE("wrap %p, d3drm %p.\n", wrap, d3drm); 3028 3029 if (!(object = heap_alloc_zero(sizeof(*object)))) 3030 return E_OUTOFMEMORY; 3031 3032 object->IDirect3DRMWrap_iface.lpVtbl = &d3drm_wrap_vtbl; 3033 object->ref = 1; 3034 3035 d3drm_object_init(&object->obj, classname); 3036 3037 *wrap = object; 3038 3039 return S_OK; 3040 } 3041