Get rid of the no longer used ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
[wine/multimedia.git] / dlls / ddraw / d3dvertexbuffer.c
blob677b93f3eb0d59561e4c37f66765812c9f8f78f9
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 <stdarg.h>
24 #include "windef.h"
25 #include "winbase.h"
26 #include "winerror.h"
27 #include "objbase.h"
28 #include "wingdi.h"
29 #include "ddraw.h"
30 #include "d3d.h"
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);
39 HRESULT WINAPI
40 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
41 REFIID riid,
42 LPVOID* obp)
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 */
48 *obp = NULL;
50 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
51 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
52 *obp = iface;
53 TRACE(" Creating IUnknown interface at %p.\n", *obp);
54 return S_OK;
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);
60 return S_OK;
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);
66 return S_OK;
68 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
69 return OLE_E_ENUM_NOMORE;
72 ULONG WINAPI
73 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
75 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
76 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
77 return ++(This->ref);
80 ULONG WINAPI
81 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
83 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
84 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
85 if (--(This->ref) == 0) {
86 HeapFree(GetProcessHeap(), 0, This->vertices);
87 HeapFree(GetProcessHeap(), 0, This);
88 return 0;
90 return This->ref;
93 HRESULT WINAPI
94 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
95 DWORD dwFlags,
96 LPVOID* lplpData,
97 LPDWORD lpdwSize)
99 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
100 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
102 if (TRACE_ON(ddraw)) {
103 TRACE(" lock flags : ");
104 DDRAW_dump_lockflag(dwFlags);
107 if (This->processed == TRUE) {
108 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
111 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
113 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
114 *lplpData = This->vertices;
116 return DD_OK;
119 HRESULT WINAPI
120 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
122 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
123 TRACE("(%p/%p)->()\n", This, iface);
124 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
125 return DD_OK;
128 HRESULT WINAPI
129 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
130 DWORD dwVertexOp,
131 DWORD dwDestIndex,
132 DWORD dwCount,
133 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
134 DWORD dwSrcIndex,
135 LPDIRECT3DDEVICE7 lpD3DDevice,
136 DWORD dwFlags)
138 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
139 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
140 return DD_OK;
143 HRESULT WINAPI
144 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
145 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
147 DWORD size;
148 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
150 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
152 size = lpD3DVertexBufferDesc->dwSize;
153 memset(lpD3DVertexBufferDesc, 0, size);
154 memcpy(lpD3DVertexBufferDesc, &This->desc,
155 (size < This->desc.dwSize) ? size : This->desc.dwSize);
157 return DD_OK;
160 HRESULT WINAPI
161 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
162 LPDIRECT3DDEVICE7 lpD3DDevice,
163 DWORD dwFlags)
165 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
166 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
168 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
170 return DD_OK;
173 HRESULT WINAPI
174 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
175 DWORD dwVertexOp,
176 DWORD dwDestIndex,
177 DWORD dwCount,
178 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
179 DWORD dwVertexTypeDesc,
180 LPDIRECT3DDEVICE7 lpD3DDevice,
181 DWORD dwFlags)
183 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
184 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
185 return DD_OK;
188 HRESULT WINAPI
189 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
190 DWORD dwVertexOp,
191 DWORD dwDestIndex,
192 DWORD dwCount,
193 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
194 DWORD dwSrcIndex,
195 LPDIRECT3DDEVICE3 lpD3DDevice,
196 DWORD dwFlags)
198 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
199 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
200 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
201 dwVertexOp,
202 dwDestIndex,
203 dwCount,
204 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
205 dwSrcIndex,
206 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
207 dwFlags);
210 HRESULT WINAPI
211 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
212 LPDIRECT3DDEVICE3 lpD3DDevice,
213 DWORD dwFlags)
215 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
216 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
217 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
218 dwFlags);
221 HRESULT WINAPI
222 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
223 REFIID riid,
224 LPVOID* obp)
226 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
227 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
228 riid,
229 obp);
232 ULONG WINAPI
233 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
235 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
236 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
239 ULONG WINAPI
240 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
242 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
243 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
246 HRESULT WINAPI
247 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
248 DWORD dwFlags,
249 LPVOID* lplpData,
250 LPDWORD lpdwSize)
252 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
253 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
254 dwFlags,
255 lplpData,
256 lpdwSize);
259 HRESULT WINAPI
260 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
262 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
263 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
266 HRESULT WINAPI
267 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
268 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
270 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
271 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
272 lpD3DVertexBufferDesc);
275 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
277 static HRESULT
278 process_vertices_strided(IDirect3DVertexBufferImpl *This,
279 DWORD dwVertexOp,
280 DWORD dwDestIndex,
281 DWORD dwCount,
282 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
283 DWORD dwVertexTypeDesc,
284 IDirect3DDeviceImpl *device_impl,
285 DWORD dwFlags)
287 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
288 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
289 char *dest_ptr;
290 int i;
292 This->processed = TRUE;
294 /* For the moment, the trick is to save the transform and lighting state at process
295 time to restore them at drawing time.
297 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
298 processing two different sets of vertices with two different rendering parameters
299 and then to display them using the same DrawPrimitive call.
301 It would be nice to check for such code here (but well, even this is not trivial
302 to do).
304 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
305 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
306 implementing this mostly useless (IMHO) API.
308 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
310 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
311 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
314 if (glThis->vertices == NULL) {
315 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
317 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
319 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
320 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
321 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
323 for (i = 0; i < dwCount; i++) {
324 int tex_index;
326 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
327 D3DVALUE *position =
328 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
329 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
330 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
331 D3DVALUE *position =
332 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
333 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
335 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
336 dest_ptr += sizeof(DWORD);
338 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
339 D3DVALUE *normal =
340 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
341 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
343 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
344 DWORD *color_d =
345 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
346 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
348 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
349 DWORD *color_s =
350 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
351 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
353 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
354 D3DVALUE *tex_coord =
355 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
356 i * lpStrideData->textureCoords[tex_index].dwStride);
357 copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
360 if (TRACE_ON(ddraw_geom)) {
361 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
362 D3DVALUE *position =
363 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
364 TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
365 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
366 D3DVALUE *position =
367 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
368 TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
370 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
371 D3DVALUE *normal =
372 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
373 TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
375 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
376 DWORD *color_d =
377 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
378 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
379 (*color_d >> 16) & 0xFF,
380 (*color_d >> 8) & 0xFF,
381 (*color_d >> 0) & 0xFF,
382 (*color_d >> 24) & 0xFF);
384 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
385 DWORD *color_s =
386 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
387 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
388 (*color_s >> 16) & 0xFF,
389 (*color_s >> 8) & 0xFF,
390 (*color_s >> 0) & 0xFF,
391 (*color_s >> 24) & 0xFF);
393 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
394 D3DVALUE *tex_coord =
395 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
396 i * lpStrideData->textureCoords[tex_index].dwStride);
397 TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
399 TRACE_(ddraw_geom)("\n");
403 return DD_OK;
406 #undef copy_and_next
408 HRESULT WINAPI
409 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
410 DWORD dwVertexOp,
411 DWORD dwDestIndex,
412 DWORD dwCount,
413 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
414 DWORD dwSrcIndex,
415 LPDIRECT3DDEVICE7 lpD3DDevice,
416 DWORD dwFlags)
418 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
419 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
420 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
421 D3DDRAWPRIMITIVESTRIDEDDATA strided;
422 DWORD size;
424 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
426 if (TRACE_ON(ddraw)) {
427 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
428 TRACE(" - flags : "); dump_D3DPV(dwFlags);
431 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
433 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
434 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
436 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
439 HRESULT WINAPI
440 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
441 DWORD dwVertexOp,
442 DWORD dwDestIndex,
443 DWORD dwCount,
444 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
445 DWORD dwVertexTypeDesc,
446 LPDIRECT3DDEVICE7 lpD3DDevice,
447 DWORD dwFlags)
449 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
450 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
452 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
453 if (TRACE_ON(ddraw)) {
454 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
455 TRACE(" - flags : "); dump_D3DPV(dwFlags);
456 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
459 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
461 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
466 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
467 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
468 #else
469 # define XCAST(fun) (void*)
470 #endif
472 IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
474 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
475 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
476 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
477 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
478 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
479 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
480 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
481 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
482 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
485 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
486 #undef XCAST
487 #endif
490 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
491 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
492 #else
493 # define XCAST(fun) (void*)
494 #endif
496 IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
498 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
499 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
500 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
501 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
502 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
503 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
504 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
505 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
508 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
509 #undef XCAST
510 #endif
512 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
514 IDirect3DVertexBufferImpl *object;
515 static const flag_info flags[] = {
516 FE(D3DVBCAPS_DONOTCLIP),
517 FE(D3DVBCAPS_OPTIMIZED),
518 FE(D3DVBCAPS_SYSTEMMEMORY),
519 FE(D3DVBCAPS_WRITEONLY)
522 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
523 if (object == NULL) return DDERR_OUTOFMEMORY;
525 object->ref = 1;
526 object->d3d = d3d;
527 object->desc = *lpD3DVertBufDesc;
528 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
529 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
531 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
532 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
534 *obj = object;
536 if (TRACE_ON(ddraw)) {
537 TRACE(" creating implementation at %p with description : \n", *obj);
538 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
539 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
540 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
544 return D3D_OK;