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 "mesa_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
< ((dwVertexTypeDesc
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); 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
, 2 * 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
< ((dwVertexTypeDesc
& D3DFVF_TEXCOUNT_MASK
) >> D3DFVF_TEXCOUNT_SHIFT
); tex_index
++) {
402 D3DVALUE
*tex_coord
=
403 (D3DVALUE
*) (((char *) lpStrideData
->textureCoords
[tex_index
].lpvData
) +
404 i
* lpStrideData
->textureCoords
[tex_index
].dwStride
);
405 TRACE_(ddraw_geom
)(" / %f %f", tex_coord
[0], tex_coord
[1]);
407 TRACE_(ddraw_geom
)("\n");
417 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface
,
421 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer
,
423 LPDIRECT3DDEVICE7 lpD3DDevice
,
426 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
427 IDirect3DVertexBufferImpl
*src_impl
= ICOM_OBJECT(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, lpSrcBuffer
);
428 IDirect3DDeviceImpl
*device_impl
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice7
, lpD3DDevice
);
429 D3DDRAWPRIMITIVESTRIDEDDATA strided
;
432 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpSrcBuffer
, dwSrcIndex
, lpD3DDevice
, dwFlags
);
434 if (TRACE_ON(ddraw
)) {
435 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp
);
436 TRACE(" - flags : "); dump_D3DPV(dwFlags
);
439 if ((dwVertexOp
& D3DVOP_TRANSFORM
) == 0) return DDERR_INVALIDPARAMS
;
441 size
= get_flexible_vertex_size(src_impl
->desc
.dwFVF
);
442 convert_FVF_to_strided_data(src_impl
->desc
.dwFVF
, ((char *) src_impl
->vertices
) + dwSrcIndex
* size
, &strided
, 0);
444 return process_vertices_strided(This
, dwVertexOp
, dwDestIndex
, dwCount
, &strided
, src_impl
->desc
.dwFVF
, device_impl
, dwFlags
);
448 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface
,
452 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData
,
453 DWORD dwVertexTypeDesc
,
454 LPDIRECT3DDEVICE7 lpD3DDevice
,
457 ICOM_THIS_FROM(IDirect3DVertexBufferImpl
, IDirect3DVertexBuffer7
, iface
);
458 IDirect3DDeviceImpl
*device_impl
= ICOM_OBJECT(IDirect3DDeviceImpl
, IDirect3DDevice7
, lpD3DDevice
);
460 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This
, iface
, dwVertexOp
, dwDestIndex
, dwCount
, lpStrideData
, dwVertexTypeDesc
, lpD3DDevice
, dwFlags
);
461 if (TRACE_ON(ddraw
)) {
462 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp
);
463 TRACE(" - flags : "); dump_D3DPV(dwFlags
);
464 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc
);
467 if ((dwVertexOp
& D3DVOP_TRANSFORM
) == 0) return DDERR_INVALIDPARAMS
;
469 return process_vertices_strided(This
, dwVertexOp
, dwDestIndex
, dwCount
, lpStrideData
, dwVertexTypeDesc
, device_impl
, dwFlags
);
474 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
475 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
477 # define XCAST(fun) (void*)
480 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7
=
482 XCAST(QueryInterface
) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface
,
483 XCAST(AddRef
) Main_IDirect3DVertexBufferImpl_7_1T_AddRef
,
484 XCAST(Release
) Main_IDirect3DVertexBufferImpl_7_1T_Release
,
485 XCAST(Lock
) Main_IDirect3DVertexBufferImpl_7_1T_Lock
,
486 XCAST(Unlock
) Main_IDirect3DVertexBufferImpl_7_1T_Unlock
,
487 XCAST(ProcessVertices
) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices
,
488 XCAST(GetVertexBufferDesc
) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc
,
489 XCAST(Optimize
) Main_IDirect3DVertexBufferImpl_7_1T_Optimize
,
490 XCAST(ProcessVerticesStrided
) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
493 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
498 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
499 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
501 # define XCAST(fun) (void*)
504 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer
=
506 XCAST(QueryInterface
) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface
,
507 XCAST(AddRef
) Thunk_IDirect3DVertexBufferImpl_1_AddRef
,
508 XCAST(Release
) Thunk_IDirect3DVertexBufferImpl_1_Release
,
509 XCAST(Lock
) Thunk_IDirect3DVertexBufferImpl_1_Lock
,
510 XCAST(Unlock
) Thunk_IDirect3DVertexBufferImpl_1_Unlock
,
511 XCAST(ProcessVertices
) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices
,
512 XCAST(GetVertexBufferDesc
) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc
,
513 XCAST(Optimize
) Thunk_IDirect3DVertexBufferImpl_1_Optimize
516 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
520 HRESULT
d3dvertexbuffer_create(IDirect3DVertexBufferImpl
**obj
, IDirectDrawImpl
*d3d
, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc
, DWORD dwFlags
)
522 IDirect3DVertexBufferImpl
*object
;
523 static const flag_info flags
[] = {
524 FE(D3DVBCAPS_DONOTCLIP
),
525 FE(D3DVBCAPS_OPTIMIZED
),
526 FE(D3DVBCAPS_SYSTEMMEMORY
),
527 FE(D3DVBCAPS_WRITEONLY
)
530 object
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, sizeof(IDirect3DVertexBufferGLImpl
));
531 if (object
== NULL
) return DDERR_OUTOFMEMORY
;
535 object
->desc
= *lpD3DVertBufDesc
;
536 object
->vertex_buffer_size
= get_flexible_vertex_size(lpD3DVertBufDesc
->dwFVF
) * lpD3DVertBufDesc
->dwNumVertices
;
537 object
->vertices
= HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY
, object
->vertex_buffer_size
);
539 ICOM_INIT_INTERFACE(object
, IDirect3DVertexBuffer
, VTABLE_IDirect3DVertexBuffer
);
540 ICOM_INIT_INTERFACE(object
, IDirect3DVertexBuffer7
, VTABLE_IDirect3DVertexBuffer7
);
544 if (TRACE_ON(ddraw
)) {
545 TRACE(" creating implementation at %p with description : \n", *obj
);
546 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc
->dwCaps
, flags
, sizeof(flags
)/sizeof(flags
[0]), TRUE
);
547 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc
->dwFVF
);
548 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc
->dwNumVertices
);