Jeff Smith : d3drm: Implement d3drm_frame3_AddRotation().

Alexandre Julliard julliard at winehq.org
Thu Jun 20 16:04:18 CDT 2019


Module: wine
Branch: master
Commit: c241a9c054838d338e1d69f510c6e1fea0be7401
URL:    https://source.winehq.org/git/wine.git/?a=commit;h=c241a9c054838d338e1d69f510c6e1fea0be7401

Author: Jeff Smith <whydoubt at gmail.com>
Date:   Thu Jun 20 02:47:54 2019 +0430

d3drm: Implement d3drm_frame3_AddRotation().

Signed-off-by: Jeff Smith <whydoubt at gmail.com>
Signed-off-by: Henri Verbeet <hverbeet at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>

---

 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 af1a3ac..b6b4075 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 0d18d08..e1ade86 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);
 }




More information about the wine-cvs mailing list