Fix two more corner cases in UNIXFS_get_unix_path and UNIXFS_path_to_pidl.
[wine/multimedia.git] / dlls / ddraw / vertexbuffer.c
blob1081815033f2fc7b80f39c9666d485fe36f1ed4e
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 < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); 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, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, i) * 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 < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
402 D3DVALUE *tex_coord =
403 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
404 i * lpStrideData->textureCoords[tex_index].dwStride);
405 switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) {
406 case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break;
407 case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break;
408 case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break;
409 case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break;
410 default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break;
413 TRACE_(ddraw_geom)("\n");
417 return DD_OK;
420 #undef copy_and_next
422 HRESULT WINAPI
423 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
424 DWORD dwVertexOp,
425 DWORD dwDestIndex,
426 DWORD dwCount,
427 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
428 DWORD dwSrcIndex,
429 LPDIRECT3DDEVICE7 lpD3DDevice,
430 DWORD dwFlags)
432 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
433 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
434 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
435 D3DDRAWPRIMITIVESTRIDEDDATA strided;
436 DWORD size;
438 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
440 if (TRACE_ON(ddraw)) {
441 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
442 TRACE(" - flags : "); dump_D3DPV(dwFlags);
445 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
447 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
448 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
450 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
453 HRESULT WINAPI
454 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
455 DWORD dwVertexOp,
456 DWORD dwDestIndex,
457 DWORD dwCount,
458 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
459 DWORD dwVertexTypeDesc,
460 LPDIRECT3DDEVICE7 lpD3DDevice,
461 DWORD dwFlags)
463 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
464 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
466 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
467 if (TRACE_ON(ddraw)) {
468 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
469 TRACE(" - flags : "); dump_D3DPV(dwFlags);
470 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
473 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
475 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
480 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
481 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
482 #else
483 # define XCAST(fun) (void*)
484 #endif
486 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
488 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
489 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
490 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
491 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
492 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
493 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
494 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
495 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
496 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
499 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
500 #undef XCAST
501 #endif
504 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
505 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
506 #else
507 # define XCAST(fun) (void*)
508 #endif
510 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
512 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
513 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
514 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
515 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
516 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
517 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
518 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
519 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
522 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
523 #undef XCAST
524 #endif
526 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
528 IDirect3DVertexBufferImpl *object;
529 static const flag_info flags[] = {
530 FE(D3DVBCAPS_DONOTCLIP),
531 FE(D3DVBCAPS_OPTIMIZED),
532 FE(D3DVBCAPS_SYSTEMMEMORY),
533 FE(D3DVBCAPS_WRITEONLY)
536 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
537 if (object == NULL) return DDERR_OUTOFMEMORY;
539 object->ref = 1;
540 object->d3d = d3d;
541 object->desc = *lpD3DVertBufDesc;
542 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
543 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
545 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
546 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
548 *obj = object;
550 if (TRACE_ON(ddraw)) {
551 TRACE(" creating implementation at %p with description : \n", *obj);
552 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
553 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
554 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
558 return D3D_OK;