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);
35 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
39 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
40 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
42 /* By default, set the object pointer to NULL */
45 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
46 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
48 TRACE(" Creating IUnknown interface at %p.\n", *obp);
51 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
52 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
53 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
54 TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp);
57 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
58 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
59 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
60 TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
63 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
64 return OLE_E_ENUM_NOMORE;
68 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
70 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
71 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
76 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
78 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
79 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
80 if (--(This->ref) == 0) {
81 HeapFree(GetProcessHeap(), 0, This->vertices);
82 HeapFree(GetProcessHeap(), 0, This);
89 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
94 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
95 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
97 if (TRACE_ON(ddraw)) {
98 TRACE(" lock flags : ");
99 DDRAW_dump_lockflag(dwFlags);
102 if (This->processed == TRUE) {
103 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
106 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
108 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
109 *lplpData = This->vertices;
115 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
117 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
118 TRACE("(%p/%p)->()\n", This, iface);
119 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
124 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
128 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
130 LPDIRECT3DDEVICE7 lpD3DDevice,
133 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
134 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
139 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
140 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
143 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
145 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
147 size = lpD3DVertexBufferDesc->dwSize;
148 memset(lpD3DVertexBufferDesc, 0, size);
149 memcpy(lpD3DVertexBufferDesc, &This->desc,
150 (size < This->desc.dwSize) ? size : This->desc.dwSize);
156 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
157 LPDIRECT3DDEVICE7 lpD3DDevice,
160 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
161 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
163 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
169 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
173 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
174 DWORD dwVertexTypeDesc,
175 LPDIRECT3DDEVICE7 lpD3DDevice,
178 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
179 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
184 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
188 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
190 LPDIRECT3DDEVICE3 lpD3DDevice,
193 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
194 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
195 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
199 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
201 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
206 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
207 LPDIRECT3DDEVICE3 lpD3DDevice,
210 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
211 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
212 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
217 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
221 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
222 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
228 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
230 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
231 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
235 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
237 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
238 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
242 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
247 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
248 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
255 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
257 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
258 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
262 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
263 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
265 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
266 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
267 lpD3DVertexBufferDesc);
270 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
273 process_vertices_strided(IDirect3DVertexBufferImpl *This,
277 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
278 DWORD dwVertexTypeDesc,
279 IDirect3DDeviceImpl *device_impl,
282 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
283 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
287 This->processed = TRUE;
289 /* For the moment, the trick is to save the transform and lighting state at process
290 time to restore them at drawing time.
292 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
293 processing two different sets of vertices with two different rendering parameters
294 and then to display them using the same DrawPrimitive call.
296 It would be nice to check for such code here (but well, even this is not trivial
299 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
300 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
301 implementing this mostly useless (IMHO) API.
303 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
305 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
306 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
309 if (glThis->vertices == NULL) {
310 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
312 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
314 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
315 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
316 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
318 for (i = 0; i < dwCount; i++) {
321 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
323 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
324 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
325 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
327 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
328 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
330 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
331 dest_ptr += sizeof(DWORD);
333 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
335 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
336 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
338 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
340 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
341 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
343 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
345 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
346 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
348 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
349 D3DVALUE *tex_coord =
350 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
351 i * lpStrideData->textureCoords[tex_index].dwStride);
352 copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
355 if (TRACE_ON(ddraw)) {
356 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
358 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
359 TRACE(" %f %f %f", position[0], position[1], position[2]);
360 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
362 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
363 TRACE(" %f %f %f %f", position[0], position[1], position[2], position[3]);
365 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
367 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
368 TRACE(" / %f %f %f", normal[0], normal[1], normal[2]);
370 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
372 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
373 TRACE(" / %02lx %02lx %02lx %02lx",
374 (*color_d >> 16) & 0xFF,
375 (*color_d >> 8) & 0xFF,
376 (*color_d >> 0) & 0xFF,
377 (*color_d >> 24) & 0xFF);
379 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
381 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
382 TRACE(" / %02lx %02lx %02lx %02lx",
383 (*color_s >> 16) & 0xFF,
384 (*color_s >> 8) & 0xFF,
385 (*color_s >> 0) & 0xFF,
386 (*color_s >> 24) & 0xFF);
388 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
389 D3DVALUE *tex_coord =
390 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
391 i * lpStrideData->textureCoords[tex_index].dwStride);
392 TRACE(" / %f %f", tex_coord[0], tex_coord[1]);
404 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
408 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
410 LPDIRECT3DDEVICE7 lpD3DDevice,
413 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
414 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
415 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
416 D3DDRAWPRIMITIVESTRIDEDDATA strided;
419 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
421 if (TRACE_ON(ddraw)) {
422 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
423 TRACE(" - flags : "); dump_D3DPV(dwFlags);
426 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
428 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
429 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
431 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
435 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
439 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
440 DWORD dwVertexTypeDesc,
441 LPDIRECT3DDEVICE7 lpD3DDevice,
444 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
445 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
447 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
448 if (TRACE_ON(ddraw)) {
449 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
450 TRACE(" - flags : "); dump_D3DPV(dwFlags);
451 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
454 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
456 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
461 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
462 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
464 # define XCAST(fun) (void*)
467 ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 =
469 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
470 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
471 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
472 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
473 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
474 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
475 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
476 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
477 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
478 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
481 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
486 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
487 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
489 # define XCAST(fun) (void*)
492 ICOM_VTABLE(IDirect3DVertexBuffer) VTABLE_IDirect3DVertexBuffer =
494 ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
495 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
496 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
497 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
498 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
499 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
500 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
501 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
502 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
505 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
509 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirect3DImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
511 IDirect3DVertexBufferImpl *object;
512 static const flag_info flags[] = {
513 FE(D3DVBCAPS_DONOTCLIP),
514 FE(D3DVBCAPS_OPTIMIZED),
515 FE(D3DVBCAPS_SYSTEMMEMORY),
516 FE(D3DVBCAPS_WRITEONLY)
519 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
520 if (object == NULL) return DDERR_OUTOFMEMORY;
524 object->desc = *lpD3DVertBufDesc;
525 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
526 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
528 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
529 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
533 if (TRACE_ON(ddraw)) {
534 TRACE(" creating implementation at %p with description : \n", *obj);
535 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
536 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
537 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);