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