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