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
27 #include "wine/debug.h"
29 #include "d3d_private.h"
30 #include "mesa_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
33 WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
36 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
40 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
41 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
43 /* By default, set the object pointer to NULL */
46 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
47 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
49 TRACE(" Creating IUnknown interface at %p.\n", *obp);
52 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
53 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
54 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
55 TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp);
58 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
59 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
60 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
61 TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
64 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
65 return OLE_E_ENUM_NOMORE;
69 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
71 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
72 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
77 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
79 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
80 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
81 if (--(This->ref) == 0) {
82 HeapFree(GetProcessHeap(), 0, This->vertices);
83 HeapFree(GetProcessHeap(), 0, This);
90 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
95 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
96 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
98 if (TRACE_ON(ddraw)) {
99 TRACE(" lock flags : ");
100 DDRAW_dump_lockflag(dwFlags);
103 if (This->processed == TRUE) {
104 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
107 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
109 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
110 *lplpData = This->vertices;
116 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
118 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
119 TRACE("(%p/%p)->()\n", This, iface);
120 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
125 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
129 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
131 LPDIRECT3DDEVICE7 lpD3DDevice,
134 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
135 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
140 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
141 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
144 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
146 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
148 size = lpD3DVertexBufferDesc->dwSize;
149 memset(lpD3DVertexBufferDesc, 0, size);
150 memcpy(lpD3DVertexBufferDesc, &This->desc,
151 (size < This->desc.dwSize) ? size : This->desc.dwSize);
157 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
158 LPDIRECT3DDEVICE7 lpD3DDevice,
161 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
162 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
164 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
170 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
174 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
175 DWORD dwVertexTypeDesc,
176 LPDIRECT3DDEVICE7 lpD3DDevice,
179 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
180 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
185 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
189 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
191 LPDIRECT3DDEVICE3 lpD3DDevice,
194 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
195 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
196 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
200 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
202 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
207 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
208 LPDIRECT3DDEVICE3 lpD3DDevice,
211 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
212 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
213 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
218 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
222 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
223 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
229 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
231 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
232 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
236 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
238 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
239 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
243 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
248 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
249 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
256 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
258 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
259 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
263 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
264 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
266 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
267 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
268 lpD3DVertexBufferDesc);
271 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
274 process_vertices_strided(IDirect3DVertexBufferImpl *This,
278 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
279 DWORD dwVertexTypeDesc,
280 IDirect3DDeviceImpl *device_impl,
283 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
284 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
288 This->processed = TRUE;
290 /* For the moment, the trick is to save the transform and lighting state at process
291 time to restore them at drawing time.
293 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
294 processing two different sets of vertices with two different rendering parameters
295 and then to display them using the same DrawPrimitive call.
297 It would be nice to check for such code here (but well, even this is not trivial
300 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
301 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
302 implementing this mostly useless (IMHO) API.
304 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
306 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
307 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
310 if (glThis->vertices == NULL) {
311 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
313 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
315 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
316 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
317 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
319 for (i = 0; i < dwCount; i++) {
322 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
324 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
325 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
326 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
328 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
329 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
331 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
332 dest_ptr += sizeof(DWORD);
334 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
336 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
337 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
339 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
341 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
342 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
344 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
346 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
347 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
349 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
350 D3DVALUE *tex_coord =
351 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
352 i * lpStrideData->textureCoords[tex_index].dwStride);
353 copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
356 if (TRACE_ON(ddraw_geom)) {
357 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
359 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
360 TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
361 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
363 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
364 TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
366 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
368 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
369 TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
371 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
373 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
374 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
375 (*color_d >> 16) & 0xFF,
376 (*color_d >> 8) & 0xFF,
377 (*color_d >> 0) & 0xFF,
378 (*color_d >> 24) & 0xFF);
380 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
382 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
383 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
384 (*color_s >> 16) & 0xFF,
385 (*color_s >> 8) & 0xFF,
386 (*color_s >> 0) & 0xFF,
387 (*color_s >> 24) & 0xFF);
389 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
390 D3DVALUE *tex_coord =
391 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
392 i * lpStrideData->textureCoords[tex_index].dwStride);
393 TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
395 TRACE_(ddraw_geom)("\n");
405 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
409 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
411 LPDIRECT3DDEVICE7 lpD3DDevice,
414 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
415 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
416 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
417 D3DDRAWPRIMITIVESTRIDEDDATA strided;
420 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
422 if (TRACE_ON(ddraw)) {
423 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
424 TRACE(" - flags : "); dump_D3DPV(dwFlags);
427 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
429 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
430 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
432 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
436 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
440 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
441 DWORD dwVertexTypeDesc,
442 LPDIRECT3DDEVICE7 lpD3DDevice,
445 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
446 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
448 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
449 if (TRACE_ON(ddraw)) {
450 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
451 TRACE(" - flags : "); dump_D3DPV(dwFlags);
452 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
455 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
457 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
462 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
463 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
465 # define XCAST(fun) (void*)
468 ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 =
470 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
471 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
472 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
473 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
474 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
475 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
476 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
477 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
478 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
479 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
482 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
487 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
488 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
490 # define XCAST(fun) (void*)
493 ICOM_VTABLE(IDirect3DVertexBuffer) VTABLE_IDirect3DVertexBuffer =
495 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
496 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
497 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
498 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
499 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
500 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
501 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
502 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
503 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
506 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
510 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
512 IDirect3DVertexBufferImpl *object;
513 static const flag_info flags[] = {
514 FE(D3DVBCAPS_DONOTCLIP),
515 FE(D3DVBCAPS_OPTIMIZED),
516 FE(D3DVBCAPS_SYSTEMMEMORY),
517 FE(D3DVBCAPS_WRITEONLY)
520 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
521 if (object == NULL) return DDERR_OUTOFMEMORY;
525 object->desc = *lpD3DVertBufDesc;
526 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
527 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
529 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
530 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
534 if (TRACE_ON(ddraw)) {
535 TRACE(" creating implementation at %p with description : \n", *obj);
536 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
537 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
538 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);