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
31 #include "wine/debug.h"
33 #include "d3d_private.h"
34 #include "mesa_private.h"
36 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
37 WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
40 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
44 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
45 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
47 /* By default, set the object pointer to NULL */
50 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
51 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
53 TRACE(" Creating IUnknown interface at %p.\n", *obp);
56 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
57 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
58 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
59 TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp);
62 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
63 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
64 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
65 TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
68 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
69 return OLE_E_ENUM_NOMORE;
73 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
75 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
76 ULONG ref = InterlockedIncrement(&This->ref);
78 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
84 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
86 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
87 ULONG ref = InterlockedDecrement(&This->ref);
89 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
92 HeapFree(GetProcessHeap(), 0, This->vertices);
93 HeapFree(GetProcessHeap(), 0, This);
100 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
105 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
106 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
108 if (TRACE_ON(ddraw)) {
109 TRACE(" lock flags : ");
110 DDRAW_dump_lockflag(dwFlags);
113 if (This->processed) {
114 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
117 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
119 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
120 *lplpData = This->vertices;
126 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
128 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
129 TRACE("(%p/%p)->()\n", This, iface);
130 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
135 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
139 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
141 LPDIRECT3DDEVICE7 lpD3DDevice,
144 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
145 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
150 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
151 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
154 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
156 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
158 size = lpD3DVertexBufferDesc->dwSize;
159 memset(lpD3DVertexBufferDesc, 0, size);
160 memcpy(lpD3DVertexBufferDesc, &This->desc,
161 (size < This->desc.dwSize) ? size : This->desc.dwSize);
167 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
168 LPDIRECT3DDEVICE7 lpD3DDevice,
171 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
172 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
174 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
180 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
184 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
185 DWORD dwVertexTypeDesc,
186 LPDIRECT3DDEVICE7 lpD3DDevice,
189 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
190 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
195 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
199 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
201 LPDIRECT3DDEVICE3 lpD3DDevice,
204 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
205 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
206 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
210 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
212 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
217 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
218 LPDIRECT3DDEVICE3 lpD3DDevice,
221 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
222 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
223 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
228 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
232 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
233 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
239 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
241 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
242 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
246 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
248 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
249 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
253 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
258 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
259 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
266 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
268 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
269 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
273 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
274 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
276 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
277 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
278 lpD3DVertexBufferDesc);
281 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
284 process_vertices_strided(IDirect3DVertexBufferImpl *This,
288 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
289 DWORD dwVertexTypeDesc,
290 IDirect3DDeviceImpl *device_impl,
293 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
294 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
298 This->processed = TRUE;
300 /* For the moment, the trick is to save the transform and lighting state at process
301 time to restore them at drawing time.
303 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
304 processing two different sets of vertices with two different rendering parameters
305 and then to display them using the same DrawPrimitive call.
307 It would be nice to check for such code here (but well, even this is not trivial
310 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
311 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
312 implementing this mostly useless (IMHO) API.
314 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
316 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
317 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
320 if (glThis->vertices == NULL) {
321 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
323 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
325 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
326 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
327 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
329 for (i = 0; i < dwCount; i++) {
330 unsigned int tex_index;
332 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
334 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
335 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
336 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
338 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
339 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
341 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
342 dest_ptr += sizeof(DWORD);
344 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
346 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
347 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
349 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
351 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
352 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
354 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
356 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
357 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
359 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
360 D3DVALUE *tex_coord =
361 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
362 i * lpStrideData->textureCoords[tex_index].dwStride);
363 copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
366 if (TRACE_ON(ddraw_geom)) {
367 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
369 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
370 TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
371 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
373 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
374 TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
376 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
378 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
379 TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
381 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
383 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
384 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
385 (*color_d >> 16) & 0xFF,
386 (*color_d >> 8) & 0xFF,
387 (*color_d >> 0) & 0xFF,
388 (*color_d >> 24) & 0xFF);
390 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
392 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
393 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
394 (*color_s >> 16) & 0xFF,
395 (*color_s >> 8) & 0xFF,
396 (*color_s >> 0) & 0xFF,
397 (*color_s >> 24) & 0xFF);
399 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
400 D3DVALUE *tex_coord =
401 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
402 i * lpStrideData->textureCoords[tex_index].dwStride);
403 TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
405 TRACE_(ddraw_geom)("\n");
415 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
419 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
421 LPDIRECT3DDEVICE7 lpD3DDevice,
424 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
425 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
426 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
427 D3DDRAWPRIMITIVESTRIDEDDATA strided;
430 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
432 if (TRACE_ON(ddraw)) {
433 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
434 TRACE(" - flags : "); dump_D3DPV(dwFlags);
437 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
439 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
440 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
442 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
446 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
450 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
451 DWORD dwVertexTypeDesc,
452 LPDIRECT3DDEVICE7 lpD3DDevice,
455 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
456 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
458 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
459 if (TRACE_ON(ddraw)) {
460 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
461 TRACE(" - flags : "); dump_D3DPV(dwFlags);
462 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
465 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
467 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
472 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
473 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
475 # define XCAST(fun) (void*)
478 IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
480 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
481 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
482 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
483 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
484 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
485 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
486 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
487 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
488 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
491 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
496 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
497 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
499 # define XCAST(fun) (void*)
502 IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
504 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
505 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
506 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
507 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
508 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
509 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
510 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
511 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
514 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
518 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
520 IDirect3DVertexBufferImpl *object;
521 static const flag_info flags[] = {
522 FE(D3DVBCAPS_DONOTCLIP),
523 FE(D3DVBCAPS_OPTIMIZED),
524 FE(D3DVBCAPS_SYSTEMMEMORY),
525 FE(D3DVBCAPS_WRITEONLY)
528 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
529 if (object == NULL) return DDERR_OUTOFMEMORY;
533 object->desc = *lpD3DVertBufDesc;
534 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
535 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
537 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
538 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
542 if (TRACE_ON(ddraw)) {
543 TRACE(" creating implementation at %p with description : \n", *obj);
544 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
545 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
546 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);