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 "opengl_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 < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); 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, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index) * 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 < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
400 D3DVALUE *tex_coord =
401 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
402 i * lpStrideData->textureCoords[tex_index].dwStride);
403 switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) {
404 case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break;
405 case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break;
406 case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break;
407 case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break;
408 default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break;
411 TRACE_(ddraw_geom)("\n");
421 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
425 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
427 LPDIRECT3DDEVICE7 lpD3DDevice,
430 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
431 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
432 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
433 D3DDRAWPRIMITIVESTRIDEDDATA strided;
436 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
438 if (TRACE_ON(ddraw)) {
439 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
440 TRACE(" - flags : "); dump_D3DPV(dwFlags);
443 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
445 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
446 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
448 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
452 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
456 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
457 DWORD dwVertexTypeDesc,
458 LPDIRECT3DDEVICE7 lpD3DDevice,
461 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
462 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
464 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
465 if (TRACE_ON(ddraw)) {
466 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
467 TRACE(" - flags : "); dump_D3DPV(dwFlags);
468 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
471 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
473 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
478 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
479 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
481 # define XCAST(fun) (void*)
484 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
486 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
487 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
488 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
489 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
490 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
491 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
492 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
493 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
494 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
497 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
502 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
503 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
505 # define XCAST(fun) (void*)
508 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
510 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
511 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
512 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
513 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
514 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
515 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
516 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
517 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
520 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
524 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
526 IDirect3DVertexBufferImpl *object;
527 static const flag_info flags[] = {
528 FE(D3DVBCAPS_DONOTCLIP),
529 FE(D3DVBCAPS_OPTIMIZED),
530 FE(D3DVBCAPS_SYSTEMMEMORY),
531 FE(D3DVBCAPS_WRITEONLY)
534 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
535 if (object == NULL) return DDERR_OUTOFMEMORY;
539 object->desc = *lpD3DVertBufDesc;
540 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
541 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
543 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
544 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
548 if (TRACE_ON(ddraw)) {
549 TRACE(" creating implementation at %p with description :\n", *obj);
550 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
551 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
552 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);