Implement NtAccessCheck.
[wine/gsoc-2012-control.git] / dlls / ddraw / d3dvertexbuffer.c
blob7775b871e5d6f593f31cddc4ca377232057e4acf
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 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 < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); 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, 2 * 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 < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
400 D3DVALUE *tex_coord =
401 (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) +
402 i * lpStrideData->textureCoords[tex_index].dwStride);
403 TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
405 TRACE_(ddraw_geom)("\n");
409 return DD_OK;
412 #undef copy_and_next
414 HRESULT WINAPI
415 GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
416 DWORD dwVertexOp,
417 DWORD dwDestIndex,
418 DWORD dwCount,
419 LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
420 DWORD dwSrcIndex,
421 LPDIRECT3DDEVICE7 lpD3DDevice,
422 DWORD dwFlags)
424 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
425 IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
426 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
427 D3DDRAWPRIMITIVESTRIDEDDATA strided;
428 DWORD size;
430 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
432 if (TRACE_ON(ddraw)) {
433 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
434 TRACE(" - flags : "); dump_D3DPV(dwFlags);
437 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
439 size = get_flexible_vertex_size(src_impl->desc.dwFVF);
440 convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);
442 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
445 HRESULT WINAPI
446 GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
447 DWORD dwVertexOp,
448 DWORD dwDestIndex,
449 DWORD dwCount,
450 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
451 DWORD dwVertexTypeDesc,
452 LPDIRECT3DDEVICE7 lpD3DDevice,
453 DWORD dwFlags)
455 ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
456 IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
458 TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
459 if (TRACE_ON(ddraw)) {
460 TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
461 TRACE(" - flags : "); dump_D3DPV(dwFlags);
462 TRACE(" - vertex format : "); dump_flexible_vertex(dwVertexTypeDesc);
465 if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;
467 return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
472 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
473 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
474 #else
475 # define XCAST(fun) (void*)
476 #endif
478 IDirect3DVertexBuffer7Vtbl VTABLE_IDirect3DVertexBuffer7 =
480 XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
481 XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
482 XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
483 XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
484 XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
485 XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
486 XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
487 XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
488 XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
491 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
492 #undef XCAST
493 #endif
496 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
497 # define XCAST(fun) (typeof(VTABLE_IDirect3DVertexBuffer.fun))
498 #else
499 # define XCAST(fun) (void*)
500 #endif
502 IDirect3DVertexBufferVtbl VTABLE_IDirect3DVertexBuffer =
504 XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
505 XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
506 XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
507 XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
508 XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
509 XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
510 XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
511 XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
514 #if !defined(__STRICT_ANSI__) && defined(__GNUC__)
515 #undef XCAST
516 #endif
518 HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
520 IDirect3DVertexBufferImpl *object;
521 static const flag_info flags[] = {
522 FE(D3DVBCAPS_DONOTCLIP),
523 FE(D3DVBCAPS_OPTIMIZED),
524 FE(D3DVBCAPS_SYSTEMMEMORY),
525 FE(D3DVBCAPS_WRITEONLY)
528 object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
529 if (object == NULL) return DDERR_OUTOFMEMORY;
531 object->ref = 1;
532 object->d3d = d3d;
533 object->desc = *lpD3DVertBufDesc;
534 object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
535 object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
537 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer, VTABLE_IDirect3DVertexBuffer);
538 ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);
540 *obj = object;
542 if (TRACE_ON(ddraw)) {
543 TRACE(" creating implementation at %p with description : \n", *obj);
544 TRACE(" flags : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
545 TRACE(" vertex type : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
546 TRACE(" num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
550 return D3D_OK;