xref: /reactos/dll/directx/wine/d3drm/face.c (revision 8a978a17)
1 /*
2  * Implementation of IDirect3DRMFace Interface
3  *
4  * Copyright 2013 André Hentschel
5  *
6  * This library is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU Lesser General Public
8  * License as published by the Free Software Foundation; either
9  * version 2.1 of the License, or (at your option) any later version.
10  *
11  * This library is distributed in the hope that it will be useful,
12  * but WITHOUT ANY WARRANTY; without even the implied warranty of
13  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  * Lesser General Public License for more details.
15  *
16  * You should have received a copy of the GNU Lesser General Public
17  * License along with this library; if not, write to the Free Software
18  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
19  */
20 
21 #include "d3drm_private.h"
22 
23 WINE_DEFAULT_DEBUG_CHANNEL(d3drm);
24 
25 static inline struct d3drm_face *impl_from_IDirect3DRMFace(IDirect3DRMFace *iface)
26 {
27     return CONTAINING_RECORD(iface, struct d3drm_face, IDirect3DRMFace_iface);
28 }
29 
30 static inline struct d3drm_face *impl_from_IDirect3DRMFace2(IDirect3DRMFace2 *iface)
31 {
32     return CONTAINING_RECORD(iface, struct d3drm_face, IDirect3DRMFace2_iface);
33 }
34 
35 static HRESULT WINAPI d3drm_face1_QueryInterface(IDirect3DRMFace *iface, REFIID riid, void **out)
36 {
37     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
38 
39     TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
40 
41     if (IsEqualGUID(riid, &IID_IDirect3DRMFace)
42             || IsEqualGUID(riid, &IID_IDirect3DRMObject)
43             || IsEqualGUID(riid, &IID_IUnknown))
44     {
45         *out = &face->IDirect3DRMFace_iface;
46     }
47     else if(IsEqualGUID(riid, &IID_IDirect3DRMFace2))
48     {
49         *out = &face->IDirect3DRMFace2_iface;
50     }
51     else
52     {
53         *out = NULL;
54         WARN("%s not implemented, returning E_NOINTERFACE.\n", debugstr_guid(riid));
55         return E_NOINTERFACE;
56     }
57 
58     IUnknown_AddRef((IUnknown *)*out);
59     return S_OK;
60 }
61 
62 static ULONG WINAPI d3drm_face1_AddRef(IDirect3DRMFace *iface)
63 {
64     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
65     ULONG refcount = InterlockedIncrement(&face->ref);
66 
67     TRACE("%p increasing refcount to %u.\n", iface, refcount);
68 
69     return refcount;
70 }
71 
72 static ULONG WINAPI d3drm_face1_Release(IDirect3DRMFace *iface)
73 {
74     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
75     ULONG refcount = InterlockedDecrement(&face->ref);
76 
77     TRACE("%p decreasing refcount to %u.\n", iface, refcount);
78 
79     if (!refcount)
80     {
81         d3drm_object_cleanup((IDirect3DRMObject *)iface, &face->obj);
82         heap_free(face);
83     }
84 
85     return refcount;
86 }
87 
88 static HRESULT WINAPI d3drm_face1_Clone(IDirect3DRMFace *iface,
89         IUnknown *outer, REFIID iid, void **out)
90 {
91     FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out);
92 
93     return E_NOTIMPL;
94 }
95 
96 static HRESULT WINAPI d3drm_face1_AddDestroyCallback(IDirect3DRMFace *iface,
97         D3DRMOBJECTCALLBACK cb, void *ctx)
98 {
99     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
100 
101     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
102 
103     return IDirect3DRMFace2_AddDestroyCallback(&face->IDirect3DRMFace2_iface, cb, ctx);
104 }
105 
106 static HRESULT WINAPI d3drm_face1_DeleteDestroyCallback(IDirect3DRMFace *iface,
107         D3DRMOBJECTCALLBACK cb, void *ctx)
108 {
109     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
110 
111     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
112 
113     return IDirect3DRMFace2_DeleteDestroyCallback(&face->IDirect3DRMFace2_iface, cb, ctx);
114 }
115 
116 static HRESULT WINAPI d3drm_face2_SetAppData(IDirect3DRMFace2 *iface, DWORD data)
117 {
118     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
119 
120     TRACE("iface %p, data %#x.\n", iface, data);
121 
122     face->obj.appdata = data;
123 
124     return D3DRM_OK;
125 }
126 
127 static HRESULT WINAPI d3drm_face1_SetAppData(IDirect3DRMFace *iface, DWORD data)
128 {
129     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
130 
131     TRACE("iface %p, data %#x.\n", iface, data);
132 
133     return d3drm_face2_SetAppData(&face->IDirect3DRMFace2_iface, data);
134 }
135 
136 static DWORD WINAPI d3drm_face2_GetAppData(IDirect3DRMFace2 *iface)
137 {
138     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
139 
140     TRACE("iface %p.\n", iface);
141 
142     return face->obj.appdata;
143 }
144 
145 static DWORD WINAPI d3drm_face1_GetAppData(IDirect3DRMFace *iface)
146 {
147     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
148 
149     TRACE("iface %p.\n", iface);
150 
151     return d3drm_face2_GetAppData(&face->IDirect3DRMFace2_iface);
152 }
153 
154 static HRESULT WINAPI d3drm_face2_SetName(IDirect3DRMFace2 *iface, const char *name)
155 {
156     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
157 
158     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
159 
160     return d3drm_object_set_name(&face->obj, name);
161 }
162 
163 static HRESULT WINAPI d3drm_face1_SetName(IDirect3DRMFace *iface, const char *name)
164 {
165     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
166 
167     TRACE("iface %p, name %s.\n", iface, debugstr_a(name));
168 
169     return d3drm_face2_SetName(&face->IDirect3DRMFace2_iface, name);
170 }
171 
172 static HRESULT WINAPI d3drm_face2_GetName(IDirect3DRMFace2 *iface, DWORD *size, char *name)
173 {
174     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
175 
176     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
177 
178     return d3drm_object_get_name(&face->obj, size, name);
179 }
180 
181 static HRESULT WINAPI d3drm_face1_GetName(IDirect3DRMFace *iface, DWORD *size, char *name)
182 {
183     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
184 
185     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
186 
187     return d3drm_face2_GetName(&face->IDirect3DRMFace2_iface, size, name);
188 }
189 
190 static HRESULT WINAPI d3drm_face1_GetClassName(IDirect3DRMFace *iface, DWORD *size, char *name)
191 {
192     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
193 
194     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
195 
196     return IDirect3DRMFace2_GetClassName(&face->IDirect3DRMFace2_iface, size, name);
197 }
198 
199 static HRESULT WINAPI d3drm_face1_AddVertex(IDirect3DRMFace *iface, D3DVALUE x, D3DVALUE y, D3DVALUE z)
200 {
201     FIXME("iface %p, x %.8e, y %.8e, z %.8e stub!\n", iface, x, y, z);
202 
203     return E_NOTIMPL;
204 }
205 
206 static HRESULT WINAPI d3drm_face1_AddVertexAndNormalIndexed(IDirect3DRMFace *iface,
207         DWORD vertex, DWORD normal)
208 {
209     FIXME("iface %p, vertex %u, normal %u stub!\n", iface, vertex, normal);
210 
211     return E_NOTIMPL;
212 }
213 
214 static HRESULT WINAPI d3drm_face2_SetColorRGB(IDirect3DRMFace2 *iface, D3DVALUE red, D3DVALUE green, D3DVALUE blue)
215 {
216     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
217 
218     TRACE("iface %p, red %.8e, green %.8e, blue %.8e.\n", iface, red, green, blue);
219 
220     d3drm_set_color(&face->color, red, green, blue, 1.0f);
221 
222     return D3DRM_OK;
223 }
224 
225 static HRESULT WINAPI d3drm_face1_SetColorRGB(IDirect3DRMFace *iface,
226         D3DVALUE red, D3DVALUE green, D3DVALUE blue)
227 {
228     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
229 
230     TRACE("iface %p, red %.8e, green %.8e, blue %.8e.\n", iface, red, green, blue);
231 
232     return d3drm_face2_SetColorRGB(&face->IDirect3DRMFace2_iface, red, green, blue);
233 }
234 
235 static HRESULT WINAPI d3drm_face2_SetColor(IDirect3DRMFace2 *iface, D3DCOLOR color)
236 {
237     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
238 
239     TRACE("iface %p, color 0x%08x.\n", iface, color);
240 
241     face->color = color;
242 
243     return D3DRM_OK;
244 }
245 
246 static HRESULT WINAPI d3drm_face1_SetColor(IDirect3DRMFace *iface, D3DCOLOR color)
247 {
248     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
249 
250     TRACE("iface %p, color 0x%08x.\n", iface, color);
251 
252     return d3drm_face2_SetColor(&face->IDirect3DRMFace2_iface, color);
253 }
254 
255 static HRESULT WINAPI d3drm_face1_SetTexture(IDirect3DRMFace *iface, IDirect3DRMTexture *texture)
256 {
257     FIXME("iface %p, texture %p stub!\n", iface, texture);
258 
259     return E_NOTIMPL;
260 }
261 
262 static HRESULT WINAPI d3drm_face1_SetTextureCoordinates(IDirect3DRMFace *iface,
263         DWORD vertex, D3DVALUE u, D3DVALUE v)
264 {
265     FIXME("iface %p, vertex %u, u %.8e, v %.8e stub!\n", iface, vertex, u, v);
266 
267     return E_NOTIMPL;
268 }
269 
270 static HRESULT WINAPI d3drm_face1_SetMaterial(IDirect3DRMFace *iface, IDirect3DRMMaterial *material)
271 {
272     FIXME("iface %p, material %p stub!\n", iface, material);
273 
274     return E_NOTIMPL;
275 }
276 
277 static HRESULT WINAPI d3drm_face1_SetTextureTopology(IDirect3DRMFace *iface, BOOL wrap_u, BOOL wrap_v)
278 {
279     FIXME("iface %p, wrap_u %#x, wrap_v %#x stub!\n", iface, wrap_u, wrap_v);
280 
281     return E_NOTIMPL;
282 }
283 
284 static HRESULT WINAPI d3drm_face1_GetVertex(IDirect3DRMFace *iface,
285         DWORD index, D3DVECTOR *vertex, D3DVECTOR *normal)
286 {
287     FIXME("iface %p, index %u, vertex %p, normal %p stub!\n", iface, index, vertex, normal);
288 
289     return E_NOTIMPL;
290 }
291 
292 static HRESULT WINAPI d3drm_face1_GetVertices(IDirect3DRMFace *iface,
293         DWORD *vertex_count, D3DVECTOR *coords, D3DVECTOR *normals)
294 {
295     FIXME("iface %p, vertex_count %p, coords %p, normals %p stub!\n",
296             iface, vertex_count, coords, normals);
297 
298     return E_NOTIMPL;
299 }
300 
301 static HRESULT WINAPI d3drm_face1_GetTextureCoordinates(IDirect3DRMFace *iface,
302         DWORD vertex, D3DVALUE *u, D3DVALUE *v)
303 {
304     FIXME("iface %p, vertex %u, u %p, v %p stub!\n", iface, vertex, u, v);
305 
306     return E_NOTIMPL;
307 }
308 
309 static HRESULT WINAPI d3drm_face1_GetTextureTopology(IDirect3DRMFace *iface, BOOL *wrap_u, BOOL *wrap_v)
310 {
311     FIXME("iface %p, wrap_u %p, wrap_v %p stub!\n", iface, wrap_u, wrap_v);
312 
313     return E_NOTIMPL;
314 }
315 
316 static HRESULT WINAPI d3drm_face1_GetNormal(IDirect3DRMFace *iface, D3DVECTOR *normal)
317 {
318     FIXME("iface %p, normal %p stub!\n", iface, normal);
319 
320     return E_NOTIMPL;
321 }
322 
323 static HRESULT WINAPI d3drm_face1_GetTexture(IDirect3DRMFace *iface, IDirect3DRMTexture **texture)
324 {
325     FIXME("iface %p, texture %p stub!\n", iface, texture);
326 
327     return E_NOTIMPL;
328 }
329 
330 static HRESULT WINAPI d3drm_face1_GetMaterial(IDirect3DRMFace *iface, IDirect3DRMMaterial **material)
331 {
332     FIXME("iface %p, material %p stub!\n", iface, material);
333 
334     return E_NOTIMPL;
335 }
336 
337 static int WINAPI d3drm_face1_GetVertexCount(IDirect3DRMFace *iface)
338 {
339     FIXME("iface %p stub!\n", iface);
340 
341     return 0;
342 }
343 
344 static int WINAPI d3drm_face1_GetVertexIndex(IDirect3DRMFace *iface, DWORD which)
345 {
346     FIXME("iface %p, which %u stub!\n", iface, which);
347 
348     return 0;
349 }
350 
351 static int WINAPI d3drm_face1_GetTextureCoordinateIndex(IDirect3DRMFace *iface, DWORD which)
352 {
353     FIXME("iface %p, which %u stub!\n", iface, which);
354 
355     return 0;
356 }
357 
358 static D3DCOLOR WINAPI d3drm_face2_GetColor(IDirect3DRMFace2 *iface)
359 {
360     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
361 
362     TRACE("iface %p.\n", iface);
363 
364     return face->color;
365 }
366 
367 static D3DCOLOR WINAPI d3drm_face1_GetColor(IDirect3DRMFace *iface)
368 {
369     struct d3drm_face *face = impl_from_IDirect3DRMFace(iface);
370 
371     TRACE("iface %p.\n", iface);
372 
373     return d3drm_face2_GetColor(&face->IDirect3DRMFace2_iface);
374 }
375 
376 static const struct IDirect3DRMFaceVtbl d3drm_face1_vtbl =
377 {
378     d3drm_face1_QueryInterface,
379     d3drm_face1_AddRef,
380     d3drm_face1_Release,
381     d3drm_face1_Clone,
382     d3drm_face1_AddDestroyCallback,
383     d3drm_face1_DeleteDestroyCallback,
384     d3drm_face1_SetAppData,
385     d3drm_face1_GetAppData,
386     d3drm_face1_SetName,
387     d3drm_face1_GetName,
388     d3drm_face1_GetClassName,
389     d3drm_face1_AddVertex,
390     d3drm_face1_AddVertexAndNormalIndexed,
391     d3drm_face1_SetColorRGB,
392     d3drm_face1_SetColor,
393     d3drm_face1_SetTexture,
394     d3drm_face1_SetTextureCoordinates,
395     d3drm_face1_SetMaterial,
396     d3drm_face1_SetTextureTopology,
397     d3drm_face1_GetVertex,
398     d3drm_face1_GetVertices,
399     d3drm_face1_GetTextureCoordinates,
400     d3drm_face1_GetTextureTopology,
401     d3drm_face1_GetNormal,
402     d3drm_face1_GetTexture,
403     d3drm_face1_GetMaterial,
404     d3drm_face1_GetVertexCount,
405     d3drm_face1_GetVertexIndex,
406     d3drm_face1_GetTextureCoordinateIndex,
407     d3drm_face1_GetColor,
408 };
409 
410 static HRESULT WINAPI d3drm_face2_QueryInterface(IDirect3DRMFace2 *iface, REFIID riid, void **out)
411 {
412     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
413 
414     return d3drm_face1_QueryInterface(&face->IDirect3DRMFace_iface, riid, out);
415 }
416 
417 static ULONG WINAPI d3drm_face2_AddRef(IDirect3DRMFace2 *iface)
418 {
419     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
420 
421     return d3drm_face1_AddRef(&face->IDirect3DRMFace_iface);
422 }
423 
424 static ULONG WINAPI d3drm_face2_Release(IDirect3DRMFace2 *iface)
425 {
426     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
427 
428     return d3drm_face1_Release(&face->IDirect3DRMFace_iface);
429 }
430 
431 static HRESULT WINAPI d3drm_face2_Clone(IDirect3DRMFace2 *iface,
432         IUnknown *outer, REFIID iid, void **out)
433 {
434     FIXME("iface %p, outer %p, iid %s, out %p stub!\n", iface, outer, debugstr_guid(iid), out);
435 
436     return E_NOTIMPL;
437 }
438 
439 static HRESULT WINAPI d3drm_face2_AddDestroyCallback(IDirect3DRMFace2 *iface,
440         D3DRMOBJECTCALLBACK cb, void *ctx)
441 {
442     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
443 
444     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
445 
446     return d3drm_object_add_destroy_callback(&face->obj, cb, ctx);
447 }
448 
449 static HRESULT WINAPI d3drm_face2_DeleteDestroyCallback(IDirect3DRMFace2 *iface,
450         D3DRMOBJECTCALLBACK cb, void *ctx)
451 {
452     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
453 
454     TRACE("iface %p, cb %p, ctx %p.\n", iface, cb, ctx);
455 
456     return d3drm_object_delete_destroy_callback(&face->obj, cb, ctx);
457 }
458 
459 static HRESULT WINAPI d3drm_face2_GetClassName(IDirect3DRMFace2 *iface, DWORD *size, char *name)
460 {
461     struct d3drm_face *face = impl_from_IDirect3DRMFace2(iface);
462 
463     TRACE("iface %p, size %p, name %p.\n", iface, size, name);
464 
465     return d3drm_object_get_class_name(&face->obj, size, name);
466 }
467 
468 static HRESULT WINAPI d3drm_face2_AddVertex(IDirect3DRMFace2 *iface, D3DVALUE x, D3DVALUE y, D3DVALUE z)
469 {
470     FIXME("iface %p, x %.8e, y %.8e, z %.8e stub!\n", iface, x, y, z);
471 
472     return E_NOTIMPL;
473 }
474 
475 static HRESULT WINAPI d3drm_face2_AddVertexAndNormalIndexed(IDirect3DRMFace2 *iface,
476         DWORD vertex, DWORD normal)
477 {
478     FIXME("iface %p, vertex %u, normal %u stub!\n", iface, vertex, normal);
479 
480     return E_NOTIMPL;
481 }
482 
483 static HRESULT WINAPI d3drm_face2_SetTexture(IDirect3DRMFace2 *iface, IDirect3DRMTexture3 *texture)
484 {
485     FIXME("iface %p, texture %p stub!\n", iface, texture);
486 
487     return E_NOTIMPL;
488 }
489 
490 static HRESULT WINAPI d3drm_face2_SetTextureCoordinates(IDirect3DRMFace2 *iface,
491         DWORD vertex, D3DVALUE u, D3DVALUE v)
492 {
493     FIXME("iface %p, vertex %u, u %.8e, v %.8e stub!\n", iface, vertex, u, v);
494 
495     return E_NOTIMPL;
496 }
497 
498 static HRESULT WINAPI d3drm_face2_SetMaterial(IDirect3DRMFace2 *iface, IDirect3DRMMaterial2 *material)
499 {
500     FIXME("iface %p, material %p stub!\n", iface, material);
501 
502     return E_NOTIMPL;
503 }
504 
505 static HRESULT WINAPI d3drm_face2_SetTextureTopology(IDirect3DRMFace2 *iface, BOOL wrap_u, BOOL wrap_v)
506 {
507     FIXME("iface %p, wrap_u %#x, wrap_v %#x stub!\n", iface, wrap_u, wrap_v);
508 
509     return E_NOTIMPL;
510 }
511 
512 static HRESULT WINAPI d3drm_face2_GetVertex(IDirect3DRMFace2 *iface,
513         DWORD index, D3DVECTOR *vertex, D3DVECTOR *normal)
514 {
515     FIXME("iface %p, index %u, vertex %p, normal %p stub!\n", iface, index, vertex, normal);
516 
517     return E_NOTIMPL;
518 }
519 
520 static HRESULT WINAPI d3drm_face2_GetVertices(IDirect3DRMFace2 *iface,
521         DWORD *vertex_count, D3DVECTOR *coords, D3DVECTOR *normals)
522 {
523     FIXME("iface %p, vertex_count %p, coords %p, normals %p stub!\n",
524             iface, vertex_count, coords, normals);
525 
526     return E_NOTIMPL;
527 }
528 
529 static HRESULT WINAPI d3drm_face2_GetTextureCoordinates(IDirect3DRMFace2 *iface,
530         DWORD vertex, D3DVALUE *u, D3DVALUE *v)
531 {
532     FIXME("iface %p, vertex %u, u %p, v %p stub!\n", iface, vertex, u, v);
533 
534     return E_NOTIMPL;
535 }
536 
537 static HRESULT WINAPI d3drm_face2_GetTextureTopology(IDirect3DRMFace2 *iface, BOOL *wrap_u, BOOL *wrap_v)
538 {
539     FIXME("iface %p, wrap_u %p, wrap_v %p stub!\n", iface, wrap_u, wrap_v);
540 
541     return E_NOTIMPL;
542 }
543 
544 static HRESULT WINAPI d3drm_face2_GetNormal(IDirect3DRMFace2 *iface, D3DVECTOR *normal)
545 {
546     FIXME("iface %p, normal %p stub!\n", iface, normal);
547 
548     return E_NOTIMPL;
549 }
550 
551 static HRESULT WINAPI d3drm_face2_GetTexture(IDirect3DRMFace2 *iface, IDirect3DRMTexture3 **texture)
552 {
553     FIXME("iface %p, texture %p stub!\n", iface, texture);
554 
555     return E_NOTIMPL;
556 }
557 
558 static HRESULT WINAPI d3drm_face2_GetMaterial(IDirect3DRMFace2 *iface, IDirect3DRMMaterial2 **material)
559 {
560     FIXME("iface %p, material %p stub!\n", iface, material);
561 
562     return E_NOTIMPL;
563 }
564 
565 static int WINAPI d3drm_face2_GetVertexCount(IDirect3DRMFace2 *iface)
566 {
567     FIXME("iface %p stub!\n", iface);
568 
569     return 0;
570 }
571 
572 static int WINAPI d3drm_face2_GetVertexIndex(IDirect3DRMFace2 *iface, DWORD which)
573 {
574     FIXME("iface %p, which %u stub!\n", iface, which);
575 
576     return 0;
577 }
578 
579 static int WINAPI d3drm_face2_GetTextureCoordinateIndex(IDirect3DRMFace2 *iface, DWORD which)
580 {
581     FIXME("iface %p, which %u stub!\n", iface, which);
582 
583     return 0;
584 }
585 
586 static const struct IDirect3DRMFace2Vtbl d3drm_face2_vtbl =
587 {
588     d3drm_face2_QueryInterface,
589     d3drm_face2_AddRef,
590     d3drm_face2_Release,
591     d3drm_face2_Clone,
592     d3drm_face2_AddDestroyCallback,
593     d3drm_face2_DeleteDestroyCallback,
594     d3drm_face2_SetAppData,
595     d3drm_face2_GetAppData,
596     d3drm_face2_SetName,
597     d3drm_face2_GetName,
598     d3drm_face2_GetClassName,
599     d3drm_face2_AddVertex,
600     d3drm_face2_AddVertexAndNormalIndexed,
601     d3drm_face2_SetColorRGB,
602     d3drm_face2_SetColor,
603     d3drm_face2_SetTexture,
604     d3drm_face2_SetTextureCoordinates,
605     d3drm_face2_SetMaterial,
606     d3drm_face2_SetTextureTopology,
607     d3drm_face2_GetVertex,
608     d3drm_face2_GetVertices,
609     d3drm_face2_GetTextureCoordinates,
610     d3drm_face2_GetTextureTopology,
611     d3drm_face2_GetNormal,
612     d3drm_face2_GetTexture,
613     d3drm_face2_GetMaterial,
614     d3drm_face2_GetVertexCount,
615     d3drm_face2_GetVertexIndex,
616     d3drm_face2_GetTextureCoordinateIndex,
617     d3drm_face2_GetColor,
618 };
619 
620 HRESULT d3drm_face_create(struct d3drm_face **face)
621 {
622     static const char classname[] = "Face";
623     struct d3drm_face *object;
624 
625     TRACE("face %p.\n", face);
626 
627     if (!(object = heap_alloc_zero(sizeof(*object))))
628         return E_OUTOFMEMORY;
629 
630     object->IDirect3DRMFace_iface.lpVtbl = &d3drm_face1_vtbl;
631     object->IDirect3DRMFace2_iface.lpVtbl = &d3drm_face2_vtbl;
632     object->ref = 1;
633 
634     d3drm_object_init(&object->obj, classname);
635 
636     *face = object;
637 
638     return S_OK;
639 }
640