2 * Copyright (c) 2002 Lionel ULMER
4 * This file contains the implementation of Direct3DVertexBuffer COM object
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.
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.
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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
33 #include "wine/debug.h"
35 #include "d3d_private.h"
36 #include "opengl_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw
);
39 WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom
);
42 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface
,
46 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
47 TRACE("(%p/%p)->(%s,%p)\n", This
, iface
, debugstr_guid(riid
), obp
);
49 /* By default, set the object pointer to NULL */
52 if ( IsEqualGUID( &IID_IUnknown
, riid
) ) {
53 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This
,IDirect3DVertexBuffer7
));
55 TRACE(" Creating IUnknown interface at %p.\n", *obp
);
58 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer
, riid
) ) {
59 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This
,IDirect3DVertexBuffer7
));
60 *obp
= ICOM_INTERFACE(This
, IDirect3DVertexBuffer
);
61 TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp
);
64 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7
, riid
) ) {
65 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This
,IDirect3DVertexBuffer7
));
66 *obp
= ICOM_INTERFACE(This
, IDirect3DVertexBuffer7
);
67 TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp
);
70 FIXME("(%p): interface for IID %s NOT found!\n", This
, debugstr_guid(riid
));
71 return OLE_E_ENUM_NOMORE
;
75 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface
)
77 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
78 ULONG ref
= InterlockedIncrement(&This
->ref
);
80 TRACE("(%p/%p)->() incrementing from %lu.\n", This
, iface
, ref
- 1);
86 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface
)
88 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
89 ULONG ref
= InterlockedDecrement(&This
->ref
);
91 TRACE("(%p/%p)->() decrementing from %lu.\n", This
, iface
, ref
+ 1);
94 HeapFree(GetProcessHeap(), 0, This
->vertices
);
95 HeapFree(GetProcessHeap(), 0, This
);
102 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface
,
107 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
108 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This
, iface
, dwFlags
, lplpData
, lpdwSize
);
110 if (TRACE_ON(ddraw
)) {
111 TRACE(" lock flags : ");
112 DDRAW_dump_lockflag(dwFlags
);
115 if (This
->processed
) {
116 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
119 if (This
->desc
.dwCaps
& D3DVBCAPS_OPTIMIZED
) return D3DERR_VERTEXBUFFEROPTIMIZED
;
121 if (lpdwSize
!= NULL
) *lpdwSize
= This
->vertex_buffer_size
;
122 *lplpData
= This
->vertices
;
128 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface
)
130 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
131 TRACE("(%p/%p)->()\n", This
, iface
);
132 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
137 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface
,
141 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer
,
143 LPDIRECT3DDEVICE7 lpD3DDevice
,
146 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
147 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpSrcBuffer
, dwSrcIndex
, lpD3DDevice
, dwFlags
);
152 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface
,
153 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc
)
156 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
158 TRACE("(%p/%p)->(%p)\n", This
, iface
, lpD3DVertexBufferDesc
);
160 size
= lpD3DVertexBufferDesc
->dwSize
;
161 memset(lpD3DVertexBufferDesc
, 0, size
);
162 memcpy(lpD3DVertexBufferDesc
, &This
->desc
,
163 (size
< This
->desc
.dwSize
) ? size
: This
->desc
.dwSize
);
169 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface
,
170 LPDIRECT3DDEVICE7 lpD3DDevice
,
173 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
174 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This
, iface
, lpD3DDevice
, dwFlags
);
176 This
->desc
.dwCaps
|= D3DVBCAPS_OPTIMIZED
;
182 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface
,
186 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData
,
187 DWORD dwVertexTypeDesc
,
188 LPDIRECT3DDEVICE7 lpD3DDevice
,
191 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
192 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpStrideData
, dwVertexTypeDesc
, lpD3DDevice
, dwFlags
);
197 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface
,
201 LPDIRECT3DVERTEXBUFFER lpSrcBuffer
,
203 LPDIRECT3DDEVICE3 lpD3DDevice
,
206 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface
,
207 dwVertexOp
, dwDestIndex
, dwCount
, lpSrcBuffer
, dwSrcIndex
, lpD3DDevice
, dwFlags
);
208 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
),
212 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, lpSrcBuffer
),
214 COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice3
, IDirect3DDevice7
, lpD3DDevice
),
219 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface
,
220 LPDIRECT3DDEVICE3 lpD3DDevice
,
223 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface
, lpD3DDevice
, dwFlags
);
224 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
),
225 COM_INTERFACE_CAST(IDirect3DDeviceImpl
, IDirect3DDevice3
, IDirect3DDevice7
, lpD3DDevice
),
230 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface
,
234 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface
, debugstr_guid(riid
), obp
);
235 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
),
241 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface
)
243 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface
);
244 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
));
248 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface
)
250 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface
);
251 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
));
255 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface
,
260 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface
, dwFlags
, lplpData
, lpdwSize
);
261 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
),
268 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface
)
270 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface
);
271 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
));
275 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface
,
276 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc
)
278 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface
, lpD3DVertexBufferDesc
);
279 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer
, IDirect3DVertexBuffer7
, iface
),
280 lpD3DVertexBufferDesc
);
283 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
286 process_vertices_strided(IDirect3DVertexBufferImpl
*This
,
290 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData
,
291 DWORD dwVertexTypeDesc
,
292 IDirect3DDeviceImpl
*device_impl
,
295 IDirect3DVertexBufferGLImpl
*glThis
= (IDirect3DVertexBufferGLImpl
*) This
;
296 DWORD size
= get_flexible_vertex_size(dwVertexTypeDesc
);
300 This
->processed
= TRUE
;
302 /* For the moment, the trick is to save the transform and lighting state at process
303 time to restore them at drawing time.
305 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
306 processing two different sets of vertices with two different rendering parameters
307 and then to display them using the same DrawPrimitive call.
309 It would be nice to check for such code here (but well, even this is not trivial
312 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
313 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
314 implementing this mostly useless (IMHO) API.
316 glThis
->dwVertexTypeDesc
= dwVertexTypeDesc
;
318 if (dwVertexTypeDesc
& D3DFVF_NORMAL
) {
319 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
322 if (glThis
->vertices
== NULL
) {
323 glThis
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, size
* This
->desc
.dwNumVertices
);
325 dest_ptr
= ((char *) glThis
->vertices
) + dwDestIndex
* size
;
327 memcpy(&(glThis
->world_mat
), device_impl
->world_mat
, sizeof(D3DMATRIX
));
328 memcpy(&(glThis
->view_mat
), device_impl
->view_mat
, sizeof(D3DMATRIX
));
329 memcpy(&(glThis
->proj_mat
), device_impl
->proj_mat
, sizeof(D3DMATRIX
));
331 for (i
= 0; i
< dwCount
; i
++) {
332 unsigned int tex_index
;
334 if ((dwVertexTypeDesc
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
336 (D3DVALUE
*) (((char *) lpStrideData
->position
.lpvData
) + i
* lpStrideData
->position
.dwStride
);
337 copy_and_next(dest_ptr
, position
, 3 * sizeof(D3DVALUE
));
338 } else if ((dwVertexTypeDesc
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
340 (D3DVALUE
*) (((char *) lpStrideData
->position
.lpvData
) + i
* lpStrideData
->position
.dwStride
);
341 copy_and_next(dest_ptr
, position
, 4 * sizeof(D3DVALUE
));
343 if (dwVertexTypeDesc
& D3DFVF_RESERVED1
) {
344 dest_ptr
+= sizeof(DWORD
);
346 if (dwVertexTypeDesc
& D3DFVF_NORMAL
) {
348 (D3DVALUE
*) (((char *) lpStrideData
->normal
.lpvData
) + i
* lpStrideData
->normal
.dwStride
);
349 copy_and_next(dest_ptr
, normal
, 3 * sizeof(D3DVALUE
));
351 if (dwVertexTypeDesc
& D3DFVF_DIFFUSE
) {
353 (DWORD
*) (((char *) lpStrideData
->diffuse
.lpvData
) + i
* lpStrideData
->diffuse
.dwStride
);
354 copy_and_next(dest_ptr
, color_d
, sizeof(DWORD
));
356 if (dwVertexTypeDesc
& D3DFVF_SPECULAR
) {
358 (DWORD
*) (((char *) lpStrideData
->specular
.lpvData
) + i
* lpStrideData
->specular
.dwStride
);
359 copy_and_next(dest_ptr
, color_s
, sizeof(DWORD
));
361 for (tex_index
= 0; tex_index
< GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc
); tex_index
++) {
362 D3DVALUE
*tex_coord
=
363 (D3DVALUE
*) (((char *) lpStrideData
->textureCoords
[tex_index
].lpvData
) +
364 i
* lpStrideData
->textureCoords
[tex_index
].dwStride
);
365 copy_and_next(dest_ptr
, tex_coord
, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc
, i
) * sizeof(D3DVALUE
));
368 if (TRACE_ON(ddraw_geom
)) {
369 if ((dwVertexTypeDesc
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZ
) {
371 (D3DVALUE
*) (((char *) lpStrideData
->position
.lpvData
) + i
* lpStrideData
->position
.dwStride
);
372 TRACE_(ddraw_geom
)(" %f %f %f", position
[0], position
[1], position
[2]);
373 } else if ((dwVertexTypeDesc
& D3DFVF_POSITION_MASK
) == D3DFVF_XYZRHW
) {
375 (D3DVALUE
*) (((char *) lpStrideData
->position
.lpvData
) + i
* lpStrideData
->position
.dwStride
);
376 TRACE_(ddraw_geom
)(" %f %f %f %f", position
[0], position
[1], position
[2], position
[3]);
378 if (dwVertexTypeDesc
& D3DFVF_NORMAL
) {
380 (D3DVALUE
*) (((char *) lpStrideData
->normal
.lpvData
) + i
* lpStrideData
->normal
.dwStride
);
381 TRACE_(ddraw_geom
)(" / %f %f %f", normal
[0], normal
[1], normal
[2]);
383 if (dwVertexTypeDesc
& D3DFVF_DIFFUSE
) {
385 (DWORD
*) (((char *) lpStrideData
->diffuse
.lpvData
) + i
* lpStrideData
->diffuse
.dwStride
);
386 TRACE_(ddraw_geom
)(" / %02lx %02lx %02lx %02lx",
387 (*color_d
>> 16) & 0xFF,
388 (*color_d
>> 8) & 0xFF,
389 (*color_d
>> 0) & 0xFF,
390 (*color_d
>> 24) & 0xFF);
392 if (dwVertexTypeDesc
& D3DFVF_SPECULAR
) {
394 (DWORD
*) (((char *) lpStrideData
->specular
.lpvData
) + i
* lpStrideData
->specular
.dwStride
);
395 TRACE_(ddraw_geom
)(" / %02lx %02lx %02lx %02lx",
396 (*color_s
>> 16) & 0xFF,
397 (*color_s
>> 8) & 0xFF,
398 (*color_s
>> 0) & 0xFF,
399 (*color_s
>> 24) & 0xFF);
401 for (tex_index
= 0; tex_index
< GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc
); tex_index
++) {
402 D3DVALUE
*tex_coord
=
403 (D3DVALUE
*) (((char *) lpStrideData
->textureCoords
[tex_index
].lpvData
) +
404 i
* lpStrideData
->textureCoords
[tex_index
].dwStride
);
405 switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc
, tex_index
)) {
406 case 1: TRACE_(ddraw_geom
)(" / %f", tex_coord
[0]); break;
407 case 2: TRACE_(ddraw_geom
)(" / %f %f", tex_coord
[0], tex_coord
[1]); break;
408 case 3: TRACE_(ddraw_geom
)(" / %f %f %f", tex_coord
[0], tex_coord
[1], tex_coord
[2]); break;
409 case 4: TRACE_(ddraw_geom
)(" / %f %f %f %f", tex_coord
[0], tex_coord
[1], tex_coord
[2], tex_coord
[3]); break;
410 default: TRACE_(ddraw_geom
)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc
, tex_index
)); break;
413 TRACE_(ddraw_geom
)("\n");
423 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface
,
427 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer
,
429 LPDIRECT3DDEVICE7 lpD3DDevice
,
432 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
433 IDirect3DVertexBufferImpl
*src_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpSrcBuffer
);
434 IDirect3DDeviceImpl
*device_impl
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice7
, lpD3DDevice
);
435 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
438 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpSrcBuffer
, dwSrcIndex
, lpD3DDevice
, dwFlags
);
440 if (TRACE_ON(ddraw
)) {
441 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp
);
442 TRACE(" - flags : "); dump_D3DPV(dwFlags
);
445 if ((dwVertexOp
& D3DVOP_TRANSFORM
) == 0) return DDERR_INVALIDPARAMS
;
447 size
= get_flexible_vertex_size(src_impl
->desc
.dwFVF
);
448 convert_FVF_to_strided_data(src_impl
->desc
.dwFVF
, ((char *) src_impl
->vertices
) + dwSrcIndex
* size
, &strided
, 0);
450 return process_vertices_strided(This
, dwVertexOp
, dwDestIndex
, dwCount
, &strided
, src_impl
->desc
.dwFVF
, device_impl
, dwFlags
);
454 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface
,
458 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData
,
459 DWORD dwVertexTypeDesc
,
460 LPDIRECT3DDEVICE7 lpD3DDevice
,
463 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
464 IDirect3DDeviceImpl
*device_impl
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice7
, lpD3DDevice
);
466 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpStrideData
, dwVertexTypeDesc
, lpD3DDevice
, dwFlags
);
467 if (TRACE_ON(ddraw
)) {
468 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp
);
469 TRACE(" - flags : "); dump_D3DPV(dwFlags
);
470 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc
);
473 if ((dwVertexOp
& D3DVOP_TRANSFORM
) == 0) return DDERR_INVALIDPARAMS
;
475 return process_vertices_strided(This
, dwVertexOp
, dwDestIndex
, dwCount
, lpStrideData
, dwVertexTypeDesc
, device_impl
, dwFlags
);
480 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
481 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
483 # define XCAST(fun) (void*)
486 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7
=
488 XCAST(QueryInterface
) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface
,
489 XCAST(AddRef
) Main_IDirect3DVertexBufferImpl_7_1T_AddRef
,
490 XCAST(Release
) Main_IDirect3DVertexBufferImpl_7_1T_Release
,
491 XCAST(Lock
) Main_IDirect3DVertexBufferImpl_7_1T_Lock
,
492 XCAST(Unlock
) Main_IDirect3DVertexBufferImpl_7_1T_Unlock
,
493 XCAST(ProcessVertices
) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices
,
494 XCAST(GetVertexBufferDesc
) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc
,
495 XCAST(Optimize
) Main_IDirect3DVertexBufferImpl_7_1T_Optimize
,
496 XCAST(ProcessVerticesStrided
) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
499 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
504 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
505 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
507 # define XCAST(fun) (void*)
510 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer
=
512 XCAST(QueryInterface
) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface
,
513 XCAST(AddRef
) Thunk_IDirect3DVertexBufferImpl_1_AddRef
,
514 XCAST(Release
) Thunk_IDirect3DVertexBufferImpl_1_Release
,
515 XCAST(Lock
) Thunk_IDirect3DVertexBufferImpl_1_Lock
,
516 XCAST(Unlock
) Thunk_IDirect3DVertexBufferImpl_1_Unlock
,
517 XCAST(ProcessVertices
) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices
,
518 XCAST(GetVertexBufferDesc
) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc
,
519 XCAST(Optimize
) Thunk_IDirect3DVertexBufferImpl_1_Optimize
522 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
526 HRESULT
d3dvertexbuffer_create(IDirect3DVertexBufferImpl
**obj
, IDirectDrawImpl
*d3d
, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc
, DWORD dwFlags
)
528 IDirect3DVertexBufferImpl
*object
;
529 static const flag_info flags
[] = {
530 FE(D3DVBCAPS_DONOTCLIP
),
531 FE(D3DVBCAPS_OPTIMIZED
),
532 FE(D3DVBCAPS_SYSTEMMEMORY
),
533 FE(D3DVBCAPS_WRITEONLY
)
536 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVertexBufferGLImpl
));
537 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
541 object
->desc
= *lpD3DVertBufDesc
;
542 object
->vertex_buffer_size
= get_flexible_vertex_size(lpD3DVertBufDesc
->dwFVF
) * lpD3DVertBufDesc
->dwNumVertices
;
543 object
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->vertex_buffer_size
);
545 ICOM_INIT_INTERFACE(object
, IDirect3DVertexBuffer
, VTABLE_IDirect3DVertexBuffer
);
546 ICOM_INIT_INTERFACE(object
, IDirect3DVertexBuffer7
, VTABLE_IDirect3DVertexBuffer7
);
550 if (TRACE_ON(ddraw
)) {
551 TRACE(" creating implementation at %p with description : \n", *obj
);
552 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc
->dwCaps
, flags
, sizeof(flags
)/sizeof(flags
[0]), TRUE
);
553 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc
->dwFVF
);
554 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc
->dwNumVertices
);