Replaced tempnam by mkstemps.
[wine/wine-kai.git] / dlls / ddraw / d3dvertexbuffer.c
blob3052d348cb1f890bf69d4deede9b42c1243b65fa
1 /* Direct3D Viewport
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
21 #include "config.h"
22 #include "windef.h"
23 #include "winerror.h"
24 #include "objbase.h"
25 #include "ddraw.h"
26 #include "d3d.h"
27 #include "wine/debug.h"
29 #include "d3d_private.h"
30 #include "mesa_private.h"
32 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
34 HRESULT WINAPI
35 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
36 REFIID riid,
37 LPVOID* obp)
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 */
43 *obp = NULL;
45 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
46 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
47 *obp = iface;
48 TRACE(" Creating IUnknown interface at %p.\n", *obp);
49 return S_OK;
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);
55 return S_OK;
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);
61 return S_OK;
63 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
64 return OLE_E_ENUM_NOMORE;
67 ULONG WINAPI
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);
72 return ++(This->ref);
75 ULONG WINAPI
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);
83 return 0;
85 return This->ref;
88 HRESULT WINAPI
89 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
90 DWORD dwFlags,
91 LPVOID* lplpData,
92 LPDWORD lpdwSize)
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;
111 return DD_OK;
114 HRESULT WINAPI
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 :-) */
120 return DD_OK;
123 HRESULT WINAPI
124 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
125 DWORD dwVertexOp,
126 DWORD dwDestIndex,
127 DWORD dwCount,
128 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
129 DWORD dwSrcIndex,
130 LPDIRECT3DDEVICE7 lpD3DDevice,
131 DWORD dwFlags)
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);
135 return DD_OK;
138 HRESULT WINAPI
139 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
140 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
142 DWORD size;
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);
152 return DD_OK;
155 HRESULT WINAPI
156 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
157 LPDIRECT3DDEVICE7 lpD3DDevice,
158 DWORD dwFlags)
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;
165 return DD_OK;
168 HRESULT WINAPI
169 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
170 DWORD dwVertexOp,
171 DWORD dwDestIndex,
172 DWORD dwCount,
173 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
174 DWORD dwVertexTypeDesc,
175 LPDIRECT3DDEVICE7 lpD3DDevice,
176 DWORD dwFlags)
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);
180 return DD_OK;
183 HRESULT WINAPI
184 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
185 DWORD dwVertexOp,
186 DWORD dwDestIndex,
187 DWORD dwCount,
188 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
189 DWORD dwSrcIndex,
190 LPDIRECT3DDEVICE3 lpD3DDevice,
191 DWORD dwFlags)
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),
196 dwVertexOp,
197 dwDestIndex,
198 dwCount,
199 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
200 dwSrcIndex,
201 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
202 dwFlags);
205 HRESULT WINAPI
206 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
207 LPDIRECT3DDEVICE3 lpD3DDevice,
208 DWORD dwFlags)
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),
213 dwFlags);
216 HRESULT WINAPI
217 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
218 REFIID riid,
219 LPVOID* obp)
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),
223 riid,
224 obp);
227 ULONG WINAPI
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));
234 ULONG WINAPI
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));
241 HRESULT WINAPI
242 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
243 DWORD dwFlags,
244 LPVOID* lplpData,
245 LPDWORD lpdwSize)
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),
249 dwFlags,
250 lplpData,
251 lpdwSize);
254 HRESULT WINAPI
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));
261 HRESULT WINAPI
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)
272 static HRESULT
273 process_vertices_strided(IDirect3DVertexBufferImpl *This,
274 DWORD dwVertexOp,
275 DWORD dwDestIndex,
276 DWORD dwCount,
277 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
278 DWORD dwVertexTypeDesc,
279 IDirect3DDeviceImpl *device_impl,
280 DWORD dwFlags)
282 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
283 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
284 char *dest_ptr;
285 int i;
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
297 to do).
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++) {
319 int tex_index;
321 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
322 D3DVALUE *position =
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) {
326 D3DVALUE *position =
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) {
334 D3DVALUE *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) {
339 DWORD *color_d =
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) {
344 DWORD *color_s =
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) {
357 D3DVALUE *position =
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) {
361 D3DVALUE *position =
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) {
366 D3DVALUE *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) {
371 DWORD *color_d =
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) {
380 DWORD *color_s =
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]);
394 TRACE("\n");
398 return DD_OK;
401 #undef copy_and_next
403 HRESULT WINAPI
404 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
405 DWORD dwVertexOp,
406 DWORD dwDestIndex,
407 DWORD dwCount,
408 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
409 DWORD dwSrcIndex,
410 LPDIRECT3DDEVICE7 lpD3DDevice,
411 DWORD dwFlags)
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;
417 DWORD size;
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);
434 HRESULT WINAPI
435 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
436 DWORD dwVertexOp,
437 DWORD dwDestIndex,
438 DWORD dwCount,
439 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
440 DWORD dwVertexTypeDesc,
441 LPDIRECT3DDEVICE7 lpD3DDevice,
442 DWORD dwFlags)
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))
463 #else
464 # define XCAST(fun) (void*)
465 #endif
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__)
482 #undef XCAST
483 #endif
486 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
487 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
488 #else
489 # define XCAST(fun) (void*)
490 #endif
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__)
506 #undef XCAST
507 #endif
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;
522 object->ref = 1;
523 object->d3d = d3d;
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);
531 *obj = object;
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);
541 return D3D_OK;