usp10: Update tests in test_ScriptItemIzeShapePlace to match Windows results.
[wine/multimedia.git] / dlls / ddraw / vertexbuffer.c
blobf4142c58458da11444bda71973a60bf03bae8d96
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, 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 "opengl_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 ULONG ref = InterlockedIncrement(&This->ref);
78 TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, ref - 1);
80 return ref;
83 ULONG WINAPI
84 Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
86 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
87 ULONG ref = InterlockedDecrement(&This->ref);
89 TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, ref + 1);
91 if (ref == 0) {
92 HeapFree(GetProcessHeap(), 0, This->vertices);
93 HeapFree(GetProcessHeap(), 0, This);
94 return 0;
96 return ref;
99 HRESULT WINAPI
100 Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
101 DWORD dwFlags,
102 LPVOID* lplpData,
103 LPDWORD lpdwSize)
105 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
106 TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);
108 if (TRACE_ON(ddraw)) {
109 TRACE(" lock flags : ");
110 DDRAW_dump_lockflag(dwFlags);
113 if (This->processed) {
114 WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
117 if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;
119 if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
120 *lplpData = This->vertices;
122 return DD_OK;
125 HRESULT WINAPI
126 Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
128 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
129 TRACE("(%p/%p)->()\n", This, iface);
130 /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
131 return DD_OK;
134 HRESULT WINAPI
135 Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
136 DWORD dwVertexOp,
137 DWORD dwDestIndex,
138 DWORD dwCount,
139 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
140 DWORD dwSrcIndex,
141 LPDIRECT3DDEVICE7 lpD3DDevice,
142 DWORD dwFlags)
144 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
145 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
146 return DD_OK;
149 HRESULT WINAPI
150 Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
151 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
153 DWORD size;
154 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
156 TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
158 size = lpD3DVertexBufferDesc->dwSize;
159 memset(lpD3DVertexBufferDesc, 0, size);
160 memcpy(lpD3DVertexBufferDesc, &This->desc,
161 (size < This->desc.dwSize) ? size : This->desc.dwSize);
163 return DD_OK;
166 HRESULT WINAPI
167 Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
168 LPDIRECT3DDEVICE7 lpD3DDevice,
169 DWORD dwFlags)
171 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
172 FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);
174 This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;
176 return DD_OK;
179 HRESULT WINAPI
180 Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
181 DWORD dwVertexOp,
182 DWORD dwDestIndex,
183 DWORD dwCount,
184 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
185 DWORD dwVertexTypeDesc,
186 LPDIRECT3DDEVICE7 lpD3DDevice,
187 DWORD dwFlags)
189 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
190 FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
191 return DD_OK;
194 HRESULT WINAPI
195 Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
196 DWORD dwVertexOp,
197 DWORD dwDestIndex,
198 DWORD dwCount,
199 LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
200 DWORD dwSrcIndex,
201 LPDIRECT3DDEVICE3 lpD3DDevice,
202 DWORD dwFlags)
204 TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
205 dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
206 return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
207 dwVertexOp,
208 dwDestIndex,
209 dwCount,
210 COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
211 dwSrcIndex,
212 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
213 dwFlags);
216 HRESULT WINAPI
217 Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
218 LPDIRECT3DDEVICE3 lpD3DDevice,
219 DWORD dwFlags)
221 TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
222 return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
223 COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
224 dwFlags);
227 HRESULT WINAPI
228 Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
229 REFIID riid,
230 LPVOID* obp)
232 TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
233 return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
234 riid,
235 obp);
238 ULONG WINAPI
239 Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
241 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
242 return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
245 ULONG WINAPI
246 Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
248 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
249 return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
252 HRESULT WINAPI
253 Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
254 DWORD dwFlags,
255 LPVOID* lplpData,
256 LPDWORD lpdwSize)
258 TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
259 return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
260 dwFlags,
261 lplpData,
262 lpdwSize);
265 HRESULT WINAPI
266 Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
268 TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
269 return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
272 HRESULT WINAPI
273 Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
274 LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
276 TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
277 return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
278 lpD3DVertexBufferDesc);
281 #define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)
283 static HRESULT
284 process_vertices_strided(IDirect3DVertexBufferImpl *This,
285 DWORD dwVertexOp,
286 DWORD dwDestIndex,
287 DWORD dwCount,
288 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
289 DWORD dwVertexTypeDesc,
290 IDirect3DDeviceImpl *device_impl,
291 DWORD dwFlags)
293 IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
294 DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
295 char *dest_ptr;
296 unsigned int i;
298 This->processed = TRUE;
300 /* For the moment, the trick is to save the transform and lighting state at process
301 time to restore them at drawing time.
303 The BIG problem with this method is nothing prevents D3D to do dirty tricks like
304 processing two different sets of vertices with two different rendering parameters
305 and then to display them using the same DrawPrimitive call.
307 It would be nice to check for such code here (but well, even this is not trivial
308 to do).
310 This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
311 in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
312 implementing this mostly useless (IMHO) API.
314 glThis->dwVertexTypeDesc = dwVertexTypeDesc;
316 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
317 WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
320 if (glThis->vertices == NULL) {
321 glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
323 dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
325 memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
326 memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
327 memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));
329 for (i = 0; i < dwCount; i++) {
330 unsigned int tex_index;
332 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
333 D3DVALUE *position =
334 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
335 copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
336 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
337 D3DVALUE *position =
338 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
339 copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
341 if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
342 dest_ptr += sizeof(DWORD);
344 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
345 D3DVALUE *normal =
346 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
347 copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
349 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
350 DWORD *color_d =
351 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
352 copy_and_next(dest_ptr, color_d, sizeof(DWORD));
354 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
355 DWORD *color_s =
356 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
357 copy_and_next(dest_ptr, color_s, sizeof(DWORD));
359 for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
360 D3DVALUE *tex_coord =
361 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
362 i * lpStrideData->textureCoords[tex_index].dwStride);
363 copy_and_next(dest_ptr, tex_coord, GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index) * sizeof(D3DVALUE));
366 if (TRACE_ON(ddraw_geom)) {
367 if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
368 D3DVALUE *position =
369 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
370 TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
371 } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
372 D3DVALUE *position =
373 (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
374 TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
376 if (dwVertexTypeDesc & D3DFVF_NORMAL) {
377 D3DVALUE *normal =
378 (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);
379 TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
381 if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
382 DWORD *color_d =
383 (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
384 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
385 (*color_d >> 16) & 0xFF,
386 (*color_d >> 8) & 0xFF,
387 (*color_d >> 0) & 0xFF,
388 (*color_d >> 24) & 0xFF);
390 if (dwVertexTypeDesc & D3DFVF_SPECULAR) {
391 DWORD *color_s =
392 (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
393 TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
394 (*color_s >> 16) & 0xFF,
395 (*color_s >> 8) & 0xFF,
396 (*color_s >> 0) & 0xFF,
397 (*color_s >> 24) & 0xFF);
399 for (tex_index = 0; tex_index < GET_TEXCOUNT_FROM_FVF(dwVertexTypeDesc); tex_index++) {
400 D3DVALUE *tex_coord =
401 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
402 i * lpStrideData->textureCoords[tex_index].dwStride);
403 switch (GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)) {
404 case 1: TRACE_(ddraw_geom)(" / %f", tex_coord[0]); break;
405 case 2: TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]); break;
406 case 3: TRACE_(ddraw_geom)(" / %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2]); break;
407 case 4: TRACE_(ddraw_geom)(" / %f %f %f %f", tex_coord[0], tex_coord[1], tex_coord[2], tex_coord[3]); break;
408 default: TRACE_(ddraw_geom)("Invalid texture size (%ld) !!!", GET_TEXCOORD_SIZE_FROM_FVF(dwVertexTypeDesc, tex_index)); break;
411 TRACE_(ddraw_geom)("\n");
415 return DD_OK;
418 #undef copy_and_next
420 HRESULT WINAPI
421 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
422 DWORD dwVertexOp,
423 DWORD dwDestIndex,
424 DWORD dwCount,
425 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
426 DWORD dwSrcIndex,
427 LPDIRECT3DDEVICE7 lpD3DDevice,
428 DWORD dwFlags)
430 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
431 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
432 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
433 D3DDRAWPRIMITIVESTRIDEDDATA strided;
434 DWORD size;
436 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
438 if (TRACE_ON(ddraw)) {
439 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
440 TRACE(" - flags : "); dump_D3DPV(dwFlags);
443 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
445 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
446 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
448 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
451 HRESULT WINAPI
452 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
453 DWORD dwVertexOp,
454 DWORD dwDestIndex,
455 DWORD dwCount,
456 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
457 DWORD dwVertexTypeDesc,
458 LPDIRECT3DDEVICE7 lpD3DDevice,
459 DWORD dwFlags)
461 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
462 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
464 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
465 if (TRACE_ON(ddraw)) {
466 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
467 TRACE(" - flags : "); dump_D3DPV(dwFlags);
468 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
471 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
473 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
478 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
479 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
480 #else
481 # define XCAST(fun) (void*)
482 #endif
484 static const IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
486 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
487 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
488 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
489 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
490 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
491 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
492 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
493 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
494 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
497 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
498 #undef XCAST
499 #endif
502 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
503 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
504 #else
505 # define XCAST(fun) (void*)
506 #endif
508 static const IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
510 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
511 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
512 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
513 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
514 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
515 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
516 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
517 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
520 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
521 #undef XCAST
522 #endif
524 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
526 IDirect3DVertexBufferImpl *object;
527 static const flag_info flags[] = {
528 FE(D3DVBCAPS_DONOTCLIP),
529 FE(D3DVBCAPS_OPTIMIZED),
530 FE(D3DVBCAPS_SYSTEMMEMORY),
531 FE(D3DVBCAPS_WRITEONLY)
534 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
535 if (object == NULL) return DDERR_OUTOFMEMORY;
537 object->ref = 1;
538 object->d3d = d3d;
539 object->desc = *lpD3DVertBufDesc;
540 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
541 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
543 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
544 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
546 *obj = object;
548 if (TRACE_ON(ddraw)) {
549 TRACE(" creating implementation at %p with description :\n", *obj);
550 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
551 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
552 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
556 return D3D_OK;