Dylan Smith : d3dx9: Implement ID3DXMesh:: CloneMesh without vertex buffer conversion.
Alexandre Julliard
julliard at winehq.org
Tue May 10 13:33:40 CDT 2011
Module: wine
Branch: master
Commit: e62a4276ed381525f58e531b3a6f73c52f37d1f9
URL: http://source.winehq.org/git/wine.git/?a=commit;h=e62a4276ed381525f58e531b3a6f73c52f37d1f9
Author: Dylan Smith <dylan.ah.smith at gmail.com>
Date: Mon May 9 06:30:34 2011 -0400
d3dx9: Implement ID3DXMesh::CloneMesh without vertex buffer conversion.
---
dlls/d3dx9_36/mesh.c | 101 +++++++++++++++++++++++++++++++++++++++++++++++--
1 files changed, 96 insertions(+), 5 deletions(-)
diff --git a/dlls/d3dx9_36/mesh.c b/dlls/d3dx9_36/mesh.c
index 4dffa62..cfb19bc 100644
--- a/dlls/d3dx9_36/mesh.c
+++ b/dlls/d3dx9_36/mesh.c
@@ -25,6 +25,7 @@
#include "config.h"
#include "wine/port.h"
+#define COBJMACROS
#define NONAMELESSUNION
#include "windef.h"
#include "wingdi.h"
@@ -232,20 +233,110 @@ static HRESULT WINAPI ID3DXMeshImpl_GetDevice(ID3DXMesh *iface, LPDIRECT3DDEVICE
static HRESULT WINAPI ID3DXMeshImpl_CloneMeshFVF(ID3DXMesh *iface, DWORD options, DWORD fvf, LPDIRECT3DDEVICE9 device, LPD3DXMESH *clone_mesh)
{
ID3DXMeshImpl *This = impl_from_ID3DXMesh(iface);
+ HRESULT hr;
+ D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE];
- FIXME("(%p)->(%u,%u,%p,%p): stub\n", This, options, fvf, device, clone_mesh);
+ TRACE("(%p)->(%x,%x,%p,%p)\n", This, options, fvf, device, clone_mesh);
- return E_NOTIMPL;
+ hr = D3DXDeclaratorFromFVF(fvf, declaration);
+ if (FAILED(hr)) return hr;
+
+ return iface->lpVtbl->CloneMesh(iface, options, declaration, device, clone_mesh);
}
static HRESULT WINAPI ID3DXMeshImpl_CloneMesh(ID3DXMesh *iface, DWORD options, CONST D3DVERTEXELEMENT9 *declaration, LPDIRECT3DDEVICE9 device,
- LPD3DXMESH *clone_mesh)
+ LPD3DXMESH *clone_mesh_out)
{
ID3DXMeshImpl *This = impl_from_ID3DXMesh(iface);
+ ID3DXMeshImpl *cloned_this;
+ ID3DXMesh *clone_mesh;
+ D3DVERTEXELEMENT9 orig_declaration[MAX_FVF_DECL_SIZE] = { D3DDECL_END() };
+ void *data_in, *data_out;
+ DWORD vertex_size;
+ HRESULT hr;
+ int i;
- FIXME("(%p)->(%u,%p,%p,%p): stub\n", This, options, declaration, device, clone_mesh);
+ TRACE("(%p)->(%x,%p,%p,%p)\n", This, options, declaration, device, clone_mesh_out);
- return E_NOTIMPL;
+ if (!clone_mesh_out)
+ return D3DERR_INVALIDCALL;
+
+ hr = iface->lpVtbl->GetDeclaration(iface, orig_declaration);
+ if (FAILED(hr)) return hr;
+
+ for (i = 0; orig_declaration[i].Stream != 0xff; i++) {
+ if (memcmp(&orig_declaration[i], &declaration[i], sizeof(*declaration)))
+ {
+ FIXME("Vertex buffer conversion not implemented.\n");
+ return E_NOTIMPL;
+ }
+ }
+
+ hr = D3DXCreateMesh(This->numfaces, This->numvertices, options & ~D3DXMESH_VB_SHARE,
+ declaration, device, &clone_mesh);
+ if (FAILED(hr)) return hr;
+
+ cloned_this = impl_from_ID3DXMesh(clone_mesh);
+ vertex_size = clone_mesh->lpVtbl->GetNumBytesPerVertex(clone_mesh);
+
+ if (options & D3DXMESH_VB_SHARE) {
+ IDirect3DVertexBuffer9_AddRef(This->vertex_buffer);
+ /* FIXME: refactor to avoid creating a new vertex buffer */
+ IDirect3DVertexBuffer9_Release(cloned_this->vertex_buffer);
+ cloned_this->vertex_buffer = This->vertex_buffer;
+ } else {
+ hr = iface->lpVtbl->LockVertexBuffer(iface, D3DLOCK_READONLY, &data_in);
+ if (FAILED(hr)) goto error;
+ hr = clone_mesh->lpVtbl->LockVertexBuffer(clone_mesh, D3DLOCK_DISCARD, &data_out);
+ if (FAILED(hr)) {
+ iface->lpVtbl->UnlockVertexBuffer(iface);
+ goto error;
+ }
+ memcpy(data_out, data_in, This->numvertices * vertex_size);
+ clone_mesh->lpVtbl->UnlockVertexBuffer(clone_mesh);
+ iface->lpVtbl->UnlockVertexBuffer(iface);
+ }
+
+ hr = iface->lpVtbl->LockIndexBuffer(iface, D3DLOCK_READONLY, &data_in);
+ if (FAILED(hr)) goto error;
+ hr = clone_mesh->lpVtbl->LockIndexBuffer(clone_mesh, D3DLOCK_DISCARD, &data_out);
+ if (FAILED(hr)) {
+ iface->lpVtbl->UnlockIndexBuffer(iface);
+ goto error;
+ }
+ if ((options ^ This->options) & D3DXMESH_32BIT) {
+ if (options & D3DXMESH_32BIT) {
+ for (i = 0; i < This->numfaces * 3; i++)
+ ((DWORD*)data_out)[i] = ((WORD*)data_in)[i];
+ } else {
+ for (i = 0; i < This->numfaces * 3; i++)
+ ((WORD*)data_out)[i] = ((DWORD*)data_in)[i];
+ }
+ } else {
+ memcpy(data_out, data_in, This->numfaces * 3 * (options & D3DXMESH_32BIT ? 4 : 2));
+ }
+ clone_mesh->lpVtbl->UnlockIndexBuffer(clone_mesh);
+ iface->lpVtbl->UnlockIndexBuffer(iface);
+
+ memcpy(cloned_this->attrib_buffer, This->attrib_buffer, This->numfaces * sizeof(*This->attrib_buffer));
+
+ if (This->attrib_table_size)
+ {
+ cloned_this->attrib_table_size = This->attrib_table_size;
+ cloned_this->attrib_table = HeapAlloc(GetProcessHeap(), 0, This->attrib_table_size * sizeof(*This->attrib_table));
+ if (!cloned_this->attrib_table) {
+ hr = E_OUTOFMEMORY;
+ goto error;
+ }
+ memcpy(cloned_this->attrib_table, This->attrib_table, This->attrib_table_size * sizeof(*This->attrib_table));
+ }
+
+ *clone_mesh_out = clone_mesh;
+
+ return D3D_OK;
+error:
+ IUnknown_Release(clone_mesh);
+ return hr;
}
static HRESULT WINAPI ID3DXMeshImpl_GetVertexBuffer(ID3DXMesh *iface, LPDIRECT3DVERTEXBUFFER9 *vertex_buffer)
More information about the wine-cvs
mailing list