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