Implementation of the ID3DXMatrixStack interface, with a few tests
=Jérôme Gardou
jerome
Mon Oct 27 13:32:47 CDT 2008
---
dlls/d3dx8/d3dx8_private.h | 8 ++-
dlls/d3dx8/math.c | 143 +++++++++++++++++++++++++++++++++++--------
dlls/d3dx8/tests/math.c | 30 +++++++++
3 files changed, 152 insertions(+), 29 deletions(-)
diff --git a/dlls/d3dx8/d3dx8_private.h b/dlls/d3dx8/d3dx8_private.h
index 923f285..6d116c5 100644
--- a/dlls/d3dx8/d3dx8_private.h
+++ b/dlls/d3dx8/d3dx8_private.h
@@ -79,6 +79,11 @@ struct ID3DXFontImpl
/*****************************************************************************
* ID3DXMatrixStackImpl implementation structure
*/
+typedef struct D3DXMatrixStackNode {
+ D3DMATRIX* matrix ;
+ struct D3DXMatrixStackNode* next ;
+} D3DXMatrixStackNode;
+
struct ID3DXMatrixStackImpl
{
/* IUnknown fields */
@@ -86,8 +91,7 @@ struct ID3DXMatrixStackImpl
LONG ref;
/* ID3DXMatrixStack fields */
- int current;
- D3DXMATRIX *stack;
+ D3DXMatrixStackNode* top;
};
#endif /*__WINE_D3DX8_PRIVATE_H */
diff --git a/dlls/d3dx8/math.c b/dlls/d3dx8/math.c
index 3bc171f..cad9cdc 100644
--- a/dlls/d3dx8/math.c
+++ b/dlls/d3dx8/math.c
@@ -584,6 +584,8 @@ D3DXMATRIX* WINAPI D3DXMatrixTranspose(D3DXMATRIX *pout, CONST D3DXMATRIX *pm)
HRESULT WINAPI D3DXCreateMatrixStack(DWORD flags, LPD3DXMATRIXSTACK* ppstack)
{
ID3DXMatrixStackImpl* object;
+ if(ppstack == NULL)
+ return D3DERR_INVALIDCALL ;
object = HeapAlloc(GetProcessHeap(), HEAP_ZERO_MEMORY, sizeof(ID3DXMatrixStackImpl));
if ( object == NULL )
@@ -593,7 +595,21 @@ HRESULT WINAPI D3DXCreateMatrixStack(DWORD flags, LPD3DXMATRIXSTACK* ppstack)
}
object->lpVtbl = &ID3DXMatrixStack_Vtbl;
object->ref = 1;
- object->current = 0;
+ object->top = HeapAlloc(GetProcessHeap(), 0, sizeof(D3DXMatrixStackNode)) ;
+ if (object->top == NULL) {
+ *ppstack = NULL ;
+ HeapFree(GetProcessHeap(), 0, object) ;
+ return E_OUTOFMEMORY ;
+ }
+ object->top->matrix = HeapAlloc(GetProcessHeap(), 0, sizeof(D3DMATRIX)) ;
+ if (object->top->matrix == NULL) {
+ *ppstack = NULL ;
+ HeapFree(GetProcessHeap(), 0, object->top) ;
+ HeapFree(GetProcessHeap(), 0, object) ;
+ return E_OUTOFMEMORY ;
+ }
+ D3DXMatrixIdentity(object->top->matrix) ;
+ object->top->next = NULL ;
*ppstack = (LPD3DXMATRIXSTACK)object;
return D3D_OK;
}
@@ -624,7 +640,15 @@ static ULONG WINAPI ID3DXMatrixStackImpl_Release(ID3DXMatrixStack* iface)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
ULONG ref = InterlockedDecrement(&This->ref);
- if ( !ref ) HeapFree(GetProcessHeap(), 0, This);
+ if ( !ref ) {
+ while (This->top->next != NULL) {
+ This->lpVtbl->Pop(iface) ;
+ }
+ /*Freeing the last one*/
+ HeapFree(GetProcessHeap(),0, This->top->matrix) ;
+ HeapFree(GetProcessHeap(), 0, This->top) ;
+ HeapFree(GetProcessHeap(), 0, This);
+ }
TRACE("(%p) : ReleaseRef to %d\n", This, ref);
return ref;
}
@@ -632,106 +656,171 @@ static ULONG WINAPI ID3DXMatrixStackImpl_Release(ID3DXMatrixStack* iface)
static D3DXMATRIX* WINAPI ID3DXMatrixStackImpl_GetTop(ID3DXMatrixStack *iface)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return NULL;
+ return This->top->matrix ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_LoadIdentity(ID3DXMatrixStack *iface)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixIdentity(This->top->matrix) ;
return D3D_OK;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_LoadMatrix(ID3DXMatrixStack *iface, LPD3DXMATRIX pm)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
+ if(iface == NULL || pm == NULL)
+ return D3DERR_INVALIDCALL ;
+ CopyMemory(This->top->matrix, pm, sizeof(D3DMATRIX)) ;
return D3D_OK;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrix(ID3DXMatrixStack *iface, LPD3DXMATRIX pm)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
+ if(iface == NULL || pm == NULL)
+ return D3DERR_INVALIDCALL ;
+ D3DXMatrixMultiply(This->top->matrix, This->top->matrix, pm) ;
return D3D_OK;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_MultMatrixLocal(ID3DXMatrixStack *iface, LPD3DXMATRIX pm)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
+ if(iface == NULL || pm == NULL)
+ return D3DERR_INVALIDCALL ;
+ D3DXMatrixMultiply(This->top->matrix, pm, This->top->matrix) ;
return D3D_OK;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_Pop(ID3DXMatrixStack *iface)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+ if(This->top->next != NULL) {
+ D3DXMatrixStackNode* current = This->top ;
+ This->top = current->next ;
+ HeapFree(GetProcessHeap(), 0, current->matrix) ;
+ HeapFree(GetProcessHeap(), 0, current) ;
+ } else
+ D3DXMatrixIdentity(This->top->matrix) ;
+
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_Push(ID3DXMatrixStack *iface)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
+ D3DXMatrixStackNode* current ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ current = HeapAlloc(GetProcessHeap(), 0, sizeof(D3DXMatrixStackNode)) ;
+ current->next = This->top ;
+ current->matrix = HeapAlloc(GetProcessHeap(), 0, sizeof(D3DMATRIX)) ;
+ CopyMemory(current->matrix, This->top->matrix, sizeof(D3DMATRIX)) ;
+ This->top = current ;
return D3D_OK;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxis(ID3DXMatrixStack *iface, LPD3DXVECTOR3 pv, FLOAT angle)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL || pv == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixRotationAxis( &tmp, pv, angle );
+ D3DXMatrixMultiply(This->top->matrix, This->top->matrix, &tmp) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_RotateAxisLocal(ID3DXMatrixStack *iface, LPD3DXVECTOR3 pv, FLOAT angle)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL || pv == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixRotationAxis( &tmp, pv, angle );
+ D3DXMatrixMultiply(This->top->matrix, &tmp, This->top->matrix) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRoll(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixRotationYawPitchRoll( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, This->top->matrix, &tmp) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_RotateYawPitchRollLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixRotationYawPitchRoll( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, &tmp, This->top->matrix) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_Scale(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixScaling( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, &tmp, This->top->matrix) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_ScaleLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixScaling( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, &tmp, This->top->matrix) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_Translate(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixTranslation( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, This->top->matrix, &tmp) ;
+ return D3D_OK ;
}
static HRESULT WINAPI ID3DXMatrixStackImpl_TranslateLocal(ID3DXMatrixStack *iface, FLOAT x, FLOAT y, FLOAT z)
{
ID3DXMatrixStackImpl *This = (ID3DXMatrixStackImpl *)iface;
- FIXME("(%p) : stub\n",This);
- return D3D_OK;
+ D3DXMATRIX tmp ;
+ if(iface == NULL)
+ return D3DERR_INVALIDCALL ;
+
+ D3DXMatrixTranslation( &tmp, x, y, z);
+ D3DXMatrixMultiply(This->top->matrix, &tmp, This->top->matrix) ;
+ return D3D_OK ;
}
static const ID3DXMatrixStackVtbl ID3DXMatrixStack_Vtbl =
diff --git a/dlls/d3dx8/tests/math.c b/dlls/d3dx8/tests/math.c
index 6a4b44d..4d38d6c 100644
--- a/dlls/d3dx8/tests/math.c
+++ b/dlls/d3dx8/tests/math.c
@@ -1396,6 +1396,35 @@ static void D3X8Vector4Test(void)
expect_vec4(expectedtrans,gottrans);
}
+static void D3DXMatrixStackTest(void)
+{
+ LPD3DXMATRIXSTACK MatrixStack = NULL;
+ D3DMATRIX* matrix_ptr = NULL;
+ ULONG ref ;
+ D3DXCreateMatrixStack(0 ,&MatrixStack) ;
+ ok(MatrixStack != NULL, "Could not create the ID3DXMatrixStack interface\n") ;
+
+ matrix_ptr = ID3DXMatrixStack_GetTop(MatrixStack) ;
+ ok(matrix_ptr != NULL, "Expected GetTop to return a non NULL matrix pointer\n") ;
+ ok(D3DXMatrixIsIdentity(matrix_ptr) == TRUE, "Expected top matrix of the new stack being identity\n") ;
+ ref = ID3DXMatrixStack_AddRef(MatrixStack) ;
+ ok(ref == 2, "Expected 2, got %d : expected GetTop to not addref\n", ref);
+
+ ID3DXMatrixStack_Push(MatrixStack) ;
+ ref = ID3DXMatrixStack_AddRef(MatrixStack) ;
+ ok(ref == 3, "Expected 3, got %d : expected Push to not addref\n", ref);
+ ID3DXMatrixStack_Pop(MatrixStack) ;
+ ID3DXMatrixStack_Pop(MatrixStack) ;
+ matrix_ptr = ID3DXMatrixStack_GetTop(MatrixStack) ;
+ ok(matrix_ptr != NULL, "Expected GetTop to return a non NULL matrix pointer\n") ;
+ ok(D3DXMatrixIsIdentity(matrix_ptr) == TRUE, "Expected top matrix of the stack being identity after over popping\n") ;
+
+ /*Release everything*/
+ do {
+ ref = ID3DXMatrixStack_Release(MatrixStack) ;
+ } while ( ref != 0) ;
+}
+
START_TEST(math)
{
D3DXColorTest();
@@ -1405,4 +1434,5 @@ START_TEST(math)
D3X8Vector2Test();
D3X8Vector3Test();
D3X8Vector4Test();
+ D3DXMatrixStackTest() ;
}
--
1.5.4.3
--------------030208040004000407050400--
More information about the wine-patches
mailing list