Moved d3ddevice and direct3d objects files to ddraw root dir.
[wine.git] / dlls / ddraw / vertexbuffer.c
blobdeb970a5a11673f2887621723ebc1ca8e12a4ed5
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 #define CONST_VTABLE
26 #include "windef.h"
27 #include "winbase.h"
28 #include "winerror.h"
29 #include "objbase.h"
30 #include "wingdi.h"
31 #include "ddraw.h"
32 #include "d3d.h"
33 #include "wine/debug.h"
35 #include "d3d_private.h"
36 #include "opengl_private.h"
38 WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
39 WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);
41 HRESULT WINAPI
42 Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
43 REFIID riid,
44 LPVOID* obp)
46 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
47 TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);
49 /* By default, set the object pointer to NULL */
50 *obp = NULL;
52 if ( IsEqualGUID( &IID_IUnknown, riid ) ) {
53 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
54 *obp = iface;
55 TRACE(" Creating IUnknown interface at %p.\n", *obp);
56 return S_OK;
58 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
59 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
60 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
61 TRACE(" Creating IDirect3DVertexBuffer interface %p\n", *obp);
62 return S_OK;
64 if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
65 IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
66 *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
67 TRACE(" Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
68 return S_OK;
70 FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
71 return OLE_E_ENUM_NOMORE;
74 ULONG WINAPI
75 Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
77 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
78 ULONG ref = InterlockedIncrement(&This->ref);
80 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
82 return ref;
85 ULONG WINAPI
86 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
88 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
89 ULONG ref = InterlockedDecrement(&This->ref);
91 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
93 if (ref == 0) {
94 HeapFree(GetProcessHeap(), 0, This->vertices);
95 HeapFree(GetProcessHeap(), 0, This);
96 return 0;
98 return ref;
101 HRESULT WINAPI
102 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
103 DWORD dwFlags,
104 LPVOID* lplpData,
105 LPDWORD lpdwSize)
107 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
108 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
110 if (TRACE_ON(ddraw)) {
111 TRACE(" lock flags : ");
112 DDRAW_dump_lockflag(dwFlags);
115 if (This->processed) {
116 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
119 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
121 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
122 *lplpData = This->vertices;
124 return DD_OK;
127 HRESULT WINAPI
128 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
130 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
131 TRACE("(%p/%p)->()\n", This, iface);
132 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
133 return DD_OK;
136 HRESULT WINAPI
137 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
138 DWORD dwVertexOp,
139 DWORD dwDestIndex,
140 DWORD dwCount,
141 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
142 DWORD dwSrcIndex,
143 LPDIRECT3DDEVICE7 lpD3DDevice,
144 DWORD dwFlags)
146 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
147 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
148 return DD_OK;
151 HRESULT WINAPI
152 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
153 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
155 DWORD size;
156 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
158 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
160 size = lpD3DVertexBufferDesc->dwSize;
161 memset(lpD3DVertexBufferDesc, 0, size);
162 memcpy(lpD3DVertexBufferDesc, &This->desc,
163 (size < This->desc.dwSize) ? size : This->desc.dwSize);
165 return DD_OK;
168 HRESULT WINAPI
169 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
170 LPDIRECT3DDEVICE7 lpD3DDevice,
171 DWORD dwFlags)
173 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
174 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
176 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
178 return DD_OK;
181 HRESULT WINAPI
182 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
183 DWORD dwVertexOp,
184 DWORD dwDestIndex,
185 DWORD dwCount,
186 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
187 DWORD dwVertexTypeDesc,
188 LPDIRECT3DDEVICE7 lpD3DDevice,
189 DWORD dwFlags)
191 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
192 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
193 return DD_OK;
196 HRESULT WINAPI
197 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
198 DWORD dwVertexOp,
199 DWORD dwDestIndex,
200 DWORD dwCount,
201 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
202 DWORD dwSrcIndex,
203 LPDIRECT3DDEVICE3 lpD3DDevice,
204 DWORD dwFlags)
206 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
207 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
208 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
209 dwVertexOp,
210 dwDestIndex,
211 dwCount,
212 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
213 dwSrcIndex,
214 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
215 dwFlags);
218 HRESULT WINAPI
219 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
220 LPDIRECT3DDEVICE3 lpD3DDevice,
221 DWORD dwFlags)
223 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
224 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
225 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
226 dwFlags);
229 HRESULT WINAPI
230 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
231 REFIID riid,
232 LPVOID* obp)
234 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
235 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
236 riid,
237 obp);
240 ULONG WINAPI
241 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
243 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
244 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
247 ULONG WINAPI
248 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
250 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
251 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
254 HRESULT WINAPI
255 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
256 DWORD dwFlags,
257 LPVOID* lplpData,
258 LPDWORD lpdwSize)
260 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
261 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
262 dwFlags,
263 lplpData,
264 lpdwSize);
267 HRESULT WINAPI
268 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
270 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
271 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
274 HRESULT WINAPI
275 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
276 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
278 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
279 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
280 lpD3DVertexBufferDesc);
283 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
285 static HRESULT
286 process_vertices_strided(IDirect3DVertexBufferImpl *This,
287 DWORD dwVertexOp,
288 DWORD dwDestIndex,
289 DWORD dwCount,
290 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
291 DWORD dwVertexTypeDesc,
292 IDirect3DDeviceImpl *device_impl,
293 DWORD dwFlags)
295 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
296 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
297 char *dest_ptr;
298 unsigned int i;
300 This->processed = TRUE;
302 /* For the moment, the trick is to save the transform and lighting state at process
303 time to restore them at drawing time.
305 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
306 processing two different sets of vertices with two different rendering parameters
307 and then to display them using the same DrawPrimitive call.
309 It would be nice to check for such code here (but well, even this is not trivial
310 to do).
312 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
313 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
314 implementing this mostly useless (IMHO) API.
316 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
318 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
319 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
322 if (glThis->vertices == NULL) {
323 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
325 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
327 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
328 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
329 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
331 for (i = 0; i < dwCount; i++) {
332 unsigned int tex_index;
334 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
335 D3DVALUE *position =
336 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
337 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
338 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
339 D3DVALUE *position =
340 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
341 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
343 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
344 dest_ptr += sizeof(DWORD);
346 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
347 D3DVALUE *normal =
348 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
349 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
351 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
352 DWORD *color_d =
353 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
354 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
356 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
357 DWORD *color_s =
358 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
359 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
361 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
362 D3DVALUE *tex_coord =
363 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
364 i * lpStrideData->textureCoords[tex_index].dwStride);
365 copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
368 if (TRACE_ON(ddraw_geom)) {
369 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
370 D3DVALUE *position =
371 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
372 TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
373 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
374 D3DVALUE *position =
375 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
376 TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
378 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
379 D3DVALUE *normal =
380 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
381 TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
383 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
384 DWORD *color_d =
385 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
386 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
387 (*color_d >> 16) & 0xFF,
388 (*color_d >> 8) & 0xFF,
389 (*color_d >> 0) & 0xFF,
390 (*color_d >> 24) & 0xFF);
392 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
393 DWORD *color_s =
394 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
395 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
396 (*color_s >> 16) & 0xFF,
397 (*color_s >> 8) & 0xFF,
398 (*color_s >> 0) & 0xFF,
399 (*color_s >> 24) & 0xFF);
401 for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
402 D3DVALUE *tex_coord =
403 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
404 i * lpStrideData->textureCoords[tex_index].dwStride);
405 TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
407 TRACE_(ddraw_geom)("\n");
411 return DD_OK;
414 #undef copy_and_next
416 HRESULT WINAPI
417 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
418 DWORD dwVertexOp,
419 DWORD dwDestIndex,
420 DWORD dwCount,
421 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
422 DWORD dwSrcIndex,
423 LPDIRECT3DDEVICE7 lpD3DDevice,
424 DWORD dwFlags)
426 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
427 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
428 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
429 D3DDRAWPRIMITIVESTRIDEDDATA strided;
430 DWORD size;
432 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
434 if (TRACE_ON(ddraw)) {
435 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
436 TRACE(" - flags : "); dump_D3DPV(dwFlags);
439 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
441 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
442 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
444 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
447 HRESULT WINAPI
448 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
449 DWORD dwVertexOp,
450 DWORD dwDestIndex,
451 DWORD dwCount,
452 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
453 DWORD dwVertexTypeDesc,
454 LPDIRECT3DDEVICE7 lpD3DDevice,
455 DWORD dwFlags)
457 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
458 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
460 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
461 if (TRACE_ON(ddraw)) {
462 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
463 TRACE(" - flags : "); dump_D3DPV(dwFlags);
464 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
467 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
469 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
474 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
475 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
476 #else
477 # define XCAST(fun) (void*)
478 #endif
480 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
482 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
483 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
484 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
485 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
486 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
487 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
488 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
489 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
490 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
493 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
494 #undef XCAST
495 #endif
498 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
499 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
500 #else
501 # define XCAST(fun) (void*)
502 #endif
504 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
506 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
507 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
508 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
509 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
510 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
511 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
512 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
513 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
516 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
517 #undef XCAST
518 #endif
520 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
522 IDirect3DVertexBufferImpl *object;
523 static const flag_info flags[] = {
524 FE(D3DVBCAPS_DONOTCLIP),
525 FE(D3DVBCAPS_OPTIMIZED),
526 FE(D3DVBCAPS_SYSTEMMEMORY),
527 FE(D3DVBCAPS_WRITEONLY)
530 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
531 if (object == NULL) return DDERR_OUTOFMEMORY;
533 object->ref = 1;
534 object->d3d = d3d;
535 object->desc = *lpD3DVertBufDesc;
536 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
537 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
539 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
540 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
542 *obj = object;
544 if (TRACE_ON(ddraw)) {
545 TRACE(" creating implementation at %p with description : \n", *obj);
546 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
547 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
548 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
552 return D3D_OK;