d3dx9_36: Implement D3DXCreateMesh and initial ID3DXMesh methods.

This commit is contained in:
Misha Koshelev 2010-09-16 17:02:48 -05:00 committed by Alexandre Julliard
parent 2b94a71d23
commit af0c074d7b
3 changed files with 569 additions and 37 deletions

View File

@ -93,6 +93,24 @@ typedef struct ID3DXMatrixStackImpl
D3DXMATRIX *stack;
} ID3DXMatrixStackImpl;
/* ID3DXMesh */
typedef struct ID3DXMeshImpl
{
/* IUnknown fields */
const ID3DXMeshVtbl *lpVtbl;
LONG ref;
/* ID3DXMesh fields */
DWORD numfaces;
DWORD numvertices;
DWORD options;
DWORD fvf;
IDirect3DDevice9 *device;
IDirect3DVertexDeclaration9 *vertex_declaration;
IDirect3DVertexBuffer9 *vertex_buffer;
IDirect3DIndexBuffer9 *index_buffer;
} ID3DXMeshImpl;
/*ID3DXSprite */
typedef struct _SPRITE {
LPDIRECT3DTEXTURE9 texture;

View File

@ -29,9 +29,351 @@
#include "wingdi.h"
#include "d3dx9.h"
#include "wine/debug.h"
#include "d3dx9_36_private.h"
WINE_DEFAULT_DEBUG_CHANNEL(d3dx);
/*** IUnknown methods ***/
static HRESULT WINAPI ID3DXMeshImpl_QueryInterface(ID3DXMesh *iface, REFIID riid, LPVOID *object)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)->(%s, %p)\n", This, debugstr_guid(riid), object);
if (IsEqualGUID(riid, &IID_IUnknown) ||
IsEqualGUID(riid, &IID_ID3DXBaseMesh) ||
IsEqualGUID(riid, &IID_ID3DXMesh))
{
iface->lpVtbl->AddRef(iface);
*object = This;
return S_OK;
}
WARN("Interface %s not found.\n", debugstr_guid(riid));
return E_NOINTERFACE;
}
static ULONG WINAPI ID3DXMeshImpl_AddRef(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)->(): AddRef from %d\n", This, This->ref);
return InterlockedIncrement(&This->ref);
}
static ULONG WINAPI ID3DXMeshImpl_Release(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
TRACE("(%p)->(): Release from %d\n", This, ref + 1);
if (!ref)
{
IDirect3DIndexBuffer9_Release(This->index_buffer);
IDirect3DVertexBuffer9_Release(This->vertex_buffer);
IDirect3DVertexDeclaration9_Release(This->vertex_declaration);
IDirect3DDevice9_Release(This->device);
HeapFree(GetProcessHeap(), 0, This);
}
return ref;
}
/*** ID3DXBaseMesh ***/
static HRESULT WINAPI ID3DXMeshImpl_DrawSubset(ID3DXMesh *iface, DWORD attrib_id)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u): stub\n", This, attrib_id);
return E_NOTIMPL;
}
static DWORD WINAPI ID3DXMeshImpl_GetNumFaces(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)\n", This);
return This->numfaces;
}
static DWORD WINAPI ID3DXMeshImpl_GetNumVertices(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)\n", This);
return This->numvertices;
}
static DWORD WINAPI ID3DXMeshImpl_GetFVF(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)\n", This);
return This->fvf;
}
static HRESULT WINAPI ID3DXMeshImpl_GetDeclaration(ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
UINT numelements;
TRACE("(%p)\n", This);
if (declaration == NULL) return D3DERR_INVALIDCALL;
return IDirect3DVertexDeclaration9_GetDeclaration(This->vertex_declaration,
declaration,
&numelements);
}
static DWORD WINAPI ID3DXMeshImpl_GetNumBytesPerVertex(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p): stub\n", This);
return 0; /* arbitrary since we cannot return E_NOTIMPL */
}
static DWORD WINAPI ID3DXMeshImpl_GetOptions(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)\n", This);
return This->options;
}
static HRESULT WINAPI ID3DXMeshImpl_GetDevice(ID3DXMesh *iface, LPDIRECT3DDEVICE9 *device)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)->(%p)\n", This, device);
if (device == NULL) return D3DERR_INVALIDCALL;
*device = This->device;
IDirect3DDevice9_AddRef(This->device);
return D3D_OK;
}
static HRESULT WINAPI ID3DXMeshImpl_CloneMeshFVF(ID3DXMesh *iface, DWORD options, DWORD fvf, LPDIRECT3DDEVICE9 device, LPD3DXMESH *clone_mesh)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%u,%p,%p): stub\n", This, options, fvf, device, clone_mesh);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_CloneMesh(ID3DXMesh *iface, DWORD options, CONST D3DVERTEXELEMENT9 *declaration, LPDIRECT3DDEVICE9 device,
LPD3DXMESH *clone_mesh)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p,%p,%p): stub\n", This, options, declaration, device, clone_mesh);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_GetVertexBuffer(ID3DXMesh *iface, LPDIRECT3DVERTEXBUFFER9 *vertex_buffer)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)->(%p)\n", This, vertex_buffer);
if (vertex_buffer == NULL) return D3DERR_INVALIDCALL;
*vertex_buffer = This->vertex_buffer;
IDirect3DVertexBuffer9_AddRef(This->vertex_buffer);
return D3D_OK;
}
static HRESULT WINAPI ID3DXMeshImpl_GetIndexBuffer(ID3DXMesh *iface, LPDIRECT3DINDEXBUFFER9 *index_buffer)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
TRACE("(%p)->(%p)\n", This, index_buffer);
if (index_buffer == NULL) return D3DERR_INVALIDCALL;
*index_buffer = This->index_buffer;
IDirect3DIndexBuffer9_AddRef(This->index_buffer);
return D3D_OK;
}
static HRESULT WINAPI ID3DXMeshImpl_LockVertexBuffer(ID3DXMesh *iface, DWORD flags, LPVOID *data)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p): stub\n", This, flags, data);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_UnlockVertexBuffer(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p): stub\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_LockIndexBuffer(ID3DXMesh *iface, DWORD flags, LPVOID *data)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p): stub\n", This, flags, data);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_UnlockIndexBuffer(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p): stub\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_GetAttributeTable(ID3DXMesh *iface, D3DXATTRIBUTERANGE *attrib_table, DWORD *attrib_table_size)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%p,%p): stub\n", This, attrib_table, attrib_table_size);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_ConvertPointRepsToAdjacency(ID3DXMesh *iface, CONST DWORD *point_reps, DWORD *adjacency)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%p,%p): stub\n", This, point_reps, adjacency);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_ConvertAdjacencyToPointReps(ID3DXMesh *iface, CONST DWORD *adjacency, DWORD *point_reps)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%p,%p): stub\n", This, adjacency, point_reps);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_GenerateAdjacency(ID3DXMesh *iface, FLOAT epsilon, DWORD *adjacency)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%f,%p): stub\n", This, epsilon, adjacency);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_UpdateSemantics(ID3DXMesh *iface, D3DVERTEXELEMENT9 declaration[MAX_FVF_DECL_SIZE])
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%p): stub\n", This, declaration);
return E_NOTIMPL;
}
/*** ID3DXMesh ***/
static HRESULT WINAPI ID3DXMeshImpl_LockAttributeBuffer(ID3DXMesh *iface, DWORD flags, DWORD **data)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p): stub\n", This, flags, data);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_UnlockAttributeBuffer(ID3DXMesh *iface)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p): stub\n", This);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_Optimize(ID3DXMesh *iface, DWORD flags, CONST DWORD *adjacency_in, DWORD *adjacency_out,
DWORD *face_remap, LPD3DXBUFFER *vertex_remap, LPD3DXMESH *opt_mesh)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p,%p,%p,%p,%p): stub\n", This, flags, adjacency_in, adjacency_out, face_remap, vertex_remap, opt_mesh);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_OptimizeInplace(ID3DXMesh *iface, DWORD flags, CONST DWORD *adjacency_in, DWORD *adjacency_out,
DWORD *face_remap, LPD3DXBUFFER *vertex_remap)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%u,%p,%p,%p,%p): stub\n", This, flags, adjacency_in, adjacency_out, face_remap, vertex_remap);
return E_NOTIMPL;
}
static HRESULT WINAPI ID3DXMeshImpl_SetAttributeTable(ID3DXMesh *iface, CONST D3DXATTRIBUTERANGE *attrib_table, DWORD attrib_table_size)
{
ID3DXMeshImpl *This = (ID3DXMeshImpl *)iface;
FIXME("(%p)->(%p,%u): stub\n", This, attrib_table, attrib_table_size);
return E_NOTIMPL;
}
static const struct ID3DXMeshVtbl D3DXMesh_Vtbl =
{
/*** IUnknown methods ***/
ID3DXMeshImpl_QueryInterface,
ID3DXMeshImpl_AddRef,
ID3DXMeshImpl_Release,
/*** ID3DXBaseMesh ***/
ID3DXMeshImpl_DrawSubset,
ID3DXMeshImpl_GetNumFaces,
ID3DXMeshImpl_GetNumVertices,
ID3DXMeshImpl_GetFVF,
ID3DXMeshImpl_GetDeclaration,
ID3DXMeshImpl_GetNumBytesPerVertex,
ID3DXMeshImpl_GetOptions,
ID3DXMeshImpl_GetDevice,
ID3DXMeshImpl_CloneMeshFVF,
ID3DXMeshImpl_CloneMesh,
ID3DXMeshImpl_GetVertexBuffer,
ID3DXMeshImpl_GetIndexBuffer,
ID3DXMeshImpl_LockVertexBuffer,
ID3DXMeshImpl_UnlockVertexBuffer,
ID3DXMeshImpl_LockIndexBuffer,
ID3DXMeshImpl_UnlockIndexBuffer,
ID3DXMeshImpl_GetAttributeTable,
ID3DXMeshImpl_ConvertPointRepsToAdjacency,
ID3DXMeshImpl_ConvertAdjacencyToPointReps,
ID3DXMeshImpl_GenerateAdjacency,
ID3DXMeshImpl_UpdateSemantics,
/*** ID3DXMesh ***/
ID3DXMeshImpl_LockAttributeBuffer,
ID3DXMeshImpl_UnlockAttributeBuffer,
ID3DXMeshImpl_Optimize,
ID3DXMeshImpl_OptimizeInplace,
ID3DXMeshImpl_SetAttributeTable
};
/*************************************************************************
* D3DXBoxBoundProbe
*/
@ -599,12 +941,99 @@ BOOL WINAPI D3DXSphereBoundProbe(CONST D3DXVECTOR3 *pcenter, FLOAT radius, CONST
return TRUE;
}
/*************************************************************************
* D3DXCreateMesh
*/
HRESULT WINAPI D3DXCreateMesh(DWORD numfaces, DWORD numvertices, DWORD options, CONST D3DVERTEXELEMENT9 *declaration,
LPDIRECT3DDEVICE9 device, LPD3DXMESH *mesh)
{
FIXME("(%d, %d, %d, %p, %p, %p): stub\n", numfaces, numvertices, options, declaration, device, mesh);
HRESULT hr;
DWORD fvf;
IDirect3DVertexDeclaration9 *vertex_declaration;
IDirect3DVertexBuffer9 *vertex_buffer;
IDirect3DIndexBuffer9 *index_buffer;
ID3DXMeshImpl *object;
return E_NOTIMPL;
TRACE("(%d, %d, %d, %p, %p, %p)\n", numfaces, numvertices, options, declaration, device, mesh);
if (numfaces == 0 || numvertices == 0 || declaration == NULL || device == NULL || mesh == NULL)
{
return D3DERR_INVALIDCALL;
}
hr = D3DXFVFFromDeclarator(declaration, &fvf);
if (hr != D3D_OK)
{
fvf = 0;
}
/* Create vertex declaration */
hr = IDirect3DDevice9_CreateVertexDeclaration(device,
declaration,
&vertex_declaration);
if (FAILED(hr))
{
WARN("Unexpected return value %x from IDirect3DDevice9_CreateVertexDeclaration.\n",hr);
return hr;
}
/* Create vertex buffer */
hr = IDirect3DDevice9_CreateVertexBuffer(device,
numvertices * D3DXGetDeclVertexSize(declaration, declaration[0].Stream),
0,
fvf,
D3DPOOL_MANAGED,
&vertex_buffer,
NULL);
if (FAILED(hr))
{
WARN("Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n",hr);
IDirect3DVertexDeclaration9_Release(vertex_declaration);
return hr;
}
/* Create index buffer */
hr = IDirect3DDevice9_CreateIndexBuffer(device,
numfaces * 6, /* 3 vertices per triangle, 2 triangles per face */
0,
D3DFMT_INDEX16,
D3DPOOL_MANAGED,
&index_buffer,
NULL);
if (FAILED(hr))
{
WARN("Unexpected return value %x from IDirect3DDevice9_CreateVertexBuffer.\n",hr);
IDirect3DVertexBuffer9_Release(vertex_buffer);
IDirect3DVertexDeclaration9_Release(vertex_declaration);
return hr;
}
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXMeshImpl));
if (object == NULL)
{
IDirect3DIndexBuffer9_Release(index_buffer);
IDirect3DVertexBuffer9_Release(vertex_buffer);
IDirect3DVertexDeclaration9_Release(vertex_declaration);
*mesh = NULL;
return E_OUTOFMEMORY;
}
object->lpVtbl = &D3DXMesh_Vtbl;
object->ref = 1;
object->numfaces = numfaces;
object->numvertices = numvertices;
object->options = options;
object->fvf = fvf;
object->device = device;
IDirect3DDevice9_AddRef(device);
object->vertex_declaration = vertex_declaration;
object->vertex_buffer = vertex_buffer;
object->index_buffer = index_buffer;
*mesh = (ID3DXMesh*)object;
return D3D_OK;
}
HRESULT WINAPI D3DXCreateBox(LPDIRECT3DDEVICE9 device, FLOAT width, FLOAT height,

View File

@ -58,6 +58,9 @@ struct mesh
DWORD number_of_faces;
face *faces;
DWORD fvf;
UINT vertex_size;
};
static void free_mesh(struct mesh *mesh)
@ -132,11 +135,18 @@ static void compare_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mes
ok(vertex_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, vertex_buffer_description.Usage, 0);
ok(vertex_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
name, vertex_buffer_description.Pool, D3DPOOL_DEFAULT);
expected = number_of_vertices * sizeof(D3DXVECTOR3) * 2;
ok(vertex_buffer_description.FVF == mesh->fvf, "Test %s, result %x, expected %x\n",
name, vertex_buffer_description.FVF, mesh->fvf);
if (mesh->fvf == 0)
{
expected = number_of_vertices * mesh->vertex_size;
}
else
{
expected = number_of_vertices * D3DXGetFVFVertexSize(mesh->fvf);
}
ok(vertex_buffer_description.Size == expected, "Test %s, result %x, expected %x\n",
name, vertex_buffer_description.Size, expected);
ok(vertex_buffer_description.FVF == (D3DFVF_XYZ | D3DFVF_NORMAL), "Test %s, result %x, expected %x (D3DFVF_XYZ | D3DFVF_NORMAL)\n",
name, vertex_buffer_description.FVF, D3DFVF_XYZ | D3DFVF_NORMAL);
}
/* specify offset and size to avoid potential overruns */
@ -191,7 +201,7 @@ static void compare_mesh(const char *name, ID3DXMesh *d3dxmesh, struct mesh *mes
name, index_buffer_description.Format, D3DFMT_INDEX16);
ok(index_buffer_description.Type == D3DRTYPE_INDEXBUFFER, "Test %s, result %x, expected %x (D3DRTYPE_INDEXBUFFER)\n",
name, index_buffer_description.Type, D3DRTYPE_INDEXBUFFER);
ok(index_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, index_buffer_description.Usage, 0);
todo_wine ok(index_buffer_description.Usage == 0, "Test %s, result %x, expected %x\n", name, index_buffer_description.Usage, 0);
ok(index_buffer_description.Pool == D3DPOOL_MANAGED, "Test %s, result %x, expected %x (D3DPOOL_DEFAULT)\n",
name, index_buffer_description.Pool, D3DPOOL_DEFAULT);
expected = number_of_faces * sizeof(WORD) * 3;
@ -995,19 +1005,30 @@ static void D3DXCreateMeshTest(void)
ID3DXMesh *d3dxmesh;
int i, size;
D3DVERTEXELEMENT9 test_decl[MAX_FVF_DECL_SIZE];
DWORD fvf, options;
DWORD options;
struct mesh mesh;
static const D3DVERTEXELEMENT9 decl[3] = {
static const D3DVERTEXELEMENT9 decl1[3] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 0xC, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
D3DDECL_END(), };
hr = D3DXCreateMesh(0, 0, 0, NULL, NULL, NULL);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
static const D3DVERTEXELEMENT9 decl2[] = {
{0, 0, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_POSITION, 0},
{0, 12, D3DDECLTYPE_FLOAT3, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_NORMAL, 0},
{0, 24, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_PSIZE, 0},
{0, 28, D3DDECLTYPE_D3DCOLOR, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_COLOR, 1},
{0, 32, D3DDECLTYPE_FLOAT1, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 0},
/* 8 bytes padding */
{0, 44, D3DDECLTYPE_FLOAT4, D3DDECLMETHOD_DEFAULT, D3DDECLUSAGE_TEXCOORD, 1},
D3DDECL_END(),
};
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl, NULL, &d3dxmesh);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(0, 0, 0, NULL, NULL, NULL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, NULL, &d3dxmesh);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
wnd = CreateWindow("static", "d3dx9_test", 0, 0, 0, 0, 0, NULL, NULL, NULL, NULL);
if (!wnd)
@ -1035,14 +1056,14 @@ static void D3DXCreateMeshTest(void)
return;
}
hr = D3DXCreateMesh(0, 3, D3DXMESH_MANAGED, decl, device, &d3dxmesh);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(0, 3, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 0, D3DXMESH_MANAGED, decl, device, &d3dxmesh);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 0, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 3, 0, decl, device, &d3dxmesh);
todo_wine ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
hr = D3DXCreateMesh(1, 3, 0, decl1, device, &d3dxmesh);
ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
if (hr == D3D_OK)
{
@ -1050,13 +1071,77 @@ static void D3DXCreateMeshTest(void)
}
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, 0, device, &d3dxmesh);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl, device, NULL);
todo_wine ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, device, NULL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl, device, &d3dxmesh);
todo_wine ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl1, device, &d3dxmesh);
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
if (hr == D3D_OK)
{
/* device */
hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, NULL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = d3dxmesh->lpVtbl->GetDevice(d3dxmesh, &test_device);
ok(hr == D3D_OK, "Got result %x, expected %x (D3D_OK)\n", hr, D3D_OK);
ok(test_device == device, "Got result %p, expected %p\n", test_device, device);
if (hr == D3D_OK)
{
IDirect3DDevice9_Release(device);
}
/* declaration */
hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, NULL);
ok(hr == D3DERR_INVALIDCALL, "Got result %x, expected %x (D3DERR_INVALIDCALL)\n", hr, D3DERR_INVALIDCALL);
hr = d3dxmesh->lpVtbl->GetDeclaration(d3dxmesh, test_decl);
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
if (hr == D3D_OK)
{
size = sizeof(decl1) / sizeof(decl1[0]);
for (i = 0; i < size - 1; i++)
{
ok(test_decl[i].Stream == decl1[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl1[i].Stream);
ok(test_decl[i].Type == decl1[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl1[i].Type);
ok(test_decl[i].Method == decl1[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl1[i].Method);
ok(test_decl[i].Usage == decl1[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl1[i].Usage);
ok(test_decl[i].UsageIndex == decl1[i].UsageIndex, "Returned usage index %d, expected %d\n", test_decl[i].UsageIndex, decl1[i].UsageIndex);
ok(test_decl[i].Offset == decl1[i].Offset, "Returned offset %d, expected %d\n", test_decl[i].Offset, decl1[i].Offset);
}
ok(decl1[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
}
/* options */
options = d3dxmesh->lpVtbl->GetOptions(d3dxmesh);
ok(options == D3DXMESH_MANAGED, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options, D3DXMESH_MANAGED);
/* rest */
if (!new_mesh(&mesh, 3, 1))
{
skip("Couldn't create mesh\n");
}
else
{
memset(mesh.vertices, 0, mesh.number_of_vertices * sizeof(*mesh.vertices));
memset(mesh.faces, 0, mesh.number_of_faces * sizeof(*mesh.faces));
mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
compare_mesh("createmesh1", d3dxmesh, &mesh);
free_mesh(&mesh);
}
d3dxmesh->lpVtbl->Release(d3dxmesh);
}
/* Test a declaration that can't be converted to an FVF. */
hr = D3DXCreateMesh(1, 3, D3DXMESH_MANAGED, decl2, device, &d3dxmesh);
ok(hr == D3D_OK, "Got result %x, expected 0 (D3D_OK)\n", hr);
if (hr == D3D_OK)
{
@ -1079,23 +1164,19 @@ static void D3DXCreateMeshTest(void)
if (hr == D3D_OK)
{
size = sizeof(decl) / sizeof(decl[0]);
size = sizeof(decl2) / sizeof(decl2[0]);
for (i = 0; i < size - 1; i++)
{
ok(test_decl[i].Stream == decl[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl[i].Stream);
ok(test_decl[i].Type == decl[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl[i].Type);
ok(test_decl[i].Method == decl[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl[i].Method);
ok(test_decl[i].Usage == decl[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl[i].Usage);
ok(test_decl[i].UsageIndex == decl[i].UsageIndex, "Returned usage index %d, expected %d\n", test_decl[i].UsageIndex, decl[i].UsageIndex);
ok(test_decl[i].Offset == decl[i].Offset, "Returned offset %d, expected %d\n", decl[1].Offset, decl[i].Offset);
ok(test_decl[i].Stream == decl2[i].Stream, "Returned stream %d, expected %d\n", test_decl[i].Stream, decl2[i].Stream);
ok(test_decl[i].Type == decl2[i].Type, "Returned type %d, expected %d\n", test_decl[i].Type, decl2[i].Type);
ok(test_decl[i].Method == decl2[i].Method, "Returned method %d, expected %d\n", test_decl[i].Method, decl2[i].Method);
ok(test_decl[i].Usage == decl2[i].Usage, "Returned usage %d, expected %d\n", test_decl[i].Usage, decl2[i].Usage);
ok(test_decl[i].UsageIndex == decl2[i].UsageIndex, "Returned usage index %d, expected %d\n", test_decl[i].UsageIndex, decl2[i].UsageIndex);
ok(test_decl[i].Offset == decl2[i].Offset, "Returned offset %d, expected %d\n", test_decl[i].Offset, decl2[i].Offset);
}
ok(decl[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
ok(decl2[size-1].Stream == 0xFF, "Returned too long vertex declaration\n"); /* end element */
}
/* FVF */
fvf = d3dxmesh->lpVtbl->GetFVF(d3dxmesh);
ok(fvf == (D3DFVF_XYZ | D3DFVF_NORMAL), "Got result %x, expected %x (D3DFVF_XYZ | D3DFVF_NORMAL)\n", fvf, D3DFVF_XYZ | D3DFVF_NORMAL);
/* options */
options = d3dxmesh->lpVtbl->GetOptions(d3dxmesh);
ok(options == D3DXMESH_MANAGED, "Got result %x, expected %x (D3DXMESH_MANAGED)\n", options, D3DXMESH_MANAGED);
@ -1109,8 +1190,10 @@ static void D3DXCreateMeshTest(void)
{
memset(mesh.vertices, 0, mesh.number_of_vertices * sizeof(*mesh.vertices));
memset(mesh.faces, 0, mesh.number_of_faces * sizeof(*mesh.faces));
mesh.fvf = 0;
mesh.vertex_size = 60;
compare_mesh("createmeshfvf", d3dxmesh, &mesh);
compare_mesh("createmesh2", d3dxmesh, &mesh);
free_mesh(&mesh);
}
@ -1327,6 +1410,8 @@ static void test_sphere(IDirect3DDevice9 *device, FLOAT radius, UINT slices, UIN
return;
}
mesh.fvf = D3DFVF_XYZ | D3DFVF_NORMAL;
sprintf(name, "sphere (%g, %u, %u)", radius, slices, stacks);
compare_mesh(name, sphere, &mesh);