/* Direct3D Viewport
 * Copyright (c) 2002 Lionel ULMER
 *
 * This file contains the implementation of Direct3DVertexBuffer COM object
 *
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 */

#include "config.h"
#include <stdarg.h>

#include "windef.h"
#include "winbase.h"
#include "winerror.h"
#include "objbase.h"
#include "wingdi.h"
#include "ddraw.h"
#include "d3d.h"
#include "wine/debug.h"

#include "d3d_private.h"
#include "mesa_private.h"

WINE_DEFAULT_DEBUG_CHANNEL(ddraw);
WINE_DECLARE_DEBUG_CHANNEL(ddraw_geom);

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface(LPDIRECT3DVERTEXBUFFER7 iface,
                                                   REFIID riid,
                                                   LPVOID* obp)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    TRACE("(%p/%p)->(%s,%p)\n", This, iface, debugstr_guid(riid), obp);

    /* By default, set the object pointer to NULL */
    *obp = NULL;
      
    if ( IsEqualGUID( &IID_IUnknown,  riid ) ) {
        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
	*obp = iface;
	TRACE("  Creating IUnknown interface at %p.\n", *obp);
	return S_OK;
    }
    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer, riid ) ) {
        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer);
	TRACE("  Creating IDirect3DVertexBuffer interface %p\n", *obp);
	return S_OK;
    }
    if ( IsEqualGUID( &IID_IDirect3DVertexBuffer7, riid ) ) {
        IDirect3DVertexBuffer7_AddRef(ICOM_INTERFACE(This,IDirect3DVertexBuffer7));
        *obp = ICOM_INTERFACE(This, IDirect3DVertexBuffer7);
	TRACE("  Creating IDirect3DVertexBuffer7 interface %p\n", *obp);
	return S_OK;
    }
    FIXME("(%p): interface for IID %s NOT found!\n", This, debugstr_guid(riid));
    return OLE_E_ENUM_NOMORE;
}

ULONG WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_AddRef(LPDIRECT3DVERTEXBUFFER7 iface)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    TRACE("(%p/%p)->() incrementing from %lu.\n", This, iface, This->ref);
    return ++(This->ref);
}

ULONG WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_Release(LPDIRECT3DVERTEXBUFFER7 iface)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    TRACE("(%p/%p)->() decrementing from %lu.\n", This, iface, This->ref);
    if (--(This->ref) == 0) {
        HeapFree(GetProcessHeap(), 0, This->vertices);
	HeapFree(GetProcessHeap(), 0, This);
	return 0;
    }
    return This->ref;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_Lock(LPDIRECT3DVERTEXBUFFER7 iface,
                                         DWORD dwFlags,
                                         LPVOID* lplpData,
                                         LPDWORD lpdwSize)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    TRACE("(%p/%p)->(%08lx,%p,%p)\n", This, iface, dwFlags, lplpData, lpdwSize);

    if (TRACE_ON(ddraw)) {
        TRACE(" lock flags : ");
	DDRAW_dump_lockflag(dwFlags);
    }
    
    if (This->processed == TRUE) {
        WARN(" application does a Lock on a vertex buffer resulting from a ProcessVertices call. Expect problems !\n");
    }

    if (This->desc.dwCaps & D3DVBCAPS_OPTIMIZED) return D3DERR_VERTEXBUFFEROPTIMIZED;

    if (lpdwSize != NULL) *lpdwSize = This->vertex_buffer_size;
    *lplpData = This->vertices;
    
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_Unlock(LPDIRECT3DVERTEXBUFFER7 iface)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    TRACE("(%p/%p)->()\n", This, iface);
    /* Nothing to do here for now. Maybe some optimizations if ever we want to do some :-) */
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
						    DWORD dwVertexOp,
						    DWORD dwDestIndex,
						    DWORD dwCount,
						    LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
						    DWORD dwSrcIndex,
						    LPDIRECT3DDEVICE7 lpD3DDevice,
						    DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);    
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER7 iface,
                                                        LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
{
    DWORD size;
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    
    TRACE("(%p/%p)->(%p)\n", This, iface, lpD3DVertexBufferDesc);
    
    size = lpD3DVertexBufferDesc->dwSize;
    memset(lpD3DVertexBufferDesc, 0, size);
    memcpy(lpD3DVertexBufferDesc, &This->desc, 
	   (size < This->desc.dwSize) ? size : This->desc.dwSize);
    
    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_1T_Optimize(LPDIRECT3DVERTEXBUFFER7 iface,
					     LPDIRECT3DDEVICE7 lpD3DDevice,
					     DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    FIXME("(%p/%p)->(%p,%08lx): stub!\n", This, iface, lpD3DDevice, dwFlags);

    This->desc.dwCaps |= D3DVBCAPS_OPTIMIZED;

    return DD_OK;
}

HRESULT WINAPI
Main_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
                                                        DWORD dwVertexOp,
                                                        DWORD dwDestIndex,
                                                        DWORD dwCount,
                                                        LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
                                                        DWORD dwVertexTypeDesc,
                                                        LPDIRECT3DDEVICE7 lpD3DDevice,
                                                        DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    FIXME("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx): stub!\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
    return DD_OK;
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices(LPDIRECT3DVERTEXBUFFER iface,
						  DWORD dwVertexOp,
						  DWORD dwDestIndex,
						  DWORD dwCount,
						  LPDIRECT3DVERTEXBUFFER lpSrcBuffer,
						  DWORD dwSrcIndex,
						  LPDIRECT3DDEVICE3 lpD3DDevice,
						  DWORD dwFlags)
{
    TRACE("(%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface,
	  dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);
    return IDirect3DVertexBuffer7_ProcessVertices(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
						  dwVertexOp,
						  dwDestIndex,
						  dwCount,
						  COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, lpSrcBuffer),
						  dwSrcIndex,
						  COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
						  dwFlags);
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_Optimize(LPDIRECT3DVERTEXBUFFER iface,
					   LPDIRECT3DDEVICE3 lpD3DDevice,
					   DWORD dwFlags)
{
    TRACE("(%p)->(%p,%08lx) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DDevice, dwFlags);
    return IDirect3DVertexBuffer7_Optimize(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
					   COM_INTERFACE_CAST(IDirect3DDeviceImpl, IDirect3DDevice3, IDirect3DDevice7, lpD3DDevice),
					   dwFlags);
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_QueryInterface(LPDIRECT3DVERTEXBUFFER iface,
                                                 REFIID riid,
                                                 LPVOID* obp)
{
    TRACE("(%p)->(%s,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, debugstr_guid(riid), obp);
    return IDirect3DVertexBuffer7_QueryInterface(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
                                                 riid,
                                                 obp);
}

ULONG WINAPI
Thunk_IDirect3DVertexBufferImpl_1_AddRef(LPDIRECT3DVERTEXBUFFER iface)
{
    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
    return IDirect3DVertexBuffer7_AddRef(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
}

ULONG WINAPI
Thunk_IDirect3DVertexBufferImpl_1_Release(LPDIRECT3DVERTEXBUFFER iface)
{
    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
    return IDirect3DVertexBuffer7_Release(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_Lock(LPDIRECT3DVERTEXBUFFER iface,
                                       DWORD dwFlags,
                                       LPVOID* lplpData,
                                       LPDWORD lpdwSize)
{
    TRACE("(%p)->(%08lx,%p,%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, dwFlags, lplpData, lpdwSize);
    return IDirect3DVertexBuffer7_Lock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
                                       dwFlags,
                                       lplpData,
                                       lpdwSize);
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_Unlock(LPDIRECT3DVERTEXBUFFER iface)
{
    TRACE("(%p)->() thunking to IDirect3DVertexBuffer7 interface.\n", iface);
    return IDirect3DVertexBuffer7_Unlock(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface));
}

HRESULT WINAPI
Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc(LPDIRECT3DVERTEXBUFFER iface,
                                                      LPD3DVERTEXBUFFERDESC lpD3DVertexBufferDesc)
{
    TRACE("(%p)->(%p) thunking to IDirect3DVertexBuffer7 interface.\n", iface, lpD3DVertexBufferDesc);
    return IDirect3DVertexBuffer7_GetVertexBufferDesc(COM_INTERFACE_CAST(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer, IDirect3DVertexBuffer7, iface),
                                                      lpD3DVertexBufferDesc);
}

#define copy_and_next(dest, src, size) memcpy(dest, src, size); dest += (size)

static HRESULT
process_vertices_strided(IDirect3DVertexBufferImpl *This,
			 DWORD dwVertexOp,
			 DWORD dwDestIndex,
			 DWORD dwCount,
			 LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
			 DWORD dwVertexTypeDesc,
			 IDirect3DDeviceImpl *device_impl,
			 DWORD dwFlags)
{
    IDirect3DVertexBufferGLImpl *glThis = (IDirect3DVertexBufferGLImpl *) This;
    DWORD size = get_flexible_vertex_size(dwVertexTypeDesc);
    char *dest_ptr;
    int i;

    This->processed = TRUE;

    /* For the moment, the trick is to save the transform and lighting state at process
       time to restore them at drawing time.
       
       The BIG problem with this method is nothing prevents D3D to do dirty tricks like
       processing two different sets of vertices with two different rendering parameters
       and then to display them using the same DrawPrimitive call.

       It would be nice to check for such code here (but well, even this is not trivial
       to do).

       This is exactly what the TWIST.EXE demo does but using the same kind of ugly stuff
       in the D3DExecuteBuffer code. I really wonder why Microsoft went back in time when
       implementing this mostly useless (IMHO) API.
    */
    glThis->dwVertexTypeDesc = dwVertexTypeDesc;

    if (dwVertexTypeDesc & D3DFVF_NORMAL) {
        WARN(" lighting state not saved yet... Some strange stuff may happen !\n");
    }

    if (glThis->vertices == NULL) {
        glThis->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, size * This->desc.dwNumVertices);
    }
    dest_ptr = ((char *) glThis->vertices) + dwDestIndex * size;
    
    memcpy(&(glThis->world_mat), device_impl->world_mat, sizeof(D3DMATRIX));
    memcpy(&(glThis->view_mat), device_impl->view_mat, sizeof(D3DMATRIX));
    memcpy(&(glThis->proj_mat), device_impl->proj_mat, sizeof(D3DMATRIX));

    for (i = 0; i < dwCount; i++) {
        int tex_index;

	if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
	    D3DVALUE *position =
	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
	    copy_and_next(dest_ptr, position, 3 * sizeof(D3DVALUE));
	} else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
	    D3DVALUE *position =
	      (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
	    copy_and_next(dest_ptr, position, 4 * sizeof(D3DVALUE));
	}
	if (dwVertexTypeDesc & D3DFVF_RESERVED1) {
	    dest_ptr += sizeof(DWORD);
	}
	if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
	    D3DVALUE *normal = 
	      (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
	    copy_and_next(dest_ptr, normal, 3 * sizeof(D3DVALUE));
	}
	if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
	    DWORD *color_d = 
	      (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
	    copy_and_next(dest_ptr, color_d, sizeof(DWORD));
	}
	if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
	    DWORD *color_s = 
	      (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
	    copy_and_next(dest_ptr, color_s, sizeof(DWORD));
	}
	for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
	    D3DVALUE *tex_coord =
	      (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
			    i * lpStrideData->textureCoords[tex_index].dwStride);
	    copy_and_next(dest_ptr, tex_coord, 2 * sizeof(D3DVALUE));
	}

	if (TRACE_ON(ddraw_geom)) {
	    if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZ) {
	        D3DVALUE *position =
		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
		TRACE_(ddraw_geom)(" %f %f %f", position[0], position[1], position[2]);
	    } else if ((dwVertexTypeDesc & D3DFVF_POSITION_MASK) == D3DFVF_XYZRHW) {
	        D3DVALUE *position =
		  (D3DVALUE *) (((char *) lpStrideData->position.lpvData) + i * lpStrideData->position.dwStride);
		TRACE_(ddraw_geom)(" %f %f %f %f", position[0], position[1], position[2], position[3]);
	    }
	    if (dwVertexTypeDesc & D3DFVF_NORMAL) { 
	        D3DVALUE *normal = 
		  (D3DVALUE *) (((char *) lpStrideData->normal.lpvData) + i * lpStrideData->normal.dwStride);	    
		TRACE_(ddraw_geom)(" / %f %f %f", normal[0], normal[1], normal[2]);
	    }
	    if (dwVertexTypeDesc & D3DFVF_DIFFUSE) {
	        DWORD *color_d = 
		  (DWORD *) (((char *) lpStrideData->diffuse.lpvData) + i * lpStrideData->diffuse.dwStride);
		TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
				   (*color_d >> 16) & 0xFF,
				   (*color_d >>  8) & 0xFF,
				   (*color_d >>  0) & 0xFF,
				   (*color_d >> 24) & 0xFF);
	    }
	    if (dwVertexTypeDesc & D3DFVF_SPECULAR) { 
	        DWORD *color_s = 
		  (DWORD *) (((char *) lpStrideData->specular.lpvData) + i * lpStrideData->specular.dwStride);
		TRACE_(ddraw_geom)(" / %02lx %02lx %02lx %02lx",
				   (*color_s >> 16) & 0xFF,
				   (*color_s >>  8) & 0xFF,
				   (*color_s >>  0) & 0xFF,
				   (*color_s >> 24) & 0xFF);
	    }
	    for (tex_index = 0; tex_index < ((dwVertexTypeDesc & D3DFVF_TEXCOUNT_MASK) >> D3DFVF_TEXCOUNT_SHIFT); tex_index++) {
	        D3DVALUE *tex_coord =
		  (D3DVALUE *) (((char *) lpStrideData->textureCoords[tex_index].lpvData) + 
				i * lpStrideData->textureCoords[tex_index].dwStride);
		TRACE_(ddraw_geom)(" / %f %f", tex_coord[0], tex_coord[1]);
	    }
	    TRACE_(ddraw_geom)("\n");
	}
    }

    return DD_OK;
}

#undef copy_and_next

HRESULT WINAPI
GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices(LPDIRECT3DVERTEXBUFFER7 iface,
						  DWORD dwVertexOp,
						  DWORD dwDestIndex,
						  DWORD dwCount,
						  LPDIRECT3DVERTEXBUFFER7 lpSrcBuffer,
						  DWORD dwSrcIndex,
						  LPDIRECT3DDEVICE7 lpD3DDevice,
						  DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    IDirect3DVertexBufferImpl *src_impl = ICOM_OBJECT(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, lpSrcBuffer);
    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);
    D3DDRAWPRIMITIVESTRIDEDDATA strided;
    DWORD size;

    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpSrcBuffer, dwSrcIndex, lpD3DDevice, dwFlags);    

    if (TRACE_ON(ddraw)) {
        TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
	TRACE(" - flags             : "); dump_D3DPV(dwFlags);
    }

    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;

    size = get_flexible_vertex_size(src_impl->desc.dwFVF);
    convert_FVF_to_strided_data(src_impl->desc.dwFVF, ((char *) src_impl->vertices) + dwSrcIndex * size, &strided, 0);

    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, &strided, src_impl->desc.dwFVF, device_impl, dwFlags);
}

HRESULT WINAPI
GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided(LPDIRECT3DVERTEXBUFFER7 iface,
						      DWORD dwVertexOp,
						      DWORD dwDestIndex,
						      DWORD dwCount,
						      LPD3DDRAWPRIMITIVESTRIDEDDATA lpStrideData,
						      DWORD dwVertexTypeDesc,
						      LPDIRECT3DDEVICE7 lpD3DDevice,
						      DWORD dwFlags)
{
    ICOM_THIS_FROM(IDirect3DVertexBufferImpl, IDirect3DVertexBuffer7, iface);
    IDirect3DDeviceImpl *device_impl = ICOM_OBJECT(IDirect3DDeviceImpl, IDirect3DDevice7, lpD3DDevice);

    TRACE("(%p/%p)->(%08lx,%08lx,%08lx,%p,%08lx,%p,%08lx)\n", This, iface, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, lpD3DDevice, dwFlags);
    if (TRACE_ON(ddraw)) {
        TRACE(" - vertex operations : "); dump_D3DVOP(dwVertexOp);
	TRACE(" - flags             : "); dump_D3DPV(dwFlags);
	TRACE(" - vertex format     : "); dump_flexible_vertex(dwVertexTypeDesc);
    }

    if ((dwVertexOp & D3DVOP_TRANSFORM) == 0) return DDERR_INVALIDPARAMS;

    return process_vertices_strided(This, dwVertexOp, dwDestIndex, dwCount, lpStrideData, dwVertexTypeDesc, device_impl, dwFlags);
}



#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer7.fun))
#else
# define XCAST(fun)     (void*)
#endif

ICOM_VTABLE(IDirect3DVertexBuffer7) VTABLE_IDirect3DVertexBuffer7 =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    XCAST(QueryInterface) Main_IDirect3DVertexBufferImpl_7_1T_QueryInterface,
    XCAST(AddRef) Main_IDirect3DVertexBufferImpl_7_1T_AddRef,
    XCAST(Release) Main_IDirect3DVertexBufferImpl_7_1T_Release,
    XCAST(Lock) Main_IDirect3DVertexBufferImpl_7_1T_Lock,
    XCAST(Unlock) Main_IDirect3DVertexBufferImpl_7_1T_Unlock,
    XCAST(ProcessVertices) GL_IDirect3DVertexBufferImpl_7_1T_ProcessVertices,
    XCAST(GetVertexBufferDesc) Main_IDirect3DVertexBufferImpl_7_1T_GetVertexBufferDesc,
    XCAST(Optimize) Main_IDirect3DVertexBufferImpl_7_1T_Optimize,
    XCAST(ProcessVerticesStrided) GL_IDirect3DVertexBufferImpl_7_ProcessVerticesStrided
};

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
#undef XCAST
#endif


#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
# define XCAST(fun)     (typeof(VTABLE_IDirect3DVertexBuffer.fun))
#else
# define XCAST(fun)     (void*)
#endif

ICOM_VTABLE(IDirect3DVertexBuffer) VTABLE_IDirect3DVertexBuffer =
{
    ICOM_MSVTABLE_COMPAT_DummyRTTIVALUE
    XCAST(QueryInterface) Thunk_IDirect3DVertexBufferImpl_1_QueryInterface,
    XCAST(AddRef) Thunk_IDirect3DVertexBufferImpl_1_AddRef,
    XCAST(Release) Thunk_IDirect3DVertexBufferImpl_1_Release,
    XCAST(Lock) Thunk_IDirect3DVertexBufferImpl_1_Lock,
    XCAST(Unlock) Thunk_IDirect3DVertexBufferImpl_1_Unlock,
    XCAST(ProcessVertices) Thunk_IDirect3DVertexBufferImpl_1_ProcessVertices,
    XCAST(GetVertexBufferDesc) Thunk_IDirect3DVertexBufferImpl_1_GetVertexBufferDesc,
    XCAST(Optimize) Thunk_IDirect3DVertexBufferImpl_1_Optimize
};

#if !defined(__STRICT_ANSI__) && defined(__GNUC__)
#undef XCAST
#endif

HRESULT d3dvertexbuffer_create(IDirect3DVertexBufferImpl **obj, IDirectDrawImpl *d3d, LPD3DVERTEXBUFFERDESC lpD3DVertBufDesc, DWORD dwFlags)
{
    IDirect3DVertexBufferImpl *object;
    static const flag_info flags[] = {
        FE(D3DVBCAPS_DONOTCLIP),
        FE(D3DVBCAPS_OPTIMIZED),
	FE(D3DVBCAPS_SYSTEMMEMORY),
	FE(D3DVBCAPS_WRITEONLY)
    };

    object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(IDirect3DVertexBufferGLImpl));
    if (object == NULL) return DDERR_OUTOFMEMORY;

    object->ref = 1;
    object->d3d = d3d;
    object->desc = *lpD3DVertBufDesc;
    object->vertex_buffer_size = get_flexible_vertex_size(lpD3DVertBufDesc->dwFVF) * lpD3DVertBufDesc->dwNumVertices;
    object->vertices = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, object->vertex_buffer_size);
    
    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer,  VTABLE_IDirect3DVertexBuffer);
    ICOM_INIT_INTERFACE(object, IDirect3DVertexBuffer7, VTABLE_IDirect3DVertexBuffer7);

    *obj = object;

    if (TRACE_ON(ddraw)) {
        TRACE(" creating implementation at %p with description : \n", *obj);
	TRACE("  flags        : "); DDRAW_dump_flags_(lpD3DVertBufDesc->dwCaps, flags, sizeof(flags)/sizeof(flags[0]), TRUE);
	TRACE("  vertex type  : "); dump_flexible_vertex(lpD3DVertBufDesc->dwFVF);
	TRACE("  num vertices : %ld\n", lpD3DVertBufDesc->dwNumVertices);
    }
    
    
    return D3D_OK;
}
