[PATCH 09/10] d3drm: Implement d3drm_frame3_AddRotation().
Henri Verbeet
hverbeet at codeweavers.com
Wed Jun 19 16:59:54 CDT 2019
From: Jeff Smith <whydoubt at gmail.com>
Signed-off-by: Jeff Smith <whydoubt at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
---
This supersedes patch 166702.
dlls/d3drm/frame.c | 76 +++++++++++++++++++++++++++++++++++++++----
dlls/d3drm/tests/d3drm.c | 85 ++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 154 insertions(+), 7 deletions(-)
diff --git a/dlls/d3drm/frame.c b/dlls/d3drm/frame.c
index 49a5077ed73..e31d8142a31 100644
--- a/dlls/d3drm/frame.c
+++ b/dlls/d3drm/frame.c
@@ -125,6 +125,36 @@ static void d3drm_matrix_multiply_affine(struct d3drm_matrix *dst,
*dst = tmp;
}
+static void d3drm_matrix_set_rotation(struct d3drm_matrix *matrix, D3DVECTOR *axis, float theta)
+{
+ float sin_theta, cos_theta, vers_theta;
+
+ D3DRMVectorNormalize(axis);
+ sin_theta = sinf(theta);
+ cos_theta = cosf(theta);
+ vers_theta = 1.0f - cos_theta;
+
+ matrix->_11 = vers_theta * axis->u1.x * axis->u1.x + cos_theta;
+ matrix->_21 = vers_theta * axis->u1.x * axis->u2.y - sin_theta * axis->u3.z;
+ matrix->_31 = vers_theta * axis->u1.x * axis->u3.z + sin_theta * axis->u2.y;
+ matrix->_41 = 0.0f;
+
+ matrix->_12 = vers_theta * axis->u2.y * axis->u1.x + sin_theta * axis->u3.z;
+ matrix->_22 = vers_theta * axis->u2.y * axis->u2.y + cos_theta;
+ matrix->_32 = vers_theta * axis->u2.y * axis->u3.z - sin_theta * axis->u1.x;
+ matrix->_42 = 0.0f;
+
+ matrix->_13 = vers_theta * axis->u3.z * axis->u1.x - sin_theta * axis->u2.y;
+ matrix->_23 = vers_theta * axis->u3.z * axis->u2.y + sin_theta * axis->u1.x;
+ matrix->_33 = vers_theta * axis->u3.z * axis->u3.z + cos_theta;
+ matrix->_43 = 0.0f;
+
+ matrix->_14 = 0.0f;
+ matrix->_24 = 0.0f;
+ matrix->_34 = 0.0f;
+ matrix->_44 = 1.0f;
+}
+
static HRESULT WINAPI d3drm_frame_array_QueryInterface(IDirect3DRMFrameArray *iface, REFIID riid, void **out)
{
TRACE("iface %p, riid %s, out %p.\n", iface, debugstr_guid(riid), out);
@@ -1149,26 +1179,58 @@ static HRESULT WINAPI d3drm_frame1_AddScale(IDirect3DRMFrame *iface,
static HRESULT WINAPI d3drm_frame3_AddRotation(IDirect3DRMFrame3 *iface,
D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
{
- FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n",
- iface, type, x, y, z, theta);
+ struct d3drm_frame *frame = impl_from_IDirect3DRMFrame3(iface);
+ struct d3drm_matrix m;
+ D3DVECTOR axis;
- return E_NOTIMPL;
+ TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+ axis.u1.x = x;
+ axis.u2.y = y;
+ axis.u3.z = z;
+
+ switch (type)
+ {
+ case D3DRMCOMBINE_REPLACE:
+ d3drm_matrix_set_rotation(&frame->transform, &axis, theta);
+ break;
+
+ case D3DRMCOMBINE_BEFORE:
+ d3drm_matrix_set_rotation(&m, &axis, theta);
+ d3drm_matrix_multiply_affine(&frame->transform, &m, &frame->transform);
+ break;
+
+ case D3DRMCOMBINE_AFTER:
+ d3drm_matrix_set_rotation(&m, &axis, theta);
+ d3drm_matrix_multiply_affine(&frame->transform, &frame->transform, &m);
+ break;
+
+ default:
+ FIXME("Unhandled type %#x.\n", type);
+ return D3DRMERR_BADVALUE;
+ }
+
+ return D3DRM_OK;
}
static HRESULT WINAPI d3drm_frame2_AddRotation(IDirect3DRMFrame2 *iface,
D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
{
- FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta);
+ struct d3drm_frame *frame = impl_from_IDirect3DRMFrame2(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+ return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta);
}
static HRESULT WINAPI d3drm_frame1_AddRotation(IDirect3DRMFrame *iface,
D3DRMCOMBINETYPE type, D3DVALUE x, D3DVALUE y, D3DVALUE z, D3DVALUE theta)
{
- FIXME("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e stub!\n", iface, type, x, y, z, theta);
+ struct d3drm_frame *frame = impl_from_IDirect3DRMFrame(iface);
- return E_NOTIMPL;
+ TRACE("iface %p, type %#x, x %.8e, y %.8e, z %.8e, theta %.8e.\n", iface, type, x, y, z, theta);
+
+ return d3drm_frame3_AddRotation(&frame->IDirect3DRMFrame3_iface, type, x, y, z, theta);
}
static HRESULT WINAPI d3drm_frame3_AddVisual(IDirect3DRMFrame3 *iface, IUnknown *visual)
diff --git a/dlls/d3drm/tests/d3drm.c b/dlls/d3drm/tests/d3drm.c
index 776282ce286..8b2922afbea 100644
--- a/dlls/d3drm/tests/d3drm.c
+++ b/dlls/d3drm/tests/d3drm.c
@@ -22,10 +22,12 @@
#include <limits.h>
#define COBJMACROS
+#define _USE_MATH_DEFINES
#include <d3d.h>
#include <initguid.h>
#include <d3drm.h>
#include <d3drmwin.h>
+#include <math.h>
#include "wine/test.h"
@@ -123,6 +125,20 @@ static void frame_set_transform(IDirect3DRMFrame *frame,
IDirect3DRMFrame_AddTransform(frame, D3DRMCOMBINE_REPLACE, matrix);
}
+static void matrix_sanitise(D3DRMMATRIX4D m)
+{
+ unsigned int i, j;
+
+ for (i = 0; i < 4; ++i)
+ {
+ for (j = 0; j < 4; ++j)
+ {
+ if (m[i][j] > -1e-7f && m[i][j] < 1e-7f)
+ m[i][j] = 0.0f;
+ }
+ }
+}
+
static HWND create_window(void)
{
RECT r = {0, 0, 640, 480};
@@ -2915,6 +2931,75 @@ static void test_frame_transform(void)
0.0f, 0.0f, 2.0f, 0.0f,
6.0f, 6.0f, 6.0f, 1.0f, 1);
+ frame_set_transform(frame,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 3.0f, 3.0f, 3.0f, 1.0f);
+ hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 1.0f, 0.0f, 0.0f, M_PI_2);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DRMFrame_GetTransform(frame, matrix);
+ matrix_sanitise(matrix);
+ expect_matrix(matrix,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 1);
+
+ frame_set_transform(frame,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 3.0f, 3.0f, 3.0f, 1.0f);
+ hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_BEFORE, 1.0f, 0.0f, 0.0f, M_PI_2);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DRMFrame_GetTransform(frame, matrix);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ matrix_sanitise(matrix);
+ expect_matrix(matrix,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 3.0f, 3.0f, 3.0f, 1.0f, 1);
+
+ frame_set_transform(frame,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 3.0f, 3.0f, 3.0f, 1.0f);
+ hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_AFTER, 1.0f, 0.0f, 0.0f, M_PI_2);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DRMFrame_GetTransform(frame, matrix);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ matrix_sanitise(matrix);
+ expect_matrix(matrix,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 3.0f, -3.0f, 3.0f, 1.0f, 1);
+
+ hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 1.0f, M_PI_2);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DRMFrame_GetTransform(frame, matrix);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ matrix_sanitise(matrix);
+ expect_matrix(matrix,
+ 0.0f, 1.0f, 0.0f, 0.0f,
+ -1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 1);
+
+ hr = IDirect3DRMFrame_AddRotation(frame, D3DRMCOMBINE_REPLACE, 0.0f, 0.0f, 0.0f, M_PI_2);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ hr = IDirect3DRMFrame_GetTransform(frame, matrix);
+ ok(hr == D3DRM_OK, "Got unexpected hr %#x.\n", hr);
+ matrix_sanitise(matrix);
+ expect_matrix(matrix,
+ 1.0f, 0.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 1.0f, 0.0f,
+ 0.0f, -1.0f, 0.0f, 0.0f,
+ 0.0f, 0.0f, 0.0f, 1.0f, 1);
+
IDirect3DRMFrame_Release(frame);
IDirect3DRM_Release(d3drm);
}
--
2.11.0
More information about the wine-devel
mailing list